diff --git a/sp/src/materialsystem/stdshaders/Release_dx9_mod_hl2/game_shader_dx9.dll b/sp/src/materialsystem/stdshaders/Release_dx9_mod_hl2/game_shader_dx9.dll new file mode 100644 index 00000000..f7d9e1c7 Binary files /dev/null and b/sp/src/materialsystem/stdshaders/Release_dx9_mod_hl2/game_shader_dx9.dll differ diff --git a/sp/src/materialsystem/stdshaders/Release_dx9_mod_hl2/game_shader_dx9.pdb b/sp/src/materialsystem/stdshaders/Release_dx9_mod_hl2/game_shader_dx9.pdb new file mode 100644 index 00000000..e89aa569 Binary files /dev/null and b/sp/src/materialsystem/stdshaders/Release_dx9_mod_hl2/game_shader_dx9.pdb differ diff --git a/sp/src/materialsystem/stdshaders/Release_dx9_mod_hl2/vc120.pdb b/sp/src/materialsystem/stdshaders/Release_dx9_mod_hl2/vc120.pdb new file mode 100644 index 00000000..c48d605d Binary files /dev/null and b/sp/src/materialsystem/stdshaders/Release_dx9_mod_hl2/vc120.pdb differ diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/Fxaa3_11.h b/sp/src/materialsystem/stdshaders/ShaderEdit/Fxaa3_11.h new file mode 100644 index 00000000..92a37374 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/Fxaa3_11.h @@ -0,0 +1,2047 @@ +/*============================================================================ + + + NVIDIA FXAA 3.11 by TIMOTHY LOTTES + + +------------------------------------------------------------------------------ +COPYRIGHT (C) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS RESERVED. +------------------------------------------------------------------------------ +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED +*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA +OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR +CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR +LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, +OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE +THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + +------------------------------------------------------------------------------ + INTEGRATION CHECKLIST +------------------------------------------------------------------------------ +(1.) +In the shader source, setup defines for the desired configuration. +When providing multiple shaders (for different presets), +simply setup the defines differently in multiple files. +Example, + + #define FXAA_PC 1 + #define FXAA_HLSL_5 1 + #define FXAA_QUALITY__PRESET 12 + +Or, + + #define FXAA_360 1 + +Or, + + #define FXAA_PS3 1 + +Etc. + +(2.) +Then include this file, + + #include "Fxaa3_11.h" + +(3.) +Then call the FXAA pixel shader from within your desired shader. +Look at the FXAA Quality FxaaPixelShader() for docs on inputs. +As for FXAA 3.11 all inputs for all shaders are the same +to enable easy porting between platforms. + + return FxaaPixelShader(...); + +(4.) +Insure pass prior to FXAA outputs RGBL (see next section). +Or use, + + #define FXAA_GREEN_AS_LUMA 1 + +(5.) +Setup engine to provide the following constants +which are used in the FxaaPixelShader() inputs, + + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir + +Look at the FXAA Quality FxaaPixelShader() for docs on inputs. + +(6.) +Have FXAA vertex shader run as a full screen triangle, +and output "pos" and "fxaaConsolePosPos" +such that inputs in the pixel shader provide, + + // {xy} = center of pixel + FxaaFloat2 pos, + + // {xy__} = upper left of pixel + // {__zw} = lower right of pixel + FxaaFloat4 fxaaConsolePosPos, + +(7.) +Insure the texture sampler(s) used by FXAA are set to bilinear filtering. + + +------------------------------------------------------------------------------ + INTEGRATION - RGBL AND COLORSPACE +------------------------------------------------------------------------------ +FXAA3 requires RGBL as input unless the following is set, + + #define FXAA_GREEN_AS_LUMA 1 + +In which case the engine uses green in place of luma, +and requires RGB input is in a non-linear colorspace. + +RGB should be LDR (low dynamic range). +Specifically do FXAA after tonemapping. + +RGB data as returned by a texture fetch can be non-linear, +or linear when FXAA_GREEN_AS_LUMA is not set. +Note an "sRGB format" texture counts as linear, +because the result of a texture fetch is linear data. +Regular "RGBA8" textures in the sRGB colorspace are non-linear. + +If FXAA_GREEN_AS_LUMA is not set, +luma must be stored in the alpha channel prior to running FXAA. +This luma should be in a perceptual space (could be gamma 2.0). +Example pass before FXAA where output is gamma 2.0 encoded, + + color.rgb = ToneMap(color.rgb); // linear color output + color.rgb = sqrt(color.rgb); // gamma 2.0 color output + return color; + +To use FXAA, + + color.rgb = ToneMap(color.rgb); // linear color output + color.rgb = sqrt(color.rgb); // gamma 2.0 color output + color.a = dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114)); // compute luma + return color; + +Another example where output is linear encoded, +say for instance writing to an sRGB formated render target, +where the render target does the conversion back to sRGB after blending, + + color.rgb = ToneMap(color.rgb); // linear color output + return color; + +To use FXAA, + + color.rgb = ToneMap(color.rgb); // linear color output + color.a = sqrt(dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114))); // compute luma + return color; + +Getting luma correct is required for the algorithm to work correctly. + + +------------------------------------------------------------------------------ + BEING LINEARLY CORRECT? +------------------------------------------------------------------------------ +Applying FXAA to a framebuffer with linear RGB color will look worse. +This is very counter intuitive, but happends to be true in this case. +The reason is because dithering artifacts will be more visiable +in a linear colorspace. + + +------------------------------------------------------------------------------ + COMPLEX INTEGRATION +------------------------------------------------------------------------------ +Q. What if the engine is blending into RGB before wanting to run FXAA? + +A. In the last opaque pass prior to FXAA, + have the pass write out luma into alpha. + Then blend into RGB only. + FXAA should be able to run ok + assuming the blending pass did not any add aliasing. + This should be the common case for particles and common blending passes. + +A. Or use FXAA_GREEN_AS_LUMA. + +============================================================================*/ + +/*============================================================================ + + INTEGRATION KNOBS + +============================================================================*/ +// +// FXAA_PS3 and FXAA_360 choose the console algorithm (FXAA3 CONSOLE). +// FXAA_360_OPT is a prototype for the new optimized 360 version. +// +// 1 = Use API. +// 0 = Don't use API. +// +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_PS3 + #define FXAA_PS3 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_360 + #define FXAA_360 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_360_OPT + #define FXAA_360_OPT 0 +#endif +/*==========================================================================*/ +#ifndef FXAA_PC + // + // FXAA Quality + // The high quality PC algorithm. + // + #define FXAA_PC 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_PC_CONSOLE + // + // The console algorithm for PC is included + // for developers targeting really low spec machines. + // Likely better to just run FXAA_PC, and use a really low preset. + // + #define FXAA_PC_CONSOLE 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_120 + #define FXAA_GLSL_120 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_130 + #define FXAA_GLSL_130 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_3 + #define FXAA_HLSL_3 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_4 + #define FXAA_HLSL_4 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_5 + #define FXAA_HLSL_5 0 +#endif +/*==========================================================================*/ +#ifndef FXAA_GREEN_AS_LUMA + // + // For those using non-linear color, + // and either not able to get luma in alpha, or not wanting to, + // this enables FXAA to run using green as a proxy for luma. + // So with this enabled, no need to pack luma in alpha. + // + // This will turn off AA on anything which lacks some amount of green. + // Pure red and blue or combination of only R and B, will get no AA. + // + // Might want to lower the settings for both, + // fxaaConsoleEdgeThresholdMin + // fxaaQualityEdgeThresholdMin + // In order to insure AA does not get turned off on colors + // which contain a minor amount of green. + // + // 1 = On. + // 0 = Off. + // + #define FXAA_GREEN_AS_LUMA 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_EARLY_EXIT + // + // Controls algorithm's early exit path. + // On PS3 turning this ON adds 2 cycles to the shader. + // On 360 turning this OFF adds 10ths of a millisecond to the shader. + // Turning this off on console will result in a more blurry image. + // So this defaults to on. + // + // 1 = On. + // 0 = Off. + // + #define FXAA_EARLY_EXIT 1 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_DISCARD + // + // Only valid for PC OpenGL currently. + // Probably will not work when FXAA_GREEN_AS_LUMA = 1. + // + // 1 = Use discard on pixels which don't need AA. + // For APIs which enable concurrent TEX+ROP from same surface. + // 0 = Return unchanged color on pixels which don't need AA. + // + #define FXAA_DISCARD 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_FAST_PIXEL_OFFSET + // + // Used for GLSL 120 only. + // + // 1 = GL API supports fast pixel offsets + // 0 = do not use fast pixel offsets + // + #ifdef GL_EXT_gpu_shader4 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifdef GL_NV_gpu_shader5 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifdef GL_ARB_gpu_shader5 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifndef FXAA_FAST_PIXEL_OFFSET + #define FXAA_FAST_PIXEL_OFFSET 0 + #endif +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GATHER4_ALPHA + // + // 1 = API supports gather4 on alpha channel. + // 0 = API does not support gather4 on alpha channel. + // + #if (FXAA_HLSL_5 == 1) + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifdef GL_ARB_gpu_shader5 + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifdef GL_NV_gpu_shader5 + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifndef FXAA_GATHER4_ALPHA + #define FXAA_GATHER4_ALPHA 0 + #endif +#endif + +/*============================================================================ + FXAA CONSOLE PS3 - TUNING KNOBS +============================================================================*/ +#ifndef FXAA_CONSOLE__PS3_EDGE_SHARPNESS + // + // Consoles the sharpness of edges on PS3 only. + // Non-PS3 tuning is done with shader input. + // + // Due to the PS3 being ALU bound, + // there are only two safe values here: 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // + // 8.0 is sharper + // 4.0 is softer + // 2.0 is really soft (good for vector graphics inputs) + // + #if 1 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 8.0 + #endif + #if 0 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 4.0 + #endif + #if 0 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 2.0 + #endif +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_CONSOLE__PS3_EDGE_THRESHOLD + // + // Only effects PS3. + // Non-PS3 tuning is done with shader input. + // + // The minimum amount of local contrast required to apply algorithm. + // The console setting has a different mapping than the quality setting. + // + // This only applies when FXAA_EARLY_EXIT is 1. + // + // Due to the PS3 being ALU bound, + // there are only two safe values here: 0.25 and 0.125. + // These options use the shaders ability to a free *|/ by 2|4|8. + // + // 0.125 leaves less aliasing, but is softer + // 0.25 leaves more aliasing, and is sharper + // + #if 1 + #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.125 + #else + #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.25 + #endif +#endif + +/*============================================================================ + FXAA QUALITY - TUNING KNOBS +------------------------------------------------------------------------------ +NOTE the other tuning knobs are now in the shader function inputs! +============================================================================*/ +#ifndef FXAA_QUALITY__PRESET + // + // Choose the quality preset. + // This needs to be compiled into the shader as it effects code. + // Best option to include multiple presets is to + // in each shader define the preset, then include this file. + // + // OPTIONS + // ----------------------------------------------------------------------- + // 10 to 15 - default medium dither (10=fastest, 15=highest quality) + // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality) + // 39 - no dither, very expensive + // + // NOTES + // ----------------------------------------------------------------------- + // 12 = slightly faster then FXAA 3.9 and higher edge quality (default) + // 13 = about same speed as FXAA 3.9 and better than 12 + // 23 = closest to FXAA 3.9 visually and performance wise + // _ = the lowest digit is directly related to performance + // _ = the highest digit is directly related to style + // + #define FXAA_QUALITY__PRESET 12 +#endif + + +/*============================================================================ + + FXAA QUALITY - PRESETS + +============================================================================*/ + +/*============================================================================ + FXAA QUALITY - MEDIUM DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 10) + #define FXAA_QUALITY__PS 3 + #define FXAA_QUALITY__P0 1.5 + #define FXAA_QUALITY__P1 3.0 + #define FXAA_QUALITY__P2 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 11) + #define FXAA_QUALITY__PS 4 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 3.0 + #define FXAA_QUALITY__P3 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 12) + #define FXAA_QUALITY__PS 5 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 4.0 + #define FXAA_QUALITY__P4 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 13) + #define FXAA_QUALITY__PS 6 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 4.0 + #define FXAA_QUALITY__P5 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 14) + #define FXAA_QUALITY__PS 7 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 4.0 + #define FXAA_QUALITY__P6 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 15) + #define FXAA_QUALITY__PS 8 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 4.0 + #define FXAA_QUALITY__P7 12.0 +#endif + +/*============================================================================ + FXAA QUALITY - LOW DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 20) + #define FXAA_QUALITY__PS 3 + #define FXAA_QUALITY__P0 1.5 + #define FXAA_QUALITY__P1 2.0 + #define FXAA_QUALITY__P2 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 21) + #define FXAA_QUALITY__PS 4 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 22) + #define FXAA_QUALITY__PS 5 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 23) + #define FXAA_QUALITY__PS 6 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 24) + #define FXAA_QUALITY__PS 7 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 3.0 + #define FXAA_QUALITY__P6 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 25) + #define FXAA_QUALITY__PS 8 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 4.0 + #define FXAA_QUALITY__P7 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 26) + #define FXAA_QUALITY__PS 9 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 4.0 + #define FXAA_QUALITY__P8 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 27) + #define FXAA_QUALITY__PS 10 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 4.0 + #define FXAA_QUALITY__P9 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 28) + #define FXAA_QUALITY__PS 11 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 4.0 + #define FXAA_QUALITY__P10 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 29) + #define FXAA_QUALITY__PS 12 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 2.0 + #define FXAA_QUALITY__P10 4.0 + #define FXAA_QUALITY__P11 8.0 +#endif + +/*============================================================================ + FXAA QUALITY - EXTREME QUALITY +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 39) + #define FXAA_QUALITY__PS 12 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.0 + #define FXAA_QUALITY__P2 1.0 + #define FXAA_QUALITY__P3 1.0 + #define FXAA_QUALITY__P4 1.0 + #define FXAA_QUALITY__P5 1.5 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 2.0 + #define FXAA_QUALITY__P10 4.0 + #define FXAA_QUALITY__P11 8.0 +#endif + + + +/*============================================================================ + + API PORTING + +============================================================================*/ +#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1) + #define FxaaBool bool + #define FxaaDiscard discard + #define FxaaFloat float + #define FxaaFloat2 vec2 + #define FxaaFloat3 vec3 + #define FxaaFloat4 vec4 + #define FxaaHalf float + #define FxaaHalf2 vec2 + #define FxaaHalf3 vec3 + #define FxaaHalf4 vec4 + #define FxaaInt2 ivec2 + #define FxaaSat(x) clamp(x, 0.0, 1.0) + #define FxaaTex sampler2D +#else + #define FxaaBool bool + #define FxaaDiscard clip(-1) + #define FxaaFloat float + #define FxaaFloat2 float2 + #define FxaaFloat3 float3 + #define FxaaFloat4 float4 + #define FxaaHalf half + #define FxaaHalf2 half2 + #define FxaaHalf3 half3 + #define FxaaHalf4 half4 + #define FxaaSat(x) saturate(x) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_120 == 1) + // Requires, + // #version 120 + // And at least, + // #extension GL_EXT_gpu_shader4 : enable + // (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9) + #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0) + #if (FXAA_FAST_PIXEL_OFFSET == 1) + #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o) + #else + #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0) + #endif + #if (FXAA_GATHER4_ALPHA == 1) + // use #extension GL_ARB_gpu_shader5 : enable + #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) + #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) + #define FxaaTexGreen4(t, p) textureGather(t, p, 1) + #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) + #endif +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_130 == 1) + // Requires "#version 130" or better + #define FxaaTexTop(t, p) textureLod(t, p, 0.0) + #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o) + #if (FXAA_GATHER4_ALPHA == 1) + // use #extension GL_ARB_gpu_shader5 : enable + #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) + #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) + #define FxaaTexGreen4(t, p) textureGather(t, p, 1) + #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) + #endif +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_3 == 1) || (FXAA_360 == 1) || (FXAA_PS3 == 1) + #define FxaaInt2 float2 + #define FxaaTex sampler2D + #define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0)) + #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0)) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_4 == 1) + #define FxaaInt2 int2 + struct FxaaTex { SamplerState smpl; Texture2D tex; }; + #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0) + #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_5 == 1) + #define FxaaInt2 int2 + struct FxaaTex { SamplerState smpl; Texture2D tex; }; + #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0) + #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o) + #define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p) + #define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o) + #define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p) + #define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o) +#endif + + +/*============================================================================ + GREEN AS LUMA OPTION SUPPORT FUNCTION +============================================================================*/ +#if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; } +#else + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; } +#endif + + + + +/*============================================================================ + + FXAA3 QUALITY - PC + +============================================================================*/ +#if (FXAA_PC == 1) +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( + // + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy} = center of pixel + FxaaFloat2 pos, + // + // Used only for FXAA Console, and not used on the 360 version. + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy__} = upper left of pixel + // {__zw} = lower right of pixel + FxaaFloat4 fxaaConsolePosPos, + // + // Input color texture. + // {rgb_} = color in linear or perceptual color space + // if (FXAA_GREEN_AS_LUMA == 0) + // {___a} = luma in perceptual color space (not linear) + FxaaTex tex, + // + // Only used on the optimized 360 version of FXAA Console. + // For everything but 360, just use the same input here as for "tex". + // For 360, same texture, just alias with a 2nd sampler. + // This sampler needs to have an exponent bias of -1. + FxaaTex fxaaConsole360TexExpBiasNegOne, + // + // Only used on the optimized 360 version of FXAA Console. + // For everything but 360, just use the same input here as for "tex". + // For 360, same texture, just alias with a 3nd sampler. + // This sampler needs to have an exponent bias of -2. + FxaaTex fxaaConsole360TexExpBiasNegTwo, + // + // Only used on FXAA Quality. + // This must be from a constant/uniform. + // {x_} = 1.0/screenWidthInPixels + // {_y} = 1.0/screenHeightInPixels + FxaaFloat2 fxaaQualityRcpFrame, + // + // Only used on FXAA Console. + // This must be from a constant/uniform. + // This effects sub-pixel AA quality and inversely sharpness. + // Where N ranges between, + // N = 0.50 (default) + // N = 0.33 (sharper) + // {x___} = -N/screenWidthInPixels + // {_y__} = -N/screenHeightInPixels + // {__z_} = N/screenWidthInPixels + // {___w} = N/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt, + // + // Only used on FXAA Console. + // Not used on 360, but used on PS3 and PC. + // This must be from a constant/uniform. + // {x___} = -2.0/screenWidthInPixels + // {_y__} = -2.0/screenHeightInPixels + // {__z_} = 2.0/screenWidthInPixels + // {___w} = 2.0/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + // + // Only used on FXAA Console. + // Only used on 360 in place of fxaaConsoleRcpFrameOpt2. + // This must be from a constant/uniform. + // {x___} = 8.0/screenWidthInPixels + // {_y__} = 8.0/screenHeightInPixels + // {__z_} = -4.0/screenWidthInPixels + // {___w} = -4.0/screenHeightInPixels + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__SUBPIX define. + // It is here now to allow easier tuning. + // Choose the amount of sub-pixel aliasing removal. + // This can effect sharpness. + // 1.00 - upper limit (softer) + // 0.75 - default amount of filtering + // 0.50 - lower limit (sharper, less sub-pixel aliasing removal) + // 0.25 - almost off + // 0.00 - completely off + FxaaFloat fxaaQualitySubpix, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // The minimum amount of local contrast required to apply algorithm. + // 0.333 - too little (faster) + // 0.250 - low quality + // 0.166 - default + // 0.125 - high quality + // 0.063 - overkill (slower) + FxaaFloat fxaaQualityEdgeThreshold, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // 0.0833 - upper limit (default, the start of visible unfiltered edges) + // 0.0625 - high quality (faster) + // 0.0312 - visible limit (slower) + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaQualityEdgeThresholdMin, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3. + // Due to the PS3 being ALU bound, + // there are only three safe values here: 2 and 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // For all other platforms can be a non-power of two. + // 8.0 is sharper (default!!!) + // 4.0 is softer + // 2.0 is really soft (good only for vector graphics inputs) + FxaaFloat fxaaConsoleEdgeSharpness, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3. + // Due to the PS3 being ALU bound, + // there are only two safe values here: 1/4 and 1/8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // The console setting has a different mapping than the quality setting. + // Other platforms can use other values. + // 0.125 leaves less aliasing, but is softer (default!!!) + // 0.25 leaves more aliasing, and is sharper + FxaaFloat fxaaConsoleEdgeThreshold, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // The console setting has a different mapping than the quality setting. + // This only applies when FXAA_EARLY_EXIT is 1. + // This does not apply to PS3, + // PS3 was simplified to avoid more shader instructions. + // 0.06 - faster but more aliasing in darks + // 0.05 - default + // 0.04 - slower and less aliasing in darks + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaConsoleEdgeThresholdMin, + // + // Extra constants for 360 FXAA Console only. + // Use zeros or anything else for other platforms. + // These must be in physical constant registers and NOT immedates. + // Immedates will result in compiler un-optimizing. + // {xyzw} = float4(1.0, -1.0, 0.25, -0.25) + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posM; + posM.x = pos.x; + posM.y = pos.y; + #if (FXAA_GATHER4_ALPHA == 1) + #if (FXAA_DISCARD == 0) + FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); + #if (FXAA_GREEN_AS_LUMA == 0) + #define lumaM rgbyM.w + #else + #define lumaM rgbyM.y + #endif + #endif + #if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM); + FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1)); + #else + FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM); + FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1)); + #endif + #if (FXAA_DISCARD == 1) + #define lumaM luma4A.w + #endif + #define lumaE luma4A.z + #define lumaS luma4A.x + #define lumaSE luma4A.y + #define lumaNW luma4B.w + #define lumaN luma4B.z + #define lumaW luma4B.x + #else + FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); + #if (FXAA_GREEN_AS_LUMA == 0) + #define lumaM rgbyM.w + #else + #define lumaM rgbyM.y + #endif + FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy)); + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat maxSM = max(lumaS, lumaM); + FxaaFloat minSM = min(lumaS, lumaM); + FxaaFloat maxESM = max(lumaE, maxSM); + FxaaFloat minESM = min(lumaE, minSM); + FxaaFloat maxWN = max(lumaN, lumaW); + FxaaFloat minWN = min(lumaN, lumaW); + FxaaFloat rangeMax = max(maxWN, maxESM); + FxaaFloat rangeMin = min(minWN, minESM); + FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold; + FxaaFloat range = rangeMax - rangeMin; + FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled); + FxaaBool earlyExit = range < rangeMaxClamped; +/*--------------------------------------------------------------------------*/ + if(earlyExit) + #if (FXAA_DISCARD == 1) + FxaaDiscard; + #else + return rgbyM; + #endif +/*--------------------------------------------------------------------------*/ + #if (FXAA_GATHER4_ALPHA == 0) + FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); + #else + FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNS = lumaN + lumaS; + FxaaFloat lumaWE = lumaW + lumaE; + FxaaFloat subpixRcpRange = 1.0/range; + FxaaFloat subpixNSWE = lumaNS + lumaWE; + FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS; + FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNESE = lumaNE + lumaSE; + FxaaFloat lumaNWNE = lumaNW + lumaNE; + FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE; + FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNWSW = lumaNW + lumaSW; + FxaaFloat lumaSWSE = lumaSW + lumaSE; + FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2); + FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2); + FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW; + FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE; + FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4; + FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4; +/*--------------------------------------------------------------------------*/ + FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE; + FxaaFloat lengthSign = fxaaQualityRcpFrame.x; + FxaaBool horzSpan = edgeHorz >= edgeVert; + FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE; +/*--------------------------------------------------------------------------*/ + if(!horzSpan) lumaN = lumaW; + if(!horzSpan) lumaS = lumaE; + if(horzSpan) lengthSign = fxaaQualityRcpFrame.y; + FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM; +/*--------------------------------------------------------------------------*/ + FxaaFloat gradientN = lumaN - lumaM; + FxaaFloat gradientS = lumaS - lumaM; + FxaaFloat lumaNN = lumaN + lumaM; + FxaaFloat lumaSS = lumaS + lumaM; + FxaaBool pairN = abs(gradientN) >= abs(gradientS); + FxaaFloat gradient = max(abs(gradientN), abs(gradientS)); + if(pairN) lengthSign = -lengthSign; + FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange); +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posB; + posB.x = posM.x; + posB.y = posM.y; + FxaaFloat2 offNP; + offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x; + offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y; + if(!horzSpan) posB.x += lengthSign * 0.5; + if( horzSpan) posB.y += lengthSign * 0.5; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posN; + posN.x = posB.x - offNP.x * FXAA_QUALITY__P0; + posN.y = posB.y - offNP.y * FXAA_QUALITY__P0; + FxaaFloat2 posP; + posP.x = posB.x + offNP.x * FXAA_QUALITY__P0; + posP.y = posB.y + offNP.y * FXAA_QUALITY__P0; + FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0; + FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN)); + FxaaFloat subpixE = subpixC * subpixC; + FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP)); +/*--------------------------------------------------------------------------*/ + if(!pairN) lumaNN = lumaSS; + FxaaFloat gradientScaled = gradient * 1.0/4.0; + FxaaFloat lumaMM = lumaM - lumaNN * 0.5; + FxaaFloat subpixF = subpixD * subpixE; + FxaaBool lumaMLTZero = lumaMM < 0.0; +/*--------------------------------------------------------------------------*/ + lumaEndN -= lumaNN * 0.5; + lumaEndP -= lumaNN * 0.5; + FxaaBool doneN = abs(lumaEndN) >= gradientScaled; + FxaaBool doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1; + FxaaBool doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1; +/*--------------------------------------------------------------------------*/ + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 3) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 4) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 5) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 6) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 7) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 8) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 9) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 10) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 11) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 12) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12; +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } +/*--------------------------------------------------------------------------*/ + FxaaFloat dstN = posM.x - posN.x; + FxaaFloat dstP = posP.x - posM.x; + if(!horzSpan) dstN = posM.y - posN.y; + if(!horzSpan) dstP = posP.y - posM.y; +/*--------------------------------------------------------------------------*/ + FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero; + FxaaFloat spanLength = (dstP + dstN); + FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero; + FxaaFloat spanLengthRcp = 1.0/spanLength; +/*--------------------------------------------------------------------------*/ + FxaaBool directionN = dstN < dstP; + FxaaFloat dst = min(dstN, dstP); + FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP; + FxaaFloat subpixG = subpixF * subpixF; + FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5; + FxaaFloat subpixH = subpixG * fxaaQualitySubpix; +/*--------------------------------------------------------------------------*/ + FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0; + FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH); + if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign; + if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign; + #if (FXAA_DISCARD == 1) + return FxaaTexTop(tex, posM); + #else + return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM); + #endif +} +/*==========================================================================*/ +#endif + + + + +/*============================================================================ + + FXAA3 CONSOLE - PC VERSION + +------------------------------------------------------------------------------ +Instead of using this on PC, I'd suggest just using FXAA Quality with + #define FXAA_QUALITY__PRESET 10 +Or + #define FXAA_QUALITY__PRESET 20 +Either are higher qualilty and almost as fast as this on modern PC GPUs. +============================================================================*/ +#if (FXAA_PC_CONSOLE == 1) +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy)); + FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw)); + FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy)); + FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw)); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy); + #if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat lumaM = rgbyM.w; + #else + FxaaFloat lumaM = rgbyM.y; + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw); + lumaNe += 1.0/384.0; + FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe); + FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw); + FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMinM = min(lumaMin, lumaM); + FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled); + FxaaFloat lumaMaxM = max(lumaMax, lumaM); + FxaaFloat dirSwMinusNe = lumaSw - lumaNe; + FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM; + FxaaFloat dirSeMinusNw = lumaSe - lumaNw; + if(lumaMaxSubMinM < lumaMaxScaledClamped) return rgbyM; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 dir; + dir.x = dirSwMinusNe + dirSeMinusNw; + dir.y = dirSwMinusNe - dirSeMinusNw; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 dir1 = normalize(dir.xy); + FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw); + FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw); +/*--------------------------------------------------------------------------*/ + FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness; + FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2 * fxaaConsoleRcpFrameOpt2.zw); + FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2 * fxaaConsoleRcpFrameOpt2.zw); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyA = rgbyN1 + rgbyP1; + FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25); +/*--------------------------------------------------------------------------*/ + #if (FXAA_GREEN_AS_LUMA == 0) + FxaaBool twoTap = (rgbyB.w < lumaMin) || (rgbyB.w > lumaMax); + #else + FxaaBool twoTap = (rgbyB.y < lumaMin) || (rgbyB.y > lumaMax); + #endif + if(twoTap) rgbyB.xyz = rgbyA.xyz * 0.5; + return rgbyB; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + + FXAA3 CONSOLE - 360 PIXEL SHADER + +------------------------------------------------------------------------------ +This optimized version thanks to suggestions from Andy Luedke. +Should be fully tex bound in all cases. +As of the FXAA 3.11 release, I have still not tested this code, +however I fixed a bug which was in both FXAA 3.9 and FXAA 3.10. +And note this is replacing the old unoptimized version. +If it does not work, please let me know so I can fix it. +============================================================================*/ +#if (FXAA_360 == 1) +/*--------------------------------------------------------------------------*/ +[reduceTempRegUsage(4)] +float4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ + float4 lumaNwNeSwSe; + #if (FXAA_GREEN_AS_LUMA == 0) + asm { + tfetch2D lumaNwNeSwSe.w___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe._w__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.__w_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.___w, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false + }; + #else + asm { + tfetch2D lumaNwNeSwSe.y___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe._y__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.__y_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.___y, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false + }; + #endif +/*--------------------------------------------------------------------------*/ + lumaNwNeSwSe.y += 1.0/384.0; + float2 lumaMinTemp = min(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); + float2 lumaMaxTemp = max(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); + float lumaMin = min(lumaMinTemp.x, lumaMinTemp.y); + float lumaMax = max(lumaMaxTemp.x, lumaMaxTemp.y); +/*--------------------------------------------------------------------------*/ + float4 rgbyM = tex2Dlod(tex, float4(pos.xy, 0.0, 0.0)); + #if (FXAA_GREEN_AS_LUMA == 0) + float lumaMinM = min(lumaMin, rgbyM.w); + float lumaMaxM = max(lumaMax, rgbyM.w); + #else + float lumaMinM = min(lumaMin, rgbyM.y); + float lumaMaxM = max(lumaMax, rgbyM.y); + #endif + if((lumaMaxM - lumaMinM) < max(fxaaConsoleEdgeThresholdMin, lumaMax * fxaaConsoleEdgeThreshold)) return rgbyM; +/*--------------------------------------------------------------------------*/ + float2 dir; + dir.x = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.yyxx); + dir.y = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.xyxy); + dir = normalize(dir); +/*--------------------------------------------------------------------------*/ + float4 dir1 = dir.xyxy * fxaaConsoleRcpFrameOpt.xyzw; +/*--------------------------------------------------------------------------*/ + float4 dir2; + float dirAbsMinTimesC = min(abs(dir.x), abs(dir.y)) * fxaaConsoleEdgeSharpness; + dir2 = saturate(fxaaConsole360ConstDir.zzww * dir.xyxy / dirAbsMinTimesC + 0.5); + dir2 = dir2 * fxaaConsole360RcpFrameOpt2.xyxy + fxaaConsole360RcpFrameOpt2.zwzw; +/*--------------------------------------------------------------------------*/ + float4 rgbyN1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.xy, 0.0, 0.0)); + float4 rgbyP1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.zw, 0.0, 0.0)); + float4 rgbyN2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.xy, 0.0, 0.0)); + float4 rgbyP2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.zw, 0.0, 0.0)); +/*--------------------------------------------------------------------------*/ + float4 rgbyA = rgbyN1 + rgbyP1; + float4 rgbyB = rgbyN2 + rgbyP2 + rgbyA * 0.5; +/*--------------------------------------------------------------------------*/ + float4 rgbyR = ((FxaaLuma(rgbyB) - lumaMax) > 0.0) ? rgbyA : rgbyB; + rgbyR = ((FxaaLuma(rgbyB) - lumaMin) > 0.0) ? rgbyR : rgbyA; + return rgbyR; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + + FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (NO EARLY EXIT) + +============================================================================== +The code below does not exactly match the assembly. +I have a feeling that 12 cycles is possible, but was not able to get there. +Might have to increase register count to get full performance. +Note this shader does not use perspective interpolation. + +Use the following cgc options, + + --fenable-bx2 --fastmath --fastprecision --nofloatbindings + +------------------------------------------------------------------------------ + NVSHADERPERF OUTPUT +------------------------------------------------------------------------------ +For reference and to aid in debug, output of NVShaderPerf should match this, + +Shader to schedule: + 0: texpkb h0.w(TRUE), v5.zyxx, #0 + 2: addh h2.z(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x + 4: texpkb h0.w(TRUE), v5.xwxx, #0 + 6: addh h0.z(TRUE), -h2, h0.w + 7: texpkb h1.w(TRUE), v5, #0 + 9: addh h0.x(TRUE), h0.z, -h1.w + 10: addh h3.w(TRUE), h0.z, h1 + 11: texpkb h2.w(TRUE), v5.zwzz, #0 + 13: addh h0.z(TRUE), h3.w, -h2.w + 14: addh h0.x(TRUE), h2.w, h0 + 15: nrmh h1.xz(TRUE), h0_n + 16: minh_m8 h0.x(TRUE), |h1|, |h1.z| + 17: maxh h4.w(TRUE), h0, h1 + 18: divx h2.xy(TRUE), h1_n.xzzw, h0_n + 19: movr r1.zw(TRUE), v4.xxxy + 20: madr r2.xz(TRUE), -h1, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zzww, r1.zzww + 22: minh h5.w(TRUE), h0, h1 + 23: texpkb h0(TRUE), r2.xzxx, #0 + 25: madr r0.zw(TRUE), h1.xzxz, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w), r1 + 27: maxh h4.x(TRUE), h2.z, h2.w + 28: texpkb h1(TRUE), r0.zwzz, #0 + 30: addh_d2 h1(TRUE), h0, h1 + 31: madr r0.xy(TRUE), -h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 33: texpkb h0(TRUE), r0, #0 + 35: minh h4.z(TRUE), h2, h2.w + 36: fenct TRUE + 37: madr r1.xy(TRUE), h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 39: texpkb h2(TRUE), r1, #0 + 41: addh_d2 h0(TRUE), h0, h2 + 42: maxh h2.w(TRUE), h4, h4.x + 43: minh h2.x(TRUE), h5.w, h4.z + 44: addh_d2 h0(TRUE), h0, h1 + 45: slth h2.x(TRUE), h0.w, h2 + 46: sgth h2.w(TRUE), h0, h2 + 47: movh h0(TRUE), h0 + 48: addx.c0 rc(TRUE), h2, h2.w + 49: movh h0(c0.NE.x), h1 + +IPU0 ------ Simplified schedule: -------- +Pass | Unit | uOp | PC: Op +-----+--------+------+------------------------- + 1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | SCB1 | add | 2: ADDh h2.z, h0.--w-, const.--x-; + | | | + 2 | SCT0/1 | mov | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; + | TEX | txl | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; + | SCB1 | add | 6: ADDh h0.z,-h2, h0.--w-; + | | | + 3 | SCT0/1 | mov | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; + | TEX | txl | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; + | SCB0 | add | 9: ADDh h0.x, h0.z---,-h1.w---; + | SCB1 | add | 10: ADDh h3.w, h0.---z, h1; + | | | + 4 | SCT0/1 | mov | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | TEX | txl | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | SCB0 | add | 14: ADDh h0.x, h2.w---, h0; + | SCB1 | add | 13: ADDh h0.z, h3.--w-,-h2.--w-; + | | | + 5 | SCT1 | mov | 15: NRMh h1.xz, h0; + | SRB | nrm | 15: NRMh h1.xz, h0; + | SCB0 | min | 16: MINh*8 h0.x, |h1|, |h1.z---|; + | SCB1 | max | 17: MAXh h4.w, h0, h1; + | | | + 6 | SCT0 | div | 18: DIVx h2.xy, h1.xz--, h0; + | SCT1 | mov | 19: MOVr r1.zw, g[TEX0].--xy; + | SCB0 | mad | 20: MADr r2.xz,-h1, const.z-w-, r1.z-w-; + | SCB1 | min | 22: MINh h5.w, h0, h1; + | | | + 7 | SCT0/1 | mov | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; + | TEX | txl | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; + | SCB0 | max | 27: MAXh h4.x, h2.z---, h2.w---; + | SCB1 | mad | 25: MADr r0.zw, h1.--xz, const, r1; + | | | + 8 | SCT0/1 | mov | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; + | TEX | txl | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; + | SCB0/1 | add | 30: ADDh/2 h1, h0, h1; + | | | + 9 | SCT0 | mad | 31: MADr r0.xy,-h2, const.xy--, r1.zw--; + | SCT1 | mov | 33: TXLr h0, r0, const.zzzz, TEX0; + | TEX | txl | 33: TXLr h0, r0, const.zzzz, TEX0; + | SCB1 | min | 35: MINh h4.z, h2, h2.--w-; + | | | + 10 | SCT0 | mad | 37: MADr r1.xy, h2, const.xy--, r1.zw--; + | SCT1 | mov | 39: TXLr h2, r1, const.zzzz, TEX0; + | TEX | txl | 39: TXLr h2, r1, const.zzzz, TEX0; + | SCB0/1 | add | 41: ADDh/2 h0, h0, h2; + | | | + 11 | SCT0 | min | 43: MINh h2.x, h5.w---, h4.z---; + | SCT1 | max | 42: MAXh h2.w, h4, h4.---x; + | SCB0/1 | add | 44: ADDh/2 h0, h0, h1; + | | | + 12 | SCT0 | set | 45: SLTh h2.x, h0.w---, h2; + | SCT1 | set | 46: SGTh h2.w, h0, h2; + | SCB0/1 | mul | 47: MOVh h0, h0; + | | | + 13 | SCT0 | mad | 48: ADDxc0_s rc, h2, h2.w---; + | SCB0/1 | mul | 49: MOVh h0(NE0.xxxx), h1; + +Pass SCT TEX SCB + 1: 0% 100% 25% + 2: 0% 100% 25% + 3: 0% 100% 50% + 4: 0% 100% 50% + 5: 0% 0% 50% + 6: 100% 0% 75% + 7: 0% 100% 75% + 8: 0% 100% 100% + 9: 0% 100% 25% + 10: 0% 100% 100% + 11: 50% 0% 100% + 12: 50% 0% 100% + 13: 25% 0% 100% + +MEAN: 17% 61% 67% + +Pass SCT0 SCT1 TEX SCB0 SCB1 + 1: 0% 0% 100% 0% 100% + 2: 0% 0% 100% 0% 100% + 3: 0% 0% 100% 100% 100% + 4: 0% 0% 100% 100% 100% + 5: 0% 0% 0% 100% 100% + 6: 100% 100% 0% 100% 100% + 7: 0% 0% 100% 100% 100% + 8: 0% 0% 100% 100% 100% + 9: 0% 0% 100% 0% 100% + 10: 0% 0% 100% 100% 100% + 11: 100% 100% 0% 100% 100% + 12: 100% 100% 0% 100% 100% + 13: 100% 0% 0% 100% 100% + +MEAN: 30% 23% 61% 76% 100% +Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 +Results 13 cycles, 3 r regs, 923,076,923 pixels/s +============================================================================*/ +#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 0) +/*--------------------------------------------------------------------------*/ +#pragma regcount 7 +#pragma disablepc all +#pragma option O3 +#pragma option OutColorPrec=fp16 +#pragma texformat default RGBA8 +/*==========================================================================*/ +half4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ +// (1) + half4 dir; + half4 lumaNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + lumaNe.w += half(1.0/512.0); + dir.x = -lumaNe.w; + dir.z = -lumaNe.w; + #else + lumaNe.y += half(1.0/512.0); + dir.x = -lumaNe.y; + dir.z = -lumaNe.y; + #endif +/*--------------------------------------------------------------------------*/ +// (2) + half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x += lumaSw.w; + dir.z += lumaSw.w; + #else + dir.x += lumaSw.y; + dir.z += lumaSw.y; + #endif +/*--------------------------------------------------------------------------*/ +// (3) + half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x -= lumaNw.w; + dir.z += lumaNw.w; + #else + dir.x -= lumaNw.y; + dir.z += lumaNw.y; + #endif +/*--------------------------------------------------------------------------*/ +// (4) + half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x += lumaSe.w; + dir.z -= lumaSe.w; + #else + dir.x += lumaSe.y; + dir.z -= lumaSe.y; + #endif +/*--------------------------------------------------------------------------*/ +// (5) + half4 dir1_pos; + dir1_pos.xy = normalize(dir.xyz).xz; + half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); +/*--------------------------------------------------------------------------*/ +// (6) + half4 dir2_pos; + dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimesC, half(-2.0), half(2.0)); + dir1_pos.zw = pos.xy; + dir2_pos.zw = pos.xy; + half4 temp1N; + temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; +/*--------------------------------------------------------------------------*/ +// (7) + temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); + half4 rgby1; + rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; +/*--------------------------------------------------------------------------*/ +// (8) + rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); + rgby1 = (temp1N + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (9) + half4 temp2N; + temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); +/*--------------------------------------------------------------------------*/ +// (10) + half4 rgby2; + rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); + rgby2 = (temp2N + rgby2) * 0.5; +/*--------------------------------------------------------------------------*/ +// (11) + // compilier moves these scalar ops up to other cycles + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w)); + half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w)); + #else + half lumaMin = min(min(lumaNw.y, lumaSw.y), min(lumaNe.y, lumaSe.y)); + half lumaMax = max(max(lumaNw.y, lumaSw.y), max(lumaNe.y, lumaSe.y)); + #endif + rgby2 = (rgby2 + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (12) + #if (FXAA_GREEN_AS_LUMA == 0) + bool twoTapLt = rgby2.w < lumaMin; + bool twoTapGt = rgby2.w > lumaMax; + #else + bool twoTapLt = rgby2.y < lumaMin; + bool twoTapGt = rgby2.y > lumaMax; + #endif +/*--------------------------------------------------------------------------*/ +// (13) + if(twoTapLt || twoTapGt) rgby2 = rgby1; +/*--------------------------------------------------------------------------*/ + return rgby2; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + + FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (WITH EARLY EXIT) + +============================================================================== +The code mostly matches the assembly. +I have a feeling that 14 cycles is possible, but was not able to get there. +Might have to increase register count to get full performance. +Note this shader does not use perspective interpolation. + +Use the following cgc options, + + --fenable-bx2 --fastmath --fastprecision --nofloatbindings + +Use of FXAA_GREEN_AS_LUMA currently adds a cycle (16 clks). +Will look at fixing this for FXAA 3.12. +------------------------------------------------------------------------------ + NVSHADERPERF OUTPUT +------------------------------------------------------------------------------ +For reference and to aid in debug, output of NVShaderPerf should match this, + +Shader to schedule: + 0: texpkb h0.w(TRUE), v5.zyxx, #0 + 2: addh h2.y(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x + 4: texpkb h1.w(TRUE), v5.xwxx, #0 + 6: addh h0.x(TRUE), h1.w, -h2.y + 7: texpkb h2.w(TRUE), v5.zwzz, #0 + 9: minh h4.w(TRUE), h2.y, h2 + 10: maxh h5.x(TRUE), h2.y, h2.w + 11: texpkb h0.w(TRUE), v5, #0 + 13: addh h3.w(TRUE), -h0, h0.x + 14: addh h0.x(TRUE), h0.w, h0 + 15: addh h0.z(TRUE), -h2.w, h0.x + 16: addh h0.x(TRUE), h2.w, h3.w + 17: minh h5.y(TRUE), h0.w, h1.w + 18: nrmh h2.xz(TRUE), h0_n + 19: minh_m8 h2.w(TRUE), |h2.x|, |h2.z| + 20: divx h4.xy(TRUE), h2_n.xzzw, h2_n.w + 21: movr r1.zw(TRUE), v4.xxxy + 22: maxh h2.w(TRUE), h0, h1 + 23: fenct TRUE + 24: madr r0.xy(TRUE), -h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz + 26: texpkb h0(TRUE), r0, #0 + 28: maxh h5.x(TRUE), h2.w, h5 + 29: minh h5.w(TRUE), h5.y, h4 + 30: madr r1.xy(TRUE), h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz + 32: texpkb h2(TRUE), r1, #0 + 34: addh_d2 h2(TRUE), h0, h2 + 35: texpkb h1(TRUE), v4, #0 + 37: maxh h5.y(TRUE), h5.x, h1.w + 38: minh h4.w(TRUE), h1, h5 + 39: madr r0.xy(TRUE), -h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 41: texpkb h0(TRUE), r0, #0 + 43: addh_m8 h5.z(TRUE), h5.y, -h4.w + 44: madr r2.xy(TRUE), h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 46: texpkb h3(TRUE), r2, #0 + 48: addh_d2 h0(TRUE), h0, h3 + 49: addh_d2 h3(TRUE), h0, h2 + 50: movh h0(TRUE), h3 + 51: slth h3.x(TRUE), h3.w, h5.w + 52: sgth h3.w(TRUE), h3, h5.x + 53: addx.c0 rc(TRUE), h3.x, h3 + 54: slth.c0 rc(TRUE), h5.z, h5 + 55: movh h0(c0.NE.w), h2 + 56: movh h0(c0.NE.x), h1 + +IPU0 ------ Simplified schedule: -------- +Pass | Unit | uOp | PC: Op +-----+--------+------+------------------------- + 1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | SCB0 | add | 2: ADDh h2.y, h0.-w--, const.-x--; + | | | + 2 | SCT0/1 | mov | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; + | TEX | txl | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; + | SCB0 | add | 6: ADDh h0.x, h1.w---,-h2.y---; + | | | + 3 | SCT0/1 | mov | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | TEX | txl | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | SCB0 | max | 10: MAXh h5.x, h2.y---, h2.w---; + | SCB1 | min | 9: MINh h4.w, h2.---y, h2; + | | | + 4 | SCT0/1 | mov | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; + | TEX | txl | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; + | SCB0 | add | 14: ADDh h0.x, h0.w---, h0; + | SCB1 | add | 13: ADDh h3.w,-h0, h0.---x; + | | | + 5 | SCT0 | mad | 16: ADDh h0.x, h2.w---, h3.w---; + | SCT1 | mad | 15: ADDh h0.z,-h2.--w-, h0.--x-; + | SCB0 | min | 17: MINh h5.y, h0.-w--, h1.-w--; + | | | + 6 | SCT1 | mov | 18: NRMh h2.xz, h0; + | SRB | nrm | 18: NRMh h2.xz, h0; + | SCB1 | min | 19: MINh*8 h2.w, |h2.---x|, |h2.---z|; + | | | + 7 | SCT0 | div | 20: DIVx h4.xy, h2.xz--, h2.ww--; + | SCT1 | mov | 21: MOVr r1.zw, g[TEX0].--xy; + | SCB1 | max | 22: MAXh h2.w, h0, h1; + | | | + 8 | SCT0 | mad | 24: MADr r0.xy,-h2.xz--, const.zw--, r1.zw--; + | SCT1 | mov | 26: TXLr h0, r0, const.xxxx, TEX0; + | TEX | txl | 26: TXLr h0, r0, const.xxxx, TEX0; + | SCB0 | max | 28: MAXh h5.x, h2.w---, h5; + | SCB1 | min | 29: MINh h5.w, h5.---y, h4; + | | | + 9 | SCT0 | mad | 30: MADr r1.xy, h2.xz--, const.zw--, r1.zw--; + | SCT1 | mov | 32: TXLr h2, r1, const.xxxx, TEX0; + | TEX | txl | 32: TXLr h2, r1, const.xxxx, TEX0; + | SCB0/1 | add | 34: ADDh/2 h2, h0, h2; + | | | + 10 | SCT0/1 | mov | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; + | TEX | txl | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; + | SCB0 | max | 37: MAXh h5.y, h5.-x--, h1.-w--; + | SCB1 | min | 38: MINh h4.w, h1, h5; + | | | + 11 | SCT0 | mad | 39: MADr r0.xy,-h4, const.xy--, r1.zw--; + | SCT1 | mov | 41: TXLr h0, r0, const.zzzz, TEX0; + | TEX | txl | 41: TXLr h0, r0, const.zzzz, TEX0; + | SCB0 | mad | 44: MADr r2.xy, h4, const.xy--, r1.zw--; + | SCB1 | add | 43: ADDh*8 h5.z, h5.--y-,-h4.--w-; + | | | + 12 | SCT0/1 | mov | 46: TXLr h3, r2, const.xxxx, TEX0; + | TEX | txl | 46: TXLr h3, r2, const.xxxx, TEX0; + | SCB0/1 | add | 48: ADDh/2 h0, h0, h3; + | | | + 13 | SCT0/1 | mad | 49: ADDh/2 h3, h0, h2; + | SCB0/1 | mul | 50: MOVh h0, h3; + | | | + 14 | SCT0 | set | 51: SLTh h3.x, h3.w---, h5.w---; + | SCT1 | set | 52: SGTh h3.w, h3, h5.---x; + | SCB0 | set | 54: SLThc0 rc, h5.z---, h5; + | SCB1 | add | 53: ADDxc0_s rc, h3.---x, h3; + | | | + 15 | SCT0/1 | mul | 55: MOVh h0(NE0.wwww), h2; + | SCB0/1 | mul | 56: MOVh h0(NE0.xxxx), h1; + +Pass SCT TEX SCB + 1: 0% 100% 25% + 2: 0% 100% 25% + 3: 0% 100% 50% + 4: 0% 100% 50% + 5: 50% 0% 25% + 6: 0% 0% 25% + 7: 100% 0% 25% + 8: 0% 100% 50% + 9: 0% 100% 100% + 10: 0% 100% 50% + 11: 0% 100% 75% + 12: 0% 100% 100% + 13: 100% 0% 100% + 14: 50% 0% 50% + 15: 100% 0% 100% + +MEAN: 26% 60% 56% + +Pass SCT0 SCT1 TEX SCB0 SCB1 + 1: 0% 0% 100% 100% 0% + 2: 0% 0% 100% 100% 0% + 3: 0% 0% 100% 100% 100% + 4: 0% 0% 100% 100% 100% + 5: 100% 100% 0% 100% 0% + 6: 0% 0% 0% 0% 100% + 7: 100% 100% 0% 0% 100% + 8: 0% 0% 100% 100% 100% + 9: 0% 0% 100% 100% 100% + 10: 0% 0% 100% 100% 100% + 11: 0% 0% 100% 100% 100% + 12: 0% 0% 100% 100% 100% + 13: 100% 100% 0% 100% 100% + 14: 100% 100% 0% 100% 100% + 15: 100% 100% 0% 100% 100% + +MEAN: 33% 33% 60% 86% 80% +Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 +Results 15 cycles, 3 r regs, 800,000,000 pixels/s +============================================================================*/ +#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 1) +/*--------------------------------------------------------------------------*/ +#pragma regcount 7 +#pragma disablepc all +#pragma option O2 +#pragma option OutColorPrec=fp16 +#pragma texformat default RGBA8 +/*==========================================================================*/ +half4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ +// (1) + half4 rgbyNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaNe = rgbyNe.w + half(1.0/512.0); + #else + half lumaNe = rgbyNe.y + half(1.0/512.0); + #endif +/*--------------------------------------------------------------------------*/ +// (2) + half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaSwNegNe = lumaSw.w - lumaNe; + #else + half lumaSwNegNe = lumaSw.y - lumaNe; + #endif +/*--------------------------------------------------------------------------*/ +// (3) + half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxNwSw = max(lumaNw.w, lumaSw.w); + half lumaMinNwSw = min(lumaNw.w, lumaSw.w); + #else + half lumaMaxNwSw = max(lumaNw.y, lumaSw.y); + half lumaMinNwSw = min(lumaNw.y, lumaSw.y); + #endif +/*--------------------------------------------------------------------------*/ +// (4) + half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half dirZ = lumaNw.w + lumaSwNegNe; + half dirX = -lumaNw.w + lumaSwNegNe; + #else + half dirZ = lumaNw.y + lumaSwNegNe; + half dirX = -lumaNw.y + lumaSwNegNe; + #endif +/*--------------------------------------------------------------------------*/ +// (5) + half3 dir; + dir.y = 0.0; + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x = lumaSe.w + dirX; + dir.z = -lumaSe.w + dirZ; + half lumaMinNeSe = min(lumaNe, lumaSe.w); + #else + dir.x = lumaSe.y + dirX; + dir.z = -lumaSe.y + dirZ; + half lumaMinNeSe = min(lumaNe, lumaSe.y); + #endif +/*--------------------------------------------------------------------------*/ +// (6) + half4 dir1_pos; + dir1_pos.xy = normalize(dir).xz; + half dirAbsMinTimes8 = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); +/*--------------------------------------------------------------------------*/ +// (7) + half4 dir2_pos; + dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimes8, half(-2.0), half(2.0)); + dir1_pos.zw = pos.xy; + dir2_pos.zw = pos.xy; + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxNeSe = max(lumaNe, lumaSe.w); + #else + half lumaMaxNeSe = max(lumaNe, lumaSe.y); + #endif +/*--------------------------------------------------------------------------*/ +// (8) + half4 temp1N; + temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; + temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); + half lumaMax = max(lumaMaxNwSw, lumaMaxNeSe); + half lumaMin = min(lumaMinNwSw, lumaMinNeSe); +/*--------------------------------------------------------------------------*/ +// (9) + half4 rgby1; + rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; + rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); + rgby1 = (temp1N + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (10) + half4 rgbyM = h4tex2Dlod(tex, half4(pos.xy, 0.0, 0.0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxM = max(lumaMax, rgbyM.w); + half lumaMinM = min(lumaMin, rgbyM.w); + #else + half lumaMaxM = max(lumaMax, rgbyM.y); + half lumaMinM = min(lumaMin, rgbyM.y); + #endif +/*--------------------------------------------------------------------------*/ +// (11) + half4 temp2N; + temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); + half4 rgby2; + rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + half lumaRangeM = (lumaMaxM - lumaMinM) / FXAA_CONSOLE__PS3_EDGE_THRESHOLD; +/*--------------------------------------------------------------------------*/ +// (12) + rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); + rgby2 = (temp2N + rgby2) * 0.5; +/*--------------------------------------------------------------------------*/ +// (13) + rgby2 = (rgby2 + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (14) + #if (FXAA_GREEN_AS_LUMA == 0) + bool twoTapLt = rgby2.w < lumaMin; + bool twoTapGt = rgby2.w > lumaMax; + #else + bool twoTapLt = rgby2.y < lumaMin; + bool twoTapGt = rgby2.y > lumaMax; + #endif + bool earlyExit = lumaRangeM < lumaMax; + bool twoTap = twoTapLt || twoTapGt; +/*--------------------------------------------------------------------------*/ +// (15) + if(twoTap) rgby2 = rgby1; + if(earlyExit) rgby2 = rgbyM; +/*--------------------------------------------------------------------------*/ + return rgby2; } +/*==========================================================================*/ +#endif diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/basetexture_accum_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/basetexture_accum_ps30.fxc new file mode 100644 index 00000000..7226c1ec --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/basetexture_accum_ps30.fxc @@ -0,0 +1,44 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); +sampler _Sampler_01 : register( s1 ); + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float4 _texLookup_3 = tex2D( _Sampler_00, In.vTexCoord_0 ); + float3 _var0 = _texLookup_3.rgb; + float _var1 = _texLookup_3.a; + float4 _texLookup_5 = tex2D( _Sampler_01, In.vTexCoord_0 ); + float3 _var2 = _texLookup_5.rgb; + float _var3 = _texLookup_5.a; + _var0 = lerp( _var0, _var2, float( 0.800000 ) ); + _var1 = lerp( _var1, _var3, float( 0.400000 ) ); + float4 _var4 = float4( _var0, _var1 ); + Out.vColor_0 = _var4; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/basetexture_accum_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/basetexture_accum_vs30.fxc new file mode 100644 index 00000000..9c0734a8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/basetexture_accum_vs30.fxc @@ -0,0 +1,31 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + + +// Includes +#include "common_vs_fxc.h" + + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float4 _var0 = float4( In.vPos.x, In.vPos.y, In.vPos.z, 1.000000 ); + Out.vProjPos = _var0; + Out.vTexCoord_0 = In.vTexCoord_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/basetexture_blend_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/basetexture_blend_ps30.fxc new file mode 100644 index 00000000..9eb6539a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/basetexture_blend_ps30.fxc @@ -0,0 +1,40 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); +sampler _Sampler_01 : register( s1 ); + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float4 _var0 = tex2D( _Sampler_00, In.vTexCoord_0 ).rgba; + float4 _var1 = tex2D( _Sampler_01, In.vTexCoord_0 ).rgba; + float _var2 = distance( In.vTexCoord_0, float2( 0.500000, 0.500000 ) ); + _var2 = smoothstep( float( 0.000000 ), float( 0.600000 ), _var2 ); + _var0 = lerp( _var0, _var1, _var2 ); + Out.vColor_0 = _var0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/basetexture_blend_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/basetexture_blend_vs30.fxc new file mode 100644 index 00000000..9c0734a8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/basetexture_blend_vs30.fxc @@ -0,0 +1,31 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + + +// Includes +#include "common_vs_fxc.h" + + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float4 _var0 = float4( In.vPos.x, In.vPos.y, In.vPos.z, 1.000000 ); + Out.vProjPos = _var0; + Out.vTexCoord_0 = In.vTexCoord_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/common_flashlight_fxc.h b/sp/src/materialsystem/stdshaders/ShaderEdit/common_flashlight_fxc.h new file mode 100644 index 00000000..9e8c049a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/common_flashlight_fxc.h @@ -0,0 +1,821 @@ +//====== Copyright © 1996-2007, Valve Corporation, All rights reserved. =======// +// +// Purpose: Common pixel shader code specific to flashlights +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef COMMON_FLASHLIGHT_FXC_H_ +#define COMMON_FLASHLIGHT_FXC_H_ + +#include "common_ps_fxc.h" + + +// JasonM - TODO: remove this simpleton version +float DoShadow( sampler DepthSampler, float4 texCoord ) +{ + const float g_flShadowBias = 0.0005f; + float2 uoffset = float2( 0.5f/512.f, 0.0f ); + float2 voffset = float2( 0.0f, 0.5f/512.f ); + float3 projTexCoord = texCoord.xyz / texCoord.w; + float4 flashlightDepth = float4( tex2D( DepthSampler, projTexCoord + uoffset + voffset ).x, + tex2D( DepthSampler, projTexCoord + uoffset - voffset ).x, + tex2D( DepthSampler, projTexCoord - uoffset + voffset ).x, + tex2D( DepthSampler, projTexCoord - uoffset - voffset ).x ); + +# if ( defined( REVERSE_DEPTH_ON_X360 ) ) + { + flashlightDepth = 1.0f - flashlightDepth; + } +# endif + + float shadowed = 0.0f; + float z = texCoord.z/texCoord.w; + float4 dz = float4(z,z,z,z) - (flashlightDepth + float4( g_flShadowBias, g_flShadowBias, g_flShadowBias, g_flShadowBias)); + float4 shadow = float4(0.25f,0.25f,0.25f,0.25f); + + if( dz.x <= 0.0f ) + shadowed += shadow.x; + if( dz.y <= 0.0f ) + shadowed += shadow.y; + if( dz.z <= 0.0f ) + shadowed += shadow.z; + if( dz.w <= 0.0f ) + shadowed += shadow.w; + + return shadowed; +} + + +float DoShadowNvidiaRAWZOneTap( sampler DepthSampler, const float4 shadowMapPos ) +{ + float ooW = 1.0f / shadowMapPos.w; // 1 / w + float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once + + float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter + float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space + + float fDepth = dot(tex2D(DepthSampler, shadowMapCenter).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); + + return fDepth > objDepth; +} + + +float DoShadowNvidiaRAWZ( sampler DepthSampler, const float4 shadowMapPos ) +{ + float fE = 1.0f / 512.0f; // Epsilon + + float ooW = 1.0f / shadowMapPos.w; // 1 / w + float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once + + float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter + float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space + + float4 vDepths; + vDepths.x = dot(tex2D(DepthSampler, shadowMapCenter + float2( fE, fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); + vDepths.y = dot(tex2D(DepthSampler, shadowMapCenter + float2( -fE, fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); + vDepths.z = dot(tex2D(DepthSampler, shadowMapCenter + float2( fE, -fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); + vDepths.w = dot(tex2D(DepthSampler, shadowMapCenter + float2( -fE, -fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)); + + return dot(vDepths > objDepth.xxxx, float4(0.25, 0.25, 0.25, 0.25)); +} + + +float DoShadowNvidiaCheap( sampler DepthSampler, const float4 shadowMapPos ) +{ + float fTexelEpsilon = 1.0f / 1024.0f; + + float ooW = 1.0f / shadowMapPos.w; // 1 / w + float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once + + float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter + float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space + + float4 vTaps; + vTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, fTexelEpsilon), objDepth, 1 ) ).x; + vTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, fTexelEpsilon), objDepth, 1 ) ).x; + vTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, -fTexelEpsilon), objDepth, 1 ) ).x; + vTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, -fTexelEpsilon), objDepth, 1 ) ).x; + + return dot(vTaps, float4(0.25, 0.25, 0.25, 0.25)); +} + +float DoShadowNvidiaPCF3x3Box( sampler DepthSampler, const float4 shadowMapPos ) +{ + float fTexelEpsilon = 1.0f / 1024.0f; + + float ooW = 1.0f / shadowMapPos.w; // 1 / w + float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once + + float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter + float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space + + float4 vOneTaps; + vOneTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, fTexelEpsilon ), objDepth, 1 ) ).x; + vOneTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, fTexelEpsilon ), objDepth, 1 ) ).x; + vOneTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, -fTexelEpsilon ), objDepth, 1 ) ).x; + vOneTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, -fTexelEpsilon ), objDepth, 1 ) ).x; + float flOneTaps = dot( vOneTaps, float4(1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f)); + + float4 vTwoTaps; + vTwoTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, 0 ), objDepth, 1 ) ).x; + vTwoTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, 0 ), objDepth, 1 ) ).x; + vTwoTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTexelEpsilon ), objDepth, 1 ) ).x; + vTwoTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTexelEpsilon ), objDepth, 1 ) ).x; + float flTwoTaps = dot( vTwoTaps, float4(1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f)); + + float flCenterTap = tex2Dproj( DepthSampler, float4( shadowMapCenter, objDepth, 1 ) ).x * (1.0f / 9.0f); + + // Sum all 9 Taps + return flOneTaps + flTwoTaps + flCenterTap; +} + + +// +// 1 4 7 4 1 +// 4 20 33 20 4 +// 7 33 55 33 7 +// 4 20 33 20 4 +// 1 4 7 4 1 +// +float DoShadowNvidiaPCF5x5Gaussian( sampler DepthSampler, const float4 shadowMapPos ) +{ + float fEpsilon = 1.0f / 512.0f; + float fTwoEpsilon = 2.0f * fEpsilon; + + float ooW = 1.0f / shadowMapPos.w; // 1 / w + float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once + + float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter + float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space + + float4 vOneTaps; + vOneTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x; + vOneTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x; + vOneTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x; + vOneTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x; + float flOneTaps = dot( vOneTaps, float4(1.0f / 331.0f, 1.0f / 331.0f, 1.0f / 331.0f, 1.0f / 331.0f)); + + float4 vSevenTaps; + vSevenTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, 0 ), objDepth, 1 ) ).x; + vSevenTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, 0 ), objDepth, 1 ) ).x; + vSevenTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTwoEpsilon ), objDepth, 1 ) ).x; + vSevenTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTwoEpsilon ), objDepth, 1 ) ).x; + float flSevenTaps = dot( vSevenTaps, float4( 7.0f / 331.0f, 7.0f / 331.0f, 7.0f / 331.0f, 7.0f / 331.0f ) ); + + float4 vFourTapsA, vFourTapsB; + vFourTapsA.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, fEpsilon ), objDepth, 1 ) ).x; + vFourTapsA.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x; + vFourTapsA.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x; + vFourTapsA.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, fEpsilon ), objDepth, 1 ) ).x; + vFourTapsB.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, -fEpsilon ), objDepth, 1 ) ).x; + vFourTapsB.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x; + vFourTapsB.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x; + vFourTapsB.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, -fEpsilon ), objDepth, 1 ) ).x; + float flFourTapsA = dot( vFourTapsA, float4( 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f ) ); + float flFourTapsB = dot( vFourTapsB, float4( 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f ) ); + + float4 v20Taps; + v20Taps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, fEpsilon ), objDepth, 1 ) ).x; + v20Taps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, fEpsilon ), objDepth, 1 ) ).x; + v20Taps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, -fEpsilon ), objDepth, 1 ) ).x; + v20Taps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, -fEpsilon ), objDepth, 1 ) ).x; + float fl20Taps = dot( v20Taps, float4(20.0f / 331.0f, 20.0f / 331.0f, 20.0f / 331.0f, 20.0f / 331.0f)); + + float4 v33Taps; + v33Taps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, 0 ), objDepth, 1 ) ).x; + v33Taps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, 0 ), objDepth, 1 ) ).x; + v33Taps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fEpsilon ), objDepth, 1 ) ).x; + v33Taps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fEpsilon ), objDepth, 1 ) ).x; + float fl33Taps = dot( v33Taps, float4(33.0f / 331.0f, 33.0f / 331.0f, 33.0f / 331.0f, 33.0f / 331.0f)); + + float flCenterTap = tex2Dproj( DepthSampler, float4( shadowMapCenter, objDepth, 1 ) ).x * (55.0f / 331.0f); + + // Sum all 25 Taps + return flOneTaps + flSevenTaps + +flFourTapsA + flFourTapsB + fl20Taps + fl33Taps + flCenterTap; +} + + +float DoShadowATICheap( sampler DepthSampler, const float4 shadowMapPos ) +{ + float2 shadowMapCenter = shadowMapPos.xy/shadowMapPos.w; + float objDepth = shadowMapPos.z / shadowMapPos.w; + float fSampleDepth = tex2D( DepthSampler, shadowMapCenter ).x; + + objDepth = min( objDepth, 0.99999 ); //HACKHACK: On 360, surfaces at or past the far flashlight plane have an abrupt cutoff. This is temp until a smooth falloff is implemented + + return fSampleDepth > objDepth; +} + + +// Poisson disc, randomly rotated at different UVs +float DoShadowPoisson16Sample( sampler DepthSampler, sampler RandomRotationSampler, const float3 vProjCoords, const float2 vScreenPos, const float4 vShadowTweaks, bool bNvidiaHardwarePCF, bool bFetch4 ) +{ + float2 vPoissonOffset[8] = { float2( 0.3475f, 0.0042f ), + float2( 0.8806f, 0.3430f ), + float2( -0.0041f, -0.6197f ), + float2( 0.0472f, 0.4964f ), + float2( -0.3730f, 0.0874f ), + float2( -0.9217f, -0.3177f ), + float2( -0.6289f, 0.7388f ), + float2( 0.5744f, -0.7741f ) }; + + float flScaleOverMapSize = vShadowTweaks.x * 2; // Tweak parameters to shader + float2 vNoiseOffset = vShadowTweaks.zw; + float4 vLightDepths = 0, accum = 0.0f; + float2 rotOffset = 0; + + float2 shadowMapCenter = vProjCoords.xy; // Center of shadow filter + float objDepth = min( vProjCoords.z, 0.99999 ); // Object depth in shadow space + + // 2D Rotation Matrix setup + float3 RMatTop = 0, RMatBottom = 0; +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) + RMatTop.xy = tex2D( RandomRotationSampler, cFlashlightScreenScale.xy * (vScreenPos * 0.5 + 0.5) + vNoiseOffset) * 2.0 - 1.0; + RMatBottom.xy = float2(-1.0, 1.0) * RMatTop.yx; // 2x2 rotation matrix in 4-tuple +#endif + + RMatTop *= flScaleOverMapSize; // Scale up kernel while accounting for texture resolution + RMatBottom *= flScaleOverMapSize; + + RMatTop.z = shadowMapCenter.x; // To be added in d2adds generated below + RMatBottom.z = shadowMapCenter.y; + + float fResult = 0.0f; + + if ( bNvidiaHardwarePCF ) + { + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[0].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[0].xy) + RMatBottom.z; + vLightDepths.x += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[1].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[1].xy) + RMatBottom.z; + vLightDepths.y += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[2].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[2].xy) + RMatBottom.z; + vLightDepths.z += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[3].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[3].xy) + RMatBottom.z; + vLightDepths.w += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4].xy) + RMatBottom.z; + vLightDepths.x += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[5].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[5].xy) + RMatBottom.z; + vLightDepths.y += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[6].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[6].xy) + RMatBottom.z; + vLightDepths.z += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[7].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[7].xy) + RMatBottom.z; + vLightDepths.w += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x; + + fResult = dot( vLightDepths, float4( 0.25, 0.25, 0.25, 0.25) ); + } + else if ( bFetch4 ) + { +/* + +TODO: Fix this contact hardening stuff + + float flNumCloserSamples = 1; + float flAccumulatedCloserSamples = objDepth; + float4 vBlockerDepths; + + // First, search for blockers + for( int j=0; j<8; j++ ) + { + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[j].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[j].xy) + RMatBottom.z; + vBlockerDepths = tex2D( DepthSampler, rotOffset.xy ); + + // Which samples are closer than the pixel we're rendering? + float4 vCloserSamples = (vBlockerDepths < objDepth.xxxx ); // Binary comparison results + flNumCloserSamples += dot( vCloserSamples, float4(1, 1, 1, 1) ); // How many samples are closer than receiver? + flAccumulatedCloserSamples += dot (vCloserSamples, vBlockerDepths ); // Total depths from samples closer than receiver + } + + float flBlockerDepth = flAccumulatedCloserSamples / flNumCloserSamples; + float flContactHardeningScale = (objDepth - flBlockerDepth) / flBlockerDepth; + + // Scale the kernel + RMatTop.xy *= flContactHardeningScale; + RMatBottom.xy *= flContactHardeningScale; +*/ + + for( int i=0; i<8; i++ ) + { + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[i].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[i].xy) + RMatBottom.z; + vLightDepths = tex2D( DepthSampler, rotOffset.xy ); + accum += (vLightDepths > objDepth.xxxx); + } + + fResult = dot( accum, float4( 1.0f/32.0f, 1.0f/32.0f, 1.0f/32.0f, 1.0f/32.0f) ); + } + else // ATI vanilla hardware shadow mapping + { + for( int i=0; i<2; i++ ) + { + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+0].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+0].xy) + RMatBottom.z; + vLightDepths.x = tex2D( DepthSampler, rotOffset.xy ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+1].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+1].xy) + RMatBottom.z; + vLightDepths.y = tex2D( DepthSampler, rotOffset.xy ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+2].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+2].xy) + RMatBottom.z; + vLightDepths.z = tex2D( DepthSampler, rotOffset.xy ).x; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+3].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+3].xy) + RMatBottom.z; + vLightDepths.w = tex2D( DepthSampler, rotOffset.xy ).x; + + accum += (vLightDepths > objDepth.xxxx); + } + + fResult = dot( accum, float4( 0.125, 0.125, 0.125, 0.125) ); + } + + return fResult; +} + +#if defined( _X360 ) + +// Poisson disc, randomly rotated at different UVs +float DoShadow360Simple( sampler DepthSampler, const float3 vProjCoords ) +{ + float fLOD; + float2 shadowMapCenter = vProjCoords.xy; // Center of shadow filter + float objDepth = min( vProjCoords.z, 0.99999 ); // Object depth in shadow space + +#if defined( REVERSE_DEPTH_ON_X360 ) + objDepth = 1.0f - objDepth; +#endif + + float4 vSampledDepths, vWeights; + + asm { + getCompTexLOD2D fLOD.x, shadowMapCenter.xy, DepthSampler, AnisoFilter=max16to1 + setTexLOD fLOD.x + + tfetch2D vSampledDepths.x___, shadowMapCenter, DepthSampler, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths._x__, shadowMapCenter, DepthSampler, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths.__x_, shadowMapCenter, DepthSampler, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths.___x, shadowMapCenter, DepthSampler, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + + getWeights2D vWeights, shadowMapCenter.xy, DepthSampler, MagFilter=linear, MinFilter=linear, UseComputedLOD=false, UseRegisterLOD=true + }; + + vWeights = float4( (1-vWeights.x)*(1-vWeights.y), vWeights.x*(1-vWeights.y), (1-vWeights.x)*vWeights.y, vWeights.x*vWeights.y ); + +#if defined( REVERSE_DEPTH_ON_X360 ) + float4 vCompare = (vSampledDepths < objDepth.xxxx); +#else + float4 vCompare = (vSampledDepths > objDepth.xxxx); +#endif + + return dot( vCompare, vWeights ); +} + + +float Do360PCFFetch( sampler DepthSampler, float2 tc, float objDepth ) +{ + float fLOD; + float4 vSampledDepths, vWeights; + + asm { + getCompTexLOD2D fLOD.x, tc.xy, DepthSampler, AnisoFilter=max16to1 + setTexLOD fLOD.x + + tfetch2D vSampledDepths.x___, tc, DepthSampler, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths._x__, tc, DepthSampler, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths.__x_, tc, DepthSampler, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths.___x, tc, DepthSampler, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + + getWeights2D vWeights, tc.xy, DepthSampler, MagFilter=linear, MinFilter=linear, UseComputedLOD=false, UseRegisterLOD=true + }; + + vWeights = float4( (1-vWeights.x)*(1-vWeights.y), vWeights.x*(1-vWeights.y), (1-vWeights.x)*vWeights.y, vWeights.x*vWeights.y ); + +#if defined( REVERSE_DEPTH_ON_X360 ) + float4 vCompare = (vSampledDepths < objDepth.xxxx); +#else + float4 vCompare = (vSampledDepths > objDepth.xxxx); +#endif + + return dot( vCompare, vWeights ); +} + + + +float Do360NearestFetch( sampler DepthSampler, float2 tc, float objDepth ) +{ + float fLOD; + float4 vSampledDepth; + + asm { + getCompTexLOD2D fLOD.x, tc.xy, DepthSampler, AnisoFilter=max16to1 + setTexLOD fLOD.x + + tfetch2D vSampledDepth.x___, tc, DepthSampler, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + }; + +#if defined( REVERSE_DEPTH_ON_X360 ) + return (vSampledDepth.x < objDepth.x); +#else + return (vSampledDepth.x > objDepth.x); +#endif + +} + + +float AmountShadowed_8Tap_360( sampler DepthSampler, float2 tc, float objDepth ) +{ + float fLOD; + float4 vSampledDepthsA, vSampledDepthsB; + + // Optimal 8 rooks pattern to get an idea about whether we're at a penumbra or not + // From [Kallio07] "Scanline Edge-Flag Algorithm for Antialiasing" + // + // +---+---+---+---+---+---+---+---+ + // | | | | | | o | | | + // +---+---+---+---+---+---+---+---+ + // | o | | | | | | | | + // +---+---+---+---+---+---+---+---+ + // | | | | o | | | | | + // +---+---+---+---+---+---+---+---+ + // | | | | | | | o | | + // +---+---+---+---+---+---+---+---+ + // | | o | | | | | | | + // +---+---+---+---+---+---+---+---+ + // | | | | | o | | | | + // +---+---+---+---+---+---+---+---+ + // | | | | | | | | o | + // +---+---+---+---+---+---+---+---+ + // | | | o | | | | | | + // +---+---+---+---+---+---+---+---+ + // + asm { + getCompTexLOD2D fLOD.x, tc.xy, DepthSampler, AnisoFilter=max16to1 + setTexLOD fLOD.x + + tfetch2D vSampledDepthsA.x___, tc, DepthSampler, OffsetX = -2.0, OffsetY = -1.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepthsA._x__, tc, DepthSampler, OffsetX = -1.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepthsA.__x_, tc, DepthSampler, OffsetX = -1.0, OffsetY = 2.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepthsA.___x, tc, DepthSampler, OffsetX = -0.5, OffsetY = -1.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + + tfetch2D vSampledDepthsB.x___, tc, DepthSampler, OffsetX = 0.5, OffsetY = 1.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepthsB._x__, tc, DepthSampler, OffsetX = 1.0, OffsetY = -2.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepthsB.__x_, tc, DepthSampler, OffsetX = 1.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepthsB.___x, tc, DepthSampler, OffsetX = 2.0, OffsetY = 1.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + }; + +#if defined( REVERSE_DEPTH_ON_X360 ) + float4 vCompareA = (vSampledDepthsA < objDepth.xxxx); + float4 vCompareB = (vSampledDepthsB < objDepth.xxxx); +#else + float4 vCompareA = (vSampledDepthsA > objDepth.xxxx); + float4 vCompareB = (vSampledDepthsB > objDepth.xxxx); +#endif + + return dot( vCompareA, float4(0.125,0.125,0.125,0.125) ) + dot( vCompareB, float4(0.125,0.125,0.125,0.125) ); +} + + +float AmountShadowed_4Tap_360( sampler DepthSampler, float2 tc, float objDepth ) +{ + float fLOD; + float4 vSampledDepths; + + // Rotated grid pattern to get an idea about whether we're at a penumbra or not + asm { + getCompTexLOD2D fLOD.x, tc.xy, DepthSampler, AnisoFilter=max16to1 + setTexLOD fLOD.x + + tfetch2D vSampledDepths.x___, tc, DepthSampler, OffsetX = -1.0, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths._x__, tc, DepthSampler, OffsetX = -0.5, OffsetY = -1.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths.__x_, tc, DepthSampler, OffsetX = 0.5, OffsetY = 1.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + tfetch2D vSampledDepths.___x, tc, DepthSampler, OffsetX = 1.0, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point + }; + +#if defined( REVERSE_DEPTH_ON_X360 ) + float4 vCompare = (vSampledDepths < objDepth.xxxx); +#else + float4 vCompare = (vSampledDepths > objDepth.xxxx); +#endif + + return dot( vCompare, float4(0.25,0.25,0.25,0.25) ); +} + +// Poisson disc, randomly rotated at different UVs +float DoShadowPoisson360( sampler DepthSampler, sampler RandomRotationSampler, const float3 vProjCoords, const float2 vScreenPos, const float4 vShadowTweaks ) +{ + float2 vPoissonOffset[8] = { float2( 0.3475f, 0.0042f ), float2( 0.8806f, 0.3430f ), + float2( -0.0041f, -0.6197f ), float2( 0.0472f, 0.4964f ), + float2( -0.3730f, 0.0874f ), float2( -0.9217f, -0.3177f ), + float2( -0.6289f, 0.7388f ), float2( 0.5744f, -0.7741f ) }; + + float2 shadowMapCenter = vProjCoords.xy; // Center of shadow filter + float objDepth = min( vProjCoords.z, 0.99999 ); // Object depth in shadow space + +#if defined( REVERSE_DEPTH_ON_X360 ) + objDepth = 1.0f - objDepth; +#endif + + float fAmountShadowed = AmountShadowed_4Tap_360( DepthSampler, shadowMapCenter, objDepth ); + + if ( fAmountShadowed >= 1.0f ) // Fully in light + { + return 1.0f; + } + else // Do the expensive filtering since we're at least partially shadowed + { + float flScaleOverMapSize = 1.7f / 512.0f; // Tweak parameters to shader + + // 2D Rotation Matrix setup + float3 RMatTop = 0, RMatBottom = 0; +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) + RMatTop.xy = tex2D( RandomRotationSampler, cFlashlightScreenScale.xy * (vScreenPos * 0.5 + 0.5)) * 2.0 - 1.0; + RMatBottom.xy = float2(-1.0, 1.0) * RMatTop.yx; // 2x2 rotation matrix in 4-tuple +#endif + + RMatTop *= flScaleOverMapSize; // Scale up kernel while accounting for texture resolution + RMatBottom *= flScaleOverMapSize; + RMatTop.z = shadowMapCenter.x; // To be added in d2adds generated below + RMatBottom.z = shadowMapCenter.y; + float2 rotOffset = float2(0,0); + float4 vAccum = 0; + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[0].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[0].xy) + RMatBottom.z; + vAccum.x = Do360NearestFetch( DepthSampler, rotOffset, objDepth ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[1].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[1].xy) + RMatBottom.z; + vAccum.y = Do360NearestFetch( DepthSampler, rotOffset, objDepth ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[2].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[2].xy) + RMatBottom.z; + vAccum.z = Do360NearestFetch( DepthSampler, rotOffset, objDepth ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[3].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[3].xy) + RMatBottom.z; + vAccum.w = Do360NearestFetch( DepthSampler, rotOffset, objDepth ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4].xy) + RMatBottom.z; + vAccum.x += Do360NearestFetch( DepthSampler, rotOffset, objDepth ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[5].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[5].xy) + RMatBottom.z; + vAccum.y += Do360NearestFetch( DepthSampler, rotOffset, objDepth ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[6].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[6].xy) + RMatBottom.z; + vAccum.z += Do360NearestFetch( DepthSampler, rotOffset, objDepth ); + + rotOffset.x = dot (RMatTop.xy, vPoissonOffset[7].xy) + RMatTop.z; + rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[7].xy) + RMatBottom.z; + vAccum.w += Do360NearestFetch( DepthSampler, rotOffset, objDepth ); + + return dot( vAccum, float4( 0.25, 0.25, 0.25, 0.25) ); + } +} + +#endif // _X360 + + +float DoFlashlightShadow( sampler DepthSampler, sampler RandomRotationSampler, float3 vProjCoords, float2 vScreenPos, int nShadowLevel, float4 vShadowTweaks, bool bAllowHighQuality ) +{ + float flShadow = 1.0f; + +#if !defined( _X360 ) //PC + if( nShadowLevel == NVIDIA_PCF_POISSON ) + flShadow = DoShadowPoisson16Sample( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, true, false ); + else if( nShadowLevel == ATI_NOPCF ) + flShadow = DoShadowPoisson16Sample( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, false, false ); + else if( nShadowLevel == ATI_NO_PCF_FETCH4 ) + flShadow = DoShadowPoisson16Sample( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, false, true ); + + return flShadow; +#else + + // Compile-time switch for shaders which allow high quality modes on 360 + if ( bAllowHighQuality ) + { + // Static control flow switch for shadow quality. Some non-interactive sequences use the high quality path + if ( g_bHighQualityShadows ) + { + flShadow = DoShadowPoisson360( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks ); + } + else + { + flShadow = DoShadow360Simple( DepthSampler, vProjCoords ); + } + } + else + { + flShadow = DoShadow360Simple( DepthSampler, vProjCoords ); + } + + return flShadow; + +#endif +} + +float3 SpecularLight( const float3 vWorldNormal, const float3 vLightDir, const float fSpecularExponent, + const float3 vEyeDir, /*const bool bDoSpecularWarp, in sampler specularWarpSampler,*/ float fFresnel ) +{ + float3 result = float3(0.0f, 0.0f, 0.0f); + + float3 vReflect = reflect( -vEyeDir, vWorldNormal ); // Reflect view through normal + float3 vSpecular = saturate(dot( vReflect, vLightDir )); // L.R (use half-angle instead?) + vSpecular = pow( vSpecular.x, fSpecularExponent ); // Raise to specular power + + // Optionally warp as function of scalar specular and fresnel + //if ( bDoSpecularWarp ) + // vSpecular *= tex2D( specularWarpSampler, float2(vSpecular.x, fFresnel) ); // Sample at { (L.R)^k, fresnel } + vSpecular *= fFresnel; + + return vSpecular; +} + +void DoSpecularFlashlight( float3 flashlightPos, float3 worldPos, float4 flashlightSpacePosition, float3 worldNormal, + float3 attenuationFactors, float farZ, sampler FlashlightSampler, sampler FlashlightDepthSampler, sampler RandomRotationSampler, + int nShadowLevel, bool bDoShadows, bool bAllowHighQuality, const float2 vScreenPos, const float fSpecularExponent, const float3 vEyeDir, + /*const bool bDoSpecularWarp, sampler specularWarpSampler,*/ float fFresnel, float4 vShadowTweaks, + + // Outputs of this shader...separate shadowed diffuse and specular from the flashlight + out float3 diffuseLighting, out float3 specularLighting ) +{ + float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; + float3 flashlightColor = float3(1,1,1); + +#if ( defined( _X360 ) ) + + float3 ltz = vProjCoords.xyz < float3( 0.0f, 0.0f, 0.0f ); + float3 gto = vProjCoords.xyz > float3( 1.0f, 1.0f, 1.0f ); + + [branch] + if ( dot(ltz + gto, float3(1,1,1)) > 0 ) + { + clip(-1); + diffuseLighting = specularLighting = float3(0,0,0); + return; + } + else + { + flashlightColor = tex2D( FlashlightSampler, vProjCoords ); + + [branch] + if ( dot(flashlightColor.xyz, float3(1,1,1)) <= 0 ) + { + clip(-1); + diffuseLighting = specularLighting = float3(0,0,0); + return; + } + } +#else + flashlightColor = tex2D( FlashlightSampler, vProjCoords ); +#endif + + +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) + flashlightColor *= cFlashlightColor.xyz; // Flashlight color +#endif + + float3 delta = flashlightPos - worldPos; + float3 L = normalize( delta ); + float distSquared = dot( delta, delta ); + float dist = sqrt( distSquared ); + + float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f ); + + // Attenuation for light and to fade out shadow over distance + float fAtten = saturate( dot( attenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); + + // Shadowing and coloring terms +#if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) + if ( bDoShadows ) + { + float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, nShadowLevel, vShadowTweaks, bAllowHighQuality ); + float flAttenuated = lerp( flShadow, 1.0f, vShadowTweaks.y ); // Blend between fully attenuated and not attenuated + flShadow = saturate( lerp( flAttenuated, flShadow, fAtten ) ); // Blend between shadow and above, according to light attenuation + flashlightColor *= flShadow; // Shadow term + } +#endif + + diffuseLighting = fAtten; +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) + diffuseLighting *= saturate( dot( L.xyz, worldNormal.xyz ) + flFlashlightNoLambertValue ); // Lambertian term +#else + diffuseLighting *= saturate( dot( L.xyz, worldNormal.xyz ) ); // Lambertian (not Half-Lambert) term +#endif + diffuseLighting *= flashlightColor; + diffuseLighting *= endFalloffFactor; + + // Specular term (masked by diffuse) + specularLighting = diffuseLighting * SpecularLight ( worldNormal, L, fSpecularExponent, vEyeDir, /*bDoSpecularWarp, specularWarpSampler,*/ fFresnel ); +} + +// Diffuse only version +float3 DoFlashlight( float3 flashlightPos, float3 worldPos, float4 flashlightSpacePosition, float3 worldNormal, + float3 attenuationFactors, float farZ, sampler FlashlightSampler, sampler FlashlightDepthSampler, + sampler RandomRotationSampler, int nShadowLevel, bool bDoShadows, bool bAllowHighQuality, + const float2 vScreenPos, bool bClip, float4 vShadowTweaks = float4(3/1024.0f, 0.0005f, 0.0f, 0.0f), bool bHasNormal = true ) +{ + float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w; + float3 flashlightColor = float3(1,1,1); + +#if ( defined( _X360 ) ) + + float3 ltz = vProjCoords.xyz < float3( 0.0f, 0.0f, 0.0f ); + float3 gto = vProjCoords.xyz > float3( 1.0f, 1.0f, 1.0f ); + + [branch] + if ( dot(ltz + gto, float3(1,1,1)) > 0 ) + { + if ( bClip ) + { + clip(-1); + } + return float3(0,0,0); + } + else + { + flashlightColor = tex2D( FlashlightSampler, vProjCoords ); + + [branch] + if ( dot(flashlightColor.xyz, float3(1,1,1)) <= 0 ) + { + if ( bClip ) + { + clip(-1); + } + return float3(0,0,0); + } + } +#else + flashlightColor = tex2D( FlashlightSampler, vProjCoords ); +#endif + +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) + flashlightColor *= cFlashlightColor.xyz; // Flashlight color +#endif + + float3 delta = flashlightPos - worldPos; + float3 L = normalize( delta ); + float distSquared = dot( delta, delta ); + float dist = sqrt( distSquared ); + + float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f ); + + // Attenuation for light and to fade out shadow over distance + float fAtten = saturate( dot( attenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) ); + + // Shadowing and coloring terms +#if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) + if ( bDoShadows ) + { + float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, nShadowLevel, vShadowTweaks, bAllowHighQuality ); + float flAttenuated = lerp( flShadow, 1.0f, vShadowTweaks.y ); // Blend between fully attenuated and not attenuated + flShadow = saturate( lerp( flAttenuated, flShadow, fAtten ) ); // Blend between shadow and above, according to light attenuation + flashlightColor *= flShadow; // Shadow term + } +#endif + + float3 diffuseLighting = fAtten; + + float flLDotWorldNormal; + if ( bHasNormal ) + { + flLDotWorldNormal = dot( L.xyz, worldNormal.xyz ); + } + else + { + flLDotWorldNormal = 1.0f; + } + +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) + diffuseLighting *= saturate( flLDotWorldNormal + flFlashlightNoLambertValue ); // Lambertian term +#else + diffuseLighting *= saturate( flLDotWorldNormal ); // Lambertian (not Half-Lambert) term +#endif + + diffuseLighting *= flashlightColor; + diffuseLighting *= endFalloffFactor; + + return diffuseLighting; +} + +#endif //#ifndef COMMON_FLASHLIGHT_FXC_H_ diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/common_fxc.h b/sp/src/materialsystem/stdshaders/ShaderEdit/common_fxc.h new file mode 100644 index 00000000..72a1d5d4 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/common_fxc.h @@ -0,0 +1,326 @@ +//========= Copyright © 1996-2007, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef COMMON_FXC_H_ +#define COMMON_FXC_H_ + +#include "common_pragmas.h" +#include "common_hlsl_cpp_consts.h" + +#ifdef NV3X +# define HALF half +# define HALF2 half2 +# define HALF3 half3 +# define HALF4 half4 +# define HALF3x3 half3x3 +# define HALF3x4 half3x4 +# define HALF4x3 half4x3 +# define HALF_CONSTANT( _constant ) ((HALF)_constant) +#else +# define HALF float +# define HALF2 float2 +# define HALF3 float3 +# define HALF4 float4 +# define HALF3x3 float3x3 +# define HALF3x4 float3x4 +# define HALF4x3 float4x3 +# define HALF_CONSTANT( _constant ) _constant +#endif + +// This is where all common code for both vertex and pixel shaders. +#define OO_SQRT_3 0.57735025882720947f +static const HALF3 bumpBasis[3] = { + HALF3( 0.81649661064147949f, 0.0f, OO_SQRT_3 ), + HALF3( -0.40824833512306213f, 0.70710676908493042f, OO_SQRT_3 ), + HALF3( -0.40824821591377258f, -0.7071068286895752f, OO_SQRT_3 ) +}; +static const HALF3 bumpBasisTranspose[3] = { + HALF3( 0.81649661064147949f, -0.40824833512306213f, -0.40824833512306213f ), + HALF3( 0.0f, 0.70710676908493042f, -0.7071068286895752f ), + HALF3( OO_SQRT_3, OO_SQRT_3, OO_SQRT_3 ) +}; + +#if defined( _X360 ) +#define REVERSE_DEPTH_ON_X360 //uncomment to use D3DFMT_D24FS8 with an inverted depth viewport for better performance. Keep this in sync with the same named #define in public/shaderapi/shareddefs.h +//Note that the reversal happens in the viewport. So ONLY reading back from a depth texture should be affected. Projected math is unaffected. +#endif + +HALF3 CalcReflectionVectorNormalized( HALF3 normal, HALF3 eyeVector ) +{ + // FIXME: might be better of normalizing with a normalizing cube map and + // get rid of the dot( normal, normal ) + // compute reflection vector r = 2 * ((n dot v)/(n dot n)) n - v + return 2.0 * ( dot( normal, eyeVector ) / dot( normal, normal ) ) * normal - eyeVector; +} + +HALF3 CalcReflectionVectorUnnormalized( HALF3 normal, HALF3 eyeVector ) +{ + // FIXME: might be better of normalizing with a normalizing cube map and + // get rid of the dot( normal, normal ) + // compute reflection vector r = 2 * ((n dot v)/(n dot n)) n - v + // multiply all values through by N.N. uniformly scaling reflection vector won't affect result + // since it is used in a cubemap lookup + return (2.0*(dot( normal, eyeVector ))*normal) - (dot( normal, normal )*eyeVector); +} + +float3 HuePreservingColorClamp( float3 c ) +{ + // Get the max of all of the color components and a specified maximum amount + float maximum = max( max( c.x, c.y ), max( c.z, 1.0f ) ); + + return (c / maximum); +} + +HALF3 HuePreservingColorClamp( HALF3 c, HALF maxVal ) +{ + // Get the max of all of the color components and a specified maximum amount + float maximum = max( max( c.x, c.y ), max( c.z, maxVal ) ); + return (c * ( maxVal / maximum ) ); +} + +#if (AA_CLAMP==1) +HALF2 ComputeLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord ) +{ + HALF2 result = saturate(Lightmap1and2Coord.xy) * Lightmap1and2Coord.wz * 0.99; + result += Lightmap3Coord; + return result; +} + +void ComputeBumpedLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord, + out HALF2 bumpCoord1, + out HALF2 bumpCoord2, + out HALF2 bumpCoord3 ) +{ + HALF2 result = saturate(Lightmap1and2Coord.xy) * Lightmap1and2Coord.wz * 0.99; + result += Lightmap3Coord; + bumpCoord1 = result + HALF2(Lightmap1and2Coord.z, 0); + bumpCoord2 = result + 2*HALF2(Lightmap1and2Coord.z, 0); + bumpCoord3 = result + 3*HALF2(Lightmap1and2Coord.z, 0); +} +#else +HALF2 ComputeLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord ) +{ + return Lightmap1and2Coord.xy; +} + +void ComputeBumpedLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord, + out HALF2 bumpCoord1, + out HALF2 bumpCoord2, + out HALF2 bumpCoord3 ) +{ + bumpCoord1 = Lightmap1and2Coord.xy; + bumpCoord2 = Lightmap1and2Coord.wz; // reversed order!!! + bumpCoord3 = Lightmap3Coord.xy; +} +#endif + +// Versions of matrix multiply functions which force HLSL compiler to explictly use DOTs, +// not giving it the option of using MAD expansion. In a perfect world, the compiler would +// always pick the best strategy, and these shouldn't be needed.. but.. well.. umm.. +// +// lorenmcq + +float3 mul3x3(float3 v, float3x3 m) +{ +#if !defined( _X360 ) + return float3(dot(v, transpose(m)[0]), dot(v, transpose(m)[1]), dot(v, transpose(m)[2])); +#else + // xbox360 fxc.exe (new back end) borks with transposes, generates bad code + return mul( v, m ); +#endif +} + +float3 mul4x3(float4 v, float4x3 m) +{ +#if !defined( _X360 ) + return float3(dot(v, transpose(m)[0]), dot(v, transpose(m)[1]), dot(v, transpose(m)[2])); +#else + // xbox360 fxc.exe (new back end) borks with transposes, generates bad code + return mul( v, m ); +#endif +} + +float3 DecompressHDR( float4 input ) +{ + return input.rgb * input.a * MAX_HDR_OVERBRIGHT; +} + +float4 CompressHDR( float3 input ) +{ + // FIXME: want to use min so that we clamp to white, but what happens if we + // have an albedo component that's less than 1/MAX_HDR_OVERBRIGHT? + // float fMax = max( max( color.r, color.g ), color.b ); + float4 output; + float fMax = min( min( input.r, input.g ), input.b ); + if( fMax > 1.0f ) + { + float oofMax = 1.0f / fMax; + output.rgb = oofMax * input.rgb; + output.a = min( fMax / MAX_HDR_OVERBRIGHT, 1.0f ); + } + else + { + output.rgb = input.rgb; + output.a = 0.0f; + } + return output; +} + + +float3 LinearToGamma( const float3 f3linear ) +{ + return pow( f3linear, 1.0f / 2.2f ); +} + +float4 LinearToGamma( const float4 f4linear ) +{ + return float4( pow( f4linear.xyz, 1.0f / 2.2f ), f4linear.w ); +} + +float LinearToGamma( const float f1linear ) +{ + return pow( f1linear, 1.0f / 2.2f ); +} + +float3 GammaToLinear( const float3 gamma ) +{ + return pow( gamma, 2.2f ); +} + +float4 GammaToLinear( const float4 gamma ) +{ + return float4( pow( gamma.xyz, 2.2f ), gamma.w ); +} + +float GammaToLinear( const float gamma ) +{ + return pow( gamma, 2.2f ); +} + +// These two functions use the actual sRGB math +float SrgbGammaToLinear( float flSrgbGammaValue ) +{ + float x = saturate( flSrgbGammaValue ); + return ( x <= 0.04045f ) ? ( x / 12.92f ) : ( pow( ( x + 0.055f ) / 1.055f, 2.4f ) ); +} + +float SrgbLinearToGamma( float flLinearValue ) +{ + float x = saturate( flLinearValue ); + return ( x <= 0.0031308f ) ? ( x * 12.92f ) : ( 1.055f * pow( x, ( 1.0f / 2.4f ) ) ) - 0.055f; +} + +// These twofunctions use the XBox 360's exact piecewise linear algorithm +float X360GammaToLinear( float fl360GammaValue ) +{ + float flLinearValue; + + fl360GammaValue = saturate( fl360GammaValue ); + if ( fl360GammaValue < ( 96.0f / 255.0f ) ) + { + if ( fl360GammaValue < ( 64.0f / 255.0f ) ) + { + flLinearValue = fl360GammaValue * 255.0f; + } + else + { + flLinearValue = fl360GammaValue * ( 255.0f * 2.0f ) - 64.0f; + flLinearValue += floor( flLinearValue * ( 1.0f / 512.0f ) ); + } + } + else + { + if( fl360GammaValue < ( 192.0f / 255.0f ) ) + { + flLinearValue = fl360GammaValue * ( 255.0f * 4.0f ) - 256.0f; + flLinearValue += floor( flLinearValue * ( 1.0f / 256.0f ) ); + } + else + { + flLinearValue = fl360GammaValue * ( 255.0f * 8.0f ) - 1024.0f; + flLinearValue += floor( flLinearValue * ( 1.0f / 128.0f ) ); + } + } + + flLinearValue *= 1.0f / 1023.0f; + + flLinearValue = saturate( flLinearValue ); + return flLinearValue; +} + +float X360LinearToGamma( float flLinearValue ) +{ + float fl360GammaValue; + + flLinearValue = saturate( flLinearValue ); + if ( flLinearValue < ( 128.0f / 1023.0f ) ) + { + if ( flLinearValue < ( 64.0f / 1023.0f ) ) + { + fl360GammaValue = flLinearValue * ( 1023.0f * ( 1.0f / 255.0f ) ); + } + else + { + fl360GammaValue = flLinearValue * ( ( 1023.0f / 2.0f ) * ( 1.0f / 255.0f ) ) + ( 32.0f / 255.0f ); + } + } + else + { + if ( flLinearValue < ( 512.0f / 1023.0f ) ) + { + fl360GammaValue = flLinearValue * ( ( 1023.0f / 4.0f ) * ( 1.0f / 255.0f ) ) + ( 64.0f / 255.0f ); + } + else + { + fl360GammaValue = flLinearValue * ( ( 1023.0f /8.0f ) * ( 1.0f / 255.0f ) ) + ( 128.0f /255.0f ); // 1.0 -> 1.0034313725490196078431372549016 + if ( fl360GammaValue > 1.0f ) + { + fl360GammaValue = 1.0f; + } + } + } + + fl360GammaValue = saturate( fl360GammaValue ); + return fl360GammaValue; +} + +float SrgbGammaTo360Gamma( float flSrgbGammaValue ) +{ + float flLinearValue = SrgbGammaToLinear( flSrgbGammaValue ); + float fl360GammaValue = X360LinearToGamma( flLinearValue ); + return fl360GammaValue; +} + +float3 Vec3WorldToTangent( float3 iWorldVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal ) +{ + float3 vTangentVector; + vTangentVector.x = dot( iWorldVector.xyz, iWorldTangent.xyz ); + vTangentVector.y = dot( iWorldVector.xyz, iWorldBinormal.xyz ); + vTangentVector.z = dot( iWorldVector.xyz, iWorldNormal.xyz ); + return vTangentVector.xyz; // Return without normalizing +} + +float3 Vec3WorldToTangentNormalized( float3 iWorldVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal ) +{ + return normalize( Vec3WorldToTangent( iWorldVector, iWorldNormal, iWorldTangent, iWorldBinormal ) ); +} + +float3 Vec3TangentToWorld( float3 iTangentVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal ) +{ + float3 vWorldVector; + vWorldVector.xyz = iTangentVector.x * iWorldTangent.xyz; + vWorldVector.xyz += iTangentVector.y * iWorldBinormal.xyz; + vWorldVector.xyz += iTangentVector.z * iWorldNormal.xyz; + return vWorldVector.xyz; // Return without normalizing +} + +float3 Vec3TangentToWorldNormalized( float3 iTangentVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal ) +{ + return normalize( Vec3TangentToWorld( iTangentVector, iWorldNormal, iWorldTangent, iWorldBinormal ) ); +} + +#endif //#ifndef COMMON_FXC_H_ diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/common_hlsl_cpp_consts.h b/sp/src/materialsystem/stdshaders/ShaderEdit/common_hlsl_cpp_consts.h new file mode 100644 index 00000000..5989e2b0 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/common_hlsl_cpp_consts.h @@ -0,0 +1,27 @@ +//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef COMMON_HLSL_CONSTS_H_ +#define COMMON_HLSL_CONSTS_H_ + +#ifdef NV3X + #define PSHADER_VECT_SCALE 20.0 + #define VSHADER_VECT_SCALE (1.0 / (PSHADER_VECT_SCALE) ) +#else + #define PSHADER_VECT_SCALE 1.0 + #define VSHADER_VECT_SCALE 1.0 +#endif + +// GR - HDR luminance maps to 0..n range +// IMPORTANT: Keep the same value as in materialsystem_global.h +// HDRFIXME: Make this a pixel shader constant? +#define MAX_HDR_OVERBRIGHT 16.0f + +#define LINEAR_FOG_COLOR 29 +#define TONE_MAPPING_SCALE_PSH_CONSTANT 30 + +#endif //#ifndef COMMON_HLSL_CONSTS_H_ diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/common_lightmappedgeneric_fxc.h b/sp/src/materialsystem/stdshaders/ShaderEdit/common_lightmappedgeneric_fxc.h new file mode 100644 index 00000000..a1354d1a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/common_lightmappedgeneric_fxc.h @@ -0,0 +1,201 @@ + + +#if defined( _X360 ) + +void GetBaseTextureAndNormal( sampler base, sampler base2, sampler bump, bool bBase2, bool bBump, float3 coords, float3 vWeights, + out float4 vResultBase, out float4 vResultBase2, out float4 vResultBump ) +{ + vResultBase = 0; + vResultBase2 = 0; + vResultBump = 0; + + if ( !bBump ) + { + vResultBump = float4(0, 0, 1, 1); + } + +#if SEAMLESS + + vWeights = max( vWeights - 0.3, 0 ); + + vWeights *= 1.0f / dot( vWeights, float3(1,1,1) ); + + [branch] + if (vWeights.x > 0) + { + vResultBase += vWeights.x * tex2D( base, coords.zy ); + + if ( bBase2 ) + { + vResultBase2 += vWeights.x * tex2D( base2, coords.zy ); + } + + if ( bBump ) + { + vResultBump += vWeights.x * tex2D( bump, coords.zy ); + } + } + + [branch] + if (vWeights.y > 0) + { + vResultBase += vWeights.y * tex2D( base, coords.xz ); + + if ( bBase2 ) + { + vResultBase2 += vWeights.y * tex2D( base2, coords.xz ); + } + if ( bBump ) + { + vResultBump += vWeights.y * tex2D( bump, coords.xz ); + } + } + + [branch] + if (vWeights.z > 0) + { + vResultBase += vWeights.z * tex2D( base, coords.xy ); + if ( bBase2 ) + { + vResultBase2 += vWeights.z * tex2D( base2, coords.xy ); + } + + if ( bBump ) + { + vResultBump += vWeights.z * tex2D( bump, coords.xy ); + } + } + +#else // not seamless + + vResultBase = tex2D( base, coords.xy ); + + if ( bBase2 ) + { + vResultBase2 = tex2D( base2, coords.xy ); + } + + if ( bBump ) + { + vResultBump = tex2D( bump, coords.xy ); + } + +#endif + + +} + +#else // PC + +void GetBaseTextureAndNormal( sampler base, sampler base2, sampler bump, bool bBase2, bool bBump, float3 coords, float3 vWeights, + out float4 vResultBase, out float4 vResultBase2, out float4 vResultBump ) +{ + vResultBase = 0; + vResultBase2 = 0; + vResultBump = 0; + + if ( !bBump ) + { + vResultBump = float4(0, 0, 1, 1); + } + +#if SEAMLESS + + vResultBase += vWeights.x * tex2D( base, coords.zy ); + if ( bBase2 ) + { + vResultBase2 += vWeights.x * tex2D( base2, coords.zy ); + } + if ( bBump ) + { + vResultBump += vWeights.x * tex2D( bump, coords.zy ); + } + + vResultBase += vWeights.y * tex2D( base, coords.xz ); + if ( bBase2 ) + { + vResultBase2 += vWeights.y * tex2D( base2, coords.xz ); + } + if ( bBump ) + { + vResultBump += vWeights.y * tex2D( bump, coords.xz ); + } + + vResultBase += vWeights.z * tex2D( base, coords.xy ); + if ( bBase2 ) + { + vResultBase2 += vWeights.z * tex2D( base2, coords.xy ); + } + if ( bBump ) + { + vResultBump += vWeights.z * tex2D( bump, coords.xy ); + } + +#else // not seamless + + vResultBase = tex2D( base, coords.xy ); + if ( bBase2 ) + { + vResultBase2 = tex2D( base2, coords.xy ); + } + if ( bBump ) + { + vResultBump = tex2D( bump, coords.xy ); + } +#endif + +} + +#endif + + + + +float3 LightMapSample( sampler LightmapSampler, float2 vTexCoord ) +{ +# if ( !defined( _X360 ) || !defined( USE_32BIT_LIGHTMAPS_ON_360 ) ) + { + float3 sample = tex2D( LightmapSampler, vTexCoord ); + + return sample; + } +# else + { +# if 0 //1 for cheap sampling, 0 for accurate scaling from the individual samples + { + float4 sample = tex2D( LightmapSampler, vTexCoord ); + + return sample.rgb * sample.a; + } +# else + { + float4 Weights; + float4 samples_0; //no arrays allowed in inline assembly + float4 samples_1; + float4 samples_2; + float4 samples_3; + + asm { + tfetch2D samples_0, vTexCoord.xy, LightmapSampler, OffsetX = -0.5, OffsetY = -0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false + tfetch2D samples_1, vTexCoord.xy, LightmapSampler, OffsetX = 0.5, OffsetY = -0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false + tfetch2D samples_2, vTexCoord.xy, LightmapSampler, OffsetX = -0.5, OffsetY = 0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false + tfetch2D samples_3, vTexCoord.xy, LightmapSampler, OffsetX = 0.5, OffsetY = 0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false + + getWeights2D Weights, vTexCoord.xy, LightmapSampler + }; + + Weights = float4( (1-Weights.x)*(1-Weights.y), Weights.x*(1-Weights.y), (1-Weights.x)*Weights.y, Weights.x*Weights.y ); + + float3 result; + result.rgb = samples_0.rgb * (samples_0.a * Weights.x); + result.rgb += samples_1.rgb * (samples_1.a * Weights.y); + result.rgb += samples_2.rgb * (samples_2.a * Weights.z); + result.rgb += samples_3.rgb * (samples_3.a * Weights.w); + + return result; + } +# endif + } +# endif +} + diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/common_parallax.h b/sp/src/materialsystem/stdshaders/ShaderEdit/common_parallax.h new file mode 100644 index 00000000..85361a7f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/common_parallax.h @@ -0,0 +1,247 @@ +#ifndef COMMON_PARALLAX_H +#define COMMON_PARALLAX_H + +#include "common_ps_fxc.h" + +void GetWorldSpaceOffset( const bool bDoCalc, float3 wpos, float2 uvdelta, + float prlxamt, float scale, out float3 worldSpaceOffset ) +{ + if ( bDoCalc ) + { + worldSpaceOffset.xy = uvdelta * scale; + worldSpaceOffset.z = prlxamt; // * 0.7f; + } + else + worldSpaceOffset = float3( 0, 0, 0 ); +} + +float CalcDerivativeScale( const bool bDoCalc, float2 uvddx, float2 uvddy, float3 wpos ) +{ + float scale = 1; + if ( bDoCalc ) + scale = max( length( ddx( wpos ) ) / length(uvddx), length( ddy( wpos ) ) / length(uvddy) ); + return scale; +} + +float2 CalcParallaxUV_Relief( float2 inTexCoord, float3 vViewTS, float flParallaxAmt, float3 vNormal, + float3 vViewW, sampler HeightMapSampler, + const int samples_min, const int samples_max, const int binary_max, + float3 WPos, out float3 worldSpaceOffset, + const bool bDoGradient, const bool bGetOffset ) +{ + float3 p = float3(inTexCoord,1); + float3 v = normalize(vViewTS); + v.z = abs(v.z); + + float2 dx = ddx( inTexCoord ); + float2 dy = ddy( inTexCoord ); + float scale = CalcDerivativeScale( true, dx, dy, WPos ); + + flParallaxAmt /= scale; + + float depthBias = 1.0 - v.z; + depthBias = 1.0f - pow( depthBias, 10 ); + + v.xy *= depthBias * flParallaxAmt; + + int linearSearchSteps = samples_max; + if ( bDoGradient ) + { + vViewW = normalize( vViewW ); + linearSearchSteps = (int) lerp( samples_max, samples_min, dot( vViewW, vNormal ) ); + } + int binarySearchSteps = binary_max; + + v /= v.z * linearSearchSteps; + int i; + float curh = 0; + v.z *= -1.0f; + + if ( !bDoGradient ) + { + for ( i = 0; i < linearSearchSteps; i++ ) + { + curh = tex2D( HeightMapSampler, p.xy ).r; + if ( curh < p.z ) + p += v; + } + } + else + { + bool bCondition = true; + int nStepIndex = 0; + while ( bCondition == true && nStepIndex < linearSearchSteps ) + { + curh = tex2Dgrad( HeightMapSampler, p.xy, dx, dy ).r; + if ( curh > p.z ) + bCondition = false; + else + { + p += v; + nStepIndex++; + } + } + } + + for( i = 0; i < binarySearchSteps; i++ ) + { + v *= 0.5f; + float tex = tex2D(HeightMapSampler, p.xy).r; + if (p.z > tex) + p += v; + else + p -= v; + } + + GetWorldSpaceOffset( bGetOffset, WPos, (inTexCoord-p.xy), + (1.0f-p.z), scale, worldSpaceOffset ); + return p.xy; +} + + +//===================================================================================// +// This is based on Natasha Tatarchuk's Parallax Occlusion Mapping (ATI) +//===================================================================================// +// INPUT: +// inTexCoord: +// the texcoord for the height/displacement map before parallaxing +// +// vParallax: +// Compute initial parallax displacement direction: +// float2 vParallaxDirection = normalize( vViewTS.xy ); +// float fLength = length( vViewTS ); +// float fParallaxLength = sqrt( fLength * fLength - vViewTS.z * vViewTS.z ) / vViewTS.z; +// Out.vParallax = vParallaxDirection * fParallaxLength * fProjectedBumpHeight; +// +// vNormal: +// tangent space normal +// +// vViewW: +// float3 vViewW = /*normalize*/(mul( matViewInverse, float4( 0, 0, 0, 1)) - inPosition ); +// +// OUTPUT: +// the new texcoord after parallaxing + +float2 CalcParallaxUV_POM( float2 inTexCoord, float3 vViewTS, float flParallaxAmt, float3 vNormal, + float3 vViewW, sampler HeightMapSampler, + const int samples_min, const int samples_max, const int binary_max, + float3 WPos, out float3 worldSpaceOffset, + const bool bDoGradient, const bool bGetOffset ) +{ + float2 dx = ddx( inTexCoord ); + float2 dy = ddy( inTexCoord ); + + float scale = CalcDerivativeScale( true, dx, dy, WPos ); + flParallaxAmt /= scale; + + float2 vParallax = normalize( vViewTS.xy ); + float fLength = length( vViewTS ); + float fParallaxLength = sqrt( fLength * fLength - vViewTS.z * vViewTS.z ) / vViewTS.z; + vParallax *= fParallaxLength * flParallaxAmt; + + vViewW = normalize( vViewW ); + + //===============================================// + // Parallax occlusion mapping offset computation // + //===============================================// + int nNumSteps = (int) lerp( samples_max, samples_min, dot( vViewW, vNormal ) ); + + float fCurrHeight = 0.0; + float fStepSize = 1.0 / (float) nNumSteps; + float fPrevHeight = 1.0; + float fNextHeight = 0.0; + + int nStepIndex = 0; + + float2 vTexOffsetPerStep = fStepSize * vParallax; + + float2 vTexCurrentOffset = inTexCoord; + float fCurrentBound = 1.0; + + float x = 0; + float y = 0; + float xh = 0; + float yh = 0; + + float2 texOffset2 = 0; + + bool bCondition = true; + while ( bCondition == true && nStepIndex < nNumSteps ) + { + vTexCurrentOffset -= vTexOffsetPerStep; + + fCurrHeight = tex2Dgrad( HeightMapSampler, vTexCurrentOffset, dx, dy ).r; + + fCurrentBound -= fStepSize; + + if ( fCurrHeight > fCurrentBound ) + { + x = fCurrentBound; + y = fCurrentBound + fStepSize; + xh = fCurrHeight; + yh = fPrevHeight; + + texOffset2 = vTexCurrentOffset - vTexOffsetPerStep; + + bCondition = false; + } + else + { + nStepIndex++; + fPrevHeight = fCurrHeight; + } + + } // End of while ( bCondition == true && nStepIndex > -1 )#else + //fCurrentBound -= fStepSize; + + float fParallaxAmount; + float numerator = (x * (y - yh) - y * (x - xh)); + float denomenator = ((y - yh) - (x - xh)); + // avoid NaN generation + if( ( numerator == 0.0f ) && ( denomenator == 0.0f ) ) + { + fParallaxAmount = 0.0f; + } + else + { + fParallaxAmount = numerator / denomenator; + } + + fParallaxAmount = 1.0f - fParallaxAmount; + float2 vParallaxOffset = vParallax * fParallaxAmount; + float2 texSampleBase = inTexCoord - vParallaxOffset; + + vParallaxOffset = clamp( vParallaxOffset, -1, 1 ); + + GetWorldSpaceOffset( bGetOffset, WPos, vParallaxOffset, + fParallaxAmount, scale, worldSpaceOffset ); + + return texSampleBase; +} +float CalcParallaxedShadows_OneLight( float2 UV, float2 UV_prlx, float3 vecLightTS, float3 WPos, float flParallaxAmt, float flSoftening, sampler Heightmap ) +{ + float scale = CalcDerivativeScale( true, ddx( UV ), ddy( UV ), WPos ); + flParallaxAmt /= scale; + + float2 inXY = vecLightTS.xy * flParallaxAmt; + + float sh0 = tex2D( Heightmap, UV_prlx).r; + float shA = (tex2D( Heightmap, UV_prlx + inXY * 0.88 ).r - sh0 - 0.88 ) * 1 * flSoftening; + float sh9 = (tex2D( Heightmap, UV_prlx + inXY * 0.77 ).r - sh0 - 0.77 ) * 2 * flSoftening; + float sh8 = (tex2D( Heightmap, UV_prlx + inXY * 0.66 ).r - sh0 - 0.66 ) * 4 * flSoftening; + float sh7 = (tex2D( Heightmap, UV_prlx + inXY * 0.55 ).r - sh0 - 0.55 ) * 6 * flSoftening; + float sh6 = (tex2D( Heightmap, UV_prlx + inXY * 0.44 ).r - sh0 - 0.44 ) * 8 * flSoftening; + float sh5 = (tex2D( Heightmap, UV_prlx + inXY * 0.33 ).r - sh0 - 0.33 ) * 10 * flSoftening; + float sh4 = (tex2D( Heightmap, UV_prlx + inXY * 0.22 ).r - sh0 - 0.22 ) * 12 * flSoftening; + + float fShadow = 1.0f - max( max( max( max( max( max( shA, sh9 ), sh8 ), sh7 ), sh6 ), sh5 ), sh4 ); + return saturate( fShadow ); +} +float CalcParallaxedShadows( float2 UV, float3 WPos, float flParallaxAmt, float flSoftening, sampler Heightmap ) +{ + return 1; + //float3 vecLightTS = float3( 0, 0.7f, 0 ); + //return CalcParallaxedShadows_OneLight( UV, vecLightTS, WPos, flParallaxAmt, flSoftening, Heightmap ); +} + +#endif \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/common_pragmas.h b/sp/src/materialsystem/stdshaders/ShaderEdit/common_pragmas.h new file mode 100644 index 00000000..d2cf3e14 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/common_pragmas.h @@ -0,0 +1,38 @@ +//========= Copyright © 1996-2007, Valve Corporation, All rights reserved. ============// +// +// Purpose: Common shader compiler pragmas +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef COMMON_PRAGMAS_H_ +#define COMMON_PRAGMAS_H_ + +// +// Validated shader models: +// +// SHADER_MODEL_VS_1_1 +// SHADER_MODEL_VS_2_0 +// SHADER_MODEL_VS_3_0 +// +// SHADER_MODEL_PS_1_1 +// SHADER_MODEL_PS_1_4 +// SHADER_MODEL_PS_2_0 +// SHADER_MODEL_PS_2_B +// SHADER_MODEL_PS_3_0 +// +// +// +// Platforms: +// +// PC +// _X360 +// + +// Special pragmas silencing common warnings +#pragma warning ( disable : 3557 ) // warning X3557: Loop only executes for N iteration(s), forcing loop to unroll +#pragma warning ( disable : 3595 ) // warning X3595: Microcode Compiler possible performance issue: pixel shader input semantic ___ is unused +#pragma warning ( disable : 3596 ) // warning X3596: Microcode Compiler possible performance issue: pixel shader input semantic ___ is unused +#pragma warning ( disable : 4702 ) // warning X4702: complement opportunity missed because input result WAS clamped from 0 to 1 + +#endif //#ifndef COMMON_PRAGMAS_H_ diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/common_ps_fxc.h b/sp/src/materialsystem/stdshaders/ShaderEdit/common_ps_fxc.h new file mode 100644 index 00000000..b634a540 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/common_ps_fxc.h @@ -0,0 +1,664 @@ +//====== Copyright © 1996-2007, Valve Corporation, All rights reserved. =======// +// +// Purpose: Common pixel shader code +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef COMMON_PS_FXC_H_ +#define COMMON_PS_FXC_H_ + +#include "common_fxc.h" + +// Put global skip commands here. . make sure and check that the appropriate vars are defined +// so these aren't used on the wrong shaders! + +// -------------------------------------------------------------------------------- +// HDR should never be enabled if we don't aren't running in float or integer HDR mode. +// SKIP: defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED +// -------------------------------------------------------------------------------- +// We don't ever write water fog to dest alpha if we aren't doing water fog. +// SKIP: defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA +// -------------------------------------------------------------------------------- +// We don't need fog in the pixel shader if we aren't in float fog mode2 +// NOSKIP: defined $HDRTYPE && defined $HDRENABLED && defined $PIXELFOGTYPE && $HDRTYPE != HDR_TYPE_FLOAT && $FOGTYPE != 0 +// -------------------------------------------------------------------------------- +// We don't do HDR and LIGHTING_PREVIEW at the same time since it's running LDR in hammer. +// SKIP: defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0 +// -------------------------------------------------------------------------------- +// Ditch all fastpath attempts if we are doing LIGHTING_PREVIEW. +// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT +// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST +// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// -------------------------------------------------------------------------------- +// Ditch flashlight depth when flashlight is disabled +// SKIP: ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW +// -------------------------------------------------------------------------------- + +// System defined pixel shader constants + +#if defined( _X360 ) +const bool g_bHighQualityShadows : register( b0 ); +#endif + +// NOTE: w == 1.0f / (Dest alpha compressed depth range). +const float4 g_LinearFogColor : register( c29 ); + +#define OO_DESTALPHA_DEPTH_RANGE (g_LinearFogColor.w) + +// Linear and gamma light scale values +const float4 cLightScale : register( c30 ); +#define LINEAR_LIGHT_SCALE (cLightScale.x) +#define LIGHT_MAP_SCALE (cLightScale.y) +#define ENV_MAP_SCALE (cLightScale.z) +#define GAMMA_LIGHT_SCALE (cLightScale.w) + +// Flashlight constants +#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0) + const float4 cFlashlightColor : register( c10 ); //register( c28 ); + const float4 cFlashlightScreenScale : register( c11 ); //register( c31 ); // .zw are currently unused + #define flFlashlightNoLambertValue cFlashlightColor.w // This is either 0.0 or 2.0 +#endif + +#define HDR_INPUT_MAP_SCALE 16.0f + +#define TONEMAP_SCALE_NONE 0 +#define TONEMAP_SCALE_LINEAR 1 +#define TONEMAP_SCALE_GAMMA 2 + +#define PIXEL_FOG_TYPE_NONE -1 //MATERIAL_FOG_NONE is handled by PIXEL_FOG_TYPE_RANGE, this is for explicitly disabling fog in the shader +#define PIXEL_FOG_TYPE_RANGE 0 //range+none packed together in ps2b. Simply none in ps20 (instruction limits) +#define PIXEL_FOG_TYPE_HEIGHT 1 + +// If you change these, make the corresponding change in hardwareconfig.cpp +#define NVIDIA_PCF_POISSON 0 +#define ATI_NOPCF 1 +#define ATI_NO_PCF_FETCH4 2 + +struct LPREVIEW_PS_OUT +{ + float4 color : COLOR0; + float4 normal : COLOR1; + float4 position : COLOR2; + float4 flags : COLOR3; +}; + +/* +// unused +HALF Luminance( HALF3 color ) +{ + return dot( color, HALF3( HALF_CONSTANT(0.30f), HALF_CONSTANT(0.59f), HALF_CONSTANT(0.11f) ) ); +} +*/ + +/* +// unused +HALF LuminanceScaled( HALF3 color ) +{ + return dot( color, HALF3( HALF_CONSTANT(0.30f) / MAX_HDR_OVERBRIGHT, HALF_CONSTANT(0.59f) / MAX_HDR_OVERBRIGHT, HALF_CONSTANT(0.11f) / MAX_HDR_OVERBRIGHT ) ); +} +*/ + +/* +// unused +HALF AvgColor( HALF3 color ) +{ + return dot( color, HALF3( HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f) ) ); +} +*/ + +/* +// unused +HALF4 DiffuseBump( sampler lightmapSampler, + float2 lightmapTexCoord1, + float2 lightmapTexCoord2, + float2 lightmapTexCoord3, + HALF3 normal ) +{ + HALF3 lightmapColor1 = tex2D( lightmapSampler, lightmapTexCoord1 ); + HALF3 lightmapColor2 = tex2D( lightmapSampler, lightmapTexCoord2 ); + HALF3 lightmapColor3 = tex2D( lightmapSampler, lightmapTexCoord3 ); + + HALF3 diffuseLighting; + diffuseLighting = saturate( dot( normal, bumpBasis[0] ) ) * lightmapColor1 + + saturate( dot( normal, bumpBasis[1] ) ) * lightmapColor2 + + saturate( dot( normal, bumpBasis[2] ) ) * lightmapColor3; + + return HALF4( diffuseLighting, LuminanceScaled( diffuseLighting ) ); +} +*/ + + +/* +// unused +HALF Fresnel( HALF3 normal, + HALF3 eye, + HALF2 scaleBias ) +{ + HALF fresnel = HALF_CONSTANT(1.0f) - dot( normal, eye ); + fresnel = pow( fresnel, HALF_CONSTANT(5.0f) ); + + return fresnel * scaleBias.x + scaleBias.y; +} +*/ + +/* +// unused +HALF4 GetNormal( sampler normalSampler, + float2 normalTexCoord ) +{ + HALF4 normal = tex2D( normalSampler, normalTexCoord ); + normal.rgb = HALF_CONSTANT(2.0f) * normal.rgb - HALF_CONSTANT(1.0f); + + return normal; +} +*/ + +// Needs to match NormalDecodeMode_t enum in imaterialsystem.h +#define NORM_DECODE_NONE 0 +#define NORM_DECODE_ATI2N 1 +#define NORM_DECODE_ATI2N_ALPHA 2 + +float4 DecompressNormal( sampler NormalSampler, float2 tc, int nDecompressionMode, sampler AlphaSampler ) +{ + float4 normalTexel = tex2D( NormalSampler, tc ); + float4 result; + + if ( nDecompressionMode == NORM_DECODE_NONE ) + { + result = float4(normalTexel.xyz * 2.0f - 1.0f, normalTexel.a ); + } + else if ( nDecompressionMode == NORM_DECODE_ATI2N ) + { + result.xy = normalTexel.xy * 2.0f - 1.0f; + result.z = sqrt( 1.0f - dot(result.xy, result.xy) ); + result.a = 1.0f; + } + else // ATI2N plus ATI1N for alpha + { + result.xy = normalTexel.xy * 2.0f - 1.0f; + result.z = sqrt( 1.0f - dot(result.xy, result.xy) ); + result.a = tex2D( AlphaSampler, tc ).x; // Note that this comes in on the X channel + } + + return result; +} + +float4 DecompressNormal( sampler NormalSampler, float2 tc, int nDecompressionMode ) +{ + return DecompressNormal( NormalSampler, tc, nDecompressionMode, NormalSampler ); +} + + +HALF3 NormalizeWithCubemap( sampler normalizeSampler, HALF3 input ) +{ +// return texCUBE( normalizeSampler, input ) * 2.0f - 1.0f; + return texCUBE( normalizeSampler, input ); +} + +/* +HALF4 EnvReflect( sampler envmapSampler, + sampler normalizeSampler, + HALF3 normal, + float3 eye, + HALF2 fresnelScaleBias ) +{ + HALF3 normEye = NormalizeWithCubemap( normalizeSampler, eye ); + HALF fresnel = Fresnel( normal, normEye, fresnelScaleBias ); + HALF3 reflect = CalcReflectionVectorUnnormalized( normal, eye ); + return texCUBE( envmapSampler, reflect ); +} +*/ + +float CalcWaterFogAlpha( const float flWaterZ, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ, const float flFogOORange ) +{ +// float flDepthFromWater = flWaterZ - flWorldPosZ + 2.0f; // hackity hack . .this is for the DF_FUDGE_UP in view_scene.cpp + float flDepthFromWater = flWaterZ - flWorldPosZ; + + // if flDepthFromWater < 0, then set it to 0 + // This is the equivalent of moving the vert to the water surface if it's above the water surface + // We'll do this with the saturate at the end instead. +// flDepthFromWater = max( 0.0f, flDepthFromWater ); + + // Calculate the ratio of water fog to regular fog (ie. how much of the distance from the viewer + // to the vert is actually underwater. + float flDepthFromEye = flEyePosZ - flWorldPosZ; + float f = (flDepthFromWater / flDepthFromEye) * flProjPosZ; + + // $tmp.w is now the distance that we see through water. + return saturate( f * flFogOORange ); +} + +#if defined(SHADER_EDITOR_SWARM_COMPILE) +float CalcRangeFog( const float3 flEyePos, const float3 flWorldPos, const float flFogEndOverRange, const float flFogMaxDensity, const float flFogOORange ) +#else +float CalcRangeFog( const float flProjPosZ, const float flFogEndOverRange, const float flFogMaxDensity, const float flFogOORange ) +#endif // SHADER_EDITOR_SWARM_COMPILE +{ +#if defined(SHADER_EDITOR_SWARM_COMPILE) + return min( flFogMaxDensity, saturate( flFogEndOverRange + ( distance( flEyePos, flWorldPos ) * flFogOORange ) ) ); +#elif defined(SHADER_EDITOR_2013_COMPILE) + return min( flFogMaxDensity, ( saturate( flProjPosZ * flFogOORange - flFogEndOverRange ) ) ); +#else +#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b + return min( flFogMaxDensity, ( saturate( 1.0 - (flFogEndOverRange - (flProjPosZ * flFogOORange)) ) ) ); +#else + return 0.0f; //ps20 shaders will never have range fog enabled because too many ran out of slots. +#endif +#endif // SHADER_EDITOR_SWARM_COMPILE +} + +#if defined(SHADER_EDITOR_SWARM_COMPILE) +float CalcPixelFogFactor( int iPIXELFOGTYPE, const float4 fogParams, const float3 flEyePos, const float3 flWorldPos ) +#else +float CalcPixelFogFactor( int iPIXELFOGTYPE, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ ) +#endif // SHADER_EDITOR_SWARM_COMPILE +{ + float retVal; + if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_NONE ) + { + retVal = 0.0f; + } + if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE ) //range fog, or no fog depending on fog parameters + { +#if defined(SHADER_EDITOR_SWARM_COMPILE) + retVal = CalcRangeFog( flEyePos, flWorldPos, fogParams.x, fogParams.z, fogParams.w ); +#else + retVal = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.z, fogParams.w ); +#endif // SHADER_EDITOR_SWARM_COMPILE + } + else if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) //height fog + { +#if defined(SHADER_EDITOR_SWARM_COMPILE) + retVal = 0.0f; +#else + retVal = CalcWaterFogAlpha( fogParams.y, flEyePosZ, flWorldPosZ, flProjPosZ, fogParams.w ); +#endif // SHADER_EDITOR_SWARM_COMPILE + } + + return retVal; +} + +//g_FogParams not defined by default, but this is the same layout for every shader that does define it +#define g_FogEndOverRange g_FogParams.x +#define g_WaterZ g_FogParams.y +#define g_FogMaxDensity g_FogParams.z +#define g_FogOORange g_FogParams.w + +float3 BlendPixelFog( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, const int iPIXELFOGTYPE ) +{ + if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE ) //either range fog or no fog depending on fog parameters and whether this is ps20 or ps2b + { +# if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b + pixelFogFactor = saturate( pixelFogFactor ); + return lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog +# else + return vShaderColor; +# endif + } + else if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) + { + return lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) ); + } + else if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_NONE ) + { + return vShaderColor; + } +} + + +#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) && ( CONVERT_TO_SRGB != 0 ) ) +sampler1D GammaTableSampler : register( s15 ); + +float3 SRGBOutput( const float3 vShaderColor ) +{ + //On ps2b capable hardware we always have the linear->gamma conversion table texture in sampler s15. + float3 result; + result.r = tex1D( GammaTableSampler, vShaderColor.r ).r; + result.g = tex1D( GammaTableSampler, vShaderColor.g ).r; + result.b = tex1D( GammaTableSampler, vShaderColor.b ).r; + return result; +} + +#else + +float3 SRGBOutput( const float3 vShaderColor ) +{ + return vShaderColor; //ps 1.1, 1.4, and 2.0 never do srgb conversion in the pixel shader +} + +#endif + + +float SoftParticleDepth( float flDepth ) +{ + return flDepth * OO_DESTALPHA_DEPTH_RANGE; +} + + +float DepthToDestAlpha( const float flProjZ ) +{ +#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b + return SoftParticleDepth( flProjZ ); +#else + return 1.0f; +#endif +} + + +float4 FinalOutput( const float4 vShaderColor, float pixelFogFactor, const int iPIXELFOGTYPE, const int iTONEMAP_SCALE_TYPE, const bool bWriteDepthToDestAlpha = false, const float flProjZ = 1.0f ) +{ + float4 result; + if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR ) + { + result.rgb = vShaderColor.rgb * LINEAR_LIGHT_SCALE; + } + else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA ) + { + result.rgb = vShaderColor.rgb * GAMMA_LIGHT_SCALE; + } + else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_NONE ) + { + result.rgb = vShaderColor.rgb; + } + + if( bWriteDepthToDestAlpha ) +#if ( WRITEWATERFOGTODESTALPHA == 1 ) + result.a = pixelFogFactor; +#else + result.a = DepthToDestAlpha( flProjZ ); +#endif + else + result.a = vShaderColor.a; + + result.rgb = BlendPixelFog( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, iPIXELFOGTYPE ); + +#if !(defined(SHADER_EDITOR_SWARM_COMPILE)) + +#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b + result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion +#endif + +#endif // SHADER_EDITOR_SWARM_COMPILE + + return result; +} + +LPREVIEW_PS_OUT FinalOutput( const LPREVIEW_PS_OUT vShaderColor, float pixelFogFactor, const int iPIXELFOGTYPE, const int iTONEMAP_SCALE_TYPE ) +{ + LPREVIEW_PS_OUT result; + result.color = FinalOutput( vShaderColor.color, pixelFogFactor, iPIXELFOGTYPE, iTONEMAP_SCALE_TYPE ); + result.normal.rgb = SRGBOutput( vShaderColor.normal.rgb ); + result.normal.a = vShaderColor.normal.a; + + result.position.rgb = SRGBOutput( vShaderColor.position.rgb ); + result.position.a = vShaderColor.position.a; + + result.flags.rgb = SRGBOutput( vShaderColor.flags.rgb ); + result.flags.a = vShaderColor.flags.a; + + return result; +} + + + + +float RemapValClamped( float val, float A, float B, float C, float D) +{ + float cVal = (val - A) / (B - A); + cVal = saturate( cVal ); + + return C + (D - C) * cVal; +} + +//======================================// +// HSL Color space conversion routines // +//======================================// + +#define HUE 0 +#define SATURATION 1 +#define LIGHTNESS 2 + +// Convert from RGB to HSL color space +float4 RGBtoHSL( float4 inColor ) +{ + float h, s; + float flMax = max( inColor.r, max( inColor.g, inColor.b ) ); + float flMin = min( inColor.r, min( inColor.g, inColor.b ) ); + + float l = (flMax + flMin) / 2.0f; + + if (flMax == flMin) // achromatic case + { + s = h = 0; + } + else // chromatic case + { + // Next, calculate the hue + float delta = flMax - flMin; + + // First, calculate the saturation + if (l < 0.5f) // If we're in the lower hexcone + { + s = delta/(flMax + flMin); + } + else + { + s = delta/(2 - flMax - flMin); + } + + if ( inColor.r == flMax ) + { + h = (inColor.g - inColor.b)/delta; // color between yellow and magenta + } + else if ( inColor.g == flMax ) + { + h = 2 + (inColor.b - inColor.r)/delta; // color between cyan and yellow + } + else // blue must be max + { + h = 4 + (inColor.r - inColor.g)/delta; // color between magenta and cyan + } + + h *= 60.0f; + + if (h < 0.0f) + { + h += 360.0f; + } + + h /= 360.0f; + } + + return float4 (h, s, l, 1.0f); +} + +float HueToRGB( float v1, float v2, float vH ) +{ + float fResult = v1; + + vH = fmod (vH + 1.0f, 1.0f); + + if ( ( 6.0f * vH ) < 1.0f ) + { + fResult = ( v1 + ( v2 - v1 ) * 6.0f * vH ); + } + else if ( ( 2.0f * vH ) < 1.0f ) + { + fResult = ( v2 ); + } + else if ( ( 3.0f * vH ) < 2.0f ) + { + fResult = ( v1 + ( v2 - v1 ) * ( ( 2.0f / 3.0f ) - vH ) * 6.0f ); + } + + return fResult; +} + +// Convert from HSL to RGB color space +float4 HSLtoRGB( float4 hsl ) +{ + float r, g, b; + float h = hsl[HUE]; + float s = hsl[SATURATION]; + float l = hsl[LIGHTNESS]; + + if ( s == 0 ) + { + r = g = b = l; + } + else + { + float v1, v2; + + if ( l < 0.5f ) + v2 = l * ( 1.0f + s ); + else + v2 = ( l + s ) - ( s * l ); + + v1 = 2 * l - v2; + + r = HueToRGB( v1, v2, h + ( 1.0f / 3.0f ) ); + g = HueToRGB( v1, v2, h ); + b = HueToRGB( v1, v2, h - ( 1.0f / 3.0f ) ); + } + + return float4( r, g, b, 1.0f ); +} + + +// texture combining modes for combining base and detail/basetexture2 +#define TCOMBINE_RGB_EQUALS_BASE_x_DETAILx2 0 // original mode +#define TCOMBINE_RGB_ADDITIVE 1 // base.rgb+detail.rgb*fblend +#define TCOMBINE_DETAIL_OVER_BASE 2 +#define TCOMBINE_FADE 3 // straight fade between base and detail. +#define TCOMBINE_BASE_OVER_DETAIL 4 // use base alpha for blend over detail +#define TCOMBINE_RGB_ADDITIVE_SELFILLUM 5 // add detail color post lighting +#define TCOMBINE_RGB_ADDITIVE_SELFILLUM_THRESHOLD_FADE 6 +#define TCOMBINE_MOD2X_SELECT_TWO_PATTERNS 7 // use alpha channel of base to select between mod2x channels in r+a of detail +#define TCOMBINE_MULTIPLY 8 +#define TCOMBINE_MASK_BASE_BY_DETAIL_ALPHA 9 // use alpha channel of detail to mask base +#define TCOMBINE_SSBUMP_BUMP 10 // use detail to modulate lighting as an ssbump +#define TCOMBINE_SSBUMP_NOBUMP 11 // detail is an ssbump but use it as an albedo. shader does the magic here - no user needs to specify mode 11 + +float4 TextureCombine( float4 baseColor, float4 detailColor, int combine_mode, + float fBlendFactor ) +{ + if ( combine_mode == TCOMBINE_MOD2X_SELECT_TWO_PATTERNS) + { + float3 dc=lerp(detailColor.r,detailColor.a, baseColor.a); + baseColor.rgb*=lerp(float3(1,1,1),2.0*dc,fBlendFactor); + } + if ( combine_mode == TCOMBINE_RGB_EQUALS_BASE_x_DETAILx2) + baseColor.rgb*=lerp(float3(1,1,1),2.0*detailColor.rgb,fBlendFactor); + if ( combine_mode == TCOMBINE_RGB_ADDITIVE ) + baseColor.rgb += fBlendFactor * detailColor.rgb; + if ( combine_mode == TCOMBINE_DETAIL_OVER_BASE ) + { + float fblend=fBlendFactor * detailColor.a; + baseColor.rgb = lerp( baseColor.rgb, detailColor.rgb, fblend); + } + if ( combine_mode == TCOMBINE_FADE ) + { + baseColor = lerp( baseColor, detailColor, fBlendFactor); + } + if ( combine_mode == TCOMBINE_BASE_OVER_DETAIL ) + { + float fblend=fBlendFactor * (1-baseColor.a); + baseColor.rgb = lerp( baseColor.rgb, detailColor.rgb, fblend ); + baseColor.a = detailColor.a; + } + if ( combine_mode == TCOMBINE_MULTIPLY ) + { + baseColor = lerp( baseColor, baseColor*detailColor, fBlendFactor); + } + + if (combine_mode == TCOMBINE_MASK_BASE_BY_DETAIL_ALPHA ) + { + baseColor.a = lerp( baseColor.a, baseColor.a*detailColor.a, fBlendFactor ); + } + if ( combine_mode == TCOMBINE_SSBUMP_NOBUMP ) + { + baseColor.rgb = baseColor.rgb * dot( detailColor.rgb, 2.0/3.0 ); + } + return baseColor; +} + +float3 lerp5(float3 f1, float3 f2, float i1, float i2, float x) +{ + return f1+(f2-f1)*(x-i1)/(i2-i1); +} + +float3 TextureCombinePostLighting( float3 lit_baseColor, float4 detailColor, int combine_mode, + float fBlendFactor ) +{ + if ( combine_mode == TCOMBINE_RGB_ADDITIVE_SELFILLUM ) + lit_baseColor += fBlendFactor * detailColor.rgb; + if ( combine_mode == TCOMBINE_RGB_ADDITIVE_SELFILLUM_THRESHOLD_FADE ) + { + // fade in an unusual way - instead of fading out color, remap an increasing band of it from + // 0..1 + if ( fBlendFactor > 0.5) + lit_baseColor += min(1, (1.0/fBlendFactor)*max(0, detailColor.rgb-(1-fBlendFactor) ) ); + else + lit_baseColor += 2*fBlendFactor*2*max(0, detailColor.rgb-.5); + } + return lit_baseColor; +} + +//NOTE: On X360. fProjZ is expected to be pre-reversed for cheaper math here in the pixel shader +float DepthFeathering( sampler DepthSampler, const float2 vScreenPos, float fProjZ, float fProjW, float4 vDepthBlendConstants ) +{ +# if ( !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) ) //minimum requirement of ps2b + { + float flFeatheredAlpha; + float2 flDepths; +#define flSceneDepth flDepths.x +#define flSpriteDepth flDepths.y + +# if ( defined( _X360 ) ) + { + //Get depth from the depth texture. Need to sample with the offset of (0.5, 0.5) to fix rounding errors + asm { + tfetch2D flDepths.x___, vScreenPos, DepthSampler, OffsetX=0.5, OffsetY=0.5, MinFilter=point, MagFilter=point, MipFilter=point + }; + +# if( !defined( REVERSE_DEPTH_ON_X360 ) ) + flSceneDepth = 1.0f - flSceneDepth; +# endif + + //get the sprite depth into the same range as the texture depth + flSpriteDepth = fProjZ / fProjW; + + //unproject to get at the pre-projection z. This value is much more linear than depth + flDepths = vDepthBlendConstants.z / flDepths; + flDepths = vDepthBlendConstants.y - flDepths; + + flFeatheredAlpha = flSceneDepth - flSpriteDepth; + flFeatheredAlpha *= vDepthBlendConstants.x; + flFeatheredAlpha = saturate( flFeatheredAlpha ); + } +# else + { + flSceneDepth = tex2D( DepthSampler, vScreenPos ).a; // PC uses dest alpha of the frame buffer + flSpriteDepth = SoftParticleDepth( fProjZ ); + + flFeatheredAlpha = abs(flSceneDepth - flSpriteDepth) * vDepthBlendConstants.x; + flFeatheredAlpha = max( smoothstep( 0.75f, 1.0f, flSceneDepth ), flFeatheredAlpha ); //as the sprite approaches the edge of our compressed depth space, the math stops working. So as the sprite approaches the far depth, smoothly remove feathering. + flFeatheredAlpha = saturate( flFeatheredAlpha ); + } +# endif + +#undef flSceneDepth +#undef flSpriteDepth + + return flFeatheredAlpha; + } +# else + { + return 1.0f; + } +# endif +} + +#endif //#ifndef COMMON_PS_FXC_H_ \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/common_vertexlitgeneric_dx9.h b/sp/src/materialsystem/stdshaders/ShaderEdit/common_vertexlitgeneric_dx9.h new file mode 100644 index 00000000..9c2ebfc2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/common_vertexlitgeneric_dx9.h @@ -0,0 +1,449 @@ +#ifndef COMMON_VERTEXLITGENERIC_DX9_H_ +#define COMMON_VERTEXLITGENERIC_DX9_H_ + +#include "common_ps_fxc.h" + +// We store four light colors and positions in an +// array of three of these structures like so: +// +// x y z w +// +------+------+------+------+ +// | L0.rgb | | +// +------+------+------+ | +// | L0.pos | L3 | +// +------+------+------+ rgb | +// | L1.rgb | | +// +------+------+------+------+ +// | L1.pos | | +// +------+------+------+ | +// | L2.rgb | L3 | +// +------+------+------+ pos | +// | L2.pos | | +// +------+------+------+------+ +// +struct PixelShaderLightInfo +{ + float4 color; + float4 pos; +}; + +#define cOverbright 2.0f +#define cOOOverbright 0.5f + +#define LIGHTTYPE_NONE 0 +#define LIGHTTYPE_SPOT 1 +#define LIGHTTYPE_POINT 2 +#define LIGHTTYPE_DIRECTIONAL 3 + +// Better suited to Pixel shader models, 11 instructions in pixel shader +float3 PixelShaderAmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) +{ + float3 linearColor, nSquared = worldNormal * worldNormal; + float3 isNegative = ( worldNormal < 0.0 ); + float3 isPositive = 1-isNegative; + + isNegative *= nSquared; + isPositive *= nSquared; + + linearColor = isPositive.x * cAmbientCube[0] + isNegative.x * cAmbientCube[1] + + isPositive.y * cAmbientCube[2] + isNegative.y * cAmbientCube[3] + + isPositive.z * cAmbientCube[4] + isNegative.z * cAmbientCube[5]; + + return linearColor; +} + +// Better suited to Vertex shader models +// Six VS instructions due to use of constant indexing (slt, mova, mul, mul, mad, mad) +float3 VertexShaderAmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) +{ + float3 nSquared = worldNormal * worldNormal; + int3 isNegative = ( worldNormal < 0.0 ); + float3 linearColor; + linearColor = nSquared.x * cAmbientCube[isNegative.x] + + nSquared.y * cAmbientCube[isNegative.y+2] + + nSquared.z * cAmbientCube[isNegative.z+4]; + return linearColor; +} + +float3 AmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] ) +{ + // Vertex shader cases +#ifdef SHADER_MODEL_VS_1_0 + return VertexShaderAmbientLight( worldNormal, cAmbientCube ); +#elif SHADER_MODEL_VS_1_1 + return VertexShaderAmbientLight( worldNormal, cAmbientCube ); +#elif SHADER_MODEL_VS_2_0 + return VertexShaderAmbientLight( worldNormal, cAmbientCube ); +#elif SHADER_MODEL_VS_3_0 + return VertexShaderAmbientLight( worldNormal, cAmbientCube ); +#else + // Pixel shader case + return PixelShaderAmbientLight( worldNormal, cAmbientCube ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: Compute scalar diffuse term with various optional tweaks such as +// Half Lambert and ambient occlusion +//----------------------------------------------------------------------------- +float3 DiffuseTerm(const bool bHalfLambert, const float3 worldNormal, const float3 lightDir, + const bool bDoAmbientOcclusion, const float fAmbientOcclusion/*, + const bool bDoLightingWarp, in sampler lightWarpSampler*/ ) +{ + float fResult; + + float NDotL = dot( worldNormal, lightDir ); // Unsaturated dot (-1 to 1 range) + + if ( bHalfLambert ) + { + fResult = saturate(NDotL * 0.5 + 0.5); // Scale and bias to 0 to 1 range + + //if ( !bDoLightingWarp ) + { + fResult *= fResult; // Square + } + } + else + { + fResult = saturate( NDotL ); // Saturate pure Lambertian term + } + + if ( bDoAmbientOcclusion ) + { + // Raise to higher powers for darker AO values +// float fAOPower = lerp( 4.0f, 1.0f, fAmbientOcclusion ); +// result *= pow( NDotL * 0.5 + 0.5, fAOPower ); + fResult *= fAmbientOcclusion; + } + + float3 fOut = float3( fResult, fResult, fResult ); + //if ( bDoLightingWarp ) + //{ + // fOut = 2.0f * tex1D( lightWarpSampler, fResult ); + //} + + return fOut; +} + +float3 PixelShaderDoGeneralDiffuseLight( const float fAtten, const float3 worldPos, const float3 worldNormal, + /* in sampler NormalizeSampler,*/ + const float3 vPosition, const float3 vColor, const bool bHalfLambert, + const bool bDoAmbientOcclusion, const float fAmbientOcclusion/*, + const bool bDoLightingWarp, in sampler lightWarpSampler*/ ) +{ +//#if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) + float3 lightDir = normalize( vPosition - worldPos ); +//#else +// float3 lightDir = NormalizeWithCubemap( NormalizeSampler, vPosition - worldPos ); +//#endif + return vColor * fAtten * DiffuseTerm( bHalfLambert, worldNormal, lightDir, bDoAmbientOcclusion, fAmbientOcclusion/*, bDoLightingWarp, lightWarpSampler*/ ); +} + +float3 PixelShaderGetLightVector( const float3 worldPos, PixelShaderLightInfo cLightInfo[3], int nLightIndex ) +{ + if ( nLightIndex == 3 ) + { + // Unpack light 3 from w components... + float3 vLight3Pos = float3( cLightInfo[1].pos.w, cLightInfo[2].color.w, cLightInfo[2].pos.w ); + return normalize( vLight3Pos - worldPos ); + } + else + { + return normalize( cLightInfo[nLightIndex].pos - worldPos ); + } +} + +float3 PixelShaderGetLightColor( PixelShaderLightInfo cLightInfo[3], int nLightIndex ) +{ + if ( nLightIndex == 3 ) + { + // Unpack light 3 from w components... + return float3( cLightInfo[0].color.w, cLightInfo[0].pos.w, cLightInfo[1].color.w ); + } + else + { + return cLightInfo[nLightIndex].color.rgb; + } +} + +void GetLightData( PixelShaderLightInfo cLightInfo[3], int index, float3 worldpos, + out float3 color, out float3 dir ) +{ + color = PixelShaderGetLightColor( cLightInfo, index ); + dir = PixelShaderGetLightVector( worldpos, cLightInfo, index ); +} + + +void SpecularAndRimTerms( const float3 vWorldNormal, const float3 vLightDir, const float fSpecularExponent, + const float3 vEyeDir, const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + /*const bool bDoSpecularWarp, in sampler specularWarpSampler,*/ const float fFresnel, + const float3 color, /*const bool bDoRimLighting, const float fRimExponent,*/ + + // Outputs + out float3 specularLighting/*, out float3 rimLighting*/ ) +{ + //rimLighting = float3(0.0f, 0.0f, 0.0f); + + float3 vReflect = reflect( -vEyeDir, vWorldNormal ); // Reflect view through normal + float LdotR = saturate(dot( vReflect, vLightDir )); // L.R (use half-angle instead?) + specularLighting = pow( LdotR, fSpecularExponent ); // Raise to specular exponent + + // Optionally warp as function of scalar specular and fresnel + //if ( bDoSpecularWarp ) + // specularLighting *= tex2D( specularWarpSampler, float2(specularLighting.x, fFresnel) ); // Sample at { (L.R)^k, fresnel } + specularLighting *= fFresnel; // Sample at { (L.R)^k, fresnel } + + specularLighting *= saturate(dot( vWorldNormal, vLightDir )); // Mask with N.L + specularLighting *= color; // Modulate with light color + + if ( bDoAmbientOcclusion ) // Optionally modulate with ambient occlusion + specularLighting *= fAmbientOcclusion; + + //if ( bDoRimLighting ) // Optionally do rim lighting + //{ + // rimLighting = pow( LdotR, fRimExponent ); // Raise to rim exponent + // rimLighting *= saturate(dot( vWorldNormal, vLightDir )); // Mask with N.L + // rimLighting *= color; // Modulate with light color + //} +} + +// Traditional fresnel term approximation +float Fresnel( const float3 vNormal, const float3 vEyeDir ) +{ + float fresnel = 1-saturate( dot( vNormal, vEyeDir ) ); // 1-(N.V) for Fresnel term + return fresnel * fresnel; // Square for a more subtle look +} + +// Traditional fresnel term approximation which uses 4th power (square twice) +float Fresnel4( const float3 vNormal, const float3 vEyeDir ) +{ + float fresnel = 1-saturate( dot( vNormal, vEyeDir ) ); // 1-(N.V) for Fresnel term + fresnel = fresnel * fresnel; // Square + return fresnel * fresnel; // Square again for a more subtle look +} + + +// +// Custom Fresnel with low, mid and high parameters defining a piecewise continuous function +// with traditional fresnel (0 to 1 range) as input. The 0 to 0.5 range blends between +// low and mid while the 0.5 to 1 range blends between mid and high +// +// | +// | . M . . . H +// | . +// L +// | +// +---------------- +// 0 1 +// +float Fresnel( const float3 vNormal, const float3 vEyeDir, float3 vRanges ) +{ + float result, f = Fresnel( vNormal, vEyeDir ); // Traditional Fresnel + + if ( f > 0.5f ) + result = lerp( vRanges.y, vRanges.z, (2*f)-1 ); // Blend between mid and high values + else + result = lerp( vRanges.x, vRanges.y, 2*f ); // Blend between low and mid values + + return result; +} + +void PixelShaderDoSpecularLight( const float3 vWorldPos, const float3 vWorldNormal, const float fSpecularExponent, const float3 vEyeDir, + const float fAtten, const float3 vLightColor, const float3 vLightDir, + const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + /*const bool bDoSpecularWarp, in sampler specularWarpSampler,*/ float fFresnel, + /*const bool bDoRimLighting, const float fRimExponent,*/ + + // Outputs + out float3 specularLighting/*, out float3 rimLighting*/ ) +{ + // Compute Specular and rim terms + SpecularAndRimTerms( vWorldNormal, vLightDir, fSpecularExponent, + vEyeDir, bDoAmbientOcclusion, fAmbientOcclusion, + /*bDoSpecularWarp, specularWarpSampler,*/ fFresnel, vLightColor * fAtten, + /*bDoRimLighting, fRimExponent,*/ specularLighting/*, rimLighting*/ ); +} + +float3 PixelShaderDoLightingLinear( const float3 worldPos, const float3 worldNormal, + const float3 staticLightingColor, const bool bStaticLight, + const bool bAmbientLight, const float4 lightAtten, const float3 cAmbientCube[6], + /*in sampler NormalizeSampler,*/ const int nNumLights, PixelShaderLightInfo cLightInfo[3], + const bool bHalfLambert, const bool bDoAmbientOcclusion, const float fAmbientOcclusion/*, + const bool bDoLightingWarp, in sampler lightWarpSampler*/ ) +{ + float3 linearColor = 0.0f; + + if ( bStaticLight ) + { + // The static lighting comes in in gamma space and has also been premultiplied by $cOOOverbright + // need to get it into + // linear space so that we can do adds. + linearColor += GammaToLinear( staticLightingColor * cOverbright ); + } + + if ( bAmbientLight ) + { + float3 ambient = AmbientLight( worldNormal, cAmbientCube ); + + if ( bDoAmbientOcclusion ) + ambient *= fAmbientOcclusion * fAmbientOcclusion; // Note squaring... + + linearColor += ambient; + } + + if ( nNumLights > 0 ) + { + linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.x, worldPos, worldNormal, /*NormalizeSampler,*/ + cLightInfo[0].pos, cLightInfo[0].color, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion/*, + bDoLightingWarp, lightWarpSampler*/ ); + if ( nNumLights > 1 ) + { + linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.y, worldPos, worldNormal, /*NormalizeSampler,*/ + cLightInfo[1].pos, cLightInfo[1].color, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion/*, + bDoLightingWarp, lightWarpSampler*/ ); + if ( nNumLights > 2 ) + { + linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.z, worldPos, worldNormal, /*NormalizeSampler,*/ + cLightInfo[2].pos, cLightInfo[2].color, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion/*, + bDoLightingWarp, lightWarpSampler*/ ); + if ( nNumLights > 3 ) + { + // Unpack the 4th light's data from tight constant packing + float3 vLight3Color = float3( cLightInfo[0].color.w, cLightInfo[0].pos.w, cLightInfo[1].color.w ); + float3 vLight3Pos = float3( cLightInfo[1].pos.w, cLightInfo[2].color.w, cLightInfo[2].pos.w ); + linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.w, worldPos, worldNormal, /*NormalizeSampler,*/ + vLight3Pos, vLight3Color, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion/*, + bDoLightingWarp, lightWarpSampler*/ ); + } + } + } + } + + return linearColor; +} + +void PixelShaderDoSpecularLighting( const float3 worldPos, const float3 worldNormal, const float fSpecularExponent, const float3 vEyeDir, + const float4 lightAtten, const int nNumLights, PixelShaderLightInfo cLightInfo[3], + const bool bDoAmbientOcclusion, const float fAmbientOcclusion, + /*const bool bDoSpecularWarp, in sampler specularWarpSampler,*/ float fFresnel, + /*const bool bDoRimLighting, const float fRimExponent,*/ + + // Outputs + out float3 specularLighting/*, out float3 rimLighting*/ ) +{ + specularLighting /*= rimLighting*/ = float3( 0.0f, 0.0f, 0.0f ); + float3 localSpecularTerm/*, localRimTerm*/; + + if( nNumLights > 0 ) + { + PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, + lightAtten.x, PixelShaderGetLightColor( cLightInfo, 0 ), + PixelShaderGetLightVector( worldPos, cLightInfo, 0 ), + bDoAmbientOcclusion, fAmbientOcclusion, + /*bDoSpecularWarp, specularWarpSampler,*/ fFresnel, + /*bDoRimLighting, fRimExponent,*/ + localSpecularTerm/*, localRimTerm*/ ); + + specularLighting += localSpecularTerm; // Accumulate specular and rim terms + /*rimLighting += localRimTerm;*/ + } + + if( nNumLights > 1 ) + { + PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, + lightAtten.y, PixelShaderGetLightColor( cLightInfo, 1 ), + PixelShaderGetLightVector( worldPos, cLightInfo, 1 ), + bDoAmbientOcclusion, fAmbientOcclusion, + /*bDoSpecularWarp, specularWarpSampler,*/ fFresnel, + /*bDoRimLighting, fRimExponent,*/ + localSpecularTerm/*, localRimTerm*/ ); + + specularLighting += localSpecularTerm; // Accumulate specular and rim terms + /*rimLighting += localRimTerm;*/ + } + + + if( nNumLights > 2 ) + { + PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, + lightAtten.z, PixelShaderGetLightColor( cLightInfo, 2 ), + PixelShaderGetLightVector( worldPos, cLightInfo, 2 ), + bDoAmbientOcclusion, fAmbientOcclusion, + /*bDoSpecularWarp, specularWarpSampler,*/ fFresnel, + /*bDoRimLighting, fRimExponent,*/ + localSpecularTerm/*, localRimTerm*/ ); + + specularLighting += localSpecularTerm; // Accumulate specular and rim terms + /*rimLighting += localRimTerm;*/ + } + + if( nNumLights > 3 ) + { + PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir, + lightAtten.w, PixelShaderGetLightColor( cLightInfo, 3 ), + PixelShaderGetLightVector( worldPos, cLightInfo, 3 ), + bDoAmbientOcclusion, fAmbientOcclusion, + /*bDoSpecularWarp, specularWarpSampler,*/ fFresnel, + /*bDoRimLighting, fRimExponent,*/ + localSpecularTerm/*, localRimTerm*/ ); + + specularLighting += localSpecularTerm; // Accumulate specular and rim terms + /*rimLighting += localRimTerm;*/ + } + +} + +float3 PixelShaderDoRimLighting( const float3 worldNormal, const float3 vEyeDir, const float3 cAmbientCube[6], float fFresnel ) +{ + float3 vReflect = reflect( -vEyeDir, worldNormal ); // Reflect view through normal + + return fFresnel * PixelShaderAmbientLight( vEyeDir, cAmbientCube ); +} + +// Called directly by newer shaders or through the following wrapper for older shaders +float3 PixelShaderDoLighting( const float3 worldPos, const float3 worldNormal, + const float3 staticLightingColor, const bool bStaticLight, + const bool bAmbientLight, const float4 lightAtten, const float3 cAmbientCube[6], + /*in sampler NormalizeSampler,*/ const int nNumLights, PixelShaderLightInfo cLightInfo[3], + const bool bHalfLambert, + + // New optional/experimental parameters + const bool bDoAmbientOcclusion, const float fAmbientOcclusion/*, + const bool bDoLightingWarp, in sampler lightWarpSampler*/ ) +{ + float3 returnColor; + + // special case for no lighting + if( !bStaticLight && !bAmbientLight ) + { + returnColor = float3( 0.0f, 0.0f, 0.0f ); + } + else if( bStaticLight && !bAmbientLight ) + { + // special case for static lighting only + returnColor = GammaToLinear( staticLightingColor ); + } + else + { + float3 linearColor; + + linearColor = PixelShaderDoLightingLinear( worldPos, worldNormal, staticLightingColor, + bStaticLight, bAmbientLight, lightAtten, + cAmbientCube, /*NormalizeSampler,*/ nNumLights, cLightInfo, bHalfLambert, + bDoAmbientOcclusion, fAmbientOcclusion/*, + bDoLightingWarp, lightWarpSampler*/ ); + + // go ahead and clamp to the linear space equivalent of overbright 2 so that we match + // everything else. +// returnColor = HuePreservingColorClamp( linearColor, pow( 2.0f, 2.2 ) ); + returnColor = linearColor; + } + + return returnColor; +} + +#endif //#ifndef COMMON_VERTEXLITGENERIC_DX9_H_ diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/common_vs_fxc.h b/sp/src/materialsystem/stdshaders/ShaderEdit/common_vs_fxc.h new file mode 100644 index 00000000..2378abc1 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/common_vs_fxc.h @@ -0,0 +1,959 @@ +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// +// +// Purpose: This is where all common code for vertex shaders go. +// +// $NoKeywords: $ +// +//===========================================================================// + + + +#ifndef COMMON_VS_FXC_H_ +#define COMMON_VS_FXC_H_ + +#include "common_fxc.h" + +// Put global skip commands here. . make sure and check that the appropriate vars are defined +// so these aren't used on the wrong shaders! +// -------------------------------------------------------------------------------- +// Ditch all fastpath attemps if we are doing LIGHTING_PREVIEW. +// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH +// -------------------------------------------------------------------------------- + + +#ifndef COMPRESSED_VERTS +// Default to no vertex compression +#define COMPRESSED_VERTS 0 +#endif + +#if ( !defined( SHADER_MODEL_VS_2_0 ) && !defined( SHADER_MODEL_VS_3_0 ) ) +#if COMPRESSED_VERTS == 1 +#error "Vertex compression is only for DX9 and up!" +#endif +#endif + +// We're testing 2 normal compression methods +// One compressed normals+tangents into a SHORT2 each (8 bytes total) +// The other compresses them together, into a single UBYTE4 (4 bytes total) +// FIXME: pick one or the other, compare lighting quality in important cases +#define COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 0 +#define COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 1 +//#define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 +#define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 + + +#define FOGTYPE_RANGE 0 +#define FOGTYPE_HEIGHT 1 + +#define COMPILE_ERROR ( 1/0; ) + +// ------------------------- +// CONSTANTS +// ------------------------- + +#pragma def ( vs, c0, 0.0f, 1.0f, 2.0f, 0.5f ) + +const float4 cConstants1 : register(c1); +#define cOOGamma cConstants1.x +#define cOverbright 2.0f +#define cOneThird cConstants1.z +#define cOOOverbright ( 1.0f / 2.0f ) + + +// The g_bLightEnabled registers and g_nLightCountRegister hold the same information regarding +// enabling lights, but callers internal to this file tend to use the loops, while external +// callers will end up using the booleans +const bool g_bLightEnabled[4] : register(b0); + // through b3 + +const int g_nLightCountRegister : register(i0); + + +#define g_nLightCount g_nLightCountRegister.x + +const float4 cEyePosWaterZ : register(c2); +#define cEyePos cEyePosWaterZ.xyz + +// This is still used by asm stuff. +const float4 cObsoleteLightIndex : register(c3); + +const float4x4 cModelViewProj : register(c4); +const float4x4 cViewProj : register(c8); + +// Only cFlexScale.x is used +// It is a binary value used to switch on/off the addition of the flex delta stream +const float4 cFlexScale : register(c13); + +const float4 cFogParams : register(c16); +#define cFogEndOverFogRange cFogParams.x +#define cFogOne cFogParams.y +#define cFogMaxDensity cFogParams.z +#define cOOFogRange cFogParams.w + +const float4x4 cViewModel : register(c17); + +const float3 cAmbientCubeX [ 2 ] : register ( c21 ) ; +const float3 cAmbientCubeY [ 2 ] : register ( c23 ) ; +const float3 cAmbientCubeZ [ 2 ] : register ( c25 ) ; + +#ifdef SHADER_MODEL_VS_3_0 +const float4 cFlexWeights [ 512 ] : register ( c1024 ) ; +#endif + +struct LightInfo +{ + float4 color; // {xyz} is color w is light type code (see comment below) + float4 dir; // {xyz} is dir w is light type code + float4 pos; + float4 spotParams; + float4 atten; +}; + +// w components of color and dir indicate light type: +// 1x - directional +// 01 - spot +// 00 - point + +// Four lights x 5 constants each = 20 constants +LightInfo cLightInfo[4] : register(c27); +#define LIGHT_0_POSITION_REG c29 + +#ifdef SHADER_MODEL_VS_1_1 + +const float4 cModulationColor : register(c37); + +#define SHADER_SPECIFIC_CONST_0 c38 +#define SHADER_SPECIFIC_CONST_1 c39 +#define SHADER_SPECIFIC_CONST_2 c40 +#define SHADER_SPECIFIC_CONST_3 c41 +#define SHADER_SPECIFIC_CONST_4 c42 +#define SHADER_SPECIFIC_CONST_5 c43 +#define SHADER_SPECIFIC_CONST_6 c44 +#define SHADER_SPECIFIC_CONST_7 c45 +#define SHADER_SPECIFIC_CONST_8 c46 +#define SHADER_SPECIFIC_CONST_9 c47 +#define SHADER_SPECIFIC_CONST_10 c14 +#define SHADER_SPECIFIC_CONST_11 c15 + +static const int cModel0Index = 48; +const float4x3 cModel[16] : register(c48); +// last cmodel is c105 for dx80, c214 for dx90 + +#else // DX9 shaders (vs20 and beyond) + +const float4 cModulationColor : register( c47 ); + +#define SHADER_SPECIFIC_CONST_0 c48 +#define SHADER_SPECIFIC_CONST_1 c49 +#define SHADER_SPECIFIC_CONST_2 c50 +#define SHADER_SPECIFIC_CONST_3 c51 +#define SHADER_SPECIFIC_CONST_4 c52 +#define SHADER_SPECIFIC_CONST_5 c53 +#define SHADER_SPECIFIC_CONST_6 c54 +#define SHADER_SPECIFIC_CONST_7 c55 +#define SHADER_SPECIFIC_CONST_8 c56 +#define SHADER_SPECIFIC_CONST_9 c57 +#define SHADER_SPECIFIC_CONST_10 c14 +#define SHADER_SPECIFIC_CONST_11 c15 + +static const int cModel0Index = 58; +const float4x3 cModel[53] : register( c58 ); +// last cmodel is c105 for dx80, c214 for dx90 + +#define SHADER_SPECIFIC_BOOL_CONST_0 b4 +#define SHADER_SPECIFIC_BOOL_CONST_1 b5 +#define SHADER_SPECIFIC_BOOL_CONST_2 b6 +#define SHADER_SPECIFIC_BOOL_CONST_3 b7 +#define SHADER_SPECIFIC_BOOL_CONST_4 b8 +#define SHADER_SPECIFIC_BOOL_CONST_5 b9 +#define SHADER_SPECIFIC_BOOL_CONST_6 b10 +#define SHADER_SPECIFIC_BOOL_CONST_7 b11 +#endif // vertex shader model constant packing changes + + +//======================================================================================= +// Methods to decompress vertex normals +//======================================================================================= + +//----------------------------------------------------------------------------------- +// Decompress a normal from two-component compressed format +// We expect this data to come from a signed SHORT2 stream in the range of -32768..32767 +// +// -32678 and 0 are invalid encodings +// w contains the sign to use in the cross product when generating a binormal +void _DecompressShort2Tangent( float2 inputTangent, out float4 outputTangent ) +{ + float2 ztSigns = sign( inputTangent ); // sign bits for z and tangent (+1 or -1) + float2 xyAbs = abs( inputTangent ); // 1..32767 + outputTangent.xy = (xyAbs - 16384.0f) / 16384.0f; // x and y + outputTangent.z = ztSigns.x * sqrt( saturate( 1.0f - dot( outputTangent.xy, outputTangent.xy ) ) ); + outputTangent.w = ztSigns.y; +} + +//----------------------------------------------------------------------------------- +// Same code as _DecompressShort2Tangent, just one returns a float4, one a float3 +void _DecompressShort2Normal( float2 inputNormal, out float3 outputNormal ) +{ + float4 result; + _DecompressShort2Tangent( inputNormal, result ); + outputNormal = result.xyz; +} + +//----------------------------------------------------------------------------------- +// Decompress normal+tangent together +void _DecompressShort2NormalTangent( float2 inputNormal, float2 inputTangent, out float3 outputNormal, out float4 outputTangent ) +{ + // FIXME: if we end up sticking with the SHORT2 format, pack the normal and tangent into a single SHORT4 element + // (that would make unpacking normal+tangent here together much cheaper than the sum of their parts) + _DecompressShort2Normal( inputNormal, outputNormal ); + _DecompressShort2Tangent( inputTangent, outputTangent ); +} + +//======================================================================================= +// Decompress a normal and tangent from four-component compressed format +// We expect this data to come from an unsigned UBYTE4 stream in the range of 0..255 +// The final vTangent.w contains the sign to use in the cross product when generating a binormal +void _DecompressUByte4NormalTangent( float4 inputNormal, + out float3 outputNormal, // {nX, nY, nZ} + out float4 outputTangent ) // {tX, tY, tZ, sign of binormal} +{ + float fOne = 1.0f; + + float4 ztztSignBits = ( inputNormal - 128.0f ) < 0; // sign bits for zs and binormal (1 or 0) set-less-than (slt) asm instruction + float4 xyxyAbs = abs( inputNormal - 128.0f ) - ztztSignBits; // 0..127 + float4 xyxySignBits = ( xyxyAbs - 64.0f ) < 0; // sign bits for xs and ys (1 or 0) + float4 normTan = (abs( xyxyAbs - 64.0f ) - xyxySignBits) / 63.0f; // abs({nX, nY, tX, tY}) + outputNormal.xy = normTan.xy; // abs({nX, nY, __, __}) + outputTangent.xy = normTan.zw; // abs({tX, tY, __, __}) + + float4 xyxySigns = 1 - 2*xyxySignBits; // Convert sign bits to signs + float4 ztztSigns = 1 - 2*ztztSignBits; // ( [1,0] -> [-1,+1] ) + + outputNormal.z = 1.0f - outputNormal.x - outputNormal.y; // Project onto x+y+z=1 + outputNormal.xyz = normalize( outputNormal.xyz ); // Normalize onto unit sphere + outputNormal.xy *= xyxySigns.xy; // Restore x and y signs + outputNormal.z *= ztztSigns.x; // Restore z sign + + outputTangent.z = 1.0f - outputTangent.x - outputTangent.y; // Project onto x+y+z=1 + outputTangent.xyz = normalize( outputTangent.xyz ); // Normalize onto unit sphere + outputTangent.xy *= xyxySigns.zw; // Restore x and y signs + outputTangent.z *= ztztSigns.z; // Restore z sign + outputTangent.w = ztztSigns.w; // Binormal sign +} + + +//----------------------------------------------------------------------------------- +// Decompress just a normal from four-component compressed format (same as above) +// We expect this data to come from an unsigned UBYTE4 stream in the range of 0..255 +// [ When compiled, this works out to approximately 17 asm instructions ] +void _DecompressUByte4Normal( float4 inputNormal, + out float3 outputNormal) // {nX, nY, nZ} +{ + float fOne = 1.0f; + + float2 ztSigns = ( inputNormal.xy - 128.0f ) < 0; // sign bits for zs and binormal (1 or 0) set-less-than (slt) asm instruction + float2 xyAbs = abs( inputNormal.xy - 128.0f ) - ztSigns; // 0..127 + float2 xySigns = ( xyAbs - 64.0f ) < 0; // sign bits for xs and ys (1 or 0) + outputNormal.xy = ( abs( xyAbs - 64.0f ) - xySigns ) / 63.0f; // abs({nX, nY}) + + outputNormal.z = 1.0f - outputNormal.x - outputNormal.y; // Project onto x+y+z=1 + outputNormal.xyz = normalize( outputNormal.xyz ); // Normalize onto unit sphere + + outputNormal.xy *= lerp( fOne.xx, -fOne.xx, xySigns ); // Restore x and y signs + outputNormal.z *= lerp( fOne.x, -fOne.x, ztSigns.x ); // Restore z sign +} + + +void DecompressVertex_Normal( float4 inputNormal, out float3 outputNormal ) +{ + if ( COMPRESSED_VERTS == 1 ) + { + if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 ) + { + _DecompressShort2Normal( inputNormal.xy, outputNormal ); + } + else // ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) + { + _DecompressUByte4Normal( inputNormal, outputNormal ); + } + } + else + { + outputNormal = inputNormal.xyz; + } +} + +void DecompressVertex_NormalTangent( float4 inputNormal, float4 inputTangent, out float3 outputNormal, out float4 outputTangent ) +{ + if ( COMPRESSED_VERTS == 1 ) + { + if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 ) + { + _DecompressShort2NormalTangent( inputNormal.xy, inputTangent.xy, outputNormal, outputTangent ); + } + else // ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) + { + _DecompressUByte4NormalTangent( inputNormal, outputNormal, outputTangent ); + } + } + else + { + outputNormal = inputNormal.xyz; + outputTangent = inputTangent; + } +} + + +#ifdef SHADER_MODEL_VS_3_0 + +//----------------------------------------------------------------------------- +// Methods to sample morph data from a vertex texture +// NOTE: vMorphTargetTextureDim.x = width, cVertexTextureDim.y = height, cVertexTextureDim.z = # of float4 fields per vertex +// For position + normal morph for example, there will be 2 fields. +//----------------------------------------------------------------------------- +float4 SampleMorphDelta( sampler2D vt, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, const float flVertexID, const float flField ) +{ + float flColumn = floor( flVertexID / vMorphSubrect.w ); + + float4 t; + t.x = vMorphSubrect.x + vMorphTargetTextureDim.z * flColumn + flField + 0.5f; + t.y = vMorphSubrect.y + flVertexID - flColumn * vMorphSubrect.w + 0.5f; + t.xy /= vMorphTargetTextureDim.xy; + t.z = t.w = 0.f; + + return tex2Dlod( vt, t ); +} + +// Optimized version which reads 2 deltas +void SampleMorphDelta2( sampler2D vt, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, const float flVertexID, out float4 delta1, out float4 delta2 ) +{ + float flColumn = floor( flVertexID / vMorphSubrect.w ); + + float4 t; + t.x = vMorphSubrect.x + vMorphTargetTextureDim.z * flColumn + 0.5f; + t.y = vMorphSubrect.y + flVertexID - flColumn * vMorphSubrect.w + 0.5f; + t.xy /= vMorphTargetTextureDim.xy; + t.z = t.w = 0.f; + + delta1 = tex2Dlod( vt, t ); + t.x += 1.0f / vMorphTargetTextureDim.x; + delta2 = tex2Dlod( vt, t ); +} + +#endif // SHADER_MODEL_VS_3_0 + +//----------------------------------------------------------------------------- +// Method to apply morphs +//----------------------------------------------------------------------------- +bool ApplyMorph( float3 vPosFlex, in float3 vPosition, out float3 vPosition_O ) +{ + // Flexes coming in from a separate stream + float3 vPosDelta = vPosFlex.xyz * cFlexScale.x; + vPosition_O.xyz = vPosition + vPosDelta; + return true; +} + +bool ApplyMorph( float3 vPosFlex, float3 vNormalFlex, + in float3 vPosition, out float3 vPosition_O, + in float3 vNormal, out float3 vNormal_O ) +{ + // Flexes coming in from a separate stream + float3 vPosDelta = vPosFlex.xyz * cFlexScale.x; + float3 vNormalDelta = vNormalFlex.xyz * cFlexScale.x; + vPosition_O.xyz = vPosition + vPosDelta; + vNormal_O.xyz = vNormal + vNormalDelta; + return true; +} + +bool ApplyMorph( float3 vPosFlex, float3 vNormalFlex, + in float3 vPosition, out float3 vPosition_O, + in float3 vNormal, out float3 vNormal_O, + in float3 vTangent, out float3 vTangent_O ) +{ + // Flexes coming in from a separate stream + float3 vPosDelta = vPosFlex.xyz * cFlexScale.x; + float3 vNormalDelta = vNormalFlex.xyz * cFlexScale.x; + vPosition_O.xyz = vPosition + vPosDelta; + vNormal_O.xyz = vNormal + vNormalDelta; + vTangent_O.xyz = vTangent + vNormalDelta; + return true; +} + +bool ApplyMorph( float4 vPosFlex, float3 vNormalFlex, + inout float3 vPosition, inout float3 vNormal, inout float3 vTangent, out float flWrinkle ) +{ + // Flexes coming in from a separate stream + float3 vPosDelta = vPosFlex.xyz * cFlexScale.x; + float3 vNormalDelta = vNormalFlex.xyz * cFlexScale.x; + flWrinkle = vPosFlex.w * cFlexScale.y; + vPosition.xyz += vPosDelta; + vNormal += vNormalDelta; + vTangent.xyz += vNormalDelta; + return true; +} + +#ifdef SHADER_MODEL_VS_3_0 + +bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, + const float flVertexID, const float3 vMorphTexCoord, + in float3 vPosition, out float3 vPosition_O ) +{ +#if MORPHING + +#if 1 + // Flexes coming in from a separate stream + float4 vPosDelta = SampleMorphDelta( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, 0 ); + vPosition_O = vPosition + vPosDelta.xyz; +#else + float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); + float3 vPosDelta = tex2Dlod( morphSampler, t ); + vPosition += vPosDelta.xyz * vMorphTexCoord.z; +#endif // DECAL + + return true; + +#else // !MORPHING + vPosition_O = vPosition; + return false; +#endif +} + +bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, + const float flVertexID, const float3 vMorphTexCoord, + in float3 vPosition, out float3 vPosition_O, + in float3 vNormal, out float3 vNormal_O ) +{ +#if MORPHING + +#if 1 + float4 vPosDelta, vNormalDelta; + SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); + vPosition_O = vPosition + vPosDelta.xyz; + vNormal_O = vNormal + vNormalDelta.xyz; +#else + float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); + float3 vPosDelta = tex2Dlod( morphSampler, t ); + t.x += 1.0f / vMorphTargetTextureDim.x; + float3 vNormalDelta = tex2Dlod( morphSampler, t ); + vPosition += vPosDelta.xyz * vMorphTexCoord.z; + vNormal += vNormalDelta.xyz * vMorphTexCoord.z; +#endif // DECAL + + return true; + +#else // !MORPHING + vPosition_O = vPosition; + vNormal_O = vNormal; + return false; +#endif +} + +bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, + const float flVertexID, const float3 vMorphTexCoord, + in float3 vPosition, out float3 vPosition_O, + in float3 vNormal, out float3 vNormal_O, + in float3 vTangent, out float3 vTangent_O ) +{ +#if MORPHING + +#if 1 + float4 vPosDelta, vNormalDelta; + SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); + vPosition_O = vPosition + vPosDelta.xyz; + vNormal_O = vNormal + vNormalDelta.xyz; + vTangent_O = vTangent + vNormalDelta.xyz; +#else + float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); + float3 vPosDelta = tex2Dlod( morphSampler, t ); + t.x += 1.0f / vMorphTargetTextureDim.x; + float3 vNormalDelta = tex2Dlod( morphSampler, t ); + vPosition += vPosDelta.xyz * vMorphTexCoord.z; + vNormal += vNormalDelta.xyz * vMorphTexCoord.z; + vTangent += vNormalDelta.xyz * vMorphTexCoord.z; +#endif // DECAL + + return true; + +#else // MORPHING + vPosition_O = vPosition; + vNormal_O = vNormal; + vTangent_O = vTangent; + return false; +#endif +} + +bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, + const float flVertexID, const float3 vMorphTexCoord, + inout float3 vPosition, inout float3 vNormal, inout float3 vTangent, out float flWrinkle ) +{ +#if MORPHING + +#if !DECAL + float4 vPosDelta, vNormalDelta; + SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta ); + vPosition += vPosDelta.xyz; + vNormal += vNormalDelta.xyz; + vTangent += vNormalDelta.xyz; + flWrinkle = vPosDelta.w; +#else + float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f ); + float4 vPosDelta = tex2Dlod( morphSampler, t ); + t.x += 1.0f / vMorphTargetTextureDim.x; + float3 vNormalDelta = tex2Dlod( morphSampler, t ); + + vPosition += vPosDelta.xyz * vMorphTexCoord.z; + vNormal += vNormalDelta.xyz * vMorphTexCoord.z; + vTangent += vNormalDelta.xyz * vMorphTexCoord.z; + flWrinkle = vPosDelta.w * vMorphTexCoord.z; +#endif // DECAL + + return true; + +#else // MORPHING + + flWrinkle = 0.0f; + return false; + +#endif +} + +#endif // SHADER_MODEL_VS_3_0 + + +float RangeFog( const float3 projPos ) +{ + return max( cFogMaxDensity, ( -projPos.z * cOOFogRange + cFogEndOverFogRange ) ); +} + +float WaterFog( const float3 worldPos, const float3 projPos ) +{ + float4 tmp; + + tmp.xy = cEyePosWaterZ.wz - worldPos.z; + + // tmp.x is the distance from the water surface to the vert + // tmp.y is the distance from the eye position to the vert + + // if $tmp.x < 0, then set it to 0 + // This is the equivalent of moving the vert to the water surface if it's above the water surface + + tmp.x = max( 0.0f, tmp.x ); + + // $tmp.w = $tmp.x / $tmp.y + tmp.w = tmp.x / tmp.y; + + tmp.w *= projPos.z; + + // $tmp.w is now the distance that we see through water. + + return max( cFogMaxDensity, ( -tmp.w * cOOFogRange + cFogOne ) ); +} + +float CalcFog( const float3 worldPos, const float3 projPos, const int fogType ) +{ +#if defined( _X360 ) + // 360 only does pixel fog + return 1.0f; +#endif + + if( fogType == FOGTYPE_RANGE ) + { + return RangeFog( projPos ); + } + else + { +#if SHADERMODEL_VS_2_0 == 1 + // We do this work in the pixel shader in dx9, so don't do any fog here. + return 1.0f; +#else + return WaterFog( worldPos, projPos ); +#endif + } +} + +float CalcFog( const float3 worldPos, const float3 projPos, const bool bWaterFog ) +{ +#if defined( _X360 ) + // 360 only does pixel fog + return 1.0f; +#endif + + float flFog; + if( !bWaterFog ) + { + flFog = RangeFog( projPos ); + } + else + { +#if SHADERMODEL_VS_2_0 == 1 + // We do this work in the pixel shader in dx9, so don't do any fog here. + flFog = 1.0f; +#else + flFog = WaterFog( worldPos, projPos ); +#endif + } + + return flFog; +} + +float4 DecompressBoneWeights( const float4 weights ) +{ + float4 result = weights; + + if ( COMPRESSED_VERTS ) + { + // Decompress from SHORT2 to float. In our case, [-1, +32767] -> [0, +1] + // NOTE: we add 1 here so we can divide by 32768 - which is exact (divide by 32767 is not). + // This avoids cracking between meshes with different numbers of bone weights. + // We use SHORT2 instead of SHORT2N for a similar reason - the GPU's conversion + // from [-32768,+32767] to [-1,+1] is imprecise in the same way. + result += 1; + result /= 32768; + } + + return result; +} + +void SkinPosition( bool bSkinning, const float4 modelPos, + const float4 boneWeights, float4 fBoneIndices, + out float3 worldPos ) +{ +#if !defined( _X360 ) + int3 boneIndices = D3DCOLORtoUBYTE4( fBoneIndices ); +#else + int3 boneIndices = fBoneIndices; +#endif + + // Needed for invariance issues caused by multipass rendering +#if defined( _X360 ) + [isolate] +#endif + { + if ( !bSkinning ) + { + worldPos = mul4x3( modelPos, cModel[0] ); + } + else // skinning - always three bones + { + float4x3 mat1 = cModel[boneIndices[0]]; + float4x3 mat2 = cModel[boneIndices[1]]; + float4x3 mat3 = cModel[boneIndices[2]]; + + float3 weights = DecompressBoneWeights( boneWeights ).xyz; + weights[2] = 1 - (weights[0] + weights[1]); + + float4x3 blendMatrix = mat1 * weights[0] + mat2 * weights[1] + mat3 * weights[2]; + worldPos = mul4x3( modelPos, blendMatrix ); + } + } +} + +void SkinPositionAndNormal( bool bSkinning, const float4 modelPos, const float3 modelNormal, + const float4 boneWeights, float4 fBoneIndices, + out float3 worldPos, out float3 worldNormal ) +{ + // Needed for invariance issues caused by multipass rendering +#if defined( _X360 ) + [isolate] +#endif + { + +#if !defined( _X360 ) + int3 boneIndices = D3DCOLORtoUBYTE4( fBoneIndices ); +#else + int3 boneIndices = fBoneIndices; +#endif + + if ( !bSkinning ) + { + worldPos = mul4x3( modelPos, cModel[0] ); + worldNormal = mul3x3( modelNormal, ( const float3x3 )cModel[0] ); + } + else // skinning - always three bones + { + float4x3 mat1 = cModel[boneIndices[0]]; + float4x3 mat2 = cModel[boneIndices[1]]; + float4x3 mat3 = cModel[boneIndices[2]]; + + float3 weights = DecompressBoneWeights( boneWeights ).xyz; + weights[2] = 1 - (weights[0] + weights[1]); + + float4x3 blendMatrix = mat1 * weights[0] + mat2 * weights[1] + mat3 * weights[2]; + worldPos = mul4x3( modelPos, blendMatrix ); + worldNormal = mul3x3( modelNormal, ( float3x3 )blendMatrix ); + } + + } // end [isolate] +} + +// Is it worth keeping SkinPosition and SkinPositionAndNormal around since the optimizer +// gets rid of anything that isn't used? +void SkinPositionNormalAndTangentSpace( + bool bSkinning, + const float4 modelPos, const float3 modelNormal, + const float4 modelTangentS, + const float4 boneWeights, float4 fBoneIndices, + out float3 worldPos, out float3 worldNormal, + out float3 worldTangentS, out float3 worldTangentT ) +{ +#if !defined( _X360 ) + int3 boneIndices = D3DCOLORtoUBYTE4( fBoneIndices ); +#else + int3 boneIndices = fBoneIndices; +#endif + + // Needed for invariance issues caused by multipass rendering +#if defined( _X360 ) + [isolate] +#endif + { + if ( !bSkinning ) + { + worldPos = mul4x3( modelPos, cModel[0] ); + worldNormal = mul3x3( modelNormal, ( const float3x3 )cModel[0] ); + worldTangentS = mul3x3( ( float3 )modelTangentS, ( const float3x3 )cModel[0] ); + } + else // skinning - always three bones + { + float4x3 mat1 = cModel[boneIndices[0]]; + float4x3 mat2 = cModel[boneIndices[1]]; + float4x3 mat3 = cModel[boneIndices[2]]; + + float3 weights = DecompressBoneWeights( boneWeights ).xyz; + weights[2] = 1 - (weights[0] + weights[1]); + + float4x3 blendMatrix = mat1 * weights[0] + mat2 * weights[1] + mat3 * weights[2]; + worldPos = mul4x3( modelPos, blendMatrix ); + worldNormal = mul3x3( modelNormal, ( const float3x3 )blendMatrix ); + worldTangentS = mul3x3( ( float3 )modelTangentS, ( const float3x3 )blendMatrix ); + } + worldTangentT = cross( worldNormal, worldTangentS ) * -modelTangentS.w; + } +} + + +//----------------------------------------------------------------------------- +// Lighting helper functions +//----------------------------------------------------------------------------- + +float3 AmbientLight( const float3 worldNormal ) +{ + float3 nSquared = worldNormal * worldNormal; + int3 isNegative = ( worldNormal < 0.0 ); + float3 linearColor; + linearColor = nSquared.x * cAmbientCubeX[isNegative.x] + + nSquared.y * cAmbientCubeY[isNegative.y] + + nSquared.z * cAmbientCubeZ[isNegative.z]; + return linearColor; +} + +// The following "internal" routines are called "privately" by other routines in this file which +// handle the particular flavor of vs20 control flow appropriate to the original caller +float VertexAttenInternal( const float3 worldPos, int lightNum ) +{ + float result = 0.0f; + + // Get light direction + float3 lightDir = cLightInfo[lightNum].pos - worldPos; + + // Get light distance squared. + float lightDistSquared = dot( lightDir, lightDir ); + + // Get 1/lightDistance + float ooLightDist = rsqrt( lightDistSquared ); + + // Normalize light direction + lightDir *= ooLightDist; + + float3 vDist; +# if defined( _X360 ) + { + //X360 dynamic compile hits an internal compiler error using dst(), this is the breakdown of how dst() works from the 360 docs. + vDist.x = 1; + vDist.y = lightDistSquared * ooLightDist; + vDist.z = lightDistSquared; + //flDist.w = ooLightDist; + } +# else + { + vDist = dst( lightDistSquared, ooLightDist ); + } +# endif + + float flDistanceAtten = 1.0f / dot( cLightInfo[lightNum].atten.xyz, vDist ); + + // Spot attenuation + float flCosTheta = dot( cLightInfo[lightNum].dir.xyz, -lightDir ); + float flSpotAtten = (flCosTheta - cLightInfo[lightNum].spotParams.z) * cLightInfo[lightNum].spotParams.w; + flSpotAtten = max( 0.0001f, flSpotAtten ); + flSpotAtten = pow( flSpotAtten, cLightInfo[lightNum].spotParams.x ); + flSpotAtten = saturate( flSpotAtten ); + + // Select between point and spot + float flAtten = lerp( flDistanceAtten, flDistanceAtten * flSpotAtten, cLightInfo[lightNum].dir.w ); + + // Select between above and directional (no attenuation) + result = lerp( flAtten, 1.0f, cLightInfo[lightNum].color.w ); + + return result; +} + +float CosineTermInternal( const float3 worldPos, const float3 worldNormal, int lightNum, bool bHalfLambert ) +{ + // Calculate light direction assuming this is a point or spot + float3 lightDir = normalize( cLightInfo[lightNum].pos - worldPos ); + + // Select the above direction or the one in the structure, based upon light type + lightDir = lerp( lightDir, -cLightInfo[lightNum].dir, cLightInfo[lightNum].color.w ); + + // compute N dot L + float NDotL = dot( worldNormal, lightDir ); + + if ( !bHalfLambert ) + { + NDotL = max( 0.0f, NDotL ); + } + else // Half-Lambert + { + NDotL = NDotL * 0.5 + 0.5; + NDotL = NDotL * NDotL; + } + return NDotL; +} + +// This routine uses booleans to do early-outs and is meant to be called by routines OUTSIDE of this file +float GetVertexAttenForLight( const float3 worldPos, int lightNum ) +{ + float result = 0.0f; + if ( g_bLightEnabled[lightNum] ) + { + result = VertexAttenInternal( worldPos, lightNum ); + } + + return result; +} + +// This routine uses booleans to do early-outs and is meant to be called by routines OUTSIDE of this file +float CosineTerm( const float3 worldPos, const float3 worldNormal, int lightNum, bool bHalfLambert ) +{ + float flResult = 0.0f; + if ( g_bLightEnabled[lightNum] ) + { + flResult = CosineTermInternal( worldPos, worldNormal, lightNum, bHalfLambert ); + } + + return flResult; +} + +float3 DoLightInternal( const float3 worldPos, const float3 worldNormal, int lightNum, bool bHalfLambert ) +{ + return cLightInfo[lightNum].color * + CosineTermInternal( worldPos, worldNormal, lightNum, bHalfLambert ) * + VertexAttenInternal( worldPos, lightNum ); +} + +// This routine +float3 DoLighting( const float3 worldPos, const float3 worldNormal, + const float3 staticLightingColor, const bool bStaticLight, + const bool bDynamicLight, bool bHalfLambert ) +{ + float3 linearColor = float3( 0.0f, 0.0f, 0.0f ); + + if( bStaticLight ) // Static light + { + float3 col = staticLightingColor * cOverbright; +#if defined ( _X360 ) + linearColor += col * col; +#else + linearColor += GammaToLinear( col ); +#endif + } + + if( bDynamicLight ) // Dynamic light + { + for (int i = 0; i < g_nLightCount; i++) + { + linearColor += DoLightInternal( worldPos, worldNormal, i, bHalfLambert ); + } + } + + if( bDynamicLight ) + { + linearColor += AmbientLight( worldNormal ); //ambient light is already remapped + } + + return linearColor; +} + +float3 DoLightingUnrolled( const float3 worldPos, const float3 worldNormal, + const float3 staticLightingColor, const bool bStaticLight, + const bool bDynamicLight, bool bHalfLambert, const int nNumLights ) +{ + float3 linearColor = float3( 0.0f, 0.0f, 0.0f ); + + if( bStaticLight ) // Static light + { + linearColor += GammaToLinear( staticLightingColor * cOverbright ); + } + + if( bDynamicLight ) // Ambient light + { + if ( nNumLights >= 1 ) + linearColor += DoLightInternal( worldPos, worldNormal, 0, bHalfLambert ); + if ( nNumLights >= 2 ) + linearColor += DoLightInternal( worldPos, worldNormal, 1, bHalfLambert ); + if ( nNumLights >= 3 ) + linearColor += DoLightInternal( worldPos, worldNormal, 2, bHalfLambert ); + if ( nNumLights >= 4 ) + linearColor += DoLightInternal( worldPos, worldNormal, 3, bHalfLambert ); + } + + if( bDynamicLight ) + { + linearColor += AmbientLight( worldNormal ); //ambient light is already remapped + } + + return linearColor; +} + +int4 FloatToInt( in float4 floats ) +{ + return D3DCOLORtoUBYTE4( floats.zyxw / 255.001953125 ); +} + +float2 ComputeSphereMapTexCoords( in float3 reflectionVector ) +{ + // transform reflection vector into view space + reflectionVector = mul( reflectionVector, ( float3x3 )cViewModel ); + + // generate + float3 tmp = float3( reflectionVector.x, reflectionVector.y, reflectionVector.z + 1.0f ); + + // find 1 / len + float ooLen = dot( tmp, tmp ); + ooLen = 1.0f / sqrt( ooLen ); + + // tmp = tmp/|tmp| + 1 + tmp.xy = ooLen * tmp.xy + 1.0f; + + return tmp.xy * 0.5f; +} + + +#define DEFORMATION_CLAMP_TO_BOX_IN_WORLDSPACE 1 + // minxyz.minsoftness / maxxyz.maxsoftness +float3 ApplyDeformation( float3 worldpos, int deftype, float4 defparms0, float4 defparms1, + float4 defparms2, float4 defparms3 ) +{ + float3 ret = worldpos; + if ( deftype == DEFORMATION_CLAMP_TO_BOX_IN_WORLDSPACE ) + { + ret=max( ret, defparms2.xyz ); + ret=min( ret, defparms3.xyz ); + } + + return ret; +} + + +#endif //#ifndef COMMON_VS_FXC_H_ diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/cpp_shader_constant_register_map.h b/sp/src/materialsystem/stdshaders/ShaderEdit/cpp_shader_constant_register_map.h new file mode 100644 index 00000000..62c9acd1 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/cpp_shader_constant_register_map.h @@ -0,0 +1,45 @@ +//========= Copyright © 1996-2006, Valve LLC, All rights reserved. ============ +// +// Purpose: Provide convenient mapping for shader constants +// +// $NoKeywords: $ +//============================================================================= + +#define C_CODE_HACK +#include "shader_constant_register_map.h" +#undef C_CODE_HACK + +// For the C code, map the above file's defines back to integers... +#define PSREG_CONSTANT_00 0 +#define PSREG_CONSTANT_01 1 +#define PSREG_CONSTANT_02 2 +#define PSREG_CONSTANT_03 3 +#define PSREG_CONSTANT_04 4 +#define PSREG_CONSTANT_05 5 +#define PSREG_CONSTANT_06 6 +#define PSREG_CONSTANT_07 7 +#define PSREG_CONSTANT_08 8 +#define PSREG_CONSTANT_09 9 +#define PSREG_CONSTANT_10 10 +#define PSREG_CONSTANT_11 11 +#define PSREG_CONSTANT_12 12 +#define PSREG_CONSTANT_13 13 +#define PSREG_CONSTANT_14 14 +#define PSREG_CONSTANT_15 15 +#define PSREG_CONSTANT_16 16 +#define PSREG_CONSTANT_17 17 +#define PSREG_CONSTANT_18 18 +#define PSREG_CONSTANT_19 19 +#define PSREG_CONSTANT_20 20 +#define PSREG_CONSTANT_21 21 +#define PSREG_CONSTANT_22 22 +#define PSREG_CONSTANT_23 23 +#define PSREG_CONSTANT_24 24 +#define PSREG_CONSTANT_25 25 +#define PSREG_CONSTANT_26 26 +#define PSREG_CONSTANT_27 27 +#define PSREG_CONSTANT_28 28 +#define PSREG_CONSTANT_29 29 +#define PSREG_CONSTANT_30 30 +#define PSREG_CONSTANT_31 31 + diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/detail_prop_shader_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/detail_prop_shader_ps30.fxc new file mode 100644 index 00000000..6d7cc5f5 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/detail_prop_shader_ps30.fxc @@ -0,0 +1,92 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + +// Combos +// STATIC: "FLASHLIGHT" "0..1" +// DYNAMIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); +sampler _gSampler_Flashlight_Cookie : register( s1 ); +sampler _gSampler_Flashlight_Depth : register( s2 ); +sampler _gSampler_Flashlight_Random : register( s3 ); + +// Constants +const float3 g_cData_grass_spec_color : register( c16 ); // Static +const float3 _g_VecForward : register( c17 ); +const float4 _g_FogParams : register( c18 ); +const float3 _g_VecOrig : register( c19 ); +const float4 g_cFlashlightAttenuationFactors : register( c8 ); +const float4 g_cFlashlightPos : register( c9 ); +const float4 g_cShadowTweaks : register( c7 ); + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; + float3 vTexCoord_1 : TEXCOORD1; + float4 vTexCoord_2 : TEXCOORD2; + float4 vTexCoord_3 : TEXCOORD3; + float3 vTexCoord_4 : TEXCOORD4; + float vColor_0 : COLOR0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float4 _texLookup_16 = tex2D( _Sampler_00, In.vTexCoord_0 ); + float3 _var0 = _texLookup_16.rgb; + float _var1 = _texLookup_16.a; + float3 _var2 = float3( 0.000000, 0.000000, 0.000000 ); + float3 _var3 = float3( 0.000000, 0.000000, 0.000000 ); + float3 _var4 = float( -1.000000 ) * _g_VecForward; + float _var5 = _g_VecOrig.z; + float _var6 = In.vTexCoord_4.z; + float _var7 = In.vTexCoord_3.z; +#if ( FLASHLIGHT == 0 ) + float _var8 = smoothstep( float( 0.290000 ), float( 0.300000 ), _var1 ); + _var3 = In.vTexCoord_1; + _var8 = In.vColor_0 * _var8; + float3 _var9 = _var8 * g_cData_grass_spec_color; + _var2 = _var9; +#endif +#if ( FLASHLIGHT == 1 ) + float2 _var10 = In.vTexCoord_3.xy; + float _var11 = In.vTexCoord_3.w; + _var10 = _var10 / _var11; + _var4 = DoFlashlight( g_cFlashlightPos.xyz, In.vTexCoord_4, In.vTexCoord_2, _var4, + g_cFlashlightAttenuationFactors.xyz, g_cFlashlightAttenuationFactors.w, + _gSampler_Flashlight_Cookie, _gSampler_Flashlight_Depth, _gSampler_Flashlight_Random, + FLASHLIGHTDEPTHFILTERMODE, FLASHLIGHTSHADOWS, true, + _var10, false, g_cShadowTweaks ); + _var3 = _var4; +#endif + _var0 = _var0 + _var2; + _var3 = _var3; + float _var12 = _var1 - float( 0.100000 ); + _var5 = CalcPixelFogFactor( PIXELFOGTYPE, _g_FogParams, _var5, _var6, _var7 ); + _var0 = _var0 * _var3; + clip( _var12 ); + float4 _var13 = float4( _var0, _var12 ); + _var13 = FinalOutput( _var13, _var5, PIXELFOGTYPE, TONEMAP_SCALE_GAMMA, true, _var7 ); + Out.vColor_0 = _var13; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/detail_prop_shader_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/detail_prop_shader_vs30.fxc new file mode 100644 index 00000000..165ce5fd --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/detail_prop_shader_vs30.fxc @@ -0,0 +1,136 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + +// Combos +// STATIC: "FLASHLIGHT" "0..1" + +// Includes +#include "common_vs_fxc.h" + + +// Constants +const float3 g_cData_Mutable_01 : register( c48 ); // Mutable +const float g_cData_Mutable_02 : register( c49 ); // Mutable +const float _g_Time : register( c50 ); +const float4x4 g_cFlashlightWorldToTexture : register( c51 ); + +// User code - globals +float3 triangle( float3 a ) +{ + return abs( frac( a + 0.5f ) * 2.0f - 1.0f ); +} + +// User code - function bodies +void UserFunction_195( in float3 var_00, out float3 var_01 ) +{ + var_01 = triangle( var_00 ); + + var_01 = ( 3.0 - 2.000000000001 * var_01 ) * var_01 * var_01; +} + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float3 vNormal : NORMAL; + float2 vTexCoord_0 : TEXCOORD0; + float3 vTexCoord_1 : TEXCOORD1; + float3 vTexCoord_2 : TEXCOORD2; + float4 vColor_0 : COLOR0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; + float3 vTexCoord_1 : TEXCOORD1; + float4 vTexCoord_2 : TEXCOORD2; + float4 vTexCoord_3 : TEXCOORD3; + float3 vTexCoord_4 : TEXCOORD4; + float vColor_0 : COLOR0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float _var0 = dot( In.vTexCoord_2, In.vNormal ); + float _var1 = In.vTexCoord_1.z; + float3 _var2 = In.vNormal * float( -0.900000 ); + float _var3 = dot( In.vNormal, g_cData_Mutable_01 ); + float _var4 = In.vTexCoord_1.y; + float _var5 = In.vTexCoord_1.x; + float _var6 = cos( g_cData_Mutable_02 ); + float _var7 = In.vPos.x; + float _var8 = sin( g_cData_Mutable_02 ); + float _var9 = In.vPos.y; + float _var10 = In.vPos.z; + float _var11 = _g_Time * float( 0.700000 ); + float3 _var12 = In.vColor_0.xyz; + float4 _var13 = float4( 0.000000, 0.000000, 0.000000, 0.000000 ); + float3 _var14 = _var0 * In.vNormal; + _var2 = _var1 * _var2; + float3 _var15 = _var3 * In.vNormal; + float _var16 = 1.0f - _var4; + float _var17 = _var6 * _var7; + float _var18 = _var8 * _var9; + float _var19 = _var9 * _var6; + float _var20 = _var8 * _var7; + float _var21 = _var4 * float( 0.400000 ); + _var14 = In.vTexCoord_2 - _var14; + _var15 = g_cData_Mutable_01 - _var15; + float _var22 = _var16 * _var5; + _var17 = _var17 - _var18; + _var19 = _var19 + _var20; + _var12 = _var21 + _var12; + float _var23 = _var5 * _var16; + _var14 = _var14 * _var1; + _var15 = normalize( _var15 ); + float2 _var24 = float2( _var17, _var19 ); + _var14 = _var14 + _var2; + _var15 = _var15 * float( 2.000000 ); + float3 _var25 = float3( _var24, _var10 ); + _var15 = _var15 * _var22; + _var25 = _var25 * float( 0.005000 ); + _var25 = _var25 + _var11; + float3 _var26 = (float3)0; + UserFunction_195( _var25, _var26 ); + float3 _var27 = sin( _var25 ); + float3 _var28 = abs( _var26 ); + float3 _var29 = sign( _var26 ); + _var27 = abs( _var27 ); + _var28 = pow( _var28, float( 3.000000 ) ); + float _var30 = dot( _var27, float3( 0.333333, 0.333333, 0.333333 ) ); + _var29 = _var28 * _var29; + float3 _var31 = _var12 * _var30; + float _var32 = dot( _var28, float3( 0.333333, 0.333333, 0.333333 ) ); + float _var33 = pow( _var30, float( 2.000000 ) ); + _var15 = _var15 * _var29; + _var31 = lerp( _var12, _var31, float( 0.400000 ) ); + _var32 = _var32 * _var33; + _var15 = In.vPos + _var15; + _var23 = _var23 * _var32; + _var14 = _var14 + _var15; + float4 _var34 = mul( float4(_var14.xyz,1), cModelViewProj ); + float4 _var35 = _var34; +#if ( FLASHLIGHT == 1 ) + float4 _var36 = mul( float4(_var14.xyz,1), g_cFlashlightWorldToTexture ); + float2 _var37 = _var34.xy; + float _var38 = _var34.z; + float _var39 = _var34.w; + _var13 = _var36; + _var38 = _var38 - float( 0.100000 ); + float3 _var40 = float3( _var37, _var38 ); + float4 _var41 = float4( _var40, _var39 ); + _var35 = _var41; +#endif + Out.vProjPos = _var35; + Out.vTexCoord_0 = In.vTexCoord_0; + Out.vTexCoord_1 = _var31; + Out.vTexCoord_2 = _var13; + Out.vTexCoord_3 = _var35; + Out.vTexCoord_4 = _var14; + Out.vColor_0 = _var23; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/downsample_4_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/downsample_4_ps30.fxc new file mode 100644 index 00000000..df6d0b81 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/downsample_4_ps30.fxc @@ -0,0 +1,58 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); + +// Constants +const float2 _g_TexelSize : register( c16 ); + +// Arrays +static const float2 g_cArray_202[4] = +{ + float2( 0.000000f, 0.000000f ), + float2( 2.000000f, 0.000000f ), + float2( 0.000000f, 2.000000f ), + float2( 2.000000f, 2.000000f ), +}; + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float4 _var0 = float4( 0.000000, 0.000000, 0.000000, 0.000000 ); + float2 _var1 = _g_TexelSize * float( 0.500000 ); + _var1 = In.vTexCoord_0 + _var1; + for ( int _var2 = 0; _var2 < 4; _var2++ ) + { + float2 _var3 = _var1; + float2 _var4 = g_cArray_202[_var2] * _g_TexelSize; + _var3 = _var3 + _var4; + float4 _var5 = tex2D( _Sampler_00, _var3 ).rgba; + _var0 = _var0 + _var5; + } + _var0 = _var0 * float( 0.250000 ); + Out.vColor_0 = _var0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/downsample_4_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/downsample_4_vs30.fxc new file mode 100644 index 00000000..9c0734a8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/downsample_4_vs30.fxc @@ -0,0 +1,31 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + + +// Includes +#include "common_vs_fxc.h" + + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float4 _var0 = float4( In.vPos.x, In.vPos.y, In.vPos.z, 1.000000 ); + Out.vProjPos = _var0; + Out.vTexCoord_0 = In.vTexCoord_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/filelist.txt b/sp/src/materialsystem/stdshaders/ShaderEdit/filelist.txt new file mode 100644 index 00000000..ccb731f2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/filelist.txt @@ -0,0 +1,68 @@ +*** generated by shadereditor.dll *** +#BEGIN 000000_lightmap_parallax_pos_preview_vs30 +000000_lightmap_parallax_pos_preview_vs30.fxc +#DEFINES-D: +#DEFINES-S: +#SKIP: +(defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED)||(defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA)||(defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0)||(defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT)||(defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST)||(defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH)||(($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW)||0 +#COMMAND: +fxc.exe /DTOTALSHADERCOMBOS=1 /DCENTROIDMASK=0 /DNUMDYNAMICCOMBOS=1 /DFLAGS=0x0 /Dmain=main /Emain /Tvs_3_0 /DSHADER_MODEL_VS_3_0=1 /nologo /Foshader.o 000000_lightmap_parallax_pos_preview_vs30.fxc>output.txt 2>&1 +#END +************************************* +*** generated by shadereditor.dll *** +#BEGIN 000000_lightmap_parallax_pos_preview_vs30 +000000_lightmap_parallax_pos_preview_vs30.fxc +#DEFINES-D: +#DEFINES-S: +#SKIP: +(defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED)||(defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA)||(defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0)||(defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT)||(defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST)||(defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH)||(($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW)||0 +#COMMAND: +fxc.exe /DTOTALSHADERCOMBOS=1 /DCENTROIDMASK=0 /DNUMDYNAMICCOMBOS=1 /DFLAGS=0x0 /Dmain=main /Emain /Tvs_3_0 /DSHADER_MODEL_VS_3_0=1 /nologo /Foshader.o 000000_lightmap_parallax_pos_preview_vs30.fxc>output.txt 2>&1 +#END +************************************* + +*** generated by shadereditor.dll *** +#BEGIN 000000_lightmap_parallax_preview_vs30 +000000_lightmap_parallax_preview_vs30.fxc +#DEFINES-D: +#DEFINES-S: +#SKIP: +(defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED)||(defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA)||(defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0)||(defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT)||(defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST)||(defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH)||(($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW)||0 +#COMMAND: +fxc.exe /DTOTALSHADERCOMBOS=1 /DCENTROIDMASK=0 /DNUMDYNAMICCOMBOS=1 /DFLAGS=0x0 /Dmain=main /Emain /Tvs_3_0 /DSHADER_MODEL_VS_3_0=1 /nologo /Foshader.o 000000_lightmap_parallax_preview_vs30.fxc>output.txt 2>&1 +#END +************************************* +*** generated by shadereditor.dll *** +#BEGIN 000000_lightmap_parallax_preview_vs30 +000000_lightmap_parallax_preview_vs30.fxc +#DEFINES-D: +#DEFINES-S: +#SKIP: +(defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED)||(defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA)||(defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0)||(defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT)||(defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST)||(defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH)||(($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW)||0 +#COMMAND: +fxc.exe /DTOTALSHADERCOMBOS=1 /DCENTROIDMASK=0 /DNUMDYNAMICCOMBOS=1 /DFLAGS=0x0 /Dmain=main /Emain /Tvs_3_0 /DSHADER_MODEL_VS_3_0=1 /nologo /Foshader.o 000000_lightmap_parallax_preview_vs30.fxc>output.txt 2>&1 +#END +************************************* + +*** generated by shadereditor.dll *** +#BEGIN 000000_lightmap_parallax_preview_ps30 +000000_lightmap_parallax_preview_ps30.fxc +#DEFINES-D: +#DEFINES-S: +#SKIP: +(defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED)||(defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA)||(defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0)||(defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT)||(defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST)||(defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH)||(($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW)||0 +#COMMAND: +fxc.exe /DTOTALSHADERCOMBOS=48 /DCENTROIDMASK=0 /DNUMDYNAMICCOMBOS=1 /DFLAGS=0x0 /Dmain=main /Emain /Tps_3_0 /DSHADER_MODEL_PS_3_0=1 /nologo /Foshader.o 000000_lightmap_parallax_preview_ps30.fxc>output.txt 2>&1 +#END +************************************* +*** generated by shadereditor.dll *** +#BEGIN 000000_lightmap_parallax_preview_ps30 +000000_lightmap_parallax_preview_ps30.fxc +#DEFINES-D: +#DEFINES-S: +#SKIP: +(defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED)||(defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA)||(defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0)||(defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT)||(defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST)||(defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH)||(($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW)||0 +#COMMAND: +fxc.exe /DTOTALSHADERCOMBOS=48 /DCENTROIDMASK=0 /DNUMDYNAMICCOMBOS=1 /DFLAGS=0x0 /Dmain=main /Emain /Tps_3_0 /DSHADER_MODEL_PS_3_0=1 /nologo /Foshader.o 000000_lightmap_parallax_preview_ps30.fxc>output.txt 2>&1 +#END +************************************* diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_5_x_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_5_x_ps30.fxc new file mode 100644 index 00000000..cf9fe1d4 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_5_x_ps30.fxc @@ -0,0 +1,58 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); + +// Constants +const float2 _g_TexelSize : register( c16 ); + +// Arrays +static const float g_cArray_231[5] = +{ + float( 0.054489f ), + float( 0.244201f ), + float( 0.402620f ), + float( 0.244201f ), + float( 0.054489f ), +}; + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float4 _var0 = float4( 0.000000, 0.000000, 0.000000, 0.000000 ); + float2 _var1 = float2( 3.000000, 0.000000 ) * _g_TexelSize; + float2 _var2 = float2( 1.000000, 0.000000 ) * _g_TexelSize; + _var1 = In.vTexCoord_0 - _var1; + for ( int _var3 = 0; _var3 < 5; _var3++ ) + { + _var1 = _var1 + _var2; + float4 _var4 = tex2D( _Sampler_00, _var1 ).rgba; + _var4 = _var4 * g_cArray_231[_var3]; + _var0 = _var0 + _var4; + } + Out.vColor_0 = _var0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_5_x_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_5_x_vs30.fxc new file mode 100644 index 00000000..9c0734a8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_5_x_vs30.fxc @@ -0,0 +1,31 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + + +// Includes +#include "common_vs_fxc.h" + + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float4 _var0 = float4( In.vPos.x, In.vPos.y, In.vPos.z, 1.000000 ); + Out.vProjPos = _var0; + Out.vTexCoord_0 = In.vTexCoord_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_5_y_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_5_y_ps30.fxc new file mode 100644 index 00000000..d5f98cef --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_5_y_ps30.fxc @@ -0,0 +1,58 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); + +// Constants +const float2 _g_TexelSize : register( c16 ); + +// Arrays +static const float g_cArray_253[5] = +{ + float( 0.054489f ), + float( 0.244201f ), + float( 0.402620f ), + float( 0.244201f ), + float( 0.054489f ), +}; + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float4 _var0 = float4( 0.000000, 0.000000, 0.000000, 0.000000 ); + float2 _var1 = float2( 0.000000, 3.000000 ) * _g_TexelSize; + float2 _var2 = float2( 0.000000, 1.000000 ) * _g_TexelSize; + _var1 = In.vTexCoord_0 - _var1; + for ( int _var3 = 0; _var3 < 5; _var3++ ) + { + _var1 = _var1 + _var2; + float4 _var4 = tex2D( _Sampler_00, _var1 ).rgba; + _var4 = _var4 * g_cArray_253[_var3]; + _var0 = _var0 + _var4; + } + Out.vColor_0 = _var0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_5_y_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_5_y_vs30.fxc new file mode 100644 index 00000000..9c0734a8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_5_y_vs30.fxc @@ -0,0 +1,31 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + + +// Includes +#include "common_vs_fxc.h" + + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float4 _var0 = float4( In.vPos.x, In.vPos.y, In.vPos.z, 1.000000 ); + Out.vProjPos = _var0; + Out.vTexCoord_0 = In.vTexCoord_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_7_half_aceil_x_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_7_half_aceil_x_ps30.fxc new file mode 100644 index 00000000..dd26fa72 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_7_half_aceil_x_ps30.fxc @@ -0,0 +1,71 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); + +// Constants +const float2 _g_TexelSize : register( c16 ); + +// Arrays +static const float g_cArray_274[7] = +{ + float( 0.167839f ), + float( 0.684901f ), + float( 1.592437f ), + float( 2.109639f ), + float( 1.592437f ), + float( 0.684901f ), + float( 0.167839f ), +}; + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float4 _var0 = float4( 0.000000, 0.000000, 0.000000, 0.000000 ); + float2 _var1 = float2( 4.000000, 0.000000 ) * _g_TexelSize; + float2 _var2 = float2( 1.000000, 0.000000 ) * _g_TexelSize; + float _var3 = float( 0.000000 ); + _var1 = In.vTexCoord_0 - _var1; + for ( int _var4 = 0; _var4 < 7; _var4++ ) + { + _var1 = _var1 + _var2; + float4 _texLookup_16 = tex2D( _Sampler_00, _var1 ); + float3 _var5 = _texLookup_16.rgb; + float _var6 = _texLookup_16.a; + _var6 = ceil( _var6 ); + float4 _var7 = float4( _var5, _var6 ); + _var3 = _var3 + _var6; + _var7 = _var7 * g_cArray_274[_var4]; + _var0 = _var0 + _var7; + } + float3 _var8 = _var0.xyz; + float _var9 = _var0.w; + _var8 = _var8 / _var3; + _var9 = _var9 / float( 7.000000 ); + float4 _var10 = float4( _var8, _var9 ); + Out.vColor_0 = _var10; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_7_half_aceil_x_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_7_half_aceil_x_vs30.fxc new file mode 100644 index 00000000..9c0734a8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_7_half_aceil_x_vs30.fxc @@ -0,0 +1,31 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + + +// Includes +#include "common_vs_fxc.h" + + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float4 _var0 = float4( In.vPos.x, In.vPos.y, In.vPos.z, 1.000000 ); + Out.vProjPos = _var0; + Out.vTexCoord_0 = In.vTexCoord_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_7_half_aceil_y_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_7_half_aceil_y_ps30.fxc new file mode 100644 index 00000000..37faf10f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_7_half_aceil_y_ps30.fxc @@ -0,0 +1,70 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); + +// Constants +const float2 _g_TexelSize : register( c16 ); + +// Arrays +static const float g_cArray_305[7] = +{ + float( 0.167839f ), + float( 0.684901f ), + float( 1.592437f ), + float( 2.109639f ), + float( 1.592437f ), + float( 0.684901f ), + float( 0.167839f ), +}; + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float4 _var0 = float4( 0.000000, 0.000000, 0.000000, 0.000000 ); + float2 _var1 = float2( 0.000000, 4.000000 ) * _g_TexelSize; + float2 _var2 = float2( 0.000000, 1.000000 ) * _g_TexelSize; + float _var3 = float( 0.000000 ); + _var1 = In.vTexCoord_0 - _var1; + for ( int _var4 = 0; _var4 < 7; _var4++ ) + { + _var1 = _var1 + _var2; + float4 _texLookup_16 = tex2D( _Sampler_00, _var1 ); + float4 _var5 = _texLookup_16.rgba; + float _var6 = _texLookup_16.a; + _var5 = _var5 * g_cArray_305[_var4]; + _var6 = ceil( _var6 ); + _var0 = _var0 + _var5; + _var3 = _var3 + _var6; + } + float3 _var7 = _var0.xyz; + float _var8 = _var0.w; + _var7 = _var7 / _var3; + _var8 = _var8 / float( 7.000000 ); + float4 _var9 = float4( _var7, _var8 ); + Out.vColor_0 = _var9; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_7_half_aceil_y_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_7_half_aceil_y_vs30.fxc new file mode 100644 index 00000000..9c0734a8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_7_half_aceil_y_vs30.fxc @@ -0,0 +1,31 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + + +// Includes +#include "common_vs_fxc.h" + + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float4 _var0 = float4( In.vPos.x, In.vPos.y, In.vPos.z, 1.000000 ); + Out.vProjPos = _var0; + Out.vTexCoord_0 = In.vTexCoord_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_half_3_x_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_half_3_x_ps30.fxc new file mode 100644 index 00000000..4ad623d0 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_half_3_x_ps30.fxc @@ -0,0 +1,56 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); + +// Constants +const float2 _g_TexelSize : register( c16 ); + +// Arrays +static const float g_cArray_332[3] = +{ + float( 0.196842f ), + float( 0.606316f ), + float( 0.196842f ), +}; + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float4 _var0 = float4( 0.000000, 0.000000, 0.000000, 0.000000 ); + float2 _var1 = float2( 2.000000, 0.000000 ) * _g_TexelSize; + float2 _var2 = float2( 1.000000, 0.000000 ) * _g_TexelSize; + _var1 = In.vTexCoord_0 - _var1; + for ( int _var3 = 0; _var3 < 3; _var3++ ) + { + _var1 = _var1 + _var2; + float4 _var4 = tex2D( _Sampler_00, _var1 ).rgba; + _var4 = _var4 * g_cArray_332[_var3]; + _var0 = _var0 + _var4; + } + Out.vColor_0 = _var0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_half_3_x_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_half_3_x_vs30.fxc new file mode 100644 index 00000000..9c0734a8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_half_3_x_vs30.fxc @@ -0,0 +1,31 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + + +// Includes +#include "common_vs_fxc.h" + + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float4 _var0 = float4( In.vPos.x, In.vPos.y, In.vPos.z, 1.000000 ); + Out.vProjPos = _var0; + Out.vTexCoord_0 = In.vTexCoord_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_half_3_y_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_half_3_y_ps30.fxc new file mode 100644 index 00000000..8536cb69 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_half_3_y_ps30.fxc @@ -0,0 +1,56 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); + +// Constants +const float2 _g_TexelSize : register( c16 ); + +// Arrays +static const float g_cArray_351[3] = +{ + float( 0.196842f ), + float( 0.606316f ), + float( 0.196842f ), +}; + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float4 _var0 = float4( 0.000000, 0.000000, 0.000000, 0.000000 ); + float2 _var1 = float2( 0.000000, 2.000000 ) * _g_TexelSize; + float2 _var2 = float2( 0.000000, 1.000000 ) * _g_TexelSize; + _var1 = In.vTexCoord_0 - _var1; + for ( int _var3 = 0; _var3 < 3; _var3++ ) + { + _var1 = _var1 + _var2; + float4 _var4 = tex2D( _Sampler_00, _var1 ).rgba; + _var4 = _var4 * g_cArray_351[_var3]; + _var0 = _var0 + _var4; + } + Out.vColor_0 = _var0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_half_3_y_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_half_3_y_vs30.fxc new file mode 100644 index 00000000..9c0734a8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/gauss_blur_half_3_y_vs30.fxc @@ -0,0 +1,31 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + + +// Includes +#include "common_vs_fxc.h" + + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float4 _var0 = float4( In.vPos.x, In.vPos.y, In.vPos.z, 1.000000 ); + Out.vProjPos = _var0; + Out.vTexCoord_0 = In.vTexCoord_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/intrinsic.h b/sp/src/materialsystem/stdshaders/ShaderEdit/intrinsic.h new file mode 100644 index 00000000..bb9ad306 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/intrinsic.h @@ -0,0 +1,260 @@ +// Absolute value (per component). +auto abs( multi x ); + +// Returns the arccosine of each component of x. +auto acos( multi x ); + +// Test if all components of x are nonzero. +auto all( multi x ); + +// Test if any component of x is nonzero. +auto any( multi x ); + +// Returns the arcsine of each component of x. +auto asin( multi x ); + +// Returns the arctangent of x. +auto atan( multi x ); + +// Returns the arctangent of of two values (x,y). +auto atan2( multi x, auto y ); + +// Returns the smallest integer which is greater than or equal to x. +auto ceil( multi x ); + +// Clamps x to the range [min, max]. +auto clamp( multi x, auto min, auto max ); + +// Discards the current pixel, if any component of x is less than zero. +auto clip( multi x ); + +// Returns the cosine of x. +auto cos( multi x ); + +// Returns the hyperbolic cosine of x. +auto cosh( multi x ); + +// Returns the cross product of two 3D vectors. +float3 cross( float3 x, float3 y ); + +// Swizzles and scales components of the 4D vector xto compensate for the lack of UBYTE4 support in some hardware. +int4 D3DCOLORtoUBYTE4( float4 x ); + +// Returns the partial derivative of x with respect to the screen-space x-coordinate. +auto ddx( multi x ); + +// Returns the partial derivative of x with respect to the screen-space y-coordinate. +auto ddy( multi x ); + +// Converts x from radians to degrees. +auto degrees( multi x ); + +// Returns the determinant of the square matrix m. +float determinant( matrix m ); + +// Returns the distance between two points. +float distance( vector x, vector y ); + +// Returns the dot product of two vectors. +float dot( vector x, vector y ); + +// Returns the base-e exponent. +auto exp( multi x ); + +// Base 2 exponent (per component). +auto exp2( multi x ); + +// Returns -n * sign(dot(i, ng)). +auto faceforward( vector n, auto i, auto ng ); + +// Returns the greatest integer which is less than or equal to x. +auto floor( multi x ); + +// Returns the floating point remainder of x/y. +auto fmod( multi x, auto y ); + +// Returns the fractional part of x. +auto frac( multi x ); + +// Returns the mantissa and exponent of x. +auto frexp( multi x, auto exp ); + +// Returns abs(ddx(x)) + abs(ddy(x)) +auto fwidth( multi x ); + +// Returns true if x is finite, false otherwise. +bool isfinite( multi x ); + +// Returns true if x is +INF or -INF, false otherwise. +bool isinf( multi x ); + +// Returns true if x is NAN or QNAN, false otherwise. +bool isnan( multi x ); + +// Returns x * 2exp +auto ldexp( multi x, auto exp ); + +// Returns the length of the vector v. +float length( vector x ); + +// Returns x + s(y - x). +auto lerp( multi x, auto y, auto s ); + +// Returns a lighting vector (ambient, diffuse, specular, 1) +float4 lit( float n_dot_l, float n_dot_h, float m ); + +// Returns the base-e logarithm of x. +auto log( multi x ); + +// Returns the base-10 logarithm of x. +auto log10( multi x ); + +// Returns the base-2 logarithm of x. +auto log2( multi x ); + +// Selects the greater of x and y. +auto max( multi x, auto y ); + +// Selects the lesser of x and y. +auto min( multi x, auto y ); + +// Splits the value x into fractional and integer parts. +auto modf( multi x, out auto ip ); + +// Performs matrix multiplication using x and y. +multi mul( multi x, multi y ); + +// Generates a random value using the Perlin-noise algorithm. +float noise( vector x ); + +// Returns a normalized vector. +auto normalize( vector x ); + +// Returns x^y +auto pow( multi x, auto y ); + +// Converts x from degrees to radians. +auto radians( multi x ); + +// Returns a reflection vector. +auto reflect( vector i, auto n ); + +// Returns the refraction vector. +auto refract( vector i, auto n, float index ); + +// Rounds x to the nearest integer. +auto round( multi x ); + +// Returns 1 / sqrt(x) +auto rsqrt( multi x ); + +// Clamps x to the range [0, 1] +auto saturate( multi x ); + +// Computes the sign of x. +auto sign( multi x ); + +// Returns the sine of x +auto sin( multi x ); + +// Returns the sine and cosine of x. +void sincos( multi x, out auto s, out auto c ); + +// Returns the hyperbolic sine of x +auto sinh( multi x ); + +// Returns a smooth Hermite interpolation between 0 and 1. +auto smoothstep( auto min, auto max, multi x ); + +// Square root (per component) +auto sqrt( multi x ); + +// Returns (x >= y) ? 1 : 0 +auto step( multi y, auto x ); + +// Returns the tangent of x +auto tan( multi x ); + +// Returns the hyperbolic tangent of x +auto tanh( multi x ); + +// Returns the transpose of the matrix m. +matrix transpose( matrix x ); + +// Truncates floating-point value(s) to integer value(s) +auto trunc( multi x ); + +// 1D texture lookup. +float4 tex1D( sampler s, float t ); + +// 1D texture lookup. +float4 tex1D( sampler s, float t, float ddx, float ddy ); + +// 1D texture lookup with bias. +float4 tex1Dbias( sampler s, float4 t ); + +// 1D texture lookup with a gradient. +float4 tex1Dgrad( sampler s, float t, float ddx, float ddy ); + +// 1D texture lookup with LOD. +float4 tex1Dlod( sampler s, float4 t ); + +// 1D texture lookup with projective divide. +float4 tex1Dproj( sampler s, float4 t ); + + +// 2D texture lookup. +float4 tex2D( sampler s, float2 t ); + +// 2D texture lookup. +float4 tex2D( sampler s, float2 t, float2 ddx, float2 ddy ); + +// 2D texture lookup with bias. +float4 tex2Dbias( sampler s, float4 t ); + +// 2D texture lookup with a gradient. +float4 tex2Dgrad( sampler s, float2 t, float2 ddx, float2 ddy ); + +// 2D texture lookup with LOD. +float4 tex2Dlod( sampler s, float4 t ); + +// 2D texture lookup with projective divide. +float4 tex2Dproj( sampler s, float4 t ); + + +// 3D texture lookup. +float4 tex3D( sampler s, float3 t ); + +// 3D texture lookup. +float4 tex3D( sampler s, float3 t, float3 ddx, float3 ddy ); + +// 3D texture lookup with bias. +float4 tex3Dbias( sampler s, float4 t ); + +// 3D texture lookup with a gradient. +float4 tex3Dgrad( sampler s, float3 t, float3 ddx, float3 ddy ); + +// 3D texture lookup with LOD. +float4 tex3Dlod( sampler s, float4 t ); + +// 3D texture lookup with projective divide. +float4 tex3Dproj( sampler s, float4 t ); + + +// Cube texture lookup. +float4 texCUBE( sampler s, float3 t ); + +// Cube texture lookup. +float4 texCUBE( sampler s, float3 t, float3 ddx, float3 ddy ); + +// Cube texture lookup with bias. +float4 texCUBEbias( sampler s, float4 t ); + +// Cube texture lookup with a gradient. +float4 texCUBEgrad( sampler s, float3 t, float3 ddx, float3 ddy ); + +// Cube texture lookup with LOD. +float4 texCUBElod( sampler s, float4 t ); + +// Cube texture lookup with projective divide. +float4 texCUBEproj( sampler s, float4 t ); \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/lightmap_blend_bump_detail_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/lightmap_blend_bump_detail_ps30.fxc new file mode 100644 index 00000000..668eecbd --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/lightmap_blend_bump_detail_ps30.fxc @@ -0,0 +1,188 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + +// Combos +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "FLASHLIGHT" "0..1" +// DYNAMIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); +sampler _Sampler_01 : register( s1 ); +sampler _Sampler_02 : register( s2 ); +sampler _Sampler_03 : register( s3 ); +sampler _Sampler_04 : register( s4 ); +sampler _Sampler_05 : register( s5 ); +sampler _Sampler_06 : register( s6 ); +sampler _Sampler_07 : register( s7 ); +sampler _Sampler_08 : register( s8 ); +sampler _Sampler_09 : register( s9 ); +sampler _Sampler_10 : register( s10 ); +sampler _gSampler_Flashlight_Cookie : register( s11 ); +sampler _gSampler_Flashlight_Depth : register( s12 ); +sampler _gSampler_Flashlight_Random : register( s13 ); + +// Constants +const float4x4 g_cFlashlightWorldToTexture : register( c12 ); +const float2 g_cData_base_detail_0_smoothing : register( c16 ); // Static +const float2 g_cData_base_detail_1_smoothing : register( c17 ); // Static +const float3 _g_VecOrig : register( c18 ); +const float4 _g_FogParams : register( c19 ); +const float4 g_cFlashlightAttenuationFactors : register( c8 ); +const float4 g_cFlashlightPos : register( c9 ); +const float4 g_cShadowTweaks : register( c7 ); + +// Semantic structures +struct PS_INPUT +{ + float4 vTexCoord_0 : TEXCOORD0; + float4 vTexCoord_1 : TEXCOORD1; + float3 vTexCoord_2 : TEXCOORD2; + float3 vTexCoord_3 : TEXCOORD3; + float4 vTexCoord_4 : TEXCOORD4; + float3 vTexCoord_5 : TEXCOORD5; + float3 vTexCoord_6 : TEXCOORD6; + float2 vTexCoord_7 : TEXCOORD7; + float4 vColor_0 : COLOR0; + float4 vColor_1 : COLOR1; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float3 _var0 = float3( 0.000000, 0.000000, 0.000000 ); + float2 _var1 = In.vTexCoord_0.xy; + float2 _var2 = In.vTexCoord_4.zw; + float _var3 = In.vColor_1.w; + float2 _var4 = In.vTexCoord_0.zw; + float2 _var5 = In.vTexCoord_4.xy; + float _var6 = g_cData_base_detail_0_smoothing.x; + float _var7 = g_cData_base_detail_0_smoothing.y; + float2 _var8 = In.vTexCoord_7.xy; + float _var9 = g_cData_base_detail_1_smoothing.x; + float _var10 = g_cData_base_detail_1_smoothing.y; + float3 _var11 = float3( 0.000000, 0.000000, 0.000000 ); + float _var12 = _g_VecOrig.z; + float _var13 = In.vTexCoord_3.z; + float _var14 = In.vColor_0.z; + float4 _texLookup_48 = tex2D( _Sampler_00, _var1 ); + float3 _var15 = _texLookup_48.rgb; + float _var16 = _texLookup_48.b; + float3 _var17 = tex2D( _Sampler_01, _var2 ).rgb; + float4 _texLookup_51 = tex2D( _Sampler_02, _var1 ); + float3 _var18 = _texLookup_51.rgb; + float _var19 = _texLookup_51.b; + float3 _var20 = tex2D( _Sampler_03, _var2 ).rgb; + float4 _texLookup_54 = tex2D( _Sampler_04, _var4 ); + float _var21 = _texLookup_54.r; + float _var22 = _texLookup_54.g; + float3 _var23 = tex2D( _Sampler_05, _var1 ).rgb; + float3 _var24 = tex2D( _Sampler_06, _var8 ).rgb; + float4 _texLookup_58 = tex2D( _Sampler_07, _var1 ); + float3 _var25 = _texLookup_58.rgb; + float _var26 = _texLookup_58.g; + float3 _var27 = tex2D( _Sampler_08, _var8 ).rgb; + _var12 = CalcPixelFogFactor( PIXELFOGTYPE, _g_FogParams, _var12, _var13, _var14 ); + float2 _var28 = _var15.xy; + float2 _var29 = _var17.xy; + float2 _var30 = _var18.xy; + float2 _var31 = _var20.xy; + _var21 = min( _var3, _var21 ); + _var22 = max( _var3, _var22 ); + _var24 = smoothstep( _var6, _var7, _var24 ); + _var27 = smoothstep( _var9, _var10, _var27 ); + _var29 = _var29 - float( 0.500000 ); + _var31 = _var31 - float( 0.500000 ); + _var21 = lerp( _var21, _var22, _var3 ); + _var23 = _var23 * _var24; + _var25 = _var25 * _var27; + _var28 = _var28 + _var29; + _var30 = _var30 + _var31; + _var21 = smoothstep( float( 0.400000 ), float( 0.600000 ), _var21 ); + _var28 = saturate( _var28 ); + _var30 = saturate( _var30 ); + _var23 = lerp( _var23, _var25, _var21 ); + _var26 = _var26 * _var21; + float3 _var32 = float3( _var28, _var16 ); + float3 _var33 = float3( _var30, _var19 ); + _var32 = lerp( _var32, _var33, _var21 ); + _var32 = _var32 * float( 2.000000 ); + _var32 = _var32 - float( 1.000000 ); +#if ( FLASHLIGHT == 0 ) + float2 _var34 = In.vTexCoord_1.xy; + float _var35 = dot( _var32, bumpBasis[0] ); + float _var36 = dot( _var32, bumpBasis[1] ); + float _var37 = dot( _var32, bumpBasis[2] ); + float2 _var38 = In.vTexCoord_1.zw; + float3 _var39 = tex2D( _Sampler_09, _var5 ).rgb; + float3 _var40 = In.vTexCoord_3 - _g_VecOrig; + float3 _var41 = lerp( _var32, In.vTexCoord_2, float( 0.900000 ) ); + float3 _var42 = tex2D( _Sampler_09, _var34 ).rgb; + float2 _var43 = float2( _var35, _var36 ); + float3 _var44 = tex2D( _Sampler_09, _var38 ).rgb; + _var40 = reflect( _var40, _var41 ); + float3 _var45 = float3( _var43, _var37 ); + float3 _var46 = texCUBE( _Sampler_10, _var40 ).rgb; + _var45 = saturate( _var45 ); + _var46 = _var46 * float( 0.040000 ); + _var45 = _var45 * _var45; + _var46 = _var46 * ENV_MAP_SCALE; + float _var47 = _var45.x; + float _var48 = _var45.y; + float _var49 = _var45.z; + float _var50 = dot( float3( float( 1.000000 ), float( 1.000000 ), float( 1.000000 ) ), _var45 ); + _var11 = _var46; + _var42 = _var42 * _var47; + _var44 = _var44 * _var48; + _var39 = _var39 * _var49; + _var50 = LIGHT_MAP_SCALE / _var50; + _var42 = _var42 + _var44; + _var42 = _var42 + _var39; + _var42 = _var42 * _var50; + _var0 = _var42; +#endif +#if ( FLASHLIGHT == 1 ) + float3x3 _var51 = { In.vTexCoord_5, + In.vTexCoord_6, + In.vTexCoord_2 }; + float4 _var52 = mul( float4(In.vTexCoord_3.xyz,1), g_cFlashlightWorldToTexture ); + float2 _var53 = In.vColor_0.xy; + float _var54 = In.vColor_0.w; + float3 _var55 = mul( _var32, _var51 ); + _var53 = _var53 / _var54; + _var55 = normalize( _var55 ); + _var53 = _var53 * float( 0.500000 ); + _var53 = _var53 + float( 0.500000 ); + _var55 = DoFlashlight( g_cFlashlightPos.xyz, In.vTexCoord_3, _var52, _var55, + g_cFlashlightAttenuationFactors.xyz, g_cFlashlightAttenuationFactors.w, + _gSampler_Flashlight_Cookie, _gSampler_Flashlight_Depth, _gSampler_Flashlight_Random, + FLASHLIGHTDEPTHFILTERMODE, FLASHLIGHTSHADOWS, true, + _var53, false, g_cShadowTweaks ); + _var0 = _var55; +#endif + _var0 = _var0; + _var11 = _var11 * _var26; + _var0 = _var0 * _var23; + _var0 = _var0 + _var11; + float4 _var56 = float4( _var0.x, _var0.y, _var0.z, 1.000000 ); + _var56 = FinalOutput( _var56, _var12, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, true, _var14 ); + Out.vColor_0 = _var56; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/lightmap_blend_bump_detail_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/lightmap_blend_bump_detail_vs30.fxc new file mode 100644 index 00000000..692e25f5 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/lightmap_blend_bump_detail_vs30.fxc @@ -0,0 +1,82 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + + +// Includes +#include "common_vs_fxc.h" + + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float3 vNormal : NORMAL; + float3 vTangent_S : TANGENT; + float3 vTangent_T : BINORMAL; + float2 vTexCoord_0 : TEXCOORD0; + float2 vTexCoord_1 : TEXCOORD1; + float2 vTexCoord_2 : TEXCOORD2; + float4 vColor_0 : COLOR0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float4 vTexCoord_0 : TEXCOORD0; + float4 vTexCoord_1 : TEXCOORD1; + float3 vTexCoord_2 : TEXCOORD2; + float3 vTexCoord_3 : TEXCOORD3; + float4 vTexCoord_4 : TEXCOORD4; + float3 vTexCoord_5 : TEXCOORD5; + float3 vTexCoord_6 : TEXCOORD6; + float2 vTexCoord_7 : TEXCOORD7; + float4 vColor_0 : COLOR0; + float4 vColor_1 : COLOR1; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float3 _var0 = mul( float4(In.vPos.xyz,1), cModel[0] ); + float2 _var1 = In.vTexCoord_0 * float( 1.000000 ); + float2 _var2 = In.vTexCoord_0 * float( 0.120000 ); + float2 _var3 = In.vTexCoord_1 + In.vTexCoord_2; + float3 _var4 = mul( float4(In.vNormal.xyz,1), cModel[0] ); + float2 _var5 = In.vTexCoord_0 * float2( 5.000000, 5.000000 ); + float3 _var6 = mul( float4(In.vTangent_S.xyz,1), cModel[0] ); + float3 _var7 = mul( float4(In.vTangent_T.xyz,1), cModel[0] ); + float2 _var8; + { + float2 center_def = float2( 0.5f, 0.5f ); + float2 trans_def = float2( 0.0f, 0.0f ); + float fs = sin( float( 45.000000 ) ); + float fc = cos( float( 45.000000 ) ); + float4 row_0 = float4( fc * float2( 4.000000, 4.000000 ).x, -fs * float2( 4.000000, 4.000000 ).x, 0, ( -center_def.x * fc + center_def.y * fs ) * float2( 4.000000, 4.000000 ).x + center_def.x + trans_def.x ); + float4 row_1 = float4( fs * float2( 4.000000, 4.000000 ).y, fc * float2( 4.000000, 4.000000 ).y, 0, ( -center_def.x * fs - center_def.y * fc ) * float2( 4.000000, 4.000000 ).y + center_def.y + trans_def.y ); + _var8.x = dot( float4( In.vTexCoord_0, 0, 1 ), row_0 ); + _var8.y = dot( float4( In.vTexCoord_0, 0, 1 ), row_1 ); + } + float4 _var9 = mul( float4(_var0.xyz,1), cViewProj ); + float4 _var10 = float4( _var1, _var2 ); + float2 _var11 = _var3 + In.vTexCoord_2; + _var4 = normalize( _var4 ); + _var6 = normalize( _var6 ); + _var7 = normalize( _var7 ); + float4 _var12 = float4( _var3, _var11 ); + float2 _var13 = _var11 + In.vTexCoord_2; + float4 _var14 = float4( _var13, _var5 ); + Out.vProjPos = _var9; + Out.vTexCoord_0 = _var10; + Out.vTexCoord_1 = _var12; + Out.vTexCoord_2 = _var4; + Out.vTexCoord_3 = _var0; + Out.vTexCoord_4 = _var14; + Out.vTexCoord_5 = _var6; + Out.vTexCoord_6 = _var7; + Out.vTexCoord_7 = _var8; + Out.vColor_0 = _var9; + Out.vColor_1 = In.vColor_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/lightmap_parallax_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/lightmap_parallax_ps30.fxc new file mode 100644 index 00000000..e750404a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/lightmap_parallax_ps30.fxc @@ -0,0 +1,179 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + +// Combos +// DYNAMIC: "FLASHLIGHT" "0..1" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" +// DYNAMIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); +sampler _Sampler_01 : register( s1 ); +sampler _Sampler_02 : register( s2 ); +sampler _Sampler_03 : register( s3 ); +sampler _gSampler_Flashlight_Cookie : register( s4 ); +sampler _gSampler_Flashlight_Depth : register( s5 ); +sampler _gSampler_Flashlight_Random : register( s6 ); + +// Constants +const float3 _g_VecOrig : register( c16 ); +const float g_cData_parallax_geo_height : register( c17 ); // Static +const float4x4 g_cFlashlightWorldToTexture : register( c12 ); +const float4x4 g_cCMatrix_ViewProj : register( c18 ); +const float4 g_cFlashlightAttenuationFactors : register( c8 ); +const float4 g_cFlashlightPos : register( c9 ); +const float4 g_cShadowTweaks : register( c7 ); +const float4 _g_FogParams : register( c22 ); + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; + float4 vTexCoord_1 : TEXCOORD1; + float3 vTexCoord_2 : TEXCOORD2; + float3 vTexCoord_3 : TEXCOORD3; + float2 vTexCoord_4 : TEXCOORD4; + float3 vTexCoord_5 : TEXCOORD5; + float3 vTexCoord_6 : TEXCOORD6; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; + float vDepth : DEPTH; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float3 _var0 = float3( 0.000000, 0.000000, 0.000000 ); + float2 _var1 = float2( 0.000000, 0.000000 ); + float3x3 _var2 = { In.vTexCoord_5, + In.vTexCoord_6, + In.vTexCoord_2 }; + float3 _var3 = In.vTexCoord_3 - _g_VecOrig; + float3 _var4 = _g_VecOrig - In.vTexCoord_3; + float3 _var5 = float3( 0.000000, 0.000000, 0.000000 ); + float _var6 = _g_VecOrig.z; + _var3 = mul( _var2, _var3 ); +#if ( FLASHLIGHT == 0 ) + float3 _var8 = (float3)0; + float2 _var7 = CalcParallaxUV_Relief( In.vTexCoord_0, _var3, g_cData_parallax_geo_height, In.vTexCoord_2, _var4, + _Sampler_00, 10, 30, 5, In.vTexCoord_3, + _var8, true, true ); + _var5 = _var8; + _var1 = _var7; +#endif +#if ( FLASHLIGHT == 1 ) + float3 _var10 = (float3)0; + float2 _var9 = CalcParallaxUV_Relief( In.vTexCoord_0, _var3, g_cData_parallax_geo_height, In.vTexCoord_2, _var4, + _Sampler_00, 8, 15, 5, In.vTexCoord_3, + _var10, false, true ); + _var10 = _var10 * float( 0.900000 ); + _var1 = _var9; + _var5 = _var10; +#endif + _var1 = _var1; + _var5 = _var5; + float3 _var11 = tex2D( _Sampler_01, _var1 ).rgb; + float _var12 = _var5.x; + float _var13 = _var5.y; + float _var14 = _var5.z; + float3 _var15 = tex2D( _Sampler_02, _var1 ).rgb; + _var11 = _var11 * float( 2.000000 ); + float3 _var16 = _var12 * In.vTexCoord_5; + float3 _var17 = _var13 * In.vTexCoord_6; + float _var18 = _var14 * g_cData_parallax_geo_height; + float _var19 = 1.0f - _var14; + _var11 = _var11 - float( 1.000000 ); + _var16 = _var16 + _var17; + float3 _var20 = _var18 * In.vTexCoord_2; + _var19 = _var19 * _var19; +#if ( FLASHLIGHT == 0 ) + float2 _var21 = In.vTexCoord_1.xy; + float _var22 = dot( _var11, bumpBasis[0] ); + float _var23 = dot( _var11, bumpBasis[1] ); + float _var24 = dot( _var11, bumpBasis[2] ); + float2 _var25 = In.vTexCoord_1.zw; + float3 _var26 = tex2D( _Sampler_03, In.vTexCoord_4 ).rgb; + float3 _var27 = tex2D( _Sampler_03, _var21 ).rgb; + _var22 = saturate( _var22 ); + _var23 = saturate( _var23 ); + _var24 = saturate( _var24 ); + float3 _var28 = tex2D( _Sampler_03, _var25 ).rgb; + float2 _var29 = float2( _var22, _var23 ); + float3 _var30 = float3( _var29, _var24 ); + _var30 = _var30 * _var30; + float _var31 = _var30.x; + float _var32 = _var30.y; + float _var33 = _var30.z; + float _var34 = dot( float3( float( 1.000000 ), float( 1.000000 ), float( 1.000000 ) ), _var30 ); + _var27 = _var27 * _var31; + _var28 = _var28 * _var32; + _var26 = _var26 * _var33; + _var34 = LIGHT_MAP_SCALE / _var34; + _var27 = _var27 + _var28; + _var27 = _var27 + _var26; + _var27 = _var27 * _var34; + _var0 = _var27; +#endif + _var16 = _var16 + _var20; + _var15 = _var15 * _var19; + _var16 = In.vTexCoord_3 - _var16; + float4 _var35 = mul( float4(_var16.xyz,1), g_cCMatrix_ViewProj ); + float _var36 = _var16.z; +#if ( FLASHLIGHT == 1 ) + float3 _var37 = mul( _var11, _var2 ); + float4 _var38 = mul( float4(_var16.xyz,1), g_cFlashlightWorldToTexture ); + float2 _var39 = _var35.xy; + float _var40 = _var35.w; + _var37 = normalize( _var37 ); + _var39 = _var39 / _var40; + _var39 = _var39 * float( 0.500000 ); + _var39 = _var39 + float( 0.500000 ); + _var37 = DoFlashlight( g_cFlashlightPos.xyz, _var16, _var38, _var37, + g_cFlashlightAttenuationFactors.xyz, g_cFlashlightAttenuationFactors.w, + _gSampler_Flashlight_Cookie, _gSampler_Flashlight_Depth, _gSampler_Flashlight_Random, + FLASHLIGHTDEPTHFILTERMODE, FLASHLIGHTSHADOWS, true, + _var39, false, g_cShadowTweaks ); + float3 _var41 = _var37; +#if ( FLASHLIGHTSHADOWS == 1 ) + float _var42 = dot( float3( float( 1.000000 ), float( 1.000000 ), float( 1.000000 ) ), _var37 ); + if ( _var42 > float( 0.010000 ) ) + { + float3 _var43 = _var16 - float3( g_cFlashlightPos.xyz ); + _var43 = mul( _var2, _var43 ); + _var43 = normalize( _var43 ); + float _var44 = CalcParallaxedShadows_OneLight( In.vTexCoord_0, _var1, _var43, + In.vTexCoord_3, g_cData_parallax_geo_height, float( 1.000000 ), _Sampler_00 ); + _var41 = _var41 * _var44; + } +#endif + _var0 = _var41; +#endif + _var0 = _var0; + float _var45 = _var35.z; + float _var46 = _var35.z; + float _var47 = _var35.w; + _var0 = _var0 * _var15; + _var6 = CalcPixelFogFactor( PIXELFOGTYPE, _g_FogParams, _var6, _var36, _var45 ); + _var46 = _var46 / _var47; + float4 _var48 = float4( _var0.x, _var0.y, _var0.z, 1.000000 ); + _var46 = saturate( _var46 ); + _var48 = FinalOutput( _var48, _var6, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, true, _var45 ); + Out.vColor_0 = _var48; + Out.vDepth = _var46; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/lightmap_parallax_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/lightmap_parallax_vs30.fxc new file mode 100644 index 00000000..8bff4055 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/lightmap_parallax_vs30.fxc @@ -0,0 +1,64 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + + +// Includes +#include "common_vs_fxc.h" + + +// Constants +const float g_cData_parallax_geo_height : register( c48 ); // Static + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float3 vNormal : NORMAL; + float3 vTangent_S : TANGENT; + float3 vTangent_T : BINORMAL; + float2 vTexCoord_0 : TEXCOORD0; + float2 vTexCoord_1 : TEXCOORD1; + float2 vTexCoord_2 : TEXCOORD2; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; + float4 vTexCoord_1 : TEXCOORD1; + float3 vTexCoord_2 : TEXCOORD2; + float3 vTexCoord_3 : TEXCOORD3; + float2 vTexCoord_4 : TEXCOORD4; + float3 vTexCoord_5 : TEXCOORD5; + float3 vTexCoord_6 : TEXCOORD6; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float3 _var0 = mul( float4(In.vPos.xyz,1), cModel[0] ); + float3 _var1 = mul( float4(In.vNormal.xyz,1), cModel[0] ); + float2 _var2 = In.vTexCoord_1 + In.vTexCoord_2; + float3 _var3 = mul( float4(In.vTangent_S.xyz,1), cModel[0] ); + float3 _var4 = mul( float4(In.vTangent_T.xyz,1), cModel[0] ); + _var1 = normalize( _var1 ); + float2 _var5 = _var2 + In.vTexCoord_2; + _var3 = normalize( _var3 ); + _var4 = normalize( _var4 ); + float3 _var6 = _var1 * g_cData_parallax_geo_height; + float4 _var7 = float4( _var2, _var5 ); + float2 _var8 = _var5 + In.vTexCoord_2; + _var0 = _var0 + _var6; + float4 _var9 = mul( float4(_var0.xyz,1), cViewProj ); + Out.vProjPos = _var9; + Out.vTexCoord_0 = In.vTexCoord_0; + Out.vTexCoord_1 = _var7; + Out.vTexCoord_2 = _var1; + Out.vTexCoord_3 = _var0; + Out.vTexCoord_4 = _var8; + Out.vTexCoord_5 = _var3; + Out.vTexCoord_6 = _var4; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/model_chromatic_aberration_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/model_chromatic_aberration_ps30.fxc new file mode 100644 index 00000000..ab3789b9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/model_chromatic_aberration_ps30.fxc @@ -0,0 +1,101 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); +sampler _Sampler_01 : register( s1 ); +sampler _Sampler_02 : register( s2 ); + +// Constants +const float4x4 g_cCMatrix_ViewProj : register( c16 ); + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; + float3 vTexCoord_1 : TEXCOORD1; + float3 vTexCoord_2 : TEXCOORD2; + float4 vTexCoord_3 : TEXCOORD3; + float3 vTexCoord_4 : TEXCOORD4; + float3 vTexCoord_5 : TEXCOORD5; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float2 _var0 = In.vTexCoord_3.xy; + float _var1 = In.vTexCoord_3.w; + float3 _var2 = tex2D( _Sampler_00, In.vTexCoord_0 ).rgb; + float3x3 _var3 = { In.vTexCoord_4, + In.vTexCoord_5, + In.vTexCoord_1 }; + float3 _var4 = normalize( In.vTexCoord_2 ); + float _var5 = In.vTexCoord_3.z; + _var0 = _var0 / _var1; + _var2 = lerp( _var2, float3( 0.500000, 0.500000, 1.000000 ), float( 0.500000 ) ); + _var5 = smoothstep( float( 1.000000 ), float( 2.500000 ), _var5 ); + _var0 = _var0 * float2( 0.500000, -0.500000 ); + _var2 = _var2 * float( 2.000000 ); + _var5 = float( 0.800000 ) * _var5; + _var0 = _var0 + float( 0.500000 ); + _var2 = _var2 - float( 1.000000 ); + _var2 = mul( _var2, _var3 ); + _var2 = normalize( _var2 ); + float3 _var6 = mul( float4(_var2.xyz,1), (float3x3)g_cCMatrix_ViewProj ); + float _var7 = dot( _var2, _var4 ); + float3 _var8 = reflect( _var4, _var2 ); + float2 _var9 = _var6.xy; + float _var10 = smoothstep( float( -0.050000 ), float( -0.100000 ), _var7 ); + float _var11 = abs( _var7 ); + float _var12 = smoothstep( float( -1.000000 ), float( 0.000000 ), _var7 ); + float3 _var13 = texCUBE( _Sampler_01, _var8 ).rgb; + float _var14 = smoothstep( float( -1.000000 ), float( -0.500000 ), _var7 ); + float _var15 = smoothstep( float( 0.100000 ), float( -0.500000 ), _var7 ); + _var9 = _var9 * _var10; + _var11 = 1.0f - _var11; + float _var16 = pow( _var12, float( 2.000000 ) ); + _var13 = _var13 * ENV_MAP_SCALE; + _var14 = min( _var14, _var15 ); + float _var17 = pow( _var12, float( 20.000000 ) ); + _var9 = _var9 * float2( 1.000000, -1.000000 ); + _var11 = _var11 * float( 0.100000 ); + float3 _var18 = lerp( float( 1.000000 ), float3( 0.830000, 0.867400, 1.000000 ), _var16 ); + _var14 = _var14 * float( 0.500000 ); + _var17 = _var17 * float( 0.300000 ); + float _var19 = float( 0.005000 ) + _var11; + float _var20 = float( 0.010000 ) + _var11; + float _var21 = float( 0.015000 ) + _var11; + float2 _var22 = _var9 * _var19; + float2 _var23 = _var9 * _var20; + float2 _var24 = _var9 * _var21; + _var22 = _var0 - _var22; + _var23 = _var0 - _var23; + _var24 = _var0 - _var24; + float _var25 = tex2D( _Sampler_02, _var22 ).r; + float _var26 = tex2D( _Sampler_02, _var23 ).g; + float _var27 = tex2D( _Sampler_02, _var24 ).b; + float2 _var28 = float2( _var25, _var26 ); + float3 _var29 = float3( _var28, _var27 ); + _var29 = _var29 * _var18; + _var29 = lerp( _var29, _var13, _var14 ); + _var29 = lerp( _var29, float( 1.000000 ), _var17 ); + float4 _var30 = float4( _var29, _var5 ); + Out.vColor_0 = _var30; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/model_chromatic_aberration_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/model_chromatic_aberration_vs30.fxc new file mode 100644 index 00000000..46ce7c9e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/model_chromatic_aberration_vs30.fxc @@ -0,0 +1,65 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + +// Combos +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +// Includes +#include "common_vs_fxc.h" + + +// Constants +const float3 _g_VecOrig : register( c48 ); + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vTangent_S : TANGENT; + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; + float3 vTexCoord_1 : TEXCOORD1; + float3 vTexCoord_2 : TEXCOORD2; + float4 vTexCoord_3 : TEXCOORD3; + float3 vTexCoord_4 : TEXCOORD4; + float3 vTexCoord_5 : TEXCOORD5; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float3 _var0 = (float3)0; + float4 _var1 = (float4)0; + DecompressVertex_NormalTangent( In.vNormal, In.vTangent_S, _var0, _var1 ); + float3 _var2 = (float3)0; + float3 _var3 = (float3)0; + float3 _var4 = (float3)0; + float3 _var5 = (float3)0; + SkinPositionNormalAndTangentSpace( SKINNING, float4( In.vPos, 1 ), _var0, _var1, + In.vBoneWeights, In.vBoneIndices, + _var2, _var3, _var4, _var5 ); + float4 _var6 = mul( float4(_var2.xyz,1), cViewProj ); + _var3 = normalize( _var3 ); + float3 _var7 = _var2 - _g_VecOrig; + _var4 = normalize( _var4 ); + _var5 = normalize( _var5 ); + Out.vProjPos = _var6; + Out.vTexCoord_0 = In.vTexCoord_0; + Out.vTexCoord_1 = _var3; + Out.vTexCoord_2 = _var7; + Out.vTexCoord_3 = _var6; + Out.vTexCoord_4 = _var4; + Out.vTexCoord_5 = _var5; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/model_cubemap_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/model_cubemap_ps30.fxc new file mode 100644 index 00000000..1e89098d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/model_cubemap_ps30.fxc @@ -0,0 +1,41 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + +// Combos +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); + +// Semantic structures +struct PS_INPUT +{ + float3 vTexCoord_0 : TEXCOORD0; + float3 vTexCoord_1 : TEXCOORD1; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float3 _var0 = reflect( In.vTexCoord_0, In.vTexCoord_1 ); + float4 _var1 = texCUBE( _Sampler_00, _var0 ).rgba; + _var1 = FinalOutput( _var1, float( 0.000000 ), PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, true, float( 0.000000 ) ); + Out.vColor_0 = _var1; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/model_cubemap_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/model_cubemap_vs30.fxc new file mode 100644 index 00000000..ba65e96c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/model_cubemap_vs30.fxc @@ -0,0 +1,50 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + +// Combos +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "SKINNING" "0..1" + +// Includes +#include "common_vs_fxc.h" + + +// Constants +const float3 _g_VecOrig : register( c48 ); + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float3 vTexCoord_0 : TEXCOORD0; + float3 vTexCoord_1 : TEXCOORD1; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float3 _var0 = (float3)0; + DecompressVertex_Normal( In.vNormal, _var0 ); + float3 _var1 = (float3)0; + float3 _var2 = (float3)0; + SkinPositionAndNormal( SKINNING, float4( In.vPos, 1 ), _var0, + In.vBoneWeights, In.vBoneIndices, + _var1, _var2 ); + float4 _var3 = mul( float4(_var1.xyz,1), cViewProj ); + float3 _var4 = _var1 - _g_VecOrig; + _var4 = normalize( _var4 ); + Out.vProjPos = _var3; + Out.vTexCoord_0 = _var4; + Out.vTexCoord_1 = _var2; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/model_litsphere_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/model_litsphere_ps30.fxc new file mode 100644 index 00000000..6f7aa0ab --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/model_litsphere_ps30.fxc @@ -0,0 +1,99 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Combos +// STATIC: "FLASHLIGHT" "0..1" +// DYNAMIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" +// DYNAMIC: "NUM_LIGHTS" "0..4" +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" + +// Samplers +sampler _Sampler_00 : register( s0 ); +sampler _gSampler_Flashlight_Cookie : register( s1 ); +sampler _gSampler_Flashlight_Depth : register( s2 ); +sampler _gSampler_Flashlight_Random : register( s3 ); +sampler _Sampler_04 : register( s4 ); + +// Constants +const float4x3 g_cCMatrix_View : register( c16 ); +const float4 _g_FogParams : register( c19 ); +const float3 _g_VecOrig : register( c20 ); +const float4 g_cFlashlightAttenuationFactors : register( c8 ); +const float4 g_cFlashlightPos : register( c9 ); +const float4 g_cShadowTweaks : register( c7 ); +const float3 g_cAmbientCube[6] : register( c0 ); +PixelShaderLightInfo g_cLightInfo[3] : register( c6 ); + +// Arrays + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; + float3 vTexCoord_1 : TEXCOORD1; + float3 vTexCoord_2 : TEXCOORD2; + float4 vTexCoord_3 : TEXCOORD3; + float4 vTexCoord_4 : TEXCOORD4; + float4 vColor_0 : COLOR0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float4 _texLookup_12 = tex2D( _Sampler_00, In.vTexCoord_0 ); + float3 _var0 = _texLookup_12.rgb; + float _var1 = _texLookup_12.a; + float3 _var2 = float3( 0.000000, 0.000000, 0.000000 ); + float3 _var3 = mul( float4(In.vTexCoord_2.xyz,1), (float3x3)g_cCMatrix_View ); + float _var4 = _g_VecOrig.z; + float _var5 = In.vTexCoord_1.z; + float _var6 = In.vTexCoord_3.z; +#if ( FLASHLIGHT == 1 ) + float2 _var7 = In.vTexCoord_3.xy; + float _var8 = In.vTexCoord_3.w; + _var7 = _var7 / _var8; + float3 _var9 = DoFlashlight( g_cFlashlightPos.xyz, In.vTexCoord_1, In.vTexCoord_4, In.vTexCoord_2, + g_cFlashlightAttenuationFactors.xyz, g_cFlashlightAttenuationFactors.w, + _gSampler_Flashlight_Cookie, _gSampler_Flashlight_Depth, _gSampler_Flashlight_Random, + FLASHLIGHTDEPTHFILTERMODE, FLASHLIGHTSHADOWS, true, + _var7, false, g_cShadowTweaks ); + _var2 = _var9; +#endif +#if ( FLASHLIGHT == 0 ) + float3 _var10 = PixelShaderDoLighting( In.vTexCoord_1, In.vTexCoord_2, float3(0,0,0), + false, true, In.vColor_0, + g_cAmbientCube, NUM_LIGHTS, g_cLightInfo, + false, false, 1.0f ); + _var2 = _var10; +#endif + _var2 = _var2; + float2 _var11 = _var3.xy; + _var4 = CalcPixelFogFactor( PIXELFOGTYPE, _g_FogParams, _var4, _var5, _var6 ); + _var11 = _var11 * float2( 1.000000, -1.000000 ); + _var11 = _var11 * float( 0.500000 ); + _var11 = _var11 + float( 0.500000 ); + float3 _var12 = tex2D( _Sampler_04, _var11 ).rgb; + _var2 = _var2 + _var12; + _var0 = _var0 * _var2; + float4 _var13 = float4( _var0, _var1 ); + _var13 = FinalOutput( _var13, _var4, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, true, _var6 ); + Out.vColor_0 = _var13; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/model_litsphere_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/model_litsphere_vs30.fxc new file mode 100644 index 00000000..d4166e5e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/model_litsphere_vs30.fxc @@ -0,0 +1,71 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + +// Includes +#include "common_vs_fxc.h" + + +// Combos +// DYNAMIC: "SKINNING" "0..1" +// STATIC: "FLASHLIGHT" "0..1" + +// Samplers + +// Constants +const float4x4 g_cFlashlightWorldToTexture : register( c48 ); + +// Arrays + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float3 vNormal : NORMAL; + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; + float3 vTexCoord_1 : TEXCOORD1; + float3 vTexCoord_2 : TEXCOORD2; + float4 vTexCoord_3 : TEXCOORD3; + float4 vTexCoord_4 : TEXCOORD4; + float4 vTexCoord_5 : TEXCOORD5; + float4 vColor_0 : COLOR0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float3 _var0 = (float3)0; + float3 _var1 = (float3)0; + SkinPositionAndNormal( SKINNING, float4( In.vPos, 1 ), In.vNormal, + In.vBoneWeights, In.vBoneIndices, + _var0, _var1 ); + float4 _var2 = float4( 0.000000, 0.000000, 0.000000, 0.000000 ); + float4 _var3 = mul( float4(_var0.xyz,1), cViewProj ); +#if ( FLASHLIGHT == 1 ) + float4 _var4 = mul( float4(_var0.xyz,1), g_cFlashlightWorldToTexture ); + _var2 = _var4; +#endif + float4 _var5 = mul( float4(_var1.xyz,1), cViewProj ); + float4 _var6 = float4( GetVertexAttenForLight( _var0, 0 ), + GetVertexAttenForLight( _var0, 1 ), + GetVertexAttenForLight( _var0, 2 ), + GetVertexAttenForLight( _var0, 3 ) ); + Out.vProjPos = _var3; + Out.vTexCoord_0 = In.vTexCoord_0; + Out.vTexCoord_1 = _var0; + Out.vTexCoord_2 = _var1; + Out.vTexCoord_3 = _var3; + Out.vTexCoord_4 = _var2; + Out.vTexCoord_5 = _var5; + Out.vColor_0 = _var6; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/model_snowy_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/model_snowy_ps30.fxc new file mode 100644 index 00000000..deb7ecff --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/model_snowy_ps30.fxc @@ -0,0 +1,209 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + +// Combos +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// STATIC: "FLASHLIGHT" "0..1" +// DYNAMIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" +// DYNAMIC: "NUM_LIGHTS" "0..4" +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); +sampler _Sampler_01 : register( s1 ); +sampler _Sampler_02 : register( s2 ); +sampler _Sampler_03 : register( s3 ); +sampler _Sampler_04 : register( s4 ); +sampler _Sampler_05 : register( s5 ); +sampler _gSampler_Flashlight_Cookie : register( s6 ); +sampler _gSampler_Flashlight_Depth : register( s7 ); +sampler _gSampler_Flashlight_Random : register( s8 ); +sampler _Sampler_09 : register( s9 ); + +// Constants +const float4 _g_FogParams : register( c16 ); +const float3 _g_VecOrig : register( c17 ); +const float4 g_cFlashlightAttenuationFactors : register( c8 ); +const float4 g_cFlashlightPos : register( c9 ); +const float4 g_cShadowTweaks : register( c7 ); +const float3 g_cAmbientCube[6] : register( c0 ); +PixelShaderLightInfo g_cLightInfo[3] : register( c6 ); + +// Semantic structures +struct PS_INPUT +{ + float4 vTexCoord_0 : TEXCOORD0; + float3 vTexCoord_1 : TEXCOORD1; + float3 vTexCoord_2 : TEXCOORD2; + float4 vTexCoord_3 : TEXCOORD3; + float4 vTexCoord_4 : TEXCOORD4; + float3 vTexCoord_5 : TEXCOORD5; + float3 vTexCoord_6 : TEXCOORD6; + float3 vTexCoord_7 : TEXCOORD7; + float4 vColor_0 : COLOR0; + float4 vColor_1 : COLOR1; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float3 _var0 = float3( 0.000000, 0.000000, 0.000000 ); + float2 _var1 = In.vTexCoord_0.xy; + float2 _var2 = In.vTexCoord_0.zw; + float _var3 = In.vColor_1.w; + float _var4 = In.vColor_1.x; + float _var5 = In.vColor_1.y; + float _var6 = In.vColor_1.z; + float _var7 = dot( In.vTexCoord_1, float3( 0.000000, 0.000000, 1.000000 ) ); + float3x3 _var8 = { In.vTexCoord_5, + In.vTexCoord_6, + In.vTexCoord_1 }; + float2 _var9 = In.vTexCoord_4.xy; + float _var10 = In.vTexCoord_4.w; + float3 _var11 = normalize( In.vTexCoord_7 ); + float3 _var12 = float3( 0.000000, 0.000000, 0.000000 ); + float _var13 = In.vTexCoord_4.z; + float _var14 = _g_VecOrig.z; + float _var15 = In.vTexCoord_2.z; + float _var16 = In.vTexCoord_4.z; + float4 _texLookup_56 = tex2D( _Sampler_00, _var1 ); + float3 _var17 = _texLookup_56.rgb; + float _var18 = _texLookup_56.a; + float3 _var19 = float3( _var2, _var3 ); + _var9 = _var9 / _var10; + float3 _var20 = _var11 * float( -1.000000 ); + float _var21 = tex2D( _Sampler_01, _var1 ).r; + float4 _texLookup_62 = tex2D( _Sampler_02, _var1 ); + float3 _var22 = _texLookup_62.rgb; + float _var23 = _texLookup_62.a; + _var13 = smoothstep( float( 50.000000 ), float( 0.000000 ), _var13 ); + _var14 = CalcPixelFogFactor( PIXELFOGTYPE, _g_FogParams, _var14, _var15, _var16 ); + float3 _var24 = _var19 * float( 0.015000 ); + float _var25 = 1.0f - _var21; + float _var26 = _var21 * float( 150.000000 ); + _var13 = _var13 * float( 0.500000 ); + float2 _var27 = _var24.zy; + float2 _var28 = _var24.xz; + float2 _var29 = _var24.xy; + _var25 = _var25 + _var26; + _var13 = _var13 + float( 0.100000 ); + float3 _var30 = tex2D( _Sampler_03, _var27 ).rgb; + float3 _var31 = tex2D( _Sampler_03, _var28 ).rgb; + float3 _var32 = tex2D( _Sampler_03, _var29 ).rgb; + float4 _var33 = tex2D( _Sampler_04, _var27 ).rgba; + float4 _var34 = tex2D( _Sampler_04, _var28 ).rgba; + float4 _var35 = tex2D( _Sampler_04, _var29 ).rgba; + float3 _var36 = _var19 * _var13; + _var30 = _var30 * _var4; + _var31 = _var31 * _var5; + _var32 = _var32 * _var6; + _var33 = _var33 * _var4; + _var34 = _var34 * _var5; + _var35 = _var35 * _var6; + float2 _var37 = _var36.zy; + float2 _var38 = _var36.xz; + float2 _var39 = _var36.xy; + _var30 = _var30 + _var31; + _var33 = _var33 + _var34; + float3 _var40 = tex2D( _Sampler_05, _var37 ).rgb; + float3 _var41 = tex2D( _Sampler_05, _var38 ).rgb; + float3 _var42 = tex2D( _Sampler_05, _var39 ).rgb; + _var30 = _var30 + _var32; + _var33 = _var33 + _var35; + _var40 = _var40 * _var4; + _var41 = _var41 * _var5; + _var42 = _var42 * _var6; + float _var43 = _var33.w; + float3 _var44 = _var33.xyz; + _var40 = _var40 + _var41; + float _var45 = pow( _var43, float( 10.000000 ) ); + float _var46 = _var43 * float( 0.500000 ); + _var44 = _var44 * float3( 0.540000, 0.570000, 0.600000 ); + _var40 = _var40 + _var42; + float _var47 = min( _var7, _var45 ); + float _var48 = max( _var7, _var45 ); + _var46 = _var46 + float( 0.500000 ); + float _var49 = _var40.x; + float3 _var50 = _var40 * float( 2.000000 ); + _var47 = lerp( _var47, _var48, _var7 ); + float3 _var51 = lerp( float3( 0.900000, 0.950000, 1.000000 ), float3( 0.500000, 0.700000, 1.000000 ), _var49 ); + _var50 = _var50 - float( 1.000000 ); + _var47 = smoothstep( float( 0.100000 ), float( 0.600000 ), _var47 ); + _var50 = normalize( _var50 ); + _var46 = min( _var47, _var46 ); + _var17 = lerp( _var17, _var30, _var46 ); + _var22 = lerp( _var22, _var44, _var46 ); + _var17 = _var17 * float( 2.000000 ); + _var17 = _var17 - float( 1.000000 ); + _var17 = mul( _var17, _var8 ); + _var17 = normalize( _var17 ); + float _var52 = dot( _var17, _var20 ); + float _var53 = dot( _var17, _var50 ); + _var52 = abs( _var52 ); + _var53 = smoothstep( float( 0.995000 ), float( 0.996000 ), _var53 ); + _var52 = 1.0f - _var52; + _var51 = _var51 * _var53; + _var52 = pow( _var52, float( 3.000000 ) ); + _var51 = _var51 * float( 0.400000 ); + float _var54 = max( _var52, _var18 ); + _var51 = _var51 * _var47; +#if ( FLASHLIGHT == 1 ) + float3 _var55 = (float3)0; + float3 _var56 = (float3)0; + DoSpecularFlashlight( g_cFlashlightPos.xyz, In.vTexCoord_2, In.vColor_0, _var17, + g_cFlashlightAttenuationFactors.xyz, g_cFlashlightAttenuationFactors.w, + _gSampler_Flashlight_Cookie, _gSampler_Flashlight_Depth, _gSampler_Flashlight_Random, + FLASHLIGHTDEPTHFILTERMODE, FLASHLIGHTSHADOWS, true, + _var9, _var25, _var20, _var54, g_cShadowTweaks, + _var55, _var56 ); + _var0 = _var55; + _var12 = _var56; +#endif +#if ( FLASHLIGHT == 0 ) + float3 _var57 = (float3)0; + PixelShaderDoSpecularLighting( In.vTexCoord_2, _var17, _var25, _var20, + In.vTexCoord_3, NUM_LIGHTS, g_cLightInfo, + false, 1.0f, _var54, _var57 ); + float3 _var58 = PixelShaderDoLighting( In.vTexCoord_2, _var17, float3(0,0,0), + false, true, In.vTexCoord_3, + g_cAmbientCube, NUM_LIGHTS, g_cLightInfo, + false, false, 1.0f ); + _var12 = _var57; + _var0 = _var58; +#endif + _var0 = _var0; + _var12 = _var12; + _var0 = _var0 * _var22; + _var0 = _var0 + _var12; +#if ( FLASHLIGHT == 0 ) + float3 _var59 = reflect( _var11, _var17 ); + float3 _var60 = texCUBE( _Sampler_09, _var59 ).rgb; + _var60 = _var60 * ENV_MAP_SCALE; + float3 _var61 = _var60 * _var18; + _var61 = lerp( _var61, _var60, _var47 ); + _var61 = _var52 * _var61; + _var61 = _var61 * float( 0.100000 ); + _var0 = _var0 + _var61; +#endif + _var0 = _var0 + _var51; + float4 _var62 = float4( _var0, _var23 ); + _var62 = FinalOutput( _var62, _var14, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, true, _var16 ); + Out.vColor_0 = _var62; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/model_snowy_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/model_snowy_vs30.fxc new file mode 100644 index 00000000..9424faea --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/model_snowy_vs30.fxc @@ -0,0 +1,118 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + +// Combos +// DYNAMIC: "COMPRESSED_VERTS" "0..1" +// DYNAMIC: "MORPHING" "0..1" +// DYNAMIC: "SKINNING" "0..1" +// STATIC: "FLASHLIGHT" "0..1" + +// Includes +#include "common_vs_fxc.h" + + +// Samplers +sampler2D morphSampler : register( D3DVERTEXTEXTURESAMPLER0, s0 ); + +// Constants +const float3 _g_VecOrig : register( c48 ); +const float4x4 g_cFlashlightWorldToTexture : register( c49 ); +#ifdef SHADER_MODEL_VS_3_0 +const float3 g_cMorphTargetTextureDim : register( SHADER_SPECIFIC_CONST_10 ); +const float4 g_cMorphSubrect : register( SHADER_SPECIFIC_CONST_11 ); +#endif + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float3 vFlexDelta : POSITION1; + float3 vFlexDelta_Normal : NORMAL1; + float4 vBoneWeights : BLENDWEIGHT; + float4 vBoneIndices : BLENDINDICES; + float4 vNormal : NORMAL; + float4 vTangent_S : TANGENT; + float2 vTexCoord_0 : TEXCOORD0; +#ifdef SHADER_MODEL_VS_3_0 + float vVertexID : POSITION2; +#endif +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float4 vTexCoord_0 : TEXCOORD0; + float3 vTexCoord_1 : TEXCOORD1; + float3 vTexCoord_2 : TEXCOORD2; + float4 vTexCoord_3 : TEXCOORD3; + float4 vTexCoord_4 : TEXCOORD4; + float3 vTexCoord_5 : TEXCOORD5; + float3 vTexCoord_6 : TEXCOORD6; + float3 vTexCoord_7 : TEXCOORD7; + float4 vColor_0 : COLOR0; + float4 vColor_1 : COLOR1; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float3 _var0 = (float3)0; + float4 _var1 = (float4)0; + DecompressVertex_NormalTangent( In.vNormal, In.vTangent_S, _var0, _var1 ); + float2 _var2 = In.vPos.xy; + float4 _var3 = float4( 0.000000, 0.000000, 0.000000, 0.000000 ); + float _var4 = In.vPos.z; + float3 _var5 = _var1.xyz; + float _var6 = _var1.w; + float4 _var7 = float4( In.vTexCoord_0, _var2 ); + float3 _var8 = _var0 * _var0; + float3 _var9 = (float3)0; +#if !defined( SHADER_MODEL_VS_3_0 ) || !MORPHING + ApplyMorph( In.vFlexDelta, In.vFlexDelta_Normal, + In.vPos, _var9, + _var0, _var0, + _var5, _var5 ); +#else + ApplyMorph( morphSampler, g_cMorphTargetTextureDim, g_cMorphSubrect, + In.vVertexID, float3( 0, 0, 0 ), + In.vPos, _var9, + _var0, _var0, + _var5, _var5 ); +#endif + float4 _var10 = float4( _var8, _var4 ); + float4 _var11 = float4( _var5, _var6 ); + float3 _var12 = (float3)0; + float3 _var13 = (float3)0; + float3 _var14 = (float3)0; + float3 _var15 = (float3)0; + SkinPositionNormalAndTangentSpace( SKINNING, float4( _var9, 1 ), _var0, _var11, + In.vBoneWeights, In.vBoneIndices, + _var12, _var13, _var14, _var15 ); + float4 _var16 = mul( float4(_var12.xyz,1), cViewProj ); + _var13 = normalize( _var13 ); + float4 _var17 = float4( GetVertexAttenForLight( _var12, 0 ), + GetVertexAttenForLight( _var12, 1 ), + GetVertexAttenForLight( _var12, 2 ), + GetVertexAttenForLight( _var12, 3 ) ); + _var14 = normalize( _var14 ); + _var15 = normalize( _var15 ); + float3 _var18 = _var12 - _g_VecOrig; +#if ( FLASHLIGHT == 1 ) + float4 _var19 = mul( float4(_var12.xyz,1), g_cFlashlightWorldToTexture ); + _var3 = _var19; +#endif + Out.vProjPos = _var16; + Out.vTexCoord_0 = _var7; + Out.vTexCoord_1 = _var13; + Out.vTexCoord_2 = _var12; + Out.vTexCoord_3 = _var17; + Out.vTexCoord_4 = _var16; + Out.vTexCoord_5 = _var14; + Out.vTexCoord_6 = _var15; + Out.vTexCoord_7 = _var18; + Out.vColor_0 = _var3; + Out.vColor_1 = _var10; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/postproc_sunrays_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/postproc_sunrays_ps30.fxc new file mode 100644 index 00000000..bcf60e78 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/postproc_sunrays_ps30.fxc @@ -0,0 +1,69 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" + + +// Combos + +// Samplers +sampler _Sampler_00 : register( s0 ); +sampler _Sampler_01 : register( s1 ); + +// Constants +const float4 g_cData_sun_data : register( c0 ); // Callback + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float4 _texLookup_9 = tex2D( _Sampler_00, In.vTexCoord_0 ); + float3 _var0 = _texLookup_9.rgb; + float _var1 = _texLookup_9.a; + float3 _var2 = float3( 0.000000, 0.000000, 0.000000 ); + float2 _var3 = In.vTexCoord_0; + float2 _var4 = g_cData_sun_data.xy; + float _var5 = float( 1.000000 ); + float _var6 = g_cData_sun_data.z; + _var4 = In.vTexCoord_0 - _var4; + _var6 = saturate( _var6 ); + float _var7 = length( _var4 ); + float2 _var8 = _var4 / _var7; + float _var9 = smoothstep( float( 0.000000 ), float( 0.700000 ), _var7 ); + _var8 = _var8 * _var9; + _var8 = _var8 * float( 0.010000 ); + for ( int _var10 = 0; _var10 < 35; _var10++ ) + { + float2 _var11 = _var8; + _var5 = _var5 * float( 0.960000 ); + _var3 = _var3 - _var11; + float4 _texLookup_28 = tex2D( _Sampler_01, _var3 ); + float3 _var12 = _texLookup_28.rgb; + float _var13 = _texLookup_28.a; + _var12 = _var12 * _var13; + _var12 = _var12 * _var5; + _var2 = _var2 + _var12; + } + _var2 = _var2 * float( 0.050000 ); + _var2 = _var2 * _var6; + _var0 = _var0 + _var2; + float4 _var14 = float4( _var0, _var1 ); + Out.vColor_0 = _var14; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/postproc_sunrays_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/postproc_sunrays_vs30.fxc new file mode 100644 index 00000000..1bc4fd75 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/postproc_sunrays_vs30.fxc @@ -0,0 +1,36 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + +// Includes +#include "common_vs_fxc.h" + + +// Combos + +// Samplers + +// Constants + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float4 _var0 = float4( In.vPos.x, In.vPos.y, In.vPos.z, 1.000000 ); + Out.vProjPos = _var0; + Out.vTexCoord_0 = In.vTexCoord_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/sprite_sun_nodepth_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/sprite_sun_nodepth_ps30.fxc new file mode 100644 index 00000000..c1a736d1 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/sprite_sun_nodepth_ps30.fxc @@ -0,0 +1,41 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + +// Combos +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; + float4 vColor_0 : COLOR0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float4 _var0 = tex2D( _Sampler_00, In.vTexCoord_0 ).rgba; + _var0 = _var0 * In.vColor_0; + _var0 = FinalOutput( _var0, float( 0.000000 ), PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, false, 1.0f ); + Out.vColor_0 = _var0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/sprite_sun_nodepth_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/sprite_sun_nodepth_vs30.fxc new file mode 100644 index 00000000..f5c86cd6 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/sprite_sun_nodepth_vs30.fxc @@ -0,0 +1,34 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + + +// Includes +#include "common_vs_fxc.h" + + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; + float4 vColor_0 : COLOR0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; + float4 vColor_0 : COLOR0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float4 _var0 = mul( float4(In.vPos.xyz,1), cModelViewProj ); + Out.vProjPos = _var0; + Out.vTexCoord_0 = In.vTexCoord_0; + Out.vColor_0 = In.vColor_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_calc_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_calc_ps30.fxc new file mode 100644 index 00000000..3a7bda57 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_calc_ps30.fxc @@ -0,0 +1,228 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); + +// Constants +const float2 _g_TexelSize : register( c16 ); + +// User code - globals +#define PI 3.14159265 + +//-------------------------------------------------------- +//a list of user parameters + +#define METHOD 0 + +static float near = 7; //Z-near +static float far = 192.0; //Z-far +static float zScaleLinear = near / far; +static float zScaleLinearRev = far / near; + +#if ( METHOD == 0 ) +static int samples = 3; //samples on the first ring (3 - 5) +static int rings = 3; //ring count (3 - 5) +static float radius_close = 6.0; //ao radius +static float radius_far = 0.5; //ao radius +#else +static int samples = 24; //samples on the first ring (3 - 5) +static float radius_close = 7.0; //ao radius +static float radius_far = 1.5; //ao radius +#endif + +static float dist_exp = 6.0f; + +static float diffarea = 0.45; //self-shadowing reduction +static float gdisplace = 0.4; //gauss bell center + +static float lumInfluence = 0.4; //how much luminance affects occlusion +static float aoBoost_far = 2.5f; +static float aoBoost_close = 6.0f; + +static bool noise = true; //use noise instead of pattern for sample dithering? +static bool onlyAO = true; //use only ambient occlusion pass? +static bool fadeout = true; + +//-------------------------------------------------------- + +float2 rand(float2 coord, float2 size) //generating noise/pattern texture for dithering +{ + float noiseX = ((frac(1.0-coord.x*(size.x/2.0))*0.25)+(frac(coord.y*(size.y/2.0))*0.75))*2.0-1.0; + float noiseY = ((frac(1.0-coord.x*(size.x/2.0))*0.75)+(frac(coord.y*(size.y/2.0))*0.25))*2.0-1.0; + + if (noise) + { + noiseX = frac(sin(dot(coord ,float2(12.9898,78.233))) * 43758.5453) * 2.0-1.0; + noiseY = frac(sin(dot(coord ,float2(12.9898,78.233)*2.0)) * 43758.5453) * 2.0-1.0; + } + return float2(noiseX,noiseY)*0.001; +} + +float readDepth(in float2 coord, sampler tex) +{ + return tex2D(tex, coord ).a * zScaleLinear; + //return (2.0 * near) / (far + near - tex2D(tex, coord ).a * (far-near)); +} + +float readDepth(float linDepth) +{ + return linDepth * zScaleLinear; +} + +float compareDepths(in float depth1, in float depth2,inout int far) +{ + float garea = 2.0; //gauss bell width + float diff = (depth1 - depth2)*100.0; //depth difference (0-100) + //reduce left bell width to avoid self-shadowing + + + if ( diff < gdisplace ) + { + garea = diffarea; + }else{ + far = 1; + } + + float gauss = pow(2.7182,-2.0*(diff-gdisplace)*(diff-gdisplace)/(garea*garea)); + return gauss; +} + +float calAO(float2 uv,float localDepth, float depth, float dw, float dh, sampler tex) +{ + float dd = (1.0-depth)*lerp( radius_far, radius_close, localDepth ); + + float temp = 0.0; + float temp2 = 0.0; + float coordw = uv.x + dw*dd; + float coordh = uv.y + dh*dd; + float coordw2 = uv.x - dw*dd; + float coordh2 = uv.y - dh*dd; + + float2 coord = float2(coordw , coordh); + float2 coord2 = float2(coordw2, coordh2); + + int far = 0; + temp = compareDepths(depth, readDepth(coord,tex),far); + //DEPTH EXTRAPOLATION: + if (far > 0) + { + temp2 = compareDepths(readDepth(coord2,tex),depth,far); + temp += (1.0-temp)*temp2; + } + + return temp; +} + +// User code - function bodies +void DoSSAO( in float2 uv, in float2 texelSize, in sampler color_depth, out float ao_out ) +{ + float2 size = 1.0f / texelSize; + + float2 noise = rand(uv,size); + float depthSample = tex2D(color_depth, uv ).a; + float depth = readDepth(depthSample); + depthSample = pow( (1.0f - depthSample), dist_exp ); + float d; + + float w = texelSize.x/clamp(depth,0.25,1.0)+(noise.x*(1.0-noise.x)); + float h = texelSize.y/clamp(depth,0.25,1.0)+(noise.y*(1.0-noise.y)); + + float pw; + float ph; + + float ao; + float s; + + int ringsamples; + +#if (METHOD == 0) + for (int i = 1; i <= rings; i++) + { + ringsamples = i * samples; + for (int j = 0 ; j < ringsamples ; j += 1) + { + float step = PI*2.0 / float(ringsamples); + pw = (cos(float(j)*step)*float(i)); + ph = (sin(float(j)*step)*float(i)); + ao += calAO( uv, depthSample, depth, pw*w, ph*h, color_depth ); + s += 1.0; + } + } + ao /= s; + ao = 1.0-ao; +#else + float dl = PI*(3.0-sqrt(5.0)); + float dz = 1.0/float(samples); + float l = 0.0; + float z = 1.0 - dz/2.0; + + for (int i = 0; i <= samples; i ++) + { + float r = sqrt(1.0-z); + + pw = cos(l)*r; + ph = sin(l)*r; + ao += calAO(uv,depthSample,depth,pw*w,ph*h,color_depth); + z = z - dz; + l = l + dl; + } + + ao /= float(samples); + ao = 1.0-ao; +#endif + + float3 color = tex2D(color_depth,uv).rgb; + + float3 lumcoeff = float3(0.299,0.587,0.114); + float lum = dot(color.rgb, lumcoeff); + float3 luminance = float3(lum, lum, lum); + + ao = pow( ao, lerp( aoBoost_far, aoBoost_close, depthSample ) ); + + //lum = lerp(ao,1.0,luminance*lumInfluence); + ao_out = lerp(ao,1.0,luminance*lumInfluence); + + if ( fadeout ) + { + float fade = depth * zScaleLinearRev; + ao_out = lerp( ao_out, 0.65, pow( fade, 3 ) ); + } + + //if(onlyAO) + // ao = lum; //ambient occlusion only + //else + // col = color * lum; +} + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float _var0 = (float)0; + DoSSAO( In.vTexCoord_0, _g_TexelSize, _Sampler_00, _var0 ); + float4 _var1 = float4( _var0.x, _var0.x, _var0.x, 1.000000 ); + Out.vColor_0 = _var1; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_calc_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_calc_vs30.fxc new file mode 100644 index 00000000..9c0734a8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_calc_vs30.fxc @@ -0,0 +1,31 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + + +// Includes +#include "common_vs_fxc.h" + + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float4 _var0 = float4( In.vPos.x, In.vPos.y, In.vPos.z, 1.000000 ); + Out.vProjPos = _var0; + Out.vTexCoord_0 = In.vTexCoord_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_combine_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_combine_ps30.fxc new file mode 100644 index 00000000..5ffbad27 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_combine_ps30.fxc @@ -0,0 +1,43 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); +sampler _Sampler_01 : register( s1 ); + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float4 _texLookup_3 = tex2D( _Sampler_00, In.vTexCoord_0 ); + float3 _var0 = _texLookup_3.rgb; + float _var1 = _texLookup_3.a; + float _var2 = tex2D( _Sampler_01, In.vTexCoord_0 ).r; + _var2 = _var2 * float( 2.000000 ); + _var0 = _var0 * _var2; + _var0 = _var0 * float( 0.850000 ); + float4 _var3 = float4( _var0, _var1 ); + Out.vColor_0 = _var3; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_combine_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_combine_vs30.fxc new file mode 100644 index 00000000..9c0734a8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_combine_vs30.fxc @@ -0,0 +1,31 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + + +// Includes +#include "common_vs_fxc.h" + + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float4 _var0 = float4( In.vPos.x, In.vPos.y, In.vPos.z, 1.000000 ); + Out.vProjPos = _var0; + Out.vTexCoord_0 = In.vTexCoord_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_fxaa_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_fxaa_ps30.fxc new file mode 100644 index 00000000..06ce553f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_fxaa_ps30.fxc @@ -0,0 +1,97 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); + +// Constants +const float2 _g_TexelSize : register( c16 ); + +// User code - globals +#define FXAA_PC 1 +#define FXAA_HLSL_3 1 +#define FXAA_GREEN_AS_LUMA 1 +#define FXAA_DISCARD 1 +#define FXAA_QUALITY__PRESET 10 + +#include "fxaa3_11.h" + +// User code - function bodies +void DoFXAA( in sampler tex, in float2 uv, in float2 texelsize, out float4 col ) +{ + col = FxaaPixelShader( uv, + (float4)0, + tex, + tex, + tex, + texelsize, + (float4)0, + (float4)0, + (float4)0, + // fxaaQualitySubpix + // This used to be the FXAA_QUALITY__SUBPIX define. + // It is here now to allow easier tuning. + // Choose the amount of sub-pixel aliasing removal. + // This can effect sharpness. + // 1.00 - upper limit (softer) + // 0.75 - default amount of filtering + // 0.50 - lower limit (sharper, less sub-pixel aliasing removal) + // 0.25 - almost off + // 0.00 - completely off + 0.5, + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // The minimum amount of local contrast required to apply algorithm. + // 0.333 - too little (faster) + // 0.250 - low quality + // 0.166 - default + // 0.125 - high quality + // 0.063 - overkill (slower) + // fxaaQualityEdgeThreshold + 0.2, + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // 0.0833 - upper limit (default, the start of visible unfiltered edges) + // 0.0625 - high quality (faster) + // 0.0312 - visible limit (slower) + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + 0.0833, + 0, 0, 0, (float4)0 ); +} + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float4 _var0 = (float4)0; + DoFXAA( _Sampler_00, In.vTexCoord_0, _g_TexelSize, _var0 ); + Out.vColor_0 = _var0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_fxaa_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_fxaa_vs30.fxc new file mode 100644 index 00000000..9c0734a8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/ssao_fxaa_vs30.fxc @@ -0,0 +1,31 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + + +// Includes +#include "common_vs_fxc.h" + + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float4 _var0 = float4( In.vPos.x, In.vPos.y, In.vPos.z, 1.000000 ); + Out.vProjPos = _var0; + Out.vTexCoord_0 = In.vTexCoord_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/sunrays_calc_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/sunrays_calc_ps30.fxc new file mode 100644 index 00000000..e15e593a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/sunrays_calc_ps30.fxc @@ -0,0 +1,64 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); + +// Constants +const float4 g_cData_sun_data : register( c16 ); // Callback + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float3 _var0 = float3( 0.000000, 0.000000, 0.000000 ); + float2 _var1 = In.vTexCoord_0; + float2 _var2 = g_cData_sun_data.xy; + float _var3 = float( 1.000000 ); + float _var4 = g_cData_sun_data.z; + _var2 = In.vTexCoord_0 - _var2; + _var4 = saturate( _var4 ); + float _var5 = length( _var2 ); + float2 _var6 = _var2 / _var5; + float _var7 = smoothstep( float( 0.000000 ), float( 0.700000 ), _var5 ); + _var6 = _var6 * _var7; + _var6 = _var6 * float( 0.011000 ); + for ( int _var8 = 0; _var8 < 35; _var8++ ) + { + float2 _var9 = _var6; + _var3 = _var3 * float( 0.950000 ); + _var1 = _var1 - _var9; + float4 _texLookup_26 = tex2D( _Sampler_00, _var1 ); + float3 _var10 = _texLookup_26.rgb; + float _var11 = _texLookup_26.a; + _var10 = _var10 * _var11; + _var10 = _var10 * _var3; + _var0 = _var0 + _var10; + } + _var0 = _var0 * float( 0.060000 ); + _var0 = _var0 * _var4; + float4 _var12 = float4( _var0.x, _var0.y, _var0.z, 1.000000 ); + Out.vColor_0 = _var12; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/sunrays_calc_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/sunrays_calc_vs30.fxc new file mode 100644 index 00000000..9c0734a8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/sunrays_calc_vs30.fxc @@ -0,0 +1,31 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + + +// Includes +#include "common_vs_fxc.h" + + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float4 _var0 = float4( In.vPos.x, In.vPos.y, In.vPos.z, 1.000000 ); + Out.vProjPos = _var0; + Out.vTexCoord_0 = In.vTexCoord_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/swarm_test_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/swarm_test_ps30.fxc new file mode 100644 index 00000000..8bf67b80 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/swarm_test_ps30.fxc @@ -0,0 +1,59 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); +sampler _Sampler_01 : register( s1 ); + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float3 _var0 = float3( 0.000000, 0.000000, 0.000000 ); + float4 _texLookup_12 = tex2D( _Sampler_00, In.vTexCoord_0 ); + float3 _var1 = _texLookup_12.rgb; + float _var2 = _texLookup_12.a; + for ( int _var3 = -40; _var3 <= 40; _var3++ ) + { + float2 _var4 = float2( 0.005000, 0.000000 ) * _var3; + float _var5 = abs( _var3 ); + _var4 = _var4 + In.vTexCoord_0; + _var5 = _var5 / float( 25.000000 ); + float3 _var6 = tex2D( _Sampler_01, _var4 ).rgb; + float _var7 = _var4.x; + _var5 = 1.0f - _var5; + _var6 = smoothstep( float( 0.250000 ), float( 0.350000 ), _var6 ); + _var7 = _var7 - float( 0.500000 ); + _var5 = pow( _var5, float( 2.000000 ) ); + _var7 = abs( _var7 ); + _var7 = smoothstep( float( 0.500000 ), float( 0.400000 ), _var7 ); + _var7 = _var7 * _var5; + _var6 = _var6 * _var7; + _var0 = _var0 + _var6; + } + _var0 = _var0 * float3( 0.030000, 0.040000, 0.050000 ); + _var0 = _var0 + _var1; + float4 _var8 = float4( _var0, _var2 ); + Out.vColor_0 = _var8; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/swarm_test_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/swarm_test_vs30.fxc new file mode 100644 index 00000000..1063824b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/swarm_test_vs30.fxc @@ -0,0 +1,30 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + +// Includes +#include "common_vs_fxc.h" + + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float4 _var0 = float4( In.vPos.x, In.vPos.y, In.vPos.z, 1.000000 ); + Out.vProjPos = _var0; + Out.vTexCoord_0 = In.vTexCoord_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/uniquefilestocopy.txt b/sp/src/materialsystem/stdshaders/ShaderEdit/uniquefilestocopy.txt new file mode 100644 index 00000000..4e9258b9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/uniquefilestocopy.txt @@ -0,0 +1,17 @@ +bin\dx_proxy.dll +..\..\..\..\common\sourcesdk\bin\source2007\bin\tier0.dll +..\..\..\..\common\sourcesdk\bin\source2007\bin\vstdlib.dll +common_fxc.h +common_hlsl_cpp_consts.h +common_pragmas.h +common_ps_fxc.h +common_vs_fxc.h +common_vertexlitgeneric_dx9.h +common_lightmappedgeneric_fxc.h +common_flashlight_fxc.h +common_parallax.h +..\..\..\..\common\sourcesdk\bin\source2007\bin\shadercompile.exe +..\..\..\..\common\sourcesdk\bin\source2007\bin\shadercompile_dll.dll +000000_lightmap_parallax_pos_preview_vs30.fxc +000000_lightmap_parallax_preview_vs30.fxc +000000_lightmap_parallax_preview_ps30.fxc diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/unnamedshader_ps30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/unnamedshader_ps30.fxc new file mode 100644 index 00000000..b3ced570 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/unnamedshader_ps30.fxc @@ -0,0 +1,90 @@ +// ******************************** +// ** auto generated pixelshader ** +// ******************************** + +// Combos +// DYNAMIC: "FLASHLIGHT" "0..1" +// DYNAMIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" +// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" +// DYNAMIC: "PIXELFOGTYPE" "0..1" +// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1" + +// Includes +#include "common_ps_fxc.h" +#include "common_vertexlitgeneric_dx9.h" +#include "common_lightmappedgeneric_fxc.h" +#include "common_flashlight_fxc.h" +#include "common_parallax.h" + + +// Samplers +sampler _Sampler_00 : register( s0 ); +sampler _Sampler_01 : register( s1 ); +sampler _Sampler_02 : register( s2 ); +sampler _gSampler_Flashlight_Cookie : register( s3 ); +sampler _gSampler_Flashlight_Depth : register( s4 ); +sampler _gSampler_Flashlight_Random : register( s5 ); + +// Constants +const float4x4 g_cFlashlightWorldToTexture : register( c12 ); +const float4 _g_FogParams : register( c16 ); +const float3 _g_VecOrig : register( c17 ); +const float4 g_cFlashlightAttenuationFactors : register( c8 ); +const float4 g_cFlashlightPos : register( c9 ); +const float4 g_cShadowTweaks : register( c7 ); + +// Semantic structures +struct PS_INPUT +{ + float2 vTexCoord_0 : TEXCOORD0; + float2 vTexCoord_1 : TEXCOORD1; + float3 vTexCoord_2 : TEXCOORD2; + float3 vTexCoord_3 : TEXCOORD3; + float4 vTexCoord_4 : TEXCOORD4; + float4 vColor_0 : COLOR0; +}; + +struct PS_OUTPUT +{ + float4 vColor_0 : COLOR0; +}; + +// Entry point +PS_OUTPUT main( const PS_INPUT In ) +{ + PS_OUTPUT Out; + float3 _var0 = float3( 0.000000, 0.000000, 0.000000 ); + float3 _var1 = tex2D( _Sampler_00, In.vTexCoord_0 ).rgb; + float3 _var2 = tex2D( _Sampler_01, In.vTexCoord_0 ).rgb; + float _var3 = In.vColor_0.w; + float _var4 = _g_VecOrig.z; + float _var5 = In.vTexCoord_3.z; + float _var6 = In.vTexCoord_4.z; +#if ( FLASHLIGHT == 0 ) + float3 _var7 = tex2D( _Sampler_02, In.vTexCoord_1 ).rgb; + _var7 = _var7 * LIGHT_MAP_SCALE; + _var0 = _var7; +#endif +#if ( FLASHLIGHT == 1 ) + float4 _var8 = mul( float4(In.vTexCoord_3.xyz,1), g_cFlashlightWorldToTexture ); + float2 _var9 = In.vTexCoord_4.xy; + float _var10 = In.vTexCoord_4.w; + _var9 = _var9 / _var10; + _var9 = _var9 * float( 0.500000 ); + _var9 = _var9 + float( 0.500000 ); + float3 _var11 = DoFlashlight( g_cFlashlightPos.xyz, In.vTexCoord_3, _var8, In.vTexCoord_2, + g_cFlashlightAttenuationFactors.xyz, g_cFlashlightAttenuationFactors.w, + _gSampler_Flashlight_Cookie, _gSampler_Flashlight_Depth, _gSampler_Flashlight_Random, + FLASHLIGHTDEPTHFILTERMODE, FLASHLIGHTSHADOWS, true, + _var9, false, g_cShadowTweaks ); + _var0 = _var11; +#endif + _var0 = _var0; + _var1 = lerp( _var1, _var2, _var3 ); + _var4 = CalcPixelFogFactor( PIXELFOGTYPE, _g_FogParams, _var4, _var5, _var6 ); + _var0 = _var0 * _var1; + float4 _var12 = float4( _var0.x, _var0.y, _var0.z, 1.000000 ); + _var12 = FinalOutput( _var12, _var4, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, true, _var6 ); + Out.vColor_0 = _var12; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/ShaderEdit/unnamedshader_vs30.fxc b/sp/src/materialsystem/stdshaders/ShaderEdit/unnamedshader_vs30.fxc new file mode 100644 index 00000000..49e60abd --- /dev/null +++ b/sp/src/materialsystem/stdshaders/ShaderEdit/unnamedshader_vs30.fxc @@ -0,0 +1,46 @@ +// ********************************* +// ** auto generated vertexshader ** +// ********************************* + + +// Includes +#include "common_vs_fxc.h" + + +// Semantic structures +struct VS_INPUT +{ + float3 vPos : POSITION; + float3 vNormal : NORMAL; + float2 vTexCoord_0 : TEXCOORD0; + float2 vTexCoord_1 : TEXCOORD1; + float4 vColor_0 : COLOR0; +}; + +struct VS_OUTPUT +{ + float4 vProjPos : POSITION; + float2 vTexCoord_0 : TEXCOORD0; + float2 vTexCoord_1 : TEXCOORD1; + float3 vTexCoord_2 : TEXCOORD2; + float3 vTexCoord_3 : TEXCOORD3; + float4 vTexCoord_4 : TEXCOORD4; + float4 vColor_0 : COLOR0; +}; + +// Entry point +VS_OUTPUT main( const VS_INPUT In ) +{ + VS_OUTPUT Out; + float3 _var0 = mul( float4(In.vPos.xyz,1), cModel[0] ); + float3 _var1 = mul( float4(In.vNormal.xyz,1), cModel[0] ); + float4 _var2 = mul( float4(_var0.xyz,1), cViewProj ); + Out.vProjPos = _var2; + Out.vTexCoord_0 = In.vTexCoord_0; + Out.vTexCoord_1 = In.vTexCoord_1; + Out.vTexCoord_2 = _var1; + Out.vTexCoord_3 = _var0; + Out.vTexCoord_4 = _var2; + Out.vColor_0 = In.vColor_0; + return Out; +} \ No newline at end of file diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_Bloom_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_Bloom_ps20b.inc new file mode 100644 index 00000000..169870ee --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_Bloom_ps20b.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_bloom_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_bloom_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_bloom_ps20b 0 +class sdk_bloom_ps20b_Dynamic_Index +{ +public: + sdk_bloom_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_bloom_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_Refract_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_Refract_vs20.inc new file mode 100644 index 00000000..58adb397 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_Refract_vs20.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_refract_vs20_Static_Index +{ +private: + int m_nMODEL; +#ifdef _DEBUG + bool m_bMODEL; +#endif +public: + void SetMODEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMODEL = i; +#ifdef _DEBUG + m_bMODEL = true; +#endif + } + void SetMODEL( bool i ) + { + m_nMODEL = i ? 1 : 0; +#ifdef _DEBUG + m_bMODEL = true; +#endif + } +private: + int m_nCOLORMODULATE; +#ifdef _DEBUG + bool m_bCOLORMODULATE; +#endif +public: + void SetCOLORMODULATE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLORMODULATE = i; +#ifdef _DEBUG + m_bCOLORMODULATE = true; +#endif + } + void SetCOLORMODULATE( bool i ) + { + m_nCOLORMODULATE = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLORMODULATE = true; +#endif + } +public: + sdk_refract_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bMODEL = false; +#endif // _DEBUG + m_nMODEL = 0; +#ifdef _DEBUG + m_bCOLORMODULATE = false; +#endif // _DEBUG + m_nCOLORMODULATE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bMODEL && m_bCOLORMODULATE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nMODEL ) + ( 8 * m_nCOLORMODULATE ) + 0; + } +}; +#define shaderStaticTest_sdk_refract_vs20 vsh_forgot_to_set_static_MODEL + vsh_forgot_to_set_static_COLORMODULATE + 0 +class sdk_refract_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_refract_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_refract_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_ShatteredGlass_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_ShatteredGlass_ps20.inc new file mode 100644 index 00000000..161c4c79 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_ShatteredGlass_ps20.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_shatteredglass_ps20_Static_Index +{ +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nHDRTYPE; +#ifdef _DEBUG + bool m_bHDRTYPE; +#endif +public: + void SetHDRTYPE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nHDRTYPE = i; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } + void SetHDRTYPE( bool i ) + { + m_nHDRTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } +private: + int m_nPARALLAXCORRECT; +#ifdef _DEBUG + bool m_bPARALLAXCORRECT; +#endif +public: + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } + void SetPARALLAXCORRECT( bool i ) + { + m_nPARALLAXCORRECT = i ? 1 : 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } +public: + sdk_shatteredglass_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bHDRTYPE = false; +#endif // _DEBUG + m_nHDRTYPE = 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + m_nPARALLAXCORRECT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCUBEMAP && m_bVERTEXCOLOR && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bHDRTYPE && m_bPARALLAXCORRECT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nCUBEMAP ) + ( 4 * m_nVERTEXCOLOR ) + ( 8 * m_nENVMAPMASK ) + ( 16 * m_nBASEALPHAENVMAPMASK ) + ( 32 * m_nHDRTYPE ) + ( 96 * m_nPARALLAXCORRECT ) + 0; + } +}; +#define shaderStaticTest_sdk_shatteredglass_ps20 psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_HDRTYPE + psh_forgot_to_set_static_PARALLAXCORRECT + 0 +class sdk_shatteredglass_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_shatteredglass_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_shatteredglass_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_ShatteredGlass_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_ShatteredGlass_ps20b.inc new file mode 100644 index 00000000..5c79bd11 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_ShatteredGlass_ps20b.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_shatteredglass_ps20b_Static_Index +{ +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nHDRTYPE; +#ifdef _DEBUG + bool m_bHDRTYPE; +#endif +public: + void SetHDRTYPE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nHDRTYPE = i; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } + void SetHDRTYPE( bool i ) + { + m_nHDRTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } +private: + int m_nPARALLAXCORRECT; +#ifdef _DEBUG + bool m_bPARALLAXCORRECT; +#endif +public: + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } + void SetPARALLAXCORRECT( bool i ) + { + m_nPARALLAXCORRECT = i ? 1 : 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } +public: + sdk_shatteredglass_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bHDRTYPE = false; +#endif // _DEBUG + m_nHDRTYPE = 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + m_nPARALLAXCORRECT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCUBEMAP && m_bVERTEXCOLOR && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bHDRTYPE && m_bPARALLAXCORRECT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nCUBEMAP ) + ( 4 * m_nVERTEXCOLOR ) + ( 8 * m_nENVMAPMASK ) + ( 16 * m_nBASEALPHAENVMAPMASK ) + ( 32 * m_nHDRTYPE ) + ( 96 * m_nPARALLAXCORRECT ) + 0; + } +}; +#define shaderStaticTest_sdk_shatteredglass_ps20b psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_HDRTYPE + psh_forgot_to_set_static_PARALLAXCORRECT + 0 +class sdk_shatteredglass_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_shatteredglass_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_shatteredglass_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_ShatteredGlass_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_ShatteredGlass_vs20.inc new file mode 100644 index 00000000..a3e18d53 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_ShatteredGlass_vs20.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_shatteredglass_vs20_Static_Index +{ +private: + int m_nENVMAP_MASK; +#ifdef _DEBUG + bool m_bENVMAP_MASK; +#endif +public: + void SetENVMAP_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAP_MASK = i; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif + } + void SetENVMAP_MASK( bool i ) + { + m_nENVMAP_MASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif + } +public: + sdk_shatteredglass_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bENVMAP_MASK = false; +#endif // _DEBUG + m_nENVMAP_MASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bENVMAP_MASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nENVMAP_MASK ) + 0; + } +}; +#define shaderStaticTest_sdk_shatteredglass_vs20 vsh_forgot_to_set_static_ENVMAP_MASK + 0 +class sdk_shatteredglass_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_shatteredglass_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_shatteredglass_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_UnlitGeneric_MaskBaseByDetailAlpha_ps11.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_UnlitGeneric_MaskBaseByDetailAlpha_ps11.inc new file mode 100644 index 00000000..522e1e9e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_UnlitGeneric_MaskBaseByDetailAlpha_ps11.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_unlitgeneric_maskbasebydetailalpha_ps11_Static_Index +{ +public: + sdk_unlitgeneric_maskbasebydetailalpha_ps11_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_unlitgeneric_maskbasebydetailalpha_ps11 0 +class sdk_unlitgeneric_maskbasebydetailalpha_ps11_Dynamic_Index +{ +public: + sdk_unlitgeneric_maskbasebydetailalpha_ps11_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_unlitgeneric_maskbasebydetailalpha_ps11 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WaterCheap_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WaterCheap_ps20.inc new file mode 100644 index 00000000..49475ba9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WaterCheap_ps20.inc @@ -0,0 +1,237 @@ +#include "shaderlib/cshader.h" +class sdk_watercheap_ps20_Static_Index +{ +private: + int m_nMULTITEXTURE; +#ifdef _DEBUG + bool m_bMULTITEXTURE; +#endif +public: + void SetMULTITEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMULTITEXTURE = i; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } + void SetMULTITEXTURE( bool i ) + { + m_nMULTITEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } +private: + int m_nFRESNEL; +#ifdef _DEBUG + bool m_bFRESNEL; +#endif +public: + void SetFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFRESNEL = i; +#ifdef _DEBUG + m_bFRESNEL = true; +#endif + } + void SetFRESNEL( bool i ) + { + m_nFRESNEL = i ? 1 : 0; +#ifdef _DEBUG + m_bFRESNEL = true; +#endif + } +private: + int m_nBLEND; +#ifdef _DEBUG + bool m_bBLEND; +#endif +public: + void SetBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLEND = i; +#ifdef _DEBUG + m_bBLEND = true; +#endif + } + void SetBLEND( bool i ) + { + m_nBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bBLEND = true; +#endif + } +private: + int m_nREFRACTALPHA; +#ifdef _DEBUG + bool m_bREFRACTALPHA; +#endif +public: + void SetREFRACTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACTALPHA = i; +#ifdef _DEBUG + m_bREFRACTALPHA = true; +#endif + } + void SetREFRACTALPHA( bool i ) + { + m_nREFRACTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACTALPHA = true; +#endif + } +private: + int m_nHDRTYPE; +#ifdef _DEBUG + bool m_bHDRTYPE; +#endif +public: + void SetHDRTYPE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nHDRTYPE = i; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } + void SetHDRTYPE( bool i ) + { + m_nHDRTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } +private: + int m_nNORMAL_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMAL_DECODE_MODE; +#endif +public: + void SetNORMAL_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMAL_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } + void SetNORMAL_DECODE_MODE( bool i ) + { + m_nNORMAL_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } +public: + sdk_watercheap_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bMULTITEXTURE = false; +#endif // _DEBUG + m_nMULTITEXTURE = 0; +#ifdef _DEBUG + m_bFRESNEL = false; +#endif // _DEBUG + m_nFRESNEL = 0; +#ifdef _DEBUG + m_bBLEND = false; +#endif // _DEBUG + m_nBLEND = 0; +#ifdef _DEBUG + m_bREFRACTALPHA = false; +#endif // _DEBUG + m_nREFRACTALPHA = 0; +#ifdef _DEBUG + m_bHDRTYPE = false; +#endif // _DEBUG + m_nHDRTYPE = 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMAL_DECODE_MODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bMULTITEXTURE && m_bFRESNEL && m_bBLEND && m_bREFRACTALPHA && m_bHDRTYPE && m_bNORMAL_DECODE_MODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nMULTITEXTURE ) + ( 8 * m_nFRESNEL ) + ( 16 * m_nBLEND ) + ( 32 * m_nREFRACTALPHA ) + ( 64 * m_nHDRTYPE ) + ( 192 * m_nNORMAL_DECODE_MODE ) + 0; + } +}; +#define shaderStaticTest_sdk_watercheap_ps20 psh_forgot_to_set_static_MULTITEXTURE + psh_forgot_to_set_static_FRESNEL + psh_forgot_to_set_static_BLEND + psh_forgot_to_set_static_REFRACTALPHA + psh_forgot_to_set_static_HDRTYPE + psh_forgot_to_set_static_NORMAL_DECODE_MODE + 0 +class sdk_watercheap_ps20_Dynamic_Index +{ +private: + int m_nHDRENABLED; +#ifdef _DEBUG + bool m_bHDRENABLED; +#endif +public: + void SetHDRENABLED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHDRENABLED = i; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } + void SetHDRENABLED( bool i ) + { + m_nHDRENABLED = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_watercheap_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bHDRENABLED = false; +#endif // _DEBUG + m_nHDRENABLED = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bHDRENABLED && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nHDRENABLED ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_watercheap_ps20 psh_forgot_to_set_dynamic_HDRENABLED + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WaterCheap_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WaterCheap_ps20b.inc new file mode 100644 index 00000000..6ddfc76f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WaterCheap_ps20b.inc @@ -0,0 +1,262 @@ +#include "shaderlib/cshader.h" +class sdk_watercheap_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nMULTITEXTURE; +#ifdef _DEBUG + bool m_bMULTITEXTURE; +#endif +public: + void SetMULTITEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMULTITEXTURE = i; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } + void SetMULTITEXTURE( bool i ) + { + m_nMULTITEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } +private: + int m_nFRESNEL; +#ifdef _DEBUG + bool m_bFRESNEL; +#endif +public: + void SetFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFRESNEL = i; +#ifdef _DEBUG + m_bFRESNEL = true; +#endif + } + void SetFRESNEL( bool i ) + { + m_nFRESNEL = i ? 1 : 0; +#ifdef _DEBUG + m_bFRESNEL = true; +#endif + } +private: + int m_nBLEND; +#ifdef _DEBUG + bool m_bBLEND; +#endif +public: + void SetBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLEND = i; +#ifdef _DEBUG + m_bBLEND = true; +#endif + } + void SetBLEND( bool i ) + { + m_nBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bBLEND = true; +#endif + } +private: + int m_nREFRACTALPHA; +#ifdef _DEBUG + bool m_bREFRACTALPHA; +#endif +public: + void SetREFRACTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACTALPHA = i; +#ifdef _DEBUG + m_bREFRACTALPHA = true; +#endif + } + void SetREFRACTALPHA( bool i ) + { + m_nREFRACTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACTALPHA = true; +#endif + } +private: + int m_nHDRTYPE; +#ifdef _DEBUG + bool m_bHDRTYPE; +#endif +public: + void SetHDRTYPE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nHDRTYPE = i; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } + void SetHDRTYPE( bool i ) + { + m_nHDRTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } +private: + int m_nNORMAL_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMAL_DECODE_MODE; +#endif +public: + void SetNORMAL_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMAL_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } + void SetNORMAL_DECODE_MODE( bool i ) + { + m_nNORMAL_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } +public: + sdk_watercheap_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bMULTITEXTURE = false; +#endif // _DEBUG + m_nMULTITEXTURE = 0; +#ifdef _DEBUG + m_bFRESNEL = false; +#endif // _DEBUG + m_nFRESNEL = 0; +#ifdef _DEBUG + m_bBLEND = false; +#endif // _DEBUG + m_nBLEND = 0; +#ifdef _DEBUG + m_bREFRACTALPHA = false; +#endif // _DEBUG + m_nREFRACTALPHA = 0; +#ifdef _DEBUG + m_bHDRTYPE = false; +#endif // _DEBUG + m_nHDRTYPE = 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMAL_DECODE_MODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bMULTITEXTURE && m_bFRESNEL && m_bBLEND && m_bREFRACTALPHA && m_bHDRTYPE && m_bNORMAL_DECODE_MODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nMULTITEXTURE ) + ( 16 * m_nFRESNEL ) + ( 32 * m_nBLEND ) + ( 64 * m_nREFRACTALPHA ) + ( 128 * m_nHDRTYPE ) + ( 384 * m_nNORMAL_DECODE_MODE ) + 0; + } +}; +#define shaderStaticTest_sdk_watercheap_ps20b psh_forgot_to_set_static_MULTITEXTURE + psh_forgot_to_set_static_FRESNEL + psh_forgot_to_set_static_BLEND + psh_forgot_to_set_static_REFRACTALPHA + psh_forgot_to_set_static_HDRTYPE + psh_forgot_to_set_static_NORMAL_DECODE_MODE + 0 +class sdk_watercheap_ps20b_Dynamic_Index +{ +private: + int m_nHDRENABLED; +#ifdef _DEBUG + bool m_bHDRENABLED; +#endif +public: + void SetHDRENABLED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHDRENABLED = i; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } + void SetHDRENABLED( bool i ) + { + m_nHDRENABLED = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_watercheap_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bHDRENABLED = false; +#endif // _DEBUG + m_nHDRENABLED = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bHDRENABLED && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nHDRENABLED ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_watercheap_ps20b psh_forgot_to_set_dynamic_HDRENABLED + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WaterCheap_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WaterCheap_vs20.inc new file mode 100644 index 00000000..49244f88 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WaterCheap_vs20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_watercheap_vs20_Static_Index +{ +private: + int m_nBLEND; +#ifdef _DEBUG + bool m_bBLEND; +#endif +public: + void SetBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLEND = i; +#ifdef _DEBUG + m_bBLEND = true; +#endif + } + void SetBLEND( bool i ) + { + m_nBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bBLEND = true; +#endif + } +public: + sdk_watercheap_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bBLEND = false; +#endif // _DEBUG + m_nBLEND = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBLEND; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nBLEND ) + 0; + } +}; +#define shaderStaticTest_sdk_watercheap_vs20 vsh_forgot_to_set_static_BLEND + 0 +class sdk_watercheap_vs20_Dynamic_Index +{ +public: + sdk_watercheap_vs20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_watercheap_vs20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_Water_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_Water_ps20.inc new file mode 100644 index 00000000..4929b59c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_Water_ps20.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_water_ps20_Static_Index +{ +private: + int m_nBASETEXTURE; +#ifdef _DEBUG + bool m_bBASETEXTURE; +#endif +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } + void SetBASETEXTURE( bool i ) + { + m_nBASETEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } +private: + int m_nMULTITEXTURE; +#ifdef _DEBUG + bool m_bMULTITEXTURE; +#endif +public: + void SetMULTITEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMULTITEXTURE = i; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } + void SetMULTITEXTURE( bool i ) + { + m_nMULTITEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } +private: + int m_nREFLECT; +#ifdef _DEBUG + bool m_bREFLECT; +#endif +public: + void SetREFLECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFLECT = i; +#ifdef _DEBUG + m_bREFLECT = true; +#endif + } + void SetREFLECT( bool i ) + { + m_nREFLECT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFLECT = true; +#endif + } +private: + int m_nREFRACT; +#ifdef _DEBUG + bool m_bREFRACT; +#endif +public: + void SetREFRACT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACT = i; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } + void SetREFRACT( bool i ) + { + m_nREFRACT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } +private: + int m_nABOVEWATER; +#ifdef _DEBUG + bool m_bABOVEWATER; +#endif +public: + void SetABOVEWATER( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nABOVEWATER = i; +#ifdef _DEBUG + m_bABOVEWATER = true; +#endif + } + void SetABOVEWATER( bool i ) + { + m_nABOVEWATER = i ? 1 : 0; +#ifdef _DEBUG + m_bABOVEWATER = true; +#endif + } +private: + int m_nNORMAL_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMAL_DECODE_MODE; +#endif +public: + void SetNORMAL_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMAL_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } + void SetNORMAL_DECODE_MODE( bool i ) + { + m_nNORMAL_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } +public: + sdk_water_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bBASETEXTURE = false; +#endif // _DEBUG + m_nBASETEXTURE = 0; +#ifdef _DEBUG + m_bMULTITEXTURE = false; +#endif // _DEBUG + m_nMULTITEXTURE = 0; +#ifdef _DEBUG + m_bREFLECT = false; +#endif // _DEBUG + m_nREFLECT = 0; +#ifdef _DEBUG + m_bREFRACT = false; +#endif // _DEBUG + m_nREFRACT = 0; +#ifdef _DEBUG + m_bABOVEWATER = false; +#endif // _DEBUG + m_nABOVEWATER = 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMAL_DECODE_MODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBASETEXTURE && m_bMULTITEXTURE && m_bREFLECT && m_bREFRACT && m_bABOVEWATER && m_bNORMAL_DECODE_MODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nBASETEXTURE ) + ( 4 * m_nMULTITEXTURE ) + ( 8 * m_nREFLECT ) + ( 16 * m_nREFRACT ) + ( 32 * m_nABOVEWATER ) + ( 64 * m_nNORMAL_DECODE_MODE ) + 0; + } +}; +#define shaderStaticTest_sdk_water_ps20 psh_forgot_to_set_static_BASETEXTURE + psh_forgot_to_set_static_MULTITEXTURE + psh_forgot_to_set_static_REFLECT + psh_forgot_to_set_static_REFRACT + psh_forgot_to_set_static_ABOVEWATER + psh_forgot_to_set_static_NORMAL_DECODE_MODE + 0 +class sdk_water_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_water_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_water_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_Water_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_Water_ps20b.inc new file mode 100644 index 00000000..675efa7a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_Water_ps20b.inc @@ -0,0 +1,287 @@ +#include "shaderlib/cshader.h" +class sdk_water_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nBASETEXTURE; +#ifdef _DEBUG + bool m_bBASETEXTURE; +#endif +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } + void SetBASETEXTURE( bool i ) + { + m_nBASETEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } +private: + int m_nMULTITEXTURE; +#ifdef _DEBUG + bool m_bMULTITEXTURE; +#endif +public: + void SetMULTITEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMULTITEXTURE = i; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } + void SetMULTITEXTURE( bool i ) + { + m_nMULTITEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } +private: + int m_nREFLECT; +#ifdef _DEBUG + bool m_bREFLECT; +#endif +public: + void SetREFLECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFLECT = i; +#ifdef _DEBUG + m_bREFLECT = true; +#endif + } + void SetREFLECT( bool i ) + { + m_nREFLECT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFLECT = true; +#endif + } +private: + int m_nREFRACT; +#ifdef _DEBUG + bool m_bREFRACT; +#endif +public: + void SetREFRACT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACT = i; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } + void SetREFRACT( bool i ) + { + m_nREFRACT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } +private: + int m_nABOVEWATER; +#ifdef _DEBUG + bool m_bABOVEWATER; +#endif +public: + void SetABOVEWATER( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nABOVEWATER = i; +#ifdef _DEBUG + m_bABOVEWATER = true; +#endif + } + void SetABOVEWATER( bool i ) + { + m_nABOVEWATER = i ? 1 : 0; +#ifdef _DEBUG + m_bABOVEWATER = true; +#endif + } +private: + int m_nBLURRY_REFRACT; +#ifdef _DEBUG + bool m_bBLURRY_REFRACT; +#endif +public: + void SetBLURRY_REFRACT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLURRY_REFRACT = i; +#ifdef _DEBUG + m_bBLURRY_REFRACT = true; +#endif + } + void SetBLURRY_REFRACT( bool i ) + { + m_nBLURRY_REFRACT = i ? 1 : 0; +#ifdef _DEBUG + m_bBLURRY_REFRACT = true; +#endif + } +private: + int m_nNORMAL_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMAL_DECODE_MODE; +#endif +public: + void SetNORMAL_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMAL_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } + void SetNORMAL_DECODE_MODE( bool i ) + { + m_nNORMAL_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } +public: + sdk_water_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bBASETEXTURE = false; +#endif // _DEBUG + m_nBASETEXTURE = 0; +#ifdef _DEBUG + m_bMULTITEXTURE = false; +#endif // _DEBUG + m_nMULTITEXTURE = 0; +#ifdef _DEBUG + m_bREFLECT = false; +#endif // _DEBUG + m_nREFLECT = 0; +#ifdef _DEBUG + m_bREFRACT = false; +#endif // _DEBUG + m_nREFRACT = 0; +#ifdef _DEBUG + m_bABOVEWATER = false; +#endif // _DEBUG + m_nABOVEWATER = 0; +#ifdef _DEBUG + m_bBLURRY_REFRACT = false; +#endif // _DEBUG + m_nBLURRY_REFRACT = 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMAL_DECODE_MODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bBASETEXTURE && m_bMULTITEXTURE && m_bREFLECT && m_bREFRACT && m_bABOVEWATER && m_bBLURRY_REFRACT && m_bNORMAL_DECODE_MODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nBASETEXTURE ) + ( 16 * m_nMULTITEXTURE ) + ( 32 * m_nREFLECT ) + ( 64 * m_nREFRACT ) + ( 128 * m_nABOVEWATER ) + ( 256 * m_nBLURRY_REFRACT ) + ( 512 * m_nNORMAL_DECODE_MODE ) + 0; + } +}; +#define shaderStaticTest_sdk_water_ps20b psh_forgot_to_set_static_BASETEXTURE + psh_forgot_to_set_static_MULTITEXTURE + psh_forgot_to_set_static_REFLECT + psh_forgot_to_set_static_REFRACT + psh_forgot_to_set_static_ABOVEWATER + psh_forgot_to_set_static_BLURRY_REFRACT + psh_forgot_to_set_static_NORMAL_DECODE_MODE + 0 +class sdk_water_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_water_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_water_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_Water_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_Water_vs20.inc new file mode 100644 index 00000000..67e8f134 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_Water_vs20.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class sdk_water_vs20_Static_Index +{ +private: + int m_nBASETEXTURE; +#ifdef _DEBUG + bool m_bBASETEXTURE; +#endif +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } + void SetBASETEXTURE( bool i ) + { + m_nBASETEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } +private: + int m_nMULTITEXTURE; +#ifdef _DEBUG + bool m_bMULTITEXTURE; +#endif +public: + void SetMULTITEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMULTITEXTURE = i; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } + void SetMULTITEXTURE( bool i ) + { + m_nMULTITEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } +public: + sdk_water_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bBASETEXTURE = false; +#endif // _DEBUG + m_nBASETEXTURE = 0; +#ifdef _DEBUG + m_bMULTITEXTURE = false; +#endif // _DEBUG + m_nMULTITEXTURE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBASETEXTURE && m_bMULTITEXTURE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nBASETEXTURE ) + ( 2 * m_nMULTITEXTURE ) + 0; + } +}; +#define shaderStaticTest_sdk_water_vs20 vsh_forgot_to_set_static_BASETEXTURE + vsh_forgot_to_set_static_MULTITEXTURE + 0 +class sdk_water_vs20_Dynamic_Index +{ +public: + sdk_water_vs20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_water_vs20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WorldVertexTransition_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WorldVertexTransition_ps20.inc new file mode 100644 index 00000000..67613947 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WorldVertexTransition_ps20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_worldvertextransition_ps20_Static_Index +{ +private: + int m_nMACROS; +#ifdef _DEBUG + bool m_bMACROS; +#endif +public: + void SetMACROS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMACROS = i; +#ifdef _DEBUG + m_bMACROS = true; +#endif + } + void SetMACROS( bool i ) + { + m_nMACROS = i ? 1 : 0; +#ifdef _DEBUG + m_bMACROS = true; +#endif + } +public: + sdk_worldvertextransition_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bMACROS = false; +#endif // _DEBUG + m_nMACROS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bMACROS; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nMACROS ) + 0; + } +}; +#define shaderStaticTest_sdk_worldvertextransition_ps20 psh_forgot_to_set_static_MACROS + 0 +class sdk_worldvertextransition_ps20_Dynamic_Index +{ +public: + sdk_worldvertextransition_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_worldvertextransition_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WorldVertexTransition_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WorldVertexTransition_ps20b.inc new file mode 100644 index 00000000..cd00eaf5 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WorldVertexTransition_ps20b.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class sdk_worldvertextransition_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nMACROS; +#ifdef _DEBUG + bool m_bMACROS; +#endif +public: + void SetMACROS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMACROS = i; +#ifdef _DEBUG + m_bMACROS = true; +#endif + } + void SetMACROS( bool i ) + { + m_nMACROS = i ? 1 : 0; +#ifdef _DEBUG + m_bMACROS = true; +#endif + } +public: + sdk_worldvertextransition_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bMACROS = false; +#endif // _DEBUG + m_nMACROS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bMACROS; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + ( 2 * m_nMACROS ) + 0; + } +}; +#define shaderStaticTest_sdk_worldvertextransition_ps20b psh_forgot_to_set_static_MACROS + 0 +class sdk_worldvertextransition_ps20b_Dynamic_Index +{ +public: + sdk_worldvertextransition_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_worldvertextransition_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WorldVertexTransition_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WorldVertexTransition_vs20.inc new file mode 100644 index 00000000..fbf30e08 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_WorldVertexTransition_vs20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_worldvertextransition_vs20_Static_Index +{ +public: + sdk_worldvertextransition_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_worldvertextransition_vs20 0 +class sdk_worldvertextransition_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_worldvertextransition_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_worldvertextransition_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cable_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cable_ps20.inc new file mode 100644 index 00000000..6d6f0122 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cable_ps20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_cable_ps20_Static_Index +{ +public: + sdk_cable_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_cable_ps20 0 +class sdk_cable_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_cable_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_cable_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cable_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cable_ps20b.inc new file mode 100644 index 00000000..0e73dbdf --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cable_ps20b.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_cable_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_cable_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_cable_ps20b 0 +class sdk_cable_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_cable_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_cable_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cable_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cable_vs20.inc new file mode 100644 index 00000000..d2ef4642 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cable_vs20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_cable_vs20_Static_Index +{ +public: + sdk_cable_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_cable_vs20 0 +class sdk_cable_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_cable_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_cable_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_blended_pass_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_blended_pass_ps20.inc new file mode 100644 index 00000000..5d52f92f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_blended_pass_ps20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_cloak_blended_pass_ps20_Static_Index +{ +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +public: + sdk_cloak_blended_pass_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBUMPMAP; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nBUMPMAP ) + 0; + } +}; +#define shaderStaticTest_sdk_cloak_blended_pass_ps20 psh_forgot_to_set_static_BUMPMAP + 0 +class sdk_cloak_blended_pass_ps20_Dynamic_Index +{ +public: + sdk_cloak_blended_pass_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_cloak_blended_pass_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_blended_pass_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_blended_pass_ps20b.inc new file mode 100644 index 00000000..c724bbd2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_blended_pass_ps20b.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class sdk_cloak_blended_pass_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +public: + sdk_cloak_blended_pass_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bBUMPMAP; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + ( 2 * m_nBUMPMAP ) + 0; + } +}; +#define shaderStaticTest_sdk_cloak_blended_pass_ps20b psh_forgot_to_set_static_BUMPMAP + 0 +class sdk_cloak_blended_pass_ps20b_Dynamic_Index +{ +public: + sdk_cloak_blended_pass_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_cloak_blended_pass_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_blended_pass_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_blended_pass_ps30.inc new file mode 100644 index 00000000..778aaf04 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_blended_pass_ps30.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class sdk_cloak_blended_pass_ps30_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +public: + sdk_cloak_blended_pass_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bBUMPMAP; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + ( 2 * m_nBUMPMAP ) + 0; + } +}; +#define shaderStaticTest_sdk_cloak_blended_pass_ps30 psh_forgot_to_set_static_BUMPMAP + 0 +class sdk_cloak_blended_pass_ps30_Dynamic_Index +{ +public: + sdk_cloak_blended_pass_ps30_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_cloak_blended_pass_ps30 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_blended_pass_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_blended_pass_vs20.inc new file mode 100644 index 00000000..7f431299 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_blended_pass_vs20.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_cloak_blended_pass_vs20_Static_Index +{ +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +public: + sdk_cloak_blended_pass_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBUMPMAP; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nBUMPMAP ) + 0; + } +}; +#define shaderStaticTest_sdk_cloak_blended_pass_vs20 vsh_forgot_to_set_static_BUMPMAP + 0 +class sdk_cloak_blended_pass_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_cloak_blended_pass_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_cloak_blended_pass_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_blended_pass_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_blended_pass_vs30.inc new file mode 100644 index 00000000..f3121788 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_blended_pass_vs30.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_cloak_blended_pass_vs30_Static_Index +{ +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +public: + sdk_cloak_blended_pass_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBUMPMAP; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 8 * m_nBUMPMAP ) + 0; + } +}; +#define shaderStaticTest_sdk_cloak_blended_pass_vs30 vsh_forgot_to_set_static_BUMPMAP + 0 +class sdk_cloak_blended_pass_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_cloak_blended_pass_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_cloak_blended_pass_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_ps20.inc new file mode 100644 index 00000000..6fa1f696 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_ps20.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_cloak_ps20_Static_Index +{ +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +public: + sdk_cloak_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bLIGHTWARPTEXTURE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 12 * m_nLIGHTWARPTEXTURE ) + 0; + } +}; +#define shaderStaticTest_sdk_cloak_ps20 psh_forgot_to_set_static_LIGHTWARPTEXTURE + 0 +class sdk_cloak_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_cloak_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITEWATERFOGTODESTALPHA && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITEWATERFOGTODESTALPHA ) + ( 4 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_cloak_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_ps20b.inc new file mode 100644 index 00000000..ffa60576 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_ps20b.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_cloak_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +public: + sdk_cloak_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bLIGHTWARPTEXTURE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 20 * m_nCONVERT_TO_SRGB ) + ( 40 * m_nLIGHTWARPTEXTURE ) + 0; + } +}; +#define shaderStaticTest_sdk_cloak_ps20b psh_forgot_to_set_static_LIGHTWARPTEXTURE + 0 +class sdk_cloak_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_cloak_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITEWATERFOGTODESTALPHA && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITEWATERFOGTODESTALPHA ) + ( 4 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_cloak_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_vs20.inc new file mode 100644 index 00000000..e4ef5c40 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_cloak_vs20.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_cloak_vs20_Static_Index +{ +private: + int m_nMODEL; +#ifdef _DEBUG + bool m_bMODEL; +#endif +public: + void SetMODEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMODEL = i; +#ifdef _DEBUG + m_bMODEL = true; +#endif + } + void SetMODEL( bool i ) + { + m_nMODEL = i ? 1 : 0; +#ifdef _DEBUG + m_bMODEL = true; +#endif + } +public: + sdk_cloak_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bMODEL = false; +#endif // _DEBUG + m_nMODEL = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bMODEL; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 8 * m_nMODEL ) + 0; + } +}; +#define shaderStaticTest_sdk_cloak_vs20 vsh_forgot_to_set_static_MODEL + 0 +class sdk_cloak_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_cloak_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_cloak_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_core_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_core_ps20.inc new file mode 100644 index 00000000..d6701fc7 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_core_ps20.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_core_ps20_Static_Index +{ +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nFLOWMAP; +#ifdef _DEBUG + bool m_bFLOWMAP; +#endif +public: + void SetFLOWMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLOWMAP = i; +#ifdef _DEBUG + m_bFLOWMAP = true; +#endif + } + void SetFLOWMAP( bool i ) + { + m_nFLOWMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bFLOWMAP = true; +#endif + } +private: + int m_nCORECOLORTEXTURE; +#ifdef _DEBUG + bool m_bCORECOLORTEXTURE; +#endif +public: + void SetCORECOLORTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCORECOLORTEXTURE = i; +#ifdef _DEBUG + m_bCORECOLORTEXTURE = true; +#endif + } + void SetCORECOLORTEXTURE( bool i ) + { + m_nCORECOLORTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bCORECOLORTEXTURE = true; +#endif + } +private: + int m_nREFRACT; +#ifdef _DEBUG + bool m_bREFRACT; +#endif +public: + void SetREFRACT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACT = i; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } + void SetREFRACT( bool i ) + { + m_nREFRACT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } +public: + sdk_core_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bFLOWMAP = false; +#endif // _DEBUG + m_nFLOWMAP = 0; +#ifdef _DEBUG + m_bCORECOLORTEXTURE = false; +#endif // _DEBUG + m_nCORECOLORTEXTURE = 0; +#ifdef _DEBUG + m_bREFRACT = false; +#endif // _DEBUG + m_nREFRACT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCUBEMAP && m_bFLOWMAP && m_bCORECOLORTEXTURE && m_bREFRACT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nCUBEMAP ) + ( 4 * m_nFLOWMAP ) + ( 8 * m_nCORECOLORTEXTURE ) + ( 16 * m_nREFRACT ) + 0; + } +}; +#define shaderStaticTest_sdk_core_ps20 psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_FLOWMAP + psh_forgot_to_set_static_CORECOLORTEXTURE + psh_forgot_to_set_static_REFRACT + 0 +class sdk_core_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_core_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_core_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_core_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_core_ps20b.inc new file mode 100644 index 00000000..9b9a843d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_core_ps20b.inc @@ -0,0 +1,187 @@ +#include "shaderlib/cshader.h" +class sdk_core_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nFLOWMAP; +#ifdef _DEBUG + bool m_bFLOWMAP; +#endif +public: + void SetFLOWMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLOWMAP = i; +#ifdef _DEBUG + m_bFLOWMAP = true; +#endif + } + void SetFLOWMAP( bool i ) + { + m_nFLOWMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bFLOWMAP = true; +#endif + } +private: + int m_nCORECOLORTEXTURE; +#ifdef _DEBUG + bool m_bCORECOLORTEXTURE; +#endif +public: + void SetCORECOLORTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCORECOLORTEXTURE = i; +#ifdef _DEBUG + m_bCORECOLORTEXTURE = true; +#endif + } + void SetCORECOLORTEXTURE( bool i ) + { + m_nCORECOLORTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bCORECOLORTEXTURE = true; +#endif + } +private: + int m_nREFRACT; +#ifdef _DEBUG + bool m_bREFRACT; +#endif +public: + void SetREFRACT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACT = i; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } + void SetREFRACT( bool i ) + { + m_nREFRACT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } +public: + sdk_core_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bFLOWMAP = false; +#endif // _DEBUG + m_nFLOWMAP = 0; +#ifdef _DEBUG + m_bCORECOLORTEXTURE = false; +#endif // _DEBUG + m_nCORECOLORTEXTURE = 0; +#ifdef _DEBUG + m_bREFRACT = false; +#endif // _DEBUG + m_nREFRACT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bCUBEMAP && m_bFLOWMAP && m_bCORECOLORTEXTURE && m_bREFRACT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nCONVERT_TO_SRGB ) + ( 4 * m_nCUBEMAP ) + ( 8 * m_nFLOWMAP ) + ( 16 * m_nCORECOLORTEXTURE ) + ( 32 * m_nREFRACT ) + 0; + } +}; +#define shaderStaticTest_sdk_core_ps20b psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_FLOWMAP + psh_forgot_to_set_static_CORECOLORTEXTURE + psh_forgot_to_set_static_REFRACT + 0 +class sdk_core_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_core_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_core_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_core_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_core_vs20.inc new file mode 100644 index 00000000..ef6a680c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_core_vs20.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_core_vs20_Static_Index +{ +private: + int m_nMODEL; +#ifdef _DEBUG + bool m_bMODEL; +#endif +public: + void SetMODEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMODEL = i; +#ifdef _DEBUG + m_bMODEL = true; +#endif + } + void SetMODEL( bool i ) + { + m_nMODEL = i ? 1 : 0; +#ifdef _DEBUG + m_bMODEL = true; +#endif + } +public: + sdk_core_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bMODEL = false; +#endif // _DEBUG + m_nMODEL = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bMODEL; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nMODEL ) + 0; + } +}; +#define shaderStaticTest_sdk_core_vs20 vsh_forgot_to_set_static_MODEL + 0 +class sdk_core_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_core_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_core_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_decalmodulate_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_decalmodulate_ps20.inc new file mode 100644 index 00000000..cc1e6113 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_decalmodulate_ps20.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_decalmodulate_ps20_Static_Index +{ +private: + int m_nVERTEXALPHA; +#ifdef _DEBUG + bool m_bVERTEXALPHA; +#endif +public: + void SetVERTEXALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXALPHA = i; +#ifdef _DEBUG + m_bVERTEXALPHA = true; +#endif + } + void SetVERTEXALPHA( bool i ) + { + m_nVERTEXALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXALPHA = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +public: + sdk_decalmodulate_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXALPHA = false; +#endif // _DEBUG + m_nVERTEXALPHA = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXALPHA && m_bFLASHLIGHT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nVERTEXALPHA ) + ( 4 * m_nFLASHLIGHT ) + 0; + } +}; +#define shaderStaticTest_sdk_decalmodulate_ps20 psh_forgot_to_set_static_VERTEXALPHA + psh_forgot_to_set_static_FLASHLIGHT + 0 +class sdk_decalmodulate_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_decalmodulate_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_decalmodulate_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_decalmodulate_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_decalmodulate_ps20b.inc new file mode 100644 index 00000000..e35c8a54 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_decalmodulate_ps20b.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_decalmodulate_ps20b_Static_Index +{ +private: + int m_nVERTEXALPHA; +#ifdef _DEBUG + bool m_bVERTEXALPHA; +#endif +public: + void SetVERTEXALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXALPHA = i; +#ifdef _DEBUG + m_bVERTEXALPHA = true; +#endif + } + void SetVERTEXALPHA( bool i ) + { + m_nVERTEXALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXALPHA = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_decalmodulate_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXALPHA = false; +#endif // _DEBUG + m_nVERTEXALPHA = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXALPHA && m_bFLASHLIGHT && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nVERTEXALPHA ) + ( 8 * m_nFLASHLIGHT ) + ( 16 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_decalmodulate_ps20b psh_forgot_to_set_static_VERTEXALPHA + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_decalmodulate_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_decalmodulate_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_decalmodulate_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_decalmodulate_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_decalmodulate_ps30.inc new file mode 100644 index 00000000..db6747a2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_decalmodulate_ps30.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_decalmodulate_ps30_Static_Index +{ +private: + int m_nVERTEXALPHA; +#ifdef _DEBUG + bool m_bVERTEXALPHA; +#endif +public: + void SetVERTEXALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXALPHA = i; +#ifdef _DEBUG + m_bVERTEXALPHA = true; +#endif + } + void SetVERTEXALPHA( bool i ) + { + m_nVERTEXALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXALPHA = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_decalmodulate_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXALPHA = false; +#endif // _DEBUG + m_nVERTEXALPHA = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXALPHA && m_bFLASHLIGHT && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nVERTEXALPHA ) + ( 8 * m_nFLASHLIGHT ) + ( 16 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_decalmodulate_ps30 psh_forgot_to_set_static_VERTEXALPHA + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_decalmodulate_ps30_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_decalmodulate_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_decalmodulate_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_decalmodulate_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_decalmodulate_vs20.inc new file mode 100644 index 00000000..0f571fd7 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_decalmodulate_vs20.inc @@ -0,0 +1,187 @@ +#include "shaderlib/cshader.h" +class sdk_decalmodulate_vs20_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +public: + sdk_decalmodulate_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bLIGHTING_PREVIEW && m_bFLASHLIGHT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nVERTEXCOLOR ) + ( 8 * m_nLIGHTING_PREVIEW ) + ( 16 * m_nFLASHLIGHT ) + 0; + } +}; +#define shaderStaticTest_sdk_decalmodulate_vs20 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_LIGHTING_PREVIEW + vsh_forgot_to_set_static_FLASHLIGHT + 0 +class sdk_decalmodulate_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_decalmodulate_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG && m_bCOMPRESSED_VERTS && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + ( 2 * m_nCOMPRESSED_VERTS ) + ( 4 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_decalmodulate_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_decalmodulate_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_decalmodulate_vs30.inc new file mode 100644 index 00000000..38617b8c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_decalmodulate_vs30.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_decalmodulate_vs30_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +public: + sdk_decalmodulate_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bLIGHTING_PREVIEW && m_bFLASHLIGHT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 16 * m_nVERTEXCOLOR ) + ( 32 * m_nLIGHTING_PREVIEW ) + ( 64 * m_nFLASHLIGHT ) + 0; + } +}; +#define shaderStaticTest_sdk_decalmodulate_vs30 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_LIGHTING_PREVIEW + vsh_forgot_to_set_static_FLASHLIGHT + 0 +class sdk_decalmodulate_vs30_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_decalmodulate_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG && m_bCOMPRESSED_VERTS && m_bSKINNING && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + ( 2 * m_nCOMPRESSED_VERTS ) + ( 4 * m_nSKINNING ) + ( 8 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_decalmodulate_vs30 vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_depthwrite_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_depthwrite_ps20.inc new file mode 100644 index 00000000..938ab9bd --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_depthwrite_ps20.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_depthwrite_ps20_Static_Index +{ +private: + int m_nCOLOR_DEPTH; +#ifdef _DEBUG + bool m_bCOLOR_DEPTH; +#endif +public: + void SetCOLOR_DEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLOR_DEPTH = i; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } + void SetCOLOR_DEPTH( bool i ) + { + m_nCOLOR_DEPTH = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } +public: + sdk_depthwrite_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bCOLOR_DEPTH = false; +#endif // _DEBUG + m_nCOLOR_DEPTH = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCOLOR_DEPTH; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nCOLOR_DEPTH ) + 0; + } +}; +#define shaderStaticTest_sdk_depthwrite_ps20 psh_forgot_to_set_static_COLOR_DEPTH + 0 +class sdk_depthwrite_ps20_Dynamic_Index +{ +private: + int m_nALPHACLIP; +#ifdef _DEBUG + bool m_bALPHACLIP; +#endif +public: + void SetALPHACLIP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nALPHACLIP = i; +#ifdef _DEBUG + m_bALPHACLIP = true; +#endif + } + void SetALPHACLIP( bool i ) + { + m_nALPHACLIP = i ? 1 : 0; +#ifdef _DEBUG + m_bALPHACLIP = true; +#endif + } +public: + sdk_depthwrite_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bALPHACLIP = false; +#endif // _DEBUG + m_nALPHACLIP = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bALPHACLIP; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nALPHACLIP ) + 0; + } +}; +#define shaderDynamicTest_sdk_depthwrite_ps20 psh_forgot_to_set_dynamic_ALPHACLIP + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_depthwrite_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_depthwrite_ps20b.inc new file mode 100644 index 00000000..fc639347 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_depthwrite_ps20b.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_depthwrite_ps20b_Static_Index +{ +private: + int m_nCOLOR_DEPTH; +#ifdef _DEBUG + bool m_bCOLOR_DEPTH; +#endif +public: + void SetCOLOR_DEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLOR_DEPTH = i; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } + void SetCOLOR_DEPTH( bool i ) + { + m_nCOLOR_DEPTH = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } +public: + sdk_depthwrite_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCOLOR_DEPTH = false; +#endif // _DEBUG + m_nCOLOR_DEPTH = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCOLOR_DEPTH; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nCOLOR_DEPTH ) + 0; + } +}; +#define shaderStaticTest_sdk_depthwrite_ps20b psh_forgot_to_set_static_COLOR_DEPTH + 0 +class sdk_depthwrite_ps20b_Dynamic_Index +{ +private: + int m_nALPHACLIP; +#ifdef _DEBUG + bool m_bALPHACLIP; +#endif +public: + void SetALPHACLIP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nALPHACLIP = i; +#ifdef _DEBUG + m_bALPHACLIP = true; +#endif + } + void SetALPHACLIP( bool i ) + { + m_nALPHACLIP = i ? 1 : 0; +#ifdef _DEBUG + m_bALPHACLIP = true; +#endif + } +public: + sdk_depthwrite_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bALPHACLIP = false; +#endif // _DEBUG + m_nALPHACLIP = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bALPHACLIP; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nALPHACLIP ) + 0; + } +}; +#define shaderDynamicTest_sdk_depthwrite_ps20b psh_forgot_to_set_dynamic_ALPHACLIP + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_depthwrite_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_depthwrite_ps30.inc new file mode 100644 index 00000000..7ebec65d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_depthwrite_ps30.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_depthwrite_ps30_Static_Index +{ +private: + int m_nCOLOR_DEPTH; +#ifdef _DEBUG + bool m_bCOLOR_DEPTH; +#endif +public: + void SetCOLOR_DEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLOR_DEPTH = i; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } + void SetCOLOR_DEPTH( bool i ) + { + m_nCOLOR_DEPTH = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } +public: + sdk_depthwrite_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bCOLOR_DEPTH = false; +#endif // _DEBUG + m_nCOLOR_DEPTH = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCOLOR_DEPTH; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nCOLOR_DEPTH ) + 0; + } +}; +#define shaderStaticTest_sdk_depthwrite_ps30 psh_forgot_to_set_static_COLOR_DEPTH + 0 +class sdk_depthwrite_ps30_Dynamic_Index +{ +private: + int m_nALPHACLIP; +#ifdef _DEBUG + bool m_bALPHACLIP; +#endif +public: + void SetALPHACLIP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nALPHACLIP = i; +#ifdef _DEBUG + m_bALPHACLIP = true; +#endif + } + void SetALPHACLIP( bool i ) + { + m_nALPHACLIP = i ? 1 : 0; +#ifdef _DEBUG + m_bALPHACLIP = true; +#endif + } +public: + sdk_depthwrite_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bALPHACLIP = false; +#endif // _DEBUG + m_nALPHACLIP = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bALPHACLIP; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nALPHACLIP ) + 0; + } +}; +#define shaderDynamicTest_sdk_depthwrite_ps30 psh_forgot_to_set_dynamic_ALPHACLIP + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_depthwrite_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_depthwrite_vs20.inc new file mode 100644 index 00000000..09a93ed2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_depthwrite_vs20.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_depthwrite_vs20_Static_Index +{ +private: + int m_nONLY_PROJECT_POSITION; +#ifdef _DEBUG + bool m_bONLY_PROJECT_POSITION; +#endif +public: + void SetONLY_PROJECT_POSITION( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nONLY_PROJECT_POSITION = i; +#ifdef _DEBUG + m_bONLY_PROJECT_POSITION = true; +#endif + } + void SetONLY_PROJECT_POSITION( bool i ) + { + m_nONLY_PROJECT_POSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bONLY_PROJECT_POSITION = true; +#endif + } +private: + int m_nCOLOR_DEPTH; +#ifdef _DEBUG + bool m_bCOLOR_DEPTH; +#endif +public: + void SetCOLOR_DEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLOR_DEPTH = i; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } + void SetCOLOR_DEPTH( bool i ) + { + m_nCOLOR_DEPTH = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } +private: + int m_nTREESWAY; +#ifdef _DEBUG + bool m_bTREESWAY; +#endif +public: + void SetTREESWAY( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nTREESWAY = i; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif + } + void SetTREESWAY( bool i ) + { + m_nTREESWAY = i ? 1 : 0; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif + } +public: + sdk_depthwrite_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bONLY_PROJECT_POSITION = false; +#endif // _DEBUG + m_nONLY_PROJECT_POSITION = 0; +#ifdef _DEBUG + m_bCOLOR_DEPTH = false; +#endif // _DEBUG + m_nCOLOR_DEPTH = 0; +#ifdef _DEBUG + m_bTREESWAY = false; +#endif // _DEBUG + m_nTREESWAY = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bONLY_PROJECT_POSITION && m_bCOLOR_DEPTH && m_bTREESWAY; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nONLY_PROJECT_POSITION ) + ( 4 * m_nCOLOR_DEPTH ) + ( 8 * m_nTREESWAY ) + 0; + } +}; +#define shaderStaticTest_sdk_depthwrite_vs20 vsh_forgot_to_set_static_ONLY_PROJECT_POSITION + vsh_forgot_to_set_static_COLOR_DEPTH + vsh_forgot_to_set_static_TREESWAY + 0 +class sdk_depthwrite_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_depthwrite_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_depthwrite_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_depthwrite_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_depthwrite_vs30.inc new file mode 100644 index 00000000..d208700a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_depthwrite_vs30.inc @@ -0,0 +1,187 @@ +#include "shaderlib/cshader.h" +class sdk_depthwrite_vs30_Static_Index +{ +private: + int m_nONLY_PROJECT_POSITION; +#ifdef _DEBUG + bool m_bONLY_PROJECT_POSITION; +#endif +public: + void SetONLY_PROJECT_POSITION( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nONLY_PROJECT_POSITION = i; +#ifdef _DEBUG + m_bONLY_PROJECT_POSITION = true; +#endif + } + void SetONLY_PROJECT_POSITION( bool i ) + { + m_nONLY_PROJECT_POSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bONLY_PROJECT_POSITION = true; +#endif + } +private: + int m_nCOLOR_DEPTH; +#ifdef _DEBUG + bool m_bCOLOR_DEPTH; +#endif +public: + void SetCOLOR_DEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLOR_DEPTH = i; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } + void SetCOLOR_DEPTH( bool i ) + { + m_nCOLOR_DEPTH = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } +private: + int m_nTREESWAY; +#ifdef _DEBUG + bool m_bTREESWAY; +#endif +public: + void SetTREESWAY( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nTREESWAY = i; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif + } + void SetTREESWAY( bool i ) + { + m_nTREESWAY = i ? 1 : 0; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif + } +public: + sdk_depthwrite_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bONLY_PROJECT_POSITION = false; +#endif // _DEBUG + m_nONLY_PROJECT_POSITION = 0; +#ifdef _DEBUG + m_bCOLOR_DEPTH = false; +#endif // _DEBUG + m_nCOLOR_DEPTH = 0; +#ifdef _DEBUG + m_bTREESWAY = false; +#endif // _DEBUG + m_nTREESWAY = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bONLY_PROJECT_POSITION && m_bCOLOR_DEPTH && m_bTREESWAY; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 8 * m_nONLY_PROJECT_POSITION ) + ( 8 * m_nCOLOR_DEPTH ) + ( 16 * m_nTREESWAY ) + 0; + } +}; +#define shaderStaticTest_sdk_depthwrite_vs30 vsh_forgot_to_set_static_ONLY_PROJECT_POSITION + vsh_forgot_to_set_static_COLOR_DEPTH + vsh_forgot_to_set_static_TREESWAY + 0 +class sdk_depthwrite_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_depthwrite_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_depthwrite_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_emissive_scroll_blended_pass_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_emissive_scroll_blended_pass_ps20.inc new file mode 100644 index 00000000..c415f0a5 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_emissive_scroll_blended_pass_ps20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_emissive_scroll_blended_pass_ps20_Static_Index +{ +public: + sdk_emissive_scroll_blended_pass_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_emissive_scroll_blended_pass_ps20 0 +class sdk_emissive_scroll_blended_pass_ps20_Dynamic_Index +{ +public: + sdk_emissive_scroll_blended_pass_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_emissive_scroll_blended_pass_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_emissive_scroll_blended_pass_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_emissive_scroll_blended_pass_ps20b.inc new file mode 100644 index 00000000..42dd5742 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_emissive_scroll_blended_pass_ps20b.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_emissive_scroll_blended_pass_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_emissive_scroll_blended_pass_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_emissive_scroll_blended_pass_ps20b 0 +class sdk_emissive_scroll_blended_pass_ps20b_Dynamic_Index +{ +public: + sdk_emissive_scroll_blended_pass_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_emissive_scroll_blended_pass_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_emissive_scroll_blended_pass_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_emissive_scroll_blended_pass_ps30.inc new file mode 100644 index 00000000..f0e08917 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_emissive_scroll_blended_pass_ps30.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_emissive_scroll_blended_pass_ps30_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_emissive_scroll_blended_pass_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_emissive_scroll_blended_pass_ps30 0 +class sdk_emissive_scroll_blended_pass_ps30_Dynamic_Index +{ +public: + sdk_emissive_scroll_blended_pass_ps30_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_emissive_scroll_blended_pass_ps30 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_emissive_scroll_blended_pass_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_emissive_scroll_blended_pass_vs20.inc new file mode 100644 index 00000000..a7f2793f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_emissive_scroll_blended_pass_vs20.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class sdk_emissive_scroll_blended_pass_vs20_Static_Index +{ +public: + sdk_emissive_scroll_blended_pass_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_emissive_scroll_blended_pass_vs20 0 +class sdk_emissive_scroll_blended_pass_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_emissive_scroll_blended_pass_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_emissive_scroll_blended_pass_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_emissive_scroll_blended_pass_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_emissive_scroll_blended_pass_vs30.inc new file mode 100644 index 00000000..5abcbad5 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_emissive_scroll_blended_pass_vs30.inc @@ -0,0 +1,110 @@ +#include "shaderlib/cshader.h" +class sdk_emissive_scroll_blended_pass_vs30_Static_Index +{ +public: + sdk_emissive_scroll_blended_pass_vs30_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_emissive_scroll_blended_pass_vs30 0 +class sdk_emissive_scroll_blended_pass_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_emissive_scroll_blended_pass_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_emissive_scroll_blended_pass_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_engine_post_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_engine_post_ps20b.inc new file mode 100644 index 00000000..8d65f79a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_engine_post_ps20b.inc @@ -0,0 +1,362 @@ +#include "shaderlib/cshader.h" +class sdk_engine_post_ps20b_Static_Index +{ +private: + int m_nTOOL_MODE; +#ifdef _DEBUG + bool m_bTOOL_MODE; +#endif +public: + void SetTOOL_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTOOL_MODE = i; +#ifdef _DEBUG + m_bTOOL_MODE = true; +#endif + } + void SetTOOL_MODE( bool i ) + { + m_nTOOL_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bTOOL_MODE = true; +#endif + } +private: + int m_nDEPTH_BLUR_ENABLE; +#ifdef _DEBUG + bool m_bDEPTH_BLUR_ENABLE; +#endif +public: + void SetDEPTH_BLUR_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDEPTH_BLUR_ENABLE = i; +#ifdef _DEBUG + m_bDEPTH_BLUR_ENABLE = true; +#endif + } + void SetDEPTH_BLUR_ENABLE( bool i ) + { + m_nDEPTH_BLUR_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bDEPTH_BLUR_ENABLE = true; +#endif + } +public: + sdk_engine_post_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bTOOL_MODE = false; +#endif // _DEBUG + m_nTOOL_MODE = 0; +#ifdef _DEBUG + m_bDEPTH_BLUR_ENABLE = false; +#endif // _DEBUG + m_nDEPTH_BLUR_ENABLE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTOOL_MODE && m_bDEPTH_BLUR_ENABLE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2048 * m_nTOOL_MODE ) + ( 4096 * m_nDEPTH_BLUR_ENABLE ) + 0; + } +}; +#define shaderStaticTest_sdk_engine_post_ps20b psh_forgot_to_set_static_TOOL_MODE + psh_forgot_to_set_static_DEPTH_BLUR_ENABLE + 0 +class sdk_engine_post_ps20b_Dynamic_Index +{ +private: + int m_nAA_ENABLE; +#ifdef _DEBUG + bool m_bAA_ENABLE; +#endif +public: + void SetAA_ENABLE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nAA_ENABLE = i; +#ifdef _DEBUG + m_bAA_ENABLE = true; +#endif + } + void SetAA_ENABLE( bool i ) + { + m_nAA_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bAA_ENABLE = true; +#endif + } +private: + int m_nCOL_CORRECT_NUM_LOOKUPS; +#ifdef _DEBUG + bool m_bCOL_CORRECT_NUM_LOOKUPS; +#endif +public: + void SetCOL_CORRECT_NUM_LOOKUPS( int i ) + { + Assert( i >= 0 && i <= 3 ); + m_nCOL_CORRECT_NUM_LOOKUPS = i; +#ifdef _DEBUG + m_bCOL_CORRECT_NUM_LOOKUPS = true; +#endif + } + void SetCOL_CORRECT_NUM_LOOKUPS( bool i ) + { + m_nCOL_CORRECT_NUM_LOOKUPS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOL_CORRECT_NUM_LOOKUPS = true; +#endif + } +private: + int m_nCONVERT_FROM_LINEAR; +#ifdef _DEBUG + bool m_bCONVERT_FROM_LINEAR; +#endif +public: + void SetCONVERT_FROM_LINEAR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_FROM_LINEAR = i; +#ifdef _DEBUG + m_bCONVERT_FROM_LINEAR = true; +#endif + } + void SetCONVERT_FROM_LINEAR( bool i ) + { + m_nCONVERT_FROM_LINEAR = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_FROM_LINEAR = true; +#endif + } +private: + int m_nCONVERT_TO_LINEAR; +#ifdef _DEBUG + bool m_bCONVERT_TO_LINEAR; +#endif +public: + void SetCONVERT_TO_LINEAR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_LINEAR = i; +#ifdef _DEBUG + m_bCONVERT_TO_LINEAR = true; +#endif + } + void SetCONVERT_TO_LINEAR( bool i ) + { + m_nCONVERT_TO_LINEAR = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_LINEAR = true; +#endif + } +private: + int m_nNOISE_ENABLE; +#ifdef _DEBUG + bool m_bNOISE_ENABLE; +#endif +public: + void SetNOISE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNOISE_ENABLE = i; +#ifdef _DEBUG + m_bNOISE_ENABLE = true; +#endif + } + void SetNOISE_ENABLE( bool i ) + { + m_nNOISE_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bNOISE_ENABLE = true; +#endif + } +private: + int m_nVIGNETTE_ENABLE; +#ifdef _DEBUG + bool m_bVIGNETTE_ENABLE; +#endif +public: + void SetVIGNETTE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVIGNETTE_ENABLE = i; +#ifdef _DEBUG + m_bVIGNETTE_ENABLE = true; +#endif + } + void SetVIGNETTE_ENABLE( bool i ) + { + m_nVIGNETTE_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bVIGNETTE_ENABLE = true; +#endif + } +private: + int m_nLOCAL_CONTRAST_ENABLE; +#ifdef _DEBUG + bool m_bLOCAL_CONTRAST_ENABLE; +#endif +public: + void SetLOCAL_CONTRAST_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLOCAL_CONTRAST_ENABLE = i; +#ifdef _DEBUG + m_bLOCAL_CONTRAST_ENABLE = true; +#endif + } + void SetLOCAL_CONTRAST_ENABLE( bool i ) + { + m_nLOCAL_CONTRAST_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bLOCAL_CONTRAST_ENABLE = true; +#endif + } +private: + int m_nBLURRED_VIGNETTE_ENABLE; +#ifdef _DEBUG + bool m_bBLURRED_VIGNETTE_ENABLE; +#endif +public: + void SetBLURRED_VIGNETTE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLURRED_VIGNETTE_ENABLE = i; +#ifdef _DEBUG + m_bBLURRED_VIGNETTE_ENABLE = true; +#endif + } + void SetBLURRED_VIGNETTE_ENABLE( bool i ) + { + m_nBLURRED_VIGNETTE_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bBLURRED_VIGNETTE_ENABLE = true; +#endif + } +private: + int m_nVOMIT_ENABLE; +#ifdef _DEBUG + bool m_bVOMIT_ENABLE; +#endif +public: + void SetVOMIT_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVOMIT_ENABLE = i; +#ifdef _DEBUG + m_bVOMIT_ENABLE = true; +#endif + } + void SetVOMIT_ENABLE( bool i ) + { + m_nVOMIT_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bVOMIT_ENABLE = true; +#endif + } +private: + int m_nTV_GAMMA; +#ifdef _DEBUG + bool m_bTV_GAMMA; +#endif +public: + void SetTV_GAMMA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTV_GAMMA = i; +#ifdef _DEBUG + m_bTV_GAMMA = true; +#endif + } + void SetTV_GAMMA( bool i ) + { + m_nTV_GAMMA = i ? 1 : 0; +#ifdef _DEBUG + m_bTV_GAMMA = true; +#endif + } +private: + int m_nDESATURATEENABLE; +#ifdef _DEBUG + bool m_bDESATURATEENABLE; +#endif +public: + void SetDESATURATEENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDESATURATEENABLE = i; +#ifdef _DEBUG + m_bDESATURATEENABLE = true; +#endif + } + void SetDESATURATEENABLE( bool i ) + { + m_nDESATURATEENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bDESATURATEENABLE = true; +#endif + } +public: + sdk_engine_post_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bAA_ENABLE = false; +#endif // _DEBUG + m_nAA_ENABLE = 0; +#ifdef _DEBUG + m_bCOL_CORRECT_NUM_LOOKUPS = false; +#endif // _DEBUG + m_nCOL_CORRECT_NUM_LOOKUPS = 0; +#ifdef _DEBUG + m_bCONVERT_FROM_LINEAR = false; +#endif // _DEBUG + m_nCONVERT_FROM_LINEAR = 0; +#ifdef _DEBUG + m_bCONVERT_TO_LINEAR = false; +#endif // _DEBUG + m_nCONVERT_TO_LINEAR = 0; +#ifdef _DEBUG + m_bNOISE_ENABLE = false; +#endif // _DEBUG + m_nNOISE_ENABLE = 0; +#ifdef _DEBUG + m_bVIGNETTE_ENABLE = false; +#endif // _DEBUG + m_nVIGNETTE_ENABLE = 0; +#ifdef _DEBUG + m_bLOCAL_CONTRAST_ENABLE = false; +#endif // _DEBUG + m_nLOCAL_CONTRAST_ENABLE = 0; +#ifdef _DEBUG + m_bBLURRED_VIGNETTE_ENABLE = false; +#endif // _DEBUG + m_nBLURRED_VIGNETTE_ENABLE = 0; +#ifdef _DEBUG + m_bVOMIT_ENABLE = false; +#endif // _DEBUG + m_nVOMIT_ENABLE = 0; +#ifdef _DEBUG + m_bTV_GAMMA = false; +#endif // _DEBUG + m_nTV_GAMMA = 0; +#ifdef _DEBUG + m_bDESATURATEENABLE = false; +#endif // _DEBUG + m_nDESATURATEENABLE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bAA_ENABLE && m_bCOL_CORRECT_NUM_LOOKUPS && m_bCONVERT_FROM_LINEAR && m_bCONVERT_TO_LINEAR && m_bNOISE_ENABLE && m_bVIGNETTE_ENABLE && m_bLOCAL_CONTRAST_ENABLE && m_bBLURRED_VIGNETTE_ENABLE && m_bVOMIT_ENABLE && m_bTV_GAMMA && m_bDESATURATEENABLE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nAA_ENABLE ) + ( 1 * m_nCOL_CORRECT_NUM_LOOKUPS ) + ( 4 * m_nCONVERT_FROM_LINEAR ) + ( 8 * m_nCONVERT_TO_LINEAR ) + ( 16 * m_nNOISE_ENABLE ) + ( 32 * m_nVIGNETTE_ENABLE ) + ( 64 * m_nLOCAL_CONTRAST_ENABLE ) + ( 128 * m_nBLURRED_VIGNETTE_ENABLE ) + ( 256 * m_nVOMIT_ENABLE ) + ( 512 * m_nTV_GAMMA ) + ( 1024 * m_nDESATURATEENABLE ) + 0; + } +}; +#define shaderDynamicTest_sdk_engine_post_ps20b psh_forgot_to_set_dynamic_AA_ENABLE + psh_forgot_to_set_dynamic_COL_CORRECT_NUM_LOOKUPS + psh_forgot_to_set_dynamic_CONVERT_FROM_LINEAR + psh_forgot_to_set_dynamic_CONVERT_TO_LINEAR + psh_forgot_to_set_dynamic_NOISE_ENABLE + psh_forgot_to_set_dynamic_VIGNETTE_ENABLE + psh_forgot_to_set_dynamic_LOCAL_CONTRAST_ENABLE + psh_forgot_to_set_dynamic_BLURRED_VIGNETTE_ENABLE + psh_forgot_to_set_dynamic_VOMIT_ENABLE + psh_forgot_to_set_dynamic_TV_GAMMA + psh_forgot_to_set_dynamic_DESATURATEENABLE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eye_refract_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eye_refract_ps20.inc new file mode 100644 index 00000000..850964b3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eye_refract_ps20.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_eye_refract_ps20_Static_Index +{ +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +public: + sdk_eye_refract_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bFLASHLIGHT && m_bLIGHTWARPTEXTURE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 3 * m_nFLASHLIGHT ) + ( 6 * m_nLIGHTWARPTEXTURE ) + 0; + } +}; +#define shaderStaticTest_sdk_eye_refract_ps20 psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_LIGHTWARPTEXTURE + 0 +class sdk_eye_refract_ps20_Dynamic_Index +{ +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_eye_refract_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_eye_refract_ps20 psh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eye_refract_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eye_refract_ps20b.inc new file mode 100644 index 00000000..93308c81 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eye_refract_ps20b.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_eye_refract_ps20b_Static_Index +{ +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +private: + int m_nSPHERETEXKILLCOMBO; +#ifdef _DEBUG + bool m_bSPHERETEXKILLCOMBO; +#endif +public: + void SetSPHERETEXKILLCOMBO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSPHERETEXKILLCOMBO = i; +#ifdef _DEBUG + m_bSPHERETEXKILLCOMBO = true; +#endif + } + void SetSPHERETEXKILLCOMBO( bool i ) + { + m_nSPHERETEXKILLCOMBO = i ? 1 : 0; +#ifdef _DEBUG + m_bSPHERETEXKILLCOMBO = true; +#endif + } +private: + int m_nRAYTRACESPHERE; +#ifdef _DEBUG + bool m_bRAYTRACESPHERE; +#endif +public: + void SetRAYTRACESPHERE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nRAYTRACESPHERE = i; +#ifdef _DEBUG + m_bRAYTRACESPHERE = true; +#endif + } + void SetRAYTRACESPHERE( bool i ) + { + m_nRAYTRACESPHERE = i ? 1 : 0; +#ifdef _DEBUG + m_bRAYTRACESPHERE = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_eye_refract_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; +#ifdef _DEBUG + m_bSPHERETEXKILLCOMBO = false; +#endif // _DEBUG + m_nSPHERETEXKILLCOMBO = 0; +#ifdef _DEBUG + m_bRAYTRACESPHERE = false; +#endif // _DEBUG + m_nRAYTRACESPHERE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bFLASHLIGHT && m_bLIGHTWARPTEXTURE && m_bSPHERETEXKILLCOMBO && m_bRAYTRACESPHERE && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 10 * m_nFLASHLIGHT ) + ( 20 * m_nLIGHTWARPTEXTURE ) + ( 40 * m_nSPHERETEXKILLCOMBO ) + ( 80 * m_nRAYTRACESPHERE ) + ( 160 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_eye_refract_ps20b psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_SPHERETEXKILLCOMBO + psh_forgot_to_set_static_RAYTRACESPHERE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_eye_refract_ps20b_Dynamic_Index +{ +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_eye_refract_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bNUM_LIGHTS && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nNUM_LIGHTS ) + ( 5 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_eye_refract_ps20b psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eye_refract_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eye_refract_ps30.inc new file mode 100644 index 00000000..76c39918 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eye_refract_ps30.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_eye_refract_ps30_Static_Index +{ +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +private: + int m_nSPHERETEXKILLCOMBO; +#ifdef _DEBUG + bool m_bSPHERETEXKILLCOMBO; +#endif +public: + void SetSPHERETEXKILLCOMBO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSPHERETEXKILLCOMBO = i; +#ifdef _DEBUG + m_bSPHERETEXKILLCOMBO = true; +#endif + } + void SetSPHERETEXKILLCOMBO( bool i ) + { + m_nSPHERETEXKILLCOMBO = i ? 1 : 0; +#ifdef _DEBUG + m_bSPHERETEXKILLCOMBO = true; +#endif + } +private: + int m_nRAYTRACESPHERE; +#ifdef _DEBUG + bool m_bRAYTRACESPHERE; +#endif +public: + void SetRAYTRACESPHERE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nRAYTRACESPHERE = i; +#ifdef _DEBUG + m_bRAYTRACESPHERE = true; +#endif + } + void SetRAYTRACESPHERE( bool i ) + { + m_nRAYTRACESPHERE = i ? 1 : 0; +#ifdef _DEBUG + m_bRAYTRACESPHERE = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_eye_refract_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; +#ifdef _DEBUG + m_bSPHERETEXKILLCOMBO = false; +#endif // _DEBUG + m_nSPHERETEXKILLCOMBO = 0; +#ifdef _DEBUG + m_bRAYTRACESPHERE = false; +#endif // _DEBUG + m_nRAYTRACESPHERE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bFLASHLIGHT && m_bLIGHTWARPTEXTURE && m_bSPHERETEXKILLCOMBO && m_bRAYTRACESPHERE && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 10 * m_nFLASHLIGHT ) + ( 20 * m_nLIGHTWARPTEXTURE ) + ( 40 * m_nSPHERETEXKILLCOMBO ) + ( 80 * m_nRAYTRACESPHERE ) + ( 160 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_eye_refract_ps30 psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_SPHERETEXKILLCOMBO + psh_forgot_to_set_static_RAYTRACESPHERE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_eye_refract_ps30_Dynamic_Index +{ +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_eye_refract_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bNUM_LIGHTS && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nNUM_LIGHTS ) + ( 5 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_eye_refract_ps30 psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eye_refract_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eye_refract_vs20.inc new file mode 100644 index 00000000..ec10825b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eye_refract_vs20.inc @@ -0,0 +1,287 @@ +#include "shaderlib/cshader.h" +class sdk_eye_refract_vs20_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +public: + sdk_eye_refract_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bLIGHTWARPTEXTURE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 160 * m_nINTRO ) + ( 320 * m_nHALFLAMBERT ) + ( 640 * m_nFLASHLIGHT ) + ( 1280 * m_nLIGHTWARPTEXTURE ) + 0; + } +}; +#define shaderStaticTest_sdk_eye_refract_vs20 vsh_forgot_to_set_static_INTRO + vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_FLASHLIGHT + vsh_forgot_to_set_static_LIGHTWARPTEXTURE + 0 +class sdk_eye_refract_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_eye_refract_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDOWATERFOG && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDOWATERFOG ) + ( 8 * m_nDYNAMIC_LIGHT ) + ( 16 * m_nSTATIC_LIGHT ) + ( 32 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_eye_refract_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eye_refract_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eye_refract_vs30.inc new file mode 100644 index 00000000..4729f2ab --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eye_refract_vs30.inc @@ -0,0 +1,312 @@ +#include "shaderlib/cshader.h" +class sdk_eye_refract_vs30_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +public: + sdk_eye_refract_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bLIGHTWARPTEXTURE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 320 * m_nINTRO ) + ( 640 * m_nHALFLAMBERT ) + ( 1280 * m_nFLASHLIGHT ) + ( 2560 * m_nLIGHTWARPTEXTURE ) + 0; + } +}; +#define shaderStaticTest_sdk_eye_refract_vs30 vsh_forgot_to_set_static_INTRO + vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_FLASHLIGHT + vsh_forgot_to_set_static_LIGHTWARPTEXTURE + 0 +class sdk_eye_refract_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_eye_refract_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDOWATERFOG && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bNUM_LIGHTS && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDOWATERFOG ) + ( 8 * m_nDYNAMIC_LIGHT ) + ( 16 * m_nSTATIC_LIGHT ) + ( 32 * m_nNUM_LIGHTS ) + ( 160 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_eye_refract_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_NUM_LIGHTS + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyeglint_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyeglint_ps20.inc new file mode 100644 index 00000000..3c83a6ca --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyeglint_ps20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_eyeglint_ps20_Static_Index +{ +public: + sdk_eyeglint_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyeglint_ps20 0 +class sdk_eyeglint_ps20_Dynamic_Index +{ +public: + sdk_eyeglint_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_eyeglint_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyeglint_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyeglint_ps20b.inc new file mode 100644 index 00000000..2dbb669b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyeglint_ps20b.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_eyeglint_ps20b_Static_Index +{ +public: + sdk_eyeglint_ps20b_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyeglint_ps20b 0 +class sdk_eyeglint_ps20b_Dynamic_Index +{ +public: + sdk_eyeglint_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_eyeglint_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyeglint_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyeglint_vs20.inc new file mode 100644 index 00000000..05087222 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyeglint_vs20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_eyeglint_vs20_Static_Index +{ +public: + sdk_eyeglint_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyeglint_vs20 0 +class sdk_eyeglint_vs20_Dynamic_Index +{ +public: + sdk_eyeglint_vs20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_eyeglint_vs20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_ps11.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_ps11.inc new file mode 100644 index 00000000..721122e3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_ps11.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_flashlight_ps11_Static_Index +{ +public: + sdk_eyes_flashlight_ps11_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyes_flashlight_ps11 0 +class sdk_eyes_flashlight_ps11_Dynamic_Index +{ +public: + sdk_eyes_flashlight_ps11_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_eyes_flashlight_ps11 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_ps20.inc new file mode 100644 index 00000000..9e576f91 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_ps20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_flashlight_ps20_Static_Index +{ +public: + sdk_eyes_flashlight_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyes_flashlight_ps20 0 +class sdk_eyes_flashlight_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_eyes_flashlight_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_flashlight_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_ps20b.inc new file mode 100644 index 00000000..d156ca25 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_ps20b.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_flashlight_ps20b_Static_Index +{ +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_eyes_flashlight_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_eyes_flashlight_ps20b psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_eyes_flashlight_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_eyes_flashlight_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_flashlight_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_ps30.inc new file mode 100644 index 00000000..57ddecae --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_ps30.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_flashlight_ps30_Static_Index +{ +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_eyes_flashlight_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_eyes_flashlight_ps30 psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_eyes_flashlight_ps30_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_eyes_flashlight_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_flashlight_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_vs20.inc new file mode 100644 index 00000000..c93c72de --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_vs20.inc @@ -0,0 +1,110 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_flashlight_vs20_Static_Index +{ +public: + sdk_eyes_flashlight_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyes_flashlight_vs20 0 +class sdk_eyes_flashlight_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_eyes_flashlight_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_flashlight_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_vs30.inc new file mode 100644 index 00000000..1244088b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_flashlight_vs30.inc @@ -0,0 +1,135 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_flashlight_vs30_Static_Index +{ +public: + sdk_eyes_flashlight_vs30_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyes_flashlight_vs30 0 +class sdk_eyes_flashlight_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_eyes_flashlight_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDOWATERFOG && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDOWATERFOG ) + ( 8 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_flashlight_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_ps20.inc new file mode 100644 index 00000000..cbbb103d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_ps20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_ps20_Static_Index +{ +public: + sdk_eyes_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyes_ps20 0 +class sdk_eyes_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_eyes_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_ps20b.inc new file mode 100644 index 00000000..f10f16d4 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_ps20b.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_ps20b_Static_Index +{ +public: + sdk_eyes_ps20b_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyes_ps20b 0 +class sdk_eyes_ps20b_Dynamic_Index +{ +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_eyes_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITE_DEPTH_TO_DESTALPHA && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_ps20b psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_ps30.inc new file mode 100644 index 00000000..2353f65d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_ps30.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_ps30_Static_Index +{ +public: + sdk_eyes_ps30_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyes_ps30 0 +class sdk_eyes_ps30_Dynamic_Index +{ +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_eyes_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITE_DEPTH_TO_DESTALPHA && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_ps30 psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_vs20.inc new file mode 100644 index 00000000..5b896790 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_vs20.inc @@ -0,0 +1,262 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_vs20_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nUSE_STATIC_CONTROL_FLOW; +#ifdef _DEBUG + bool m_bUSE_STATIC_CONTROL_FLOW; +#endif +public: + void SetUSE_STATIC_CONTROL_FLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_STATIC_CONTROL_FLOW = i; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } + void SetUSE_STATIC_CONTROL_FLOW( bool i ) + { + m_nUSE_STATIC_CONTROL_FLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } +public: + sdk_eyes_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = false; +#endif // _DEBUG + m_nUSE_STATIC_CONTROL_FLOW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO && m_bHALFLAMBERT && m_bUSE_STATIC_CONTROL_FLOW; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 96 * m_nINTRO ) + ( 192 * m_nHALFLAMBERT ) + ( 384 * m_nUSE_STATIC_CONTROL_FLOW ) + 0; + } +}; +#define shaderStaticTest_sdk_eyes_vs20 vsh_forgot_to_set_static_INTRO + vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_USE_STATIC_CONTROL_FLOW + 0 +class sdk_eyes_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_eyes_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDOWATERFOG && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDOWATERFOG ) + ( 8 * m_nDYNAMIC_LIGHT ) + ( 16 * m_nSTATIC_LIGHT ) + ( 32 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_vs30.inc new file mode 100644 index 00000000..d14fa273 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_eyes_vs30.inc @@ -0,0 +1,237 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_vs30_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +public: + sdk_eyes_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO && m_bHALFLAMBERT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 64 * m_nINTRO ) + ( 128 * m_nHALFLAMBERT ) + 0; + } +}; +#define shaderStaticTest_sdk_eyes_vs30 vsh_forgot_to_set_static_INTRO + vsh_forgot_to_set_static_HALFLAMBERT + 0 +class sdk_eyes_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_eyes_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDOWATERFOG && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDOWATERFOG ) + ( 8 * m_nDYNAMIC_LIGHT ) + ( 16 * m_nSTATIC_LIGHT ) + ( 32 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flashlight_ps11.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flashlight_ps11.inc new file mode 100644 index 00000000..fc6f849d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flashlight_ps11.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class sdk_flashlight_ps11_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nNOCULL; +#ifdef _DEBUG + bool m_bNOCULL; +#endif +public: + void SetNOCULL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNOCULL = i; +#ifdef _DEBUG + m_bNOCULL = true; +#endif + } + void SetNOCULL( bool i ) + { + m_nNOCULL = i ? 1 : 0; +#ifdef _DEBUG + m_bNOCULL = true; +#endif + } +public: + sdk_flashlight_ps11_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bNOCULL = false; +#endif // _DEBUG + m_nNOCULL = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bNOCULL; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nNORMALMAP ) + ( 2 * m_nNOCULL ) + 0; + } +}; +#define shaderStaticTest_sdk_flashlight_ps11 psh_forgot_to_set_static_NORMALMAP + psh_forgot_to_set_static_NOCULL + 0 +class sdk_flashlight_ps11_Dynamic_Index +{ +public: + sdk_flashlight_ps11_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_flashlight_ps11 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flashlight_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flashlight_ps20.inc new file mode 100644 index 00000000..3d25ff86 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flashlight_ps20.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_flashlight_ps20_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nNORMALMAP2; +#ifdef _DEBUG + bool m_bNORMALMAP2; +#endif +public: + void SetNORMALMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP2 = i; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } + void SetNORMALMAP2( bool i ) + { + m_nNORMALMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +public: + sdk_flashlight_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bNORMALMAP2 = false; +#endif // _DEBUG + m_nNORMALMAP2 = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bNORMALMAP2 && m_bWORLDVERTEXTRANSITION && m_bSEAMLESS && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nNORMALMAP ) + ( 6 * m_nNORMALMAP2 ) + ( 12 * m_nWORLDVERTEXTRANSITION ) + ( 24 * m_nSEAMLESS ) + ( 48 * m_nDETAILTEXTURE ) + ( 96 * m_nDETAIL_BLEND_MODE ) + 0; + } +}; +#define shaderStaticTest_sdk_flashlight_ps20 psh_forgot_to_set_static_NORMALMAP + psh_forgot_to_set_static_NORMALMAP2 + psh_forgot_to_set_static_WORLDVERTEXTRANSITION + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + 0 +class sdk_flashlight_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_flashlight_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_flashlight_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flashlight_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flashlight_ps20b.inc new file mode 100644 index 00000000..0e2bf822 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flashlight_ps20b.inc @@ -0,0 +1,262 @@ +#include "shaderlib/cshader.h" +class sdk_flashlight_ps20b_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nNORMALMAP2; +#ifdef _DEBUG + bool m_bNORMALMAP2; +#endif +public: + void SetNORMALMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP2 = i; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } + void SetNORMALMAP2( bool i ) + { + m_nNORMALMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_flashlight_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bNORMALMAP2 = false; +#endif // _DEBUG + m_nNORMALMAP2 = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bNORMALMAP2 && m_bWORLDVERTEXTRANSITION && m_bSEAMLESS && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nNORMALMAP ) + ( 12 * m_nNORMALMAP2 ) + ( 24 * m_nWORLDVERTEXTRANSITION ) + ( 48 * m_nSEAMLESS ) + ( 96 * m_nDETAILTEXTURE ) + ( 192 * m_nDETAIL_BLEND_MODE ) + ( 384 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_flashlight_ps20b psh_forgot_to_set_static_NORMALMAP + psh_forgot_to_set_static_NORMALMAP2 + psh_forgot_to_set_static_WORLDVERTEXTRANSITION + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_flashlight_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_flashlight_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_flashlight_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flashlight_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flashlight_ps30.inc new file mode 100644 index 00000000..88331a5b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flashlight_ps30.inc @@ -0,0 +1,262 @@ +#include "shaderlib/cshader.h" +class sdk_flashlight_ps30_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nNORMALMAP2; +#ifdef _DEBUG + bool m_bNORMALMAP2; +#endif +public: + void SetNORMALMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP2 = i; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } + void SetNORMALMAP2( bool i ) + { + m_nNORMALMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_flashlight_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bNORMALMAP2 = false; +#endif // _DEBUG + m_nNORMALMAP2 = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bNORMALMAP2 && m_bWORLDVERTEXTRANSITION && m_bSEAMLESS && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nNORMALMAP ) + ( 12 * m_nNORMALMAP2 ) + ( 24 * m_nWORLDVERTEXTRANSITION ) + ( 48 * m_nSEAMLESS ) + ( 96 * m_nDETAILTEXTURE ) + ( 192 * m_nDETAIL_BLEND_MODE ) + ( 384 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_flashlight_ps30 psh_forgot_to_set_static_NORMALMAP + psh_forgot_to_set_static_NORMALMAP2 + psh_forgot_to_set_static_WORLDVERTEXTRANSITION + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_flashlight_ps30_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_flashlight_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_flashlight_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flesh_interior_blended_pass_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flesh_interior_blended_pass_ps20.inc new file mode 100644 index 00000000..0b73f03b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flesh_interior_blended_pass_ps20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_flesh_interior_blended_pass_ps20_Static_Index +{ +public: + sdk_flesh_interior_blended_pass_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_flesh_interior_blended_pass_ps20 0 +class sdk_flesh_interior_blended_pass_ps20_Dynamic_Index +{ +public: + sdk_flesh_interior_blended_pass_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_flesh_interior_blended_pass_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flesh_interior_blended_pass_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flesh_interior_blended_pass_ps20b.inc new file mode 100644 index 00000000..dd85606f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flesh_interior_blended_pass_ps20b.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_flesh_interior_blended_pass_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_flesh_interior_blended_pass_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_flesh_interior_blended_pass_ps20b 0 +class sdk_flesh_interior_blended_pass_ps20b_Dynamic_Index +{ +public: + sdk_flesh_interior_blended_pass_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_flesh_interior_blended_pass_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flesh_interior_blended_pass_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flesh_interior_blended_pass_vs20.inc new file mode 100644 index 00000000..e2241b31 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_flesh_interior_blended_pass_vs20.inc @@ -0,0 +1,237 @@ +#include "shaderlib/cshader.h" +class sdk_flesh_interior_blended_pass_vs20_Static_Index +{ +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nUSE_STATIC_CONTROL_FLOW; +#ifdef _DEBUG + bool m_bUSE_STATIC_CONTROL_FLOW; +#endif +public: + void SetUSE_STATIC_CONTROL_FLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_STATIC_CONTROL_FLOW = i; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } + void SetUSE_STATIC_CONTROL_FLOW( bool i ) + { + m_nUSE_STATIC_CONTROL_FLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } +public: + sdk_flesh_interior_blended_pass_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = false; +#endif // _DEBUG + m_nUSE_STATIC_CONTROL_FLOW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bHALFLAMBERT && m_bUSE_STATIC_CONTROL_FLOW; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 96 * m_nHALFLAMBERT ) + ( 192 * m_nUSE_STATIC_CONTROL_FLOW ) + 0; + } +}; +#define shaderStaticTest_sdk_flesh_interior_blended_pass_vs20 vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_USE_STATIC_CONTROL_FLOW + 0 +class sdk_flesh_interior_blended_pass_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_flesh_interior_blended_pass_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDOWATERFOG && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDOWATERFOG ) + ( 8 * m_nDYNAMIC_LIGHT ) + ( 16 * m_nSTATIC_LIGHT ) + ( 32 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_flesh_interior_blended_pass_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_decal_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_decal_ps20.inc new file mode 100644 index 00000000..91c81ef9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_decal_ps20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_decal_ps20_Static_Index +{ +public: + sdk_lightmappedgeneric_decal_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_decal_ps20 0 +class sdk_lightmappedgeneric_decal_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_lightmappedgeneric_decal_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_decal_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_decal_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_decal_ps20b.inc new file mode 100644 index 00000000..e11d31ca --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_decal_ps20b.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_decal_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_lightmappedgeneric_decal_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_decal_ps20b 0 +class sdk_lightmappedgeneric_decal_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_lightmappedgeneric_decal_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_decal_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_decal_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_decal_vs20.inc new file mode 100644 index 00000000..a53c8769 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_decal_vs20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_decal_vs20_Static_Index +{ +public: + sdk_lightmappedgeneric_decal_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_decal_vs20 0 +class sdk_lightmappedgeneric_decal_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_decal_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_decal_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_ps20.inc new file mode 100644 index 00000000..e24bcc01 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_ps20.inc @@ -0,0 +1,262 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_flashlight_ps20_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nNORMALMAP2; +#ifdef _DEBUG + bool m_bNORMALMAP2; +#endif +public: + void SetNORMALMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP2 = i; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } + void SetNORMALMAP2( bool i ) + { + m_nNORMALMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nFANCY_BLENDING; +#ifdef _DEBUG + bool m_bFANCY_BLENDING; +#endif +public: + void SetFANCY_BLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFANCY_BLENDING = i; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } + void SetFANCY_BLENDING( bool i ) + { + m_nFANCY_BLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bNORMALMAP2 = false; +#endif // _DEBUG + m_nNORMALMAP2 = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = false; +#endif // _DEBUG + m_nFANCY_BLENDING = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bNORMALMAP2 && m_bWORLDVERTEXTRANSITION && m_bFANCY_BLENDING && m_bSEAMLESS && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bBASETEXTURETRANSFORM2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nNORMALMAP ) + ( 6 * m_nNORMALMAP2 ) + ( 12 * m_nWORLDVERTEXTRANSITION ) + ( 24 * m_nFANCY_BLENDING ) + ( 48 * m_nSEAMLESS ) + ( 96 * m_nDETAILTEXTURE ) + ( 192 * m_nDETAIL_BLEND_MODE ) + ( 384 * m_nBASETEXTURETRANSFORM2 ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_flashlight_ps20 psh_forgot_to_set_static_NORMALMAP + psh_forgot_to_set_static_NORMALMAP2 + psh_forgot_to_set_static_WORLDVERTEXTRANSITION + psh_forgot_to_set_static_FANCY_BLENDING + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_BASETEXTURETRANSFORM2 + 0 +class sdk_lightmappedgeneric_flashlight_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_flashlight_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_ps20b.inc new file mode 100644 index 00000000..e4ba14aa --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_ps20b.inc @@ -0,0 +1,362 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_flashlight_ps20b_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nNORMALMAP2; +#ifdef _DEBUG + bool m_bNORMALMAP2; +#endif +public: + void SetNORMALMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP2 = i; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } + void SetNORMALMAP2( bool i ) + { + m_nNORMALMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nFANCY_BLENDING; +#ifdef _DEBUG + bool m_bFANCY_BLENDING; +#endif +public: + void SetFANCY_BLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFANCY_BLENDING = i; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } + void SetFANCY_BLENDING( bool i ) + { + m_nFANCY_BLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nPHONG; +#ifdef _DEBUG + bool m_bPHONG; +#endif +public: + void SetPHONG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONG = i; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } + void SetPHONG( bool i ) + { + m_nPHONG = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } +private: + int m_nPHONGMASK; +#ifdef _DEBUG + bool m_bPHONGMASK; +#endif +public: + void SetPHONGMASK( int i ) + { + Assert( i >= 0 && i <= 3 ); + m_nPHONGMASK = i; +#ifdef _DEBUG + m_bPHONGMASK = true; +#endif + } + void SetPHONGMASK( bool i ) + { + m_nPHONGMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONGMASK = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bNORMALMAP2 = false; +#endif // _DEBUG + m_nNORMALMAP2 = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = false; +#endif // _DEBUG + m_nFANCY_BLENDING = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bPHONG = false; +#endif // _DEBUG + m_nPHONG = 0; +#ifdef _DEBUG + m_bPHONGMASK = false; +#endif // _DEBUG + m_nPHONGMASK = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bNORMALMAP2 && m_bWORLDVERTEXTRANSITION && m_bFANCY_BLENDING && m_bSEAMLESS && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bFLASHLIGHTDEPTHFILTERMODE && m_bPHONG && m_bPHONGMASK && m_bBASETEXTURETRANSFORM2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nNORMALMAP ) + ( 12 * m_nNORMALMAP2 ) + ( 24 * m_nWORLDVERTEXTRANSITION ) + ( 48 * m_nFANCY_BLENDING ) + ( 96 * m_nSEAMLESS ) + ( 192 * m_nDETAILTEXTURE ) + ( 384 * m_nDETAIL_BLEND_MODE ) + ( 768 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 2304 * m_nPHONG ) + ( 4608 * m_nPHONGMASK ) + ( 18432 * m_nBASETEXTURETRANSFORM2 ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_flashlight_ps20b psh_forgot_to_set_static_NORMALMAP + psh_forgot_to_set_static_NORMALMAP2 + psh_forgot_to_set_static_WORLDVERTEXTRANSITION + psh_forgot_to_set_static_FANCY_BLENDING + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_PHONG + psh_forgot_to_set_static_PHONGMASK + psh_forgot_to_set_static_BASETEXTURETRANSFORM2 + 0 +class sdk_lightmappedgeneric_flashlight_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_flashlight_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_ps30.inc new file mode 100644 index 00000000..a9734f15 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_ps30.inc @@ -0,0 +1,362 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_flashlight_ps30_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nNORMALMAP2; +#ifdef _DEBUG + bool m_bNORMALMAP2; +#endif +public: + void SetNORMALMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP2 = i; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } + void SetNORMALMAP2( bool i ) + { + m_nNORMALMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nFANCY_BLENDING; +#ifdef _DEBUG + bool m_bFANCY_BLENDING; +#endif +public: + void SetFANCY_BLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFANCY_BLENDING = i; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } + void SetFANCY_BLENDING( bool i ) + { + m_nFANCY_BLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nPHONG; +#ifdef _DEBUG + bool m_bPHONG; +#endif +public: + void SetPHONG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONG = i; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } + void SetPHONG( bool i ) + { + m_nPHONG = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } +private: + int m_nPHONGMASK; +#ifdef _DEBUG + bool m_bPHONGMASK; +#endif +public: + void SetPHONGMASK( int i ) + { + Assert( i >= 0 && i <= 3 ); + m_nPHONGMASK = i; +#ifdef _DEBUG + m_bPHONGMASK = true; +#endif + } + void SetPHONGMASK( bool i ) + { + m_nPHONGMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONGMASK = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bNORMALMAP2 = false; +#endif // _DEBUG + m_nNORMALMAP2 = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = false; +#endif // _DEBUG + m_nFANCY_BLENDING = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bPHONG = false; +#endif // _DEBUG + m_nPHONG = 0; +#ifdef _DEBUG + m_bPHONGMASK = false; +#endif // _DEBUG + m_nPHONGMASK = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bNORMALMAP2 && m_bWORLDVERTEXTRANSITION && m_bFANCY_BLENDING && m_bSEAMLESS && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bFLASHLIGHTDEPTHFILTERMODE && m_bPHONG && m_bPHONGMASK && m_bBASETEXTURETRANSFORM2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nNORMALMAP ) + ( 12 * m_nNORMALMAP2 ) + ( 24 * m_nWORLDVERTEXTRANSITION ) + ( 48 * m_nFANCY_BLENDING ) + ( 96 * m_nSEAMLESS ) + ( 192 * m_nDETAILTEXTURE ) + ( 384 * m_nDETAIL_BLEND_MODE ) + ( 768 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 2304 * m_nPHONG ) + ( 4608 * m_nPHONGMASK ) + ( 18432 * m_nBASETEXTURETRANSFORM2 ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_flashlight_ps30 psh_forgot_to_set_static_NORMALMAP + psh_forgot_to_set_static_NORMALMAP2 + psh_forgot_to_set_static_WORLDVERTEXTRANSITION + psh_forgot_to_set_static_FANCY_BLENDING + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_PHONG + psh_forgot_to_set_static_PHONGMASK + psh_forgot_to_set_static_BASETEXTURETRANSFORM2 + 0 +class sdk_lightmappedgeneric_flashlight_ps30_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_flashlight_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_vs11.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_vs11.inc new file mode 100644 index 00000000..94142c09 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_vs11.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_flashlight_vs11_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_vs11_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bWORLDVERTEXTRANSITION && m_bVERTEXCOLOR; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nNORMALMAP ) + ( 4 * m_nWORLDVERTEXTRANSITION ) + ( 8 * m_nVERTEXCOLOR ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_flashlight_vs11 vsh_forgot_to_set_static_NORMALMAP + vsh_forgot_to_set_static_WORLDVERTEXTRANSITION + vsh_forgot_to_set_static_VERTEXCOLOR + 0 +class sdk_lightmappedgeneric_flashlight_vs11_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_vs11_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_flashlight_vs11 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_vs20.inc new file mode 100644 index 00000000..95edefe2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_vs20.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_flashlight_vs20_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nDETAIL; +#ifdef _DEBUG + bool m_bDETAIL; +#endif +public: + void SetDETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL = i; +#ifdef _DEBUG + m_bDETAIL = true; +#endif + } + void SetDETAIL( bool i ) + { + m_nDETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL = true; +#endif + } +private: + int m_nPHONG; +#ifdef _DEBUG + bool m_bPHONG; +#endif +public: + void SetPHONG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONG = i; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } + void SetPHONG( bool i ) + { + m_nPHONG = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bDETAIL = false; +#endif // _DEBUG + m_nDETAIL = 0; +#ifdef _DEBUG + m_bPHONG = false; +#endif // _DEBUG + m_nPHONG = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bWORLDVERTEXTRANSITION && m_bSEAMLESS && m_bDETAIL && m_bPHONG && m_bBASETEXTURETRANSFORM2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nNORMALMAP ) + ( 4 * m_nWORLDVERTEXTRANSITION ) + ( 8 * m_nSEAMLESS ) + ( 16 * m_nDETAIL ) + ( 32 * m_nPHONG ) + ( 64 * m_nBASETEXTURETRANSFORM2 ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_flashlight_vs20 vsh_forgot_to_set_static_NORMALMAP + vsh_forgot_to_set_static_WORLDVERTEXTRANSITION + vsh_forgot_to_set_static_SEAMLESS + vsh_forgot_to_set_static_DETAIL + vsh_forgot_to_set_static_PHONG + vsh_forgot_to_set_static_BASETEXTURETRANSFORM2 + 0 +class sdk_lightmappedgeneric_flashlight_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_flashlight_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_vs30.inc new file mode 100644 index 00000000..376110e3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_flashlight_vs30.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_flashlight_vs30_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nDETAIL; +#ifdef _DEBUG + bool m_bDETAIL; +#endif +public: + void SetDETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL = i; +#ifdef _DEBUG + m_bDETAIL = true; +#endif + } + void SetDETAIL( bool i ) + { + m_nDETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL = true; +#endif + } +private: + int m_nPHONG; +#ifdef _DEBUG + bool m_bPHONG; +#endif +public: + void SetPHONG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONG = i; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } + void SetPHONG( bool i ) + { + m_nPHONG = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bDETAIL = false; +#endif // _DEBUG + m_nDETAIL = 0; +#ifdef _DEBUG + m_bPHONG = false; +#endif // _DEBUG + m_nPHONG = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bWORLDVERTEXTRANSITION && m_bSEAMLESS && m_bDETAIL && m_bPHONG && m_bBASETEXTURETRANSFORM2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nNORMALMAP ) + ( 4 * m_nWORLDVERTEXTRANSITION ) + ( 8 * m_nSEAMLESS ) + ( 16 * m_nDETAIL ) + ( 32 * m_nPHONG ) + ( 64 * m_nBASETEXTURETRANSFORM2 ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_flashlight_vs30 vsh_forgot_to_set_static_NORMALMAP + vsh_forgot_to_set_static_WORLDVERTEXTRANSITION + vsh_forgot_to_set_static_SEAMLESS + vsh_forgot_to_set_static_DETAIL + vsh_forgot_to_set_static_PHONG + vsh_forgot_to_set_static_BASETEXTURETRANSFORM2 + 0 +class sdk_lightmappedgeneric_flashlight_vs30_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_flashlight_vs30 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_lightingonly_overbright2_ps11.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_lightingonly_overbright2_ps11.inc new file mode 100644 index 00000000..d11eaeb9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_lightingonly_overbright2_ps11.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_lightingonly_overbright2_ps11_Static_Index +{ +public: + sdk_lightmappedgeneric_lightingonly_overbright2_ps11_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_lightingonly_overbright2_ps11 0 +class sdk_lightmappedgeneric_lightingonly_overbright2_ps11_Dynamic_Index +{ +public: + sdk_lightmappedgeneric_lightingonly_overbright2_ps11_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_lightingonly_overbright2_ps11 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_lightingonly_vs11.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_lightingonly_vs11.inc new file mode 100644 index 00000000..5bb3dc94 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_lightingonly_vs11.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_lightingonly_vs11_Static_Index +{ +public: + sdk_lightmappedgeneric_lightingonly_vs11_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_lightingonly_vs11 0 +class sdk_lightmappedgeneric_lightingonly_vs11_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_lightingonly_vs11_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_lightingonly_vs11 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_ps11.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_ps11.inc new file mode 100644 index 00000000..30f358a1 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_ps11.inc @@ -0,0 +1,160 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_ps11_Static_Index +{ +private: + int m_nBASETEXTURE; +#ifdef _DEBUG + bool m_bBASETEXTURE; +#endif +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } + void SetBASETEXTURE( bool i ) + { + m_nBASETEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } +private: + int m_nENVMAP; +#ifdef _DEBUG + bool m_bENVMAP; +#endif +public: + void SetENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAP = i; +#ifdef _DEBUG + m_bENVMAP = true; +#endif + } + void SetENVMAP( bool i ) + { + m_nENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAP = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +public: + sdk_lightmappedgeneric_ps11_Static_Index( ) + { +#ifdef _DEBUG + m_bBASETEXTURE = false; +#endif // _DEBUG + m_nBASETEXTURE = 0; +#ifdef _DEBUG + m_bENVMAP = false; +#endif // _DEBUG + m_nENVMAP = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBASETEXTURE && m_bENVMAP && m_bENVMAPMASK && m_bSELFILLUM && m_bBASEALPHAENVMAPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nBASETEXTURE ) + ( 2 * m_nENVMAP ) + ( 4 * m_nENVMAPMASK ) + ( 8 * m_nSELFILLUM ) + ( 16 * m_nBASEALPHAENVMAPMASK ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_ps11 psh_forgot_to_set_static_BASETEXTURE + psh_forgot_to_set_static_ENVMAP + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + 0 +class sdk_lightmappedgeneric_ps11_Dynamic_Index +{ +public: + sdk_lightmappedgeneric_ps11_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_ps11 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_ps20.inc new file mode 100644 index 00000000..68dc4d81 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_ps20.inc @@ -0,0 +1,712 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_ps20_Static_Index +{ +private: + int m_nMASKEDBLENDING; +#ifdef _DEBUG + bool m_bMASKEDBLENDING; +#endif +public: + void SetMASKEDBLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMASKEDBLENDING = i; +#ifdef _DEBUG + m_bMASKEDBLENDING = true; +#endif + } + void SetMASKEDBLENDING( bool i ) + { + m_nMASKEDBLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bMASKEDBLENDING = true; +#endif + } +private: + int m_nBASETEXTURE2; +#ifdef _DEBUG + bool m_bBASETEXTURE2; +#endif +public: + void SetBASETEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE2 = i; +#ifdef _DEBUG + m_bBASETEXTURE2 = true; +#endif + } + void SetBASETEXTURE2( bool i ) + { + m_nBASETEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE2 = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nBUMPMAP2; +#ifdef _DEBUG + bool m_bBUMPMAP2; +#endif +public: + void SetBUMPMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP2 = i; +#ifdef _DEBUG + m_bBUMPMAP2 = true; +#endif + } + void SetBUMPMAP2( bool i ) + { + m_nBUMPMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP2 = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nNORMALMAPALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bNORMALMAPALPHAENVMAPMASK; +#endif +public: + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } + void SetNORMALMAPALPHAENVMAPMASK( bool i ) + { + m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } +private: + int m_nDIFFUSEBUMPMAP; +#ifdef _DEBUG + bool m_bDIFFUSEBUMPMAP; +#endif +public: + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } + void SetDIFFUSEBUMPMAP( bool i ) + { + m_nDIFFUSEBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } +private: + int m_nBASETEXTURENOENVMAP; +#ifdef _DEBUG + bool m_bBASETEXTURENOENVMAP; +#endif +public: + void SetBASETEXTURENOENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURENOENVMAP = i; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = true; +#endif + } + void SetBASETEXTURENOENVMAP( bool i ) + { + m_nBASETEXTURENOENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = true; +#endif + } +private: + int m_nBASETEXTURE2NOENVMAP; +#ifdef _DEBUG + bool m_bBASETEXTURE2NOENVMAP; +#endif +public: + void SetBASETEXTURE2NOENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE2NOENVMAP = i; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = true; +#endif + } + void SetBASETEXTURE2NOENVMAP( bool i ) + { + m_nBASETEXTURE2NOENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = true; +#endif + } +private: + int m_nWARPLIGHTING; +#ifdef _DEBUG + bool m_bWARPLIGHTING; +#endif +public: + void SetWARPLIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWARPLIGHTING = i; +#ifdef _DEBUG + m_bWARPLIGHTING = true; +#endif + } + void SetWARPLIGHTING( bool i ) + { + m_nWARPLIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bWARPLIGHTING = true; +#endif + } +private: + int m_nFANCY_BLENDING; +#ifdef _DEBUG + bool m_bFANCY_BLENDING; +#endif +public: + void SetFANCY_BLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFANCY_BLENDING = i; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } + void SetFANCY_BLENDING( bool i ) + { + m_nFANCY_BLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nOUTLINE; +#ifdef _DEBUG + bool m_bOUTLINE; +#endif +public: + void SetOUTLINE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTLINE = i; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } + void SetOUTLINE( bool i ) + { + m_nOUTLINE = i ? 1 : 0; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } +private: + int m_nSOFTEDGES; +#ifdef _DEBUG + bool m_bSOFTEDGES; +#endif +public: + void SetSOFTEDGES( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSOFTEDGES = i; +#ifdef _DEBUG + m_bSOFTEDGES = true; +#endif + } + void SetSOFTEDGES( bool i ) + { + m_nSOFTEDGES = i ? 1 : 0; +#ifdef _DEBUG + m_bSOFTEDGES = true; +#endif + } +private: + int m_nBUMPMASK; +#ifdef _DEBUG + bool m_bBUMPMASK; +#endif +public: + void SetBUMPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMASK = i; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } + void SetBUMPMASK( bool i ) + { + m_nBUMPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } +private: + int m_nNORMAL_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMAL_DECODE_MODE; +#endif +public: + void SetNORMAL_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMAL_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } + void SetNORMAL_DECODE_MODE( bool i ) + { + m_nNORMAL_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } +private: + int m_nNORMALMASK_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMALMASK_DECODE_MODE; +#endif +public: + void SetNORMALMASK_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMALMASK_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMALMASK_DECODE_MODE = true; +#endif + } + void SetNORMALMASK_DECODE_MODE( bool i ) + { + m_nNORMALMASK_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMASK_DECODE_MODE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 11 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +public: + sdk_lightmappedgeneric_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bMASKEDBLENDING = false; +#endif // _DEBUG + m_nMASKEDBLENDING = 0; +#ifdef _DEBUG + m_bBASETEXTURE2 = false; +#endif // _DEBUG + m_nBASETEXTURE2 = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bBUMPMAP2 = false; +#endif // _DEBUG + m_nBUMPMAP2 = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nNORMALMAPALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = false; +#endif // _DEBUG + m_nDIFFUSEBUMPMAP = 0; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = false; +#endif // _DEBUG + m_nBASETEXTURENOENVMAP = 0; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = false; +#endif // _DEBUG + m_nBASETEXTURE2NOENVMAP = 0; +#ifdef _DEBUG + m_bWARPLIGHTING = false; +#endif // _DEBUG + m_nWARPLIGHTING = 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = false; +#endif // _DEBUG + m_nFANCY_BLENDING = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bOUTLINE = false; +#endif // _DEBUG + m_nOUTLINE = 0; +#ifdef _DEBUG + m_bSOFTEDGES = false; +#endif // _DEBUG + m_nSOFTEDGES = 0; +#ifdef _DEBUG + m_bBUMPMASK = false; +#endif // _DEBUG + m_nBUMPMASK = 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMAL_DECODE_MODE = 0; +#ifdef _DEBUG + m_bNORMALMASK_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMALMASK_DECODE_MODE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bMASKEDBLENDING && m_bBASETEXTURE2 && m_bDETAILTEXTURE && m_bBUMPMAP && m_bBUMPMAP2 && m_bCUBEMAP && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bNORMALMAPALPHAENVMAPMASK && m_bDIFFUSEBUMPMAP && m_bBASETEXTURENOENVMAP && m_bBASETEXTURE2NOENVMAP && m_bWARPLIGHTING && m_bFANCY_BLENDING && m_bSEAMLESS && m_bOUTLINE && m_bSOFTEDGES && m_bBUMPMASK && m_bNORMAL_DECODE_MODE && m_bNORMALMASK_DECODE_MODE && m_bDETAIL_BLEND_MODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 48 * m_nMASKEDBLENDING ) + ( 96 * m_nBASETEXTURE2 ) + ( 192 * m_nDETAILTEXTURE ) + ( 384 * m_nBUMPMAP ) + ( 1152 * m_nBUMPMAP2 ) + ( 2304 * m_nCUBEMAP ) + ( 4608 * m_nENVMAPMASK ) + ( 9216 * m_nBASEALPHAENVMAPMASK ) + ( 18432 * m_nSELFILLUM ) + ( 36864 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 73728 * m_nDIFFUSEBUMPMAP ) + ( 147456 * m_nBASETEXTURENOENVMAP ) + ( 294912 * m_nBASETEXTURE2NOENVMAP ) + ( 589824 * m_nWARPLIGHTING ) + ( 1179648 * m_nFANCY_BLENDING ) + ( 2359296 * m_nSEAMLESS ) + ( 4718592 * m_nOUTLINE ) + ( 9437184 * m_nSOFTEDGES ) + ( 18874368 * m_nBUMPMASK ) + ( 37748736 * m_nNORMAL_DECODE_MODE ) + ( 37748736 * m_nNORMALMASK_DECODE_MODE ) + ( 37748736 * m_nDETAIL_BLEND_MODE ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_ps20 psh_forgot_to_set_static_MASKEDBLENDING + psh_forgot_to_set_static_BASETEXTURE2 + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_BUMPMAP2 + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_DIFFUSEBUMPMAP + psh_forgot_to_set_static_BASETEXTURENOENVMAP + psh_forgot_to_set_static_BASETEXTURE2NOENVMAP + psh_forgot_to_set_static_WARPLIGHTING + psh_forgot_to_set_static_FANCY_BLENDING + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_OUTLINE + psh_forgot_to_set_static_SOFTEDGES + psh_forgot_to_set_static_BUMPMASK + psh_forgot_to_set_static_NORMAL_DECODE_MODE + psh_forgot_to_set_static_NORMALMASK_DECODE_MODE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + 0 +class sdk_lightmappedgeneric_ps20_Dynamic_Index +{ +private: + int m_nFASTPATHENVMAPCONTRAST; +#ifdef _DEBUG + bool m_bFASTPATHENVMAPCONTRAST; +#endif +public: + void SetFASTPATHENVMAPCONTRAST( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATHENVMAPCONTRAST = i; +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = true; +#endif + } + void SetFASTPATHENVMAPCONTRAST( bool i ) + { + m_nFASTPATHENVMAPCONTRAST = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = true; +#endif + } +private: + int m_nFASTPATH; +#ifdef _DEBUG + bool m_bFASTPATH; +#endif +public: + void SetFASTPATH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH = i; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } + void SetFASTPATH( bool i ) + { + m_nFASTPATH = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +public: + sdk_lightmappedgeneric_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = false; +#endif // _DEBUG + m_nFASTPATHENVMAPCONTRAST = 0; +#ifdef _DEBUG + m_bFASTPATH = false; +#endif // _DEBUG + m_nFASTPATH = 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bFASTPATHENVMAPCONTRAST && m_bFASTPATH && m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bLIGHTING_PREVIEW; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nFASTPATHENVMAPCONTRAST ) + ( 2 * m_nFASTPATH ) + ( 4 * m_nWRITEWATERFOGTODESTALPHA ) + ( 8 * m_nPIXELFOGTYPE ) + ( 16 * m_nLIGHTING_PREVIEW ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_ps20 psh_forgot_to_set_dynamic_FASTPATHENVMAPCONTRAST + psh_forgot_to_set_dynamic_FASTPATH + psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_LIGHTING_PREVIEW + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_ps20b.inc new file mode 100644 index 00000000..4acdc5be --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_ps20b.inc @@ -0,0 +1,762 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_ps20b_Static_Index +{ +private: + int m_nMASKEDBLENDING; +#ifdef _DEBUG + bool m_bMASKEDBLENDING; +#endif +public: + void SetMASKEDBLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMASKEDBLENDING = i; +#ifdef _DEBUG + m_bMASKEDBLENDING = true; +#endif + } + void SetMASKEDBLENDING( bool i ) + { + m_nMASKEDBLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bMASKEDBLENDING = true; +#endif + } +private: + int m_nBASETEXTURE2; +#ifdef _DEBUG + bool m_bBASETEXTURE2; +#endif +public: + void SetBASETEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE2 = i; +#ifdef _DEBUG + m_bBASETEXTURE2 = true; +#endif + } + void SetBASETEXTURE2( bool i ) + { + m_nBASETEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE2 = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nBUMPMAP2; +#ifdef _DEBUG + bool m_bBUMPMAP2; +#endif +public: + void SetBUMPMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP2 = i; +#ifdef _DEBUG + m_bBUMPMAP2 = true; +#endif + } + void SetBUMPMAP2( bool i ) + { + m_nBUMPMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP2 = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nNORMALMAPALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bNORMALMAPALPHAENVMAPMASK; +#endif +public: + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } + void SetNORMALMAPALPHAENVMAPMASK( bool i ) + { + m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } +private: + int m_nDIFFUSEBUMPMAP; +#ifdef _DEBUG + bool m_bDIFFUSEBUMPMAP; +#endif +public: + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } + void SetDIFFUSEBUMPMAP( bool i ) + { + m_nDIFFUSEBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } +private: + int m_nBASETEXTURENOENVMAP; +#ifdef _DEBUG + bool m_bBASETEXTURENOENVMAP; +#endif +public: + void SetBASETEXTURENOENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURENOENVMAP = i; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = true; +#endif + } + void SetBASETEXTURENOENVMAP( bool i ) + { + m_nBASETEXTURENOENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = true; +#endif + } +private: + int m_nBASETEXTURE2NOENVMAP; +#ifdef _DEBUG + bool m_bBASETEXTURE2NOENVMAP; +#endif +public: + void SetBASETEXTURE2NOENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE2NOENVMAP = i; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = true; +#endif + } + void SetBASETEXTURE2NOENVMAP( bool i ) + { + m_nBASETEXTURE2NOENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = true; +#endif + } +private: + int m_nWARPLIGHTING; +#ifdef _DEBUG + bool m_bWARPLIGHTING; +#endif +public: + void SetWARPLIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWARPLIGHTING = i; +#ifdef _DEBUG + m_bWARPLIGHTING = true; +#endif + } + void SetWARPLIGHTING( bool i ) + { + m_nWARPLIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bWARPLIGHTING = true; +#endif + } +private: + int m_nFANCY_BLENDING; +#ifdef _DEBUG + bool m_bFANCY_BLENDING; +#endif +public: + void SetFANCY_BLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFANCY_BLENDING = i; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } + void SetFANCY_BLENDING( bool i ) + { + m_nFANCY_BLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } +private: + int m_nRELIEF_MAPPING; +#ifdef _DEBUG + bool m_bRELIEF_MAPPING; +#endif +public: + void SetRELIEF_MAPPING( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nRELIEF_MAPPING = i; +#ifdef _DEBUG + m_bRELIEF_MAPPING = true; +#endif + } + void SetRELIEF_MAPPING( bool i ) + { + m_nRELIEF_MAPPING = i ? 1 : 0; +#ifdef _DEBUG + m_bRELIEF_MAPPING = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nBUMPMASK; +#ifdef _DEBUG + bool m_bBUMPMASK; +#endif +public: + void SetBUMPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMASK = i; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } + void SetBUMPMASK( bool i ) + { + m_nBUMPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } +private: + int m_nNORMAL_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMAL_DECODE_MODE; +#endif +public: + void SetNORMAL_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMAL_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } + void SetNORMAL_DECODE_MODE( bool i ) + { + m_nNORMAL_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } +private: + int m_nNORMALMASK_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMALMASK_DECODE_MODE; +#endif +public: + void SetNORMALMASK_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMALMASK_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMALMASK_DECODE_MODE = true; +#endif + } + void SetNORMALMASK_DECODE_MODE( bool i ) + { + m_nNORMALMASK_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMASK_DECODE_MODE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 11 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +private: + int m_nPARALLAXCORRECT; +#ifdef _DEBUG + bool m_bPARALLAXCORRECT; +#endif +public: + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } + void SetPARALLAXCORRECT( bool i ) + { + m_nPARALLAXCORRECT = i ? 1 : 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } +public: + sdk_lightmappedgeneric_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bMASKEDBLENDING = false; +#endif // _DEBUG + m_nMASKEDBLENDING = 0; +#ifdef _DEBUG + m_bBASETEXTURE2 = false; +#endif // _DEBUG + m_nBASETEXTURE2 = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bBUMPMAP2 = false; +#endif // _DEBUG + m_nBUMPMAP2 = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nNORMALMAPALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = false; +#endif // _DEBUG + m_nDIFFUSEBUMPMAP = 0; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = false; +#endif // _DEBUG + m_nBASETEXTURENOENVMAP = 0; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = false; +#endif // _DEBUG + m_nBASETEXTURE2NOENVMAP = 0; +#ifdef _DEBUG + m_bWARPLIGHTING = false; +#endif // _DEBUG + m_nWARPLIGHTING = 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = false; +#endif // _DEBUG + m_nFANCY_BLENDING = 0; +#ifdef _DEBUG + m_bRELIEF_MAPPING = false; +#endif // _DEBUG + m_nRELIEF_MAPPING = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bBUMPMASK = false; +#endif // _DEBUG + m_nBUMPMASK = 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMAL_DECODE_MODE = 0; +#ifdef _DEBUG + m_bNORMALMASK_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMALMASK_DECODE_MODE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + m_nPARALLAXCORRECT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bMASKEDBLENDING && m_bBASETEXTURE2 && m_bDETAILTEXTURE && m_bBUMPMAP && m_bBUMPMAP2 && m_bCUBEMAP && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bNORMALMAPALPHAENVMAPMASK && m_bDIFFUSEBUMPMAP && m_bBASETEXTURENOENVMAP && m_bBASETEXTURE2NOENVMAP && m_bWARPLIGHTING && m_bFANCY_BLENDING && m_bRELIEF_MAPPING && m_bSEAMLESS && m_bBUMPMASK && m_bNORMAL_DECODE_MODE && m_bNORMALMASK_DECODE_MODE && m_bDETAIL_BLEND_MODE && m_bBASETEXTURETRANSFORM2 && m_bPARALLAXCORRECT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 96 * m_nMASKEDBLENDING ) + ( 192 * m_nBASETEXTURE2 ) + ( 384 * m_nDETAILTEXTURE ) + ( 768 * m_nBUMPMAP ) + ( 2304 * m_nBUMPMAP2 ) + ( 4608 * m_nCUBEMAP ) + ( 9216 * m_nENVMAPMASK ) + ( 18432 * m_nBASEALPHAENVMAPMASK ) + ( 36864 * m_nSELFILLUM ) + ( 73728 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 147456 * m_nDIFFUSEBUMPMAP ) + ( 294912 * m_nBASETEXTURENOENVMAP ) + ( 589824 * m_nBASETEXTURE2NOENVMAP ) + ( 1179648 * m_nWARPLIGHTING ) + ( 2359296 * m_nFANCY_BLENDING ) + ( 4718592 * m_nRELIEF_MAPPING ) + ( 4718592 * m_nSEAMLESS ) + ( 9437184 * m_nBUMPMASK ) + ( 18874368 * m_nNORMAL_DECODE_MODE ) + ( 18874368 * m_nNORMALMASK_DECODE_MODE ) + ( 18874368 * m_nDETAIL_BLEND_MODE ) + ( 226492416 * m_nBASETEXTURETRANSFORM2 ) + ( 452984832 * m_nPARALLAXCORRECT ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_ps20b psh_forgot_to_set_static_MASKEDBLENDING + psh_forgot_to_set_static_BASETEXTURE2 + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_BUMPMAP2 + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_DIFFUSEBUMPMAP + psh_forgot_to_set_static_BASETEXTURENOENVMAP + psh_forgot_to_set_static_BASETEXTURE2NOENVMAP + psh_forgot_to_set_static_WARPLIGHTING + psh_forgot_to_set_static_FANCY_BLENDING + psh_forgot_to_set_static_RELIEF_MAPPING + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_BUMPMASK + psh_forgot_to_set_static_NORMAL_DECODE_MODE + psh_forgot_to_set_static_NORMALMASK_DECODE_MODE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_BASETEXTURETRANSFORM2 + psh_forgot_to_set_static_PARALLAXCORRECT + 0 +class sdk_lightmappedgeneric_ps20b_Dynamic_Index +{ +private: + int m_nFASTPATHENVMAPCONTRAST; +#ifdef _DEBUG + bool m_bFASTPATHENVMAPCONTRAST; +#endif +public: + void SetFASTPATHENVMAPCONTRAST( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATHENVMAPCONTRAST = i; +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = true; +#endif + } + void SetFASTPATHENVMAPCONTRAST( bool i ) + { + m_nFASTPATHENVMAPCONTRAST = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = true; +#endif + } +private: + int m_nFASTPATH; +#ifdef _DEBUG + bool m_bFASTPATH; +#endif +public: + void SetFASTPATH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH = i; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } + void SetFASTPATH( bool i ) + { + m_nFASTPATH = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_lightmappedgeneric_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = false; +#endif // _DEBUG + m_nFASTPATHENVMAPCONTRAST = 0; +#ifdef _DEBUG + m_bFASTPATH = false; +#endif // _DEBUG + m_nFASTPATH = 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bFASTPATHENVMAPCONTRAST && m_bFASTPATH && m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bLIGHTING_PREVIEW && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nFASTPATHENVMAPCONTRAST ) + ( 2 * m_nFASTPATH ) + ( 4 * m_nWRITEWATERFOGTODESTALPHA ) + ( 8 * m_nPIXELFOGTYPE ) + ( 16 * m_nLIGHTING_PREVIEW ) + ( 48 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_ps20b psh_forgot_to_set_dynamic_FASTPATHENVMAPCONTRAST + psh_forgot_to_set_dynamic_FASTPATH + psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_LIGHTING_PREVIEW + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_ps30.inc new file mode 100644 index 00000000..205c6bda --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_ps30.inc @@ -0,0 +1,737 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_ps30_Static_Index +{ +private: + int m_nMASKEDBLENDING; +#ifdef _DEBUG + bool m_bMASKEDBLENDING; +#endif +public: + void SetMASKEDBLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMASKEDBLENDING = i; +#ifdef _DEBUG + m_bMASKEDBLENDING = true; +#endif + } + void SetMASKEDBLENDING( bool i ) + { + m_nMASKEDBLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bMASKEDBLENDING = true; +#endif + } +private: + int m_nBASETEXTURE2; +#ifdef _DEBUG + bool m_bBASETEXTURE2; +#endif +public: + void SetBASETEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE2 = i; +#ifdef _DEBUG + m_bBASETEXTURE2 = true; +#endif + } + void SetBASETEXTURE2( bool i ) + { + m_nBASETEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE2 = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nBUMPMAP2; +#ifdef _DEBUG + bool m_bBUMPMAP2; +#endif +public: + void SetBUMPMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP2 = i; +#ifdef _DEBUG + m_bBUMPMAP2 = true; +#endif + } + void SetBUMPMAP2( bool i ) + { + m_nBUMPMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP2 = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nNORMALMAPALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bNORMALMAPALPHAENVMAPMASK; +#endif +public: + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } + void SetNORMALMAPALPHAENVMAPMASK( bool i ) + { + m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } +private: + int m_nDIFFUSEBUMPMAP; +#ifdef _DEBUG + bool m_bDIFFUSEBUMPMAP; +#endif +public: + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } + void SetDIFFUSEBUMPMAP( bool i ) + { + m_nDIFFUSEBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } +private: + int m_nBASETEXTURENOENVMAP; +#ifdef _DEBUG + bool m_bBASETEXTURENOENVMAP; +#endif +public: + void SetBASETEXTURENOENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURENOENVMAP = i; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = true; +#endif + } + void SetBASETEXTURENOENVMAP( bool i ) + { + m_nBASETEXTURENOENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = true; +#endif + } +private: + int m_nBASETEXTURE2NOENVMAP; +#ifdef _DEBUG + bool m_bBASETEXTURE2NOENVMAP; +#endif +public: + void SetBASETEXTURE2NOENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE2NOENVMAP = i; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = true; +#endif + } + void SetBASETEXTURE2NOENVMAP( bool i ) + { + m_nBASETEXTURE2NOENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = true; +#endif + } +private: + int m_nWARPLIGHTING; +#ifdef _DEBUG + bool m_bWARPLIGHTING; +#endif +public: + void SetWARPLIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWARPLIGHTING = i; +#ifdef _DEBUG + m_bWARPLIGHTING = true; +#endif + } + void SetWARPLIGHTING( bool i ) + { + m_nWARPLIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bWARPLIGHTING = true; +#endif + } +private: + int m_nFANCY_BLENDING; +#ifdef _DEBUG + bool m_bFANCY_BLENDING; +#endif +public: + void SetFANCY_BLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFANCY_BLENDING = i; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } + void SetFANCY_BLENDING( bool i ) + { + m_nFANCY_BLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nBUMPMASK; +#ifdef _DEBUG + bool m_bBUMPMASK; +#endif +public: + void SetBUMPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMASK = i; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } + void SetBUMPMASK( bool i ) + { + m_nBUMPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } +private: + int m_nNORMAL_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMAL_DECODE_MODE; +#endif +public: + void SetNORMAL_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMAL_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } + void SetNORMAL_DECODE_MODE( bool i ) + { + m_nNORMAL_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } +private: + int m_nNORMALMASK_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMALMASK_DECODE_MODE; +#endif +public: + void SetNORMALMASK_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMALMASK_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMALMASK_DECODE_MODE = true; +#endif + } + void SetNORMALMASK_DECODE_MODE( bool i ) + { + m_nNORMALMASK_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMASK_DECODE_MODE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 11 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +private: + int m_nPARALLAXCORRECT; +#ifdef _DEBUG + bool m_bPARALLAXCORRECT; +#endif +public: + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } + void SetPARALLAXCORRECT( bool i ) + { + m_nPARALLAXCORRECT = i ? 1 : 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } +public: + sdk_lightmappedgeneric_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bMASKEDBLENDING = false; +#endif // _DEBUG + m_nMASKEDBLENDING = 0; +#ifdef _DEBUG + m_bBASETEXTURE2 = false; +#endif // _DEBUG + m_nBASETEXTURE2 = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bBUMPMAP2 = false; +#endif // _DEBUG + m_nBUMPMAP2 = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nNORMALMAPALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = false; +#endif // _DEBUG + m_nDIFFUSEBUMPMAP = 0; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = false; +#endif // _DEBUG + m_nBASETEXTURENOENVMAP = 0; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = false; +#endif // _DEBUG + m_nBASETEXTURE2NOENVMAP = 0; +#ifdef _DEBUG + m_bWARPLIGHTING = false; +#endif // _DEBUG + m_nWARPLIGHTING = 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = false; +#endif // _DEBUG + m_nFANCY_BLENDING = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bBUMPMASK = false; +#endif // _DEBUG + m_nBUMPMASK = 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMAL_DECODE_MODE = 0; +#ifdef _DEBUG + m_bNORMALMASK_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMALMASK_DECODE_MODE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + m_nPARALLAXCORRECT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bMASKEDBLENDING && m_bBASETEXTURE2 && m_bDETAILTEXTURE && m_bBUMPMAP && m_bBUMPMAP2 && m_bCUBEMAP && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bNORMALMAPALPHAENVMAPMASK && m_bDIFFUSEBUMPMAP && m_bBASETEXTURENOENVMAP && m_bBASETEXTURE2NOENVMAP && m_bWARPLIGHTING && m_bFANCY_BLENDING && m_bSEAMLESS && m_bBUMPMASK && m_bNORMAL_DECODE_MODE && m_bNORMALMASK_DECODE_MODE && m_bDETAIL_BLEND_MODE && m_bBASETEXTURETRANSFORM2 && m_bPARALLAXCORRECT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 96 * m_nMASKEDBLENDING ) + ( 192 * m_nBASETEXTURE2 ) + ( 384 * m_nDETAILTEXTURE ) + ( 768 * m_nBUMPMAP ) + ( 2304 * m_nBUMPMAP2 ) + ( 4608 * m_nCUBEMAP ) + ( 9216 * m_nENVMAPMASK ) + ( 18432 * m_nBASEALPHAENVMAPMASK ) + ( 36864 * m_nSELFILLUM ) + ( 73728 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 147456 * m_nDIFFUSEBUMPMAP ) + ( 294912 * m_nBASETEXTURENOENVMAP ) + ( 589824 * m_nBASETEXTURE2NOENVMAP ) + ( 1179648 * m_nWARPLIGHTING ) + ( 2359296 * m_nFANCY_BLENDING ) + ( 4718592 * m_nSEAMLESS ) + ( 9437184 * m_nBUMPMASK ) + ( 18874368 * m_nNORMAL_DECODE_MODE ) + ( 18874368 * m_nNORMALMASK_DECODE_MODE ) + ( 18874368 * m_nDETAIL_BLEND_MODE ) + ( 226492416 * m_nBASETEXTURETRANSFORM2 ) + ( 452984832 * m_nPARALLAXCORRECT ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_ps30 psh_forgot_to_set_static_MASKEDBLENDING + psh_forgot_to_set_static_BASETEXTURE2 + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_BUMPMAP2 + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_DIFFUSEBUMPMAP + psh_forgot_to_set_static_BASETEXTURENOENVMAP + psh_forgot_to_set_static_BASETEXTURE2NOENVMAP + psh_forgot_to_set_static_WARPLIGHTING + psh_forgot_to_set_static_FANCY_BLENDING + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_BUMPMASK + psh_forgot_to_set_static_NORMAL_DECODE_MODE + psh_forgot_to_set_static_NORMALMASK_DECODE_MODE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_BASETEXTURETRANSFORM2 + psh_forgot_to_set_static_PARALLAXCORRECT + 0 +class sdk_lightmappedgeneric_ps30_Dynamic_Index +{ +private: + int m_nFASTPATHENVMAPCONTRAST; +#ifdef _DEBUG + bool m_bFASTPATHENVMAPCONTRAST; +#endif +public: + void SetFASTPATHENVMAPCONTRAST( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATHENVMAPCONTRAST = i; +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = true; +#endif + } + void SetFASTPATHENVMAPCONTRAST( bool i ) + { + m_nFASTPATHENVMAPCONTRAST = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = true; +#endif + } +private: + int m_nFASTPATH; +#ifdef _DEBUG + bool m_bFASTPATH; +#endif +public: + void SetFASTPATH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH = i; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } + void SetFASTPATH( bool i ) + { + m_nFASTPATH = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_lightmappedgeneric_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = false; +#endif // _DEBUG + m_nFASTPATHENVMAPCONTRAST = 0; +#ifdef _DEBUG + m_bFASTPATH = false; +#endif // _DEBUG + m_nFASTPATH = 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bFASTPATHENVMAPCONTRAST && m_bFASTPATH && m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bLIGHTING_PREVIEW && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nFASTPATHENVMAPCONTRAST ) + ( 2 * m_nFASTPATH ) + ( 4 * m_nWRITEWATERFOGTODESTALPHA ) + ( 8 * m_nPIXELFOGTYPE ) + ( 16 * m_nLIGHTING_PREVIEW ) + ( 48 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_ps30 psh_forgot_to_set_dynamic_FASTPATHENVMAPCONTRAST + psh_forgot_to_set_dynamic_FASTPATH + psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_LIGHTING_PREVIEW + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_vs20.inc new file mode 100644 index 00000000..90c3dbb9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_vs20.inc @@ -0,0 +1,362 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_vs20_Static_Index +{ +private: + int m_nENVMAP_MASK; +#ifdef _DEBUG + bool m_bENVMAP_MASK; +#endif +public: + void SetENVMAP_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAP_MASK = i; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif + } + void SetENVMAP_MASK( bool i ) + { + m_nENVMAP_MASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif + } +private: + int m_nTANGENTSPACE; +#ifdef _DEBUG + bool m_bTANGENTSPACE; +#endif +public: + void SetTANGENTSPACE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTANGENTSPACE = i; +#ifdef _DEBUG + m_bTANGENTSPACE = true; +#endif + } + void SetTANGENTSPACE( bool i ) + { + m_nTANGENTSPACE = i ? 1 : 0; +#ifdef _DEBUG + m_bTANGENTSPACE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nDIFFUSEBUMPMAP; +#ifdef _DEBUG + bool m_bDIFFUSEBUMPMAP; +#endif +public: + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } + void SetDIFFUSEBUMPMAP( bool i ) + { + m_nDIFFUSEBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nVERTEXALPHATEXBLENDFACTOR; +#ifdef _DEBUG + bool m_bVERTEXALPHATEXBLENDFACTOR; +#endif +public: + void SetVERTEXALPHATEXBLENDFACTOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXALPHATEXBLENDFACTOR = i; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = true; +#endif + } + void SetVERTEXALPHATEXBLENDFACTOR( bool i ) + { + m_nVERTEXALPHATEXBLENDFACTOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = true; +#endif + } +private: + int m_nRELIEF_MAPPING; +#ifdef _DEBUG + bool m_bRELIEF_MAPPING; +#endif +public: + void SetRELIEF_MAPPING( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nRELIEF_MAPPING = i; +#ifdef _DEBUG + m_bRELIEF_MAPPING = true; +#endif + } + void SetRELIEF_MAPPING( bool i ) + { + m_nRELIEF_MAPPING = i ? 1 : 0; +#ifdef _DEBUG + m_bRELIEF_MAPPING = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nBUMPMASK; +#ifdef _DEBUG + bool m_bBUMPMASK; +#endif +public: + void SetBUMPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMASK = i; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } + void SetBUMPMASK( bool i ) + { + m_nBUMPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +public: + sdk_lightmappedgeneric_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bENVMAP_MASK = false; +#endif // _DEBUG + m_nENVMAP_MASK = 0; +#ifdef _DEBUG + m_bTANGENTSPACE = false; +#endif // _DEBUG + m_nTANGENTSPACE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = false; +#endif // _DEBUG + m_nDIFFUSEBUMPMAP = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = false; +#endif // _DEBUG + m_nVERTEXALPHATEXBLENDFACTOR = 0; +#ifdef _DEBUG + m_bRELIEF_MAPPING = false; +#endif // _DEBUG + m_nRELIEF_MAPPING = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bBUMPMASK = false; +#endif // _DEBUG + m_nBUMPMASK = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bENVMAP_MASK && m_bTANGENTSPACE && m_bBUMPMAP && m_bDIFFUSEBUMPMAP && m_bVERTEXCOLOR && m_bVERTEXALPHATEXBLENDFACTOR && m_bRELIEF_MAPPING && m_bSEAMLESS && m_bBUMPMASK && m_bBASETEXTURETRANSFORM2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 8 * m_nENVMAP_MASK ) + ( 16 * m_nTANGENTSPACE ) + ( 32 * m_nBUMPMAP ) + ( 64 * m_nDIFFUSEBUMPMAP ) + ( 128 * m_nVERTEXCOLOR ) + ( 256 * m_nVERTEXALPHATEXBLENDFACTOR ) + ( 512 * m_nRELIEF_MAPPING ) + ( 512 * m_nSEAMLESS ) + ( 1024 * m_nBUMPMASK ) + ( 2048 * m_nBASETEXTURETRANSFORM2 ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_vs20 vsh_forgot_to_set_static_ENVMAP_MASK + vsh_forgot_to_set_static_TANGENTSPACE + vsh_forgot_to_set_static_BUMPMAP + vsh_forgot_to_set_static_DIFFUSEBUMPMAP + vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_VERTEXALPHATEXBLENDFACTOR + vsh_forgot_to_set_static_RELIEF_MAPPING + vsh_forgot_to_set_static_SEAMLESS + vsh_forgot_to_set_static_BUMPMASK + vsh_forgot_to_set_static_BASETEXTURETRANSFORM2 + 0 +class sdk_lightmappedgeneric_vs20_Dynamic_Index +{ +private: + int m_nFASTPATH; +#ifdef _DEBUG + bool m_bFASTPATH; +#endif +public: + void SetFASTPATH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH = i; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } + void SetFASTPATH( bool i ) + { + m_nFASTPATH = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +public: + sdk_lightmappedgeneric_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bFASTPATH = false; +#endif // _DEBUG + m_nFASTPATH = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bFASTPATH && m_bDOWATERFOG && m_bLIGHTING_PREVIEW; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nFASTPATH ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nLIGHTING_PREVIEW ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_vs20 vsh_forgot_to_set_dynamic_FASTPATH + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_vs30.inc new file mode 100644 index 00000000..5fda5413 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedgeneric_vs30.inc @@ -0,0 +1,362 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_vs30_Static_Index +{ +private: + int m_nENVMAP_MASK; +#ifdef _DEBUG + bool m_bENVMAP_MASK; +#endif +public: + void SetENVMAP_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAP_MASK = i; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif + } + void SetENVMAP_MASK( bool i ) + { + m_nENVMAP_MASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif + } +private: + int m_nTANGENTSPACE; +#ifdef _DEBUG + bool m_bTANGENTSPACE; +#endif +public: + void SetTANGENTSPACE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTANGENTSPACE = i; +#ifdef _DEBUG + m_bTANGENTSPACE = true; +#endif + } + void SetTANGENTSPACE( bool i ) + { + m_nTANGENTSPACE = i ? 1 : 0; +#ifdef _DEBUG + m_bTANGENTSPACE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nDIFFUSEBUMPMAP; +#ifdef _DEBUG + bool m_bDIFFUSEBUMPMAP; +#endif +public: + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } + void SetDIFFUSEBUMPMAP( bool i ) + { + m_nDIFFUSEBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nVERTEXALPHATEXBLENDFACTOR; +#ifdef _DEBUG + bool m_bVERTEXALPHATEXBLENDFACTOR; +#endif +public: + void SetVERTEXALPHATEXBLENDFACTOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXALPHATEXBLENDFACTOR = i; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = true; +#endif + } + void SetVERTEXALPHATEXBLENDFACTOR( bool i ) + { + m_nVERTEXALPHATEXBLENDFACTOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = true; +#endif + } +private: + int m_nRELIEF_MAPPING; +#ifdef _DEBUG + bool m_bRELIEF_MAPPING; +#endif +public: + void SetRELIEF_MAPPING( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nRELIEF_MAPPING = i; +#ifdef _DEBUG + m_bRELIEF_MAPPING = true; +#endif + } + void SetRELIEF_MAPPING( bool i ) + { + m_nRELIEF_MAPPING = i ? 1 : 0; +#ifdef _DEBUG + m_bRELIEF_MAPPING = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nBUMPMASK; +#ifdef _DEBUG + bool m_bBUMPMASK; +#endif +public: + void SetBUMPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMASK = i; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } + void SetBUMPMASK( bool i ) + { + m_nBUMPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +public: + sdk_lightmappedgeneric_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bENVMAP_MASK = false; +#endif // _DEBUG + m_nENVMAP_MASK = 0; +#ifdef _DEBUG + m_bTANGENTSPACE = false; +#endif // _DEBUG + m_nTANGENTSPACE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = false; +#endif // _DEBUG + m_nDIFFUSEBUMPMAP = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = false; +#endif // _DEBUG + m_nVERTEXALPHATEXBLENDFACTOR = 0; +#ifdef _DEBUG + m_bRELIEF_MAPPING = false; +#endif // _DEBUG + m_nRELIEF_MAPPING = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bBUMPMASK = false; +#endif // _DEBUG + m_nBUMPMASK = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bENVMAP_MASK && m_bTANGENTSPACE && m_bBUMPMAP && m_bDIFFUSEBUMPMAP && m_bVERTEXCOLOR && m_bVERTEXALPHATEXBLENDFACTOR && m_bRELIEF_MAPPING && m_bSEAMLESS && m_bBUMPMASK && m_bBASETEXTURETRANSFORM2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 8 * m_nENVMAP_MASK ) + ( 16 * m_nTANGENTSPACE ) + ( 32 * m_nBUMPMAP ) + ( 64 * m_nDIFFUSEBUMPMAP ) + ( 128 * m_nVERTEXCOLOR ) + ( 256 * m_nVERTEXALPHATEXBLENDFACTOR ) + ( 512 * m_nRELIEF_MAPPING ) + ( 512 * m_nSEAMLESS ) + ( 1024 * m_nBUMPMASK ) + ( 2048 * m_nBASETEXTURETRANSFORM2 ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_vs30 vsh_forgot_to_set_static_ENVMAP_MASK + vsh_forgot_to_set_static_TANGENTSPACE + vsh_forgot_to_set_static_BUMPMAP + vsh_forgot_to_set_static_DIFFUSEBUMPMAP + vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_VERTEXALPHATEXBLENDFACTOR + vsh_forgot_to_set_static_RELIEF_MAPPING + vsh_forgot_to_set_static_SEAMLESS + vsh_forgot_to_set_static_BUMPMASK + vsh_forgot_to_set_static_BASETEXTURETRANSFORM2 + 0 +class sdk_lightmappedgeneric_vs30_Dynamic_Index +{ +private: + int m_nFASTPATH; +#ifdef _DEBUG + bool m_bFASTPATH; +#endif +public: + void SetFASTPATH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH = i; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } + void SetFASTPATH( bool i ) + { + m_nFASTPATH = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +public: + sdk_lightmappedgeneric_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bFASTPATH = false; +#endif // _DEBUG + m_nFASTPATH = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bFASTPATH && m_bDOWATERFOG && m_bLIGHTING_PREVIEW; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nFASTPATH ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nLIGHTING_PREVIEW ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_vs30 vsh_forgot_to_set_dynamic_FASTPATH + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedreflective_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedreflective_ps20.inc new file mode 100644 index 00000000..469d8062 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedreflective_ps20.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedreflective_ps20_Static_Index +{ +private: + int m_nBASETEXTURE; +#ifdef _DEBUG + bool m_bBASETEXTURE; +#endif +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } + void SetBASETEXTURE( bool i ) + { + m_nBASETEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } +private: + int m_nREFLECT; +#ifdef _DEBUG + bool m_bREFLECT; +#endif +public: + void SetREFLECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFLECT = i; +#ifdef _DEBUG + m_bREFLECT = true; +#endif + } + void SetREFLECT( bool i ) + { + m_nREFLECT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFLECT = true; +#endif + } +private: + int m_nREFRACT; +#ifdef _DEBUG + bool m_bREFRACT; +#endif +public: + void SetREFRACT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACT = i; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } + void SetREFRACT( bool i ) + { + m_nREFRACT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +public: + sdk_lightmappedreflective_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bBASETEXTURE = false; +#endif // _DEBUG + m_nBASETEXTURE = 0; +#ifdef _DEBUG + m_bREFLECT = false; +#endif // _DEBUG + m_nREFLECT = 0; +#ifdef _DEBUG + m_bREFRACT = false; +#endif // _DEBUG + m_nREFRACT = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBASETEXTURE && m_bREFLECT && m_bREFRACT && m_bENVMAPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nBASETEXTURE ) + ( 4 * m_nREFLECT ) + ( 8 * m_nREFRACT ) + ( 16 * m_nENVMAPMASK ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedreflective_ps20 psh_forgot_to_set_static_BASETEXTURE + psh_forgot_to_set_static_REFLECT + psh_forgot_to_set_static_REFRACT + psh_forgot_to_set_static_ENVMAPMASK + 0 +class sdk_lightmappedreflective_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_lightmappedreflective_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedreflective_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedreflective_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedreflective_ps20b.inc new file mode 100644 index 00000000..e5a00725 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedreflective_ps20b.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedreflective_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nBASETEXTURE; +#ifdef _DEBUG + bool m_bBASETEXTURE; +#endif +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } + void SetBASETEXTURE( bool i ) + { + m_nBASETEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } +private: + int m_nREFLECT; +#ifdef _DEBUG + bool m_bREFLECT; +#endif +public: + void SetREFLECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFLECT = i; +#ifdef _DEBUG + m_bREFLECT = true; +#endif + } + void SetREFLECT( bool i ) + { + m_nREFLECT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFLECT = true; +#endif + } +private: + int m_nREFRACT; +#ifdef _DEBUG + bool m_bREFRACT; +#endif +public: + void SetREFRACT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACT = i; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } + void SetREFRACT( bool i ) + { + m_nREFRACT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +public: + sdk_lightmappedreflective_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bBASETEXTURE = false; +#endif // _DEBUG + m_nBASETEXTURE = 0; +#ifdef _DEBUG + m_bREFLECT = false; +#endif // _DEBUG + m_nREFLECT = 0; +#ifdef _DEBUG + m_bREFRACT = false; +#endif // _DEBUG + m_nREFRACT = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bBASETEXTURE && m_bREFLECT && m_bREFRACT && m_bENVMAPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nBASETEXTURE ) + ( 16 * m_nREFLECT ) + ( 32 * m_nREFRACT ) + ( 64 * m_nENVMAPMASK ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedreflective_ps20b psh_forgot_to_set_static_BASETEXTURE + psh_forgot_to_set_static_REFLECT + psh_forgot_to_set_static_REFRACT + psh_forgot_to_set_static_ENVMAPMASK + 0 +class sdk_lightmappedreflective_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_lightmappedreflective_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedreflective_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedreflective_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedreflective_vs20.inc new file mode 100644 index 00000000..4321a47b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_lightmappedreflective_vs20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedreflective_vs20_Static_Index +{ +private: + int m_nBASETEXTURE; +#ifdef _DEBUG + bool m_bBASETEXTURE; +#endif +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } + void SetBASETEXTURE( bool i ) + { + m_nBASETEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } +public: + sdk_lightmappedreflective_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bBASETEXTURE = false; +#endif // _DEBUG + m_nBASETEXTURE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBASETEXTURE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nBASETEXTURE ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedreflective_vs20 vsh_forgot_to_set_static_BASETEXTURE + 0 +class sdk_lightmappedreflective_vs20_Dynamic_Index +{ +public: + sdk_lightmappedreflective_vs20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedreflective_vs20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_monitorscreen_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_monitorscreen_ps20.inc new file mode 100644 index 00000000..12b6a1b6 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_monitorscreen_ps20.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_monitorscreen_ps20_Static_Index +{ +private: + int m_nTEXTURE2; +#ifdef _DEBUG + bool m_bTEXTURE2; +#endif +public: + void SetTEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTEXTURE2 = i; +#ifdef _DEBUG + m_bTEXTURE2 = true; +#endif + } + void SetTEXTURE2( bool i ) + { + m_nTEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bTEXTURE2 = true; +#endif + } +public: + sdk_monitorscreen_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bTEXTURE2 = false; +#endif // _DEBUG + m_nTEXTURE2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTEXTURE2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nTEXTURE2 ) + 0; + } +}; +#define shaderStaticTest_sdk_monitorscreen_ps20 psh_forgot_to_set_static_TEXTURE2 + 0 +class sdk_monitorscreen_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_monitorscreen_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_monitorscreen_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_monitorscreen_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_monitorscreen_ps20b.inc new file mode 100644 index 00000000..39daea2f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_monitorscreen_ps20b.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_monitorscreen_ps20b_Static_Index +{ +private: + int m_nTEXTURE2; +#ifdef _DEBUG + bool m_bTEXTURE2; +#endif +public: + void SetTEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTEXTURE2 = i; +#ifdef _DEBUG + m_bTEXTURE2 = true; +#endif + } + void SetTEXTURE2( bool i ) + { + m_nTEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bTEXTURE2 = true; +#endif + } +public: + sdk_monitorscreen_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bTEXTURE2 = false; +#endif // _DEBUG + m_nTEXTURE2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTEXTURE2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nTEXTURE2 ) + 0; + } +}; +#define shaderStaticTest_sdk_monitorscreen_ps20b psh_forgot_to_set_static_TEXTURE2 + 0 +class sdk_monitorscreen_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_monitorscreen_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_monitorscreen_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_refract_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_refract_ps20.inc new file mode 100644 index 00000000..839d80a2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_refract_ps20.inc @@ -0,0 +1,262 @@ +#include "shaderlib/cshader.h" +class sdk_refract_ps20_Static_Index +{ +private: + int m_nBLUR; +#ifdef _DEBUG + bool m_bBLUR; +#endif +public: + void SetBLUR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLUR = i; +#ifdef _DEBUG + m_bBLUR = true; +#endif + } + void SetBLUR( bool i ) + { + m_nBLUR = i ? 1 : 0; +#ifdef _DEBUG + m_bBLUR = true; +#endif + } +private: + int m_nFADEOUTONSILHOUETTE; +#ifdef _DEBUG + bool m_bFADEOUTONSILHOUETTE; +#endif +public: + void SetFADEOUTONSILHOUETTE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFADEOUTONSILHOUETTE = i; +#ifdef _DEBUG + m_bFADEOUTONSILHOUETTE = true; +#endif + } + void SetFADEOUTONSILHOUETTE( bool i ) + { + m_nFADEOUTONSILHOUETTE = i ? 1 : 0; +#ifdef _DEBUG + m_bFADEOUTONSILHOUETTE = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nREFRACTTINTTEXTURE; +#ifdef _DEBUG + bool m_bREFRACTTINTTEXTURE; +#endif +public: + void SetREFRACTTINTTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACTTINTTEXTURE = i; +#ifdef _DEBUG + m_bREFRACTTINTTEXTURE = true; +#endif + } + void SetREFRACTTINTTEXTURE( bool i ) + { + m_nREFRACTTINTTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACTTINTTEXTURE = true; +#endif + } +private: + int m_nMASKED; +#ifdef _DEBUG + bool m_bMASKED; +#endif +public: + void SetMASKED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMASKED = i; +#ifdef _DEBUG + m_bMASKED = true; +#endif + } + void SetMASKED( bool i ) + { + m_nMASKED = i ? 1 : 0; +#ifdef _DEBUG + m_bMASKED = true; +#endif + } +private: + int m_nCOLORMODULATE; +#ifdef _DEBUG + bool m_bCOLORMODULATE; +#endif +public: + void SetCOLORMODULATE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLORMODULATE = i; +#ifdef _DEBUG + m_bCOLORMODULATE = true; +#endif + } + void SetCOLORMODULATE( bool i ) + { + m_nCOLORMODULATE = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLORMODULATE = true; +#endif + } +private: + int m_nSECONDARY_NORMAL; +#ifdef _DEBUG + bool m_bSECONDARY_NORMAL; +#endif +public: + void SetSECONDARY_NORMAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSECONDARY_NORMAL = i; +#ifdef _DEBUG + m_bSECONDARY_NORMAL = true; +#endif + } + void SetSECONDARY_NORMAL( bool i ) + { + m_nSECONDARY_NORMAL = i ? 1 : 0; +#ifdef _DEBUG + m_bSECONDARY_NORMAL = true; +#endif + } +private: + int m_nNORMAL_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMAL_DECODE_MODE; +#endif +public: + void SetNORMAL_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMAL_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } + void SetNORMAL_DECODE_MODE( bool i ) + { + m_nNORMAL_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } +public: + sdk_refract_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bBLUR = false; +#endif // _DEBUG + m_nBLUR = 0; +#ifdef _DEBUG + m_bFADEOUTONSILHOUETTE = false; +#endif // _DEBUG + m_nFADEOUTONSILHOUETTE = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bREFRACTTINTTEXTURE = false; +#endif // _DEBUG + m_nREFRACTTINTTEXTURE = 0; +#ifdef _DEBUG + m_bMASKED = false; +#endif // _DEBUG + m_nMASKED = 0; +#ifdef _DEBUG + m_bCOLORMODULATE = false; +#endif // _DEBUG + m_nCOLORMODULATE = 0; +#ifdef _DEBUG + m_bSECONDARY_NORMAL = false; +#endif // _DEBUG + m_nSECONDARY_NORMAL = 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMAL_DECODE_MODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBLUR && m_bFADEOUTONSILHOUETTE && m_bCUBEMAP && m_bREFRACTTINTTEXTURE && m_bMASKED && m_bCOLORMODULATE && m_bSECONDARY_NORMAL && m_bNORMAL_DECODE_MODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nBLUR ) + ( 4 * m_nFADEOUTONSILHOUETTE ) + ( 8 * m_nCUBEMAP ) + ( 16 * m_nREFRACTTINTTEXTURE ) + ( 32 * m_nMASKED ) + ( 64 * m_nCOLORMODULATE ) + ( 128 * m_nSECONDARY_NORMAL ) + ( 256 * m_nNORMAL_DECODE_MODE ) + 0; + } +}; +#define shaderStaticTest_sdk_refract_ps20 psh_forgot_to_set_static_BLUR + psh_forgot_to_set_static_FADEOUTONSILHOUETTE + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_REFRACTTINTTEXTURE + psh_forgot_to_set_static_MASKED + psh_forgot_to_set_static_COLORMODULATE + psh_forgot_to_set_static_SECONDARY_NORMAL + psh_forgot_to_set_static_NORMAL_DECODE_MODE + 0 +class sdk_refract_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_refract_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_refract_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_refract_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_refract_ps20b.inc new file mode 100644 index 00000000..3d877ae0 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_refract_ps20b.inc @@ -0,0 +1,337 @@ +#include "shaderlib/cshader.h" +class sdk_refract_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nBLUR; +#ifdef _DEBUG + bool m_bBLUR; +#endif +public: + void SetBLUR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLUR = i; +#ifdef _DEBUG + m_bBLUR = true; +#endif + } + void SetBLUR( bool i ) + { + m_nBLUR = i ? 1 : 0; +#ifdef _DEBUG + m_bBLUR = true; +#endif + } +private: + int m_nFADEOUTONSILHOUETTE; +#ifdef _DEBUG + bool m_bFADEOUTONSILHOUETTE; +#endif +public: + void SetFADEOUTONSILHOUETTE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFADEOUTONSILHOUETTE = i; +#ifdef _DEBUG + m_bFADEOUTONSILHOUETTE = true; +#endif + } + void SetFADEOUTONSILHOUETTE( bool i ) + { + m_nFADEOUTONSILHOUETTE = i ? 1 : 0; +#ifdef _DEBUG + m_bFADEOUTONSILHOUETTE = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nREFRACTTINTTEXTURE; +#ifdef _DEBUG + bool m_bREFRACTTINTTEXTURE; +#endif +public: + void SetREFRACTTINTTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACTTINTTEXTURE = i; +#ifdef _DEBUG + m_bREFRACTTINTTEXTURE = true; +#endif + } + void SetREFRACTTINTTEXTURE( bool i ) + { + m_nREFRACTTINTTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACTTINTTEXTURE = true; +#endif + } +private: + int m_nMASKED; +#ifdef _DEBUG + bool m_bMASKED; +#endif +public: + void SetMASKED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMASKED = i; +#ifdef _DEBUG + m_bMASKED = true; +#endif + } + void SetMASKED( bool i ) + { + m_nMASKED = i ? 1 : 0; +#ifdef _DEBUG + m_bMASKED = true; +#endif + } +private: + int m_nCOLORMODULATE; +#ifdef _DEBUG + bool m_bCOLORMODULATE; +#endif +public: + void SetCOLORMODULATE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLORMODULATE = i; +#ifdef _DEBUG + m_bCOLORMODULATE = true; +#endif + } + void SetCOLORMODULATE( bool i ) + { + m_nCOLORMODULATE = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLORMODULATE = true; +#endif + } +private: + int m_nSECONDARY_NORMAL; +#ifdef _DEBUG + bool m_bSECONDARY_NORMAL; +#endif +public: + void SetSECONDARY_NORMAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSECONDARY_NORMAL = i; +#ifdef _DEBUG + m_bSECONDARY_NORMAL = true; +#endif + } + void SetSECONDARY_NORMAL( bool i ) + { + m_nSECONDARY_NORMAL = i ? 1 : 0; +#ifdef _DEBUG + m_bSECONDARY_NORMAL = true; +#endif + } +private: + int m_nNORMAL_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMAL_DECODE_MODE; +#endif +public: + void SetNORMAL_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMAL_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } + void SetNORMAL_DECODE_MODE( bool i ) + { + m_nNORMAL_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } +private: + int m_nSHADER_SRGB_READ; +#ifdef _DEBUG + bool m_bSHADER_SRGB_READ; +#endif +public: + void SetSHADER_SRGB_READ( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSHADER_SRGB_READ = i; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = true; +#endif + } + void SetSHADER_SRGB_READ( bool i ) + { + m_nSHADER_SRGB_READ = i ? 1 : 0; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = true; +#endif + } +public: + sdk_refract_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bBLUR = false; +#endif // _DEBUG + m_nBLUR = 0; +#ifdef _DEBUG + m_bFADEOUTONSILHOUETTE = false; +#endif // _DEBUG + m_nFADEOUTONSILHOUETTE = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bREFRACTTINTTEXTURE = false; +#endif // _DEBUG + m_nREFRACTTINTTEXTURE = 0; +#ifdef _DEBUG + m_bMASKED = false; +#endif // _DEBUG + m_nMASKED = 0; +#ifdef _DEBUG + m_bCOLORMODULATE = false; +#endif // _DEBUG + m_nCOLORMODULATE = 0; +#ifdef _DEBUG + m_bSECONDARY_NORMAL = false; +#endif // _DEBUG + m_nSECONDARY_NORMAL = 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMAL_DECODE_MODE = 0; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = false; +#endif // _DEBUG + m_nSHADER_SRGB_READ = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bBLUR && m_bFADEOUTONSILHOUETTE && m_bCUBEMAP && m_bREFRACTTINTTEXTURE && m_bMASKED && m_bCOLORMODULATE && m_bSECONDARY_NORMAL && m_bNORMAL_DECODE_MODE && m_bSHADER_SRGB_READ; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nBLUR ) + ( 16 * m_nFADEOUTONSILHOUETTE ) + ( 32 * m_nCUBEMAP ) + ( 64 * m_nREFRACTTINTTEXTURE ) + ( 128 * m_nMASKED ) + ( 256 * m_nCOLORMODULATE ) + ( 512 * m_nSECONDARY_NORMAL ) + ( 1024 * m_nNORMAL_DECODE_MODE ) + ( 1024 * m_nSHADER_SRGB_READ ) + 0; + } +}; +#define shaderStaticTest_sdk_refract_ps20b psh_forgot_to_set_static_BLUR + psh_forgot_to_set_static_FADEOUTONSILHOUETTE + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_REFRACTTINTTEXTURE + psh_forgot_to_set_static_MASKED + psh_forgot_to_set_static_COLORMODULATE + psh_forgot_to_set_static_SECONDARY_NORMAL + psh_forgot_to_set_static_NORMAL_DECODE_MODE + psh_forgot_to_set_static_SHADER_SRGB_READ + 0 +class sdk_refract_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_refract_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_refract_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_screenspaceeffect_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_screenspaceeffect_vs20.inc new file mode 100644 index 00000000..607c12cd --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_screenspaceeffect_vs20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_screenspaceeffect_vs20_Static_Index +{ +private: + int m_nX360APPCHOOSER; +#ifdef _DEBUG + bool m_bX360APPCHOOSER; +#endif +public: + void SetX360APPCHOOSER( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nX360APPCHOOSER = i; +#ifdef _DEBUG + m_bX360APPCHOOSER = true; +#endif + } + void SetX360APPCHOOSER( bool i ) + { + m_nX360APPCHOOSER = i ? 1 : 0; +#ifdef _DEBUG + m_bX360APPCHOOSER = true; +#endif + } +public: + sdk_screenspaceeffect_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bX360APPCHOOSER = true; +#endif // _DEBUG + m_nX360APPCHOOSER = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bX360APPCHOOSER; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nX360APPCHOOSER ) + 0; + } +}; +#define shaderStaticTest_sdk_screenspaceeffect_vs20 0 +class sdk_screenspaceeffect_vs20_Dynamic_Index +{ +public: + sdk_screenspaceeffect_vs20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_screenspaceeffect_vs20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_skin_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_skin_ps20b.inc new file mode 100644 index 00000000..15a41433 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_skin_ps20b.inc @@ -0,0 +1,562 @@ +#include "shaderlib/cshader.h" +class sdk_skin_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nSELFILLUMFRESNEL; +#ifdef _DEBUG + bool m_bSELFILLUMFRESNEL; +#endif +public: + void SetSELFILLUMFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUMFRESNEL = i; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } + void SetSELFILLUMFRESNEL( bool i ) + { + m_nSELFILLUMFRESNEL = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +private: + int m_nPHONGWARPTEXTURE; +#ifdef _DEBUG + bool m_bPHONGWARPTEXTURE; +#endif +public: + void SetPHONGWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONGWARPTEXTURE = i; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = true; +#endif + } + void SetPHONGWARPTEXTURE( bool i ) + { + m_nPHONGWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = true; +#endif + } +private: + int m_nWRINKLEMAP; +#ifdef _DEBUG + bool m_bWRINKLEMAP; +#endif +public: + void SetWRINKLEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRINKLEMAP = i; +#ifdef _DEBUG + m_bWRINKLEMAP = true; +#endif + } + void SetWRINKLEMAP( bool i ) + { + m_nWRINKLEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bWRINKLEMAP = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 6 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nRIMLIGHT; +#ifdef _DEBUG + bool m_bRIMLIGHT; +#endif +public: + void SetRIMLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nRIMLIGHT = i; +#ifdef _DEBUG + m_bRIMLIGHT = true; +#endif + } + void SetRIMLIGHT( bool i ) + { + m_nRIMLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bRIMLIGHT = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nFASTPATH_NOBUMP; +#ifdef _DEBUG + bool m_bFASTPATH_NOBUMP; +#endif +public: + void SetFASTPATH_NOBUMP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH_NOBUMP = i; +#ifdef _DEBUG + m_bFASTPATH_NOBUMP = true; +#endif + } + void SetFASTPATH_NOBUMP( bool i ) + { + m_nFASTPATH_NOBUMP = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATH_NOBUMP = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +private: + int m_nPHONG_HALFLAMBERT; +#ifdef _DEBUG + bool m_bPHONG_HALFLAMBERT; +#endif +public: + void SetPHONG_HALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONG_HALFLAMBERT = i; +#ifdef _DEBUG + m_bPHONG_HALFLAMBERT = true; +#endif + } + void SetPHONG_HALFLAMBERT( bool i ) + { + m_nPHONG_HALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONG_HALFLAMBERT = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +public: + sdk_skin_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = false; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = false; +#endif // _DEBUG + m_nSELFILLUMFRESNEL = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = false; +#endif // _DEBUG + m_nPHONGWARPTEXTURE = 0; +#ifdef _DEBUG + m_bWRINKLEMAP = false; +#endif // _DEBUG + m_nWRINKLEMAP = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bRIMLIGHT = false; +#endif // _DEBUG + m_nRIMLIGHT = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bFASTPATH_NOBUMP = false; +#endif // _DEBUG + m_nFASTPATH_NOBUMP = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; +#ifdef _DEBUG + m_bPHONG_HALFLAMBERT = false; +#endif // _DEBUG + m_nPHONG_HALFLAMBERT = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bCUBEMAP && m_bSELFILLUM && m_bSELFILLUMFRESNEL && m_bFLASHLIGHT && m_bLIGHTWARPTEXTURE && m_bPHONGWARPTEXTURE && m_bWRINKLEMAP && m_bDETAIL_BLEND_MODE && m_bDETAILTEXTURE && m_bRIMLIGHT && m_bFLASHLIGHTDEPTHFILTERMODE && m_bFASTPATH_NOBUMP && m_bBLENDTINTBYBASEALPHA && m_bPHONG_HALFLAMBERT && m_bENVMAPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 80 * m_nCONVERT_TO_SRGB ) + ( 80 * m_nCUBEMAP ) + ( 160 * m_nSELFILLUM ) + ( 320 * m_nSELFILLUMFRESNEL ) + ( 640 * m_nFLASHLIGHT ) + ( 1280 * m_nLIGHTWARPTEXTURE ) + ( 2560 * m_nPHONGWARPTEXTURE ) + ( 5120 * m_nWRINKLEMAP ) + ( 10240 * m_nDETAIL_BLEND_MODE ) + ( 71680 * m_nDETAILTEXTURE ) + ( 143360 * m_nRIMLIGHT ) + ( 286720 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 860160 * m_nFASTPATH_NOBUMP ) + ( 1720320 * m_nBLENDTINTBYBASEALPHA ) + ( 3440640 * m_nPHONG_HALFLAMBERT ) + ( 6881280 * m_nENVMAPMASK ) + 0; + } +}; +#define shaderStaticTest_sdk_skin_ps20b psh_forgot_to_set_static_CONVERT_TO_SRGB + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_SELFILLUMFRESNEL + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_PHONGWARPTEXTURE + psh_forgot_to_set_static_WRINKLEMAP + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_RIMLIGHT + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_FASTPATH_NOBUMP + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_PHONG_HALFLAMBERT + psh_forgot_to_set_static_ENVMAPMASK + 0 +class sdk_skin_ps20b_Dynamic_Index +{ +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_skin_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nNUM_LIGHTS ) + ( 20 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 40 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_skin_ps20b psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_skin_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_skin_ps30.inc new file mode 100644 index 00000000..3c53e88b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_skin_ps30.inc @@ -0,0 +1,562 @@ +#include "shaderlib/cshader.h" +class sdk_skin_ps30_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nSELFILLUMFRESNEL; +#ifdef _DEBUG + bool m_bSELFILLUMFRESNEL; +#endif +public: + void SetSELFILLUMFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUMFRESNEL = i; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } + void SetSELFILLUMFRESNEL( bool i ) + { + m_nSELFILLUMFRESNEL = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +private: + int m_nPHONGWARPTEXTURE; +#ifdef _DEBUG + bool m_bPHONGWARPTEXTURE; +#endif +public: + void SetPHONGWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONGWARPTEXTURE = i; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = true; +#endif + } + void SetPHONGWARPTEXTURE( bool i ) + { + m_nPHONGWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = true; +#endif + } +private: + int m_nWRINKLEMAP; +#ifdef _DEBUG + bool m_bWRINKLEMAP; +#endif +public: + void SetWRINKLEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRINKLEMAP = i; +#ifdef _DEBUG + m_bWRINKLEMAP = true; +#endif + } + void SetWRINKLEMAP( bool i ) + { + m_nWRINKLEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bWRINKLEMAP = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 6 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nRIMLIGHT; +#ifdef _DEBUG + bool m_bRIMLIGHT; +#endif +public: + void SetRIMLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nRIMLIGHT = i; +#ifdef _DEBUG + m_bRIMLIGHT = true; +#endif + } + void SetRIMLIGHT( bool i ) + { + m_nRIMLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bRIMLIGHT = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nFASTPATH_NOBUMP; +#ifdef _DEBUG + bool m_bFASTPATH_NOBUMP; +#endif +public: + void SetFASTPATH_NOBUMP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH_NOBUMP = i; +#ifdef _DEBUG + m_bFASTPATH_NOBUMP = true; +#endif + } + void SetFASTPATH_NOBUMP( bool i ) + { + m_nFASTPATH_NOBUMP = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATH_NOBUMP = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +private: + int m_nPHONG_HALFLAMBERT; +#ifdef _DEBUG + bool m_bPHONG_HALFLAMBERT; +#endif +public: + void SetPHONG_HALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONG_HALFLAMBERT = i; +#ifdef _DEBUG + m_bPHONG_HALFLAMBERT = true; +#endif + } + void SetPHONG_HALFLAMBERT( bool i ) + { + m_nPHONG_HALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONG_HALFLAMBERT = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +public: + sdk_skin_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = false; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = false; +#endif // _DEBUG + m_nSELFILLUMFRESNEL = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = false; +#endif // _DEBUG + m_nPHONGWARPTEXTURE = 0; +#ifdef _DEBUG + m_bWRINKLEMAP = false; +#endif // _DEBUG + m_nWRINKLEMAP = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bRIMLIGHT = false; +#endif // _DEBUG + m_nRIMLIGHT = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bFASTPATH_NOBUMP = false; +#endif // _DEBUG + m_nFASTPATH_NOBUMP = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; +#ifdef _DEBUG + m_bPHONG_HALFLAMBERT = false; +#endif // _DEBUG + m_nPHONG_HALFLAMBERT = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bCUBEMAP && m_bSELFILLUM && m_bSELFILLUMFRESNEL && m_bFLASHLIGHT && m_bLIGHTWARPTEXTURE && m_bPHONGWARPTEXTURE && m_bWRINKLEMAP && m_bDETAIL_BLEND_MODE && m_bDETAILTEXTURE && m_bRIMLIGHT && m_bFLASHLIGHTDEPTHFILTERMODE && m_bFASTPATH_NOBUMP && m_bBLENDTINTBYBASEALPHA && m_bPHONG_HALFLAMBERT && m_bENVMAPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 80 * m_nCONVERT_TO_SRGB ) + ( 80 * m_nCUBEMAP ) + ( 160 * m_nSELFILLUM ) + ( 320 * m_nSELFILLUMFRESNEL ) + ( 640 * m_nFLASHLIGHT ) + ( 1280 * m_nLIGHTWARPTEXTURE ) + ( 2560 * m_nPHONGWARPTEXTURE ) + ( 5120 * m_nWRINKLEMAP ) + ( 10240 * m_nDETAIL_BLEND_MODE ) + ( 71680 * m_nDETAILTEXTURE ) + ( 143360 * m_nRIMLIGHT ) + ( 286720 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 860160 * m_nFASTPATH_NOBUMP ) + ( 1720320 * m_nBLENDTINTBYBASEALPHA ) + ( 3440640 * m_nPHONG_HALFLAMBERT ) + ( 6881280 * m_nENVMAPMASK ) + 0; + } +}; +#define shaderStaticTest_sdk_skin_ps30 psh_forgot_to_set_static_CONVERT_TO_SRGB + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_SELFILLUMFRESNEL + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_PHONGWARPTEXTURE + psh_forgot_to_set_static_WRINKLEMAP + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_RIMLIGHT + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_FASTPATH_NOBUMP + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_PHONG_HALFLAMBERT + psh_forgot_to_set_static_ENVMAPMASK + 0 +class sdk_skin_ps30_Dynamic_Index +{ +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_skin_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nNUM_LIGHTS ) + ( 20 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 40 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_skin_ps30 psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_skin_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_skin_vs20.inc new file mode 100644 index 00000000..22a29bf7 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_skin_vs20.inc @@ -0,0 +1,187 @@ +#include "shaderlib/cshader.h" +class sdk_skin_vs20_Static_Index +{ +private: + int m_nUSE_STATIC_CONTROL_FLOW; +#ifdef _DEBUG + bool m_bUSE_STATIC_CONTROL_FLOW; +#endif +public: + void SetUSE_STATIC_CONTROL_FLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_STATIC_CONTROL_FLOW = i; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } + void SetUSE_STATIC_CONTROL_FLOW( bool i ) + { + m_nUSE_STATIC_CONTROL_FLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } +public: + sdk_skin_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = false; +#endif // _DEBUG + m_nUSE_STATIC_CONTROL_FLOW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bUSE_STATIC_CONTROL_FLOW; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 48 * m_nUSE_STATIC_CONTROL_FLOW ) + 0; + } +}; +#define shaderStaticTest_sdk_skin_vs20 vsh_forgot_to_set_static_USE_STATIC_CONTROL_FLOW + 0 +class sdk_skin_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_skin_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nLIGHTING_PREVIEW ) + ( 16 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_skin_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_skin_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_skin_vs30.inc new file mode 100644 index 00000000..fb6a1125 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_skin_vs30.inc @@ -0,0 +1,187 @@ +#include "shaderlib/cshader.h" +class sdk_skin_vs30_Static_Index +{ +private: + int m_nDECAL; +#ifdef _DEBUG + bool m_bDECAL; +#endif +public: + void SetDECAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDECAL = i; +#ifdef _DEBUG + m_bDECAL = true; +#endif + } + void SetDECAL( bool i ) + { + m_nDECAL = i ? 1 : 0; +#ifdef _DEBUG + m_bDECAL = true; +#endif + } +public: + sdk_skin_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bDECAL = false; +#endif // _DEBUG + m_nDECAL = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDECAL; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 32 * m_nDECAL ) + 0; + } +}; +#define shaderStaticTest_sdk_skin_vs30 vsh_forgot_to_set_static_DECAL + 0 +class sdk_skin_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_skin_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nLIGHTING_PREVIEW ) + ( 16 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_skin_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinecard_vs11.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinecard_vs11.inc new file mode 100644 index 00000000..9040c4e9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinecard_vs11.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_splinecard_vs11_Static_Index +{ +public: + sdk_splinecard_vs11_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_splinecard_vs11 0 +class sdk_splinecard_vs11_Dynamic_Index +{ +public: + sdk_splinecard_vs11_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_splinecard_vs11 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinecard_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinecard_vs20.inc new file mode 100644 index 00000000..28e9ae56 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinecard_vs20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_splinecard_vs20_Static_Index +{ +public: + sdk_splinecard_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_splinecard_vs20 0 +class sdk_splinecard_vs20_Dynamic_Index +{ +public: + sdk_splinecard_vs20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_splinecard_vs20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinerope_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinerope_ps20.inc new file mode 100644 index 00000000..f43cdb2f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinerope_ps20.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_splinerope_ps20_Static_Index +{ +private: + int m_nSHADER_SRGB_READ; +#ifdef _DEBUG + bool m_bSHADER_SRGB_READ; +#endif +public: + void SetSHADER_SRGB_READ( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nSHADER_SRGB_READ = i; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = true; +#endif + } + void SetSHADER_SRGB_READ( bool i ) + { + m_nSHADER_SRGB_READ = i ? 1 : 0; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = true; +#endif + } +private: + int m_nSHADOWDEPTH; +#ifdef _DEBUG + bool m_bSHADOWDEPTH; +#endif +public: + void SetSHADOWDEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSHADOWDEPTH = i; +#ifdef _DEBUG + m_bSHADOWDEPTH = true; +#endif + } + void SetSHADOWDEPTH( bool i ) + { + m_nSHADOWDEPTH = i ? 1 : 0; +#ifdef _DEBUG + m_bSHADOWDEPTH = true; +#endif + } +public: + sdk_splinerope_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bSHADER_SRGB_READ = false; +#endif // _DEBUG + m_nSHADER_SRGB_READ = 0; +#ifdef _DEBUG + m_bSHADOWDEPTH = false; +#endif // _DEBUG + m_nSHADOWDEPTH = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bSHADER_SRGB_READ && m_bSHADOWDEPTH; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nSHADER_SRGB_READ ) + ( 2 * m_nSHADOWDEPTH ) + 0; + } +}; +#define shaderStaticTest_sdk_splinerope_ps20 psh_forgot_to_set_static_SHADER_SRGB_READ + psh_forgot_to_set_static_SHADOWDEPTH + 0 +class sdk_splinerope_ps20_Dynamic_Index +{ +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_splinerope_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITE_DEPTH_TO_DESTALPHA && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_splinerope_ps20 psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinerope_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinerope_ps20b.inc new file mode 100644 index 00000000..75ce64e9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinerope_ps20b.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_splinerope_ps20b_Static_Index +{ +private: + int m_nSHADER_SRGB_READ; +#ifdef _DEBUG + bool m_bSHADER_SRGB_READ; +#endif +public: + void SetSHADER_SRGB_READ( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nSHADER_SRGB_READ = i; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = true; +#endif + } + void SetSHADER_SRGB_READ( bool i ) + { + m_nSHADER_SRGB_READ = i ? 1 : 0; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = true; +#endif + } +private: + int m_nSHADOWDEPTH; +#ifdef _DEBUG + bool m_bSHADOWDEPTH; +#endif +public: + void SetSHADOWDEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSHADOWDEPTH = i; +#ifdef _DEBUG + m_bSHADOWDEPTH = true; +#endif + } + void SetSHADOWDEPTH( bool i ) + { + m_nSHADOWDEPTH = i ? 1 : 0; +#ifdef _DEBUG + m_bSHADOWDEPTH = true; +#endif + } +public: + sdk_splinerope_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bSHADER_SRGB_READ = false; +#endif // _DEBUG + m_nSHADER_SRGB_READ = 0; +#ifdef _DEBUG + m_bSHADOWDEPTH = false; +#endif // _DEBUG + m_nSHADOWDEPTH = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bSHADER_SRGB_READ && m_bSHADOWDEPTH; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nSHADER_SRGB_READ ) + ( 4 * m_nSHADOWDEPTH ) + 0; + } +}; +#define shaderStaticTest_sdk_splinerope_ps20b psh_forgot_to_set_static_SHADER_SRGB_READ + psh_forgot_to_set_static_SHADOWDEPTH + 0 +class sdk_splinerope_ps20b_Dynamic_Index +{ +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_splinerope_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITE_DEPTH_TO_DESTALPHA && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_splinerope_ps20b psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinerope_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinerope_ps30.inc new file mode 100644 index 00000000..6427d06f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinerope_ps30.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_splinerope_ps30_Static_Index +{ +private: + int m_nSHADER_SRGB_READ; +#ifdef _DEBUG + bool m_bSHADER_SRGB_READ; +#endif +public: + void SetSHADER_SRGB_READ( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nSHADER_SRGB_READ = i; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = true; +#endif + } + void SetSHADER_SRGB_READ( bool i ) + { + m_nSHADER_SRGB_READ = i ? 1 : 0; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = true; +#endif + } +private: + int m_nSHADOWDEPTH; +#ifdef _DEBUG + bool m_bSHADOWDEPTH; +#endif +public: + void SetSHADOWDEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSHADOWDEPTH = i; +#ifdef _DEBUG + m_bSHADOWDEPTH = true; +#endif + } + void SetSHADOWDEPTH( bool i ) + { + m_nSHADOWDEPTH = i ? 1 : 0; +#ifdef _DEBUG + m_bSHADOWDEPTH = true; +#endif + } +public: + sdk_splinerope_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bSHADER_SRGB_READ = false; +#endif // _DEBUG + m_nSHADER_SRGB_READ = 0; +#ifdef _DEBUG + m_bSHADOWDEPTH = false; +#endif // _DEBUG + m_nSHADOWDEPTH = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bSHADER_SRGB_READ && m_bSHADOWDEPTH; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nSHADER_SRGB_READ ) + ( 2 * m_nSHADOWDEPTH ) + 0; + } +}; +#define shaderStaticTest_sdk_splinerope_ps30 psh_forgot_to_set_static_SHADER_SRGB_READ + psh_forgot_to_set_static_SHADOWDEPTH + 0 +class sdk_splinerope_ps30_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_splinerope_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_splinerope_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinerope_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinerope_vs20.inc new file mode 100644 index 00000000..ba584299 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinerope_vs20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_splinerope_vs20_Static_Index +{ +public: + sdk_splinerope_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_splinerope_vs20 0 +class sdk_splinerope_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_splinerope_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_splinerope_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinerope_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinerope_vs30.inc new file mode 100644 index 00000000..97c31b1b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_splinerope_vs30.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_splinerope_vs30_Static_Index +{ +public: + sdk_splinerope_vs30_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_splinerope_vs30 0 +class sdk_splinerope_vs30_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_splinerope_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_splinerope_vs30 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_sprite_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_sprite_ps20.inc new file mode 100644 index 00000000..ac161fb8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_sprite_ps20.inc @@ -0,0 +1,187 @@ +#include "shaderlib/cshader.h" +class sdk_sprite_ps20_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nCONSTANTCOLOR; +#ifdef _DEBUG + bool m_bCONSTANTCOLOR; +#endif +public: + void SetCONSTANTCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONSTANTCOLOR = i; +#ifdef _DEBUG + m_bCONSTANTCOLOR = true; +#endif + } + void SetCONSTANTCOLOR( bool i ) + { + m_nCONSTANTCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bCONSTANTCOLOR = true; +#endif + } +private: + int m_nHDRTYPE; +#ifdef _DEBUG + bool m_bHDRTYPE; +#endif +public: + void SetHDRTYPE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nHDRTYPE = i; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } + void SetHDRTYPE( bool i ) + { + m_nHDRTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } +private: + int m_nSRGB; +#ifdef _DEBUG + bool m_bSRGB; +#endif +public: + void SetSRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSRGB = i; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } + void SetSRGB( bool i ) + { + m_nSRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } +public: + sdk_sprite_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bCONSTANTCOLOR = false; +#endif // _DEBUG + m_nCONSTANTCOLOR = 0; +#ifdef _DEBUG + m_bHDRTYPE = false; +#endif // _DEBUG + m_nHDRTYPE = 0; +#ifdef _DEBUG + m_bSRGB = false; +#endif // _DEBUG + m_nSRGB = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bCONSTANTCOLOR && m_bHDRTYPE && m_bSRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nVERTEXCOLOR ) + ( 8 * m_nCONSTANTCOLOR ) + ( 16 * m_nHDRTYPE ) + ( 48 * m_nSRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_sprite_ps20 psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_CONSTANTCOLOR + psh_forgot_to_set_static_HDRTYPE + psh_forgot_to_set_static_SRGB + 0 +class sdk_sprite_ps20_Dynamic_Index +{ +private: + int m_nHDRENABLED; +#ifdef _DEBUG + bool m_bHDRENABLED; +#endif +public: + void SetHDRENABLED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHDRENABLED = i; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } + void SetHDRENABLED( bool i ) + { + m_nHDRENABLED = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_sprite_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bHDRENABLED = false; +#endif // _DEBUG + m_nHDRENABLED = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bHDRENABLED && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nHDRENABLED ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_sprite_ps20 psh_forgot_to_set_dynamic_HDRENABLED + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_sprite_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_sprite_ps20b.inc new file mode 100644 index 00000000..35d69c88 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_sprite_ps20b.inc @@ -0,0 +1,237 @@ +#include "shaderlib/cshader.h" +class sdk_sprite_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nCONSTANTCOLOR; +#ifdef _DEBUG + bool m_bCONSTANTCOLOR; +#endif +public: + void SetCONSTANTCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONSTANTCOLOR = i; +#ifdef _DEBUG + m_bCONSTANTCOLOR = true; +#endif + } + void SetCONSTANTCOLOR( bool i ) + { + m_nCONSTANTCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bCONSTANTCOLOR = true; +#endif + } +private: + int m_nHDRTYPE; +#ifdef _DEBUG + bool m_bHDRTYPE; +#endif +public: + void SetHDRTYPE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nHDRTYPE = i; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } + void SetHDRTYPE( bool i ) + { + m_nHDRTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } +private: + int m_nSRGB; +#ifdef _DEBUG + bool m_bSRGB; +#endif +public: + void SetSRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSRGB = i; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } + void SetSRGB( bool i ) + { + m_nSRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } +private: + int m_nSRGB_OUTPUT_ADAPTER; +#ifdef _DEBUG + bool m_bSRGB_OUTPUT_ADAPTER; +#endif +public: + void SetSRGB_OUTPUT_ADAPTER( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSRGB_OUTPUT_ADAPTER = i; +#ifdef _DEBUG + m_bSRGB_OUTPUT_ADAPTER = true; +#endif + } + void SetSRGB_OUTPUT_ADAPTER( bool i ) + { + m_nSRGB_OUTPUT_ADAPTER = i ? 1 : 0; +#ifdef _DEBUG + m_bSRGB_OUTPUT_ADAPTER = true; +#endif + } +public: + sdk_sprite_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bCONSTANTCOLOR = false; +#endif // _DEBUG + m_nCONSTANTCOLOR = 0; +#ifdef _DEBUG + m_bHDRTYPE = false; +#endif // _DEBUG + m_nHDRTYPE = 0; +#ifdef _DEBUG + m_bSRGB = false; +#endif // _DEBUG + m_nSRGB = 0; +#ifdef _DEBUG + m_bSRGB_OUTPUT_ADAPTER = false; +#endif // _DEBUG + m_nSRGB_OUTPUT_ADAPTER = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bVERTEXCOLOR && m_bCONSTANTCOLOR && m_bHDRTYPE && m_bSRGB && m_bSRGB_OUTPUT_ADAPTER; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nVERTEXCOLOR ) + ( 16 * m_nCONSTANTCOLOR ) + ( 32 * m_nHDRTYPE ) + ( 96 * m_nSRGB ) + ( 192 * m_nSRGB_OUTPUT_ADAPTER ) + 0; + } +}; +#define shaderStaticTest_sdk_sprite_ps20b psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_CONSTANTCOLOR + psh_forgot_to_set_static_HDRTYPE + psh_forgot_to_set_static_SRGB + psh_forgot_to_set_static_SRGB_OUTPUT_ADAPTER + 0 +class sdk_sprite_ps20b_Dynamic_Index +{ +private: + int m_nHDRENABLED; +#ifdef _DEBUG + bool m_bHDRENABLED; +#endif +public: + void SetHDRENABLED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHDRENABLED = i; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } + void SetHDRENABLED( bool i ) + { + m_nHDRENABLED = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_sprite_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bHDRENABLED = false; +#endif // _DEBUG + m_nHDRENABLED = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bHDRENABLED && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nHDRENABLED ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_sprite_ps20b psh_forgot_to_set_dynamic_HDRENABLED + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_sprite_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_sprite_vs20.inc new file mode 100644 index 00000000..25ac196d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_sprite_vs20.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_sprite_vs20_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nSRGB; +#ifdef _DEBUG + bool m_bSRGB; +#endif +public: + void SetSRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSRGB = i; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } + void SetSRGB( bool i ) + { + m_nSRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } +public: + sdk_sprite_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bSRGB = false; +#endif // _DEBUG + m_nSRGB = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bSRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nVERTEXCOLOR ) + ( 4 * m_nSRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_sprite_vs20 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_SRGB + 0 +class sdk_sprite_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_sprite_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_sprite_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_spritecard_ps11.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_spritecard_ps11.inc new file mode 100644 index 00000000..cd74b706 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_spritecard_ps11.inc @@ -0,0 +1,110 @@ +#include "shaderlib/cshader.h" +class sdk_spritecard_ps11_Static_Index +{ +private: + int m_nADDBASETEXTURE2; +#ifdef _DEBUG + bool m_bADDBASETEXTURE2; +#endif +public: + void SetADDBASETEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nADDBASETEXTURE2 = i; +#ifdef _DEBUG + m_bADDBASETEXTURE2 = true; +#endif + } + void SetADDBASETEXTURE2( bool i ) + { + m_nADDBASETEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bADDBASETEXTURE2 = true; +#endif + } +private: + int m_nADDSELF; +#ifdef _DEBUG + bool m_bADDSELF; +#endif +public: + void SetADDSELF( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nADDSELF = i; +#ifdef _DEBUG + m_bADDSELF = true; +#endif + } + void SetADDSELF( bool i ) + { + m_nADDSELF = i ? 1 : 0; +#ifdef _DEBUG + m_bADDSELF = true; +#endif + } +private: + int m_nUSEALPHAASRGB; +#ifdef _DEBUG + bool m_bUSEALPHAASRGB; +#endif +public: + void SetUSEALPHAASRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSEALPHAASRGB = i; +#ifdef _DEBUG + m_bUSEALPHAASRGB = true; +#endif + } + void SetUSEALPHAASRGB( bool i ) + { + m_nUSEALPHAASRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bUSEALPHAASRGB = true; +#endif + } +public: + sdk_spritecard_ps11_Static_Index( ) + { +#ifdef _DEBUG + m_bADDBASETEXTURE2 = false; +#endif // _DEBUG + m_nADDBASETEXTURE2 = 0; +#ifdef _DEBUG + m_bADDSELF = false; +#endif // _DEBUG + m_nADDSELF = 0; +#ifdef _DEBUG + m_bUSEALPHAASRGB = false; +#endif // _DEBUG + m_nUSEALPHAASRGB = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bADDBASETEXTURE2 && m_bADDSELF && m_bUSEALPHAASRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nADDBASETEXTURE2 ) + ( 2 * m_nADDSELF ) + ( 4 * m_nUSEALPHAASRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_spritecard_ps11 psh_forgot_to_set_static_ADDBASETEXTURE2 + psh_forgot_to_set_static_ADDSELF + psh_forgot_to_set_static_USEALPHAASRGB + 0 +class sdk_spritecard_ps11_Dynamic_Index +{ +public: + sdk_spritecard_ps11_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_spritecard_ps11 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_spritecard_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_spritecard_ps20.inc new file mode 100644 index 00000000..8a66eb28 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_spritecard_ps20.inc @@ -0,0 +1,260 @@ +#include "shaderlib/cshader.h" +class sdk_spritecard_ps20_Static_Index +{ +private: + int m_nDUALSEQUENCE; +#ifdef _DEBUG + bool m_bDUALSEQUENCE; +#endif +public: + void SetDUALSEQUENCE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDUALSEQUENCE = i; +#ifdef _DEBUG + m_bDUALSEQUENCE = true; +#endif + } + void SetDUALSEQUENCE( bool i ) + { + m_nDUALSEQUENCE = i ? 1 : 0; +#ifdef _DEBUG + m_bDUALSEQUENCE = true; +#endif + } +private: + int m_nSEQUENCE_BLEND_MODE; +#ifdef _DEBUG + bool m_bSEQUENCE_BLEND_MODE; +#endif +public: + void SetSEQUENCE_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nSEQUENCE_BLEND_MODE = i; +#ifdef _DEBUG + m_bSEQUENCE_BLEND_MODE = true; +#endif + } + void SetSEQUENCE_BLEND_MODE( bool i ) + { + m_nSEQUENCE_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEQUENCE_BLEND_MODE = true; +#endif + } +private: + int m_nADDBASETEXTURE2; +#ifdef _DEBUG + bool m_bADDBASETEXTURE2; +#endif +public: + void SetADDBASETEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nADDBASETEXTURE2 = i; +#ifdef _DEBUG + m_bADDBASETEXTURE2 = true; +#endif + } + void SetADDBASETEXTURE2( bool i ) + { + m_nADDBASETEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bADDBASETEXTURE2 = true; +#endif + } +private: + int m_nMAXLUMFRAMEBLEND1; +#ifdef _DEBUG + bool m_bMAXLUMFRAMEBLEND1; +#endif +public: + void SetMAXLUMFRAMEBLEND1( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMAXLUMFRAMEBLEND1 = i; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND1 = true; +#endif + } + void SetMAXLUMFRAMEBLEND1( bool i ) + { + m_nMAXLUMFRAMEBLEND1 = i ? 1 : 0; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND1 = true; +#endif + } +private: + int m_nMAXLUMFRAMEBLEND2; +#ifdef _DEBUG + bool m_bMAXLUMFRAMEBLEND2; +#endif +public: + void SetMAXLUMFRAMEBLEND2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMAXLUMFRAMEBLEND2 = i; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND2 = true; +#endif + } + void SetMAXLUMFRAMEBLEND2( bool i ) + { + m_nMAXLUMFRAMEBLEND2 = i ? 1 : 0; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND2 = true; +#endif + } +private: + int m_nEXTRACTGREENALPHA; +#ifdef _DEBUG + bool m_bEXTRACTGREENALPHA; +#endif +public: + void SetEXTRACTGREENALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nEXTRACTGREENALPHA = i; +#ifdef _DEBUG + m_bEXTRACTGREENALPHA = true; +#endif + } + void SetEXTRACTGREENALPHA( bool i ) + { + m_nEXTRACTGREENALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bEXTRACTGREENALPHA = true; +#endif + } +private: + int m_nCOLORRAMP; +#ifdef _DEBUG + bool m_bCOLORRAMP; +#endif +public: + void SetCOLORRAMP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLORRAMP = i; +#ifdef _DEBUG + m_bCOLORRAMP = true; +#endif + } + void SetCOLORRAMP( bool i ) + { + m_nCOLORRAMP = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLORRAMP = true; +#endif + } +private: + int m_nANIMBLEND; +#ifdef _DEBUG + bool m_bANIMBLEND; +#endif +public: + void SetANIMBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nANIMBLEND = i; +#ifdef _DEBUG + m_bANIMBLEND = true; +#endif + } + void SetANIMBLEND( bool i ) + { + m_nANIMBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bANIMBLEND = true; +#endif + } +private: + int m_nADDSELF; +#ifdef _DEBUG + bool m_bADDSELF; +#endif +public: + void SetADDSELF( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nADDSELF = i; +#ifdef _DEBUG + m_bADDSELF = true; +#endif + } + void SetADDSELF( bool i ) + { + m_nADDSELF = i ? 1 : 0; +#ifdef _DEBUG + m_bADDSELF = true; +#endif + } +public: + sdk_spritecard_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bDUALSEQUENCE = false; +#endif // _DEBUG + m_nDUALSEQUENCE = 0; +#ifdef _DEBUG + m_bSEQUENCE_BLEND_MODE = false; +#endif // _DEBUG + m_nSEQUENCE_BLEND_MODE = 0; +#ifdef _DEBUG + m_bADDBASETEXTURE2 = false; +#endif // _DEBUG + m_nADDBASETEXTURE2 = 0; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND1 = false; +#endif // _DEBUG + m_nMAXLUMFRAMEBLEND1 = 0; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND2 = false; +#endif // _DEBUG + m_nMAXLUMFRAMEBLEND2 = 0; +#ifdef _DEBUG + m_bEXTRACTGREENALPHA = false; +#endif // _DEBUG + m_nEXTRACTGREENALPHA = 0; +#ifdef _DEBUG + m_bCOLORRAMP = false; +#endif // _DEBUG + m_nCOLORRAMP = 0; +#ifdef _DEBUG + m_bANIMBLEND = false; +#endif // _DEBUG + m_nANIMBLEND = 0; +#ifdef _DEBUG + m_bADDSELF = false; +#endif // _DEBUG + m_nADDSELF = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDUALSEQUENCE && m_bSEQUENCE_BLEND_MODE && m_bADDBASETEXTURE2 && m_bMAXLUMFRAMEBLEND1 && m_bMAXLUMFRAMEBLEND2 && m_bEXTRACTGREENALPHA && m_bCOLORRAMP && m_bANIMBLEND && m_bADDSELF; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDUALSEQUENCE ) + ( 2 * m_nSEQUENCE_BLEND_MODE ) + ( 6 * m_nADDBASETEXTURE2 ) + ( 12 * m_nMAXLUMFRAMEBLEND1 ) + ( 24 * m_nMAXLUMFRAMEBLEND2 ) + ( 48 * m_nEXTRACTGREENALPHA ) + ( 96 * m_nCOLORRAMP ) + ( 192 * m_nANIMBLEND ) + ( 384 * m_nADDSELF ) + 0; + } +}; +#define shaderStaticTest_sdk_spritecard_ps20 psh_forgot_to_set_static_DUALSEQUENCE + psh_forgot_to_set_static_SEQUENCE_BLEND_MODE + psh_forgot_to_set_static_ADDBASETEXTURE2 + psh_forgot_to_set_static_MAXLUMFRAMEBLEND1 + psh_forgot_to_set_static_MAXLUMFRAMEBLEND2 + psh_forgot_to_set_static_EXTRACTGREENALPHA + psh_forgot_to_set_static_COLORRAMP + psh_forgot_to_set_static_ANIMBLEND + psh_forgot_to_set_static_ADDSELF + 0 +class sdk_spritecard_ps20_Dynamic_Index +{ +public: + sdk_spritecard_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_spritecard_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_spritecard_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_spritecard_ps20b.inc new file mode 100644 index 00000000..73de883f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_spritecard_ps20b.inc @@ -0,0 +1,310 @@ +#include "shaderlib/cshader.h" +class sdk_spritecard_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nDUALSEQUENCE; +#ifdef _DEBUG + bool m_bDUALSEQUENCE; +#endif +public: + void SetDUALSEQUENCE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDUALSEQUENCE = i; +#ifdef _DEBUG + m_bDUALSEQUENCE = true; +#endif + } + void SetDUALSEQUENCE( bool i ) + { + m_nDUALSEQUENCE = i ? 1 : 0; +#ifdef _DEBUG + m_bDUALSEQUENCE = true; +#endif + } +private: + int m_nSEQUENCE_BLEND_MODE; +#ifdef _DEBUG + bool m_bSEQUENCE_BLEND_MODE; +#endif +public: + void SetSEQUENCE_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nSEQUENCE_BLEND_MODE = i; +#ifdef _DEBUG + m_bSEQUENCE_BLEND_MODE = true; +#endif + } + void SetSEQUENCE_BLEND_MODE( bool i ) + { + m_nSEQUENCE_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEQUENCE_BLEND_MODE = true; +#endif + } +private: + int m_nADDBASETEXTURE2; +#ifdef _DEBUG + bool m_bADDBASETEXTURE2; +#endif +public: + void SetADDBASETEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nADDBASETEXTURE2 = i; +#ifdef _DEBUG + m_bADDBASETEXTURE2 = true; +#endif + } + void SetADDBASETEXTURE2( bool i ) + { + m_nADDBASETEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bADDBASETEXTURE2 = true; +#endif + } +private: + int m_nMAXLUMFRAMEBLEND1; +#ifdef _DEBUG + bool m_bMAXLUMFRAMEBLEND1; +#endif +public: + void SetMAXLUMFRAMEBLEND1( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMAXLUMFRAMEBLEND1 = i; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND1 = true; +#endif + } + void SetMAXLUMFRAMEBLEND1( bool i ) + { + m_nMAXLUMFRAMEBLEND1 = i ? 1 : 0; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND1 = true; +#endif + } +private: + int m_nMAXLUMFRAMEBLEND2; +#ifdef _DEBUG + bool m_bMAXLUMFRAMEBLEND2; +#endif +public: + void SetMAXLUMFRAMEBLEND2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMAXLUMFRAMEBLEND2 = i; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND2 = true; +#endif + } + void SetMAXLUMFRAMEBLEND2( bool i ) + { + m_nMAXLUMFRAMEBLEND2 = i ? 1 : 0; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND2 = true; +#endif + } +private: + int m_nEXTRACTGREENALPHA; +#ifdef _DEBUG + bool m_bEXTRACTGREENALPHA; +#endif +public: + void SetEXTRACTGREENALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nEXTRACTGREENALPHA = i; +#ifdef _DEBUG + m_bEXTRACTGREENALPHA = true; +#endif + } + void SetEXTRACTGREENALPHA( bool i ) + { + m_nEXTRACTGREENALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bEXTRACTGREENALPHA = true; +#endif + } +private: + int m_nCOLORRAMP; +#ifdef _DEBUG + bool m_bCOLORRAMP; +#endif +public: + void SetCOLORRAMP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLORRAMP = i; +#ifdef _DEBUG + m_bCOLORRAMP = true; +#endif + } + void SetCOLORRAMP( bool i ) + { + m_nCOLORRAMP = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLORRAMP = true; +#endif + } +private: + int m_nANIMBLEND; +#ifdef _DEBUG + bool m_bANIMBLEND; +#endif +public: + void SetANIMBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nANIMBLEND = i; +#ifdef _DEBUG + m_bANIMBLEND = true; +#endif + } + void SetANIMBLEND( bool i ) + { + m_nANIMBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bANIMBLEND = true; +#endif + } +private: + int m_nADDSELF; +#ifdef _DEBUG + bool m_bADDSELF; +#endif +public: + void SetADDSELF( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nADDSELF = i; +#ifdef _DEBUG + m_bADDSELF = true; +#endif + } + void SetADDSELF( bool i ) + { + m_nADDSELF = i ? 1 : 0; +#ifdef _DEBUG + m_bADDSELF = true; +#endif + } +private: + int m_nDEPTHBLEND; +#ifdef _DEBUG + bool m_bDEPTHBLEND; +#endif +public: + void SetDEPTHBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDEPTHBLEND = i; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } + void SetDEPTHBLEND( bool i ) + { + m_nDEPTHBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } +public: + sdk_spritecard_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bDUALSEQUENCE = false; +#endif // _DEBUG + m_nDUALSEQUENCE = 0; +#ifdef _DEBUG + m_bSEQUENCE_BLEND_MODE = false; +#endif // _DEBUG + m_nSEQUENCE_BLEND_MODE = 0; +#ifdef _DEBUG + m_bADDBASETEXTURE2 = false; +#endif // _DEBUG + m_nADDBASETEXTURE2 = 0; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND1 = false; +#endif // _DEBUG + m_nMAXLUMFRAMEBLEND1 = 0; +#ifdef _DEBUG + m_bMAXLUMFRAMEBLEND2 = false; +#endif // _DEBUG + m_nMAXLUMFRAMEBLEND2 = 0; +#ifdef _DEBUG + m_bEXTRACTGREENALPHA = false; +#endif // _DEBUG + m_nEXTRACTGREENALPHA = 0; +#ifdef _DEBUG + m_bCOLORRAMP = false; +#endif // _DEBUG + m_nCOLORRAMP = 0; +#ifdef _DEBUG + m_bANIMBLEND = false; +#endif // _DEBUG + m_nANIMBLEND = 0; +#ifdef _DEBUG + m_bADDSELF = false; +#endif // _DEBUG + m_nADDSELF = 0; +#ifdef _DEBUG + m_bDEPTHBLEND = false; +#endif // _DEBUG + m_nDEPTHBLEND = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bDUALSEQUENCE && m_bSEQUENCE_BLEND_MODE && m_bADDBASETEXTURE2 && m_bMAXLUMFRAMEBLEND1 && m_bMAXLUMFRAMEBLEND2 && m_bEXTRACTGREENALPHA && m_bCOLORRAMP && m_bANIMBLEND && m_bADDSELF && m_bDEPTHBLEND; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + ( 2 * m_nDUALSEQUENCE ) + ( 4 * m_nSEQUENCE_BLEND_MODE ) + ( 12 * m_nADDBASETEXTURE2 ) + ( 24 * m_nMAXLUMFRAMEBLEND1 ) + ( 48 * m_nMAXLUMFRAMEBLEND2 ) + ( 96 * m_nEXTRACTGREENALPHA ) + ( 192 * m_nCOLORRAMP ) + ( 384 * m_nANIMBLEND ) + ( 768 * m_nADDSELF ) + ( 1536 * m_nDEPTHBLEND ) + 0; + } +}; +#define shaderStaticTest_sdk_spritecard_ps20b psh_forgot_to_set_static_DUALSEQUENCE + psh_forgot_to_set_static_SEQUENCE_BLEND_MODE + psh_forgot_to_set_static_ADDBASETEXTURE2 + psh_forgot_to_set_static_MAXLUMFRAMEBLEND1 + psh_forgot_to_set_static_MAXLUMFRAMEBLEND2 + psh_forgot_to_set_static_EXTRACTGREENALPHA + psh_forgot_to_set_static_COLORRAMP + psh_forgot_to_set_static_ANIMBLEND + psh_forgot_to_set_static_ADDSELF + psh_forgot_to_set_static_DEPTHBLEND + 0 +class sdk_spritecard_ps20b_Dynamic_Index +{ +public: + sdk_spritecard_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_spritecard_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_spritecard_vs11.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_spritecard_vs11.inc new file mode 100644 index 00000000..085cefa2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_spritecard_vs11.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_spritecard_vs11_Static_Index +{ +private: + int m_nDUALSEQUENCE; +#ifdef _DEBUG + bool m_bDUALSEQUENCE; +#endif +public: + void SetDUALSEQUENCE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nDUALSEQUENCE = i; +#ifdef _DEBUG + m_bDUALSEQUENCE = true; +#endif + } + void SetDUALSEQUENCE( bool i ) + { + m_nDUALSEQUENCE = i ? 1 : 0; +#ifdef _DEBUG + m_bDUALSEQUENCE = true; +#endif + } +public: + sdk_spritecard_vs11_Static_Index( ) + { +#ifdef _DEBUG + m_bDUALSEQUENCE = false; +#endif // _DEBUG + m_nDUALSEQUENCE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDUALSEQUENCE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 3 * m_nDUALSEQUENCE ) + 0; + } +}; +#define shaderStaticTest_sdk_spritecard_vs11 vsh_forgot_to_set_static_DUALSEQUENCE + 0 +class sdk_spritecard_vs11_Dynamic_Index +{ +private: + int m_nORIENTATION; +#ifdef _DEBUG + bool m_bORIENTATION; +#endif +public: + void SetORIENTATION( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nORIENTATION = i; +#ifdef _DEBUG + m_bORIENTATION = true; +#endif + } + void SetORIENTATION( bool i ) + { + m_nORIENTATION = i ? 1 : 0; +#ifdef _DEBUG + m_bORIENTATION = true; +#endif + } +public: + sdk_spritecard_vs11_Dynamic_Index() + { +#ifdef _DEBUG + m_bORIENTATION = false; +#endif // _DEBUG + m_nORIENTATION = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bORIENTATION; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nORIENTATION ) + 0; + } +}; +#define shaderDynamicTest_sdk_spritecard_vs11 vsh_forgot_to_set_dynamic_ORIENTATION + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_spritecard_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_spritecard_vs20.inc new file mode 100644 index 00000000..9fcca215 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_spritecard_vs20.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_spritecard_vs20_Static_Index +{ +private: + int m_nDUALSEQUENCE; +#ifdef _DEBUG + bool m_bDUALSEQUENCE; +#endif +public: + void SetDUALSEQUENCE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDUALSEQUENCE = i; +#ifdef _DEBUG + m_bDUALSEQUENCE = true; +#endif + } + void SetDUALSEQUENCE( bool i ) + { + m_nDUALSEQUENCE = i ? 1 : 0; +#ifdef _DEBUG + m_bDUALSEQUENCE = true; +#endif + } +public: + sdk_spritecard_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bDUALSEQUENCE = false; +#endif // _DEBUG + m_nDUALSEQUENCE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDUALSEQUENCE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 3 * m_nDUALSEQUENCE ) + 0; + } +}; +#define shaderStaticTest_sdk_spritecard_vs20 vsh_forgot_to_set_static_DUALSEQUENCE + 0 +class sdk_spritecard_vs20_Dynamic_Index +{ +private: + int m_nORIENTATION; +#ifdef _DEBUG + bool m_bORIENTATION; +#endif +public: + void SetORIENTATION( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nORIENTATION = i; +#ifdef _DEBUG + m_bORIENTATION = true; +#endif + } + void SetORIENTATION( bool i ) + { + m_nORIENTATION = i ? 1 : 0; +#ifdef _DEBUG + m_bORIENTATION = true; +#endif + } +public: + sdk_spritecard_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bORIENTATION = false; +#endif // _DEBUG + m_nORIENTATION = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bORIENTATION; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nORIENTATION ) + 0; + } +}; +#define shaderDynamicTest_sdk_spritecard_vs20 vsh_forgot_to_set_dynamic_ORIENTATION + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_bump_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_bump_ps20.inc new file mode 100644 index 00000000..bd2b6155 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_bump_ps20.inc @@ -0,0 +1,110 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_bump_ps20_Static_Index +{ +public: + sdk_teeth_bump_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_teeth_bump_ps20 0 +class sdk_teeth_bump_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +public: + sdk_teeth_bump_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bAMBIENT_LIGHT; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nNUM_LIGHTS ) + ( 6 * m_nAMBIENT_LIGHT ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_bump_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_bump_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_bump_ps20b.inc new file mode 100644 index 00000000..8d774cf4 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_bump_ps20b.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_bump_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_teeth_bump_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 40 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_bump_ps20b 0 +class sdk_teeth_bump_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_teeth_bump_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bAMBIENT_LIGHT && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nNUM_LIGHTS ) + ( 10 * m_nAMBIENT_LIGHT ) + ( 20 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_bump_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_bump_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_bump_ps30.inc new file mode 100644 index 00000000..b3ae4c8f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_bump_ps30.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_bump_ps30_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_teeth_bump_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 40 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_bump_ps30 0 +class sdk_teeth_bump_ps30_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_teeth_bump_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bAMBIENT_LIGHT && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nNUM_LIGHTS ) + ( 10 * m_nAMBIENT_LIGHT ) + ( 20 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_bump_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_bump_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_bump_vs20.inc new file mode 100644 index 00000000..95700dc2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_bump_vs20.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_bump_vs20_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +private: + int m_nUSE_STATIC_CONTROL_FLOW; +#ifdef _DEBUG + bool m_bUSE_STATIC_CONTROL_FLOW; +#endif +public: + void SetUSE_STATIC_CONTROL_FLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_STATIC_CONTROL_FLOW = i; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } + void SetUSE_STATIC_CONTROL_FLOW( bool i ) + { + m_nUSE_STATIC_CONTROL_FLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } +public: + sdk_teeth_bump_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = false; +#endif // _DEBUG + m_nUSE_STATIC_CONTROL_FLOW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO && m_bUSE_STATIC_CONTROL_FLOW; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 48 * m_nINTRO ) + ( 96 * m_nUSE_STATIC_CONTROL_FLOW ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_bump_vs20 vsh_forgot_to_set_static_INTRO + vsh_forgot_to_set_static_USE_STATIC_CONTROL_FLOW + 0 +class sdk_teeth_bump_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_teeth_bump_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bSTATIC_LIGHT && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nSTATIC_LIGHT ) + ( 16 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_bump_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_bump_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_bump_vs30.inc new file mode 100644 index 00000000..61d78dbe --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_bump_vs30.inc @@ -0,0 +1,187 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_bump_vs30_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +public: + sdk_teeth_bump_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 32 * m_nINTRO ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_bump_vs30 vsh_forgot_to_set_static_INTRO + 0 +class sdk_teeth_bump_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_teeth_bump_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bSTATIC_LIGHT && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nSTATIC_LIGHT ) + ( 16 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_bump_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_flashlight_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_flashlight_ps20.inc new file mode 100644 index 00000000..773cf54a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_flashlight_ps20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_flashlight_ps20_Static_Index +{ +public: + sdk_teeth_flashlight_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_teeth_flashlight_ps20 0 +class sdk_teeth_flashlight_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_teeth_flashlight_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_flashlight_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_flashlight_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_flashlight_ps20b.inc new file mode 100644 index 00000000..209eb19f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_flashlight_ps20b.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_flashlight_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_teeth_flashlight_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_flashlight_ps20b psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_teeth_flashlight_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_teeth_flashlight_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_flashlight_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_flashlight_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_flashlight_ps30.inc new file mode 100644 index 00000000..3e08d8f2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_flashlight_ps30.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_flashlight_ps30_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_teeth_flashlight_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_flashlight_ps30 psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_teeth_flashlight_ps30_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_teeth_flashlight_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_flashlight_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_flashlight_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_flashlight_vs20.inc new file mode 100644 index 00000000..b3728827 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_flashlight_vs20.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_flashlight_vs20_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +public: + sdk_teeth_flashlight_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 8 * m_nINTRO ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_flashlight_vs20 vsh_forgot_to_set_static_INTRO + 0 +class sdk_teeth_flashlight_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_teeth_flashlight_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_flashlight_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_flashlight_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_flashlight_vs30.inc new file mode 100644 index 00000000..e69d95bf --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_flashlight_vs30.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_flashlight_vs30_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +public: + sdk_teeth_flashlight_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 16 * m_nINTRO ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_flashlight_vs30 vsh_forgot_to_set_static_INTRO + 0 +class sdk_teeth_flashlight_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_teeth_flashlight_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_flashlight_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_ps20.inc new file mode 100644 index 00000000..b7eae9b2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_ps20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_ps20_Static_Index +{ +public: + sdk_teeth_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_teeth_ps20 0 +class sdk_teeth_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_teeth_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_ps20b.inc new file mode 100644 index 00000000..1fcf1c6b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_ps20b.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_teeth_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_ps20b 0 +class sdk_teeth_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_teeth_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_ps30.inc new file mode 100644 index 00000000..d2cc52f3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_ps30.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_ps30_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_teeth_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_ps30 0 +class sdk_teeth_ps30_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_teeth_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_vs20.inc new file mode 100644 index 00000000..18cc3990 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_vs20.inc @@ -0,0 +1,237 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_vs20_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +private: + int m_nUSE_STATIC_CONTROL_FLOW; +#ifdef _DEBUG + bool m_bUSE_STATIC_CONTROL_FLOW; +#endif +public: + void SetUSE_STATIC_CONTROL_FLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_STATIC_CONTROL_FLOW = i; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } + void SetUSE_STATIC_CONTROL_FLOW( bool i ) + { + m_nUSE_STATIC_CONTROL_FLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } +public: + sdk_teeth_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = false; +#endif // _DEBUG + m_nUSE_STATIC_CONTROL_FLOW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO && m_bUSE_STATIC_CONTROL_FLOW; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 96 * m_nINTRO ) + ( 192 * m_nUSE_STATIC_CONTROL_FLOW ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_vs20 vsh_forgot_to_set_static_INTRO + vsh_forgot_to_set_static_USE_STATIC_CONTROL_FLOW + 0 +class sdk_teeth_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_teeth_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nDYNAMIC_LIGHT ) + ( 16 * m_nSTATIC_LIGHT ) + ( 32 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_vs30.inc new file mode 100644 index 00000000..985f57e8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_teeth_vs30.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_vs30_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +public: + sdk_teeth_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 64 * m_nINTRO ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_vs30 vsh_forgot_to_set_static_INTRO + 0 +class sdk_teeth_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_teeth_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nDYNAMIC_LIGHT ) + ( 16 * m_nSTATIC_LIGHT ) + ( 32 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_notexture_ps11.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_notexture_ps11.inc new file mode 100644 index 00000000..c2c319ce --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_notexture_ps11.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_unlitgeneric_notexture_ps11_Static_Index +{ +public: + sdk_unlitgeneric_notexture_ps11_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_unlitgeneric_notexture_ps11 0 +class sdk_unlitgeneric_notexture_ps11_Dynamic_Index +{ +public: + sdk_unlitgeneric_notexture_ps11_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_unlitgeneric_notexture_ps11 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_notexture_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_notexture_ps20.inc new file mode 100644 index 00000000..95fe136f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_notexture_ps20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_unlitgeneric_notexture_ps20_Static_Index +{ +public: + sdk_unlitgeneric_notexture_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_unlitgeneric_notexture_ps20 0 +class sdk_unlitgeneric_notexture_ps20_Dynamic_Index +{ +public: + sdk_unlitgeneric_notexture_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_unlitgeneric_notexture_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_notexture_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_notexture_ps20b.inc new file mode 100644 index 00000000..c661cdcc --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_notexture_ps20b.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_unlitgeneric_notexture_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_unlitgeneric_notexture_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_unlitgeneric_notexture_ps20b 0 +class sdk_unlitgeneric_notexture_ps20b_Dynamic_Index +{ +public: + sdk_unlitgeneric_notexture_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_unlitgeneric_notexture_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_ps11.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_ps11.inc new file mode 100644 index 00000000..30c5c529 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_ps11.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_unlitgeneric_ps11_Static_Index +{ +public: + sdk_unlitgeneric_ps11_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_unlitgeneric_ps11 0 +class sdk_unlitgeneric_ps11_Dynamic_Index +{ +public: + sdk_unlitgeneric_ps11_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_unlitgeneric_ps11 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_ps20.inc new file mode 100644 index 00000000..96088dec --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_ps20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_unlitgeneric_ps20_Static_Index +{ +public: + sdk_unlitgeneric_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_unlitgeneric_ps20 0 +class sdk_unlitgeneric_ps20_Dynamic_Index +{ +public: + sdk_unlitgeneric_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_unlitgeneric_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_ps20b.inc new file mode 100644 index 00000000..5f0347a2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_ps20b.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_unlitgeneric_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_unlitgeneric_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_unlitgeneric_ps20b 0 +class sdk_unlitgeneric_ps20b_Dynamic_Index +{ +public: + sdk_unlitgeneric_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_unlitgeneric_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_vs20.inc new file mode 100644 index 00000000..ea58edbc --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlitgeneric_vs20.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_unlitgeneric_vs20_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +public: + sdk_unlitgeneric_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 8 * m_nVERTEXCOLOR ) + 0; + } +}; +#define shaderStaticTest_sdk_unlitgeneric_vs20 vsh_forgot_to_set_static_VERTEXCOLOR + 0 +class sdk_unlitgeneric_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_unlitgeneric_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_unlitgeneric_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_ps20.inc new file mode 100644 index 00000000..47ecb668 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_ps20.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_unlittwotexture_ps20_Static_Index +{ +private: + int m_nTRANSLUCENT; +#ifdef _DEBUG + bool m_bTRANSLUCENT; +#endif +public: + void SetTRANSLUCENT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTRANSLUCENT = i; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } + void SetTRANSLUCENT( bool i ) + { + m_nTRANSLUCENT = i ? 1 : 0; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } +public: + sdk_unlittwotexture_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bTRANSLUCENT = false; +#endif // _DEBUG + m_nTRANSLUCENT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTRANSLUCENT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nTRANSLUCENT ) + 0; + } +}; +#define shaderStaticTest_sdk_unlittwotexture_ps20 psh_forgot_to_set_static_TRANSLUCENT + 0 +class sdk_unlittwotexture_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_unlittwotexture_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_unlittwotexture_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_ps20b.inc new file mode 100644 index 00000000..52b755c8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_ps20b.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_unlittwotexture_ps20b_Static_Index +{ +private: + int m_nTRANSLUCENT; +#ifdef _DEBUG + bool m_bTRANSLUCENT; +#endif +public: + void SetTRANSLUCENT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTRANSLUCENT = i; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } + void SetTRANSLUCENT( bool i ) + { + m_nTRANSLUCENT = i ? 1 : 0; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } +public: + sdk_unlittwotexture_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bTRANSLUCENT = false; +#endif // _DEBUG + m_nTRANSLUCENT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTRANSLUCENT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nTRANSLUCENT ) + 0; + } +}; +#define shaderStaticTest_sdk_unlittwotexture_ps20b psh_forgot_to_set_static_TRANSLUCENT + 0 +class sdk_unlittwotexture_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_unlittwotexture_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_unlittwotexture_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_vs20.inc new file mode 100644 index 00000000..a9757e65 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_unlittwotexture_vs20.inc @@ -0,0 +1,110 @@ +#include "shaderlib/cshader.h" +class sdk_unlittwotexture_vs20_Static_Index +{ +public: + sdk_unlittwotexture_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_unlittwotexture_vs20 0 +class sdk_unlittwotexture_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_unlittwotexture_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_unlittwotexture_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_bump_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_bump_ps20.inc new file mode 100644 index 00000000..b6cbcf56 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_bump_ps20.inc @@ -0,0 +1,437 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_bump_ps20_Static_Index +{ +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nSELFILLUMFRESNEL; +#ifdef _DEBUG + bool m_bSELFILLUMFRESNEL; +#endif +public: + void SetSELFILLUMFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUMFRESNEL = i; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } + void SetSELFILLUMFRESNEL( bool i ) + { + m_nSELFILLUMFRESNEL = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } +private: + int m_nNORMALMAPALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bNORMALMAPALPHAENVMAPMASK; +#endif +public: + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } + void SetNORMALMAPALPHAENVMAPMASK( bool i ) + { + m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 6 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = false; +#endif // _DEBUG + m_nSELFILLUMFRESNEL = 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nNORMALMAPALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bLIGHTWARPTEXTURE && m_bSELFILLUM && m_bSELFILLUMFRESNEL && m_bNORMALMAPALPHAENVMAPMASK && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bBLENDTINTBYBASEALPHA && m_bENVMAPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 24 * m_nCUBEMAP ) + ( 48 * m_nDIFFUSELIGHTING ) + ( 96 * m_nLIGHTWARPTEXTURE ) + ( 192 * m_nSELFILLUM ) + ( 384 * m_nSELFILLUMFRESNEL ) + ( 768 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 1536 * m_nHALFLAMBERT ) + ( 3072 * m_nFLASHLIGHT ) + ( 6144 * m_nDETAILTEXTURE ) + ( 12288 * m_nDETAIL_BLEND_MODE ) + ( 86016 * m_nBLENDTINTBYBASEALPHA ) + ( 172032 * m_nENVMAPMASK ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_bump_ps20 psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_SELFILLUMFRESNEL + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_HALFLAMBERT + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_ENVMAPMASK + 0 +class sdk_vertexlit_and_unlit_generic_bump_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITEWATERFOGTODESTALPHA && m_bNUM_LIGHTS && m_bAMBIENT_LIGHT; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITEWATERFOGTODESTALPHA ) + ( 4 * m_nNUM_LIGHTS ) + ( 12 * m_nAMBIENT_LIGHT ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_bump_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_bump_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_bump_ps20b.inc new file mode 100644 index 00000000..7c81e32f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_bump_ps20b.inc @@ -0,0 +1,437 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_bump_ps20b_Static_Index +{ +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nSELFILLUMFRESNEL; +#ifdef _DEBUG + bool m_bSELFILLUMFRESNEL; +#endif +public: + void SetSELFILLUMFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUMFRESNEL = i; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } + void SetSELFILLUMFRESNEL( bool i ) + { + m_nSELFILLUMFRESNEL = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } +private: + int m_nNORMALMAPALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bNORMALMAPALPHAENVMAPMASK; +#endif +public: + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } + void SetNORMALMAPALPHAENVMAPMASK( bool i ) + { + m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 6 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = false; +#endif // _DEBUG + m_nSELFILLUMFRESNEL = 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nNORMALMAPALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bLIGHTWARPTEXTURE && m_bSELFILLUM && m_bSELFILLUMFRESNEL && m_bNORMALMAPALPHAENVMAPMASK && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bFLASHLIGHTDEPTHFILTERMODE && m_bBLENDTINTBYBASEALPHA && m_bENVMAPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 20 * m_nCUBEMAP ) + ( 40 * m_nDIFFUSELIGHTING ) + ( 80 * m_nLIGHTWARPTEXTURE ) + ( 160 * m_nSELFILLUM ) + ( 320 * m_nSELFILLUMFRESNEL ) + ( 640 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 1280 * m_nHALFLAMBERT ) + ( 2560 * m_nFLASHLIGHT ) + ( 5120 * m_nDETAILTEXTURE ) + ( 10240 * m_nDETAIL_BLEND_MODE ) + ( 71680 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 215040 * m_nBLENDTINTBYBASEALPHA ) + ( 430080 * m_nENVMAPMASK ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_bump_ps20b psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_SELFILLUMFRESNEL + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_HALFLAMBERT + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_ENVMAPMASK + 0 +class sdk_vertexlit_and_unlit_generic_bump_ps20b_Dynamic_Index +{ +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bNUM_LIGHTS && m_bAMBIENT_LIGHT && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nNUM_LIGHTS ) + ( 5 * m_nAMBIENT_LIGHT ) + ( 10 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_bump_ps20b psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_bump_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_bump_ps30.inc new file mode 100644 index 00000000..1cb70971 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_bump_ps30.inc @@ -0,0 +1,437 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_bump_ps30_Static_Index +{ +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nSELFILLUMFRESNEL; +#ifdef _DEBUG + bool m_bSELFILLUMFRESNEL; +#endif +public: + void SetSELFILLUMFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUMFRESNEL = i; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } + void SetSELFILLUMFRESNEL( bool i ) + { + m_nSELFILLUMFRESNEL = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } +private: + int m_nNORMALMAPALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bNORMALMAPALPHAENVMAPMASK; +#endif +public: + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } + void SetNORMALMAPALPHAENVMAPMASK( bool i ) + { + m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 6 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = false; +#endif // _DEBUG + m_nSELFILLUMFRESNEL = 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nNORMALMAPALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bLIGHTWARPTEXTURE && m_bSELFILLUM && m_bSELFILLUMFRESNEL && m_bNORMALMAPALPHAENVMAPMASK && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bFLASHLIGHTDEPTHFILTERMODE && m_bBLENDTINTBYBASEALPHA && m_bENVMAPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 20 * m_nCUBEMAP ) + ( 40 * m_nDIFFUSELIGHTING ) + ( 80 * m_nLIGHTWARPTEXTURE ) + ( 160 * m_nSELFILLUM ) + ( 320 * m_nSELFILLUMFRESNEL ) + ( 640 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 1280 * m_nHALFLAMBERT ) + ( 2560 * m_nFLASHLIGHT ) + ( 5120 * m_nDETAILTEXTURE ) + ( 10240 * m_nDETAIL_BLEND_MODE ) + ( 71680 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 215040 * m_nBLENDTINTBYBASEALPHA ) + ( 430080 * m_nENVMAPMASK ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_bump_ps30 psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_SELFILLUMFRESNEL + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_HALFLAMBERT + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_ENVMAPMASK + 0 +class sdk_vertexlit_and_unlit_generic_bump_ps30_Dynamic_Index +{ +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bNUM_LIGHTS && m_bAMBIENT_LIGHT && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nNUM_LIGHTS ) + ( 5 * m_nAMBIENT_LIGHT ) + ( 10 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_bump_ps30 psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_bump_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_bump_vs20.inc new file mode 100644 index 00000000..7c9fe088 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_bump_vs20.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_bump_vs20_Static_Index +{ +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nUSE_WITH_2B; +#ifdef _DEBUG + bool m_bUSE_WITH_2B; +#endif +public: + void SetUSE_WITH_2B( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_WITH_2B = i; +#ifdef _DEBUG + m_bUSE_WITH_2B = true; +#endif + } + void SetUSE_WITH_2B( bool i ) + { + m_nUSE_WITH_2B = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_WITH_2B = true; +#endif + } +private: + int m_nUSE_STATIC_CONTROL_FLOW; +#ifdef _DEBUG + bool m_bUSE_STATIC_CONTROL_FLOW; +#endif +public: + void SetUSE_STATIC_CONTROL_FLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_STATIC_CONTROL_FLOW = i; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } + void SetUSE_STATIC_CONTROL_FLOW( bool i ) + { + m_nUSE_STATIC_CONTROL_FLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bUSE_WITH_2B = false; +#endif // _DEBUG + m_nUSE_WITH_2B = 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = false; +#endif // _DEBUG + m_nUSE_STATIC_CONTROL_FLOW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bHALFLAMBERT && m_bUSE_WITH_2B && m_bUSE_STATIC_CONTROL_FLOW; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 24 * m_nHALFLAMBERT ) + ( 48 * m_nUSE_WITH_2B ) + ( 96 * m_nUSE_STATIC_CONTROL_FLOW ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_bump_vs20 vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_USE_WITH_2B + vsh_forgot_to_set_static_USE_STATIC_CONTROL_FLOW + 0 +class sdk_vertexlit_and_unlit_generic_bump_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_bump_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_bump_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_bump_vs30.inc new file mode 100644 index 00000000..06841a47 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_bump_vs30.inc @@ -0,0 +1,237 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_bump_vs30_Static_Index +{ +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nUSE_WITH_2B; +#ifdef _DEBUG + bool m_bUSE_WITH_2B; +#endif +public: + void SetUSE_WITH_2B( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_WITH_2B = i; +#ifdef _DEBUG + m_bUSE_WITH_2B = true; +#endif + } + void SetUSE_WITH_2B( bool i ) + { + m_nUSE_WITH_2B = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_WITH_2B = true; +#endif + } +private: + int m_nDECAL; +#ifdef _DEBUG + bool m_bDECAL; +#endif +public: + void SetDECAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDECAL = i; +#ifdef _DEBUG + m_bDECAL = true; +#endif + } + void SetDECAL( bool i ) + { + m_nDECAL = i ? 1 : 0; +#ifdef _DEBUG + m_bDECAL = true; +#endif + } +private: + int m_nSM30_VERTEXID; +#ifdef _DEBUG + bool m_bSM30_VERTEXID; +#endif +public: + void SetSM30_VERTEXID( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSM30_VERTEXID = i; +#ifdef _DEBUG + m_bSM30_VERTEXID = true; +#endif + } + void SetSM30_VERTEXID( bool i ) + { + m_nSM30_VERTEXID = i ? 1 : 0; +#ifdef _DEBUG + m_bSM30_VERTEXID = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bUSE_WITH_2B = false; +#endif // _DEBUG + m_nUSE_WITH_2B = 0; +#ifdef _DEBUG + m_bDECAL = false; +#endif // _DEBUG + m_nDECAL = 0; +#ifdef _DEBUG + m_bSM30_VERTEXID = false; +#endif // _DEBUG + m_nSM30_VERTEXID = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bHALFLAMBERT && m_bUSE_WITH_2B && m_bDECAL && m_bSM30_VERTEXID; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 16 * m_nHALFLAMBERT ) + ( 32 * m_nUSE_WITH_2B ) + ( 64 * m_nDECAL ) + ( 128 * m_nSM30_VERTEXID ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_bump_vs30 vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_USE_WITH_2B + vsh_forgot_to_set_static_DECAL + vsh_forgot_to_set_static_SM30_VERTEXID + 0 +class sdk_vertexlit_and_unlit_generic_bump_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_bump_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_ps20.inc new file mode 100644 index 00000000..0bf098cd --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_ps20.inc @@ -0,0 +1,562 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_ps20_Static_Index +{ +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nSELFILLUM_ENVMAPMASK_ALPHA; +#ifdef _DEBUG + bool m_bSELFILLUM_ENVMAPMASK_ALPHA; +#endif +public: + void SetSELFILLUM_ENVMAPMASK_ALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM_ENVMAPMASK_ALPHA = i; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = true; +#endif + } + void SetSELFILLUM_ENVMAPMASK_ALPHA( bool i ) + { + m_nSELFILLUM_ENVMAPMASK_ALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 9 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nSEAMLESS_BASE; +#ifdef _DEBUG + bool m_bSEAMLESS_BASE; +#endif +public: + void SetSEAMLESS_BASE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_BASE = i; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } + void SetSEAMLESS_BASE( bool i ) + { + m_nSEAMLESS_BASE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } +private: + int m_nSEAMLESS_DETAIL; +#ifdef _DEBUG + bool m_bSEAMLESS_DETAIL; +#endif +public: + void SetSEAMLESS_DETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_DETAIL = i; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } + void SetSEAMLESS_DETAIL( bool i ) + { + m_nSEAMLESS_DETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } +private: + int m_nDISTANCEALPHA; +#ifdef _DEBUG + bool m_bDISTANCEALPHA; +#endif +public: + void SetDISTANCEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHA = i; +#ifdef _DEBUG + m_bDISTANCEALPHA = true; +#endif + } + void SetDISTANCEALPHA( bool i ) + { + m_nDISTANCEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bDISTANCEALPHA = true; +#endif + } +private: + int m_nDISTANCEALPHAFROMDETAIL; +#ifdef _DEBUG + bool m_bDISTANCEALPHAFROMDETAIL; +#endif +public: + void SetDISTANCEALPHAFROMDETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHAFROMDETAIL = i; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = true; +#endif + } + void SetDISTANCEALPHAFROMDETAIL( bool i ) + { + m_nDISTANCEALPHAFROMDETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = true; +#endif + } +private: + int m_nSOFT_MASK; +#ifdef _DEBUG + bool m_bSOFT_MASK; +#endif +public: + void SetSOFT_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSOFT_MASK = i; +#ifdef _DEBUG + m_bSOFT_MASK = true; +#endif + } + void SetSOFT_MASK( bool i ) + { + m_nSOFT_MASK = i ? 1 : 0; +#ifdef _DEBUG + m_bSOFT_MASK = true; +#endif + } +private: + int m_nOUTLINE; +#ifdef _DEBUG + bool m_bOUTLINE; +#endif +public: + void SetOUTLINE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTLINE = i; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } + void SetOUTLINE( bool i ) + { + m_nOUTLINE = i ? 1 : 0; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } +private: + int m_nOUTER_GLOW; +#ifdef _DEBUG + bool m_bOUTER_GLOW; +#endif +public: + void SetOUTER_GLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTER_GLOW = i; +#ifdef _DEBUG + m_bOUTER_GLOW = true; +#endif + } + void SetOUTER_GLOW( bool i ) + { + m_nOUTER_GLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bOUTER_GLOW = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +private: + int m_nCUBEMAP_SPHERE_LEGACY; +#ifdef _DEBUG + bool m_bCUBEMAP_SPHERE_LEGACY; +#endif +public: + void SetCUBEMAP_SPHERE_LEGACY( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP_SPHERE_LEGACY = i; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = true; +#endif + } + void SetCUBEMAP_SPHERE_LEGACY( bool i ) + { + m_nCUBEMAP_SPHERE_LEGACY = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = false; +#endif // _DEBUG + m_nSELFILLUM_ENVMAPMASK_ALPHA = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = false; +#endif // _DEBUG + m_nSEAMLESS_BASE = 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = false; +#endif // _DEBUG + m_nSEAMLESS_DETAIL = 0; +#ifdef _DEBUG + m_bDISTANCEALPHA = false; +#endif // _DEBUG + m_nDISTANCEALPHA = 0; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = false; +#endif // _DEBUG + m_nDISTANCEALPHAFROMDETAIL = 0; +#ifdef _DEBUG + m_bSOFT_MASK = false; +#endif // _DEBUG + m_nSOFT_MASK = 0; +#ifdef _DEBUG + m_bOUTLINE = false; +#endif // _DEBUG + m_nOUTLINE = 0; +#ifdef _DEBUG + m_bOUTER_GLOW = false; +#endif // _DEBUG + m_nOUTER_GLOW = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = false; +#endif // _DEBUG + m_nCUBEMAP_SPHERE_LEGACY = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDETAILTEXTURE && m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bVERTEXCOLOR && m_bFLASHLIGHT && m_bSELFILLUM_ENVMAPMASK_ALPHA && m_bDETAIL_BLEND_MODE && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bDISTANCEALPHA && m_bDISTANCEALPHAFROMDETAIL && m_bSOFT_MASK && m_bOUTLINE && m_bOUTER_GLOW && m_bBLENDTINTBYBASEALPHA && m_bCUBEMAP_SPHERE_LEGACY; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 6 * m_nDETAILTEXTURE ) + ( 12 * m_nCUBEMAP ) + ( 24 * m_nDIFFUSELIGHTING ) + ( 48 * m_nENVMAPMASK ) + ( 96 * m_nBASEALPHAENVMAPMASK ) + ( 192 * m_nSELFILLUM ) + ( 384 * m_nVERTEXCOLOR ) + ( 768 * m_nFLASHLIGHT ) + ( 1536 * m_nSELFILLUM_ENVMAPMASK_ALPHA ) + ( 3072 * m_nDETAIL_BLEND_MODE ) + ( 30720 * m_nSEAMLESS_BASE ) + ( 61440 * m_nSEAMLESS_DETAIL ) + ( 122880 * m_nDISTANCEALPHA ) + ( 245760 * m_nDISTANCEALPHAFROMDETAIL ) + ( 491520 * m_nSOFT_MASK ) + ( 983040 * m_nOUTLINE ) + ( 1966080 * m_nOUTER_GLOW ) + ( 3932160 * m_nBLENDTINTBYBASEALPHA ) + ( 7864320 * m_nCUBEMAP_SPHERE_LEGACY ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_ps20 psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_SELFILLUM_ENVMAPMASK_ALPHA + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_SEAMLESS_BASE + psh_forgot_to_set_static_SEAMLESS_DETAIL + psh_forgot_to_set_static_DISTANCEALPHA + psh_forgot_to_set_static_DISTANCEALPHAFROMDETAIL + psh_forgot_to_set_static_SOFT_MASK + psh_forgot_to_set_static_OUTLINE + psh_forgot_to_set_static_OUTER_GLOW + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_CUBEMAP_SPHERE_LEGACY + 0 +class sdk_vertexlit_and_unlit_generic_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bLIGHTING_PREVIEW; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nLIGHTING_PREVIEW ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_LIGHTING_PREVIEW + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_ps20b.inc new file mode 100644 index 00000000..ee74372c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_ps20b.inc @@ -0,0 +1,637 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_ps20b_Static_Index +{ +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nSELFILLUM_ENVMAPMASK_ALPHA; +#ifdef _DEBUG + bool m_bSELFILLUM_ENVMAPMASK_ALPHA; +#endif +public: + void SetSELFILLUM_ENVMAPMASK_ALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM_ENVMAPMASK_ALPHA = i; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = true; +#endif + } + void SetSELFILLUM_ENVMAPMASK_ALPHA( bool i ) + { + m_nSELFILLUM_ENVMAPMASK_ALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 9 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nSEAMLESS_BASE; +#ifdef _DEBUG + bool m_bSEAMLESS_BASE; +#endif +public: + void SetSEAMLESS_BASE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_BASE = i; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } + void SetSEAMLESS_BASE( bool i ) + { + m_nSEAMLESS_BASE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } +private: + int m_nSEAMLESS_DETAIL; +#ifdef _DEBUG + bool m_bSEAMLESS_DETAIL; +#endif +public: + void SetSEAMLESS_DETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_DETAIL = i; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } + void SetSEAMLESS_DETAIL( bool i ) + { + m_nSEAMLESS_DETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } +private: + int m_nDISTANCEALPHA; +#ifdef _DEBUG + bool m_bDISTANCEALPHA; +#endif +public: + void SetDISTANCEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHA = i; +#ifdef _DEBUG + m_bDISTANCEALPHA = true; +#endif + } + void SetDISTANCEALPHA( bool i ) + { + m_nDISTANCEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bDISTANCEALPHA = true; +#endif + } +private: + int m_nDISTANCEALPHAFROMDETAIL; +#ifdef _DEBUG + bool m_bDISTANCEALPHAFROMDETAIL; +#endif +public: + void SetDISTANCEALPHAFROMDETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHAFROMDETAIL = i; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = true; +#endif + } + void SetDISTANCEALPHAFROMDETAIL( bool i ) + { + m_nDISTANCEALPHAFROMDETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = true; +#endif + } +private: + int m_nSOFT_MASK; +#ifdef _DEBUG + bool m_bSOFT_MASK; +#endif +public: + void SetSOFT_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSOFT_MASK = i; +#ifdef _DEBUG + m_bSOFT_MASK = true; +#endif + } + void SetSOFT_MASK( bool i ) + { + m_nSOFT_MASK = i ? 1 : 0; +#ifdef _DEBUG + m_bSOFT_MASK = true; +#endif + } +private: + int m_nOUTLINE; +#ifdef _DEBUG + bool m_bOUTLINE; +#endif +public: + void SetOUTLINE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTLINE = i; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } + void SetOUTLINE( bool i ) + { + m_nOUTLINE = i ? 1 : 0; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } +private: + int m_nOUTER_GLOW; +#ifdef _DEBUG + bool m_bOUTER_GLOW; +#endif +public: + void SetOUTER_GLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTER_GLOW = i; +#ifdef _DEBUG + m_bOUTER_GLOW = true; +#endif + } + void SetOUTER_GLOW( bool i ) + { + m_nOUTER_GLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bOUTER_GLOW = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nDEPTHBLEND; +#ifdef _DEBUG + bool m_bDEPTHBLEND; +#endif +public: + void SetDEPTHBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDEPTHBLEND = i; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } + void SetDEPTHBLEND( bool i ) + { + m_nDEPTHBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +private: + int m_nSRGB_INPUT_ADAPTER; +#ifdef _DEBUG + bool m_bSRGB_INPUT_ADAPTER; +#endif +public: + void SetSRGB_INPUT_ADAPTER( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSRGB_INPUT_ADAPTER = i; +#ifdef _DEBUG + m_bSRGB_INPUT_ADAPTER = true; +#endif + } + void SetSRGB_INPUT_ADAPTER( bool i ) + { + m_nSRGB_INPUT_ADAPTER = i ? 1 : 0; +#ifdef _DEBUG + m_bSRGB_INPUT_ADAPTER = true; +#endif + } +private: + int m_nCUBEMAP_SPHERE_LEGACY; +#ifdef _DEBUG + bool m_bCUBEMAP_SPHERE_LEGACY; +#endif +public: + void SetCUBEMAP_SPHERE_LEGACY( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP_SPHERE_LEGACY = i; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = true; +#endif + } + void SetCUBEMAP_SPHERE_LEGACY( bool i ) + { + m_nCUBEMAP_SPHERE_LEGACY = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = false; +#endif // _DEBUG + m_nSELFILLUM_ENVMAPMASK_ALPHA = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = false; +#endif // _DEBUG + m_nSEAMLESS_BASE = 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = false; +#endif // _DEBUG + m_nSEAMLESS_DETAIL = 0; +#ifdef _DEBUG + m_bDISTANCEALPHA = false; +#endif // _DEBUG + m_nDISTANCEALPHA = 0; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = false; +#endif // _DEBUG + m_nDISTANCEALPHAFROMDETAIL = 0; +#ifdef _DEBUG + m_bSOFT_MASK = false; +#endif // _DEBUG + m_nSOFT_MASK = 0; +#ifdef _DEBUG + m_bOUTLINE = false; +#endif // _DEBUG + m_nOUTLINE = 0; +#ifdef _DEBUG + m_bOUTER_GLOW = false; +#endif // _DEBUG + m_nOUTER_GLOW = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bDEPTHBLEND = false; +#endif // _DEBUG + m_nDEPTHBLEND = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; +#ifdef _DEBUG + m_bSRGB_INPUT_ADAPTER = false; +#endif // _DEBUG + m_nSRGB_INPUT_ADAPTER = 0; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = false; +#endif // _DEBUG + m_nCUBEMAP_SPHERE_LEGACY = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDETAILTEXTURE && m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bVERTEXCOLOR && m_bFLASHLIGHT && m_bSELFILLUM_ENVMAPMASK_ALPHA && m_bDETAIL_BLEND_MODE && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bDISTANCEALPHA && m_bDISTANCEALPHAFROMDETAIL && m_bSOFT_MASK && m_bOUTLINE && m_bOUTER_GLOW && m_bFLASHLIGHTDEPTHFILTERMODE && m_bDEPTHBLEND && m_bBLENDTINTBYBASEALPHA && m_bSRGB_INPUT_ADAPTER && m_bCUBEMAP_SPHERE_LEGACY; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 6 * m_nDETAILTEXTURE ) + ( 12 * m_nCUBEMAP ) + ( 24 * m_nDIFFUSELIGHTING ) + ( 48 * m_nENVMAPMASK ) + ( 96 * m_nBASEALPHAENVMAPMASK ) + ( 192 * m_nSELFILLUM ) + ( 384 * m_nVERTEXCOLOR ) + ( 768 * m_nFLASHLIGHT ) + ( 1536 * m_nSELFILLUM_ENVMAPMASK_ALPHA ) + ( 3072 * m_nDETAIL_BLEND_MODE ) + ( 30720 * m_nSEAMLESS_BASE ) + ( 61440 * m_nSEAMLESS_DETAIL ) + ( 122880 * m_nDISTANCEALPHA ) + ( 245760 * m_nDISTANCEALPHAFROMDETAIL ) + ( 491520 * m_nSOFT_MASK ) + ( 983040 * m_nOUTLINE ) + ( 1966080 * m_nOUTER_GLOW ) + ( 3932160 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 11796480 * m_nDEPTHBLEND ) + ( 23592960 * m_nBLENDTINTBYBASEALPHA ) + ( 47185920 * m_nSRGB_INPUT_ADAPTER ) + ( 94371840 * m_nCUBEMAP_SPHERE_LEGACY ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_ps20b psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_SELFILLUM_ENVMAPMASK_ALPHA + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_SEAMLESS_BASE + psh_forgot_to_set_static_SEAMLESS_DETAIL + psh_forgot_to_set_static_DISTANCEALPHA + psh_forgot_to_set_static_DISTANCEALPHAFROMDETAIL + psh_forgot_to_set_static_SOFT_MASK + psh_forgot_to_set_static_OUTLINE + psh_forgot_to_set_static_OUTER_GLOW + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_DEPTHBLEND + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_SRGB_INPUT_ADAPTER + psh_forgot_to_set_static_CUBEMAP_SPHERE_LEGACY + 0 +class sdk_vertexlit_and_unlit_generic_ps20b_Dynamic_Index +{ +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bLIGHTING_PREVIEW && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nLIGHTING_PREVIEW ) + ( 3 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_ps20b psh_forgot_to_set_dynamic_LIGHTING_PREVIEW + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_ps30.inc new file mode 100644 index 00000000..c5a18611 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_ps30.inc @@ -0,0 +1,612 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_ps30_Static_Index +{ +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nSELFILLUM_ENVMAPMASK_ALPHA; +#ifdef _DEBUG + bool m_bSELFILLUM_ENVMAPMASK_ALPHA; +#endif +public: + void SetSELFILLUM_ENVMAPMASK_ALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM_ENVMAPMASK_ALPHA = i; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = true; +#endif + } + void SetSELFILLUM_ENVMAPMASK_ALPHA( bool i ) + { + m_nSELFILLUM_ENVMAPMASK_ALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 9 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nSEAMLESS_BASE; +#ifdef _DEBUG + bool m_bSEAMLESS_BASE; +#endif +public: + void SetSEAMLESS_BASE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_BASE = i; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } + void SetSEAMLESS_BASE( bool i ) + { + m_nSEAMLESS_BASE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } +private: + int m_nSEAMLESS_DETAIL; +#ifdef _DEBUG + bool m_bSEAMLESS_DETAIL; +#endif +public: + void SetSEAMLESS_DETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_DETAIL = i; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } + void SetSEAMLESS_DETAIL( bool i ) + { + m_nSEAMLESS_DETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } +private: + int m_nDISTANCEALPHA; +#ifdef _DEBUG + bool m_bDISTANCEALPHA; +#endif +public: + void SetDISTANCEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHA = i; +#ifdef _DEBUG + m_bDISTANCEALPHA = true; +#endif + } + void SetDISTANCEALPHA( bool i ) + { + m_nDISTANCEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bDISTANCEALPHA = true; +#endif + } +private: + int m_nDISTANCEALPHAFROMDETAIL; +#ifdef _DEBUG + bool m_bDISTANCEALPHAFROMDETAIL; +#endif +public: + void SetDISTANCEALPHAFROMDETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHAFROMDETAIL = i; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = true; +#endif + } + void SetDISTANCEALPHAFROMDETAIL( bool i ) + { + m_nDISTANCEALPHAFROMDETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = true; +#endif + } +private: + int m_nSOFT_MASK; +#ifdef _DEBUG + bool m_bSOFT_MASK; +#endif +public: + void SetSOFT_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSOFT_MASK = i; +#ifdef _DEBUG + m_bSOFT_MASK = true; +#endif + } + void SetSOFT_MASK( bool i ) + { + m_nSOFT_MASK = i ? 1 : 0; +#ifdef _DEBUG + m_bSOFT_MASK = true; +#endif + } +private: + int m_nOUTLINE; +#ifdef _DEBUG + bool m_bOUTLINE; +#endif +public: + void SetOUTLINE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTLINE = i; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } + void SetOUTLINE( bool i ) + { + m_nOUTLINE = i ? 1 : 0; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } +private: + int m_nOUTER_GLOW; +#ifdef _DEBUG + bool m_bOUTER_GLOW; +#endif +public: + void SetOUTER_GLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTER_GLOW = i; +#ifdef _DEBUG + m_bOUTER_GLOW = true; +#endif + } + void SetOUTER_GLOW( bool i ) + { + m_nOUTER_GLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bOUTER_GLOW = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nDEPTHBLEND; +#ifdef _DEBUG + bool m_bDEPTHBLEND; +#endif +public: + void SetDEPTHBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDEPTHBLEND = i; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } + void SetDEPTHBLEND( bool i ) + { + m_nDEPTHBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +private: + int m_nCUBEMAP_SPHERE_LEGACY; +#ifdef _DEBUG + bool m_bCUBEMAP_SPHERE_LEGACY; +#endif +public: + void SetCUBEMAP_SPHERE_LEGACY( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP_SPHERE_LEGACY = i; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = true; +#endif + } + void SetCUBEMAP_SPHERE_LEGACY( bool i ) + { + m_nCUBEMAP_SPHERE_LEGACY = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = false; +#endif // _DEBUG + m_nSELFILLUM_ENVMAPMASK_ALPHA = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = false; +#endif // _DEBUG + m_nSEAMLESS_BASE = 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = false; +#endif // _DEBUG + m_nSEAMLESS_DETAIL = 0; +#ifdef _DEBUG + m_bDISTANCEALPHA = false; +#endif // _DEBUG + m_nDISTANCEALPHA = 0; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = false; +#endif // _DEBUG + m_nDISTANCEALPHAFROMDETAIL = 0; +#ifdef _DEBUG + m_bSOFT_MASK = false; +#endif // _DEBUG + m_nSOFT_MASK = 0; +#ifdef _DEBUG + m_bOUTLINE = false; +#endif // _DEBUG + m_nOUTLINE = 0; +#ifdef _DEBUG + m_bOUTER_GLOW = false; +#endif // _DEBUG + m_nOUTER_GLOW = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bDEPTHBLEND = false; +#endif // _DEBUG + m_nDEPTHBLEND = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = false; +#endif // _DEBUG + m_nCUBEMAP_SPHERE_LEGACY = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDETAILTEXTURE && m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bVERTEXCOLOR && m_bFLASHLIGHT && m_bSELFILLUM_ENVMAPMASK_ALPHA && m_bDETAIL_BLEND_MODE && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bDISTANCEALPHA && m_bDISTANCEALPHAFROMDETAIL && m_bSOFT_MASK && m_bOUTLINE && m_bOUTER_GLOW && m_bFLASHLIGHTDEPTHFILTERMODE && m_bDEPTHBLEND && m_bBLENDTINTBYBASEALPHA && m_bCUBEMAP_SPHERE_LEGACY; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 6 * m_nDETAILTEXTURE ) + ( 12 * m_nCUBEMAP ) + ( 24 * m_nDIFFUSELIGHTING ) + ( 48 * m_nENVMAPMASK ) + ( 96 * m_nBASEALPHAENVMAPMASK ) + ( 192 * m_nSELFILLUM ) + ( 384 * m_nVERTEXCOLOR ) + ( 768 * m_nFLASHLIGHT ) + ( 1536 * m_nSELFILLUM_ENVMAPMASK_ALPHA ) + ( 3072 * m_nDETAIL_BLEND_MODE ) + ( 30720 * m_nSEAMLESS_BASE ) + ( 61440 * m_nSEAMLESS_DETAIL ) + ( 122880 * m_nDISTANCEALPHA ) + ( 245760 * m_nDISTANCEALPHAFROMDETAIL ) + ( 491520 * m_nSOFT_MASK ) + ( 983040 * m_nOUTLINE ) + ( 1966080 * m_nOUTER_GLOW ) + ( 3932160 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 11796480 * m_nDEPTHBLEND ) + ( 23592960 * m_nBLENDTINTBYBASEALPHA ) + ( 47185920 * m_nCUBEMAP_SPHERE_LEGACY ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_ps30 psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_SELFILLUM_ENVMAPMASK_ALPHA + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_SEAMLESS_BASE + psh_forgot_to_set_static_SEAMLESS_DETAIL + psh_forgot_to_set_static_DISTANCEALPHA + psh_forgot_to_set_static_DISTANCEALPHAFROMDETAIL + psh_forgot_to_set_static_SOFT_MASK + psh_forgot_to_set_static_OUTLINE + psh_forgot_to_set_static_OUTER_GLOW + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_DEPTHBLEND + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_CUBEMAP_SPHERE_LEGACY + 0 +class sdk_vertexlit_and_unlit_generic_ps30_Dynamic_Index +{ +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bLIGHTING_PREVIEW && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nLIGHTING_PREVIEW ) + ( 3 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_ps30 psh_forgot_to_set_dynamic_LIGHTING_PREVIEW + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_vs20.inc new file mode 100644 index 00000000..d63378dc --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_vs20.inc @@ -0,0 +1,462 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_vs20_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nSEAMLESS_BASE; +#ifdef _DEBUG + bool m_bSEAMLESS_BASE; +#endif +public: + void SetSEAMLESS_BASE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_BASE = i; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } + void SetSEAMLESS_BASE( bool i ) + { + m_nSEAMLESS_BASE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } +private: + int m_nSEAMLESS_DETAIL; +#ifdef _DEBUG + bool m_bSEAMLESS_DETAIL; +#endif +public: + void SetSEAMLESS_DETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_DETAIL = i; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } + void SetSEAMLESS_DETAIL( bool i ) + { + m_nSEAMLESS_DETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } +private: + int m_nSEPARATE_DETAIL_UVS; +#ifdef _DEBUG + bool m_bSEPARATE_DETAIL_UVS; +#endif +public: + void SetSEPARATE_DETAIL_UVS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEPARATE_DETAIL_UVS = i; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = true; +#endif + } + void SetSEPARATE_DETAIL_UVS( bool i ) + { + m_nSEPARATE_DETAIL_UVS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = true; +#endif + } +private: + int m_nUSE_STATIC_CONTROL_FLOW; +#ifdef _DEBUG + bool m_bUSE_STATIC_CONTROL_FLOW; +#endif +public: + void SetUSE_STATIC_CONTROL_FLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_STATIC_CONTROL_FLOW = i; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } + void SetUSE_STATIC_CONTROL_FLOW( bool i ) + { + m_nUSE_STATIC_CONTROL_FLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } +private: + int m_nDONT_GAMMA_CONVERT_VERTEX_COLOR; +#ifdef _DEBUG + bool m_bDONT_GAMMA_CONVERT_VERTEX_COLOR; +#endif +public: + void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i; +#ifdef _DEBUG + m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; +#endif + } + void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( bool i ) + { + m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; +#endif + } +private: + int m_nTREESWAY; +#ifdef _DEBUG + bool m_bTREESWAY; +#endif +public: + void SetTREESWAY( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nTREESWAY = i; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif + } + void SetTREESWAY( bool i ) + { + m_nTREESWAY = i ? 1 : 0; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = false; +#endif // _DEBUG + m_nSEAMLESS_BASE = 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = false; +#endif // _DEBUG + m_nSEAMLESS_DETAIL = 0; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = false; +#endif // _DEBUG + m_nSEPARATE_DETAIL_UVS = 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = false; +#endif // _DEBUG + m_nUSE_STATIC_CONTROL_FLOW = 0; +#ifdef _DEBUG + m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = false; +#endif // _DEBUG + m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = 0; +#ifdef _DEBUG + m_bTREESWAY = false; +#endif // _DEBUG + m_nTREESWAY = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bCUBEMAP && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bSEPARATE_DETAIL_UVS && m_bUSE_STATIC_CONTROL_FLOW && m_bDONT_GAMMA_CONVERT_VERTEX_COLOR && m_bTREESWAY; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 192 * m_nVERTEXCOLOR ) + ( 384 * m_nCUBEMAP ) + ( 768 * m_nHALFLAMBERT ) + ( 1536 * m_nFLASHLIGHT ) + ( 3072 * m_nSEAMLESS_BASE ) + ( 6144 * m_nSEAMLESS_DETAIL ) + ( 12288 * m_nSEPARATE_DETAIL_UVS ) + ( 24576 * m_nUSE_STATIC_CONTROL_FLOW ) + ( 49152 * m_nDONT_GAMMA_CONVERT_VERTEX_COLOR ) + ( 98304 * m_nTREESWAY ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_vs20 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_CUBEMAP + vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_FLASHLIGHT + vsh_forgot_to_set_static_SEAMLESS_BASE + vsh_forgot_to_set_static_SEAMLESS_DETAIL + vsh_forgot_to_set_static_SEPARATE_DETAIL_UVS + vsh_forgot_to_set_static_USE_STATIC_CONTROL_FLOW + vsh_forgot_to_set_static_DONT_GAMMA_CONVERT_VERTEX_COLOR + vsh_forgot_to_set_static_TREESWAY + 0 +class sdk_vertexlit_and_unlit_generic_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDYNAMIC_LIGHT ) + ( 4 * m_nSTATIC_LIGHT ) + ( 8 * m_nDOWATERFOG ) + ( 16 * m_nSKINNING ) + ( 32 * m_nLIGHTING_PREVIEW ) + ( 64 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_vs30.inc new file mode 100644 index 00000000..f2bc6c63 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_and_unlit_generic_vs30.inc @@ -0,0 +1,487 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_vs30_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nSEAMLESS_BASE; +#ifdef _DEBUG + bool m_bSEAMLESS_BASE; +#endif +public: + void SetSEAMLESS_BASE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_BASE = i; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } + void SetSEAMLESS_BASE( bool i ) + { + m_nSEAMLESS_BASE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } +private: + int m_nSEAMLESS_DETAIL; +#ifdef _DEBUG + bool m_bSEAMLESS_DETAIL; +#endif +public: + void SetSEAMLESS_DETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_DETAIL = i; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } + void SetSEAMLESS_DETAIL( bool i ) + { + m_nSEAMLESS_DETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } +private: + int m_nSEPARATE_DETAIL_UVS; +#ifdef _DEBUG + bool m_bSEPARATE_DETAIL_UVS; +#endif +public: + void SetSEPARATE_DETAIL_UVS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEPARATE_DETAIL_UVS = i; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = true; +#endif + } + void SetSEPARATE_DETAIL_UVS( bool i ) + { + m_nSEPARATE_DETAIL_UVS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = true; +#endif + } +private: + int m_nDECAL; +#ifdef _DEBUG + bool m_bDECAL; +#endif +public: + void SetDECAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDECAL = i; +#ifdef _DEBUG + m_bDECAL = true; +#endif + } + void SetDECAL( bool i ) + { + m_nDECAL = i ? 1 : 0; +#ifdef _DEBUG + m_bDECAL = true; +#endif + } +private: + int m_nSM30_VERTEXID; +#ifdef _DEBUG + bool m_bSM30_VERTEXID; +#endif +public: + void SetSM30_VERTEXID( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSM30_VERTEXID = i; +#ifdef _DEBUG + m_bSM30_VERTEXID = true; +#endif + } + void SetSM30_VERTEXID( bool i ) + { + m_nSM30_VERTEXID = i ? 1 : 0; +#ifdef _DEBUG + m_bSM30_VERTEXID = true; +#endif + } +private: + int m_nDONT_GAMMA_CONVERT_VERTEX_COLOR; +#ifdef _DEBUG + bool m_bDONT_GAMMA_CONVERT_VERTEX_COLOR; +#endif +public: + void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i; +#ifdef _DEBUG + m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; +#endif + } + void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( bool i ) + { + m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; +#endif + } +private: + int m_nTREESWAY; +#ifdef _DEBUG + bool m_bTREESWAY; +#endif +public: + void SetTREESWAY( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nTREESWAY = i; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif + } + void SetTREESWAY( bool i ) + { + m_nTREESWAY = i ? 1 : 0; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = false; +#endif // _DEBUG + m_nSEAMLESS_BASE = 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = false; +#endif // _DEBUG + m_nSEAMLESS_DETAIL = 0; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = false; +#endif // _DEBUG + m_nSEPARATE_DETAIL_UVS = 0; +#ifdef _DEBUG + m_bDECAL = false; +#endif // _DEBUG + m_nDECAL = 0; +#ifdef _DEBUG + m_bSM30_VERTEXID = false; +#endif // _DEBUG + m_nSM30_VERTEXID = 0; +#ifdef _DEBUG + m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = false; +#endif // _DEBUG + m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = 0; +#ifdef _DEBUG + m_bTREESWAY = false; +#endif // _DEBUG + m_nTREESWAY = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bCUBEMAP && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bSEPARATE_DETAIL_UVS && m_bDECAL && m_bSM30_VERTEXID && m_bDONT_GAMMA_CONVERT_VERTEX_COLOR && m_bTREESWAY; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 128 * m_nVERTEXCOLOR ) + ( 256 * m_nCUBEMAP ) + ( 512 * m_nHALFLAMBERT ) + ( 1024 * m_nFLASHLIGHT ) + ( 2048 * m_nSEAMLESS_BASE ) + ( 4096 * m_nSEAMLESS_DETAIL ) + ( 8192 * m_nSEPARATE_DETAIL_UVS ) + ( 16384 * m_nDECAL ) + ( 32768 * m_nSM30_VERTEXID ) + ( 65536 * m_nDONT_GAMMA_CONVERT_VERTEX_COLOR ) + ( 131072 * m_nTREESWAY ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_vs30 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_CUBEMAP + vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_FLASHLIGHT + vsh_forgot_to_set_static_SEAMLESS_BASE + vsh_forgot_to_set_static_SEAMLESS_DETAIL + vsh_forgot_to_set_static_SEPARATE_DETAIL_UVS + vsh_forgot_to_set_static_DECAL + vsh_forgot_to_set_static_SM30_VERTEXID + vsh_forgot_to_set_static_DONT_GAMMA_CONVERT_VERTEX_COLOR + vsh_forgot_to_set_static_TREESWAY + 0 +class sdk_vertexlit_and_unlit_generic_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDYNAMIC_LIGHT ) + ( 4 * m_nSTATIC_LIGHT ) + ( 8 * m_nDOWATERFOG ) + ( 16 * m_nSKINNING ) + ( 32 * m_nLIGHTING_PREVIEW ) + ( 64 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_lighting_only_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_lighting_only_ps20.inc new file mode 100644 index 00000000..365fb68e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_lighting_only_ps20.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_lighting_only_ps20_Static_Index +{ +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +public: + sdk_vertexlit_lighting_only_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDIFFUSELIGHTING && m_bHALFLAMBERT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 6 * m_nDIFFUSELIGHTING ) + ( 12 * m_nHALFLAMBERT ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_lighting_only_ps20 psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_HALFLAMBERT + 0 +class sdk_vertexlit_lighting_only_ps20_Dynamic_Index +{ +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_vertexlit_lighting_only_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bAMBIENT_LIGHT && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nAMBIENT_LIGHT ) + ( 2 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_lighting_only_ps20 psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_lighting_only_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_lighting_only_ps20b.inc new file mode 100644 index 00000000..a9d3beaa --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlit_lighting_only_ps20b.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_lighting_only_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +public: + sdk_vertexlit_lighting_only_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bDIFFUSELIGHTING && m_bHALFLAMBERT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 10 * m_nCONVERT_TO_SRGB ) + ( 20 * m_nDIFFUSELIGHTING ) + ( 40 * m_nHALFLAMBERT ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_lighting_only_ps20b psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_HALFLAMBERT + 0 +class sdk_vertexlit_lighting_only_ps20b_Dynamic_Index +{ +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_vertexlit_lighting_only_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bAMBIENT_LIGHT && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nAMBIENT_LIGHT ) + ( 2 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_lighting_only_ps20b psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlitgeneric_lightingonly_overbright2_ps11.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlitgeneric_lightingonly_overbright2_ps11.inc new file mode 100644 index 00000000..9f9d2b41 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vertexlitgeneric_lightingonly_overbright2_ps11.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlitgeneric_lightingonly_overbright2_ps11_Static_Index +{ +public: + sdk_vertexlitgeneric_lightingonly_overbright2_ps11_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_vertexlitgeneric_lightingonly_overbright2_ps11 0 +class sdk_vertexlitgeneric_lightingonly_overbright2_ps11_Dynamic_Index +{ +public: + sdk_vertexlitgeneric_lightingonly_overbright2_ps11_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_vertexlitgeneric_lightingonly_overbright2_ps11 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vortwarp_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vortwarp_ps20.inc new file mode 100644 index 00000000..aa256b31 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vortwarp_ps20.inc @@ -0,0 +1,337 @@ +#include "shaderlib/cshader.h" +class sdk_vortwarp_ps20_Static_Index +{ +private: + int m_nBASETEXTURE; +#ifdef _DEBUG + bool m_bBASETEXTURE; +#endif +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } + void SetBASETEXTURE( bool i ) + { + m_nBASETEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nNORMALMAPALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bNORMALMAPALPHAENVMAPMASK; +#endif +public: + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } + void SetNORMALMAPALPHAENVMAPMASK( bool i ) + { + m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nTRANSLUCENT; +#ifdef _DEBUG + bool m_bTRANSLUCENT; +#endif +public: + void SetTRANSLUCENT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTRANSLUCENT = i; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } + void SetTRANSLUCENT( bool i ) + { + m_nTRANSLUCENT = i ? 1 : 0; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } +public: + sdk_vortwarp_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bBASETEXTURE = false; +#endif // _DEBUG + m_nBASETEXTURE = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nNORMALMAPALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bTRANSLUCENT = false; +#endif // _DEBUG + m_nTRANSLUCENT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBASETEXTURE && m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bNORMALMAPALPHAENVMAPMASK && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bTRANSLUCENT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 48 * m_nBASETEXTURE ) + ( 96 * m_nCUBEMAP ) + ( 192 * m_nDIFFUSELIGHTING ) + ( 384 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 768 * m_nHALFLAMBERT ) + ( 1536 * m_nFLASHLIGHT ) + ( 3072 * m_nTRANSLUCENT ) + 0; + } +}; +#define shaderStaticTest_sdk_vortwarp_ps20 psh_forgot_to_set_static_BASETEXTURE + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_HALFLAMBERT + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_TRANSLUCENT + 0 +class sdk_vortwarp_ps20_Dynamic_Index +{ +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWARPINGIN; +#ifdef _DEBUG + bool m_bWARPINGIN; +#endif +public: + void SetWARPINGIN( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWARPINGIN = i; +#ifdef _DEBUG + m_bWARPINGIN = true; +#endif + } + void SetWARPINGIN( bool i ) + { + m_nWARPINGIN = i ? 1 : 0; +#ifdef _DEBUG + m_bWARPINGIN = true; +#endif + } +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_vortwarp_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWARPINGIN = false; +#endif // _DEBUG + m_nWARPINGIN = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bWARPINGIN && m_bAMBIENT_LIGHT && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nWARPINGIN ) + ( 8 * m_nAMBIENT_LIGHT ) + ( 16 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vortwarp_ps20 psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WARPINGIN + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vortwarp_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vortwarp_ps20b.inc new file mode 100644 index 00000000..8f14f7c5 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vortwarp_ps20b.inc @@ -0,0 +1,362 @@ +#include "shaderlib/cshader.h" +class sdk_vortwarp_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nBASETEXTURE; +#ifdef _DEBUG + bool m_bBASETEXTURE; +#endif +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } + void SetBASETEXTURE( bool i ) + { + m_nBASETEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nNORMALMAPALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bNORMALMAPALPHAENVMAPMASK; +#endif +public: + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } + void SetNORMALMAPALPHAENVMAPMASK( bool i ) + { + m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nTRANSLUCENT; +#ifdef _DEBUG + bool m_bTRANSLUCENT; +#endif +public: + void SetTRANSLUCENT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTRANSLUCENT = i; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } + void SetTRANSLUCENT( bool i ) + { + m_nTRANSLUCENT = i ? 1 : 0; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } +public: + sdk_vortwarp_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bBASETEXTURE = false; +#endif // _DEBUG + m_nBASETEXTURE = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nNORMALMAPALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bTRANSLUCENT = false; +#endif // _DEBUG + m_nTRANSLUCENT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bBASETEXTURE && m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bNORMALMAPALPHAENVMAPMASK && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bTRANSLUCENT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 80 * m_nCONVERT_TO_SRGB ) + ( 160 * m_nBASETEXTURE ) + ( 320 * m_nCUBEMAP ) + ( 640 * m_nDIFFUSELIGHTING ) + ( 1280 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 2560 * m_nHALFLAMBERT ) + ( 5120 * m_nFLASHLIGHT ) + ( 10240 * m_nTRANSLUCENT ) + 0; + } +}; +#define shaderStaticTest_sdk_vortwarp_ps20b psh_forgot_to_set_static_BASETEXTURE + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_HALFLAMBERT + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_TRANSLUCENT + 0 +class sdk_vortwarp_ps20b_Dynamic_Index +{ +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWARPINGIN; +#ifdef _DEBUG + bool m_bWARPINGIN; +#endif +public: + void SetWARPINGIN( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWARPINGIN = i; +#ifdef _DEBUG + m_bWARPINGIN = true; +#endif + } + void SetWARPINGIN( bool i ) + { + m_nWARPINGIN = i ? 1 : 0; +#ifdef _DEBUG + m_bWARPINGIN = true; +#endif + } +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_vortwarp_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWARPINGIN = false; +#endif // _DEBUG + m_nWARPINGIN = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bWARPINGIN && m_bAMBIENT_LIGHT && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nWARPINGIN ) + ( 8 * m_nAMBIENT_LIGHT ) + ( 16 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vortwarp_ps20b psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WARPINGIN + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vortwarp_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vortwarp_vs20.inc new file mode 100644 index 00000000..5222dc12 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_vortwarp_vs20.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_vortwarp_vs20_Static_Index +{ +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +public: + sdk_vortwarp_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bHALFLAMBERT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 8 * m_nHALFLAMBERT ) + 0; + } +}; +#define shaderStaticTest_sdk_vortwarp_vs20 vsh_forgot_to_set_static_HALFLAMBERT + 0 +class sdk_vortwarp_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_vortwarp_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_vortwarp_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_windowimposter_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_windowimposter_ps20.inc new file mode 100644 index 00000000..7c34f6ee --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_windowimposter_ps20.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_windowimposter_ps20_Static_Index +{ +private: + int m_nPARALLAXCORRECT; +#ifdef _DEBUG + bool m_bPARALLAXCORRECT; +#endif +public: + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } + void SetPARALLAXCORRECT( bool i ) + { + m_nPARALLAXCORRECT = i ? 1 : 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } +public: + sdk_windowimposter_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + m_nPARALLAXCORRECT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bPARALLAXCORRECT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nPARALLAXCORRECT ) + 0; + } +}; +#define shaderStaticTest_sdk_windowimposter_ps20 psh_forgot_to_set_static_PARALLAXCORRECT + 0 +class sdk_windowimposter_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_windowimposter_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_windowimposter_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_windowimposter_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_windowimposter_ps20b.inc new file mode 100644 index 00000000..e94fc94d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_windowimposter_ps20b.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_windowimposter_ps20b_Static_Index +{ +private: + int m_nPARALLAXCORRECT; +#ifdef _DEBUG + bool m_bPARALLAXCORRECT; +#endif +public: + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } + void SetPARALLAXCORRECT( bool i ) + { + m_nPARALLAXCORRECT = i ? 1 : 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } +public: + sdk_windowimposter_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + m_nPARALLAXCORRECT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bPARALLAXCORRECT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nPARALLAXCORRECT ) + 0; + } +}; +#define shaderStaticTest_sdk_windowimposter_ps20b psh_forgot_to_set_static_PARALLAXCORRECT + 0 +class sdk_windowimposter_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_windowimposter_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_windowimposter_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_windowimposter_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_windowimposter_vs20.inc new file mode 100644 index 00000000..faa096a2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_windowimposter_vs20.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_windowimposter_vs20_Static_Index +{ +private: + int m_nPARALLAXCORRECT; +#ifdef _DEBUG + bool m_bPARALLAXCORRECT; +#endif +public: + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } + void SetPARALLAXCORRECT( bool i ) + { + m_nPARALLAXCORRECT = i ? 1 : 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } +public: + sdk_windowimposter_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + m_nPARALLAXCORRECT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bPARALLAXCORRECT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nPARALLAXCORRECT ) + 0; + } +}; +#define shaderStaticTest_sdk_windowimposter_vs20 vsh_forgot_to_set_static_PARALLAXCORRECT + 0 +class sdk_windowimposter_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_windowimposter_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_windowimposter_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_worldtwotextureblend_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_worldtwotextureblend_ps20.inc new file mode 100644 index 00000000..eeef1cae --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_worldtwotextureblend_ps20.inc @@ -0,0 +1,287 @@ +#include "shaderlib/cshader.h" +class sdk_worldtwotextureblend_ps20_Static_Index +{ +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nDIFFUSEBUMPMAP; +#ifdef _DEBUG + bool m_bDIFFUSEBUMPMAP; +#endif +public: + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } + void SetDIFFUSEBUMPMAP( bool i ) + { + m_nDIFFUSEBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } +private: + int m_nDETAIL_ALPHA_MASK_BASE_TEXTURE; +#ifdef _DEBUG + bool m_bDETAIL_ALPHA_MASK_BASE_TEXTURE; +#endif +public: + void SetDETAIL_ALPHA_MASK_BASE_TEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_ALPHA_MASK_BASE_TEXTURE = i; +#ifdef _DEBUG + m_bDETAIL_ALPHA_MASK_BASE_TEXTURE = true; +#endif + } + void SetDETAIL_ALPHA_MASK_BASE_TEXTURE( bool i ) + { + m_nDETAIL_ALPHA_MASK_BASE_TEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_ALPHA_MASK_BASE_TEXTURE = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +public: + sdk_worldtwotextureblend_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = false; +#endif // _DEBUG + m_nDIFFUSEBUMPMAP = 0; +#ifdef _DEBUG + m_bDETAIL_ALPHA_MASK_BASE_TEXTURE = false; +#endif // _DEBUG + m_nDETAIL_ALPHA_MASK_BASE_TEXTURE = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDETAILTEXTURE && m_bBUMPMAP && m_bVERTEXCOLOR && m_bSELFILLUM && m_bDIFFUSEBUMPMAP && m_bDETAIL_ALPHA_MASK_BASE_TEXTURE && m_bFLASHLIGHT && m_bSEAMLESS; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nDETAILTEXTURE ) + ( 8 * m_nBUMPMAP ) + ( 16 * m_nVERTEXCOLOR ) + ( 32 * m_nSELFILLUM ) + ( 64 * m_nDIFFUSEBUMPMAP ) + ( 128 * m_nDETAIL_ALPHA_MASK_BASE_TEXTURE ) + ( 256 * m_nFLASHLIGHT ) + ( 512 * m_nSEAMLESS ) + 0; + } +}; +#define shaderStaticTest_sdk_worldtwotextureblend_ps20 psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_DIFFUSEBUMPMAP + psh_forgot_to_set_static_DETAIL_ALPHA_MASK_BASE_TEXTURE + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_SEAMLESS + 0 +class sdk_worldtwotextureblend_ps20_Dynamic_Index +{ +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_worldtwotextureblend_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_worldtwotextureblend_ps20 psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_worldtwotextureblend_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_worldtwotextureblend_ps20b.inc new file mode 100644 index 00000000..5663a738 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_worldtwotextureblend_ps20b.inc @@ -0,0 +1,387 @@ +#include "shaderlib/cshader.h" +class sdk_worldtwotextureblend_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nDIFFUSEBUMPMAP; +#ifdef _DEBUG + bool m_bDIFFUSEBUMPMAP; +#endif +public: + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } + void SetDIFFUSEBUMPMAP( bool i ) + { + m_nDIFFUSEBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } +private: + int m_nDETAIL_ALPHA_MASK_BASE_TEXTURE; +#ifdef _DEBUG + bool m_bDETAIL_ALPHA_MASK_BASE_TEXTURE; +#endif +public: + void SetDETAIL_ALPHA_MASK_BASE_TEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_ALPHA_MASK_BASE_TEXTURE = i; +#ifdef _DEBUG + m_bDETAIL_ALPHA_MASK_BASE_TEXTURE = true; +#endif + } + void SetDETAIL_ALPHA_MASK_BASE_TEXTURE( bool i ) + { + m_nDETAIL_ALPHA_MASK_BASE_TEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_ALPHA_MASK_BASE_TEXTURE = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_worldtwotextureblend_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = false; +#endif // _DEBUG + m_nDIFFUSEBUMPMAP = 0; +#ifdef _DEBUG + m_bDETAIL_ALPHA_MASK_BASE_TEXTURE = false; +#endif // _DEBUG + m_nDETAIL_ALPHA_MASK_BASE_TEXTURE = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bDETAILTEXTURE && m_bBUMPMAP && m_bVERTEXCOLOR && m_bSELFILLUM && m_bDIFFUSEBUMPMAP && m_bDETAIL_ALPHA_MASK_BASE_TEXTURE && m_bFLASHLIGHT && m_bSEAMLESS && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 16 * m_nCONVERT_TO_SRGB ) + ( 32 * m_nDETAILTEXTURE ) + ( 64 * m_nBUMPMAP ) + ( 128 * m_nVERTEXCOLOR ) + ( 256 * m_nSELFILLUM ) + ( 512 * m_nDIFFUSEBUMPMAP ) + ( 1024 * m_nDETAIL_ALPHA_MASK_BASE_TEXTURE ) + ( 2048 * m_nFLASHLIGHT ) + ( 4096 * m_nSEAMLESS ) + ( 8192 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_worldtwotextureblend_ps20b psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_DIFFUSEBUMPMAP + psh_forgot_to_set_static_DETAIL_ALPHA_MASK_BASE_TEXTURE + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_worldtwotextureblend_ps20b_Dynamic_Index +{ +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_worldtwotextureblend_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 8 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_worldtwotextureblend_ps20b psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_worldvertexalpha_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_worldvertexalpha_ps20.inc new file mode 100644 index 00000000..ebeb6c88 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_worldvertexalpha_ps20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_worldvertexalpha_ps20_Static_Index +{ +private: + int m_nPASS; +#ifdef _DEBUG + bool m_bPASS; +#endif +public: + void SetPASS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPASS = i; +#ifdef _DEBUG + m_bPASS = true; +#endif + } + void SetPASS( bool i ) + { + m_nPASS = i ? 1 : 0; +#ifdef _DEBUG + m_bPASS = true; +#endif + } +public: + sdk_worldvertexalpha_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bPASS = false; +#endif // _DEBUG + m_nPASS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bPASS; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPASS ) + 0; + } +}; +#define shaderStaticTest_sdk_worldvertexalpha_ps20 psh_forgot_to_set_static_PASS + 0 +class sdk_worldvertexalpha_ps20_Dynamic_Index +{ +public: + sdk_worldvertexalpha_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_worldvertexalpha_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/SDK_worldvertexalpha_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_worldvertexalpha_ps20b.inc new file mode 100644 index 00000000..94e4df59 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/SDK_worldvertexalpha_ps20b.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class sdk_worldvertexalpha_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nPASS; +#ifdef _DEBUG + bool m_bPASS; +#endif +public: + void SetPASS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPASS = i; +#ifdef _DEBUG + m_bPASS = true; +#endif + } + void SetPASS( bool i ) + { + m_nPASS = i ? 1 : 0; +#ifdef _DEBUG + m_bPASS = true; +#endif + } +public: + sdk_worldvertexalpha_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bPASS = false; +#endif // _DEBUG + m_nPASS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bPASS; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + ( 2 * m_nPASS ) + 0; + } +}; +#define shaderStaticTest_sdk_worldvertexalpha_ps20b psh_forgot_to_set_static_PASS + 0 +class sdk_worldvertexalpha_ps20b_Dynamic_Index +{ +public: + sdk_worldvertexalpha_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_worldvertexalpha_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/skymask_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/skymask_ps20.inc new file mode 100644 index 00000000..7f54f48c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/skymask_ps20.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class skymask_ps20_Static_Index +{ +private: + int m_nDRAWWHITE; +#ifdef _DEBUG + bool m_bDRAWWHITE; +#endif +public: + void SetDRAWWHITE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDRAWWHITE = i; +#ifdef _DEBUG + m_bDRAWWHITE = true; +#endif + } + void SetDRAWWHITE( bool i ) + { + m_nDRAWWHITE = i ? 1 : 0; +#ifdef _DEBUG + m_bDRAWWHITE = true; +#endif + } +private: + int m_nCOMBINE; +#ifdef _DEBUG + bool m_bCOMBINE; +#endif +public: + void SetCOMBINE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMBINE = i; +#ifdef _DEBUG + m_bCOMBINE = true; +#endif + } + void SetCOMBINE( bool i ) + { + m_nCOMBINE = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMBINE = true; +#endif + } +public: + skymask_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bDRAWWHITE = false; +#endif // _DEBUG + m_nDRAWWHITE = 0; +#ifdef _DEBUG + m_bCOMBINE = false; +#endif // _DEBUG + m_nCOMBINE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDRAWWHITE && m_bCOMBINE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDRAWWHITE ) + ( 2 * m_nCOMBINE ) + 0; + } +}; +#define shaderStaticTest_skymask_ps20 psh_forgot_to_set_static_DRAWWHITE + psh_forgot_to_set_static_COMBINE + 0 +class skymask_ps20_Dynamic_Index +{ +public: + skymask_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_skymask_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9/skymask_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9/skymask_vs20.inc new file mode 100644 index 00000000..4ad47a92 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9/skymask_vs20.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class skymask_vs20_Static_Index +{ +private: + int m_nDRAWWHITE; +#ifdef _DEBUG + bool m_bDRAWWHITE; +#endif +public: + void SetDRAWWHITE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDRAWWHITE = i; +#ifdef _DEBUG + m_bDRAWWHITE = true; +#endif + } + void SetDRAWWHITE( bool i ) + { + m_nDRAWWHITE = i ? 1 : 0; +#ifdef _DEBUG + m_bDRAWWHITE = true; +#endif + } +private: + int m_nCOMBINE; +#ifdef _DEBUG + bool m_bCOMBINE; +#endif +public: + void SetCOMBINE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMBINE = i; +#ifdef _DEBUG + m_bCOMBINE = true; +#endif + } + void SetCOMBINE( bool i ) + { + m_nCOMBINE = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMBINE = true; +#endif + } +public: + skymask_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bDRAWWHITE = false; +#endif // _DEBUG + m_nDRAWWHITE = 0; +#ifdef _DEBUG + m_bCOMBINE = false; +#endif // _DEBUG + m_nCOMBINE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDRAWWHITE && m_bCOMBINE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDRAWWHITE ) + ( 2 * m_nCOMBINE ) + 0; + } +}; +#define shaderStaticTest_skymask_vs20 vsh_forgot_to_set_static_DRAWWHITE + vsh_forgot_to_set_static_COMBINE + 0 +class skymask_vs20_Dynamic_Index +{ +public: + skymask_vs20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_skymask_vs20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Bloom_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Bloom_ps20.inc new file mode 100644 index 00000000..afbca75f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Bloom_ps20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_bloom_ps20_Static_Index +{ +public: + sdk_bloom_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_bloom_ps20 0 +class sdk_bloom_ps20_Dynamic_Index +{ +public: + sdk_bloom_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_bloom_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Bloom_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Bloom_ps20b.inc new file mode 100644 index 00000000..169870ee --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Bloom_ps20b.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_bloom_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_bloom_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_bloom_ps20b 0 +class sdk_bloom_ps20b_Dynamic_Index +{ +public: + sdk_bloom_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_bloom_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Refract_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Refract_vs20.inc new file mode 100644 index 00000000..58adb397 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Refract_vs20.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_refract_vs20_Static_Index +{ +private: + int m_nMODEL; +#ifdef _DEBUG + bool m_bMODEL; +#endif +public: + void SetMODEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMODEL = i; +#ifdef _DEBUG + m_bMODEL = true; +#endif + } + void SetMODEL( bool i ) + { + m_nMODEL = i ? 1 : 0; +#ifdef _DEBUG + m_bMODEL = true; +#endif + } +private: + int m_nCOLORMODULATE; +#ifdef _DEBUG + bool m_bCOLORMODULATE; +#endif +public: + void SetCOLORMODULATE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLORMODULATE = i; +#ifdef _DEBUG + m_bCOLORMODULATE = true; +#endif + } + void SetCOLORMODULATE( bool i ) + { + m_nCOLORMODULATE = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLORMODULATE = true; +#endif + } +public: + sdk_refract_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bMODEL = false; +#endif // _DEBUG + m_nMODEL = 0; +#ifdef _DEBUG + m_bCOLORMODULATE = false; +#endif // _DEBUG + m_nCOLORMODULATE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bMODEL && m_bCOLORMODULATE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nMODEL ) + ( 8 * m_nCOLORMODULATE ) + 0; + } +}; +#define shaderStaticTest_sdk_refract_vs20 vsh_forgot_to_set_static_MODEL + vsh_forgot_to_set_static_COLORMODULATE + 0 +class sdk_refract_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_refract_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_refract_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_ShatteredGlass_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_ShatteredGlass_ps20.inc new file mode 100644 index 00000000..161c4c79 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_ShatteredGlass_ps20.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_shatteredglass_ps20_Static_Index +{ +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nHDRTYPE; +#ifdef _DEBUG + bool m_bHDRTYPE; +#endif +public: + void SetHDRTYPE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nHDRTYPE = i; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } + void SetHDRTYPE( bool i ) + { + m_nHDRTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } +private: + int m_nPARALLAXCORRECT; +#ifdef _DEBUG + bool m_bPARALLAXCORRECT; +#endif +public: + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } + void SetPARALLAXCORRECT( bool i ) + { + m_nPARALLAXCORRECT = i ? 1 : 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } +public: + sdk_shatteredglass_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bHDRTYPE = false; +#endif // _DEBUG + m_nHDRTYPE = 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + m_nPARALLAXCORRECT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCUBEMAP && m_bVERTEXCOLOR && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bHDRTYPE && m_bPARALLAXCORRECT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nCUBEMAP ) + ( 4 * m_nVERTEXCOLOR ) + ( 8 * m_nENVMAPMASK ) + ( 16 * m_nBASEALPHAENVMAPMASK ) + ( 32 * m_nHDRTYPE ) + ( 96 * m_nPARALLAXCORRECT ) + 0; + } +}; +#define shaderStaticTest_sdk_shatteredglass_ps20 psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_HDRTYPE + psh_forgot_to_set_static_PARALLAXCORRECT + 0 +class sdk_shatteredglass_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_shatteredglass_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_shatteredglass_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_ShatteredGlass_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_ShatteredGlass_ps20b.inc new file mode 100644 index 00000000..5c79bd11 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_ShatteredGlass_ps20b.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_shatteredglass_ps20b_Static_Index +{ +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nHDRTYPE; +#ifdef _DEBUG + bool m_bHDRTYPE; +#endif +public: + void SetHDRTYPE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nHDRTYPE = i; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } + void SetHDRTYPE( bool i ) + { + m_nHDRTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } +private: + int m_nPARALLAXCORRECT; +#ifdef _DEBUG + bool m_bPARALLAXCORRECT; +#endif +public: + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } + void SetPARALLAXCORRECT( bool i ) + { + m_nPARALLAXCORRECT = i ? 1 : 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } +public: + sdk_shatteredglass_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bHDRTYPE = false; +#endif // _DEBUG + m_nHDRTYPE = 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + m_nPARALLAXCORRECT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCUBEMAP && m_bVERTEXCOLOR && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bHDRTYPE && m_bPARALLAXCORRECT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nCUBEMAP ) + ( 4 * m_nVERTEXCOLOR ) + ( 8 * m_nENVMAPMASK ) + ( 16 * m_nBASEALPHAENVMAPMASK ) + ( 32 * m_nHDRTYPE ) + ( 96 * m_nPARALLAXCORRECT ) + 0; + } +}; +#define shaderStaticTest_sdk_shatteredglass_ps20b psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_HDRTYPE + psh_forgot_to_set_static_PARALLAXCORRECT + 0 +class sdk_shatteredglass_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_shatteredglass_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_shatteredglass_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_ShatteredGlass_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_ShatteredGlass_vs20.inc new file mode 100644 index 00000000..a3e18d53 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_ShatteredGlass_vs20.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_shatteredglass_vs20_Static_Index +{ +private: + int m_nENVMAP_MASK; +#ifdef _DEBUG + bool m_bENVMAP_MASK; +#endif +public: + void SetENVMAP_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAP_MASK = i; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif + } + void SetENVMAP_MASK( bool i ) + { + m_nENVMAP_MASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif + } +public: + sdk_shatteredglass_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bENVMAP_MASK = false; +#endif // _DEBUG + m_nENVMAP_MASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bENVMAP_MASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nENVMAP_MASK ) + 0; + } +}; +#define shaderStaticTest_sdk_shatteredglass_vs20 vsh_forgot_to_set_static_ENVMAP_MASK + 0 +class sdk_shatteredglass_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_shatteredglass_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_shatteredglass_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WaterCheap_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WaterCheap_ps20.inc new file mode 100644 index 00000000..49475ba9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WaterCheap_ps20.inc @@ -0,0 +1,237 @@ +#include "shaderlib/cshader.h" +class sdk_watercheap_ps20_Static_Index +{ +private: + int m_nMULTITEXTURE; +#ifdef _DEBUG + bool m_bMULTITEXTURE; +#endif +public: + void SetMULTITEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMULTITEXTURE = i; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } + void SetMULTITEXTURE( bool i ) + { + m_nMULTITEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } +private: + int m_nFRESNEL; +#ifdef _DEBUG + bool m_bFRESNEL; +#endif +public: + void SetFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFRESNEL = i; +#ifdef _DEBUG + m_bFRESNEL = true; +#endif + } + void SetFRESNEL( bool i ) + { + m_nFRESNEL = i ? 1 : 0; +#ifdef _DEBUG + m_bFRESNEL = true; +#endif + } +private: + int m_nBLEND; +#ifdef _DEBUG + bool m_bBLEND; +#endif +public: + void SetBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLEND = i; +#ifdef _DEBUG + m_bBLEND = true; +#endif + } + void SetBLEND( bool i ) + { + m_nBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bBLEND = true; +#endif + } +private: + int m_nREFRACTALPHA; +#ifdef _DEBUG + bool m_bREFRACTALPHA; +#endif +public: + void SetREFRACTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACTALPHA = i; +#ifdef _DEBUG + m_bREFRACTALPHA = true; +#endif + } + void SetREFRACTALPHA( bool i ) + { + m_nREFRACTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACTALPHA = true; +#endif + } +private: + int m_nHDRTYPE; +#ifdef _DEBUG + bool m_bHDRTYPE; +#endif +public: + void SetHDRTYPE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nHDRTYPE = i; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } + void SetHDRTYPE( bool i ) + { + m_nHDRTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } +private: + int m_nNORMAL_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMAL_DECODE_MODE; +#endif +public: + void SetNORMAL_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMAL_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } + void SetNORMAL_DECODE_MODE( bool i ) + { + m_nNORMAL_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } +public: + sdk_watercheap_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bMULTITEXTURE = false; +#endif // _DEBUG + m_nMULTITEXTURE = 0; +#ifdef _DEBUG + m_bFRESNEL = false; +#endif // _DEBUG + m_nFRESNEL = 0; +#ifdef _DEBUG + m_bBLEND = false; +#endif // _DEBUG + m_nBLEND = 0; +#ifdef _DEBUG + m_bREFRACTALPHA = false; +#endif // _DEBUG + m_nREFRACTALPHA = 0; +#ifdef _DEBUG + m_bHDRTYPE = false; +#endif // _DEBUG + m_nHDRTYPE = 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMAL_DECODE_MODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bMULTITEXTURE && m_bFRESNEL && m_bBLEND && m_bREFRACTALPHA && m_bHDRTYPE && m_bNORMAL_DECODE_MODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nMULTITEXTURE ) + ( 8 * m_nFRESNEL ) + ( 16 * m_nBLEND ) + ( 32 * m_nREFRACTALPHA ) + ( 64 * m_nHDRTYPE ) + ( 192 * m_nNORMAL_DECODE_MODE ) + 0; + } +}; +#define shaderStaticTest_sdk_watercheap_ps20 psh_forgot_to_set_static_MULTITEXTURE + psh_forgot_to_set_static_FRESNEL + psh_forgot_to_set_static_BLEND + psh_forgot_to_set_static_REFRACTALPHA + psh_forgot_to_set_static_HDRTYPE + psh_forgot_to_set_static_NORMAL_DECODE_MODE + 0 +class sdk_watercheap_ps20_Dynamic_Index +{ +private: + int m_nHDRENABLED; +#ifdef _DEBUG + bool m_bHDRENABLED; +#endif +public: + void SetHDRENABLED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHDRENABLED = i; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } + void SetHDRENABLED( bool i ) + { + m_nHDRENABLED = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_watercheap_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bHDRENABLED = false; +#endif // _DEBUG + m_nHDRENABLED = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bHDRENABLED && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nHDRENABLED ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_watercheap_ps20 psh_forgot_to_set_dynamic_HDRENABLED + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WaterCheap_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WaterCheap_ps20b.inc new file mode 100644 index 00000000..6ddfc76f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WaterCheap_ps20b.inc @@ -0,0 +1,262 @@ +#include "shaderlib/cshader.h" +class sdk_watercheap_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nMULTITEXTURE; +#ifdef _DEBUG + bool m_bMULTITEXTURE; +#endif +public: + void SetMULTITEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMULTITEXTURE = i; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } + void SetMULTITEXTURE( bool i ) + { + m_nMULTITEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } +private: + int m_nFRESNEL; +#ifdef _DEBUG + bool m_bFRESNEL; +#endif +public: + void SetFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFRESNEL = i; +#ifdef _DEBUG + m_bFRESNEL = true; +#endif + } + void SetFRESNEL( bool i ) + { + m_nFRESNEL = i ? 1 : 0; +#ifdef _DEBUG + m_bFRESNEL = true; +#endif + } +private: + int m_nBLEND; +#ifdef _DEBUG + bool m_bBLEND; +#endif +public: + void SetBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLEND = i; +#ifdef _DEBUG + m_bBLEND = true; +#endif + } + void SetBLEND( bool i ) + { + m_nBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bBLEND = true; +#endif + } +private: + int m_nREFRACTALPHA; +#ifdef _DEBUG + bool m_bREFRACTALPHA; +#endif +public: + void SetREFRACTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACTALPHA = i; +#ifdef _DEBUG + m_bREFRACTALPHA = true; +#endif + } + void SetREFRACTALPHA( bool i ) + { + m_nREFRACTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACTALPHA = true; +#endif + } +private: + int m_nHDRTYPE; +#ifdef _DEBUG + bool m_bHDRTYPE; +#endif +public: + void SetHDRTYPE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nHDRTYPE = i; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } + void SetHDRTYPE( bool i ) + { + m_nHDRTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } +private: + int m_nNORMAL_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMAL_DECODE_MODE; +#endif +public: + void SetNORMAL_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMAL_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } + void SetNORMAL_DECODE_MODE( bool i ) + { + m_nNORMAL_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } +public: + sdk_watercheap_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bMULTITEXTURE = false; +#endif // _DEBUG + m_nMULTITEXTURE = 0; +#ifdef _DEBUG + m_bFRESNEL = false; +#endif // _DEBUG + m_nFRESNEL = 0; +#ifdef _DEBUG + m_bBLEND = false; +#endif // _DEBUG + m_nBLEND = 0; +#ifdef _DEBUG + m_bREFRACTALPHA = false; +#endif // _DEBUG + m_nREFRACTALPHA = 0; +#ifdef _DEBUG + m_bHDRTYPE = false; +#endif // _DEBUG + m_nHDRTYPE = 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMAL_DECODE_MODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bMULTITEXTURE && m_bFRESNEL && m_bBLEND && m_bREFRACTALPHA && m_bHDRTYPE && m_bNORMAL_DECODE_MODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nMULTITEXTURE ) + ( 16 * m_nFRESNEL ) + ( 32 * m_nBLEND ) + ( 64 * m_nREFRACTALPHA ) + ( 128 * m_nHDRTYPE ) + ( 384 * m_nNORMAL_DECODE_MODE ) + 0; + } +}; +#define shaderStaticTest_sdk_watercheap_ps20b psh_forgot_to_set_static_MULTITEXTURE + psh_forgot_to_set_static_FRESNEL + psh_forgot_to_set_static_BLEND + psh_forgot_to_set_static_REFRACTALPHA + psh_forgot_to_set_static_HDRTYPE + psh_forgot_to_set_static_NORMAL_DECODE_MODE + 0 +class sdk_watercheap_ps20b_Dynamic_Index +{ +private: + int m_nHDRENABLED; +#ifdef _DEBUG + bool m_bHDRENABLED; +#endif +public: + void SetHDRENABLED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHDRENABLED = i; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } + void SetHDRENABLED( bool i ) + { + m_nHDRENABLED = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_watercheap_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bHDRENABLED = false; +#endif // _DEBUG + m_nHDRENABLED = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bHDRENABLED && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nHDRENABLED ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_watercheap_ps20b psh_forgot_to_set_dynamic_HDRENABLED + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WaterCheap_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WaterCheap_vs20.inc new file mode 100644 index 00000000..49244f88 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WaterCheap_vs20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_watercheap_vs20_Static_Index +{ +private: + int m_nBLEND; +#ifdef _DEBUG + bool m_bBLEND; +#endif +public: + void SetBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLEND = i; +#ifdef _DEBUG + m_bBLEND = true; +#endif + } + void SetBLEND( bool i ) + { + m_nBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bBLEND = true; +#endif + } +public: + sdk_watercheap_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bBLEND = false; +#endif // _DEBUG + m_nBLEND = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBLEND; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nBLEND ) + 0; + } +}; +#define shaderStaticTest_sdk_watercheap_vs20 vsh_forgot_to_set_static_BLEND + 0 +class sdk_watercheap_vs20_Dynamic_Index +{ +public: + sdk_watercheap_vs20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_watercheap_vs20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Water_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Water_ps20.inc new file mode 100644 index 00000000..4929b59c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Water_ps20.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_water_ps20_Static_Index +{ +private: + int m_nBASETEXTURE; +#ifdef _DEBUG + bool m_bBASETEXTURE; +#endif +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } + void SetBASETEXTURE( bool i ) + { + m_nBASETEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } +private: + int m_nMULTITEXTURE; +#ifdef _DEBUG + bool m_bMULTITEXTURE; +#endif +public: + void SetMULTITEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMULTITEXTURE = i; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } + void SetMULTITEXTURE( bool i ) + { + m_nMULTITEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } +private: + int m_nREFLECT; +#ifdef _DEBUG + bool m_bREFLECT; +#endif +public: + void SetREFLECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFLECT = i; +#ifdef _DEBUG + m_bREFLECT = true; +#endif + } + void SetREFLECT( bool i ) + { + m_nREFLECT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFLECT = true; +#endif + } +private: + int m_nREFRACT; +#ifdef _DEBUG + bool m_bREFRACT; +#endif +public: + void SetREFRACT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACT = i; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } + void SetREFRACT( bool i ) + { + m_nREFRACT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } +private: + int m_nABOVEWATER; +#ifdef _DEBUG + bool m_bABOVEWATER; +#endif +public: + void SetABOVEWATER( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nABOVEWATER = i; +#ifdef _DEBUG + m_bABOVEWATER = true; +#endif + } + void SetABOVEWATER( bool i ) + { + m_nABOVEWATER = i ? 1 : 0; +#ifdef _DEBUG + m_bABOVEWATER = true; +#endif + } +private: + int m_nNORMAL_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMAL_DECODE_MODE; +#endif +public: + void SetNORMAL_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMAL_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } + void SetNORMAL_DECODE_MODE( bool i ) + { + m_nNORMAL_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } +public: + sdk_water_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bBASETEXTURE = false; +#endif // _DEBUG + m_nBASETEXTURE = 0; +#ifdef _DEBUG + m_bMULTITEXTURE = false; +#endif // _DEBUG + m_nMULTITEXTURE = 0; +#ifdef _DEBUG + m_bREFLECT = false; +#endif // _DEBUG + m_nREFLECT = 0; +#ifdef _DEBUG + m_bREFRACT = false; +#endif // _DEBUG + m_nREFRACT = 0; +#ifdef _DEBUG + m_bABOVEWATER = false; +#endif // _DEBUG + m_nABOVEWATER = 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMAL_DECODE_MODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBASETEXTURE && m_bMULTITEXTURE && m_bREFLECT && m_bREFRACT && m_bABOVEWATER && m_bNORMAL_DECODE_MODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nBASETEXTURE ) + ( 4 * m_nMULTITEXTURE ) + ( 8 * m_nREFLECT ) + ( 16 * m_nREFRACT ) + ( 32 * m_nABOVEWATER ) + ( 64 * m_nNORMAL_DECODE_MODE ) + 0; + } +}; +#define shaderStaticTest_sdk_water_ps20 psh_forgot_to_set_static_BASETEXTURE + psh_forgot_to_set_static_MULTITEXTURE + psh_forgot_to_set_static_REFLECT + psh_forgot_to_set_static_REFRACT + psh_forgot_to_set_static_ABOVEWATER + psh_forgot_to_set_static_NORMAL_DECODE_MODE + 0 +class sdk_water_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_water_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_water_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Water_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Water_ps20b.inc new file mode 100644 index 00000000..675efa7a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Water_ps20b.inc @@ -0,0 +1,287 @@ +#include "shaderlib/cshader.h" +class sdk_water_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nBASETEXTURE; +#ifdef _DEBUG + bool m_bBASETEXTURE; +#endif +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } + void SetBASETEXTURE( bool i ) + { + m_nBASETEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } +private: + int m_nMULTITEXTURE; +#ifdef _DEBUG + bool m_bMULTITEXTURE; +#endif +public: + void SetMULTITEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMULTITEXTURE = i; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } + void SetMULTITEXTURE( bool i ) + { + m_nMULTITEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } +private: + int m_nREFLECT; +#ifdef _DEBUG + bool m_bREFLECT; +#endif +public: + void SetREFLECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFLECT = i; +#ifdef _DEBUG + m_bREFLECT = true; +#endif + } + void SetREFLECT( bool i ) + { + m_nREFLECT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFLECT = true; +#endif + } +private: + int m_nREFRACT; +#ifdef _DEBUG + bool m_bREFRACT; +#endif +public: + void SetREFRACT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACT = i; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } + void SetREFRACT( bool i ) + { + m_nREFRACT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } +private: + int m_nABOVEWATER; +#ifdef _DEBUG + bool m_bABOVEWATER; +#endif +public: + void SetABOVEWATER( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nABOVEWATER = i; +#ifdef _DEBUG + m_bABOVEWATER = true; +#endif + } + void SetABOVEWATER( bool i ) + { + m_nABOVEWATER = i ? 1 : 0; +#ifdef _DEBUG + m_bABOVEWATER = true; +#endif + } +private: + int m_nBLURRY_REFRACT; +#ifdef _DEBUG + bool m_bBLURRY_REFRACT; +#endif +public: + void SetBLURRY_REFRACT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLURRY_REFRACT = i; +#ifdef _DEBUG + m_bBLURRY_REFRACT = true; +#endif + } + void SetBLURRY_REFRACT( bool i ) + { + m_nBLURRY_REFRACT = i ? 1 : 0; +#ifdef _DEBUG + m_bBLURRY_REFRACT = true; +#endif + } +private: + int m_nNORMAL_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMAL_DECODE_MODE; +#endif +public: + void SetNORMAL_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMAL_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } + void SetNORMAL_DECODE_MODE( bool i ) + { + m_nNORMAL_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } +public: + sdk_water_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bBASETEXTURE = false; +#endif // _DEBUG + m_nBASETEXTURE = 0; +#ifdef _DEBUG + m_bMULTITEXTURE = false; +#endif // _DEBUG + m_nMULTITEXTURE = 0; +#ifdef _DEBUG + m_bREFLECT = false; +#endif // _DEBUG + m_nREFLECT = 0; +#ifdef _DEBUG + m_bREFRACT = false; +#endif // _DEBUG + m_nREFRACT = 0; +#ifdef _DEBUG + m_bABOVEWATER = false; +#endif // _DEBUG + m_nABOVEWATER = 0; +#ifdef _DEBUG + m_bBLURRY_REFRACT = false; +#endif // _DEBUG + m_nBLURRY_REFRACT = 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMAL_DECODE_MODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bBASETEXTURE && m_bMULTITEXTURE && m_bREFLECT && m_bREFRACT && m_bABOVEWATER && m_bBLURRY_REFRACT && m_bNORMAL_DECODE_MODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nBASETEXTURE ) + ( 16 * m_nMULTITEXTURE ) + ( 32 * m_nREFLECT ) + ( 64 * m_nREFRACT ) + ( 128 * m_nABOVEWATER ) + ( 256 * m_nBLURRY_REFRACT ) + ( 512 * m_nNORMAL_DECODE_MODE ) + 0; + } +}; +#define shaderStaticTest_sdk_water_ps20b psh_forgot_to_set_static_BASETEXTURE + psh_forgot_to_set_static_MULTITEXTURE + psh_forgot_to_set_static_REFLECT + psh_forgot_to_set_static_REFRACT + psh_forgot_to_set_static_ABOVEWATER + psh_forgot_to_set_static_BLURRY_REFRACT + psh_forgot_to_set_static_NORMAL_DECODE_MODE + 0 +class sdk_water_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_water_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_water_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Water_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Water_vs20.inc new file mode 100644 index 00000000..67e8f134 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_Water_vs20.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class sdk_water_vs20_Static_Index +{ +private: + int m_nBASETEXTURE; +#ifdef _DEBUG + bool m_bBASETEXTURE; +#endif +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } + void SetBASETEXTURE( bool i ) + { + m_nBASETEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } +private: + int m_nMULTITEXTURE; +#ifdef _DEBUG + bool m_bMULTITEXTURE; +#endif +public: + void SetMULTITEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMULTITEXTURE = i; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } + void SetMULTITEXTURE( bool i ) + { + m_nMULTITEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bMULTITEXTURE = true; +#endif + } +public: + sdk_water_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bBASETEXTURE = false; +#endif // _DEBUG + m_nBASETEXTURE = 0; +#ifdef _DEBUG + m_bMULTITEXTURE = false; +#endif // _DEBUG + m_nMULTITEXTURE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBASETEXTURE && m_bMULTITEXTURE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nBASETEXTURE ) + ( 2 * m_nMULTITEXTURE ) + 0; + } +}; +#define shaderStaticTest_sdk_water_vs20 vsh_forgot_to_set_static_BASETEXTURE + vsh_forgot_to_set_static_MULTITEXTURE + 0 +class sdk_water_vs20_Dynamic_Index +{ +public: + sdk_water_vs20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_water_vs20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WorldVertexTransition_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WorldVertexTransition_ps20.inc new file mode 100644 index 00000000..67613947 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WorldVertexTransition_ps20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_worldvertextransition_ps20_Static_Index +{ +private: + int m_nMACROS; +#ifdef _DEBUG + bool m_bMACROS; +#endif +public: + void SetMACROS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMACROS = i; +#ifdef _DEBUG + m_bMACROS = true; +#endif + } + void SetMACROS( bool i ) + { + m_nMACROS = i ? 1 : 0; +#ifdef _DEBUG + m_bMACROS = true; +#endif + } +public: + sdk_worldvertextransition_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bMACROS = false; +#endif // _DEBUG + m_nMACROS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bMACROS; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nMACROS ) + 0; + } +}; +#define shaderStaticTest_sdk_worldvertextransition_ps20 psh_forgot_to_set_static_MACROS + 0 +class sdk_worldvertextransition_ps20_Dynamic_Index +{ +public: + sdk_worldvertextransition_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_worldvertextransition_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WorldVertexTransition_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WorldVertexTransition_ps20b.inc new file mode 100644 index 00000000..cd00eaf5 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WorldVertexTransition_ps20b.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class sdk_worldvertextransition_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nMACROS; +#ifdef _DEBUG + bool m_bMACROS; +#endif +public: + void SetMACROS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMACROS = i; +#ifdef _DEBUG + m_bMACROS = true; +#endif + } + void SetMACROS( bool i ) + { + m_nMACROS = i ? 1 : 0; +#ifdef _DEBUG + m_bMACROS = true; +#endif + } +public: + sdk_worldvertextransition_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bMACROS = false; +#endif // _DEBUG + m_nMACROS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bMACROS; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + ( 2 * m_nMACROS ) + 0; + } +}; +#define shaderStaticTest_sdk_worldvertextransition_ps20b psh_forgot_to_set_static_MACROS + 0 +class sdk_worldvertextransition_ps20b_Dynamic_Index +{ +public: + sdk_worldvertextransition_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_worldvertextransition_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WorldVertexTransition_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WorldVertexTransition_vs20.inc new file mode 100644 index 00000000..fbf30e08 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_WorldVertexTransition_vs20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_worldvertextransition_vs20_Static_Index +{ +public: + sdk_worldvertextransition_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_worldvertextransition_vs20 0 +class sdk_worldvertextransition_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_worldvertextransition_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_worldvertextransition_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_bloomadd_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_bloomadd_ps20.inc new file mode 100644 index 00000000..c0643ebe --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_bloomadd_ps20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_bloomadd_ps20_Static_Index +{ +public: + sdk_bloomadd_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_bloomadd_ps20 0 +class sdk_bloomadd_ps20_Dynamic_Index +{ +public: + sdk_bloomadd_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_bloomadd_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_bloomadd_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_bloomadd_ps20b.inc new file mode 100644 index 00000000..861e517b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_bloomadd_ps20b.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_bloomadd_ps20b_Static_Index +{ +public: + sdk_bloomadd_ps20b_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_bloomadd_ps20b 0 +class sdk_bloomadd_ps20b_Dynamic_Index +{ +public: + sdk_bloomadd_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_bloomadd_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cable_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cable_ps20.inc new file mode 100644 index 00000000..6d6f0122 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cable_ps20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_cable_ps20_Static_Index +{ +public: + sdk_cable_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_cable_ps20 0 +class sdk_cable_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_cable_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_cable_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cable_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cable_ps20b.inc new file mode 100644 index 00000000..0e73dbdf --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cable_ps20b.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_cable_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_cable_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_cable_ps20b 0 +class sdk_cable_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_cable_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_cable_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cable_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cable_vs20.inc new file mode 100644 index 00000000..d2ef4642 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cable_vs20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_cable_vs20_Static_Index +{ +public: + sdk_cable_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_cable_vs20 0 +class sdk_cable_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_cable_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_cable_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cloak_blended_pass_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cloak_blended_pass_ps20.inc new file mode 100644 index 00000000..5d52f92f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cloak_blended_pass_ps20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_cloak_blended_pass_ps20_Static_Index +{ +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +public: + sdk_cloak_blended_pass_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBUMPMAP; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nBUMPMAP ) + 0; + } +}; +#define shaderStaticTest_sdk_cloak_blended_pass_ps20 psh_forgot_to_set_static_BUMPMAP + 0 +class sdk_cloak_blended_pass_ps20_Dynamic_Index +{ +public: + sdk_cloak_blended_pass_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_cloak_blended_pass_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cloak_blended_pass_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cloak_blended_pass_ps20b.inc new file mode 100644 index 00000000..c724bbd2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cloak_blended_pass_ps20b.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class sdk_cloak_blended_pass_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +public: + sdk_cloak_blended_pass_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bBUMPMAP; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + ( 2 * m_nBUMPMAP ) + 0; + } +}; +#define shaderStaticTest_sdk_cloak_blended_pass_ps20b psh_forgot_to_set_static_BUMPMAP + 0 +class sdk_cloak_blended_pass_ps20b_Dynamic_Index +{ +public: + sdk_cloak_blended_pass_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_cloak_blended_pass_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cloak_blended_pass_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cloak_blended_pass_ps30.inc new file mode 100644 index 00000000..778aaf04 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cloak_blended_pass_ps30.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class sdk_cloak_blended_pass_ps30_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +public: + sdk_cloak_blended_pass_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bBUMPMAP; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + ( 2 * m_nBUMPMAP ) + 0; + } +}; +#define shaderStaticTest_sdk_cloak_blended_pass_ps30 psh_forgot_to_set_static_BUMPMAP + 0 +class sdk_cloak_blended_pass_ps30_Dynamic_Index +{ +public: + sdk_cloak_blended_pass_ps30_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_cloak_blended_pass_ps30 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cloak_blended_pass_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cloak_blended_pass_vs20.inc new file mode 100644 index 00000000..7f431299 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cloak_blended_pass_vs20.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_cloak_blended_pass_vs20_Static_Index +{ +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +public: + sdk_cloak_blended_pass_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBUMPMAP; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nBUMPMAP ) + 0; + } +}; +#define shaderStaticTest_sdk_cloak_blended_pass_vs20 vsh_forgot_to_set_static_BUMPMAP + 0 +class sdk_cloak_blended_pass_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_cloak_blended_pass_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_cloak_blended_pass_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cloak_blended_pass_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cloak_blended_pass_vs30.inc new file mode 100644 index 00000000..f3121788 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_cloak_blended_pass_vs30.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_cloak_blended_pass_vs30_Static_Index +{ +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +public: + sdk_cloak_blended_pass_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBUMPMAP; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 8 * m_nBUMPMAP ) + 0; + } +}; +#define shaderStaticTest_sdk_cloak_blended_pass_vs30 vsh_forgot_to_set_static_BUMPMAP + 0 +class sdk_cloak_blended_pass_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_cloak_blended_pass_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_cloak_blended_pass_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_decalmodulate_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_decalmodulate_ps20.inc new file mode 100644 index 00000000..cc1e6113 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_decalmodulate_ps20.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_decalmodulate_ps20_Static_Index +{ +private: + int m_nVERTEXALPHA; +#ifdef _DEBUG + bool m_bVERTEXALPHA; +#endif +public: + void SetVERTEXALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXALPHA = i; +#ifdef _DEBUG + m_bVERTEXALPHA = true; +#endif + } + void SetVERTEXALPHA( bool i ) + { + m_nVERTEXALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXALPHA = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +public: + sdk_decalmodulate_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXALPHA = false; +#endif // _DEBUG + m_nVERTEXALPHA = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXALPHA && m_bFLASHLIGHT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nVERTEXALPHA ) + ( 4 * m_nFLASHLIGHT ) + 0; + } +}; +#define shaderStaticTest_sdk_decalmodulate_ps20 psh_forgot_to_set_static_VERTEXALPHA + psh_forgot_to_set_static_FLASHLIGHT + 0 +class sdk_decalmodulate_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_decalmodulate_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_decalmodulate_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_decalmodulate_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_decalmodulate_ps20b.inc new file mode 100644 index 00000000..e35c8a54 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_decalmodulate_ps20b.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_decalmodulate_ps20b_Static_Index +{ +private: + int m_nVERTEXALPHA; +#ifdef _DEBUG + bool m_bVERTEXALPHA; +#endif +public: + void SetVERTEXALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXALPHA = i; +#ifdef _DEBUG + m_bVERTEXALPHA = true; +#endif + } + void SetVERTEXALPHA( bool i ) + { + m_nVERTEXALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXALPHA = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_decalmodulate_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXALPHA = false; +#endif // _DEBUG + m_nVERTEXALPHA = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXALPHA && m_bFLASHLIGHT && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nVERTEXALPHA ) + ( 8 * m_nFLASHLIGHT ) + ( 16 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_decalmodulate_ps20b psh_forgot_to_set_static_VERTEXALPHA + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_decalmodulate_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_decalmodulate_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_decalmodulate_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_decalmodulate_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_decalmodulate_ps30.inc new file mode 100644 index 00000000..db6747a2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_decalmodulate_ps30.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_decalmodulate_ps30_Static_Index +{ +private: + int m_nVERTEXALPHA; +#ifdef _DEBUG + bool m_bVERTEXALPHA; +#endif +public: + void SetVERTEXALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXALPHA = i; +#ifdef _DEBUG + m_bVERTEXALPHA = true; +#endif + } + void SetVERTEXALPHA( bool i ) + { + m_nVERTEXALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXALPHA = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_decalmodulate_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXALPHA = false; +#endif // _DEBUG + m_nVERTEXALPHA = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXALPHA && m_bFLASHLIGHT && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nVERTEXALPHA ) + ( 8 * m_nFLASHLIGHT ) + ( 16 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_decalmodulate_ps30 psh_forgot_to_set_static_VERTEXALPHA + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_decalmodulate_ps30_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_decalmodulate_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_decalmodulate_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_decalmodulate_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_decalmodulate_vs20.inc new file mode 100644 index 00000000..0f571fd7 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_decalmodulate_vs20.inc @@ -0,0 +1,187 @@ +#include "shaderlib/cshader.h" +class sdk_decalmodulate_vs20_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +public: + sdk_decalmodulate_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bLIGHTING_PREVIEW && m_bFLASHLIGHT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nVERTEXCOLOR ) + ( 8 * m_nLIGHTING_PREVIEW ) + ( 16 * m_nFLASHLIGHT ) + 0; + } +}; +#define shaderStaticTest_sdk_decalmodulate_vs20 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_LIGHTING_PREVIEW + vsh_forgot_to_set_static_FLASHLIGHT + 0 +class sdk_decalmodulate_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_decalmodulate_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG && m_bCOMPRESSED_VERTS && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + ( 2 * m_nCOMPRESSED_VERTS ) + ( 4 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_decalmodulate_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_decalmodulate_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_decalmodulate_vs30.inc new file mode 100644 index 00000000..38617b8c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_decalmodulate_vs30.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_decalmodulate_vs30_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +public: + sdk_decalmodulate_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bLIGHTING_PREVIEW && m_bFLASHLIGHT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 16 * m_nVERTEXCOLOR ) + ( 32 * m_nLIGHTING_PREVIEW ) + ( 64 * m_nFLASHLIGHT ) + 0; + } +}; +#define shaderStaticTest_sdk_decalmodulate_vs30 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_LIGHTING_PREVIEW + vsh_forgot_to_set_static_FLASHLIGHT + 0 +class sdk_decalmodulate_vs30_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_decalmodulate_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG && m_bCOMPRESSED_VERTS && m_bSKINNING && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + ( 2 * m_nCOMPRESSED_VERTS ) + ( 4 * m_nSKINNING ) + ( 8 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_decalmodulate_vs30 vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_depthwrite_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_depthwrite_ps20.inc new file mode 100644 index 00000000..938ab9bd --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_depthwrite_ps20.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_depthwrite_ps20_Static_Index +{ +private: + int m_nCOLOR_DEPTH; +#ifdef _DEBUG + bool m_bCOLOR_DEPTH; +#endif +public: + void SetCOLOR_DEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLOR_DEPTH = i; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } + void SetCOLOR_DEPTH( bool i ) + { + m_nCOLOR_DEPTH = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } +public: + sdk_depthwrite_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bCOLOR_DEPTH = false; +#endif // _DEBUG + m_nCOLOR_DEPTH = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCOLOR_DEPTH; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nCOLOR_DEPTH ) + 0; + } +}; +#define shaderStaticTest_sdk_depthwrite_ps20 psh_forgot_to_set_static_COLOR_DEPTH + 0 +class sdk_depthwrite_ps20_Dynamic_Index +{ +private: + int m_nALPHACLIP; +#ifdef _DEBUG + bool m_bALPHACLIP; +#endif +public: + void SetALPHACLIP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nALPHACLIP = i; +#ifdef _DEBUG + m_bALPHACLIP = true; +#endif + } + void SetALPHACLIP( bool i ) + { + m_nALPHACLIP = i ? 1 : 0; +#ifdef _DEBUG + m_bALPHACLIP = true; +#endif + } +public: + sdk_depthwrite_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bALPHACLIP = false; +#endif // _DEBUG + m_nALPHACLIP = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bALPHACLIP; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nALPHACLIP ) + 0; + } +}; +#define shaderDynamicTest_sdk_depthwrite_ps20 psh_forgot_to_set_dynamic_ALPHACLIP + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_depthwrite_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_depthwrite_ps20b.inc new file mode 100644 index 00000000..fc639347 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_depthwrite_ps20b.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_depthwrite_ps20b_Static_Index +{ +private: + int m_nCOLOR_DEPTH; +#ifdef _DEBUG + bool m_bCOLOR_DEPTH; +#endif +public: + void SetCOLOR_DEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLOR_DEPTH = i; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } + void SetCOLOR_DEPTH( bool i ) + { + m_nCOLOR_DEPTH = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } +public: + sdk_depthwrite_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCOLOR_DEPTH = false; +#endif // _DEBUG + m_nCOLOR_DEPTH = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCOLOR_DEPTH; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nCOLOR_DEPTH ) + 0; + } +}; +#define shaderStaticTest_sdk_depthwrite_ps20b psh_forgot_to_set_static_COLOR_DEPTH + 0 +class sdk_depthwrite_ps20b_Dynamic_Index +{ +private: + int m_nALPHACLIP; +#ifdef _DEBUG + bool m_bALPHACLIP; +#endif +public: + void SetALPHACLIP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nALPHACLIP = i; +#ifdef _DEBUG + m_bALPHACLIP = true; +#endif + } + void SetALPHACLIP( bool i ) + { + m_nALPHACLIP = i ? 1 : 0; +#ifdef _DEBUG + m_bALPHACLIP = true; +#endif + } +public: + sdk_depthwrite_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bALPHACLIP = false; +#endif // _DEBUG + m_nALPHACLIP = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bALPHACLIP; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nALPHACLIP ) + 0; + } +}; +#define shaderDynamicTest_sdk_depthwrite_ps20b psh_forgot_to_set_dynamic_ALPHACLIP + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_depthwrite_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_depthwrite_ps30.inc new file mode 100644 index 00000000..7ebec65d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_depthwrite_ps30.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_depthwrite_ps30_Static_Index +{ +private: + int m_nCOLOR_DEPTH; +#ifdef _DEBUG + bool m_bCOLOR_DEPTH; +#endif +public: + void SetCOLOR_DEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLOR_DEPTH = i; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } + void SetCOLOR_DEPTH( bool i ) + { + m_nCOLOR_DEPTH = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } +public: + sdk_depthwrite_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bCOLOR_DEPTH = false; +#endif // _DEBUG + m_nCOLOR_DEPTH = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCOLOR_DEPTH; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nCOLOR_DEPTH ) + 0; + } +}; +#define shaderStaticTest_sdk_depthwrite_ps30 psh_forgot_to_set_static_COLOR_DEPTH + 0 +class sdk_depthwrite_ps30_Dynamic_Index +{ +private: + int m_nALPHACLIP; +#ifdef _DEBUG + bool m_bALPHACLIP; +#endif +public: + void SetALPHACLIP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nALPHACLIP = i; +#ifdef _DEBUG + m_bALPHACLIP = true; +#endif + } + void SetALPHACLIP( bool i ) + { + m_nALPHACLIP = i ? 1 : 0; +#ifdef _DEBUG + m_bALPHACLIP = true; +#endif + } +public: + sdk_depthwrite_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bALPHACLIP = false; +#endif // _DEBUG + m_nALPHACLIP = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bALPHACLIP; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nALPHACLIP ) + 0; + } +}; +#define shaderDynamicTest_sdk_depthwrite_ps30 psh_forgot_to_set_dynamic_ALPHACLIP + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_depthwrite_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_depthwrite_vs20.inc new file mode 100644 index 00000000..09a93ed2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_depthwrite_vs20.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_depthwrite_vs20_Static_Index +{ +private: + int m_nONLY_PROJECT_POSITION; +#ifdef _DEBUG + bool m_bONLY_PROJECT_POSITION; +#endif +public: + void SetONLY_PROJECT_POSITION( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nONLY_PROJECT_POSITION = i; +#ifdef _DEBUG + m_bONLY_PROJECT_POSITION = true; +#endif + } + void SetONLY_PROJECT_POSITION( bool i ) + { + m_nONLY_PROJECT_POSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bONLY_PROJECT_POSITION = true; +#endif + } +private: + int m_nCOLOR_DEPTH; +#ifdef _DEBUG + bool m_bCOLOR_DEPTH; +#endif +public: + void SetCOLOR_DEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLOR_DEPTH = i; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } + void SetCOLOR_DEPTH( bool i ) + { + m_nCOLOR_DEPTH = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } +private: + int m_nTREESWAY; +#ifdef _DEBUG + bool m_bTREESWAY; +#endif +public: + void SetTREESWAY( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nTREESWAY = i; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif + } + void SetTREESWAY( bool i ) + { + m_nTREESWAY = i ? 1 : 0; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif + } +public: + sdk_depthwrite_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bONLY_PROJECT_POSITION = false; +#endif // _DEBUG + m_nONLY_PROJECT_POSITION = 0; +#ifdef _DEBUG + m_bCOLOR_DEPTH = false; +#endif // _DEBUG + m_nCOLOR_DEPTH = 0; +#ifdef _DEBUG + m_bTREESWAY = false; +#endif // _DEBUG + m_nTREESWAY = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bONLY_PROJECT_POSITION && m_bCOLOR_DEPTH && m_bTREESWAY; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nONLY_PROJECT_POSITION ) + ( 4 * m_nCOLOR_DEPTH ) + ( 8 * m_nTREESWAY ) + 0; + } +}; +#define shaderStaticTest_sdk_depthwrite_vs20 vsh_forgot_to_set_static_ONLY_PROJECT_POSITION + vsh_forgot_to_set_static_COLOR_DEPTH + vsh_forgot_to_set_static_TREESWAY + 0 +class sdk_depthwrite_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_depthwrite_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_depthwrite_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_depthwrite_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_depthwrite_vs30.inc new file mode 100644 index 00000000..d208700a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_depthwrite_vs30.inc @@ -0,0 +1,187 @@ +#include "shaderlib/cshader.h" +class sdk_depthwrite_vs30_Static_Index +{ +private: + int m_nONLY_PROJECT_POSITION; +#ifdef _DEBUG + bool m_bONLY_PROJECT_POSITION; +#endif +public: + void SetONLY_PROJECT_POSITION( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nONLY_PROJECT_POSITION = i; +#ifdef _DEBUG + m_bONLY_PROJECT_POSITION = true; +#endif + } + void SetONLY_PROJECT_POSITION( bool i ) + { + m_nONLY_PROJECT_POSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bONLY_PROJECT_POSITION = true; +#endif + } +private: + int m_nCOLOR_DEPTH; +#ifdef _DEBUG + bool m_bCOLOR_DEPTH; +#endif +public: + void SetCOLOR_DEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLOR_DEPTH = i; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } + void SetCOLOR_DEPTH( bool i ) + { + m_nCOLOR_DEPTH = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLOR_DEPTH = true; +#endif + } +private: + int m_nTREESWAY; +#ifdef _DEBUG + bool m_bTREESWAY; +#endif +public: + void SetTREESWAY( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nTREESWAY = i; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif + } + void SetTREESWAY( bool i ) + { + m_nTREESWAY = i ? 1 : 0; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif + } +public: + sdk_depthwrite_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bONLY_PROJECT_POSITION = false; +#endif // _DEBUG + m_nONLY_PROJECT_POSITION = 0; +#ifdef _DEBUG + m_bCOLOR_DEPTH = false; +#endif // _DEBUG + m_nCOLOR_DEPTH = 0; +#ifdef _DEBUG + m_bTREESWAY = false; +#endif // _DEBUG + m_nTREESWAY = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bONLY_PROJECT_POSITION && m_bCOLOR_DEPTH && m_bTREESWAY; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 8 * m_nONLY_PROJECT_POSITION ) + ( 8 * m_nCOLOR_DEPTH ) + ( 16 * m_nTREESWAY ) + 0; + } +}; +#define shaderStaticTest_sdk_depthwrite_vs30 vsh_forgot_to_set_static_ONLY_PROJECT_POSITION + vsh_forgot_to_set_static_COLOR_DEPTH + vsh_forgot_to_set_static_TREESWAY + 0 +class sdk_depthwrite_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_depthwrite_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_depthwrite_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_emissive_scroll_blended_pass_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_emissive_scroll_blended_pass_ps20.inc new file mode 100644 index 00000000..c415f0a5 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_emissive_scroll_blended_pass_ps20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_emissive_scroll_blended_pass_ps20_Static_Index +{ +public: + sdk_emissive_scroll_blended_pass_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_emissive_scroll_blended_pass_ps20 0 +class sdk_emissive_scroll_blended_pass_ps20_Dynamic_Index +{ +public: + sdk_emissive_scroll_blended_pass_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_emissive_scroll_blended_pass_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_emissive_scroll_blended_pass_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_emissive_scroll_blended_pass_ps20b.inc new file mode 100644 index 00000000..42dd5742 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_emissive_scroll_blended_pass_ps20b.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_emissive_scroll_blended_pass_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_emissive_scroll_blended_pass_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_emissive_scroll_blended_pass_ps20b 0 +class sdk_emissive_scroll_blended_pass_ps20b_Dynamic_Index +{ +public: + sdk_emissive_scroll_blended_pass_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_emissive_scroll_blended_pass_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_emissive_scroll_blended_pass_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_emissive_scroll_blended_pass_ps30.inc new file mode 100644 index 00000000..f0e08917 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_emissive_scroll_blended_pass_ps30.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_emissive_scroll_blended_pass_ps30_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_emissive_scroll_blended_pass_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_emissive_scroll_blended_pass_ps30 0 +class sdk_emissive_scroll_blended_pass_ps30_Dynamic_Index +{ +public: + sdk_emissive_scroll_blended_pass_ps30_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_emissive_scroll_blended_pass_ps30 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_emissive_scroll_blended_pass_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_emissive_scroll_blended_pass_vs20.inc new file mode 100644 index 00000000..a7f2793f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_emissive_scroll_blended_pass_vs20.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class sdk_emissive_scroll_blended_pass_vs20_Static_Index +{ +public: + sdk_emissive_scroll_blended_pass_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_emissive_scroll_blended_pass_vs20 0 +class sdk_emissive_scroll_blended_pass_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_emissive_scroll_blended_pass_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_emissive_scroll_blended_pass_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_emissive_scroll_blended_pass_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_emissive_scroll_blended_pass_vs30.inc new file mode 100644 index 00000000..5abcbad5 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_emissive_scroll_blended_pass_vs30.inc @@ -0,0 +1,110 @@ +#include "shaderlib/cshader.h" +class sdk_emissive_scroll_blended_pass_vs30_Static_Index +{ +public: + sdk_emissive_scroll_blended_pass_vs30_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_emissive_scroll_blended_pass_vs30 0 +class sdk_emissive_scroll_blended_pass_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_emissive_scroll_blended_pass_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_emissive_scroll_blended_pass_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_engine_post_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_engine_post_ps20b.inc new file mode 100644 index 00000000..8d65f79a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_engine_post_ps20b.inc @@ -0,0 +1,362 @@ +#include "shaderlib/cshader.h" +class sdk_engine_post_ps20b_Static_Index +{ +private: + int m_nTOOL_MODE; +#ifdef _DEBUG + bool m_bTOOL_MODE; +#endif +public: + void SetTOOL_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTOOL_MODE = i; +#ifdef _DEBUG + m_bTOOL_MODE = true; +#endif + } + void SetTOOL_MODE( bool i ) + { + m_nTOOL_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bTOOL_MODE = true; +#endif + } +private: + int m_nDEPTH_BLUR_ENABLE; +#ifdef _DEBUG + bool m_bDEPTH_BLUR_ENABLE; +#endif +public: + void SetDEPTH_BLUR_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDEPTH_BLUR_ENABLE = i; +#ifdef _DEBUG + m_bDEPTH_BLUR_ENABLE = true; +#endif + } + void SetDEPTH_BLUR_ENABLE( bool i ) + { + m_nDEPTH_BLUR_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bDEPTH_BLUR_ENABLE = true; +#endif + } +public: + sdk_engine_post_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bTOOL_MODE = false; +#endif // _DEBUG + m_nTOOL_MODE = 0; +#ifdef _DEBUG + m_bDEPTH_BLUR_ENABLE = false; +#endif // _DEBUG + m_nDEPTH_BLUR_ENABLE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTOOL_MODE && m_bDEPTH_BLUR_ENABLE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2048 * m_nTOOL_MODE ) + ( 4096 * m_nDEPTH_BLUR_ENABLE ) + 0; + } +}; +#define shaderStaticTest_sdk_engine_post_ps20b psh_forgot_to_set_static_TOOL_MODE + psh_forgot_to_set_static_DEPTH_BLUR_ENABLE + 0 +class sdk_engine_post_ps20b_Dynamic_Index +{ +private: + int m_nAA_ENABLE; +#ifdef _DEBUG + bool m_bAA_ENABLE; +#endif +public: + void SetAA_ENABLE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nAA_ENABLE = i; +#ifdef _DEBUG + m_bAA_ENABLE = true; +#endif + } + void SetAA_ENABLE( bool i ) + { + m_nAA_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bAA_ENABLE = true; +#endif + } +private: + int m_nCOL_CORRECT_NUM_LOOKUPS; +#ifdef _DEBUG + bool m_bCOL_CORRECT_NUM_LOOKUPS; +#endif +public: + void SetCOL_CORRECT_NUM_LOOKUPS( int i ) + { + Assert( i >= 0 && i <= 3 ); + m_nCOL_CORRECT_NUM_LOOKUPS = i; +#ifdef _DEBUG + m_bCOL_CORRECT_NUM_LOOKUPS = true; +#endif + } + void SetCOL_CORRECT_NUM_LOOKUPS( bool i ) + { + m_nCOL_CORRECT_NUM_LOOKUPS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOL_CORRECT_NUM_LOOKUPS = true; +#endif + } +private: + int m_nCONVERT_FROM_LINEAR; +#ifdef _DEBUG + bool m_bCONVERT_FROM_LINEAR; +#endif +public: + void SetCONVERT_FROM_LINEAR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_FROM_LINEAR = i; +#ifdef _DEBUG + m_bCONVERT_FROM_LINEAR = true; +#endif + } + void SetCONVERT_FROM_LINEAR( bool i ) + { + m_nCONVERT_FROM_LINEAR = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_FROM_LINEAR = true; +#endif + } +private: + int m_nCONVERT_TO_LINEAR; +#ifdef _DEBUG + bool m_bCONVERT_TO_LINEAR; +#endif +public: + void SetCONVERT_TO_LINEAR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_LINEAR = i; +#ifdef _DEBUG + m_bCONVERT_TO_LINEAR = true; +#endif + } + void SetCONVERT_TO_LINEAR( bool i ) + { + m_nCONVERT_TO_LINEAR = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_LINEAR = true; +#endif + } +private: + int m_nNOISE_ENABLE; +#ifdef _DEBUG + bool m_bNOISE_ENABLE; +#endif +public: + void SetNOISE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNOISE_ENABLE = i; +#ifdef _DEBUG + m_bNOISE_ENABLE = true; +#endif + } + void SetNOISE_ENABLE( bool i ) + { + m_nNOISE_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bNOISE_ENABLE = true; +#endif + } +private: + int m_nVIGNETTE_ENABLE; +#ifdef _DEBUG + bool m_bVIGNETTE_ENABLE; +#endif +public: + void SetVIGNETTE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVIGNETTE_ENABLE = i; +#ifdef _DEBUG + m_bVIGNETTE_ENABLE = true; +#endif + } + void SetVIGNETTE_ENABLE( bool i ) + { + m_nVIGNETTE_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bVIGNETTE_ENABLE = true; +#endif + } +private: + int m_nLOCAL_CONTRAST_ENABLE; +#ifdef _DEBUG + bool m_bLOCAL_CONTRAST_ENABLE; +#endif +public: + void SetLOCAL_CONTRAST_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLOCAL_CONTRAST_ENABLE = i; +#ifdef _DEBUG + m_bLOCAL_CONTRAST_ENABLE = true; +#endif + } + void SetLOCAL_CONTRAST_ENABLE( bool i ) + { + m_nLOCAL_CONTRAST_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bLOCAL_CONTRAST_ENABLE = true; +#endif + } +private: + int m_nBLURRED_VIGNETTE_ENABLE; +#ifdef _DEBUG + bool m_bBLURRED_VIGNETTE_ENABLE; +#endif +public: + void SetBLURRED_VIGNETTE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLURRED_VIGNETTE_ENABLE = i; +#ifdef _DEBUG + m_bBLURRED_VIGNETTE_ENABLE = true; +#endif + } + void SetBLURRED_VIGNETTE_ENABLE( bool i ) + { + m_nBLURRED_VIGNETTE_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bBLURRED_VIGNETTE_ENABLE = true; +#endif + } +private: + int m_nVOMIT_ENABLE; +#ifdef _DEBUG + bool m_bVOMIT_ENABLE; +#endif +public: + void SetVOMIT_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVOMIT_ENABLE = i; +#ifdef _DEBUG + m_bVOMIT_ENABLE = true; +#endif + } + void SetVOMIT_ENABLE( bool i ) + { + m_nVOMIT_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bVOMIT_ENABLE = true; +#endif + } +private: + int m_nTV_GAMMA; +#ifdef _DEBUG + bool m_bTV_GAMMA; +#endif +public: + void SetTV_GAMMA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTV_GAMMA = i; +#ifdef _DEBUG + m_bTV_GAMMA = true; +#endif + } + void SetTV_GAMMA( bool i ) + { + m_nTV_GAMMA = i ? 1 : 0; +#ifdef _DEBUG + m_bTV_GAMMA = true; +#endif + } +private: + int m_nDESATURATEENABLE; +#ifdef _DEBUG + bool m_bDESATURATEENABLE; +#endif +public: + void SetDESATURATEENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDESATURATEENABLE = i; +#ifdef _DEBUG + m_bDESATURATEENABLE = true; +#endif + } + void SetDESATURATEENABLE( bool i ) + { + m_nDESATURATEENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bDESATURATEENABLE = true; +#endif + } +public: + sdk_engine_post_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bAA_ENABLE = false; +#endif // _DEBUG + m_nAA_ENABLE = 0; +#ifdef _DEBUG + m_bCOL_CORRECT_NUM_LOOKUPS = false; +#endif // _DEBUG + m_nCOL_CORRECT_NUM_LOOKUPS = 0; +#ifdef _DEBUG + m_bCONVERT_FROM_LINEAR = false; +#endif // _DEBUG + m_nCONVERT_FROM_LINEAR = 0; +#ifdef _DEBUG + m_bCONVERT_TO_LINEAR = false; +#endif // _DEBUG + m_nCONVERT_TO_LINEAR = 0; +#ifdef _DEBUG + m_bNOISE_ENABLE = false; +#endif // _DEBUG + m_nNOISE_ENABLE = 0; +#ifdef _DEBUG + m_bVIGNETTE_ENABLE = false; +#endif // _DEBUG + m_nVIGNETTE_ENABLE = 0; +#ifdef _DEBUG + m_bLOCAL_CONTRAST_ENABLE = false; +#endif // _DEBUG + m_nLOCAL_CONTRAST_ENABLE = 0; +#ifdef _DEBUG + m_bBLURRED_VIGNETTE_ENABLE = false; +#endif // _DEBUG + m_nBLURRED_VIGNETTE_ENABLE = 0; +#ifdef _DEBUG + m_bVOMIT_ENABLE = false; +#endif // _DEBUG + m_nVOMIT_ENABLE = 0; +#ifdef _DEBUG + m_bTV_GAMMA = false; +#endif // _DEBUG + m_nTV_GAMMA = 0; +#ifdef _DEBUG + m_bDESATURATEENABLE = false; +#endif // _DEBUG + m_nDESATURATEENABLE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bAA_ENABLE && m_bCOL_CORRECT_NUM_LOOKUPS && m_bCONVERT_FROM_LINEAR && m_bCONVERT_TO_LINEAR && m_bNOISE_ENABLE && m_bVIGNETTE_ENABLE && m_bLOCAL_CONTRAST_ENABLE && m_bBLURRED_VIGNETTE_ENABLE && m_bVOMIT_ENABLE && m_bTV_GAMMA && m_bDESATURATEENABLE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nAA_ENABLE ) + ( 1 * m_nCOL_CORRECT_NUM_LOOKUPS ) + ( 4 * m_nCONVERT_FROM_LINEAR ) + ( 8 * m_nCONVERT_TO_LINEAR ) + ( 16 * m_nNOISE_ENABLE ) + ( 32 * m_nVIGNETTE_ENABLE ) + ( 64 * m_nLOCAL_CONTRAST_ENABLE ) + ( 128 * m_nBLURRED_VIGNETTE_ENABLE ) + ( 256 * m_nVOMIT_ENABLE ) + ( 512 * m_nTV_GAMMA ) + ( 1024 * m_nDESATURATEENABLE ) + 0; + } +}; +#define shaderDynamicTest_sdk_engine_post_ps20b psh_forgot_to_set_dynamic_AA_ENABLE + psh_forgot_to_set_dynamic_COL_CORRECT_NUM_LOOKUPS + psh_forgot_to_set_dynamic_CONVERT_FROM_LINEAR + psh_forgot_to_set_dynamic_CONVERT_TO_LINEAR + psh_forgot_to_set_dynamic_NOISE_ENABLE + psh_forgot_to_set_dynamic_VIGNETTE_ENABLE + psh_forgot_to_set_dynamic_LOCAL_CONTRAST_ENABLE + psh_forgot_to_set_dynamic_BLURRED_VIGNETTE_ENABLE + psh_forgot_to_set_dynamic_VOMIT_ENABLE + psh_forgot_to_set_dynamic_TV_GAMMA + psh_forgot_to_set_dynamic_DESATURATEENABLE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eye_refract_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eye_refract_ps20.inc new file mode 100644 index 00000000..850964b3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eye_refract_ps20.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_eye_refract_ps20_Static_Index +{ +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +public: + sdk_eye_refract_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bFLASHLIGHT && m_bLIGHTWARPTEXTURE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 3 * m_nFLASHLIGHT ) + ( 6 * m_nLIGHTWARPTEXTURE ) + 0; + } +}; +#define shaderStaticTest_sdk_eye_refract_ps20 psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_LIGHTWARPTEXTURE + 0 +class sdk_eye_refract_ps20_Dynamic_Index +{ +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_eye_refract_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_eye_refract_ps20 psh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eye_refract_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eye_refract_ps20b.inc new file mode 100644 index 00000000..93308c81 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eye_refract_ps20b.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_eye_refract_ps20b_Static_Index +{ +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +private: + int m_nSPHERETEXKILLCOMBO; +#ifdef _DEBUG + bool m_bSPHERETEXKILLCOMBO; +#endif +public: + void SetSPHERETEXKILLCOMBO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSPHERETEXKILLCOMBO = i; +#ifdef _DEBUG + m_bSPHERETEXKILLCOMBO = true; +#endif + } + void SetSPHERETEXKILLCOMBO( bool i ) + { + m_nSPHERETEXKILLCOMBO = i ? 1 : 0; +#ifdef _DEBUG + m_bSPHERETEXKILLCOMBO = true; +#endif + } +private: + int m_nRAYTRACESPHERE; +#ifdef _DEBUG + bool m_bRAYTRACESPHERE; +#endif +public: + void SetRAYTRACESPHERE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nRAYTRACESPHERE = i; +#ifdef _DEBUG + m_bRAYTRACESPHERE = true; +#endif + } + void SetRAYTRACESPHERE( bool i ) + { + m_nRAYTRACESPHERE = i ? 1 : 0; +#ifdef _DEBUG + m_bRAYTRACESPHERE = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_eye_refract_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; +#ifdef _DEBUG + m_bSPHERETEXKILLCOMBO = false; +#endif // _DEBUG + m_nSPHERETEXKILLCOMBO = 0; +#ifdef _DEBUG + m_bRAYTRACESPHERE = false; +#endif // _DEBUG + m_nRAYTRACESPHERE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bFLASHLIGHT && m_bLIGHTWARPTEXTURE && m_bSPHERETEXKILLCOMBO && m_bRAYTRACESPHERE && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 10 * m_nFLASHLIGHT ) + ( 20 * m_nLIGHTWARPTEXTURE ) + ( 40 * m_nSPHERETEXKILLCOMBO ) + ( 80 * m_nRAYTRACESPHERE ) + ( 160 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_eye_refract_ps20b psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_SPHERETEXKILLCOMBO + psh_forgot_to_set_static_RAYTRACESPHERE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_eye_refract_ps20b_Dynamic_Index +{ +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_eye_refract_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bNUM_LIGHTS && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nNUM_LIGHTS ) + ( 5 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_eye_refract_ps20b psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eye_refract_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eye_refract_ps30.inc new file mode 100644 index 00000000..76c39918 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eye_refract_ps30.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_eye_refract_ps30_Static_Index +{ +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +private: + int m_nSPHERETEXKILLCOMBO; +#ifdef _DEBUG + bool m_bSPHERETEXKILLCOMBO; +#endif +public: + void SetSPHERETEXKILLCOMBO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSPHERETEXKILLCOMBO = i; +#ifdef _DEBUG + m_bSPHERETEXKILLCOMBO = true; +#endif + } + void SetSPHERETEXKILLCOMBO( bool i ) + { + m_nSPHERETEXKILLCOMBO = i ? 1 : 0; +#ifdef _DEBUG + m_bSPHERETEXKILLCOMBO = true; +#endif + } +private: + int m_nRAYTRACESPHERE; +#ifdef _DEBUG + bool m_bRAYTRACESPHERE; +#endif +public: + void SetRAYTRACESPHERE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nRAYTRACESPHERE = i; +#ifdef _DEBUG + m_bRAYTRACESPHERE = true; +#endif + } + void SetRAYTRACESPHERE( bool i ) + { + m_nRAYTRACESPHERE = i ? 1 : 0; +#ifdef _DEBUG + m_bRAYTRACESPHERE = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_eye_refract_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; +#ifdef _DEBUG + m_bSPHERETEXKILLCOMBO = false; +#endif // _DEBUG + m_nSPHERETEXKILLCOMBO = 0; +#ifdef _DEBUG + m_bRAYTRACESPHERE = false; +#endif // _DEBUG + m_nRAYTRACESPHERE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bFLASHLIGHT && m_bLIGHTWARPTEXTURE && m_bSPHERETEXKILLCOMBO && m_bRAYTRACESPHERE && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 10 * m_nFLASHLIGHT ) + ( 20 * m_nLIGHTWARPTEXTURE ) + ( 40 * m_nSPHERETEXKILLCOMBO ) + ( 80 * m_nRAYTRACESPHERE ) + ( 160 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_eye_refract_ps30 psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_SPHERETEXKILLCOMBO + psh_forgot_to_set_static_RAYTRACESPHERE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_eye_refract_ps30_Dynamic_Index +{ +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_eye_refract_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bNUM_LIGHTS && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nNUM_LIGHTS ) + ( 5 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_eye_refract_ps30 psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eye_refract_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eye_refract_vs20.inc new file mode 100644 index 00000000..ec10825b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eye_refract_vs20.inc @@ -0,0 +1,287 @@ +#include "shaderlib/cshader.h" +class sdk_eye_refract_vs20_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +public: + sdk_eye_refract_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bLIGHTWARPTEXTURE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 160 * m_nINTRO ) + ( 320 * m_nHALFLAMBERT ) + ( 640 * m_nFLASHLIGHT ) + ( 1280 * m_nLIGHTWARPTEXTURE ) + 0; + } +}; +#define shaderStaticTest_sdk_eye_refract_vs20 vsh_forgot_to_set_static_INTRO + vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_FLASHLIGHT + vsh_forgot_to_set_static_LIGHTWARPTEXTURE + 0 +class sdk_eye_refract_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_eye_refract_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDOWATERFOG && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDOWATERFOG ) + ( 8 * m_nDYNAMIC_LIGHT ) + ( 16 * m_nSTATIC_LIGHT ) + ( 32 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_eye_refract_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eye_refract_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eye_refract_vs30.inc new file mode 100644 index 00000000..4729f2ab --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eye_refract_vs30.inc @@ -0,0 +1,312 @@ +#include "shaderlib/cshader.h" +class sdk_eye_refract_vs30_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +public: + sdk_eye_refract_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bLIGHTWARPTEXTURE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 320 * m_nINTRO ) + ( 640 * m_nHALFLAMBERT ) + ( 1280 * m_nFLASHLIGHT ) + ( 2560 * m_nLIGHTWARPTEXTURE ) + 0; + } +}; +#define shaderStaticTest_sdk_eye_refract_vs30 vsh_forgot_to_set_static_INTRO + vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_FLASHLIGHT + vsh_forgot_to_set_static_LIGHTWARPTEXTURE + 0 +class sdk_eye_refract_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_eye_refract_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDOWATERFOG && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bNUM_LIGHTS && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDOWATERFOG ) + ( 8 * m_nDYNAMIC_LIGHT ) + ( 16 * m_nSTATIC_LIGHT ) + ( 32 * m_nNUM_LIGHTS ) + ( 160 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_eye_refract_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_NUM_LIGHTS + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyeglint_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyeglint_ps20.inc new file mode 100644 index 00000000..3c83a6ca --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyeglint_ps20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_eyeglint_ps20_Static_Index +{ +public: + sdk_eyeglint_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyeglint_ps20 0 +class sdk_eyeglint_ps20_Dynamic_Index +{ +public: + sdk_eyeglint_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_eyeglint_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyeglint_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyeglint_ps20b.inc new file mode 100644 index 00000000..2dbb669b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyeglint_ps20b.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_eyeglint_ps20b_Static_Index +{ +public: + sdk_eyeglint_ps20b_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyeglint_ps20b 0 +class sdk_eyeglint_ps20b_Dynamic_Index +{ +public: + sdk_eyeglint_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_eyeglint_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyeglint_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyeglint_vs20.inc new file mode 100644 index 00000000..05087222 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyeglint_vs20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_eyeglint_vs20_Static_Index +{ +public: + sdk_eyeglint_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyeglint_vs20 0 +class sdk_eyeglint_vs20_Dynamic_Index +{ +public: + sdk_eyeglint_vs20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_eyeglint_vs20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_ps11.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_ps11.inc new file mode 100644 index 00000000..721122e3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_ps11.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_flashlight_ps11_Static_Index +{ +public: + sdk_eyes_flashlight_ps11_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyes_flashlight_ps11 0 +class sdk_eyes_flashlight_ps11_Dynamic_Index +{ +public: + sdk_eyes_flashlight_ps11_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_eyes_flashlight_ps11 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_ps20.inc new file mode 100644 index 00000000..9e576f91 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_ps20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_flashlight_ps20_Static_Index +{ +public: + sdk_eyes_flashlight_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyes_flashlight_ps20 0 +class sdk_eyes_flashlight_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_eyes_flashlight_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_flashlight_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_ps20b.inc new file mode 100644 index 00000000..d156ca25 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_ps20b.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_flashlight_ps20b_Static_Index +{ +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_eyes_flashlight_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_eyes_flashlight_ps20b psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_eyes_flashlight_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_eyes_flashlight_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_flashlight_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_ps30.inc new file mode 100644 index 00000000..57ddecae --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_ps30.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_flashlight_ps30_Static_Index +{ +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_eyes_flashlight_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_eyes_flashlight_ps30 psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_eyes_flashlight_ps30_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_eyes_flashlight_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_flashlight_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_vs20.inc new file mode 100644 index 00000000..c93c72de --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_vs20.inc @@ -0,0 +1,110 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_flashlight_vs20_Static_Index +{ +public: + sdk_eyes_flashlight_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyes_flashlight_vs20 0 +class sdk_eyes_flashlight_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_eyes_flashlight_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_flashlight_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_vs30.inc new file mode 100644 index 00000000..1244088b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_flashlight_vs30.inc @@ -0,0 +1,135 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_flashlight_vs30_Static_Index +{ +public: + sdk_eyes_flashlight_vs30_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyes_flashlight_vs30 0 +class sdk_eyes_flashlight_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_eyes_flashlight_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDOWATERFOG && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDOWATERFOG ) + ( 8 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_flashlight_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_ps20.inc new file mode 100644 index 00000000..cbbb103d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_ps20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_ps20_Static_Index +{ +public: + sdk_eyes_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyes_ps20 0 +class sdk_eyes_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_eyes_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_ps20b.inc new file mode 100644 index 00000000..f10f16d4 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_ps20b.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_ps20b_Static_Index +{ +public: + sdk_eyes_ps20b_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyes_ps20b 0 +class sdk_eyes_ps20b_Dynamic_Index +{ +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_eyes_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITE_DEPTH_TO_DESTALPHA && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_ps20b psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_ps30.inc new file mode 100644 index 00000000..2353f65d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_ps30.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_ps30_Static_Index +{ +public: + sdk_eyes_ps30_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_eyes_ps30 0 +class sdk_eyes_ps30_Dynamic_Index +{ +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_eyes_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITE_DEPTH_TO_DESTALPHA && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_ps30 psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_vs20.inc new file mode 100644 index 00000000..5b896790 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_vs20.inc @@ -0,0 +1,262 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_vs20_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nUSE_STATIC_CONTROL_FLOW; +#ifdef _DEBUG + bool m_bUSE_STATIC_CONTROL_FLOW; +#endif +public: + void SetUSE_STATIC_CONTROL_FLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_STATIC_CONTROL_FLOW = i; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } + void SetUSE_STATIC_CONTROL_FLOW( bool i ) + { + m_nUSE_STATIC_CONTROL_FLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } +public: + sdk_eyes_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = false; +#endif // _DEBUG + m_nUSE_STATIC_CONTROL_FLOW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO && m_bHALFLAMBERT && m_bUSE_STATIC_CONTROL_FLOW; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 96 * m_nINTRO ) + ( 192 * m_nHALFLAMBERT ) + ( 384 * m_nUSE_STATIC_CONTROL_FLOW ) + 0; + } +}; +#define shaderStaticTest_sdk_eyes_vs20 vsh_forgot_to_set_static_INTRO + vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_USE_STATIC_CONTROL_FLOW + 0 +class sdk_eyes_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_eyes_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDOWATERFOG && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDOWATERFOG ) + ( 8 * m_nDYNAMIC_LIGHT ) + ( 16 * m_nSTATIC_LIGHT ) + ( 32 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_vs30.inc new file mode 100644 index 00000000..d14fa273 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_eyes_vs30.inc @@ -0,0 +1,237 @@ +#include "shaderlib/cshader.h" +class sdk_eyes_vs30_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +public: + sdk_eyes_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO && m_bHALFLAMBERT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 64 * m_nINTRO ) + ( 128 * m_nHALFLAMBERT ) + 0; + } +}; +#define shaderStaticTest_sdk_eyes_vs30 vsh_forgot_to_set_static_INTRO + vsh_forgot_to_set_static_HALFLAMBERT + 0 +class sdk_eyes_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_eyes_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDOWATERFOG && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDOWATERFOG ) + ( 8 * m_nDYNAMIC_LIGHT ) + ( 16 * m_nSTATIC_LIGHT ) + ( 32 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_eyes_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flashlight_ps11.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flashlight_ps11.inc new file mode 100644 index 00000000..fc6f849d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flashlight_ps11.inc @@ -0,0 +1,85 @@ +#include "shaderlib/cshader.h" +class sdk_flashlight_ps11_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nNOCULL; +#ifdef _DEBUG + bool m_bNOCULL; +#endif +public: + void SetNOCULL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNOCULL = i; +#ifdef _DEBUG + m_bNOCULL = true; +#endif + } + void SetNOCULL( bool i ) + { + m_nNOCULL = i ? 1 : 0; +#ifdef _DEBUG + m_bNOCULL = true; +#endif + } +public: + sdk_flashlight_ps11_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bNOCULL = false; +#endif // _DEBUG + m_nNOCULL = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bNOCULL; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nNORMALMAP ) + ( 2 * m_nNOCULL ) + 0; + } +}; +#define shaderStaticTest_sdk_flashlight_ps11 psh_forgot_to_set_static_NORMALMAP + psh_forgot_to_set_static_NOCULL + 0 +class sdk_flashlight_ps11_Dynamic_Index +{ +public: + sdk_flashlight_ps11_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_flashlight_ps11 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flashlight_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flashlight_ps20.inc new file mode 100644 index 00000000..3d25ff86 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flashlight_ps20.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_flashlight_ps20_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nNORMALMAP2; +#ifdef _DEBUG + bool m_bNORMALMAP2; +#endif +public: + void SetNORMALMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP2 = i; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } + void SetNORMALMAP2( bool i ) + { + m_nNORMALMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +public: + sdk_flashlight_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bNORMALMAP2 = false; +#endif // _DEBUG + m_nNORMALMAP2 = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bNORMALMAP2 && m_bWORLDVERTEXTRANSITION && m_bSEAMLESS && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nNORMALMAP ) + ( 6 * m_nNORMALMAP2 ) + ( 12 * m_nWORLDVERTEXTRANSITION ) + ( 24 * m_nSEAMLESS ) + ( 48 * m_nDETAILTEXTURE ) + ( 96 * m_nDETAIL_BLEND_MODE ) + 0; + } +}; +#define shaderStaticTest_sdk_flashlight_ps20 psh_forgot_to_set_static_NORMALMAP + psh_forgot_to_set_static_NORMALMAP2 + psh_forgot_to_set_static_WORLDVERTEXTRANSITION + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + 0 +class sdk_flashlight_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_flashlight_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_flashlight_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flashlight_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flashlight_ps20b.inc new file mode 100644 index 00000000..0e2bf822 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flashlight_ps20b.inc @@ -0,0 +1,262 @@ +#include "shaderlib/cshader.h" +class sdk_flashlight_ps20b_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nNORMALMAP2; +#ifdef _DEBUG + bool m_bNORMALMAP2; +#endif +public: + void SetNORMALMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP2 = i; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } + void SetNORMALMAP2( bool i ) + { + m_nNORMALMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_flashlight_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bNORMALMAP2 = false; +#endif // _DEBUG + m_nNORMALMAP2 = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bNORMALMAP2 && m_bWORLDVERTEXTRANSITION && m_bSEAMLESS && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nNORMALMAP ) + ( 12 * m_nNORMALMAP2 ) + ( 24 * m_nWORLDVERTEXTRANSITION ) + ( 48 * m_nSEAMLESS ) + ( 96 * m_nDETAILTEXTURE ) + ( 192 * m_nDETAIL_BLEND_MODE ) + ( 384 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_flashlight_ps20b psh_forgot_to_set_static_NORMALMAP + psh_forgot_to_set_static_NORMALMAP2 + psh_forgot_to_set_static_WORLDVERTEXTRANSITION + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_flashlight_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_flashlight_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_flashlight_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flashlight_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flashlight_ps30.inc new file mode 100644 index 00000000..88331a5b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flashlight_ps30.inc @@ -0,0 +1,262 @@ +#include "shaderlib/cshader.h" +class sdk_flashlight_ps30_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nNORMALMAP2; +#ifdef _DEBUG + bool m_bNORMALMAP2; +#endif +public: + void SetNORMALMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP2 = i; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } + void SetNORMALMAP2( bool i ) + { + m_nNORMALMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_flashlight_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bNORMALMAP2 = false; +#endif // _DEBUG + m_nNORMALMAP2 = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bNORMALMAP2 && m_bWORLDVERTEXTRANSITION && m_bSEAMLESS && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nNORMALMAP ) + ( 12 * m_nNORMALMAP2 ) + ( 24 * m_nWORLDVERTEXTRANSITION ) + ( 48 * m_nSEAMLESS ) + ( 96 * m_nDETAILTEXTURE ) + ( 192 * m_nDETAIL_BLEND_MODE ) + ( 384 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_flashlight_ps30 psh_forgot_to_set_static_NORMALMAP + psh_forgot_to_set_static_NORMALMAP2 + psh_forgot_to_set_static_WORLDVERTEXTRANSITION + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_flashlight_ps30_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_flashlight_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_flashlight_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flesh_interior_blended_pass_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flesh_interior_blended_pass_ps20.inc new file mode 100644 index 00000000..0b73f03b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flesh_interior_blended_pass_ps20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_flesh_interior_blended_pass_ps20_Static_Index +{ +public: + sdk_flesh_interior_blended_pass_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_flesh_interior_blended_pass_ps20 0 +class sdk_flesh_interior_blended_pass_ps20_Dynamic_Index +{ +public: + sdk_flesh_interior_blended_pass_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_flesh_interior_blended_pass_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flesh_interior_blended_pass_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flesh_interior_blended_pass_ps20b.inc new file mode 100644 index 00000000..dd85606f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flesh_interior_blended_pass_ps20b.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_flesh_interior_blended_pass_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_flesh_interior_blended_pass_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_flesh_interior_blended_pass_ps20b 0 +class sdk_flesh_interior_blended_pass_ps20b_Dynamic_Index +{ +public: + sdk_flesh_interior_blended_pass_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_flesh_interior_blended_pass_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flesh_interior_blended_pass_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flesh_interior_blended_pass_vs20.inc new file mode 100644 index 00000000..e2241b31 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_flesh_interior_blended_pass_vs20.inc @@ -0,0 +1,237 @@ +#include "shaderlib/cshader.h" +class sdk_flesh_interior_blended_pass_vs20_Static_Index +{ +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nUSE_STATIC_CONTROL_FLOW; +#ifdef _DEBUG + bool m_bUSE_STATIC_CONTROL_FLOW; +#endif +public: + void SetUSE_STATIC_CONTROL_FLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_STATIC_CONTROL_FLOW = i; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } + void SetUSE_STATIC_CONTROL_FLOW( bool i ) + { + m_nUSE_STATIC_CONTROL_FLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } +public: + sdk_flesh_interior_blended_pass_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = false; +#endif // _DEBUG + m_nUSE_STATIC_CONTROL_FLOW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bHALFLAMBERT && m_bUSE_STATIC_CONTROL_FLOW; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 96 * m_nHALFLAMBERT ) + ( 192 * m_nUSE_STATIC_CONTROL_FLOW ) + 0; + } +}; +#define shaderStaticTest_sdk_flesh_interior_blended_pass_vs20 vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_USE_STATIC_CONTROL_FLOW + 0 +class sdk_flesh_interior_blended_pass_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_flesh_interior_blended_pass_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bSKINNING && m_bDOWATERFOG && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nSKINNING ) + ( 4 * m_nDOWATERFOG ) + ( 8 * m_nDYNAMIC_LIGHT ) + ( 16 * m_nSTATIC_LIGHT ) + ( 32 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_flesh_interior_blended_pass_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_decal_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_decal_ps20.inc new file mode 100644 index 00000000..91c81ef9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_decal_ps20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_decal_ps20_Static_Index +{ +public: + sdk_lightmappedgeneric_decal_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_decal_ps20 0 +class sdk_lightmappedgeneric_decal_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_lightmappedgeneric_decal_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_decal_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_decal_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_decal_ps20b.inc new file mode 100644 index 00000000..e11d31ca --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_decal_ps20b.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_decal_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_lightmappedgeneric_decal_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_decal_ps20b 0 +class sdk_lightmappedgeneric_decal_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_lightmappedgeneric_decal_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_decal_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_decal_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_decal_vs20.inc new file mode 100644 index 00000000..a53c8769 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_decal_vs20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_decal_vs20_Static_Index +{ +public: + sdk_lightmappedgeneric_decal_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_decal_vs20 0 +class sdk_lightmappedgeneric_decal_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_decal_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_decal_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_ps20.inc new file mode 100644 index 00000000..e24bcc01 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_ps20.inc @@ -0,0 +1,262 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_flashlight_ps20_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nNORMALMAP2; +#ifdef _DEBUG + bool m_bNORMALMAP2; +#endif +public: + void SetNORMALMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP2 = i; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } + void SetNORMALMAP2( bool i ) + { + m_nNORMALMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nFANCY_BLENDING; +#ifdef _DEBUG + bool m_bFANCY_BLENDING; +#endif +public: + void SetFANCY_BLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFANCY_BLENDING = i; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } + void SetFANCY_BLENDING( bool i ) + { + m_nFANCY_BLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bNORMALMAP2 = false; +#endif // _DEBUG + m_nNORMALMAP2 = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = false; +#endif // _DEBUG + m_nFANCY_BLENDING = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bNORMALMAP2 && m_bWORLDVERTEXTRANSITION && m_bFANCY_BLENDING && m_bSEAMLESS && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bBASETEXTURETRANSFORM2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nNORMALMAP ) + ( 6 * m_nNORMALMAP2 ) + ( 12 * m_nWORLDVERTEXTRANSITION ) + ( 24 * m_nFANCY_BLENDING ) + ( 48 * m_nSEAMLESS ) + ( 96 * m_nDETAILTEXTURE ) + ( 192 * m_nDETAIL_BLEND_MODE ) + ( 384 * m_nBASETEXTURETRANSFORM2 ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_flashlight_ps20 psh_forgot_to_set_static_NORMALMAP + psh_forgot_to_set_static_NORMALMAP2 + psh_forgot_to_set_static_WORLDVERTEXTRANSITION + psh_forgot_to_set_static_FANCY_BLENDING + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_BASETEXTURETRANSFORM2 + 0 +class sdk_lightmappedgeneric_flashlight_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_flashlight_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_ps20b.inc new file mode 100644 index 00000000..e4ba14aa --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_ps20b.inc @@ -0,0 +1,362 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_flashlight_ps20b_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nNORMALMAP2; +#ifdef _DEBUG + bool m_bNORMALMAP2; +#endif +public: + void SetNORMALMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP2 = i; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } + void SetNORMALMAP2( bool i ) + { + m_nNORMALMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nFANCY_BLENDING; +#ifdef _DEBUG + bool m_bFANCY_BLENDING; +#endif +public: + void SetFANCY_BLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFANCY_BLENDING = i; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } + void SetFANCY_BLENDING( bool i ) + { + m_nFANCY_BLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nPHONG; +#ifdef _DEBUG + bool m_bPHONG; +#endif +public: + void SetPHONG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONG = i; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } + void SetPHONG( bool i ) + { + m_nPHONG = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } +private: + int m_nPHONGMASK; +#ifdef _DEBUG + bool m_bPHONGMASK; +#endif +public: + void SetPHONGMASK( int i ) + { + Assert( i >= 0 && i <= 3 ); + m_nPHONGMASK = i; +#ifdef _DEBUG + m_bPHONGMASK = true; +#endif + } + void SetPHONGMASK( bool i ) + { + m_nPHONGMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONGMASK = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bNORMALMAP2 = false; +#endif // _DEBUG + m_nNORMALMAP2 = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = false; +#endif // _DEBUG + m_nFANCY_BLENDING = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bPHONG = false; +#endif // _DEBUG + m_nPHONG = 0; +#ifdef _DEBUG + m_bPHONGMASK = false; +#endif // _DEBUG + m_nPHONGMASK = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bNORMALMAP2 && m_bWORLDVERTEXTRANSITION && m_bFANCY_BLENDING && m_bSEAMLESS && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bFLASHLIGHTDEPTHFILTERMODE && m_bPHONG && m_bPHONGMASK && m_bBASETEXTURETRANSFORM2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nNORMALMAP ) + ( 12 * m_nNORMALMAP2 ) + ( 24 * m_nWORLDVERTEXTRANSITION ) + ( 48 * m_nFANCY_BLENDING ) + ( 96 * m_nSEAMLESS ) + ( 192 * m_nDETAILTEXTURE ) + ( 384 * m_nDETAIL_BLEND_MODE ) + ( 768 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 2304 * m_nPHONG ) + ( 4608 * m_nPHONGMASK ) + ( 18432 * m_nBASETEXTURETRANSFORM2 ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_flashlight_ps20b psh_forgot_to_set_static_NORMALMAP + psh_forgot_to_set_static_NORMALMAP2 + psh_forgot_to_set_static_WORLDVERTEXTRANSITION + psh_forgot_to_set_static_FANCY_BLENDING + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_PHONG + psh_forgot_to_set_static_PHONGMASK + psh_forgot_to_set_static_BASETEXTURETRANSFORM2 + 0 +class sdk_lightmappedgeneric_flashlight_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_flashlight_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_ps30.inc new file mode 100644 index 00000000..a9734f15 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_ps30.inc @@ -0,0 +1,362 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_flashlight_ps30_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nNORMALMAP2; +#ifdef _DEBUG + bool m_bNORMALMAP2; +#endif +public: + void SetNORMALMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP2 = i; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } + void SetNORMALMAP2( bool i ) + { + m_nNORMALMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP2 = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nFANCY_BLENDING; +#ifdef _DEBUG + bool m_bFANCY_BLENDING; +#endif +public: + void SetFANCY_BLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFANCY_BLENDING = i; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } + void SetFANCY_BLENDING( bool i ) + { + m_nFANCY_BLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nPHONG; +#ifdef _DEBUG + bool m_bPHONG; +#endif +public: + void SetPHONG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONG = i; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } + void SetPHONG( bool i ) + { + m_nPHONG = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } +private: + int m_nPHONGMASK; +#ifdef _DEBUG + bool m_bPHONGMASK; +#endif +public: + void SetPHONGMASK( int i ) + { + Assert( i >= 0 && i <= 3 ); + m_nPHONGMASK = i; +#ifdef _DEBUG + m_bPHONGMASK = true; +#endif + } + void SetPHONGMASK( bool i ) + { + m_nPHONGMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONGMASK = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bNORMALMAP2 = false; +#endif // _DEBUG + m_nNORMALMAP2 = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = false; +#endif // _DEBUG + m_nFANCY_BLENDING = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bPHONG = false; +#endif // _DEBUG + m_nPHONG = 0; +#ifdef _DEBUG + m_bPHONGMASK = false; +#endif // _DEBUG + m_nPHONGMASK = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bNORMALMAP2 && m_bWORLDVERTEXTRANSITION && m_bFANCY_BLENDING && m_bSEAMLESS && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bFLASHLIGHTDEPTHFILTERMODE && m_bPHONG && m_bPHONGMASK && m_bBASETEXTURETRANSFORM2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nNORMALMAP ) + ( 12 * m_nNORMALMAP2 ) + ( 24 * m_nWORLDVERTEXTRANSITION ) + ( 48 * m_nFANCY_BLENDING ) + ( 96 * m_nSEAMLESS ) + ( 192 * m_nDETAILTEXTURE ) + ( 384 * m_nDETAIL_BLEND_MODE ) + ( 768 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 2304 * m_nPHONG ) + ( 4608 * m_nPHONGMASK ) + ( 18432 * m_nBASETEXTURETRANSFORM2 ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_flashlight_ps30 psh_forgot_to_set_static_NORMALMAP + psh_forgot_to_set_static_NORMALMAP2 + psh_forgot_to_set_static_WORLDVERTEXTRANSITION + psh_forgot_to_set_static_FANCY_BLENDING + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_PHONG + psh_forgot_to_set_static_PHONGMASK + psh_forgot_to_set_static_BASETEXTURETRANSFORM2 + 0 +class sdk_lightmappedgeneric_flashlight_ps30_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_flashlight_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_vs11.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_vs11.inc new file mode 100644 index 00000000..94142c09 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_vs11.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_flashlight_vs11_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_vs11_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bWORLDVERTEXTRANSITION && m_bVERTEXCOLOR; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nNORMALMAP ) + ( 4 * m_nWORLDVERTEXTRANSITION ) + ( 8 * m_nVERTEXCOLOR ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_flashlight_vs11 vsh_forgot_to_set_static_NORMALMAP + vsh_forgot_to_set_static_WORLDVERTEXTRANSITION + vsh_forgot_to_set_static_VERTEXCOLOR + 0 +class sdk_lightmappedgeneric_flashlight_vs11_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_vs11_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_flashlight_vs11 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_vs20.inc new file mode 100644 index 00000000..95edefe2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_vs20.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_flashlight_vs20_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nDETAIL; +#ifdef _DEBUG + bool m_bDETAIL; +#endif +public: + void SetDETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL = i; +#ifdef _DEBUG + m_bDETAIL = true; +#endif + } + void SetDETAIL( bool i ) + { + m_nDETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL = true; +#endif + } +private: + int m_nPHONG; +#ifdef _DEBUG + bool m_bPHONG; +#endif +public: + void SetPHONG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONG = i; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } + void SetPHONG( bool i ) + { + m_nPHONG = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bDETAIL = false; +#endif // _DEBUG + m_nDETAIL = 0; +#ifdef _DEBUG + m_bPHONG = false; +#endif // _DEBUG + m_nPHONG = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bWORLDVERTEXTRANSITION && m_bSEAMLESS && m_bDETAIL && m_bPHONG && m_bBASETEXTURETRANSFORM2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nNORMALMAP ) + ( 4 * m_nWORLDVERTEXTRANSITION ) + ( 8 * m_nSEAMLESS ) + ( 16 * m_nDETAIL ) + ( 32 * m_nPHONG ) + ( 64 * m_nBASETEXTURETRANSFORM2 ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_flashlight_vs20 vsh_forgot_to_set_static_NORMALMAP + vsh_forgot_to_set_static_WORLDVERTEXTRANSITION + vsh_forgot_to_set_static_SEAMLESS + vsh_forgot_to_set_static_DETAIL + vsh_forgot_to_set_static_PHONG + vsh_forgot_to_set_static_BASETEXTURETRANSFORM2 + 0 +class sdk_lightmappedgeneric_flashlight_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_flashlight_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_vs30.inc new file mode 100644 index 00000000..376110e3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_flashlight_vs30.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_flashlight_vs30_Static_Index +{ +private: + int m_nNORMALMAP; +#ifdef _DEBUG + bool m_bNORMALMAP; +#endif +public: + void SetNORMALMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAP = i; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } + void SetNORMALMAP( bool i ) + { + m_nNORMALMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAP = true; +#endif + } +private: + int m_nWORLDVERTEXTRANSITION; +#ifdef _DEBUG + bool m_bWORLDVERTEXTRANSITION; +#endif +public: + void SetWORLDVERTEXTRANSITION( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWORLDVERTEXTRANSITION = i; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } + void SetWORLDVERTEXTRANSITION( bool i ) + { + m_nWORLDVERTEXTRANSITION = i ? 1 : 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nDETAIL; +#ifdef _DEBUG + bool m_bDETAIL; +#endif +public: + void SetDETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL = i; +#ifdef _DEBUG + m_bDETAIL = true; +#endif + } + void SetDETAIL( bool i ) + { + m_nDETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL = true; +#endif + } +private: + int m_nPHONG; +#ifdef _DEBUG + bool m_bPHONG; +#endif +public: + void SetPHONG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONG = i; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } + void SetPHONG( bool i ) + { + m_nPHONG = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONG = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bNORMALMAP = false; +#endif // _DEBUG + m_nNORMALMAP = 0; +#ifdef _DEBUG + m_bWORLDVERTEXTRANSITION = false; +#endif // _DEBUG + m_nWORLDVERTEXTRANSITION = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bDETAIL = false; +#endif // _DEBUG + m_nDETAIL = 0; +#ifdef _DEBUG + m_bPHONG = false; +#endif // _DEBUG + m_nPHONG = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bNORMALMAP && m_bWORLDVERTEXTRANSITION && m_bSEAMLESS && m_bDETAIL && m_bPHONG && m_bBASETEXTURETRANSFORM2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nNORMALMAP ) + ( 4 * m_nWORLDVERTEXTRANSITION ) + ( 8 * m_nSEAMLESS ) + ( 16 * m_nDETAIL ) + ( 32 * m_nPHONG ) + ( 64 * m_nBASETEXTURETRANSFORM2 ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_flashlight_vs30 vsh_forgot_to_set_static_NORMALMAP + vsh_forgot_to_set_static_WORLDVERTEXTRANSITION + vsh_forgot_to_set_static_SEAMLESS + vsh_forgot_to_set_static_DETAIL + vsh_forgot_to_set_static_PHONG + vsh_forgot_to_set_static_BASETEXTURETRANSFORM2 + 0 +class sdk_lightmappedgeneric_flashlight_vs30_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_flashlight_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_flashlight_vs30 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_lightingonly_overbright2_ps11.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_lightingonly_overbright2_ps11.inc new file mode 100644 index 00000000..d11eaeb9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_lightingonly_overbright2_ps11.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_lightingonly_overbright2_ps11_Static_Index +{ +public: + sdk_lightmappedgeneric_lightingonly_overbright2_ps11_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_lightingonly_overbright2_ps11 0 +class sdk_lightmappedgeneric_lightingonly_overbright2_ps11_Dynamic_Index +{ +public: + sdk_lightmappedgeneric_lightingonly_overbright2_ps11_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_lightingonly_overbright2_ps11 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_lightingonly_vs11.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_lightingonly_vs11.inc new file mode 100644 index 00000000..5bb3dc94 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_lightingonly_vs11.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_lightingonly_vs11_Static_Index +{ +public: + sdk_lightmappedgeneric_lightingonly_vs11_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_lightingonly_vs11 0 +class sdk_lightmappedgeneric_lightingonly_vs11_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_lightingonly_vs11_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_lightingonly_vs11 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_ps11.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_ps11.inc new file mode 100644 index 00000000..30f358a1 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_ps11.inc @@ -0,0 +1,160 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_ps11_Static_Index +{ +private: + int m_nBASETEXTURE; +#ifdef _DEBUG + bool m_bBASETEXTURE; +#endif +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } + void SetBASETEXTURE( bool i ) + { + m_nBASETEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } +private: + int m_nENVMAP; +#ifdef _DEBUG + bool m_bENVMAP; +#endif +public: + void SetENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAP = i; +#ifdef _DEBUG + m_bENVMAP = true; +#endif + } + void SetENVMAP( bool i ) + { + m_nENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAP = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +public: + sdk_lightmappedgeneric_ps11_Static_Index( ) + { +#ifdef _DEBUG + m_bBASETEXTURE = false; +#endif // _DEBUG + m_nBASETEXTURE = 0; +#ifdef _DEBUG + m_bENVMAP = false; +#endif // _DEBUG + m_nENVMAP = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBASETEXTURE && m_bENVMAP && m_bENVMAPMASK && m_bSELFILLUM && m_bBASEALPHAENVMAPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nBASETEXTURE ) + ( 2 * m_nENVMAP ) + ( 4 * m_nENVMAPMASK ) + ( 8 * m_nSELFILLUM ) + ( 16 * m_nBASEALPHAENVMAPMASK ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_ps11 psh_forgot_to_set_static_BASETEXTURE + psh_forgot_to_set_static_ENVMAP + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + 0 +class sdk_lightmappedgeneric_ps11_Dynamic_Index +{ +public: + sdk_lightmappedgeneric_ps11_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_ps11 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_ps20b.inc new file mode 100644 index 00000000..4acdc5be --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_ps20b.inc @@ -0,0 +1,762 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_ps20b_Static_Index +{ +private: + int m_nMASKEDBLENDING; +#ifdef _DEBUG + bool m_bMASKEDBLENDING; +#endif +public: + void SetMASKEDBLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMASKEDBLENDING = i; +#ifdef _DEBUG + m_bMASKEDBLENDING = true; +#endif + } + void SetMASKEDBLENDING( bool i ) + { + m_nMASKEDBLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bMASKEDBLENDING = true; +#endif + } +private: + int m_nBASETEXTURE2; +#ifdef _DEBUG + bool m_bBASETEXTURE2; +#endif +public: + void SetBASETEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE2 = i; +#ifdef _DEBUG + m_bBASETEXTURE2 = true; +#endif + } + void SetBASETEXTURE2( bool i ) + { + m_nBASETEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE2 = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nBUMPMAP2; +#ifdef _DEBUG + bool m_bBUMPMAP2; +#endif +public: + void SetBUMPMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP2 = i; +#ifdef _DEBUG + m_bBUMPMAP2 = true; +#endif + } + void SetBUMPMAP2( bool i ) + { + m_nBUMPMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP2 = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nNORMALMAPALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bNORMALMAPALPHAENVMAPMASK; +#endif +public: + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } + void SetNORMALMAPALPHAENVMAPMASK( bool i ) + { + m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } +private: + int m_nDIFFUSEBUMPMAP; +#ifdef _DEBUG + bool m_bDIFFUSEBUMPMAP; +#endif +public: + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } + void SetDIFFUSEBUMPMAP( bool i ) + { + m_nDIFFUSEBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } +private: + int m_nBASETEXTURENOENVMAP; +#ifdef _DEBUG + bool m_bBASETEXTURENOENVMAP; +#endif +public: + void SetBASETEXTURENOENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURENOENVMAP = i; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = true; +#endif + } + void SetBASETEXTURENOENVMAP( bool i ) + { + m_nBASETEXTURENOENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = true; +#endif + } +private: + int m_nBASETEXTURE2NOENVMAP; +#ifdef _DEBUG + bool m_bBASETEXTURE2NOENVMAP; +#endif +public: + void SetBASETEXTURE2NOENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE2NOENVMAP = i; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = true; +#endif + } + void SetBASETEXTURE2NOENVMAP( bool i ) + { + m_nBASETEXTURE2NOENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = true; +#endif + } +private: + int m_nWARPLIGHTING; +#ifdef _DEBUG + bool m_bWARPLIGHTING; +#endif +public: + void SetWARPLIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWARPLIGHTING = i; +#ifdef _DEBUG + m_bWARPLIGHTING = true; +#endif + } + void SetWARPLIGHTING( bool i ) + { + m_nWARPLIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bWARPLIGHTING = true; +#endif + } +private: + int m_nFANCY_BLENDING; +#ifdef _DEBUG + bool m_bFANCY_BLENDING; +#endif +public: + void SetFANCY_BLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFANCY_BLENDING = i; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } + void SetFANCY_BLENDING( bool i ) + { + m_nFANCY_BLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } +private: + int m_nRELIEF_MAPPING; +#ifdef _DEBUG + bool m_bRELIEF_MAPPING; +#endif +public: + void SetRELIEF_MAPPING( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nRELIEF_MAPPING = i; +#ifdef _DEBUG + m_bRELIEF_MAPPING = true; +#endif + } + void SetRELIEF_MAPPING( bool i ) + { + m_nRELIEF_MAPPING = i ? 1 : 0; +#ifdef _DEBUG + m_bRELIEF_MAPPING = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nBUMPMASK; +#ifdef _DEBUG + bool m_bBUMPMASK; +#endif +public: + void SetBUMPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMASK = i; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } + void SetBUMPMASK( bool i ) + { + m_nBUMPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } +private: + int m_nNORMAL_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMAL_DECODE_MODE; +#endif +public: + void SetNORMAL_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMAL_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } + void SetNORMAL_DECODE_MODE( bool i ) + { + m_nNORMAL_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } +private: + int m_nNORMALMASK_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMALMASK_DECODE_MODE; +#endif +public: + void SetNORMALMASK_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMALMASK_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMALMASK_DECODE_MODE = true; +#endif + } + void SetNORMALMASK_DECODE_MODE( bool i ) + { + m_nNORMALMASK_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMASK_DECODE_MODE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 11 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +private: + int m_nPARALLAXCORRECT; +#ifdef _DEBUG + bool m_bPARALLAXCORRECT; +#endif +public: + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } + void SetPARALLAXCORRECT( bool i ) + { + m_nPARALLAXCORRECT = i ? 1 : 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } +public: + sdk_lightmappedgeneric_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bMASKEDBLENDING = false; +#endif // _DEBUG + m_nMASKEDBLENDING = 0; +#ifdef _DEBUG + m_bBASETEXTURE2 = false; +#endif // _DEBUG + m_nBASETEXTURE2 = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bBUMPMAP2 = false; +#endif // _DEBUG + m_nBUMPMAP2 = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nNORMALMAPALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = false; +#endif // _DEBUG + m_nDIFFUSEBUMPMAP = 0; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = false; +#endif // _DEBUG + m_nBASETEXTURENOENVMAP = 0; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = false; +#endif // _DEBUG + m_nBASETEXTURE2NOENVMAP = 0; +#ifdef _DEBUG + m_bWARPLIGHTING = false; +#endif // _DEBUG + m_nWARPLIGHTING = 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = false; +#endif // _DEBUG + m_nFANCY_BLENDING = 0; +#ifdef _DEBUG + m_bRELIEF_MAPPING = false; +#endif // _DEBUG + m_nRELIEF_MAPPING = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bBUMPMASK = false; +#endif // _DEBUG + m_nBUMPMASK = 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMAL_DECODE_MODE = 0; +#ifdef _DEBUG + m_bNORMALMASK_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMALMASK_DECODE_MODE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + m_nPARALLAXCORRECT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bMASKEDBLENDING && m_bBASETEXTURE2 && m_bDETAILTEXTURE && m_bBUMPMAP && m_bBUMPMAP2 && m_bCUBEMAP && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bNORMALMAPALPHAENVMAPMASK && m_bDIFFUSEBUMPMAP && m_bBASETEXTURENOENVMAP && m_bBASETEXTURE2NOENVMAP && m_bWARPLIGHTING && m_bFANCY_BLENDING && m_bRELIEF_MAPPING && m_bSEAMLESS && m_bBUMPMASK && m_bNORMAL_DECODE_MODE && m_bNORMALMASK_DECODE_MODE && m_bDETAIL_BLEND_MODE && m_bBASETEXTURETRANSFORM2 && m_bPARALLAXCORRECT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 96 * m_nMASKEDBLENDING ) + ( 192 * m_nBASETEXTURE2 ) + ( 384 * m_nDETAILTEXTURE ) + ( 768 * m_nBUMPMAP ) + ( 2304 * m_nBUMPMAP2 ) + ( 4608 * m_nCUBEMAP ) + ( 9216 * m_nENVMAPMASK ) + ( 18432 * m_nBASEALPHAENVMAPMASK ) + ( 36864 * m_nSELFILLUM ) + ( 73728 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 147456 * m_nDIFFUSEBUMPMAP ) + ( 294912 * m_nBASETEXTURENOENVMAP ) + ( 589824 * m_nBASETEXTURE2NOENVMAP ) + ( 1179648 * m_nWARPLIGHTING ) + ( 2359296 * m_nFANCY_BLENDING ) + ( 4718592 * m_nRELIEF_MAPPING ) + ( 4718592 * m_nSEAMLESS ) + ( 9437184 * m_nBUMPMASK ) + ( 18874368 * m_nNORMAL_DECODE_MODE ) + ( 18874368 * m_nNORMALMASK_DECODE_MODE ) + ( 18874368 * m_nDETAIL_BLEND_MODE ) + ( 226492416 * m_nBASETEXTURETRANSFORM2 ) + ( 452984832 * m_nPARALLAXCORRECT ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_ps20b psh_forgot_to_set_static_MASKEDBLENDING + psh_forgot_to_set_static_BASETEXTURE2 + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_BUMPMAP2 + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_DIFFUSEBUMPMAP + psh_forgot_to_set_static_BASETEXTURENOENVMAP + psh_forgot_to_set_static_BASETEXTURE2NOENVMAP + psh_forgot_to_set_static_WARPLIGHTING + psh_forgot_to_set_static_FANCY_BLENDING + psh_forgot_to_set_static_RELIEF_MAPPING + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_BUMPMASK + psh_forgot_to_set_static_NORMAL_DECODE_MODE + psh_forgot_to_set_static_NORMALMASK_DECODE_MODE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_BASETEXTURETRANSFORM2 + psh_forgot_to_set_static_PARALLAXCORRECT + 0 +class sdk_lightmappedgeneric_ps20b_Dynamic_Index +{ +private: + int m_nFASTPATHENVMAPCONTRAST; +#ifdef _DEBUG + bool m_bFASTPATHENVMAPCONTRAST; +#endif +public: + void SetFASTPATHENVMAPCONTRAST( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATHENVMAPCONTRAST = i; +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = true; +#endif + } + void SetFASTPATHENVMAPCONTRAST( bool i ) + { + m_nFASTPATHENVMAPCONTRAST = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = true; +#endif + } +private: + int m_nFASTPATH; +#ifdef _DEBUG + bool m_bFASTPATH; +#endif +public: + void SetFASTPATH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH = i; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } + void SetFASTPATH( bool i ) + { + m_nFASTPATH = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_lightmappedgeneric_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = false; +#endif // _DEBUG + m_nFASTPATHENVMAPCONTRAST = 0; +#ifdef _DEBUG + m_bFASTPATH = false; +#endif // _DEBUG + m_nFASTPATH = 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bFASTPATHENVMAPCONTRAST && m_bFASTPATH && m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bLIGHTING_PREVIEW && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nFASTPATHENVMAPCONTRAST ) + ( 2 * m_nFASTPATH ) + ( 4 * m_nWRITEWATERFOGTODESTALPHA ) + ( 8 * m_nPIXELFOGTYPE ) + ( 16 * m_nLIGHTING_PREVIEW ) + ( 48 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_ps20b psh_forgot_to_set_dynamic_FASTPATHENVMAPCONTRAST + psh_forgot_to_set_dynamic_FASTPATH + psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_LIGHTING_PREVIEW + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_ps30.inc new file mode 100644 index 00000000..205c6bda --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_ps30.inc @@ -0,0 +1,737 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_ps30_Static_Index +{ +private: + int m_nMASKEDBLENDING; +#ifdef _DEBUG + bool m_bMASKEDBLENDING; +#endif +public: + void SetMASKEDBLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMASKEDBLENDING = i; +#ifdef _DEBUG + m_bMASKEDBLENDING = true; +#endif + } + void SetMASKEDBLENDING( bool i ) + { + m_nMASKEDBLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bMASKEDBLENDING = true; +#endif + } +private: + int m_nBASETEXTURE2; +#ifdef _DEBUG + bool m_bBASETEXTURE2; +#endif +public: + void SetBASETEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE2 = i; +#ifdef _DEBUG + m_bBASETEXTURE2 = true; +#endif + } + void SetBASETEXTURE2( bool i ) + { + m_nBASETEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE2 = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nBUMPMAP2; +#ifdef _DEBUG + bool m_bBUMPMAP2; +#endif +public: + void SetBUMPMAP2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP2 = i; +#ifdef _DEBUG + m_bBUMPMAP2 = true; +#endif + } + void SetBUMPMAP2( bool i ) + { + m_nBUMPMAP2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP2 = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nNORMALMAPALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bNORMALMAPALPHAENVMAPMASK; +#endif +public: + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } + void SetNORMALMAPALPHAENVMAPMASK( bool i ) + { + m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } +private: + int m_nDIFFUSEBUMPMAP; +#ifdef _DEBUG + bool m_bDIFFUSEBUMPMAP; +#endif +public: + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } + void SetDIFFUSEBUMPMAP( bool i ) + { + m_nDIFFUSEBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } +private: + int m_nBASETEXTURENOENVMAP; +#ifdef _DEBUG + bool m_bBASETEXTURENOENVMAP; +#endif +public: + void SetBASETEXTURENOENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURENOENVMAP = i; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = true; +#endif + } + void SetBASETEXTURENOENVMAP( bool i ) + { + m_nBASETEXTURENOENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = true; +#endif + } +private: + int m_nBASETEXTURE2NOENVMAP; +#ifdef _DEBUG + bool m_bBASETEXTURE2NOENVMAP; +#endif +public: + void SetBASETEXTURE2NOENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE2NOENVMAP = i; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = true; +#endif + } + void SetBASETEXTURE2NOENVMAP( bool i ) + { + m_nBASETEXTURE2NOENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = true; +#endif + } +private: + int m_nWARPLIGHTING; +#ifdef _DEBUG + bool m_bWARPLIGHTING; +#endif +public: + void SetWARPLIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWARPLIGHTING = i; +#ifdef _DEBUG + m_bWARPLIGHTING = true; +#endif + } + void SetWARPLIGHTING( bool i ) + { + m_nWARPLIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bWARPLIGHTING = true; +#endif + } +private: + int m_nFANCY_BLENDING; +#ifdef _DEBUG + bool m_bFANCY_BLENDING; +#endif +public: + void SetFANCY_BLENDING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFANCY_BLENDING = i; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } + void SetFANCY_BLENDING( bool i ) + { + m_nFANCY_BLENDING = i ? 1 : 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nBUMPMASK; +#ifdef _DEBUG + bool m_bBUMPMASK; +#endif +public: + void SetBUMPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMASK = i; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } + void SetBUMPMASK( bool i ) + { + m_nBUMPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } +private: + int m_nNORMAL_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMAL_DECODE_MODE; +#endif +public: + void SetNORMAL_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMAL_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } + void SetNORMAL_DECODE_MODE( bool i ) + { + m_nNORMAL_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } +private: + int m_nNORMALMASK_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMALMASK_DECODE_MODE; +#endif +public: + void SetNORMALMASK_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMALMASK_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMALMASK_DECODE_MODE = true; +#endif + } + void SetNORMALMASK_DECODE_MODE( bool i ) + { + m_nNORMALMASK_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMASK_DECODE_MODE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 11 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +private: + int m_nPARALLAXCORRECT; +#ifdef _DEBUG + bool m_bPARALLAXCORRECT; +#endif +public: + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } + void SetPARALLAXCORRECT( bool i ) + { + m_nPARALLAXCORRECT = i ? 1 : 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } +public: + sdk_lightmappedgeneric_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bMASKEDBLENDING = false; +#endif // _DEBUG + m_nMASKEDBLENDING = 0; +#ifdef _DEBUG + m_bBASETEXTURE2 = false; +#endif // _DEBUG + m_nBASETEXTURE2 = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bBUMPMAP2 = false; +#endif // _DEBUG + m_nBUMPMAP2 = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nNORMALMAPALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = false; +#endif // _DEBUG + m_nDIFFUSEBUMPMAP = 0; +#ifdef _DEBUG + m_bBASETEXTURENOENVMAP = false; +#endif // _DEBUG + m_nBASETEXTURENOENVMAP = 0; +#ifdef _DEBUG + m_bBASETEXTURE2NOENVMAP = false; +#endif // _DEBUG + m_nBASETEXTURE2NOENVMAP = 0; +#ifdef _DEBUG + m_bWARPLIGHTING = false; +#endif // _DEBUG + m_nWARPLIGHTING = 0; +#ifdef _DEBUG + m_bFANCY_BLENDING = false; +#endif // _DEBUG + m_nFANCY_BLENDING = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bBUMPMASK = false; +#endif // _DEBUG + m_nBUMPMASK = 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMAL_DECODE_MODE = 0; +#ifdef _DEBUG + m_bNORMALMASK_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMALMASK_DECODE_MODE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + m_nPARALLAXCORRECT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bMASKEDBLENDING && m_bBASETEXTURE2 && m_bDETAILTEXTURE && m_bBUMPMAP && m_bBUMPMAP2 && m_bCUBEMAP && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bNORMALMAPALPHAENVMAPMASK && m_bDIFFUSEBUMPMAP && m_bBASETEXTURENOENVMAP && m_bBASETEXTURE2NOENVMAP && m_bWARPLIGHTING && m_bFANCY_BLENDING && m_bSEAMLESS && m_bBUMPMASK && m_bNORMAL_DECODE_MODE && m_bNORMALMASK_DECODE_MODE && m_bDETAIL_BLEND_MODE && m_bBASETEXTURETRANSFORM2 && m_bPARALLAXCORRECT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 96 * m_nMASKEDBLENDING ) + ( 192 * m_nBASETEXTURE2 ) + ( 384 * m_nDETAILTEXTURE ) + ( 768 * m_nBUMPMAP ) + ( 2304 * m_nBUMPMAP2 ) + ( 4608 * m_nCUBEMAP ) + ( 9216 * m_nENVMAPMASK ) + ( 18432 * m_nBASEALPHAENVMAPMASK ) + ( 36864 * m_nSELFILLUM ) + ( 73728 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 147456 * m_nDIFFUSEBUMPMAP ) + ( 294912 * m_nBASETEXTURENOENVMAP ) + ( 589824 * m_nBASETEXTURE2NOENVMAP ) + ( 1179648 * m_nWARPLIGHTING ) + ( 2359296 * m_nFANCY_BLENDING ) + ( 4718592 * m_nSEAMLESS ) + ( 9437184 * m_nBUMPMASK ) + ( 18874368 * m_nNORMAL_DECODE_MODE ) + ( 18874368 * m_nNORMALMASK_DECODE_MODE ) + ( 18874368 * m_nDETAIL_BLEND_MODE ) + ( 226492416 * m_nBASETEXTURETRANSFORM2 ) + ( 452984832 * m_nPARALLAXCORRECT ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_ps30 psh_forgot_to_set_static_MASKEDBLENDING + psh_forgot_to_set_static_BASETEXTURE2 + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_BUMPMAP2 + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_DIFFUSEBUMPMAP + psh_forgot_to_set_static_BASETEXTURENOENVMAP + psh_forgot_to_set_static_BASETEXTURE2NOENVMAP + psh_forgot_to_set_static_WARPLIGHTING + psh_forgot_to_set_static_FANCY_BLENDING + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_BUMPMASK + psh_forgot_to_set_static_NORMAL_DECODE_MODE + psh_forgot_to_set_static_NORMALMASK_DECODE_MODE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_BASETEXTURETRANSFORM2 + psh_forgot_to_set_static_PARALLAXCORRECT + 0 +class sdk_lightmappedgeneric_ps30_Dynamic_Index +{ +private: + int m_nFASTPATHENVMAPCONTRAST; +#ifdef _DEBUG + bool m_bFASTPATHENVMAPCONTRAST; +#endif +public: + void SetFASTPATHENVMAPCONTRAST( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATHENVMAPCONTRAST = i; +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = true; +#endif + } + void SetFASTPATHENVMAPCONTRAST( bool i ) + { + m_nFASTPATHENVMAPCONTRAST = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = true; +#endif + } +private: + int m_nFASTPATH; +#ifdef _DEBUG + bool m_bFASTPATH; +#endif +public: + void SetFASTPATH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH = i; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } + void SetFASTPATH( bool i ) + { + m_nFASTPATH = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_lightmappedgeneric_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bFASTPATHENVMAPCONTRAST = false; +#endif // _DEBUG + m_nFASTPATHENVMAPCONTRAST = 0; +#ifdef _DEBUG + m_bFASTPATH = false; +#endif // _DEBUG + m_nFASTPATH = 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bFASTPATHENVMAPCONTRAST && m_bFASTPATH && m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bLIGHTING_PREVIEW && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nFASTPATHENVMAPCONTRAST ) + ( 2 * m_nFASTPATH ) + ( 4 * m_nWRITEWATERFOGTODESTALPHA ) + ( 8 * m_nPIXELFOGTYPE ) + ( 16 * m_nLIGHTING_PREVIEW ) + ( 48 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_ps30 psh_forgot_to_set_dynamic_FASTPATHENVMAPCONTRAST + psh_forgot_to_set_dynamic_FASTPATH + psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_LIGHTING_PREVIEW + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_vs20.inc new file mode 100644 index 00000000..90c3dbb9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_vs20.inc @@ -0,0 +1,362 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_vs20_Static_Index +{ +private: + int m_nENVMAP_MASK; +#ifdef _DEBUG + bool m_bENVMAP_MASK; +#endif +public: + void SetENVMAP_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAP_MASK = i; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif + } + void SetENVMAP_MASK( bool i ) + { + m_nENVMAP_MASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif + } +private: + int m_nTANGENTSPACE; +#ifdef _DEBUG + bool m_bTANGENTSPACE; +#endif +public: + void SetTANGENTSPACE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTANGENTSPACE = i; +#ifdef _DEBUG + m_bTANGENTSPACE = true; +#endif + } + void SetTANGENTSPACE( bool i ) + { + m_nTANGENTSPACE = i ? 1 : 0; +#ifdef _DEBUG + m_bTANGENTSPACE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nDIFFUSEBUMPMAP; +#ifdef _DEBUG + bool m_bDIFFUSEBUMPMAP; +#endif +public: + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } + void SetDIFFUSEBUMPMAP( bool i ) + { + m_nDIFFUSEBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nVERTEXALPHATEXBLENDFACTOR; +#ifdef _DEBUG + bool m_bVERTEXALPHATEXBLENDFACTOR; +#endif +public: + void SetVERTEXALPHATEXBLENDFACTOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXALPHATEXBLENDFACTOR = i; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = true; +#endif + } + void SetVERTEXALPHATEXBLENDFACTOR( bool i ) + { + m_nVERTEXALPHATEXBLENDFACTOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = true; +#endif + } +private: + int m_nRELIEF_MAPPING; +#ifdef _DEBUG + bool m_bRELIEF_MAPPING; +#endif +public: + void SetRELIEF_MAPPING( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nRELIEF_MAPPING = i; +#ifdef _DEBUG + m_bRELIEF_MAPPING = true; +#endif + } + void SetRELIEF_MAPPING( bool i ) + { + m_nRELIEF_MAPPING = i ? 1 : 0; +#ifdef _DEBUG + m_bRELIEF_MAPPING = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nBUMPMASK; +#ifdef _DEBUG + bool m_bBUMPMASK; +#endif +public: + void SetBUMPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMASK = i; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } + void SetBUMPMASK( bool i ) + { + m_nBUMPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +public: + sdk_lightmappedgeneric_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bENVMAP_MASK = false; +#endif // _DEBUG + m_nENVMAP_MASK = 0; +#ifdef _DEBUG + m_bTANGENTSPACE = false; +#endif // _DEBUG + m_nTANGENTSPACE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = false; +#endif // _DEBUG + m_nDIFFUSEBUMPMAP = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = false; +#endif // _DEBUG + m_nVERTEXALPHATEXBLENDFACTOR = 0; +#ifdef _DEBUG + m_bRELIEF_MAPPING = false; +#endif // _DEBUG + m_nRELIEF_MAPPING = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bBUMPMASK = false; +#endif // _DEBUG + m_nBUMPMASK = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bENVMAP_MASK && m_bTANGENTSPACE && m_bBUMPMAP && m_bDIFFUSEBUMPMAP && m_bVERTEXCOLOR && m_bVERTEXALPHATEXBLENDFACTOR && m_bRELIEF_MAPPING && m_bSEAMLESS && m_bBUMPMASK && m_bBASETEXTURETRANSFORM2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 8 * m_nENVMAP_MASK ) + ( 16 * m_nTANGENTSPACE ) + ( 32 * m_nBUMPMAP ) + ( 64 * m_nDIFFUSEBUMPMAP ) + ( 128 * m_nVERTEXCOLOR ) + ( 256 * m_nVERTEXALPHATEXBLENDFACTOR ) + ( 512 * m_nRELIEF_MAPPING ) + ( 512 * m_nSEAMLESS ) + ( 1024 * m_nBUMPMASK ) + ( 2048 * m_nBASETEXTURETRANSFORM2 ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_vs20 vsh_forgot_to_set_static_ENVMAP_MASK + vsh_forgot_to_set_static_TANGENTSPACE + vsh_forgot_to_set_static_BUMPMAP + vsh_forgot_to_set_static_DIFFUSEBUMPMAP + vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_VERTEXALPHATEXBLENDFACTOR + vsh_forgot_to_set_static_RELIEF_MAPPING + vsh_forgot_to_set_static_SEAMLESS + vsh_forgot_to_set_static_BUMPMASK + vsh_forgot_to_set_static_BASETEXTURETRANSFORM2 + 0 +class sdk_lightmappedgeneric_vs20_Dynamic_Index +{ +private: + int m_nFASTPATH; +#ifdef _DEBUG + bool m_bFASTPATH; +#endif +public: + void SetFASTPATH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH = i; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } + void SetFASTPATH( bool i ) + { + m_nFASTPATH = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +public: + sdk_lightmappedgeneric_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bFASTPATH = false; +#endif // _DEBUG + m_nFASTPATH = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bFASTPATH && m_bDOWATERFOG && m_bLIGHTING_PREVIEW; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nFASTPATH ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nLIGHTING_PREVIEW ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_vs20 vsh_forgot_to_set_dynamic_FASTPATH + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_vs30.inc new file mode 100644 index 00000000..5fda5413 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedgeneric_vs30.inc @@ -0,0 +1,362 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedgeneric_vs30_Static_Index +{ +private: + int m_nENVMAP_MASK; +#ifdef _DEBUG + bool m_bENVMAP_MASK; +#endif +public: + void SetENVMAP_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAP_MASK = i; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif + } + void SetENVMAP_MASK( bool i ) + { + m_nENVMAP_MASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAP_MASK = true; +#endif + } +private: + int m_nTANGENTSPACE; +#ifdef _DEBUG + bool m_bTANGENTSPACE; +#endif +public: + void SetTANGENTSPACE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTANGENTSPACE = i; +#ifdef _DEBUG + m_bTANGENTSPACE = true; +#endif + } + void SetTANGENTSPACE( bool i ) + { + m_nTANGENTSPACE = i ? 1 : 0; +#ifdef _DEBUG + m_bTANGENTSPACE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nDIFFUSEBUMPMAP; +#ifdef _DEBUG + bool m_bDIFFUSEBUMPMAP; +#endif +public: + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } + void SetDIFFUSEBUMPMAP( bool i ) + { + m_nDIFFUSEBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nVERTEXALPHATEXBLENDFACTOR; +#ifdef _DEBUG + bool m_bVERTEXALPHATEXBLENDFACTOR; +#endif +public: + void SetVERTEXALPHATEXBLENDFACTOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXALPHATEXBLENDFACTOR = i; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = true; +#endif + } + void SetVERTEXALPHATEXBLENDFACTOR( bool i ) + { + m_nVERTEXALPHATEXBLENDFACTOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = true; +#endif + } +private: + int m_nRELIEF_MAPPING; +#ifdef _DEBUG + bool m_bRELIEF_MAPPING; +#endif +public: + void SetRELIEF_MAPPING( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nRELIEF_MAPPING = i; +#ifdef _DEBUG + m_bRELIEF_MAPPING = true; +#endif + } + void SetRELIEF_MAPPING( bool i ) + { + m_nRELIEF_MAPPING = i ? 1 : 0; +#ifdef _DEBUG + m_bRELIEF_MAPPING = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nBUMPMASK; +#ifdef _DEBUG + bool m_bBUMPMASK; +#endif +public: + void SetBUMPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMASK = i; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } + void SetBUMPMASK( bool i ) + { + m_nBUMPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMASK = true; +#endif + } +private: + int m_nBASETEXTURETRANSFORM2; +#ifdef _DEBUG + bool m_bBASETEXTURETRANSFORM2; +#endif +public: + void SetBASETEXTURETRANSFORM2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURETRANSFORM2 = i; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } + void SetBASETEXTURETRANSFORM2( bool i ) + { + m_nBASETEXTURETRANSFORM2 = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = true; +#endif + } +public: + sdk_lightmappedgeneric_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bENVMAP_MASK = false; +#endif // _DEBUG + m_nENVMAP_MASK = 0; +#ifdef _DEBUG + m_bTANGENTSPACE = false; +#endif // _DEBUG + m_nTANGENTSPACE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = false; +#endif // _DEBUG + m_nDIFFUSEBUMPMAP = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bVERTEXALPHATEXBLENDFACTOR = false; +#endif // _DEBUG + m_nVERTEXALPHATEXBLENDFACTOR = 0; +#ifdef _DEBUG + m_bRELIEF_MAPPING = false; +#endif // _DEBUG + m_nRELIEF_MAPPING = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bBUMPMASK = false; +#endif // _DEBUG + m_nBUMPMASK = 0; +#ifdef _DEBUG + m_bBASETEXTURETRANSFORM2 = false; +#endif // _DEBUG + m_nBASETEXTURETRANSFORM2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bENVMAP_MASK && m_bTANGENTSPACE && m_bBUMPMAP && m_bDIFFUSEBUMPMAP && m_bVERTEXCOLOR && m_bVERTEXALPHATEXBLENDFACTOR && m_bRELIEF_MAPPING && m_bSEAMLESS && m_bBUMPMASK && m_bBASETEXTURETRANSFORM2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 8 * m_nENVMAP_MASK ) + ( 16 * m_nTANGENTSPACE ) + ( 32 * m_nBUMPMAP ) + ( 64 * m_nDIFFUSEBUMPMAP ) + ( 128 * m_nVERTEXCOLOR ) + ( 256 * m_nVERTEXALPHATEXBLENDFACTOR ) + ( 512 * m_nRELIEF_MAPPING ) + ( 512 * m_nSEAMLESS ) + ( 1024 * m_nBUMPMASK ) + ( 2048 * m_nBASETEXTURETRANSFORM2 ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedgeneric_vs30 vsh_forgot_to_set_static_ENVMAP_MASK + vsh_forgot_to_set_static_TANGENTSPACE + vsh_forgot_to_set_static_BUMPMAP + vsh_forgot_to_set_static_DIFFUSEBUMPMAP + vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_VERTEXALPHATEXBLENDFACTOR + vsh_forgot_to_set_static_RELIEF_MAPPING + vsh_forgot_to_set_static_SEAMLESS + vsh_forgot_to_set_static_BUMPMASK + vsh_forgot_to_set_static_BASETEXTURETRANSFORM2 + 0 +class sdk_lightmappedgeneric_vs30_Dynamic_Index +{ +private: + int m_nFASTPATH; +#ifdef _DEBUG + bool m_bFASTPATH; +#endif +public: + void SetFASTPATH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH = i; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } + void SetFASTPATH( bool i ) + { + m_nFASTPATH = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATH = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +public: + sdk_lightmappedgeneric_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bFASTPATH = false; +#endif // _DEBUG + m_nFASTPATH = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bFASTPATH && m_bDOWATERFOG && m_bLIGHTING_PREVIEW; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nFASTPATH ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nLIGHTING_PREVIEW ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedgeneric_vs30 vsh_forgot_to_set_dynamic_FASTPATH + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedreflective_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedreflective_ps20.inc new file mode 100644 index 00000000..469d8062 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedreflective_ps20.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedreflective_ps20_Static_Index +{ +private: + int m_nBASETEXTURE; +#ifdef _DEBUG + bool m_bBASETEXTURE; +#endif +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } + void SetBASETEXTURE( bool i ) + { + m_nBASETEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } +private: + int m_nREFLECT; +#ifdef _DEBUG + bool m_bREFLECT; +#endif +public: + void SetREFLECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFLECT = i; +#ifdef _DEBUG + m_bREFLECT = true; +#endif + } + void SetREFLECT( bool i ) + { + m_nREFLECT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFLECT = true; +#endif + } +private: + int m_nREFRACT; +#ifdef _DEBUG + bool m_bREFRACT; +#endif +public: + void SetREFRACT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACT = i; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } + void SetREFRACT( bool i ) + { + m_nREFRACT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +public: + sdk_lightmappedreflective_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bBASETEXTURE = false; +#endif // _DEBUG + m_nBASETEXTURE = 0; +#ifdef _DEBUG + m_bREFLECT = false; +#endif // _DEBUG + m_nREFLECT = 0; +#ifdef _DEBUG + m_bREFRACT = false; +#endif // _DEBUG + m_nREFRACT = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBASETEXTURE && m_bREFLECT && m_bREFRACT && m_bENVMAPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nBASETEXTURE ) + ( 4 * m_nREFLECT ) + ( 8 * m_nREFRACT ) + ( 16 * m_nENVMAPMASK ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedreflective_ps20 psh_forgot_to_set_static_BASETEXTURE + psh_forgot_to_set_static_REFLECT + psh_forgot_to_set_static_REFRACT + psh_forgot_to_set_static_ENVMAPMASK + 0 +class sdk_lightmappedreflective_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_lightmappedreflective_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedreflective_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedreflective_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedreflective_ps20b.inc new file mode 100644 index 00000000..e5a00725 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedreflective_ps20b.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedreflective_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nBASETEXTURE; +#ifdef _DEBUG + bool m_bBASETEXTURE; +#endif +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } + void SetBASETEXTURE( bool i ) + { + m_nBASETEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } +private: + int m_nREFLECT; +#ifdef _DEBUG + bool m_bREFLECT; +#endif +public: + void SetREFLECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFLECT = i; +#ifdef _DEBUG + m_bREFLECT = true; +#endif + } + void SetREFLECT( bool i ) + { + m_nREFLECT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFLECT = true; +#endif + } +private: + int m_nREFRACT; +#ifdef _DEBUG + bool m_bREFRACT; +#endif +public: + void SetREFRACT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACT = i; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } + void SetREFRACT( bool i ) + { + m_nREFRACT = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACT = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +public: + sdk_lightmappedreflective_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bBASETEXTURE = false; +#endif // _DEBUG + m_nBASETEXTURE = 0; +#ifdef _DEBUG + m_bREFLECT = false; +#endif // _DEBUG + m_nREFLECT = 0; +#ifdef _DEBUG + m_bREFRACT = false; +#endif // _DEBUG + m_nREFRACT = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bBASETEXTURE && m_bREFLECT && m_bREFRACT && m_bENVMAPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nBASETEXTURE ) + ( 16 * m_nREFLECT ) + ( 32 * m_nREFRACT ) + ( 64 * m_nENVMAPMASK ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedreflective_ps20b psh_forgot_to_set_static_BASETEXTURE + psh_forgot_to_set_static_REFLECT + psh_forgot_to_set_static_REFRACT + psh_forgot_to_set_static_ENVMAPMASK + 0 +class sdk_lightmappedreflective_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_lightmappedreflective_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedreflective_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedreflective_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedreflective_vs20.inc new file mode 100644 index 00000000..4321a47b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_lightmappedreflective_vs20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_lightmappedreflective_vs20_Static_Index +{ +private: + int m_nBASETEXTURE; +#ifdef _DEBUG + bool m_bBASETEXTURE; +#endif +public: + void SetBASETEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASETEXTURE = i; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } + void SetBASETEXTURE( bool i ) + { + m_nBASETEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bBASETEXTURE = true; +#endif + } +public: + sdk_lightmappedreflective_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bBASETEXTURE = false; +#endif // _DEBUG + m_nBASETEXTURE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBASETEXTURE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nBASETEXTURE ) + 0; + } +}; +#define shaderStaticTest_sdk_lightmappedreflective_vs20 vsh_forgot_to_set_static_BASETEXTURE + 0 +class sdk_lightmappedreflective_vs20_Dynamic_Index +{ +public: + sdk_lightmappedreflective_vs20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_lightmappedreflective_vs20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_monitorscreen_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_monitorscreen_ps20.inc new file mode 100644 index 00000000..12b6a1b6 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_monitorscreen_ps20.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_monitorscreen_ps20_Static_Index +{ +private: + int m_nTEXTURE2; +#ifdef _DEBUG + bool m_bTEXTURE2; +#endif +public: + void SetTEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTEXTURE2 = i; +#ifdef _DEBUG + m_bTEXTURE2 = true; +#endif + } + void SetTEXTURE2( bool i ) + { + m_nTEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bTEXTURE2 = true; +#endif + } +public: + sdk_monitorscreen_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bTEXTURE2 = false; +#endif // _DEBUG + m_nTEXTURE2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTEXTURE2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nTEXTURE2 ) + 0; + } +}; +#define shaderStaticTest_sdk_monitorscreen_ps20 psh_forgot_to_set_static_TEXTURE2 + 0 +class sdk_monitorscreen_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_monitorscreen_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_monitorscreen_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_monitorscreen_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_monitorscreen_ps20b.inc new file mode 100644 index 00000000..39daea2f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_monitorscreen_ps20b.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_monitorscreen_ps20b_Static_Index +{ +private: + int m_nTEXTURE2; +#ifdef _DEBUG + bool m_bTEXTURE2; +#endif +public: + void SetTEXTURE2( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTEXTURE2 = i; +#ifdef _DEBUG + m_bTEXTURE2 = true; +#endif + } + void SetTEXTURE2( bool i ) + { + m_nTEXTURE2 = i ? 1 : 0; +#ifdef _DEBUG + m_bTEXTURE2 = true; +#endif + } +public: + sdk_monitorscreen_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bTEXTURE2 = false; +#endif // _DEBUG + m_nTEXTURE2 = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTEXTURE2; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nTEXTURE2 ) + 0; + } +}; +#define shaderStaticTest_sdk_monitorscreen_ps20b psh_forgot_to_set_static_TEXTURE2 + 0 +class sdk_monitorscreen_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_monitorscreen_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_monitorscreen_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_refract_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_refract_ps20.inc new file mode 100644 index 00000000..839d80a2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_refract_ps20.inc @@ -0,0 +1,262 @@ +#include "shaderlib/cshader.h" +class sdk_refract_ps20_Static_Index +{ +private: + int m_nBLUR; +#ifdef _DEBUG + bool m_bBLUR; +#endif +public: + void SetBLUR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLUR = i; +#ifdef _DEBUG + m_bBLUR = true; +#endif + } + void SetBLUR( bool i ) + { + m_nBLUR = i ? 1 : 0; +#ifdef _DEBUG + m_bBLUR = true; +#endif + } +private: + int m_nFADEOUTONSILHOUETTE; +#ifdef _DEBUG + bool m_bFADEOUTONSILHOUETTE; +#endif +public: + void SetFADEOUTONSILHOUETTE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFADEOUTONSILHOUETTE = i; +#ifdef _DEBUG + m_bFADEOUTONSILHOUETTE = true; +#endif + } + void SetFADEOUTONSILHOUETTE( bool i ) + { + m_nFADEOUTONSILHOUETTE = i ? 1 : 0; +#ifdef _DEBUG + m_bFADEOUTONSILHOUETTE = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nREFRACTTINTTEXTURE; +#ifdef _DEBUG + bool m_bREFRACTTINTTEXTURE; +#endif +public: + void SetREFRACTTINTTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACTTINTTEXTURE = i; +#ifdef _DEBUG + m_bREFRACTTINTTEXTURE = true; +#endif + } + void SetREFRACTTINTTEXTURE( bool i ) + { + m_nREFRACTTINTTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACTTINTTEXTURE = true; +#endif + } +private: + int m_nMASKED; +#ifdef _DEBUG + bool m_bMASKED; +#endif +public: + void SetMASKED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMASKED = i; +#ifdef _DEBUG + m_bMASKED = true; +#endif + } + void SetMASKED( bool i ) + { + m_nMASKED = i ? 1 : 0; +#ifdef _DEBUG + m_bMASKED = true; +#endif + } +private: + int m_nCOLORMODULATE; +#ifdef _DEBUG + bool m_bCOLORMODULATE; +#endif +public: + void SetCOLORMODULATE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLORMODULATE = i; +#ifdef _DEBUG + m_bCOLORMODULATE = true; +#endif + } + void SetCOLORMODULATE( bool i ) + { + m_nCOLORMODULATE = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLORMODULATE = true; +#endif + } +private: + int m_nSECONDARY_NORMAL; +#ifdef _DEBUG + bool m_bSECONDARY_NORMAL; +#endif +public: + void SetSECONDARY_NORMAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSECONDARY_NORMAL = i; +#ifdef _DEBUG + m_bSECONDARY_NORMAL = true; +#endif + } + void SetSECONDARY_NORMAL( bool i ) + { + m_nSECONDARY_NORMAL = i ? 1 : 0; +#ifdef _DEBUG + m_bSECONDARY_NORMAL = true; +#endif + } +private: + int m_nNORMAL_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMAL_DECODE_MODE; +#endif +public: + void SetNORMAL_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMAL_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } + void SetNORMAL_DECODE_MODE( bool i ) + { + m_nNORMAL_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } +public: + sdk_refract_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bBLUR = false; +#endif // _DEBUG + m_nBLUR = 0; +#ifdef _DEBUG + m_bFADEOUTONSILHOUETTE = false; +#endif // _DEBUG + m_nFADEOUTONSILHOUETTE = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bREFRACTTINTTEXTURE = false; +#endif // _DEBUG + m_nREFRACTTINTTEXTURE = 0; +#ifdef _DEBUG + m_bMASKED = false; +#endif // _DEBUG + m_nMASKED = 0; +#ifdef _DEBUG + m_bCOLORMODULATE = false; +#endif // _DEBUG + m_nCOLORMODULATE = 0; +#ifdef _DEBUG + m_bSECONDARY_NORMAL = false; +#endif // _DEBUG + m_nSECONDARY_NORMAL = 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMAL_DECODE_MODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bBLUR && m_bFADEOUTONSILHOUETTE && m_bCUBEMAP && m_bREFRACTTINTTEXTURE && m_bMASKED && m_bCOLORMODULATE && m_bSECONDARY_NORMAL && m_bNORMAL_DECODE_MODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nBLUR ) + ( 4 * m_nFADEOUTONSILHOUETTE ) + ( 8 * m_nCUBEMAP ) + ( 16 * m_nREFRACTTINTTEXTURE ) + ( 32 * m_nMASKED ) + ( 64 * m_nCOLORMODULATE ) + ( 128 * m_nSECONDARY_NORMAL ) + ( 256 * m_nNORMAL_DECODE_MODE ) + 0; + } +}; +#define shaderStaticTest_sdk_refract_ps20 psh_forgot_to_set_static_BLUR + psh_forgot_to_set_static_FADEOUTONSILHOUETTE + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_REFRACTTINTTEXTURE + psh_forgot_to_set_static_MASKED + psh_forgot_to_set_static_COLORMODULATE + psh_forgot_to_set_static_SECONDARY_NORMAL + psh_forgot_to_set_static_NORMAL_DECODE_MODE + 0 +class sdk_refract_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_refract_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_refract_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_refract_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_refract_ps20b.inc new file mode 100644 index 00000000..3d877ae0 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_refract_ps20b.inc @@ -0,0 +1,337 @@ +#include "shaderlib/cshader.h" +class sdk_refract_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nBLUR; +#ifdef _DEBUG + bool m_bBLUR; +#endif +public: + void SetBLUR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLUR = i; +#ifdef _DEBUG + m_bBLUR = true; +#endif + } + void SetBLUR( bool i ) + { + m_nBLUR = i ? 1 : 0; +#ifdef _DEBUG + m_bBLUR = true; +#endif + } +private: + int m_nFADEOUTONSILHOUETTE; +#ifdef _DEBUG + bool m_bFADEOUTONSILHOUETTE; +#endif +public: + void SetFADEOUTONSILHOUETTE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFADEOUTONSILHOUETTE = i; +#ifdef _DEBUG + m_bFADEOUTONSILHOUETTE = true; +#endif + } + void SetFADEOUTONSILHOUETTE( bool i ) + { + m_nFADEOUTONSILHOUETTE = i ? 1 : 0; +#ifdef _DEBUG + m_bFADEOUTONSILHOUETTE = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nREFRACTTINTTEXTURE; +#ifdef _DEBUG + bool m_bREFRACTTINTTEXTURE; +#endif +public: + void SetREFRACTTINTTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nREFRACTTINTTEXTURE = i; +#ifdef _DEBUG + m_bREFRACTTINTTEXTURE = true; +#endif + } + void SetREFRACTTINTTEXTURE( bool i ) + { + m_nREFRACTTINTTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bREFRACTTINTTEXTURE = true; +#endif + } +private: + int m_nMASKED; +#ifdef _DEBUG + bool m_bMASKED; +#endif +public: + void SetMASKED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMASKED = i; +#ifdef _DEBUG + m_bMASKED = true; +#endif + } + void SetMASKED( bool i ) + { + m_nMASKED = i ? 1 : 0; +#ifdef _DEBUG + m_bMASKED = true; +#endif + } +private: + int m_nCOLORMODULATE; +#ifdef _DEBUG + bool m_bCOLORMODULATE; +#endif +public: + void SetCOLORMODULATE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOLORMODULATE = i; +#ifdef _DEBUG + m_bCOLORMODULATE = true; +#endif + } + void SetCOLORMODULATE( bool i ) + { + m_nCOLORMODULATE = i ? 1 : 0; +#ifdef _DEBUG + m_bCOLORMODULATE = true; +#endif + } +private: + int m_nSECONDARY_NORMAL; +#ifdef _DEBUG + bool m_bSECONDARY_NORMAL; +#endif +public: + void SetSECONDARY_NORMAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSECONDARY_NORMAL = i; +#ifdef _DEBUG + m_bSECONDARY_NORMAL = true; +#endif + } + void SetSECONDARY_NORMAL( bool i ) + { + m_nSECONDARY_NORMAL = i ? 1 : 0; +#ifdef _DEBUG + m_bSECONDARY_NORMAL = true; +#endif + } +private: + int m_nNORMAL_DECODE_MODE; +#ifdef _DEBUG + bool m_bNORMAL_DECODE_MODE; +#endif +public: + void SetNORMAL_DECODE_MODE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nNORMAL_DECODE_MODE = i; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } + void SetNORMAL_DECODE_MODE( bool i ) + { + m_nNORMAL_DECODE_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = true; +#endif + } +private: + int m_nSHADER_SRGB_READ; +#ifdef _DEBUG + bool m_bSHADER_SRGB_READ; +#endif +public: + void SetSHADER_SRGB_READ( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSHADER_SRGB_READ = i; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = true; +#endif + } + void SetSHADER_SRGB_READ( bool i ) + { + m_nSHADER_SRGB_READ = i ? 1 : 0; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = true; +#endif + } +public: + sdk_refract_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bBLUR = false; +#endif // _DEBUG + m_nBLUR = 0; +#ifdef _DEBUG + m_bFADEOUTONSILHOUETTE = false; +#endif // _DEBUG + m_nFADEOUTONSILHOUETTE = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bREFRACTTINTTEXTURE = false; +#endif // _DEBUG + m_nREFRACTTINTTEXTURE = 0; +#ifdef _DEBUG + m_bMASKED = false; +#endif // _DEBUG + m_nMASKED = 0; +#ifdef _DEBUG + m_bCOLORMODULATE = false; +#endif // _DEBUG + m_nCOLORMODULATE = 0; +#ifdef _DEBUG + m_bSECONDARY_NORMAL = false; +#endif // _DEBUG + m_nSECONDARY_NORMAL = 0; +#ifdef _DEBUG + m_bNORMAL_DECODE_MODE = false; +#endif // _DEBUG + m_nNORMAL_DECODE_MODE = 0; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = false; +#endif // _DEBUG + m_nSHADER_SRGB_READ = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bBLUR && m_bFADEOUTONSILHOUETTE && m_bCUBEMAP && m_bREFRACTTINTTEXTURE && m_bMASKED && m_bCOLORMODULATE && m_bSECONDARY_NORMAL && m_bNORMAL_DECODE_MODE && m_bSHADER_SRGB_READ; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nBLUR ) + ( 16 * m_nFADEOUTONSILHOUETTE ) + ( 32 * m_nCUBEMAP ) + ( 64 * m_nREFRACTTINTTEXTURE ) + ( 128 * m_nMASKED ) + ( 256 * m_nCOLORMODULATE ) + ( 512 * m_nSECONDARY_NORMAL ) + ( 1024 * m_nNORMAL_DECODE_MODE ) + ( 1024 * m_nSHADER_SRGB_READ ) + 0; + } +}; +#define shaderStaticTest_sdk_refract_ps20b psh_forgot_to_set_static_BLUR + psh_forgot_to_set_static_FADEOUTONSILHOUETTE + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_REFRACTTINTTEXTURE + psh_forgot_to_set_static_MASKED + psh_forgot_to_set_static_COLORMODULATE + psh_forgot_to_set_static_SECONDARY_NORMAL + psh_forgot_to_set_static_NORMAL_DECODE_MODE + psh_forgot_to_set_static_SHADER_SRGB_READ + 0 +class sdk_refract_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_refract_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_refract_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_screenspaceeffect_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_screenspaceeffect_vs20.inc new file mode 100644 index 00000000..607c12cd --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_screenspaceeffect_vs20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_screenspaceeffect_vs20_Static_Index +{ +private: + int m_nX360APPCHOOSER; +#ifdef _DEBUG + bool m_bX360APPCHOOSER; +#endif +public: + void SetX360APPCHOOSER( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nX360APPCHOOSER = i; +#ifdef _DEBUG + m_bX360APPCHOOSER = true; +#endif + } + void SetX360APPCHOOSER( bool i ) + { + m_nX360APPCHOOSER = i ? 1 : 0; +#ifdef _DEBUG + m_bX360APPCHOOSER = true; +#endif + } +public: + sdk_screenspaceeffect_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bX360APPCHOOSER = true; +#endif // _DEBUG + m_nX360APPCHOOSER = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bX360APPCHOOSER; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nX360APPCHOOSER ) + 0; + } +}; +#define shaderStaticTest_sdk_screenspaceeffect_vs20 0 +class sdk_screenspaceeffect_vs20_Dynamic_Index +{ +public: + sdk_screenspaceeffect_vs20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_screenspaceeffect_vs20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_skin_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_skin_ps20b.inc new file mode 100644 index 00000000..15a41433 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_skin_ps20b.inc @@ -0,0 +1,562 @@ +#include "shaderlib/cshader.h" +class sdk_skin_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nSELFILLUMFRESNEL; +#ifdef _DEBUG + bool m_bSELFILLUMFRESNEL; +#endif +public: + void SetSELFILLUMFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUMFRESNEL = i; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } + void SetSELFILLUMFRESNEL( bool i ) + { + m_nSELFILLUMFRESNEL = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +private: + int m_nPHONGWARPTEXTURE; +#ifdef _DEBUG + bool m_bPHONGWARPTEXTURE; +#endif +public: + void SetPHONGWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONGWARPTEXTURE = i; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = true; +#endif + } + void SetPHONGWARPTEXTURE( bool i ) + { + m_nPHONGWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = true; +#endif + } +private: + int m_nWRINKLEMAP; +#ifdef _DEBUG + bool m_bWRINKLEMAP; +#endif +public: + void SetWRINKLEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRINKLEMAP = i; +#ifdef _DEBUG + m_bWRINKLEMAP = true; +#endif + } + void SetWRINKLEMAP( bool i ) + { + m_nWRINKLEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bWRINKLEMAP = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 6 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nRIMLIGHT; +#ifdef _DEBUG + bool m_bRIMLIGHT; +#endif +public: + void SetRIMLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nRIMLIGHT = i; +#ifdef _DEBUG + m_bRIMLIGHT = true; +#endif + } + void SetRIMLIGHT( bool i ) + { + m_nRIMLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bRIMLIGHT = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nFASTPATH_NOBUMP; +#ifdef _DEBUG + bool m_bFASTPATH_NOBUMP; +#endif +public: + void SetFASTPATH_NOBUMP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH_NOBUMP = i; +#ifdef _DEBUG + m_bFASTPATH_NOBUMP = true; +#endif + } + void SetFASTPATH_NOBUMP( bool i ) + { + m_nFASTPATH_NOBUMP = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATH_NOBUMP = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +private: + int m_nPHONG_HALFLAMBERT; +#ifdef _DEBUG + bool m_bPHONG_HALFLAMBERT; +#endif +public: + void SetPHONG_HALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONG_HALFLAMBERT = i; +#ifdef _DEBUG + m_bPHONG_HALFLAMBERT = true; +#endif + } + void SetPHONG_HALFLAMBERT( bool i ) + { + m_nPHONG_HALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONG_HALFLAMBERT = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +public: + sdk_skin_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = false; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = false; +#endif // _DEBUG + m_nSELFILLUMFRESNEL = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = false; +#endif // _DEBUG + m_nPHONGWARPTEXTURE = 0; +#ifdef _DEBUG + m_bWRINKLEMAP = false; +#endif // _DEBUG + m_nWRINKLEMAP = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bRIMLIGHT = false; +#endif // _DEBUG + m_nRIMLIGHT = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bFASTPATH_NOBUMP = false; +#endif // _DEBUG + m_nFASTPATH_NOBUMP = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; +#ifdef _DEBUG + m_bPHONG_HALFLAMBERT = false; +#endif // _DEBUG + m_nPHONG_HALFLAMBERT = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bCUBEMAP && m_bSELFILLUM && m_bSELFILLUMFRESNEL && m_bFLASHLIGHT && m_bLIGHTWARPTEXTURE && m_bPHONGWARPTEXTURE && m_bWRINKLEMAP && m_bDETAIL_BLEND_MODE && m_bDETAILTEXTURE && m_bRIMLIGHT && m_bFLASHLIGHTDEPTHFILTERMODE && m_bFASTPATH_NOBUMP && m_bBLENDTINTBYBASEALPHA && m_bPHONG_HALFLAMBERT && m_bENVMAPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 80 * m_nCONVERT_TO_SRGB ) + ( 80 * m_nCUBEMAP ) + ( 160 * m_nSELFILLUM ) + ( 320 * m_nSELFILLUMFRESNEL ) + ( 640 * m_nFLASHLIGHT ) + ( 1280 * m_nLIGHTWARPTEXTURE ) + ( 2560 * m_nPHONGWARPTEXTURE ) + ( 5120 * m_nWRINKLEMAP ) + ( 10240 * m_nDETAIL_BLEND_MODE ) + ( 71680 * m_nDETAILTEXTURE ) + ( 143360 * m_nRIMLIGHT ) + ( 286720 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 860160 * m_nFASTPATH_NOBUMP ) + ( 1720320 * m_nBLENDTINTBYBASEALPHA ) + ( 3440640 * m_nPHONG_HALFLAMBERT ) + ( 6881280 * m_nENVMAPMASK ) + 0; + } +}; +#define shaderStaticTest_sdk_skin_ps20b psh_forgot_to_set_static_CONVERT_TO_SRGB + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_SELFILLUMFRESNEL + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_PHONGWARPTEXTURE + psh_forgot_to_set_static_WRINKLEMAP + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_RIMLIGHT + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_FASTPATH_NOBUMP + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_PHONG_HALFLAMBERT + psh_forgot_to_set_static_ENVMAPMASK + 0 +class sdk_skin_ps20b_Dynamic_Index +{ +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_skin_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nNUM_LIGHTS ) + ( 20 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 40 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_skin_ps20b psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_skin_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_skin_ps30.inc new file mode 100644 index 00000000..3c53e88b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_skin_ps30.inc @@ -0,0 +1,562 @@ +#include "shaderlib/cshader.h" +class sdk_skin_ps30_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nSELFILLUMFRESNEL; +#ifdef _DEBUG + bool m_bSELFILLUMFRESNEL; +#endif +public: + void SetSELFILLUMFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUMFRESNEL = i; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } + void SetSELFILLUMFRESNEL( bool i ) + { + m_nSELFILLUMFRESNEL = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +private: + int m_nPHONGWARPTEXTURE; +#ifdef _DEBUG + bool m_bPHONGWARPTEXTURE; +#endif +public: + void SetPHONGWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONGWARPTEXTURE = i; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = true; +#endif + } + void SetPHONGWARPTEXTURE( bool i ) + { + m_nPHONGWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = true; +#endif + } +private: + int m_nWRINKLEMAP; +#ifdef _DEBUG + bool m_bWRINKLEMAP; +#endif +public: + void SetWRINKLEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRINKLEMAP = i; +#ifdef _DEBUG + m_bWRINKLEMAP = true; +#endif + } + void SetWRINKLEMAP( bool i ) + { + m_nWRINKLEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bWRINKLEMAP = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 6 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nRIMLIGHT; +#ifdef _DEBUG + bool m_bRIMLIGHT; +#endif +public: + void SetRIMLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nRIMLIGHT = i; +#ifdef _DEBUG + m_bRIMLIGHT = true; +#endif + } + void SetRIMLIGHT( bool i ) + { + m_nRIMLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bRIMLIGHT = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nFASTPATH_NOBUMP; +#ifdef _DEBUG + bool m_bFASTPATH_NOBUMP; +#endif +public: + void SetFASTPATH_NOBUMP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFASTPATH_NOBUMP = i; +#ifdef _DEBUG + m_bFASTPATH_NOBUMP = true; +#endif + } + void SetFASTPATH_NOBUMP( bool i ) + { + m_nFASTPATH_NOBUMP = i ? 1 : 0; +#ifdef _DEBUG + m_bFASTPATH_NOBUMP = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +private: + int m_nPHONG_HALFLAMBERT; +#ifdef _DEBUG + bool m_bPHONG_HALFLAMBERT; +#endif +public: + void SetPHONG_HALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPHONG_HALFLAMBERT = i; +#ifdef _DEBUG + m_bPHONG_HALFLAMBERT = true; +#endif + } + void SetPHONG_HALFLAMBERT( bool i ) + { + m_nPHONG_HALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bPHONG_HALFLAMBERT = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +public: + sdk_skin_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = false; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = false; +#endif // _DEBUG + m_nSELFILLUMFRESNEL = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; +#ifdef _DEBUG + m_bPHONGWARPTEXTURE = false; +#endif // _DEBUG + m_nPHONGWARPTEXTURE = 0; +#ifdef _DEBUG + m_bWRINKLEMAP = false; +#endif // _DEBUG + m_nWRINKLEMAP = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bRIMLIGHT = false; +#endif // _DEBUG + m_nRIMLIGHT = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bFASTPATH_NOBUMP = false; +#endif // _DEBUG + m_nFASTPATH_NOBUMP = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; +#ifdef _DEBUG + m_bPHONG_HALFLAMBERT = false; +#endif // _DEBUG + m_nPHONG_HALFLAMBERT = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bCUBEMAP && m_bSELFILLUM && m_bSELFILLUMFRESNEL && m_bFLASHLIGHT && m_bLIGHTWARPTEXTURE && m_bPHONGWARPTEXTURE && m_bWRINKLEMAP && m_bDETAIL_BLEND_MODE && m_bDETAILTEXTURE && m_bRIMLIGHT && m_bFLASHLIGHTDEPTHFILTERMODE && m_bFASTPATH_NOBUMP && m_bBLENDTINTBYBASEALPHA && m_bPHONG_HALFLAMBERT && m_bENVMAPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 80 * m_nCONVERT_TO_SRGB ) + ( 80 * m_nCUBEMAP ) + ( 160 * m_nSELFILLUM ) + ( 320 * m_nSELFILLUMFRESNEL ) + ( 640 * m_nFLASHLIGHT ) + ( 1280 * m_nLIGHTWARPTEXTURE ) + ( 2560 * m_nPHONGWARPTEXTURE ) + ( 5120 * m_nWRINKLEMAP ) + ( 10240 * m_nDETAIL_BLEND_MODE ) + ( 71680 * m_nDETAILTEXTURE ) + ( 143360 * m_nRIMLIGHT ) + ( 286720 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 860160 * m_nFASTPATH_NOBUMP ) + ( 1720320 * m_nBLENDTINTBYBASEALPHA ) + ( 3440640 * m_nPHONG_HALFLAMBERT ) + ( 6881280 * m_nENVMAPMASK ) + 0; + } +}; +#define shaderStaticTest_sdk_skin_ps30 psh_forgot_to_set_static_CONVERT_TO_SRGB + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_SELFILLUMFRESNEL + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_PHONGWARPTEXTURE + psh_forgot_to_set_static_WRINKLEMAP + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_RIMLIGHT + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_FASTPATH_NOBUMP + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_PHONG_HALFLAMBERT + psh_forgot_to_set_static_ENVMAPMASK + 0 +class sdk_skin_ps30_Dynamic_Index +{ +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_skin_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nNUM_LIGHTS ) + ( 20 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 40 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_skin_ps30 psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_skin_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_skin_vs20.inc new file mode 100644 index 00000000..22a29bf7 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_skin_vs20.inc @@ -0,0 +1,187 @@ +#include "shaderlib/cshader.h" +class sdk_skin_vs20_Static_Index +{ +private: + int m_nUSE_STATIC_CONTROL_FLOW; +#ifdef _DEBUG + bool m_bUSE_STATIC_CONTROL_FLOW; +#endif +public: + void SetUSE_STATIC_CONTROL_FLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_STATIC_CONTROL_FLOW = i; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } + void SetUSE_STATIC_CONTROL_FLOW( bool i ) + { + m_nUSE_STATIC_CONTROL_FLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } +public: + sdk_skin_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = false; +#endif // _DEBUG + m_nUSE_STATIC_CONTROL_FLOW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bUSE_STATIC_CONTROL_FLOW; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 48 * m_nUSE_STATIC_CONTROL_FLOW ) + 0; + } +}; +#define shaderStaticTest_sdk_skin_vs20 vsh_forgot_to_set_static_USE_STATIC_CONTROL_FLOW + 0 +class sdk_skin_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_skin_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nLIGHTING_PREVIEW ) + ( 16 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_skin_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_skin_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_skin_vs30.inc new file mode 100644 index 00000000..fb6a1125 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_skin_vs30.inc @@ -0,0 +1,187 @@ +#include "shaderlib/cshader.h" +class sdk_skin_vs30_Static_Index +{ +private: + int m_nDECAL; +#ifdef _DEBUG + bool m_bDECAL; +#endif +public: + void SetDECAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDECAL = i; +#ifdef _DEBUG + m_bDECAL = true; +#endif + } + void SetDECAL( bool i ) + { + m_nDECAL = i ? 1 : 0; +#ifdef _DEBUG + m_bDECAL = true; +#endif + } +public: + sdk_skin_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bDECAL = false; +#endif // _DEBUG + m_nDECAL = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDECAL; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 32 * m_nDECAL ) + 0; + } +}; +#define shaderStaticTest_sdk_skin_vs30 vsh_forgot_to_set_static_DECAL + 0 +class sdk_skin_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_skin_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nLIGHTING_PREVIEW ) + ( 16 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_skin_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_splinerope_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_splinerope_ps20.inc new file mode 100644 index 00000000..f43cdb2f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_splinerope_ps20.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_splinerope_ps20_Static_Index +{ +private: + int m_nSHADER_SRGB_READ; +#ifdef _DEBUG + bool m_bSHADER_SRGB_READ; +#endif +public: + void SetSHADER_SRGB_READ( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nSHADER_SRGB_READ = i; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = true; +#endif + } + void SetSHADER_SRGB_READ( bool i ) + { + m_nSHADER_SRGB_READ = i ? 1 : 0; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = true; +#endif + } +private: + int m_nSHADOWDEPTH; +#ifdef _DEBUG + bool m_bSHADOWDEPTH; +#endif +public: + void SetSHADOWDEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSHADOWDEPTH = i; +#ifdef _DEBUG + m_bSHADOWDEPTH = true; +#endif + } + void SetSHADOWDEPTH( bool i ) + { + m_nSHADOWDEPTH = i ? 1 : 0; +#ifdef _DEBUG + m_bSHADOWDEPTH = true; +#endif + } +public: + sdk_splinerope_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bSHADER_SRGB_READ = false; +#endif // _DEBUG + m_nSHADER_SRGB_READ = 0; +#ifdef _DEBUG + m_bSHADOWDEPTH = false; +#endif // _DEBUG + m_nSHADOWDEPTH = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bSHADER_SRGB_READ && m_bSHADOWDEPTH; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nSHADER_SRGB_READ ) + ( 2 * m_nSHADOWDEPTH ) + 0; + } +}; +#define shaderStaticTest_sdk_splinerope_ps20 psh_forgot_to_set_static_SHADER_SRGB_READ + psh_forgot_to_set_static_SHADOWDEPTH + 0 +class sdk_splinerope_ps20_Dynamic_Index +{ +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_splinerope_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITE_DEPTH_TO_DESTALPHA && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_splinerope_ps20 psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_splinerope_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_splinerope_ps20b.inc new file mode 100644 index 00000000..75ce64e9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_splinerope_ps20b.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_splinerope_ps20b_Static_Index +{ +private: + int m_nSHADER_SRGB_READ; +#ifdef _DEBUG + bool m_bSHADER_SRGB_READ; +#endif +public: + void SetSHADER_SRGB_READ( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nSHADER_SRGB_READ = i; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = true; +#endif + } + void SetSHADER_SRGB_READ( bool i ) + { + m_nSHADER_SRGB_READ = i ? 1 : 0; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = true; +#endif + } +private: + int m_nSHADOWDEPTH; +#ifdef _DEBUG + bool m_bSHADOWDEPTH; +#endif +public: + void SetSHADOWDEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSHADOWDEPTH = i; +#ifdef _DEBUG + m_bSHADOWDEPTH = true; +#endif + } + void SetSHADOWDEPTH( bool i ) + { + m_nSHADOWDEPTH = i ? 1 : 0; +#ifdef _DEBUG + m_bSHADOWDEPTH = true; +#endif + } +public: + sdk_splinerope_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bSHADER_SRGB_READ = false; +#endif // _DEBUG + m_nSHADER_SRGB_READ = 0; +#ifdef _DEBUG + m_bSHADOWDEPTH = false; +#endif // _DEBUG + m_nSHADOWDEPTH = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bSHADER_SRGB_READ && m_bSHADOWDEPTH; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nSHADER_SRGB_READ ) + ( 4 * m_nSHADOWDEPTH ) + 0; + } +}; +#define shaderStaticTest_sdk_splinerope_ps20b psh_forgot_to_set_static_SHADER_SRGB_READ + psh_forgot_to_set_static_SHADOWDEPTH + 0 +class sdk_splinerope_ps20b_Dynamic_Index +{ +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_splinerope_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITE_DEPTH_TO_DESTALPHA && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_splinerope_ps20b psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_splinerope_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_splinerope_ps30.inc new file mode 100644 index 00000000..6427d06f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_splinerope_ps30.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_splinerope_ps30_Static_Index +{ +private: + int m_nSHADER_SRGB_READ; +#ifdef _DEBUG + bool m_bSHADER_SRGB_READ; +#endif +public: + void SetSHADER_SRGB_READ( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nSHADER_SRGB_READ = i; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = true; +#endif + } + void SetSHADER_SRGB_READ( bool i ) + { + m_nSHADER_SRGB_READ = i ? 1 : 0; +#ifdef _DEBUG + m_bSHADER_SRGB_READ = true; +#endif + } +private: + int m_nSHADOWDEPTH; +#ifdef _DEBUG + bool m_bSHADOWDEPTH; +#endif +public: + void SetSHADOWDEPTH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSHADOWDEPTH = i; +#ifdef _DEBUG + m_bSHADOWDEPTH = true; +#endif + } + void SetSHADOWDEPTH( bool i ) + { + m_nSHADOWDEPTH = i ? 1 : 0; +#ifdef _DEBUG + m_bSHADOWDEPTH = true; +#endif + } +public: + sdk_splinerope_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bSHADER_SRGB_READ = false; +#endif // _DEBUG + m_nSHADER_SRGB_READ = 0; +#ifdef _DEBUG + m_bSHADOWDEPTH = false; +#endif // _DEBUG + m_nSHADOWDEPTH = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bSHADER_SRGB_READ && m_bSHADOWDEPTH; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nSHADER_SRGB_READ ) + ( 2 * m_nSHADOWDEPTH ) + 0; + } +}; +#define shaderStaticTest_sdk_splinerope_ps30 psh_forgot_to_set_static_SHADER_SRGB_READ + psh_forgot_to_set_static_SHADOWDEPTH + 0 +class sdk_splinerope_ps30_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_splinerope_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_splinerope_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_splinerope_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_splinerope_vs20.inc new file mode 100644 index 00000000..ba584299 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_splinerope_vs20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_splinerope_vs20_Static_Index +{ +public: + sdk_splinerope_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_splinerope_vs20 0 +class sdk_splinerope_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_splinerope_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_splinerope_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_splinerope_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_splinerope_vs30.inc new file mode 100644 index 00000000..97c31b1b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_splinerope_vs30.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_splinerope_vs30_Static_Index +{ +public: + sdk_splinerope_vs30_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_splinerope_vs30 0 +class sdk_splinerope_vs30_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_splinerope_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_splinerope_vs30 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_sprite_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_sprite_ps20.inc new file mode 100644 index 00000000..ac161fb8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_sprite_ps20.inc @@ -0,0 +1,187 @@ +#include "shaderlib/cshader.h" +class sdk_sprite_ps20_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nCONSTANTCOLOR; +#ifdef _DEBUG + bool m_bCONSTANTCOLOR; +#endif +public: + void SetCONSTANTCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONSTANTCOLOR = i; +#ifdef _DEBUG + m_bCONSTANTCOLOR = true; +#endif + } + void SetCONSTANTCOLOR( bool i ) + { + m_nCONSTANTCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bCONSTANTCOLOR = true; +#endif + } +private: + int m_nHDRTYPE; +#ifdef _DEBUG + bool m_bHDRTYPE; +#endif +public: + void SetHDRTYPE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nHDRTYPE = i; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } + void SetHDRTYPE( bool i ) + { + m_nHDRTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } +private: + int m_nSRGB; +#ifdef _DEBUG + bool m_bSRGB; +#endif +public: + void SetSRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSRGB = i; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } + void SetSRGB( bool i ) + { + m_nSRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } +public: + sdk_sprite_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bCONSTANTCOLOR = false; +#endif // _DEBUG + m_nCONSTANTCOLOR = 0; +#ifdef _DEBUG + m_bHDRTYPE = false; +#endif // _DEBUG + m_nHDRTYPE = 0; +#ifdef _DEBUG + m_bSRGB = false; +#endif // _DEBUG + m_nSRGB = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bCONSTANTCOLOR && m_bHDRTYPE && m_bSRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nVERTEXCOLOR ) + ( 8 * m_nCONSTANTCOLOR ) + ( 16 * m_nHDRTYPE ) + ( 48 * m_nSRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_sprite_ps20 psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_CONSTANTCOLOR + psh_forgot_to_set_static_HDRTYPE + psh_forgot_to_set_static_SRGB + 0 +class sdk_sprite_ps20_Dynamic_Index +{ +private: + int m_nHDRENABLED; +#ifdef _DEBUG + bool m_bHDRENABLED; +#endif +public: + void SetHDRENABLED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHDRENABLED = i; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } + void SetHDRENABLED( bool i ) + { + m_nHDRENABLED = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_sprite_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bHDRENABLED = false; +#endif // _DEBUG + m_nHDRENABLED = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bHDRENABLED && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nHDRENABLED ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_sprite_ps20 psh_forgot_to_set_dynamic_HDRENABLED + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_sprite_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_sprite_ps20b.inc new file mode 100644 index 00000000..35d69c88 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_sprite_ps20b.inc @@ -0,0 +1,237 @@ +#include "shaderlib/cshader.h" +class sdk_sprite_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nCONSTANTCOLOR; +#ifdef _DEBUG + bool m_bCONSTANTCOLOR; +#endif +public: + void SetCONSTANTCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONSTANTCOLOR = i; +#ifdef _DEBUG + m_bCONSTANTCOLOR = true; +#endif + } + void SetCONSTANTCOLOR( bool i ) + { + m_nCONSTANTCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bCONSTANTCOLOR = true; +#endif + } +private: + int m_nHDRTYPE; +#ifdef _DEBUG + bool m_bHDRTYPE; +#endif +public: + void SetHDRTYPE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nHDRTYPE = i; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } + void SetHDRTYPE( bool i ) + { + m_nHDRTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRTYPE = true; +#endif + } +private: + int m_nSRGB; +#ifdef _DEBUG + bool m_bSRGB; +#endif +public: + void SetSRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSRGB = i; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } + void SetSRGB( bool i ) + { + m_nSRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } +private: + int m_nSRGB_OUTPUT_ADAPTER; +#ifdef _DEBUG + bool m_bSRGB_OUTPUT_ADAPTER; +#endif +public: + void SetSRGB_OUTPUT_ADAPTER( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSRGB_OUTPUT_ADAPTER = i; +#ifdef _DEBUG + m_bSRGB_OUTPUT_ADAPTER = true; +#endif + } + void SetSRGB_OUTPUT_ADAPTER( bool i ) + { + m_nSRGB_OUTPUT_ADAPTER = i ? 1 : 0; +#ifdef _DEBUG + m_bSRGB_OUTPUT_ADAPTER = true; +#endif + } +public: + sdk_sprite_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bCONSTANTCOLOR = false; +#endif // _DEBUG + m_nCONSTANTCOLOR = 0; +#ifdef _DEBUG + m_bHDRTYPE = false; +#endif // _DEBUG + m_nHDRTYPE = 0; +#ifdef _DEBUG + m_bSRGB = false; +#endif // _DEBUG + m_nSRGB = 0; +#ifdef _DEBUG + m_bSRGB_OUTPUT_ADAPTER = false; +#endif // _DEBUG + m_nSRGB_OUTPUT_ADAPTER = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bVERTEXCOLOR && m_bCONSTANTCOLOR && m_bHDRTYPE && m_bSRGB && m_bSRGB_OUTPUT_ADAPTER; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nVERTEXCOLOR ) + ( 16 * m_nCONSTANTCOLOR ) + ( 32 * m_nHDRTYPE ) + ( 96 * m_nSRGB ) + ( 192 * m_nSRGB_OUTPUT_ADAPTER ) + 0; + } +}; +#define shaderStaticTest_sdk_sprite_ps20b psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_CONSTANTCOLOR + psh_forgot_to_set_static_HDRTYPE + psh_forgot_to_set_static_SRGB + psh_forgot_to_set_static_SRGB_OUTPUT_ADAPTER + 0 +class sdk_sprite_ps20b_Dynamic_Index +{ +private: + int m_nHDRENABLED; +#ifdef _DEBUG + bool m_bHDRENABLED; +#endif +public: + void SetHDRENABLED( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHDRENABLED = i; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } + void SetHDRENABLED( bool i ) + { + m_nHDRENABLED = i ? 1 : 0; +#ifdef _DEBUG + m_bHDRENABLED = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_sprite_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bHDRENABLED = false; +#endif // _DEBUG + m_nHDRENABLED = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bHDRENABLED && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nHDRENABLED ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_sprite_ps20b psh_forgot_to_set_dynamic_HDRENABLED + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_sprite_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_sprite_vs20.inc new file mode 100644 index 00000000..25ac196d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_sprite_vs20.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_sprite_vs20_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nSRGB; +#ifdef _DEBUG + bool m_bSRGB; +#endif +public: + void SetSRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSRGB = i; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } + void SetSRGB( bool i ) + { + m_nSRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bSRGB = true; +#endif + } +public: + sdk_sprite_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bSRGB = false; +#endif // _DEBUG + m_nSRGB = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bSRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nVERTEXCOLOR ) + ( 4 * m_nSRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_sprite_vs20 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_SRGB + 0 +class sdk_sprite_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_sprite_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_sprite_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_bump_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_bump_ps20.inc new file mode 100644 index 00000000..bd2b6155 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_bump_ps20.inc @@ -0,0 +1,110 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_bump_ps20_Static_Index +{ +public: + sdk_teeth_bump_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_teeth_bump_ps20 0 +class sdk_teeth_bump_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +public: + sdk_teeth_bump_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bAMBIENT_LIGHT; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nNUM_LIGHTS ) + ( 6 * m_nAMBIENT_LIGHT ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_bump_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_bump_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_bump_ps20b.inc new file mode 100644 index 00000000..8d774cf4 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_bump_ps20b.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_bump_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_teeth_bump_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 40 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_bump_ps20b 0 +class sdk_teeth_bump_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_teeth_bump_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bAMBIENT_LIGHT && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nNUM_LIGHTS ) + ( 10 * m_nAMBIENT_LIGHT ) + ( 20 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_bump_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_bump_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_bump_ps30.inc new file mode 100644 index 00000000..b3ae4c8f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_bump_ps30.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_bump_ps30_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_teeth_bump_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 40 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_bump_ps30 0 +class sdk_teeth_bump_ps30_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_teeth_bump_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bAMBIENT_LIGHT && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nNUM_LIGHTS ) + ( 10 * m_nAMBIENT_LIGHT ) + ( 20 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_bump_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_bump_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_bump_vs20.inc new file mode 100644 index 00000000..95700dc2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_bump_vs20.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_bump_vs20_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +private: + int m_nUSE_STATIC_CONTROL_FLOW; +#ifdef _DEBUG + bool m_bUSE_STATIC_CONTROL_FLOW; +#endif +public: + void SetUSE_STATIC_CONTROL_FLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_STATIC_CONTROL_FLOW = i; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } + void SetUSE_STATIC_CONTROL_FLOW( bool i ) + { + m_nUSE_STATIC_CONTROL_FLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } +public: + sdk_teeth_bump_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = false; +#endif // _DEBUG + m_nUSE_STATIC_CONTROL_FLOW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO && m_bUSE_STATIC_CONTROL_FLOW; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 48 * m_nINTRO ) + ( 96 * m_nUSE_STATIC_CONTROL_FLOW ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_bump_vs20 vsh_forgot_to_set_static_INTRO + vsh_forgot_to_set_static_USE_STATIC_CONTROL_FLOW + 0 +class sdk_teeth_bump_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_teeth_bump_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bSTATIC_LIGHT && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nSTATIC_LIGHT ) + ( 16 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_bump_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_bump_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_bump_vs30.inc new file mode 100644 index 00000000..61d78dbe --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_bump_vs30.inc @@ -0,0 +1,187 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_bump_vs30_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +public: + sdk_teeth_bump_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 32 * m_nINTRO ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_bump_vs30 vsh_forgot_to_set_static_INTRO + 0 +class sdk_teeth_bump_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_teeth_bump_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bSTATIC_LIGHT && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nSTATIC_LIGHT ) + ( 16 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_bump_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_flashlight_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_flashlight_ps20.inc new file mode 100644 index 00000000..773cf54a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_flashlight_ps20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_flashlight_ps20_Static_Index +{ +public: + sdk_teeth_flashlight_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_teeth_flashlight_ps20 0 +class sdk_teeth_flashlight_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_teeth_flashlight_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_flashlight_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_flashlight_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_flashlight_ps20b.inc new file mode 100644 index 00000000..209eb19f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_flashlight_ps20b.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_flashlight_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_teeth_flashlight_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_flashlight_ps20b psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_teeth_flashlight_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_teeth_flashlight_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_flashlight_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_flashlight_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_flashlight_ps30.inc new file mode 100644 index 00000000..3e08d8f2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_flashlight_ps30.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_flashlight_ps30_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_teeth_flashlight_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + ( 8 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_flashlight_ps30 psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_teeth_flashlight_ps30_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_teeth_flashlight_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_flashlight_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_flashlight_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_flashlight_vs20.inc new file mode 100644 index 00000000..b3728827 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_flashlight_vs20.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_flashlight_vs20_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +public: + sdk_teeth_flashlight_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 8 * m_nINTRO ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_flashlight_vs20 vsh_forgot_to_set_static_INTRO + 0 +class sdk_teeth_flashlight_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_teeth_flashlight_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_flashlight_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_flashlight_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_flashlight_vs30.inc new file mode 100644 index 00000000..e69d95bf --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_flashlight_vs30.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_flashlight_vs30_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +public: + sdk_teeth_flashlight_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 16 * m_nINTRO ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_flashlight_vs30 vsh_forgot_to_set_static_INTRO + 0 +class sdk_teeth_flashlight_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_teeth_flashlight_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_flashlight_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_ps20.inc new file mode 100644 index 00000000..b7eae9b2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_ps20.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_ps20_Static_Index +{ +public: + sdk_teeth_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_teeth_ps20 0 +class sdk_teeth_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_teeth_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_ps20b.inc new file mode 100644 index 00000000..1fcf1c6b --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_ps20b.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_teeth_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_ps20b 0 +class sdk_teeth_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_teeth_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_ps30.inc new file mode 100644 index 00000000..d2cc52f3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_ps30.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_ps30_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_teeth_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_ps30 0 +class sdk_teeth_ps30_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_teeth_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_ps30 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_vs20.inc new file mode 100644 index 00000000..18cc3990 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_vs20.inc @@ -0,0 +1,237 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_vs20_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +private: + int m_nUSE_STATIC_CONTROL_FLOW; +#ifdef _DEBUG + bool m_bUSE_STATIC_CONTROL_FLOW; +#endif +public: + void SetUSE_STATIC_CONTROL_FLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_STATIC_CONTROL_FLOW = i; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } + void SetUSE_STATIC_CONTROL_FLOW( bool i ) + { + m_nUSE_STATIC_CONTROL_FLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } +public: + sdk_teeth_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = false; +#endif // _DEBUG + m_nUSE_STATIC_CONTROL_FLOW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO && m_bUSE_STATIC_CONTROL_FLOW; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 96 * m_nINTRO ) + ( 192 * m_nUSE_STATIC_CONTROL_FLOW ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_vs20 vsh_forgot_to_set_static_INTRO + vsh_forgot_to_set_static_USE_STATIC_CONTROL_FLOW + 0 +class sdk_teeth_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_teeth_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nDYNAMIC_LIGHT ) + ( 16 * m_nSTATIC_LIGHT ) + ( 32 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_vs30.inc new file mode 100644 index 00000000..985f57e8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_teeth_vs30.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_teeth_vs30_Static_Index +{ +private: + int m_nINTRO; +#ifdef _DEBUG + bool m_bINTRO; +#endif +public: + void SetINTRO( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nINTRO = i; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } + void SetINTRO( bool i ) + { + m_nINTRO = i ? 1 : 0; +#ifdef _DEBUG + m_bINTRO = true; +#endif + } +public: + sdk_teeth_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bINTRO = false; +#endif // _DEBUG + m_nINTRO = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bINTRO; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 64 * m_nINTRO ) + 0; + } +}; +#define shaderStaticTest_sdk_teeth_vs30 vsh_forgot_to_set_static_INTRO + 0 +class sdk_teeth_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_teeth_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nDYNAMIC_LIGHT ) + ( 16 * m_nSTATIC_LIGHT ) + ( 32 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_teeth_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlitgeneric_ps11.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlitgeneric_ps11.inc new file mode 100644 index 00000000..30c5c529 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlitgeneric_ps11.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_unlitgeneric_ps11_Static_Index +{ +public: + sdk_unlitgeneric_ps11_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_unlitgeneric_ps11 0 +class sdk_unlitgeneric_ps11_Dynamic_Index +{ +public: + sdk_unlitgeneric_ps11_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_unlitgeneric_ps11 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlitgeneric_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlitgeneric_ps20.inc new file mode 100644 index 00000000..96088dec --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlitgeneric_ps20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_unlitgeneric_ps20_Static_Index +{ +public: + sdk_unlitgeneric_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_unlitgeneric_ps20 0 +class sdk_unlitgeneric_ps20_Dynamic_Index +{ +public: + sdk_unlitgeneric_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_unlitgeneric_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlitgeneric_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlitgeneric_ps20b.inc new file mode 100644 index 00000000..5f0347a2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlitgeneric_ps20b.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class sdk_unlitgeneric_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +public: + sdk_unlitgeneric_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCONVERT_TO_SRGB ) + 0; + } +}; +#define shaderStaticTest_sdk_unlitgeneric_ps20b 0 +class sdk_unlitgeneric_ps20b_Dynamic_Index +{ +public: + sdk_unlitgeneric_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_unlitgeneric_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlitgeneric_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlitgeneric_vs20.inc new file mode 100644 index 00000000..ea58edbc --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlitgeneric_vs20.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_unlitgeneric_vs20_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +public: + sdk_unlitgeneric_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 8 * m_nVERTEXCOLOR ) + 0; + } +}; +#define shaderStaticTest_sdk_unlitgeneric_vs20 vsh_forgot_to_set_static_VERTEXCOLOR + 0 +class sdk_unlitgeneric_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_unlitgeneric_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_unlitgeneric_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_ps20.inc new file mode 100644 index 00000000..47ecb668 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_ps20.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_unlittwotexture_ps20_Static_Index +{ +private: + int m_nTRANSLUCENT; +#ifdef _DEBUG + bool m_bTRANSLUCENT; +#endif +public: + void SetTRANSLUCENT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTRANSLUCENT = i; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } + void SetTRANSLUCENT( bool i ) + { + m_nTRANSLUCENT = i ? 1 : 0; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } +public: + sdk_unlittwotexture_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bTRANSLUCENT = false; +#endif // _DEBUG + m_nTRANSLUCENT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTRANSLUCENT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nTRANSLUCENT ) + 0; + } +}; +#define shaderStaticTest_sdk_unlittwotexture_ps20 psh_forgot_to_set_static_TRANSLUCENT + 0 +class sdk_unlittwotexture_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_unlittwotexture_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_unlittwotexture_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_ps20b.inc new file mode 100644 index 00000000..52b755c8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_ps20b.inc @@ -0,0 +1,112 @@ +#include "shaderlib/cshader.h" +class sdk_unlittwotexture_ps20b_Static_Index +{ +private: + int m_nTRANSLUCENT; +#ifdef _DEBUG + bool m_bTRANSLUCENT; +#endif +public: + void SetTRANSLUCENT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTRANSLUCENT = i; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } + void SetTRANSLUCENT( bool i ) + { + m_nTRANSLUCENT = i ? 1 : 0; +#ifdef _DEBUG + m_bTRANSLUCENT = true; +#endif + } +public: + sdk_unlittwotexture_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bTRANSLUCENT = false; +#endif // _DEBUG + m_nTRANSLUCENT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTRANSLUCENT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nTRANSLUCENT ) + 0; + } +}; +#define shaderStaticTest_sdk_unlittwotexture_ps20b psh_forgot_to_set_static_TRANSLUCENT + 0 +class sdk_unlittwotexture_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +public: + sdk_unlittwotexture_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITE_DEPTH_TO_DESTALPHA ) + 0; + } +}; +#define shaderDynamicTest_sdk_unlittwotexture_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_vs20.inc new file mode 100644 index 00000000..a9757e65 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_unlittwotexture_vs20.inc @@ -0,0 +1,110 @@ +#include "shaderlib/cshader.h" +class sdk_unlittwotexture_vs20_Static_Index +{ +public: + sdk_unlittwotexture_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_unlittwotexture_vs20 0 +class sdk_unlittwotexture_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_unlittwotexture_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + 0; + } +}; +#define shaderDynamicTest_sdk_unlittwotexture_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_bump_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_bump_ps20.inc new file mode 100644 index 00000000..b6cbcf56 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_bump_ps20.inc @@ -0,0 +1,437 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_bump_ps20_Static_Index +{ +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nSELFILLUMFRESNEL; +#ifdef _DEBUG + bool m_bSELFILLUMFRESNEL; +#endif +public: + void SetSELFILLUMFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUMFRESNEL = i; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } + void SetSELFILLUMFRESNEL( bool i ) + { + m_nSELFILLUMFRESNEL = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } +private: + int m_nNORMALMAPALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bNORMALMAPALPHAENVMAPMASK; +#endif +public: + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } + void SetNORMALMAPALPHAENVMAPMASK( bool i ) + { + m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 6 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = false; +#endif // _DEBUG + m_nSELFILLUMFRESNEL = 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nNORMALMAPALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bLIGHTWARPTEXTURE && m_bSELFILLUM && m_bSELFILLUMFRESNEL && m_bNORMALMAPALPHAENVMAPMASK && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bBLENDTINTBYBASEALPHA && m_bENVMAPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 24 * m_nCUBEMAP ) + ( 48 * m_nDIFFUSELIGHTING ) + ( 96 * m_nLIGHTWARPTEXTURE ) + ( 192 * m_nSELFILLUM ) + ( 384 * m_nSELFILLUMFRESNEL ) + ( 768 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 1536 * m_nHALFLAMBERT ) + ( 3072 * m_nFLASHLIGHT ) + ( 6144 * m_nDETAILTEXTURE ) + ( 12288 * m_nDETAIL_BLEND_MODE ) + ( 86016 * m_nBLENDTINTBYBASEALPHA ) + ( 172032 * m_nENVMAPMASK ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_bump_ps20 psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_SELFILLUMFRESNEL + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_HALFLAMBERT + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_ENVMAPMASK + 0 +class sdk_vertexlit_and_unlit_generic_bump_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bWRITEWATERFOGTODESTALPHA && m_bNUM_LIGHTS && m_bAMBIENT_LIGHT; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nWRITEWATERFOGTODESTALPHA ) + ( 4 * m_nNUM_LIGHTS ) + ( 12 * m_nAMBIENT_LIGHT ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_bump_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_bump_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_bump_ps20b.inc new file mode 100644 index 00000000..7c81e32f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_bump_ps20b.inc @@ -0,0 +1,437 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_bump_ps20b_Static_Index +{ +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nSELFILLUMFRESNEL; +#ifdef _DEBUG + bool m_bSELFILLUMFRESNEL; +#endif +public: + void SetSELFILLUMFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUMFRESNEL = i; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } + void SetSELFILLUMFRESNEL( bool i ) + { + m_nSELFILLUMFRESNEL = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } +private: + int m_nNORMALMAPALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bNORMALMAPALPHAENVMAPMASK; +#endif +public: + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } + void SetNORMALMAPALPHAENVMAPMASK( bool i ) + { + m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 6 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = false; +#endif // _DEBUG + m_nSELFILLUMFRESNEL = 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nNORMALMAPALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bLIGHTWARPTEXTURE && m_bSELFILLUM && m_bSELFILLUMFRESNEL && m_bNORMALMAPALPHAENVMAPMASK && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bFLASHLIGHTDEPTHFILTERMODE && m_bBLENDTINTBYBASEALPHA && m_bENVMAPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 20 * m_nCUBEMAP ) + ( 40 * m_nDIFFUSELIGHTING ) + ( 80 * m_nLIGHTWARPTEXTURE ) + ( 160 * m_nSELFILLUM ) + ( 320 * m_nSELFILLUMFRESNEL ) + ( 640 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 1280 * m_nHALFLAMBERT ) + ( 2560 * m_nFLASHLIGHT ) + ( 5120 * m_nDETAILTEXTURE ) + ( 10240 * m_nDETAIL_BLEND_MODE ) + ( 71680 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 215040 * m_nBLENDTINTBYBASEALPHA ) + ( 430080 * m_nENVMAPMASK ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_bump_ps20b psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_SELFILLUMFRESNEL + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_HALFLAMBERT + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_ENVMAPMASK + 0 +class sdk_vertexlit_and_unlit_generic_bump_ps20b_Dynamic_Index +{ +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bNUM_LIGHTS && m_bAMBIENT_LIGHT && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nNUM_LIGHTS ) + ( 5 * m_nAMBIENT_LIGHT ) + ( 10 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_bump_ps20b psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_bump_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_bump_ps30.inc new file mode 100644 index 00000000..1cb70971 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_bump_ps30.inc @@ -0,0 +1,437 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_bump_ps30_Static_Index +{ +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nLIGHTWARPTEXTURE; +#ifdef _DEBUG + bool m_bLIGHTWARPTEXTURE; +#endif +public: + void SetLIGHTWARPTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTWARPTEXTURE = i; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } + void SetLIGHTWARPTEXTURE( bool i ) + { + m_nLIGHTWARPTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nSELFILLUMFRESNEL; +#ifdef _DEBUG + bool m_bSELFILLUMFRESNEL; +#endif +public: + void SetSELFILLUMFRESNEL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUMFRESNEL = i; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } + void SetSELFILLUMFRESNEL( bool i ) + { + m_nSELFILLUMFRESNEL = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = true; +#endif + } +private: + int m_nNORMALMAPALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bNORMALMAPALPHAENVMAPMASK; +#endif +public: + void SetNORMALMAPALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNORMALMAPALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } + void SetNORMALMAPALPHAENVMAPMASK( bool i ) + { + m_nNORMALMAPALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 6 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bLIGHTWARPTEXTURE = false; +#endif // _DEBUG + m_nLIGHTWARPTEXTURE = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bSELFILLUMFRESNEL = false; +#endif // _DEBUG + m_nSELFILLUMFRESNEL = 0; +#ifdef _DEBUG + m_bNORMALMAPALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nNORMALMAPALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bLIGHTWARPTEXTURE && m_bSELFILLUM && m_bSELFILLUMFRESNEL && m_bNORMALMAPALPHAENVMAPMASK && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bDETAILTEXTURE && m_bDETAIL_BLEND_MODE && m_bFLASHLIGHTDEPTHFILTERMODE && m_bBLENDTINTBYBASEALPHA && m_bENVMAPMASK; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 20 * m_nCUBEMAP ) + ( 40 * m_nDIFFUSELIGHTING ) + ( 80 * m_nLIGHTWARPTEXTURE ) + ( 160 * m_nSELFILLUM ) + ( 320 * m_nSELFILLUMFRESNEL ) + ( 640 * m_nNORMALMAPALPHAENVMAPMASK ) + ( 1280 * m_nHALFLAMBERT ) + ( 2560 * m_nFLASHLIGHT ) + ( 5120 * m_nDETAILTEXTURE ) + ( 10240 * m_nDETAIL_BLEND_MODE ) + ( 71680 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 215040 * m_nBLENDTINTBYBASEALPHA ) + ( 430080 * m_nENVMAPMASK ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_bump_ps30 psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_LIGHTWARPTEXTURE + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_SELFILLUMFRESNEL + psh_forgot_to_set_static_NORMALMAPALPHAENVMAPMASK + psh_forgot_to_set_static_HALFLAMBERT + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_ENVMAPMASK + 0 +class sdk_vertexlit_and_unlit_generic_bump_ps30_Dynamic_Index +{ +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bNUM_LIGHTS && m_bAMBIENT_LIGHT && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nNUM_LIGHTS ) + ( 5 * m_nAMBIENT_LIGHT ) + ( 10 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_bump_ps30 psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_bump_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_bump_vs20.inc new file mode 100644 index 00000000..7c9fe088 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_bump_vs20.inc @@ -0,0 +1,212 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_bump_vs20_Static_Index +{ +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nUSE_WITH_2B; +#ifdef _DEBUG + bool m_bUSE_WITH_2B; +#endif +public: + void SetUSE_WITH_2B( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_WITH_2B = i; +#ifdef _DEBUG + m_bUSE_WITH_2B = true; +#endif + } + void SetUSE_WITH_2B( bool i ) + { + m_nUSE_WITH_2B = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_WITH_2B = true; +#endif + } +private: + int m_nUSE_STATIC_CONTROL_FLOW; +#ifdef _DEBUG + bool m_bUSE_STATIC_CONTROL_FLOW; +#endif +public: + void SetUSE_STATIC_CONTROL_FLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_STATIC_CONTROL_FLOW = i; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } + void SetUSE_STATIC_CONTROL_FLOW( bool i ) + { + m_nUSE_STATIC_CONTROL_FLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bUSE_WITH_2B = false; +#endif // _DEBUG + m_nUSE_WITH_2B = 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = false; +#endif // _DEBUG + m_nUSE_STATIC_CONTROL_FLOW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bHALFLAMBERT && m_bUSE_WITH_2B && m_bUSE_STATIC_CONTROL_FLOW; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 24 * m_nHALFLAMBERT ) + ( 48 * m_nUSE_WITH_2B ) + ( 96 * m_nUSE_STATIC_CONTROL_FLOW ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_bump_vs20 vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_USE_WITH_2B + vsh_forgot_to_set_static_USE_STATIC_CONTROL_FLOW + 0 +class sdk_vertexlit_and_unlit_generic_bump_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_bump_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_bump_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_bump_vs30.inc new file mode 100644 index 00000000..06841a47 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_bump_vs30.inc @@ -0,0 +1,237 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_bump_vs30_Static_Index +{ +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nUSE_WITH_2B; +#ifdef _DEBUG + bool m_bUSE_WITH_2B; +#endif +public: + void SetUSE_WITH_2B( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_WITH_2B = i; +#ifdef _DEBUG + m_bUSE_WITH_2B = true; +#endif + } + void SetUSE_WITH_2B( bool i ) + { + m_nUSE_WITH_2B = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_WITH_2B = true; +#endif + } +private: + int m_nDECAL; +#ifdef _DEBUG + bool m_bDECAL; +#endif +public: + void SetDECAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDECAL = i; +#ifdef _DEBUG + m_bDECAL = true; +#endif + } + void SetDECAL( bool i ) + { + m_nDECAL = i ? 1 : 0; +#ifdef _DEBUG + m_bDECAL = true; +#endif + } +private: + int m_nSM30_VERTEXID; +#ifdef _DEBUG + bool m_bSM30_VERTEXID; +#endif +public: + void SetSM30_VERTEXID( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSM30_VERTEXID = i; +#ifdef _DEBUG + m_bSM30_VERTEXID = true; +#endif + } + void SetSM30_VERTEXID( bool i ) + { + m_nSM30_VERTEXID = i ? 1 : 0; +#ifdef _DEBUG + m_bSM30_VERTEXID = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bUSE_WITH_2B = false; +#endif // _DEBUG + m_nUSE_WITH_2B = 0; +#ifdef _DEBUG + m_bDECAL = false; +#endif // _DEBUG + m_nDECAL = 0; +#ifdef _DEBUG + m_bSM30_VERTEXID = false; +#endif // _DEBUG + m_nSM30_VERTEXID = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bHALFLAMBERT && m_bUSE_WITH_2B && m_bDECAL && m_bSM30_VERTEXID; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 16 * m_nHALFLAMBERT ) + ( 32 * m_nUSE_WITH_2B ) + ( 64 * m_nDECAL ) + ( 128 * m_nSM30_VERTEXID ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_bump_vs30 vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_USE_WITH_2B + vsh_forgot_to_set_static_DECAL + vsh_forgot_to_set_static_SM30_VERTEXID + 0 +class sdk_vertexlit_and_unlit_generic_bump_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_bump_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_bump_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_ps20.inc new file mode 100644 index 00000000..0bf098cd --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_ps20.inc @@ -0,0 +1,562 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_ps20_Static_Index +{ +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nSELFILLUM_ENVMAPMASK_ALPHA; +#ifdef _DEBUG + bool m_bSELFILLUM_ENVMAPMASK_ALPHA; +#endif +public: + void SetSELFILLUM_ENVMAPMASK_ALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM_ENVMAPMASK_ALPHA = i; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = true; +#endif + } + void SetSELFILLUM_ENVMAPMASK_ALPHA( bool i ) + { + m_nSELFILLUM_ENVMAPMASK_ALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 9 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nSEAMLESS_BASE; +#ifdef _DEBUG + bool m_bSEAMLESS_BASE; +#endif +public: + void SetSEAMLESS_BASE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_BASE = i; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } + void SetSEAMLESS_BASE( bool i ) + { + m_nSEAMLESS_BASE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } +private: + int m_nSEAMLESS_DETAIL; +#ifdef _DEBUG + bool m_bSEAMLESS_DETAIL; +#endif +public: + void SetSEAMLESS_DETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_DETAIL = i; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } + void SetSEAMLESS_DETAIL( bool i ) + { + m_nSEAMLESS_DETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } +private: + int m_nDISTANCEALPHA; +#ifdef _DEBUG + bool m_bDISTANCEALPHA; +#endif +public: + void SetDISTANCEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHA = i; +#ifdef _DEBUG + m_bDISTANCEALPHA = true; +#endif + } + void SetDISTANCEALPHA( bool i ) + { + m_nDISTANCEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bDISTANCEALPHA = true; +#endif + } +private: + int m_nDISTANCEALPHAFROMDETAIL; +#ifdef _DEBUG + bool m_bDISTANCEALPHAFROMDETAIL; +#endif +public: + void SetDISTANCEALPHAFROMDETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHAFROMDETAIL = i; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = true; +#endif + } + void SetDISTANCEALPHAFROMDETAIL( bool i ) + { + m_nDISTANCEALPHAFROMDETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = true; +#endif + } +private: + int m_nSOFT_MASK; +#ifdef _DEBUG + bool m_bSOFT_MASK; +#endif +public: + void SetSOFT_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSOFT_MASK = i; +#ifdef _DEBUG + m_bSOFT_MASK = true; +#endif + } + void SetSOFT_MASK( bool i ) + { + m_nSOFT_MASK = i ? 1 : 0; +#ifdef _DEBUG + m_bSOFT_MASK = true; +#endif + } +private: + int m_nOUTLINE; +#ifdef _DEBUG + bool m_bOUTLINE; +#endif +public: + void SetOUTLINE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTLINE = i; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } + void SetOUTLINE( bool i ) + { + m_nOUTLINE = i ? 1 : 0; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } +private: + int m_nOUTER_GLOW; +#ifdef _DEBUG + bool m_bOUTER_GLOW; +#endif +public: + void SetOUTER_GLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTER_GLOW = i; +#ifdef _DEBUG + m_bOUTER_GLOW = true; +#endif + } + void SetOUTER_GLOW( bool i ) + { + m_nOUTER_GLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bOUTER_GLOW = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +private: + int m_nCUBEMAP_SPHERE_LEGACY; +#ifdef _DEBUG + bool m_bCUBEMAP_SPHERE_LEGACY; +#endif +public: + void SetCUBEMAP_SPHERE_LEGACY( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP_SPHERE_LEGACY = i; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = true; +#endif + } + void SetCUBEMAP_SPHERE_LEGACY( bool i ) + { + m_nCUBEMAP_SPHERE_LEGACY = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = false; +#endif // _DEBUG + m_nSELFILLUM_ENVMAPMASK_ALPHA = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = false; +#endif // _DEBUG + m_nSEAMLESS_BASE = 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = false; +#endif // _DEBUG + m_nSEAMLESS_DETAIL = 0; +#ifdef _DEBUG + m_bDISTANCEALPHA = false; +#endif // _DEBUG + m_nDISTANCEALPHA = 0; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = false; +#endif // _DEBUG + m_nDISTANCEALPHAFROMDETAIL = 0; +#ifdef _DEBUG + m_bSOFT_MASK = false; +#endif // _DEBUG + m_nSOFT_MASK = 0; +#ifdef _DEBUG + m_bOUTLINE = false; +#endif // _DEBUG + m_nOUTLINE = 0; +#ifdef _DEBUG + m_bOUTER_GLOW = false; +#endif // _DEBUG + m_nOUTER_GLOW = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = false; +#endif // _DEBUG + m_nCUBEMAP_SPHERE_LEGACY = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDETAILTEXTURE && m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bVERTEXCOLOR && m_bFLASHLIGHT && m_bSELFILLUM_ENVMAPMASK_ALPHA && m_bDETAIL_BLEND_MODE && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bDISTANCEALPHA && m_bDISTANCEALPHAFROMDETAIL && m_bSOFT_MASK && m_bOUTLINE && m_bOUTER_GLOW && m_bBLENDTINTBYBASEALPHA && m_bCUBEMAP_SPHERE_LEGACY; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 6 * m_nDETAILTEXTURE ) + ( 12 * m_nCUBEMAP ) + ( 24 * m_nDIFFUSELIGHTING ) + ( 48 * m_nENVMAPMASK ) + ( 96 * m_nBASEALPHAENVMAPMASK ) + ( 192 * m_nSELFILLUM ) + ( 384 * m_nVERTEXCOLOR ) + ( 768 * m_nFLASHLIGHT ) + ( 1536 * m_nSELFILLUM_ENVMAPMASK_ALPHA ) + ( 3072 * m_nDETAIL_BLEND_MODE ) + ( 30720 * m_nSEAMLESS_BASE ) + ( 61440 * m_nSEAMLESS_DETAIL ) + ( 122880 * m_nDISTANCEALPHA ) + ( 245760 * m_nDISTANCEALPHAFROMDETAIL ) + ( 491520 * m_nSOFT_MASK ) + ( 983040 * m_nOUTLINE ) + ( 1966080 * m_nOUTER_GLOW ) + ( 3932160 * m_nBLENDTINTBYBASEALPHA ) + ( 7864320 * m_nCUBEMAP_SPHERE_LEGACY ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_ps20 psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_SELFILLUM_ENVMAPMASK_ALPHA + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_SEAMLESS_BASE + psh_forgot_to_set_static_SEAMLESS_DETAIL + psh_forgot_to_set_static_DISTANCEALPHA + psh_forgot_to_set_static_DISTANCEALPHAFROMDETAIL + psh_forgot_to_set_static_SOFT_MASK + psh_forgot_to_set_static_OUTLINE + psh_forgot_to_set_static_OUTER_GLOW + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_CUBEMAP_SPHERE_LEGACY + 0 +class sdk_vertexlit_and_unlit_generic_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE && m_bLIGHTING_PREVIEW; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + ( 2 * m_nLIGHTING_PREVIEW ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_LIGHTING_PREVIEW + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_ps20b.inc new file mode 100644 index 00000000..ee74372c --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_ps20b.inc @@ -0,0 +1,637 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_ps20b_Static_Index +{ +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nSELFILLUM_ENVMAPMASK_ALPHA; +#ifdef _DEBUG + bool m_bSELFILLUM_ENVMAPMASK_ALPHA; +#endif +public: + void SetSELFILLUM_ENVMAPMASK_ALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM_ENVMAPMASK_ALPHA = i; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = true; +#endif + } + void SetSELFILLUM_ENVMAPMASK_ALPHA( bool i ) + { + m_nSELFILLUM_ENVMAPMASK_ALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 9 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nSEAMLESS_BASE; +#ifdef _DEBUG + bool m_bSEAMLESS_BASE; +#endif +public: + void SetSEAMLESS_BASE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_BASE = i; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } + void SetSEAMLESS_BASE( bool i ) + { + m_nSEAMLESS_BASE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } +private: + int m_nSEAMLESS_DETAIL; +#ifdef _DEBUG + bool m_bSEAMLESS_DETAIL; +#endif +public: + void SetSEAMLESS_DETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_DETAIL = i; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } + void SetSEAMLESS_DETAIL( bool i ) + { + m_nSEAMLESS_DETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } +private: + int m_nDISTANCEALPHA; +#ifdef _DEBUG + bool m_bDISTANCEALPHA; +#endif +public: + void SetDISTANCEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHA = i; +#ifdef _DEBUG + m_bDISTANCEALPHA = true; +#endif + } + void SetDISTANCEALPHA( bool i ) + { + m_nDISTANCEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bDISTANCEALPHA = true; +#endif + } +private: + int m_nDISTANCEALPHAFROMDETAIL; +#ifdef _DEBUG + bool m_bDISTANCEALPHAFROMDETAIL; +#endif +public: + void SetDISTANCEALPHAFROMDETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHAFROMDETAIL = i; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = true; +#endif + } + void SetDISTANCEALPHAFROMDETAIL( bool i ) + { + m_nDISTANCEALPHAFROMDETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = true; +#endif + } +private: + int m_nSOFT_MASK; +#ifdef _DEBUG + bool m_bSOFT_MASK; +#endif +public: + void SetSOFT_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSOFT_MASK = i; +#ifdef _DEBUG + m_bSOFT_MASK = true; +#endif + } + void SetSOFT_MASK( bool i ) + { + m_nSOFT_MASK = i ? 1 : 0; +#ifdef _DEBUG + m_bSOFT_MASK = true; +#endif + } +private: + int m_nOUTLINE; +#ifdef _DEBUG + bool m_bOUTLINE; +#endif +public: + void SetOUTLINE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTLINE = i; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } + void SetOUTLINE( bool i ) + { + m_nOUTLINE = i ? 1 : 0; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } +private: + int m_nOUTER_GLOW; +#ifdef _DEBUG + bool m_bOUTER_GLOW; +#endif +public: + void SetOUTER_GLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTER_GLOW = i; +#ifdef _DEBUG + m_bOUTER_GLOW = true; +#endif + } + void SetOUTER_GLOW( bool i ) + { + m_nOUTER_GLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bOUTER_GLOW = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nDEPTHBLEND; +#ifdef _DEBUG + bool m_bDEPTHBLEND; +#endif +public: + void SetDEPTHBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDEPTHBLEND = i; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } + void SetDEPTHBLEND( bool i ) + { + m_nDEPTHBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +private: + int m_nSRGB_INPUT_ADAPTER; +#ifdef _DEBUG + bool m_bSRGB_INPUT_ADAPTER; +#endif +public: + void SetSRGB_INPUT_ADAPTER( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSRGB_INPUT_ADAPTER = i; +#ifdef _DEBUG + m_bSRGB_INPUT_ADAPTER = true; +#endif + } + void SetSRGB_INPUT_ADAPTER( bool i ) + { + m_nSRGB_INPUT_ADAPTER = i ? 1 : 0; +#ifdef _DEBUG + m_bSRGB_INPUT_ADAPTER = true; +#endif + } +private: + int m_nCUBEMAP_SPHERE_LEGACY; +#ifdef _DEBUG + bool m_bCUBEMAP_SPHERE_LEGACY; +#endif +public: + void SetCUBEMAP_SPHERE_LEGACY( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP_SPHERE_LEGACY = i; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = true; +#endif + } + void SetCUBEMAP_SPHERE_LEGACY( bool i ) + { + m_nCUBEMAP_SPHERE_LEGACY = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = false; +#endif // _DEBUG + m_nSELFILLUM_ENVMAPMASK_ALPHA = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = false; +#endif // _DEBUG + m_nSEAMLESS_BASE = 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = false; +#endif // _DEBUG + m_nSEAMLESS_DETAIL = 0; +#ifdef _DEBUG + m_bDISTANCEALPHA = false; +#endif // _DEBUG + m_nDISTANCEALPHA = 0; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = false; +#endif // _DEBUG + m_nDISTANCEALPHAFROMDETAIL = 0; +#ifdef _DEBUG + m_bSOFT_MASK = false; +#endif // _DEBUG + m_nSOFT_MASK = 0; +#ifdef _DEBUG + m_bOUTLINE = false; +#endif // _DEBUG + m_nOUTLINE = 0; +#ifdef _DEBUG + m_bOUTER_GLOW = false; +#endif // _DEBUG + m_nOUTER_GLOW = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bDEPTHBLEND = false; +#endif // _DEBUG + m_nDEPTHBLEND = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; +#ifdef _DEBUG + m_bSRGB_INPUT_ADAPTER = false; +#endif // _DEBUG + m_nSRGB_INPUT_ADAPTER = 0; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = false; +#endif // _DEBUG + m_nCUBEMAP_SPHERE_LEGACY = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDETAILTEXTURE && m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bVERTEXCOLOR && m_bFLASHLIGHT && m_bSELFILLUM_ENVMAPMASK_ALPHA && m_bDETAIL_BLEND_MODE && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bDISTANCEALPHA && m_bDISTANCEALPHAFROMDETAIL && m_bSOFT_MASK && m_bOUTLINE && m_bOUTER_GLOW && m_bFLASHLIGHTDEPTHFILTERMODE && m_bDEPTHBLEND && m_bBLENDTINTBYBASEALPHA && m_bSRGB_INPUT_ADAPTER && m_bCUBEMAP_SPHERE_LEGACY; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 6 * m_nDETAILTEXTURE ) + ( 12 * m_nCUBEMAP ) + ( 24 * m_nDIFFUSELIGHTING ) + ( 48 * m_nENVMAPMASK ) + ( 96 * m_nBASEALPHAENVMAPMASK ) + ( 192 * m_nSELFILLUM ) + ( 384 * m_nVERTEXCOLOR ) + ( 768 * m_nFLASHLIGHT ) + ( 1536 * m_nSELFILLUM_ENVMAPMASK_ALPHA ) + ( 3072 * m_nDETAIL_BLEND_MODE ) + ( 30720 * m_nSEAMLESS_BASE ) + ( 61440 * m_nSEAMLESS_DETAIL ) + ( 122880 * m_nDISTANCEALPHA ) + ( 245760 * m_nDISTANCEALPHAFROMDETAIL ) + ( 491520 * m_nSOFT_MASK ) + ( 983040 * m_nOUTLINE ) + ( 1966080 * m_nOUTER_GLOW ) + ( 3932160 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 11796480 * m_nDEPTHBLEND ) + ( 23592960 * m_nBLENDTINTBYBASEALPHA ) + ( 47185920 * m_nSRGB_INPUT_ADAPTER ) + ( 94371840 * m_nCUBEMAP_SPHERE_LEGACY ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_ps20b psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_SELFILLUM_ENVMAPMASK_ALPHA + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_SEAMLESS_BASE + psh_forgot_to_set_static_SEAMLESS_DETAIL + psh_forgot_to_set_static_DISTANCEALPHA + psh_forgot_to_set_static_DISTANCEALPHAFROMDETAIL + psh_forgot_to_set_static_SOFT_MASK + psh_forgot_to_set_static_OUTLINE + psh_forgot_to_set_static_OUTER_GLOW + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_DEPTHBLEND + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_SRGB_INPUT_ADAPTER + psh_forgot_to_set_static_CUBEMAP_SPHERE_LEGACY + 0 +class sdk_vertexlit_and_unlit_generic_ps20b_Dynamic_Index +{ +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bLIGHTING_PREVIEW && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nLIGHTING_PREVIEW ) + ( 3 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_ps20b psh_forgot_to_set_dynamic_LIGHTING_PREVIEW + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_ps30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_ps30.inc new file mode 100644 index 00000000..c5a18611 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_ps30.inc @@ -0,0 +1,612 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_ps30_Static_Index +{ +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nENVMAPMASK; +#ifdef _DEBUG + bool m_bENVMAPMASK; +#endif +public: + void SetENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPMASK = i; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } + void SetENVMAPMASK( bool i ) + { + m_nENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPMASK = true; +#endif + } +private: + int m_nBASEALPHAENVMAPMASK; +#ifdef _DEBUG + bool m_bBASEALPHAENVMAPMASK; +#endif +public: + void SetBASEALPHAENVMAPMASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBASEALPHAENVMAPMASK = i; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } + void SetBASEALPHAENVMAPMASK( bool i ) + { + m_nBASEALPHAENVMAPMASK = i ? 1 : 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nSELFILLUM_ENVMAPMASK_ALPHA; +#ifdef _DEBUG + bool m_bSELFILLUM_ENVMAPMASK_ALPHA; +#endif +public: + void SetSELFILLUM_ENVMAPMASK_ALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM_ENVMAPMASK_ALPHA = i; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = true; +#endif + } + void SetSELFILLUM_ENVMAPMASK_ALPHA( bool i ) + { + m_nSELFILLUM_ENVMAPMASK_ALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = true; +#endif + } +private: + int m_nDETAIL_BLEND_MODE; +#ifdef _DEBUG + bool m_bDETAIL_BLEND_MODE; +#endif +public: + void SetDETAIL_BLEND_MODE( int i ) + { + Assert( i >= 0 && i <= 9 ); + m_nDETAIL_BLEND_MODE = i; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } + void SetDETAIL_BLEND_MODE( bool i ) + { + m_nDETAIL_BLEND_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = true; +#endif + } +private: + int m_nSEAMLESS_BASE; +#ifdef _DEBUG + bool m_bSEAMLESS_BASE; +#endif +public: + void SetSEAMLESS_BASE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_BASE = i; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } + void SetSEAMLESS_BASE( bool i ) + { + m_nSEAMLESS_BASE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } +private: + int m_nSEAMLESS_DETAIL; +#ifdef _DEBUG + bool m_bSEAMLESS_DETAIL; +#endif +public: + void SetSEAMLESS_DETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_DETAIL = i; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } + void SetSEAMLESS_DETAIL( bool i ) + { + m_nSEAMLESS_DETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } +private: + int m_nDISTANCEALPHA; +#ifdef _DEBUG + bool m_bDISTANCEALPHA; +#endif +public: + void SetDISTANCEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHA = i; +#ifdef _DEBUG + m_bDISTANCEALPHA = true; +#endif + } + void SetDISTANCEALPHA( bool i ) + { + m_nDISTANCEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bDISTANCEALPHA = true; +#endif + } +private: + int m_nDISTANCEALPHAFROMDETAIL; +#ifdef _DEBUG + bool m_bDISTANCEALPHAFROMDETAIL; +#endif +public: + void SetDISTANCEALPHAFROMDETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDISTANCEALPHAFROMDETAIL = i; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = true; +#endif + } + void SetDISTANCEALPHAFROMDETAIL( bool i ) + { + m_nDISTANCEALPHAFROMDETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = true; +#endif + } +private: + int m_nSOFT_MASK; +#ifdef _DEBUG + bool m_bSOFT_MASK; +#endif +public: + void SetSOFT_MASK( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSOFT_MASK = i; +#ifdef _DEBUG + m_bSOFT_MASK = true; +#endif + } + void SetSOFT_MASK( bool i ) + { + m_nSOFT_MASK = i ? 1 : 0; +#ifdef _DEBUG + m_bSOFT_MASK = true; +#endif + } +private: + int m_nOUTLINE; +#ifdef _DEBUG + bool m_bOUTLINE; +#endif +public: + void SetOUTLINE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTLINE = i; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } + void SetOUTLINE( bool i ) + { + m_nOUTLINE = i ? 1 : 0; +#ifdef _DEBUG + m_bOUTLINE = true; +#endif + } +private: + int m_nOUTER_GLOW; +#ifdef _DEBUG + bool m_bOUTER_GLOW; +#endif +public: + void SetOUTER_GLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nOUTER_GLOW = i; +#ifdef _DEBUG + m_bOUTER_GLOW = true; +#endif + } + void SetOUTER_GLOW( bool i ) + { + m_nOUTER_GLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bOUTER_GLOW = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +private: + int m_nDEPTHBLEND; +#ifdef _DEBUG + bool m_bDEPTHBLEND; +#endif +public: + void SetDEPTHBLEND( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDEPTHBLEND = i; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } + void SetDEPTHBLEND( bool i ) + { + m_nDEPTHBLEND = i ? 1 : 0; +#ifdef _DEBUG + m_bDEPTHBLEND = true; +#endif + } +private: + int m_nBLENDTINTBYBASEALPHA; +#ifdef _DEBUG + bool m_bBLENDTINTBYBASEALPHA; +#endif +public: + void SetBLENDTINTBYBASEALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLENDTINTBYBASEALPHA = i; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } + void SetBLENDTINTBYBASEALPHA( bool i ) + { + m_nBLENDTINTBYBASEALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = true; +#endif + } +private: + int m_nCUBEMAP_SPHERE_LEGACY; +#ifdef _DEBUG + bool m_bCUBEMAP_SPHERE_LEGACY; +#endif +public: + void SetCUBEMAP_SPHERE_LEGACY( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP_SPHERE_LEGACY = i; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = true; +#endif + } + void SetCUBEMAP_SPHERE_LEGACY( bool i ) + { + m_nCUBEMAP_SPHERE_LEGACY = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_ps30_Static_Index( ) + { +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bENVMAPMASK = false; +#endif // _DEBUG + m_nENVMAPMASK = 0; +#ifdef _DEBUG + m_bBASEALPHAENVMAPMASK = false; +#endif // _DEBUG + m_nBASEALPHAENVMAPMASK = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bSELFILLUM_ENVMAPMASK_ALPHA = false; +#endif // _DEBUG + m_nSELFILLUM_ENVMAPMASK_ALPHA = 0; +#ifdef _DEBUG + m_bDETAIL_BLEND_MODE = false; +#endif // _DEBUG + m_nDETAIL_BLEND_MODE = 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = false; +#endif // _DEBUG + m_nSEAMLESS_BASE = 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = false; +#endif // _DEBUG + m_nSEAMLESS_DETAIL = 0; +#ifdef _DEBUG + m_bDISTANCEALPHA = false; +#endif // _DEBUG + m_nDISTANCEALPHA = 0; +#ifdef _DEBUG + m_bDISTANCEALPHAFROMDETAIL = false; +#endif // _DEBUG + m_nDISTANCEALPHAFROMDETAIL = 0; +#ifdef _DEBUG + m_bSOFT_MASK = false; +#endif // _DEBUG + m_nSOFT_MASK = 0; +#ifdef _DEBUG + m_bOUTLINE = false; +#endif // _DEBUG + m_nOUTLINE = 0; +#ifdef _DEBUG + m_bOUTER_GLOW = false; +#endif // _DEBUG + m_nOUTER_GLOW = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; +#ifdef _DEBUG + m_bDEPTHBLEND = false; +#endif // _DEBUG + m_nDEPTHBLEND = 0; +#ifdef _DEBUG + m_bBLENDTINTBYBASEALPHA = false; +#endif // _DEBUG + m_nBLENDTINTBYBASEALPHA = 0; +#ifdef _DEBUG + m_bCUBEMAP_SPHERE_LEGACY = false; +#endif // _DEBUG + m_nCUBEMAP_SPHERE_LEGACY = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDETAILTEXTURE && m_bCUBEMAP && m_bDIFFUSELIGHTING && m_bENVMAPMASK && m_bBASEALPHAENVMAPMASK && m_bSELFILLUM && m_bVERTEXCOLOR && m_bFLASHLIGHT && m_bSELFILLUM_ENVMAPMASK_ALPHA && m_bDETAIL_BLEND_MODE && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bDISTANCEALPHA && m_bDISTANCEALPHAFROMDETAIL && m_bSOFT_MASK && m_bOUTLINE && m_bOUTER_GLOW && m_bFLASHLIGHTDEPTHFILTERMODE && m_bDEPTHBLEND && m_bBLENDTINTBYBASEALPHA && m_bCUBEMAP_SPHERE_LEGACY; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 6 * m_nDETAILTEXTURE ) + ( 12 * m_nCUBEMAP ) + ( 24 * m_nDIFFUSELIGHTING ) + ( 48 * m_nENVMAPMASK ) + ( 96 * m_nBASEALPHAENVMAPMASK ) + ( 192 * m_nSELFILLUM ) + ( 384 * m_nVERTEXCOLOR ) + ( 768 * m_nFLASHLIGHT ) + ( 1536 * m_nSELFILLUM_ENVMAPMASK_ALPHA ) + ( 3072 * m_nDETAIL_BLEND_MODE ) + ( 30720 * m_nSEAMLESS_BASE ) + ( 61440 * m_nSEAMLESS_DETAIL ) + ( 122880 * m_nDISTANCEALPHA ) + ( 245760 * m_nDISTANCEALPHAFROMDETAIL ) + ( 491520 * m_nSOFT_MASK ) + ( 983040 * m_nOUTLINE ) + ( 1966080 * m_nOUTER_GLOW ) + ( 3932160 * m_nFLASHLIGHTDEPTHFILTERMODE ) + ( 11796480 * m_nDEPTHBLEND ) + ( 23592960 * m_nBLENDTINTBYBASEALPHA ) + ( 47185920 * m_nCUBEMAP_SPHERE_LEGACY ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_ps30 psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_CUBEMAP + psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_ENVMAPMASK + psh_forgot_to_set_static_BASEALPHAENVMAPMASK + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_SELFILLUM_ENVMAPMASK_ALPHA + psh_forgot_to_set_static_DETAIL_BLEND_MODE + psh_forgot_to_set_static_SEAMLESS_BASE + psh_forgot_to_set_static_SEAMLESS_DETAIL + psh_forgot_to_set_static_DISTANCEALPHA + psh_forgot_to_set_static_DISTANCEALPHAFROMDETAIL + psh_forgot_to_set_static_SOFT_MASK + psh_forgot_to_set_static_OUTLINE + psh_forgot_to_set_static_OUTER_GLOW + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + psh_forgot_to_set_static_DEPTHBLEND + psh_forgot_to_set_static_BLENDTINTBYBASEALPHA + psh_forgot_to_set_static_CUBEMAP_SPHERE_LEGACY + 0 +class sdk_vertexlit_and_unlit_generic_ps30_Dynamic_Index +{ +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_ps30_Dynamic_Index() + { +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bLIGHTING_PREVIEW && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nLIGHTING_PREVIEW ) + ( 3 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_ps30 psh_forgot_to_set_dynamic_LIGHTING_PREVIEW + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_vs20.inc new file mode 100644 index 00000000..d63378dc --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_vs20.inc @@ -0,0 +1,462 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_vs20_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nSEAMLESS_BASE; +#ifdef _DEBUG + bool m_bSEAMLESS_BASE; +#endif +public: + void SetSEAMLESS_BASE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_BASE = i; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } + void SetSEAMLESS_BASE( bool i ) + { + m_nSEAMLESS_BASE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } +private: + int m_nSEAMLESS_DETAIL; +#ifdef _DEBUG + bool m_bSEAMLESS_DETAIL; +#endif +public: + void SetSEAMLESS_DETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_DETAIL = i; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } + void SetSEAMLESS_DETAIL( bool i ) + { + m_nSEAMLESS_DETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } +private: + int m_nSEPARATE_DETAIL_UVS; +#ifdef _DEBUG + bool m_bSEPARATE_DETAIL_UVS; +#endif +public: + void SetSEPARATE_DETAIL_UVS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEPARATE_DETAIL_UVS = i; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = true; +#endif + } + void SetSEPARATE_DETAIL_UVS( bool i ) + { + m_nSEPARATE_DETAIL_UVS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = true; +#endif + } +private: + int m_nUSE_STATIC_CONTROL_FLOW; +#ifdef _DEBUG + bool m_bUSE_STATIC_CONTROL_FLOW; +#endif +public: + void SetUSE_STATIC_CONTROL_FLOW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nUSE_STATIC_CONTROL_FLOW = i; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } + void SetUSE_STATIC_CONTROL_FLOW( bool i ) + { + m_nUSE_STATIC_CONTROL_FLOW = i ? 1 : 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = true; +#endif + } +private: + int m_nDONT_GAMMA_CONVERT_VERTEX_COLOR; +#ifdef _DEBUG + bool m_bDONT_GAMMA_CONVERT_VERTEX_COLOR; +#endif +public: + void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i; +#ifdef _DEBUG + m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; +#endif + } + void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( bool i ) + { + m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; +#endif + } +private: + int m_nTREESWAY; +#ifdef _DEBUG + bool m_bTREESWAY; +#endif +public: + void SetTREESWAY( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nTREESWAY = i; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif + } + void SetTREESWAY( bool i ) + { + m_nTREESWAY = i ? 1 : 0; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = false; +#endif // _DEBUG + m_nSEAMLESS_BASE = 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = false; +#endif // _DEBUG + m_nSEAMLESS_DETAIL = 0; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = false; +#endif // _DEBUG + m_nSEPARATE_DETAIL_UVS = 0; +#ifdef _DEBUG + m_bUSE_STATIC_CONTROL_FLOW = false; +#endif // _DEBUG + m_nUSE_STATIC_CONTROL_FLOW = 0; +#ifdef _DEBUG + m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = false; +#endif // _DEBUG + m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = 0; +#ifdef _DEBUG + m_bTREESWAY = false; +#endif // _DEBUG + m_nTREESWAY = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bCUBEMAP && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bSEPARATE_DETAIL_UVS && m_bUSE_STATIC_CONTROL_FLOW && m_bDONT_GAMMA_CONVERT_VERTEX_COLOR && m_bTREESWAY; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 192 * m_nVERTEXCOLOR ) + ( 384 * m_nCUBEMAP ) + ( 768 * m_nHALFLAMBERT ) + ( 1536 * m_nFLASHLIGHT ) + ( 3072 * m_nSEAMLESS_BASE ) + ( 6144 * m_nSEAMLESS_DETAIL ) + ( 12288 * m_nSEPARATE_DETAIL_UVS ) + ( 24576 * m_nUSE_STATIC_CONTROL_FLOW ) + ( 49152 * m_nDONT_GAMMA_CONVERT_VERTEX_COLOR ) + ( 98304 * m_nTREESWAY ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_vs20 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_CUBEMAP + vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_FLASHLIGHT + vsh_forgot_to_set_static_SEAMLESS_BASE + vsh_forgot_to_set_static_SEAMLESS_DETAIL + vsh_forgot_to_set_static_SEPARATE_DETAIL_UVS + vsh_forgot_to_set_static_USE_STATIC_CONTROL_FLOW + vsh_forgot_to_set_static_DONT_GAMMA_CONVERT_VERTEX_COLOR + vsh_forgot_to_set_static_TREESWAY + 0 +class sdk_vertexlit_and_unlit_generic_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDYNAMIC_LIGHT ) + ( 4 * m_nSTATIC_LIGHT ) + ( 8 * m_nDOWATERFOG ) + ( 16 * m_nSKINNING ) + ( 32 * m_nLIGHTING_PREVIEW ) + ( 64 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_vs30.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_vs30.inc new file mode 100644 index 00000000..f2bc6c63 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_and_unlit_generic_vs30.inc @@ -0,0 +1,487 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_and_unlit_generic_vs30_Static_Index +{ +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nCUBEMAP; +#ifdef _DEBUG + bool m_bCUBEMAP; +#endif +public: + void SetCUBEMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCUBEMAP = i; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } + void SetCUBEMAP( bool i ) + { + m_nCUBEMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bCUBEMAP = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nSEAMLESS_BASE; +#ifdef _DEBUG + bool m_bSEAMLESS_BASE; +#endif +public: + void SetSEAMLESS_BASE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_BASE = i; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } + void SetSEAMLESS_BASE( bool i ) + { + m_nSEAMLESS_BASE = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = true; +#endif + } +private: + int m_nSEAMLESS_DETAIL; +#ifdef _DEBUG + bool m_bSEAMLESS_DETAIL; +#endif +public: + void SetSEAMLESS_DETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS_DETAIL = i; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } + void SetSEAMLESS_DETAIL( bool i ) + { + m_nSEAMLESS_DETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = true; +#endif + } +private: + int m_nSEPARATE_DETAIL_UVS; +#ifdef _DEBUG + bool m_bSEPARATE_DETAIL_UVS; +#endif +public: + void SetSEPARATE_DETAIL_UVS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEPARATE_DETAIL_UVS = i; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = true; +#endif + } + void SetSEPARATE_DETAIL_UVS( bool i ) + { + m_nSEPARATE_DETAIL_UVS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = true; +#endif + } +private: + int m_nDECAL; +#ifdef _DEBUG + bool m_bDECAL; +#endif +public: + void SetDECAL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDECAL = i; +#ifdef _DEBUG + m_bDECAL = true; +#endif + } + void SetDECAL( bool i ) + { + m_nDECAL = i ? 1 : 0; +#ifdef _DEBUG + m_bDECAL = true; +#endif + } +private: + int m_nSM30_VERTEXID; +#ifdef _DEBUG + bool m_bSM30_VERTEXID; +#endif +public: + void SetSM30_VERTEXID( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSM30_VERTEXID = i; +#ifdef _DEBUG + m_bSM30_VERTEXID = true; +#endif + } + void SetSM30_VERTEXID( bool i ) + { + m_nSM30_VERTEXID = i ? 1 : 0; +#ifdef _DEBUG + m_bSM30_VERTEXID = true; +#endif + } +private: + int m_nDONT_GAMMA_CONVERT_VERTEX_COLOR; +#ifdef _DEBUG + bool m_bDONT_GAMMA_CONVERT_VERTEX_COLOR; +#endif +public: + void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i; +#ifdef _DEBUG + m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; +#endif + } + void SetDONT_GAMMA_CONVERT_VERTEX_COLOR( bool i ) + { + m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = true; +#endif + } +private: + int m_nTREESWAY; +#ifdef _DEBUG + bool m_bTREESWAY; +#endif +public: + void SetTREESWAY( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nTREESWAY = i; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif + } + void SetTREESWAY( bool i ) + { + m_nTREESWAY = i ? 1 : 0; +#ifdef _DEBUG + m_bTREESWAY = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_vs30_Static_Index( ) + { +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bCUBEMAP = false; +#endif // _DEBUG + m_nCUBEMAP = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bSEAMLESS_BASE = false; +#endif // _DEBUG + m_nSEAMLESS_BASE = 0; +#ifdef _DEBUG + m_bSEAMLESS_DETAIL = false; +#endif // _DEBUG + m_nSEAMLESS_DETAIL = 0; +#ifdef _DEBUG + m_bSEPARATE_DETAIL_UVS = false; +#endif // _DEBUG + m_nSEPARATE_DETAIL_UVS = 0; +#ifdef _DEBUG + m_bDECAL = false; +#endif // _DEBUG + m_nDECAL = 0; +#ifdef _DEBUG + m_bSM30_VERTEXID = false; +#endif // _DEBUG + m_nSM30_VERTEXID = 0; +#ifdef _DEBUG + m_bDONT_GAMMA_CONVERT_VERTEX_COLOR = false; +#endif // _DEBUG + m_nDONT_GAMMA_CONVERT_VERTEX_COLOR = 0; +#ifdef _DEBUG + m_bTREESWAY = false; +#endif // _DEBUG + m_nTREESWAY = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bVERTEXCOLOR && m_bCUBEMAP && m_bHALFLAMBERT && m_bFLASHLIGHT && m_bSEAMLESS_BASE && m_bSEAMLESS_DETAIL && m_bSEPARATE_DETAIL_UVS && m_bDECAL && m_bSM30_VERTEXID && m_bDONT_GAMMA_CONVERT_VERTEX_COLOR && m_bTREESWAY; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 128 * m_nVERTEXCOLOR ) + ( 256 * m_nCUBEMAP ) + ( 512 * m_nHALFLAMBERT ) + ( 1024 * m_nFLASHLIGHT ) + ( 2048 * m_nSEAMLESS_BASE ) + ( 4096 * m_nSEAMLESS_DETAIL ) + ( 8192 * m_nSEPARATE_DETAIL_UVS ) + ( 16384 * m_nDECAL ) + ( 32768 * m_nSM30_VERTEXID ) + ( 65536 * m_nDONT_GAMMA_CONVERT_VERTEX_COLOR ) + ( 131072 * m_nTREESWAY ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_and_unlit_generic_vs30 vsh_forgot_to_set_static_VERTEXCOLOR + vsh_forgot_to_set_static_CUBEMAP + vsh_forgot_to_set_static_HALFLAMBERT + vsh_forgot_to_set_static_FLASHLIGHT + vsh_forgot_to_set_static_SEAMLESS_BASE + vsh_forgot_to_set_static_SEAMLESS_DETAIL + vsh_forgot_to_set_static_SEPARATE_DETAIL_UVS + vsh_forgot_to_set_static_DECAL + vsh_forgot_to_set_static_SM30_VERTEXID + vsh_forgot_to_set_static_DONT_GAMMA_CONVERT_VERTEX_COLOR + vsh_forgot_to_set_static_TREESWAY + 0 +class sdk_vertexlit_and_unlit_generic_vs30_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDYNAMIC_LIGHT; +#ifdef _DEBUG + bool m_bDYNAMIC_LIGHT; +#endif +public: + void SetDYNAMIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDYNAMIC_LIGHT = i; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } + void SetDYNAMIC_LIGHT( bool i ) + { + m_nDYNAMIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = true; +#endif + } +private: + int m_nSTATIC_LIGHT; +#ifdef _DEBUG + bool m_bSTATIC_LIGHT; +#endif +public: + void SetSTATIC_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSTATIC_LIGHT = i; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } + void SetSTATIC_LIGHT( bool i ) + { + m_nSTATIC_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nMORPHING; +#ifdef _DEBUG + bool m_bMORPHING; +#endif +public: + void SetMORPHING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nMORPHING = i; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } + void SetMORPHING( bool i ) + { + m_nMORPHING = i ? 1 : 0; +#ifdef _DEBUG + m_bMORPHING = true; +#endif + } +public: + sdk_vertexlit_and_unlit_generic_vs30_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDYNAMIC_LIGHT = false; +#endif // _DEBUG + m_nDYNAMIC_LIGHT = 0; +#ifdef _DEBUG + m_bSTATIC_LIGHT = false; +#endif // _DEBUG + m_nSTATIC_LIGHT = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bMORPHING = false; +#endif // _DEBUG + m_nMORPHING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDYNAMIC_LIGHT && m_bSTATIC_LIGHT && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bMORPHING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDYNAMIC_LIGHT ) + ( 4 * m_nSTATIC_LIGHT ) + ( 8 * m_nDOWATERFOG ) + ( 16 * m_nSKINNING ) + ( 32 * m_nLIGHTING_PREVIEW ) + ( 64 * m_nMORPHING ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_and_unlit_generic_vs30 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DYNAMIC_LIGHT + vsh_forgot_to_set_dynamic_STATIC_LIGHT + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_MORPHING + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_lighting_only_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_lighting_only_ps20.inc new file mode 100644 index 00000000..365fb68e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_lighting_only_ps20.inc @@ -0,0 +1,137 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_lighting_only_ps20_Static_Index +{ +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +public: + sdk_vertexlit_lighting_only_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDIFFUSELIGHTING && m_bHALFLAMBERT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 6 * m_nDIFFUSELIGHTING ) + ( 12 * m_nHALFLAMBERT ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_lighting_only_ps20 psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_HALFLAMBERT + 0 +class sdk_vertexlit_lighting_only_ps20_Dynamic_Index +{ +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_vertexlit_lighting_only_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bAMBIENT_LIGHT && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nAMBIENT_LIGHT ) + ( 2 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_lighting_only_ps20 psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_lighting_only_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_lighting_only_ps20b.inc new file mode 100644 index 00000000..a9d3beaa --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlit_lighting_only_ps20b.inc @@ -0,0 +1,162 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlit_lighting_only_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nDIFFUSELIGHTING; +#ifdef _DEBUG + bool m_bDIFFUSELIGHTING; +#endif +public: + void SetDIFFUSELIGHTING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSELIGHTING = i; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } + void SetDIFFUSELIGHTING( bool i ) + { + m_nDIFFUSELIGHTING = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSELIGHTING = true; +#endif + } +private: + int m_nHALFLAMBERT; +#ifdef _DEBUG + bool m_bHALFLAMBERT; +#endif +public: + void SetHALFLAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALFLAMBERT = i; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } + void SetHALFLAMBERT( bool i ) + { + m_nHALFLAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALFLAMBERT = true; +#endif + } +public: + sdk_vertexlit_lighting_only_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bDIFFUSELIGHTING = false; +#endif // _DEBUG + m_nDIFFUSELIGHTING = 0; +#ifdef _DEBUG + m_bHALFLAMBERT = false; +#endif // _DEBUG + m_nHALFLAMBERT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bDIFFUSELIGHTING && m_bHALFLAMBERT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 10 * m_nCONVERT_TO_SRGB ) + ( 20 * m_nDIFFUSELIGHTING ) + ( 40 * m_nHALFLAMBERT ) + 0; + } +}; +#define shaderStaticTest_sdk_vertexlit_lighting_only_ps20b psh_forgot_to_set_static_DIFFUSELIGHTING + psh_forgot_to_set_static_HALFLAMBERT + 0 +class sdk_vertexlit_lighting_only_ps20b_Dynamic_Index +{ +private: + int m_nAMBIENT_LIGHT; +#ifdef _DEBUG + bool m_bAMBIENT_LIGHT; +#endif +public: + void SetAMBIENT_LIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nAMBIENT_LIGHT = i; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } + void SetAMBIENT_LIGHT( bool i ) + { + m_nAMBIENT_LIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bAMBIENT_LIGHT = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + sdk_vertexlit_lighting_only_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bAMBIENT_LIGHT = false; +#endif // _DEBUG + m_nAMBIENT_LIGHT = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bAMBIENT_LIGHT && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nAMBIENT_LIGHT ) + ( 2 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_sdk_vertexlit_lighting_only_ps20b psh_forgot_to_set_dynamic_AMBIENT_LIGHT + psh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlitgeneric_lightingonly_overbright2_ps11.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlitgeneric_lightingonly_overbright2_ps11.inc new file mode 100644 index 00000000..9f9d2b41 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_vertexlitgeneric_lightingonly_overbright2_ps11.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class sdk_vertexlitgeneric_lightingonly_overbright2_ps11_Static_Index +{ +public: + sdk_vertexlitgeneric_lightingonly_overbright2_ps11_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_sdk_vertexlitgeneric_lightingonly_overbright2_ps11 0 +class sdk_vertexlitgeneric_lightingonly_overbright2_ps11_Dynamic_Index +{ +public: + sdk_vertexlitgeneric_lightingonly_overbright2_ps11_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_sdk_vertexlitgeneric_lightingonly_overbright2_ps11 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_windowimposter_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_windowimposter_ps20.inc new file mode 100644 index 00000000..7c34f6ee --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_windowimposter_ps20.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_windowimposter_ps20_Static_Index +{ +private: + int m_nPARALLAXCORRECT; +#ifdef _DEBUG + bool m_bPARALLAXCORRECT; +#endif +public: + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } + void SetPARALLAXCORRECT( bool i ) + { + m_nPARALLAXCORRECT = i ? 1 : 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } +public: + sdk_windowimposter_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + m_nPARALLAXCORRECT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bPARALLAXCORRECT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nPARALLAXCORRECT ) + 0; + } +}; +#define shaderStaticTest_sdk_windowimposter_ps20 psh_forgot_to_set_static_PARALLAXCORRECT + 0 +class sdk_windowimposter_ps20_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_windowimposter_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_windowimposter_ps20 psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_windowimposter_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_windowimposter_ps20b.inc new file mode 100644 index 00000000..e94fc94d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_windowimposter_ps20b.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_windowimposter_ps20b_Static_Index +{ +private: + int m_nPARALLAXCORRECT; +#ifdef _DEBUG + bool m_bPARALLAXCORRECT; +#endif +public: + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } + void SetPARALLAXCORRECT( bool i ) + { + m_nPARALLAXCORRECT = i ? 1 : 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } +public: + sdk_windowimposter_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + m_nPARALLAXCORRECT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bPARALLAXCORRECT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nPARALLAXCORRECT ) + 0; + } +}; +#define shaderStaticTest_sdk_windowimposter_ps20b psh_forgot_to_set_static_PARALLAXCORRECT + 0 +class sdk_windowimposter_ps20b_Dynamic_Index +{ +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_windowimposter_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_windowimposter_ps20b psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_windowimposter_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_windowimposter_vs20.inc new file mode 100644 index 00000000..faa096a2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_windowimposter_vs20.inc @@ -0,0 +1,87 @@ +#include "shaderlib/cshader.h" +class sdk_windowimposter_vs20_Static_Index +{ +private: + int m_nPARALLAXCORRECT; +#ifdef _DEBUG + bool m_bPARALLAXCORRECT; +#endif +public: + void SetPARALLAXCORRECT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPARALLAXCORRECT = i; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } + void SetPARALLAXCORRECT( bool i ) + { + m_nPARALLAXCORRECT = i ? 1 : 0; +#ifdef _DEBUG + m_bPARALLAXCORRECT = true; +#endif + } +public: + sdk_windowimposter_vs20_Static_Index( ) + { +#ifdef _DEBUG + m_bPARALLAXCORRECT = false; +#endif // _DEBUG + m_nPARALLAXCORRECT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bPARALLAXCORRECT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nPARALLAXCORRECT ) + 0; + } +}; +#define shaderStaticTest_sdk_windowimposter_vs20 vsh_forgot_to_set_static_PARALLAXCORRECT + 0 +class sdk_windowimposter_vs20_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_windowimposter_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; +#define shaderDynamicTest_sdk_windowimposter_vs20 vsh_forgot_to_set_dynamic_DOWATERFOG + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_worldtwotextureblend_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_worldtwotextureblend_ps20.inc new file mode 100644 index 00000000..eeef1cae --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_worldtwotextureblend_ps20.inc @@ -0,0 +1,287 @@ +#include "shaderlib/cshader.h" +class sdk_worldtwotextureblend_ps20_Static_Index +{ +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nDIFFUSEBUMPMAP; +#ifdef _DEBUG + bool m_bDIFFUSEBUMPMAP; +#endif +public: + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } + void SetDIFFUSEBUMPMAP( bool i ) + { + m_nDIFFUSEBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } +private: + int m_nDETAIL_ALPHA_MASK_BASE_TEXTURE; +#ifdef _DEBUG + bool m_bDETAIL_ALPHA_MASK_BASE_TEXTURE; +#endif +public: + void SetDETAIL_ALPHA_MASK_BASE_TEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_ALPHA_MASK_BASE_TEXTURE = i; +#ifdef _DEBUG + m_bDETAIL_ALPHA_MASK_BASE_TEXTURE = true; +#endif + } + void SetDETAIL_ALPHA_MASK_BASE_TEXTURE( bool i ) + { + m_nDETAIL_ALPHA_MASK_BASE_TEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_ALPHA_MASK_BASE_TEXTURE = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +public: + sdk_worldtwotextureblend_ps20_Static_Index( ) + { +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = false; +#endif // _DEBUG + m_nDIFFUSEBUMPMAP = 0; +#ifdef _DEBUG + m_bDETAIL_ALPHA_MASK_BASE_TEXTURE = false; +#endif // _DEBUG + m_nDETAIL_ALPHA_MASK_BASE_TEXTURE = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDETAILTEXTURE && m_bBUMPMAP && m_bVERTEXCOLOR && m_bSELFILLUM && m_bDIFFUSEBUMPMAP && m_bDETAIL_ALPHA_MASK_BASE_TEXTURE && m_bFLASHLIGHT && m_bSEAMLESS; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nDETAILTEXTURE ) + ( 8 * m_nBUMPMAP ) + ( 16 * m_nVERTEXCOLOR ) + ( 32 * m_nSELFILLUM ) + ( 64 * m_nDIFFUSEBUMPMAP ) + ( 128 * m_nDETAIL_ALPHA_MASK_BASE_TEXTURE ) + ( 256 * m_nFLASHLIGHT ) + ( 512 * m_nSEAMLESS ) + 0; + } +}; +#define shaderStaticTest_sdk_worldtwotextureblend_ps20 psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_DIFFUSEBUMPMAP + psh_forgot_to_set_static_DETAIL_ALPHA_MASK_BASE_TEXTURE + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_SEAMLESS + 0 +class sdk_worldtwotextureblend_ps20_Dynamic_Index +{ +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +public: + sdk_worldtwotextureblend_ps20_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + 0; + } +}; +#define shaderDynamicTest_sdk_worldtwotextureblend_ps20 psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_worldtwotextureblend_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_worldtwotextureblend_ps20b.inc new file mode 100644 index 00000000..5663a738 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/SDK_worldtwotextureblend_ps20b.inc @@ -0,0 +1,387 @@ +#include "shaderlib/cshader.h" +class sdk_worldtwotextureblend_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nDETAILTEXTURE; +#ifdef _DEBUG + bool m_bDETAILTEXTURE; +#endif +public: + void SetDETAILTEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAILTEXTURE = i; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } + void SetDETAILTEXTURE( bool i ) + { + m_nDETAILTEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAILTEXTURE = true; +#endif + } +private: + int m_nBUMPMAP; +#ifdef _DEBUG + bool m_bBUMPMAP; +#endif +public: + void SetBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBUMPMAP = i; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } + void SetBUMPMAP( bool i ) + { + m_nBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bBUMPMAP = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nSELFILLUM; +#ifdef _DEBUG + bool m_bSELFILLUM; +#endif +public: + void SetSELFILLUM( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSELFILLUM = i; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } + void SetSELFILLUM( bool i ) + { + m_nSELFILLUM = i ? 1 : 0; +#ifdef _DEBUG + m_bSELFILLUM = true; +#endif + } +private: + int m_nDIFFUSEBUMPMAP; +#ifdef _DEBUG + bool m_bDIFFUSEBUMPMAP; +#endif +public: + void SetDIFFUSEBUMPMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDIFFUSEBUMPMAP = i; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } + void SetDIFFUSEBUMPMAP( bool i ) + { + m_nDIFFUSEBUMPMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = true; +#endif + } +private: + int m_nDETAIL_ALPHA_MASK_BASE_TEXTURE; +#ifdef _DEBUG + bool m_bDETAIL_ALPHA_MASK_BASE_TEXTURE; +#endif +public: + void SetDETAIL_ALPHA_MASK_BASE_TEXTURE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL_ALPHA_MASK_BASE_TEXTURE = i; +#ifdef _DEBUG + m_bDETAIL_ALPHA_MASK_BASE_TEXTURE = true; +#endif + } + void SetDETAIL_ALPHA_MASK_BASE_TEXTURE( bool i ) + { + m_nDETAIL_ALPHA_MASK_BASE_TEXTURE = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL_ALPHA_MASK_BASE_TEXTURE = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nSEAMLESS; +#ifdef _DEBUG + bool m_bSEAMLESS; +#endif +public: + void SetSEAMLESS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEAMLESS = i; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } + void SetSEAMLESS( bool i ) + { + m_nSEAMLESS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEAMLESS = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + sdk_worldtwotextureblend_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = g_pHardwareConfig->NeedsShaderSRGBConversion(); +#ifdef _DEBUG + m_bDETAILTEXTURE = false; +#endif // _DEBUG + m_nDETAILTEXTURE = 0; +#ifdef _DEBUG + m_bBUMPMAP = false; +#endif // _DEBUG + m_nBUMPMAP = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bSELFILLUM = false; +#endif // _DEBUG + m_nSELFILLUM = 0; +#ifdef _DEBUG + m_bDIFFUSEBUMPMAP = false; +#endif // _DEBUG + m_nDIFFUSEBUMPMAP = 0; +#ifdef _DEBUG + m_bDETAIL_ALPHA_MASK_BASE_TEXTURE = false; +#endif // _DEBUG + m_nDETAIL_ALPHA_MASK_BASE_TEXTURE = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bSEAMLESS = false; +#endif // _DEBUG + m_nSEAMLESS = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bDETAILTEXTURE && m_bBUMPMAP && m_bVERTEXCOLOR && m_bSELFILLUM && m_bDIFFUSEBUMPMAP && m_bDETAIL_ALPHA_MASK_BASE_TEXTURE && m_bFLASHLIGHT && m_bSEAMLESS && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 16 * m_nCONVERT_TO_SRGB ) + ( 32 * m_nDETAILTEXTURE ) + ( 64 * m_nBUMPMAP ) + ( 128 * m_nVERTEXCOLOR ) + ( 256 * m_nSELFILLUM ) + ( 512 * m_nDIFFUSEBUMPMAP ) + ( 1024 * m_nDETAIL_ALPHA_MASK_BASE_TEXTURE ) + ( 2048 * m_nFLASHLIGHT ) + ( 4096 * m_nSEAMLESS ) + ( 8192 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_sdk_worldtwotextureblend_ps20b psh_forgot_to_set_static_DETAILTEXTURE + psh_forgot_to_set_static_BUMPMAP + psh_forgot_to_set_static_VERTEXCOLOR + psh_forgot_to_set_static_SELFILLUM + psh_forgot_to_set_static_DIFFUSEBUMPMAP + psh_forgot_to_set_static_DETAIL_ALPHA_MASK_BASE_TEXTURE + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_SEAMLESS + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class sdk_worldtwotextureblend_ps20b_Dynamic_Index +{ +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + sdk_worldtwotextureblend_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 8 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_sdk_worldtwotextureblend_ps20b psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/blurgaussian_3x3_ps20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/blurgaussian_3x3_ps20.inc new file mode 100644 index 00000000..01b921ca --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/blurgaussian_3x3_ps20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class blurgaussian_3x3_ps20_Static_Index +{ +public: + blurgaussian_3x3_ps20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_blurgaussian_3x3_ps20 0 +class blurgaussian_3x3_ps20_Dynamic_Index +{ +public: + blurgaussian_3x3_ps20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_blurgaussian_3x3_ps20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/blurgaussian_3x3_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/blurgaussian_3x3_ps20b.inc new file mode 100644 index 00000000..d5298ae8 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/blurgaussian_3x3_ps20b.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class blurgaussian_3x3_ps20b_Static_Index +{ +public: + blurgaussian_3x3_ps20b_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_blurgaussian_3x3_ps20b 0 +class blurgaussian_3x3_ps20b_Dynamic_Index +{ +public: + blurgaussian_3x3_ps20b_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_blurgaussian_3x3_ps20b 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/depth_of_field_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/depth_of_field_ps20b.inc new file mode 100644 index 00000000..99961231 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/depth_of_field_ps20b.inc @@ -0,0 +1,60 @@ +#include "shaderlib/cshader.h" +class depth_of_field_ps20b_Static_Index +{ +public: + depth_of_field_ps20b_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_depth_of_field_ps20b 0 +class depth_of_field_ps20b_Dynamic_Index +{ +private: + int m_nQUALITY; +#ifdef _DEBUG + bool m_bQUALITY; +#endif +public: + void SetQUALITY( int i ) + { + Assert( i >= 0 && i <= 3 ); + m_nQUALITY = i; +#ifdef _DEBUG + m_bQUALITY = true; +#endif + } + void SetQUALITY( bool i ) + { + m_nQUALITY = i ? 1 : 0; +#ifdef _DEBUG + m_bQUALITY = true; +#endif + } +public: + depth_of_field_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bQUALITY = false; +#endif // _DEBUG + m_nQUALITY = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bQUALITY; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nQUALITY ) + 0; + } +}; +#define shaderDynamicTest_depth_of_field_ps20b psh_forgot_to_set_dynamic_QUALITY + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/depth_of_field_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/depth_of_field_vs20.inc new file mode 100644 index 00000000..a014d1b9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/depth_of_field_vs20.inc @@ -0,0 +1,33 @@ +#include "shaderlib/cshader.h" +class depth_of_field_vs20_Static_Index +{ +public: + depth_of_field_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_depth_of_field_vs20 0 +class depth_of_field_vs20_Dynamic_Index +{ +public: + depth_of_field_vs20_Dynamic_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderDynamicTest_depth_of_field_vs20 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/engine_post_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/engine_post_ps20b.inc new file mode 100644 index 00000000..ec25f0d9 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/engine_post_ps20b.inc @@ -0,0 +1,362 @@ +#include "shaderlib/cshader.h" +class engine_post_ps20b_Static_Index +{ +private: + int m_nTOOL_MODE; +#ifdef _DEBUG + bool m_bTOOL_MODE; +#endif +public: + void SetTOOL_MODE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTOOL_MODE = i; +#ifdef _DEBUG + m_bTOOL_MODE = true; +#endif + } + void SetTOOL_MODE( bool i ) + { + m_nTOOL_MODE = i ? 1 : 0; +#ifdef _DEBUG + m_bTOOL_MODE = true; +#endif + } +private: + int m_nDEPTH_BLUR_ENABLE; +#ifdef _DEBUG + bool m_bDEPTH_BLUR_ENABLE; +#endif +public: + void SetDEPTH_BLUR_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDEPTH_BLUR_ENABLE = i; +#ifdef _DEBUG + m_bDEPTH_BLUR_ENABLE = true; +#endif + } + void SetDEPTH_BLUR_ENABLE( bool i ) + { + m_nDEPTH_BLUR_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bDEPTH_BLUR_ENABLE = true; +#endif + } +public: + engine_post_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bTOOL_MODE = false; +#endif // _DEBUG + m_nTOOL_MODE = 0; +#ifdef _DEBUG + m_bDEPTH_BLUR_ENABLE = false; +#endif // _DEBUG + m_nDEPTH_BLUR_ENABLE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTOOL_MODE && m_bDEPTH_BLUR_ENABLE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2048 * m_nTOOL_MODE ) + ( 4096 * m_nDEPTH_BLUR_ENABLE ) + 0; + } +}; +#define shaderStaticTest_engine_post_ps20b psh_forgot_to_set_static_TOOL_MODE + psh_forgot_to_set_static_DEPTH_BLUR_ENABLE + 0 +class engine_post_ps20b_Dynamic_Index +{ +private: + int m_nAA_ENABLE; +#ifdef _DEBUG + bool m_bAA_ENABLE; +#endif +public: + void SetAA_ENABLE( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nAA_ENABLE = i; +#ifdef _DEBUG + m_bAA_ENABLE = true; +#endif + } + void SetAA_ENABLE( bool i ) + { + m_nAA_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bAA_ENABLE = true; +#endif + } +private: + int m_nCOL_CORRECT_NUM_LOOKUPS; +#ifdef _DEBUG + bool m_bCOL_CORRECT_NUM_LOOKUPS; +#endif +public: + void SetCOL_CORRECT_NUM_LOOKUPS( int i ) + { + Assert( i >= 0 && i <= 3 ); + m_nCOL_CORRECT_NUM_LOOKUPS = i; +#ifdef _DEBUG + m_bCOL_CORRECT_NUM_LOOKUPS = true; +#endif + } + void SetCOL_CORRECT_NUM_LOOKUPS( bool i ) + { + m_nCOL_CORRECT_NUM_LOOKUPS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOL_CORRECT_NUM_LOOKUPS = true; +#endif + } +private: + int m_nCONVERT_FROM_LINEAR; +#ifdef _DEBUG + bool m_bCONVERT_FROM_LINEAR; +#endif +public: + void SetCONVERT_FROM_LINEAR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_FROM_LINEAR = i; +#ifdef _DEBUG + m_bCONVERT_FROM_LINEAR = true; +#endif + } + void SetCONVERT_FROM_LINEAR( bool i ) + { + m_nCONVERT_FROM_LINEAR = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_FROM_LINEAR = true; +#endif + } +private: + int m_nCONVERT_TO_LINEAR; +#ifdef _DEBUG + bool m_bCONVERT_TO_LINEAR; +#endif +public: + void SetCONVERT_TO_LINEAR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCONVERT_TO_LINEAR = i; +#ifdef _DEBUG + m_bCONVERT_TO_LINEAR = true; +#endif + } + void SetCONVERT_TO_LINEAR( bool i ) + { + m_nCONVERT_TO_LINEAR = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_LINEAR = true; +#endif + } +private: + int m_nNOISE_ENABLE; +#ifdef _DEBUG + bool m_bNOISE_ENABLE; +#endif +public: + void SetNOISE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nNOISE_ENABLE = i; +#ifdef _DEBUG + m_bNOISE_ENABLE = true; +#endif + } + void SetNOISE_ENABLE( bool i ) + { + m_nNOISE_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bNOISE_ENABLE = true; +#endif + } +private: + int m_nVIGNETTE_ENABLE; +#ifdef _DEBUG + bool m_bVIGNETTE_ENABLE; +#endif +public: + void SetVIGNETTE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVIGNETTE_ENABLE = i; +#ifdef _DEBUG + m_bVIGNETTE_ENABLE = true; +#endif + } + void SetVIGNETTE_ENABLE( bool i ) + { + m_nVIGNETTE_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bVIGNETTE_ENABLE = true; +#endif + } +private: + int m_nLOCAL_CONTRAST_ENABLE; +#ifdef _DEBUG + bool m_bLOCAL_CONTRAST_ENABLE; +#endif +public: + void SetLOCAL_CONTRAST_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLOCAL_CONTRAST_ENABLE = i; +#ifdef _DEBUG + m_bLOCAL_CONTRAST_ENABLE = true; +#endif + } + void SetLOCAL_CONTRAST_ENABLE( bool i ) + { + m_nLOCAL_CONTRAST_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bLOCAL_CONTRAST_ENABLE = true; +#endif + } +private: + int m_nBLURRED_VIGNETTE_ENABLE; +#ifdef _DEBUG + bool m_bBLURRED_VIGNETTE_ENABLE; +#endif +public: + void SetBLURRED_VIGNETTE_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nBLURRED_VIGNETTE_ENABLE = i; +#ifdef _DEBUG + m_bBLURRED_VIGNETTE_ENABLE = true; +#endif + } + void SetBLURRED_VIGNETTE_ENABLE( bool i ) + { + m_nBLURRED_VIGNETTE_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bBLURRED_VIGNETTE_ENABLE = true; +#endif + } +private: + int m_nVOMIT_ENABLE; +#ifdef _DEBUG + bool m_bVOMIT_ENABLE; +#endif +public: + void SetVOMIT_ENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVOMIT_ENABLE = i; +#ifdef _DEBUG + m_bVOMIT_ENABLE = true; +#endif + } + void SetVOMIT_ENABLE( bool i ) + { + m_nVOMIT_ENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bVOMIT_ENABLE = true; +#endif + } +private: + int m_nTV_GAMMA; +#ifdef _DEBUG + bool m_bTV_GAMMA; +#endif +public: + void SetTV_GAMMA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTV_GAMMA = i; +#ifdef _DEBUG + m_bTV_GAMMA = true; +#endif + } + void SetTV_GAMMA( bool i ) + { + m_nTV_GAMMA = i ? 1 : 0; +#ifdef _DEBUG + m_bTV_GAMMA = true; +#endif + } +private: + int m_nDESATURATEENABLE; +#ifdef _DEBUG + bool m_bDESATURATEENABLE; +#endif +public: + void SetDESATURATEENABLE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDESATURATEENABLE = i; +#ifdef _DEBUG + m_bDESATURATEENABLE = true; +#endif + } + void SetDESATURATEENABLE( bool i ) + { + m_nDESATURATEENABLE = i ? 1 : 0; +#ifdef _DEBUG + m_bDESATURATEENABLE = true; +#endif + } +public: + engine_post_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bAA_ENABLE = false; +#endif // _DEBUG + m_nAA_ENABLE = 0; +#ifdef _DEBUG + m_bCOL_CORRECT_NUM_LOOKUPS = false; +#endif // _DEBUG + m_nCOL_CORRECT_NUM_LOOKUPS = 0; +#ifdef _DEBUG + m_bCONVERT_FROM_LINEAR = false; +#endif // _DEBUG + m_nCONVERT_FROM_LINEAR = 0; +#ifdef _DEBUG + m_bCONVERT_TO_LINEAR = false; +#endif // _DEBUG + m_nCONVERT_TO_LINEAR = 0; +#ifdef _DEBUG + m_bNOISE_ENABLE = false; +#endif // _DEBUG + m_nNOISE_ENABLE = 0; +#ifdef _DEBUG + m_bVIGNETTE_ENABLE = false; +#endif // _DEBUG + m_nVIGNETTE_ENABLE = 0; +#ifdef _DEBUG + m_bLOCAL_CONTRAST_ENABLE = false; +#endif // _DEBUG + m_nLOCAL_CONTRAST_ENABLE = 0; +#ifdef _DEBUG + m_bBLURRED_VIGNETTE_ENABLE = false; +#endif // _DEBUG + m_nBLURRED_VIGNETTE_ENABLE = 0; +#ifdef _DEBUG + m_bVOMIT_ENABLE = false; +#endif // _DEBUG + m_nVOMIT_ENABLE = 0; +#ifdef _DEBUG + m_bTV_GAMMA = false; +#endif // _DEBUG + m_nTV_GAMMA = 0; +#ifdef _DEBUG + m_bDESATURATEENABLE = false; +#endif // _DEBUG + m_nDESATURATEENABLE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bAA_ENABLE && m_bCOL_CORRECT_NUM_LOOKUPS && m_bCONVERT_FROM_LINEAR && m_bCONVERT_TO_LINEAR && m_bNOISE_ENABLE && m_bVIGNETTE_ENABLE && m_bLOCAL_CONTRAST_ENABLE && m_bBLURRED_VIGNETTE_ENABLE && m_bVOMIT_ENABLE && m_bTV_GAMMA && m_bDESATURATEENABLE; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nAA_ENABLE ) + ( 1 * m_nCOL_CORRECT_NUM_LOOKUPS ) + ( 4 * m_nCONVERT_FROM_LINEAR ) + ( 8 * m_nCONVERT_TO_LINEAR ) + ( 16 * m_nNOISE_ENABLE ) + ( 32 * m_nVIGNETTE_ENABLE ) + ( 64 * m_nLOCAL_CONTRAST_ENABLE ) + ( 128 * m_nBLURRED_VIGNETTE_ENABLE ) + ( 256 * m_nVOMIT_ENABLE ) + ( 512 * m_nTV_GAMMA ) + ( 1024 * m_nDESATURATEENABLE ) + 0; + } +}; +#define shaderDynamicTest_engine_post_ps20b psh_forgot_to_set_dynamic_AA_ENABLE + psh_forgot_to_set_dynamic_COL_CORRECT_NUM_LOOKUPS + psh_forgot_to_set_dynamic_CONVERT_FROM_LINEAR + psh_forgot_to_set_dynamic_CONVERT_TO_LINEAR + psh_forgot_to_set_dynamic_NOISE_ENABLE + psh_forgot_to_set_dynamic_VIGNETTE_ENABLE + psh_forgot_to_set_dynamic_LOCAL_CONTRAST_ENABLE + psh_forgot_to_set_dynamic_BLURRED_VIGNETTE_ENABLE + psh_forgot_to_set_dynamic_VOMIT_ENABLE + psh_forgot_to_set_dynamic_TV_GAMMA + psh_forgot_to_set_dynamic_DESATURATEENABLE + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/example_model_ps20b.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/example_model_ps20b.inc new file mode 100644 index 00000000..1d9a37a2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/example_model_ps20b.inc @@ -0,0 +1,237 @@ +#include "shaderlib/cshader.h" +class example_model_ps20b_Static_Index +{ +private: + int m_nCONVERT_TO_SRGB; +#ifdef _DEBUG + bool m_bCONVERT_TO_SRGB; +#endif +public: + void SetCONVERT_TO_SRGB( int i ) + { + Assert( i >= 0 && i <= 0 ); + m_nCONVERT_TO_SRGB = i; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } + void SetCONVERT_TO_SRGB( bool i ) + { + m_nCONVERT_TO_SRGB = i ? 1 : 0; +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = true; +#endif + } +private: + int m_nFLASHLIGHT; +#ifdef _DEBUG + bool m_bFLASHLIGHT; +#endif +public: + void SetFLASHLIGHT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHT = i; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } + void SetFLASHLIGHT( bool i ) + { + m_nFLASHLIGHT = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHT = true; +#endif + } +private: + int m_nFLASHLIGHTDEPTHFILTERMODE; +#ifdef _DEBUG + bool m_bFLASHLIGHTDEPTHFILTERMODE; +#endif +public: + void SetFLASHLIGHTDEPTHFILTERMODE( int i ) + { + Assert( i >= 0 && i <= 2 ); + m_nFLASHLIGHTDEPTHFILTERMODE = i; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } + void SetFLASHLIGHTDEPTHFILTERMODE( bool i ) + { + m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = true; +#endif + } +public: + example_model_ps20b_Static_Index( ) + { +#ifdef _DEBUG + m_bCONVERT_TO_SRGB = false; +#endif // _DEBUG + m_nCONVERT_TO_SRGB = 0; +#ifdef _DEBUG + m_bFLASHLIGHT = false; +#endif // _DEBUG + m_nFLASHLIGHT = 0; +#ifdef _DEBUG + m_bFLASHLIGHTDEPTHFILTERMODE = false; +#endif // _DEBUG + m_nFLASHLIGHTDEPTHFILTERMODE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bFLASHLIGHT && m_bFLASHLIGHTDEPTHFILTERMODE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 80 * m_nCONVERT_TO_SRGB ) + ( 80 * m_nFLASHLIGHT ) + ( 160 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0; + } +}; +#define shaderStaticTest_example_model_ps20b psh_forgot_to_set_static_CONVERT_TO_SRGB + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0 +class example_model_ps20b_Dynamic_Index +{ +private: + int m_nWRITEWATERFOGTODESTALPHA; +#ifdef _DEBUG + bool m_bWRITEWATERFOGTODESTALPHA; +#endif +public: + void SetWRITEWATERFOGTODESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITEWATERFOGTODESTALPHA = i; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } + void SetWRITEWATERFOGTODESTALPHA( bool i ) + { + m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = true; +#endif + } +private: + int m_nPIXELFOGTYPE; +#ifdef _DEBUG + bool m_bPIXELFOGTYPE; +#endif +public: + void SetPIXELFOGTYPE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nPIXELFOGTYPE = i; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } + void SetPIXELFOGTYPE( bool i ) + { + m_nPIXELFOGTYPE = i ? 1 : 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +private: + int m_nWRITE_DEPTH_TO_DESTALPHA; +#ifdef _DEBUG + bool m_bWRITE_DEPTH_TO_DESTALPHA; +#endif +public: + void SetWRITE_DEPTH_TO_DESTALPHA( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nWRITE_DEPTH_TO_DESTALPHA = i; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } + void SetWRITE_DEPTH_TO_DESTALPHA( bool i ) + { + m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = true; +#endif + } +private: + int m_nFLASHLIGHTSHADOWS; +#ifdef _DEBUG + bool m_bFLASHLIGHTSHADOWS; +#endif +public: + void SetFLASHLIGHTSHADOWS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nFLASHLIGHTSHADOWS = i; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } + void SetFLASHLIGHTSHADOWS( bool i ) + { + m_nFLASHLIGHTSHADOWS = i ? 1 : 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = true; +#endif + } +public: + example_model_ps20b_Dynamic_Index() + { +#ifdef _DEBUG + m_bWRITEWATERFOGTODESTALPHA = false; +#endif // _DEBUG + m_nWRITEWATERFOGTODESTALPHA = 0; +#ifdef _DEBUG + m_bPIXELFOGTYPE = false; +#endif // _DEBUG + m_nPIXELFOGTYPE = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; +#ifdef _DEBUG + m_bWRITE_DEPTH_TO_DESTALPHA = false; +#endif // _DEBUG + m_nWRITE_DEPTH_TO_DESTALPHA = 0; +#ifdef _DEBUG + m_bFLASHLIGHTSHADOWS = false; +#endif // _DEBUG + m_nFLASHLIGHTSHADOWS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nNUM_LIGHTS ) + ( 20 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 40 * m_nFLASHLIGHTSHADOWS ) + 0; + } +}; +#define shaderDynamicTest_example_model_ps20b psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0 diff --git a/sp/src/materialsystem/stdshaders/fxctmp9_tmp/example_model_vs20.inc b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/example_model_vs20.inc new file mode 100644 index 00000000..fcd08eb2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/fxctmp9_tmp/example_model_vs20.inc @@ -0,0 +1,160 @@ +#include "shaderlib/cshader.h" +class example_model_vs20_Static_Index +{ +public: + example_model_vs20_Static_Index( ) + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +#define shaderStaticTest_example_model_vs20 0 +class example_model_vs20_Dynamic_Index +{ +private: + int m_nCOMPRESSED_VERTS; +#ifdef _DEBUG + bool m_bCOMPRESSED_VERTS; +#endif +public: + void SetCOMPRESSED_VERTS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nCOMPRESSED_VERTS = i; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } + void SetCOMPRESSED_VERTS( bool i ) + { + m_nCOMPRESSED_VERTS = i ? 1 : 0; +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = true; +#endif + } +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +private: + int m_nLIGHTING_PREVIEW; +#ifdef _DEBUG + bool m_bLIGHTING_PREVIEW; +#endif +public: + void SetLIGHTING_PREVIEW( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nLIGHTING_PREVIEW = i; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } + void SetLIGHTING_PREVIEW( bool i ) + { + m_nLIGHTING_PREVIEW = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = true; +#endif + } +private: + int m_nNUM_LIGHTS; +#ifdef _DEBUG + bool m_bNUM_LIGHTS; +#endif +public: + void SetNUM_LIGHTS( int i ) + { + Assert( i >= 0 && i <= 4 ); + m_nNUM_LIGHTS = i; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } + void SetNUM_LIGHTS( bool i ) + { + m_nNUM_LIGHTS = i ? 1 : 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = true; +#endif + } +public: + example_model_vs20_Dynamic_Index() + { +#ifdef _DEBUG + m_bCOMPRESSED_VERTS = false; +#endif // _DEBUG + m_nCOMPRESSED_VERTS = 0; +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; +#ifdef _DEBUG + m_bLIGHTING_PREVIEW = false; +#endif // _DEBUG + m_nLIGHTING_PREVIEW = 0; +#ifdef _DEBUG + m_bNUM_LIGHTS = false; +#endif // _DEBUG + m_nNUM_LIGHTS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bNUM_LIGHTS; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nLIGHTING_PREVIEW ) + ( 16 * m_nNUM_LIGHTS ) + 0; + } +}; +#define shaderDynamicTest_example_model_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0 diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_Eyes.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_Eyes.inc new file mode 100644 index 00000000..6420be52 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_Eyes.inc @@ -0,0 +1,134 @@ +class sdk_eyes_Static_Index +{ +private: + int m_nHALF_LAMBERT; +#ifdef _DEBUG + bool m_bHALF_LAMBERT; +#endif +public: + void SetHALF_LAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALF_LAMBERT = i; +#ifdef _DEBUG + m_bHALF_LAMBERT = true; +#endif + } + void SetHALF_LAMBERT( bool i ) + { + m_nHALF_LAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALF_LAMBERT = true; +#endif + } +public: + sdk_eyes_Static_Index() + { +#ifdef _DEBUG + m_bHALF_LAMBERT = false; +#endif // _DEBUG + m_nHALF_LAMBERT = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bHALF_LAMBERT; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 88 * m_nHALF_LAMBERT ) + 0; + } +}; +class sdk_eyes_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nLIGHT_COMBO; +#ifdef _DEBUG + bool m_bLIGHT_COMBO; +#endif +public: + void SetLIGHT_COMBO( int i ) + { + Assert( i >= 0 && i <= 21 ); + m_nLIGHT_COMBO = i; +#ifdef _DEBUG + m_bLIGHT_COMBO = true; +#endif + } + void SetLIGHT_COMBO( bool i ) + { + m_nLIGHT_COMBO = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHT_COMBO = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_eyes_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bLIGHT_COMBO = false; +#endif // _DEBUG + m_nLIGHT_COMBO = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG && m_bLIGHT_COMBO && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + ( 2 * m_nLIGHT_COMBO ) + ( 44 * m_nSKINNING ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_LightmappedGeneric_BaseTexture.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_LightmappedGeneric_BaseTexture.inc new file mode 100644 index 00000000..fe6d6921 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_LightmappedGeneric_BaseTexture.inc @@ -0,0 +1,57 @@ +class sdk_lightmappedgeneric_basetexture_Static_Index +{ +public: + sdk_lightmappedgeneric_basetexture_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_lightmappedgeneric_basetexture_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_basetexture_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_LightmappedGeneric_BumpmappedLightmap_Base_ps14.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_LightmappedGeneric_BumpmappedLightmap_Base_ps14.inc new file mode 100644 index 00000000..4b9837cf --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_LightmappedGeneric_BumpmappedLightmap_Base_ps14.inc @@ -0,0 +1,57 @@ +class sdk_lightmappedgeneric_bumpmappedlightmap_base_ps14_Static_Index +{ +public: + sdk_lightmappedgeneric_bumpmappedlightmap_base_ps14_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_lightmappedgeneric_bumpmappedlightmap_base_ps14_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_bumpmappedlightmap_base_ps14_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_LightmappedGeneric_BumpmappedLightmap_Blend_ps14.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_LightmappedGeneric_BumpmappedLightmap_Blend_ps14.inc new file mode 100644 index 00000000..8fa2fdad --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_LightmappedGeneric_BumpmappedLightmap_Blend_ps14.inc @@ -0,0 +1,57 @@ +class sdk_lightmappedgeneric_bumpmappedlightmap_blend_ps14_Static_Index +{ +public: + sdk_lightmappedgeneric_bumpmappedlightmap_blend_ps14_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_lightmappedgeneric_bumpmappedlightmap_blend_ps14_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_bumpmappedlightmap_blend_ps14_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_LightmappedGeneric_Decal.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_LightmappedGeneric_Decal.inc new file mode 100644 index 00000000..a61b6686 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_LightmappedGeneric_Decal.inc @@ -0,0 +1,57 @@ +class sdk_lightmappedgeneric_decal_Static_Index +{ +public: + sdk_lightmappedgeneric_decal_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_lightmappedgeneric_decal_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_decal_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_LightmappedGeneric_LightingOnly.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_LightmappedGeneric_LightingOnly.inc new file mode 100644 index 00000000..ccbc3081 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_LightmappedGeneric_LightingOnly.inc @@ -0,0 +1,57 @@ +class sdk_lightmappedgeneric_lightingonly_Static_Index +{ +public: + sdk_lightmappedgeneric_lightingonly_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_lightmappedgeneric_lightingonly_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_lightingonly_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_UnlitGeneric_LightingOnly.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_UnlitGeneric_LightingOnly.inc new file mode 100644 index 00000000..42974139 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_UnlitGeneric_LightingOnly.inc @@ -0,0 +1,82 @@ +class sdk_unlitgeneric_lightingonly_Static_Index +{ +public: + sdk_unlitgeneric_lightingonly_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_unlitgeneric_lightingonly_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_unlitgeneric_lightingonly_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + ( 2 * m_nSKINNING ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_UnlitTwoTexture.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_UnlitTwoTexture.inc new file mode 100644 index 00000000..3959419d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_UnlitTwoTexture.inc @@ -0,0 +1,82 @@ +class sdk_unlittwotexture_Static_Index +{ +public: + sdk_unlittwotexture_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_unlittwotexture_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_unlittwotexture_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + ( 2 * m_nSKINNING ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_VertexLitGeneric_EnvmappedBumpmap_NoLighting.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_VertexLitGeneric_EnvmappedBumpmap_NoLighting.inc new file mode 100644 index 00000000..20696e87 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_VertexLitGeneric_EnvmappedBumpmap_NoLighting.inc @@ -0,0 +1,82 @@ +class sdk_vertexlitgeneric_envmappedbumpmap_nolighting_Static_Index +{ +public: + sdk_vertexlitgeneric_envmappedbumpmap_nolighting_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_vertexlitgeneric_envmappedbumpmap_nolighting_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_vertexlitgeneric_envmappedbumpmap_nolighting_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + ( 2 * m_nSKINNING ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.inc new file mode 100644 index 00000000..42fbe392 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.inc @@ -0,0 +1,82 @@ +class sdk_vertexlitgeneric_envmappedbumpmap_nolighting_ps14_Static_Index +{ +public: + sdk_vertexlitgeneric_envmappedbumpmap_nolighting_ps14_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_vertexlitgeneric_envmappedbumpmap_nolighting_ps14_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_vertexlitgeneric_envmappedbumpmap_nolighting_ps14_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + ( 2 * m_nSKINNING ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_VertexLitGeneric_SelfIllumOnly.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_VertexLitGeneric_SelfIllumOnly.inc new file mode 100644 index 00000000..b8fb4774 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_VertexLitGeneric_SelfIllumOnly.inc @@ -0,0 +1,82 @@ +class sdk_vertexlitgeneric_selfillumonly_Static_Index +{ +public: + sdk_vertexlitgeneric_selfillumonly_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_vertexlitgeneric_selfillumonly_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_vertexlitgeneric_selfillumonly_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + ( 2 * m_nSKINNING ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_VertexLitGeneric_vs11.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_VertexLitGeneric_vs11.inc new file mode 100644 index 00000000..77853d4d --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_VertexLitGeneric_vs11.inc @@ -0,0 +1,200 @@ +class sdk_vertexlitgeneric_vs11_Static_Index +{ +private: + int m_nHALF_LAMBERT; +#ifdef _DEBUG + bool m_bHALF_LAMBERT; +#endif +public: + void SetHALF_LAMBERT( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nHALF_LAMBERT = i; +#ifdef _DEBUG + m_bHALF_LAMBERT = true; +#endif + } + void SetHALF_LAMBERT( bool i ) + { + m_nHALF_LAMBERT = i ? 1 : 0; +#ifdef _DEBUG + m_bHALF_LAMBERT = true; +#endif + } +private: + int m_nENVMAP; +#ifdef _DEBUG + bool m_bENVMAP; +#endif +public: + void SetENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAP = i; +#ifdef _DEBUG + m_bENVMAP = true; +#endif + } + void SetENVMAP( bool i ) + { + m_nENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAP = true; +#endif + } +private: + int m_nENVMAPCAMERASPACE; +#ifdef _DEBUG + bool m_bENVMAPCAMERASPACE; +#endif +public: + void SetENVMAPCAMERASPACE( int i ) + { + } + void SetENVMAPCAMERASPACE( bool i ) + { + } +private: + int m_nENVMAPSPHERE; +#ifdef _DEBUG + bool m_bENVMAPSPHERE; +#endif +public: + void SetENVMAPSPHERE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPSPHERE = i; +#ifdef _DEBUG + m_bENVMAPSPHERE = true; +#endif + } + void SetENVMAPSPHERE( bool i ) + { + m_nENVMAPSPHERE = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPSPHERE = true; +#endif + } +public: + sdk_vertexlitgeneric_vs11_Static_Index() + { +#ifdef _DEBUG + m_bHALF_LAMBERT = false; +#endif // _DEBUG + m_nHALF_LAMBERT = 0; +#ifdef _DEBUG + m_bENVMAP = false; +#endif // _DEBUG + m_nENVMAP = 0; +#ifdef _DEBUG + m_bENVMAPCAMERASPACE = true; +#endif // _DEBUG + m_nENVMAPCAMERASPACE = 0; +#ifdef _DEBUG + m_bENVMAPSPHERE = false; +#endif // _DEBUG + m_nENVMAPSPHERE = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bHALF_LAMBERT && m_bENVMAP && m_bENVMAPCAMERASPACE && m_bENVMAPSPHERE; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 88 * m_nHALF_LAMBERT ) + ( 176 * m_nENVMAP ) + ( 352 * m_nENVMAPCAMERASPACE ) + ( 352 * m_nENVMAPSPHERE ) + 0; + } +}; +class sdk_vertexlitgeneric_vs11_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nLIGHT_COMBO; +#ifdef _DEBUG + bool m_bLIGHT_COMBO; +#endif +public: + void SetLIGHT_COMBO( int i ) + { + Assert( i >= 0 && i <= 21 ); + m_nLIGHT_COMBO = i; +#ifdef _DEBUG + m_bLIGHT_COMBO = true; +#endif + } + void SetLIGHT_COMBO( bool i ) + { + m_nLIGHT_COMBO = i ? 1 : 0; +#ifdef _DEBUG + m_bLIGHT_COMBO = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_vertexlitgeneric_vs11_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bLIGHT_COMBO = false; +#endif // _DEBUG + m_nLIGHT_COMBO = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG && m_bLIGHT_COMBO && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + ( 2 * m_nLIGHT_COMBO ) + ( 44 * m_nSKINNING ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_WorldVertexAlpha.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_WorldVertexAlpha.inc new file mode 100644 index 00000000..b1f29af6 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_WorldVertexAlpha.inc @@ -0,0 +1,57 @@ +class sdk_worldvertexalpha_Static_Index +{ +public: + sdk_worldvertexalpha_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_worldvertexalpha_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_worldvertexalpha_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_WorldVertexTransition.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_WorldVertexTransition.inc new file mode 100644 index 00000000..6a2424ca --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_WorldVertexTransition.inc @@ -0,0 +1,57 @@ +class sdk_worldvertextransition_Static_Index +{ +public: + sdk_worldvertextransition_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_worldvertextransition_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_worldvertextransition_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_WorldVertexTransition_Seamless.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_WorldVertexTransition_Seamless.inc new file mode 100644 index 00000000..8a5cae90 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_WorldVertexTransition_Seamless.inc @@ -0,0 +1,57 @@ +class sdk_worldvertextransition_seamless_Static_Index +{ +public: + sdk_worldvertextransition_seamless_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_worldvertextransition_seamless_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_worldvertextransition_seamless_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_WorldVertexTransition_vs14.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_WorldVertexTransition_vs14.inc new file mode 100644 index 00000000..3f468c2e --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_WorldVertexTransition_vs14.inc @@ -0,0 +1,57 @@ +class sdk_worldvertextransition_vs14_Static_Index +{ +public: + sdk_worldvertextransition_vs14_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_worldvertextransition_vs14_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_worldvertextransition_vs14_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_emissive_scroll_blended_pass_dx8_vs11.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_emissive_scroll_blended_pass_dx8_vs11.inc new file mode 100644 index 00000000..30cb66d1 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_emissive_scroll_blended_pass_dx8_vs11.inc @@ -0,0 +1,57 @@ +class sdk_emissive_scroll_blended_pass_dx8_vs11_Static_Index +{ +public: + sdk_emissive_scroll_blended_pass_dx8_vs11_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_emissive_scroll_blended_pass_dx8_vs11_Dynamic_Index +{ +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_emissive_scroll_blended_pass_dx8_vs11_Dynamic_Index() + { +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nSKINNING ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_eyes_flashlight_vs11.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_eyes_flashlight_vs11.inc new file mode 100644 index 00000000..03cb5fca --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_eyes_flashlight_vs11.inc @@ -0,0 +1,82 @@ +class sdk_eyes_flashlight_vs11_Static_Index +{ +public: + sdk_eyes_flashlight_vs11_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_eyes_flashlight_vs11_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_eyes_flashlight_vs11_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + ( 2 * m_nSKINNING ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_lightmappedgeneric_basetextureblend.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_lightmappedgeneric_basetextureblend.inc new file mode 100644 index 00000000..5c067f5a --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_lightmappedgeneric_basetextureblend.inc @@ -0,0 +1,57 @@ +class sdk_lightmappedgeneric_basetextureblend_Static_Index +{ +public: + sdk_lightmappedgeneric_basetextureblend_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_lightmappedgeneric_basetextureblend_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_basetextureblend_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_lightmappedgeneric_bumpmappedenvmap.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_lightmappedgeneric_bumpmappedenvmap.inc new file mode 100644 index 00000000..0a3be2ed --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_lightmappedgeneric_bumpmappedenvmap.inc @@ -0,0 +1,57 @@ +class sdk_lightmappedgeneric_bumpmappedenvmap_Static_Index +{ +public: + sdk_lightmappedgeneric_bumpmappedenvmap_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_lightmappedgeneric_bumpmappedenvmap_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_bumpmappedenvmap_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_lightmappedgeneric_bumpmappedenvmap_ps14.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_lightmappedgeneric_bumpmappedenvmap_ps14.inc new file mode 100644 index 00000000..991951a2 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_lightmappedgeneric_bumpmappedenvmap_ps14.inc @@ -0,0 +1,57 @@ +class sdk_lightmappedgeneric_bumpmappedenvmap_ps14_Static_Index +{ +public: + sdk_lightmappedgeneric_bumpmappedenvmap_ps14_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_lightmappedgeneric_bumpmappedenvmap_ps14_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_bumpmappedenvmap_ps14_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_lightmappedgeneric_bumpmappedlightmap.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_lightmappedgeneric_bumpmappedlightmap.inc new file mode 100644 index 00000000..236d3876 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_lightmappedgeneric_bumpmappedlightmap.inc @@ -0,0 +1,57 @@ +class sdk_lightmappedgeneric_bumpmappedlightmap_Static_Index +{ +public: + sdk_lightmappedgeneric_bumpmappedlightmap_Static_Index() + { + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG +#endif // _DEBUG + return 0; + } +}; +class sdk_lightmappedgeneric_bumpmappedlightmap_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_bumpmappedlightmap_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_lightmappedgeneric_vs11.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_lightmappedgeneric_vs11.inc new file mode 100644 index 00000000..d9b2a9f3 --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_lightmappedgeneric_vs11.inc @@ -0,0 +1,175 @@ +class sdk_lightmappedgeneric_vs11_Static_Index +{ +private: + int m_nDETAIL; +#ifdef _DEBUG + bool m_bDETAIL; +#endif +public: + void SetDETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL = i; +#ifdef _DEBUG + m_bDETAIL = true; +#endif + } + void SetDETAIL( bool i ) + { + m_nDETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL = true; +#endif + } +private: + int m_nENVMAP; +#ifdef _DEBUG + bool m_bENVMAP; +#endif +public: + void SetENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAP = i; +#ifdef _DEBUG + m_bENVMAP = true; +#endif + } + void SetENVMAP( bool i ) + { + m_nENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAP = true; +#endif + } +private: + int m_nENVMAPCAMERASPACE; +#ifdef _DEBUG + bool m_bENVMAPCAMERASPACE; +#endif +public: + void SetENVMAPCAMERASPACE( int i ) + { + } + void SetENVMAPCAMERASPACE( bool i ) + { + } +private: + int m_nENVMAPSPHERE; +#ifdef _DEBUG + bool m_bENVMAPSPHERE; +#endif +public: + void SetENVMAPSPHERE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPSPHERE = i; +#ifdef _DEBUG + m_bENVMAPSPHERE = true; +#endif + } + void SetENVMAPSPHERE( bool i ) + { + m_nENVMAPSPHERE = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPSPHERE = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +public: + sdk_lightmappedgeneric_vs11_Static_Index() + { +#ifdef _DEBUG + m_bDETAIL = false; +#endif // _DEBUG + m_nDETAIL = 0; +#ifdef _DEBUG + m_bENVMAP = false; +#endif // _DEBUG + m_nENVMAP = 0; +#ifdef _DEBUG + m_bENVMAPCAMERASPACE = true; +#endif // _DEBUG + m_nENVMAPCAMERASPACE = 0; +#ifdef _DEBUG + m_bENVMAPSPHERE = false; +#endif // _DEBUG + m_nENVMAPSPHERE = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDETAIL && m_bENVMAP && m_bENVMAPCAMERASPACE && m_bENVMAPSPHERE && m_bVERTEXCOLOR; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 2 * m_nDETAIL ) + ( 4 * m_nENVMAP ) + ( 8 * m_nENVMAPCAMERASPACE ) + ( 8 * m_nENVMAPSPHERE ) + ( 16 * m_nVERTEXCOLOR ) + 0; + } +}; +class sdk_lightmappedgeneric_vs11_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +public: + sdk_lightmappedgeneric_vs11_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_unlitgeneric_vs11.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_unlitgeneric_vs11.inc new file mode 100644 index 00000000..78d7d89f --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_unlitgeneric_vs11.inc @@ -0,0 +1,225 @@ +class sdk_unlitgeneric_vs11_Static_Index +{ +private: + int m_nDETAIL; +#ifdef _DEBUG + bool m_bDETAIL; +#endif +public: + void SetDETAIL( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDETAIL = i; +#ifdef _DEBUG + m_bDETAIL = true; +#endif + } + void SetDETAIL( bool i ) + { + m_nDETAIL = i ? 1 : 0; +#ifdef _DEBUG + m_bDETAIL = true; +#endif + } +private: + int m_nENVMAP; +#ifdef _DEBUG + bool m_bENVMAP; +#endif +public: + void SetENVMAP( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAP = i; +#ifdef _DEBUG + m_bENVMAP = true; +#endif + } + void SetENVMAP( bool i ) + { + m_nENVMAP = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAP = true; +#endif + } +private: + int m_nENVMAPCAMERASPACE; +#ifdef _DEBUG + bool m_bENVMAPCAMERASPACE; +#endif +public: + void SetENVMAPCAMERASPACE( int i ) + { + } + void SetENVMAPCAMERASPACE( bool i ) + { + } +private: + int m_nENVMAPSPHERE; +#ifdef _DEBUG + bool m_bENVMAPSPHERE; +#endif +public: + void SetENVMAPSPHERE( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nENVMAPSPHERE = i; +#ifdef _DEBUG + m_bENVMAPSPHERE = true; +#endif + } + void SetENVMAPSPHERE( bool i ) + { + m_nENVMAPSPHERE = i ? 1 : 0; +#ifdef _DEBUG + m_bENVMAPSPHERE = true; +#endif + } +private: + int m_nVERTEXCOLOR; +#ifdef _DEBUG + bool m_bVERTEXCOLOR; +#endif +public: + void SetVERTEXCOLOR( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nVERTEXCOLOR = i; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } + void SetVERTEXCOLOR( bool i ) + { + m_nVERTEXCOLOR = i ? 1 : 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = true; +#endif + } +private: + int m_nSEPARATEDETAILUVS; +#ifdef _DEBUG + bool m_bSEPARATEDETAILUVS; +#endif +public: + void SetSEPARATEDETAILUVS( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSEPARATEDETAILUVS = i; +#ifdef _DEBUG + m_bSEPARATEDETAILUVS = true; +#endif + } + void SetSEPARATEDETAILUVS( bool i ) + { + m_nSEPARATEDETAILUVS = i ? 1 : 0; +#ifdef _DEBUG + m_bSEPARATEDETAILUVS = true; +#endif + } +public: + sdk_unlitgeneric_vs11_Static_Index() + { +#ifdef _DEBUG + m_bDETAIL = false; +#endif // _DEBUG + m_nDETAIL = 0; +#ifdef _DEBUG + m_bENVMAP = false; +#endif // _DEBUG + m_nENVMAP = 0; +#ifdef _DEBUG + m_bENVMAPCAMERASPACE = true; +#endif // _DEBUG + m_nENVMAPCAMERASPACE = 0; +#ifdef _DEBUG + m_bENVMAPSPHERE = false; +#endif // _DEBUG + m_nENVMAPSPHERE = 0; +#ifdef _DEBUG + m_bVERTEXCOLOR = false; +#endif // _DEBUG + m_nVERTEXCOLOR = 0; +#ifdef _DEBUG + m_bSEPARATEDETAILUVS = false; +#endif // _DEBUG + m_nSEPARATEDETAILUVS = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bDETAIL && m_bENVMAP && m_bENVMAPCAMERASPACE && m_bENVMAPSPHERE && m_bVERTEXCOLOR && m_bSEPARATEDETAILUVS; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nDETAIL ) + ( 8 * m_nENVMAP ) + ( 16 * m_nENVMAPCAMERASPACE ) + ( 16 * m_nENVMAPSPHERE ) + ( 32 * m_nVERTEXCOLOR ) + ( 64 * m_nSEPARATEDETAILUVS ) + 0; + } +}; +class sdk_unlitgeneric_vs11_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_unlitgeneric_vs11_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + ( 2 * m_nSKINNING ) + 0; + } +}; diff --git a/sp/src/materialsystem/stdshaders/vshtmp9/SDK_vertexlitgeneric_flashlight_vs11.inc b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_vertexlitgeneric_flashlight_vs11.inc new file mode 100644 index 00000000..03b6a0ca --- /dev/null +++ b/sp/src/materialsystem/stdshaders/vshtmp9/SDK_vertexlitgeneric_flashlight_vs11.inc @@ -0,0 +1,109 @@ +class sdk_vertexlitgeneric_flashlight_vs11_Static_Index +{ +private: + int m_nTEETH; +#ifdef _DEBUG + bool m_bTEETH; +#endif +public: + void SetTEETH( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nTEETH = i; +#ifdef _DEBUG + m_bTEETH = true; +#endif + } + void SetTEETH( bool i ) + { + m_nTEETH = i ? 1 : 0; +#ifdef _DEBUG + m_bTEETH = true; +#endif + } +public: + sdk_vertexlitgeneric_flashlight_vs11_Static_Index() + { +#ifdef _DEBUG + m_bTEETH = false; +#endif // _DEBUG + m_nTEETH = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllStaticVarsDefined = m_bTEETH; + Assert( bAllStaticVarsDefined ); +#endif // _DEBUG + return ( 4 * m_nTEETH ) + 0; + } +}; +class sdk_vertexlitgeneric_flashlight_vs11_Dynamic_Index +{ +private: + int m_nDOWATERFOG; +#ifdef _DEBUG + bool m_bDOWATERFOG; +#endif +public: + void SetDOWATERFOG( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nDOWATERFOG = i; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } + void SetDOWATERFOG( bool i ) + { + m_nDOWATERFOG = i ? 1 : 0; +#ifdef _DEBUG + m_bDOWATERFOG = true; +#endif + } +private: + int m_nSKINNING; +#ifdef _DEBUG + bool m_bSKINNING; +#endif +public: + void SetSKINNING( int i ) + { + Assert( i >= 0 && i <= 1 ); + m_nSKINNING = i; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } + void SetSKINNING( bool i ) + { + m_nSKINNING = i ? 1 : 0; +#ifdef _DEBUG + m_bSKINNING = true; +#endif + } +public: + sdk_vertexlitgeneric_flashlight_vs11_Dynamic_Index() + { +#ifdef _DEBUG + m_bDOWATERFOG = false; +#endif // _DEBUG + m_nDOWATERFOG = 0; +#ifdef _DEBUG + m_bSKINNING = false; +#endif // _DEBUG + m_nSKINNING = 0; + } + int GetIndex() + { + // Asserts to make sure that we aren't using any skipped combinations. + // Asserts to make sure that we are setting all of the combination vars. +#ifdef _DEBUG + bool bAllDynamicVarsDefined = m_bDOWATERFOG && m_bSKINNING; + Assert( bAllDynamicVarsDefined ); +#endif // _DEBUG + return ( 1 * m_nDOWATERFOG ) + ( 2 * m_nSKINNING ) + 0; + } +}; diff --git a/sp/src/mathlib/3dnow.cpp b/sp/src/mathlib/3dnow.cpp new file mode 100644 index 00000000..db17c8c1 --- /dev/null +++ b/sp/src/mathlib/3dnow.cpp @@ -0,0 +1,197 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: 3DNow Math primitives. +// +//=====================================================================================// + +#include +#include // Needed for FLT_EPSILON +#include "basetypes.h" +#include +#include "tier0/dbg.h" +#include "mathlib/mathlib.h" +#include "mathlib/amd3dx.h" +#include "mathlib/vector.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#if !defined(COMPILER_MSVC64) && !defined(LINUX) +// Implement for 64-bit Windows if needed. +// Clang hits "fatal error: error in backend:" and other errors when trying +// to compile the inline assembly below. 3DNow support is highly unlikely to +// be useful/used, so it's not worth spending time on fixing. + +#pragma warning(disable:4244) // "conversion from 'const int' to 'float', possible loss of data" +#pragma warning(disable:4730) // "mixing _m64 and floating point expressions may result in incorrect code" + +//----------------------------------------------------------------------------- +// 3D Now Implementations of optimized routines: +//----------------------------------------------------------------------------- +float _3DNow_Sqrt(float x) +{ + Assert( s_bMathlibInitialized ); + float root = 0.f; +#ifdef _WIN32 + _asm + { + femms + movd mm0, x + PFRSQRT (mm1,mm0) + punpckldq mm0, mm0 + PFMUL (mm0, mm1) + movd root, mm0 + femms + } +#elif LINUX + __asm __volatile__( "femms" ); + __asm __volatile__ + ( + "pfrsqrt %y0, %y1 \n\t" + "punpckldq %y1, %y1 \n\t" + "pfmul %y1, %y0 \n\t" + : "=y" (root), "=y" (x) + :"0" (x) + ); + __asm __volatile__( "femms" ); +#else +#error +#endif + + return root; +} + +// NJS FIXME: Need to test Recripricol squareroot performance and accuraccy +// on AMD's before using the specialized instruction. +float _3DNow_RSqrt(float x) +{ + Assert( s_bMathlibInitialized ); + + return 1.f / _3DNow_Sqrt(x); +} + + +float FASTCALL _3DNow_VectorNormalize (Vector& vec) +{ + Assert( s_bMathlibInitialized ); + float *v = &vec[0]; + float radius = 0.f; + + if ( v[0] || v[1] || v[2] ) + { +#ifdef _WIN32 + _asm + { + mov eax, v + femms + movq mm0, QWORD PTR [eax] + movd mm1, DWORD PTR [eax+8] + movq mm2, mm0 + movq mm3, mm1 + PFMUL (mm0, mm0) + PFMUL (mm1, mm1) + PFACC (mm0, mm0) + PFADD (mm1, mm0) + PFRSQRT (mm0, mm1) + punpckldq mm1, mm1 + PFMUL (mm1, mm0) + PFMUL (mm2, mm0) + PFMUL (mm3, mm0) + movq QWORD PTR [eax], mm2 + movd DWORD PTR [eax+8], mm3 + movd radius, mm1 + femms + } +#elif LINUX + long long a,c; + int b,d; + memcpy(&a,&vec[0],sizeof(a)); + memcpy(&b,&vec[2],sizeof(b)); + memcpy(&c,&vec[0],sizeof(c)); + memcpy(&d,&vec[2],sizeof(d)); + + __asm __volatile__( "femms" ); + __asm __volatile__ + ( + "pfmul %y3, %y3\n\t" + "pfmul %y0, %y0 \n\t" + "pfacc %y3, %y3 \n\t" + "pfadd %y3, %y0 \n\t" + "pfrsqrt %y0, %y3 \n\t" + "punpckldq %y0, %y0 \n\t" + "pfmul %y3, %y0 \n\t" + "pfmul %y3, %y2 \n\t" + "pfmul %y3, %y1 \n\t" + : "=y" (radius), "=y" (c), "=y" (d) + : "y" (a), "0" (b), "1" (c), "2" (d) + ); + memcpy(&vec[0],&c,sizeof(c)); + memcpy(&vec[2],&d,sizeof(d)); + __asm __volatile__( "femms" ); + +#else +#error +#endif + } + return radius; +} + + +void FASTCALL _3DNow_VectorNormalizeFast (Vector& vec) +{ + _3DNow_VectorNormalize( vec ); +} + + +// JAY: This complains with the latest processor pack +#pragma warning(disable: 4730) + +float _3DNow_InvRSquared(const float* v) +{ + Assert( s_bMathlibInitialized ); + float r2 = 1.f; +#ifdef _WIN32 + _asm { // AMD 3DNow only routine + mov eax, v + femms + movq mm0, QWORD PTR [eax] + movd mm1, DWORD PTR [eax+8] + movd mm2, [r2] + PFMUL (mm0, mm0) + PFMUL (mm1, mm1) + PFACC (mm0, mm0) + PFADD (mm1, mm0) + PFMAX (mm1, mm2) + PFRCP (mm0, mm1) + movd [r2], mm0 + femms + } +#elif LINUX + long long a,c; + int b; + memcpy(&a,&v[0],sizeof(a)); + memcpy(&b,&v[2],sizeof(b)); + memcpy(&c,&v[0],sizeof(c)); + + __asm __volatile__( "femms" ); + __asm __volatile__ + ( + "PFMUL %y2, %y2 \n\t" + "PFMUL %y3, %y3 \n\t" + "PFACC %y2, %y2 \n\t" + "PFADD %y2, %y3 \n\t" + "PFMAX %y3, %y4 \n\t" + "PFRCP %y3, %y2 \n\t" + "movq %y2, %y0 \n\t" + : "=y" (r2) + : "0" (r2), "y" (a), "y" (b), "y" (c) + ); + __asm __volatile__( "femms" ); +#else +#error +#endif + + return r2; +} + +#endif // COMPILER_MSVC64 diff --git a/sp/src/mathlib/3dnow.h b/sp/src/mathlib/3dnow.h new file mode 100644 index 00000000..c39b2ec5 --- /dev/null +++ b/sp/src/mathlib/3dnow.h @@ -0,0 +1,16 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=====================================================================================// + +#ifndef _3DNOW_H +#define _3DNOW_H + +float _3DNow_Sqrt(float x); +float _3DNow_RSqrt(float x); +float FASTCALL _3DNow_VectorNormalize (Vector& vec); +void FASTCALL _3DNow_VectorNormalizeFast (Vector& vec); +float _3DNow_InvRSquared(const float* v); + +#endif // _3DNOW_H diff --git a/sp/src/mathlib/IceKey.cpp b/sp/src/mathlib/IceKey.cpp new file mode 100644 index 00000000..e739ce6f --- /dev/null +++ b/sp/src/mathlib/IceKey.cpp @@ -0,0 +1,393 @@ +// Purpose: C++ implementation of the ICE encryption algorithm. +// Taken from public domain code, as written by Matthew Kwan - July 1996 +// http://www.darkside.com.au/ice/ + +#if !defined(_STATIC_LINKED) || defined(_SHARED_LIB) + +#include "mathlib/IceKey.H" +#include "tier0/memdbgon.h" +#pragma warning(disable: 4244) + + + /* Structure of a single round subkey */ +class IceSubkey { + public: + unsigned long val[3]; +}; + + + /* The S-boxes */ +static unsigned long ice_sbox[4][1024]; +static int ice_sboxes_initialised = 0; + + + /* Modulo values for the S-boxes */ +static const int ice_smod[4][4] = { + {333, 313, 505, 369}, + {379, 375, 319, 391}, + {361, 445, 451, 397}, + {397, 425, 395, 505}}; + + /* XOR values for the S-boxes */ +static const int ice_sxor[4][4] = { + {0x83, 0x85, 0x9b, 0xcd}, + {0xcc, 0xa7, 0xad, 0x41}, + {0x4b, 0x2e, 0xd4, 0x33}, + {0xea, 0xcb, 0x2e, 0x04}}; + + /* Permutation values for the P-box */ +static const unsigned long ice_pbox[32] = { + 0x00000001, 0x00000080, 0x00000400, 0x00002000, + 0x00080000, 0x00200000, 0x01000000, 0x40000000, + 0x00000008, 0x00000020, 0x00000100, 0x00004000, + 0x00010000, 0x00800000, 0x04000000, 0x20000000, + 0x00000004, 0x00000010, 0x00000200, 0x00008000, + 0x00020000, 0x00400000, 0x08000000, 0x10000000, + 0x00000002, 0x00000040, 0x00000800, 0x00001000, + 0x00040000, 0x00100000, 0x02000000, 0x80000000}; + + /* The key rotation schedule */ +static const int ice_keyrot[16] = { + 0, 1, 2, 3, 2, 1, 3, 0, + 1, 3, 2, 0, 3, 1, 0, 2}; + + +/* + * 8-bit Galois Field multiplication of a by b, modulo m. + * Just like arithmetic multiplication, except that additions and + * subtractions are replaced by XOR. + */ + +static unsigned int +gf_mult ( + register unsigned int a, + register unsigned int b, + register unsigned int m +) { + register unsigned int res = 0; + + while (b) { + if (b & 1) + res ^= a; + + a <<= 1; + b >>= 1; + + if (a >= 256) + a ^= m; + } + + return (res); +} + + +/* + * Galois Field exponentiation. + * Raise the base to the power of 7, modulo m. + */ + +static unsigned long +gf_exp7 ( + register unsigned int b, + unsigned int m +) { + register unsigned int x; + + if (b == 0) + return (0); + + x = gf_mult (b, b, m); + x = gf_mult (b, x, m); + x = gf_mult (x, x, m); + return (gf_mult (b, x, m)); +} + + +/* + * Carry out the ICE 32-bit P-box permutation. + */ + +static unsigned long +ice_perm32 ( + register unsigned long x +) { + register unsigned long res = 0; + register const unsigned long *pbox = ice_pbox; + + while (x) { + if (x & 1) + res |= *pbox; + pbox++; + x >>= 1; + } + + return (res); +} + + +/* + * Initialise the ICE S-boxes. + * This only has to be done once. + */ + +static void +ice_sboxes_init (void) +{ + register int i; + + for (i=0; i<1024; i++) { + int col = (i >> 1) & 0xff; + int row = (i & 0x1) | ((i & 0x200) >> 8); + unsigned long x; + + x = gf_exp7 (col ^ ice_sxor[0][row], ice_smod[0][row]) << 24; + ice_sbox[0][i] = ice_perm32 (x); + + x = gf_exp7 (col ^ ice_sxor[1][row], ice_smod[1][row]) << 16; + ice_sbox[1][i] = ice_perm32 (x); + + x = gf_exp7 (col ^ ice_sxor[2][row], ice_smod[2][row]) << 8; + ice_sbox[2][i] = ice_perm32 (x); + + x = gf_exp7 (col ^ ice_sxor[3][row], ice_smod[3][row]); + ice_sbox[3][i] = ice_perm32 (x); + } +} + + +/* + * Create a new ICE key. + */ + +IceKey::IceKey (int n) +{ + if (!ice_sboxes_initialised) { + ice_sboxes_init (); + ice_sboxes_initialised = 1; + } + + if (n < 1) { + _size = 1; + _rounds = 8; + } else { + _size = n; + _rounds = n * 16; + } + + _keysched = new IceSubkey[_rounds]; +} + + +/* + * Destroy an ICE key. + */ + +IceKey::~IceKey () +{ + int i, j; + + for (i=0; i<_rounds; i++) + for (j=0; j<3; j++) + _keysched[i].val[j] = 0; + + _rounds = _size = 0; + + delete[] _keysched; +} + + +/* + * The single round ICE f function. + */ + +static unsigned long +ice_f ( + register unsigned long p, + const IceSubkey *sk +) { + unsigned long tl, tr; /* Expanded 40-bit values */ + unsigned long al, ar; /* Salted expanded 40-bit values */ + + /* Left half expansion */ + tl = ((p >> 16) & 0x3ff) | (((p >> 14) | (p << 18)) & 0xffc00); + + /* Right half expansion */ + tr = (p & 0x3ff) | ((p << 2) & 0xffc00); + + /* Perform the salt permutation */ + // al = (tr & sk->val[2]) | (tl & ~sk->val[2]); + // ar = (tl & sk->val[2]) | (tr & ~sk->val[2]); + al = sk->val[2] & (tl ^ tr); + ar = al ^ tr; + al ^= tl; + + al ^= sk->val[0]; /* XOR with the subkey */ + ar ^= sk->val[1]; + + /* S-box lookup and permutation */ + return (ice_sbox[0][al >> 10] | ice_sbox[1][al & 0x3ff] + | ice_sbox[2][ar >> 10] | ice_sbox[3][ar & 0x3ff]); +} + + +/* + * Encrypt a block of 8 bytes of data with the given ICE key. + */ + +void +IceKey::encrypt ( + const unsigned char *ptext, + unsigned char *ctext +) const +{ + register int i; + register unsigned long l, r; + + l = (((unsigned long) ptext[0]) << 24) + | (((unsigned long) ptext[1]) << 16) + | (((unsigned long) ptext[2]) << 8) | ptext[3]; + r = (((unsigned long) ptext[4]) << 24) + | (((unsigned long) ptext[5]) << 16) + | (((unsigned long) ptext[6]) << 8) | ptext[7]; + + for (i = 0; i < _rounds; i += 2) { + l ^= ice_f (r, &_keysched[i]); + r ^= ice_f (l, &_keysched[i + 1]); + } + + for (i = 0; i < 4; i++) { + ctext[3 - i] = r & 0xff; + ctext[7 - i] = l & 0xff; + + r >>= 8; + l >>= 8; + } +} + + +/* + * Decrypt a block of 8 bytes of data with the given ICE key. + */ + +void +IceKey::decrypt ( + const unsigned char *ctext, + unsigned char *ptext +) const +{ + register int i; + register unsigned long l, r; + + l = (((unsigned long) ctext[0]) << 24) + | (((unsigned long) ctext[1]) << 16) + | (((unsigned long) ctext[2]) << 8) | ctext[3]; + r = (((unsigned long) ctext[4]) << 24) + | (((unsigned long) ctext[5]) << 16) + | (((unsigned long) ctext[6]) << 8) | ctext[7]; + + for (i = _rounds - 1; i > 0; i -= 2) { + l ^= ice_f (r, &_keysched[i]); + r ^= ice_f (l, &_keysched[i - 1]); + } + + for (i = 0; i < 4; i++) { + ptext[3 - i] = r & 0xff; + ptext[7 - i] = l & 0xff; + + r >>= 8; + l >>= 8; + } +} + + +/* + * Set 8 rounds [n, n+7] of the key schedule of an ICE key. + */ + +void +IceKey::scheduleBuild ( + unsigned short *kb, + int n, + const int *keyrot +) { + int i; + + for (i=0; i<8; i++) { + register int j; + register int kr = keyrot[i]; + IceSubkey *isk = &_keysched[n + i]; + + for (j=0; j<3; j++) + isk->val[j] = 0; + + for (j=0; j<15; j++) { + register int k; + unsigned long *curr_sk = &isk->val[j % 3]; + + for (k=0; k<4; k++) { + unsigned short *curr_kb = &kb[(kr + k) & 3]; + register int bit = *curr_kb & 1; + + *curr_sk = (*curr_sk << 1) | bit; + *curr_kb = (*curr_kb >> 1) | ((bit ^ 1) << 15); + } + } + } +} + + +/* + * Set the key schedule of an ICE key. + */ + +void +IceKey::set ( + const unsigned char *key +) { + int i; + + if (_rounds == 8) { + unsigned short kb[4]; + + for (i=0; i<4; i++) + kb[3 - i] = (key[i*2] << 8) | key[i*2 + 1]; + + scheduleBuild (kb, 0, ice_keyrot); + return; + } + + for (i=0; i<_size; i++) { + int j; + unsigned short kb[4]; + + for (j=0; j<4; j++) + kb[3 - j] = (key[i*8 + j*2] << 8) | key[i*8 + j*2 + 1]; + + scheduleBuild (kb, i*8, ice_keyrot); + scheduleBuild (kb, _rounds - 8 - i*8, &ice_keyrot[8]); + } +} + + +/* + * Return the key size, in bytes. + */ + +int +IceKey::keySize () const +{ + return (_size * 8); +} + + +/* + * Return the block size, in bytes. + */ + +int +IceKey::blockSize () const +{ + return (8); +} + +#endif // !_STATIC_LINKED || _SHARED_LIB diff --git a/sp/src/mathlib/almostequal.cpp b/sp/src/mathlib/almostequal.cpp new file mode 100644 index 00000000..53b8a9e3 --- /dev/null +++ b/sp/src/mathlib/almostequal.cpp @@ -0,0 +1,97 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Fast ways to compare equality of two floats. Assumes +// sizeof(float) == sizeof(int) and we are using IEEE format. +// +// Source: http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm +//=====================================================================================// + +#include +#include + +#include "mathlib/mathlib.h" + +static inline bool AE_IsInfinite(float a) +{ + const int kInfAsInt = 0x7F800000; + + // An infinity has an exponent of 255 (shift left 23 positions) and + // a zero mantissa. There are two infinities - positive and negative. + if ((*(int*)&a & 0x7FFFFFFF) == kInfAsInt) + return true; + return false; +} + +static inline bool AE_IsNan(float a) +{ + // a NAN has an exponent of 255 (shifted left 23 positions) and + // a non-zero mantissa. + int exp = *(int*)&a & 0x7F800000; + int mantissa = *(int*)&a & 0x007FFFFF; + if (exp == 0x7F800000 && mantissa != 0) + return true; + return false; +} + +static inline int AE_Sign(float a) +{ + // The sign bit of a number is the high bit. + return (*(int*)&a) & 0x80000000; +} + +// This is the 'final' version of the AlmostEqualUlps function. +// The optional checks are included for completeness, but in many +// cases they are not necessary, or even not desirable. +bool AlmostEqual(float a, float b, int maxUlps) +{ + // There are several optional checks that you can do, depending + // on what behavior you want from your floating point comparisons. + // These checks should not be necessary and they are included + // mainly for completeness. + + // If a or b are infinity (positive or negative) then + // only return true if they are exactly equal to each other - + // that is, if they are both infinities of the same sign. + // This check is only needed if you will be generating + // infinities and you don't want them 'close' to numbers + // near FLT_MAX. + if (AE_IsInfinite(a) || AE_IsInfinite(b)) + return a == b; + + // If a or b are a NAN, return false. NANs are equal to nothing, + // not even themselves. + // This check is only needed if you will be generating NANs + // and you use a maxUlps greater than 4 million or you want to + // ensure that a NAN does not equal itself. + if (AE_IsNan(a) || AE_IsNan(b)) + return false; + + // After adjusting floats so their representations are lexicographically + // ordered as twos-complement integers a very small positive number + // will compare as 'close' to a very small negative number. If this is + // not desireable, and if you are on a platform that supports + // subnormals (which is the only place the problem can show up) then + // you need this check. + // The check for a == b is because zero and negative zero have different + // signs but are equal to each other. + if (AE_Sign(a) != AE_Sign(b)) + return a == b; + + int aInt = *(int*)&a; + // Make aInt lexicographically ordered as a twos-complement int + if (aInt < 0) + aInt = 0x80000000 - aInt; + // Make bInt lexicographically ordered as a twos-complement int + int bInt = *(int*)&b; + if (bInt < 0) + bInt = 0x80000000 - bInt; + + // Now we can compare aInt and bInt to find out how far apart a and b + // are. + int intDiff = abs(aInt - bInt); + if (intDiff <= maxUlps) + return true; + return false; +} + + diff --git a/sp/src/mathlib/anorms.cpp b/sp/src/mathlib/anorms.cpp new file mode 100644 index 00000000..5ce1c7e6 --- /dev/null +++ b/sp/src/mathlib/anorms.cpp @@ -0,0 +1,181 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// +#if !defined(_STATIC_LINKED) || defined(_SHARED_LIB) + + +#include "mathlib/vector.h" +#include "mathlib/anorms.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +Vector g_anorms[NUMVERTEXNORMALS] = +{ + Vector(-0.525731, 0.000000, 0.850651), + Vector(-0.442863, 0.238856, 0.864188), + Vector(-0.295242, 0.000000, 0.955423), + Vector(-0.309017, 0.500000, 0.809017), + Vector(-0.162460, 0.262866, 0.951056), + Vector(0.000000, 0.000000, 1.000000), + Vector(0.000000, 0.850651, 0.525731), + Vector(-0.147621, 0.716567, 0.681718), + Vector(0.147621, 0.716567, 0.681718), + Vector(0.000000, 0.525731, 0.850651), + Vector(0.309017, 0.500000, 0.809017), + Vector(0.525731, 0.000000, 0.850651), + Vector(0.295242, 0.000000, 0.955423), + Vector(0.442863, 0.238856, 0.864188), + Vector(0.162460, 0.262866, 0.951056), + Vector(-0.681718, 0.147621, 0.716567), + Vector(-0.809017, 0.309017, 0.500000), + Vector(-0.587785, 0.425325, 0.688191), + Vector(-0.850651, 0.525731, 0.000000), + Vector(-0.864188, 0.442863, 0.238856), + Vector(-0.716567, 0.681718, 0.147621), + Vector(-0.688191, 0.587785, 0.425325), + Vector(-0.500000, 0.809017, 0.309017), + Vector(-0.238856, 0.864188, 0.442863), + Vector(-0.425325, 0.688191, 0.587785), + Vector(-0.716567, 0.681718, -0.147621), + Vector(-0.500000, 0.809017, -0.309017), + Vector(-0.525731, 0.850651, 0.000000), + Vector(0.000000, 0.850651, -0.525731), + Vector(-0.238856, 0.864188, -0.442863), + Vector(0.000000, 0.955423, -0.295242), + Vector(-0.262866, 0.951056, -0.162460), + Vector(0.000000, 1.000000, 0.000000), + Vector(0.000000, 0.955423, 0.295242), + Vector(-0.262866, 0.951056, 0.162460), + Vector(0.238856, 0.864188, 0.442863), + Vector(0.262866, 0.951056, 0.162460), + Vector(0.500000, 0.809017, 0.309017), + Vector(0.238856, 0.864188, -0.442863), + Vector(0.262866, 0.951056, -0.162460), + Vector(0.500000, 0.809017, -0.309017), + Vector(0.850651, 0.525731, 0.000000), + Vector(0.716567, 0.681718, 0.147621), + Vector(0.716567, 0.681718, -0.147621), + Vector(0.525731, 0.850651, 0.000000), + Vector(0.425325, 0.688191, 0.587785), + Vector(0.864188, 0.442863, 0.238856), + Vector(0.688191, 0.587785, 0.425325), + Vector(0.809017, 0.309017, 0.500000), + Vector(0.681718, 0.147621, 0.716567), + Vector(0.587785, 0.425325, 0.688191), + Vector(0.955423, 0.295242, 0.000000), + Vector(1.000000, 0.000000, 0.000000), + Vector(0.951056, 0.162460, 0.262866), + Vector(0.850651, -0.525731, 0.000000), + Vector(0.955423, -0.295242, 0.000000), + Vector(0.864188, -0.442863, 0.238856), + Vector(0.951056, -0.162460, 0.262866), + Vector(0.809017, -0.309017, 0.500000), + Vector(0.681718, -0.147621, 0.716567), + Vector(0.850651, 0.000000, 0.525731), + Vector(0.864188, 0.442863, -0.238856), + Vector(0.809017, 0.309017, -0.500000), + Vector(0.951056, 0.162460, -0.262866), + Vector(0.525731, 0.000000, -0.850651), + Vector(0.681718, 0.147621, -0.716567), + Vector(0.681718, -0.147621, -0.716567), + Vector(0.850651, 0.000000, -0.525731), + Vector(0.809017, -0.309017, -0.500000), + Vector(0.864188, -0.442863, -0.238856), + Vector(0.951056, -0.162460, -0.262866), + Vector(0.147621, 0.716567, -0.681718), + Vector(0.309017, 0.500000, -0.809017), + Vector(0.425325, 0.688191, -0.587785), + Vector(0.442863, 0.238856, -0.864188), + Vector(0.587785, 0.425325, -0.688191), + Vector(0.688191, 0.587785, -0.425325), + Vector(-0.147621, 0.716567, -0.681718), + Vector(-0.309017, 0.500000, -0.809017), + Vector(0.000000, 0.525731, -0.850651), + Vector(-0.525731, 0.000000, -0.850651), + Vector(-0.442863, 0.238856, -0.864188), + Vector(-0.295242, 0.000000, -0.955423), + Vector(-0.162460, 0.262866, -0.951056), + Vector(0.000000, 0.000000, -1.000000), + Vector(0.295242, 0.000000, -0.955423), + Vector(0.162460, 0.262866, -0.951056), + Vector(-0.442863, -0.238856, -0.864188), + Vector(-0.309017, -0.500000, -0.809017), + Vector(-0.162460, -0.262866, -0.951056), + Vector(0.000000, -0.850651, -0.525731), + Vector(-0.147621, -0.716567, -0.681718), + Vector(0.147621, -0.716567, -0.681718), + Vector(0.000000, -0.525731, -0.850651), + Vector(0.309017, -0.500000, -0.809017), + Vector(0.442863, -0.238856, -0.864188), + Vector(0.162460, -0.262866, -0.951056), + Vector(0.238856, -0.864188, -0.442863), + Vector(0.500000, -0.809017, -0.309017), + Vector(0.425325, -0.688191, -0.587785), + Vector(0.716567, -0.681718, -0.147621), + Vector(0.688191, -0.587785, -0.425325), + Vector(0.587785, -0.425325, -0.688191), + Vector(0.000000, -0.955423, -0.295242), + Vector(0.000000, -1.000000, 0.000000), + Vector(0.262866, -0.951056, -0.162460), + Vector(0.000000, -0.850651, 0.525731), + Vector(0.000000, -0.955423, 0.295242), + Vector(0.238856, -0.864188, 0.442863), + Vector(0.262866, -0.951056, 0.162460), + Vector(0.500000, -0.809017, 0.309017), + Vector(0.716567, -0.681718, 0.147621), + Vector(0.525731, -0.850651, 0.000000), + Vector(-0.238856, -0.864188, -0.442863), + Vector(-0.500000, -0.809017, -0.309017), + Vector(-0.262866, -0.951056, -0.162460), + Vector(-0.850651, -0.525731, 0.000000), + Vector(-0.716567, -0.681718, -0.147621), + Vector(-0.716567, -0.681718, 0.147621), + Vector(-0.525731, -0.850651, 0.000000), + Vector(-0.500000, -0.809017, 0.309017), + Vector(-0.238856, -0.864188, 0.442863), + Vector(-0.262866, -0.951056, 0.162460), + Vector(-0.864188, -0.442863, 0.238856), + Vector(-0.809017, -0.309017, 0.500000), + Vector(-0.688191, -0.587785, 0.425325), + Vector(-0.681718, -0.147621, 0.716567), + Vector(-0.442863, -0.238856, 0.864188), + Vector(-0.587785, -0.425325, 0.688191), + Vector(-0.309017, -0.500000, 0.809017), + Vector(-0.147621, -0.716567, 0.681718), + Vector(-0.425325, -0.688191, 0.587785), + Vector(-0.162460, -0.262866, 0.951056), + Vector(0.442863, -0.238856, 0.864188), + Vector(0.162460, -0.262866, 0.951056), + Vector(0.309017, -0.500000, 0.809017), + Vector(0.147621, -0.716567, 0.681718), + Vector(0.000000, -0.525731, 0.850651), + Vector(0.425325, -0.688191, 0.587785), + Vector(0.587785, -0.425325, 0.688191), + Vector(0.688191, -0.587785, 0.425325), + Vector(-0.955423, 0.295242, 0.000000), + Vector(-0.951056, 0.162460, 0.262866), + Vector(-1.000000, 0.000000, 0.000000), + Vector(-0.850651, 0.000000, 0.525731), + Vector(-0.955423, -0.295242, 0.000000), + Vector(-0.951056, -0.162460, 0.262866), + Vector(-0.864188, 0.442863, -0.238856), + Vector(-0.951056, 0.162460, -0.262866), + Vector(-0.809017, 0.309017, -0.500000), + Vector(-0.864188, -0.442863, -0.238856), + Vector(-0.951056, -0.162460, -0.262866), + Vector(-0.809017, -0.309017, -0.500000), + Vector(-0.681718, 0.147621, -0.716567), + Vector(-0.681718, -0.147621, -0.716567), + Vector(-0.850651, 0.000000, -0.525731), + Vector(-0.688191, 0.587785, -0.425325), + Vector(-0.587785, 0.425325, -0.688191), + Vector(-0.425325, 0.688191, -0.587785), + Vector(-0.425325, -0.688191, -0.587785), + Vector(-0.587785, -0.425325, -0.688191), + Vector(-0.688191, -0.587785, -0.425325) +}; + +#endif // !_STATIC_LINKED || _SHARED_LIB \ No newline at end of file diff --git a/sp/src/mathlib/bumpvects.cpp b/sp/src/mathlib/bumpvects.cpp new file mode 100644 index 00000000..5edbe4d4 --- /dev/null +++ b/sp/src/mathlib/bumpvects.cpp @@ -0,0 +1,69 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// + +#if !defined(_STATIC_LINKED) || defined(_SHARED_LIB) + + +#ifdef QUIVER +#include "r_local.h" +#endif +#include "mathlib/bumpvects.h" +#include "mathlib/vector.h" +#include + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// z is coming out of the face. + +void GetBumpNormals( const Vector& sVect, const Vector& tVect, const Vector& flatNormal, + const Vector& phongNormal, Vector bumpNormals[NUM_BUMP_VECTS] ) +{ + Vector tmpNormal; + bool leftHanded; + int i; + + assert( NUM_BUMP_VECTS == 3 ); + + // Are we left or right handed? + CrossProduct( sVect, tVect, tmpNormal ); + if( DotProduct( flatNormal, tmpNormal ) < 0.0f ) + { + leftHanded = true; + } + else + { + leftHanded = false; + } + + // Build a basis for the face around the phong normal + matrix3x4_t smoothBasis; + CrossProduct( phongNormal.Base(), sVect.Base(), smoothBasis[1] ); + VectorNormalize( smoothBasis[1] ); + CrossProduct( smoothBasis[1], phongNormal.Base(), smoothBasis[0] ); + VectorNormalize( smoothBasis[0] ); + VectorCopy( phongNormal.Base(), smoothBasis[2] ); + + if( leftHanded ) + { + VectorNegate( smoothBasis[1] ); + } + + // move the g_localBumpBasis into world space to create bumpNormals + for( i = 0; i < 3; i++ ) + { + VectorIRotate( g_localBumpBasis[i], smoothBasis, bumpNormals[i] ); + } +} + +#endif // !_STATIC_LINKED || _SHARED_LIB \ No newline at end of file diff --git a/sp/src/mathlib/color_conversion.cpp b/sp/src/mathlib/color_conversion.cpp new file mode 100644 index 00000000..c3125258 --- /dev/null +++ b/sp/src/mathlib/color_conversion.cpp @@ -0,0 +1,637 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Color conversion routines. +// +//=====================================================================================// + +#include +#include // Needed for FLT_EPSILON +#include "basetypes.h" +#include +#include "tier0/dbg.h" +#include "mathlib/mathlib.h" +#include "mathlib/vector.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// Gamma conversion support +//----------------------------------------------------------------------------- +static byte texgammatable[256]; // palette is sent through this to convert to screen gamma + +static float texturetolinear[256]; // texture (0..255) to linear (0..1) +static int lineartotexture[1024]; // linear (0..1) to texture (0..255) +static int lineartoscreen[1024]; // linear (0..1) to gamma corrected vertex light (0..255) + +// build a lightmap texture to combine with surface texture, adjust for src*dst+dst*src, ramp reprogramming, etc +float lineartovertex[4096]; // linear (0..4) to screen corrected vertex space (0..1?) +unsigned char lineartolightmap[4096]; // linear (0..4) to screen corrected texture value (0..255) + +static float g_Mathlib_GammaToLinear[256]; // gamma (0..1) to linear (0..1) +static float g_Mathlib_LinearToGamma[256]; // linear (0..1) to gamma (0..1) + +// This is aligned to 16-byte boundaries so that we can load it +// onto SIMD registers easily if needed (used by SSE version of lightmaps) +// TODO: move this into the one DLL that actually uses it, instead of statically +// linking it everywhere via mathlib. +ALIGN128 float power2_n[256] = // 2**(index - 128) / 255 +{ + 1.152445441982634800E-041, 2.304890883965269600E-041, 4.609781767930539200E-041, 9.219563535861078400E-041, + 1.843912707172215700E-040, 3.687825414344431300E-040, 7.375650828688862700E-040, 1.475130165737772500E-039, + 2.950260331475545100E-039, 5.900520662951090200E-039, 1.180104132590218000E-038, 2.360208265180436100E-038, + 4.720416530360872100E-038, 9.440833060721744200E-038, 1.888166612144348800E-037, 3.776333224288697700E-037, + 7.552666448577395400E-037, 1.510533289715479100E-036, 3.021066579430958200E-036, 6.042133158861916300E-036, + 1.208426631772383300E-035, 2.416853263544766500E-035, 4.833706527089533100E-035, 9.667413054179066100E-035, + 1.933482610835813200E-034, 3.866965221671626400E-034, 7.733930443343252900E-034, 1.546786088668650600E-033, + 3.093572177337301200E-033, 6.187144354674602300E-033, 1.237428870934920500E-032, 2.474857741869840900E-032, + 4.949715483739681800E-032, 9.899430967479363700E-032, 1.979886193495872700E-031, 3.959772386991745500E-031, + 7.919544773983491000E-031, 1.583908954796698200E-030, 3.167817909593396400E-030, 6.335635819186792800E-030, + 1.267127163837358600E-029, 2.534254327674717100E-029, 5.068508655349434200E-029, 1.013701731069886800E-028, + 2.027403462139773700E-028, 4.054806924279547400E-028, 8.109613848559094700E-028, 1.621922769711818900E-027, + 3.243845539423637900E-027, 6.487691078847275800E-027, 1.297538215769455200E-026, 2.595076431538910300E-026, + 5.190152863077820600E-026, 1.038030572615564100E-025, 2.076061145231128300E-025, 4.152122290462256500E-025, + 8.304244580924513000E-025, 1.660848916184902600E-024, 3.321697832369805200E-024, 6.643395664739610400E-024, + 1.328679132947922100E-023, 2.657358265895844200E-023, 5.314716531791688300E-023, 1.062943306358337700E-022, + 2.125886612716675300E-022, 4.251773225433350700E-022, 8.503546450866701300E-022, 1.700709290173340300E-021, + 3.401418580346680500E-021, 6.802837160693361100E-021, 1.360567432138672200E-020, 2.721134864277344400E-020, + 5.442269728554688800E-020, 1.088453945710937800E-019, 2.176907891421875500E-019, 4.353815782843751100E-019, + 8.707631565687502200E-019, 1.741526313137500400E-018, 3.483052626275000900E-018, 6.966105252550001700E-018, + 1.393221050510000300E-017, 2.786442101020000700E-017, 5.572884202040001400E-017, 1.114576840408000300E-016, + 2.229153680816000600E-016, 4.458307361632001100E-016, 8.916614723264002200E-016, 1.783322944652800400E-015, + 3.566645889305600900E-015, 7.133291778611201800E-015, 1.426658355722240400E-014, 2.853316711444480700E-014, + 5.706633422888961400E-014, 1.141326684577792300E-013, 2.282653369155584600E-013, 4.565306738311169100E-013, + 9.130613476622338300E-013, 1.826122695324467700E-012, 3.652245390648935300E-012, 7.304490781297870600E-012, + 1.460898156259574100E-011, 2.921796312519148200E-011, 5.843592625038296500E-011, 1.168718525007659300E-010, + 2.337437050015318600E-010, 4.674874100030637200E-010, 9.349748200061274400E-010, 1.869949640012254900E-009, + 3.739899280024509800E-009, 7.479798560049019500E-009, 1.495959712009803900E-008, 2.991919424019607800E-008, + 5.983838848039215600E-008, 1.196767769607843100E-007, 2.393535539215686200E-007, 4.787071078431372500E-007, + 9.574142156862745000E-007, 1.914828431372549000E-006, 3.829656862745098000E-006, 7.659313725490196000E-006, + 1.531862745098039200E-005, 3.063725490196078400E-005, 6.127450980392156800E-005, 1.225490196078431400E-004, + 2.450980392156862700E-004, 4.901960784313725400E-004, 9.803921568627450800E-004, 1.960784313725490200E-003, + 3.921568627450980300E-003, 7.843137254901960700E-003, 1.568627450980392100E-002, 3.137254901960784300E-002, + 6.274509803921568500E-002, 1.254901960784313700E-001, 2.509803921568627400E-001, 5.019607843137254800E-001, + 1.003921568627451000E+000, 2.007843137254901900E+000, 4.015686274509803900E+000, 8.031372549019607700E+000, + 1.606274509803921500E+001, 3.212549019607843100E+001, 6.425098039215686200E+001, 1.285019607843137200E+002, + 2.570039215686274500E+002, 5.140078431372548900E+002, 1.028015686274509800E+003, 2.056031372549019600E+003, + 4.112062745098039200E+003, 8.224125490196078300E+003, 1.644825098039215700E+004, 3.289650196078431300E+004, + 6.579300392156862700E+004, 1.315860078431372500E+005, 2.631720156862745100E+005, 5.263440313725490100E+005, + 1.052688062745098000E+006, 2.105376125490196000E+006, 4.210752250980392100E+006, 8.421504501960784200E+006, + 1.684300900392156800E+007, 3.368601800784313700E+007, 6.737203601568627400E+007, 1.347440720313725500E+008, + 2.694881440627450900E+008, 5.389762881254901900E+008, 1.077952576250980400E+009, 2.155905152501960800E+009, + 4.311810305003921500E+009, 8.623620610007843000E+009, 1.724724122001568600E+010, 3.449448244003137200E+010, + 6.898896488006274400E+010, 1.379779297601254900E+011, 2.759558595202509800E+011, 5.519117190405019500E+011, + 1.103823438081003900E+012, 2.207646876162007800E+012, 4.415293752324015600E+012, 8.830587504648031200E+012, + 1.766117500929606200E+013, 3.532235001859212500E+013, 7.064470003718425000E+013, 1.412894000743685000E+014, + 2.825788001487370000E+014, 5.651576002974740000E+014, 1.130315200594948000E+015, 2.260630401189896000E+015, + 4.521260802379792000E+015, 9.042521604759584000E+015, 1.808504320951916800E+016, 3.617008641903833600E+016, + 7.234017283807667200E+016, 1.446803456761533400E+017, 2.893606913523066900E+017, 5.787213827046133800E+017, + 1.157442765409226800E+018, 2.314885530818453500E+018, 4.629771061636907000E+018, 9.259542123273814000E+018, + 1.851908424654762800E+019, 3.703816849309525600E+019, 7.407633698619051200E+019, 1.481526739723810200E+020, + 2.963053479447620500E+020, 5.926106958895241000E+020, 1.185221391779048200E+021, 2.370442783558096400E+021, + 4.740885567116192800E+021, 9.481771134232385600E+021, 1.896354226846477100E+022, 3.792708453692954200E+022, + 7.585416907385908400E+022, 1.517083381477181700E+023, 3.034166762954363400E+023, 6.068333525908726800E+023, + 1.213666705181745400E+024, 2.427333410363490700E+024, 4.854666820726981400E+024, 9.709333641453962800E+024, + 1.941866728290792600E+025, 3.883733456581585100E+025, 7.767466913163170200E+025, 1.553493382632634000E+026, + 3.106986765265268100E+026, 6.213973530530536200E+026, 1.242794706106107200E+027, 2.485589412212214500E+027, + 4.971178824424429000E+027, 9.942357648848857900E+027, 1.988471529769771600E+028, 3.976943059539543200E+028, + 7.953886119079086300E+028, 1.590777223815817300E+029, 3.181554447631634500E+029, 6.363108895263269100E+029, + 1.272621779052653800E+030, 2.545243558105307600E+030, 5.090487116210615300E+030, 1.018097423242123100E+031, + 2.036194846484246100E+031, 4.072389692968492200E+031, 8.144779385936984400E+031, 1.628955877187396900E+032, + 3.257911754374793800E+032, 6.515823508749587500E+032, 1.303164701749917500E+033, 2.606329403499835000E+033, + 5.212658806999670000E+033, 1.042531761399934000E+034, 2.085063522799868000E+034, 4.170127045599736000E+034, + 8.340254091199472000E+034, 1.668050818239894400E+035, 3.336101636479788800E+035, 6.672203272959577600E+035 +}; + +// You can use this to double check the exponent table and assert that +// the precomputation is correct. +#ifdef DBGFLAG_ASSERT +#pragma warning(push) +#pragma warning( disable : 4189 ) // disable unused local variable warning +static void CheckExponentTable() +{ + for( int i = 0; i < 256; i++ ) + { + float testAgainst = pow( 2.0f, i - 128 ) / 255.0f; + float diff = testAgainst - power2_n[i] ; + float relativeDiff = diff / testAgainst; + Assert( testAgainst == 0 ? + power2_n[i] < 1.16E-041 : + power2_n[i] == testAgainst ); + } +} +#pragma warning(pop) +#endif + +void BuildGammaTable( float gamma, float texGamma, float brightness, int overbright ) +{ + int i, inf; + float g1, g3; + + // Con_Printf("BuildGammaTable %.1f %.1f %.1f\n", g, v_lightgamma.GetFloat(), v_texgamma.GetFloat() ); + + float g = gamma; + if (g > 3.0) + { + g = 3.0; + } + + g = 1.0 / g; + g1 = texGamma * g; + + if (brightness <= 0.0) + { + g3 = 0.125; + } + else if (brightness > 1.0) + { + g3 = 0.05; + } + else + { + g3 = 0.125 - (brightness * brightness) * 0.075; + } + + for (i=0 ; i<256 ; i++) + { + inf = 255 * pow ( i/255.f, g1 ); + if (inf < 0) + inf = 0; + if (inf > 255) + inf = 255; + texgammatable[i] = inf; + } + + for (i=0 ; i<1024 ; i++) + { + float f; + + f = i / 1023.0; + + // scale up + if (brightness > 1.0) + f = f * brightness; + + // shift up + if (f <= g3) + f = (f / g3) * 0.125; + else + f = 0.125 + ((f - g3) / (1.0 - g3)) * 0.875; + + // convert linear space to desired gamma space + inf = 255 * pow ( f, g ); + + if (inf < 0) + inf = 0; + if (inf > 255) + inf = 255; + lineartoscreen[i] = inf; + } + + /* + for (i=0 ; i<1024 ; i++) + { + // convert from screen gamma space to linear space + lineargammatable[i] = 1023 * pow ( i/1023.0, v_gamma.GetFloat() ); + // convert from linear gamma space to screen space + screengammatable[i] = 1023 * pow ( i/1023.0, 1.0 / v_gamma.GetFloat() ); + } + */ + + for (i=0 ; i<256 ; i++) + { + // convert from nonlinear texture space (0..255) to linear space (0..1) + texturetolinear[i] = pow( i / 255.f, texGamma ); + + // convert from linear space (0..1) to nonlinear (sRGB) space (0..1) + g_Mathlib_LinearToGamma[i] = LinearToGammaFullRange( i / 255.f ); + + // convert from sRGB gamma space (0..1) to linear space (0..1) + g_Mathlib_GammaToLinear[i] = GammaToLinearFullRange( i / 255.f ); + } + + for (i=0 ; i<1024 ; i++) + { + // convert from linear space (0..1) to nonlinear texture space (0..255) + lineartotexture[i] = pow( i / 1023.0, 1.0 / texGamma ) * 255; + } + +#if 0 + for (i=0 ; i<256 ; i++) + { + float f; + + // convert from nonlinear lightmap space (0..255) to linear space (0..4) + // f = (i / 255.0) * sqrt( 4 ); + f = i * (2.0 / 255.0); + f = f * f; + + texlighttolinear[i] = f; + } +#endif + + { + float f; + float overbrightFactor = 1.0f; + + // Can't do overbright without texcombine + // UNDONE: Add GAMMA ramp to rectify this + if ( overbright == 2 ) + { + overbrightFactor = 0.5; + } + else if ( overbright == 4 ) + { + overbrightFactor = 0.25; + } + + for (i=0 ; i<4096 ; i++) + { + // convert from linear 0..4 (x1024) to screen corrected vertex space (0..1?) + f = pow ( i/1024.0, 1.0 / gamma ); + + lineartovertex[i] = f * overbrightFactor; + if (lineartovertex[i] > 1) + lineartovertex[i] = 1; + + int nLightmap = RoundFloatToInt( f * 255 * overbrightFactor ); + nLightmap = clamp( nLightmap, 0, 255 ); + lineartolightmap[i] = (unsigned char)nLightmap; + } + } +} + +float GammaToLinearFullRange( float gamma ) +{ + return pow( gamma, 2.2f ); +} + +float LinearToGammaFullRange( float linear ) +{ + return pow( linear, 1.0f / 2.2f ); +} + +float GammaToLinear( float gamma ) +{ + Assert( s_bMathlibInitialized ); + if ( gamma < 0.0f ) + { + return 0.0f; + } + + if ( gamma >= 0.95f ) + { + // Use GammaToLinearFullRange maybe if you trip this. +// X360TEMP +// Assert( gamma <= 1.0f ); + return 1.0f; + } + + int index = RoundFloatToInt( gamma * 255.0f ); + Assert( index >= 0 && index < 256 ); + return g_Mathlib_GammaToLinear[index]; +} + +float LinearToGamma( float linear ) +{ + Assert( s_bMathlibInitialized ); + if ( linear < 0.0f ) + { + return 0.0f; + } + if ( linear > 1.0f ) + { + // Use LinearToGammaFullRange maybe if you trip this. + Assert( 0 ); + return 1.0f; + } + + int index = RoundFloatToInt( linear * 255.0f ); + Assert( index >= 0 && index < 256 ); + return g_Mathlib_LinearToGamma[index]; +} + +//----------------------------------------------------------------------------- +// Helper functions to convert between sRGB and 360 gamma space +//----------------------------------------------------------------------------- +float SrgbGammaToLinear( float flSrgbGammaValue ) +{ + float x = clamp( flSrgbGammaValue, 0.0f, 1.0f ); + return ( x <= 0.04045f ) ? ( x / 12.92f ) : ( pow( ( x + 0.055f ) / 1.055f, 2.4f ) ); +} + +float SrgbLinearToGamma( float flLinearValue ) +{ + float x = clamp( flLinearValue, 0.0f, 1.0f ); + return ( x <= 0.0031308f ) ? ( x * 12.92f ) : ( 1.055f * pow( x, ( 1.0f / 2.4f ) ) ) - 0.055f; +} + +float X360GammaToLinear( float fl360GammaValue ) +{ + float flLinearValue; + + fl360GammaValue = clamp( fl360GammaValue, 0.0f, 1.0f ); + if ( fl360GammaValue < ( 96.0f / 255.0f ) ) + { + if ( fl360GammaValue < ( 64.0f / 255.0f ) ) + { + flLinearValue = fl360GammaValue * 255.0f; + } + else + { + flLinearValue = fl360GammaValue * ( 255.0f * 2.0f ) - 64.0f; + flLinearValue += floor( flLinearValue * ( 1.0f / 512.0f ) ); + } + } + else + { + if( fl360GammaValue < ( 192.0f / 255.0f ) ) + { + flLinearValue = fl360GammaValue * ( 255.0f * 4.0f ) - 256.0f; + flLinearValue += floor( flLinearValue * ( 1.0f / 256.0f ) ); + } + else + { + flLinearValue = fl360GammaValue * ( 255.0f * 8.0f ) - 1024.0f; + flLinearValue += floor( flLinearValue * ( 1.0f / 128.0f ) ); + } + } + + flLinearValue *= 1.0f / 1023.0f; + + flLinearValue = clamp( flLinearValue, 0.0f, 1.0f ); + return flLinearValue; +} + +float X360LinearToGamma( float flLinearValue ) +{ + float fl360GammaValue; + + flLinearValue = clamp( flLinearValue, 0.0f, 1.0f ); + if ( flLinearValue < ( 128.0f / 1023.0f ) ) + { + if ( flLinearValue < ( 64.0f / 1023.0f ) ) + { + fl360GammaValue = flLinearValue * ( 1023.0f * ( 1.0f / 255.0f ) ); + } + else + { + fl360GammaValue = flLinearValue * ( ( 1023.0f / 2.0f ) * ( 1.0f / 255.0f ) ) + ( 32.0f / 255.0f ); + } + } + else + { + if ( flLinearValue < ( 512.0f / 1023.0f ) ) + { + fl360GammaValue = flLinearValue * ( ( 1023.0f / 4.0f ) * ( 1.0f / 255.0f ) ) + ( 64.0f / 255.0f ); + } + else + { + fl360GammaValue = flLinearValue * ( ( 1023.0f /8.0f ) * ( 1.0f / 255.0f ) ) + ( 128.0f /255.0f ); // 1.0 -> 1.0034313725490196078431372549016 + if ( fl360GammaValue > 1.0f ) + { + fl360GammaValue = 1.0f; + } + } + } + + fl360GammaValue = clamp( fl360GammaValue, 0.0f, 1.0f ); + return fl360GammaValue; +} + +float SrgbGammaTo360Gamma( float flSrgbGammaValue ) +{ + float flLinearValue = SrgbGammaToLinear( flSrgbGammaValue ); + float fl360GammaValue = X360LinearToGamma( flLinearValue ); + return fl360GammaValue; +} + +// convert texture to linear 0..1 value +float TextureToLinear( int c ) +{ + Assert( s_bMathlibInitialized ); + if (c < 0) + return 0; + if (c > 255) + return 1.0; + + return texturetolinear[c]; +} + +// convert texture to linear 0..1 value +int LinearToTexture( float f ) +{ + Assert( s_bMathlibInitialized ); + int i; + i = f * 1023; // assume 0..1 range + if (i < 0) + i = 0; + if (i > 1023) + i = 1023; + + return lineartotexture[i]; +} + + +// converts 0..1 linear value to screen gamma (0..255) +int LinearToScreenGamma( float f ) +{ + Assert( s_bMathlibInitialized ); + int i; + i = f * 1023; // assume 0..1 range + if (i < 0) + i = 0; + if (i > 1023) + i = 1023; + + return lineartoscreen[i]; +} + +void ColorRGBExp32ToVector( const ColorRGBExp32& in, Vector& out ) +{ + Assert( s_bMathlibInitialized ); + // FIXME: Why is there a factor of 255 built into this? + out.x = 255.0f * TexLightToLinear( in.r, in.exponent ); + out.y = 255.0f * TexLightToLinear( in.g, in.exponent ); + out.z = 255.0f * TexLightToLinear( in.b, in.exponent ); +} + +#if 0 +// assumes that the desired mantissa range is 128..255 +static int VectorToColorRGBExp32_CalcExponent( float in ) +{ + int power = 0; + + if( in != 0.0f ) + { + while( in > 255.0f ) + { + power += 1; + in *= 0.5f; + } + + while( in < 128.0f ) + { + power -= 1; + in *= 2.0f; + } + } + + return power; +} + +void VectorToColorRGBExp32( const Vector& vin, ColorRGBExp32 &c ) +{ + Vector v = vin; + Assert( s_bMathlibInitialized ); + Assert( v.x >= 0.0f && v.y >= 0.0f && v.z >= 0.0f ); + int i; + float max = v[0]; + for( i = 1; i < 3; i++ ) + { + // Get the maximum value. + if( v[i] > max ) + { + max = v[i]; + } + } + + // figure out the exponent for this luxel. + int exponent = VectorToColorRGBExp32_CalcExponent( max ); + + // make the exponent fits into a signed byte. + if( exponent < -128 ) + { + exponent = -128; + } + else if( exponent > 127 ) + { + exponent = 127; + } + + // undone: optimize with a table + float scalar = pow( 2.0f, -exponent ); + // convert to mantissa x 2^exponent format + for( i = 0; i < 3; i++ ) + { + v[i] *= scalar; + // clamp + if( v[i] > 255.0f ) + { + v[i] = 255.0f; + } + } + c.r = ( unsigned char )v[0]; + c.g = ( unsigned char )v[1]; + c.b = ( unsigned char )v[2]; + c.exponent = ( signed char )exponent; +} + +#else + +// given a floating point number f, return an exponent e such that +// for f' = f * 2^e, f is on [128..255]. +// Uses IEEE 754 representation to directly extract this information +// from the float. +inline static int VectorToColorRGBExp32_CalcExponent( const float *pin ) +{ + // The thing we will take advantage of here is that the exponent component + // is stored in the float itself, and because we want to map to 128..255, we + // want an "ideal" exponent of 2^7. So, we compute the difference between the + // input exponent and 7 to work out the normalizing exponent. Thus if you pass in + // 32 (represented in IEEE 754 as 2^5), this function will return 2 + // (because 32 * 2^2 = 128) + if (*pin == 0.0f) + return 0; + + unsigned int fbits = *reinterpret_cast(pin); + + // the exponent component is bits 23..30, and biased by +127 + const unsigned int biasedSeven = 7 + 127; + + signed int expComponent = ( fbits & 0x7F800000 ) >> 23; + expComponent -= biasedSeven; // now the difference from seven (positive if was less than, etc) + return expComponent; +} + + + +/// Slightly faster version of the function to turn a float-vector color into +/// a compressed-exponent notation 32bit color. However, still not SIMD optimized. +/// PS3 developer: note there is a movement of a float onto an int here, which is +/// bad on the base registers -- consider doing this as Altivec code, or better yet +/// moving it onto the cell. +/// \warning: Assumes an IEEE 754 single-precision float representation! Those of you +/// porting to an 8080 are out of luck. +void VectorToColorRGBExp32( const Vector& vin, ColorRGBExp32 &c ) +{ + Assert( s_bMathlibInitialized ); + Assert( vin.x >= 0.0f && vin.y >= 0.0f && vin.z >= 0.0f ); + + // work out which of the channels is the largest ( we will use that to map the exponent ) + // this is a sluggish branch-based decision tree -- most architectures will offer a [max] + // assembly opcode to do this faster. + const float *pMax; + if (vin.x > vin.y) + { + if (vin.x > vin.z) + { + pMax = &vin.x; + } + else + { + pMax = &vin.z; + } + } + else + { + if (vin.y > vin.z) + { + pMax = &vin.y; + } + else + { + pMax = &vin.z; + } + } + + // now work out the exponent for this luxel. + signed int exponent = VectorToColorRGBExp32_CalcExponent( pMax ); + + // make sure the exponent fits into a signed byte. + // (in single precision format this is assured because it was a signed byte to begin with) + Assert(exponent > -128 && exponent <= 127); + + // promote the exponent back onto a scalar that we'll use to normalize all the numbers + float scalar; + { + unsigned int fbits = (127 - exponent) << 23; + scalar = *reinterpret_cast(&fbits); + } + + // we should never need to clamp: + Assert(vin.x * scalar <= 255.0f && + vin.y * scalar <= 255.0f && + vin.z * scalar <= 255.0f); + + // This awful construction is necessary to prevent VC2005 from using the + // fldcw/fnstcw control words around every float-to-unsigned-char operation. + { + int red = (vin.x * scalar); + int green = (vin.y * scalar); + int blue = (vin.z * scalar); + + c.r = red; + c.g = green; + c.b = blue; + } + /* + c.r = ( unsigned char )(vin.x * scalar); + c.g = ( unsigned char )(vin.y * scalar); + c.b = ( unsigned char )(vin.z * scalar); + */ + + c.exponent = ( signed char )exponent; +} + +#endif \ No newline at end of file diff --git a/sp/src/mathlib/datagen.pl b/sp/src/mathlib/datagen.pl new file mode 100644 index 00000000..9646002d --- /dev/null +++ b/sp/src/mathlib/datagen.pl @@ -0,0 +1,63 @@ +#! perl +use Text::Wrap; + +# generate output data for noise generators + +srand(31456); + +print < + +HaltonSequenceGenerator_t::HaltonSequenceGenerator_t(int b) +{ + base=b; + fbase=(float) b; + seed=1; + +} + +float HaltonSequenceGenerator_t::GetElement(int elem) +{ + int tmpseed=seed; + float ret=0.0; + float base_inv=1.0/fbase; + while(tmpseed) + { + int dig=tmpseed % base; + ret+=((float) dig)*base_inv; + base_inv/=fbase; + tmpseed/=base; + } + return ret; +} diff --git a/sp/src/mathlib/imagequant.cpp b/sp/src/mathlib/imagequant.cpp new file mode 100644 index 00000000..47ba4f4c --- /dev/null +++ b/sp/src/mathlib/imagequant.cpp @@ -0,0 +1,96 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#include +#include + +#define N_EXTRAVALUES 1 +#define N_DIMENSIONS (3+N_EXTRAVALUES) + +#define PIXEL(x,y,c) Image[4*((x)+((Width*(y))))+c] + +static uint8 Weights[]={5,7,4,8}; +static int ExtraValueXForms[3*N_EXTRAVALUES]={ + 76,151,28, +}; + + + +#define MAX_QUANTIZE_IMAGE_WIDTH 4096 + +void ColorQuantize(uint8 const *Image, + int Width, + int Height, + int flags, int ncolors, + uint8 *out_pixels, + uint8 *out_palette, + int firstcolor) +{ + int Error[MAX_QUANTIZE_IMAGE_WIDTH+1][3][2]; + struct Sample *s=AllocSamples(Width*Height,N_DIMENSIONS); + int x,y,c; + for(y=0;yValue[c]=PIXEL(x,y,c); + // now, let's generate extra values to quantize on + for(int i=0;i>=8; + NthSample(s,y*Width+x,N_DIMENSIONS)->Value[c]=(uint8) + (min(255,max(0,val1))); + } + } + struct QuantizedValue *q=Quantize(s,Width*Height,N_DIMENSIONS, + ncolors,Weights,firstcolor); + delete[] s; + memset(out_palette,0x55,768); + for(int p=0;p<256;p++) + { + struct QuantizedValue *v=FindQNode(q,p); + if (v) + for(int c=0;c<3;c++) + out_palette[p*3+c]=v->Mean[c]; + } + memset(Error,0,sizeof(Error)); + for(y=0;yvalue); + if (! (flags & QUANTFLAGS_NODITHER)) + for(int i=0;i<3;i++) + { + int newerr=samp[i]-f->Mean[i]; + int orthog_error=(newerr*3)/8; + Error[x+1][i][ErrorUse]+=orthog_error; + Error[x][i][ErrorUpdate]=orthog_error; + Error[x+1][i][ErrorUpdate]=newerr-2*orthog_error; + } + } + } + if (q) FreeQuantization(q); +} + diff --git a/sp/src/mathlib/lightdesc.cpp b/sp/src/mathlib/lightdesc.cpp new file mode 100644 index 00000000..7d69282d --- /dev/null +++ b/sp/src/mathlib/lightdesc.cpp @@ -0,0 +1,312 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=====================================================================================// + +#include +#include +#include "mathlib.h" + +void LightDesc_t::RecalculateDerivedValues(void) +{ + m_Flags = LIGHTTYPE_OPTIMIZATIONFLAGS_DERIVED_VALUES_CALCED; + if (m_Attenuation0) + m_Flags|=LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION0; + if (m_Attenuation1) + m_Flags|=LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION1; + if (m_Attenuation2) + m_Flags|=LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION2; + + if (m_Type==MATERIAL_LIGHT_SPOT) + { + m_ThetaDot=cos(m_Theta); + m_PhiDot=cos(m_Phi); + float spread=m_ThetaDot-m_PhiDot; + if (spread>1.0e-10) + { + // note - this quantity is very sensitive to round off error. the sse + // reciprocal approximation won't cut it here. + OneOver_ThetaDot_Minus_PhiDot=1.0/spread; + } + else + { + // hard falloff instead of divide by zero + OneOver_ThetaDot_Minus_PhiDot=1.0; + } + } + if (m_Type==MATERIAL_LIGHT_DIRECTIONAL) + { + // set position to be real far away in the right direction + m_Position=m_Direction; + m_Position *= 2.0e6; + } + + m_RangeSquared=m_Range*m_Range; + +} + +void LightDesc_t::ComputeLightAtPointsForDirectional( + const FourVectors &pos, const FourVectors &normal, + FourVectors &color, bool DoHalfLambert ) const +{ + FourVectors delta; + delta.DuplicateVector(m_Direction); +// delta.VectorNormalizeFast(); + fltx4 strength=delta*normal; + if (DoHalfLambert) + { + strength=AddSIMD(MulSIMD(strength,Four_PointFives),Four_PointFives); + } + else + strength=MaxSIMD(Four_Zeros,delta*normal); + + color.x=AddSIMD(color.x,MulSIMD(strength,ReplicateX4(m_Color.x))); + color.y=AddSIMD(color.y,MulSIMD(strength,ReplicateX4(m_Color.y))); + color.z=AddSIMD(color.z,MulSIMD(strength,ReplicateX4(m_Color.z))); +} + + +void LightDesc_t::ComputeLightAtPoints( const FourVectors &pos, const FourVectors &normal, + FourVectors &color, bool DoHalfLambert ) const +{ + FourVectors delta; + Assert((m_Type==MATERIAL_LIGHT_POINT) || (m_Type==MATERIAL_LIGHT_SPOT) || (m_Type==MATERIAL_LIGHT_DIRECTIONAL)); + switch (m_Type) + { + case MATERIAL_LIGHT_POINT: + case MATERIAL_LIGHT_SPOT: + delta.DuplicateVector(m_Position); + delta-=pos; + break; + + case MATERIAL_LIGHT_DIRECTIONAL: + ComputeLightAtPointsForDirectional( pos, normal, color, DoHalfLambert ); + return; + } + + fltx4 dist2 = delta*delta; + + dist2=MaxSIMD( Four_Ones, dist2 ); + + fltx4 falloff; + + if( m_Flags & LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION0 ) + { + falloff = ReplicateX4(m_Attenuation0); + } + else + falloff= Four_Epsilons; + + if( m_Flags & LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION1 ) + { + falloff=AddSIMD(falloff,MulSIMD(ReplicateX4(m_Attenuation1),SqrtEstSIMD(dist2))); + } + + if( m_Flags & LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION2 ) + { + falloff=AddSIMD(falloff,MulSIMD(ReplicateX4(m_Attenuation2),dist2)); + } + + falloff=ReciprocalEstSIMD(falloff); + // Cull out light beyond this radius + // now, zero out elements for which dist2 was > range^2. !!speed!! lights should store dist^2 in sse format + if (m_Range != 0.f) + { + fltx4 RangeSquared=ReplicateX4(m_RangeSquared); // !!speed!! + falloff=AndSIMD(falloff,CmpLtSIMD(dist2,RangeSquared)); + } + + delta.VectorNormalizeFast(); + fltx4 strength=delta*normal; + if (DoHalfLambert) + { + strength=AddSIMD(MulSIMD(strength,Four_PointFives),Four_PointFives); + } + else + strength=MaxSIMD(Four_Zeros,delta*normal); + + switch(m_Type) + { + case MATERIAL_LIGHT_POINT: + // half-lambert + break; + + case MATERIAL_LIGHT_SPOT: + { + fltx4 dot2=SubSIMD(Four_Zeros,delta*m_Direction); // dot position with spot light dir for cone falloff + + + fltx4 cone_falloff_scale=MulSIMD(ReplicateX4(OneOver_ThetaDot_Minus_PhiDot), + SubSIMD(dot2,ReplicateX4(m_PhiDot))); + cone_falloff_scale=MinSIMD(cone_falloff_scale,Four_Ones); + + if ((m_Falloff!=0.0) && (m_Falloff!=1.0)) + { + // !!speed!! could compute integer exponent needed by powsimd and store in light + cone_falloff_scale=PowSIMD(cone_falloff_scale,m_Falloff); + } + strength=MulSIMD(cone_falloff_scale,strength); + + // now, zero out lighting where dot2 range^2. !!speed!! lights should store dist^2 in sse format + if (m_Range != 0.f) + { + fltx4 RangeSquared=ReplicateX4(m_RangeSquared); // !!speed!! + falloff=AndSIMD(falloff,CmpLtSIMD(dist2,RangeSquared)); + } + + delta.VectorNormalizeFast(); + fltx4 strength = Four_Ones; + //fltx4 strength=delta; + //fltx4 strength = MaxSIMD(Four_Zeros,delta); + + switch(m_Type) + { + case MATERIAL_LIGHT_POINT: + // half-lambert + break; + + case MATERIAL_LIGHT_SPOT: + { + fltx4 dot2=SubSIMD(Four_Zeros,delta*m_Direction); // dot position with spot light dir for cone falloff + + + fltx4 cone_falloff_scale=MulSIMD(ReplicateX4(OneOver_ThetaDot_Minus_PhiDot), + SubSIMD(dot2,ReplicateX4(m_PhiDot))); + cone_falloff_scale=MinSIMD(cone_falloff_scale,Four_Ones); + + if ((m_Falloff!=0.0) && (m_Falloff!=1.0)) + { + // !!speed!! could compute integer exponent needed by powsimd and store in light + cone_falloff_scale=PowSIMD(cone_falloff_scale,m_Falloff); + } + strength=MulSIMD(cone_falloff_scale,strength); + + // now, zero out lighting where dot2 0 ) + m_Color *= fScaleFactor; +} + +void LightDesc_t::SetupNewStyleAttenuation( float fFiftyPercentDistance, + float fZeroPercentDistance ) +{ + // new style storing 50% and 0% distances + float d50=fFiftyPercentDistance; + float d0=fZeroPercentDistance; + if (d0 +#include // Needed for FLT_EPSILON + +#include "tier0/basetypes.h" +#include +#include "tier0/dbg.h" + +#include "tier0/vprof.h" +//#define _VPROF_MATHLIB + +#pragma warning(disable:4244) // "conversion from 'const int' to 'float', possible loss of data" +#pragma warning(disable:4730) // "mixing _m64 and floating point expressions may result in incorrect code" + +#include "mathlib/mathlib.h" +#include "mathlib/vector.h" +#if !defined( _X360 ) +#include "mathlib/amd3dx.h" +#ifndef OSX +#include "3dnow.h" +#endif +#include "sse.h" +#endif + +#include "mathlib/ssemath.h" +#include "mathlib/ssequaternion.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +bool s_bMathlibInitialized = false; + +#ifdef PARANOID +// User must provide an implementation of Sys_Error() +void Sys_Error (char *error, ...); +#endif + +const Vector vec3_origin(0,0,0); +const QAngle vec3_angle(0,0,0); +const Vector vec3_invalid( FLT_MAX, FLT_MAX, FLT_MAX ); +const int nanmask = 255<<23; + +//----------------------------------------------------------------------------- +// Standard C implementations of optimized routines: +//----------------------------------------------------------------------------- +float _sqrtf(float _X) +{ + Assert( s_bMathlibInitialized ); + return sqrtf(_X); +} + +float _rsqrtf(float x) +{ + Assert( s_bMathlibInitialized ); + + return 1.f / _sqrtf( x ); +} + +float FASTCALL _VectorNormalize (Vector& vec) +{ +#ifdef _VPROF_MATHLIB + VPROF_BUDGET( "_VectorNormalize", "Mathlib" ); +#endif + Assert( s_bMathlibInitialized ); + float radius = sqrtf(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z); + + // FLT_EPSILON is added to the radius to eliminate the possibility of divide by zero. + float iradius = 1.f / ( radius + FLT_EPSILON ); + + vec.x *= iradius; + vec.y *= iradius; + vec.z *= iradius; + + return radius; +} + +// TODO: Add fast C VectorNormalizeFast. +// Perhaps use approximate rsqrt trick, if the accuracy isn't too bad. +void FASTCALL _VectorNormalizeFast (Vector& vec) +{ + Assert( s_bMathlibInitialized ); + + // FLT_EPSILON is added to the radius to eliminate the possibility of divide by zero. + float iradius = 1.f / ( sqrtf(vec.x*vec.x + vec.y*vec.y + vec.z*vec.z) + FLT_EPSILON ); + + vec.x *= iradius; + vec.y *= iradius; + vec.z *= iradius; + +} + +float _InvRSquared(const float* v) +{ + Assert( s_bMathlibInitialized ); + float r2 = DotProduct(v, v); + return r2 < 1.f ? 1.f : 1/r2; +} + +//----------------------------------------------------------------------------- +// Function pointers selecting the appropriate implementation +//----------------------------------------------------------------------------- +float (*pfSqrt)(float x) = _sqrtf; +float (*pfRSqrt)(float x) = _rsqrtf; +float (*pfRSqrtFast)(float x) = _rsqrtf; +float (FASTCALL *pfVectorNormalize)(Vector& v) = _VectorNormalize; +void (FASTCALL *pfVectorNormalizeFast)(Vector& v) = _VectorNormalizeFast; +float (*pfInvRSquared)(const float* v) = _InvRSquared; +void (*pfFastSinCos)(float x, float* s, float* c) = SinCos; +float (*pfFastCos)(float x) = cosf; + +float SinCosTable[SIN_TABLE_SIZE]; +void InitSinCosTable() +{ + for( int i = 0; i < SIN_TABLE_SIZE; i++ ) + { + SinCosTable[i] = sin(i * 2.0 * M_PI / SIN_TABLE_SIZE); + } +} + +qboolean VectorsEqual( const float *v1, const float *v2 ) +{ + Assert( s_bMathlibInitialized ); + return ( ( v1[0] == v2[0] ) && + ( v1[1] == v2[1] ) && + ( v1[2] == v2[2] ) ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Generates Euler angles given a left-handed orientation matrix. The +// columns of the matrix contain the forward, left, and up vectors. +// Input : matrix - Left-handed orientation matrix. +// angles[PITCH, YAW, ROLL]. Receives right-handed counterclockwise +// rotations in degrees around Y, Z, and X respectively. +//----------------------------------------------------------------------------- + +void MatrixAngles( const matrix3x4_t& matrix, RadianEuler &angles, Vector &position ) +{ + MatrixGetColumn( matrix, 3, position ); + MatrixAngles( matrix, angles ); +} + +void MatrixAngles( const matrix3x4_t &matrix, Quaternion &q, Vector &pos ) +{ +#ifdef _VPROF_MATHLIB + VPROF_BUDGET( "MatrixQuaternion", "Mathlib" ); +#endif + float trace; + trace = matrix[0][0] + matrix[1][1] + matrix[2][2] + 1.0f; + if( trace > 1.0f + FLT_EPSILON ) + { + // VPROF_INCREMENT_COUNTER("MatrixQuaternion A",1); + q.x = ( matrix[2][1] - matrix[1][2] ); + q.y = ( matrix[0][2] - matrix[2][0] ); + q.z = ( matrix[1][0] - matrix[0][1] ); + q.w = trace; + } + else if ( matrix[0][0] > matrix[1][1] && matrix[0][0] > matrix[2][2] ) + { + // VPROF_INCREMENT_COUNTER("MatrixQuaternion B",1); + trace = 1.0f + matrix[0][0] - matrix[1][1] - matrix[2][2]; + q.x = trace; + q.y = (matrix[1][0] + matrix[0][1] ); + q.z = (matrix[0][2] + matrix[2][0] ); + q.w = (matrix[2][1] - matrix[1][2] ); + } + else if (matrix[1][1] > matrix[2][2]) + { + // VPROF_INCREMENT_COUNTER("MatrixQuaternion C",1); + trace = 1.0f + matrix[1][1] - matrix[0][0] - matrix[2][2]; + q.x = (matrix[0][1] + matrix[1][0] ); + q.y = trace; + q.z = (matrix[2][1] + matrix[1][2] ); + q.w = (matrix[0][2] - matrix[2][0] ); + } + else + { + // VPROF_INCREMENT_COUNTER("MatrixQuaternion D",1); + trace = 1.0f + matrix[2][2] - matrix[0][0] - matrix[1][1]; + q.x = (matrix[0][2] + matrix[2][0] ); + q.y = (matrix[2][1] + matrix[1][2] ); + q.z = trace; + q.w = (matrix[1][0] - matrix[0][1] ); + } + + QuaternionNormalize( q ); + +#if 0 + // check against the angle version + RadianEuler ang; + MatrixAngles( matrix, ang ); + Quaternion test; + AngleQuaternion( ang, test ); + float d = QuaternionDotProduct( q, test ); + Assert( fabs(d) > 0.99 && fabs(d) < 1.01 ); +#endif + + MatrixGetColumn( matrix, 3, pos ); +} + +void MatrixAngles( const matrix3x4_t& matrix, float *angles ) +{ +#ifdef _VPROF_MATHLIB + VPROF_BUDGET( "MatrixAngles", "Mathlib" ); +#endif + Assert( s_bMathlibInitialized ); + float forward[3]; + float left[3]; + float up[3]; + + // + // Extract the basis vectors from the matrix. Since we only need the Z + // component of the up vector, we don't get X and Y. + // + forward[0] = matrix[0][0]; + forward[1] = matrix[1][0]; + forward[2] = matrix[2][0]; + left[0] = matrix[0][1]; + left[1] = matrix[1][1]; + left[2] = matrix[2][1]; + up[2] = matrix[2][2]; + + float xyDist = sqrtf( forward[0] * forward[0] + forward[1] * forward[1] ); + + // enough here to get angles? + if ( xyDist > 0.001f ) + { + // (yaw) y = ATAN( forward.y, forward.x ); -- in our space, forward is the X axis + angles[1] = RAD2DEG( atan2f( forward[1], forward[0] ) ); + + // (pitch) x = ATAN( -forward.z, sqrt(forward.x*forward.x+forward.y*forward.y) ); + angles[0] = RAD2DEG( atan2f( -forward[2], xyDist ) ); + + // (roll) z = ATAN( left.z, up.z ); + angles[2] = RAD2DEG( atan2f( left[2], up[2] ) ); + } + else // forward is mostly Z, gimbal lock- + { + // (yaw) y = ATAN( -left.x, left.y ); -- forward is mostly z, so use right for yaw + angles[1] = RAD2DEG( atan2f( -left[0], left[1] ) ); + + // (pitch) x = ATAN( -forward.z, sqrt(forward.x*forward.x+forward.y*forward.y) ); + angles[0] = RAD2DEG( atan2f( -forward[2], xyDist ) ); + + // Assume no roll in this case as one degree of freedom has been lost (i.e. yaw == roll) + angles[2] = 0; + } +} + + +// transform in1 by the matrix in2 +void VectorTransform (const float *in1, const matrix3x4_t& in2, float *out) +{ + Assert( s_bMathlibInitialized ); + Assert( in1 != 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]; +} + + +// assuming the matrix is orthonormal, transform in1 by the transpose (also the inverse in this case) of in2. +void VectorITransform (const float *in1, const matrix3x4_t& in2, float *out) +{ + Assert( s_bMathlibInitialized ); + float in1t[3]; + + in1t[0] = in1[0] - in2[0][3]; + in1t[1] = in1[1] - in2[1][3]; + in1t[2] = in1[2] - in2[2][3]; + + out[0] = in1t[0] * in2[0][0] + in1t[1] * in2[1][0] + in1t[2] * in2[2][0]; + out[1] = in1t[0] * in2[0][1] + in1t[1] * in2[1][1] + in1t[2] * in2[2][1]; + out[2] = in1t[0] * in2[0][2] + in1t[1] * in2[1][2] + in1t[2] * in2[2][2]; +} + + +// assume in2 is a rotation and rotate the input vector +void VectorRotate( const float *in1, const matrix3x4_t& in2, float *out ) +{ + Assert( s_bMathlibInitialized ); + Assert( in1 != out ); + out[0] = DotProduct( in1, in2[0] ); + out[1] = DotProduct( in1, in2[1] ); + out[2] = DotProduct( in1, in2[2] ); +} + +// assume in2 is a rotation and rotate the input vector +void VectorRotate( const Vector &in1, const QAngle &in2, Vector &out ) +{ + matrix3x4_t matRotate; + AngleMatrix( in2, matRotate ); + VectorRotate( in1, matRotate, out ); +} + +// assume in2 is a rotation and rotate the input vector +void VectorRotate( const Vector &in1, const Quaternion &in2, Vector &out ) +{ + matrix3x4_t matRotate; + QuaternionMatrix( in2, matRotate ); + VectorRotate( in1, matRotate, out ); +} + + +// rotate by the inverse of the matrix +void VectorIRotate( const float *in1, const matrix3x4_t& in2, float *out ) +{ + Assert( s_bMathlibInitialized ); + Assert( in1 != 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]; +} + +#ifndef VECTOR_NO_SLOW_OPERATIONS +// transform a set of angles in the output space of parentMatrix to the input space +QAngle TransformAnglesToLocalSpace( const QAngle &angles, const matrix3x4_t &parentMatrix ) +{ + matrix3x4_t angToWorld, worldToParent, localMatrix; + MatrixInvert( parentMatrix, worldToParent ); + AngleMatrix( angles, angToWorld ); + ConcatTransforms( worldToParent, angToWorld, localMatrix ); + + QAngle out; + MatrixAngles( localMatrix, out ); + return out; +} + +// transform a set of angles in the input space of parentMatrix to the output space +QAngle TransformAnglesToWorldSpace( const QAngle &angles, const matrix3x4_t &parentMatrix ) +{ + matrix3x4_t angToParent, angToWorld; + AngleMatrix( angles, angToParent ); + ConcatTransforms( parentMatrix, angToParent, angToWorld ); + QAngle out; + MatrixAngles( angToWorld, out ); + return out; +} + +#endif // VECTOR_NO_SLOW_OPERATIONS + +void MatrixInitialize( matrix3x4_t &mat, const Vector &vecOrigin, const Vector &vecXAxis, const Vector &vecYAxis, const Vector &vecZAxis ) +{ + MatrixSetColumn( vecXAxis, 0, mat ); + MatrixSetColumn( vecYAxis, 1, mat ); + MatrixSetColumn( vecZAxis, 2, mat ); + MatrixSetColumn( vecOrigin, 3, mat ); +} + +void MatrixCopy( const matrix3x4_t& in, matrix3x4_t& out ) +{ + Assert( s_bMathlibInitialized ); + memcpy( out.Base(), in.Base(), sizeof( float ) * 3 * 4 ); +} + +//----------------------------------------------------------------------------- +// Matrix equality test +//----------------------------------------------------------------------------- +bool MatricesAreEqual( const matrix3x4_t &src1, const matrix3x4_t &src2, float flTolerance ) +{ + for ( int i = 0; i < 3; ++i ) + { + for ( int j = 0; j < 4; ++j ) + { + if ( fabs( src1[i][j] - src2[i][j] ) > flTolerance ) + return false; + } + } + return true; +} + +// NOTE: This is just the transpose not a general inverse +void MatrixInvert( const matrix3x4_t& in, matrix3x4_t& out ) +{ + Assert( s_bMathlibInitialized ); + if ( &in == &out ) + { + V_swap(out[0][1],out[1][0]); + V_swap(out[0][2],out[2][0]); + V_swap(out[1][2],out[2][1]); + } + else + { + // transpose the matrix + out[0][0] = in[0][0]; + out[0][1] = in[1][0]; + out[0][2] = in[2][0]; + + out[1][0] = in[0][1]; + out[1][1] = in[1][1]; + out[1][2] = in[2][1]; + + out[2][0] = in[0][2]; + out[2][1] = in[1][2]; + out[2][2] = in[2][2]; + } + + // now fix up the translation to be in the other space + float tmp[3]; + tmp[0] = in[0][3]; + tmp[1] = in[1][3]; + tmp[2] = in[2][3]; + + out[0][3] = -DotProduct( tmp, out[0] ); + out[1][3] = -DotProduct( tmp, out[1] ); + out[2][3] = -DotProduct( tmp, out[2] ); +} + +void MatrixGetColumn( const matrix3x4_t& in, int column, Vector &out ) +{ + out.x = in[0][column]; + out.y = in[1][column]; + out.z = in[2][column]; +} + +void MatrixSetColumn( const Vector &in, int column, matrix3x4_t& out ) +{ + out[0][column] = in.x; + out[1][column] = in.y; + out[2][column] = in.z; +} + +void MatrixScaleBy ( const float flScale, matrix3x4_t &out ) +{ + out[0][0] *= flScale; + out[1][0] *= flScale; + out[2][0] *= flScale; + out[0][1] *= flScale; + out[1][1] *= flScale; + out[2][1] *= flScale; + out[0][2] *= flScale; + out[1][2] *= flScale; + out[2][2] *= flScale; +} + +void MatrixScaleByZero ( matrix3x4_t &out ) +{ + out[0][0] = 0.0f; + out[1][0] = 0.0f; + out[2][0] = 0.0f; + out[0][1] = 0.0f; + out[1][1] = 0.0f; + out[2][1] = 0.0f; + out[0][2] = 0.0f; + out[1][2] = 0.0f; + out[2][2] = 0.0f; +} + + + +int VectorCompare (const float *v1, const float *v2) +{ + Assert( s_bMathlibInitialized ); + int i; + + for (i=0 ; i<3 ; i++) + if (v1[i] != v2[i]) + return 0; + + return 1; +} + +void CrossProduct (const float* v1, const float* v2, float* cross) +{ + Assert( s_bMathlibInitialized ); + Assert( v1 != cross ); + Assert( v2 != 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]; +} + +int Q_log2(int val) +{ + int answer=0; + while (val>>=1) + answer++; + return answer; +} + +// Matrix is right-handed x=forward, y=left, z=up. We a left-handed convention for vectors in the game code (forward, right, up) +void MatrixVectors( const matrix3x4_t &matrix, Vector* pForward, Vector *pRight, Vector *pUp ) +{ + MatrixGetColumn( matrix, 0, *pForward ); + MatrixGetColumn( matrix, 1, *pRight ); + MatrixGetColumn( matrix, 2, *pUp ); + *pRight *= -1.0f; +} + + +void VectorVectors( const Vector &forward, Vector &right, Vector &up ) +{ + Assert( s_bMathlibInitialized ); + Vector tmp; + + if (forward[0] == 0 && forward[1] == 0) + { + // pitch 90 degrees up/down from identity + right[0] = 0; + right[1] = -1; + right[2] = 0; + up[0] = -forward[2]; + up[1] = 0; + up[2] = 0; + } + else + { + tmp[0] = 0; tmp[1] = 0; tmp[2] = 1.0; + CrossProduct( forward, tmp, right ); + VectorNormalize( right ); + CrossProduct( right, forward, up ); + VectorNormalize( up ); + } +} + +void VectorMatrix( const Vector &forward, matrix3x4_t& matrix) +{ + Assert( s_bMathlibInitialized ); + Vector right, up; + VectorVectors(forward, right, up); + + MatrixSetColumn( forward, 0, matrix ); + MatrixSetColumn( -right, 1, matrix ); + MatrixSetColumn( up, 2, matrix ); +} + + +void VectorAngles( const float *forward, float *angles ) +{ + Assert( s_bMathlibInitialized ); + float tmp, yaw, pitch; + + if (forward[1] == 0 && forward[0] == 0) + { + yaw = 0; + if (forward[2] > 0) + pitch = 270; + else + pitch = 90; + } + else + { + yaw = (atan2(forward[1], forward[0]) * 180 / M_PI); + if (yaw < 0) + yaw += 360; + + tmp = sqrt (forward[0]*forward[0] + forward[1]*forward[1]); + pitch = (atan2(-forward[2], tmp) * 180 / M_PI); + if (pitch < 0) + pitch += 360; + } + + angles[0] = pitch; + angles[1] = yaw; + angles[2] = 0; +} + + +/* +================ +R_ConcatRotations +================ +*/ +void ConcatRotations (const float in1[3][3], const float in2[3][3], float out[3][3]) +{ + Assert( s_bMathlibInitialized ); + Assert( in1 != out ); + Assert( in2 != out ); + 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[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[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]; +} + +void ConcatTransforms_Aligned( const matrix3x4_t &m0, const matrix3x4_t &m1, matrix3x4_t &out ) +{ + Assert( (((size_t)&m0) % 16) == 0 ); + Assert( (((size_t)&m1) % 16) == 0 ); + Assert( (((size_t)&out) % 16) == 0 ); + + fltx4 lastMask = *(fltx4 *)(&g_SIMD_ComponentMask[3]); + fltx4 rowA0 = LoadAlignedSIMD( m0.m_flMatVal[0] ); + fltx4 rowA1 = LoadAlignedSIMD( m0.m_flMatVal[1] ); + fltx4 rowA2 = LoadAlignedSIMD( m0.m_flMatVal[2] ); + + fltx4 rowB0 = LoadAlignedSIMD( m1.m_flMatVal[0] ); + fltx4 rowB1 = LoadAlignedSIMD( m1.m_flMatVal[1] ); + fltx4 rowB2 = LoadAlignedSIMD( m1.m_flMatVal[2] ); + + // now we have the rows of m0 and the columns of m1 + // first output row + fltx4 A0 = SplatXSIMD(rowA0); + fltx4 A1 = SplatYSIMD(rowA0); + fltx4 A2 = SplatZSIMD(rowA0); + fltx4 mul00 = MulSIMD( A0, rowB0 ); + fltx4 mul01 = MulSIMD( A1, rowB1 ); + fltx4 mul02 = MulSIMD( A2, rowB2 ); + fltx4 out0 = AddSIMD( mul00, AddSIMD(mul01,mul02) ); + + // second output row + A0 = SplatXSIMD(rowA1); + A1 = SplatYSIMD(rowA1); + A2 = SplatZSIMD(rowA1); + fltx4 mul10 = MulSIMD( A0, rowB0 ); + fltx4 mul11 = MulSIMD( A1, rowB1 ); + fltx4 mul12 = MulSIMD( A2, rowB2 ); + fltx4 out1 = AddSIMD( mul10, AddSIMD(mul11,mul12) ); + + // third output row + A0 = SplatXSIMD(rowA2); + A1 = SplatYSIMD(rowA2); + A2 = SplatZSIMD(rowA2); + fltx4 mul20 = MulSIMD( A0, rowB0 ); + fltx4 mul21 = MulSIMD( A1, rowB1 ); + fltx4 mul22 = MulSIMD( A2, rowB2 ); + fltx4 out2 = AddSIMD( mul20, AddSIMD(mul21,mul22) ); + + // add in translation vector + A0 = AndSIMD(rowA0,lastMask); + A1 = AndSIMD(rowA1,lastMask); + A2 = AndSIMD(rowA2,lastMask); + out0 = AddSIMD(out0, A0); + out1 = AddSIMD(out1, A1); + out2 = AddSIMD(out2, A2); + + StoreAlignedSIMD( out.m_flMatVal[0], out0 ); + StoreAlignedSIMD( out.m_flMatVal[1], out1 ); + StoreAlignedSIMD( out.m_flMatVal[2], out2 ); +} + +/* +================ +R_ConcatTransforms +================ +*/ + +void ConcatTransforms (const matrix3x4_t& in1, const matrix3x4_t& in2, matrix3x4_t& out) +{ +#if 0 + // test for ones that'll be 2x faster + if ( (((size_t)&in1) % 16) == 0 && (((size_t)&in2) % 16) == 0 && (((size_t)&out) % 16) == 0 ) + { + ConcatTransforms_Aligned( in1, in2, out ); + return; + } +#endif + + fltx4 lastMask = *(fltx4 *)(&g_SIMD_ComponentMask[3]); + fltx4 rowA0 = LoadUnalignedSIMD( in1.m_flMatVal[0] ); + fltx4 rowA1 = LoadUnalignedSIMD( in1.m_flMatVal[1] ); + fltx4 rowA2 = LoadUnalignedSIMD( in1.m_flMatVal[2] ); + + fltx4 rowB0 = LoadUnalignedSIMD( in2.m_flMatVal[0] ); + fltx4 rowB1 = LoadUnalignedSIMD( in2.m_flMatVal[1] ); + fltx4 rowB2 = LoadUnalignedSIMD( in2.m_flMatVal[2] ); + + // now we have the rows of m0 and the columns of m1 + // first output row + fltx4 A0 = SplatXSIMD(rowA0); + fltx4 A1 = SplatYSIMD(rowA0); + fltx4 A2 = SplatZSIMD(rowA0); + fltx4 mul00 = MulSIMD( A0, rowB0 ); + fltx4 mul01 = MulSIMD( A1, rowB1 ); + fltx4 mul02 = MulSIMD( A2, rowB2 ); + fltx4 out0 = AddSIMD( mul00, AddSIMD(mul01,mul02) ); + + // second output row + A0 = SplatXSIMD(rowA1); + A1 = SplatYSIMD(rowA1); + A2 = SplatZSIMD(rowA1); + fltx4 mul10 = MulSIMD( A0, rowB0 ); + fltx4 mul11 = MulSIMD( A1, rowB1 ); + fltx4 mul12 = MulSIMD( A2, rowB2 ); + fltx4 out1 = AddSIMD( mul10, AddSIMD(mul11,mul12) ); + + // third output row + A0 = SplatXSIMD(rowA2); + A1 = SplatYSIMD(rowA2); + A2 = SplatZSIMD(rowA2); + fltx4 mul20 = MulSIMD( A0, rowB0 ); + fltx4 mul21 = MulSIMD( A1, rowB1 ); + fltx4 mul22 = MulSIMD( A2, rowB2 ); + fltx4 out2 = AddSIMD( mul20, AddSIMD(mul21,mul22) ); + + // add in translation vector + A0 = AndSIMD(rowA0,lastMask); + A1 = AndSIMD(rowA1,lastMask); + A2 = AndSIMD(rowA2,lastMask); + out0 = AddSIMD(out0, A0); + out1 = AddSIMD(out1, A1); + out2 = AddSIMD(out2, A2); + + // write to output + StoreUnalignedSIMD( out.m_flMatVal[0], out0 ); + StoreUnalignedSIMD( out.m_flMatVal[1], out1 ); + StoreUnalignedSIMD( out.m_flMatVal[2], out2 ); +} + + +/* +=================== +FloorDivMod + +Returns mathematically correct (floor-based) quotient and remainder for +numer and denom, both of which should contain no fractional part. The +quotient must fit in 32 bits. +==================== +*/ + +void FloorDivMod (double numer, double denom, int *quotient, + int *rem) +{ + Assert( s_bMathlibInitialized ); + int q, r; + double x; + +#ifdef PARANOID + if (denom <= 0.0) + Sys_Error ("FloorDivMod: bad denominator %d\n", denom); + +// if ((floor(numer) != numer) || (floor(denom) != denom)) +// Sys_Error ("FloorDivMod: non-integer numer or denom %f %f\n", +// numer, denom); +#endif + + if (numer >= 0.0) + { + + x = floor(numer / denom); + q = (int)x; + r = Floor2Int(numer - (x * denom)); + } + else + { + // + // perform operations with positive values, and fix mod to make floor-based + // + x = floor(-numer / denom); + q = -(int)x; + r = Floor2Int(-numer - (x * denom)); + if (r != 0) + { + q--; + r = (int)denom - r; + } + } + + *quotient = q; + *rem = r; +} + + +/* +=================== +GreatestCommonDivisor +==================== +*/ +int GreatestCommonDivisor (int i1, int i2) +{ + Assert( s_bMathlibInitialized ); + if (i1 > i2) + { + if (i2 == 0) + return (i1); + return GreatestCommonDivisor (i2, i1 % i2); + } + else + { + if (i1 == 0) + return (i2); + return GreatestCommonDivisor (i1, i2 % i1); + } +} + + +bool IsDenormal( const float &val ) +{ + const int x = *reinterpret_cast (&val); // needs 32-bit int + const int abs_mantissa = x & 0x007FFFFF; + const int biased_exponent = x & 0x7F800000; + + return ( biased_exponent == 0 && abs_mantissa != 0 ); +} + +int SignbitsForPlane (cplane_t *out) +{ + Assert( s_bMathlibInitialized ); + int bits, j; + + // for fast box on planeside test + + bits = 0; + for (j=0 ; j<3 ; j++) + { + if (out->normal[j] < 0) + bits |= 1<type < 3) + { + if (p->dist <= emins[p->type]) + return 1; + if (p->dist >= emaxs[p->type]) + return 2; + return 3; + } + + // general case + switch (p->signbits) + { + case 0: + dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; + dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; + break; + case 1: + dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; + dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; + break; + case 2: + dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; + dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; + break; + case 3: + dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; + dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; + break; + case 4: + dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; + dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; + break; + case 5: + dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2]; + dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2]; + break; + case 6: + dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; + dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; + break; + case 7: + dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2]; + dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2]; + break; + default: + dist1 = dist2 = 0; // shut up compiler + Assert( 0 ); + break; + } + + sides = 0; + if (dist1 >= p->dist) + sides = 1; + if (dist2 < p->dist) + sides |= 2; + + Assert( sides != 0 ); + + return sides; +} + +//----------------------------------------------------------------------------- +// Euler QAngle -> Basis Vectors +//----------------------------------------------------------------------------- + +void AngleVectors (const QAngle &angles, Vector *forward) +{ + Assert( s_bMathlibInitialized ); + Assert( forward ); + + float sp, sy, cp, cy; + + SinCos( DEG2RAD( angles[YAW] ), &sy, &cy ); + SinCos( DEG2RAD( angles[PITCH] ), &sp, &cp ); + + forward->x = cp*cy; + forward->y = cp*sy; + forward->z = -sp; +} + +//----------------------------------------------------------------------------- +// Euler QAngle -> Basis Vectors. Each vector is optional +//----------------------------------------------------------------------------- +void AngleVectors( const QAngle &angles, Vector *forward, Vector *right, Vector *up ) +{ + Assert( s_bMathlibInitialized ); + + float sr, sp, sy, cr, cp, cy; + +#ifdef _X360 + fltx4 radians, scale, sine, cosine; + radians = LoadUnaligned3SIMD( angles.Base() ); + scale = ReplicateX4( M_PI_F / 180.f ); + radians = MulSIMD( radians, scale ); + SinCos3SIMD( sine, cosine, radians ); + sp = SubFloat( sine, 0 ); sy = SubFloat( sine, 1 ); sr = SubFloat( sine, 2 ); + cp = SubFloat( cosine, 0 ); cy = SubFloat( cosine, 1 ); cr = SubFloat( cosine, 2 ); +#else + SinCos( DEG2RAD( angles[YAW] ), &sy, &cy ); + SinCos( DEG2RAD( angles[PITCH] ), &sp, &cp ); + SinCos( DEG2RAD( angles[ROLL] ), &sr, &cr ); +#endif + + if (forward) + { + forward->x = cp*cy; + forward->y = cp*sy; + forward->z = -sp; + } + + if (right) + { + right->x = (-1*sr*sp*cy+-1*cr*-sy); + right->y = (-1*sr*sp*sy+-1*cr*cy); + right->z = -1*sr*cp; + } + + if (up) + { + up->x = (cr*sp*cy+-sr*-sy); + up->y = (cr*sp*sy+-sr*cy); + up->z = cr*cp; + } +} + +//----------------------------------------------------------------------------- +// Euler QAngle -> Basis Vectors transposed +//----------------------------------------------------------------------------- + +void AngleVectorsTranspose (const QAngle &angles, Vector *forward, Vector *right, Vector *up) +{ + Assert( s_bMathlibInitialized ); + float sr, sp, sy, cr, cp, cy; + + SinCos( DEG2RAD( angles[YAW] ), &sy, &cy ); + SinCos( DEG2RAD( angles[PITCH] ), &sp, &cp ); + SinCos( DEG2RAD( angles[ROLL] ), &sr, &cr ); + + if (forward) + { + forward->x = cp*cy; + forward->y = (sr*sp*cy+cr*-sy); + forward->z = (cr*sp*cy+-sr*-sy); + } + + if (right) + { + right->x = cp*sy; + right->y = (sr*sp*sy+cr*cy); + right->z = (cr*sp*sy+-sr*cy); + } + + if (up) + { + up->x = -sp; + up->y = sr*cp; + up->z = cr*cp; + } +} + +//----------------------------------------------------------------------------- +// Forward direction vector -> Euler angles +//----------------------------------------------------------------------------- + +void VectorAngles( const Vector& forward, QAngle &angles ) +{ + Assert( s_bMathlibInitialized ); + float tmp, yaw, pitch; + + if (forward[1] == 0 && forward[0] == 0) + { + yaw = 0; + if (forward[2] > 0) + pitch = 270; + else + pitch = 90; + } + else + { + yaw = (atan2(forward[1], forward[0]) * 180 / M_PI); + if (yaw < 0) + yaw += 360; + + tmp = FastSqrt (forward[0]*forward[0] + forward[1]*forward[1]); + pitch = (atan2(-forward[2], tmp) * 180 / M_PI); + if (pitch < 0) + pitch += 360; + } + + angles[0] = pitch; + angles[1] = yaw; + angles[2] = 0; +} + +//----------------------------------------------------------------------------- +// Forward direction vector with a reference up vector -> Euler angles +//----------------------------------------------------------------------------- + +void VectorAngles( const Vector &forward, const Vector &pseudoup, QAngle &angles ) +{ + Assert( s_bMathlibInitialized ); + + Vector left; + + CrossProduct( pseudoup, forward, left ); + VectorNormalizeFast( left ); + + float xyDist = sqrtf( forward[0] * forward[0] + forward[1] * forward[1] ); + + // enough here to get angles? + if ( xyDist > 0.001f ) + { + // (yaw) y = ATAN( forward.y, forward.x ); -- in our space, forward is the X axis + angles[1] = RAD2DEG( atan2f( forward[1], forward[0] ) ); + + // The engine does pitch inverted from this, but we always end up negating it in the DLL + // UNDONE: Fix the engine to make it consistent + // (pitch) x = ATAN( -forward.z, sqrt(forward.x*forward.x+forward.y*forward.y) ); + angles[0] = RAD2DEG( atan2f( -forward[2], xyDist ) ); + + float up_z = (left[1] * forward[0]) - (left[0] * forward[1]); + + // (roll) z = ATAN( left.z, up.z ); + angles[2] = RAD2DEG( atan2f( left[2], up_z ) ); + } + else // forward is mostly Z, gimbal lock- + { + // (yaw) y = ATAN( -left.x, left.y ); -- forward is mostly z, so use right for yaw + angles[1] = RAD2DEG( atan2f( -left[0], left[1] ) ); //This was originally copied from the "void MatrixAngles( const matrix3x4_t& matrix, float *angles )" code, and it's 180 degrees off, negated the values and it all works now (Dave Kircher) + + // The engine does pitch inverted from this, but we always end up negating it in the DLL + // UNDONE: Fix the engine to make it consistent + // (pitch) x = ATAN( -forward.z, sqrt(forward.x*forward.x+forward.y*forward.y) ); + angles[0] = RAD2DEG( atan2f( -forward[2], xyDist ) ); + + // Assume no roll in this case as one degree of freedom has been lost (i.e. yaw == roll) + angles[2] = 0; + } +} + +void SetIdentityMatrix( matrix3x4_t& matrix ) +{ + memset( matrix.Base(), 0, sizeof(float)*3*4 ); + matrix[0][0] = 1.0; + matrix[1][1] = 1.0; + matrix[2][2] = 1.0; +} + + +//----------------------------------------------------------------------------- +// Builds a scale matrix +//----------------------------------------------------------------------------- +void SetScaleMatrix( float x, float y, float z, matrix3x4_t &dst ) +{ + dst[0][0] = x; dst[0][1] = 0.0f; dst[0][2] = 0.0f; dst[0][3] = 0.0f; + dst[1][0] = 0.0f; dst[1][1] = y; dst[1][2] = 0.0f; dst[1][3] = 0.0f; + dst[2][0] = 0.0f; dst[2][1] = 0.0f; dst[2][2] = z; dst[2][3] = 0.0f; +} + + +//----------------------------------------------------------------------------- +// Purpose: Builds the matrix for a counterclockwise rotation about an arbitrary axis. +// +// | ax2 + (1 - ax2)cosQ axay(1 - cosQ) - azsinQ azax(1 - cosQ) + aysinQ | +// Ra(Q) = | axay(1 - cosQ) + azsinQ ay2 + (1 - ay2)cosQ ayaz(1 - cosQ) - axsinQ | +// | azax(1 - cosQ) - aysinQ ayaz(1 - cosQ) + axsinQ az2 + (1 - az2)cosQ | +// +// Input : mat - +// vAxisOrRot - +// angle - +//----------------------------------------------------------------------------- +void MatrixBuildRotationAboutAxis( const Vector &vAxisOfRot, float angleDegrees, matrix3x4_t &dst ) +{ + float radians; + float axisXSquared; + float axisYSquared; + float axisZSquared; + float fSin; + float fCos; + + radians = angleDegrees * ( M_PI / 180.0 ); + fSin = sin( radians ); + fCos = cos( radians ); + + axisXSquared = vAxisOfRot[0] * vAxisOfRot[0]; + axisYSquared = vAxisOfRot[1] * vAxisOfRot[1]; + axisZSquared = vAxisOfRot[2] * vAxisOfRot[2]; + + // Column 0: + dst[0][0] = axisXSquared + (1 - axisXSquared) * fCos; + dst[1][0] = vAxisOfRot[0] * vAxisOfRot[1] * (1 - fCos) + vAxisOfRot[2] * fSin; + dst[2][0] = vAxisOfRot[2] * vAxisOfRot[0] * (1 - fCos) - vAxisOfRot[1] * fSin; + + // Column 1: + dst[0][1] = vAxisOfRot[0] * vAxisOfRot[1] * (1 - fCos) - vAxisOfRot[2] * fSin; + dst[1][1] = axisYSquared + (1 - axisYSquared) * fCos; + dst[2][1] = vAxisOfRot[1] * vAxisOfRot[2] * (1 - fCos) + vAxisOfRot[0] * fSin; + + // Column 2: + dst[0][2] = vAxisOfRot[2] * vAxisOfRot[0] * (1 - fCos) + vAxisOfRot[1] * fSin; + dst[1][2] = vAxisOfRot[1] * vAxisOfRot[2] * (1 - fCos) - vAxisOfRot[0] * fSin; + dst[2][2] = axisZSquared + (1 - axisZSquared) * fCos; + + // Column 3: + dst[0][3] = 0; + dst[1][3] = 0; + dst[2][3] = 0; +} + + +//----------------------------------------------------------------------------- +// Computes the transpose +//----------------------------------------------------------------------------- +void MatrixTranspose( matrix3x4_t& mat ) +{ + vec_t tmp; + tmp = mat[0][1]; mat[0][1] = mat[1][0]; mat[1][0] = tmp; + tmp = mat[0][2]; mat[0][2] = mat[2][0]; mat[2][0] = tmp; + tmp = mat[1][2]; mat[1][2] = mat[2][1]; mat[2][1] = tmp; +} + +void MatrixTranspose( const matrix3x4_t& src, matrix3x4_t& dst ) +{ + dst[0][0] = src[0][0]; dst[0][1] = src[1][0]; dst[0][2] = src[2][0]; dst[0][3] = 0.0f; + dst[1][0] = src[0][1]; dst[1][1] = src[1][1]; dst[1][2] = src[2][1]; dst[1][3] = 0.0f; + dst[2][0] = src[0][2]; dst[2][1] = src[1][2]; dst[2][2] = src[2][2]; dst[2][3] = 0.0f; +} + + +//----------------------------------------------------------------------------- +// Purpose: converts engine euler angles into a matrix +// Input : vec3_t angles - PITCH, YAW, ROLL +// Output : *matrix - left-handed column matrix +// the basis vectors for the rotations will be in the columns as follows: +// matrix[][0] is forward +// matrix[][1] is left +// matrix[][2] is up +//----------------------------------------------------------------------------- +void AngleMatrix( RadianEuler const &angles, const Vector &position, matrix3x4_t& matrix ) +{ + AngleMatrix( angles, matrix ); + MatrixSetColumn( position, 3, matrix ); +} + +void AngleMatrix( const RadianEuler& angles, matrix3x4_t& matrix ) +{ + QAngle quakeEuler( RAD2DEG( angles.y ), RAD2DEG( angles.z ), RAD2DEG( angles.x ) ); + + AngleMatrix( quakeEuler, matrix ); +} + + +void AngleMatrix( const QAngle &angles, const Vector &position, matrix3x4_t& matrix ) +{ + AngleMatrix( angles, matrix ); + MatrixSetColumn( position, 3, matrix ); +} + +void AngleMatrix( const QAngle &angles, matrix3x4_t& matrix ) +{ +#ifdef _VPROF_MATHLIB + VPROF_BUDGET( "AngleMatrix", "Mathlib" ); +#endif + Assert( s_bMathlibInitialized ); + + float sr, sp, sy, cr, cp, cy; + +#ifdef _X360 + fltx4 radians, scale, sine, cosine; + radians = LoadUnaligned3SIMD( angles.Base() ); + scale = ReplicateX4( M_PI_F / 180.f ); + radians = MulSIMD( radians, scale ); + SinCos3SIMD( sine, cosine, radians ); + + sp = SubFloat( sine, 0 ); sy = SubFloat( sine, 1 ); sr = SubFloat( sine, 2 ); + cp = SubFloat( cosine, 0 ); cy = SubFloat( cosine, 1 ); cr = SubFloat( cosine, 2 ); +#else + SinCos( DEG2RAD( angles[YAW] ), &sy, &cy ); + SinCos( DEG2RAD( angles[PITCH] ), &sp, &cp ); + SinCos( DEG2RAD( angles[ROLL] ), &sr, &cr ); +#endif + + // matrix = (YAW * PITCH) * ROLL + matrix[0][0] = cp*cy; + matrix[1][0] = cp*sy; + matrix[2][0] = -sp; + + float crcy = cr*cy; + float crsy = cr*sy; + float srcy = sr*cy; + float srsy = sr*sy; + matrix[0][1] = sp*srcy-crsy; + matrix[1][1] = sp*srsy+crcy; + matrix[2][1] = sr*cp; + + matrix[0][2] = (sp*crcy+srsy); + matrix[1][2] = (sp*crsy-srcy); + matrix[2][2] = cr*cp; + + matrix[0][3] = 0.0f; + matrix[1][3] = 0.0f; + matrix[2][3] = 0.0f; +} + +void AngleIMatrix( const RadianEuler& angles, matrix3x4_t& matrix ) +{ + QAngle quakeEuler( RAD2DEG( angles.y ), RAD2DEG( angles.z ), RAD2DEG( angles.x ) ); + + AngleIMatrix( quakeEuler, matrix ); +} + +void AngleIMatrix (const QAngle& angles, matrix3x4_t& matrix ) +{ + Assert( s_bMathlibInitialized ); + float sr, sp, sy, cr, cp, cy; + + SinCos( DEG2RAD( angles[YAW] ), &sy, &cy ); + SinCos( DEG2RAD( angles[PITCH] ), &sp, &cp ); + SinCos( DEG2RAD( angles[ROLL] ), &sr, &cr ); + + // matrix = (YAW * PITCH) * ROLL + 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.f; + matrix[1][3] = 0.f; + matrix[2][3] = 0.f; +} + +void AngleIMatrix (const QAngle &angles, const Vector &position, matrix3x4_t &mat ) +{ + AngleIMatrix( angles, mat ); + + Vector vecTranslation; + VectorRotate( position, mat, vecTranslation ); + vecTranslation *= -1.0f; + MatrixSetColumn( vecTranslation, 3, mat ); +} + + +//----------------------------------------------------------------------------- +// Bounding box construction methods +//----------------------------------------------------------------------------- + +void ClearBounds (Vector& mins, Vector& maxs) +{ + Assert( s_bMathlibInitialized ); + mins[0] = mins[1] = mins[2] = 99999; + maxs[0] = maxs[1] = maxs[2] = -99999; +} + +void AddPointToBounds (const Vector& v, Vector& mins, Vector& maxs) +{ + Assert( s_bMathlibInitialized ); + 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; + } +} + +// solve a x^2 + b x + c = 0 +bool SolveQuadratic( float a, float b, float c, float &root1, float &root2 ) +{ + Assert( s_bMathlibInitialized ); + if (a == 0) + { + if (b != 0) + { + // no x^2 component, it's a linear system + root1 = root2 = -c / b; + return true; + } + if (c == 0) + { + // all zero's + root1 = root2 = 0; + return true; + } + return false; + } + + float tmp = b * b - 4.0f * a * c; + + if (tmp < 0) + { + // imaginary number, bah, no solution. + return false; + } + + tmp = sqrt( tmp ); + root1 = (-b + tmp) / (2.0f * a); + root2 = (-b - tmp) / (2.0f * a); + return true; +} + +// solves for "a, b, c" where "a x^2 + b x + c = y", return true if solution exists +bool SolveInverseQuadratic( float x1, float y1, float x2, float y2, float x3, float y3, float &a, float &b, float &c ) +{ + float det = (x1 - x2)*(x1 - x3)*(x2 - x3); + + // FIXME: check with some sort of epsilon + if (det == 0.0) + return false; + + a = (x3*(-y1 + y2) + x2*(y1 - y3) + x1*(-y2 + y3)) / det; + + b = (x3*x3*(y1 - y2) + x1*x1*(y2 - y3) + x2*x2*(-y1 + y3)) / det; + + c = (x1*x3*(-x1 + x3)*y2 + x2*x2*(x3*y1 - x1*y3) + x2*(-(x3*x3*y1) + x1*x1*y3)) / det; + + return true; +} + +bool SolveInverseQuadraticMonotonic( float x1, float y1, float x2, float y2, float x3, float y3, + float &a, float &b, float &c ) +{ + // use SolveInverseQuadratic, but if the sigm of the derivative at the start point is the wrong + // sign, displace the mid point + + // first, sort parameters + if (x1>x2) + { + V_swap(x1,x2); + V_swap(y1,y2); + } + if (x2>x3) + { + V_swap(x2,x3); + V_swap(y2,y3); + } + if (x1>x2) + { + V_swap(x1,x2); + V_swap(y1,y2); + } + // this code is not fast. what it does is when the curve would be non-monotonic, slowly shifts + // the center point closer to the linear line between the endpoints. Should anyone need htis + // function to be actually fast, it would be fairly easy to change it to be so. + for(float blend_to_linear_factor=0.0;blend_to_linear_factor<=1.0;blend_to_linear_factor+=0.05) + { + float tempy2=(1-blend_to_linear_factor)*y2+blend_to_linear_factor*FLerp(y1,y3,x1,x3,x2); + if (!SolveInverseQuadratic(x1,y1,x2,tempy2,x3,y3,a,b,c)) + return false; + float derivative=2.0*a+b; + if ( (y1=0.0) + return true; + } + else + { + if ( (y1>y2) && (y2>y3)) // monotonically decreasing + { + if (derivative<=0.0) + return true; + } + else + return true; + } + } + return true; +} + + +// solves for "a, b, c" where "1/(a x^2 + b x + c ) = y", return true if solution exists +bool SolveInverseReciprocalQuadratic( float x1, float y1, float x2, float y2, float x3, float y3, float &a, float &b, float &c ) +{ + float det = (x1 - x2)*(x1 - x3)*(x2 - x3)*y1*y2*y3; + + // FIXME: check with some sort of epsilon + if (det == 0.0) + return false; + + a = (x1*y1*(y2 - y3) + x3*(y1 - y2)*y3 + x2*y2*(-y1 + y3)) / det; + + b = (x2*x2*y2*(y1 - y3) + x3*x3*(-y1 + y2)*y3 + x1*x1*y1*(-y2 + y3)) / det; + + c = (x2*(x2 - x3)*x3*y2*y3 + x1*x1*y1*(x2*y2 - x3*y3) + x1*(-(x2*x2*y1*y2) + x3*x3*y1*y3)) / det; + + return true; +} + + +// Rotate a vector around the Z axis (YAW) +void VectorYawRotate( const Vector &in, float flYaw, Vector &out) +{ + Assert( s_bMathlibInitialized ); + if (&in == &out ) + { + Vector tmp; + tmp = in; + VectorYawRotate( tmp, flYaw, out ); + return; + } + + float sy, cy; + + SinCos( DEG2RAD(flYaw), &sy, &cy ); + + out.x = in.x * cy - in.y * sy; + out.y = in.x * sy + in.y * cy; + out.z = in.z; +} + + + +float Bias( float x, float biasAmt ) +{ + // WARNING: not thread safe + static float lastAmt = -1; + static float lastExponent = 0; + if( lastAmt != biasAmt ) + { + lastExponent = log( biasAmt ) * -1.4427f; // (-1.4427 = 1 / log(0.5)) + } + return pow( x, lastExponent ); +} + + +float Gain( float x, float biasAmt ) +{ + // WARNING: not thread safe + if( x < 0.5 ) + return 0.5f * Bias( 2*x, 1-biasAmt ); + else + return 1 - 0.5f * Bias( 2 - 2*x, 1-biasAmt ); +} + + +float SmoothCurve( float x ) +{ + return (1 - cos( x * M_PI )) * 0.5f; +} + + +inline float MovePeak( float x, float flPeakPos ) +{ + // Todo: make this higher-order? + if( x < flPeakPos ) + return x * 0.5f / flPeakPos; + else + return 0.5 + 0.5 * (x - flPeakPos) / (1 - flPeakPos); +} + + +float SmoothCurve_Tweak( float x, float flPeakPos, float flPeakSharpness ) +{ + float flMovedPeak = MovePeak( x, flPeakPos ); + float flSharpened = Gain( flMovedPeak, flPeakSharpness ); + return SmoothCurve( flSharpened ); +} + +//----------------------------------------------------------------------------- +// make sure quaternions are within 180 degrees of one another, if not, reverse q +//----------------------------------------------------------------------------- + +void QuaternionAlign( const Quaternion &p, const Quaternion &q, Quaternion &qt ) +{ + Assert( s_bMathlibInitialized ); + + // FIXME: can this be done with a quat dot product? + + int i; + // 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++) + { + qt[i] = -q[i]; + } + } + else if (&qt != &q) + { + for (i = 0; i < 4; i++) + { + qt[i] = q[i]; + } + } +} + + +//----------------------------------------------------------------------------- +// Do a piecewise addition of the quaternion elements. This actually makes little +// mathematical sense, but it's a cheap way to simulate a slerp. +//----------------------------------------------------------------------------- +void QuaternionBlend( const Quaternion &p, const Quaternion &q, float t, Quaternion &qt ) +{ + Assert( s_bMathlibInitialized ); +#if ALLOW_SIMD_QUATERNION_MATH + fltx4 psimd, qsimd, qtsimd; + psimd = LoadUnalignedSIMD( p.Base() ); + qsimd = LoadUnalignedSIMD( q.Base() ); + qtsimd = QuaternionBlendSIMD( psimd, qsimd, t ); + StoreUnalignedSIMD( qt.Base(), qtsimd ); +#else + // decide if one of the quaternions is backwards + Quaternion q2; + QuaternionAlign( p, q, q2 ); + QuaternionBlendNoAlign( p, q2, t, qt ); +#endif +} + + +void QuaternionBlendNoAlign( const Quaternion &p, const Quaternion &q, float t, Quaternion &qt ) +{ + Assert( s_bMathlibInitialized ); + float sclp, sclq; + int i; + + // 0.0 returns p, 1.0 return q. + sclp = 1.0f - t; + sclq = t; + for (i = 0; i < 4; i++) { + qt[i] = sclp * p[i] + sclq * q[i]; + } + QuaternionNormalize( qt ); +} + + + +void QuaternionIdentityBlend( const Quaternion &p, float t, Quaternion &qt ) +{ + Assert( s_bMathlibInitialized ); + float sclp; + + sclp = 1.0f - t; + + qt.x = p.x * sclp; + qt.y = p.y * sclp; + qt.z = p.z * sclp; + if (qt.w < 0.0) + { + qt.w = p.w * sclp - t; + } + else + { + qt.w = p.w * sclp + t; + } + QuaternionNormalize( qt ); +} + +//----------------------------------------------------------------------------- +// Quaternion sphereical linear interpolation +//----------------------------------------------------------------------------- + +void QuaternionSlerp( const Quaternion &p, const Quaternion &q, float t, Quaternion &qt ) +{ + Quaternion q2; + // 0.0 returns p, 1.0 return q. + + // decide if one of the quaternions is backwards + QuaternionAlign( p, q, q2 ); + + QuaternionSlerpNoAlign( p, q2, t, qt ); +} + + +void QuaternionSlerpNoAlign( const Quaternion &p, const Quaternion &q, float t, Quaternion &qt ) +{ + Assert( s_bMathlibInitialized ); + float omega, cosom, sinom, sclp, sclq; + int i; + + // 0.0 returns p, 1.0 return q. + + cosom = p[0]*q[0] + p[1]*q[1] + p[2]*q[2] + p[3]*q[3]; + + if ((1.0f + cosom) > 0.000001f) { + if ((1.0f - cosom) > 0.000001f) { + omega = acos( cosom ); + sinom = sin( omega ); + sclp = sin( (1.0f - t)*omega) / sinom; + sclq = sin( t*omega ) / sinom; + } + else { + // TODO: add short circuit for cosom == 1.0f? + sclp = 1.0f - t; + sclq = t; + } + for (i = 0; i < 4; i++) { + qt[i] = sclp * p[i] + sclq * q[i]; + } + } + else { + Assert( &qt != &q ); + + qt[0] = -q[1]; + qt[1] = q[0]; + qt[2] = -q[3]; + qt[3] = q[2]; + sclp = sin( (1.0f - t) * (0.5f * M_PI)); + sclq = sin( t * (0.5f * M_PI)); + for (i = 0; i < 3; i++) { + qt[i] = sclp * p[i] + sclq * qt[i]; + } + } + + Assert( qt.IsValid() ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns the angular delta between the two normalized quaternions in degrees. +//----------------------------------------------------------------------------- +float QuaternionAngleDiff( const Quaternion &p, const Quaternion &q ) +{ +#if 1 + // this code path is here for 2 reasons: + // 1 - acos maps 1-epsilon to values much larger than epsilon (vs asin, which maps epsilon to itself) + // this means that in floats, anything below ~0.05 degrees truncates to 0 + // 2 - normalized quaternions are frequently slightly non-normalized due to float precision issues, + // and the epsilon off of normalized can be several percents of a degree + Quaternion qInv, diff; + QuaternionConjugate( q, qInv ); + QuaternionMult( p, qInv, diff ); + + // Note if the quaternion is slightly non-normalized the square root below may be more than 1, + // the value is clamped to one otherwise it may result in asin() returning an undefined result. + float sinang = MIN( 1.0f, sqrt( diff.x * diff.x + diff.y * diff.y + diff.z * diff.z ) ); + float angle = RAD2DEG( 2 * asin( sinang ) ); + return angle; +#else + Quaternion q2; + QuaternionAlign( p, q, q2 ); + + Assert( s_bMathlibInitialized ); + float cosom = p.x * q2.x + p.y * q2.y + p.z * q2.z + p.w * q2.w; + + if ( cosom > -1.0f ) + { + if ( cosom < 1.0f ) + { + float omega = 2 * fabs( acos( cosom ) ); + return RAD2DEG( omega ); + } + return 0.0f; + } + + return 180.0f; +#endif +} + +void QuaternionConjugate( const Quaternion &p, Quaternion &q ) +{ + Assert( s_bMathlibInitialized ); + Assert( q.IsValid() ); + + q.x = -p.x; + q.y = -p.y; + q.z = -p.z; + q.w = p.w; +} + +void QuaternionInvert( const Quaternion &p, Quaternion &q ) +{ + Assert( s_bMathlibInitialized ); + Assert( q.IsValid() ); + + QuaternionConjugate( p, q ); + + float magnitudeSqr = QuaternionDotProduct( p, p ); + Assert( magnitudeSqr ); + if ( magnitudeSqr ) + { + float inv = 1.0f / magnitudeSqr; + q.x *= inv; + q.y *= inv; + q.z *= inv; + q.w *= inv; + } +} + +//----------------------------------------------------------------------------- +// Make sure the quaternion is of unit length +//----------------------------------------------------------------------------- +float QuaternionNormalize( Quaternion &q ) +{ + Assert( s_bMathlibInitialized ); + float radius, iradius; + + Assert( q.IsValid() ); + + radius = q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]; + + if ( radius ) // > FLT_EPSILON && ((radius < 1.0f - 4*FLT_EPSILON) || (radius > 1.0f + 4*FLT_EPSILON)) + { + radius = sqrt(radius); + iradius = 1.0f/radius; + q[3] *= iradius; + q[2] *= iradius; + q[1] *= iradius; + q[0] *= iradius; + } + return radius; +} + + +void QuaternionScale( const Quaternion &p, float t, Quaternion &q ) +{ + Assert( s_bMathlibInitialized ); + +#if 0 + Quaternion p0; + Quaternion q; + p0.Init( 0.0, 0.0, 0.0, 1.0 ); + + // slerp in "reverse order" so that p doesn't get realigned + QuaternionSlerp( p, p0, 1.0 - fabs( t ), q ); + if (t < 0.0) + { + q.w = -q.w; + } +#else + float r; + + // FIXME: nick, this isn't overly sensitive to accuracy, and it may be faster to + // use the cos part (w) of the quaternion (sin(omega)*N,cos(omega)) to figure the new scale. + float sinom = sqrt( DotProduct( &p.x, &p.x ) ); + sinom = min( sinom, 1.f ); + + float sinsom = sin( asin( sinom ) * t ); + + t = sinsom / (sinom + FLT_EPSILON); + VectorScale( &p.x, t, &q.x ); + + // rescale rotation + r = 1.0f - sinsom * sinsom; + + // Assert( r >= 0 ); + if (r < 0.0f) + r = 0.0f; + r = sqrt( r ); + + // keep sign of rotation + if (p.w < 0) + q.w = -r; + else + q.w = r; +#endif + + Assert( q.IsValid() ); + + return; +} + + +void QuaternionAdd( const Quaternion &p, const Quaternion &q, Quaternion &qt ) +{ + Assert( s_bMathlibInitialized ); + Assert( p.IsValid() ); + Assert( q.IsValid() ); + + // decide if one of the quaternions is backwards + Quaternion q2; + QuaternionAlign( p, q, q2 ); + + // is this right??? + qt[0] = p[0] + q2[0]; + qt[1] = p[1] + q2[1]; + qt[2] = p[2] + q2[2]; + qt[3] = p[3] + q2[3]; + + return; +} + + +float QuaternionDotProduct( const Quaternion &p, const Quaternion &q ) +{ + Assert( s_bMathlibInitialized ); + Assert( p.IsValid() ); + Assert( q.IsValid() ); + + return p.x * q.x + p.y * q.y + p.z * q.z + p.w * q.w; +} + + +// qt = p * q +void QuaternionMult( const Quaternion &p, const Quaternion &q, Quaternion &qt ) +{ + Assert( s_bMathlibInitialized ); + Assert( p.IsValid() ); + Assert( q.IsValid() ); + + if (&p == &qt) + { + Quaternion p2 = p; + QuaternionMult( p2, q, qt ); + return; + } + + // decide if one of the quaternions is backwards + Quaternion q2; + QuaternionAlign( p, q, q2 ); + + qt.x = p.x * q2.w + p.y * q2.z - p.z * q2.y + p.w * q2.x; + qt.y = -p.x * q2.z + p.y * q2.w + p.z * q2.x + p.w * q2.y; + qt.z = p.x * q2.y - p.y * q2.x + p.z * q2.w + p.w * q2.z; + qt.w = -p.x * q2.x - p.y * q2.y - p.z * q2.z + p.w * q2.w; +} + + +void QuaternionMatrix( const Quaternion &q, const Vector &pos, matrix3x4_t& matrix ) +{ + Assert( pos.IsValid() ); + + QuaternionMatrix( q, matrix ); + + matrix[0][3] = pos.x; + matrix[1][3] = pos.y; + matrix[2][3] = pos.z; +} + +void QuaternionMatrix( const Quaternion &q, matrix3x4_t& matrix ) +{ + Assert( s_bMathlibInitialized ); + Assert( q.IsValid() ); + +#ifdef _VPROF_MATHLIB + VPROF_BUDGET( "QuaternionMatrix", "Mathlib" ); +#endif + +// Original code +// This should produce the same code as below with optimization, but looking at the assmebly, +// it doesn't. There are 7 extra multiplies in the release build of this, go figure. +#if 1 + matrix[0][0] = 1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z; + matrix[1][0] = 2.0 * q.x * q.y + 2.0 * q.w * q.z; + matrix[2][0] = 2.0 * q.x * q.z - 2.0 * q.w * q.y; + + matrix[0][1] = 2.0f * q.x * q.y - 2.0f * q.w * q.z; + matrix[1][1] = 1.0f - 2.0f * q.x * q.x - 2.0f * q.z * q.z; + matrix[2][1] = 2.0f * q.y * q.z + 2.0f * q.w * q.x; + + matrix[0][2] = 2.0f * q.x * q.z + 2.0f * q.w * q.y; + matrix[1][2] = 2.0f * q.y * q.z - 2.0f * q.w * q.x; + matrix[2][2] = 1.0f - 2.0f * q.x * q.x - 2.0f * q.y * q.y; + + matrix[0][3] = 0.0f; + matrix[1][3] = 0.0f; + matrix[2][3] = 0.0f; +#else + float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; + + // precalculate common multiplitcations + x2 = q.x + q.x; + y2 = q.y + q.y; + z2 = q.z + q.z; + xx = q.x * x2; + xy = q.x * y2; + xz = q.x * z2; + yy = q.y * y2; + yz = q.y * z2; + zz = q.z * z2; + wx = q.w * x2; + wy = q.w * y2; + wz = q.w * z2; + + matrix[0][0] = 1.0 - (yy + zz); + matrix[0][1] = xy - wz; + matrix[0][2] = xz + wy; + matrix[0][3] = 0.0f; + + matrix[1][0] = xy + wz; + matrix[1][1] = 1.0 - (xx + zz); + matrix[1][2] = yz - wx; + matrix[1][3] = 0.0f; + + matrix[2][0] = xz - wy; + matrix[2][1] = yz + wx; + matrix[2][2] = 1.0 - (xx + yy); + matrix[2][3] = 0.0f; +#endif +} + + +//----------------------------------------------------------------------------- +// Purpose: Converts a quaternion into engine angles +// Input : *quaternion - q3 + q0.i + q1.j + q2.k +// *outAngles - PITCH, YAW, ROLL +//----------------------------------------------------------------------------- +void QuaternionAngles( const Quaternion &q, QAngle &angles ) +{ + Assert( s_bMathlibInitialized ); + Assert( q.IsValid() ); + +#ifdef _VPROF_MATHLIB + VPROF_BUDGET( "QuaternionAngles", "Mathlib" ); +#endif + +#if 1 + // FIXME: doing it this way calculates too much data, needs to do an optimized version... + matrix3x4_t matrix; + QuaternionMatrix( q, matrix ); + MatrixAngles( matrix, angles ); +#else + float m11, m12, m13, m23, m33; + + m11 = ( 2.0f * q.w * q.w ) + ( 2.0f * q.x * q.x ) - 1.0f; + m12 = ( 2.0f * q.x * q.y ) + ( 2.0f * q.w * q.z ); + m13 = ( 2.0f * q.x * q.z ) - ( 2.0f * q.w * q.y ); + m23 = ( 2.0f * q.y * q.z ) + ( 2.0f * q.w * q.x ); + m33 = ( 2.0f * q.w * q.w ) + ( 2.0f * q.z * q.z ) - 1.0f; + + // FIXME: this code has a singularity near PITCH +-90 + angles[YAW] = RAD2DEG( atan2(m12, m11) ); + angles[PITCH] = RAD2DEG( asin(-m13) ); + angles[ROLL] = RAD2DEG( atan2(m23, m33) ); +#endif + + Assert( angles.IsValid() ); +} + +//----------------------------------------------------------------------------- +// Purpose: Converts a quaternion to an axis / angle in degrees +// (exponential map) +//----------------------------------------------------------------------------- +void QuaternionAxisAngle( const Quaternion &q, Vector &axis, float &angle ) +{ + angle = RAD2DEG(2 * acos(q.w)); + if ( angle > 180 ) + { + angle -= 360; + } + axis.x = q.x; + axis.y = q.y; + axis.z = q.z; + VectorNormalize( axis ); +} + +//----------------------------------------------------------------------------- +// Purpose: Converts an exponential map (ang/axis) to a quaternion +//----------------------------------------------------------------------------- +void AxisAngleQuaternion( const Vector &axis, float angle, Quaternion &q ) +{ + float sa, ca; + + SinCos( DEG2RAD(angle) * 0.5f, &sa, &ca ); + + q.x = axis.x * sa; + q.y = axis.y * sa; + q.z = axis.z * sa; + q.w = ca; +} + + +//----------------------------------------------------------------------------- +// Purpose: Converts radian-euler axis aligned angles to a quaternion +// Input : *pfAngles - Right-handed Euler angles in radians +// *outQuat - quaternion of form (i,j,k,real) +//----------------------------------------------------------------------------- +void AngleQuaternion( const RadianEuler &angles, Quaternion &outQuat ) +{ + Assert( s_bMathlibInitialized ); +// Assert( angles.IsValid() ); + +#ifdef _VPROF_MATHLIB + VPROF_BUDGET( "AngleQuaternion", "Mathlib" ); +#endif + + float sr, sp, sy, cr, cp, cy; + +#ifdef _X360 + fltx4 radians, scale, sine, cosine; + radians = LoadUnaligned3SIMD( &angles.x ); + scale = ReplicateX4( 0.5f ); + radians = MulSIMD( radians, scale ); + SinCos3SIMD( sine, cosine, radians ); + + // NOTE: The ordering here is *different* from the AngleQuaternion below + // because p, y, r are not in the same locations in QAngle + RadianEuler. Yay! + sr = SubFloat( sine, 0 ); sp = SubFloat( sine, 1 ); sy = SubFloat( sine, 2 ); + cr = SubFloat( cosine, 0 ); cp = SubFloat( cosine, 1 ); cy = SubFloat( cosine, 2 ); +#else + SinCos( angles.z * 0.5f, &sy, &cy ); + SinCos( angles.y * 0.5f, &sp, &cp ); + SinCos( angles.x * 0.5f, &sr, &cr ); +#endif + + // NJS: for some reason VC6 wasn't recognizing the common subexpressions: + float srXcp = sr * cp, crXsp = cr * sp; + outQuat.x = srXcp*cy-crXsp*sy; // X + outQuat.y = crXsp*cy+srXcp*sy; // Y + + float crXcp = cr * cp, srXsp = sr * sp; + outQuat.z = crXcp*sy-srXsp*cy; // Z + outQuat.w = crXcp*cy+srXsp*sy; // W (real component) +} + + +//----------------------------------------------------------------------------- +// Purpose: Converts engine-format euler angles to a quaternion +// Input : angles - Right-handed Euler angles in degrees as follows: +// [0]: PITCH: Clockwise rotation around the Y axis. +// [1]: YAW: Counterclockwise rotation around the Z axis. +// [2]: ROLL: Counterclockwise rotation around the X axis. +// *outQuat - quaternion of form (i,j,k,real) +//----------------------------------------------------------------------------- +void AngleQuaternion( const QAngle &angles, Quaternion &outQuat ) +{ +#ifdef _VPROF_MATHLIB + VPROF_BUDGET( "AngleQuaternion", "Mathlib" ); +#endif + + float sr, sp, sy, cr, cp, cy; + +#ifdef _X360 + fltx4 radians, scale, sine, cosine; + radians = LoadUnaligned3SIMD( angles.Base() ); + scale = ReplicateX4( 0.5f * M_PI_F / 180.f ); + radians = MulSIMD( radians, scale ); + SinCos3SIMD( sine, cosine, radians ); + + // NOTE: The ordering here is *different* from the AngleQuaternion above + // because p, y, r are not in the same locations in QAngle + RadianEuler. Yay! + sp = SubFloat( sine, 0 ); sy = SubFloat( sine, 1 ); sr = SubFloat( sine, 2 ); + cp = SubFloat( cosine, 0 ); cy = SubFloat( cosine, 1 ); cr = SubFloat( cosine, 2 ); +#else + SinCos( DEG2RAD( angles.y ) * 0.5f, &sy, &cy ); + SinCos( DEG2RAD( angles.x ) * 0.5f, &sp, &cp ); + SinCos( DEG2RAD( angles.z ) * 0.5f, &sr, &cr ); +#endif + + // NJS: for some reason VC6 wasn't recognizing the common subexpressions: + float srXcp = sr * cp, crXsp = cr * sp; + outQuat.x = srXcp*cy-crXsp*sy; // X + outQuat.y = crXsp*cy+srXcp*sy; // Y + + float crXcp = cr * cp, srXsp = sr * sp; + outQuat.z = crXcp*sy-srXsp*cy; // Z + outQuat.w = crXcp*cy+srXsp*sy; // W (real component) +} + + +//----------------------------------------------------------------------------- +// Purpose: Converts a basis to a quaternion +//----------------------------------------------------------------------------- +void BasisToQuaternion( const Vector &vecForward, const Vector &vecRight, const Vector &vecUp, Quaternion &q ) +{ + Assert( fabs( vecForward.LengthSqr() - 1.0f ) < 1e-3 ); + Assert( fabs( vecRight.LengthSqr() - 1.0f ) < 1e-3 ); + Assert( fabs( vecUp.LengthSqr() - 1.0f ) < 1e-3 ); + + Vector vecLeft; + VectorMultiply( vecRight, -1.0f, vecLeft ); + + // FIXME: Don't know why, but this doesn't match at all with other result + // so we can't use this super-fast way. + /* + // Find the trace of the matrix: + float flTrace = vecForward.x + vecLeft.y + vecUp.z + 1.0f; + if ( flTrace > 1e-6 ) + { + float flSqrtTrace = FastSqrt( flTrace ); + float s = 0.5f / flSqrtTrace; + q.x = ( vecUp.y - vecLeft.z ) * s; + q.y = ( vecForward.z - vecUp.x ) * s; + q.z = ( vecLeft.x - vecForward.y ) * s; + q.w = 0.5f * flSqrtTrace; + } + else + { + if (( vecForward.x > vecLeft.y ) && ( vecForward.x > vecUp.z ) ) + { + float flSqrtTrace = FastSqrt( 1.0f + vecForward.x - vecLeft.y - vecUp.z ); + float s = 0.5f / flSqrtTrace; + q.x = 0.5f * flSqrtTrace; + q.y = ( vecForward.y + vecLeft.x ) * s; + q.z = ( vecUp.x + vecForward.z ) * s; + q.w = ( vecUp.y - vecLeft.z ) * s; + } + else if ( vecLeft.y > vecUp.z ) + { + float flSqrtTrace = FastSqrt( 1.0f + vecLeft.y - vecForward.x - vecUp.z ); + float s = 0.5f / flSqrtTrace; + q.x = ( vecForward.y + vecLeft.x ) * s; + q.y = 0.5f * flSqrtTrace; + q.z = ( vecUp.y + vecLeft.z ) * s; + q.w = ( vecForward.z - vecUp.x ) * s; + } + else + { + float flSqrtTrace = FastSqrt( 1.0 + vecUp.z - vecForward.x - vecLeft.y ); + float s = 0.5f / flSqrtTrace; + q.x = ( vecUp.x + vecForward.z ) * s; + q.y = ( vecUp.y + vecLeft.z ) * s; + q.z = 0.5f * flSqrtTrace; + q.w = ( vecLeft.x - vecForward.y ) * s; + } + } + QuaternionNormalize( q ); + */ + + // Version 2: Go through angles + + matrix3x4_t mat; + MatrixSetColumn( vecForward, 0, mat ); + MatrixSetColumn( vecLeft, 1, mat ); + MatrixSetColumn( vecUp, 2, mat ); + + QAngle angles; + MatrixAngles( mat, angles ); + +// Quaternion q2; + AngleQuaternion( angles, q ); + +// Assert( fabs(q.x - q2.x) < 1e-3 ); +// Assert( fabs(q.y - q2.y) < 1e-3 ); +// Assert( fabs(q.z - q2.z) < 1e-3 ); +// Assert( fabs(q.w - q2.w) < 1e-3 ); +} + +// FIXME: Optimize! +void MatrixQuaternion( const matrix3x4_t &mat, Quaternion &q ) +{ + QAngle angles; + MatrixAngles( mat, angles ); + AngleQuaternion( angles, q ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Converts a quaternion into engine angles +// Input : *quaternion - q3 + q0.i + q1.j + q2.k +// *outAngles - PITCH, YAW, ROLL +//----------------------------------------------------------------------------- +void QuaternionAngles( const Quaternion &q, RadianEuler &angles ) +{ + Assert( s_bMathlibInitialized ); + Assert( q.IsValid() ); + + // FIXME: doing it this way calculates too much data, needs to do an optimized version... + matrix3x4_t matrix; + QuaternionMatrix( q, matrix ); + MatrixAngles( matrix, angles ); + + Assert( angles.IsValid() ); +} + +//----------------------------------------------------------------------------- +// Purpose: A helper function to normalize p2.x->p1.x and p3.x->p4.x to +// be the same length as p2.x->p3.x +// Input : &p2 - +// &p4 - +// p4n - +//----------------------------------------------------------------------------- +void Spline_Normalize( + const Vector &p1, + const Vector &p2, + const Vector &p3, + const Vector &p4, + Vector& p1n, + Vector& p4n ) +{ + float dt = p3.x - p2.x; + + p1n = p1; + p4n = p4; + + if ( dt != 0.0 ) + { + if (p1.x != p2.x) + { + // Equivalent to p1n = p2 - (p2 - p1) * (dt / (p2.x - p1.x)); + VectorLerp( p2, p1, dt / (p2.x - p1.x), p1n ); + } + if (p4.x != p3.x) + { + // Equivalent to p4n = p3 + (p4 - p3) * (dt / (p4.x - p3.x)); + VectorLerp( p3, p4, dt / (p4.x - p3.x), p4n ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +//----------------------------------------------------------------------------- + +void Catmull_Rom_Spline( + const Vector &p1, + const Vector &p2, + const Vector &p3, + const Vector &p4, + float t, + Vector& output ) +{ + Assert( s_bMathlibInitialized ); + float tSqr = t*t*0.5f; + float tSqrSqr = t*tSqr; + t *= 0.5f; + + Assert( &output != &p1 ); + Assert( &output != &p2 ); + Assert( &output != &p3 ); + Assert( &output != &p4 ); + + output.Init(); + + Vector a, b, c, d; + + // matrix row 1 + VectorScale( p1, -tSqrSqr, a ); // 0.5 t^3 * [ (-1*p1) + ( 3*p2) + (-3*p3) + p4 ] + VectorScale( p2, tSqrSqr*3, b ); + VectorScale( p3, tSqrSqr*-3, c ); + VectorScale( p4, tSqrSqr, d ); + + VectorAdd( a, output, output ); + VectorAdd( b, output, output ); + VectorAdd( c, output, output ); + VectorAdd( d, output, output ); + + // matrix row 2 + VectorScale( p1, tSqr*2, a ); // 0.5 t^2 * [ ( 2*p1) + (-5*p2) + ( 4*p3) - p4 ] + VectorScale( p2, tSqr*-5, b ); + VectorScale( p3, tSqr*4, c ); + VectorScale( p4, -tSqr, d ); + + VectorAdd( a, output, output ); + VectorAdd( b, output, output ); + VectorAdd( c, output, output ); + VectorAdd( d, output, output ); + + // matrix row 3 + VectorScale( p1, -t, a ); // 0.5 t * [ (-1*p1) + p3 ] + VectorScale( p3, t, b ); + + VectorAdd( a, output, output ); + VectorAdd( b, output, output ); + + // matrix row 4 + VectorAdd( p2, output, output ); // p2 +} + +void Catmull_Rom_Spline_Tangent( + const Vector &p1, + const Vector &p2, + const Vector &p3, + const Vector &p4, + float t, + Vector& output ) +{ + Assert( s_bMathlibInitialized ); + float tOne = 3*t*t*0.5f; + float tTwo = 2*t*0.5f; + float tThree = 0.5; + + Assert( &output != &p1 ); + Assert( &output != &p2 ); + Assert( &output != &p3 ); + Assert( &output != &p4 ); + + output.Init(); + + Vector a, b, c, d; + + // matrix row 1 + VectorScale( p1, -tOne, a ); // 0.5 t^3 * [ (-1*p1) + ( 3*p2) + (-3*p3) + p4 ] + VectorScale( p2, tOne*3, b ); + VectorScale( p3, tOne*-3, c ); + VectorScale( p4, tOne, d ); + + VectorAdd( a, output, output ); + VectorAdd( b, output, output ); + VectorAdd( c, output, output ); + VectorAdd( d, output, output ); + + // matrix row 2 + VectorScale( p1, tTwo*2, a ); // 0.5 t^2 * [ ( 2*p1) + (-5*p2) + ( 4*p3) - p4 ] + VectorScale( p2, tTwo*-5, b ); + VectorScale( p3, tTwo*4, c ); + VectorScale( p4, -tTwo, d ); + + VectorAdd( a, output, output ); + VectorAdd( b, output, output ); + VectorAdd( c, output, output ); + VectorAdd( d, output, output ); + + // matrix row 3 + VectorScale( p1, -tThree, a ); // 0.5 t * [ (-1*p1) + p3 ] + VectorScale( p3, tThree, b ); + + VectorAdd( a, output, output ); + VectorAdd( b, output, output ); +} + +// area under the curve [0..t] +void Catmull_Rom_Spline_Integral( + const Vector &p1, + const Vector &p2, + const Vector &p3, + const Vector &p4, + float t, + Vector& output ) +{ + output = p2*t + -0.25f*(p1 - p3)*t*t + + (1.0f/6.0f)*(2.0f*p1 - 5.0f*p2 + 4.0f*p3 - p4)*t*t*t + - 0.125f*(p1 - 3.0f*p2 + 3.0f*p3 - p4)*t*t*t*t; +} + + +// area under the curve [0..1] +void Catmull_Rom_Spline_Integral( + const Vector &p1, + const Vector &p2, + const Vector &p3, + const Vector &p4, + Vector& output ) +{ + output = (-0.25f * p1 + 3.25f * p2 + 3.25f * p3 - 0.25f * p4) * (1.0f / 6.0f); +} + + +void Catmull_Rom_Spline_Normalize( + const Vector &p1, + const Vector &p2, + const Vector &p3, + const Vector &p4, + float t, + Vector& output ) +{ + // Normalize p2->p1 and p3->p4 to be the same length as p2->p3 + float dt = p3.DistTo(p2); + + Vector p1n, p4n; + VectorSubtract( p1, p2, p1n ); + VectorSubtract( p4, p3, p4n ); + + VectorNormalize( p1n ); + VectorNormalize( p4n ); + + VectorMA( p2, dt, p1n, p1n ); + VectorMA( p3, dt, p4n, p4n ); + + Catmull_Rom_Spline( p1n, p2, p3, p4n, t, output ); +} + + +void Catmull_Rom_Spline_Integral_Normalize( + const Vector &p1, + const Vector &p2, + const Vector &p3, + const Vector &p4, + float t, + Vector& output ) +{ + // Normalize p2->p1 and p3->p4 to be the same length as p2->p3 + float dt = p3.DistTo(p2); + + Vector p1n, p4n; + VectorSubtract( p1, p2, p1n ); + VectorSubtract( p4, p3, p4n ); + + VectorNormalize( p1n ); + VectorNormalize( p4n ); + + VectorMA( p2, dt, p1n, p1n ); + VectorMA( p3, dt, p4n, p4n ); + + Catmull_Rom_Spline_Integral( p1n, p2, p3, p4n, t, output ); +} + + +void Catmull_Rom_Spline_NormalizeX( + const Vector &p1, + const Vector &p2, + const Vector &p3, + const Vector &p4, + float t, + Vector& output ) +{ + Vector p1n, p4n; + Spline_Normalize( p1, p2, p3, p4, p1n, p4n ); + Catmull_Rom_Spline( p1n, p2, p3, p4n, t, output ); +} + + +//----------------------------------------------------------------------------- +// Purpose: basic hermite spline. t = 0 returns p1, t = 1 returns p2, +// d1 and d2 are used to entry and exit slope of curve +// Input : +//----------------------------------------------------------------------------- + +void Hermite_Spline( + const Vector &p1, + const Vector &p2, + const Vector &d1, + const Vector &d2, + float t, + Vector& output ) +{ + Assert( s_bMathlibInitialized ); + float tSqr = t*t; + float tCube = t*tSqr; + + Assert( &output != &p1 ); + Assert( &output != &p2 ); + Assert( &output != &d1 ); + Assert( &output != &d2 ); + + float b1 = 2.0f*tCube-3.0f*tSqr+1.0f; + float b2 = 1.0f - b1; // -2*tCube+3*tSqr; + float b3 = tCube-2*tSqr+t; + float b4 = tCube-tSqr; + + VectorScale( p1, b1, output ); + VectorMA( output, b2, p2, output ); + VectorMA( output, b3, d1, output ); + VectorMA( output, b4, d2, output ); +} + +float Hermite_Spline( + float p1, + float p2, + float d1, + float d2, + float t ) +{ + Assert( s_bMathlibInitialized ); + float output; + float tSqr = t*t; + float tCube = t*tSqr; + + float b1 = 2.0f*tCube-3.0f*tSqr+1.0f; + float b2 = 1.0f - b1; // -2*tCube+3*tSqr; + float b3 = tCube-2*tSqr+t; + float b4 = tCube-tSqr; + + output = p1 * b1; + output += p2 * b2; + output += d1 * b3; + output += d2 * b4; + + return output; +} + + +void Hermite_SplineBasis( float t, float basis[4] ) +{ + float tSqr = t*t; + float tCube = t*tSqr; + + basis[0] = 2.0f*tCube-3.0f*tSqr+1.0f; + basis[1] = 1.0f - basis[0]; // -2*tCube+3*tSqr; + basis[2] = tCube-2*tSqr+t; + basis[3] = tCube-tSqr; +} + +//----------------------------------------------------------------------------- +// Purpose: simple three data point hermite spline. +// t = 0 returns p1, t = 1 returns p2, +// slopes are generated from the p0->p1 and p1->p2 segments +// this is reasonable C1 method when there's no "p3" data yet. +// Input : +//----------------------------------------------------------------------------- + +// BUG: the VectorSubtract()'s calls go away if the global optimizer is enabled +#pragma optimize( "g", off ) + +void Hermite_Spline( const Vector &p0, const Vector &p1, const Vector &p2, float t, Vector& output ) +{ + Vector e10, e21; + VectorSubtract( p1, p0, e10 ); + VectorSubtract( p2, p1, e21 ); + Hermite_Spline( p1, p2, e10, e21, t, output ); +} + +#pragma optimize( "", on ) + +float Hermite_Spline( float p0, float p1, float p2, float t ) +{ + return Hermite_Spline( p1, p2, p1 - p0, p2 - p1, t ); +} + + +void Hermite_Spline( const Quaternion &q0, const Quaternion &q1, const Quaternion &q2, float t, Quaternion &output ) +{ + // cheap, hacked version of quaternions + Quaternion q0a; + Quaternion q1a; + + QuaternionAlign( q2, q0, q0a ); + QuaternionAlign( q2, q1, q1a ); + + output.x = Hermite_Spline( q0a.x, q1a.x, q2.x, t ); + output.y = Hermite_Spline( q0a.y, q1a.y, q2.y, t ); + output.z = Hermite_Spline( q0a.z, q1a.z, q2.z, t ); + output.w = Hermite_Spline( q0a.w, q1a.w, q2.w, t ); + + QuaternionNormalize( output ); +} + +// See http://en.wikipedia.org/wiki/Kochanek-Bartels_curves +// +// Tension: -1 = Round -> 1 = Tight +// Bias: -1 = Pre-shoot (bias left) -> 1 = Post-shoot (bias right) +// Continuity: -1 = Box corners -> 1 = Inverted corners +// +// If T=B=C=0 it's the same matrix as Catmull-Rom. +// If T=1 & B=C=0 it's the same as Cubic. +// If T=B=0 & C=-1 it's just linear interpolation +// +// See http://news.povray.org/povray.binaries.tutorials/attachment/%3CXns91B880592482seed7@povray.org%3E/Splines.bas.txt +// for example code and descriptions of various spline types... +// +void Kochanek_Bartels_Spline( + float tension, + float bias, + float continuity, + const Vector &p1, + const Vector &p2, + const Vector &p3, + const Vector &p4, + float t, + Vector& output ) +{ + Assert( s_bMathlibInitialized ); + + float ffa, ffb, ffc, ffd; + + ffa = ( 1.0f - tension ) * ( 1.0f + continuity ) * ( 1.0f + bias ); + ffb = ( 1.0f - tension ) * ( 1.0f - continuity ) * ( 1.0f - bias ); + ffc = ( 1.0f - tension ) * ( 1.0f - continuity ) * ( 1.0f + bias ); + ffd = ( 1.0f - tension ) * ( 1.0f + continuity ) * ( 1.0f - bias ); + + float tSqr = t*t*0.5f; + float tSqrSqr = t*tSqr; + t *= 0.5f; + + Assert( &output != &p1 ); + Assert( &output != &p2 ); + Assert( &output != &p3 ); + Assert( &output != &p4 ); + + output.Init(); + + Vector a, b, c, d; + + // matrix row 1 + VectorScale( p1, tSqrSqr * -ffa, a ); + VectorScale( p2, tSqrSqr * ( 4.0f + ffa - ffb - ffc ), b ); + VectorScale( p3, tSqrSqr * ( -4.0f + ffb + ffc - ffd ), c ); + VectorScale( p4, tSqrSqr * ffd, d ); + + VectorAdd( a, output, output ); + VectorAdd( b, output, output ); + VectorAdd( c, output, output ); + VectorAdd( d, output, output ); + + // matrix row 2 + VectorScale( p1, tSqr* 2 * ffa, a ); + VectorScale( p2, tSqr * ( -6 - 2 * ffa + 2 * ffb + ffc ), b ); + VectorScale( p3, tSqr * ( 6 - 2 * ffb - ffc + ffd ), c ); + VectorScale( p4, tSqr * -ffd, d ); + + VectorAdd( a, output, output ); + VectorAdd( b, output, output ); + VectorAdd( c, output, output ); + VectorAdd( d, output, output ); + + // matrix row 3 + VectorScale( p1, t * -ffa, a ); + VectorScale( p2, t * ( ffa - ffb ), b ); + VectorScale( p3, t * ffb, c ); + // p4 unchanged + + VectorAdd( a, output, output ); + VectorAdd( b, output, output ); + VectorAdd( c, output, output ); + + // matrix row 4 + // p1, p3, p4 unchanged + // p2 is multiplied by 1 and added, so just added it directly + + VectorAdd( p2, output, output ); +} + +void Kochanek_Bartels_Spline_NormalizeX( + float tension, + float bias, + float continuity, + const Vector &p1, + const Vector &p2, + const Vector &p3, + const Vector &p4, + float t, + Vector& output ) +{ + Vector p1n, p4n; + Spline_Normalize( p1, p2, p3, p4, p1n, p4n ); + Kochanek_Bartels_Spline( tension, bias, continuity, p1n, p2, p3, p4n, t, output ); +} + +void Cubic_Spline( + const Vector &p1, + const Vector &p2, + const Vector &p3, + const Vector &p4, + float t, + Vector& output ) +{ + Assert( s_bMathlibInitialized ); + + float tSqr = t*t; + float tSqrSqr = t*tSqr; + + Assert( &output != &p1 ); + Assert( &output != &p2 ); + Assert( &output != &p3 ); + Assert( &output != &p4 ); + + output.Init(); + + Vector a, b, c, d; + + // matrix row 1 + VectorScale( p2, tSqrSqr * 2, b ); + VectorScale( p3, tSqrSqr * -2, c ); + + VectorAdd( b, output, output ); + VectorAdd( c, output, output ); + + // matrix row 2 + VectorScale( p2, tSqr * -3, b ); + VectorScale( p3, tSqr * 3, c ); + + VectorAdd( b, output, output ); + VectorAdd( c, output, output ); + + // matrix row 3 + // no influence + // p4 unchanged + + // matrix row 4 + // p1, p3, p4 unchanged + VectorAdd( p2, output, output ); +} + +void Cubic_Spline_NormalizeX( + const Vector &p1, + const Vector &p2, + const Vector &p3, + const Vector &p4, + float t, + Vector& output ) +{ + Vector p1n, p4n; + Spline_Normalize( p1, p2, p3, p4, p1n, p4n ); + Cubic_Spline( p1n, p2, p3, p4n, t, output ); +} + +void BSpline( + const Vector &p1, + const Vector &p2, + const Vector &p3, + const Vector &p4, + float t, + Vector& output ) +{ + Assert( s_bMathlibInitialized ); + + float oneOver6 = 1.0f / 6.0f; + + float tSqr = t * t * oneOver6; + float tSqrSqr = t*tSqr; + t *= oneOver6; + + Assert( &output != &p1 ); + Assert( &output != &p2 ); + Assert( &output != &p3 ); + Assert( &output != &p4 ); + + output.Init(); + + Vector a, b, c, d; + + // matrix row 1 + VectorScale( p1, -tSqrSqr, a ); + VectorScale( p2, tSqrSqr * 3.0f, b ); + VectorScale( p3, tSqrSqr * -3.0f, c ); + VectorScale( p4, tSqrSqr, d ); + + VectorAdd( a, output, output ); + VectorAdd( b, output, output ); + VectorAdd( c, output, output ); + VectorAdd( d, output, output ); + + // matrix row 2 + VectorScale( p1, tSqr * 3.0f, a ); + VectorScale( p2, tSqr * -6.0f, b ); + VectorScale( p3, tSqr * 3.0f, c ); + + VectorAdd( a, output, output ); + VectorAdd( b, output, output ); + VectorAdd( c, output, output ); + + // matrix row 3 + VectorScale( p1, t * -3.0f, a ); + VectorScale( p3, t * 3.0f, c ); + // p4 unchanged + + VectorAdd( a, output, output ); + VectorAdd( c, output, output ); + + // matrix row 4 + // p1 and p3 scaled by 1.0f, so done below + VectorScale( p1, oneOver6, a ); + VectorScale( p2, 4.0f * oneOver6, b ); + VectorScale( p3, oneOver6, c ); + + VectorAdd( a, output, output ); + VectorAdd( b, output, output ); + VectorAdd( c, output, output ); +} + +void BSpline_NormalizeX( + const Vector &p1, + const Vector &p2, + const Vector &p3, + const Vector &p4, + float t, + Vector& output ) +{ + Vector p1n, p4n; + Spline_Normalize( p1, p2, p3, p4, p1n, p4n ); + BSpline( p1n, p2, p3, p4n, t, output ); +} + +void Parabolic_Spline( + const Vector &p1, + const Vector &p2, + const Vector &p3, + const Vector &p4, + float t, + Vector& output ) +{ + Assert( s_bMathlibInitialized ); + + float tSqr = t*t*0.5f; + t *= 0.5f; + + Assert( &output != &p1 ); + Assert( &output != &p2 ); + Assert( &output != &p3 ); + Assert( &output != &p4 ); + + output.Init(); + + Vector a, b, c, d; + + // matrix row 1 + // no influence from t cubed + + // matrix row 2 + VectorScale( p1, tSqr, a ); + VectorScale( p2, tSqr * -2.0f, b ); + VectorScale( p3, tSqr, c ); + + VectorAdd( a, output, output ); + VectorAdd( b, output, output ); + VectorAdd( c, output, output ); + + // matrix row 3 + VectorScale( p1, t * -2.0f, a ); + VectorScale( p2, t * 2.0f, b ); + // p4 unchanged + + VectorAdd( a, output, output ); + VectorAdd( b, output, output ); + + // matrix row 4 + VectorScale( p1, 0.5f, a ); + VectorScale( p2, 0.5f, b ); + + VectorAdd( a, output, output ); + VectorAdd( b, output, output ); +} + +void Parabolic_Spline_NormalizeX( + const Vector &p1, + const Vector &p2, + const Vector &p3, + const Vector &p4, + float t, + Vector& output ) +{ + Vector p1n, p4n; + Spline_Normalize( p1, p2, p3, p4, p1n, p4n ); + Parabolic_Spline( p1n, p2, p3, p4n, t, output ); +} + +//----------------------------------------------------------------------------- +// Purpose: Compress the input values for a ranged result such that from 75% to 200% smoothly of the range maps +//----------------------------------------------------------------------------- + +float RangeCompressor( float flValue, float flMin, float flMax, float flBase ) +{ + // clamp base + if (flBase < flMin) + flBase = flMin; + if (flBase > flMax) + flBase = flMax; + + flValue += flBase; + + // convert to 0 to 1 value + float flMid = (flValue - flMin) / (flMax - flMin); + // convert to -1 to 1 value + float flTarget = flMid * 2 - 1; + + if (fabs(flTarget) > 0.75) + { + float t = (fabs(flTarget) - 0.75) / (1.25); + if (t < 1.0) + { + if (flTarget > 0) + { + flTarget = Hermite_Spline( 0.75, 1, 0.75, 0, t ); + } + else + { + flTarget = -Hermite_Spline( 0.75, 1, 0.75, 0, t ); + } + } + else + { + flTarget = (flTarget > 0) ? 1.0f : -1.0f; + } + } + + flMid = (flTarget + 1 ) / 2.0; + flValue = flMin * (1 - flMid) + flMax * flMid; + + flValue -= flBase; + + return flValue; +} + + +//#pragma optimize( "", on ) + +//----------------------------------------------------------------------------- +// Transforms a AABB into another space; which will inherently grow the box. +//----------------------------------------------------------------------------- +void TransformAABB( const matrix3x4_t& transform, const Vector &vecMinsIn, const Vector &vecMaxsIn, Vector &vecMinsOut, Vector &vecMaxsOut ) +{ + Vector localCenter; + VectorAdd( vecMinsIn, vecMaxsIn, localCenter ); + localCenter *= 0.5f; + + Vector localExtents; + VectorSubtract( vecMaxsIn, localCenter, localExtents ); + + Vector worldCenter; + VectorTransform( localCenter, transform, worldCenter ); + + Vector worldExtents; + worldExtents.x = DotProductAbs( localExtents, transform[0] ); + worldExtents.y = DotProductAbs( localExtents, transform[1] ); + worldExtents.z = DotProductAbs( localExtents, transform[2] ); + + VectorSubtract( worldCenter, worldExtents, vecMinsOut ); + VectorAdd( worldCenter, worldExtents, vecMaxsOut ); +} + + +//----------------------------------------------------------------------------- +// Uses the inverse transform of in1 +//----------------------------------------------------------------------------- +void ITransformAABB( const matrix3x4_t& transform, const Vector &vecMinsIn, const Vector &vecMaxsIn, Vector &vecMinsOut, Vector &vecMaxsOut ) +{ + Vector worldCenter; + VectorAdd( vecMinsIn, vecMaxsIn, worldCenter ); + worldCenter *= 0.5f; + + Vector worldExtents; + VectorSubtract( vecMaxsIn, worldCenter, worldExtents ); + + Vector localCenter; + VectorITransform( worldCenter, transform, localCenter ); + + Vector localExtents; + localExtents.x = FloatMakePositive( worldExtents.x * transform[0][0] ) + + FloatMakePositive( worldExtents.y * transform[1][0] ) + + FloatMakePositive( worldExtents.z * transform[2][0] ); + localExtents.y = FloatMakePositive( worldExtents.x * transform[0][1] ) + + FloatMakePositive( worldExtents.y * transform[1][1] ) + + FloatMakePositive( worldExtents.z * transform[2][1] ); + localExtents.z = FloatMakePositive( worldExtents.x * transform[0][2] ) + + FloatMakePositive( worldExtents.y * transform[1][2] ) + + FloatMakePositive( worldExtents.z * transform[2][2] ); + + VectorSubtract( localCenter, localExtents, vecMinsOut ); + VectorAdd( localCenter, localExtents, vecMaxsOut ); +} + + +//----------------------------------------------------------------------------- +// Rotates a AABB into another space; which will inherently grow the box. +// (same as TransformAABB, but doesn't take the translation into account) +//----------------------------------------------------------------------------- +void RotateAABB( const matrix3x4_t &transform, const Vector &vecMinsIn, const Vector &vecMaxsIn, Vector &vecMinsOut, Vector &vecMaxsOut ) +{ + Vector localCenter; + VectorAdd( vecMinsIn, vecMaxsIn, localCenter ); + localCenter *= 0.5f; + + Vector localExtents; + VectorSubtract( vecMaxsIn, localCenter, localExtents ); + + Vector newCenter; + VectorRotate( localCenter, transform, newCenter ); + + Vector newExtents; + newExtents.x = DotProductAbs( localExtents, transform[0] ); + newExtents.y = DotProductAbs( localExtents, transform[1] ); + newExtents.z = DotProductAbs( localExtents, transform[2] ); + + VectorSubtract( newCenter, newExtents, vecMinsOut ); + VectorAdd( newCenter, newExtents, vecMaxsOut ); +} + + +//----------------------------------------------------------------------------- +// Uses the inverse transform of in1 +//----------------------------------------------------------------------------- +void IRotateAABB( const matrix3x4_t &transform, const Vector &vecMinsIn, const Vector &vecMaxsIn, Vector &vecMinsOut, Vector &vecMaxsOut ) +{ + Vector oldCenter; + VectorAdd( vecMinsIn, vecMaxsIn, oldCenter ); + oldCenter *= 0.5f; + + Vector oldExtents; + VectorSubtract( vecMaxsIn, oldCenter, oldExtents ); + + Vector newCenter; + VectorIRotate( oldCenter, transform, newCenter ); + + Vector newExtents; + newExtents.x = FloatMakePositive( oldExtents.x * transform[0][0] ) + + FloatMakePositive( oldExtents.y * transform[1][0] ) + + FloatMakePositive( oldExtents.z * transform[2][0] ); + newExtents.y = FloatMakePositive( oldExtents.x * transform[0][1] ) + + FloatMakePositive( oldExtents.y * transform[1][1] ) + + FloatMakePositive( oldExtents.z * transform[2][1] ); + newExtents.z = FloatMakePositive( oldExtents.x * transform[0][2] ) + + FloatMakePositive( oldExtents.y * transform[1][2] ) + + FloatMakePositive( oldExtents.z * transform[2][2] ); + + VectorSubtract( newCenter, newExtents, vecMinsOut ); + VectorAdd( newCenter, newExtents, vecMaxsOut ); +} + + +float CalcSqrDistanceToAABB( const Vector &mins, const Vector &maxs, const Vector &point ) +{ + float flDelta; + float flDistSqr = 0.0f; + + if ( point.x < mins.x ) + { + flDelta = (mins.x - point.x); + flDistSqr += flDelta * flDelta; + } + else if ( point.x > maxs.x ) + { + flDelta = (point.x - maxs.x); + flDistSqr += flDelta * flDelta; + } + + if ( point.y < mins.y ) + { + flDelta = (mins.y - point.y); + flDistSqr += flDelta * flDelta; + } + else if ( point.y > maxs.y ) + { + flDelta = (point.y - maxs.y); + flDistSqr += flDelta * flDelta; + } + + if ( point.z < mins.z ) + { + flDelta = (mins.z - point.z); + flDistSqr += flDelta * flDelta; + } + else if ( point.z > maxs.z ) + { + flDelta = (point.z - maxs.z); + flDistSqr += flDelta * flDelta; + } + + return flDistSqr; +} + + +void CalcClosestPointOnAABB( const Vector &mins, const Vector &maxs, const Vector &point, Vector &closestOut ) +{ + closestOut.x = clamp( point.x, mins.x, maxs.x ); + closestOut.y = clamp( point.y, mins.y, maxs.y ); + closestOut.z = clamp( point.z, mins.z, maxs.z ); +} + +void CalcSqrDistAndClosestPointOnAABB( const Vector &mins, const Vector &maxs, const Vector &point, Vector &closestOut, float &distSqrOut ) +{ + distSqrOut = 0.0f; + for ( int i = 0; i < 3; i++ ) + { + if ( point[i] < mins[i] ) + { + closestOut[i] = mins[i]; + float flDelta = closestOut[i] - mins[i]; + distSqrOut += flDelta * flDelta; + } + else if ( point[i] > maxs[i] ) + { + closestOut[i] = maxs[i]; + float flDelta = closestOut[i] - maxs[i]; + distSqrOut += flDelta * flDelta; + } + else + { + closestOut[i] = point[i]; + } + } + +} + +float CalcClosestPointToLineT( const Vector &P, const Vector &vLineA, const Vector &vLineB, Vector &vDir ) +{ + Assert( s_bMathlibInitialized ); + VectorSubtract( vLineB, vLineA, vDir ); + + // D dot [P - (A + D*t)] = 0 + // t = ( DP - DA) / DD + float div = vDir.Dot( vDir ); + if( div < 0.00001f ) + { + return 0; + } + else + { + return (vDir.Dot( P ) - vDir.Dot( vLineA )) / div; + } +} + +void CalcClosestPointOnLine( const Vector &P, const Vector &vLineA, const Vector &vLineB, Vector &vClosest, float *outT ) +{ + Assert( s_bMathlibInitialized ); + Vector vDir; + float t = CalcClosestPointToLineT( P, vLineA, vLineB, vDir ); + if ( outT ) *outT = t; + vClosest.MulAdd( vLineA, vDir, t ); +} + + +float CalcDistanceToLine( const Vector &P, const Vector &vLineA, const Vector &vLineB, float *outT ) +{ + Assert( s_bMathlibInitialized ); + Vector vClosest; + CalcClosestPointOnLine( P, vLineA, vLineB, vClosest, outT ); + return P.DistTo(vClosest); +} + +float CalcDistanceSqrToLine( const Vector &P, const Vector &vLineA, const Vector &vLineB, float *outT ) +{ + Assert( s_bMathlibInitialized ); + Vector vClosest; + CalcClosestPointOnLine( P, vLineA, vLineB, vClosest, outT ); + return P.DistToSqr(vClosest); +} + +void CalcClosestPointOnLineSegment( const Vector &P, const Vector &vLineA, const Vector &vLineB, Vector &vClosest, float *outT ) +{ + Vector vDir; + float t = CalcClosestPointToLineT( P, vLineA, vLineB, vDir ); + t = clamp( t, 0.f, 1.f ); + if ( outT ) + { + *outT = t; + } + vClosest.MulAdd( vLineA, vDir, t ); +} + + +float CalcDistanceToLineSegment( const Vector &P, const Vector &vLineA, const Vector &vLineB, float *outT ) +{ + Assert( s_bMathlibInitialized ); + Vector vClosest; + CalcClosestPointOnLineSegment( P, vLineA, vLineB, vClosest, outT ); + return P.DistTo( vClosest ); +} + +float CalcDistanceSqrToLineSegment( const Vector &P, const Vector &vLineA, const Vector &vLineB, float *outT ) +{ + Assert( s_bMathlibInitialized ); + Vector vClosest; + CalcClosestPointOnLineSegment( P, vLineA, vLineB, vClosest, outT ); + return P.DistToSqr(vClosest); +} + +float CalcClosestPointToLineT2D( const Vector2D &P, const Vector2D &vLineA, const Vector2D &vLineB, Vector2D &vDir ) +{ + Assert( s_bMathlibInitialized ); + Vector2DSubtract( vLineB, vLineA, vDir ); + + // D dot [P - (A + D*t)] = 0 + // t = (DP - DA) / DD + float div = vDir.Dot( vDir ); + if( div < 0.00001f ) + { + return 0; + } + else + { + return (vDir.Dot( P ) - vDir.Dot( vLineA )) / div; + } +} + +void CalcClosestPointOnLine2D( const Vector2D &P, const Vector2D &vLineA, const Vector2D &vLineB, Vector2D &vClosest, float *outT ) +{ + Assert( s_bMathlibInitialized ); + Vector2D vDir; + float t = CalcClosestPointToLineT2D( P, vLineA, vLineB, vDir ); + if ( outT ) *outT = t; + vClosest.MulAdd( vLineA, vDir, t ); +} + +float CalcDistanceToLine2D( const Vector2D &P, const Vector2D &vLineA, const Vector2D &vLineB, float *outT ) +{ + Assert( s_bMathlibInitialized ); + Vector2D vClosest; + CalcClosestPointOnLine2D( P, vLineA, vLineB, vClosest, outT ); + return P.DistTo( vClosest ); +} + +float CalcDistanceSqrToLine2D( const Vector2D &P, const Vector2D &vLineA, const Vector2D &vLineB, float *outT ) +{ + Assert( s_bMathlibInitialized ); + Vector2D vClosest; + CalcClosestPointOnLine2D( P, vLineA, vLineB, vClosest, outT ); + return P.DistToSqr(vClosest); +} + +void CalcClosestPointOnLineSegment2D( const Vector2D &P, const Vector2D &vLineA, const Vector2D &vLineB, Vector2D &vClosest, float *outT ) +{ + Vector2D vDir; + float t = CalcClosestPointToLineT2D( P, vLineA, vLineB, vDir ); + t = clamp( t, 0.f, 1.f ); + if ( outT ) + { + *outT = t; + } + vClosest.MulAdd( vLineA, vDir, t ); +} + +float CalcDistanceToLineSegment2D( const Vector2D &P, const Vector2D &vLineA, const Vector2D &vLineB, float *outT ) +{ + Assert( s_bMathlibInitialized ); + Vector2D vClosest; + CalcClosestPointOnLineSegment2D( P, vLineA, vLineB, vClosest, outT ); + return P.DistTo( vClosest ); +} + +float CalcDistanceSqrToLineSegment2D( const Vector2D &P, const Vector2D &vLineA, const Vector2D &vLineB, float *outT ) +{ + Assert( s_bMathlibInitialized ); + Vector2D vClosest; + CalcClosestPointOnLineSegment2D( P, vLineA, vLineB, vClosest, outT ); + return P.DistToSqr( vClosest ); +} + +// Do we have another epsilon we could use +#define LINE_EPS ( 0.000001f ) + +//----------------------------------------------------------------------------- +// Purpose: Given lines p1->p2 and p3->p4, computes a line segment (pa->pb) and returns the parameters 0->1 multipliers +// along each segment for the returned points +// Input : p1 - +// p2 - +// p3 - +// p4 - +// *s1 - +// *s2 - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CalcLineToLineIntersectionSegment( + const Vector& p1,const Vector& p2,const Vector& p3,const Vector& p4,Vector *s1,Vector *s2, + float *t1, float *t2) +{ + Vector p13,p43,p21; + float d1343,d4321,d1321,d4343,d2121; + float numer,denom; + + p13.x = p1.x - p3.x; + p13.y = p1.y - p3.y; + p13.z = p1.z - p3.z; + p43.x = p4.x - p3.x; + p43.y = p4.y - p3.y; + p43.z = p4.z - p3.z; + + if (fabs(p43.x) < LINE_EPS && fabs(p43.y) < LINE_EPS && fabs(p43.z) < LINE_EPS) + return false; + p21.x = p2.x - p1.x; + p21.y = p2.y - p1.y; + p21.z = p2.z - p1.z; + if (fabs(p21.x) < LINE_EPS && fabs(p21.y) < LINE_EPS && fabs(p21.z) < LINE_EPS) + return false; + + d1343 = p13.x * p43.x + p13.y * p43.y + p13.z * p43.z; + d4321 = p43.x * p21.x + p43.y * p21.y + p43.z * p21.z; + d1321 = p13.x * p21.x + p13.y * p21.y + p13.z * p21.z; + d4343 = p43.x * p43.x + p43.y * p43.y + p43.z * p43.z; + d2121 = p21.x * p21.x + p21.y * p21.y + p21.z * p21.z; + + denom = d2121 * d4343 - d4321 * d4321; + if (fabs(denom) < LINE_EPS) + return false; + numer = d1343 * d4321 - d1321 * d4343; + + *t1 = numer / denom; + *t2 = (d1343 + d4321 * (*t1)) / d4343; + + s1->x = p1.x + *t1 * p21.x; + s1->y = p1.y + *t1 * p21.y; + s1->z = p1.z + *t1 * p21.z; + s2->x = p3.x + *t2 * p43.x; + s2->y = p3.y + *t2 * p43.y; + s2->z = p3.z + *t2 * p43.z; + + return true; +} + +#pragma optimize( "", off ) + +#ifndef EXCEPTION_EXECUTE_HANDLER +#define EXCEPTION_EXECUTE_HANDLER 1 +#endif + +#pragma optimize( "", on ) + +static bool s_b3DNowEnabled = false; +static bool s_bMMXEnabled = false; +static bool s_bSSEEnabled = false; +static bool s_bSSE2Enabled = false; + +void MathLib_Init( float gamma, float texGamma, float brightness, int overbright, bool bAllow3DNow, bool bAllowSSE, bool bAllowSSE2, bool bAllowMMX ) +{ + if ( s_bMathlibInitialized ) + return; + + // FIXME: Hook SSE into VectorAligned + Vector4DAligned + +#if !defined( _X360 ) + // Grab the processor information: + const CPUInformation& pi = *GetCPUInformation(); + + // Select the default generic routines. + pfSqrt = _sqrtf; + pfRSqrt = _rsqrtf; + pfRSqrtFast = _rsqrtf; + pfVectorNormalize = _VectorNormalize; + pfVectorNormalizeFast = _VectorNormalizeFast; + pfInvRSquared = _InvRSquared; + pfFastSinCos = SinCos; + pfFastCos = cosf; + + if ( bAllowMMX && pi.m_bMMX ) + { + // Select the MMX specific routines if available + // (MMX routines were used by SW span fillers - not currently used for HW) + s_bMMXEnabled = true; + } + else + { + s_bMMXEnabled = false; + } + + // SSE Generally performs better than 3DNow when present, so this is placed + // first to allow SSE to override these settings. +#if !defined( OSX ) && !defined( PLATFORM_WINDOWS_PC64 ) && !defined(LINUX) + if ( bAllow3DNow && pi.m_b3DNow ) + { + s_b3DNowEnabled = true; + + // Select the 3DNow specific routines if available; + pfVectorNormalize = _3DNow_VectorNormalize; + pfVectorNormalizeFast = _3DNow_VectorNormalizeFast; + pfInvRSquared = _3DNow_InvRSquared; + pfSqrt = _3DNow_Sqrt; + pfRSqrt = _3DNow_RSqrt; + pfRSqrtFast = _3DNow_RSqrt; + } + else +#endif + { + s_b3DNowEnabled = false; + } + + if ( bAllowSSE && pi.m_bSSE ) + { + s_bSSEEnabled = true; + +#ifndef PLATFORM_WINDOWS_PC64 + // These are not yet available. + // Select the SSE specific routines if available + pfVectorNormalize = _VectorNormalize; + pfVectorNormalizeFast = _SSE_VectorNormalizeFast; + pfInvRSquared = _SSE_InvRSquared; + pfSqrt = _SSE_Sqrt; + pfRSqrt = _SSE_RSqrtAccurate; + pfRSqrtFast = _SSE_RSqrtFast; +#endif +#ifdef PLATFORM_WINDOWS_PC32 + pfFastSinCos = _SSE_SinCos; + pfFastCos = _SSE_cos; +#endif + } + else + { + s_bSSEEnabled = false; + } + + if ( bAllowSSE2 && pi.m_bSSE2 ) + { + s_bSSE2Enabled = true; +#ifdef PLATFORM_WINDOWS_PC32 + pfFastSinCos = _SSE2_SinCos; + pfFastCos = _SSE2_cos; +#endif + } + else + { + s_bSSE2Enabled = false; + } +#endif + + s_bMathlibInitialized = true; + + InitSinCosTable(); + BuildGammaTable( gamma, texGamma, brightness, overbright ); +} + +bool MathLib_3DNowEnabled( void ) +{ + Assert( s_bMathlibInitialized ); + return s_b3DNowEnabled; +} + +bool MathLib_MMXEnabled( void ) +{ + Assert( s_bMathlibInitialized ); + return s_bMMXEnabled; +} + +bool MathLib_SSEEnabled( void ) +{ + Assert( s_bMathlibInitialized ); + return s_bSSEEnabled; +} + +bool MathLib_SSE2Enabled( void ) +{ + Assert( s_bMathlibInitialized ); + return s_bSSE2Enabled; +} + +float Approach( float target, float value, float speed ) +{ + float delta = target - value; + + if ( delta > speed ) + value += speed; + else if ( delta < -speed ) + value -= speed; + else + value = target; + + return value; +} + +// BUGBUG: Why doesn't this call angle diff?!?!? +float ApproachAngle( float target, float value, float speed ) +{ + target = anglemod( target ); + value = anglemod( value ); + + float delta = target - value; + + // Speed is assumed to be positive + if ( speed < 0 ) + speed = -speed; + + if ( delta < -180 ) + delta += 360; + else if ( delta > 180 ) + delta -= 360; + + if ( delta > speed ) + value += speed; + else if ( delta < -speed ) + value -= speed; + else + value = target; + + return value; +} + + +// BUGBUG: Why do we need both of these? +float AngleDiff( float destAngle, float srcAngle ) +{ + float delta; + + delta = fmodf(destAngle - srcAngle, 360.0f); + if ( destAngle > srcAngle ) + { + if ( delta >= 180 ) + delta -= 360; + } + else + { + if ( delta <= -180 ) + delta += 360; + } + return delta; +} + + +float AngleDistance( float next, float cur ) +{ + float delta = next - cur; + + if ( delta < -180 ) + delta += 360; + else if ( delta > 180 ) + delta -= 360; + + return delta; +} + + +float AngleNormalize( float angle ) +{ + angle = fmodf(angle, 360.0f); + if (angle > 180) + { + angle -= 360; + } + if (angle < -180) + { + angle += 360; + } + return angle; +} + +//-------------------------------------------------------------------------------------------------------------- +// ensure that 0 <= angle <= 360 +float AngleNormalizePositive( float angle ) +{ + angle = fmodf( angle, 360.0f ); + + if (angle < 0.0f) + { + angle += 360.0f; + } + + return angle; +} + +//-------------------------------------------------------------------------------------------------------------- +bool AnglesAreEqual( float a, float b, float tolerance ) +{ + return (fabs( AngleDiff( a, b ) ) < tolerance); +} + +void RotationDeltaAxisAngle( const QAngle &srcAngles, const QAngle &destAngles, Vector &deltaAxis, float &deltaAngle ) +{ + Quaternion srcQuat, destQuat, srcQuatInv, out; + AngleQuaternion( srcAngles, srcQuat ); + AngleQuaternion( destAngles, destQuat ); + QuaternionScale( srcQuat, -1, srcQuatInv ); + QuaternionMult( destQuat, srcQuatInv, out ); + + QuaternionNormalize( out ); + QuaternionAxisAngle( out, deltaAxis, deltaAngle ); +} + +void RotationDelta( const QAngle &srcAngles, const QAngle &destAngles, QAngle *out ) +{ + matrix3x4_t src, srcInv; + matrix3x4_t dest; + AngleMatrix( srcAngles, src ); + AngleMatrix( destAngles, dest ); + // xform = src(-1) * dest + MatrixInvert( src, srcInv ); + matrix3x4_t xform; + ConcatTransforms( dest, srcInv, xform ); + QAngle xformAngles; + MatrixAngles( xform, xformAngles ); + if ( out ) + { + *out = xformAngles; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Computes a triangle normal +//----------------------------------------------------------------------------- +void ComputeTrianglePlane( const Vector& v1, const Vector& v2, const Vector& v3, Vector& normal, float& intercept ) +{ + Vector e1, e2; + VectorSubtract( v2, v1, e1 ); + VectorSubtract( v3, v1, e2 ); + CrossProduct( e1, e2, normal ); + VectorNormalize( normal ); + intercept = DotProduct( normal, v1 ); +} + +//----------------------------------------------------------------------------- +// Purpose: This is a clone of BaseWindingForPlane() +// Input : *outVerts - an array of preallocated verts to build the polygon in +// normal - the plane normal +// dist - the plane constant +// Output : int - vert count (always 4) +//----------------------------------------------------------------------------- +int PolyFromPlane( Vector *outVerts, const Vector& normal, float dist, float fHalfScale ) +{ + int i, x; + vec_t max, v; + Vector org, vright, vup; + + // find the major axis + + max = -16384; //MAX_COORD_INTEGER + x = -1; + for (i=0 ; i<3; i++) + { + v = fabs(normal[i]); + if (v > max) + { + x = i; + max = v; + } + } + + if (x==-1) + return 0; + + // Build a unit vector along something other than the major axis + VectorCopy (vec3_origin, vup); + switch (x) + { + case 0: + case 1: + vup[2] = 1; + break; + case 2: + vup[0] = 1; + break; + } + + // Remove the component of this vector along the normal + v = DotProduct (vup, normal); + VectorMA (vup, -v, normal, vup); + // Make it a unit (perpendicular) + VectorNormalize (vup); + + // Center of the poly is at normal * dist + VectorScale (normal, dist, org); + // Calculate the third orthonormal basis vector for our plane space (this one and vup are in the plane) + CrossProduct (vup, normal, vright); + + // Make the plane's basis vectors big (these are the half-sides of the polygon we're making) + VectorScale (vup, fHalfScale, vup); + VectorScale (vright, fHalfScale, vright); + + // Move diagonally away from org to create the corner verts + VectorSubtract (org, vright, outVerts[0]); // left + VectorAdd (outVerts[0], vup, outVerts[0]); // up + + VectorAdd (org, vright, outVerts[1]); // right + VectorAdd (outVerts[1], vup, outVerts[1]); // up + + VectorAdd (org, vright, outVerts[2]); // right + VectorSubtract (outVerts[2], vup, outVerts[2]); // down + + VectorSubtract (org, vright, outVerts[3]); // left + VectorSubtract (outVerts[3], vup, outVerts[3]); // down + + // The four corners form a planar quadrilateral normal to "normal" + return 4; +} + +//----------------------------------------------------------------------------- +// Purpose: clip a poly to the plane and return the poly on the front side of the plane +// Input : *inVerts - input polygon +// vertCount - # verts in input poly +// *outVerts - destination poly +// normal - plane normal +// dist - plane constant +// Output : int - # verts in output poly +//----------------------------------------------------------------------------- + +int ClipPolyToPlane( Vector *inVerts, int vertCount, Vector *outVerts, const Vector& normal, float dist, float fOnPlaneEpsilon ) +{ + vec_t *dists = (vec_t *)stackalloc( sizeof(vec_t) * vertCount * 4 ); //4x vertcount should cover all cases + int *sides = (int *)stackalloc( sizeof(vec_t) * vertCount * 4 ); + int counts[3]; + vec_t dot; + int i, j; + Vector mid = vec3_origin; + int outCount; + + counts[0] = counts[1] = counts[2] = 0; + + // determine sides for each point + for ( i = 0; i < vertCount; i++ ) + { + dot = DotProduct( inVerts[i], normal) - dist; + dists[i] = dot; + if ( dot > fOnPlaneEpsilon ) + { + sides[i] = SIDE_FRONT; + } + else if ( dot < -fOnPlaneEpsilon ) + { + sides[i] = SIDE_BACK; + } + else + { + sides[i] = SIDE_ON; + } + counts[sides[i]]++; + } + sides[i] = sides[0]; + dists[i] = dists[0]; + + if (!counts[0]) + return 0; + + if (!counts[1]) + { + // Copy to output verts + for ( i = 0; i < vertCount; i++ ) + { + VectorCopy( inVerts[i], outVerts[i] ); + } + return vertCount; + } + + outCount = 0; + for ( i = 0; i < vertCount; i++ ) + { + Vector& p1 = inVerts[i]; + + if (sides[i] == SIDE_ON) + { + VectorCopy( p1, outVerts[outCount]); + outCount++; + continue; + } + + if (sides[i] == SIDE_FRONT) + { + VectorCopy( p1, outVerts[outCount]); + outCount++; + } + + if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i]) + continue; + + // generate a split point + Vector& p2 = inVerts[(i+1)%vertCount]; + + 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, outVerts[outCount]); + outCount++; + } + + return outCount; +} + + +int ClipPolyToPlane_Precise( double *inVerts, int vertCount, double *outVerts, const double *normal, double dist, double fOnPlaneEpsilon ) +{ + double *dists = (double *)stackalloc( sizeof(double) * vertCount * 4 ); //4x vertcount should cover all cases + int *sides = (int *)stackalloc( sizeof(double) * vertCount * 4 ); + int counts[3]; + double dot; + int i, j; + //Vector mid = vec3_origin; + double mid[3]; + mid[0] = 0.0; + mid[1] = 0.0; + mid[2] = 0.0; + int outCount; + + counts[0] = counts[1] = counts[2] = 0; + + // determine sides for each point + for ( i = 0; i < vertCount; i++ ) + { + //dot = DotProduct( inVerts[i], normal) - dist; + dot = ((inVerts[i*3 + 0] * normal[0]) + (inVerts[i*3 + 1] * normal[1]) + (inVerts[i*3 + 2] * normal[2])) - dist; + dists[i] = dot; + if ( dot > fOnPlaneEpsilon ) + { + sides[i] = SIDE_FRONT; + } + else if ( dot < -fOnPlaneEpsilon ) + { + sides[i] = SIDE_BACK; + } + else + { + sides[i] = SIDE_ON; + } + counts[sides[i]]++; + } + sides[i] = sides[0]; + dists[i] = dists[0]; + + if (!counts[0]) + return 0; + + if (!counts[1]) + { + // Copy to output verts + //for ( i = 0; i < vertCount; i++ ) + for ( i = 0; i < vertCount * 3; i++ ) + { + //VectorCopy( inVerts[i], outVerts[i] ); + outVerts[i] = inVerts[i]; + } + return vertCount; + } + + outCount = 0; + for ( i = 0; i < vertCount; i++ ) + { + //Vector& p1 = inVerts[i]; + double *p1 = &inVerts[i*3]; + //p1[0] = inVerts[i*3 + 0]; + //p1[1] = inVerts[i*3 + 1]; + //p1[2] = inVerts[i*3 + 2]; + + if (sides[i] == SIDE_ON) + { + //VectorCopy( p1, outVerts[outCount]); + outVerts[outCount*3 + 0] = p1[0]; + outVerts[outCount*3 + 1] = p1[1]; + outVerts[outCount*3 + 2] = p1[2]; + outCount++; + continue; + } + + if (sides[i] == SIDE_FRONT) + { + //VectorCopy( p1, outVerts[outCount]); + outVerts[outCount*3 + 0] = p1[0]; + outVerts[outCount*3 + 1] = p1[1]; + outVerts[outCount*3 + 2] = p1[2]; + outCount++; + } + + if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i]) + continue; + + // generate a split point + //Vector& p2 = inVerts[(i+1)%vertCount]; + int wrappedindex = (i+1)%vertCount; + double *p2 = &inVerts[wrappedindex*3]; + //p2[0] = inVerts[wrappedindex*3 + 0]; + //p2[1] = inVerts[wrappedindex*3 + 1]; + //p2[2] = inVerts[wrappedindex*3 + 2]; + + dot = dists[i] / (dists[i]-dists[i+1]); + for (j=0 ; j<3 ; j++) + { + mid[j] = (double)p1[j] + dot*((double)p2[j]-(double)p1[j]); + } + + //VectorCopy (mid, outVerts[outCount]); + outVerts[outCount*3 + 0] = mid[0]; + outVerts[outCount*3 + 1] = mid[1]; + outVerts[outCount*3 + 2] = mid[2]; + outCount++; + } + + return outCount; +} + +int CeilPow2( int in ) +{ + int retval; + + retval = 1; + while( retval < in ) + retval <<= 1; + return retval; +} + +int FloorPow2( int in ) +{ + int retval; + + retval = 1; + while( retval < in ) + retval <<= 1; + return retval >> 1; +} + + +//----------------------------------------------------------------------------- +// Computes Y fov from an X fov and a screen aspect ratio +//----------------------------------------------------------------------------- +float CalcFovY( float flFovX, float flAspect ) +{ + if ( flFovX < 1 || flFovX > 179) + { + flFovX = 90; // error, set to 90 + } + + // The long, but illustrative version (more closely matches CShaderAPIDX8::PerspectiveX, which + // is what it's based on). + // + //float width = 2 * zNear * tan( DEG2RAD( fov_x / 2.0 ) ); + //float height = width / screenaspect; + //float yRadians = atan( (height/2.0) / zNear ); + //return RAD2DEG( yRadians ) * 2; + + // The short and sweet version. + float val = atan( tan( DEG2RAD( flFovX ) * 0.5f ) / flAspect ); + val = RAD2DEG( val ) * 2.0f; + return val; +} + +float CalcFovX( float flFovY, float flAspect ) +{ + return RAD2DEG( atan( tan( DEG2RAD( flFovY ) * 0.5f ) * flAspect ) ) * 2.0f; +} + + +//----------------------------------------------------------------------------- +// Generate a frustum based on perspective view parameters +//----------------------------------------------------------------------------- +void GeneratePerspectiveFrustum( const Vector& origin, const Vector &forward, + const Vector &right, const Vector &up, float flZNear, float flZFar, + float flFovX, float flFovY, Frustum_t &frustum ) +{ + float flIntercept = DotProduct( origin, forward ); + + // Setup the near and far planes. + frustum.SetPlane( FRUSTUM_FARZ, PLANE_ANYZ, -forward, -flZFar - flIntercept ); + frustum.SetPlane( FRUSTUM_NEARZ, PLANE_ANYZ, forward, flZNear + flIntercept ); + + flFovX *= 0.5f; + flFovY *= 0.5f; + + float flTanX = tan( DEG2RAD( flFovX ) ); + float flTanY = tan( DEG2RAD( flFovY ) ); + + // OPTIMIZE: Normalizing these planes is not necessary for culling + Vector normalPos, normalNeg; + + VectorMA( right, flTanX, forward, normalPos ); + VectorMA( normalPos, -2.0f, right, normalNeg ); + + VectorNormalize( normalPos ); + VectorNormalize( normalNeg ); + + frustum.SetPlane( FRUSTUM_LEFT, PLANE_ANYZ, normalPos, normalPos.Dot( origin ) ); + frustum.SetPlane( FRUSTUM_RIGHT, PLANE_ANYZ, normalNeg, normalNeg.Dot( origin ) ); + + VectorMA( up, flTanY, forward, normalPos ); + VectorMA( normalPos, -2.0f, up, normalNeg ); + + VectorNormalize( normalPos ); + VectorNormalize( normalNeg ); + + frustum.SetPlane( FRUSTUM_BOTTOM, PLANE_ANYZ, normalPos, normalPos.Dot( origin ) ); + frustum.SetPlane( FRUSTUM_TOP, PLANE_ANYZ, normalNeg, normalNeg.Dot( origin ) ); +} + + +//----------------------------------------------------------------------------- +// Version that accepts angles instead of vectors +//----------------------------------------------------------------------------- +void GeneratePerspectiveFrustum( const Vector& origin, const QAngle &angles, float flZNear, float flZFar, float flFovX, float flAspectRatio, Frustum_t &frustum ) +{ + Vector vecForward, vecRight, vecUp; + AngleVectors( angles, &vecForward, &vecRight, &vecUp ); + float flFovY = CalcFovY( flFovX, flAspectRatio ); + GeneratePerspectiveFrustum( origin, vecForward, vecRight, vecUp, flZNear, flZFar, flFovX, flFovY, frustum ); +} + +bool R_CullBox( const Vector& mins, const Vector& maxs, const Frustum_t &frustum ) +{ + return (( BoxOnPlaneSide( mins, maxs, frustum.GetPlane(FRUSTUM_RIGHT) ) == 2 ) || + ( BoxOnPlaneSide( mins, maxs, frustum.GetPlane(FRUSTUM_LEFT) ) == 2 ) || + ( BoxOnPlaneSide( mins, maxs, frustum.GetPlane(FRUSTUM_TOP) ) == 2 ) || + ( BoxOnPlaneSide( mins, maxs, frustum.GetPlane(FRUSTUM_BOTTOM) ) == 2 ) || + ( BoxOnPlaneSide( mins, maxs, frustum.GetPlane(FRUSTUM_NEARZ) ) == 2 ) || + ( BoxOnPlaneSide( mins, maxs, frustum.GetPlane(FRUSTUM_FARZ) ) == 2 ) ); +} + +bool R_CullBoxSkipNear( const Vector& mins, const Vector& maxs, const Frustum_t &frustum ) +{ + return (( BoxOnPlaneSide( mins, maxs, frustum.GetPlane(FRUSTUM_RIGHT) ) == 2 ) || + ( BoxOnPlaneSide( mins, maxs, frustum.GetPlane(FRUSTUM_LEFT) ) == 2 ) || + ( BoxOnPlaneSide( mins, maxs, frustum.GetPlane(FRUSTUM_TOP) ) == 2 ) || + ( BoxOnPlaneSide( mins, maxs, frustum.GetPlane(FRUSTUM_BOTTOM) ) == 2 ) || + ( BoxOnPlaneSide( mins, maxs, frustum.GetPlane(FRUSTUM_FARZ) ) == 2 ) ); +} + + +// NOTE: This routine was taken (and modified) from NVidia's BlinnReflection demo +// Creates basis vectors, based on a vertex and index list. +// See the NVidia white paper 'GDC2K PerPixel Lighting' for a description +// of how this computation works +#define SMALL_FLOAT 1e-12 + +void CalcTriangleTangentSpace( const Vector &p0, const Vector &p1, const Vector &p2, + const Vector2D &t0, const Vector2D &t1, const Vector2D& t2, + Vector &sVect, Vector &tVect ) +{ + /* Compute the partial derivatives of X, Y, and Z with respect to S and T. */ + sVect.Init( 0.0f, 0.0f, 0.0f ); + tVect.Init( 0.0f, 0.0f, 0.0f ); + + // x, s, t + Vector edge01( p1.x - p0.x, t1.x - t0.x, t1.y - t0.y ); + Vector edge02( p2.x - p0.x, t2.x - t0.x, t2.y - t0.y ); + + Vector cross; + CrossProduct( edge01, edge02, cross ); + if ( fabs( cross.x ) > SMALL_FLOAT ) + { + sVect.x += -cross.y / cross.x; + tVect.x += -cross.z / cross.x; + } + + // y, s, t + edge01.Init( p1.y - p0.y, t1.x - t0.x, t1.y - t0.y ); + edge02.Init( p2.y - p0.y, t2.x - t0.x, t2.y - t0.y ); + + CrossProduct( edge01, edge02, cross ); + if ( fabs( cross.x ) > SMALL_FLOAT ) + { + sVect.y += -cross.y / cross.x; + tVect.y += -cross.z / cross.x; + } + + // z, s, t + edge01.Init( p1.z - p0.z, t1.x - t0.x, t1.y - t0.y ); + edge02.Init( p2.z - p0.z, t2.x - t0.x, t2.y - t0.y ); + + CrossProduct( edge01, edge02, cross ); + if( fabs( cross.x ) > SMALL_FLOAT ) + { + sVect.z += -cross.y / cross.x; + tVect.z += -cross.z / cross.x; + } + + // Normalize sVect and tVect + VectorNormalize( sVect ); + VectorNormalize( tVect ); +} + + +//----------------------------------------------------------------------------- +// Convert RGB to HSV +//----------------------------------------------------------------------------- +void RGBtoHSV( const Vector &rgb, Vector &hsv ) +{ + float flMax = max( rgb.x, rgb.y ); + flMax = max( flMax, rgb.z ); + float flMin = min( rgb.x, rgb.y ); + flMin = min( flMin, rgb.z ); + + // hsv.z is the value + hsv.z = flMax; + + // hsv.y is the saturation + if (flMax != 0.0F) + { + hsv.y = (flMax - flMin) / flMax; + } + else + { + hsv.y = 0.0F; + } + + // hsv.x is the hue + if (hsv.y == 0.0F) + { + hsv.x = -1.0f; + } + else + { + float32 d = flMax - flMin; + if (rgb.x == flMax) + { + hsv.x = (rgb.y - rgb.z) / d; + } + else if (rgb.y == flMax) + { + hsv.x = 2.0F + (rgb.z - rgb.x) / d; + } + else + { + hsv.x = 4.0F + (rgb.x - rgb.y) / d; + } + hsv.x *= 60.0F; + if ( hsv.x < 0.0F ) + { + hsv.x += 360.0F; + } + } +} + + +//----------------------------------------------------------------------------- +// Convert HSV to RGB +//----------------------------------------------------------------------------- +void HSVtoRGB( const Vector &hsv, Vector &rgb ) +{ + if ( hsv.y == 0.0F ) + { + rgb.Init( hsv.z, hsv.z, hsv.z ); + return; + } + + float32 hue = hsv.x; + if (hue == 360.0F) + { + hue = 0.0F; + } + hue /= 60.0F; + int i = hue; // integer part + float32 f = hue - i; // fractional part + float32 p = hsv.z * (1.0F - hsv.y); + float32 q = hsv.z * (1.0F - hsv.y * f); + float32 t = hsv.z * (1.0F - hsv.y * (1.0F - f)); + switch(i) + { + case 0: rgb.Init( hsv.z, t, p ); break; + case 1: rgb.Init( q, hsv.z, p ); break; + case 2: rgb.Init( p, hsv.z, t ); break; + case 3: rgb.Init( p, q, hsv.z ); break; + case 4: rgb.Init( t, p, hsv.z ); break; + case 5: rgb.Init( hsv.z, p, q ); break; + } +} + + +void GetInterpolationData( float const *pKnotPositions, + float const *pKnotValues, + int nNumValuesinList, + int nInterpolationRange, + float flPositionToInterpolateAt, + bool bWrap, + float *pValueA, + float *pValueB, + float *pInterpolationValue) +{ + // first, find the bracketting knots by looking for the first knot >= our index + + int idx; + for(idx = 0; idx < nNumValuesinList; idx++ ) + { + if ( pKnotPositions[idx] >= flPositionToInterpolateAt ) + break; + } + int nKnot1, nKnot2; + float flOffsetFromStartOfGap, flSizeOfGap; + if ( idx == 0) + { + if ( bWrap ) + { + nKnot1 = nNumValuesinList-1; + nKnot2 = 0; + flSizeOfGap = + ( pKnotPositions[nKnot2] + ( nInterpolationRange-pKnotPositions[nKnot1] ) ); + flOffsetFromStartOfGap = + flPositionToInterpolateAt + ( nInterpolationRange-pKnotPositions[nKnot1] ); + } + else + { + *pValueA = *pValueB = pKnotValues[0]; + *pInterpolationValue = 1.0; + return; + } + } + else if ( idx == nNumValuesinList ) // ran out of values + { + if ( bWrap ) + { + nKnot1 = nNumValuesinList -1; + nKnot2 = 0; + flSizeOfGap = ( pKnotPositions[nKnot2] + + ( nInterpolationRange-pKnotPositions[nKnot1] ) ); + flOffsetFromStartOfGap = flPositionToInterpolateAt - pKnotPositions[nKnot1]; + } + else + { + *pValueA = *pValueB = pKnotValues[nNumValuesinList-1]; + *pInterpolationValue = 1.0; + return; + } + + } + else + { + nKnot1 = idx-1; + nKnot2 = idx; + flSizeOfGap = pKnotPositions[nKnot2]-pKnotPositions[nKnot1]; + flOffsetFromStartOfGap = flPositionToInterpolateAt-pKnotPositions[nKnot1]; + } + + *pValueA = pKnotValues[nKnot1]; + *pValueB = pKnotValues[nKnot2]; + *pInterpolationValue = FLerp( 0, 1, 0, flSizeOfGap, flOffsetFromStartOfGap ); + return; +} + +float RandomVectorInUnitSphere( Vector *pVector ) +{ + // Guarantee uniform random distribution within a sphere + // Graphics gems III contains this algorithm ("Nonuniform random point sets via warping") + float u = ((float)rand() / VALVE_RAND_MAX); + float v = ((float)rand() / VALVE_RAND_MAX); + float w = ((float)rand() / VALVE_RAND_MAX); + + float flPhi = acos( 1 - 2 * u ); + float flTheta = 2 * M_PI * v; + float flRadius = powf( w, 1.0f / 3.0f ); + + float flSinPhi, flCosPhi; + float flSinTheta, flCosTheta; + SinCos( flPhi, &flSinPhi, &flCosPhi ); + SinCos( flTheta, &flSinTheta, &flCosTheta ); + + pVector->x = flRadius * flSinPhi * flCosTheta; + pVector->y = flRadius * flSinPhi * flSinTheta; + pVector->z = flRadius * flCosPhi; + return flRadius; +} + +float RandomVectorInUnitCircle( Vector2D *pVector ) +{ + // Guarantee uniform random distribution within a sphere + // Graphics gems III contains this algorithm ("Nonuniform random point sets via warping") + float u = ((float)rand() / VALVE_RAND_MAX); + float v = ((float)rand() / VALVE_RAND_MAX); + + float flTheta = 2 * M_PI * v; + float flRadius = powf( u, 1.0f / 2.0f ); + + float flSinTheta, flCosTheta; + SinCos( flTheta, &flSinTheta, &flCosTheta ); + + pVector->x = flRadius * flCosTheta; + pVector->y = flRadius * flSinTheta; + return flRadius; +} +#ifdef FP_EXCEPTIONS_ENABLED +#include // For _clearfp and _controlfp_s +#endif + +// FPExceptionDisable and FPExceptionEnabler taken from my blog post +// at http://www.altdevblogaday.com/2012/04/20/exceptional-floating-point/ + +#ifdef FP_EXCEPTIONS_ENABLED +// These functions are all inlined NOPs if FP_EXCEPTIONS_ENABLED is not defined. +FPExceptionDisabler::FPExceptionDisabler() +{ + // Retrieve the current state of the exception flags. This + // must be done before changing them. _MCW_EM is a bit + // mask representing all available exception masks. + _controlfp_s(&mOldValues, 0, 0); + // Set all of the exception flags, which suppresses FP + // exceptions on the x87 and SSE units. + _controlfp_s(0, _MCW_EM, _MCW_EM); +} + +FPExceptionDisabler::~FPExceptionDisabler() +{ + // Clear any pending FP exceptions. This must be done + // prior to enabling FP exceptions since otherwise there + // may be a 'deferred crash' as soon the exceptions are + // enabled. + _clearfp(); + + // Reset (possibly enabling) the exception status. + _controlfp_s(0, mOldValues, _MCW_EM); +} + +// Overflow, divide-by-zero, and invalid-operation are the FP +// exceptions most frequently associated with bugs. +FPExceptionEnabler::FPExceptionEnabler(unsigned int enableBits /*= _EM_OVERFLOW | _EM_ZERODIVIDE | _EM_INVALID*/) +{ + // Retrieve the current state of the exception flags. This + // must be done before changing them. _MCW_EM is a bit + // mask representing all available exception masks. + _controlfp_s(&mOldValues, 0, 0); + + // Make sure no non-exception flags have been specified, + // to avoid accidental changing of rounding modes, etc. + enableBits &= _MCW_EM; + + // Clear any pending FP exceptions. This must be done + // prior to enabling FP exceptions since otherwise there + // may be a 'deferred crash' as soon the exceptions are + // enabled. + _clearfp(); + + // Zero out the specified bits, leaving other bits alone. + _controlfp_s(0, ~enableBits, enableBits); +} + +FPExceptionEnabler::~FPExceptionEnabler() +{ + // Reset the exception state. + _controlfp_s(0, mOldValues, _MCW_EM); +} +#endif diff --git a/sp/src/mathlib/noisedata.h b/sp/src/mathlib/noisedata.h new file mode 100644 index 00000000..6d5cd3d0 --- /dev/null +++ b/sp/src/mathlib/noisedata.h @@ -0,0 +1,180 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: static data for noise() primitives. +// +// $Workfile: $ +// $NoKeywords: $ +//=============================================================================// +// +// **** DO NOT EDIT THIS FILE. GENERATED BY DATAGEN.PL **** +// + +static int perm_a[]={ + 66,147,106,213,89,115,239,25,171,175,9,114,141,226,118,128,41,208,4,56, + 180,248,43,82,246,219,94,245,133,131,222,103,160,130,168,145,238,38,23,6, + 236,67,99,2,70,232,80,209,1,3,68,65,102,210,13,73,55,252,187,170,22,36, + 52,181,117,163,46,79,166,224,148,75,113,95,156,185,220,164,51,142,161,35, + 206,251,45,136,197,190,132,32,218,127,63,27,137,93,242,20,189,108,183, + 122,139,191,249,253,87,98,69,0,144,64,24,214,97,116,158,42,107,15,53,212, + 83,111,152,240,74,237,62,77,205,149,26,151,178,204,91,176,234,49,154,203, + 33,221,125,134,165,124,86,39,37,60,150,157,179,109,110,44,159,153,5,100, + 10,207,40,186,96,215,143,162,230,184,101,54,174,247,76,59,241,223,192,84, + 104,78,169,146,138,30,48,85,233,19,29,92,126,17,199,250,31,81,188,225,28, + 112,88,11,182,173,211,129,194,172,14,120,200,167,135,12,177,227,229,155, + 201,61,105,195,193,244,235,58,8,196,123,254,16,18,50,121,71,243,90,57, + 202,119,255,47,7,198,228,21,217,216,231,140,72,34 +}; + +static int perm_b[]={ + 123,108,201,64,40,75,24,221,137,110,191,142,9,69,230,83,7,247,51,54,115, + 133,180,248,109,116,62,99,251,55,89,253,65,106,228,167,131,132,58,143, + 97,102,163,202,149,234,12,117,174,94,121,74,32,113,20,60,159,182,204,29, + 244,118,3,178,255,38,6,114,36,93,30,134,213,90,245,209,88,232,162,125, + 84,166,70,136,208,231,27,71,157,80,76,0,170,225,203,176,33,161,196,128, + 252,236,246,2,138,1,250,197,77,243,218,242,19,164,68,212,14,237,144,63, + 46,103,177,188,85,223,8,160,222,4,216,219,35,15,44,23,126,127,100,226, + 235,37,168,101,49,22,11,73,61,135,111,183,72,96,185,239,82,18,50,155, + 186,153,17,233,146,156,107,5,254,10,192,198,148,207,104,13,124,48,95, + 129,120,206,199,81,249,91,150,210,119,240,122,194,92,34,28,205,175,227, + 179,220,140,152,79,26,195,47,66,173,169,241,53,184,187,145,112,238,214, + 147,98,171,229,200,151,25,67,78,189,217,130,224,57,172,59,41,43,16,105, + 158,165,21,45,56,141,139,215,190,86,42,52,39,87,181,31,154,193,211 +}; + +static int perm_c[]={ + 97,65,96,25,122,26,219,85,148,251,102,0,140,130,136,213,138,60,236,52, + 178,131,115,183,144,78,147,168,39,45,169,70,57,146,67,142,252,216,28,54, + 86,222,194,200,48,5,205,125,214,56,181,255,196,155,37,218,153,208,66, + 242,73,248,206,61,62,246,177,2,197,107,162,152,89,41,6,160,94,8,201,38, + 235,228,165,93,111,239,74,231,121,47,166,221,157,64,77,244,29,105,150, + 123,190,191,225,118,133,42,10,84,185,159,124,132,240,180,44,1,9,19,99, + 254,12,207,186,71,234,184,11,20,16,193,139,175,98,59,113,27,170,230,91, + 187,46,156,249,108,195,171,114,14,188,82,192,233,24,32,241,87,164,90,43, + 163,245,92,40,215,55,226,15,3,112,158,250,172,22,227,137,35,128,145,247, + 161,119,80,217,189,81,7,63,202,120,223,83,179,4,106,199,229,95,53,50,33, + 182,72,143,23,243,75,18,173,141,167,198,204,58,174,237,17,129,238,127, + 31,101,176,36,30,110,209,34,203,135,232,68,149,49,134,126,212,79,76,117, + 104,210,211,224,253,100,220,109,116,88,13,151,154,69,21,51,103 +}; + +static int perm_d[]={ + 94,234,145,235,151,166,187,238,4,5,128,115,87,107,229,175,190,108,218, + 32,17,220,97,90,122,121,71,109,64,227,225,75,81,19,27,162,3,89,139,69, + 92,26,48,215,116,191,114,2,104,157,66,39,1,127,96,124,30,0,82,233,219, + 42,131,173,35,201,182,144,14,98,148,244,160,159,179,91,31,68,119,154, + 205,113,149,167,44,60,18,228,251,245,43,10,80,15,129,67,181,174,6,45, + 194,237,213,52,99,232,211,212,164,217,57,153,156,102,134,20,249,132,55, + 204,65,33,231,85,61,37,163,193,189,170,226,63,168,236,165,224,242,195, + 41,200,40,70,112,100,36,172,130,74,137,252,243,135,230,161,207,16,146, + 198,118,150,24,29,250,188,25,209,103,23,105,47,7,46,133,83,184,50,79, + 110,120,53,253,206,214,9,240,101,147,152,183,254,59,126,216,197,171,51, + 208,248,202,58,176,28,72,177,185,141,12,11,56,222,86,178,155,223,88,111, + 73,142,210,138,239,221,199,192,84,93,241,125,76,77,255,95,8,78,247,186, + 123,196,13,140,180,143,54,106,136,34,62,169,38,117,22,21,49,203,158,246 +}; + +static float impulse_xcoords[]={ + 0.788235,0.541176,0.972549,0.082353,0.352941,0.811765,0.286275,0.752941, + 0.203922,0.705882,0.537255,0.886275,0.580392,0.137255,0.800000,0.533333, + 0.117647,0.447059,0.129412,0.925490,0.086275,0.478431,0.666667,0.568627, + 0.678431,0.313725,0.321569,0.349020,0.988235,0.419608,0.898039,0.219608, + 0.243137,0.623529,0.501961,0.772549,0.952941,0.517647,0.949020,0.701961, + 0.454902,0.505882,0.564706,0.960784,0.207843,0.007843,0.831373,0.184314, + 0.576471,0.462745,0.572549,0.247059,0.262745,0.694118,0.615686,0.121569, + 0.384314,0.749020,0.145098,0.717647,0.415686,0.607843,0.105882,0.101961, + 0.200000,0.807843,0.521569,0.780392,0.466667,0.552941,0.996078,0.627451, + 0.992157,0.529412,0.407843,0.011765,0.709804,0.458824,0.058824,0.819608, + 0.176471,0.317647,0.392157,0.223529,0.156863,0.490196,0.325490,0.074510, + 0.239216,0.164706,0.890196,0.603922,0.921569,0.839216,0.854902,0.098039, + 0.686275,0.843137,0.152941,0.372549,0.062745,0.474510,0.486275,0.227451, + 0.400000,0.298039,0.309804,0.274510,0.054902,0.815686,0.647059,0.635294, + 0.662745,0.976471,0.094118,0.509804,0.650980,0.211765,0.180392,0.003922, + 0.827451,0.278431,0.023529,0.525490,0.450980,0.725490,0.690196,0.941176, + 0.639216,0.560784,0.196078,0.364706,0.043137,0.494118,0.796078,0.113725, + 0.760784,0.729412,0.258824,0.290196,0.584314,0.674510,0.823529,0.905882, + 0.917647,0.070588,0.862745,0.345098,0.913725,0.937255,0.031373,0.215686, + 0.768627,0.333333,0.411765,0.423529,0.945098,0.721569,0.039216,0.792157, + 0.956863,0.266667,0.254902,0.047059,0.294118,0.658824,0.250980,1.000000, + 0.984314,0.756863,0.027451,0.305882,0.835294,0.513725,0.360784,0.776471, + 0.611765,0.192157,0.866667,0.858824,0.592157,0.803922,0.141176,0.435294, + 0.588235,0.619608,0.341176,0.109804,0.356863,0.270588,0.737255,0.847059, + 0.050980,0.764706,0.019608,0.870588,0.933333,0.784314,0.549020,0.337255, + 0.631373,0.929412,0.231373,0.427451,0.078431,0.498039,0.968627,0.654902, + 0.125490,0.698039,0.015686,0.878431,0.713725,0.368627,0.431373,0.874510, + 0.403922,0.556863,0.443137,0.964706,0.909804,0.301961,0.035294,0.850980, + 0.882353,0.741176,0.380392,0.133333,0.470588,0.643137,0.282353,0.396078, + 0.980392,0.168627,0.149020,0.235294,0.670588,0.596078,0.733333,0.160784, + 0.376471,0.682353,0.545098,0.482353,0.745098,0.894118,0.188235,0.329412, + 0.439216,0.901961,0.000000,0.600000,0.388235,0.172549,0.090196,0.066667 +}; + +static float impulse_ycoords[]={ + 0.827451,0.337255,0.941176,0.886275,0.878431,0.239216,0.400000,0.164706, + 0.490196,0.411765,0.964706,0.349020,0.803922,0.317647,0.647059,0.431373, + 0.933333,0.156863,0.094118,0.219608,0.039216,0.521569,0.498039,0.705882, + 0.717647,0.047059,0.631373,0.517647,0.984314,0.847059,0.482353,0.439216, + 0.250980,0.862745,0.690196,0.913725,0.270588,0.070588,0.027451,0.694118, + 0.811765,0.000000,0.494118,0.823529,0.800000,0.600000,0.003922,0.443137, + 0.639216,0.376471,0.031373,0.035294,0.552941,0.215686,0.305882,0.133333, + 0.564706,0.176471,0.211765,0.874510,0.360784,0.654902,0.223529,0.807843, + 0.372549,0.137255,0.321569,0.015686,0.007843,0.262745,0.125490,0.078431, + 0.396078,0.976471,0.929412,1.000000,0.937255,0.509804,0.188235,0.850980, + 0.831373,0.392157,0.741176,0.541176,0.592157,0.286275,0.345098,0.572549, + 0.537255,0.725490,0.839216,0.184314,0.772549,0.149020,0.505882,0.423529, + 0.780392,0.011765,0.890196,0.086275,0.427451,0.023529,0.788235,0.050980, + 0.760784,0.603922,0.066667,0.643137,0.623529,0.960784,0.172549,0.333333, + 0.082353,0.290196,0.992157,0.709804,0.894118,0.596078,0.243137,0.752941, + 0.486275,0.670588,0.949020,0.784314,0.145098,0.560784,0.513725,0.180392, + 0.580392,0.996078,0.380392,0.556863,0.407843,0.945098,0.117647,0.058824, + 0.678431,0.129412,0.192157,0.105882,0.968627,0.545098,0.462745,0.227451, + 0.019608,0.866667,0.674510,0.207843,0.627451,0.819608,0.921569,0.356863, + 0.447059,0.533333,0.435294,0.341176,0.054902,0.529412,0.235294,0.764706, + 0.615686,0.043137,0.745098,0.266667,0.501961,0.619608,0.776471,0.450980, + 0.309804,0.325490,0.200000,0.635294,0.247059,0.698039,0.721569,0.168627, + 0.854902,0.141176,0.611765,0.525490,0.415686,0.298039,0.254902,0.858824, + 0.568627,0.329412,0.062745,0.843137,0.588235,0.733333,0.607843,0.478431, + 0.576471,0.662745,0.470588,0.666667,0.980392,0.113725,0.898039,0.203922, + 0.294118,0.152941,0.098039,0.909804,0.796078,0.768627,0.713725,0.196078, + 0.368627,0.419608,0.352941,0.090196,0.749020,0.121569,0.882353,0.278431, + 0.388235,0.917647,0.701961,0.729412,0.835294,0.258824,0.301961,0.101961, + 0.792157,0.474510,0.686275,0.658824,0.364706,0.682353,0.458824,0.815686, + 0.282353,0.160784,0.870588,0.988235,0.756863,0.549020,0.274510,0.384314, + 0.650980,0.737255,0.901961,0.956863,0.972549,0.584314,0.925490,0.403922, + 0.074510,0.454902,0.952941,0.109804,0.313725,0.905882,0.231373,0.466667 +}; + +static float impulse_zcoords[]={ + 0.082353,0.643137,0.415686,0.929412,0.568627,0.509804,0.537255,0.815686, + 0.698039,0.941176,0.776471,0.752941,0.737255,0.525490,0.498039,0.423529, + 0.792157,0.125490,0.619608,0.164706,0.368627,0.870588,0.137255,0.372549, + 0.466667,0.486275,0.501961,0.513725,0.709804,0.576471,0.203922,0.258824, + 0.152941,0.556863,0.223529,0.047059,0.235294,0.474510,0.764706,0.552941, + 0.847059,0.145098,0.176471,0.937255,0.654902,0.894118,0.729412,0.054902, + 0.666667,0.749020,0.262745,0.560784,0.431373,0.286275,0.352941,0.239216, + 0.156863,0.839216,0.427451,0.949020,0.384314,0.227451,0.180392,0.074510, + 0.172549,0.356863,0.066667,0.517647,0.447059,0.184314,0.062745,0.670588, + 0.603922,0.219608,0.270588,0.976471,0.505882,0.627451,0.819608,0.854902, + 0.843137,0.019608,0.713725,0.035294,0.925490,0.349020,0.866667,0.701961, + 0.909804,0.811765,0.717647,0.141176,0.917647,0.023529,0.098039,0.803922, + 0.733333,0.658824,0.827451,0.133333,0.858824,0.800000,0.635294,1.000000, + 0.078431,0.450980,0.835294,0.321569,0.360784,0.529412,0.725490,0.572549, + 0.639216,0.341176,0.533333,0.094118,0.149020,0.545098,0.101961,0.901961, + 0.278431,0.694118,0.521569,0.490196,0.454902,0.329412,0.274510,0.027451, + 0.745098,0.933333,0.443137,0.168627,0.192157,0.988235,0.070588,0.972549, + 0.768627,0.400000,0.470588,0.207843,0.215686,0.388235,0.439216,0.780392, + 0.482353,0.121569,0.964706,0.086275,0.890196,0.337255,0.109804,0.305882, + 0.113725,0.435294,0.721569,0.772549,0.807843,0.741176,0.254902,0.596078, + 0.494118,0.317647,0.419608,0.000000,0.188235,0.031373,0.376471,0.380392, + 0.611765,0.945098,0.411765,0.313725,0.874510,0.588235,0.678431,0.160784, + 0.007843,0.090196,0.850980,0.788235,0.705882,0.266667,0.309804,0.541176, + 0.231373,0.129412,0.294118,0.243137,0.913725,0.996078,0.117647,0.478431, + 0.290196,0.549020,0.682353,0.784314,0.396078,0.831373,0.984314,0.584314, + 0.039216,0.250980,0.600000,0.392157,0.298039,0.050980,0.364706,0.105882, + 0.623529,0.886275,0.980392,0.325490,0.247059,0.690196,0.674510,0.960784, + 0.647059,0.211765,0.882353,0.686275,0.823529,0.058824,0.956863,0.043137, + 0.345098,0.301961,0.592157,0.862745,0.607843,0.458824,0.282353,0.003922, + 0.580392,0.760784,0.564706,0.011765,0.968627,0.905882,0.756863,0.952941, + 0.662745,0.015686,0.898039,0.196078,0.333333,0.992157,0.650980,0.407843, + 0.796078,0.615686,0.878431,0.921569,0.631373,0.200000,0.403922,0.462745 +}; + diff --git a/sp/src/mathlib/polyhedron.cpp b/sp/src/mathlib/polyhedron.cpp new file mode 100644 index 00000000..5a858f19 --- /dev/null +++ b/sp/src/mathlib/polyhedron.cpp @@ -0,0 +1,2293 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "mathlib/polyhedron.h" +#include "mathlib/vmatrix.h" +#include +#include +#include "tier1/utlvector.h" + + + +struct GeneratePolyhedronFromPlanes_Point; +struct GeneratePolyhedronFromPlanes_PointLL; +struct GeneratePolyhedronFromPlanes_Line; +struct GeneratePolyhedronFromPlanes_LineLL; +struct GeneratePolyhedronFromPlanes_Polygon; +struct GeneratePolyhedronFromPlanes_PolygonLL; + +struct GeneratePolyhedronFromPlanes_UnorderedPointLL; +struct GeneratePolyhedronFromPlanes_UnorderedLineLL; +struct GeneratePolyhedronFromPlanes_UnorderedPolygonLL; + +Vector FindPointInPlanes( const float *pPlanes, int planeCount ); +bool FindConvexShapeLooseAABB( const float *pInwardFacingPlanes, int iPlaneCount, Vector *pAABBMins, Vector *pAABBMaxs ); +CPolyhedron *ClipLinkedGeometry( GeneratePolyhedronFromPlanes_UnorderedPolygonLL *pPolygons, GeneratePolyhedronFromPlanes_UnorderedLineLL *pLines, GeneratePolyhedronFromPlanes_UnorderedPointLL *pPoints, const float *pOutwardFacingPlanes, int iPlaneCount, float fOnPlaneEpsilon, bool bUseTemporaryMemory ); +CPolyhedron *ConvertLinkedGeometryToPolyhedron( GeneratePolyhedronFromPlanes_UnorderedPolygonLL *pPolygons, GeneratePolyhedronFromPlanes_UnorderedLineLL *pLines, GeneratePolyhedronFromPlanes_UnorderedPointLL *pPoints, bool bUseTemporaryMemory ); + +//#define ENABLE_DEBUG_POLYHEDRON_DUMPS //Dumps debug information to disk for use with glview. Requires that tier2 also be in all projects using debug mathlib +//#define DEBUG_DUMP_POLYHEDRONS_TO_NUMBERED_GLVIEWS //dumps successfully generated polyhedrons + +#ifdef _DEBUG +void DumpPolyhedronToGLView( const CPolyhedron *pPolyhedron, const char *pFilename, const VMatrix *pTransform ); +void DumpPlaneToGlView( const float *pPlane, float fGrayScale, const char *pszFileName, const VMatrix *pTransform ); +void DumpLineToGLView( const Vector &vPoint1, const Vector &vColor1, const Vector &vPoint2, const Vector &vColor2, float fThickness, FILE *pFile ); +void DumpAABBToGLView( const Vector &vCenter, const Vector &vExtents, const Vector &vColor, FILE *pFile ); + +#if defined( ENABLE_DEBUG_POLYHEDRON_DUMPS ) && defined( WIN32 ) +#include "winlite.h" +#endif + +static VMatrix s_matIdentity( 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f ); +#endif + +#if defined( DEBUG_DUMP_POLYHEDRONS_TO_NUMBERED_GLVIEWS ) +static int g_iPolyhedronDumpCounter = 0; +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#if defined( _DEBUG ) && defined( ENABLE_DEBUG_POLYHEDRON_DUMPS ) +void CreateDumpDirectory( const char *szDirectoryName ) +{ +#if defined( WIN32 ) + CreateDirectory( szDirectoryName, NULL ); +#else + Assert( false ); //TODO: create directories in linux +#endif +} +#endif + + + +void CPolyhedron_AllocByNew::Release( void ) +{ + delete this; +} + +CPolyhedron_AllocByNew *CPolyhedron_AllocByNew::Allocate( unsigned short iVertices, unsigned short iLines, unsigned short iIndices, unsigned short iPolygons ) //creates the polyhedron along with enough memory to hold all it's data in a single allocation +{ + void *pMemory = new unsigned char [ sizeof( CPolyhedron_AllocByNew ) + + (iVertices * sizeof(Vector)) + + (iLines * sizeof(Polyhedron_IndexedLine_t)) + + (iIndices * sizeof( Polyhedron_IndexedLineReference_t )) + + (iPolygons * sizeof( Polyhedron_IndexedPolygon_t ))]; + +#include "tier0/memdbgoff.h" //the following placement new doesn't compile with memory debugging + CPolyhedron_AllocByNew *pAllocated = new ( pMemory ) CPolyhedron_AllocByNew; +#include "tier0/memdbgon.h" + + pAllocated->iVertexCount = iVertices; + pAllocated->iLineCount = iLines; + pAllocated->iIndexCount = iIndices; + pAllocated->iPolygonCount = iPolygons; + pAllocated->pVertices = (Vector *)(pAllocated + 1); //start vertex memory at the end of the class + pAllocated->pLines = (Polyhedron_IndexedLine_t *)(pAllocated->pVertices + iVertices); + pAllocated->pIndices = (Polyhedron_IndexedLineReference_t *)(pAllocated->pLines + iLines); + pAllocated->pPolygons = (Polyhedron_IndexedPolygon_t *)(pAllocated->pIndices + iIndices); + + return pAllocated; +} + + +class CPolyhedron_TempMemory : public CPolyhedron +{ +public: +#ifdef DBGFLAG_ASSERT + int iReferenceCount; +#endif + + virtual void Release( void ) + { +#ifdef DBGFLAG_ASSERT + --iReferenceCount; +#endif + } + + CPolyhedron_TempMemory( void ) +#ifdef DBGFLAG_ASSERT + : iReferenceCount( 0 ) +#endif + { }; +}; + + +static CUtlVector s_TempMemoryPolyhedron_Buffer; +static CPolyhedron_TempMemory s_TempMemoryPolyhedron; + +CPolyhedron *GetTempPolyhedron( unsigned short iVertices, unsigned short iLines, unsigned short iIndices, unsigned short iPolygons ) //grab the temporary polyhedron. Avoids new/delete for quick work. Can only be in use by one chunk of code at a time +{ + AssertMsg( s_TempMemoryPolyhedron.iReferenceCount == 0, "Temporary polyhedron memory being rewritten before released" ); +#ifdef DBGFLAG_ASSERT + ++s_TempMemoryPolyhedron.iReferenceCount; +#endif + s_TempMemoryPolyhedron_Buffer.SetCount( (sizeof( Vector ) * iVertices) + + (sizeof( Polyhedron_IndexedLine_t ) * iLines) + + (sizeof( Polyhedron_IndexedLineReference_t ) * iIndices) + + (sizeof( Polyhedron_IndexedPolygon_t ) * iPolygons) ); + + s_TempMemoryPolyhedron.iVertexCount = iVertices; + s_TempMemoryPolyhedron.iLineCount = iLines; + s_TempMemoryPolyhedron.iIndexCount = iIndices; + s_TempMemoryPolyhedron.iPolygonCount = iPolygons; + + s_TempMemoryPolyhedron.pVertices = (Vector *)s_TempMemoryPolyhedron_Buffer.Base(); + s_TempMemoryPolyhedron.pLines = (Polyhedron_IndexedLine_t *)(&s_TempMemoryPolyhedron.pVertices[s_TempMemoryPolyhedron.iVertexCount]); + s_TempMemoryPolyhedron.pIndices = (Polyhedron_IndexedLineReference_t *)(&s_TempMemoryPolyhedron.pLines[s_TempMemoryPolyhedron.iLineCount]); + s_TempMemoryPolyhedron.pPolygons = (Polyhedron_IndexedPolygon_t *)(&s_TempMemoryPolyhedron.pIndices[s_TempMemoryPolyhedron.iIndexCount]); + + return &s_TempMemoryPolyhedron; +} + + +Vector CPolyhedron::Center( void ) +{ + if( iVertexCount == 0 ) + return vec3_origin; + + Vector vAABBMin, vAABBMax; + vAABBMin = vAABBMax = pVertices[0]; + for( int i = 1; i != iVertexCount; ++i ) + { + Vector &vPoint = pVertices[i]; + if( vPoint.x < vAABBMin.x ) + vAABBMin.x = vPoint.x; + if( vPoint.y < vAABBMin.y ) + vAABBMin.y = vPoint.y; + if( vPoint.z < vAABBMin.z ) + vAABBMin.z = vPoint.z; + + if( vPoint.x > vAABBMax.x ) + vAABBMax.x = vPoint.x; + if( vPoint.y > vAABBMax.y ) + vAABBMax.y = vPoint.y; + if( vPoint.z > vAABBMax.z ) + vAABBMax.z = vPoint.z; + } + return ((vAABBMin + vAABBMax) * 0.5f); +} + +enum PolyhedronPointPlanarity +{ + POINT_DEAD, + POINT_ONPLANE, + POINT_ALIVE +}; + +struct GeneratePolyhedronFromPlanes_Point +{ + Vector ptPosition; + GeneratePolyhedronFromPlanes_LineLL *pConnectedLines; //keep these in a clockwise order, circular linking + float fPlaneDist; //used in plane cutting + PolyhedronPointPlanarity planarity; + int iSaveIndices; +}; + +struct GeneratePolyhedronFromPlanes_Line +{ + GeneratePolyhedronFromPlanes_Point *pPoints[2]; //the 2 connecting points in no particular order + GeneratePolyhedronFromPlanes_Polygon *pPolygons[2]; //viewing from the outside with the point connections going up, 0 is the left polygon, 1 is the right + int iSaveIndices; + bool bAlive; //connected to at least one living point + bool bCut; //connected to at least one dead point + + GeneratePolyhedronFromPlanes_LineLL *pPointLineLinks[2]; //rather than going into a point and searching for its link to this line, lets just cache it to eliminate searching + GeneratePolyhedronFromPlanes_LineLL *pPolygonLineLinks[2]; //rather than going into a polygon and searching for its link to this line, lets just cache it to eliminate searching +#ifdef POLYHEDRON_EXTENSIVE_DEBUGGING + int iDebugFlags; +#endif +}; + +struct GeneratePolyhedronFromPlanes_LineLL +{ + GeneratePolyhedronFromPlanes_Line *pLine; + int iReferenceIndex; //whatever is referencing the line should know which side of the line it's on (points and polygons), for polygons, it's which point to follow to continue going clockwise, which makes polygon 0 the one on the left side of an upward facing line vector, for points, it's the OTHER point's index + GeneratePolyhedronFromPlanes_LineLL *pPrev; + GeneratePolyhedronFromPlanes_LineLL *pNext; +}; + +struct GeneratePolyhedronFromPlanes_Polygon +{ + Vector vSurfaceNormal; + GeneratePolyhedronFromPlanes_LineLL *pLines; //keep these in a clockwise order, circular linking + + bool bMissingASide; +}; + +struct GeneratePolyhedronFromPlanes_UnorderedPolygonLL //an unordered collection of polygons +{ + GeneratePolyhedronFromPlanes_Polygon *pPolygon; + GeneratePolyhedronFromPlanes_UnorderedPolygonLL *pNext; + GeneratePolyhedronFromPlanes_UnorderedPolygonLL *pPrev; +}; + +struct GeneratePolyhedronFromPlanes_UnorderedLineLL //an unordered collection of lines +{ + GeneratePolyhedronFromPlanes_Line *pLine; + GeneratePolyhedronFromPlanes_UnorderedLineLL *pNext; + GeneratePolyhedronFromPlanes_UnorderedLineLL *pPrev; +}; + +struct GeneratePolyhedronFromPlanes_UnorderedPointLL //an unordered collection of points +{ + GeneratePolyhedronFromPlanes_Point *pPoint; + GeneratePolyhedronFromPlanes_UnorderedPointLL *pNext; + GeneratePolyhedronFromPlanes_UnorderedPointLL *pPrev; +}; + + + + +CPolyhedron *ClipPolyhedron( const CPolyhedron *pExistingPolyhedron, const float *pOutwardFacingPlanes, int iPlaneCount, float fOnPlaneEpsilon, bool bUseTemporaryMemory ) +{ + if( pExistingPolyhedron == NULL ) + return NULL; + + AssertMsg( (pExistingPolyhedron->iVertexCount >= 3) && (pExistingPolyhedron->iPolygonCount >= 2), "Polyhedron doesn't meet absolute minimum spec" ); + + float *pUsefulPlanes = (float *)stackalloc( sizeof( float ) * 4 * iPlaneCount ); + int iUsefulPlaneCount = 0; + Vector *pExistingVertices = pExistingPolyhedron->pVertices; + + //A large part of clipping will either eliminate the polyhedron entirely, or clip nothing at all, so lets just check for those first and throw away useless planes + { + int iLiveCount = 0; + int iDeadCount = 0; + const float fNegativeOnPlaneEpsilon = -fOnPlaneEpsilon; + + for( int i = 0; i != iPlaneCount; ++i ) + { + Vector vNormal = *((Vector *)&pOutwardFacingPlanes[(i * 4) + 0]); + float fPlaneDist = pOutwardFacingPlanes[(i * 4) + 3]; + + for( int j = 0; j != pExistingPolyhedron->iVertexCount; ++j ) + { + float fPointDist = vNormal.Dot( pExistingVertices[j] ) - fPlaneDist; + + if( fPointDist <= fNegativeOnPlaneEpsilon ) + ++iLiveCount; + else if( fPointDist > fOnPlaneEpsilon ) + ++iDeadCount; + } + + if( iLiveCount == 0 ) + { + //all points are dead or on the plane, so the polyhedron is dead + return NULL; + } + + if( iDeadCount != 0 ) + { + //at least one point died, this plane yields useful results + pUsefulPlanes[(iUsefulPlaneCount * 4) + 0] = vNormal.x; + pUsefulPlanes[(iUsefulPlaneCount * 4) + 1] = vNormal.y; + pUsefulPlanes[(iUsefulPlaneCount * 4) + 2] = vNormal.z; + pUsefulPlanes[(iUsefulPlaneCount * 4) + 3] = fPlaneDist; + ++iUsefulPlaneCount; + } + } + } + + if( iUsefulPlaneCount == 0 ) + { + //testing shows that the polyhedron won't even be cut, clone the existing polyhedron and return that + + CPolyhedron *pReturn; + if( bUseTemporaryMemory ) + { + pReturn = GetTempPolyhedron( pExistingPolyhedron->iVertexCount, + pExistingPolyhedron->iLineCount, + pExistingPolyhedron->iIndexCount, + pExistingPolyhedron->iPolygonCount ); + } + else + { + pReturn = CPolyhedron_AllocByNew::Allocate( pExistingPolyhedron->iVertexCount, + pExistingPolyhedron->iLineCount, + pExistingPolyhedron->iIndexCount, + pExistingPolyhedron->iPolygonCount ); + } + + memcpy( pReturn->pVertices, pExistingPolyhedron->pVertices, sizeof( Vector ) * pReturn->iVertexCount ); + memcpy( pReturn->pLines, pExistingPolyhedron->pLines, sizeof( Polyhedron_IndexedLine_t ) * pReturn->iLineCount ); + memcpy( pReturn->pIndices, pExistingPolyhedron->pIndices, sizeof( Polyhedron_IndexedLineReference_t ) * pReturn->iIndexCount ); + memcpy( pReturn->pPolygons, pExistingPolyhedron->pPolygons, sizeof( Polyhedron_IndexedPolygon_t ) * pReturn->iPolygonCount ); + + return pReturn; + } + + + + //convert the polyhedron to linked geometry + GeneratePolyhedronFromPlanes_Point *pStartPoints = (GeneratePolyhedronFromPlanes_Point *)stackalloc( pExistingPolyhedron->iVertexCount * sizeof( GeneratePolyhedronFromPlanes_Point ) ); + GeneratePolyhedronFromPlanes_Line *pStartLines = (GeneratePolyhedronFromPlanes_Line *)stackalloc( pExistingPolyhedron->iLineCount * sizeof( GeneratePolyhedronFromPlanes_Line ) ); + GeneratePolyhedronFromPlanes_Polygon *pStartPolygons = (GeneratePolyhedronFromPlanes_Polygon *)stackalloc( pExistingPolyhedron->iPolygonCount * sizeof( GeneratePolyhedronFromPlanes_Polygon ) ); + + GeneratePolyhedronFromPlanes_LineLL *pStartLineLinks = (GeneratePolyhedronFromPlanes_LineLL *)stackalloc( pExistingPolyhedron->iLineCount * 4 * sizeof( GeneratePolyhedronFromPlanes_LineLL ) ); + + int iCurrentLineLinkIndex = 0; + + //setup points + for( int i = 0; i != pExistingPolyhedron->iVertexCount; ++i ) + { + pStartPoints[i].ptPosition = pExistingPolyhedron->pVertices[i]; + pStartPoints[i].pConnectedLines = NULL; //we won't be circular linking until later + } + + //setup lines and interlink to points (line links are not yet circularly linked, and are unordered) + for( int i = 0; i != pExistingPolyhedron->iLineCount; ++i ) + { + for( int j = 0; j != 2; ++j ) + { + pStartLines[i].pPoints[j] = &pStartPoints[pExistingPolyhedron->pLines[i].iPointIndices[j]]; + + GeneratePolyhedronFromPlanes_LineLL *pLineLink = &pStartLineLinks[iCurrentLineLinkIndex++]; + pStartLines[i].pPointLineLinks[j] = pLineLink; + pLineLink->pLine = &pStartLines[i]; + pLineLink->iReferenceIndex = 1 - j; + //pLineLink->pPrev = NULL; + pLineLink->pNext = pStartLines[i].pPoints[j]->pConnectedLines; + pStartLines[i].pPoints[j]->pConnectedLines = pLineLink; + } + } + + + + //setup polygons + for( int i = 0; i != pExistingPolyhedron->iPolygonCount; ++i ) + { + pStartPolygons[i].vSurfaceNormal = pExistingPolyhedron->pPolygons[i].polyNormal; + Polyhedron_IndexedLineReference_t *pOffsetPolyhedronLines = &pExistingPolyhedron->pIndices[pExistingPolyhedron->pPolygons[i].iFirstIndex]; + + + GeneratePolyhedronFromPlanes_LineLL *pFirstLink = &pStartLineLinks[iCurrentLineLinkIndex]; + pStartPolygons[i].pLines = pFirstLink; //technically going to link to itself on first pass, then get linked properly immediately afterward + for( int j = 0; j != pExistingPolyhedron->pPolygons[i].iIndexCount; ++j ) + { + GeneratePolyhedronFromPlanes_LineLL *pLineLink = &pStartLineLinks[iCurrentLineLinkIndex++]; + pLineLink->pLine = &pStartLines[pOffsetPolyhedronLines[j].iLineIndex]; + pLineLink->iReferenceIndex = pOffsetPolyhedronLines[j].iEndPointIndex; + + pLineLink->pLine->pPolygons[pLineLink->iReferenceIndex] = &pStartPolygons[i]; + pLineLink->pLine->pPolygonLineLinks[pLineLink->iReferenceIndex] = pLineLink; + + pLineLink->pPrev = pStartPolygons[i].pLines; + pStartPolygons[i].pLines->pNext = pLineLink; + pStartPolygons[i].pLines = pLineLink; + } + + pFirstLink->pPrev = pStartPolygons[i].pLines; + pStartPolygons[i].pLines->pNext = pFirstLink; + } + + Assert( iCurrentLineLinkIndex == (pExistingPolyhedron->iLineCount * 4) ); + + //go back to point line links so we can circularly link them as well as order them now that every point has all its line links + for( int i = 0; i != pExistingPolyhedron->iVertexCount; ++i ) + { + //interlink the points + { + GeneratePolyhedronFromPlanes_LineLL *pLastVisitedLink = pStartPoints[i].pConnectedLines; + GeneratePolyhedronFromPlanes_LineLL *pCurrentLink = pLastVisitedLink; + + do + { + pCurrentLink->pPrev = pLastVisitedLink; + pLastVisitedLink = pCurrentLink; + pCurrentLink = pCurrentLink->pNext; + } while( pCurrentLink ); + + //circular link + pLastVisitedLink->pNext = pStartPoints[i].pConnectedLines; + pStartPoints[i].pConnectedLines->pPrev = pLastVisitedLink; + } + + + //fix ordering + GeneratePolyhedronFromPlanes_LineLL *pFirstLink = pStartPoints[i].pConnectedLines; + GeneratePolyhedronFromPlanes_LineLL *pWorkLink = pFirstLink; + GeneratePolyhedronFromPlanes_LineLL *pSearchLink; + GeneratePolyhedronFromPlanes_Polygon *pLookingForPolygon; + Assert( pFirstLink->pNext != pFirstLink ); + do + { + pLookingForPolygon = pWorkLink->pLine->pPolygons[1 - pWorkLink->iReferenceIndex]; //grab pointer to left polygon + pSearchLink = pWorkLink->pPrev; + + while( pSearchLink->pLine->pPolygons[pSearchLink->iReferenceIndex] != pLookingForPolygon ) + pSearchLink = pSearchLink->pPrev; + + Assert( pSearchLink->pLine->pPolygons[pSearchLink->iReferenceIndex] == pWorkLink->pLine->pPolygons[1 - pWorkLink->iReferenceIndex] ); + + //pluck the search link from wherever it is + pSearchLink->pPrev->pNext = pSearchLink->pNext; + pSearchLink->pNext->pPrev = pSearchLink->pPrev; + + //insert the search link just before the work link + pSearchLink->pPrev = pWorkLink->pPrev; + pSearchLink->pNext = pWorkLink; + + pSearchLink->pPrev->pNext = pSearchLink; + pWorkLink->pPrev = pSearchLink; + + pWorkLink = pSearchLink; + } while( pWorkLink != pFirstLink ); + } + + GeneratePolyhedronFromPlanes_UnorderedPointLL *pPoints = (GeneratePolyhedronFromPlanes_UnorderedPointLL *)stackalloc( pExistingPolyhedron->iVertexCount * sizeof( GeneratePolyhedronFromPlanes_UnorderedPointLL ) ); + GeneratePolyhedronFromPlanes_UnorderedLineLL *pLines = (GeneratePolyhedronFromPlanes_UnorderedLineLL *)stackalloc( pExistingPolyhedron->iLineCount * sizeof( GeneratePolyhedronFromPlanes_UnorderedLineLL ) ); + GeneratePolyhedronFromPlanes_UnorderedPolygonLL *pPolygons = (GeneratePolyhedronFromPlanes_UnorderedPolygonLL *)stackalloc( pExistingPolyhedron->iPolygonCount * sizeof( GeneratePolyhedronFromPlanes_UnorderedPolygonLL ) ); + + //setup point collection + { + pPoints[0].pPrev = NULL; + pPoints[0].pPoint = &pStartPoints[0]; + pPoints[0].pNext = &pPoints[1]; + int iLastPoint = pExistingPolyhedron->iVertexCount - 1; + for( int i = 1; i != iLastPoint; ++i ) + { + pPoints[i].pPrev = &pPoints[i - 1]; + pPoints[i].pPoint = &pStartPoints[i]; + pPoints[i].pNext = &pPoints[i + 1]; + } + pPoints[iLastPoint].pPrev = &pPoints[iLastPoint - 1]; + pPoints[iLastPoint].pPoint = &pStartPoints[iLastPoint]; + pPoints[iLastPoint].pNext = NULL; + } + + //setup line collection + { + pLines[0].pPrev = NULL; + pLines[0].pLine = &pStartLines[0]; + pLines[0].pNext = &pLines[1]; + int iLastLine = pExistingPolyhedron->iLineCount - 1; + for( int i = 1; i != iLastLine; ++i ) + { + pLines[i].pPrev = &pLines[i - 1]; + pLines[i].pLine = &pStartLines[i]; + pLines[i].pNext = &pLines[i + 1]; + } + pLines[iLastLine].pPrev = &pLines[iLastLine - 1]; + pLines[iLastLine].pLine = &pStartLines[iLastLine]; + pLines[iLastLine].pNext = NULL; + } + + //setup polygon collection + { + pPolygons[0].pPrev = NULL; + pPolygons[0].pPolygon = &pStartPolygons[0]; + pPolygons[0].pNext = &pPolygons[1]; + int iLastPolygon = pExistingPolyhedron->iPolygonCount - 1; + for( int i = 1; i != iLastPolygon; ++i ) + { + pPolygons[i].pPrev = &pPolygons[i - 1]; + pPolygons[i].pPolygon = &pStartPolygons[i]; + pPolygons[i].pNext = &pPolygons[i + 1]; + } + pPolygons[iLastPolygon].pPrev = &pPolygons[iLastPolygon - 1]; + pPolygons[iLastPolygon].pPolygon = &pStartPolygons[iLastPolygon]; + pPolygons[iLastPolygon].pNext = NULL; + } + + return ClipLinkedGeometry( pPolygons, pLines, pPoints, pUsefulPlanes, iUsefulPlaneCount, fOnPlaneEpsilon, bUseTemporaryMemory ); +} + + + +Vector FindPointInPlanes( const float *pPlanes, int planeCount ) +{ + Vector point = vec3_origin; + + for ( int i = 0; i < planeCount; i++ ) + { + float fD = DotProduct( *(Vector *)&pPlanes[i*4], point ) - pPlanes[i*4 + 3]; + if ( fD < 0 ) + { + point -= fD * (*(Vector *)&pPlanes[i*4]); + } + } + return point; +} + + + +bool FindConvexShapeLooseAABB( const float *pInwardFacingPlanes, int iPlaneCount, Vector *pAABBMins, Vector *pAABBMaxs ) //bounding box of the convex shape (subject to floating point error) +{ + //returns false if the AABB hasn't been set + if( pAABBMins == NULL && pAABBMaxs == NULL ) //no use in actually finding out what it is + return false; + + struct FindConvexShapeAABB_Polygon_t + { + float *verts; + int iVertCount; + }; + + float *pMovedPlanes = (float *)stackalloc( iPlaneCount * 4 * sizeof( float ) ); + //Vector vPointInPlanes = FindPointInPlanes( pInwardFacingPlanes, iPlaneCount ); + + for( int i = 0; i != iPlaneCount; ++i ) + { + pMovedPlanes[(i * 4) + 0] = pInwardFacingPlanes[(i * 4) + 0]; + pMovedPlanes[(i * 4) + 1] = pInwardFacingPlanes[(i * 4) + 1]; + pMovedPlanes[(i * 4) + 2] = pInwardFacingPlanes[(i * 4) + 2]; + pMovedPlanes[(i * 4) + 3] = pInwardFacingPlanes[(i * 4) + 3] - 100.0f; //move planes out a lot to kill some imprecision problems + } + + + + //vAABBMins = vAABBMaxs = FindPointInPlanes( pPlanes, iPlaneCount ); + float *vertsIn = NULL; //we'll be allocating a new buffer for this with each new polygon, and moving it off to the polygon array + float *vertsOut = (float *)stackalloc( (iPlaneCount + 4) * (sizeof( float ) * 3) ); //each plane will initially have 4 points in its polygon representation, and each plane clip has the possibility to add 1 point to the polygon + float *vertsSwap; + + FindConvexShapeAABB_Polygon_t *pPolygons = (FindConvexShapeAABB_Polygon_t *)stackalloc( iPlaneCount * sizeof( FindConvexShapeAABB_Polygon_t ) ); + int iPolyCount = 0; + + for ( int i = 0; i < iPlaneCount; i++ ) + { + Vector *pPlaneNormal = (Vector *)&pInwardFacingPlanes[i*4]; + float fPlaneDist = pInwardFacingPlanes[(i*4) + 3]; + + if( vertsIn == NULL ) + vertsIn = (float *)stackalloc( (iPlaneCount + 4) * (sizeof( float ) * 3) ); + + // Build a big-ass poly in this plane + int vertCount = PolyFromPlane( (Vector *)vertsIn, *pPlaneNormal, fPlaneDist, 100000.0f ); + + //chop it by every other plane + for( int j = 0; j < iPlaneCount; j++ ) + { + // don't clip planes with themselves + if ( i == j ) + continue; + + // Chop the polygon against this plane + vertCount = ClipPolyToPlane( (Vector *)vertsIn, vertCount, (Vector *)vertsOut, *(Vector *)&pMovedPlanes[j*4], pMovedPlanes[(j*4) + 3], 0.0f ); + + //swap the input and output arrays + vertsSwap = vertsIn; vertsIn = vertsOut; vertsOut = vertsSwap; + + // Less than a poly left, something's wrong, don't bother with this polygon + if ( vertCount < 3 ) + break; + } + + if ( vertCount < 3 ) + continue; //not enough to work with + + pPolygons[iPolyCount].iVertCount = vertCount; + pPolygons[iPolyCount].verts = vertsIn; + vertsIn = NULL; + ++iPolyCount; + } + + if( iPolyCount == 0 ) + return false; + + //initialize the AABB to the first point available + Vector vAABBMins, vAABBMaxs; + vAABBMins = vAABBMaxs = ((Vector *)pPolygons[0].verts)[0]; + + if( pAABBMins && pAABBMaxs ) //they want the full box + { + for( int i = 0; i != iPolyCount; ++i ) + { + Vector *PolyVerts = (Vector *)pPolygons[i].verts; + for( int j = 0; j != pPolygons[i].iVertCount; ++j ) + { + if( PolyVerts[j].x < vAABBMins.x ) + vAABBMins.x = PolyVerts[j].x; + if( PolyVerts[j].y < vAABBMins.y ) + vAABBMins.y = PolyVerts[j].y; + if( PolyVerts[j].z < vAABBMins.z ) + vAABBMins.z = PolyVerts[j].z; + + if( PolyVerts[j].x > vAABBMaxs.x ) + vAABBMaxs.x = PolyVerts[j].x; + if( PolyVerts[j].y > vAABBMaxs.y ) + vAABBMaxs.y = PolyVerts[j].y; + if( PolyVerts[j].z > vAABBMaxs.z ) + vAABBMaxs.z = PolyVerts[j].z; + } + } + *pAABBMins = vAABBMins; + *pAABBMaxs = vAABBMaxs; + } + else if( pAABBMins ) //they only want the min + { + for( int i = 0; i != iPolyCount; ++i ) + { + Vector *PolyVerts = (Vector *)pPolygons[i].verts; + for( int j = 0; j != pPolygons[i].iVertCount; ++j ) + { + if( PolyVerts[j].x < vAABBMins.x ) + vAABBMins.x = PolyVerts[j].x; + if( PolyVerts[j].y < vAABBMins.y ) + vAABBMins.y = PolyVerts[j].y; + if( PolyVerts[j].z < vAABBMins.z ) + vAABBMins.z = PolyVerts[j].z; + } + } + *pAABBMins = vAABBMins; + } + else //they only want the max + { + for( int i = 0; i != iPolyCount; ++i ) + { + Vector *PolyVerts = (Vector *)pPolygons[i].verts; + for( int j = 0; j != pPolygons[i].iVertCount; ++j ) + { + if( PolyVerts[j].x > vAABBMaxs.x ) + vAABBMaxs.x = PolyVerts[j].x; + if( PolyVerts[j].y > vAABBMaxs.y ) + vAABBMaxs.y = PolyVerts[j].y; + if( PolyVerts[j].z > vAABBMaxs.z ) + vAABBMaxs.z = PolyVerts[j].z; + } + } + *pAABBMaxs = vAABBMaxs; + } + + return true; +} + + + + + + + +CPolyhedron *ConvertLinkedGeometryToPolyhedron( GeneratePolyhedronFromPlanes_UnorderedPolygonLL *pPolygons, GeneratePolyhedronFromPlanes_UnorderedLineLL *pLines, GeneratePolyhedronFromPlanes_UnorderedPointLL *pPoints, bool bUseTemporaryMemory ) +{ + Assert( (pPolygons != NULL) && (pLines != NULL) && (pPoints != NULL) ); + unsigned int iPolyCount = 0, iLineCount = 0, iPointCount = 0, iIndexCount = 0; + + GeneratePolyhedronFromPlanes_UnorderedPolygonLL *pActivePolygonWalk = pPolygons; + do + { + ++iPolyCount; + GeneratePolyhedronFromPlanes_LineLL *pLineWalk = pActivePolygonWalk->pPolygon->pLines; + GeneratePolyhedronFromPlanes_LineLL *pFirstLine = pLineWalk; + Assert( pLineWalk != NULL ); + + do + { + ++iIndexCount; + pLineWalk = pLineWalk->pNext; + } while( pLineWalk != pFirstLine ); + + pActivePolygonWalk = pActivePolygonWalk->pNext; + } while( pActivePolygonWalk ); + + GeneratePolyhedronFromPlanes_UnorderedLineLL *pActiveLineWalk = pLines; + do + { + ++iLineCount; + pActiveLineWalk = pActiveLineWalk->pNext; + } while( pActiveLineWalk ); + + GeneratePolyhedronFromPlanes_UnorderedPointLL *pActivePointWalk = pPoints; + do + { + ++iPointCount; + pActivePointWalk = pActivePointWalk->pNext; + } while( pActivePointWalk ); + + CPolyhedron *pReturn; + if( bUseTemporaryMemory ) + { + pReturn = GetTempPolyhedron( iPointCount, iLineCount, iIndexCount, iPolyCount ); + } + else + { + pReturn = CPolyhedron_AllocByNew::Allocate( iPointCount, iLineCount, iIndexCount, iPolyCount ); + } + + Vector *pVertexArray = pReturn->pVertices; + Polyhedron_IndexedLine_t *pLineArray = pReturn->pLines; + Polyhedron_IndexedLineReference_t *pIndexArray = pReturn->pIndices; + Polyhedron_IndexedPolygon_t *pPolyArray = pReturn->pPolygons; + + //copy points + pActivePointWalk = pPoints; + for( unsigned int i = 0; i != iPointCount; ++i ) + { + pVertexArray[i] = pActivePointWalk->pPoint->ptPosition; + pActivePointWalk->pPoint->iSaveIndices = i; //storing array indices + pActivePointWalk = pActivePointWalk->pNext; + } + + //copy lines + pActiveLineWalk = pLines; + for( unsigned int i = 0; i != iLineCount; ++i ) + { + pLineArray[i].iPointIndices[0] = (unsigned short)pActiveLineWalk->pLine->pPoints[0]->iSaveIndices; + pLineArray[i].iPointIndices[1] = (unsigned short)pActiveLineWalk->pLine->pPoints[1]->iSaveIndices; + + pActiveLineWalk->pLine->iSaveIndices = i; //storing array indices + + pActiveLineWalk = pActiveLineWalk->pNext; + } + + //copy polygons and indices at the same time + pActivePolygonWalk = pPolygons; + iIndexCount = 0; + for( unsigned int i = 0; i != iPolyCount; ++i ) + { + pPolyArray[i].polyNormal = pActivePolygonWalk->pPolygon->vSurfaceNormal; + pPolyArray[i].iFirstIndex = iIndexCount; + + GeneratePolyhedronFromPlanes_LineLL *pLineWalk = pActivePolygonWalk->pPolygon->pLines; + GeneratePolyhedronFromPlanes_LineLL *pFirstLine = pLineWalk; + do + { + //pIndexArray[iIndexCount] = pLineWalk->pLine->pPoints[pLineWalk->iReferenceIndex]->iWorkData; //startpoint of each line, iWorkData is the index of the vertex + pIndexArray[iIndexCount].iLineIndex = pLineWalk->pLine->iSaveIndices; + pIndexArray[iIndexCount].iEndPointIndex = pLineWalk->iReferenceIndex; + + ++iIndexCount; + pLineWalk = pLineWalk->pNext; + } while( pLineWalk != pFirstLine ); + + pPolyArray[i].iIndexCount = iIndexCount - pPolyArray[i].iFirstIndex; + + pActivePolygonWalk = pActivePolygonWalk->pNext; + } + +#if defined( _DEBUG ) && defined( ENABLE_DEBUG_POLYHEDRON_DUMPS ) && defined( DEBUG_DUMP_POLYHEDRONS_TO_NUMBERED_GLVIEWS ) + char szCollisionFile[128]; + CreateDumpDirectory( "PolyhedronDumps" ); + Q_snprintf( szCollisionFile, 128, "PolyhedronDumps/NewStyle_PolyhedronDump%i.txt", g_iPolyhedronDumpCounter ); + ++g_iPolyhedronDumpCounter; + + remove( szCollisionFile ); + DumpPolyhedronToGLView( pReturn, szCollisionFile, &s_matIdentity ); + DumpPolyhedronToGLView( pReturn, "PolyhedronDumps/NewStyle_PolyhedronDump_All-Appended.txt", &s_matIdentity ); +#endif + + return pReturn; +} + + + +#ifdef _DEBUG + +void DumpPointListToGLView( GeneratePolyhedronFromPlanes_UnorderedPointLL *pHead, PolyhedronPointPlanarity planarity, const Vector &vColor, const char *szDumpFile, const VMatrix *pTransform ) +{ +#ifdef ENABLE_DEBUG_POLYHEDRON_DUMPS + if( pTransform == NULL ) + pTransform = &s_matIdentity; + + FILE *pFile = fopen( szDumpFile, "ab" ); + + while( pHead ) + { + if( pHead->pPoint->planarity == planarity ) + { + const Vector vPointExtents( 0.5f, 0.5f, 0.01f ); + DumpAABBToGLView( (*pTransform) * pHead->pPoint->ptPosition, vPointExtents, vColor, pFile ); + } + pHead = pHead->pNext; + } + + fclose( pFile ); +#endif +} + +const char * DumpPolyhedronCutHistory( const CUtlVector &DumpedHistory, const CUtlVector &CutHistory, const VMatrix *pTransform ) +{ +#ifdef ENABLE_DEBUG_POLYHEDRON_DUMPS + if( pTransform == NULL ) + pTransform = &s_matIdentity; + + static char szDumpFile[100] = "FailedPolyhedronCut_Error.txt"; //most recent filename returned for further dumping + + for( int i = 0; i != DumpedHistory.Count(); ++i ) + { + if( DumpedHistory[i] != NULL ) + { + Q_snprintf( szDumpFile, 100, "FailedPolyhedronCut_%d.txt", i ); + DumpPolyhedronToGLView( DumpedHistory[i], szDumpFile, pTransform ); + DumpPlaneToGlView( CutHistory[i], 1.0f, szDumpFile, pTransform ); + } + } + + return szDumpFile; +#else + return NULL; +#endif +} + +#ifdef ENABLE_DEBUG_POLYHEDRON_DUMPS +#define AssertMsg_DumpPolyhedron(condition, message)\ + if( (condition) == false )\ + {\ + VMatrix matTransform;\ + matTransform.Identity();\ + matTransform[0][0] = matTransform[1][1] = matTransform[2][2] = 25.0f;\ + matTransform.SetTranslation( -DebugCutHistory.Tail()->Center() * 25.0f );\ + const char *szLastDumpFile = DumpPolyhedronCutHistory( DebugCutHistory, PlaneCutHistory, &matTransform );\ + DumpPointListToGLView( pAllPoints, POINT_ALIVE, Vector( 0.9f, 0.9f, 0.9f ), szLastDumpFile, &matTransform );\ + DumpPointListToGLView( pAllPoints, POINT_ONPLANE, Vector( 0.5f, 0.5f, 0.5f ), szLastDumpFile, &matTransform );\ + DumpPointListToGLView( pDeadPointCollection, POINT_DEAD, Vector( 0.1f, 0.1f, 0.1f ), szLastDumpFile, &matTransform );\ + if( pStartPoint )\ + {\ + FILE *pFileDumpRepairProgress = fopen( szLastDumpFile, "ab" );\ + DumpAABBToGLView( matTransform * pStartPoint->ptPosition, Vector( 2.0f, 0.05f, 0.05f ), Vector( 0.0f, 1.0f, 0.0f ), pFileDumpRepairProgress );\ + DumpAABBToGLView( matTransform * pWorkPoint->ptPosition, Vector( 2.0f, 0.05f, 0.05f ), Vector( 1.0f, 0.0f, 0.0f ), pFileDumpRepairProgress );\ + fclose( pFileDumpRepairProgress );\ + }\ + AssertMsg( condition, message );\ + } +#else +#define AssertMsg_DumpPolyhedron(condition, message) AssertMsg( condition, message ) +#endif +#define Assert_DumpPolyhedron(condition) AssertMsg_DumpPolyhedron( condition, #condition ) + +#else + +#define AssertMsg_DumpPolyhedron(condition, message) NULL; +#define Assert_DumpPolyhedron(condition) NULL; + +#endif + +CPolyhedron *ClipLinkedGeometry( GeneratePolyhedronFromPlanes_UnorderedPolygonLL *pAllPolygons, GeneratePolyhedronFromPlanes_UnorderedLineLL *pAllLines, GeneratePolyhedronFromPlanes_UnorderedPointLL *pAllPoints, const float *pOutwardFacingPlanes, int iPlaneCount, float fOnPlaneEpsilon, bool bUseTemporaryMemory ) +{ + const float fNegativeOnPlaneEpsilon = -fOnPlaneEpsilon; + +#ifdef _DEBUG + CUtlVector DebugCutHistory; + CUtlVector PlaneCutHistory; + GeneratePolyhedronFromPlanes_Point *pStartPoint = NULL; + GeneratePolyhedronFromPlanes_Point *pWorkPoint = NULL; + + static int iPolyhedronClipCount = 0; + ++iPolyhedronClipCount; + + DebugCutHistory.AddToTail( ConvertLinkedGeometryToPolyhedron( pAllPolygons, pAllLines, pAllPoints, false ) ); +#endif + + //clear out polygon work variables + { + GeneratePolyhedronFromPlanes_UnorderedPolygonLL *pActivePolygonWalk = pAllPolygons; + do + { + pActivePolygonWalk->pPolygon->bMissingASide = false; + pActivePolygonWalk = pActivePolygonWalk->pNext; + } while( pActivePolygonWalk ); + } + + + //Collections of dead pointers for reallocation, shouldn't be touched until the current loop iteration is done. + GeneratePolyhedronFromPlanes_UnorderedPointLL *pDeadPointCollection = NULL; + GeneratePolyhedronFromPlanes_UnorderedLineLL *pDeadLineCollection = NULL; + GeneratePolyhedronFromPlanes_UnorderedPolygonLL *pDeadPolygonCollection = NULL; + GeneratePolyhedronFromPlanes_LineLL *pDeadLineLinkCollection = NULL; + + + for( int iCurrentPlane = 0; iCurrentPlane != iPlaneCount; ++iCurrentPlane ) + { + //clear out line work variables + { + GeneratePolyhedronFromPlanes_UnorderedLineLL *pActiveLineWalk = pAllLines; + do + { + pActiveLineWalk->pLine->bAlive = false; + pActiveLineWalk->pLine->bCut = false; + + pActiveLineWalk = pActiveLineWalk->pNext; + } while( pActiveLineWalk ); + } + + //TODO: Move these pointers into a reallocation pool + pDeadPointCollection = NULL; + pDeadLineCollection = NULL; + pDeadLineLinkCollection = NULL; + pDeadPolygonCollection = NULL; + + Vector vNormal = *((Vector *)&pOutwardFacingPlanes[(iCurrentPlane * 4) + 0]); + /*double vNormalAsDouble[3]; + vNormalAsDouble[0] = vNormal.x; + vNormalAsDouble[1] = vNormal.y; + vNormalAsDouble[2] = vNormal.z;*/ + float fPlaneDist = pOutwardFacingPlanes[(iCurrentPlane * 4) + 3]; + + //=================================================================================================== + // Step 1: Categorize each point as being either cut, split, or alive + //=================================================================================================== + { + bool bAllPointsDead = true; + bool bAllPointsAlive = true; + + //find point distances from the plane + GeneratePolyhedronFromPlanes_UnorderedPointLL *pActivePointWalk = pAllPoints; + do + { + GeneratePolyhedronFromPlanes_Point *pPoint = pActivePointWalk->pPoint; + float fPointDist = vNormal.Dot( pPoint->ptPosition ) - fPlaneDist; + if( fPointDist > fOnPlaneEpsilon ) + { + pPoint->planarity = POINT_DEAD; //point is dead, bang bang + + //mark connected lines as cut + GeneratePolyhedronFromPlanes_LineLL *pLineWalk = pPoint->pConnectedLines; + GeneratePolyhedronFromPlanes_LineLL *pFirstLine = pLineWalk; + do + { + pLineWalk->pLine->bCut = true; + pLineWalk = pLineWalk->pNext; + } while( pLineWalk != pFirstLine ); + + bAllPointsAlive = false; + } + else if( fPointDist <= fNegativeOnPlaneEpsilon ) + { + pPoint->planarity = POINT_ALIVE; //point is in behind plane, not voted off the island....yet + bAllPointsDead = false; + + //mark connected lines as alive + GeneratePolyhedronFromPlanes_LineLL *pLineWalk = pPoint->pConnectedLines; + GeneratePolyhedronFromPlanes_LineLL *pFirstLine = pLineWalk; + do + { + pLineWalk->pLine->bAlive = true; //mark the line as alive + pLineWalk = pLineWalk->pNext; + } while( pLineWalk != pFirstLine ); + } + else + { + pPoint->planarity = POINT_ONPLANE; //point is on the plane, he's everyone's buddy + + //Project on-plane points leaning towards death closer to the plane. This battles floating point precision decay. + // Consider the case of a large on-plane epsilon leaving protrusions over time + /*if( fPointDist < 0.0f ) + { + double distAsDouble = fPointDist; + double vPositionAsDouble[3]; + vPositionAsDouble[0] = pPoint->ptPosition.x; + vPositionAsDouble[1] = pPoint->ptPosition.y; + vPositionAsDouble[2] = pPoint->ptPosition.z; + + pPoint->ptPosition.x = vPositionAsDouble[0] - (distAsDouble * vNormalAsDouble[0]); + pPoint->ptPosition.y = vPositionAsDouble[1] - (distAsDouble * vNormalAsDouble[1]); + pPoint->ptPosition.z = vPositionAsDouble[2] - (distAsDouble * vNormalAsDouble[2]); + +#if ( 0 && defined( _DEBUG ) ) + float fDebugDist = vNormal.Dot( pPoint->ptPosition ) - fPlaneDist; //just for looking at in watch windows + AssertMsg( fabs( fDebugDist ) < fabs(fPointDist), "Projected point is further from plane than unprojected." ); +#endif + fPointDist = vNormal.Dot( pPoint->ptPosition ) - fPlaneDist; //recompute dist (not guaranteed to be 0.0 like we want) + }*/ + } + + pPoint->fPlaneDist = fPointDist; + + pActivePointWalk = pActivePointWalk->pNext; + } while( pActivePointWalk ); + + if( bAllPointsDead ) //all the points either died or are on the plane, no polyhedron left at all + { +#ifdef _DEBUG + for( int i = DebugCutHistory.Count(); --i >= 0; ) + { + if( DebugCutHistory[i] ) + DebugCutHistory[i]->Release(); + } + DebugCutHistory.RemoveAll(); +#endif + + return NULL; + } + + if( bAllPointsAlive ) + continue; //no cuts made + + + //Scan for onplane points connected to only other onplane/dead points, these points get downgraded to dead status. + { + GeneratePolyhedronFromPlanes_UnorderedPointLL *pActivePointWalk = pAllPoints; + do + { + if( pActivePointWalk->pPoint->planarity == POINT_ONPLANE ) + { + GeneratePolyhedronFromPlanes_LineLL *pOnPlaneLineWalk = pActivePointWalk->pPoint->pConnectedLines; + GeneratePolyhedronFromPlanes_LineLL *pStartLineWalk = pOnPlaneLineWalk; + bool bDead = true; //assume it's dead and disprove + do + { + if ( pOnPlaneLineWalk->pLine->bAlive ) + { + bDead = false; + } + else if ( pOnPlaneLineWalk->pLine->bCut ) + { + //connected to a dead point. + if( pOnPlaneLineWalk->pNext->pLine->bCut || pOnPlaneLineWalk->pPrev->pLine->bCut ) + { + //This on-plane point is surrounded by dead points on one polygon of the polyhedron. + // We have to downgrade this point to dead to avoid situations where float imprecision + // turns the polyhedron into a *slightly* concave shape. Concave shapes might break this algorithm, even falsely concave shapes. + bDead = true; + break; + } + } + + pOnPlaneLineWalk = pOnPlaneLineWalk->pNext; + } while( pOnPlaneLineWalk != pStartLineWalk ); + + if( bDead ) + { + pActivePointWalk->pPoint->planarity = POINT_DEAD; + + pOnPlaneLineWalk = pStartLineWalk; + + //mark connected lines as cut + do + { + pOnPlaneLineWalk->pLine->bCut = true; + pOnPlaneLineWalk = pOnPlaneLineWalk->pNext; + } while( pOnPlaneLineWalk != pStartLineWalk ); + } + } + pActivePointWalk = pActivePointWalk->pNext; + } while( pActivePointWalk ); + } +#ifdef _DEBUG + PlaneCutHistory.AddToTail( &pOutwardFacingPlanes[iCurrentPlane * 4] ); +#endif + } + + + + +#ifdef _DEBUG + //Run around the edges of all the polygons and ensure they don't have more than one point of lowered "alive" status (alive > onplane > dead) surrounded by higher status + // It indicates a concave shape. It's impossible to have it occur in theoretical space. But floating point numbers introduce error. + { + GeneratePolyhedronFromPlanes_UnorderedPolygonLL *pDebugPolygonWalk = pAllPolygons; + do + { + int iSurroundedCount = 0; + GeneratePolyhedronFromPlanes_LineLL *pDebugLineWalk = pDebugPolygonWalk->pPolygon->pLines; + GeneratePolyhedronFromPlanes_LineLL *pFirstDebugLine = pDebugLineWalk; + + do + { + PolyhedronPointPlanarity currentPlanarity = pDebugLineWalk->pLine->pPoints[pDebugLineWalk->iReferenceIndex]->planarity; + + GeneratePolyhedronFromPlanes_LineLL *pNext = pDebugLineWalk->pNext; + PolyhedronPointPlanarity nextPlanarity = pNext->pLine->pPoints[pNext->iReferenceIndex]->planarity; + + if( currentPlanarity < nextPlanarity ) + { + GeneratePolyhedronFromPlanes_LineLL *pPrev = pDebugLineWalk->pPrev; + PolyhedronPointPlanarity prevPlanarity = pPrev->pLine->pPoints[pPrev->iReferenceIndex]->planarity; + + if( currentPlanarity < prevPlanarity ) + { + ++iSurroundedCount; + } + } + + pDebugLineWalk = pDebugLineWalk->pNext; + } while( pDebugLineWalk != pFirstDebugLine ); + + AssertMsg_DumpPolyhedron( iSurroundedCount <= 1, "Concave polygon, cutting process might break. Consider adjusting the on-plane epsilon to better compensate for floating point precision." ); + pDebugPolygonWalk = pDebugPolygonWalk->pNext; + } while( pDebugPolygonWalk ); + } +#endif + + //=================================================================================================== + // Step 2: Remove dead lines. A dead line is one with a dead point that isn't connected to a living point + //=================================================================================================== + { + GeneratePolyhedronFromPlanes_UnorderedLineLL *pActiveLineWalk = pAllLines; + do + { + GeneratePolyhedronFromPlanes_Line *pLine = pActiveLineWalk->pLine; + if( (pLine->bAlive == false) && (pLine->bCut == true) ) //not connected to a live point, but connected to a dead one. Dead line + { + //remove line from connected polygons + for( int i = 0; i != 2; ++i ) + { + GeneratePolyhedronFromPlanes_Polygon *pPolygon = pLine->pPolygons[i]; + GeneratePolyhedronFromPlanes_LineLL *pLineLink = pLine->pPolygonLineLinks[i]; + + pPolygon->bMissingASide = true; + + if( pLineLink->pNext == pLineLink ) + { + //this was the last line of the polygon, it's dead + pPolygon->pLines = NULL; + } + else + { + //link around this line + pPolygon->pLines = pLineLink->pPrev; //Always have the polygon's head line be just before the gap in the polygon + pLineLink->pNext->pPrev = pLineLink->pPrev; + pLineLink->pPrev->pNext = pLineLink->pNext; + } + + //move the line link to the dead list + pLineLink->pNext = pDeadLineLinkCollection; + pDeadLineLinkCollection = pLineLink; + } + + //remove the line from connected points + for( int i = 0; i != 2; ++i ) + { + GeneratePolyhedronFromPlanes_Point *pPoint = pLine->pPoints[i]; + GeneratePolyhedronFromPlanes_LineLL *pLineLink = pLine->pPointLineLinks[i]; + + if( pLineLink->pNext == pLineLink ) + { + //this is the last line + pPoint->pConnectedLines = NULL; + Assert( pPoint->planarity != POINT_ALIVE ); + pPoint->planarity = POINT_DEAD; //in case it was merely POINT_ONPLANE before + } + else + { + //link around this line + pPoint->pConnectedLines = pLineLink->pNext; //in case pLineLink was the head line + pLineLink->pNext->pPrev = pLineLink->pPrev; + pLineLink->pPrev->pNext = pLineLink->pNext; + } + + //move the line link to the dead list + pLineLink->pNext = pDeadLineLinkCollection; + pDeadLineLinkCollection = pLineLink; + } + + //move the line to the dead list + { + //link past this node + if( pActiveLineWalk->pPrev ) + pActiveLineWalk->pPrev->pNext = pActiveLineWalk->pNext; + else + pAllLines = pActiveLineWalk->pNext; + + if( pActiveLineWalk->pNext ) + pActiveLineWalk->pNext->pPrev = pActiveLineWalk->pPrev; + + GeneratePolyhedronFromPlanes_UnorderedLineLL *pNextLineWalk = pActiveLineWalk->pNext; + + //add to the dead list + pActiveLineWalk->pNext = pDeadLineCollection; + pDeadLineCollection = pActiveLineWalk; + + //next + pActiveLineWalk = pNextLineWalk; + } + } + else + { + pActiveLineWalk = pActiveLineWalk->pNext; + } + } while( pActiveLineWalk ); + } + + + //=================================================================================================== + // Step 3: Remove dead polygons. A dead polygon has less than 2 lines. + //=================================================================================================== + { + GeneratePolyhedronFromPlanes_UnorderedPolygonLL *pActivePolygonWalk = pAllPolygons; + do + { + GeneratePolyhedronFromPlanes_Polygon *pPolygon = pActivePolygonWalk->pPolygon; + GeneratePolyhedronFromPlanes_LineLL *pHeadLine = pPolygon->pLines; + + bool bDead = (pHeadLine == NULL) || (pHeadLine->pNext == pHeadLine); + if( !bDead ) + { + //there's a rare case where a polygon can be almost entirely coplanar with the cut, it comes purely out of the land of imprecision + bDead = true; //assume it's dead, and disprove + + GeneratePolyhedronFromPlanes_LineLL *pTestLineWalk = pHeadLine; + do + { + if( pTestLineWalk->pLine->bAlive ) + { + bDead = false; + break; + } + + pTestLineWalk = pTestLineWalk->pNext; + } while( pTestLineWalk != pHeadLine ); + } + + if( bDead ) + { + //dead polygon, move it to the dead list + + //link around this node + if( pActivePolygonWalk->pPrev ) + pActivePolygonWalk->pPrev->pNext = pActivePolygonWalk->pNext; + else + pAllPolygons = pAllPolygons->pNext; //pActivePolygonWalk was the head node + + if( pActivePolygonWalk->pNext ) + pActivePolygonWalk->pNext->pPrev = pActivePolygonWalk->pPrev; + + GeneratePolyhedronFromPlanes_UnorderedPolygonLL *pNextPolygonWalk = pActivePolygonWalk->pNext; + + //add to the dead list + pActivePolygonWalk->pNext = pDeadPolygonCollection; + pDeadPolygonCollection = pActivePolygonWalk; + + //next + pActivePolygonWalk = pNextPolygonWalk; + } + else + { + AssertMsg_DumpPolyhedron( (pActivePolygonWalk->pPolygon->pLines != NULL) && + (pActivePolygonWalk->pPolygon->pLines != pActivePolygonWalk->pPolygon->pLines->pNext), "Living polygon with less than 2 lines" ); + + pActivePolygonWalk = pActivePolygonWalk->pNext; + } + } while( pActivePolygonWalk ); + } + + //=================================================================================================== + // Step 4: Remove dead points. + //=================================================================================================== + { + GeneratePolyhedronFromPlanes_UnorderedPointLL *pActivePointWalk = pAllPoints; + do + { + if( pActivePointWalk->pPoint->planarity == POINT_DEAD ) + { + GeneratePolyhedronFromPlanes_UnorderedPointLL *pNext = pActivePointWalk->pNext; + + if( pActivePointWalk->pPrev ) + pActivePointWalk->pPrev->pNext = pActivePointWalk->pNext; + else + pAllPoints = pAllPoints->pNext; + + if( pActivePointWalk->pNext ) + pActivePointWalk->pNext->pPrev = pActivePointWalk->pPrev; + + pActivePointWalk->pNext = pDeadPointCollection; + pDeadPointCollection = pActivePointWalk; + + pActivePointWalk = pNext; + } + else + { + pActivePointWalk = pActivePointWalk->pNext; + } + } while( pActivePointWalk ); + } + + + //=================================================================================================== + // Step 5: Handle cut lines + //=================================================================================================== + { + GeneratePolyhedronFromPlanes_UnorderedLineLL *pActiveLineWalk = pAllLines; + do + { + GeneratePolyhedronFromPlanes_Line *pWorkLine = pActiveLineWalk->pLine; + Assert_DumpPolyhedron( (pWorkLine->bAlive == true) || (pWorkLine->bCut == false) ); //all dead lines should have already been removed + + if( pWorkLine->bCut ) + { + GeneratePolyhedronFromPlanes_Point **pLinePoints = pWorkLine->pPoints; + + Assert_DumpPolyhedron( (pLinePoints[0]->planarity == POINT_DEAD) || (pLinePoints[1]->planarity == POINT_DEAD) ); //one of the two has to be a dead point + + int iDeadIndex = (pLinePoints[0]->planarity == POINT_DEAD)?(0):(1); + int iLivingIndex = 1 - iDeadIndex; + GeneratePolyhedronFromPlanes_Point *pDeadPoint = pLinePoints[iDeadIndex]; + GeneratePolyhedronFromPlanes_Point *pLivingPoint = pLinePoints[iLivingIndex]; + + Assert_DumpPolyhedron( pLivingPoint->planarity == POINT_ALIVE ); //if this point were on-plane or dead, the line should be dead + + //We'll be de-linking from the old point and generating a new one. We do this so other lines can still access the dead point's untouched data. + + //Generate a new point + GeneratePolyhedronFromPlanes_Point *pNewPoint = (GeneratePolyhedronFromPlanes_Point *)stackalloc( sizeof( GeneratePolyhedronFromPlanes_Point ) ); + { + //add this point to the active list + pAllPoints->pPrev = (GeneratePolyhedronFromPlanes_UnorderedPointLL *)stackalloc( sizeof( GeneratePolyhedronFromPlanes_UnorderedPointLL ) ); + pAllPoints->pPrev->pNext = pAllPoints; + pAllPoints = pAllPoints->pPrev; + pAllPoints->pPrev = NULL; + pAllPoints->pPoint = pNewPoint; + + + float fInvTotalDist = 1.0f/(pDeadPoint->fPlaneDist - pLivingPoint->fPlaneDist); //subtraction because the living index is known to be negative + pNewPoint->ptPosition = (pLivingPoint->ptPosition * (pDeadPoint->fPlaneDist * fInvTotalDist)) - (pDeadPoint->ptPosition * (pLivingPoint->fPlaneDist * fInvTotalDist)); + +#if ( 0 && defined( _DEBUG ) ) + float fDebugDist = vNormal.Dot( pNewPoint->ptPosition ) - fPlaneDist; //just for looking at in watch windows + AssertMsg_DumpPolyhedron( fabs( fDebugDist ) < fOnPlaneEpsilon, "Generated split point is far from plane" ); + + //verify that the new point isn't sitting on top of another + { + GeneratePolyhedronFromPlanes_UnorderedPointLL *pActivePointWalk = pAllPoints; + do + { + if( pActivePointWalk->pPoint != pNewPoint ) + { + Vector vDiff = pActivePointWalk->pPoint->ptPosition - pNewPoint->ptPosition; + + AssertMsg_DumpPolyhedron( vDiff.Length() > fOnPlaneEpsilon, "Generated a point on top of another" ); + } + pActivePointWalk = pActivePointWalk->pNext; + } while( pActivePointWalk ); + } +#endif + + pNewPoint->planarity = POINT_ONPLANE; + pNewPoint->fPlaneDist = 0.0f; + } + + GeneratePolyhedronFromPlanes_LineLL *pNewLineLink = pNewPoint->pConnectedLines = (GeneratePolyhedronFromPlanes_LineLL *)stackalloc( sizeof( GeneratePolyhedronFromPlanes_LineLL ) ); + pNewLineLink->pLine = pWorkLine; + pNewLineLink->pNext = pNewLineLink; + pNewLineLink->pPrev = pNewLineLink; + pNewLineLink->iReferenceIndex = iLivingIndex; + + pWorkLine->pPoints[iDeadIndex] = pNewPoint; + pWorkLine->pPointLineLinks[iDeadIndex] = pNewLineLink; + pNewPoint->pConnectedLines = pNewLineLink; + + //A new line is needed on each polygon touching the dead point to connect the two new endpoints for split lines. + // So mark connected polygons as missing a side. + for( int i = 0; i != 2; ++i ) + pWorkLine->pPolygons[i]->bMissingASide = true; + + + //Always have a cut polygon's head line be just before the gap in the polygon. + // In this case, we know that one of the two polygons goes clockwise into the dead point, so have that polygon point at this line. + // We don't know enough about the other polygon to do anything here, but another cut line will handle that polygon. So it all works out in the end. + pWorkLine->pPolygons[iDeadIndex]->pLines = pWorkLine->pPolygonLineLinks[iDeadIndex]; + } + + pActiveLineWalk = pActiveLineWalk->pNext; + } while( pActiveLineWalk ); + } + + + //=================================================================================================== + // Step 6: Repair polygons that are missing a side. And generate the new coplanar polygon. + //=================================================================================================== + { + //Find the first polygon missing a side. + // We'll then walk from polygon to polygon using line connections so that we can generate the new polygon in a clockwise manner. + GeneratePolyhedronFromPlanes_UnorderedPolygonLL *pActivePolygonWalk = pAllPolygons; + + while( (pActivePolygonWalk != NULL) && (pActivePolygonWalk->pPolygon->bMissingASide == false) ) + { + pActivePolygonWalk = pActivePolygonWalk->pNext; + } + + //acquire iteration data +#ifndef _DEBUG + GeneratePolyhedronFromPlanes_Point *pStartPoint; + GeneratePolyhedronFromPlanes_Point *pWorkPoint; +#endif + + GeneratePolyhedronFromPlanes_LineLL *pLastLineLink; + GeneratePolyhedronFromPlanes_Polygon *pWorkPolygon; + GeneratePolyhedronFromPlanes_LineLL *pTestLine; + +#ifdef _DEBUG + GeneratePolyhedronFromPlanes_Polygon *pLastWorkPolygon = NULL; + GeneratePolyhedronFromPlanes_Point *pLastWorkPoint = NULL; +#endif + + if( pActivePolygonWalk ) + { + //grab the polygon we'll be starting with + GeneratePolyhedronFromPlanes_Polygon *pBrokenPolygon = pActivePolygonWalk->pPolygon; + + { + GeneratePolyhedronFromPlanes_LineLL *pTemp = pBrokenPolygon->pLines->pNext; + pStartPoint = pTemp->pLine->pPoints[1 - pTemp->iReferenceIndex]; + Assert_DumpPolyhedron( pStartPoint->planarity == POINT_ONPLANE ); //every working point should be coplanar + pLastLineLink = pTemp->pLine->pPointLineLinks[1 - pTemp->iReferenceIndex]->pNext; + pWorkPolygon = pBrokenPolygon; + } + + pWorkPoint = pStartPoint; + pTestLine = pLastLineLink->pPrev; //rotate counterclockwise around the point + } + else + { + //apparently the plane was entirely through existing polygonal borders, extremely rare but it can happen with inefficient cutting planes + GeneratePolyhedronFromPlanes_UnorderedPointLL *pActivePointWalk = pAllPoints; + while( (pActivePointWalk != NULL) && (pActivePointWalk->pPoint->planarity != POINT_ONPLANE) ) + { + pActivePointWalk = pActivePointWalk->pNext; + } + + Assert( pActivePointWalk != NULL ); + + pStartPoint = pWorkPoint = pActivePointWalk->pPoint; + GeneratePolyhedronFromPlanes_LineLL *pLines = pWorkPoint->pConnectedLines; + + while( !pLines->pLine->bAlive ) //seek clockwise until we find a line not on the plane + pLines = pLines->pNext; + + while( pLines->pLine->bAlive ) //now seek counterclockwise until we find a line on the plane (in case we started on an alive line last seek) + pLines = pLines->pPrev; + + //now pLines points at one side of the polygon, with pActivePointWalk + pLastLineLink = pLines; + pTestLine = pLines->pPrev; + pWorkPolygon = pTestLine->pLine->pPolygons[1 - pTestLine->iReferenceIndex]; + + } + + //create the new polygon + GeneratePolyhedronFromPlanes_Polygon *pNewPolygon = (GeneratePolyhedronFromPlanes_Polygon *)stackalloc( sizeof( GeneratePolyhedronFromPlanes_Polygon ) ); + { + //before we forget, add this polygon to the active list + pAllPolygons->pPrev = (GeneratePolyhedronFromPlanes_UnorderedPolygonLL *)stackalloc( sizeof( GeneratePolyhedronFromPlanes_UnorderedPolygonLL ) ); + pAllPolygons->pPrev->pNext = pAllPolygons; + pAllPolygons = pAllPolygons->pPrev; + pAllPolygons->pPrev = NULL; + pAllPolygons->pPolygon = pNewPolygon; + + pNewPolygon->bMissingASide = false; //technically missing all it's sides, but we're fixing it now + pNewPolygon->vSurfaceNormal = vNormal; + pNewPolygon->pLines = NULL; + } + + + + //=================================================================================================================== + // The general idea of the upcoming algorithm to put together a new polygon and patch broken polygons... + // You have a point and a line the algorithm just jumped across. + // 1. Rotate through the point's line links one time counterclockwise (pPrev) + // 2. If the line is cut, then we make a new bridging line in the polygon between that line and the one counterclockwise to it. (pPrev) + // If the line is on-plane. Skip the bridge line making, but set links to the new polygon as if we'd just created the bridge + // 3. Once we follow a line back to the point where we started, we should be all done. + + do + { + if( pWorkPolygon->bMissingASide ) + { + //during the cutting process we made sure that the head line link was going clockwise into the missing area + GeneratePolyhedronFromPlanes_LineLL *pGapLines[2]; + pGapLines[1] = pTestLine->pLine->pPolygonLineLinks[pTestLine->iReferenceIndex]; //get the same line, but in the polygons linked list. + Assert_DumpPolyhedron( pGapLines[1]->pLine == pTestLine->pLine ); + pGapLines[0] = pGapLines[1]->pPrev; + + Assert_DumpPolyhedron( pWorkPolygon->bMissingASide ); + +#ifdef _DEBUG + { + //ensure that the space between the gap lines is the only space where fixing is required + GeneratePolyhedronFromPlanes_LineLL *pDebugLineWalk = pGapLines[1]->pNext; + + while( pDebugLineWalk != pGapLines[0] ) + { + Assert_DumpPolyhedron( pDebugLineWalk->pLine->bCut == false ); + pDebugLineWalk = pDebugLineWalk->pNext; + } + } +#endif + + GeneratePolyhedronFromPlanes_Line *pJoinLine = (GeneratePolyhedronFromPlanes_Line *)stackalloc( sizeof( GeneratePolyhedronFromPlanes_Line ) ); + { + //before we forget, add this line to the active list + pAllLines->pPrev = (GeneratePolyhedronFromPlanes_UnorderedLineLL *)stackalloc( sizeof( GeneratePolyhedronFromPlanes_UnorderedLineLL ) ); + pAllLines->pPrev->pNext = pAllLines; + pAllLines = pAllLines->pPrev; + pAllLines->pPrev = NULL; + pAllLines->pLine = pJoinLine; + + pJoinLine->bAlive = false; + pJoinLine->bCut = false; + } + + + pJoinLine->pPoints[0] = pGapLines[0]->pLine->pPoints[pGapLines[0]->iReferenceIndex]; + pJoinLine->pPoints[1] = pGapLines[1]->pLine->pPoints[1 - pGapLines[1]->iReferenceIndex]; + + pJoinLine->pPolygons[0] = pNewPolygon; + pJoinLine->pPolygons[1] = pWorkPolygon; + + //now create all 4 links into the line + GeneratePolyhedronFromPlanes_LineLL *pPointLinks[2]; + pPointLinks[0] = (GeneratePolyhedronFromPlanes_LineLL *)stackalloc( sizeof( GeneratePolyhedronFromPlanes_LineLL ) ); + pPointLinks[1] = (GeneratePolyhedronFromPlanes_LineLL *)stackalloc( sizeof( GeneratePolyhedronFromPlanes_LineLL ) ); + + GeneratePolyhedronFromPlanes_LineLL *pPolygonLinks[2]; + pPolygonLinks[0] = (GeneratePolyhedronFromPlanes_LineLL *)stackalloc( sizeof( GeneratePolyhedronFromPlanes_LineLL ) ); + pPolygonLinks[1] = (GeneratePolyhedronFromPlanes_LineLL *)stackalloc( sizeof( GeneratePolyhedronFromPlanes_LineLL ) ); + + pPointLinks[0]->pLine = pPointLinks[1]->pLine = pPolygonLinks[0]->pLine = pPolygonLinks[1]->pLine = pJoinLine; + + pJoinLine->pPointLineLinks[0] = pPointLinks[0]; + pJoinLine->pPointLineLinks[1] = pPointLinks[1]; + pJoinLine->pPolygonLineLinks[0] = pPolygonLinks[0]; + pJoinLine->pPolygonLineLinks[1] = pPolygonLinks[1]; + + + + pPointLinks[0]->iReferenceIndex = 1; + pPointLinks[1]->iReferenceIndex = 0; + + //Insert before the link from point 0 to gap line 0 (counterclockwise rotation) + { + GeneratePolyhedronFromPlanes_LineLL *pWorkLink = pGapLines[0]->pLine->pPointLineLinks[pGapLines[0]->iReferenceIndex]; + Assert_DumpPolyhedron( pWorkLink->pLine == pGapLines[0]->pLine ); + + pPointLinks[0]->pPrev = pWorkLink->pPrev; + pPointLinks[0]->pNext = pWorkLink; + + pWorkLink->pPrev->pNext = pPointLinks[0]; + pWorkLink->pPrev = pPointLinks[0]; + } + + //Insert after the link from point 1 to gap line 1 (clockwise rotation) + { + GeneratePolyhedronFromPlanes_LineLL *pWorkLink = pGapLines[1]->pLine->pPointLineLinks[1 - pGapLines[1]->iReferenceIndex]; + Assert_DumpPolyhedron( pWorkLink->pLine == pGapLines[1]->pLine ); + + pPointLinks[1]->pNext = pWorkLink->pNext; + pPointLinks[1]->pPrev = pWorkLink; + + pWorkLink->pNext->pPrev = pPointLinks[1]; + pWorkLink->pNext = pPointLinks[1]; + } + + + + + pPolygonLinks[0]->iReferenceIndex = 0; + pPolygonLinks[1]->iReferenceIndex = 1; + + //Insert before the head line in the new polygon (at the end of the clockwise order) + { + if( pNewPolygon->pLines == NULL ) + { + //this is the first line being added to the polygon + pNewPolygon->pLines = pPolygonLinks[0]; + pPolygonLinks[0]->pNext = pPolygonLinks[0]; + pPolygonLinks[0]->pPrev = pPolygonLinks[0]; + } + else + { + GeneratePolyhedronFromPlanes_LineLL *pWorkLink = pNewPolygon->pLines; + + pPolygonLinks[0]->pNext = pWorkLink; + pPolygonLinks[0]->pPrev = pWorkLink->pPrev; + + pWorkLink->pPrev->pNext = pPolygonLinks[0]; + pWorkLink->pPrev = pPolygonLinks[0]; + } + } + + //Insert after the head line in the work polygon + { + GeneratePolyhedronFromPlanes_LineLL *pWorkLink = pWorkPolygon->pLines; + + pPolygonLinks[1]->pNext = pWorkLink->pNext; + pPolygonLinks[1]->pPrev = pWorkLink; + + pWorkLink->pNext->pPrev = pPolygonLinks[1]; + pWorkLink->pNext = pPolygonLinks[1]; + } + + pWorkPolygon->bMissingASide = false; //repairs are finished + +#ifdef _DEBUG + pLastWorkPolygon = pWorkPolygon; + pLastWorkPoint = pWorkPoint; +#endif + //move to the next point + pWorkPoint = pJoinLine->pPoints[0]; + pLastLineLink = pJoinLine->pPointLineLinks[0]; + Assert_DumpPolyhedron( pWorkPoint->planarity == POINT_ONPLANE ); //every working point should be coplanar + + pTestLine = pLastLineLink->pPrev; + if( pTestLine->pLine->pPoints[pTestLine->iReferenceIndex]->planarity == POINT_ALIVE ) + pWorkPolygon = pTestLine->pLine->pPolygons[pTestLine->iReferenceIndex]; + else + pWorkPolygon = pTestLine->pLine->pPolygons[1 - pTestLine->iReferenceIndex]; + + Assert_DumpPolyhedron( pWorkPolygon != pLastWorkPolygon ); + Assert_DumpPolyhedron( (pWorkPoint == pStartPoint) || + (pGapLines[0]->pLine->bCut == false) || + (pWorkPolygon->bMissingASide == true) ); //if we're not done fixing, and if the shared line was cut, the next polygon must be missing a side + } + else + { + //line is on the plane, meaning the polygon isn't broken and doesn't need patching + Assert_DumpPolyhedron( pTestLine->pLine->bCut == false ); + Assert_DumpPolyhedron( (pTestLine->pLine->pPoints[0]->planarity == POINT_ONPLANE) && (pTestLine->pLine->pPoints[1]->planarity == POINT_ONPLANE) ); + + + //link to this line from the new polygon + GeneratePolyhedronFromPlanes_LineLL *pNewLineLink; + pNewLineLink = (GeneratePolyhedronFromPlanes_LineLL *)stackalloc( sizeof( GeneratePolyhedronFromPlanes_LineLL ) ); + + pNewLineLink->pLine = pTestLine->pLine; + pNewLineLink->iReferenceIndex = pTestLine->iReferenceIndex; + + //Insert before the head line in the new polygon (at the end of the clockwise order) + { + if( pNewPolygon->pLines == NULL ) + { + //this is the first line being added to the polygon + pNewPolygon->pLines = pNewLineLink; + pNewLineLink->pNext = pNewLineLink; + pNewLineLink->pPrev = pNewLineLink; + } + else + { + GeneratePolyhedronFromPlanes_LineLL *pWorkLink = pNewPolygon->pLines; + + pNewLineLink->pNext = pWorkLink; + pNewLineLink->pPrev = pWorkLink->pPrev; + + pWorkLink->pPrev->pNext = pNewLineLink; + pWorkLink->pPrev = pNewLineLink; + } + } + + //Since the entire line is on the plane, that means it used to point to something that used to reside where the new polygon is going + // Update the link to the new the polygon pointer and be on our way + pTestLine->pLine->pPolygons[pTestLine->iReferenceIndex] = pNewPolygon; + pTestLine->pLine->pPolygonLineLinks[pTestLine->iReferenceIndex] = pNewLineLink; + +#ifdef _DEBUG + pLastWorkPolygon = pWorkPolygon; + pLastWorkPoint = pWorkPoint; +#endif + + pWorkPoint = pTestLine->pLine->pPoints[pTestLine->iReferenceIndex]; + pLastLineLink = pTestLine->pLine->pPointLineLinks[pTestLine->iReferenceIndex]; + Assert_DumpPolyhedron( pWorkPoint->planarity == POINT_ONPLANE ); //every working point should be coplanar + + pTestLine = pLastLineLink->pPrev; + if( pTestLine->pLine->pPoints[pTestLine->iReferenceIndex]->planarity == POINT_ALIVE ) + pWorkPolygon = pTestLine->pLine->pPolygons[pTestLine->iReferenceIndex]; + else + pWorkPolygon = pTestLine->pLine->pPolygons[1 - pTestLine->iReferenceIndex]; + + Assert_DumpPolyhedron( pWorkPolygon != pLastWorkPolygon ); + } + } while( pWorkPoint != pStartPoint ); + } + +#ifdef _DEBUG + //verify that repairs are complete + { + GeneratePolyhedronFromPlanes_UnorderedPolygonLL *pDebugPolygonWalk = pAllPolygons; + do + { + AssertMsg_DumpPolyhedron( pDebugPolygonWalk->pPolygon->bMissingASide == false, "Some polygons not repaired after cut" ); + pDebugPolygonWalk = pDebugPolygonWalk->pNext; + } while( pDebugPolygonWalk ); + + + GeneratePolyhedronFromPlanes_UnorderedPointLL *pDebugPointWalk = pAllPoints; + do + { + AssertMsg_DumpPolyhedron( pDebugPointWalk->pPoint->pConnectedLines, "Point connected to no lines after cut" ); + pDebugPointWalk = pDebugPointWalk->pNext; + } while( pDebugPointWalk ); + + pStartPoint = NULL; + } + + //maintain the cut history + DebugCutHistory.AddToTail( ConvertLinkedGeometryToPolyhedron( pAllPolygons, pAllLines, pAllPoints, false ) ); +#endif + } + +#ifdef _DEBUG + for( int i = DebugCutHistory.Count(); --i >= 0; ) + { + if( DebugCutHistory[i] ) + DebugCutHistory[i]->Release(); + } + DebugCutHistory.RemoveAll(); +#endif + + return ConvertLinkedGeometryToPolyhedron( pAllPolygons, pAllLines, pAllPoints, bUseTemporaryMemory ); +} + + + +#define STARTPOINTTOLINELINKS(iPointNum, lineindex1, iOtherPointIndex1, lineindex2, iOtherPointIndex2, lineindex3, iOtherPointIndex3 )\ + StartingBoxPoints[iPointNum].pConnectedLines = &StartingPoints_To_Lines_Links[(iPointNum * 3) + 0];\ + StartingPoints_To_Lines_Links[(iPointNum * 3) + 0].pLine = &StartingBoxLines[lineindex1];\ + StartingPoints_To_Lines_Links[(iPointNum * 3) + 0].iReferenceIndex = iOtherPointIndex1;\ + StartingBoxLines[lineindex1].pPointLineLinks[1 - iOtherPointIndex1] = &StartingPoints_To_Lines_Links[(iPointNum * 3) + 0];\ + StartingPoints_To_Lines_Links[(iPointNum * 3) + 0].pPrev = &StartingPoints_To_Lines_Links[(iPointNum * 3) + 2];\ + StartingPoints_To_Lines_Links[(iPointNum * 3) + 0].pNext = &StartingPoints_To_Lines_Links[(iPointNum * 3) + 1];\ + StartingPoints_To_Lines_Links[(iPointNum * 3) + 1].pLine = &StartingBoxLines[lineindex2];\ + StartingPoints_To_Lines_Links[(iPointNum * 3) + 1].iReferenceIndex = iOtherPointIndex2;\ + StartingBoxLines[lineindex2].pPointLineLinks[1 - iOtherPointIndex2] = &StartingPoints_To_Lines_Links[(iPointNum * 3) + 1];\ + StartingPoints_To_Lines_Links[(iPointNum * 3) + 1].pPrev = &StartingPoints_To_Lines_Links[(iPointNum * 3) + 0];\ + StartingPoints_To_Lines_Links[(iPointNum * 3) + 1].pNext = &StartingPoints_To_Lines_Links[(iPointNum * 3) + 2];\ + StartingPoints_To_Lines_Links[(iPointNum * 3) + 2].pLine = &StartingBoxLines[lineindex3];\ + StartingPoints_To_Lines_Links[(iPointNum * 3) + 2].iReferenceIndex = iOtherPointIndex3;\ + StartingBoxLines[lineindex3].pPointLineLinks[1 - iOtherPointIndex3] = &StartingPoints_To_Lines_Links[(iPointNum * 3) + 2];\ + StartingPoints_To_Lines_Links[(iPointNum * 3) + 2].pPrev = &StartingPoints_To_Lines_Links[(iPointNum * 3) + 1];\ + StartingPoints_To_Lines_Links[(iPointNum * 3) + 2].pNext = &StartingPoints_To_Lines_Links[(iPointNum * 3) + 0]; + +#define STARTBOXCONNECTION( linenum, point1, point2, poly1, poly2 )\ + StartingBoxLines[linenum].pPoints[0] = &StartingBoxPoints[point1];\ + StartingBoxLines[linenum].pPoints[1] = &StartingBoxPoints[point2];\ + StartingBoxLines[linenum].pPolygons[0] = &StartingBoxPolygons[poly1];\ + StartingBoxLines[linenum].pPolygons[1] = &StartingBoxPolygons[poly2]; + +#define STARTPOLYGONTOLINELINKS( polynum, lineindex1, iThisPolyIndex1, lineindex2, iThisPolyIndex2, lineindex3, iThisPolyIndex3, lineindex4, iThisPolyIndex4 )\ + StartingBoxPolygons[polynum].pLines = &StartingPolygon_To_Lines_Links[(polynum * 4) + 0];\ + StartingPolygon_To_Lines_Links[(polynum * 4) + 0].pLine = &StartingBoxLines[lineindex1];\ + StartingPolygon_To_Lines_Links[(polynum * 4) + 0].iReferenceIndex = iThisPolyIndex1;\ + StartingBoxLines[lineindex1].pPolygonLineLinks[iThisPolyIndex1] = &StartingPolygon_To_Lines_Links[(polynum * 4) + 0];\ + StartingPolygon_To_Lines_Links[(polynum * 4) + 0].pPrev = &StartingPolygon_To_Lines_Links[(polynum * 4) + 3];\ + StartingPolygon_To_Lines_Links[(polynum * 4) + 0].pNext = &StartingPolygon_To_Lines_Links[(polynum * 4) + 1];\ + StartingPolygon_To_Lines_Links[(polynum * 4) + 1].pLine = &StartingBoxLines[lineindex2];\ + StartingPolygon_To_Lines_Links[(polynum * 4) + 1].iReferenceIndex = iThisPolyIndex2;\ + StartingBoxLines[lineindex2].pPolygonLineLinks[iThisPolyIndex2] = &StartingPolygon_To_Lines_Links[(polynum * 4) + 1];\ + StartingPolygon_To_Lines_Links[(polynum * 4) + 1].pPrev = &StartingPolygon_To_Lines_Links[(polynum * 4) + 0];\ + StartingPolygon_To_Lines_Links[(polynum * 4) + 1].pNext = &StartingPolygon_To_Lines_Links[(polynum * 4) + 2];\ + StartingPolygon_To_Lines_Links[(polynum * 4) + 2].pLine = &StartingBoxLines[lineindex3];\ + StartingPolygon_To_Lines_Links[(polynum * 4) + 2].iReferenceIndex = iThisPolyIndex3;\ + StartingBoxLines[lineindex3].pPolygonLineLinks[iThisPolyIndex3] = &StartingPolygon_To_Lines_Links[(polynum * 4) + 2];\ + StartingPolygon_To_Lines_Links[(polynum * 4) + 2].pPrev = &StartingPolygon_To_Lines_Links[(polynum * 4) + 1];\ + StartingPolygon_To_Lines_Links[(polynum * 4) + 2].pNext = &StartingPolygon_To_Lines_Links[(polynum * 4) + 3];\ + StartingPolygon_To_Lines_Links[(polynum * 4) + 3].pLine = &StartingBoxLines[lineindex4];\ + StartingPolygon_To_Lines_Links[(polynum * 4) + 3].iReferenceIndex = iThisPolyIndex4;\ + StartingBoxLines[lineindex4].pPolygonLineLinks[iThisPolyIndex4] = &StartingPolygon_To_Lines_Links[(polynum * 4) + 3];\ + StartingPolygon_To_Lines_Links[(polynum * 4) + 3].pPrev = &StartingPolygon_To_Lines_Links[(polynum * 4) + 2];\ + StartingPolygon_To_Lines_Links[(polynum * 4) + 3].pNext = &StartingPolygon_To_Lines_Links[(polynum * 4) + 0]; + + +CPolyhedron *GeneratePolyhedronFromPlanes( const float *pOutwardFacingPlanes, int iPlaneCount, float fOnPlaneEpsilon, bool bUseTemporaryMemory ) +{ + //this is version 2 of the polyhedron generator, version 1 made individual polygons and joined points together, some guesswork is involved and it therefore isn't a solid method + //this version will start with a cube and hack away at it (retaining point connection information) to produce a polyhedron with no guesswork involved, this method should be rock solid + + //the polygon clipping functions we're going to use want inward facing planes + float *pFlippedPlanes = (float *)stackalloc( (iPlaneCount * 4) * sizeof( float ) ); + for( int i = 0; i != iPlaneCount * 4; ++i ) + { + pFlippedPlanes[i] = -pOutwardFacingPlanes[i]; + } + + //our first goal is to find the size of a cube big enough to encapsulate all points that will be in the final polyhedron + Vector vAABBMins, vAABBMaxs; + if( FindConvexShapeLooseAABB( pFlippedPlanes, iPlaneCount, &vAABBMins, &vAABBMaxs ) == false ) + return NULL; //no shape to work with apparently + + + //grow the bounding box to a larger size since it's probably inaccurate a bit + { + Vector vGrow = (vAABBMaxs - vAABBMins) * 0.5f; + vGrow.x += 100.0f; + vGrow.y += 100.0f; + vGrow.z += 100.0f; + + vAABBMaxs += vGrow; + vAABBMins -= vGrow; + } + + //generate our starting cube using the 2x AABB so we can start hacking away at it + + + + //create our starting box on the stack + GeneratePolyhedronFromPlanes_Point StartingBoxPoints[8]; + GeneratePolyhedronFromPlanes_Line StartingBoxLines[12]; + GeneratePolyhedronFromPlanes_Polygon StartingBoxPolygons[6]; + GeneratePolyhedronFromPlanes_LineLL StartingPoints_To_Lines_Links[24]; //8 points, 3 lines per point + GeneratePolyhedronFromPlanes_LineLL StartingPolygon_To_Lines_Links[24]; //6 polygons, 4 lines per poly + + GeneratePolyhedronFromPlanes_UnorderedPolygonLL StartingPolygonList[6]; //6 polygons + GeneratePolyhedronFromPlanes_UnorderedLineLL StartingLineList[12]; //12 lines + GeneratePolyhedronFromPlanes_UnorderedPointLL StartingPointList[8]; //8 points + + + //I had to work all this out on a whiteboard if it seems completely unintuitive. + { + StartingBoxPoints[0].ptPosition.Init( vAABBMins.x, vAABBMins.y, vAABBMins.z ); + STARTPOINTTOLINELINKS( 0, 0, 1, 4, 1, 3, 0 ); + + StartingBoxPoints[1].ptPosition.Init( vAABBMins.x, vAABBMaxs.y, vAABBMins.z ); + STARTPOINTTOLINELINKS( 1, 0, 0, 1, 1, 5, 1 ); + + StartingBoxPoints[2].ptPosition.Init( vAABBMins.x, vAABBMins.y, vAABBMaxs.z ); + STARTPOINTTOLINELINKS( 2, 4, 0, 8, 1, 11, 0 ); + + StartingBoxPoints[3].ptPosition.Init( vAABBMins.x, vAABBMaxs.y, vAABBMaxs.z ); + STARTPOINTTOLINELINKS( 3, 5, 0, 9, 1, 8, 0 ); + + StartingBoxPoints[4].ptPosition.Init( vAABBMaxs.x, vAABBMins.y, vAABBMins.z ); + STARTPOINTTOLINELINKS( 4, 2, 0, 3, 1, 7, 1 ); + + StartingBoxPoints[5].ptPosition.Init( vAABBMaxs.x, vAABBMaxs.y, vAABBMins.z ); + STARTPOINTTOLINELINKS( 5, 1, 0, 2, 1, 6, 1 ); + + StartingBoxPoints[6].ptPosition.Init( vAABBMaxs.x, vAABBMins.y, vAABBMaxs.z ); + STARTPOINTTOLINELINKS( 6, 7, 0, 11, 1, 10, 0 ); + + StartingBoxPoints[7].ptPosition.Init( vAABBMaxs.x, vAABBMaxs.y, vAABBMaxs.z ); + STARTPOINTTOLINELINKS( 7, 6, 0, 10, 1, 9, 0 ); + + STARTBOXCONNECTION( 0, 0, 1, 0, 5 ); + STARTBOXCONNECTION( 1, 1, 5, 1, 5 ); + STARTBOXCONNECTION( 2, 5, 4, 2, 5 ); + STARTBOXCONNECTION( 3, 4, 0, 3, 5 ); + STARTBOXCONNECTION( 4, 0, 2, 3, 0 ); + STARTBOXCONNECTION( 5, 1, 3, 0, 1 ); + STARTBOXCONNECTION( 6, 5, 7, 1, 2 ); + STARTBOXCONNECTION( 7, 4, 6, 2, 3 ); + STARTBOXCONNECTION( 8, 2, 3, 4, 0 ); + STARTBOXCONNECTION( 9, 3, 7, 4, 1 ); + STARTBOXCONNECTION( 10, 7, 6, 4, 2 ); + STARTBOXCONNECTION( 11, 6, 2, 4, 3 ); + + + STARTBOXCONNECTION( 0, 0, 1, 5, 0 ); + STARTBOXCONNECTION( 1, 1, 5, 5, 1 ); + STARTBOXCONNECTION( 2, 5, 4, 5, 2 ); + STARTBOXCONNECTION( 3, 4, 0, 5, 3 ); + STARTBOXCONNECTION( 4, 0, 2, 0, 3 ); + STARTBOXCONNECTION( 5, 1, 3, 1, 0 ); + STARTBOXCONNECTION( 6, 5, 7, 2, 1 ); + STARTBOXCONNECTION( 7, 4, 6, 3, 2 ); + STARTBOXCONNECTION( 8, 2, 3, 0, 4 ); + STARTBOXCONNECTION( 9, 3, 7, 1, 4 ); + STARTBOXCONNECTION( 10, 7, 6, 2, 4 ); + STARTBOXCONNECTION( 11, 6, 2, 3, 4 ); + + StartingBoxPolygons[0].vSurfaceNormal.Init( -1.0f, 0.0f, 0.0f ); + StartingBoxPolygons[1].vSurfaceNormal.Init( 0.0f, 1.0f, 0.0f ); + StartingBoxPolygons[2].vSurfaceNormal.Init( 1.0f, 0.0f, 0.0f ); + StartingBoxPolygons[3].vSurfaceNormal.Init( 0.0f, -1.0f, 0.0f ); + StartingBoxPolygons[4].vSurfaceNormal.Init( 0.0f, 0.0f, 1.0f ); + StartingBoxPolygons[5].vSurfaceNormal.Init( 0.0f, 0.0f, -1.0f ); + + + STARTPOLYGONTOLINELINKS( 0, 0, 1, 5, 1, 8, 0, 4, 0 ); + STARTPOLYGONTOLINELINKS( 1, 1, 1, 6, 1, 9, 0, 5, 0 ); + STARTPOLYGONTOLINELINKS( 2, 2, 1, 7, 1, 10, 0, 6, 0 ); + STARTPOLYGONTOLINELINKS( 3, 3, 1, 4, 1, 11, 0, 7, 0 ); + STARTPOLYGONTOLINELINKS( 4, 8, 1, 9, 1, 10, 1, 11, 1 ); + STARTPOLYGONTOLINELINKS( 5, 0, 0, 3, 0, 2, 0, 1, 0 ); + + + { + StartingPolygonList[0].pPolygon = &StartingBoxPolygons[0]; + StartingPolygonList[0].pNext = &StartingPolygonList[1]; + StartingPolygonList[0].pPrev = NULL; + + StartingPolygonList[1].pPolygon = &StartingBoxPolygons[1]; + StartingPolygonList[1].pNext = &StartingPolygonList[2]; + StartingPolygonList[1].pPrev = &StartingPolygonList[0]; + + StartingPolygonList[2].pPolygon = &StartingBoxPolygons[2]; + StartingPolygonList[2].pNext = &StartingPolygonList[3]; + StartingPolygonList[2].pPrev = &StartingPolygonList[1]; + + StartingPolygonList[3].pPolygon = &StartingBoxPolygons[3]; + StartingPolygonList[3].pNext = &StartingPolygonList[4]; + StartingPolygonList[3].pPrev = &StartingPolygonList[2]; + + StartingPolygonList[4].pPolygon = &StartingBoxPolygons[4]; + StartingPolygonList[4].pNext = &StartingPolygonList[5]; + StartingPolygonList[4].pPrev = &StartingPolygonList[3]; + + StartingPolygonList[5].pPolygon = &StartingBoxPolygons[5]; + StartingPolygonList[5].pNext = NULL; + StartingPolygonList[5].pPrev = &StartingPolygonList[4]; + } + + + + { + StartingLineList[0].pLine = &StartingBoxLines[0]; + StartingLineList[0].pNext = &StartingLineList[1]; + StartingLineList[0].pPrev = NULL; + + StartingLineList[1].pLine = &StartingBoxLines[1]; + StartingLineList[1].pNext = &StartingLineList[2]; + StartingLineList[1].pPrev = &StartingLineList[0]; + + StartingLineList[2].pLine = &StartingBoxLines[2]; + StartingLineList[2].pNext = &StartingLineList[3]; + StartingLineList[2].pPrev = &StartingLineList[1]; + + StartingLineList[3].pLine = &StartingBoxLines[3]; + StartingLineList[3].pNext = &StartingLineList[4]; + StartingLineList[3].pPrev = &StartingLineList[2]; + + StartingLineList[4].pLine = &StartingBoxLines[4]; + StartingLineList[4].pNext = &StartingLineList[5]; + StartingLineList[4].pPrev = &StartingLineList[3]; + + StartingLineList[5].pLine = &StartingBoxLines[5]; + StartingLineList[5].pNext = &StartingLineList[6]; + StartingLineList[5].pPrev = &StartingLineList[4]; + + StartingLineList[6].pLine = &StartingBoxLines[6]; + StartingLineList[6].pNext = &StartingLineList[7]; + StartingLineList[6].pPrev = &StartingLineList[5]; + + StartingLineList[7].pLine = &StartingBoxLines[7]; + StartingLineList[7].pNext = &StartingLineList[8]; + StartingLineList[7].pPrev = &StartingLineList[6]; + + StartingLineList[8].pLine = &StartingBoxLines[8]; + StartingLineList[8].pNext = &StartingLineList[9]; + StartingLineList[8].pPrev = &StartingLineList[7]; + + StartingLineList[9].pLine = &StartingBoxLines[9]; + StartingLineList[9].pNext = &StartingLineList[10]; + StartingLineList[9].pPrev = &StartingLineList[8]; + + StartingLineList[10].pLine = &StartingBoxLines[10]; + StartingLineList[10].pNext = &StartingLineList[11]; + StartingLineList[10].pPrev = &StartingLineList[9]; + + StartingLineList[11].pLine = &StartingBoxLines[11]; + StartingLineList[11].pNext = NULL; + StartingLineList[11].pPrev = &StartingLineList[10]; + } + + { + StartingPointList[0].pPoint = &StartingBoxPoints[0]; + StartingPointList[0].pNext = &StartingPointList[1]; + StartingPointList[0].pPrev = NULL; + + StartingPointList[1].pPoint = &StartingBoxPoints[1]; + StartingPointList[1].pNext = &StartingPointList[2]; + StartingPointList[1].pPrev = &StartingPointList[0]; + + StartingPointList[2].pPoint = &StartingBoxPoints[2]; + StartingPointList[2].pNext = &StartingPointList[3]; + StartingPointList[2].pPrev = &StartingPointList[1]; + + StartingPointList[3].pPoint = &StartingBoxPoints[3]; + StartingPointList[3].pNext = &StartingPointList[4]; + StartingPointList[3].pPrev = &StartingPointList[2]; + + StartingPointList[4].pPoint = &StartingBoxPoints[4]; + StartingPointList[4].pNext = &StartingPointList[5]; + StartingPointList[4].pPrev = &StartingPointList[3]; + + StartingPointList[5].pPoint = &StartingBoxPoints[5]; + StartingPointList[5].pNext = &StartingPointList[6]; + StartingPointList[5].pPrev = &StartingPointList[4]; + + StartingPointList[6].pPoint = &StartingBoxPoints[6]; + StartingPointList[6].pNext = &StartingPointList[7]; + StartingPointList[6].pPrev = &StartingPointList[5]; + + StartingPointList[7].pPoint = &StartingBoxPoints[7]; + StartingPointList[7].pNext = NULL; + StartingPointList[7].pPrev = &StartingPointList[6]; + } + } + + return ClipLinkedGeometry( StartingPolygonList, StartingLineList, StartingPointList, pOutwardFacingPlanes, iPlaneCount, fOnPlaneEpsilon, bUseTemporaryMemory ); +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#ifdef _DEBUG +void DumpAABBToGLView( const Vector &vCenter, const Vector &vExtents, const Vector &vColor, FILE *pFile ) +{ +#ifdef ENABLE_DEBUG_POLYHEDRON_DUMPS + Vector vMins = vCenter - vExtents; + Vector vMaxs = vCenter + vExtents; + + //x min side + fprintf( pFile, "4\n" ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMins.y, vMins.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMins.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMaxs.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMaxs.y, vMins.z, vColor.x, vColor.y, vColor.z ); + + fprintf( pFile, "4\n" ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMaxs.y, vMins.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMaxs.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMins.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMins.y, vMins.z, vColor.x, vColor.y, vColor.z ); + + //x max side + fprintf( pFile, "4\n" ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMins.y, vMins.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMins.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMaxs.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMaxs.y, vMins.z, vColor.x, vColor.y, vColor.z ); + + fprintf( pFile, "4\n" ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMaxs.y, vMins.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMaxs.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMins.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMins.y, vMins.z, vColor.x, vColor.y, vColor.z ); + + + //y min side + fprintf( pFile, "4\n" ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMins.y, vMins.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMins.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMins.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMins.y, vMins.z, vColor.x, vColor.y, vColor.z ); + + fprintf( pFile, "4\n" ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMins.y, vMins.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMins.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMins.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMins.y, vMins.z, vColor.x, vColor.y, vColor.z ); + + + + //y max side + fprintf( pFile, "4\n" ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMaxs.y, vMins.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMaxs.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMaxs.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMaxs.y, vMins.z, vColor.x, vColor.y, vColor.z ); + + fprintf( pFile, "4\n" ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMaxs.y, vMins.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMaxs.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMaxs.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMaxs.y, vMins.z, vColor.x, vColor.y, vColor.z ); + + + + //z min side + fprintf( pFile, "4\n" ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMins.y, vMins.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMaxs.y, vMins.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMaxs.y, vMins.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMins.y, vMins.z, vColor.x, vColor.y, vColor.z ); + + fprintf( pFile, "4\n" ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMins.y, vMins.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMaxs.y, vMins.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMaxs.y, vMins.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMins.y, vMins.z, vColor.x, vColor.y, vColor.z ); + + + //z max side + fprintf( pFile, "4\n" ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMins.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMaxs.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMaxs.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMins.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + + fprintf( pFile, "4\n" ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMins.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMaxs.x, vMaxs.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMaxs.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vMins.x, vMins.y, vMaxs.z, vColor.x, vColor.y, vColor.z ); +#endif +} + +void DumpLineToGLView( const Vector &vPoint1, const Vector &vColor1, const Vector &vPoint2, const Vector &vColor2, float fThickness, FILE *pFile ) +{ +#ifdef ENABLE_DEBUG_POLYHEDRON_DUMPS + Vector vDirection = vPoint2 - vPoint1; + vDirection.NormalizeInPlace(); + + Vector vPseudoPerpandicular = vec3_origin; + + if( vDirection.x != 0.0f ) + vPseudoPerpandicular.z = 1.0f; + else + vPseudoPerpandicular.x = 1.0f; + + Vector vWidth = vDirection.Cross( vPseudoPerpandicular ); + vWidth.NormalizeInPlace(); + + Vector vHeight = vDirection.Cross( vWidth ); + vHeight.NormalizeInPlace(); + + fThickness *= 0.5f; //we use half thickness in both directions + vDirection *= fThickness; + vWidth *= fThickness; + vHeight *= fThickness; + + Vector vLinePoints[8]; + vLinePoints[0] = vPoint1 - vDirection - vWidth - vHeight; + vLinePoints[1] = vPoint1 - vDirection - vWidth + vHeight; + vLinePoints[2] = vPoint1 - vDirection + vWidth - vHeight; + vLinePoints[3] = vPoint1 - vDirection + vWidth + vHeight; + + vLinePoints[4] = vPoint2 + vDirection - vWidth - vHeight; + vLinePoints[5] = vPoint2 + vDirection - vWidth + vHeight; + vLinePoints[6] = vPoint2 + vDirection + vWidth - vHeight; + vLinePoints[7] = vPoint2 + vDirection + vWidth + vHeight; + + const Vector *pLineColors[8] = { &vColor1, &vColor1, &vColor1, &vColor1, &vColor2, &vColor2, &vColor2, &vColor2 }; + + +#define DPTGLV_LINE_WRITEPOINT(index) fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vLinePoints[index].x, vLinePoints[index].y, vLinePoints[index].z, pLineColors[index]->x, pLineColors[index]->y, pLineColors[index]->z ); +#define DPTGLV_LINE_DOUBLESIDEDQUAD(index1,index2,index3,index4)\ + fprintf( pFile, "4\n" );\ + DPTGLV_LINE_WRITEPOINT(index1);\ + DPTGLV_LINE_WRITEPOINT(index2);\ + DPTGLV_LINE_WRITEPOINT(index3);\ + DPTGLV_LINE_WRITEPOINT(index4);\ + fprintf( pFile, "4\n" );\ + DPTGLV_LINE_WRITEPOINT(index4);\ + DPTGLV_LINE_WRITEPOINT(index3);\ + DPTGLV_LINE_WRITEPOINT(index2);\ + DPTGLV_LINE_WRITEPOINT(index1); + + + DPTGLV_LINE_DOUBLESIDEDQUAD(0,4,6,2); + DPTGLV_LINE_DOUBLESIDEDQUAD(3,7,5,1); + DPTGLV_LINE_DOUBLESIDEDQUAD(1,5,4,0); + DPTGLV_LINE_DOUBLESIDEDQUAD(2,6,7,3); + DPTGLV_LINE_DOUBLESIDEDQUAD(0,2,3,1); + DPTGLV_LINE_DOUBLESIDEDQUAD(5,7,6,4); +#endif +} + +void DumpPolyhedronToGLView( const CPolyhedron *pPolyhedron, const char *pFilename, const VMatrix *pTransform ) +{ +#ifdef ENABLE_DEBUG_POLYHEDRON_DUMPS + if ( (pPolyhedron == NULL) || (pPolyhedron->iVertexCount == 0) ) + return; + + if( pTransform == NULL ) + pTransform = &s_matIdentity; + + printf("Writing %s...\n", pFilename ); + + FILE *pFile = fopen( pFilename, "ab" ); + + //randomizing an array of colors to help spot shared/unshared vertices + Vector *pColors = (Vector *)stackalloc( sizeof( Vector ) * pPolyhedron->iVertexCount ); + int counter; + for( counter = 0; counter != pPolyhedron->iVertexCount; ++counter ) + { + pColors[counter].Init( rand()/32768.0f, rand()/32768.0f, rand()/32768.0f ); + } + + Vector *pTransformedPoints = (Vector *)stackalloc( pPolyhedron->iVertexCount * sizeof( Vector ) ); + for ( counter = 0; counter != pPolyhedron->iVertexCount; ++counter ) + { + pTransformedPoints[counter] = (*pTransform) * pPolyhedron->pVertices[counter]; + } + + for ( counter = 0; counter != pPolyhedron->iPolygonCount; ++counter ) + { + fprintf( pFile, "%i\n", pPolyhedron->pPolygons[counter].iIndexCount ); + int counter2; + for( counter2 = 0; counter2 != pPolyhedron->pPolygons[counter].iIndexCount; ++counter2 ) + { + Polyhedron_IndexedLineReference_t *pLineReference = &pPolyhedron->pIndices[pPolyhedron->pPolygons[counter].iFirstIndex + counter2]; + + Vector *pVertex = &pTransformedPoints[pPolyhedron->pLines[pLineReference->iLineIndex].iPointIndices[pLineReference->iEndPointIndex]]; + Vector *pColor = &pColors[pPolyhedron->pLines[pLineReference->iLineIndex].iPointIndices[pLineReference->iEndPointIndex]]; + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n",pVertex->x, pVertex->y, pVertex->z, pColor->x, pColor->y, pColor->z ); + } + } + + for( counter = 0; counter != pPolyhedron->iLineCount; ++counter ) + { + const Vector vOne( 1.0f, 1.0f, 1.0f ); + DumpLineToGLView( pTransformedPoints[pPolyhedron->pLines[counter].iPointIndices[0]], vOne - pColors[pPolyhedron->pLines[counter].iPointIndices[0]], + pTransformedPoints[pPolyhedron->pLines[counter].iPointIndices[1]], vOne - pColors[pPolyhedron->pLines[counter].iPointIndices[1]], + 0.1f, pFile ); + } + + for( counter = 0; counter != pPolyhedron->iVertexCount; ++counter ) + { + const Vector vPointHalfSize(0.15f, 0.15f, 0.15f ); + DumpAABBToGLView( pTransformedPoints[counter], vPointHalfSize, pColors[counter], pFile ); + } + + fclose( pFile ); +#endif +} + + +void DumpPlaneToGlView( const float *pPlane, float fGrayScale, const char *pszFileName, const VMatrix *pTransform ) +{ +#ifdef ENABLE_DEBUG_POLYHEDRON_DUMPS + if( pTransform == NULL ) + pTransform = &s_matIdentity; + + FILE *pFile = fopen( pszFileName, "ab" ); + + //transform the plane + Vector vNormal = pTransform->ApplyRotation( *(Vector *)pPlane ); + float fDist = pPlane[3] * vNormal.NormalizeInPlace(); //possible scaling going on + fDist += vNormal.Dot( pTransform->GetTranslation() ); + + Vector vPlaneVerts[4]; + + PolyFromPlane( vPlaneVerts, vNormal, fDist, 100000.0f ); + + fprintf( pFile, "4\n" ); + + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vPlaneVerts[0].x, vPlaneVerts[0].y, vPlaneVerts[0].z, fGrayScale, fGrayScale, fGrayScale ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vPlaneVerts[1].x, vPlaneVerts[1].y, vPlaneVerts[1].z, fGrayScale, fGrayScale, fGrayScale ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vPlaneVerts[2].x, vPlaneVerts[2].y, vPlaneVerts[2].z, fGrayScale, fGrayScale, fGrayScale ); + fprintf( pFile, "%6.3f %6.3f %6.3f %.2f %.2f %.2f\n", vPlaneVerts[3].x, vPlaneVerts[3].y, vPlaneVerts[3].z, fGrayScale, fGrayScale, fGrayScale ); + + fclose( pFile ); +#endif +} +#endif + + diff --git a/sp/src/mathlib/powsse.cpp b/sp/src/mathlib/powsse.cpp new file mode 100644 index 00000000..b026c642 --- /dev/null +++ b/sp/src/mathlib/powsse.cpp @@ -0,0 +1,96 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=====================================================================================// + +#include "mathlib/ssemath.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + + +fltx4 Pow_FixedPoint_Exponent_SIMD( const fltx4 & x, int exponent) +{ + fltx4 rslt=Four_Ones; // x^0=1.0 + int xp=abs(exponent); + if (xp & 3) // fraction present? + { + fltx4 sq_rt=SqrtEstSIMD(x); + if (xp & 1) // .25? + rslt=SqrtEstSIMD(sq_rt); // x^.25 + if (xp & 2) + rslt=MulSIMD(rslt,sq_rt); + } + xp>>=2; // strip fraction + fltx4 curpower=x; // curpower iterates through x,x^2,x^4,x^8,x^16... + + while(1) + { + if (xp & 1) + rslt=MulSIMD(rslt,curpower); + xp>>=1; + if (xp) + curpower=MulSIMD(curpower,curpower); + else + break; + } + if (exponent<0) + return ReciprocalEstSaturateSIMD(rslt); // pow(x,-b)=1/pow(x,b) + else + return rslt; +} + + + + +/* + * (c) Ian Stephenson + * + * ian@dctsystems.co.uk + * + * Fast pow() reference implementation + */ + + +static float shift23=(1<<23); +static float OOshift23=1.0/(1<<23); + +float FastLog2(float i) +{ + float LogBodge=0.346607f; + float x; + float y; + x=*(int *)&i; + x*= OOshift23; //1/pow(2,23); + x=x-127; + + y=x-floorf(x); + y=(y-y*y)*LogBodge; + return x+y; +} +float FastPow2(float i) +{ + float PowBodge=0.33971f; + float x; + float y=i-floorf(i); + y=(y-y*y)*PowBodge; + + x=i+127-y; + x*= shift23; //pow(2,23); + *(int*)&x=(int)x; + return x; +} +float FastPow(float a, float b) +{ + if (a <= OOshift23) + { + return 0.0f; + } + return FastPow2(b*FastLog2(a)); +} +float FastPow10( float i ) +{ + return FastPow2( i * 3.321928f ); +} + diff --git a/sp/src/mathlib/quantize.cpp b/sp/src/mathlib/quantize.cpp new file mode 100644 index 00000000..e829d2d2 --- /dev/null +++ b/sp/src/mathlib/quantize.cpp @@ -0,0 +1,679 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef STDIO_H +#include +#endif + +#ifndef STRING_H +#include +#endif + +#ifndef QUANTIZE_H +#include +#endif + +#include +#include + +#include + +static int current_ndims; +static struct QuantizedValue *current_root; +static int current_ssize; + +static uint8 *current_weights; + +double SquaredError; + +#define SPLIT_THEN_SORT 1 + +#define SQ(x) ((x)*(x)) + +static struct QuantizedValue *AllocQValue(void) +{ + struct QuantizedValue *ret=new QuantizedValue; + ret->Samples=0; + ret->Children[0]=ret->Children[1]=0; + ret->NSamples=0; + + ret->ErrorMeasure=new double[current_ndims]; + ret->Mean=new uint8[current_ndims]; + ret->Mins=new uint8[current_ndims]; + ret->Maxs=new uint8[current_ndims]; + ret->Sums=new int [current_ndims]; + memset(ret->Sums,0,sizeof(int)*current_ndims); + ret->NQuant=0; + ret->sortdim=-1; + return ret; +} + +void FreeQuantization(struct QuantizedValue *t) +{ + if (t) + { + delete[] t->ErrorMeasure; + delete[] t->Mean; + delete[] t->Mins; + delete[] t->Maxs; + FreeQuantization(t->Children[0]); + FreeQuantization(t->Children[1]); + delete[] t->Sums; + delete[] t; + } +} + +static int QNumSort(void const *a, void const *b) +{ + int32 as=((struct Sample *) a)->QNum; + int32 bs=((struct Sample *) b)->QNum; + if (as==bs) return 0; + return (as>bs)?1:-1; +} + +#if SPLIT_THEN_SORT +#else +static int current_sort_dim; + +static int samplesort(void const *a, void const *b) +{ + uint8 as=((struct Sample *) a)->Value[current_sort_dim]; + uint8 bs=((struct Sample *) b)->Value[current_sort_dim]; + if (as==bs) return 0; + return (as>bs)?1:-1; +} +#endif + +static int sortlong(void const *a, void const *b) +{ + // treat the entire vector of values as a long integer for duplicate removal. + return memcmp(((struct Sample *) a)->Value, + ((struct Sample *) b)->Value,current_ndims); +} + + + +#define NEXTSAMPLE(s) ( (struct Sample *) (((uint8 *) s)+current_ssize)) +#define SAMPLE(s,i) NthSample(s,i,current_ndims) + +static void SetNDims(int n) +{ + current_ssize=sizeof(struct Sample)+(n-1); + current_ndims=n; +} + +int CompressSamples(struct Sample *s, int nsamples, int ndims) +{ + SetNDims(ndims); + qsort(s,nsamples,current_ssize,sortlong); + // now, they are all sorted by treating all dimensions as a large number. + // we may now remove duplicates. + struct Sample *src=s; + struct Sample *dst=s; + struct Sample *lastdst=dst; + dst=NEXTSAMPLE(dst); // copy first sample to get the ball rolling + src=NEXTSAMPLE(src); + int noutput=1; + while(--nsamples) // while some remain + { + if (memcmp(src->Value,lastdst->Value,current_ndims)) + { + // yikes, a difference has been found! + memcpy(dst,src,current_ssize); + lastdst=dst; + dst=NEXTSAMPLE(dst); + noutput++; + } + else + lastdst->Count++; + src=NEXTSAMPLE(src); + } + return noutput; +} + +void PrintSamples(struct Sample const *s, int nsamples, int ndims) +{ + SetNDims(ndims); + int cnt=0; + while(nsamples--) + { + printf("sample #%d, count=%d, values=\n { ",cnt++,s->Count); + for(int d=0;dValue[d]); + printf("}\n"); + s=NEXTSAMPLE(s); + } +} + +void PrintQTree(struct QuantizedValue const *p,int idlevel) +{ + int i; + + if (p) + { + for(i=0;iNSamples,p->value); + for(i=0;iMean[i]); + printf("}\n"); + for(i=0;iErrorMeasure[i]); + printf("}\n"); + for(i=0;iMins[i]); + printf("} Maxs={"); + for(i=0;iMaxs[i]); + printf("}\n"); + PrintQTree(p->Children[0],idlevel+2); + PrintQTree(p->Children[1],idlevel+2); + } +} + +static void UpdateStats(struct QuantizedValue *v) +{ + // first, find mean + int32 Means[MAXDIMS]; + double Errors[MAXDIMS]; + double WorstError[MAXDIMS]; + int i,j; + + memset(Means,0,sizeof(Means)); + int N=0; + for(i=0;iNSamples;i++) + { + struct Sample *s=SAMPLE(v->Samples,i); + N+=s->Count; + for(j=0;jValue[j]; + Means[j]+=v*s->Count; + } + } + for(j=0;jMean[j]=(uint8) (Means[j]/N); + Errors[j]=WorstError[j]=0.; + } + for(i=0;iNSamples;i++) + { + struct Sample *s=SAMPLE(v->Samples,i); + double c=s->Count; + for(j=0;jValue[j]-v->Mean[j]); + Errors[j]+=c*diff; // charles uses abs not sq() + if (diff>WorstError[j]) + WorstError[j]=diff; + } + } + v->TotalError=0.; + double ErrorScale=1.; // /sqrt((double) (N)); + for(j=0;jErrorMeasure[j]=(ErrorScale*Errors[j]*current_weights[j]); + v->TotalError+=v->ErrorMeasure[j]; +#if SPLIT_THEN_SORT + v->ErrorMeasure[j]*=WorstError[j]; +#endif + } + v->TotSamples=N; +} + +static int ErrorDim; +static double ErrorVal; +static struct QuantizedValue *ErrorNode; + +static void UpdateWorst(struct QuantizedValue *q) +{ + if (q->Children[0]) + { + // not a leaf node + UpdateWorst(q->Children[0]); + UpdateWorst(q->Children[1]); + } + else + { + if (q->TotalError>ErrorVal) + { + ErrorVal=q->TotalError; + ErrorNode=q; + ErrorDim=0; + for(int d=0;dErrorMeasure[d]>q->ErrorMeasure[ErrorDim]) + ErrorDim=d; + } + } +} + +static int FindWorst(void) +{ + ErrorVal=-1.; + UpdateWorst(current_root); + return (ErrorVal>0); +} + + + +static void SubdivideNode(struct QuantizedValue *n, int whichdim) +{ + int NAdded=0; + int i; + +#if SPLIT_THEN_SORT + // we will try the "split then sort" method. This works by finding the + // means for all samples above and below the mean along the given axis. + // samples are then split into two groups, with the selection based upon + // which of the n-dimensional means the sample is closest to. + double LocalMean[MAXDIMS][2]; + int totsamps[2]; + for(i=0;iNSamples;i++) + { + uint8 v; + int whichside=1; + struct Sample *sl; + sl=SAMPLE(n->Samples,i); + v=sl->Value[whichdim]; + if (vmaxv) { maxv=v; maxS=sl; } + if (vMean[whichdim]) + whichside=0; + totsamps[whichside]+=sl->Count; + for(int d=0;dCount*sl->Value[d]; + } + + if (totsamps[0] && totsamps[1]) + for(i=0;iValue[i]; + LocalMean[i][1]=maxS->Value[i]; + } + } + + // now, we have 2 n-dimensional means. We will label each sample + // for which one it is nearer to by using the QNum field. + for(i=0;iNSamples;i++) + { + double dist[2]; + dist[0]=dist[1]=0.; + struct Sample *s=SAMPLE(n->Samples,i); + for(int d=0;dValue[d]); + s->QNum=(dist[0]sortdim=-1; + qsort(n->Samples,n->NSamples,current_ssize,QNumSort); + for(i=0;iNSamples;i++,NAdded++) + if (SAMPLE(n->Samples,i)->QNum) + break; + +#else + if (whichdim != n->sortdim) + { + current_sort_dim=whichdim; + qsort(n->Samples,n->NSamples,current_ssize,samplesort); + n->sortdim=whichdim; + } + // now, the samples are sorted along the proper dimension. we need + // to find the place to cut in order to split the node. this is + // complicated by the fact that each sample entry can represent many + // samples. What we will do is start at the beginning of the array, + // adding samples to the first node, until either the number added + // is >=TotSamples/2, or there is only one left. + int TotAdded=0; + for(;;) + { + if (NAdded==n->NSamples-1) + break; + if (TotAdded>=n->TotSamples/2) + break; + TotAdded+=SAMPLE(n->Samples,NAdded)->Count; + NAdded++; + } +#endif + struct QuantizedValue *a=AllocQValue(); + a->sortdim=n->sortdim; + a->Samples=n->Samples; + a->NSamples=NAdded; + n->Children[0]=a; + UpdateStats(a); + a=AllocQValue(); + a->Samples=SAMPLE(n->Samples,NAdded); + a->NSamples=n->NSamples-NAdded; + a->sortdim=n->sortdim; + n->Children[1]=a; + UpdateStats(a); +} + +static int colorid=0; + +static void Label(struct QuantizedValue *q, int updatecolor) +{ + // fill in max/min values for tree, etc. + if (q) + { + Label(q->Children[0],updatecolor); + Label(q->Children[1],updatecolor); + if (! q->Children[0]) // leaf node? + { + if (updatecolor) + { + q->value=colorid++; + for(int j=0;jNSamples;j++) + { + SAMPLE(q->Samples,j)->QNum=q->value; + SAMPLE(q->Samples,j)->qptr=q; + } + } + for(int i=0;iMins[i]=q->Mean[i]; + q->Maxs[i]=q->Mean[i]; + } + } + else + for(int i=0;iMins[i]=min(q->Children[0]->Mins[i],q->Children[1]->Mins[i]); + q->Maxs[i]=max(q->Children[0]->Maxs[i],q->Children[1]->Maxs[i]); + } + } +} + +struct QuantizedValue *FindQNode(struct QuantizedValue const *q, int32 code) +{ + if (! (q->Children[0])) + if (code==q->value) return (struct QuantizedValue *) q; + else return 0; + else + { + struct QuantizedValue *found=FindQNode(q->Children[0],code); + if (! found) found=FindQNode(q->Children[1],code); + return found; + } +} + + +void CheckInRange(struct QuantizedValue *q, uint8 *max, uint8 *min) +{ + if (q) + { + if (q->Children[0]) + { + // non-leaf node + CheckInRange(q->Children[0],q->Maxs, q->Mins); + CheckInRange(q->Children[1],q->Maxs, q->Mins); + CheckInRange(q->Children[0],max, min); + CheckInRange(q->Children[1],max, min); + } + for (int i=0;iMaxs[i]>max[i]) printf("error1\n"); + if (q->Mins[i]Samples=s; + current_root->NSamples=nsamples; + UpdateStats(current_root); + while(--nvalues) + { + if (! FindWorst()) + break; // if Mins[i]<=val2) && (q->Maxs[i]>=val2)) val1=val2; + else + { + val1=(val2<=q->Mins[i])?q->Mins[i]:q->Maxs[i]; + } + err+=weights[i]*SQ(val1-val2); + } + return err; +} + +double MaximumError(struct QuantizedValue const *q, uint8 const *sample, + int ndims, uint8 const *weights) +{ + double err=0; + for(int i=0;iMins[i])>abs(val2-q->Maxs[i]))? + q->Mins[i]: + q->Maxs[i]; + err+=weights[i]*SQ(val2-val1); + } + return err; +} + + + +// heap (priority queue) routines used for nearest-neghbor searches +struct FHeap { + int heap_n; + double *heap[MAXQUANT]; +}; + +void InitHeap(struct FHeap *h) +{ + h->heap_n=0; +} + + +void UpHeap(int k, struct FHeap *h) +{ + double *tmpk=h->heap[k]; + double tmpkn=*tmpk; + while((k>1) && (tmpkn <= *(h->heap[k/2]))) + { + h->heap[k]=h->heap[k/2]; + k/=2; + } + h->heap[k]=tmpk; +} + +void HeapInsert(struct FHeap *h,double *elem) +{ + h->heap_n++; + h->heap[h->heap_n]=elem; + UpHeap(h->heap_n,h); +} + +void DownHeap(int k, struct FHeap *h) +{ + double *v=h->heap[k]; + while(k<=h->heap_n/2) + { + int j=2*k; + if (jheap_n) + if (*(h->heap[j]) >= *(h->heap[j+1])) + j++; + if (*v < *(h->heap[j])) + { + h->heap[k]=v; + return; + } + h->heap[k]=h->heap[j]; k=j; + } + h->heap[k]=v; +} + +void *RemoveHeapItem(struct FHeap *h) +{ + void *ret=0; + if (h->heap_n!=0) + { + ret=h->heap[1]; + h->heap[1]=h->heap[h->heap_n]; + h->heap_n--; + DownHeap(1,h); + } + return ret; +} + +// now, nearest neighbor finder. Use a heap to traverse the tree, stopping +// when there are no nodes with a minimum error < the current error. + +struct FHeap TheQueue; + +#define PUSHNODE(a) { \ + (a)->MinError=MinimumError(a,sample,ndims,weights); \ + if ((a)->MinError < besterror) HeapInsert(&TheQueue,&(a)->MinError); \ + } + +struct QuantizedValue *FindMatch(uint8 const *sample, int ndims, + uint8 *weights, struct QuantizedValue *q) +{ + InitHeap(&TheQueue); + struct QuantizedValue *bestmatch=0; + double besterror=1.0e63; + PUSHNODE(q); + for(;;) + { + struct QuantizedValue *test=(struct QuantizedValue *) + RemoveHeapItem(&TheQueue); + if (! test) break; // heap empty +// printf("got pop node =%p minerror=%f\n",test,test->MinError); + + if (test->MinError>besterror) break; + if (test->Children[0]) + { + // it's a parent node. put the children on the queue + struct QuantizedValue *c1=test->Children[0]; + struct QuantizedValue *c2=test->Children[1]; + c1->MinError=MinimumError(c1,sample,ndims,weights); + if (c1->MinError < besterror) + HeapInsert(&TheQueue,&(c1->MinError)); + c2->MinError=MinimumError(c2,sample,ndims,weights); + if (c2->MinError < besterror) + HeapInsert(&TheQueue,&(c2->MinError)); + } + else + { + // it's a leaf node. This must be a new minimum or the MinError + // test would have failed. + if (test->MinError < besterror) + { + bestmatch=test; + besterror=test->MinError; + } + } + } + if (bestmatch) + { + SquaredError+=besterror; + bestmatch->NQuant++; + for(int i=0;iSums[i]+=sample[i]; + } + return bestmatch; +} + +static void RecalcMeans(struct QuantizedValue *q) +{ + if (q) + { + if (q->Children[0]) + { + // not a leaf, invoke recursively. + RecalcMeans(q->Children[0]); + RecalcMeans(q->Children[0]); + } + else + { + // it's a leaf. Set the means + if (q->NQuant) + { + for(int i=0;iMean[i]=(uint8) (q->Sums[i]/q->NQuant); + q->Sums[i]=0; + } + q->NQuant=0; + } + } + } +} + +void OptimizeQuantizer(struct QuantizedValue *q, int ndims) +{ + SetNDims(ndims); + RecalcMeans(q); // reset q values + Label(q,0); // update max/mins +} + + +static void RecalcStats(struct QuantizedValue *q) +{ + if (q) + { + UpdateStats(q); + RecalcStats(q->Children[0]); + RecalcStats(q->Children[1]); + } +} + +void RecalculateValues(struct QuantizedValue *q, int ndims) +{ + SetNDims(ndims); + RecalcStats(q); + Label(q,0); +} diff --git a/sp/src/mathlib/randsse.cpp b/sp/src/mathlib/randsse.cpp new file mode 100644 index 00000000..b718d399 --- /dev/null +++ b/sp/src/mathlib/randsse.cpp @@ -0,0 +1,109 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: generates 4 randum numbers in the range 0..1 quickly, using SIMD +// +//=====================================================================================// + +#include +#include // Needed for FLT_EPSILON +#include "basetypes.h" +#include +#include "tier0/dbg.h" +#include "mathlib/mathlib.h" +#include "mathlib/vector.h" +#include "mathlib/ssemath.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// see knuth volume 3 for insight. + +class SIMDRandStreamContext +{ + fltx4 m_RandY[55]; + + fltx4 *m_pRand_J, *m_pRand_K; + + +public: + void Seed( uint32 seed ) + { + m_pRand_J=m_RandY+23; m_pRand_K=m_RandY+54; + for(int i=0;i<55;i++) + { + for(int j=0;j<4;j++) + { + SubFloat( m_RandY[i], j) = (seed>>16)/65536.0; + seed=(seed+1)*3141592621u; + } + } + } + + inline fltx4 RandSIMD( void ) + { + // ret= rand[k]+rand[j] + fltx4 retval=AddSIMD( *m_pRand_K, *m_pRand_J ); + + // if ( ret>=1.0) ret-=1.0 + fltx4 overflow_mask=CmpGeSIMD( retval, Four_Ones ); + retval=SubSIMD( retval, AndSIMD( Four_Ones, overflow_mask ) ); + + *m_pRand_K = retval; + + // update pointers w/ wrap-around + if ( --m_pRand_J < m_RandY ) + m_pRand_J=m_RandY+54; + if ( --m_pRand_K < m_RandY ) + m_pRand_K=m_RandY+54; + + return retval; + } +}; + +#define MAX_SIMULTANEOUS_RANDOM_STREAMS 32 + +static SIMDRandStreamContext s_SIMDRandContexts[MAX_SIMULTANEOUS_RANDOM_STREAMS]; + +static volatile int s_nRandContextsInUse[MAX_SIMULTANEOUS_RANDOM_STREAMS]; + +void SeedRandSIMD(uint32 seed) +{ + for( int i = 0; i> 2); + int ntrailing_pixels_per_source_line=(srcwidth & 3); + for(int y=0;y( p_write_ptr ); + // copy full input blocks + for(int x=0;xx=Pow_FixedPoint_Exponent_SIMD( src->x, fixed_point_exp ); + src->y=Pow_FixedPoint_Exponent_SIMD( src->y, fixed_point_exp ); + src->z=Pow_FixedPoint_Exponent_SIMD( src->z, fixed_point_exp ); + src++; + } while (--nv); + } +} + +CSIMDVectorMatrix & CSIMDVectorMatrix::operator+=( CSIMDVectorMatrix const &src ) +{ + Assert( m_nWidth == src.m_nWidth ); + Assert( m_nHeight == src.m_nHeight ); + int nv=NVectors(); + if ( nv ) + { + FourVectors *srcv=src.m_pData; + FourVectors *destv=m_pData; + do // !! speed !! inline more iters + { + *( destv++ ) += *( srcv++ ); + } while ( --nv ); + } + return *this; +} + +CSIMDVectorMatrix & CSIMDVectorMatrix::operator*=( Vector const &src ) +{ + int nv=NVectors(); + if ( nv ) + { + FourVectors scalevalue; + scalevalue.DuplicateVector( src ); + FourVectors *destv=m_pData; + do // !! speed !! inline more iters + { + destv->VProduct( scalevalue ); + destv++; + } while ( --nv ); + } + return *this; +} + diff --git a/sp/src/mathlib/sparse_convolution_noise.cpp b/sp/src/mathlib/sparse_convolution_noise.cpp new file mode 100644 index 00000000..dbf19b60 --- /dev/null +++ b/sp/src/mathlib/sparse_convolution_noise.cpp @@ -0,0 +1,218 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: noise() primitives. +// +//=====================================================================================// + +#include +#include "basetypes.h" +#include +#include "tier0/dbg.h" +#include "mathlib/mathlib.h" +#include "mathlib/vector.h" +#include "mathlib/noise.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// generate high quality noise based upon "sparse convolution". HIgher quality than perlin noise, +// and no direcitonal artifacts. + +#include "noisedata.h" + +#define N_IMPULSES_PER_CELL 5 +#define NORMALIZING_FACTOR 1.0 + +//(0.5/N_IMPULSES_PER_CELL) + +static inline int LatticeCoord(float x) +{ + return ((int) floor(x)) & 0xff; +} + +static inline int Hash4D(int ix, int iy, int iz, int idx) +{ + int ret=perm_a[ix]; + ret=perm_b[(ret+iy) & 0xff]; + ret=perm_c[(ret+iz) & 0xff]; + ret=perm_d[(ret+idx) & 0xff]; + return ret; +} + +#define SQ(x) ((x)*(x)) + +static float CellNoise( int ix, int iy, int iz, float xfrac, float yfrac, float zfrac, + float (*pNoiseShapeFunction)(float) ) +{ + float ret=0; + for(int idx=0;idx +#include // Needed for FLT_EPSILON +#include "basetypes.h" +#include +#include "tier0/dbg.h" +#include "mathlib/mathlib.h" +#include "mathlib/vector.h" +#include "mathlib/spherical_geometry.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +float s_flFactorials[]={ + 1., + 1., + 2., + 6., + 24., + 120., + 720., + 5040., + 40320., + 362880., + 3628800., + 39916800., + 479001600., + 6227020800., + 87178291200., + 1307674368000., + 20922789888000., + 355687428096000., + 6402373705728000., + 121645100408832000., + 2432902008176640000., + 51090942171709440000., + 1124000727777607680000., + 25852016738884976640000., + 620448401733239439360000., + 15511210043330985984000000., + 403291461126605635584000000., + 10888869450418352160768000000., + 304888344611713860501504000000., + 8841761993739701954543616000000., + 265252859812191058636308480000000., + 8222838654177922817725562880000000., + 263130836933693530167218012160000000., + 8683317618811886495518194401280000000. +}; + +float AssociatedLegendrePolynomial( int nL, int nM, float flX ) +{ + // evaluate associated legendre polynomial at flX, using recurrence relation + float flPmm = 1.; + if ( nM > 0 ) + { + float flSomX2 = sqrt( ( 1 - flX ) * ( 1 + flX ) ); + float flFact = 1.; + for( int i = 0 ; i < nM; i++ ) + { + flPmm *= -flFact * flSomX2; + flFact += 2.0; + } + } + if ( nL == nM ) + return flPmm; + float flPmmp1 = flX * ( 2.0 * nM + 1.0 ) * flPmm; + if ( nL == nM + 1 ) + return flPmmp1; + float flPll = 0.; + for( int nLL = nM + 2 ; nLL <= nL; nLL++ ) + { + flPll = ( ( 2.0 * nLL - 1.0 ) * flX * flPmmp1 - ( nLL + nM - 1.0 ) * flPmm ) * ( 1.0 / ( nLL - nM ) ); + flPmm = flPmmp1; + flPmmp1 = flPll; + } + return flPll; +} + +static float SHNormalizationFactor( int nL, int nM ) +{ + double flTemp = ( ( 2. * nL + 1.0 ) * s_flFactorials[ nL - nM ] )/ ( 4. * M_PI * s_flFactorials[ nL + nM ] ); + return sqrt( flTemp ); +} + +#define SQRT_2 1.414213562373095 + +FORCEINLINE float SphericalHarmonic( int nL, int nM, float flTheta, float flPhi, float flCosTheta ) +{ + if ( nM == 0 ) + return SHNormalizationFactor( nL, 0 ) * AssociatedLegendrePolynomial( nL, nM, flCosTheta ); + + if ( nM > 0 ) + return SQRT_2 * SHNormalizationFactor( nL, nM ) * cos ( nM * flPhi ) * + AssociatedLegendrePolynomial( nL, nM, flCosTheta ); + + return + SQRT_2 * SHNormalizationFactor( nL, -nM ) * sin( -nM * flPhi ) * AssociatedLegendrePolynomial( nL, -nM, flCosTheta ); + +} + +float SphericalHarmonic( int nL, int nM, float flTheta, float flPhi ) +{ + return SphericalHarmonic( nL, nM, flTheta, flPhi, cos( flTheta ) ); +} + +float SphericalHarmonic( int nL, int nM, Vector const &vecDirection ) +{ + Assert( fabs( VectorLength( vecDirection ) - 1.0 ) < 0.0001 ); + float flPhi = acos( vecDirection.z ); + float flTheta = 0; + float S = Square( vecDirection.x ) + Square( vecDirection.y ); + if ( S > 0 ) + { + flTheta = atan2( vecDirection.y, vecDirection.x ); + } + return SphericalHarmonic( nL, nM, flTheta, flPhi, cos( flTheta ) ); +} + diff --git a/sp/src/mathlib/sse.cpp b/sp/src/mathlib/sse.cpp new file mode 100644 index 00000000..2260550b --- /dev/null +++ b/sp/src/mathlib/sse.cpp @@ -0,0 +1,1097 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: SSE Math primitives. +// +//=====================================================================================// + +#include +#include // Needed for FLT_EPSILON +#include "basetypes.h" +#include +#include "tier0/dbg.h" +#include "mathlib/mathlib.h" +#include "mathlib/vector.h" +#include "sse.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#ifndef COMPILER_MSVC64 +// Implement for 64-bit Windows if needed. + +static const uint32 _sincos_masks[] = { (uint32)0x0, (uint32)~0x0 }; +static const uint32 _sincos_inv_masks[] = { (uint32)~0x0, (uint32)0x0 }; + +//----------------------------------------------------------------------------- +// Macros and constants required by some of the SSE assembly: +//----------------------------------------------------------------------------- + +#ifdef _WIN32 + #define _PS_EXTERN_CONST(Name, Val) \ + const __declspec(align(16)) float _ps_##Name[4] = { Val, Val, Val, Val } + + #define _PS_EXTERN_CONST_TYPE(Name, Type, Val) \ + const __declspec(align(16)) Type _ps_##Name[4] = { Val, Val, Val, Val }; \ + + #define _EPI32_CONST(Name, Val) \ + static const __declspec(align(16)) __int32 _epi32_##Name[4] = { Val, Val, Val, Val } + + #define _PS_CONST(Name, Val) \ + static const __declspec(align(16)) float _ps_##Name[4] = { Val, Val, Val, Val } +#elif POSIX + #define _PS_EXTERN_CONST(Name, Val) \ + const float _ps_##Name[4] __attribute__((aligned(16))) = { Val, Val, Val, Val } + + #define _PS_EXTERN_CONST_TYPE(Name, Type, Val) \ + const Type _ps_##Name[4] __attribute__((aligned(16))) = { Val, Val, Val, Val }; \ + + #define _EPI32_CONST(Name, Val) \ + static const int32 _epi32_##Name[4] __attribute__((aligned(16))) = { Val, Val, Val, Val } + + #define _PS_CONST(Name, Val) \ + static const float _ps_##Name[4] __attribute__((aligned(16))) = { Val, Val, Val, Val } +#endif + +_PS_EXTERN_CONST(am_0, 0.0f); +_PS_EXTERN_CONST(am_1, 1.0f); +_PS_EXTERN_CONST(am_m1, -1.0f); +_PS_EXTERN_CONST(am_0p5, 0.5f); +_PS_EXTERN_CONST(am_1p5, 1.5f); +_PS_EXTERN_CONST(am_pi, (float)M_PI); +_PS_EXTERN_CONST(am_pi_o_2, (float)(M_PI / 2.0)); +_PS_EXTERN_CONST(am_2_o_pi, (float)(2.0 / M_PI)); +_PS_EXTERN_CONST(am_pi_o_4, (float)(M_PI / 4.0)); +_PS_EXTERN_CONST(am_4_o_pi, (float)(4.0 / M_PI)); +_PS_EXTERN_CONST_TYPE(am_sign_mask, int32, 0x80000000); +_PS_EXTERN_CONST_TYPE(am_inv_sign_mask, int32, ~0x80000000); +_PS_EXTERN_CONST_TYPE(am_min_norm_pos,int32, 0x00800000); +_PS_EXTERN_CONST_TYPE(am_mant_mask, int32, 0x7f800000); +_PS_EXTERN_CONST_TYPE(am_inv_mant_mask, int32, ~0x7f800000); + +_EPI32_CONST(1, 1); +_EPI32_CONST(2, 2); + +_PS_CONST(sincos_p0, 0.15707963267948963959e1f); +_PS_CONST(sincos_p1, -0.64596409750621907082e0f); +_PS_CONST(sincos_p2, 0.7969262624561800806e-1f); +_PS_CONST(sincos_p3, -0.468175413106023168e-2f); + +#ifdef PFN_VECTORMA +void __cdecl _SSE_VectorMA( const float *start, float scale, const float *direction, float *dest ); +#endif + +//----------------------------------------------------------------------------- +// SSE implementations of optimized routines: +//----------------------------------------------------------------------------- +float _SSE_Sqrt(float x) +{ + Assert( s_bMathlibInitialized ); + float root = 0.f; +#ifdef _WIN32 + _asm + { + sqrtss xmm0, x + movss root, xmm0 + } +#elif POSIX + _mm_store_ss( &root, _mm_sqrt_ss( _mm_load_ss( &x ) ) ); +#endif + return root; +} + +// Single iteration NewtonRaphson reciprocal square root: +// 0.5 * rsqrtps * (3 - x * rsqrtps(x) * rsqrtps(x)) +// Very low error, and fine to use in place of 1.f / sqrtf(x). +#if 0 +float _SSE_RSqrtAccurate(float x) +{ + Assert( s_bMathlibInitialized ); + + float rroot; + _asm + { + rsqrtss xmm0, x + movss rroot, xmm0 + } + + return (0.5f * rroot) * (3.f - (x * rroot) * rroot); +} +#else + +#ifdef POSIX +const __m128 f3 = _mm_set_ss(3.0f); // 3 as SSE value +const __m128 f05 = _mm_set_ss(0.5f); // 0.5 as SSE value +#endif + +// Intel / Kipps SSE RSqrt. Significantly faster than above. +float _SSE_RSqrtAccurate(float a) +{ + +#ifdef _WIN32 + float x; + float half = 0.5f; + float three = 3.f; + + __asm + { + movss xmm3, a; + movss xmm1, half; + movss xmm2, three; + rsqrtss xmm0, xmm3; + + mulss xmm3, xmm0; + mulss xmm1, xmm0; + mulss xmm3, xmm0; + subss xmm2, xmm3; + mulss xmm1, xmm2; + + movss x, xmm1; + } + + return x; +#elif POSIX + __m128 xx = _mm_load_ss( &a ); + __m128 xr = _mm_rsqrt_ss( xx ); + __m128 xt; + + xt = _mm_mul_ss( xr, xr ); + xt = _mm_mul_ss( xt, xx ); + xt = _mm_sub_ss( f3, xt ); + xt = _mm_mul_ss( xt, f05 ); + xr = _mm_mul_ss( xr, xt ); + + _mm_store_ss( &a, xr ); + return a; +#else + #error "Not Implemented" +#endif + +} +#endif + +// Simple SSE rsqrt. Usually accurate to around 6 (relative) decimal places +// or so, so ok for closed transforms. (ie, computing lighting normals) +float _SSE_RSqrtFast(float x) +{ + Assert( s_bMathlibInitialized ); + + float rroot; +#ifdef _WIN32 + _asm + { + rsqrtss xmm0, x + movss rroot, xmm0 + } +#elif POSIX + __asm__ __volatile__( "rsqrtss %0, %1" : "=x" (rroot) : "x" (x) ); +#else +#error +#endif + + return rroot; +} + +float FASTCALL _SSE_VectorNormalize (Vector& vec) +{ + Assert( s_bMathlibInitialized ); + + // NOTE: This is necessary to prevent an memory overwrite... + // sice vec only has 3 floats, we can't "movaps" directly into it. +#ifdef _WIN32 + __declspec(align(16)) float result[4]; +#elif POSIX + float result[4] __attribute__((aligned(16))); +#endif + + float *v = &vec[0]; + float *r = &result[0]; + + float radius = 0.f; + // Blah, get rid of these comparisons ... in reality, if you have all 3 as zero, it shouldn't + // be much of a performance win, considering you will very likely miss 3 branch predicts in a row. + if ( v[0] || v[1] || v[2] ) + { +#ifdef _WIN32 + _asm + { + mov eax, v + mov edx, r +#ifdef ALIGNED_VECTOR + movaps xmm4, [eax] // r4 = vx, vy, vz, X + movaps xmm1, xmm4 // r1 = r4 +#else + movups xmm4, [eax] // r4 = vx, vy, vz, X + movaps xmm1, xmm4 // r1 = r4 +#endif + mulps xmm1, xmm4 // r1 = vx * vx, vy * vy, vz * vz, X + movhlps xmm3, xmm1 // r3 = vz * vz, X, X, X + movaps xmm2, xmm1 // r2 = r1 + shufps xmm2, xmm2, 1 // r2 = vy * vy, X, X, X + addss xmm1, xmm2 // r1 = (vx * vx) + (vy * vy), X, X, X + addss xmm1, xmm3 // r1 = (vx * vx) + (vy * vy) + (vz * vz), X, X, X + sqrtss xmm1, xmm1 // r1 = sqrt((vx * vx) + (vy * vy) + (vz * vz)), X, X, X + movss radius, xmm1 // radius = sqrt((vx * vx) + (vy * vy) + (vz * vz)) + rcpss xmm1, xmm1 // r1 = 1/radius, X, X, X + shufps xmm1, xmm1, 0 // r1 = 1/radius, 1/radius, 1/radius, X + mulps xmm4, xmm1 // r4 = vx * 1/radius, vy * 1/radius, vz * 1/radius, X + movaps [edx], xmm4 // v = vx * 1/radius, vy * 1/radius, vz * 1/radius, X + } +#elif POSIX + __asm__ __volatile__( +#ifdef ALIGNED_VECTOR + "movaps %2, %%xmm4 \n\t" + "movaps %%xmm4, %%xmm1 \n\t" +#else + "movups %2, %%xmm4 \n\t" + "movaps %%xmm4, %%xmm1 \n\t" +#endif + "mulps %%xmm4, %%xmm1 \n\t" + "movhlps %%xmm1, %%xmm3 \n\t" + "movaps %%xmm1, %%xmm2 \n\t" + "shufps $1, %%xmm2, %%xmm2 \n\t" + "addss %%xmm2, %%xmm1 \n\t" + "addss %%xmm3, %%xmm1 \n\t" + "sqrtss %%xmm1, %%xmm1 \n\t" + "movss %%xmm1, %0 \n\t" + "rcpss %%xmm1, %%xmm1 \n\t" + "shufps $0, %%xmm1, %%xmm1 \n\t" + "mulps %%xmm1, %%xmm4 \n\t" + "movaps %%xmm4, %1 \n\t" + : "=m" (radius), "=m" (result) + : "m" (*v) + : "xmm1", "xmm2", "xmm3", "xmm4" + ); +#else + #error "Not Implemented" +#endif + vec.x = result[0]; + vec.y = result[1]; + vec.z = result[2]; + + } + + return radius; +} + +void FASTCALL _SSE_VectorNormalizeFast (Vector& vec) +{ + float ool = _SSE_RSqrtAccurate( FLT_EPSILON + vec.x * vec.x + vec.y * vec.y + vec.z * vec.z ); + + vec.x *= ool; + vec.y *= ool; + vec.z *= ool; +} + +float _SSE_InvRSquared(const float* v) +{ + float inv_r2 = 1.f; +#ifdef _WIN32 + _asm { // Intel SSE only routine + mov eax, v + movss xmm5, inv_r2 // x5 = 1.0, 0, 0, 0 +#ifdef ALIGNED_VECTOR + movaps xmm4, [eax] // x4 = vx, vy, vz, X +#else + movups xmm4, [eax] // x4 = vx, vy, vz, X +#endif + movaps xmm1, xmm4 // x1 = x4 + mulps xmm1, xmm4 // x1 = vx * vx, vy * vy, vz * vz, X + movhlps xmm3, xmm1 // x3 = vz * vz, X, X, X + movaps xmm2, xmm1 // x2 = x1 + shufps xmm2, xmm2, 1 // x2 = vy * vy, X, X, X + addss xmm1, xmm2 // x1 = (vx * vx) + (vy * vy), X, X, X + addss xmm1, xmm3 // x1 = (vx * vx) + (vy * vy) + (vz * vz), X, X, X + maxss xmm1, xmm5 // x1 = max( 1.0, x1 ) + rcpss xmm0, xmm1 // x0 = 1 / max( 1.0, x1 ) + movss inv_r2, xmm0 // inv_r2 = x0 + } +#elif POSIX + __asm__ __volatile__( + "movss %0, %%xmm5 \n\t" +#ifdef ALIGNED_VECTOR + "movaps %1, %%xmm4 \n\t" +#else + "movups %1, %%xmm4 \n\t" +#endif + "movaps %%xmm4, %%xmm1 \n\t" + "mulps %%xmm4, %%xmm1 \n\t" + "movhlps %%xmm1, %%xmm3 \n\t" + "movaps %%xmm1, %%xmm2 \n\t" + "shufps $1, %%xmm2, %%xmm2 \n\t" + "addss %%xmm2, %%xmm1 \n\t" + "addss %%xmm3, %%xmm1 \n\t" + "maxss %%xmm5, %%xmm1 \n\t" + "rcpss %%xmm1, %%xmm0 \n\t" + "movss %%xmm0, %0 \n\t" + : "+m" (inv_r2) + : "m" (*v) + : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" + ); +#else + #error "Not Implemented" +#endif + + return inv_r2; +} + + +#ifdef POSIX +// #define _PS_CONST(Name, Val) static const ALIGN16 float _ps_##Name[4] ALIGN16_POST = { Val, Val, Val, Val } +#define _PS_CONST_TYPE(Name, Type, Val) static const ALIGN16 Type _ps_##Name[4] ALIGN16_POST = { Val, Val, Val, Val } + +_PS_CONST_TYPE(sign_mask, int, 0x80000000); +_PS_CONST_TYPE(inv_sign_mask, int, ~0x80000000); + + +#define _PI32_CONST(Name, Val) static const ALIGN16 int _pi32_##Name[4] ALIGN16_POST = { Val, Val, Val, Val } + +_PI32_CONST(1, 1); +_PI32_CONST(inv1, ~1); +_PI32_CONST(2, 2); +_PI32_CONST(4, 4); +_PI32_CONST(0x7f, 0x7f); +_PS_CONST(1 , 1.0f); +_PS_CONST(0p5, 0.5f); + +_PS_CONST(minus_cephes_DP1, -0.78515625); +_PS_CONST(minus_cephes_DP2, -2.4187564849853515625e-4); +_PS_CONST(minus_cephes_DP3, -3.77489497744594108e-8); +_PS_CONST(sincof_p0, -1.9515295891E-4); +_PS_CONST(sincof_p1, 8.3321608736E-3); +_PS_CONST(sincof_p2, -1.6666654611E-1); +_PS_CONST(coscof_p0, 2.443315711809948E-005); +_PS_CONST(coscof_p1, -1.388731625493765E-003); +_PS_CONST(coscof_p2, 4.166664568298827E-002); +_PS_CONST(cephes_FOPI, 1.27323954473516); // 4 / M_PI + +typedef union xmm_mm_union { + __m128 xmm; + __m64 mm[2]; +} xmm_mm_union; + +#define COPY_MM_TO_XMM(mm0_, mm1_, xmm_) { xmm_mm_union u; u.mm[0]=mm0_; u.mm[1]=mm1_; xmm_ = u.xmm; } + +typedef __m128 v4sf; // vector of 4 float (sse1) +typedef __m64 v2si; // vector of 2 int (mmx) + +#endif + +void _SSE_SinCos(float x, float* s, float* c) +{ +#ifdef _WIN32 + float t4, t8, t12; + + __asm + { + movss xmm0, x + movss t12, xmm0 + movss xmm1, _ps_am_inv_sign_mask + mov eax, t12 + mulss xmm0, _ps_am_2_o_pi + andps xmm0, xmm1 + and eax, 0x80000000 + + cvttss2si edx, xmm0 + mov ecx, edx + mov t12, esi + mov esi, edx + add edx, 0x1 + shl ecx, (31 - 1) + shl edx, (31 - 1) + + movss xmm4, _ps_am_1 + cvtsi2ss xmm3, esi + mov t8, eax + and esi, 0x1 + + subss xmm0, xmm3 + movss xmm3, _sincos_inv_masks[esi * 4] + minss xmm0, xmm4 + + subss xmm4, xmm0 + + movss xmm6, xmm4 + andps xmm4, xmm3 + and ecx, 0x80000000 + movss xmm2, xmm3 + andnps xmm3, xmm0 + and edx, 0x80000000 + movss xmm7, t8 + andps xmm0, xmm2 + mov t8, ecx + mov t4, edx + orps xmm4, xmm3 + + mov eax, s //mov eax, [esp + 4 + 16] + mov edx, c //mov edx, [esp + 4 + 16 + 4] + + andnps xmm2, xmm6 + orps xmm0, xmm2 + + movss xmm2, t8 + movss xmm1, xmm0 + movss xmm5, xmm4 + xorps xmm7, xmm2 + movss xmm3, _ps_sincos_p3 + mulss xmm0, xmm0 + mulss xmm4, xmm4 + movss xmm2, xmm0 + movss xmm6, xmm4 + orps xmm1, xmm7 + movss xmm7, _ps_sincos_p2 + mulss xmm0, xmm3 + mulss xmm4, xmm3 + movss xmm3, _ps_sincos_p1 + addss xmm0, xmm7 + addss xmm4, xmm7 + movss xmm7, _ps_sincos_p0 + mulss xmm0, xmm2 + mulss xmm4, xmm6 + addss xmm0, xmm3 + addss xmm4, xmm3 + movss xmm3, t4 + mulss xmm0, xmm2 + mulss xmm4, xmm6 + orps xmm5, xmm3 + mov esi, t12 + addss xmm0, xmm7 + addss xmm4, xmm7 + mulss xmm0, xmm1 + mulss xmm4, xmm5 + + // use full stores since caller might reload with full loads + movss [eax], xmm0 + movss [edx], xmm4 + } +#elif POSIX + + Assert( "Needs testing, verify impl!\n" ); + + v4sf xx = _mm_load_ss( &x ); + + v4sf xmm1, xmm2, xmm3 = _mm_setzero_ps(), sign_bit_sin, y; + v2si mm0, mm1, mm2, mm3, mm4, mm5; + sign_bit_sin = xx; + /* take the absolute value */ + xx = _mm_and_ps(xx, *(v4sf*)_ps_inv_sign_mask); + /* extract the sign bit (upper one) */ + sign_bit_sin = _mm_and_ps(sign_bit_sin, *(v4sf*)_ps_sign_mask); + + /* scale by 4/Pi */ + y = _mm_mul_ps(xx, *(v4sf*)_ps_cephes_FOPI); + + /* store the integer part of y in mm2:mm3 */ + xmm3 = _mm_movehl_ps(xmm3, y); + mm2 = _mm_cvttps_pi32(y); + mm3 = _mm_cvttps_pi32(xmm3); + + /* j=(j+1) & (~1) (see the cephes sources) */ + mm2 = _mm_add_pi32(mm2, *(v2si*)_pi32_1); + mm3 = _mm_add_pi32(mm3, *(v2si*)_pi32_1); + mm2 = _mm_and_si64(mm2, *(v2si*)_pi32_inv1); + mm3 = _mm_and_si64(mm3, *(v2si*)_pi32_inv1); + + y = _mm_cvtpi32x2_ps(mm2, mm3); + + mm4 = mm2; + mm5 = mm3; + + /* get the swap sign flag for the sine */ + mm0 = _mm_and_si64(mm2, *(v2si*)_pi32_4); + mm1 = _mm_and_si64(mm3, *(v2si*)_pi32_4); + mm0 = _mm_slli_pi32(mm0, 29); + mm1 = _mm_slli_pi32(mm1, 29); + v4sf swap_sign_bit_sin; + COPY_MM_TO_XMM(mm0, mm1, swap_sign_bit_sin); + + /* get the polynom selection mask for the sine */ + + mm2 = _mm_and_si64(mm2, *(v2si*)_pi32_2); + mm3 = _mm_and_si64(mm3, *(v2si*)_pi32_2); + mm2 = _mm_cmpeq_pi32(mm2, _mm_setzero_si64()); + mm3 = _mm_cmpeq_pi32(mm3, _mm_setzero_si64()); + v4sf poly_mask; + COPY_MM_TO_XMM(mm2, mm3, poly_mask); + + /* The magic pass: "Extended precision modular arithmetic" + x = ((x - y * DP1) - y * DP2) - y * DP3; */ + xmm1 = *(v4sf*)_ps_minus_cephes_DP1; + xmm2 = *(v4sf*)_ps_minus_cephes_DP2; + xmm3 = *(v4sf*)_ps_minus_cephes_DP3; + xmm1 = _mm_mul_ps(y, xmm1); + xmm2 = _mm_mul_ps(y, xmm2); + xmm3 = _mm_mul_ps(y, xmm3); + xx = _mm_add_ps(xx, xmm1); + xx = _mm_add_ps(xx, xmm2); + xx = _mm_add_ps(xx, xmm3); + + /* get the sign flag for the cosine */ + mm4 = _mm_sub_pi32(mm4, *(v2si*)_pi32_2); + mm5 = _mm_sub_pi32(mm5, *(v2si*)_pi32_2); + mm4 = _mm_andnot_si64(mm4, *(v2si*)_pi32_4); + mm5 = _mm_andnot_si64(mm5, *(v2si*)_pi32_4); + mm4 = _mm_slli_pi32(mm4, 29); + mm5 = _mm_slli_pi32(mm5, 29); + v4sf sign_bit_cos; + COPY_MM_TO_XMM(mm4, mm5, sign_bit_cos); + _mm_empty(); /* good-bye mmx */ + + sign_bit_sin = _mm_xor_ps(sign_bit_sin, swap_sign_bit_sin); + + + /* Evaluate the first polynom (0 <= x <= Pi/4) */ + v4sf z = _mm_mul_ps(xx,xx); + y = *(v4sf*)_ps_coscof_p0; + + y = _mm_mul_ps(y, z); + y = _mm_add_ps(y, *(v4sf*)_ps_coscof_p1); + y = _mm_mul_ps(y, z); + y = _mm_add_ps(y, *(v4sf*)_ps_coscof_p2); + y = _mm_mul_ps(y, z); + y = _mm_mul_ps(y, z); + v4sf tmp = _mm_mul_ps(z, *(v4sf*)_ps_0p5); + y = _mm_sub_ps(y, tmp); + y = _mm_add_ps(y, *(v4sf*)_ps_1); + + /* Evaluate the second polynom (Pi/4 <= x <= 0) */ + + v4sf y2 = *(v4sf*)_ps_sincof_p0; + y2 = _mm_mul_ps(y2, z); + y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p1); + y2 = _mm_mul_ps(y2, z); + y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p2); + y2 = _mm_mul_ps(y2, z); + y2 = _mm_mul_ps(y2, xx); + y2 = _mm_add_ps(y2, xx); + + /* select the correct result from the two polynoms */ + xmm3 = poly_mask; + v4sf ysin2 = _mm_and_ps(xmm3, y2); + v4sf ysin1 = _mm_andnot_ps(xmm3, y); + y2 = _mm_sub_ps(y2,ysin2); + y = _mm_sub_ps(y, ysin1); + + xmm1 = _mm_add_ps(ysin1,ysin2); + xmm2 = _mm_add_ps(y,y2); + + /* update the sign */ + _mm_store_ss( s, _mm_xor_ps(xmm1, sign_bit_sin) ); + _mm_store_ss( c, _mm_xor_ps(xmm2, sign_bit_cos) ); + +#else + #error "Not Implemented" +#endif +} + +float _SSE_cos( float x ) +{ +#ifdef _WIN32 + float temp; + __asm + { + movss xmm0, x + movss xmm1, _ps_am_inv_sign_mask + andps xmm0, xmm1 + addss xmm0, _ps_am_pi_o_2 + mulss xmm0, _ps_am_2_o_pi + + cvttss2si ecx, xmm0 + movss xmm5, _ps_am_1 + mov edx, ecx + shl edx, (31 - 1) + cvtsi2ss xmm1, ecx + and edx, 0x80000000 + and ecx, 0x1 + + subss xmm0, xmm1 + movss xmm6, _sincos_masks[ecx * 4] + minss xmm0, xmm5 + + movss xmm1, _ps_sincos_p3 + subss xmm5, xmm0 + + andps xmm5, xmm6 + movss xmm7, _ps_sincos_p2 + andnps xmm6, xmm0 + mov temp, edx + orps xmm5, xmm6 + movss xmm0, xmm5 + + mulss xmm5, xmm5 + movss xmm4, _ps_sincos_p1 + movss xmm2, xmm5 + mulss xmm5, xmm1 + movss xmm1, _ps_sincos_p0 + addss xmm5, xmm7 + mulss xmm5, xmm2 + movss xmm3, temp + addss xmm5, xmm4 + mulss xmm5, xmm2 + orps xmm0, xmm3 + addss xmm5, xmm1 + mulss xmm0, xmm5 + + movss x, xmm0 + + } +#elif POSIX + + Assert( "Needs testing, verify impl!\n" ); + + v4sf xmm1, xmm2 = _mm_setzero_ps(), xmm3, y; + v2si mm0, mm1, mm2, mm3; + /* take the absolute value */ + v4sf xx = _mm_load_ss( &x ); + + xx = _mm_and_ps(xx, *(v4sf*)_ps_inv_sign_mask); + + /* scale by 4/Pi */ + y = _mm_mul_ps(xx, *(v4sf*)_ps_cephes_FOPI); + + /* store the integer part of y in mm0:mm1 */ + xmm2 = _mm_movehl_ps(xmm2, y); + mm2 = _mm_cvttps_pi32(y); + mm3 = _mm_cvttps_pi32(xmm2); + + /* j=(j+1) & (~1) (see the cephes sources) */ + mm2 = _mm_add_pi32(mm2, *(v2si*)_pi32_1); + mm3 = _mm_add_pi32(mm3, *(v2si*)_pi32_1); + mm2 = _mm_and_si64(mm2, *(v2si*)_pi32_inv1); + mm3 = _mm_and_si64(mm3, *(v2si*)_pi32_inv1); + + y = _mm_cvtpi32x2_ps(mm2, mm3); + + + mm2 = _mm_sub_pi32(mm2, *(v2si*)_pi32_2); + mm3 = _mm_sub_pi32(mm3, *(v2si*)_pi32_2); + + /* get the swap sign flag in mm0:mm1 and the + polynom selection mask in mm2:mm3 */ + + mm0 = _mm_andnot_si64(mm2, *(v2si*)_pi32_4); + mm1 = _mm_andnot_si64(mm3, *(v2si*)_pi32_4); + mm0 = _mm_slli_pi32(mm0, 29); + mm1 = _mm_slli_pi32(mm1, 29); + + mm2 = _mm_and_si64(mm2, *(v2si*)_pi32_2); + mm3 = _mm_and_si64(mm3, *(v2si*)_pi32_2); + + mm2 = _mm_cmpeq_pi32(mm2, _mm_setzero_si64()); + mm3 = _mm_cmpeq_pi32(mm3, _mm_setzero_si64()); + + v4sf sign_bit, poly_mask; + COPY_MM_TO_XMM(mm0, mm1, sign_bit); + COPY_MM_TO_XMM(mm2, mm3, poly_mask); + _mm_empty(); /* good-bye mmx */ + + /* The magic pass: "Extended precision modular arithmetic" + x = ((x - y * DP1) - y * DP2) - y * DP3; */ + xmm1 = *(v4sf*)_ps_minus_cephes_DP1; + xmm2 = *(v4sf*)_ps_minus_cephes_DP2; + xmm3 = *(v4sf*)_ps_minus_cephes_DP3; + xmm1 = _mm_mul_ps(y, xmm1); + xmm2 = _mm_mul_ps(y, xmm2); + xmm3 = _mm_mul_ps(y, xmm3); + xx = _mm_add_ps(xx, xmm1); + xx = _mm_add_ps(xx, xmm2); + xx = _mm_add_ps(xx, xmm3); + + /* Evaluate the first polynom (0 <= x <= Pi/4) */ + y = *(v4sf*)_ps_coscof_p0; + v4sf z = _mm_mul_ps(xx,xx); + + y = _mm_mul_ps(y, z); + y = _mm_add_ps(y, *(v4sf*)_ps_coscof_p1); + y = _mm_mul_ps(y, z); + y = _mm_add_ps(y, *(v4sf*)_ps_coscof_p2); + y = _mm_mul_ps(y, z); + y = _mm_mul_ps(y, z); + v4sf tmp = _mm_mul_ps(z, *(v4sf*)_ps_0p5); + y = _mm_sub_ps(y, tmp); + y = _mm_add_ps(y, *(v4sf*)_ps_1); + + /* Evaluate the second polynom (Pi/4 <= x <= 0) */ + + v4sf y2 = *(v4sf*)_ps_sincof_p0; + y2 = _mm_mul_ps(y2, z); + y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p1); + y2 = _mm_mul_ps(y2, z); + y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p2); + y2 = _mm_mul_ps(y2, z); + y2 = _mm_mul_ps(y2, xx); + y2 = _mm_add_ps(y2, xx); + + /* select the correct result from the two polynoms */ + xmm3 = poly_mask; + y2 = _mm_and_ps(xmm3, y2); //, xmm3); + y = _mm_andnot_ps(xmm3, y); + y = _mm_add_ps(y,y2); + /* update the sign */ + + _mm_store_ss( &x, _mm_xor_ps(y, sign_bit) ); + +#else + #error "Not Implemented" +#endif + + return x; +} + +//----------------------------------------------------------------------------- +// SSE2 implementations of optimized routines: +//----------------------------------------------------------------------------- +void _SSE2_SinCos(float x, float* s, float* c) // any x +{ +#ifdef _WIN32 + __asm + { + movss xmm0, x + movaps xmm7, xmm0 + movss xmm1, _ps_am_inv_sign_mask + movss xmm2, _ps_am_sign_mask + movss xmm3, _ps_am_2_o_pi + andps xmm0, xmm1 + andps xmm7, xmm2 + mulss xmm0, xmm3 + + pxor xmm3, xmm3 + movd xmm5, _epi32_1 + movss xmm4, _ps_am_1 + + cvttps2dq xmm2, xmm0 + pand xmm5, xmm2 + movd xmm1, _epi32_2 + pcmpeqd xmm5, xmm3 + movd xmm3, _epi32_1 + cvtdq2ps xmm6, xmm2 + paddd xmm3, xmm2 + pand xmm2, xmm1 + pand xmm3, xmm1 + subss xmm0, xmm6 + pslld xmm2, (31 - 1) + minss xmm0, xmm4 + + mov eax, s // mov eax, [esp + 4 + 16] + mov edx, c // mov edx, [esp + 4 + 16 + 4] + + subss xmm4, xmm0 + pslld xmm3, (31 - 1) + + movaps xmm6, xmm4 + xorps xmm2, xmm7 + movaps xmm7, xmm5 + andps xmm6, xmm7 + andnps xmm7, xmm0 + andps xmm0, xmm5 + andnps xmm5, xmm4 + movss xmm4, _ps_sincos_p3 + orps xmm6, xmm7 + orps xmm0, xmm5 + movss xmm5, _ps_sincos_p2 + + movaps xmm1, xmm0 + movaps xmm7, xmm6 + mulss xmm0, xmm0 + mulss xmm6, xmm6 + orps xmm1, xmm2 + orps xmm7, xmm3 + movaps xmm2, xmm0 + movaps xmm3, xmm6 + mulss xmm0, xmm4 + mulss xmm6, xmm4 + movss xmm4, _ps_sincos_p1 + addss xmm0, xmm5 + addss xmm6, xmm5 + movss xmm5, _ps_sincos_p0 + mulss xmm0, xmm2 + mulss xmm6, xmm3 + addss xmm0, xmm4 + addss xmm6, xmm4 + mulss xmm0, xmm2 + mulss xmm6, xmm3 + addss xmm0, xmm5 + addss xmm6, xmm5 + mulss xmm0, xmm1 + mulss xmm6, xmm7 + + // use full stores since caller might reload with full loads + movss [eax], xmm0 + movss [edx], xmm6 + } +#elif POSIX + #warning "_SSE2_SinCos NOT implemented!" + Assert( 0 ); +#else + #error "Not Implemented" +#endif +} + +float _SSE2_cos(float x) +{ +#ifdef _WIN32 + __asm + { + movss xmm0, x + movss xmm1, _ps_am_inv_sign_mask + movss xmm2, _ps_am_pi_o_2 + movss xmm3, _ps_am_2_o_pi + andps xmm0, xmm1 + addss xmm0, xmm2 + mulss xmm0, xmm3 + + pxor xmm3, xmm3 + movd xmm5, _epi32_1 + movss xmm4, _ps_am_1 + cvttps2dq xmm2, xmm0 + pand xmm5, xmm2 + movd xmm1, _epi32_2 + pcmpeqd xmm5, xmm3 + cvtdq2ps xmm6, xmm2 + pand xmm2, xmm1 + pslld xmm2, (31 - 1) + + subss xmm0, xmm6 + movss xmm3, _ps_sincos_p3 + minss xmm0, xmm4 + subss xmm4, xmm0 + andps xmm0, xmm5 + andnps xmm5, xmm4 + orps xmm0, xmm5 + + movaps xmm1, xmm0 + movss xmm4, _ps_sincos_p2 + mulss xmm0, xmm0 + movss xmm5, _ps_sincos_p1 + orps xmm1, xmm2 + movaps xmm7, xmm0 + mulss xmm0, xmm3 + movss xmm6, _ps_sincos_p0 + addss xmm0, xmm4 + mulss xmm0, xmm7 + addss xmm0, xmm5 + mulss xmm0, xmm7 + addss xmm0, xmm6 + mulss xmm0, xmm1 + movss x, xmm0 + } +#elif POSIX + #warning "_SSE2_cos NOT implemented!" + Assert( 0 ); +#else + #error "Not Implemented" +#endif + + return x; +} + +// SSE Version of VectorTransform +void VectorTransformSSE(const float *in1, const matrix3x4_t& in2, float *out1) +{ + Assert( s_bMathlibInitialized ); + Assert( in1 != out1 ); + +#ifdef _WIN32 + __asm + { + mov eax, in1; + mov ecx, in2; + mov edx, out1; + + movss xmm0, [eax]; + mulss xmm0, [ecx]; + movss xmm1, [eax+4]; + mulss xmm1, [ecx+4]; + movss xmm2, [eax+8]; + mulss xmm2, [ecx+8]; + addss xmm0, xmm1; + addss xmm0, xmm2; + addss xmm0, [ecx+12] + movss [edx], xmm0; + add ecx, 16; + + movss xmm0, [eax]; + mulss xmm0, [ecx]; + movss xmm1, [eax+4]; + mulss xmm1, [ecx+4]; + movss xmm2, [eax+8]; + mulss xmm2, [ecx+8]; + addss xmm0, xmm1; + addss xmm0, xmm2; + addss xmm0, [ecx+12] + movss [edx+4], xmm0; + add ecx, 16; + + movss xmm0, [eax]; + mulss xmm0, [ecx]; + movss xmm1, [eax+4]; + mulss xmm1, [ecx+4]; + movss xmm2, [eax+8]; + mulss xmm2, [ecx+8]; + addss xmm0, xmm1; + addss xmm0, xmm2; + addss xmm0, [ecx+12] + movss [edx+8], xmm0; + } +#elif POSIX + #warning "VectorTransformSSE C implementation only" + out1[0] = DotProduct(in1, in2[0]) + in2[0][3]; + out1[1] = DotProduct(in1, in2[1]) + in2[1][3]; + out1[2] = DotProduct(in1, in2[2]) + in2[2][3]; +#else + #error "Not Implemented" +#endif +} + +void VectorRotateSSE( const float *in1, const matrix3x4_t& in2, float *out1 ) +{ + Assert( s_bMathlibInitialized ); + Assert( in1 != out1 ); + +#ifdef _WIN32 + __asm + { + mov eax, in1; + mov ecx, in2; + mov edx, out1; + + movss xmm0, [eax]; + mulss xmm0, [ecx]; + movss xmm1, [eax+4]; + mulss xmm1, [ecx+4]; + movss xmm2, [eax+8]; + mulss xmm2, [ecx+8]; + addss xmm0, xmm1; + addss xmm0, xmm2; + movss [edx], xmm0; + add ecx, 16; + + movss xmm0, [eax]; + mulss xmm0, [ecx]; + movss xmm1, [eax+4]; + mulss xmm1, [ecx+4]; + movss xmm2, [eax+8]; + mulss xmm2, [ecx+8]; + addss xmm0, xmm1; + addss xmm0, xmm2; + movss [edx+4], xmm0; + add ecx, 16; + + movss xmm0, [eax]; + mulss xmm0, [ecx]; + movss xmm1, [eax+4]; + mulss xmm1, [ecx+4]; + movss xmm2, [eax+8]; + mulss xmm2, [ecx+8]; + addss xmm0, xmm1; + addss xmm0, xmm2; + movss [edx+8], xmm0; + } +#elif POSIX + #warning "VectorRotateSSE C implementation only" + out1[0] = DotProduct( in1, in2[0] ); + out1[1] = DotProduct( in1, in2[1] ); + out1[2] = DotProduct( in1, in2[2] ); +#else + #error "Not Implemented" +#endif +} + +#ifdef _WIN32 +void _declspec(naked) _SSE_VectorMA( const float *start, float scale, const float *direction, float *dest ) +{ + // FIXME: This don't work!! It will overwrite memory in the write to dest + Assert(0); + + Assert( s_bMathlibInitialized ); + _asm { // Intel SSE only routine + mov eax, DWORD PTR [esp+0x04] ; *start, s0..s2 + mov ecx, DWORD PTR [esp+0x0c] ; *direction, d0..d2 + mov edx, DWORD PTR [esp+0x10] ; *dest + movss xmm2, [esp+0x08] ; x2 = scale, 0, 0, 0 +#ifdef ALIGNED_VECTOR + movaps xmm3, [ecx] ; x3 = dir0,dir1,dir2,X + pshufd xmm2, xmm2, 0 ; x2 = scale, scale, scale, scale + movaps xmm1, [eax] ; x1 = start1, start2, start3, X + mulps xmm3, xmm2 ; x3 *= x2 + addps xmm3, xmm1 ; x3 += x1 + movaps [edx], xmm3 ; *dest = x3 +#else + movups xmm3, [ecx] ; x3 = dir0,dir1,dir2,X + pshufd xmm2, xmm2, 0 ; x2 = scale, scale, scale, scale + movups xmm1, [eax] ; x1 = start1, start2, start3, X + mulps xmm3, xmm2 ; x3 *= x2 + addps xmm3, xmm1 ; x3 += x1 + movups [edx], xmm3 ; *dest = x3 +#endif + } +} +#endif + +#ifdef _WIN32 +#ifdef PFN_VECTORMA +void _declspec(naked) __cdecl _SSE_VectorMA( const Vector &start, float scale, const Vector &direction, Vector &dest ) +{ + // FIXME: This don't work!! It will overwrite memory in the write to dest + Assert(0); + + Assert( s_bMathlibInitialized ); + _asm + { + // Intel SSE only routine + mov eax, DWORD PTR [esp+0x04] ; *start, s0..s2 + mov ecx, DWORD PTR [esp+0x0c] ; *direction, d0..d2 + mov edx, DWORD PTR [esp+0x10] ; *dest + movss xmm2, [esp+0x08] ; x2 = scale, 0, 0, 0 +#ifdef ALIGNED_VECTOR + movaps xmm3, [ecx] ; x3 = dir0,dir1,dir2,X + pshufd xmm2, xmm2, 0 ; x2 = scale, scale, scale, scale + movaps xmm1, [eax] ; x1 = start1, start2, start3, X + mulps xmm3, xmm2 ; x3 *= x2 + addps xmm3, xmm1 ; x3 += x1 + movaps [edx], xmm3 ; *dest = x3 +#else + movups xmm3, [ecx] ; x3 = dir0,dir1,dir2,X + pshufd xmm2, xmm2, 0 ; x2 = scale, scale, scale, scale + movups xmm1, [eax] ; x1 = start1, start2, start3, X + mulps xmm3, xmm2 ; x3 *= x2 + addps xmm3, xmm1 ; x3 += x1 + movups [edx], xmm3 ; *dest = x3 +#endif + } +} +float (__cdecl *pfVectorMA)(Vector& v) = _VectorMA; +#endif +#endif + + +// SSE DotProduct -- it's a smidgen faster than the asm DotProduct... +// Should be validated too! :) +// NJS: (Nov 1 2002) -NOT- faster. may time a couple cycles faster in a single function like +// this, but when inlined, and instruction scheduled, the C version is faster. +// Verified this via VTune +/* +vec_t DotProduct (const vec_t *a, const vec_t *c) +{ + vec_t temp; + + __asm + { + mov eax, a; + mov ecx, c; + mov edx, DWORD PTR [temp] + movss xmm0, [eax]; + mulss xmm0, [ecx]; + movss xmm1, [eax+4]; + mulss xmm1, [ecx+4]; + movss xmm2, [eax+8]; + mulss xmm2, [ecx+8]; + addss xmm0, xmm1; + addss xmm0, xmm2; + movss [edx], xmm0; + fld DWORD PTR [edx]; + ret + } +} +*/ + +#endif // COMPILER_MSVC64 diff --git a/sp/src/mathlib/sse.h b/sp/src/mathlib/sse.h new file mode 100644 index 00000000..72de1d3b --- /dev/null +++ b/sp/src/mathlib/sse.h @@ -0,0 +1,23 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=====================================================================================// + +#ifndef _SSE_H +#define _SSE_H + +float _SSE_Sqrt(float x); +float _SSE_RSqrtAccurate(float a); +float _SSE_RSqrtFast(float x); +float FASTCALL _SSE_VectorNormalize(Vector& vec); +void FASTCALL _SSE_VectorNormalizeFast(Vector& vec); +float _SSE_InvRSquared(const float* v); +void _SSE_SinCos(float x, float* s, float* c); +float _SSE_cos( float x); +void _SSE2_SinCos(float x, float* s, float* c); +float _SSE2_cos(float x); +void VectorTransformSSE(const float *in1, const matrix3x4_t& in2, float *out1); +void VectorRotateSSE( const float *in1, const matrix3x4_t& in2, float *out1 ); + +#endif // _SSE_H diff --git a/sp/src/mathlib/sseconst.cpp b/sp/src/mathlib/sseconst.cpp new file mode 100644 index 00000000..2f923193 --- /dev/null +++ b/sp/src/mathlib/sseconst.cpp @@ -0,0 +1,1164 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#include "mathlib/ssemath.h" +#include "mathlib/ssequaternion.h" + +const fltx4 Four_PointFives={0.5,0.5,0.5,0.5}; +#ifndef _X360 +const fltx4 Four_Zeros={0.0,0.0,0.0,0.0}; +const fltx4 Four_Ones={1.0,1.0,1.0,1.0}; +#endif +const fltx4 Four_Twos={2.0,2.0,2.0,2.0}; +const fltx4 Four_Threes={3.0,3.0,3.0,3.0}; +const fltx4 Four_Fours={4.0,4.0,4.0,4.0}; +const fltx4 Four_Origin={0,0,0,1}; +const fltx4 Four_NegativeOnes={-1,-1,-1,-1}; + +const fltx4 Four_2ToThe21s={ (float) (1<<21), (float) (1<<21), (float) (1<<21), (float)(1<<21) }; +const fltx4 Four_2ToThe22s={ (float) (1<<22), (float) (1<<22), (float) (1<<22), (float)(1<<22) }; +const fltx4 Four_2ToThe23s={ (float) (1<<23), (float) (1<<23), (float) (1<<23), (float)(1<<23) }; +const fltx4 Four_2ToThe24s={ (float) (1<<24), (float) (1<<24), (float) (1<<24), (float)(1<<24) }; + +const fltx4 Four_Point225s={ .225, .225, .225, .225 }; +const fltx4 Four_Epsilons={FLT_EPSILON,FLT_EPSILON,FLT_EPSILON,FLT_EPSILON}; + +const fltx4 Four_FLT_MAX={FLT_MAX,FLT_MAX,FLT_MAX,FLT_MAX}; +const fltx4 Four_Negative_FLT_MAX={-FLT_MAX,-FLT_MAX,-FLT_MAX,-FLT_MAX}; +const fltx4 g_SIMD_0123 = { 0., 1., 2., 3. }; + +const fltx4 g_QuatMultRowSign[4] = +{ + { 1.0f, 1.0f, -1.0f, 1.0f }, + { -1.0f, 1.0f, 1.0f, 1.0f }, + { 1.0f, -1.0f, 1.0f, 1.0f }, + { -1.0f, -1.0f, -1.0f, 1.0f } +}; + +const int32 ALIGN16 g_SIMD_clear_signmask[4] ALIGN16_POST = {0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff}; +const int32 ALIGN16 g_SIMD_signmask[4] ALIGN16_POST = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; +const int32 ALIGN16 g_SIMD_lsbmask[4] ALIGN16_POST = { 0xfffffffe, 0xfffffffe, 0xfffffffe, 0xfffffffe }; +const int32 ALIGN16 g_SIMD_clear_wmask[4] ALIGN16_POST = { 0xffffffff, 0xffffffff, 0xffffffff, 0 }; +const int32 ALIGN16 g_SIMD_AllOnesMask[4] ALIGN16_POST = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; // ~0,~0,~0,~0 +const int32 ALIGN16 g_SIMD_Low16BitsMask[4] ALIGN16_POST = { 0xffff, 0xffff, 0xffff, 0xffff }; // 0xffff x 4 + +const int32 ALIGN16 g_SIMD_ComponentMask[4][4] ALIGN16_POST = +{ + { 0xFFFFFFFF, 0, 0, 0 }, { 0, 0xFFFFFFFF, 0, 0 }, { 0, 0, 0xFFFFFFFF, 0 }, { 0, 0, 0, 0xFFFFFFFF } +}; + +const int32 ALIGN16 g_SIMD_SkipTailMask[4][4] ALIGN16_POST = +{ + { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }, + { 0xffffffff, 0x00000000, 0x00000000, 0x00000000 }, + { 0xffffffff, 0xffffffff, 0x00000000, 0x00000000 }, + { 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000 }, +}; + + + // FUNCTIONS + // NOTE: WHY YOU **DO NOT** WANT TO PUT FUNCTIONS HERE +// Generally speaking, you want to make sure SIMD math functions +// are inlined, because that gives the compiler much more latitude +// in instruction scheduling. It's not that the overhead of calling +// the function is particularly great; rather, many of the SIMD +// opcodes have long latencies, and if you have a sequence of +// several dependent ones inside a function call, the latencies +// stack up to create a big penalty. If the function is inlined, +// the compiler can interleave its operations with ones from the +// caller to better hide those latencies. Finally, on the 360, +// putting parameters or return values on the stack, and then +// reading them back within the next forty cycles, is a very +// severe penalty. So, as much as possible, you want to leave your +// data on the registers. + +// That said, there are certain occasions where it is appropriate +// to call into functions -- particularly for very large blocks +// of code that will spill most of the registers anyway. Unless your +// function is more than one screen long, yours is probably not one +// of those occasions. + + + +/// You can use this to rotate a long array of FourVectors all by the same +/// matrix. The first parameter is the head of the array. The second is the +/// number of vectors to rotate. The third is the matrix. +void FourVectors::RotateManyBy(FourVectors * RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& rotationMatrix ) +{ + Assert(numVectors > 0); + if ( numVectors == 0 ) + return; + + // Splat out each of the entries in the matrix to a fltx4. Do this + // in the order that we will need them, to hide latency. I'm + // avoiding making an array of them, so that they'll remain in + // registers. + fltx4 matSplat00, matSplat01, matSplat02, + matSplat10, matSplat11, matSplat12, + matSplat20, matSplat21, matSplat22; + + { + // Load the matrix into local vectors. Sadly, matrix3x4_ts are + // often unaligned. The w components will be the tranpose row of + // the matrix, but we don't really care about that. + fltx4 matCol0 = LoadUnalignedSIMD(rotationMatrix[0]); + fltx4 matCol1 = LoadUnalignedSIMD(rotationMatrix[1]); + fltx4 matCol2 = LoadUnalignedSIMD(rotationMatrix[2]); + + matSplat00 = SplatXSIMD(matCol0); + matSplat01 = SplatYSIMD(matCol0); + matSplat02 = SplatZSIMD(matCol0); + + matSplat10 = SplatXSIMD(matCol1); + matSplat11 = SplatYSIMD(matCol1); + matSplat12 = SplatZSIMD(matCol1); + + matSplat20 = SplatXSIMD(matCol2); + matSplat21 = SplatYSIMD(matCol2); + matSplat22 = SplatZSIMD(matCol2); + } + +#ifdef _X360 + // Same algorithm as above, but the loop is unrolled to eliminate data hazard latencies + // and simplify prefetching. Named variables are deliberately used instead of arrays to + // ensure that the variables live on the registers instead of the stack (stack load/store + // is a serious penalty on 360). Nb: for prefetching to be most efficient here, the + // loop should be unrolled to 8 FourVectors per iteration; because each FourVectors is + // 48 bytes long, 48 * 8 = 384, its least common multiple with the 128-byte cache line. + // That way you can fetch the next 3 cache lines while you work on these three. + // If you do go this route, be sure to dissassemble and make sure it doesn't spill + // registers to stack as you do this; the cost of that will be excessive. Unroll the loop + // a little and just live with the fact that you'll be doing a couple of redundant dbcts + // (they don't cost you anything). Be aware that all three cores share L2 and it can only + // have eight cache lines fetching at a time. + fltx4 outX0, outY0, outZ0; // bank one of outputs + fltx4 outX1, outY1, outZ1; // bank two of outputs + + + // Because of instruction latencies and scheduling, it's actually faster to use adds and muls + // rather than madds. (Empirically determined by timing.) + const FourVectors * stop = pVectors + numVectors; + FourVectors * RESTRICT pVectNext; + // prime the pump. + if (numVectors & 0x01) + { + // odd number of vectors to process + // prime the 1 group of registers + pVectNext = pVectors++; + outX1 = AddSIMD( AddSIMD( MulSIMD( pVectNext->x, matSplat00 ), MulSIMD( pVectNext->y, matSplat01 ) ), MulSIMD( pVectNext->z, matSplat02 ) ); + outY1 = AddSIMD( AddSIMD( MulSIMD( pVectNext->x, matSplat10 ), MulSIMD( pVectNext->y, matSplat11 ) ), MulSIMD( pVectNext->z, matSplat12 ) ); + outZ1 = AddSIMD( AddSIMD( MulSIMD( pVectNext->x, matSplat20 ), MulSIMD( pVectNext->y, matSplat21 ) ), MulSIMD( pVectNext->z, matSplat22 ) ); + } + else + { + // even number of total vectors to process; + // prime the zero group and jump into the middle of the loop + outX0 = AddSIMD( AddSIMD( MulSIMD( pVectors->x, matSplat00 ), MulSIMD( pVectors->y, matSplat01 ) ), MulSIMD( pVectors->z, matSplat02 ) ); + outY0 = AddSIMD( AddSIMD( MulSIMD( pVectors->x, matSplat10 ), MulSIMD( pVectors->y, matSplat11 ) ), MulSIMD( pVectors->z, matSplat12 ) ); + outZ0 = AddSIMD( AddSIMD( MulSIMD( pVectors->x, matSplat20 ), MulSIMD( pVectors->y, matSplat21 ) ), MulSIMD( pVectors->z, matSplat22 ) ); + goto EVEN_CASE; + } + + // perform an even number of iterations through this loop. + while (pVectors < stop) + { + outX0 = MaddSIMD( pVectors->z, matSplat02, AddSIMD( MulSIMD( pVectors->x, matSplat00 ), MulSIMD( pVectors->y, matSplat01 ) ) ); + outY0 = MaddSIMD( pVectors->z, matSplat12, AddSIMD( MulSIMD( pVectors->x, matSplat10 ), MulSIMD( pVectors->y, matSplat11 ) ) ); + outZ0 = MaddSIMD( pVectors->z, matSplat22, AddSIMD( MulSIMD( pVectors->x, matSplat20 ), MulSIMD( pVectors->y, matSplat21 ) ) ); + + pVectNext->x = outX1; + pVectNext->y = outY1; + pVectNext->z = outZ1; + +EVEN_CASE: + pVectNext = pVectors+1; + + outX1 = MaddSIMD( pVectNext->z, matSplat02, AddSIMD( MulSIMD( pVectNext->x, matSplat00 ), MulSIMD( pVectNext->y, matSplat01 ) ) ); + outY1 = MaddSIMD( pVectNext->z, matSplat12, AddSIMD( MulSIMD( pVectNext->x, matSplat10 ), MulSIMD( pVectNext->y, matSplat11 ) ) ); + outZ1 = MaddSIMD( pVectNext->z, matSplat22, AddSIMD( MulSIMD( pVectNext->x, matSplat20 ), MulSIMD( pVectNext->y, matSplat21 ) ) ); + + pVectors->x = outX0; + pVectors->y = outY0; + pVectors->z = outZ0; + + pVectors += 2; + } + + // flush the last round of output + pVectNext->x = outX1; + pVectNext->y = outY1; + pVectNext->z = outZ1; +#else + // PC does not benefit from the unroll/scheduling above + fltx4 outX0, outY0, outZ0; // bank one of outputs + + + // Because of instruction latencies and scheduling, it's actually faster to use adds and muls + // rather than madds. (Empirically determined by timing.) + const FourVectors * stop = pVectors + numVectors; + + // perform an even number of iterations through this loop. + while (pVectors < stop) + { + outX0 = MaddSIMD( pVectors->z, matSplat02, AddSIMD( MulSIMD( pVectors->x, matSplat00 ), MulSIMD( pVectors->y, matSplat01 ) ) ); + outY0 = MaddSIMD( pVectors->z, matSplat12, AddSIMD( MulSIMD( pVectors->x, matSplat10 ), MulSIMD( pVectors->y, matSplat11 ) ) ); + outZ0 = MaddSIMD( pVectors->z, matSplat22, AddSIMD( MulSIMD( pVectors->x, matSplat20 ), MulSIMD( pVectors->y, matSplat21 ) ) ); + + pVectors->x = outX0; + pVectors->y = outY0; + pVectors->z = outZ0; + pVectors++; + } +#endif +} + +#ifdef _X360 +// Loop-scheduled code to process FourVectors in groups of eight quite efficiently. +void FourVectors_TransformManyGroupsOfEightBy(FourVectors * RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& rotationMatrix, FourVectors * RESTRICT pOut ) +{ + Assert(numVectors > 0); + if ( numVectors == 0 ) + return; + + AssertMsg( (pOut < pVectors && pOut+numVectors <= pVectors) || + (pOut > pVectors && pVectors+numVectors <= pOut), "FourVectors::TransformManyBy called with overlapping buffer pointers." ); + + // Splat out each of the entries in the matrix to a fltx4. Do this + // in the order that we will need them, to hide latency. I'm + // avoiding making an array of them, so that they'll remain in + // registers. + fltx4 matSplat00, matSplat01, matSplat02, matSplat03, // TWELVE REGISTERS + matSplat10, matSplat11, matSplat12, matSplat13, + matSplat20, matSplat21, matSplat22, matSplat23; + + { + // Load the matrix into local vectors. Sadly, matrix3x4_ts are + // often unaligned. The w components will be the tranpose row of + // the matrix. + fltx4 matCol0 = LoadUnalignedSIMD(rotationMatrix[0]); + fltx4 matCol1 = LoadUnalignedSIMD(rotationMatrix[1]); + fltx4 matCol2 = LoadUnalignedSIMD(rotationMatrix[2]); + + matSplat00 = SplatXSIMD(matCol0); + matSplat01 = SplatYSIMD(matCol0); + matSplat02 = SplatZSIMD(matCol0); + matSplat03 = SplatWSIMD(matCol0); + + matSplat10 = SplatXSIMD(matCol1); + matSplat11 = SplatYSIMD(matCol1); + matSplat12 = SplatZSIMD(matCol1); + matSplat13 = SplatWSIMD(matCol1); + + matSplat20 = SplatXSIMD(matCol2); + matSplat21 = SplatYSIMD(matCol2); + matSplat22 = SplatZSIMD(matCol2); + matSplat23 = SplatWSIMD(matCol2); + } + + // this macro defines how to compute a specific row from an input and certain splat columns +#define COMPUTE(res, invec, xterm, yterm, zterm, transterm) res = AddSIMD( AddSIMD( MulSIMD((invec)->z, zterm), AddSIMD( MulSIMD( (invec)->x, xterm ), MulSIMD( (invec)->y, yterm ) ) ), transterm ) +#define WRITE(term, reg, toptr) toptr->term = reg + + // define result groups (we're going to have an eight-way unroll) + + fltx4 res0X, res0Y, res0Z, res0XTemp, res0YTemp, res0ZTemp; // 48 REGISTERS + fltx4 res1X, res1Y, res1Z, res1XTemp, res1YTemp, res1ZTemp; + fltx4 res2X, res2Y, res2Z, res2XTemp, res2YTemp, res2ZTemp; + fltx4 res3X, res3Y, res3Z, res3XTemp, res3YTemp, res3ZTemp; + fltx4 res4X, res4Y, res4Z, res4XTemp, res4YTemp, res4ZTemp; + fltx4 res5X, res5Y, res5Z, res5XTemp, res5YTemp, res5ZTemp; + fltx4 res6X, res6Y, res6Z, res6XTemp, res6YTemp, res6ZTemp; + fltx4 res7X, res7Y, res7Z, res7XTemp, res7YTemp, res7ZTemp; + + +// #define FROZ(out,in,offset) COMPUTE((out+offset)->x, (in + offset), matSplat00, matSplat01, matSplat02, matSplat03); COMPUTE((out + offset )->y, (in + offset), matSplat10, matSplat11, matSplat12, matSplat13); COMPUTE((out + offset)->z, (in + offset), matSplat20, matSplat21, matSplat22, matSplat23) +#define COMPUTE_GROUP(resgroup,dataptr) COMPUTE(resgroup ## X, (dataptr), matSplat00, matSplat01, matSplat02, matSplat03); COMPUTE(resgroup ## Y, (dataptr), matSplat10, matSplat11, matSplat12, matSplat13); COMPUTE(resgroup ## Z, (dataptr), matSplat20, matSplat21, matSplat22, matSplat23) +#define WRITE_GROUP(ptr, resgroup) (ptr)->x = resgroup ## X; (ptr)->y = resgroup ## Y; (ptr)->z = resgroup ## Z + + /* + // stage 1 -- 6 ops for xyz, each w 12 cycle latency + res0X = MulSIMD( (invec)->y, matSplat01 ); + res0Temp = MaddSIMD((invec)->z, matSplat02, matSplat03); + // stage 2 -- 3 clocks for xyz + res0X = MaddSIMD( (invec)->x, matSplat00, res0X ); + // stage 3 -- 3 clocks for xyz + res0X = AddSIMD(res0X, res0Temp); + */ +#define COMPUTE_STAGE1_ROW(res, tempvar, invec, xsplat, ysplat, zsplat, transplat) res = MulSIMD( (invec)->y, ysplat ); tempvar = MaddSIMD((invec)->z, zsplat, transplat) +#define COMPUTE_STAGE2_ROW(res, tempvar, invec, xsplat, ysplat, zsplat, transplat) res = MaddSIMD( (invec)->x, xsplat, res ) +#define COMPUTE_STAGE3_ROW(res, tempvar, invec, xsplat, ysplat, zsplat, transplat) res = AddSIMD(res, tempvar) // frees up the tempvar + +#define COMPUTE_STAGE1_GROUP(resgroup, invec) COMPUTE_STAGE1_ROW(resgroup ## X, resgroup ## X ## Temp, invec, matSplat00, matSplat01, matSplat02, matSplat03);\ + COMPUTE_STAGE1_ROW(resgroup ## Y, resgroup ## Y ## Temp, invec, matSplat10, matSplat11, matSplat12, matSplat13);\ + COMPUTE_STAGE1_ROW(resgroup ## Z, resgroup ## Z ## Temp, invec, matSplat20, matSplat21, matSplat22, matSplat23) + +#define COMPUTE_STAGE2_GROUP(resgroup, invec) COMPUTE_STAGE2_ROW(resgroup ## X, resgroup ## X ## Temp, invec, matSplat00, matSplat01, matSplat02, matSplat03);\ + COMPUTE_STAGE2_ROW(resgroup ## Y, resgroup ## Y ## Temp, invec, matSplat10, matSplat11, matSplat12, matSplat13);\ + COMPUTE_STAGE2_ROW(resgroup ## Z, resgroup ## Z ## Temp, invec, matSplat20, matSplat21, matSplat22, matSplat23) + +#define COMPUTE_STAGE3_GROUP(resgroup, invec) COMPUTE_STAGE3_ROW(resgroup ## X, resgroup ## X ## Temp, invec, matSplat00, matSplat01, matSplat02, matSplat03);\ + COMPUTE_STAGE3_ROW(resgroup ## Y, resgroup ## Y ## Temp, invec, matSplat10, matSplat11, matSplat12, matSplat13);\ + COMPUTE_STAGE3_ROW(resgroup ## Z, resgroup ## Z ## Temp, invec, matSplat20, matSplat21, matSplat22, matSplat23) + + FourVectors * RESTRICT inData = pVectors; + FourVectors * RESTRICT outData = pOut; + const FourVectors * const RESTRICT STOP = pVectors + numVectors; + + // Use techniques of loop scheduling to eliminate data hazards; process + // eight groups simultaneously so that we never have any operations stalling + // waiting for data. + // Note: this loop, while pretty fast, could be faster still -- you'll notice + // that it does all of its loads, then all computation, then writes everything + // out. If made truly cyclic, such that every line interleaved a stage 1, stage 2, + // stage 3, and write, then throughput could be higher (probably by about 50%). + while (inData < STOP) + { + // start prefetching the three cache lines + // we'll hit two iterations from now + __dcbt( sizeof(FourVectors) * 16, inData ); + __dcbt( sizeof(FourVectors) * 16 + 128, inData ); + __dcbt( sizeof(FourVectors) * 16 + 256, inData ); + + // synchro + COMPUTE_STAGE1_GROUP(res0, inData + 0); + COMPUTE_STAGE1_GROUP(res1, inData + 1); + COMPUTE_STAGE1_GROUP(res2, inData + 2); + COMPUTE_STAGE1_GROUP(res3, inData + 3); + + COMPUTE_STAGE2_GROUP(res0, inData + 0); + COMPUTE_STAGE1_GROUP(res4, inData + 4); + COMPUTE_STAGE2_GROUP(res1, inData + 1); + COMPUTE_STAGE1_GROUP(res5, inData + 5); + COMPUTE_STAGE2_GROUP(res2, inData + 2); + COMPUTE_STAGE1_GROUP(res6, inData + 6); + COMPUTE_STAGE2_GROUP(res3, inData + 3); + COMPUTE_STAGE1_GROUP(res7, inData + 7); + + COMPUTE_STAGE3_GROUP(res0, inData + 0); + COMPUTE_STAGE2_GROUP(res4, inData + 4); + COMPUTE_STAGE3_GROUP(res1, inData + 1); + COMPUTE_STAGE2_GROUP(res5, inData + 5); + COMPUTE_STAGE3_GROUP(res2, inData + 2); + COMPUTE_STAGE2_GROUP(res6, inData + 6); + COMPUTE_STAGE3_GROUP(res3, inData + 3); + COMPUTE_STAGE2_GROUP(res7, inData + 7); + + COMPUTE_STAGE3_GROUP(res4, inData + 4); + WRITE_GROUP( outData + 0, res0 ); + COMPUTE_STAGE3_GROUP(res5, inData + 5); + WRITE_GROUP( outData + 1, res1 ); + COMPUTE_STAGE3_GROUP(res6, inData + 6); + WRITE_GROUP( outData + 2, res2 ); + COMPUTE_STAGE3_GROUP(res7, inData + 7); + WRITE_GROUP( outData + 3, res3 ); + + + WRITE_GROUP( outData + 4, res4 ); + WRITE_GROUP( outData + 5, res5 ); + WRITE_GROUP( outData + 6, res6 ); + WRITE_GROUP( outData + 7, res7 ); + + inData += 8; + outData += 8; + } + + +#undef COMPUTE +#undef WRITE +#undef COMPUTE_STAGE1_ROW +#undef COMPUTE_STAGE2_ROW +#undef COMPUTE_STAGE3_ROW +#undef COMPUTE_STAGE1_GROUP +#undef COMPUTE_STAGE2_GROUP +#undef COMPUTE_STAGE3_GROUP +#undef COMPUTE_GROUP +#undef WRITE_GROUP +} + +#ifdef _X360 +// Loop-scheduled code to process FourVectors in groups of eight quite efficiently. This is the version +// to call when starting on a 128-byte-aligned address. +void FourVectors_TransformManyGroupsOfEightBy_128byteAligned(FourVectors * RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& rotationMatrix, FourVectors * RESTRICT pOut ) +{ + /* If this has changed, you will need to change all the prefetches, * + * and groups of eight are no longer the ideal unit for iterating * + * on many vectors. */ + COMPILE_TIME_ASSERT( sizeof(FourVectors) == 48 ) ; + + Assert(numVectors > 0); + if ( numVectors == 0 ) + return; + + AssertMsg((numVectors & 0x07) == 0, "FourVectors_TransformManyGroupsOfEight called with numVectors % 8 != 0!"); + + // Assert alignment + AssertMsg( ( ( reinterpret_cast( pVectors ) & 127 ) == 0) && + ( ( reinterpret_cast(pOut) & 127 ) == 0), + "FourVectors_Transform..aligned called with non-128-byte-aligned buffers." ); + + // Assert non overlap + AssertMsg( (pOut < pVectors && pOut+numVectors <= pVectors) || + (pOut > pVectors && pVectors+numVectors <= pOut), "FourVectors::TransformManyBy called with overlapping buffer pointers." ); + + // Here's the plan. 8 four-vecs = 3 cache lines exactly. It takes about 400 cycles to process a group + // of eight, and cache latency is 600 cycles, so we try to prefetch two iterations ahead (eg fetch + // iteration 3 while working on iteration 1). In the case of the output, we can simply zero-flush + // the cache lines since we are sure to write into them. Because we're reading and fetching two ahead, + // we want to stop two away from the last iteration. + + // No matter what, we will need to prefetch the first two groups of eight of input (that's the + // first six cache lines) + __dcbt( 0, pVectors ); + __dcbt( 128, pVectors ); + __dcbt( 256, pVectors ); + __dcbt( 384, pVectors ); + __dcbt( 512, pVectors ); + __dcbt( 640, pVectors ); + + + // Splat out each of the entries in the matrix to a fltx4. Do this + // in the order that we will need them, to hide latency. I'm + // avoiding making an array of them, so that they'll remain in + // registers. + fltx4 matSplat00, matSplat01, matSplat02, matSplat03, // TWELVE REGISTERS + matSplat10, matSplat11, matSplat12, matSplat13, + matSplat20, matSplat21, matSplat22, matSplat23; + + { + // Load the matrix into local vectors. Sadly, matrix3x4_ts are + // often unaligned. The w components will be the tranpose row of + // the matrix. + fltx4 matCol0 = LoadUnalignedSIMD(rotationMatrix[0]); + fltx4 matCol1 = LoadUnalignedSIMD(rotationMatrix[1]); + fltx4 matCol2 = LoadUnalignedSIMD(rotationMatrix[2]); + + matSplat00 = SplatXSIMD(matCol0); + matSplat01 = SplatYSIMD(matCol0); + matSplat02 = SplatZSIMD(matCol0); + matSplat03 = SplatWSIMD(matCol0); + + matSplat10 = SplatXSIMD(matCol1); + matSplat11 = SplatYSIMD(matCol1); + matSplat12 = SplatZSIMD(matCol1); + matSplat13 = SplatWSIMD(matCol1); + + matSplat20 = SplatXSIMD(matCol2); + matSplat21 = SplatYSIMD(matCol2); + matSplat22 = SplatZSIMD(matCol2); + matSplat23 = SplatWSIMD(matCol2); + } + + // this macro defines how to compute a specific row from an input and certain splat columns +#define COMPUTE(res, invec, xterm, yterm, zterm, transterm) res = AddSIMD( AddSIMD( MulSIMD((invec)->z, zterm), AddSIMD( MulSIMD( (invec)->x, xterm ), MulSIMD( (invec)->y, yterm ) ) ), transterm ) +#define WRITE(term, reg, toptr) toptr->term = reg + + // define result groups (we're going to have an eight-way unroll) + + fltx4 res0X, res0Y, res0Z, res0XTemp, res0YTemp, res0ZTemp; // 48 REGISTERS + fltx4 res1X, res1Y, res1Z, res1XTemp, res1YTemp, res1ZTemp; + fltx4 res2X, res2Y, res2Z, res2XTemp, res2YTemp, res2ZTemp; + fltx4 res3X, res3Y, res3Z, res3XTemp, res3YTemp, res3ZTemp; + fltx4 res4X, res4Y, res4Z, res4XTemp, res4YTemp, res4ZTemp; + fltx4 res5X, res5Y, res5Z, res5XTemp, res5YTemp, res5ZTemp; + fltx4 res6X, res6Y, res6Z, res6XTemp, res6YTemp, res6ZTemp; + fltx4 res7X, res7Y, res7Z, res7XTemp, res7YTemp, res7ZTemp; + + + // #define FROZ(out,in,offset) COMPUTE((out+offset)->x, (in + offset), matSplat00, matSplat01, matSplat02, matSplat03); COMPUTE((out + offset )->y, (in + offset), matSplat10, matSplat11, matSplat12, matSplat13); COMPUTE((out + offset)->z, (in + offset), matSplat20, matSplat21, matSplat22, matSplat23) +#define COMPUTE_GROUP(resgroup,dataptr) COMPUTE(resgroup ## X, (dataptr), matSplat00, matSplat01, matSplat02, matSplat03); COMPUTE(resgroup ## Y, (dataptr), matSplat10, matSplat11, matSplat12, matSplat13); COMPUTE(resgroup ## Z, (dataptr), matSplat20, matSplat21, matSplat22, matSplat23) +#define WRITE_GROUP(ptr, resgroup) (ptr)->x = resgroup ## X; (ptr)->y = resgroup ## Y; (ptr)->z = resgroup ## Z + + /* + // stage 1 -- 6 ops for xyz, each w 12 cycle latency + res0X = MulSIMD( (invec)->y, matSplat01 ); + res0Temp = MaddSIMD((invec)->z, matSplat02, matSplat03); + // stage 2 -- 3 clocks for xyz + res0X = MaddSIMD( (invec)->x, matSplat00, res0X ); + // stage 3 -- 3 clocks for xyz + res0X = AddSIMD(res0X, res0Temp); + */ +#define COMPUTE_STAGE1_ROW(res, tempvar, invec, xsplat, ysplat, zsplat, transplat) res = MulSIMD( (invec)->y, ysplat ); tempvar = MaddSIMD((invec)->z, zsplat, transplat) +#define COMPUTE_STAGE2_ROW(res, tempvar, invec, xsplat, ysplat, zsplat, transplat) res = MaddSIMD( (invec)->x, xsplat, res ) +#define COMPUTE_STAGE3_ROW(res, tempvar, invec, xsplat, ysplat, zsplat, transplat) res = AddSIMD(res, tempvar) // frees up the tempvar + +#define COMPUTE_STAGE1_GROUP(resgroup, invec) COMPUTE_STAGE1_ROW(resgroup ## X, resgroup ## X ## Temp, invec, matSplat00, matSplat01, matSplat02, matSplat03);\ + COMPUTE_STAGE1_ROW(resgroup ## Y, resgroup ## Y ## Temp, invec, matSplat10, matSplat11, matSplat12, matSplat13);\ + COMPUTE_STAGE1_ROW(resgroup ## Z, resgroup ## Z ## Temp, invec, matSplat20, matSplat21, matSplat22, matSplat23) + +#define COMPUTE_STAGE2_GROUP(resgroup, invec) COMPUTE_STAGE2_ROW(resgroup ## X, resgroup ## X ## Temp, invec, matSplat00, matSplat01, matSplat02, matSplat03);\ + COMPUTE_STAGE2_ROW(resgroup ## Y, resgroup ## Y ## Temp, invec, matSplat10, matSplat11, matSplat12, matSplat13);\ + COMPUTE_STAGE2_ROW(resgroup ## Z, resgroup ## Z ## Temp, invec, matSplat20, matSplat21, matSplat22, matSplat23) + +#define COMPUTE_STAGE3_GROUP(resgroup, invec) COMPUTE_STAGE3_ROW(resgroup ## X, resgroup ## X ## Temp, invec, matSplat00, matSplat01, matSplat02, matSplat03);\ + COMPUTE_STAGE3_ROW(resgroup ## Y, resgroup ## Y ## Temp, invec, matSplat10, matSplat11, matSplat12, matSplat13);\ + COMPUTE_STAGE3_ROW(resgroup ## Z, resgroup ## Z ## Temp, invec, matSplat20, matSplat21, matSplat22, matSplat23) + + + // Okay. First do all but the last two turns of the crank; we don't want to overshoot with the flush-to-zero. + FourVectors * RESTRICT inData = pVectors; + FourVectors * RESTRICT outData = pOut; + const FourVectors * RESTRICT STOP; + if (numVectors > 16) + { + STOP = pVectors + numVectors - 16; + // flush the first two blocks we'll write into + __dcbz128( 0, outData ); + __dcbz128( 128, outData ); + __dcbz128( 256, outData ); + + while (inData < STOP) + { + // start prefetching the three cache lines + // we'll hit two iterations from now + __dcbt( sizeof(FourVectors) * 16, inData ); + __dcbt( sizeof(FourVectors) * 16 + 128, inData ); + __dcbt( sizeof(FourVectors) * 16 + 256, inData ); + + // synchro + COMPUTE_STAGE1_GROUP(res0, inData + 0); + COMPUTE_STAGE1_GROUP(res1, inData + 1); + COMPUTE_STAGE1_GROUP(res2, inData + 2); + COMPUTE_STAGE1_GROUP(res3, inData + 3); + + // pre-zero the three cache lines we'll overwrite + // in the next iteration + __dcbz128( 384, outData ); + __dcbz128( 512, outData ); + __dcbz128( 640, outData ); + + + COMPUTE_STAGE2_GROUP(res0, inData + 0); + COMPUTE_STAGE1_GROUP(res4, inData + 4); + COMPUTE_STAGE2_GROUP(res1, inData + 1); + COMPUTE_STAGE1_GROUP(res5, inData + 5); + COMPUTE_STAGE2_GROUP(res2, inData + 2); + COMPUTE_STAGE1_GROUP(res6, inData + 6); + COMPUTE_STAGE2_GROUP(res3, inData + 3); + COMPUTE_STAGE1_GROUP(res7, inData + 7); + + COMPUTE_STAGE3_GROUP(res0, inData + 0); + COMPUTE_STAGE2_GROUP(res4, inData + 4); + COMPUTE_STAGE3_GROUP(res1, inData + 1); + COMPUTE_STAGE2_GROUP(res5, inData + 5); + COMPUTE_STAGE3_GROUP(res2, inData + 2); + COMPUTE_STAGE2_GROUP(res6, inData + 6); + COMPUTE_STAGE3_GROUP(res3, inData + 3); + COMPUTE_STAGE2_GROUP(res7, inData + 7); + + COMPUTE_STAGE3_GROUP(res4, inData + 4); + WRITE_GROUP( outData + 0, res0 ); + COMPUTE_STAGE3_GROUP(res5, inData + 5); + WRITE_GROUP( outData + 1, res1 ); + COMPUTE_STAGE3_GROUP(res6, inData + 6); + WRITE_GROUP( outData + 2, res2 ); + COMPUTE_STAGE3_GROUP(res7, inData + 7); + WRITE_GROUP( outData + 3, res3 ); + + + WRITE_GROUP( outData + 4, res4 ); + WRITE_GROUP( outData + 5, res5 ); + WRITE_GROUP( outData + 6, res6 ); + WRITE_GROUP( outData + 7, res7 ); + + inData += 8; + outData += 8; + } + } + else if (numVectors == 16) + { + // zero out the exactly six cache lines we will write into + __dcbz128( 0, outData ); + __dcbz128( 128, outData ); + __dcbz128( 256, outData ); + __dcbz128( 384, outData ); + __dcbz128( 512, outData ); + __dcbz128( 640, outData ); + } + else if (numVectors == 8) + { + // zero out the exactly three cache lines we will write into + __dcbz128( 0, outData ); + __dcbz128( 128, outData ); + __dcbz128( 256, outData ); + } + else + { + AssertMsg(false, "Can't happen!"); + } + + // deal with the ultimate two groups (or, if we were fed + // less than 16 groups, the whole shebang) + STOP = pVectors + numVectors - 16; + + + // Use techniques of loop scheduling to eliminate data hazards; process + // eight groups simultaneously so that we never have any operations stalling + // waiting for data. + // Note: this loop, while pretty fast, could be faster still -- you'll notice + // that it does all of its loads, then all computation, then writes everything + // out. If made truly cyclic, such that every line interleaved a stage 1, stage 2, + // stage 3, and write, then throughput could be higher (probably by about 50%). + while (inData < STOP) + { + // synchro + COMPUTE_STAGE1_GROUP(res0, inData + 0); + COMPUTE_STAGE1_GROUP(res1, inData + 1); + COMPUTE_STAGE1_GROUP(res2, inData + 2); + COMPUTE_STAGE1_GROUP(res3, inData + 3); + + COMPUTE_STAGE2_GROUP(res0, inData + 0); + COMPUTE_STAGE1_GROUP(res4, inData + 4); + COMPUTE_STAGE2_GROUP(res1, inData + 1); + COMPUTE_STAGE1_GROUP(res5, inData + 5); + COMPUTE_STAGE2_GROUP(res2, inData + 2); + COMPUTE_STAGE1_GROUP(res6, inData + 6); + COMPUTE_STAGE2_GROUP(res3, inData + 3); + COMPUTE_STAGE1_GROUP(res7, inData + 7); + + COMPUTE_STAGE3_GROUP(res0, inData + 0); + COMPUTE_STAGE2_GROUP(res4, inData + 4); + COMPUTE_STAGE3_GROUP(res1, inData + 1); + COMPUTE_STAGE2_GROUP(res5, inData + 5); + COMPUTE_STAGE3_GROUP(res2, inData + 2); + COMPUTE_STAGE2_GROUP(res6, inData + 6); + COMPUTE_STAGE3_GROUP(res3, inData + 3); + COMPUTE_STAGE2_GROUP(res7, inData + 7); + + COMPUTE_STAGE3_GROUP(res4, inData + 4); + WRITE_GROUP( outData + 0, res0 ); + COMPUTE_STAGE3_GROUP(res5, inData + 5); + WRITE_GROUP( outData + 1, res1 ); + COMPUTE_STAGE3_GROUP(res6, inData + 6); + WRITE_GROUP( outData + 2, res2 ); + COMPUTE_STAGE3_GROUP(res7, inData + 7); + WRITE_GROUP( outData + 3, res3 ); + + + WRITE_GROUP( outData + 4, res4 ); + WRITE_GROUP( outData + 5, res5 ); + WRITE_GROUP( outData + 6, res6 ); + WRITE_GROUP( outData + 7, res7 ); + + inData += 8; + outData += 8; + } + + +#undef COMPUTE +#undef WRITE +#undef COMPUTE_STAGE1_ROW +#undef COMPUTE_STAGE2_ROW +#undef COMPUTE_STAGE3_ROW +#undef COMPUTE_STAGE1_GROUP +#undef COMPUTE_STAGE2_GROUP +#undef COMPUTE_STAGE3_GROUP +#undef COMPUTE_GROUP +#undef WRITE_GROUP +} +#endif + +// Transform a long array of FourVectors by a given matrix. +void FourVectors::TransformManyBy(FourVectors * RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& rotationMatrix, FourVectors * RESTRICT pOut ) +{ + Assert(numVectors > 0); + + AssertMsg( (pOut < pVectors && pOut+numVectors <= pVectors) || + (pOut > pVectors && pVectors+numVectors <= pOut), "FourVectors::TransformManyBy called with overlapping buffer pointers." ); + +#ifdef _X360 + // The really fast version of this function likes to operate on blocks of eight. So, chug through + // groups of eight, then deal with any leftovers. + int numVectorsRoundedToNearestEight = numVectors & (~0x07); + if (numVectors >= 8) + { + // aligned? + if ((reinterpret_cast(pVectors) & 127) == 0 && (reinterpret_cast(pOut) & 127) == 0) + { + FourVectors_TransformManyGroupsOfEightBy_128byteAligned(pVectors, numVectorsRoundedToNearestEight, rotationMatrix, pOut); + } + else + { + FourVectors_TransformManyGroupsOfEightBy(pVectors, numVectorsRoundedToNearestEight, rotationMatrix, pOut); + } + numVectors -= numVectorsRoundedToNearestEight; + pVectors += numVectorsRoundedToNearestEight; + pOut += numVectorsRoundedToNearestEight; + } +#endif + + // any left over? + if (numVectors > 0) + { + + // Splat out each of the entries in the matrix to a fltx4. Do this + // in the order that we will need them, to hide latency. I'm + // avoiding making an array of them, so that they'll remain in + // registers. + fltx4 matSplat00, matSplat01, matSplat02, matSplat03, // TWELVE REGISTERS + matSplat10, matSplat11, matSplat12, matSplat13, + matSplat20, matSplat21, matSplat22, matSplat23; + + { + // Load the matrix into local vectors. Sadly, matrix3x4_ts are + // often unaligned. The w components will be the transpose row of + // the matrix. + fltx4 matCol0 = LoadUnalignedSIMD(rotationMatrix[0]); + fltx4 matCol1 = LoadUnalignedSIMD(rotationMatrix[1]); + fltx4 matCol2 = LoadUnalignedSIMD(rotationMatrix[2]); + + matSplat00 = SplatXSIMD(matCol0); + matSplat01 = SplatYSIMD(matCol0); + matSplat02 = SplatZSIMD(matCol0); + matSplat03 = SplatWSIMD(matCol0); + + matSplat10 = SplatXSIMD(matCol1); + matSplat11 = SplatYSIMD(matCol1); + matSplat12 = SplatZSIMD(matCol1); + matSplat13 = SplatWSIMD(matCol1); + + matSplat20 = SplatXSIMD(matCol2); + matSplat21 = SplatYSIMD(matCol2); + matSplat22 = SplatZSIMD(matCol2); + matSplat23 = SplatWSIMD(matCol2); + } + + do + { + // Trust in the compiler to schedule these operations correctly: + pOut->x = MaddSIMD(pVectors->z, matSplat02, MaddSIMD(pVectors->y, matSplat01, MaddSIMD(pVectors->x, matSplat00, matSplat03))); + pOut->y = MaddSIMD(pVectors->z, matSplat12, MaddSIMD(pVectors->y, matSplat11, MaddSIMD(pVectors->x, matSplat00, matSplat13))); + pOut->z = MaddSIMD(pVectors->z, matSplat22, MaddSIMD(pVectors->y, matSplat21, MaddSIMD(pVectors->x, matSplat00, matSplat23))); + + ++pOut; + ++pVectors; + --numVectors; + } while(numVectors > 0); + } +} + +#ifdef _X360 +// Loop-scheduled code to process FourVectors in groups of eight quite efficiently. +static void FourVectors_TransformManyGroupsOfEightBy_InPlace(FourVectors * RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& rotationMatrix ) +{ + Assert(numVectors > 0); + if ( numVectors == 0 ) + return; + + // Prefetch line 1 and 2 + __dcbt(0,pVectors); + __dcbt(128,pVectors); + + // Splat out each of the entries in the matrix to a fltx4. Do this + // in the order that we will need them, to hide latency. I'm + // avoiding making an array of them, so that they'll remain in + // registers. + fltx4 matSplat00, matSplat01, matSplat02, matSplat03, // TWELVE REGISTERS + matSplat10, matSplat11, matSplat12, matSplat13, + matSplat20, matSplat21, matSplat22, matSplat23; + + { + // Load the matrix into local vectors. Sadly, matrix3x4_ts are + // often unaligned. The w components will be the tranpose row of + // the matrix. + fltx4 matCol0 = LoadUnalignedSIMD(rotationMatrix[0]); + fltx4 matCol1 = LoadUnalignedSIMD(rotationMatrix[1]); + fltx4 matCol2 = LoadUnalignedSIMD(rotationMatrix[2]); + + matSplat00 = SplatXSIMD(matCol0); + matSplat01 = SplatYSIMD(matCol0); + matSplat02 = SplatZSIMD(matCol0); + matSplat03 = SplatWSIMD(matCol0); + + matSplat10 = SplatXSIMD(matCol1); + matSplat11 = SplatYSIMD(matCol1); + matSplat12 = SplatZSIMD(matCol1); + matSplat13 = SplatWSIMD(matCol1); + + matSplat20 = SplatXSIMD(matCol2); + matSplat21 = SplatYSIMD(matCol2); + matSplat22 = SplatZSIMD(matCol2); + matSplat23 = SplatWSIMD(matCol2); + } + + // this macro defines how to compute a specific row from an input and certain splat columns +#define COMPUTE(res, invec, xterm, yterm, zterm, transterm) res = AddSIMD( AddSIMD( MulSIMD((invec)->z, zterm), AddSIMD( MulSIMD( (invec)->x, xterm ), MulSIMD( (invec)->y, yterm ) ) ), transterm ) +#define WRITE(term, reg, toptr) toptr->term = reg + + // define result groups (we're going to have an eight-way unroll) + + fltx4 res0X, res0Y, res0Z, res0XTemp, res0YTemp, res0ZTemp; // 48 REGISTERS + fltx4 res1X, res1Y, res1Z, res1XTemp, res1YTemp, res1ZTemp; + fltx4 res2X, res2Y, res2Z, res2XTemp, res2YTemp, res2ZTemp; + fltx4 res3X, res3Y, res3Z, res3XTemp, res3YTemp, res3ZTemp; + fltx4 res4X, res4Y, res4Z, res4XTemp, res4YTemp, res4ZTemp; + fltx4 res5X, res5Y, res5Z, res5XTemp, res5YTemp, res5ZTemp; + fltx4 res6X, res6Y, res6Z, res6XTemp, res6YTemp, res6ZTemp; + fltx4 res7X, res7Y, res7Z, res7XTemp, res7YTemp, res7ZTemp; + + + // #define FROZ(out,in,offset) COMPUTE((out+offset)->x, (in + offset), matSplat00, matSplat01, matSplat02, matSplat03); COMPUTE((out + offset )->y, (in + offset), matSplat10, matSplat11, matSplat12, matSplat13); COMPUTE((out + offset)->z, (in + offset), matSplat20, matSplat21, matSplat22, matSplat23) +#define COMPUTE_GROUP(resgroup,dataptr) COMPUTE(resgroup ## X, (dataptr), matSplat00, matSplat01, matSplat02, matSplat03); COMPUTE(resgroup ## Y, (dataptr), matSplat10, matSplat11, matSplat12, matSplat13); COMPUTE(resgroup ## Z, (dataptr), matSplat20, matSplat21, matSplat22, matSplat23) +#define WRITE_GROUP(ptr, resgroup) (ptr)->x = resgroup ## X; (ptr)->y = resgroup ## Y; (ptr)->z = resgroup ## Z + + /* + // stage 1 -- 6 ops for xyz, each w 12 cycle latency + res0X = MulSIMD( (invec)->y, matSplat01 ); + res0Temp = MaddSIMD((invec)->z, matSplat02, matSplat03); + // stage 2 -- 3 clocks for xyz + res0X = MaddSIMD( (invec)->x, matSplat00, res0X ); + // stage 3 -- 3 clocks for xyz + res0X = AddSIMD(res0X, res0Temp); + */ +#define COMPUTE_STAGE1_ROW(res, tempvar, invec, xsplat, ysplat, zsplat, transplat) res = MulSIMD( (invec)->y, ysplat ); tempvar = MaddSIMD((invec)->z, zsplat, transplat) +#define COMPUTE_STAGE2_ROW(res, tempvar, invec, xsplat, ysplat, zsplat, transplat) res = MaddSIMD( (invec)->x, xsplat, res ) +#define COMPUTE_STAGE3_ROW(res, tempvar, invec, xsplat, ysplat, zsplat, transplat) res = AddSIMD(res, tempvar) // frees up the tempvar + +#define COMPUTE_STAGE1_GROUP(resgroup, invec) COMPUTE_STAGE1_ROW(resgroup ## X, resgroup ## X ## Temp, invec, matSplat00, matSplat01, matSplat02, matSplat03);\ + COMPUTE_STAGE1_ROW(resgroup ## Y, resgroup ## Y ## Temp, invec, matSplat10, matSplat11, matSplat12, matSplat13);\ + COMPUTE_STAGE1_ROW(resgroup ## Z, resgroup ## Z ## Temp, invec, matSplat20, matSplat21, matSplat22, matSplat23) + +#define COMPUTE_STAGE2_GROUP(resgroup, invec) COMPUTE_STAGE2_ROW(resgroup ## X, resgroup ## X ## Temp, invec, matSplat00, matSplat01, matSplat02, matSplat03);\ + COMPUTE_STAGE2_ROW(resgroup ## Y, resgroup ## Y ## Temp, invec, matSplat10, matSplat11, matSplat12, matSplat13);\ + COMPUTE_STAGE2_ROW(resgroup ## Z, resgroup ## Z ## Temp, invec, matSplat20, matSplat21, matSplat22, matSplat23) + +#define COMPUTE_STAGE3_GROUP(resgroup, invec) COMPUTE_STAGE3_ROW(resgroup ## X, resgroup ## X ## Temp, invec, matSplat00, matSplat01, matSplat02, matSplat03);\ + COMPUTE_STAGE3_ROW(resgroup ## Y, resgroup ## Y ## Temp, invec, matSplat10, matSplat11, matSplat12, matSplat13);\ + COMPUTE_STAGE3_ROW(resgroup ## Z, resgroup ## Z ## Temp, invec, matSplat20, matSplat21, matSplat22, matSplat23) + + const FourVectors * const RESTRICT STOP = pVectors + numVectors; + + // Use techniques of loop scheduling to eliminate data hazards; process + // eight groups simultaneously so that we never have any operations stalling + // waiting for data. + // Note: this loop, while pretty fast, could be faster still -- you'll notice + // that it does all of its loads, then all computation, then writes everything + // out. If made truly cyclic, such that every line interleaved a stage 1, stage 2, + // stage 3, and write, then throughput could be higher (probably by about 50%). + while (pVectors < STOP) + { + // start prefetching the three cache lines + // we'll hit two iterations from now + __dcbt( sizeof(FourVectors) * 16, pVectors ); + __dcbt( sizeof(FourVectors) * 16 + 128, pVectors ); + __dcbt( sizeof(FourVectors) * 16 + 256, pVectors ); + + // synchro + COMPUTE_STAGE1_GROUP(res0, pVectors + 0); + COMPUTE_STAGE1_GROUP(res1, pVectors + 1); + COMPUTE_STAGE1_GROUP(res2, pVectors + 2); + COMPUTE_STAGE1_GROUP(res3, pVectors + 3); + + COMPUTE_STAGE2_GROUP(res0, pVectors + 0); + COMPUTE_STAGE1_GROUP(res4, pVectors + 4); + COMPUTE_STAGE2_GROUP(res1, pVectors + 1); + COMPUTE_STAGE1_GROUP(res5, pVectors + 5); + COMPUTE_STAGE2_GROUP(res2, pVectors + 2); + COMPUTE_STAGE1_GROUP(res6, pVectors + 6); + COMPUTE_STAGE2_GROUP(res3, pVectors + 3); + COMPUTE_STAGE1_GROUP(res7, pVectors + 7); + + COMPUTE_STAGE3_GROUP(res0, pVectors + 0); + COMPUTE_STAGE2_GROUP(res4, pVectors + 4); + COMPUTE_STAGE3_GROUP(res1, pVectors + 1); + COMPUTE_STAGE2_GROUP(res5, pVectors + 5); + COMPUTE_STAGE3_GROUP(res2, pVectors + 2); + COMPUTE_STAGE2_GROUP(res6, pVectors + 6); + COMPUTE_STAGE3_GROUP(res3, pVectors + 3); + COMPUTE_STAGE2_GROUP(res7, pVectors + 7); + + COMPUTE_STAGE3_GROUP(res4, pVectors + 4); + WRITE_GROUP( pVectors + 0, res0 ); + COMPUTE_STAGE3_GROUP(res5, pVectors + 5); + WRITE_GROUP( pVectors + 1, res1 ); + COMPUTE_STAGE3_GROUP(res6, pVectors + 6); + WRITE_GROUP( pVectors + 2, res2 ); + COMPUTE_STAGE3_GROUP(res7, pVectors + 7); + WRITE_GROUP( pVectors + 3, res3 ); + + WRITE_GROUP( pVectors + 4, res4 ); + WRITE_GROUP( pVectors + 5, res5 ); + WRITE_GROUP( pVectors + 6, res6 ); + WRITE_GROUP( pVectors + 7, res7 ); + + pVectors += 8; + } + + +#undef COMPUTE +#undef WRITE +#undef COMPUTE_STAGE1_ROW +#undef COMPUTE_STAGE2_ROW +#undef COMPUTE_STAGE3_ROW +#undef COMPUTE_STAGE1_GROUP +#undef COMPUTE_STAGE2_GROUP +#undef COMPUTE_STAGE3_GROUP +#undef COMPUTE_GROUP +#undef WRITE_GROUP +} +#endif + +// In-place version of above. It's necessary to have this, rather than just allowing pOut and pVectors +// to equal each other, because of the semantics of RESTRICT: pVectors and pOut must not be allowed +// to alias. (Simply un-restricting the pointers results in very poor scheduling.) +void FourVectors::TransformManyBy(FourVectors * RESTRICT pVectors, unsigned int numVectors, const matrix3x4_t& rotationMatrix ) +{ + Assert(numVectors > 0); + +#ifdef _X360 + // The really fast version of this function likes to operate on blocks of eight. So, chug through + // groups of eight, then deal with any leftovers. + int numVectorsRoundedToNearestEight = numVectors & (~0x07); + if (numVectors >= 8) + { + FourVectors_TransformManyGroupsOfEightBy_InPlace(pVectors, numVectorsRoundedToNearestEight, rotationMatrix); + numVectors -= numVectorsRoundedToNearestEight; + pVectors += numVectorsRoundedToNearestEight; + } +#endif + + // any left over? + if (numVectors > 0) + { + + // Splat out each of the entries in the matrix to a fltx4. Do this + // in the order that we will need them, to hide latency. I'm + // avoiding making an array of them, so that they'll remain in + // registers. + fltx4 matSplat00, matSplat01, matSplat02, matSplat03, // TWELVE REGISTERS + matSplat10, matSplat11, matSplat12, matSplat13, + matSplat20, matSplat21, matSplat22, matSplat23; + + { + // Load the matrix into local vectors. Sadly, matrix3x4_ts are + // often unaligned. The w components will be the transpose row of + // the matrix. + fltx4 matCol0 = LoadUnalignedSIMD(rotationMatrix[0]); + fltx4 matCol1 = LoadUnalignedSIMD(rotationMatrix[1]); + fltx4 matCol2 = LoadUnalignedSIMD(rotationMatrix[2]); + + matSplat00 = SplatXSIMD(matCol0); + matSplat01 = SplatYSIMD(matCol0); + matSplat02 = SplatZSIMD(matCol0); + matSplat03 = SplatWSIMD(matCol0); + + matSplat10 = SplatXSIMD(matCol1); + matSplat11 = SplatYSIMD(matCol1); + matSplat12 = SplatZSIMD(matCol1); + matSplat13 = SplatWSIMD(matCol1); + + matSplat20 = SplatXSIMD(matCol2); + matSplat21 = SplatYSIMD(matCol2); + matSplat22 = SplatZSIMD(matCol2); + matSplat23 = SplatWSIMD(matCol2); + } + + do + { + fltx4 resultX, resultY, resultZ; + // Trust in the compiler to schedule these operations correctly: + resultX = MaddSIMD(pVectors->z, matSplat02, MaddSIMD(pVectors->y, matSplat01, MaddSIMD(pVectors->x, matSplat00, matSplat03))); + resultY = MaddSIMD(pVectors->z, matSplat12, MaddSIMD(pVectors->y, matSplat11, MaddSIMD(pVectors->x, matSplat00, matSplat13))); + resultZ = MaddSIMD(pVectors->z, matSplat22, MaddSIMD(pVectors->y, matSplat21, MaddSIMD(pVectors->x, matSplat00, matSplat23))); + + pVectors->x = resultX; + pVectors->y = resultY; + pVectors->z = resultZ; + + ++pVectors; + --numVectors; + } while(numVectors > 0); + } +} + + +#endif + +// Transform many (horizontal) points in-place by a 3x4 matrix, +// here already loaded onto three fltx4 registers but not transposed. +// The points must be stored as 16-byte aligned. They are points +// and not vectors because we assume the w-component to be 1. +#ifdef _X360 +void TransformManyPointsBy(VectorAligned * RESTRICT pVectors, unsigned int numVectors, FLTX4 mRow0, FLTX4 mRow1, FLTX4 mRow2) +{ + /************************************************** + * Here is an elaborate and carefully scheduled * + * algorithm nicked from xboxmath.inl and hacked * + * up for 3x4 matrices. * + **************************************************/ + + COMPILE_TIME_ASSERT(sizeof(VectorAligned) == sizeof(XMFLOAT4)); // VectorAligned's need to be 16 bytes + + XMVECTOR R0[8], R1[8], R2[8]; + XMVECTOR vIn[8]; + + // C_ASSERT(UnrollCount == 8); + // C_ASSERT(sizeof(XMFLOAT4) == 16); + Assert(pVectors); + Assert(((UINT_PTR)pVectors & 3) == 0); // assert alignment + + UINT GroupIndex; + + VectorAligned * RESTRICT vCurrent = pVectors; + // sentinel pointers + VectorAligned * vStreamEnd, *vStreamGroupBase, *vStreamGroupEnd; + + { + // cook up the pointers from integer math. Necessary because otherwise we LHS all over + // the place. (Odd that this doesn't happen to the xbox math.) + + UINT_PTR InputVector = (UINT_PTR)pVectors; + UINT_PTR InputStreamEnd = InputVector + numVectors * sizeof(XMFLOAT4); + // compute start and end points on 128-byte alignment + UINT_PTR InputStreamCGroupBase = XMMin(InputVector + (XM_CACHE_LINE_SIZE - 1), InputStreamEnd) & ~(XM_CACHE_LINE_SIZE - 1); + UINT_PTR InputStreamCGroupEnd = InputStreamCGroupBase + ((InputStreamEnd - InputStreamCGroupBase) & ~(4 * XM_CACHE_LINE_SIZE - 1)); + + vStreamEnd = (VectorAligned *)InputStreamEnd; + vStreamGroupBase = (VectorAligned *)InputStreamCGroupBase; + vStreamGroupEnd = (VectorAligned *)InputStreamCGroupEnd; + } + + + __dcbt(0, vStreamGroupBase); + __dcbt(XM_CACHE_LINE_SIZE, vStreamGroupBase); + __dcbt(XM_CACHE_LINE_SIZE * 2, vStreamGroupBase); + __dcbt(XM_CACHE_LINE_SIZE * 3, vStreamGroupBase); + + while (vCurrent < vStreamGroupBase) + { + fltx4 vec = __lvx(vCurrent->Base(), 0); + + R0[0] = __vmsum4fp(vec, mRow0); + R1[0] = __vmsum4fp(vec, mRow1); + R2[0] = __vmsum4fp(vec, mRow2); + + __stvewx(R0[0], vCurrent->Base(), 0); + __stvewx(R1[0], vCurrent->Base(), 4); + __stvewx(R2[0], vCurrent->Base(), 8); + + vCurrent++; + } + + while (vCurrent < vStreamGroupEnd) + { + __dcbt(XM_CACHE_LINE_SIZE * 4, vCurrent); + __dcbt(XM_CACHE_LINE_SIZE * 5, vCurrent); + __dcbt(XM_CACHE_LINE_SIZE * 6, vCurrent); + __dcbt(XM_CACHE_LINE_SIZE * 7, vCurrent); + + for (GroupIndex = 0; GroupIndex < 4; GroupIndex++) + { + // all kinds of LHS on this pointer. Why? + VectorAligned* OutputVector = vCurrent; + + vIn[0] = __lvx(vCurrent->Base(), 0); + vCurrent++; + vIn[1] = __lvx(vCurrent->Base(), 0); + vCurrent++; + vIn[2] = __lvx(vCurrent->Base(), 0); + vCurrent++; + vIn[3] = __lvx(vCurrent->Base(), 0); + vCurrent++; + vIn[4] = __lvx(vCurrent->Base(), 0); + vCurrent++; + vIn[5] = __lvx(vCurrent->Base(), 0); + vCurrent++; + vIn[6] = __lvx(vCurrent->Base(), 0); + vCurrent++; + vIn[7] = __lvx(vCurrent->Base(), 0); + vCurrent++; + + R0[0] = __vmsum4fp(vIn[0], mRow0); + R1[0] = __vmsum4fp(vIn[0], mRow1); + R2[0] = __vmsum4fp(vIn[0], mRow2); + + R0[1] = __vmsum4fp(vIn[1], mRow0); + R1[1] = __vmsum4fp(vIn[1], mRow1); + R2[1] = __vmsum4fp(vIn[1], mRow2); + + R0[2] = __vmsum4fp(vIn[2], mRow0); + R1[2] = __vmsum4fp(vIn[2], mRow1); + R2[2] = __vmsum4fp(vIn[2], mRow2); + + R0[3] = __vmsum4fp(vIn[3], mRow0); + R1[3] = __vmsum4fp(vIn[3], mRow1); + R2[3] = __vmsum4fp(vIn[3], mRow2); + + R0[4] = __vmsum4fp(vIn[4], mRow0); + R1[4] = __vmsum4fp(vIn[4], mRow1); + R2[4] = __vmsum4fp(vIn[4], mRow2); + + R0[5] = __vmsum4fp(vIn[5], mRow0); + R1[5] = __vmsum4fp(vIn[5], mRow1); + R2[5] = __vmsum4fp(vIn[5], mRow2); + + R0[6] = __vmsum4fp(vIn[6], mRow0); + R1[6] = __vmsum4fp(vIn[6], mRow1); + R2[6] = __vmsum4fp(vIn[6], mRow2); + + R0[7] = __vmsum4fp(vIn[7], mRow0); + R1[7] = __vmsum4fp(vIn[7], mRow1); + R2[7] = __vmsum4fp(vIn[7], mRow2); + + __stvewx(R0[0], OutputVector, 0); + __stvewx(R1[0], OutputVector, 4); + __stvewx(R2[0], OutputVector, 8); + OutputVector++; + + __stvewx(R0[1], OutputVector, 0); + __stvewx(R1[1], OutputVector, 4); + __stvewx(R2[1], OutputVector, 8); + OutputVector++; + + __stvewx(R0[2], OutputVector, 0); + __stvewx(R1[2], OutputVector, 4); + __stvewx(R2[2], OutputVector, 8); + OutputVector++; + + __stvewx(R0[3], OutputVector, 0); + __stvewx(R1[3], OutputVector, 4); + __stvewx(R2[3], OutputVector, 8); + OutputVector++; + + __stvewx(R0[4], OutputVector, 0); + __stvewx(R1[4], OutputVector, 4); + __stvewx(R2[4], OutputVector, 8); + OutputVector++; + + __stvewx(R0[5], OutputVector, 0); + __stvewx(R1[5], OutputVector, 4); + __stvewx(R2[5], OutputVector, 8); + OutputVector++; + + __stvewx(R0[6], OutputVector, 0); + __stvewx(R1[6], OutputVector, 4); + __stvewx(R2[6], OutputVector, 8); + OutputVector++; + + __stvewx(R0[7], OutputVector, 0); + __stvewx(R1[7], OutputVector, 4); + __stvewx(R2[7], OutputVector, 8); + OutputVector++; + } + } + + while (vCurrent < vStreamEnd) + { + vIn[0] = __lvx(vCurrent->Base(), 0); + + R0[0] = __vmsum4fp(vIn[0], mRow0); + R1[0] = __vmsum4fp(vIn[0], mRow1); + R2[0] = __vmsum4fp(vIn[0], mRow2); + + __stvewx(R0[0], vCurrent->Base(), 0); + __stvewx(R1[0], vCurrent->Base(), 4); + __stvewx(R2[0], vCurrent->Base(), 8); + + vCurrent++; + } + + +} +#endif diff --git a/sp/src/mathlib/ssenoise.cpp b/sp/src/mathlib/ssenoise.cpp new file mode 100644 index 00000000..244a1e59 --- /dev/null +++ b/sp/src/mathlib/ssenoise.cpp @@ -0,0 +1,105 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Fast low quality noise suitable for real time use +// +//=====================================================================================// + +#include +#include // Needed for FLT_EPSILON +#include "basetypes.h" +#include +#include "tier0/dbg.h" +#include "mathlib/mathlib.h" +#include "mathlib/vector.h" +#include "mathlib/ssemath.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" +#include "noisedata.h" + + +#define MAGIC_NUMBER (1<<15) // gives 8 bits of fraction + +static fltx4 Four_MagicNumbers = { MAGIC_NUMBER, MAGIC_NUMBER, MAGIC_NUMBER, MAGIC_NUMBER }; + + +static ALIGN16 int32 idx_mask[4]= {0xffff, 0xffff, 0xffff, 0xffff}; + +#define MASK255 (*((fltx4 *)(& idx_mask ))) + +// returns 0..1 +static inline float GetLatticePointValue( int idx_x, int idx_y, int idx_z ) +{ + int ret_idx = perm_a[idx_x & 0xff]; + ret_idx = perm_b[( idx_y + ret_idx ) & 0xff]; + ret_idx = perm_c[( idx_z + ret_idx ) & 0xff]; + return impulse_xcoords[ret_idx]; + +} + +fltx4 NoiseSIMD( const fltx4 & x, const fltx4 & y, const fltx4 & z ) +{ + // use magic to convert to integer index + fltx4 x_idx = AndSIMD( MASK255, AddSIMD( x, Four_MagicNumbers ) ); + fltx4 y_idx = AndSIMD( MASK255, AddSIMD( y, Four_MagicNumbers ) ); + fltx4 z_idx = AndSIMD( MASK255, AddSIMD( z, Four_MagicNumbers ) ); + + fltx4 lattice000 = Four_Zeros, lattice001 = Four_Zeros, lattice010 = Four_Zeros, lattice011 = Four_Zeros; + fltx4 lattice100 = Four_Zeros, lattice101 = Four_Zeros, lattice110 = Four_Zeros, lattice111 = Four_Zeros; + + // FIXME: Converting the input vectors to int indices will cause load-hit-stores (48 bytes) + // Converting the indexed noise values back to vectors will cause more (128 bytes) + // The noise table could store vectors if we chunked it into 2x2x2 blocks. + fltx4 xfrac = Four_Zeros, yfrac = Four_Zeros, zfrac = Four_Zeros; +#define DOPASS(i) \ + { unsigned int xi = SubInt( x_idx, i ); \ + unsigned int yi = SubInt( y_idx, i ); \ + unsigned int zi = SubInt( z_idx, i ); \ + SubFloat( xfrac, i ) = (xi & 0xff)*(1.0/256.0); \ + SubFloat( yfrac, i ) = (yi & 0xff)*(1.0/256.0); \ + SubFloat( zfrac, i ) = (zi & 0xff)*(1.0/256.0); \ + xi>>=8; \ + yi>>=8; \ + zi>>=8; \ + \ + SubFloat( lattice000, i ) = GetLatticePointValue( xi,yi,zi ); \ + SubFloat( lattice001, i ) = GetLatticePointValue( xi,yi,zi+1 ); \ + SubFloat( lattice010, i ) = GetLatticePointValue( xi,yi+1,zi ); \ + SubFloat( lattice011, i ) = GetLatticePointValue( xi,yi+1,zi+1 ); \ + SubFloat( lattice100, i ) = GetLatticePointValue( xi+1,yi,zi ); \ + SubFloat( lattice101, i ) = GetLatticePointValue( xi+1,yi,zi+1 ); \ + SubFloat( lattice110, i ) = GetLatticePointValue( xi+1,yi+1,zi ); \ + SubFloat( lattice111, i ) = GetLatticePointValue( xi+1,yi+1,zi+1 ); \ + } + + DOPASS( 0 ); + DOPASS( 1 ); + DOPASS( 2 ); + DOPASS( 3 ); + + // now, we have 8 lattice values for each of four points as m128s, and interpolant values for + // each axis in m128 form in [xyz]frac. Perfom the trilinear interpolation as SIMD ops + + // first, do x interpolation + fltx4 l2d00 = AddSIMD( lattice000, MulSIMD( xfrac, SubSIMD( lattice100, lattice000 ) ) ); + fltx4 l2d01 = AddSIMD( lattice001, MulSIMD( xfrac, SubSIMD( lattice101, lattice001 ) ) ); + fltx4 l2d10 = AddSIMD( lattice010, MulSIMD( xfrac, SubSIMD( lattice110, lattice010 ) ) ); + fltx4 l2d11 = AddSIMD( lattice011, MulSIMD( xfrac, SubSIMD( lattice111, lattice011 ) ) ); + + // now, do y interpolation + fltx4 l1d0 = AddSIMD( l2d00, MulSIMD( yfrac, SubSIMD( l2d10, l2d00 ) ) ); + fltx4 l1d1 = AddSIMD( l2d01, MulSIMD( yfrac, SubSIMD( l2d11, l2d01 ) ) ); + + // final z interpolation + fltx4 rslt = AddSIMD( l1d0, MulSIMD( zfrac, SubSIMD( l1d1, l1d0 ) ) ); + + // map to 0..1 + return MulSIMD( Four_Twos, SubSIMD( rslt, Four_PointFives ) ); + + +} + +fltx4 NoiseSIMD( FourVectors const &pos ) +{ + return NoiseSIMD( pos.x, pos.y, pos.z ); +} diff --git a/sp/src/mathlib/vector.cpp b/sp/src/mathlib/vector.cpp new file mode 100644 index 00000000..5cb72d49 --- /dev/null +++ b/sp/src/mathlib/vector.cpp @@ -0,0 +1,12 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "mathlib/vector.h" + +Vector vec3_origin(0,0,0); + diff --git a/sp/src/mathlib/vmatrix.cpp b/sp/src/mathlib/vmatrix.cpp new file mode 100644 index 00000000..27546c0c --- /dev/null +++ b/sp/src/mathlib/vmatrix.cpp @@ -0,0 +1,1296 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#if !defined(_STATIC_LINKED) || defined(_SHARED_LIB) + +#include "basetypes.h" +#include "mathlib/vmatrix.h" +#include "mathlib/mathlib.h" +#include +#include "mathlib/vector4d.h" +#include "tier0/dbg.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#pragma warning (disable : 4700) // local variable 'x' used without having been initialized + +// ------------------------------------------------------------------------------------------- // +// Helper functions. +// ------------------------------------------------------------------------------------------- // + +#ifndef VECTOR_NO_SLOW_OPERATIONS + +VMatrix SetupMatrixIdentity() +{ + return VMatrix( + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); +} + +VMatrix SetupMatrixTranslation(const Vector &vTranslation) +{ + return VMatrix( + 1.0f, 0.0f, 0.0f, vTranslation.x, + 0.0f, 1.0f, 0.0f, vTranslation.y, + 0.0f, 0.0f, 1.0f, vTranslation.z, + 0.0f, 0.0f, 0.0f, 1.0f + ); +} + +VMatrix SetupMatrixScale(const Vector &vScale) +{ + return VMatrix( + vScale.x, 0.0f, 0.0f, 0.0f, + 0.0f, vScale.y, 0.0f, 0.0f, + 0.0f, 0.0f, vScale.z, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + ); +} + +VMatrix SetupMatrixReflection(const VPlane &thePlane) +{ + VMatrix mReflect, mBack, mForward; + Vector vOrigin, N; + + N = thePlane.m_Normal; + + mReflect.Init( + -2.0f*N.x*N.x + 1.0f, -2.0f*N.x*N.y, -2.0f*N.x*N.z, 0.0f, + -2.0f*N.y*N.x, -2.0f*N.y*N.y + 1.0f, -2.0f*N.y*N.z, 0.0f, + -2.0f*N.z*N.x, -2.0f*N.z*N.y, -2.0f*N.z*N.z + 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + ); + + vOrigin = thePlane.GetPointOnPlane(); + + mBack.Identity(); + mBack.SetTranslation(-vOrigin); + + mForward.Identity(); + mForward.SetTranslation(vOrigin); + + // (multiplied in reverse order, so it translates to the origin point, + // reflects, and translates back). + return mForward * mReflect * mBack; +} + +VMatrix SetupMatrixProjection(const Vector &vOrigin, const VPlane &thePlane) +{ + vec_t dot; + VMatrix mRet; + + + #define PN thePlane.m_Normal + #define PD thePlane.m_Dist; + + dot = PN[0]*vOrigin.x + PN[1]*vOrigin.y + PN[2]*vOrigin.z - PD; + + mRet.m[0][0] = dot - vOrigin.x * PN[0]; + mRet.m[0][1] = -vOrigin.x * PN[1]; + mRet.m[0][2] = -vOrigin.x * PN[2]; + mRet.m[0][3] = -vOrigin.x * -PD; + + mRet.m[1][0] = -vOrigin.y * PN[0]; + mRet.m[1][1] = dot - vOrigin.y * PN[1]; + mRet.m[1][2] = -vOrigin.y * PN[2]; + mRet.m[1][3] = -vOrigin.y * -PD; + + mRet.m[2][0] = -vOrigin.z * PN[0]; + mRet.m[2][1] = -vOrigin.z * PN[1]; + mRet.m[2][2] = dot - vOrigin.z * PN[2]; + mRet.m[2][3] = -vOrigin.z * -PD; + + mRet.m[3][0] = -PN[0]; + mRet.m[3][1] = -PN[1]; + mRet.m[3][2] = -PN[2]; + mRet.m[3][3] = dot + PD; + + #undef PN + #undef PD + + return mRet; +} + +VMatrix SetupMatrixAxisRot(const Vector &vAxis, vec_t fDegrees) +{ + vec_t s, c, t; + vec_t tx, ty, tz; + vec_t sx, sy, sz; + vec_t fRadians; + + + fRadians = fDegrees * (M_PI / 180.0f); + + s = (vec_t)sin(fRadians); + c = (vec_t)cos(fRadians); + t = 1.0f - c; + + tx = t * vAxis.x; ty = t * vAxis.y; tz = t * vAxis.z; + sx = s * vAxis.x; sy = s * vAxis.y; sz = s * vAxis.z; + + return VMatrix( + tx*vAxis.x + c, tx*vAxis.y - sz, tx*vAxis.z + sy, 0.0f, + tx*vAxis.y + sz, ty*vAxis.y + c, ty*vAxis.z - sx, 0.0f, + tx*vAxis.z - sy, ty*vAxis.z + sx, tz*vAxis.z + c, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); +} + +VMatrix SetupMatrixAngles(const QAngle &vAngles) +{ + VMatrix mRet; + MatrixFromAngles( vAngles, mRet ); + return mRet; +} + +VMatrix SetupMatrixOrgAngles(const Vector &origin, const QAngle &vAngles) +{ + VMatrix mRet; + mRet.SetupMatrixOrgAngles( origin, vAngles ); + return mRet; +} + +#endif // VECTOR_NO_SLOW_OPERATIONS + + +bool PlaneIntersection( const VPlane &vp1, const VPlane &vp2, const VPlane &vp3, Vector &vOut ) +{ + VMatrix mMat, mInverse; + + mMat.Init( + vp1.m_Normal.x, vp1.m_Normal.y, vp1.m_Normal.z, -vp1.m_Dist, + vp2.m_Normal.x, vp2.m_Normal.y, vp2.m_Normal.z, -vp2.m_Dist, + vp3.m_Normal.x, vp3.m_Normal.y, vp3.m_Normal.z, -vp3.m_Dist, + 0.0f, 0.0f, 0.0f, 1.0f + ); + + if(mMat.InverseGeneral(mInverse)) + { + //vOut = mInverse * Vector(0.0f, 0.0f, 0.0f); + mInverse.GetTranslation( vOut ); + return true; + } + else + { + return false; + } +} + + + +// ------------------------------------------------------------------------------------------- // +// VMatrix functions. +// ------------------------------------------------------------------------------------------- // + +VMatrix& VMatrix::operator=(const VMatrix &mOther) +{ + m[0][0] = mOther.m[0][0]; + m[0][1] = mOther.m[0][1]; + m[0][2] = mOther.m[0][2]; + m[0][3] = mOther.m[0][3]; + + m[1][0] = mOther.m[1][0]; + m[1][1] = mOther.m[1][1]; + m[1][2] = mOther.m[1][2]; + m[1][3] = mOther.m[1][3]; + + m[2][0] = mOther.m[2][0]; + m[2][1] = mOther.m[2][1]; + m[2][2] = mOther.m[2][2]; + m[2][3] = mOther.m[2][3]; + + m[3][0] = mOther.m[3][0]; + m[3][1] = mOther.m[3][1]; + m[3][2] = mOther.m[3][2]; + m[3][3] = mOther.m[3][3]; + + return *this; +} + +bool VMatrix::operator==( const VMatrix& src ) const +{ + return !memcmp( src.m, m, sizeof(m) ); +} + +void VMatrix::MatrixMul( const VMatrix &vm, VMatrix &out ) const +{ + out.Init( + m[0][0]*vm.m[0][0] + m[0][1]*vm.m[1][0] + m[0][2]*vm.m[2][0] + m[0][3]*vm.m[3][0], + m[0][0]*vm.m[0][1] + m[0][1]*vm.m[1][1] + m[0][2]*vm.m[2][1] + m[0][3]*vm.m[3][1], + m[0][0]*vm.m[0][2] + m[0][1]*vm.m[1][2] + m[0][2]*vm.m[2][2] + m[0][3]*vm.m[3][2], + m[0][0]*vm.m[0][3] + m[0][1]*vm.m[1][3] + m[0][2]*vm.m[2][3] + m[0][3]*vm.m[3][3], + + m[1][0]*vm.m[0][0] + m[1][1]*vm.m[1][0] + m[1][2]*vm.m[2][0] + m[1][3]*vm.m[3][0], + m[1][0]*vm.m[0][1] + m[1][1]*vm.m[1][1] + m[1][2]*vm.m[2][1] + m[1][3]*vm.m[3][1], + m[1][0]*vm.m[0][2] + m[1][1]*vm.m[1][2] + m[1][2]*vm.m[2][2] + m[1][3]*vm.m[3][2], + m[1][0]*vm.m[0][3] + m[1][1]*vm.m[1][3] + m[1][2]*vm.m[2][3] + m[1][3]*vm.m[3][3], + + m[2][0]*vm.m[0][0] + m[2][1]*vm.m[1][0] + m[2][2]*vm.m[2][0] + m[2][3]*vm.m[3][0], + m[2][0]*vm.m[0][1] + m[2][1]*vm.m[1][1] + m[2][2]*vm.m[2][1] + m[2][3]*vm.m[3][1], + m[2][0]*vm.m[0][2] + m[2][1]*vm.m[1][2] + m[2][2]*vm.m[2][2] + m[2][3]*vm.m[3][2], + m[2][0]*vm.m[0][3] + m[2][1]*vm.m[1][3] + m[2][2]*vm.m[2][3] + m[2][3]*vm.m[3][3], + + m[3][0]*vm.m[0][0] + m[3][1]*vm.m[1][0] + m[3][2]*vm.m[2][0] + m[3][3]*vm.m[3][0], + m[3][0]*vm.m[0][1] + m[3][1]*vm.m[1][1] + m[3][2]*vm.m[2][1] + m[3][3]*vm.m[3][1], + m[3][0]*vm.m[0][2] + m[3][1]*vm.m[1][2] + m[3][2]*vm.m[2][2] + m[3][3]*vm.m[3][2], + m[3][0]*vm.m[0][3] + m[3][1]*vm.m[1][3] + m[3][2]*vm.m[2][3] + m[3][3]*vm.m[3][3] + ); +} + +#ifndef VECTOR_NO_SLOW_OPERATIONS + +VMatrix VMatrix::operator*(const VMatrix &vm) const +{ + VMatrix ret; + MatrixMul( vm, ret ); + return ret; +} + +#endif + +bool VMatrix::InverseGeneral(VMatrix &vInverse) const +{ + return MatrixInverseGeneral( *this, vInverse ); +} + + +bool MatrixInverseGeneral(const VMatrix& src, VMatrix& dst) +{ + int iRow, i, j, iTemp, iTest; + vec_t mul, fTest, fLargest; + vec_t mat[4][8]; + int rowMap[4], iLargest; + vec_t *pOut, *pRow, *pScaleRow; + + + // How it's done. + // AX = I + // A = this + // X = the matrix we're looking for + // I = identity + + // Setup AI + for(i=0; i < 4; i++) + { + const vec_t *pIn = src[i]; + pOut = mat[i]; + + for(j=0; j < 4; j++) + { + pOut[j] = pIn[j]; + } + + pOut[4] = 0.0f; + pOut[5] = 0.0f; + pOut[6] = 0.0f; + pOut[7] = 0.0f; + pOut[i+4] = 1.0f; + + rowMap[i] = i; + } + + // Use row operations to get to reduced row-echelon form using these rules: + // 1. Multiply or divide a row by a nonzero number. + // 2. Add a multiple of one row to another. + // 3. Interchange two rows. + + for(iRow=0; iRow < 4; iRow++) + { + // Find the row with the largest element in this column. + fLargest = 0.00001f; + iLargest = -1; + for(iTest=iRow; iTest < 4; iTest++) + { + fTest = (vec_t)FloatMakePositive(mat[rowMap[iTest]][iRow]); + if(fTest > fLargest) + { + iLargest = iTest; + fLargest = fTest; + } + } + + // They're all too small.. sorry. + if(iLargest == -1) + { + return false; + } + + // Swap the rows. + iTemp = rowMap[iLargest]; + rowMap[iLargest] = rowMap[iRow]; + rowMap[iRow] = iTemp; + + pRow = mat[rowMap[iRow]]; + + // Divide this row by the element. + mul = 1.0f / pRow[iRow]; + for(j=0; j < 8; j++) + pRow[j] *= mul; + + pRow[iRow] = 1.0f; // Preserve accuracy... + + // Eliminate this element from the other rows using operation 2. + for(i=0; i < 4; i++) + { + if(i == iRow) + continue; + + pScaleRow = mat[rowMap[i]]; + + // Multiply this row by -(iRow*the element). + mul = -pScaleRow[iRow]; + for(j=0; j < 8; j++) + { + pScaleRow[j] += pRow[j] * mul; + } + + pScaleRow[iRow] = 0.0f; // Preserve accuracy... + } + } + + // The inverse is on the right side of AX now (the identity is on the left). + for(i=0; i < 4; i++) + { + const vec_t *pIn = mat[rowMap[i]] + 4; + pOut = dst.m[i]; + + for(j=0; j < 4; j++) + { + pOut[j] = pIn[j]; + } + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Does a fast inverse, assuming the matrix only contains translation and rotation. +//----------------------------------------------------------------------------- +void MatrixInverseTR( const VMatrix& src, VMatrix &dst ) +{ + Vector vTrans, vNewTrans; + + // Transpose the upper 3x3. + dst.m[0][0] = src.m[0][0]; dst.m[0][1] = src.m[1][0]; dst.m[0][2] = src.m[2][0]; + dst.m[1][0] = src.m[0][1]; dst.m[1][1] = src.m[1][1]; dst.m[1][2] = src.m[2][1]; + dst.m[2][0] = src.m[0][2]; dst.m[2][1] = src.m[1][2]; dst.m[2][2] = src.m[2][2]; + + // Transform the translation. + vTrans.Init( -src.m[0][3], -src.m[1][3], -src.m[2][3] ); + Vector3DMultiply( dst, vTrans, vNewTrans ); + MatrixSetColumn( dst, 3, vNewTrans ); + + // Fill in the bottom row. + dst.m[3][0] = dst.m[3][1] = dst.m[3][2] = 0.0f; + dst.m[3][3] = 1.0f; +} + + +void VMatrix::InverseTR( VMatrix &ret ) const +{ + MatrixInverseTR( *this, ret ); +} + +void MatrixInverseTranspose( const VMatrix& src, VMatrix& dst ) +{ + src.InverseGeneral( dst ); + MatrixTranspose( dst, dst ); +} + +//----------------------------------------------------------------------------- +// Computes the inverse transpose +//----------------------------------------------------------------------------- +void MatrixInverseTranspose( const matrix3x4_t& src, matrix3x4_t& dst ) +{ + VMatrix tmp, out; + tmp.CopyFrom3x4( src ); + ::MatrixInverseTranspose( tmp, out ); + out.Set3x4( dst ); +} + + +#ifndef VECTOR_NO_SLOW_OPERATIONS + +VMatrix VMatrix::InverseTR() const +{ + VMatrix ret; + MatrixInverseTR( *this, ret ); + return ret; +} + +Vector VMatrix::GetScale() const +{ + Vector vecs[3]; + + GetBasisVectors(vecs[0], vecs[1], vecs[2]); + + return Vector( + vecs[0].Length(), + vecs[1].Length(), + vecs[2].Length() + ); +} + +VMatrix VMatrix::Scale(const Vector &vScale) +{ + return VMatrix( + m[0][0]*vScale.x, m[0][1]*vScale.y, m[0][2]*vScale.z, m[0][3], + m[1][0]*vScale.x, m[1][1]*vScale.y, m[1][2]*vScale.z, m[1][3], + m[2][0]*vScale.x, m[2][1]*vScale.y, m[2][2]*vScale.z, m[2][3], + m[3][0]*vScale.x, m[3][1]*vScale.y, m[3][2]*vScale.z, 1.0f + ); +} + +VMatrix VMatrix::NormalizeBasisVectors() const +{ + Vector vecs[3]; + VMatrix mRet; + + + GetBasisVectors(vecs[0], vecs[1], vecs[2]); + + VectorNormalize( vecs[0] ); + VectorNormalize( vecs[1] ); + VectorNormalize( vecs[2] ); + + mRet.SetBasisVectors(vecs[0], vecs[1], vecs[2]); + + // Set everything but basis vectors to identity. + mRet.m[3][0] = mRet.m[3][1] = mRet.m[3][2] = 0.0f; + mRet.m[3][3] = 1.0f; + + return mRet; +} + +VMatrix VMatrix::Transpose() const +{ + return VMatrix( + m[0][0], m[1][0], m[2][0], m[3][0], + m[0][1], m[1][1], m[2][1], m[3][1], + m[0][2], m[1][2], m[2][2], m[3][2], + m[0][3], m[1][3], m[2][3], m[3][3]); +} + +// Transpose upper-left 3x3. +VMatrix VMatrix::Transpose3x3() const +{ + return VMatrix( + m[0][0], m[1][0], m[2][0], m[0][3], + m[0][1], m[1][1], m[2][1], m[1][3], + m[0][2], m[1][2], m[2][2], m[2][3], + m[3][0], m[3][1], m[3][2], m[3][3]); +} + +#endif // VECTOR_NO_SLOW_OPERATIONS + + +bool VMatrix::IsRotationMatrix() const +{ + Vector &v1 = (Vector&)m[0][0]; + Vector &v2 = (Vector&)m[1][0]; + Vector &v3 = (Vector&)m[2][0]; + + return + FloatMakePositive( 1 - v1.Length() ) < 0.01f && + FloatMakePositive( 1 - v2.Length() ) < 0.01f && + FloatMakePositive( 1 - v3.Length() ) < 0.01f && + FloatMakePositive( v1.Dot(v2) ) < 0.01f && + FloatMakePositive( v1.Dot(v3) ) < 0.01f && + FloatMakePositive( v2.Dot(v3) ) < 0.01f; +} + +static void SetupMatrixAnglesInternal( vec_t m[4][4], const QAngle & vAngles ) +{ + float sr, sp, sy, cr, cp, cy; + + SinCos( DEG2RAD( vAngles[YAW] ), &sy, &cy ); + SinCos( DEG2RAD( vAngles[PITCH] ), &sp, &cp ); + SinCos( DEG2RAD( vAngles[ROLL] ), &sr, &cr ); + + // matrix = (YAW * PITCH) * ROLL + m[0][0] = cp*cy; + m[1][0] = cp*sy; + m[2][0] = -sp; + m[0][1] = sr*sp*cy+cr*-sy; + m[1][1] = sr*sp*sy+cr*cy; + m[2][1] = sr*cp; + m[0][2] = (cr*sp*cy+-sr*-sy); + m[1][2] = (cr*sp*sy+-sr*cy); + m[2][2] = cr*cp; + m[0][3] = 0.f; + m[1][3] = 0.f; + m[2][3] = 0.f; +} + +void VMatrix::SetupMatrixOrgAngles( const Vector &origin, const QAngle &vAngles ) +{ + SetupMatrixAnglesInternal( m, vAngles ); + + // Add translation + m[0][3] = origin.x; + m[1][3] = origin.y; + m[2][3] = origin.z; + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = 0.0f; + m[3][3] = 1.0f; +} + + +void VMatrix::SetupMatrixAngles( const QAngle &vAngles ) +{ + SetupMatrixAnglesInternal( m, vAngles ); + + // Zero everything else + m[0][3] = 0.0f; + m[1][3] = 0.0f; + m[2][3] = 0.0f; + m[3][0] = 0.0f; + m[3][1] = 0.0f; + m[3][2] = 0.0f; + m[3][3] = 1.0f; +} + + +//----------------------------------------------------------------------------- +// Sets matrix to identity +//----------------------------------------------------------------------------- +void MatrixSetIdentity( VMatrix &dst ) +{ + dst[0][0] = 1.0f; dst[0][1] = 0.0f; dst[0][2] = 0.0f; dst[0][3] = 0.0f; + dst[1][0] = 0.0f; dst[1][1] = 1.0f; dst[1][2] = 0.0f; dst[1][3] = 0.0f; + dst[2][0] = 0.0f; dst[2][1] = 0.0f; dst[2][2] = 1.0f; dst[2][3] = 0.0f; + dst[3][0] = 0.0f; dst[3][1] = 0.0f; dst[3][2] = 0.0f; dst[3][3] = 1.0f; +} + + +//----------------------------------------------------------------------------- +// Setup a matrix from euler angles. +//----------------------------------------------------------------------------- +void MatrixFromAngles( const QAngle& vAngles, VMatrix& dst ) +{ + dst.SetupMatrixOrgAngles( vec3_origin, vAngles ); +} + + +//----------------------------------------------------------------------------- +// Creates euler angles from a matrix +//----------------------------------------------------------------------------- +void MatrixToAngles( const VMatrix& src, QAngle& vAngles ) +{ + float forward[3]; + float left[3]; + float up[3]; + + // Extract the basis vectors from the matrix. Since we only need the Z + // component of the up vector, we don't get X and Y. + forward[0] = src[0][0]; + forward[1] = src[1][0]; + forward[2] = src[2][0]; + left[0] = src[0][1]; + left[1] = src[1][1]; + left[2] = src[2][1]; + up[2] = src[2][2]; + + float xyDist = sqrtf( forward[0] * forward[0] + forward[1] * forward[1] ); + + // enough here to get angles? + if ( xyDist > 0.001f ) + { + // (yaw) y = ATAN( forward.y, forward.x ); -- in our space, forward is the X axis + vAngles[1] = RAD2DEG( atan2f( forward[1], forward[0] ) ); + + // The engine does pitch inverted from this, but we always end up negating it in the DLL + // UNDONE: Fix the engine to make it consistent + // (pitch) x = ATAN( -forward.z, sqrt(forward.x*forward.x+forward.y*forward.y) ); + vAngles[0] = RAD2DEG( atan2f( -forward[2], xyDist ) ); + + // (roll) z = ATAN( left.z, up.z ); + vAngles[2] = RAD2DEG( atan2f( left[2], up[2] ) ); + } + else // forward is mostly Z, gimbal lock- + { + // (yaw) y = ATAN( -left.x, left.y ); -- forward is mostly z, so use right for yaw + vAngles[1] = RAD2DEG( atan2f( -left[0], left[1] ) ); + + // The engine does pitch inverted from this, but we always end up negating it in the DLL + // UNDONE: Fix the engine to make it consistent + // (pitch) x = ATAN( -forward.z, sqrt(forward.x*forward.x+forward.y*forward.y) ); + vAngles[0] = RAD2DEG( atan2f( -forward[2], xyDist ) ); + + // Assume no roll in this case as one degree of freedom has been lost (i.e. yaw == roll) + vAngles[2] = 0; + } +} + + +//----------------------------------------------------------------------------- +// Transpose +//----------------------------------------------------------------------------- +inline void Swap( float& a, float& b ) +{ + float tmp = a; + a = b; + b = tmp; +} + +void MatrixTranspose( const VMatrix& src, VMatrix& dst ) +{ + if (&src == &dst) + { + Swap( dst[0][1], dst[1][0] ); + Swap( dst[0][2], dst[2][0] ); + Swap( dst[0][3], dst[3][0] ); + Swap( dst[1][2], dst[2][1] ); + Swap( dst[1][3], dst[3][1] ); + Swap( dst[2][3], dst[3][2] ); + } + else + { + dst[0][0] = src[0][0]; dst[0][1] = src[1][0]; dst[0][2] = src[2][0]; dst[0][3] = src[3][0]; + dst[1][0] = src[0][1]; dst[1][1] = src[1][1]; dst[1][2] = src[2][1]; dst[1][3] = src[3][1]; + dst[2][0] = src[0][2]; dst[2][1] = src[1][2]; dst[2][2] = src[2][2]; dst[2][3] = src[3][2]; + dst[3][0] = src[0][3]; dst[3][1] = src[1][3]; dst[3][2] = src[2][3]; dst[3][3] = src[3][3]; + } +} + + +//----------------------------------------------------------------------------- +// Matrix copy +//----------------------------------------------------------------------------- + +void MatrixCopy( const VMatrix& src, VMatrix& dst ) +{ + if (&src != &dst) + { + memcpy( dst.m, src.m, 16 * sizeof(float) ); + } +} + +//----------------------------------------------------------------------------- +// Matrix multiply +//----------------------------------------------------------------------------- +typedef float VMatrixRaw_t[4]; + +void MatrixMultiply( const VMatrix& src1, const VMatrix& src2, VMatrix& dst ) +{ + // Make sure it works if src1 == dst or src2 == dst + VMatrix tmp1, tmp2; + const VMatrixRaw_t* s1 = (&src1 == &dst) ? tmp1.m : src1.m; + const VMatrixRaw_t* s2 = (&src2 == &dst) ? tmp2.m : src2.m; + + if (&src1 == &dst) + { + MatrixCopy( src1, tmp1 ); + } + if (&src2 == &dst) + { + MatrixCopy( src2, tmp2 ); + } + + dst[0][0] = s1[0][0] * s2[0][0] + s1[0][1] * s2[1][0] + s1[0][2] * s2[2][0] + s1[0][3] * s2[3][0]; + dst[0][1] = s1[0][0] * s2[0][1] + s1[0][1] * s2[1][1] + s1[0][2] * s2[2][1] + s1[0][3] * s2[3][1]; + dst[0][2] = s1[0][0] * s2[0][2] + s1[0][1] * s2[1][2] + s1[0][2] * s2[2][2] + s1[0][3] * s2[3][2]; + dst[0][3] = s1[0][0] * s2[0][3] + s1[0][1] * s2[1][3] + s1[0][2] * s2[2][3] + s1[0][3] * s2[3][3]; + + dst[1][0] = s1[1][0] * s2[0][0] + s1[1][1] * s2[1][0] + s1[1][2] * s2[2][0] + s1[1][3] * s2[3][0]; + dst[1][1] = s1[1][0] * s2[0][1] + s1[1][1] * s2[1][1] + s1[1][2] * s2[2][1] + s1[1][3] * s2[3][1]; + dst[1][2] = s1[1][0] * s2[0][2] + s1[1][1] * s2[1][2] + s1[1][2] * s2[2][2] + s1[1][3] * s2[3][2]; + dst[1][3] = s1[1][0] * s2[0][3] + s1[1][1] * s2[1][3] + s1[1][2] * s2[2][3] + s1[1][3] * s2[3][3]; + + dst[2][0] = s1[2][0] * s2[0][0] + s1[2][1] * s2[1][0] + s1[2][2] * s2[2][0] + s1[2][3] * s2[3][0]; + dst[2][1] = s1[2][0] * s2[0][1] + s1[2][1] * s2[1][1] + s1[2][2] * s2[2][1] + s1[2][3] * s2[3][1]; + dst[2][2] = s1[2][0] * s2[0][2] + s1[2][1] * s2[1][2] + s1[2][2] * s2[2][2] + s1[2][3] * s2[3][2]; + dst[2][3] = s1[2][0] * s2[0][3] + s1[2][1] * s2[1][3] + s1[2][2] * s2[2][3] + s1[2][3] * s2[3][3]; + + dst[3][0] = s1[3][0] * s2[0][0] + s1[3][1] * s2[1][0] + s1[3][2] * s2[2][0] + s1[3][3] * s2[3][0]; + dst[3][1] = s1[3][0] * s2[0][1] + s1[3][1] * s2[1][1] + s1[3][2] * s2[2][1] + s1[3][3] * s2[3][1]; + dst[3][2] = s1[3][0] * s2[0][2] + s1[3][1] * s2[1][2] + s1[3][2] * s2[2][2] + s1[3][3] * s2[3][2]; + dst[3][3] = s1[3][0] * s2[0][3] + s1[3][1] * s2[1][3] + s1[3][2] * s2[2][3] + s1[3][3] * s2[3][3]; +} + +//----------------------------------------------------------------------------- +// Matrix/vector multiply +//----------------------------------------------------------------------------- + +void Vector4DMultiply( const VMatrix& src1, Vector4D const& src2, Vector4D& dst ) +{ + // Make sure it works if src2 == dst + Vector4D tmp; + Vector4D const&v = (&src2 == &dst) ? tmp : src2; + + if (&src2 == &dst) + { + Vector4DCopy( src2, tmp ); + } + + dst[0] = src1[0][0] * v[0] + src1[0][1] * v[1] + src1[0][2] * v[2] + src1[0][3] * v[3]; + dst[1] = src1[1][0] * v[0] + src1[1][1] * v[1] + src1[1][2] * v[2] + src1[1][3] * v[3]; + dst[2] = src1[2][0] * v[0] + src1[2][1] * v[1] + src1[2][2] * v[2] + src1[2][3] * v[3]; + dst[3] = src1[3][0] * v[0] + src1[3][1] * v[1] + src1[3][2] * v[2] + src1[3][3] * v[3]; +} + +//----------------------------------------------------------------------------- +// Matrix/vector multiply +//----------------------------------------------------------------------------- + +void Vector4DMultiplyPosition( const VMatrix& src1, Vector const& src2, Vector4D& dst ) +{ + // Make sure it works if src2 == dst + Vector tmp; + Vector const&v = ( &src2 == &dst.AsVector3D() ) ? static_cast(tmp) : src2; + + if (&src2 == &dst.AsVector3D()) + { + VectorCopy( src2, tmp ); + } + + dst[0] = src1[0][0] * v[0] + src1[0][1] * v[1] + src1[0][2] * v[2] + src1[0][3]; + dst[1] = src1[1][0] * v[0] + src1[1][1] * v[1] + src1[1][2] * v[2] + src1[1][3]; + dst[2] = src1[2][0] * v[0] + src1[2][1] * v[1] + src1[2][2] * v[2] + src1[2][3]; + dst[3] = src1[3][0] * v[0] + src1[3][1] * v[1] + src1[3][2] * v[2] + src1[3][3]; +} + + + +//----------------------------------------------------------------------------- +// Matrix/vector multiply +//----------------------------------------------------------------------------- + +void Vector3DMultiply( const VMatrix &src1, const Vector &src2, Vector &dst ) +{ + // Make sure it works if src2 == dst + Vector tmp; + const Vector &v = (&src2 == &dst) ? static_cast(tmp) : src2; + + if( &src2 == &dst ) + { + VectorCopy( src2, tmp ); + } + + dst[0] = src1[0][0] * v[0] + src1[0][1] * v[1] + src1[0][2] * v[2]; + dst[1] = src1[1][0] * v[0] + src1[1][1] * v[1] + src1[1][2] * v[2]; + dst[2] = src1[2][0] * v[0] + src1[2][1] * v[1] + src1[2][2] * v[2]; +} + + +//----------------------------------------------------------------------------- +// Vector3DMultiplyPositionProjective treats src2 as if it's a point +// and does the perspective divide at the end +//----------------------------------------------------------------------------- +void Vector3DMultiplyPositionProjective( const VMatrix& src1, const Vector &src2, Vector& dst ) +{ + // Make sure it works if src2 == dst + Vector tmp; + const Vector &v = (&src2 == &dst) ? static_cast(tmp): src2; + if( &src2 == &dst ) + { + VectorCopy( src2, tmp ); + } + + float w = src1[3][0] * v[0] + src1[3][1] * v[1] + src1[3][2] * v[2] + src1[3][3]; + if ( w != 0.0f ) + { + w = 1.0f / w; + } + + dst[0] = src1[0][0] * v[0] + src1[0][1] * v[1] + src1[0][2] * v[2] + src1[0][3]; + dst[1] = src1[1][0] * v[0] + src1[1][1] * v[1] + src1[1][2] * v[2] + src1[1][3]; + dst[2] = src1[2][0] * v[0] + src1[2][1] * v[1] + src1[2][2] * v[2] + src1[2][3]; + dst *= w; +} + + +//----------------------------------------------------------------------------- +// Vector3DMultiplyProjective treats src2 as if it's a direction +// and does the perspective divide at the end +//----------------------------------------------------------------------------- +void Vector3DMultiplyProjective( const VMatrix& src1, const Vector &src2, Vector& dst ) +{ + // Make sure it works if src2 == dst + Vector tmp; + const Vector &v = (&src2 == &dst) ? static_cast(tmp) : src2; + if( &src2 == &dst ) + { + VectorCopy( src2, tmp ); + } + + float w; + dst[0] = src1[0][0] * v[0] + src1[0][1] * v[1] + src1[0][2] * v[2]; + dst[1] = src1[1][0] * v[0] + src1[1][1] * v[1] + src1[1][2] * v[2]; + dst[2] = src1[2][0] * v[0] + src1[2][1] * v[1] + src1[2][2] * v[2]; + w = src1[3][0] * v[0] + src1[3][1] * v[1] + src1[3][2] * v[2]; + if (w != 0.0f) + { + dst /= w; + } + else + { + dst = vec3_origin; + } +} + + +//----------------------------------------------------------------------------- +// Multiplies the vector by the transpose of the matrix +//----------------------------------------------------------------------------- +void Vector4DMultiplyTranspose( const VMatrix& src1, Vector4D const& src2, Vector4D& dst ) +{ + // Make sure it works if src2 == dst + bool srcEqualsDst = (&src2 == &dst); + + Vector4D tmp; + Vector4D const&v = srcEqualsDst ? tmp : src2; + + if (srcEqualsDst) + { + Vector4DCopy( src2, tmp ); + } + + dst[0] = src1[0][0] * v[0] + src1[1][0] * v[1] + src1[2][0] * v[2] + src1[3][0] * v[3]; + dst[1] = src1[0][1] * v[0] + src1[1][1] * v[1] + src1[2][1] * v[2] + src1[3][1] * v[3]; + dst[2] = src1[0][2] * v[0] + src1[1][2] * v[1] + src1[2][2] * v[2] + src1[3][2] * v[3]; + dst[3] = src1[0][3] * v[0] + src1[1][3] * v[1] + src1[2][3] * v[2] + src1[3][3] * v[3]; +} + +//----------------------------------------------------------------------------- +// Multiplies the vector by the transpose of the matrix +//----------------------------------------------------------------------------- +void Vector3DMultiplyTranspose( const VMatrix& src1, const Vector& src2, Vector& dst ) +{ + // Make sure it works if src2 == dst + bool srcEqualsDst = (&src2 == &dst); + + Vector tmp; + const Vector&v = srcEqualsDst ? static_cast(tmp) : src2; + + if (srcEqualsDst) + { + VectorCopy( src2, tmp ); + } + + dst[0] = src1[0][0] * v[0] + src1[1][0] * v[1] + src1[2][0] * v[2]; + dst[1] = src1[0][1] * v[0] + src1[1][1] * v[1] + src1[2][1] * v[2]; + dst[2] = src1[0][2] * v[0] + src1[1][2] * v[1] + src1[2][2] * v[2]; +} + + +//----------------------------------------------------------------------------- +// Transform a plane +//----------------------------------------------------------------------------- +void MatrixTransformPlane( const VMatrix &src, const cplane_t &inPlane, cplane_t &outPlane ) +{ + // What we want to do is the following: + // 1) transform the normal into the new space. + // 2) Determine a point on the old plane given by plane dist * plane normal + // 3) Transform that point into the new space + // 4) Plane dist = DotProduct( new normal, new point ) + + // An optimized version, which works if the plane is orthogonal. + // 1) Transform the normal into the new space + // 2) Realize that transforming the old plane point into the new space + // is given by [ d * n'x + Tx, d * n'y + Ty, d * n'z + Tz ] + // where d = old plane dist, n' = transformed normal, Tn = translational component of transform + // 3) Compute the new plane dist using the dot product of the normal result of #2 + + // For a correct result, this should be an inverse-transpose matrix + // but that only matters if there are nonuniform scale or skew factors in this matrix. + Vector vTrans; + Vector3DMultiply( src, inPlane.normal, outPlane.normal ); + outPlane.dist = inPlane.dist * DotProduct( outPlane.normal, outPlane.normal ); + outPlane.dist += DotProduct( outPlane.normal, src.GetTranslation(vTrans) ); +} + + +#ifndef VECTOR_NO_SLOW_OPERATIONS + +VPlane VMatrix::operator*(const VPlane &thePlane) const +{ + VPlane ret; + TransformPlane( thePlane, ret ); + return ret; +} + +#endif + + +//----------------------------------------------------------------------------- +// Builds a rotation matrix that rotates one direction vector into another +//----------------------------------------------------------------------------- +void MatrixBuildTranslation( VMatrix& dst, float x, float y, float z ) +{ + MatrixSetIdentity( dst ); + dst[0][3] = x; + dst[1][3] = y; + dst[2][3] = z; +} + +void MatrixBuildTranslation( VMatrix& dst, const Vector &translation ) +{ + MatrixSetIdentity( dst ); + dst[0][3] = translation[0]; + dst[1][3] = translation[1]; + dst[2][3] = translation[2]; +} + + +//----------------------------------------------------------------------------- +// Purpose: Builds the matrix for a counterclockwise rotation about an arbitrary axis. +// +// | ax2 + (1 - ax2)cosQ axay(1 - cosQ) - azsinQ azax(1 - cosQ) + aysinQ | +// Ra(Q) = | axay(1 - cosQ) + azsinQ ay2 + (1 - ay2)cosQ ayaz(1 - cosQ) - axsinQ | +// | azax(1 - cosQ) - aysinQ ayaz(1 - cosQ) + axsinQ az2 + (1 - az2)cosQ | +// +// Input : mat - +// vAxisOrRot - +// angle - +//----------------------------------------------------------------------------- +void MatrixBuildRotationAboutAxis( VMatrix &dst, const Vector &vAxisOfRot, float angleDegrees ) +{ + MatrixBuildRotationAboutAxis( vAxisOfRot, angleDegrees, dst.As3x4() ); + dst[3][0] = 0; + dst[3][1] = 0; + dst[3][2] = 0; + dst[3][3] = 1; +} + + +//----------------------------------------------------------------------------- +// Builds a rotation matrix that rotates one direction vector into another +//----------------------------------------------------------------------------- +void MatrixBuildRotation( VMatrix &dst, const Vector& initialDirection, const Vector& finalDirection ) +{ + float angle = DotProduct( initialDirection, finalDirection ); + Assert( IsFinite(angle) ); + + Vector axis; + + // No rotation required + if (angle - 1.0 > -1e-3) + { + // parallel case + MatrixSetIdentity(dst); + return; + } + else if (angle + 1.0 < 1e-3) + { + // antiparallel case, pick any axis in the plane + // perpendicular to the final direction. Choose the direction (x,y,z) + // which has the minimum component of the final direction, use that + // as an initial guess, then subtract out the component which is + // parallel to the final direction + int idx = 0; + if (FloatMakePositive(finalDirection[1]) < FloatMakePositive(finalDirection[idx])) + idx = 1; + if (FloatMakePositive(finalDirection[2]) < FloatMakePositive(finalDirection[idx])) + idx = 2; + + axis.Init( 0, 0, 0 ); + axis[idx] = 1.0f; + VectorMA( axis, -DotProduct( axis, finalDirection ), finalDirection, axis ); + VectorNormalize(axis); + angle = 180.0f; + } + else + { + CrossProduct( initialDirection, finalDirection, axis ); + VectorNormalize( axis ); + angle = acos(angle) * 180 / M_PI; + } + + MatrixBuildRotationAboutAxis( dst, axis, angle ); + +#ifdef _DEBUG + Vector test; + Vector3DMultiply( dst, initialDirection, test ); + test -= finalDirection; + Assert( test.LengthSqr() < 1e-3 ); +#endif +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void MatrixBuildRotateZ( VMatrix &dst, float angleDegrees ) +{ + float radians = angleDegrees * ( M_PI / 180.0f ); + + float fSin = ( float )sin( radians ); + float fCos = ( float )cos( radians ); + + dst[0][0] = fCos; dst[0][1] = -fSin; dst[0][2] = 0.0f; dst[0][3] = 0.0f; + dst[1][0] = fSin; dst[1][1] = fCos; dst[1][2] = 0.0f; dst[1][3] = 0.0f; + dst[2][0] = 0.0f; dst[2][1] = 0.0f; dst[2][2] = 1.0f; dst[2][3] = 0.0f; + dst[3][0] = 0.0f; dst[3][1] = 0.0f; dst[3][2] = 0.0f; dst[3][3] = 1.0f; +} + +// Builds a scale matrix +void MatrixBuildScale( VMatrix &dst, float x, float y, float z ) +{ + dst[0][0] = x; dst[0][1] = 0.0f; dst[0][2] = 0.0f; dst[0][3] = 0.0f; + dst[1][0] = 0.0f; dst[1][1] = y; dst[1][2] = 0.0f; dst[1][3] = 0.0f; + dst[2][0] = 0.0f; dst[2][1] = 0.0f; dst[2][2] = z; dst[2][3] = 0.0f; + dst[3][0] = 0.0f; dst[3][1] = 0.0f; dst[3][2] = 0.0f; dst[3][3] = 1.0f; +} + +void MatrixBuildScale( VMatrix &dst, const Vector& scale ) +{ + MatrixBuildScale( dst, scale.x, scale.y, scale.z ); +} + +void MatrixBuildPerspective( VMatrix &dst, float fovX, float fovY, float zNear, float zFar ) +{ + // FIXME: collapse all of this into one matrix after we figure out what all should be in here. + float width = 2 * zNear * tan( fovX * ( M_PI/180.0f ) * 0.5f ); + float height = 2 * zNear * tan( fovY * ( M_PI/180.0f ) * 0.5f ); + + memset( dst.Base(), 0, sizeof( dst ) ); + + dst[0][0] = 2.0F * zNear / width; + dst[1][1] = 2.0F * zNear / height; + dst[2][2] = -zFar / ( zNear - zFar ); + dst[3][2] = 1.0f; + dst[2][3] = zNear * zFar / (zNear - zFar); + + + + // negate X and Y so that X points right, and Y points up. + VMatrix negateXY; + negateXY.Identity(); + negateXY[0][0] = -1.0f; + negateXY[1][1] = -1.0f; + MatrixMultiply( negateXY, dst, dst ); + + VMatrix addW; + addW.Identity(); + addW[0][3] = 1.0f; + addW[1][3] = 1.0f; + addW[2][3] = 0.0f; + MatrixMultiply( addW, dst, dst ); + + VMatrix scaleHalf; + scaleHalf.Identity(); + scaleHalf[0][0] = 0.5f; + scaleHalf[1][1] = 0.5f; + MatrixMultiply( scaleHalf, dst, dst ); +} + +static inline void CalculateAABBForNormalizedFrustum_Helper( float x, float y, float z, const VMatrix &volumeToWorld, Vector &mins, Vector &maxs ) +{ + Vector volumeSpacePos( x, y, z ); + + // Make sure it's been clipped + Assert( volumeSpacePos[0] >= -1e-3f ); + Assert( volumeSpacePos[0] - 1.0f <= 1e-3f ); + Assert( volumeSpacePos[1] >= -1e-3f ); + Assert( volumeSpacePos[1] - 1.0f <= 1e-3f ); + Assert( volumeSpacePos[2] >= -1e-3f ); + Assert( volumeSpacePos[2] - 1.0f <= 1e-3f ); + + Vector worldPos; + Vector3DMultiplyPositionProjective( volumeToWorld, volumeSpacePos, worldPos ); + AddPointToBounds( worldPos, mins, maxs ); +} + +//----------------------------------------------------------------------------- +// Given an inverse projection matrix, take the extremes of the space in transformed into world space and +// get a bounding box. +//----------------------------------------------------------------------------- +void CalculateAABBFromProjectionMatrixInverse( const VMatrix &volumeToWorld, Vector *pMins, Vector *pMaxs ) +{ + // FIXME: Could maybe do better than the compile with all of these multiplies by 0 and 1. + ClearBounds( *pMins, *pMaxs ); + CalculateAABBForNormalizedFrustum_Helper( 0, 0, 0, volumeToWorld, *pMins, *pMaxs ); + CalculateAABBForNormalizedFrustum_Helper( 0, 0, 1, volumeToWorld, *pMins, *pMaxs ); + CalculateAABBForNormalizedFrustum_Helper( 0, 1, 0, volumeToWorld, *pMins, *pMaxs ); + CalculateAABBForNormalizedFrustum_Helper( 0, 1, 1, volumeToWorld, *pMins, *pMaxs ); + CalculateAABBForNormalizedFrustum_Helper( 1, 0, 0, volumeToWorld, *pMins, *pMaxs ); + CalculateAABBForNormalizedFrustum_Helper( 1, 0, 1, volumeToWorld, *pMins, *pMaxs ); + CalculateAABBForNormalizedFrustum_Helper( 1, 1, 0, volumeToWorld, *pMins, *pMaxs ); + CalculateAABBForNormalizedFrustum_Helper( 1, 1, 1, volumeToWorld, *pMins, *pMaxs ); +} + +void CalculateAABBFromProjectionMatrix( const VMatrix &worldToVolume, Vector *pMins, Vector *pMaxs ) +{ + VMatrix volumeToWorld; + MatrixInverseGeneral( worldToVolume, volumeToWorld ); + CalculateAABBFromProjectionMatrixInverse( volumeToWorld, pMins, pMaxs ); +} + +//----------------------------------------------------------------------------- +// Given an inverse projection matrix, take the extremes of the space in transformed into world space and +// get a bounding sphere. +//----------------------------------------------------------------------------- +void CalculateSphereFromProjectionMatrixInverse( const VMatrix &volumeToWorld, Vector *pCenter, float *pflRadius ) +{ + // FIXME: Could maybe do better than the compile with all of these multiplies by 0 and 1. + + // Need 3 points: the endpoint of the line through the center of the near + far planes, + // and one point on the far plane. From that, we can derive a point somewhere on the center line + // which would produce the smallest bounding sphere. + Vector vecCenterNear, vecCenterFar, vecNearEdge, vecFarEdge; + Vector3DMultiplyPositionProjective( volumeToWorld, Vector( 0.5f, 0.5f, 0.0f ), vecCenterNear ); + Vector3DMultiplyPositionProjective( volumeToWorld, Vector( 0.5f, 0.5f, 1.0f ), vecCenterFar ); + Vector3DMultiplyPositionProjective( volumeToWorld, Vector( 0.0f, 0.0f, 0.0f ), vecNearEdge ); + Vector3DMultiplyPositionProjective( volumeToWorld, Vector( 0.0f, 0.0f, 1.0f ), vecFarEdge ); + + // Let the distance between the near + far center points = l + // Let the distance between the near center point + near edge point = h1 + // Let the distance between the far center point + far edge point = h2 + // Let the distance along the center line from the near point to the sphere center point = x + // Then let the distance between the sphere center point + near edge point == + // the distance between the sphere center point + far edge point == r == radius of sphere + // Then h1^2 + x^2 == r^2 == (l-x)^2 + h2^2 + // h1^x + x^2 = l^2 - 2 * l * x + x^2 + h2^2 + // 2 * l * x = l^2 + h2^2 - h1^2 + // x = (l^2 + h2^2 - h1^2) / (2 * l) + // r = sqrt( hl^1 + x^2 ) + Vector vecDelta; + VectorSubtract( vecCenterFar, vecCenterNear, vecDelta ); + float l = vecDelta.Length(); + float h1Sqr = vecCenterNear.DistToSqr( vecNearEdge ); + float h2Sqr = vecCenterFar.DistToSqr( vecFarEdge ); + float x = (l*l + h2Sqr - h1Sqr) / (2.0f * l); + VectorMA( vecCenterNear, (x / l), vecDelta, *pCenter ); + *pflRadius = sqrt( h1Sqr + x*x ); +} + +//----------------------------------------------------------------------------- +// Given a projection matrix, take the extremes of the space in transformed into world space and +// get a bounding sphere. +//----------------------------------------------------------------------------- +void CalculateSphereFromProjectionMatrix( const VMatrix &worldToVolume, Vector *pCenter, float *pflRadius ) +{ + VMatrix volumeToWorld; + MatrixInverseGeneral( worldToVolume, volumeToWorld ); + CalculateSphereFromProjectionMatrixInverse( volumeToWorld, pCenter, pflRadius ); +} + + +static inline void FrustumPlanesFromMatrixHelper( const VMatrix &shadowToWorld, const Vector &p1, const Vector &p2, const Vector &p3, + Vector &normal, float &dist ) +{ + Vector world1, world2, world3; + Vector3DMultiplyPositionProjective( shadowToWorld, p1, world1 ); + Vector3DMultiplyPositionProjective( shadowToWorld, p2, world2 ); + Vector3DMultiplyPositionProjective( shadowToWorld, p3, world3 ); + + Vector v1, v2; + VectorSubtract( world2, world1, v1 ); + VectorSubtract( world3, world1, v2 ); + + CrossProduct( v1, v2, normal ); + VectorNormalize( normal ); + dist = DotProduct( normal, world1 ); +} + +void FrustumPlanesFromMatrix( const VMatrix &clipToWorld, Frustum_t &frustum ) +{ + Vector normal; + float dist; + + FrustumPlanesFromMatrixHelper( clipToWorld, + Vector( 0.0f, 0.0f, 0.0f ), Vector( 1.0f, 0.0f, 0.0f ), Vector( 0.0f, 1.0f, 0.0f ), normal, dist ); + frustum.SetPlane( FRUSTUM_NEARZ, PLANE_ANYZ, normal, dist ); + + FrustumPlanesFromMatrixHelper( clipToWorld, + Vector( 0.0f, 0.0f, 1.0f ), Vector( 0.0f, 1.0f, 1.0f ), Vector( 1.0f, 0.0f, 1.0f ), normal, dist ); + frustum.SetPlane( FRUSTUM_FARZ, PLANE_ANYZ, normal, dist ); + + FrustumPlanesFromMatrixHelper( clipToWorld, + Vector( 1.0f, 0.0f, 0.0f ), Vector( 1.0f, 1.0f, 1.0f ), Vector( 1.0f, 1.0f, 0.0f ), normal, dist ); + frustum.SetPlane( FRUSTUM_RIGHT, PLANE_ANYZ, normal, dist ); + + FrustumPlanesFromMatrixHelper( clipToWorld, + Vector( 0.0f, 0.0f, 0.0f ), Vector( 0.0f, 1.0f, 1.0f ), Vector( 0.0f, 0.0f, 1.0f ), normal, dist ); + frustum.SetPlane( FRUSTUM_LEFT, PLANE_ANYZ, normal, dist ); + + FrustumPlanesFromMatrixHelper( clipToWorld, + Vector( 1.0f, 1.0f, 0.0f ), Vector( 1.0f, 1.0f, 1.0f ), Vector( 0.0f, 1.0f, 1.0f ), normal, dist ); + frustum.SetPlane( FRUSTUM_TOP, PLANE_ANYZ, normal, dist ); + + FrustumPlanesFromMatrixHelper( clipToWorld, + Vector( 1.0f, 0.0f, 0.0f ), Vector( 0.0f, 0.0f, 1.0f ), Vector( 1.0f, 0.0f, 1.0f ), normal, dist ); + frustum.SetPlane( FRUSTUM_BOTTOM, PLANE_ANYZ, normal, dist ); +} + +void MatrixBuildOrtho( VMatrix& dst, double left, double top, double right, double bottom, double zNear, double zFar ) +{ + // FIXME: This is being used incorrectly! Should read: + // D3DXMatrixOrthoOffCenterRH( &matrix, left, right, bottom, top, zNear, zFar ); + // Which is certainly why we need these extra -1 scales in y. Bleah + + // NOTE: The camera can be imagined as the following diagram: + // /z + // / + // /____ x Z is going into the screen + // | + // | + // |y + // + // (0,0,z) represents the upper-left corner of the screen. + // Our projection transform needs to transform from this space to a LH coordinate + // system that looks thusly: + // + // y| /z + // | / + // |/____ x Z is going into the screen + // + // Where x,y lies between -1 and 1, and z lies from 0 to 1 + // This is because the viewport transformation from projection space to pixels + // introduces a -1 scale in the y coordinates + // D3DXMatrixOrthoOffCenterRH( &matrix, left, right, top, bottom, zNear, zFar ); + + dst.Init( 2.0f / ( right - left ), 0.0f, 0.0f, ( left + right ) / ( left - right ), + 0.0f, 2.0f / ( bottom - top ), 0.0f, ( bottom + top ) / ( top - bottom ), + 0.0f, 0.0f, 1.0f / ( zNear - zFar ), zNear / ( zNear - zFar ), + 0.0f, 0.0f, 0.0f, 1.0f ); +} + +void MatrixBuildPerspectiveZRange( VMatrix& dst, double flZNear, double flZFar ) +{ + dst.m[2][0] = 0.0f; + dst.m[2][1] = 0.0f; + dst.m[2][2] = flZFar / ( flZNear - flZFar ); + dst.m[2][3] = flZNear * flZFar / ( flZNear - flZFar ); +} + +void MatrixBuildPerspectiveX( VMatrix& dst, double flFovX, double flAspect, double flZNear, double flZFar ) +{ + float flWidthScale = 1.0f / tanf( flFovX * M_PI / 360.0f ); + float flHeightScale = flAspect * flWidthScale; + dst.Init( flWidthScale, 0.0f, 0.0f, 0.0f, + 0.0f, flHeightScale, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, -1.0f, 0.0f ); + + MatrixBuildPerspectiveZRange ( dst, flZNear, flZFar ); +} + +void MatrixBuildPerspectiveOffCenterX( VMatrix& dst, double flFovX, double flAspect, double flZNear, double flZFar, double bottom, double top, double left, double right ) +{ + float flWidth = tanf( flFovX * M_PI / 360.0f ); + float flHeight = flWidth / flAspect; + + // bottom, top, left, right are 0..1 so convert to -/2../2 + float flLeft = -(flWidth/2.0f) * (1.0f - left) + left * (flWidth/2.0f); + float flRight = -(flWidth/2.0f) * (1.0f - right) + right * (flWidth/2.0f); + float flBottom = -(flHeight/2.0f) * (1.0f - bottom) + bottom * (flHeight/2.0f); + float flTop = -(flHeight/2.0f) * (1.0f - top) + top * (flHeight/2.0f); + + dst.Init( 1.0f / (flRight-flLeft), 0.0f, (flLeft+flRight)/(flRight-flLeft), 0.0f, + 0.0f, 1.0f /(flTop-flBottom), (flTop+flBottom)/(flTop-flBottom), 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, -1.0f, 0.0f ); + + MatrixBuildPerspectiveZRange ( dst, flZNear, flZFar ); +} +#endif // !_STATIC_LINKED || _SHARED_LIB + diff --git a/sp/src/public/BitmapFontFile.h b/sp/src/public/BitmapFontFile.h new file mode 100644 index 00000000..9628c3da --- /dev/null +++ b/sp/src/public/BitmapFontFile.h @@ -0,0 +1,54 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Baked Bitmap fonts +// +//=========================================================================== + +#ifndef _BITMAPFONTFILE_H_ +#define _BITMAPFONTFILE_H_ + +#include "datamap.h" + +#define BITMAPFONT_ID (('T'<<24)|('N'<<16)|('F'<<8)|('V')) +#define BITMAPFONT_VERSION 3 + +// style flags +#define BF_BOLD 0x0001 +#define BF_ITALIC 0x0002 +#define BF_OUTLINED 0x0004 +#define BF_DROPSHADOW 0x0008 +#define BF_BLURRED 0x0010 +#define BF_SCANLINES 0x0020 +#define BF_ANTIALIASED 0x0040 +#define BF_CUSTOM 0x0080 + +#pragma pack(1) //X360TBD +typedef struct BitmapGlyph_s +{ + DECLARE_BYTESWAP_DATADESC(); + short x; + short y; + short w; + short h; + short a; + short b; + short c; +} BitmapGlyph_t; + +typedef struct BitmapFont_s +{ + DECLARE_BYTESWAP_DATADESC(); + int m_id; + int m_Version; + short m_PageWidth; + short m_PageHeight; + short m_MaxCharWidth; + short m_MaxCharHeight; + short m_Flags; + short m_Ascent; + short m_NumGlyphs; + unsigned char m_TranslateTable[256]; +} BitmapFont_t; +#pragma pack() + +#endif \ No newline at end of file diff --git a/sp/src/public/Color.h b/sp/src/public/Color.h new file mode 100644 index 00000000..e800a372 --- /dev/null +++ b/sp/src/public/Color.h @@ -0,0 +1,103 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef COLOR_H +#define COLOR_H + +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +// Purpose: Basic handler for an rgb set of colors +// This class is fully inline +//----------------------------------------------------------------------------- +class Color +{ +public: + // constructors + Color() + { + *((int *)this) = 0; + } + Color(int _r,int _g,int _b) + { + SetColor(_r, _g, _b, 0); + } + Color(int _r,int _g,int _b,int _a) + { + SetColor(_r, _g, _b, _a); + } + + // set the color + // r - red component (0-255) + // g - green component (0-255) + // b - blue component (0-255) + // a - alpha component, controls transparency (0 - transparent, 255 - opaque); + void SetColor(int _r, int _g, int _b, int _a = 0) + { + _color[0] = (unsigned char)_r; + _color[1] = (unsigned char)_g; + _color[2] = (unsigned char)_b; + _color[3] = (unsigned char)_a; + } + + void GetColor(int &_r, int &_g, int &_b, int &_a) const + { + _r = _color[0]; + _g = _color[1]; + _b = _color[2]; + _a = _color[3]; + } + + void SetRawColor( int color32 ) + { + *((int *)this) = color32; + } + + int GetRawColor() const + { + return *((int *)this); + } + + inline int r() const { return _color[0]; } + inline int g() const { return _color[1]; } + inline int b() const { return _color[2]; } + inline int a() const { return _color[3]; } + + unsigned char &operator[](int index) + { + return _color[index]; + } + + const unsigned char &operator[](int index) const + { + return _color[index]; + } + + bool operator == (const Color &rhs) const + { + return ( *((int *)this) == *((int *)&rhs) ); + } + + bool operator != (const Color &rhs) const + { + return !(operator==(rhs)); + } + + Color &operator=( const Color &rhs ) + { + SetRawColor( rhs.GetRawColor() ); + return *this; + } + +private: + unsigned char _color[4]; +}; + + +#endif // COLOR_H diff --git a/sp/src/public/DISPCOLL_COMMON.H b/sp/src/public/DISPCOLL_COMMON.H new file mode 100644 index 00000000..ad7cb2b2 --- /dev/null +++ b/sp/src/public/DISPCOLL_COMMON.H @@ -0,0 +1,462 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef DISPCOLL_COMMON_H +#define DISPCOLL_COMMON_H +#pragma once + +#include "eifacev21.h" +#include "trace.h" +#include "builddisp.h" +#include "bitvec.h" +#ifdef ENGINE_DLL +#include "../engine/zone.h" +#endif + +#ifdef ENGINE_DLL +template +class CDispVector : public CUtlVector > +{ +}; +#else +template +class CDispVector : public CUtlVector > +{ +}; +#endif + +FORWARD_DECLARE_HANDLE( memhandle_t ); + +#define DISPCOLL_TREETRI_SIZE MAX_DISPTRIS +#define DISPCOLL_DIST_EPSILON 0.03125f +#define DISPCOLL_ROOTNODE_INDEX 0 +#define DISPCOLL_INVALID_TRI -1 +#define DISPCOLL_INVALID_FRAC -99999.9f +#define DISPCOLL_NORMAL_UNDEF 0xffff + +extern double g_flDispCollSweepTimer; +extern double g_flDispCollIntersectTimer; +extern double g_flDispCollInCallTimer; + +struct RayDispOutput_t +{ + short ndxVerts[4]; // 3 verts and a pad + float u, v; // the u, v paramters (edgeU = v1 - v0, edgeV = v2 - v0) + float dist; // intersection distance +}; + +// Assumptions: +// Max patch is 17x17, therefore 9 bits needed to represent a triangle index +// + +//============================================================================= +// Displacement Collision Triangle +class CDispCollTri +{ + + struct index_t + { + union + { + struct + { + unsigned short uiVert:9; + unsigned short uiMin:2; + unsigned short uiMax:2; + } m_Index; + + unsigned short m_IndexDummy; + }; + }; + + index_t m_TriData[3]; + +public: + unsigned short m_ucSignBits:3; // Plane test. + unsigned short m_ucPlaneType:3; // Axial test? + unsigned short m_uiFlags:5; // Uses 5-bits - maybe look into merging it with something? + + Vector m_vecNormal; // Triangle normal (plane normal). + float m_flDist; // Triangle plane dist. + + // Creation. + CDispCollTri(); + void Init( void ); + void CalcPlane( CDispVector &m_aVerts ); + void FindMinMax( CDispVector &m_aVerts ); + + // Triangle data. + inline void SetVert( int iPos, int iVert ) { Assert( ( iPos >= 0 ) && ( iPos < 3 ) ); Assert( ( iVert >= 0 ) && ( iVert < ( 1 << 9 ) ) ); m_TriData[iPos].m_Index.uiVert = iVert; } + inline int GetVert( int iPos ) const { Assert( ( iPos >= 0 ) && ( iPos < 3 ) ); return m_TriData[iPos].m_Index.uiVert; } + inline void SetMin( int iAxis, int iMin ) { Assert( ( iAxis >= 0 ) && ( iAxis < 3 ) ); Assert( ( iMin >= 0 ) && ( iMin < 3 ) ); m_TriData[iAxis].m_Index.uiMin = iMin; } + inline int GetMin( int iAxis ) const { Assert( ( iAxis >= 0 ) && ( iAxis < 3 ) ); return m_TriData[iAxis].m_Index.uiMin; } + inline void SetMax( int iAxis, int iMax ) { Assert( ( iAxis >= 0 ) && ( iAxis < 3 ) ); Assert( ( iMax >= 0 ) && ( iMax < 3 ) ); m_TriData[iAxis].m_Index.uiMax = iMax; } + inline int GetMax( int iAxis ) const { Assert( ( iAxis >= 0 ) && ( iAxis < 3 ) ); return m_TriData[iAxis].m_Index.uiMax; } +}; + +//============================================================================= +// Helper +class CDispCollHelper +{ +public: + + float m_flStartFrac; + float m_flEndFrac; + Vector m_vecImpactNormal; + float m_flImpactDist; +}; + +//============================================================================= +// Cache +#pragma pack(1) +class CDispCollTriCache +{ +public: + unsigned short m_iCrossX[3]; + unsigned short m_iCrossY[3]; + unsigned short m_iCrossZ[3]; +}; +#pragma pack() +#include "mathlib/ssemath.h" + +class CDispCollNode +{ +public: + FourVectors m_mins; + FourVectors m_maxs; +}; + +class CDispCollLeaf +{ +public: + short m_tris[2]; +}; + +// a power 4 displacement can have 341 nodes, pad out to 344 for 16-byte alignment +const int MAX_DISP_AABB_NODES = 341; +const int MAX_AABB_LIST = 344; + +struct rayleaflist_t +{ + FourVectors rayStart; + FourVectors rayExtents; + FourVectors invDelta; + int nodeList[MAX_AABB_LIST]; + int maxIndex; +}; + +//============================================================================= +// +// Displacement Collision Tree Data +// + + + +class CDispCollTree +{ +public: + + // Creation/Destruction. + CDispCollTree(); + ~CDispCollTree(); + virtual bool Create( CCoreDispInfo *pDisp ); + + // Raycasts. + // NOTE: These assume you've precalculated invDelta as well as culled to the bounds of this disp + bool AABBTree_Ray( const Ray_t &ray, const Vector &invDelta, CBaseTrace *pTrace, bool bSide = true ); + bool AABBTree_Ray( const Ray_t &ray, const Vector &invDelta, RayDispOutput_t &output ); + // NOTE: Lower perf helper function, should not be used in the game runtime + bool AABBTree_Ray( const Ray_t &ray, RayDispOutput_t &output ); + + // Hull Sweeps. + // NOTE: These assume you've precalculated invDelta as well as culled to the bounds of this disp + bool AABBTree_SweepAABB( const Ray_t &ray, const Vector &invDelta, CBaseTrace *pTrace ); + + // Hull Intersection. + bool AABBTree_IntersectAABB( const Vector &absMins, const Vector &absMaxs ); + + + // Point/Box vs. Bounds. + bool PointInBounds( Vector const &vecBoxCenter, Vector const &vecBoxMin, Vector const &vecBoxMax, bool bPoint ); + + // Utility. + inline void SetPower( int power ) { m_nPower = power; } + inline int GetPower( void ) { return m_nPower; } + + inline int GetFlags( void ) { return m_nFlags; } + inline void SetFlags( int nFlags ) { m_nFlags = nFlags; } + inline bool CheckFlags( int nFlags ) { return ( ( nFlags & GetFlags() ) != 0 ) ? true : false; } + + inline int GetWidth( void ) { return ( ( 1 << m_nPower ) + 1 ); } + inline int GetHeight( void ) { return ( ( 1 << m_nPower ) + 1 ); } + inline int GetSize( void ) { return ( ( 1 << m_nPower ) + 1 ) * ( ( 1 << m_nPower ) + 1 ); } + inline int GetTriSize( void ) { return ( ( 1 << m_nPower ) * ( 1 << m_nPower ) * 2 ); } + +// inline void SetTriFlags( short iTri, unsigned short nFlags ) { m_aTris[iTri].m_uiFlags = nFlags; } + + inline void GetStabDirection( Vector &vecDir ) { vecDir = m_vecStabDir; } + + inline void GetBounds( Vector &vecBoxMin, Vector &vecBoxMax ) { vecBoxMin = m_mins; vecBoxMax = m_maxs; } + inline int GetContents( void ) { return m_nContents; } + inline void SetSurfaceProps( int iProp, short nSurfProp ) { Assert( ( iProp >= 0 ) && ( iProp < 2 ) ); m_nSurfaceProps[iProp] = nSurfProp; } + inline short GetSurfaceProps( int iProp ) { return m_nSurfaceProps[iProp]; } + + inline unsigned int GetMemorySize( void ) { return m_nSize; } + inline unsigned int GetCacheMemorySize( void ) { return ( m_aTrisCache.Count() * sizeof(CDispCollTriCache) + m_aEdgePlanes.Count() * sizeof(Vector) ); } + + inline bool IsCached( void ) { return m_aTrisCache.Count() == m_aTris.Count(); } + + void GetVirtualMeshList( struct virtualmeshlist_t *pList ); + int AABBTree_GetTrisInSphere( const Vector ¢er, float radius, unsigned short *pIndexOut, int indexMax ); + +public: + + inline int Nodes_GetChild( int iNode, int nDirection ); + inline int Nodes_CalcCount( int nPower ); + inline int Nodes_GetParent( int iNode ); + inline int Nodes_GetLevel( int iNode ); + inline int Nodes_GetIndexFromComponents( int x, int y ); + + void LockCache(); + void UnlockCache(); + void Cache( void ); + void Uncache() { m_aTrisCache.Purge(); m_aEdgePlanes.Purge(); } + +#ifdef ENGINE_DLL + // Data manager methods + static size_t EstimatedSize( CDispCollTree *pTree ) + { + return pTree->GetCacheMemorySize(); + } + + static CDispCollTree *CreateResource( CDispCollTree *pTree ) + { + // Created ahead of time + return pTree; + } + + bool GetData() + { + return IsCached(); + } + + size_t Size() + { + return GetCacheMemorySize(); + } + + void DestroyResource() + { + Uncache(); + m_hCache = NULL; + } +#endif + bool AABBTree_Create(CCoreDispInfo* pDisp); + void AABBTree_CopyDispData(CCoreDispInfo* pDisp); + void AABBTree_CreateLeafs(void); + void AABBTree_GenerateBoxes_r(int nodeIndex, Vector* pMins, Vector* pMaxs); + void AABBTree_CalcBounds(void); +protected: + + + int AABBTree_BuildTreeTrisInSphere_r( const Vector ¢er, float radius, int iNode, unsigned short *pIndexOut, unsigned short indexMax ); + + void AABBTree_TreeTrisRayTest( const Ray_t &ray, const Vector &vecInvDelta, int iNode, CBaseTrace *pTrace, bool bSide, CDispCollTri **pImpactTri ); + void AABBTree_TreeTrisRayBarycentricTest( const Ray_t &ray, const Vector &vecInvDelta, int iNode, RayDispOutput_t &output, CDispCollTri **pImpactTri ); + + int FORCEINLINE BuildRayLeafList( int iNode, rayleaflist_t &list ); + + struct AABBTree_TreeTrisSweepTest_Args_t + { + AABBTree_TreeTrisSweepTest_Args_t( const Ray_t &ray, const Vector &vecInvDelta, const Vector &rayDir, CBaseTrace *pTrace ) + : ray( ray ), vecInvDelta( vecInvDelta ), rayDir( rayDir ), pTrace( pTrace ) {} + const Ray_t &ray; + const Vector &vecInvDelta; + const Vector &rayDir; + CBaseTrace *pTrace; + }; + +protected: + + void SweepAABBTriIntersect( const Ray_t &ray, const Vector &rayDir, int iTri, CDispCollTri *pTri, CBaseTrace *pTrace ); + + void Cache_Create( CDispCollTri *pTri, int iTri ); // Testing! + bool Cache_EdgeCrossAxisX( const Vector &vecEdge, const Vector &vecOnEdge, const Vector &vecOffEdge, CDispCollTri *pTri, unsigned short &iPlane ); + bool Cache_EdgeCrossAxisY( const Vector &vecEdge, const Vector &vecOnEdge, const Vector &vecOffEdge, CDispCollTri *pTri, unsigned short &iPlane ); + bool Cache_EdgeCrossAxisZ( const Vector &vecEdge, const Vector &vecOnEdge, const Vector &vecOffEdge, CDispCollTri *pTri, unsigned short &iPlane ); + + inline bool FacePlane( const Ray_t &ray, const Vector &rayDir, CDispCollTri *pTri, CDispCollHelper *pHelper ); + bool FORCEINLINE AxisPlanesXYZ( const Ray_t &ray, CDispCollTri *pTri, CDispCollHelper *pHelper ); + inline bool EdgeCrossAxisX( const Ray_t &ray, unsigned short iPlane, CDispCollHelper *pHelper ); + inline bool EdgeCrossAxisY( const Ray_t &ray, unsigned short iPlane, CDispCollHelper *pHelper ); + inline bool EdgeCrossAxisZ( const Ray_t &ray, unsigned short iPlane, CDispCollHelper *pHelper ); + + bool ResolveRayPlaneIntersect( float flStart, float flEnd, const Vector &vecNormal, float flDist, CDispCollHelper *pHelper ); + template bool FORCEINLINE TestOneAxisPlaneMin( const Ray_t &ray, CDispCollTri *pTri ); + template bool FORCEINLINE TestOneAxisPlaneMax( const Ray_t &ray, CDispCollTri *pTri ); + template bool EdgeCrossAxis( const Ray_t &ray, unsigned short iPlane, CDispCollHelper *pHelper ); + + // Utility + inline void CalcClosestBoxPoint( const Vector &vecPlaneNormal, const Vector &vecBoxStart, const Vector &vecBoxExtents, Vector &vecBoxPoint ); + inline void CalcClosestExtents( const Vector &vecPlaneNormal, const Vector &vecBoxExtents, Vector &vecBoxPoint ); + int AddPlane( const Vector &vecNormal ); + bool FORCEINLINE IsLeafNode(int iNode); +public: + Vector m_mins; // Bounding box of the displacement surface and base face + int m_iCounter; + Vector m_maxs; // Bounding box of the displacement surface and base face + CDispVector m_aVerts;// Displacement verts. +protected: + int m_nContents; // The displacement surface "contents" (solid, etc...) + +#ifdef ENGINE_DLL + memhandle_t m_hCache; +#endif + + int m_nPower; // Size of the displacement ( 2^power + 1 ) + int m_nFlags; + + Vector m_vecSurfPoints[4]; // Base surface points. + // Collision data. + Vector m_vecStabDir; // Direction to stab for this displacement surface (is the base face normal) + short m_nSurfaceProps[2]; // Surface properties (save off from texdata for impact responses) + +protected: + + CDispVector m_aTris; // Displacement triangles. + CDispVector m_nodes; // Nodes. + CDispVector m_leaves; // Leaves. + // Cache + CUtlVector m_aTrisCache; + CUtlVector m_aEdgePlanes; + + CDispCollHelper m_Helper; + + unsigned int m_nSize; + +}; + +FORCEINLINE bool CDispCollTree::IsLeafNode(int iNode) +{ + return iNode >= m_nodes.Count() ? true : false; +} + +//----------------------------------------------------------------------------- +// Purpose: get the child node index given the current node index and direction +// of the child (1 of 4) +// Input: iNode - current node index +// nDirection - direction of the child ( [0...3] - SW, SE, NW, NE ) +// Output: int - the index of the child node +//----------------------------------------------------------------------------- +inline int CDispCollTree::Nodes_GetChild( int iNode, int nDirection ) +{ + // node range [0...m_NodeCount) + Assert( iNode >= 0 ); + Assert( iNode < m_nodes.Count() ); + + // ( node index * 4 ) + ( direction + 1 ) + return ( ( iNode << 2 ) + ( nDirection + 1 ) ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline int CDispCollTree::Nodes_CalcCount( int nPower ) +{ + Assert( nPower >= 1 ); + Assert( nPower <= 4 ); + + return ( ( 1 << ( ( nPower + 1 ) << 1 ) ) / 3 ); +} + +//----------------------------------------------------------------------------- +// Purpose: get the parent node index given the current node +// Input: iNode - current node index +// Output: int - the index of the parent node +//----------------------------------------------------------------------------- +inline int CDispCollTree::Nodes_GetParent( int iNode ) +{ + // node range [0...m_NodeCount) + Assert( iNode >= 0 ); + Assert( iNode < m_nodes.Count() ); + + // ( node index - 1 ) / 4 + return ( ( iNode - 1 ) >> 2 ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// TODO: should make this a function - not a hardcoded set of statements!!! +//----------------------------------------------------------------------------- +inline int CDispCollTree::Nodes_GetLevel( int iNode ) +{ + // node range [0...m_NodeCount) + Assert( iNode >= 0 ); + Assert( iNode < m_nodes.Count() ); + + // level = 2^n + 1 + if ( iNode == 0 ) { return 1; } + if ( iNode < 5 ) { return 2; } + if ( iNode < 21 ) { return 3; } + if ( iNode < 85 ) { return 4; } + if ( iNode < 341 ) { return 5; } + + return -1; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline int CDispCollTree::Nodes_GetIndexFromComponents( int x, int y ) +{ + int nIndex = 0; + + // Interleave bits from the x and y values to create the index + int iShift; + for( iShift = 0; x != 0; iShift += 2, x >>= 1 ) + { + nIndex |= ( x & 1 ) << iShift; + } + + for( iShift = 1; y != 0; iShift += 2, y >>= 1 ) + { + nIndex |= ( y & 1 ) << iShift; + } + + return nIndex; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline void CDispCollTree::CalcClosestBoxPoint( const Vector &vecPlaneNormal, const Vector &vecBoxStart, + const Vector &vecBoxExtents, Vector &vecBoxPoint ) +{ + vecBoxPoint = vecBoxStart; + ( vecPlaneNormal[0] < 0.0f ) ? vecBoxPoint[0] += vecBoxExtents[0] : vecBoxPoint[0] -= vecBoxExtents[0]; + ( vecPlaneNormal[1] < 0.0f ) ? vecBoxPoint[1] += vecBoxExtents[1] : vecBoxPoint[1] -= vecBoxExtents[1]; + ( vecPlaneNormal[2] < 0.0f ) ? vecBoxPoint[2] += vecBoxExtents[2] : vecBoxPoint[2] -= vecBoxExtents[2]; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline void CDispCollTree::CalcClosestExtents( const Vector &vecPlaneNormal, const Vector &vecBoxExtents, + Vector &vecBoxPoint ) +{ + ( vecPlaneNormal[0] < 0.0f ) ? vecBoxPoint[0] = vecBoxExtents[0] : vecBoxPoint[0] = -vecBoxExtents[0]; + ( vecPlaneNormal[1] < 0.0f ) ? vecBoxPoint[1] = vecBoxExtents[1] : vecBoxPoint[1] = -vecBoxExtents[1]; + ( vecPlaneNormal[2] < 0.0f ) ? vecBoxPoint[2] = vecBoxExtents[2] : vecBoxPoint[2] = -vecBoxExtents[2]; +} + +//============================================================================= +// Global Helper Functions +CDispCollTree *DispCollTrees_Alloc( int count ); +void DispCollTrees_Free( CDispCollTree *pTrees ); +//void ApplyTerrainMod(ITerrainMod* pMod); + +#endif // DISPCOLL_COMMON_H diff --git a/sp/src/public/Friends/AddOns/AddOnMessages.h b/sp/src/public/Friends/AddOns/AddOnMessages.h new file mode 100644 index 00000000..ca778f9c --- /dev/null +++ b/sp/src/public/Friends/AddOns/AddOnMessages.h @@ -0,0 +1,56 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef ADDONMESSAGES_H +#define ADDONMESSAGES_H +#pragma once + +enum GameMessageIDs +{ + GAME_MSG_TEXT = 1, // text chat message + GAME_MSG_DATA, // binary game data + + GAME_MSG_INVITE_REQUEST, + GAME_MSG_INVITE_RESPONSE, + GAME_MSG_REJOIN_REQUEST, + GAME_MSG_REJOIN_RESPONSE, + + GAME_MSG_INVITE_PERMISSION, // ask permission to invite someone + GAME_MSG_INVITE_NOTIFY, // tell everybody that we're inviting + GAME_MSG_INVITE_DENIED, + + GAME_MSG_PLAYER_STATUS_UPDATE, + GAME_MSG_SETUP_INFO, // when user joins a game, host send the setup information of who's in the game + GAME_MSG_INVITE_CANCEL, // host has cancelled an invite + GAME_MSG_GAME_START, // if a game has a setup phase, this tells everybody the game has started + + GAME_MSG_PLAYER_KICK, // player kicked from game + GAME_MSG_UPDATING, + GAME_MSG_UP_TO_DATE, // player is up to date and ready to get data + + GAME_MSG_STARTING_CARD_HAND = 300, + GAME_MSG_STARTING_PLAYER, + GAME_MSG_CARD_PLAY, + + GAME_MSG_CHEAT_POSSIBLE = 400, // when host detects a possible cheat + + GAME_MSG_MOVE = 500, + GAME_MSG_COLOR_CHOICE, + GAME_MSG_RECONNECT_DATA, + GAME_MSG_QUIT, + GAME_MSG_PASS, + + GAME_MSG_ABORT, // phase these out + GAME_MSG_WAITING_ABORT, + +// GAME_MSG_CLOSE_WINDOW, + + // special individual game messages should take IDs 1000 and over +}; + + +#endif // ADDONMESSAGES_H + diff --git a/sp/src/public/Friends/AddOns/AddOnTypes.h b/sp/src/public/Friends/AddOns/AddOnTypes.h new file mode 100644 index 00000000..b6cf75fe --- /dev/null +++ b/sp/src/public/Friends/AddOns/AddOnTypes.h @@ -0,0 +1,18 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef ADDONTYPES_H +#define ADDONTYPES_H +#pragma once + +#ifndef WIN32 + typedef unsigned long long SessionInt64; +#else + typedef unsigned __int64 SessionInt64; +#endif + +#endif // ADDONTYPES_H + diff --git a/sp/src/public/Friends/AddOns/ISteamAddOn.h b/sp/src/public/Friends/AddOns/ISteamAddOn.h new file mode 100644 index 00000000..ff395c36 --- /dev/null +++ b/sp/src/public/Friends/AddOns/ISteamAddOn.h @@ -0,0 +1,69 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Interface to a Steam Add On +// +//=============================================================================// + +#ifndef ISTEAMADDON_H +#define ISTEAMADDON_H +#pragma once + +#include "interface.h" +#include "AddOnTypes.h" +#include + +class CUtlMsgBuffer; + +class ISteamAddOn : public IBaseInterface +{ +public: + // allows SteamAddOn to link to the core vgui factories + virtual bool Initialize(CreateInterfaceFn *vguiFactories, int factoryCount) = 0; + + // allows SteamAddOns to link to all other modules + virtual bool PostInitialize(CreateInterfaceFn *modules, int factoryCount) = 0; + + // when Friends closes down - all SteamAddOns are notified + virtual void Deactivate() = 0; + + // notifies the addon who its VGUI parent panel is + virtual void SetParent( vgui::Panel *parent ) = 0; + + // notifies the SteamAddOn of the user's ID and username. + // Note: username can be set mulitple times due to changing of name + virtual void SetUserID(unsigned int userID) = 0; + virtual void SetUserName(const char *userName) = 0; + + // Query if there are any 'open' sessions - open meaning allowing new users to join the sessions + virtual int QueryOpenSessionCount() = 0; + + // will be valid right after a call to QueryOpenInviteCount will set the addOnSessionID and hostname for + // any open sessions for this addOn. Return true if it's a valid index + virtual bool QueryOpenSessionInfo(int nOpenGameIndex, SessionInt64 &addOnSessionID, char *pszHostName) = 0; + + // returns true if this userID is involved in an addOnSession with this ID + virtual bool QueryUserInvolved(SessionInt64 addOnSessionID, unsigned int userID) = 0; + + // if session doesn't exist, then the SteamAddOn body should deal with it + virtual bool OnReceiveMsg(SessionInt64 addOnSessionID, CUtlMsgBuffer *msgBuffer) = 0; + + // Let's the SteamAddOn know when when any friend's status has changed + virtual void OnFriendStatusChanged() = 0; + + // A request to start/join this AddOn with this user ID/name. addOnSessionID will be zero if it's a new session request + virtual void OnInviteUser(unsigned int targetUserID, const char *username, SessionInt64 addOnSessionID) = 0; + + // user accepted this host's invite request + virtual void OnAcceptInviteRequest(unsigned int hostID, const char *hostUserName, SessionInt64 addOnSessionID, const char *pAppData, int dataLen) = 0; + + // user accepted this host's rejoin request + virtual void OnAcceptRejoinRequest(unsigned int hostID, const char *hostUserName, SessionInt64 addOnSessionID, const char *pAppData, int dataLen) = 0; + + // user starts this addOn from a menu + virtual void StartAddOn() = 0; +}; + +#define STEAMADDON_INTERFACE_VERSION "SteamAddOn007" + +#endif // ISTEAMADDON_H + diff --git a/sp/src/public/Friends/IFriendsNET.h b/sp/src/public/Friends/IFriendsNET.h new file mode 100644 index 00000000..b0b6c893 --- /dev/null +++ b/sp/src/public/Friends/IFriendsNET.h @@ -0,0 +1,41 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef FRIENDSNET_INTERFACE_H +#define FRIENDSNET_INTERFACE_H +#pragma once + +class CUtlMsgBuffer; +class CServerSession; + +#include "interface.h" +#include "Friends/AddOns/AddOnTypes.h" + +class IFriendsNET : public IBaseInterface +{ +public: + // check if we have network information for this user + virtual bool CheckUserRegistered(unsigned int userID) = 0; + + // update a user's network information + virtual void UpdateUserNetInfo(unsigned int userID, unsigned int netSessionID, int serverID, int IP, int port) = 0; + + // set whether or not we send directly to user or through the server + virtual void SetUserSendViaServer(unsigned int userID, bool bSendViaServer) = 0; + + // Gets a blob of data that represents this user's information + virtual bool GetUserNetInfoBlob(unsigned int userID, unsigned int dataBlob[8]) = 0; + // Sets a user's information using the same blob of data type + virtual bool SetUserNetInfoBlob(unsigned int userID, const unsigned int dataBlob[8]) = 0; + + // send binary data to user, marked with game/sessionID + virtual void SendAddOnPacket(const char *pszGameID, SessionInt64 addOnSessionID, unsigned int userID, const CUtlMsgBuffer& buffer) = 0; +}; + +#define FRIENDSNET_INTERFACE_VERSION "FriendsNET003" + +#endif // FRIENDSNET_INTERFACE_H + diff --git a/sp/src/public/Friends/IFriendsUser.h b/sp/src/public/Friends/IFriendsUser.h new file mode 100644 index 00000000..4c9375a4 --- /dev/null +++ b/sp/src/public/Friends/IFriendsUser.h @@ -0,0 +1,62 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef IFRIENDSUSER_H +#define IFRIENDSUSER_H +#ifdef _WIN32 +#pragma once +#endif + +#include "interface.h" + +//----------------------------------------------------------------------------- +// Purpose: Interface to accessing information about Friends Users +//----------------------------------------------------------------------------- +class IFriendsUser : public IBaseInterface +{ +public: + // returns true if the interface is ready for use + virtual bool IsValid() = 0; + + // returns the Friends ID of the current user + virtual unsigned int GetFriendsID() = 0; + + // returns information about a user + // information may not be known about some users, "" will be returned + virtual const char *GetUserName(unsigned int friendsID) = 0; + virtual const char *GetFirstName(unsigned int friendsID) = 0; + virtual const char *GetLastName(unsigned int friendsID) = 0; + virtual const char *GetEmail(unsigned int friendsID) = 0; + + // returns true if buddyID is a buddy of the current user + // ie. the current is authorized to see when the buddy is online + virtual bool IsBuddy(unsigned int buddyID) = 0; + + // requests authorization from a user + virtual void RequestAuthorizationFromUser(unsigned int potentialBuddyID) = 0; + + // returns the status of the buddy, > 0 is online, 4 is ingame + virtual int GetBuddyStatus(unsigned int friendsID) = 0; + + // gets the IP address of the server the buddy is on, returns false if couldn't get + virtual bool GetBuddyGameAddress(unsigned int friendsID, int *ip, int *port) = 0; + + // returns the number of buddies + virtual int GetNumberOfBuddies() = 0; + + // returns the FriendsID of a buddy - buddyIndex is valid in the range [0, GetNumberOfBuddies) + virtual unsigned int GetBuddyFriendsID(int buddyIndex) = 0; + + // sets whether or not the user can receive messages at this time + // messages will be queued until this is set to true + virtual void SetCanReceiveMessages(bool state) = 0; +}; + +#define FRIENDSUSER_INTERFACE_VERSION "FriendsUser001" + + +#endif // IFRIENDSUSER_H diff --git a/sp/src/public/IGameUIFuncs.h b/sp/src/public/IGameUIFuncs.h new file mode 100644 index 00000000..21f01e60 --- /dev/null +++ b/sp/src/public/IGameUIFuncs.h @@ -0,0 +1,30 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#ifndef IGAMEUIFUNCS_H +#define IGAMEUIFUNCS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "vgui/KeyCode.h" + +abstract_class IGameUIFuncs +{ +public: + virtual bool IsKeyDown( const char *keyname, bool& isdown ) = 0; + virtual const char *GetBindingForButtonCode( ButtonCode_t code ) = 0; + virtual ButtonCode_t GetButtonCodeForBind( const char *pBind ) = 0; + virtual void GetVideoModes( struct vmode_s **liststart, int *count ) = 0; + virtual void SetFriendsID( uint friendsID, const char *friendsName ) = 0; + virtual void GetDesktopResolution( int &width, int &height ) = 0; + virtual bool IsConnectedToVACSecureServer() = 0; +}; + +#define VENGINE_GAMEUIFUNCS_VERSION "VENGINE_GAMEUIFUNCS_VERSION005" + +#endif // IGAMEUIFUNCS_H diff --git a/sp/src/public/IHammer.h b/sp/src/public/IHammer.h new file mode 100644 index 00000000..7e85f2d7 --- /dev/null +++ b/sp/src/public/IHammer.h @@ -0,0 +1,56 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: The application object. +// +//=============================================================================// + +#ifndef IHAMMER_H +#define IHAMMER_H + +#include "appframework/IAppSystem.h" + +typedef struct tagMSG MSG; + + +class IStudioDataCache; + + +//----------------------------------------------------------------------------- +// Return values for RequestNewConfig +//----------------------------------------------------------------------------- +enum RequestRetval_t +{ + REQUEST_OK = 0, + REQUEST_QUIT +}; + + +//----------------------------------------------------------------------------- +// Interface used to drive hammer +//----------------------------------------------------------------------------- +#define INTERFACEVERSION_HAMMER "Hammer001" +class IHammer : public IAppSystem +{ +public: + virtual bool HammerPreTranslateMessage( MSG * pMsg ) = 0; + virtual bool HammerIsIdleMessage( MSG * pMsg ) = 0; + virtual bool HammerOnIdle( long count ) = 0; + + virtual void RunFrame() = 0; + + // Returns the mod and the game to initially start up + virtual const char *GetDefaultMod() = 0; + virtual const char *GetDefaultGame() = 0; + + virtual bool InitSessionGameConfig( const char *szGameDir ) = 0; + + // Request a new config from hammer's config system + virtual RequestRetval_t RequestNewConfig() = 0; + + // Returns the full path to the mod and the game to initially start up + virtual const char *GetDefaultModFullPath() = 0; + + virtual int MainLoop() = 0; +}; + +#endif // IHAMMER_H diff --git a/sp/src/public/OfflineMode.h b/sp/src/public/OfflineMode.h new file mode 100644 index 00000000..d4c1f2cd --- /dev/null +++ b/sp/src/public/OfflineMode.h @@ -0,0 +1,29 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include +#include + +#define STEAM_OFFLINE_MODE "HKEY_CURRENT_USER\\Software\\Valve\\Steam\\Offline" +#define STEAM_AFS_MODE "HKEY_CURRENT_USER\\Software\\Valve\\Steam\\OfflineAFS" +#define OFFLINE_FILE "Steam\\cached\\offline_" // first part of filename + +inline bool IsSteamInOfflineMode() +{ + int offline = 0; + vgui::system()->GetRegistryInteger( STEAM_OFFLINE_MODE, offline ); + return ( offline == 1 ); +}inline bool IsSteamInAuthenticationFailSafeMode() +{ + int offline = 0; + vgui::system()->GetRegistryInteger( STEAM_AFS_MODE, offline ); + return ( offline == 1 ); +} + +inline bool IsSteamGameServerBrowsingEnabled() +{ + return (IsSteamInAuthenticationFailSafeMode() || !IsSteamInOfflineMode()); +} diff --git a/sp/src/public/PlayerState.h b/sp/src/public/PlayerState.h new file mode 100644 index 00000000..9097ca71 --- /dev/null +++ b/sp/src/public/PlayerState.h @@ -0,0 +1,63 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef PLAYERSTATE_H +#define PLAYERSTATE_H +#ifdef _WIN32 +#pragma once +#endif + +#include "edict.h" +#include "networkvar.h" +// Only care about this stuff in game/client .dlls +#if defined( CLIENT_DLL ) +#include "predictable_entity.h" +#endif + +class CPlayerState +{ +public: + DECLARE_CLASS_NOBASE( CPlayerState ); + DECLARE_EMBEDDED_NETWORKVAR(); + + // This virtual method is necessary to generate a vtable in all cases + // (DECLARE_PREDICTABLE will generate a vtable also)! + virtual ~CPlayerState() {} + + // true if the player is dead + CNetworkVar( bool, deadflag ); + // Viewing angle (player only) + QAngle v_angle; + +// The client .dll only cares about deadflag +// the game and engine .dlls need to worry about the rest of this data +#if !defined( CLIENT_DLL ) + // Player's network name + string_t netname; + // 0:nothing, 1:force view angles, 2:add avelocity + int fixangle; + // delta angle for fixangle == FIXANGLE_RELATIVE + QAngle anglechange; + // flag to single the HLTV/Replay fake client, not transmitted + bool hltv; + bool replay; + int frags; + int deaths; +#endif + +// NOTE: Only care about this stuff in game/client dlls +// Put at end in case it has any effect on size of structure +#if defined( GAME_DLL ) + DECLARE_SIMPLE_DATADESC(); +#endif + +#if defined( CLIENT_DLL ) + DECLARE_PREDICTABLE(); +#endif +}; + +#endif // PLAYERSTATE_H diff --git a/sp/src/public/ScratchPadUtils.cpp b/sp/src/public/ScratchPadUtils.cpp new file mode 100644 index 00000000..dfb93b0d --- /dev/null +++ b/sp/src/public/ScratchPadUtils.cpp @@ -0,0 +1,467 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#if !defined(_STATIC_LINKED) || defined(_SHARED_LIB) + +#include "iscratchpad3d.h" +#include "mathlib/mathlib.h" +#include "ScratchPadUtils.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +// --------------------------------------------------------------------------------------------------------------------- // +// CScratchPadGraph implementation. +// --------------------------------------------------------------------------------------------------------------------- // + +CScratchPadGraph::CScratchPadGraph() +{ + m_pPad = NULL; +} + + +void CScratchPadGraph::Init( + IScratchPad3D *pPad, + + Vector vTimeAxis, + float flInchesPerSecond, + Vector vTimeLineColor, + float flTimeOrigin, + + float flTimeLabelEveryNSeconds, + + Vector vValueAxis, + float flInchesPerValue, + Vector vValueLineColor, + float flValueOrigin + + ) +{ + m_pPad = pPad; + m_vTimeAxis = vTimeAxis; + m_flInchesPerSecond = flInchesPerSecond; + m_vValueAxis = vValueAxis; + m_flInchesPerValue = flInchesPerValue; + m_flTimeLabelEveryNSeconds = flTimeLabelEveryNSeconds; + + m_vTimeLineColor = vTimeLineColor; + m_vValueLineColor = vValueLineColor; + + m_flTimeOrigin = flTimeOrigin; + m_flValueOrigin = flValueOrigin; + + m_nTimeLabelsDrawn = 0; + m_flHighestTime = flTimeOrigin; + m_flHighestValue = flValueOrigin; +} + + +bool CScratchPadGraph::IsInitted() const +{ + return m_pPad != NULL; +} + + +CScratchPadGraph::LineID CScratchPadGraph::AddLine( Vector vColor ) +{ + CScratchPadGraph::CLineInfo info; + info.m_bFirst = true; + info.m_vColor = vColor; + return m_LineInfos.AddToTail( info ); +} + + +void CScratchPadGraph::AddSample( LineID iLine, float flTime, float flValue ) +{ + CScratchPadGraph::CLineInfo *pInfo = &m_LineInfos[iLine]; + + UpdateTicksAndStuff( flTime, flValue ); + + if ( !pInfo->m_bFirst ) + { + // Draw a line from the last value to the current one. + Vector vStart = GetSamplePosition( pInfo->m_flLastTime, pInfo->m_flLastValue ); + Vector vEnd = GetSamplePosition( flTime, flValue ); + + m_pPad->DrawLine( + CSPVert( vStart, pInfo->m_vColor ), + CSPVert( vEnd, pInfo->m_vColor ) + ); + } + + pInfo->m_flLastTime = flTime; + pInfo->m_flLastValue = flValue; + pInfo->m_bFirst = false; +} + + +void CScratchPadGraph::AddVerticalLine( float flTime, float flMinValue, float flMaxValue, const CSPColor &vColor ) +{ + Vector v1 = GetSamplePosition( flTime, flMinValue ); + Vector v2 = GetSamplePosition( flTime, flMaxValue ); + m_pPad->DrawLine( + CSPVert( v1, vColor ), + CSPVert( v2, vColor ) ); +} + + +void CScratchPadGraph::UpdateTicksAndStuff( float flTime, float flValue ) +{ + if ( flTime > m_flHighestTime ) + { + // Update the left part of the time axis. + Vector vStart = GetSamplePosition( m_flHighestTime, m_flValueOrigin ); + Vector vEnd = GetSamplePosition( flTime, m_flValueOrigin ); + + m_pPad->DrawLine( + CSPVert( vStart, m_vTimeLineColor ), + CSPVert( vEnd, m_vTimeLineColor ) + ); + + m_flHighestTime = flTime; + } + + if ( flValue > m_flHighestValue ) + { + // Update the left part of the time axis. + Vector vStart = GetSamplePosition( m_flTimeOrigin, m_flHighestValue ); + Vector vEnd = GetSamplePosition( m_flTimeOrigin, flValue ); + + m_pPad->DrawLine( + CSPVert( vStart, m_vValueLineColor ), + CSPVert( vEnd, m_vValueLineColor ) + ); + + // Extend the lines attached to the time labels. + for ( int i=0; i < m_nTimeLabelsDrawn; i++ ) + { + float flTime = m_flTimeOrigin + m_nTimeLabelsDrawn * m_flTimeLabelEveryNSeconds; + + m_pPad->DrawLine( + CSPVert((const Vector&) GetSamplePosition( flTime, m_flHighestValue )), + CSPVert((const Vector&) GetSamplePosition( flTime, flValue ) ) + ); + } + + m_flHighestValue = flValue; + } + + // More text labels? + int iHighestTextLabel = (int)ceil( (flTime - m_flTimeOrigin) / m_flTimeLabelEveryNSeconds + 0.5f ); + while ( m_nTimeLabelsDrawn < iHighestTextLabel ) + { + CTextParams params; + + float flTime = m_flTimeOrigin + m_nTimeLabelsDrawn * m_flTimeLabelEveryNSeconds; + + params.m_bSolidBackground = true; + params.m_vPos = GetSamplePosition( flTime, m_flValueOrigin-5 ); + params.m_bTwoSided = true; + + char str[512]; + Q_snprintf( str, sizeof( str ), "time: %.2f", flTime ); + m_pPad->DrawText( str, params ); + + + // Now draw the vertical line for the value.. + m_pPad->DrawLine( + CSPVert( (const Vector&)GetSamplePosition( flTime, m_flValueOrigin ) ), + CSPVert( (const Vector&)GetSamplePosition( flTime, m_flHighestValue ) ) + ); + + + m_nTimeLabelsDrawn++; + } +} + + +Vector CScratchPadGraph::GetSamplePosition( float flTime, float flValue ) +{ + Vector vRet = + m_vTimeAxis * ((flTime - m_flTimeOrigin) * m_flInchesPerSecond) + + m_vValueAxis * ((flValue - m_flValueOrigin) * m_flInchesPerValue); + + return vRet; +} + + + +// --------------------------------------------------------------------------------------------------------------------- // +// Global functions. +// --------------------------------------------------------------------------------------------------------------------- // + +void ScratchPad_DrawLitCone( + IScratchPad3D *pPad, + const Vector &vBaseCenter, + const Vector &vTip, + const Vector &vBrightColor, + const Vector &vDarkColor, + const Vector &vLightDir, + float baseWidth, + int nSegments ) +{ + // Make orthogonal vectors. + Vector vDir = vTip - vBaseCenter; + VectorNormalize( vDir ); + + Vector vRight, vUp; + VectorVectors( vDir, vRight, vUp ); + vRight *= baseWidth; + vUp *= baseWidth; + + // Setup the top and bottom caps. + CSPVertList bottomCap, tri; + bottomCap.m_Verts.SetSize( nSegments ); + tri.m_Verts.SetSize( 3 ); + + float flDot = -vLightDir.Dot( vDir ); + Vector topColor, bottomColor; + VectorLerp( vDarkColor, vBrightColor, RemapVal( -flDot, -1, 1, 0, 1 ), bottomColor ); + + + // Draw each quad. + Vector vPrevBottom = vBaseCenter + vRight; + + for ( int i=0; i < nSegments; i++ ) + { + float flAngle = (float)(i+1) * M_PI * 2.0 / nSegments; + Vector vOffset = vRight * cos( flAngle ) + vUp * sin( flAngle ); + Vector vCurBottom = vBaseCenter + vOffset; + + const Vector &v1 = vTip; + const Vector &v2 = vPrevBottom; + const Vector &v3 = vCurBottom; + Vector vFaceNormal = (v2 - v1).Cross( v3 - v1 ); + VectorNormalize( vFaceNormal ); + + // Now light it. + flDot = -vLightDir.Dot( vFaceNormal ); + Vector vColor; + VectorLerp( vDarkColor, vBrightColor, RemapVal( flDot, -1, 1, 0, 1 ), vColor ); + + // Draw the quad. + tri.m_Verts[0] = CSPVert( v1, vColor ); + tri.m_Verts[1] = CSPVert( v2, vColor ); + tri.m_Verts[2] = CSPVert( v3, vColor ); + pPad->DrawPolygon( tri ); + + bottomCap.m_Verts[i] = CSPVert( vCurBottom, bottomColor ); + } + + pPad->DrawPolygon( bottomCap ); +} + + +void ScratchPad_DrawLitCylinder( + IScratchPad3D *pPad, + const Vector &v1, + const Vector &v2, + const Vector &vBrightColor, + const Vector &vDarkColor, + const Vector &vLightDir, + float width, + int nSegments ) +{ + // Make orthogonal vectors. + Vector vDir = v2 - v1; + VectorNormalize( vDir ); + + Vector vRight, vUp; + VectorVectors( vDir, vRight, vUp ); + vRight *= width; + vUp *= width; + + // Setup the top and bottom caps. + CSPVertList topCap, bottomCap, quad; + + topCap.m_Verts.SetSize( nSegments ); + bottomCap.m_Verts.SetSize( nSegments ); + quad.m_Verts.SetSize( 4 ); + + float flDot = -vLightDir.Dot( vDir ); + Vector topColor, bottomColor; + + VectorLerp( vDarkColor, vBrightColor, RemapVal( flDot, -1, 1, 0, 1 ), topColor ); + VectorLerp( vDarkColor, vBrightColor, RemapVal( -flDot, -1, 1, 0, 1 ), bottomColor ); + + + // Draw each quad. + Vector vPrevTop = v1 + vRight; + Vector vPrevBottom = v2 + vRight; + + for ( int i=0; i < nSegments; i++ ) + { + float flAngle = (float)(i+1) * M_PI * 2.0 / nSegments; + Vector vOffset = vRight * cos( flAngle ) + vUp * sin( flAngle ); + Vector vCurTop = v1 + vOffset; + Vector vCurBottom = v2 + vOffset; + + // Now light it. + VectorNormalize( vOffset ); + flDot = -vLightDir.Dot( vOffset ); + Vector vColor; + VectorLerp( vDarkColor, vBrightColor, RemapVal( flDot, -1, 1, 0, 1 ), vColor ); + + // Draw the quad. + quad.m_Verts[0] = CSPVert( vPrevTop, vColor ); + quad.m_Verts[1] = CSPVert( vPrevBottom, vColor ); + quad.m_Verts[2] = CSPVert( vCurBottom, vColor ); + quad.m_Verts[3] = CSPVert( vCurTop, vColor ); + pPad->DrawPolygon( quad ); + + topCap.m_Verts[i] = CSPVert( vCurTop, topColor ); + bottomCap.m_Verts[i] = CSPVert( vCurBottom, bottomColor ); + } + + pPad->DrawPolygon( topCap ); + pPad->DrawPolygon( bottomCap ); +} + + +void ScratchPad_DrawArrow( + IScratchPad3D *pPad, + const Vector &vPos, + const Vector &vDirection, + const Vector &vColor, + float flLength, + float flLineWidth, + float flHeadWidth, + int nCylinderSegments, + int nHeadSegments, + float flArrowHeadPercentage + ) +{ + Vector vNormDir = vDirection; + VectorNormalize( vNormDir ); + + Vector vConeBase = vPos + vNormDir * (flLength * ( 1 - flArrowHeadPercentage ) ); + Vector vConeEnd = vPos + vNormDir * flLength; + + Vector vLightDir( -1, -1, -1 ); + VectorNormalize( vLightDir ); // could precalculate this + + pPad->SetRenderState( IScratchPad3D::RS_FillMode, IScratchPad3D::FillMode_Solid ); + pPad->SetRenderState( IScratchPad3D::RS_ZRead, true ); + + ScratchPad_DrawLitCylinder( pPad, vPos, vConeBase, vColor, vColor*0.25f, vLightDir, flLineWidth, nCylinderSegments ); + ScratchPad_DrawLitCone( pPad, vConeBase, vConeEnd, vColor, vColor*0.25f, vLightDir, flHeadWidth, nHeadSegments ); +} + + +void ScratchPad_DrawArrowSimple( + IScratchPad3D *pPad, + const Vector &vPos, + const Vector &vDirection, + const Vector &vColor, + float flLength ) +{ + ScratchPad_DrawArrow( + pPad, + vPos, + vDirection, + vColor, + flLength, + flLength * 1.0/15, + flLength * 3.0/15, + 4, + 4 ); +} + + +void ScratchPad_DrawSphere( + IScratchPad3D *pPad, + const Vector &vCenter, + float flRadius, + const Vector &vColor, + int nSubDivs ) +{ + CUtlVector prevPoints; + prevPoints.SetSize( nSubDivs ); + + // For each vertical slice.. (the top and bottom ones are just a single point). + for ( int iSlice=0; iSlice < nSubDivs; iSlice++ ) + { + float flHalfSliceAngle = M_PI * (float)iSlice / (nSubDivs - 1); + + if ( iSlice == 0 ) + { + prevPoints[0] = vCenter + Vector( 0, 0, flRadius ); + for ( int z=1; z < prevPoints.Count(); z++ ) + prevPoints[z] = prevPoints[0]; + } + else + { + for ( int iSubPt=0; iSubPt < nSubDivs; iSubPt++ ) + { + float flHalfAngle = M_PI * (float)iSubPt / (nSubDivs - 1); + float flAngle = flHalfAngle * 2; + + Vector pt; + if ( iSlice == (nSubDivs - 1) ) + { + pt = vCenter - Vector( 0, 0, flRadius ); + } + else + { + pt.x = cos( flAngle ) * sin( flHalfSliceAngle ); + pt.y = sin( flAngle ) * sin( flHalfSliceAngle ); + pt.z = cos( flHalfSliceAngle ); + + pt *= flRadius; + pt += vCenter; + } + + pPad->DrawLine( CSPVert( pt, vColor ), CSPVert( prevPoints[iSubPt], vColor ) ); + prevPoints[iSubPt] = pt; + } + + if ( iSlice != (nSubDivs - 1) ) + { + for ( int i=0; i < nSubDivs; i++ ) + pPad->DrawLine( CSPVert( prevPoints[i], vColor ), CSPVert( prevPoints[(i+1)%nSubDivs], vColor ) ); + } + } + } +} + + +void ScratchPad_DrawAABB( + IScratchPad3D *pPad, + const Vector &vMins, + const Vector &vMaxs, + const Vector &vColor ) +{ + int vertOrder[4][2] = {{0,0},{1,0},{1,1},{0,1}}; + const Vector *vecs[2] = {&vMins, &vMaxs}; + + Vector vTop, vBottom, vPrevTop, vPrevBottom; + vTop.z = vPrevTop.z = vMaxs.z; + vBottom.z = vPrevBottom.z = vMins.z; + + vPrevTop.x = vPrevBottom.x = vecs[vertOrder[3][0]]->x; + vPrevTop.y = vPrevBottom.y = vecs[vertOrder[3][1]]->y; + + for ( int i=0; i < 4; i++ ) + { + vTop.x = vBottom.x = vecs[vertOrder[i][0]]->x; + vTop.y = vBottom.y = vecs[vertOrder[i][1]]->y; + + // Draw the top line. + pPad->DrawLine( CSPVert( vPrevTop, vColor ), CSPVert( vTop, vColor ) ); + pPad->DrawLine( CSPVert( vPrevBottom, vColor ), CSPVert( vBottom, vColor ) ); + pPad->DrawLine( CSPVert( vTop, vColor ), CSPVert( vBottom, vColor ) ); + + vPrevTop = vTop; + vPrevBottom = vBottom; + } +} + + +#endif // !_STATIC_LINKED || _SHARED_LIB + diff --git a/sp/src/public/ScratchPadUtils.h b/sp/src/public/ScratchPadUtils.h new file mode 100644 index 00000000..9ff47fe2 --- /dev/null +++ b/sp/src/public/ScratchPadUtils.h @@ -0,0 +1,163 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: This module contains helper functions for use with scratch pads. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef SCRATCHPADUTILS_H +#define SCRATCHPADUTILS_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "iscratchpad3d.h" + + +// Use this to make a graph. +class CScratchPadGraph +{ +public: + + typedef int LineID; + + CScratchPadGraph(); + + // Initialze the orientation and scales of the two axes. + // Axis indices are 0, 1, or 2 for x, y, and z. + void Init( + IScratchPad3D *pPad, + + Vector vTimeAxis = Vector(0,-1,0), + float flInchesPerSecond=1, + Vector vTimeLineColor=Vector(0,0,1), + float flTimeOrigin=0, // Where the origin of the graph is. + + float flTimeLabelEveryNSeconds=1, + + Vector vValueAxis = Vector(0,0,1), + float flInchesPerValue=1, + Vector vValueLineColor=Vector(1,0,0), + float flValueOrigin=0 // Where the origin of the graph is. + + ); + + bool IsInitted() const; + + // Add another line into the graph. + LineID AddLine( Vector vColor ); + void AddSample( LineID iLine, float flTime, float flValue ); + void AddVerticalLine( float flTime, float flMinValue, float flMaxValue, const CSPColor &vColor ); + + // Get the 3D position of a sample on the graph (so you can draw other things there). + Vector GetSamplePosition( float flTime, float flValue ); + + +private: + + void UpdateTicksAndStuff( float flTime, float flValue ); + + + +private: + class CLineInfo + { + public: + bool m_bFirst; + float m_flLastTime; + float m_flLastValue; + Vector m_vColor; + }; + + IScratchPad3D *m_pPad; + + CUtlVector m_LineInfos; + + Vector m_vTimeAxis; + float m_flInchesPerSecond; + + Vector m_vValueAxis; + float m_flInchesPerValue; + + // How often to make a time label. + float m_flTimeLabelEveryNSeconds; + int m_nTimeLabelsDrawn; + + Vector m_vTimeLineColor; + Vector m_vValueLineColor; + + float m_flTimeOrigin; + float m_flValueOrigin; + + // Used to extend the value border. + float m_flHighestValue; + float m_flHighestTime; +}; + + + +// Draw a cone. +void ScratchPad_DrawLitCone( + IScratchPad3D *pPad, + const Vector &vBaseCenter, + const Vector &vTip, + const Vector &vBrightColor, + const Vector &vDarkColor, + const Vector &vLightDir, + float baseWidth, + int nSegments ); + + +// Draw a cylinder. +void ScratchPad_DrawLitCylinder( + IScratchPad3D *pPad, + const Vector &v1, + const Vector &v2, + const Vector &vBrightColor, + const Vector &vDarkColor, + const Vector &vLightDir, + float width, + int nSegments ); + + +// Draw an arrow. +void ScratchPad_DrawArrow( + IScratchPad3D *pPad, + const Vector &vPos, + const Vector &vDirection, + const Vector &vColor, + float flLength=20, + float flLineWidth=3, + float flHeadWidth=8, + int nCylinderSegments=5, + int nHeadSegments=8, + float flArrowHeadPercentage = 0.3f // How much of the line is the arrow head. + ); + + +// Draw an arrow with less parameters.. it generates parameters based on length +// automatically to make the arrow look good. +void ScratchPad_DrawArrowSimple( + IScratchPad3D *pPad, + const Vector &vPos, + const Vector &vDirection, + const Vector &vColor, + float flLength ); + +void ScratchPad_DrawSphere( + IScratchPad3D *pPad, + const Vector &vCenter, + float flRadius, + const Vector &vColor, + int nSubDivs=7 ); + + +void ScratchPad_DrawAABB( + IScratchPad3D *pPad, + const Vector &vMins, + const Vector &vMaxs, + const Vector &vColor = Vector( 1,1,1 ) ); + + +#endif // SCRATCHPADUTILS_H diff --git a/sp/src/public/SoundParametersInternal.cpp b/sp/src/public/SoundParametersInternal.cpp new file mode 100644 index 00000000..b408c938 --- /dev/null +++ b/sp/src/public/SoundParametersInternal.cpp @@ -0,0 +1,583 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "cbase.h" + +#if !defined(_STATIC_LINKED) || defined(SOUNDEMITTERSYSTEM_DLL) + +#include "SoundEmitterSystem/isoundemittersystembase.h" +#include "interval.h" +#include "soundchars.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +struct SoundChannels +{ + int channel; + const char *name; +}; + +// NOTE: This will need to be updated if channel names are added/removed +static SoundChannels g_pChannelNames[] = +{ + { CHAN_AUTO, "CHAN_AUTO" }, + { CHAN_WEAPON, "CHAN_WEAPON" }, + { CHAN_VOICE, "CHAN_VOICE" }, + { CHAN_ITEM, "CHAN_ITEM" }, + { CHAN_BODY, "CHAN_BODY" }, + { CHAN_STREAM, "CHAN_STREAM" }, + { CHAN_STATIC, "CHAN_STATIC" }, + { CHAN_VOICE2, "CHAN_VOICE2" }, +}; + +struct VolumeLevel +{ + float volume; + const char *name; +}; + +static VolumeLevel g_pVolumeLevels[] = +{ + { VOL_NORM, "VOL_NORM" }, +}; + +struct PitchLookup +{ + float pitch; + const char *name; +}; + +static PitchLookup g_pPitchLookup[] = +{ + { PITCH_NORM, "PITCH_NORM" }, + { PITCH_LOW, "PITCH_LOW" }, + { PITCH_HIGH, "PITCH_HIGH" }, +}; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +struct SoundLevelLookup +{ + soundlevel_t level; + char const *name; +}; + +// NOTE: Needs to reflect the soundlevel_t enum defined in soundflags.h +static SoundLevelLookup g_pSoundLevels[] = +{ + { SNDLVL_NONE, "SNDLVL_NONE" }, + { SNDLVL_20dB, "SNDLVL_20dB" }, + { SNDLVL_25dB, "SNDLVL_25dB" }, + { SNDLVL_30dB, "SNDLVL_30dB" }, + { SNDLVL_35dB, "SNDLVL_35dB" }, + { SNDLVL_40dB, "SNDLVL_40dB" }, + { SNDLVL_45dB, "SNDLVL_45dB" }, + { SNDLVL_50dB, "SNDLVL_50dB" }, + { SNDLVL_55dB, "SNDLVL_55dB" }, + { SNDLVL_IDLE, "SNDLVL_IDLE" }, + { SNDLVL_TALKING, "SNDLVL_TALKING" }, + { SNDLVL_60dB, "SNDLVL_60dB" }, + { SNDLVL_65dB, "SNDLVL_65dB" }, + { SNDLVL_STATIC, "SNDLVL_STATIC" }, + { SNDLVL_70dB, "SNDLVL_70dB" }, + { SNDLVL_NORM, "SNDLVL_NORM" }, + { SNDLVL_75dB, "SNDLVL_75dB" }, + { SNDLVL_80dB, "SNDLVL_80dB" }, + { SNDLVL_85dB, "SNDLVL_85dB" }, + { SNDLVL_90dB, "SNDLVL_90dB" }, + { SNDLVL_95dB, "SNDLVL_95dB" }, + { SNDLVL_100dB, "SNDLVL_100dB" }, + { SNDLVL_105dB, "SNDLVL_105dB" }, + { SNDLVL_110dB, "SNDLVL_110dB" }, + { SNDLVL_120dB, "SNDLVL_120dB" }, + { SNDLVL_130dB, "SNDLVL_130dB" }, + { SNDLVL_GUNFIRE, "SNDLVL_GUNFIRE" }, + { SNDLVL_140dB, "SNDLVL_140dB" }, + { SNDLVL_150dB, "SNDLVL_150dB" }, + { SNDLVL_180dB, "SNDLVL_180dB" }, +}; + +static const char *_SoundLevelToString( soundlevel_t level ) +{ + int c = ARRAYSIZE( g_pSoundLevels ); + + int i; + + for ( i = 0 ; i < c; i++ ) + { + SoundLevelLookup *entry = &g_pSoundLevels[ i ]; + if ( entry->level == level ) + return entry->name; + } + + static char sz[ 32 ]; + Q_snprintf( sz, sizeof( sz ), "%i", (int)level ); + return sz; +} + +static const char *_ChannelToString( int channel ) +{ + int c = ARRAYSIZE( g_pChannelNames ); + + int i; + + for ( i = 0 ; i < c; i++ ) + { + SoundChannels *entry = &g_pChannelNames[ i ]; + if ( entry->channel == channel ) + return entry->name; + } + + static char sz[ 32 ]; + Q_snprintf( sz, sizeof( sz ), "%i", (int)channel ); + return sz; +} + +static const char *_VolumeToString( float volume ) +{ + int c = ARRAYSIZE( g_pVolumeLevels ); + + int i; + + for ( i = 0 ; i < c; i++ ) + { + VolumeLevel *entry = &g_pVolumeLevels[ i ]; + if ( entry->volume == volume ) + return entry->name; + } + + static char sz[ 32 ]; + Q_snprintf( sz, sizeof( sz ), "%.3f", volume ); + return sz; +} + +static const char *_PitchToString( float pitch ) +{ + int c = ARRAYSIZE( g_pPitchLookup ); + + int i; + + for ( i = 0 ; i < c; i++ ) + { + PitchLookup *entry = &g_pPitchLookup[ i ]; + if ( entry->pitch == pitch ) + return entry->name; + } + + static char sz[ 32 ]; + Q_snprintf( sz, sizeof( sz ), "%.3f", pitch ); + return sz; +} + +#define SNDLVL_PREFIX "SNDLVL_" + +soundlevel_t TextToSoundLevel( const char *key ) +{ + if ( !key ) + { + Assert( 0 ); + return SNDLVL_NORM; + } + + int c = ARRAYSIZE( g_pSoundLevels ); + + int i; + + for ( i = 0 ; i < c; i++ ) + { + SoundLevelLookup *entry = &g_pSoundLevels[ i ]; + if ( !Q_strcasecmp( key, entry->name ) ) + return entry->level; + } + + if ( !Q_strnicmp( key, SNDLVL_PREFIX, Q_strlen( SNDLVL_PREFIX ) ) ) + { + char const *val = key + Q_strlen( SNDLVL_PREFIX ); + int sndlvl = atoi( val ); + if ( sndlvl > 0 && sndlvl <= 180 ) + { + return ( soundlevel_t )sndlvl; + } + } + + DevMsg( "CSoundEmitterSystem: Unknown sound level %s\n", key ); + + return SNDLVL_NORM; +} + +//----------------------------------------------------------------------------- +// Purpose: Convert "chan_xxx" into integer value for channel +// Input : *name - +// Output : static int +//----------------------------------------------------------------------------- +int TextToChannel( const char *name ) +{ + if ( !name ) + { + Assert( 0 ); + // CHAN_AUTO + return CHAN_AUTO; + } + + if ( Q_strncasecmp( name, "chan_", strlen( "chan_" ) ) ) + { + return atoi( name ); + } + + int c = ARRAYSIZE( g_pChannelNames ); + int i; + + for ( i = 0; i < c; i++ ) + { + if ( !Q_strcasecmp( name, g_pChannelNames[ i ].name ) ) + { + return g_pChannelNames[ i ].channel; + } + } + + // At this point, it starts with chan_ but is not recognized + // atoi would return 0, so just do chan auto + DevMsg( "CSoundEmitterSystem: Warning, unknown channel type in sounds.txt (%s)\n", name ); + + return CHAN_AUTO; +} + +const char *SoundLevelToString( soundlevel_t level ) +{ + int c = ARRAYSIZE( g_pSoundLevels ); + + int i; + + for ( i = 0 ; i < c; i++ ) + { + SoundLevelLookup *entry = &g_pSoundLevels[ i ]; + if ( entry->level == level ) + return entry->name; + } + + static char sz[ 32 ]; + Q_snprintf( sz, sizeof( sz ), "%i", (int)level ); + return sz; +} + +const char *ChannelToString( int channel ) +{ + int c = ARRAYSIZE( g_pChannelNames ); + + int i; + + for ( i = 0 ; i < c; i++ ) + { + SoundChannels *entry = &g_pChannelNames[ i ]; + if ( entry->channel == channel ) + return entry->name; + } + + static char sz[ 32 ]; + Q_snprintf( sz, sizeof( sz ), "%i", (int)channel ); + return sz; +} + +const char *VolumeToString( float volume ) +{ + int c = ARRAYSIZE( g_pVolumeLevels ); + + int i; + + for ( i = 0 ; i < c; i++ ) + { + VolumeLevel *entry = &g_pVolumeLevels[ i ]; + if ( entry->volume == volume ) + return entry->name; + } + + static char sz[ 32 ]; + Q_snprintf( sz, sizeof( sz ), "%.3f", volume ); + return sz; +} + +const char *PitchToString( float pitch ) +{ + int c = ARRAYSIZE( g_pPitchLookup ); + + int i; + + for ( i = 0 ; i < c; i++ ) + { + PitchLookup *entry = &g_pPitchLookup[ i ]; + if ( entry->pitch == pitch ) + return entry->name; + } + + static char sz[ 32 ]; + Q_snprintf( sz, sizeof( sz ), "%.3f", pitch ); + return sz; +} + +CSoundParametersInternal::CSoundParametersInternal() +{ + m_pConvertedNames = m_pSoundNames = NULL; + m_nConvertedNames = m_nSoundNames = 0; + channel = CHAN_AUTO; // 0 + + volume.start = VOL_NORM; // 1.0f + volume.range = 0.0f; + + pitch.start = PITCH_NORM; // 100 + pitch.range = 0; + + soundlevel.start = SNDLVL_NORM; // 75dB + soundlevel.range = 0; + delay_msec = 0; + play_to_owner_only = false; + had_missing_wave_files = false; + uses_gender_token = false; + +} + +CSoundParametersInternal::CSoundParametersInternal( const CSoundParametersInternal& src ) +{ + m_pSoundNames = NULL; + m_pConvertedNames = NULL; + m_nSoundNames = 0; + m_nConvertedNames = 0; + CopyFrom( src ); +} + +CSoundParametersInternal::~CSoundParametersInternal() +{ + if ( m_nSoundNames > 1 ) + free(m_pSoundNames ); + if ( m_nConvertedNames > 1 ) + free( m_pConvertedNames); + + m_pConvertedNames = NULL; + m_pSoundNames = NULL; + m_nSoundNames = 0; + m_nConvertedNames = 0; +} + +void CSoundParametersInternal::CopyFrom( const CSoundParametersInternal& src ) +{ + if ( m_nSoundNames > 1 ) + free(m_pSoundNames); + if ( m_nConvertedNames > 1 ) + free(m_pConvertedNames); + + channel = src.channel; + volume = src.volume; + pitch = src.pitch; + soundlevel = src.soundlevel; + delay_msec = src.delay_msec; + play_to_owner_only = src.play_to_owner_only; + + m_nSoundNames = src.m_nSoundNames; + if ( m_nSoundNames ) + { + if ( m_nSoundNames > 1 ) + { + m_pSoundNames = (SoundFile*)malloc( sizeof(SoundFile)*m_nSoundNames); + memcpy( m_pSoundNames, src.m_pSoundNames, m_nSoundNames * sizeof(SoundFile) ); + } + else + { + m_pSoundNames = src.m_pSoundNames; + } + } + else + { + m_pSoundNames = NULL; + } + + m_nConvertedNames = src.m_nConvertedNames; + if ( m_nConvertedNames ) + { + if ( m_nConvertedNames > 1 ) + { + m_pConvertedNames = (SoundFile*)malloc( sizeof(SoundFile)*m_nConvertedNames); + memcpy( m_pConvertedNames, src.m_pConvertedNames, m_nConvertedNames * sizeof(SoundFile) ); + } + else + { + m_pConvertedNames = src.m_pConvertedNames; + } + } + else + { + m_pConvertedNames = NULL; + } + + had_missing_wave_files = src.had_missing_wave_files; + uses_gender_token = src.uses_gender_token; +} + +#define CompareInterval( i1, i2 ) ( memcmp( &(i1), &(i2), sizeof(i1) ) == 0 ) + +bool CSoundParametersInternal::operator == ( const CSoundParametersInternal& other ) const +{ + if ( this == &other ) + return true; + + if ( channel != other.channel ) + return false; + if ( !CompareInterval( volume, other.volume ) ) + return false; + if ( !CompareInterval( pitch, other.pitch ) ) + return false; + if ( !CompareInterval( soundlevel, other.soundlevel ) ) + return false; + if ( delay_msec != other.delay_msec ) + return false; + if ( play_to_owner_only != other.play_to_owner_only ) + return false; + + if ( m_nSoundNames != other.m_nSoundNames ) + return false; + + // Compare items + int c = m_nSoundNames; + for ( int i = 0; i < c; i++ ) + { + if ( GetSoundNames()[ i ].symbol != other.GetSoundNames()[ i ].symbol ) + return false; + } + + return true; +} + +float16 ZERO_FLOAT16; + +const char *CSoundParametersInternal::VolumeToString( void ) const +{ + if ( volume.range == ZERO_FLOAT16 ) + { + return _VolumeToString( volume.start ); + } + + static char sz[ 64 ]; + Q_snprintf( sz, sizeof( sz ), "%.3f, %.3f", (float)volume.start, (float)volume.start + (float)volume.range ); + return sz; +} + +const char *CSoundParametersInternal::ChannelToString( void ) const +{ + return _ChannelToString( channel ); +} + +const char *CSoundParametersInternal::SoundLevelToString( void ) const +{ + if ( soundlevel.range == 0 ) + { + return _SoundLevelToString( (soundlevel_t)(int)soundlevel.start ); + } + + static char sz[ 64 ]; + Q_snprintf( sz, sizeof( sz ), "%i, %i", (soundlevel_t)(int)soundlevel.start, (soundlevel_t)(int)(soundlevel.start + soundlevel.range ) ); + return sz; +} + +const char *CSoundParametersInternal::PitchToString( void ) const +{ + if ( pitch.range == 0 ) + { + return _PitchToString( (int)pitch.start ); + } + + static char sz[ 64 ]; + Q_snprintf( sz, sizeof( sz ), "%i, %i", (int)pitch.start, (int)(pitch.start + pitch.range ) ); + return sz; +} + +void CSoundParametersInternal::VolumeFromString( const char *sz ) +{ + if ( !Q_strcasecmp( sz, "VOL_NORM" ) ) + { + volume.start = VOL_NORM; + volume.range = 0.0f; + } + else + { + volume.FromInterval( ReadInterval( sz ) ); + } +} + +void CSoundParametersInternal::ChannelFromString( const char *sz ) +{ + channel = TextToChannel( sz ); +} + +void CSoundParametersInternal::PitchFromString( const char *sz ) +{ + if ( !Q_strcasecmp( sz, "PITCH_NORM" ) ) + { + pitch.start = PITCH_NORM; + pitch.range = 0; + } + else if ( !Q_strcasecmp( sz, "PITCH_LOW" ) ) + { + pitch.start = PITCH_LOW; + pitch.range = 0; + } + else if ( !Q_strcasecmp( sz, "PITCH_HIGH" ) ) + { + pitch.start = PITCH_HIGH; + pitch.range = 0; + } + else + { + pitch.FromInterval( ReadInterval( sz ) ); + } +} + +void CSoundParametersInternal::SoundLevelFromString( const char *sz ) +{ + if ( !Q_strncasecmp( sz, "SNDLVL_", strlen( "SNDLVL_" ) ) ) + { + soundlevel.start = TextToSoundLevel( sz ); + soundlevel.range = 0; + } + else + { + soundlevel.FromInterval( ReadInterval( sz ) ); + } +} + +void CSoundParametersInternal::AddToTail( SoundFile **pDest, uint16 *pDestCount, const SoundFile &source ) +{ + (*pDestCount)++; + if ( *pDestCount == 1 ) + { + // NOTE: when there's only one soundfile in the list, we store it + // packed into the pointer itself, the four bytes for the pointer is just used to store the sound file! + COMPILE_TIME_ASSERT( sizeof(SoundFile) <= sizeof(SoundFile *) ); + *((SoundFile *)(pDest)) = source; + } + else + { + SoundFile temp; + if ( *pDestCount == 2 ) + { + // Copying from a list of one soundfile. Save off the struct + // packed into the pointer field. + temp = *((SoundFile *)(pDest)); + *pDest = NULL; + } + + *pDest = (SoundFile *)realloc( *pDest, (*pDestCount) * sizeof(SoundFile) ); + (*pDest)[ *pDestCount - 1 ] = source; + + if ( *pDestCount == 2 ) + { + (*pDest)[0] = temp; + } + } +} + +#endif // !_STATIC_LINKED || SOUNDEMITTERSYSTEM_DLL diff --git a/sp/src/public/UnicodeFileHelpers.cpp b/sp/src/public/UnicodeFileHelpers.cpp new file mode 100644 index 00000000..64518274 --- /dev/null +++ b/sp/src/public/UnicodeFileHelpers.cpp @@ -0,0 +1,240 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include +#include +#include "utlbuffer.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// Purpose: Advances until non-whitespace hit +//----------------------------------------------------------------------------- +ucs2 *AdvanceOverWhitespace(ucs2 *Start) +{ + while (*Start != 0 && iswspace(*Start)) + { + Start++; + } + + return Start; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +ucs2 *ReadUnicodeToken(ucs2 *start, ucs2 *token, int tokenBufferSize, bool "ed) +{ + // skip over any whitespace + start = AdvanceOverWhitespace(start); + quoted = false; + *token = 0; + + if (!*start) + { + return start; + } + + // check to see if it's a quoted string + if (*start == '\"') + { + quoted = true; + // copy out the string until we hit an end quote + start++; + int count = 0; + while (*start && *start != '\"' && count < tokenBufferSize-1) + { + // check for special characters + if (*start == '\\' && *(start+1) == 'n') + { + start++; + *token = '\n'; + } + else if (*start == '\\' && *(start+1) == '\"') + { + start++; + *token = '\"'; + } + else + { + *token = *start; + } + + start++; + token++; + count++; + } + + if (*start == '\"') + { + start++; + } + } + else + { + // copy out the string until we hit a whitespace + int count = 0; + while (*start && !iswspace(*start) && count < tokenBufferSize-1) + { + // no checking for special characters if it's not a quoted string + *token = *start; + + start++; + token++; + count++; + } + } + + *token = 0; + return start; +} + +//----------------------------------------------------------------------------- +// Purpose: Same as above but no translation of \n +//----------------------------------------------------------------------------- +ucs2 *ReadUnicodeTokenNoSpecial(ucs2 *start, ucs2 *token, int tokenBufferSize, bool "ed) +{ + // skip over any whitespace + start = AdvanceOverWhitespace(start); + quoted = false; + *token = 0; + + if (!*start) + { + return start; + } + + // check to see if it's a quoted string + if (*start == '\"') + { + quoted = true; + // copy out the string until we hit an end quote + start++; + int count = 0; + while (*start && *start != '\"' && count < tokenBufferSize-1) + { + // check for special characters + /* + if (*start == '\\' && *(start+1) == 'n') + { + start++; + *token = '\n'; + } + else + */ + if (*start == '\\' && *(start+1) == '\"') + { + start++; + *token = '\"'; + } + else + { + *token = *start; + } + + start++; + token++; + count++; + } + + if (*start == '\"') + { + start++; + } + } + else + { + // copy out the string until we hit a whitespace + int count = 0; + while (*start && !iswspace(*start) && count < tokenBufferSize-1) + { + // no checking for special characters if it's not a quoted string + *token = *start; + + start++; + token++; + count++; + } + } + + *token = 0; + return start; +} + +//----------------------------------------------------------------------------- +// Purpose: Returns the first character after the next EOL characters +//----------------------------------------------------------------------------- +ucs2 *ReadToEndOfLine(ucs2 *start) +{ + if (!*start) + return start; + + while (*start) + { + if (*start == 0x0D || *start== 0x0A) + break; + start++; + } + + while (*start == 0x0D || *start== 0x0A) + start++; + + return start; +} + +//----------------------------------------------------------------------------- +// Purpose: file writing +//----------------------------------------------------------------------------- +void WriteUnicodeString(CUtlBuffer &buf, const wchar_t *string, bool addQuotes) +{ + if (addQuotes) + { + buf.PutUnsignedShort('\"'); + } + + for (const wchar_t *ws = string; *ws != 0; ws++) + { + // handle special characters + if (addQuotes && *ws == '\"') + { + buf.PutUnsignedShort('\\'); + } + // write the character + buf.PutUnsignedShort(*ws); + } + + if (addQuotes) + { + buf.PutUnsignedShort('\"'); + } +} + +//----------------------------------------------------------------------------- +// Purpose: file writing +//----------------------------------------------------------------------------- +void WriteAsciiStringAsUnicode(CUtlBuffer &buf, const char *string, bool addQuotes) +{ + if (addQuotes) + { + buf.PutUnsignedShort('\"'); + } + + for (const char *sz = string; *sz != 0; sz++) + { + // handle special characters + if (addQuotes && *sz == '\"') + { + buf.PutUnsignedShort('\\'); + } + buf.PutUnsignedShort(*sz); + } + + if (addQuotes) + { + buf.PutUnsignedShort('\"'); + } +} diff --git a/sp/src/public/UnicodeFileHelpers.h b/sp/src/public/UnicodeFileHelpers.h new file mode 100644 index 00000000..df35f718 --- /dev/null +++ b/sp/src/public/UnicodeFileHelpers.h @@ -0,0 +1,28 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef UNICODEFILEHELPERS_H +#define UNICODEFILEHELPERS_H +#ifdef _WIN32 +#pragma once +#endif + +#include + +// helper functions for parsing unicode file buffers +ucs2 *AdvanceOverWhitespace(ucs2 *start); +ucs2 *ReadUnicodeToken(ucs2 *start, ucs2 *token, int tokenBufferSize, bool "ed); +ucs2 *ReadUnicodeTokenNoSpecial(ucs2 *start, ucs2 *token, int tokenBufferSize, bool "ed); +ucs2 *ReadToEndOfLine(ucs2 *start); + +// writing to unicode files via CUtlBuffer +class CUtlBuffer; +void WriteUnicodeString(CUtlBuffer &buffer, const wchar_t *string, bool addQuotes = false); +void WriteAsciiStringAsUnicode(CUtlBuffer &buffer, const char *string, bool addQuotes = false); + + + +#endif // UNICODEFILEHELPERS_H diff --git a/sp/src/public/UtlCachedFileData.h b/sp/src/public/UtlCachedFileData.h new file mode 100644 index 00000000..d7b0bc46 --- /dev/null +++ b/sp/src/public/UtlCachedFileData.h @@ -0,0 +1,999 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#ifndef UTLCACHEDFILEDATA_H +#define UTLCACHEDFILEDATA_H +#if defined( WIN32 ) +#pragma once +#endif + +#include "filesystem.h" // FileNameHandle_t +#include "utlrbtree.h" +#include "utlbuffer.h" +#include "UtlSortVector.h" +#include "tier1/strtools.h" + +#include "tier0/memdbgon.h" + +// If you change to serialization protocols, this must be bumped... +#define UTL_CACHE_SYSTEM_VERSION 2 + +#define UTL_CACHED_FILE_DATA_UNDEFINED_DISKINFO (long)-2 + +// Cacheable types must derive from this and implement the appropriate methods... +abstract_class IBaseCacheInfo +{ +public: + virtual void Save( CUtlBuffer& buf ) = 0; + virtual void Restore( CUtlBuffer& buf ) = 0; + + virtual void Rebuild( char const *filename ) = 0; +}; + +typedef unsigned int (*PFNCOMPUTECACHEMETACHECKSUM)( void ); + +typedef enum +{ + UTL_CACHED_FILE_USE_TIMESTAMP = 0, + UTL_CACHED_FILE_USE_FILESIZE, +} UtlCachedFileDataType_t; + +template +class CUtlCachedFileData +{ +public: + CUtlCachedFileData + ( + char const *repositoryFileName, + int version, + PFNCOMPUTECACHEMETACHECKSUM checksumfunc = NULL, + UtlCachedFileDataType_t fileCheckType = UTL_CACHED_FILE_USE_TIMESTAMP, + bool nevercheckdisk = false, + bool readonly = false, + bool savemanifest = false + ) + : m_Elements( 0, 0, FileNameHandleLessFunc ), + m_sRepositoryFileName( repositoryFileName ), + m_nVersion( version ), + m_pfnMetaChecksum( checksumfunc ), + m_bDirty( false ), + m_bInitialized( false ), + m_uCurrentMetaChecksum( 0u ), + m_fileCheckType( fileCheckType ), + m_bNeverCheckDisk( nevercheckdisk ), + m_bReadOnly( readonly ), + m_bSaveManifest( savemanifest ) + { + Assert( !m_sRepositoryFileName.IsEmpty() ); + } + + virtual ~CUtlCachedFileData() + { + m_Elements.RemoveAll(); + int c = m_Data.Count(); + for ( int i = 0; i < c ; ++i ) + { + delete m_Data[ i ]; + } + m_Data.RemoveAll(); + } + + T* Get( char const *filename ); + const T* Get( char const *filename ) const; + + T* operator[]( int i ); + const T* operator[]( int i ) const; + + int Count() const; + + void GetElementName( int i, char *buf, int buflen ) + { + buf[ 0 ] = 0; + if ( !m_Elements.IsValidIndex( i ) ) + return; + + g_pFullFileSystem->String( m_Elements[ i ].handle, buf, buflen ); + } + + bool EntryExists( char const *filename ) const + { + ElementType_t element; + element.handle = g_pFullFileSystem->FindOrAddFileName( filename ); + int idx = m_Elements.Find( element ); + return idx != m_Elements.InvalidIndex() ? true : false; + } + + void SetElement( char const *name, long fileinfo, T* src ) + { + SetDirty( true ); + + int idx = GetIndex( name ); + + Assert( idx != m_Elements.InvalidIndex() ); + + ElementType_t& e = m_Elements[ idx ]; + + CUtlBuffer buf( 0, 0, 0 ); + + Assert( e.dataIndex != m_Data.InvalidIndex() ); + + T *dest = m_Data[ e.dataIndex ]; + + Assert( dest ); + + // I suppose we could do an assignment operator, but this should save/restore the data element just fine for + // tool purposes + ((IBaseCacheInfo *)src)->Save( buf ); + ((IBaseCacheInfo *)dest)->Restore( buf ); + + e.fileinfo = fileinfo; + if ( ( e.fileinfo == -1 ) && + ( m_fileCheckType == UTL_CACHED_FILE_USE_FILESIZE ) ) + { + e.fileinfo = 0; + } + // Force recheck + e.diskfileinfo = UTL_CACHED_FILE_DATA_UNDEFINED_DISKINFO; + } + + // If you create a cache and don't call init/shutdown, you can call this to do a quick check to see if the checksum/version + // will cause a rebuild... + bool IsUpToDate(); + + void Shutdown(); + bool Init(); + + void Save(); + + void Reload(); + + void ForceRecheckDiskInfo(); + // Iterates all entries and gets filesystem info and optionally causes rebuild on any existing items which are out of date + void CheckDiskInfo( bool force_rebuild, long cacheFileTime = 0L ); + + void SaveManifest(); + bool ManifestExists(); + + const char *GetRepositoryFileName() const { return m_sRepositoryFileName; } + + long GetFileInfo( char const *filename ) + { + ElementType_t element; + element.handle = g_pFullFileSystem->FindOrAddFileName( filename ); + int idx = m_Elements.Find( element ); + if ( idx == m_Elements.InvalidIndex() ) + { + return 0L; + } + + return m_Elements[ idx ].fileinfo; + } + + int GetNumElements() + { + return m_Elements.Count(); + } + + bool IsDirty() const + { + return m_bDirty; + } + + T *RebuildItem( const char *filename ); + +private: + + void InitSmallBuffer( FileHandle_t& fh, int fileSize, bool& deleteFile ); + void InitLargeBuffer( FileHandle_t& fh, bool& deleteFile ); + + int GetIndex( const char *filename ) + { + ElementType_t element; + element.handle = g_pFullFileSystem->FindOrAddFileName( filename ); + int idx = m_Elements.Find( element ); + if ( idx == m_Elements.InvalidIndex() ) + { + T *data = new T(); + + int dataIndex = m_Data.AddToTail( data ); + idx = m_Elements.Insert( element ); + m_Elements[ idx ].dataIndex = dataIndex; + } + + return idx; + } + + void CheckInit(); + + void SetDirty( bool dirty ) + { + m_bDirty = dirty; + } + + void RebuildCache( char const *filename, T *data ); + + struct ElementType_t + { + ElementType_t() : + handle( 0 ), + fileinfo( 0 ), + diskfileinfo( UTL_CACHED_FILE_DATA_UNDEFINED_DISKINFO ), + dataIndex( -1 ) + { + } + + FileNameHandle_t handle; + long fileinfo; + long diskfileinfo; + int dataIndex; + }; + + static bool FileNameHandleLessFunc( ElementType_t const &lhs, ElementType_t const &rhs ) + { + return lhs.handle < rhs.handle; + } + + CUtlRBTree< ElementType_t > m_Elements; + CUtlVector< T * > m_Data; + CUtlString m_sRepositoryFileName; + int m_nVersion; + PFNCOMPUTECACHEMETACHECKSUM m_pfnMetaChecksum; + unsigned int m_uCurrentMetaChecksum; + UtlCachedFileDataType_t m_fileCheckType; + bool m_bNeverCheckDisk : 1; + bool m_bReadOnly : 1; + bool m_bSaveManifest : 1; + bool m_bDirty : 1; + bool m_bInitialized : 1; + +}; + + +template +T* CUtlCachedFileData::Get( char const *filename ) +{ + int idx = GetIndex( filename ); + + ElementType_t& e = m_Elements[ idx ]; + + if ( e.fileinfo == -1 && + m_fileCheckType == UTL_CACHED_FILE_USE_FILESIZE ) + { + e.fileinfo = 0; + } + long cachefileinfo = e.fileinfo; + // Set the disk fileinfo the first time we encounter the filename + if ( e.diskfileinfo == UTL_CACHED_FILE_DATA_UNDEFINED_DISKINFO ) + { + if ( m_bNeverCheckDisk ) + { + e.diskfileinfo = cachefileinfo; + } + else + { + if ( m_fileCheckType == UTL_CACHED_FILE_USE_FILESIZE ) + { + e.diskfileinfo = g_pFullFileSystem->Size( filename, "GAME" ); + // Missing files get a disk file size of 0 + if ( e.diskfileinfo == -1 ) + { + e.diskfileinfo = 0; + } + } + else + { + e.diskfileinfo = g_pFullFileSystem->GetFileTime( filename, "GAME" ); + } + } + } + + Assert( e.dataIndex != m_Data.InvalidIndex() ); + + T *data = m_Data[ e.dataIndex ]; + + Assert( data ); + + // Compare fileinfo to disk fileinfo and rebuild cache if out of date or not correct... + if ( cachefileinfo != e.diskfileinfo ) + { + if ( !m_bReadOnly ) + { + RebuildCache( filename, data ); + } + e.fileinfo = e.diskfileinfo; + } + + return data; +} + +template +const T* CUtlCachedFileData::Get( char const *filename ) const +{ + return const_cast< CUtlCachedFileData * >(this)->Get( filename ); +} + +template +T* CUtlCachedFileData::operator[]( int i ) +{ + return m_Data[ m_Elements[ i ].dataIndex ]; +} + +template +const T* CUtlCachedFileData::operator[]( int i ) const +{ + return m_Data[ m_Elements[ i ].dataIndex ]; +} + +template +int CUtlCachedFileData::Count() const +{ + return m_Elements.Count(); +} + +template +void CUtlCachedFileData::Reload() +{ + Shutdown(); + Init(); +} + +template +bool CUtlCachedFileData::IsUpToDate() +{ + // Don't call Init/Shutdown if using this method!!! + Assert( !m_bInitialized ); + + if ( m_sRepositoryFileName.IsEmpty() ) + { + Error( "CUtlCachedFileData: Can't IsUpToDate, no repository file specified." ); + return false; + } + + // Always compute meta checksum + m_uCurrentMetaChecksum = m_pfnMetaChecksum ? (*m_pfnMetaChecksum)() : 0; + + FileHandle_t fh; + + fh = g_pFullFileSystem->Open( m_sRepositoryFileName, "rb", "MOD" ); + if ( fh == FILESYSTEM_INVALID_HANDLE ) + { + return false; + } + + // Version data is in first 12 bytes of file + byte header[ 12 ]; + g_pFullFileSystem->Read( header, sizeof( header ), fh ); + g_pFullFileSystem->Close( fh ); + + int cacheversion = *( int *)&header[ 0 ]; + + if ( UTL_CACHE_SYSTEM_VERSION != cacheversion ) + { + DevMsg( "Discarding repository '%s' due to cache system version change\n", m_sRepositoryFileName.String() ); + Assert( !m_bReadOnly ); + if ( !m_bReadOnly ) + { + g_pFullFileSystem->RemoveFile( m_sRepositoryFileName, "MOD" ); + } + return false; + } + + // Now parse data from the buffer + int version = *( int *)&header[ 4 ]; + if ( version != m_nVersion ) + { + DevMsg( "Discarding repository '%s' due to version change\n", m_sRepositoryFileName.String() ); + Assert( !m_bReadOnly ); + if ( !m_bReadOnly ) + { + g_pFullFileSystem->RemoveFile( m_sRepositoryFileName, "MOD" ); + } + return false; + } + + // This is a checksum based on any meta data files which the cache depends on (supplied by a passed in + // meta data function + unsigned int cache_meta_checksum = (unsigned int)*( int *)&header[ 8 ]; + + if ( cache_meta_checksum != m_uCurrentMetaChecksum ) + { + DevMsg( "Discarding repository '%s' due to meta checksum change\n", m_sRepositoryFileName.String() ); + Assert( !m_bReadOnly ); + if ( !m_bReadOnly ) + { + g_pFullFileSystem->RemoveFile( m_sRepositoryFileName, "MOD" ); + } + return false; + } + + // Looks valid + return true; +} + +template +void CUtlCachedFileData::InitSmallBuffer( FileHandle_t& fh, int fileSize, bool& deleteFile ) +{ + deleteFile = false; + + CUtlBuffer loadBuf; + g_pFullFileSystem->ReadToBuffer( fh, loadBuf ); + g_pFullFileSystem->Close( fh ); + + int cacheversion = 0; + loadBuf.Get( &cacheversion, sizeof( cacheversion ) ); + + if ( UTL_CACHE_SYSTEM_VERSION == cacheversion ) + { + // Now parse data from the buffer + int version = loadBuf.GetInt(); + + if ( version == m_nVersion ) + { + // This is a checksum based on any meta data files which the cache depends on (supplied by a passed in + // meta data function + unsigned int cache_meta_checksum = loadBuf.GetInt(); + + if ( cache_meta_checksum == m_uCurrentMetaChecksum ) + { + int count = loadBuf.GetInt(); + + Assert( count < 2000000 ); + + CUtlBuffer buf( 0, 0, 0 ); + + for ( int i = 0 ; i < count; ++i ) + { + int bufsize = loadBuf.GetInt(); + Assert( bufsize < 1000000 ); + + buf.Clear(); + buf.EnsureCapacity( bufsize ); + + loadBuf.Get( buf.Base(), bufsize ); + + buf.SeekGet( CUtlBuffer::SEEK_HEAD, 0 ); + buf.SeekPut( CUtlBuffer::SEEK_HEAD, bufsize ); + + // Read the element name + char elementFileName[ 512 ]; + buf.GetString( elementFileName, sizeof( elementFileName ) ); + + // Now read the element + int slot = GetIndex( elementFileName ); + + Assert( slot != m_Elements.InvalidIndex() ); + + ElementType_t& element = m_Elements[ slot ]; + + element.fileinfo = buf.GetInt(); + if ( ( element.fileinfo == -1 ) && + ( m_fileCheckType == UTL_CACHED_FILE_USE_FILESIZE ) ) + { + element.fileinfo = 0; + } + + Assert( element.dataIndex != m_Data.InvalidIndex() ); + + T *data = m_Data[ element.dataIndex ]; + + Assert( data ); + + ((IBaseCacheInfo *)data)->Restore( buf ); + } + } + else + { + Msg( "Discarding repository '%s' due to meta checksum change\n", m_sRepositoryFileName.String() ); + deleteFile = true; + } + } + else + { + Msg( "Discarding repository '%s' due to version change\n", m_sRepositoryFileName.String() ); + deleteFile = true; + } + } + else + { + DevMsg( "Discarding repository '%s' due to cache system version change\n", m_sRepositoryFileName.String() ); + deleteFile = true; + } +} + +template +void CUtlCachedFileData::InitLargeBuffer( FileHandle_t& fh, bool& deleteFile ) +{ + deleteFile = false; + + int cacheversion = 0; + g_pFullFileSystem->Read( &cacheversion, sizeof( cacheversion ), fh ); + + if ( UTL_CACHE_SYSTEM_VERSION == cacheversion ) + { + // Now parse data from the buffer + int version = 0; + g_pFullFileSystem->Read( &version, sizeof( version ), fh ); + + if ( version == m_nVersion ) + { + // This is a checksum based on any meta data files which the cache depends on (supplied by a passed in + // meta data function + unsigned int cache_meta_checksum = 0; + + g_pFullFileSystem->Read( &cache_meta_checksum, sizeof( cache_meta_checksum ), fh ); + + if ( cache_meta_checksum == m_uCurrentMetaChecksum ) + { + int count = 0; + + g_pFullFileSystem->Read( &count, sizeof( count ), fh ); + + Assert( count < 2000000 ); + + CUtlBuffer buf( 0, 0, 0 ); + + for ( int i = 0 ; i < count; ++i ) + { + int bufsize = 0; + g_pFullFileSystem->Read( &bufsize, sizeof( bufsize ), fh ); + + Assert( bufsize < 1000000 ); + if ( bufsize > 1000000 ) + { + Msg( "Discarding repository '%s' due to corruption\n", m_sRepositoryFileName.String() ); + deleteFile = true; + break; + } + + + buf.Clear(); + buf.EnsureCapacity( bufsize ); + + int nBytesRead = g_pFullFileSystem->Read( buf.Base(), bufsize, fh ); + + buf.SeekGet( CUtlBuffer::SEEK_HEAD, 0 ); + buf.SeekPut( CUtlBuffer::SEEK_HEAD, nBytesRead ); + + // Read the element name + char elementFileName[ 512 ]; + buf.GetString( elementFileName, sizeof( elementFileName ) ); + + // Now read the element + int slot = GetIndex( elementFileName ); + + Assert( slot != m_Elements.InvalidIndex() ); + + ElementType_t& element = m_Elements[ slot ]; + + element.fileinfo = buf.GetInt(); + if ( ( element.fileinfo == -1 ) && + ( m_fileCheckType == UTL_CACHED_FILE_USE_FILESIZE ) ) + { + element.fileinfo = 0; + } + + Assert( element.dataIndex != m_Data.InvalidIndex() ); + + T *data = m_Data[ element.dataIndex ]; + + Assert( data ); + + ((IBaseCacheInfo *)data)->Restore( buf ); + } + } + else + { + Msg( "Discarding repository '%s' due to meta checksum change\n", m_sRepositoryFileName.String() ); + deleteFile = true; + } + } + else + { + Msg( "Discarding repository '%s' due to version change\n", m_sRepositoryFileName.String() ); + deleteFile = true; + } + } + else + { + DevMsg( "Discarding repository '%s' due to cache system version change\n", m_sRepositoryFileName.String() ); + deleteFile = true; + } + + g_pFullFileSystem->Close( fh ); +} + +template +bool CUtlCachedFileData::Init() +{ + if ( m_bInitialized ) + { + return true; + } + + m_bInitialized = true; + + if ( m_sRepositoryFileName.IsEmpty() ) + { + Error( "CUtlCachedFileData: Can't Init, no repository file specified." ); + return false; + } + + // Always compute meta checksum + m_uCurrentMetaChecksum = m_pfnMetaChecksum ? (*m_pfnMetaChecksum)() : 0; + + FileHandle_t fh; + + fh = g_pFullFileSystem->Open( m_sRepositoryFileName, "rb", "MOD" ); + if ( fh == FILESYSTEM_INVALID_HANDLE ) + { + // Nothing on disk, we'll recreate everything from scratch... + SetDirty( true ); + return true; + } + long fileTime = g_pFullFileSystem->GetFileTime( m_sRepositoryFileName, "MOD" ); + int size = g_pFullFileSystem->Size( fh ); + + bool deletefile = false; + + if ( size > 1024 * 1024 ) + { + InitLargeBuffer( fh, deletefile ); + } + else + { + InitSmallBuffer( fh, size, deletefile ); + } + + if ( deletefile ) + { + Assert( !m_bReadOnly ); + if ( !m_bReadOnly ) + { + g_pFullFileSystem->RemoveFile( m_sRepositoryFileName, "MOD" ); + } + SetDirty( true ); + } + CheckDiskInfo( false, fileTime ); + return true; +} + +template +void CUtlCachedFileData::Save() +{ + char path[ 512 ]; + Q_strncpy( path, m_sRepositoryFileName, sizeof( path ) ); + Q_StripFilename( path ); + + g_pFullFileSystem->CreateDirHierarchy( path, "MOD" ); + + if ( g_pFullFileSystem->FileExists( m_sRepositoryFileName, "MOD" ) && + !g_pFullFileSystem->IsFileWritable( m_sRepositoryFileName, "MOD" ) ) + { + g_pFullFileSystem->SetFileWritable( m_sRepositoryFileName, true, "MOD" ); + } + + // Now write to file + FileHandle_t fh; + fh = g_pFullFileSystem->Open( m_sRepositoryFileName, "wb" ); + if ( FILESYSTEM_INVALID_HANDLE == fh ) + { + Warning( "Unable to persist cache '%s', check file permissions\n", m_sRepositoryFileName.String() ); + } + else + { + SetDirty( false ); + + int v = UTL_CACHE_SYSTEM_VERSION; + g_pFullFileSystem->Write( &v, sizeof( v ), fh ); + v = m_nVersion; + g_pFullFileSystem->Write( &v, sizeof( v ), fh ); + v = (int)m_uCurrentMetaChecksum; + g_pFullFileSystem->Write( &v, sizeof( v ), fh ); + + // Element count + int c = Count(); + + g_pFullFileSystem->Write( &c, sizeof( c ), fh ); + + // Save repository back out to disk... + CUtlBuffer buf( 0, 0, 0 ); + + for ( int i = m_Elements.FirstInorder(); i != m_Elements.InvalidIndex(); i = m_Elements.NextInorder( i ) ) + { + buf.SeekPut( CUtlBuffer::SEEK_HEAD, 0 ); + + ElementType_t& element = m_Elements[ i ]; + + char fn[ 512 ]; + g_pFullFileSystem->String( element.handle, fn, sizeof( fn ) ); + + buf.PutString( fn ); + buf.PutInt( element.fileinfo ); + + Assert( element.dataIndex != m_Data.InvalidIndex() ); + + T *data = m_Data[ element.dataIndex ]; + + Assert( data ); + + ((IBaseCacheInfo *)data)->Save( buf ); + + int bufsize = buf.TellPut(); + g_pFullFileSystem->Write( &bufsize, sizeof( bufsize ), fh ); + g_pFullFileSystem->Write( buf.Base(), bufsize, fh ); + } + + g_pFullFileSystem->Close( fh ); + } + + if ( m_bSaveManifest ) + { + SaveManifest(); + } +} + +template +void CUtlCachedFileData::Shutdown() +{ + if ( !m_bInitialized ) + return; + + m_bInitialized = false; + + if ( IsDirty() ) + { + Save(); + } + // No matter what, create the manifest if it doesn't exist on the HD yet + else if ( m_bSaveManifest && !ManifestExists() ) + { + SaveManifest(); + } + + m_Elements.RemoveAll(); +} + +template +bool CUtlCachedFileData::ManifestExists() +{ + char manifest_name[ 512 ]; + Q_strncpy( manifest_name, m_sRepositoryFileName, sizeof( manifest_name ) ); + + Q_SetExtension( manifest_name, ".manifest", sizeof( manifest_name ) ); + + return g_pFullFileSystem->FileExists( manifest_name, "MOD" ); +} + +template +void CUtlCachedFileData::SaveManifest() +{ + // Save manifest out to disk... + CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); + + for ( int i = m_Elements.FirstInorder(); i != m_Elements.InvalidIndex(); i = m_Elements.NextInorder( i ) ) + { + ElementType_t& element = m_Elements[ i ]; + + char fn[ 512 ]; + g_pFullFileSystem->String( element.handle, fn, sizeof( fn ) ); + + buf.Printf( "\"%s\"\r\n", fn ); + } + + char path[ 512 ]; + Q_strncpy( path, m_sRepositoryFileName, sizeof( path ) ); + Q_StripFilename( path ); + + g_pFullFileSystem->CreateDirHierarchy( path, "MOD" ); + + char manifest_name[ 512 ]; + Q_strncpy( manifest_name, m_sRepositoryFileName, sizeof( manifest_name ) ); + + Q_SetExtension( manifest_name, ".manifest", sizeof( manifest_name ) ); + + if ( g_pFullFileSystem->FileExists( manifest_name, "MOD" ) && + !g_pFullFileSystem->IsFileWritable( manifest_name, "MOD" ) ) + { + g_pFullFileSystem->SetFileWritable( manifest_name, true, "MOD" ); + } + + // Now write to file + FileHandle_t fh; + fh = g_pFullFileSystem->Open( manifest_name, "wb" ); + if ( FILESYSTEM_INVALID_HANDLE != fh ) + { + g_pFullFileSystem->Write( buf.Base(), buf.TellPut(), fh ); + g_pFullFileSystem->Close( fh ); + + // DevMsg( "Persisting cache manifest '%s' (%d entries)\n", manifest_name, c ); + } + else + { + Warning( "Unable to persist cache manifest '%s', check file permissions\n", manifest_name ); + } +} + +template +T *CUtlCachedFileData::RebuildItem( const char *filename ) +{ + int idx = GetIndex( filename ); + ElementType_t& e = m_Elements[ idx ]; + + ForceRecheckDiskInfo(); + + long cachefileinfo = e.fileinfo; + // Set the disk fileinfo the first time we encounter the filename + if ( e.diskfileinfo == UTL_CACHED_FILE_DATA_UNDEFINED_DISKINFO ) + { + if ( m_bNeverCheckDisk ) + { + e.diskfileinfo = cachefileinfo; + } + else + { + if ( m_fileCheckType == UTL_CACHED_FILE_USE_FILESIZE ) + { + e.diskfileinfo = g_pFullFileSystem->Size( filename, "GAME" ); + // Missing files get a disk file size of 0 + if ( e.diskfileinfo == -1 ) + { + e.diskfileinfo = 0; + } + } + else + { + e.diskfileinfo = g_pFullFileSystem->GetFileTime( filename, "GAME" ); + } + } + } + + Assert( e.dataIndex != m_Data.InvalidIndex() ); + + T *data = m_Data[ e.dataIndex ]; + + Assert( data ); + + // Compare fileinfo to disk fileinfo and rebuild cache if out of date or not correct... + if ( !m_bReadOnly ) + { + RebuildCache( filename, data ); + } + e.fileinfo = e.diskfileinfo; + + return data; +} + +template +void CUtlCachedFileData::RebuildCache( char const *filename, T *data ) +{ + Assert( !m_bReadOnly ); + + // Recache item, mark self as dirty + SetDirty( true ); + + ((IBaseCacheInfo *)data)->Rebuild( filename ); +} + +template +void CUtlCachedFileData::ForceRecheckDiskInfo() +{ + for ( int i = m_Elements.FirstInorder(); i != m_Elements.InvalidIndex(); i = m_Elements.NextInorder( i ) ) + { + ElementType_t& element = m_Elements[ i ]; + element.diskfileinfo = UTL_CACHED_FILE_DATA_UNDEFINED_DISKINFO; + } +} + +class CSortedCacheFile +{ +public: + FileNameHandle_t handle; + int index; + + bool Less( const CSortedCacheFile &file0, const CSortedCacheFile &file1, void * ) + { + char name0[ 512 ]; + char name1[ 512 ]; + g_pFullFileSystem->String( file0.handle, name0, sizeof( name0 ) ); + g_pFullFileSystem->String( file1.handle, name1, sizeof( name1 ) ); + return Q_stricmp( name0, name1 ) < 0 ? true : false; + } +}; + +// Iterates all entries and causes rebuild on any existing items which are out of date +template +void CUtlCachedFileData::CheckDiskInfo( bool forcerebuild, long cacheFileTime ) +{ + char fn[ 512 ]; + int i; + if ( forcerebuild ) + { + for ( i = m_Elements.FirstInorder(); i != m_Elements.InvalidIndex(); i = m_Elements.NextInorder( i ) ) + { + ElementType_t& element = m_Elements[ i ]; + g_pFullFileSystem->String( element.handle, fn, sizeof( fn ) ); + Get(fn); + } + return; + } + + CUtlSortVector list; + for ( i = m_Elements.FirstInorder(); i != m_Elements.InvalidIndex(); i = m_Elements.NextInorder( i ) ) + { + ElementType_t& element = m_Elements[ i ]; + CSortedCacheFile insert; + insert.handle = element.handle; + insert.index = i; + list.InsertNoSort( insert ); + } + list.RedoSort(); + + if ( !list.Count() ) + return; + + for ( int listStart = 0, listEnd = 0; listStart < list.Count(); listStart = listEnd+1 ) + { + int pathIndex = g_pFullFileSystem->GetPathIndex( m_Elements[list[listStart].index].handle ); + for ( listEnd = listStart; listEnd < list.Count(); listEnd++ ) + { + ElementType_t& element = m_Elements[ list[listEnd].index ]; + + int pathTest = g_pFullFileSystem->GetPathIndex( element.handle ); + if ( pathTest != pathIndex ) + break; + } + g_pFullFileSystem->String( m_Elements[list[listStart].index].handle, fn, sizeof( fn ) ); + Q_StripFilename( fn ); + bool bCheck = true; + + if ( m_bNeverCheckDisk ) + { + bCheck = false; + } + else + { + long pathTime = g_pFullFileSystem->GetPathTime( fn, "GAME" ); + bCheck = (pathTime > cacheFileTime) ? true : false; + } + + for ( i = listStart; i < listEnd; i++ ) + { + ElementType_t& element = m_Elements[ list[i].index ]; + + if ( element.diskfileinfo == UTL_CACHED_FILE_DATA_UNDEFINED_DISKINFO ) + { + if ( !bCheck ) + { + element.diskfileinfo = element.fileinfo; + } + else + { + g_pFullFileSystem->String( element.handle, fn, sizeof( fn ) ); + if ( m_fileCheckType == UTL_CACHED_FILE_USE_FILESIZE ) + { + element.diskfileinfo = g_pFullFileSystem->Size( fn, "GAME" ); + + // Missing files get a disk file size of 0 + if ( element.diskfileinfo == -1 ) + { + element.diskfileinfo = 0; + } + } + else + { + element.diskfileinfo = g_pFullFileSystem->GetFileTime( fn, "GAME" ); + } + } + } + } + } +} + +#include "tier0/memdbgoff.h" + +#endif // UTLCACHEDFILEDATA_H diff --git a/sp/src/public/XUnzip.cpp b/sp/src/public/XUnzip.cpp new file mode 100644 index 00000000..fbeb595e --- /dev/null +++ b/sp/src/public/XUnzip.cpp @@ -0,0 +1,4488 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// XUnzip.cpp Version 1.1 +// +// Authors: Mark Adler et al. (see below) +// +// Modified by: Lucian Wischik +// lu@wischik.com +// +// Version 1.0 - Turned C files into just a single CPP file +// - Made them compile cleanly as C++ files +// - Gave them simpler APIs +// - Added the ability to zip/unzip directly in memory without +// any intermediate files +// +// Modified by: Hans Dietrich +// hdietrich2@hotmail.com +// +// Version 1.1: - Added Unicode support to CreateZip() and ZipAdd() +// - Changed file names to avoid conflicts with Lucian's files +// +/////////////////////////////////////////////////////////////////////////////// +// +// Lucian Wischik's comments: +// -------------------------- +// THIS FILE is almost entirely based upon code by Info-ZIP. +// It has been modified by Lucian Wischik. +// The original code may be found at http://www.info-zip.org +// The original copyright text follows. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Original authors' comments: +// --------------------------- +// This is version 2002-Feb-16 of the Info-ZIP copyright and license. The +// definitive version of this document should be available at +// ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely. +// +// Copyright (c) 1990-2002 Info-ZIP. All rights reserved. +// +// For the purposes of this copyright and license, "Info-ZIP" is defined as +// the following set of individuals: +// +// Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois, +// Jean-loup Gailly, Hunter Goatley, Ian Gorman, Chris Herborth, Dirk Haase, +// Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz, +// David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko, +// Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs, +// Kai Uwe Rommel, Steve Salisbury, Dave Smith, Christian Spieler, +// Antoine Verheijen, Paul von Behren, Rich Wales, Mike White +// +// This software is provided "as is", without warranty of any kind, express +// or implied. In no event shall Info-ZIP or its contributors be held liable +// for any direct, indirect, incidental, special or consequential damages +// arising out of the use of or inability to use this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. Redistributions of source code must retain the above copyright notice, +// definition, disclaimer, and this list of conditions. +// +// 2. Redistributions in binary form (compiled executables) must reproduce +// the above copyright notice, definition, disclaimer, and this list of +// conditions in documentation and/or other materials provided with the +// distribution. The sole exception to this condition is redistribution +// of a standard UnZipSFX binary as part of a self-extracting archive; +// that is permitted without inclusion of this license, as long as the +// normal UnZipSFX banner has not been removed from the binary or disabled. +// +// 3. Altered versions--including, but not limited to, ports to new +// operating systems, existing ports with new graphical interfaces, and +// dynamic, shared, or static library versions--must be plainly marked +// as such and must not be misrepresented as being the original source. +// Such altered versions also must not be misrepresented as being +// Info-ZIP releases--including, but not limited to, labeling of the +// altered versions with the names "Info-ZIP" (or any variation thereof, +// including, but not limited to, different capitalizations), +// "Pocket UnZip", "WiZ" or "MacZip" without the explicit permission of +// Info-ZIP. Such altered versions are further prohibited from +// misrepresentative use of the Zip-Bugs or Info-ZIP e-mail addresses or +// of the Info-ZIP URL(s). +// +// 4. Info-ZIP retains the right to use the names "Info-ZIP", "Zip", "UnZip", +// "UnZipSFX", "WiZ", "Pocket UnZip", "Pocket Zip", and "MacZip" for its +// own source and binary releases. +// +/////////////////////////////////////////////////////////////////////////////// + +#if defined( WIN32 ) && !defined( _X360 ) +#define STRICT +#define WIN32_LEAN_AND_MEAN +#include +#include +#elif defined(POSIX) +#include +#include +#include +#include +#endif +#include +#include +#include +#include +#include "zip/XUnzip.h" + +#if defined(POSIX) +#define _tcslen strlen +#define _tcscpy strcpy +#define _tcscat strcat +#define _tcsstr strstr +#if !defined( _T ) +#define _T( arg ) arg +#endif +#define INVALID_HANDLE_VALUE (void*)-1 +#define CloseHandle( arg ) close( (int) arg ) +#define ZeroMemory( ptr, size ) memset( ptr, 0, size ) +#define FILE_CURRENT SEEK_CUR +#define FILE_BEGIN SEEK_SET +#define FILE_END SEEK_END +#define CreateDirectory( dir, ign ) mkdir( dir, S_IRWXU | S_IRWXG | S_IRWXO ) +#define SetFilePointer( handle, pos, ign, dir ) lseek( (int) handle, pos, dir ) +bool ReadFile( void *handle, void *outbuf, unsigned int toread, unsigned int *nread, void *ignored ) +{ + *nread = read( (int) handle, outbuf, toread ); + return *nread == toread; +} +bool WriteFile( void *handle, void *buf, unsigned int towrite, unsigned int *written, void *ignored ) +{ + *written = write( (int) handle, buf, towrite ); + return *written == towrite; +} + +#define FILE_ATTRIBUTE_NORMAL S_IFREG +#define FILE_ATTRIBUTE_DIRECTORY S_IFDIR +#define FILE_ATTRIBUTE_ARCHIVE 0 +#define FILE_ATTRIBUTE_HIDDEN 0 +#define FILE_ATTRIBUTE_READONLY 0 +#define FILE_ATTRIBUTE_SYSTEM 0 +typedef unsigned char BYTE; +#endif // POSIX + +#if defined( _X360 ) +#include "xbox/xbox_win32stubs.h" +#endif + + +// THIS FILE is almost entirely based upon code by Jean-loup Gailly +// and Mark Adler. It has been modified by Lucian Wischik. +// The original code may be found at http://www.gzip.org/zlib/ +// The original copyright text follows. +// +// +// +// zlib.h -- interface of the 'zlib' general purpose compression library +// version 1.1.3, July 9th, 1998 +// +// Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +// Jean-loup Gailly Mark Adler +// jloup@gzip.org madler@alumni.caltech.edu +// +// +// The data format used by the zlib library is described by RFCs (Request for +// Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt +// (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +// +// +// The 'zlib' compression library provides in-memory compression and +// decompression functions, including integrity checks of the uncompressed +// data. This version of the library supports only one compression method +// (deflation) but other algorithms will be added later and will have the same +// stream interface. +// +// Compression can be done in a single step if the buffers are large +// enough (for example if an input file is mmap'ed), or can be done by +// repeated calls of the compression function. In the latter case, the +// application must provide more input and/or consume the output +// (providing more output space) before each call. +// +// The library also supports reading and writing files in gzip (.gz) format +// with an interface similar to that of stdio. +// +// The library does not install any signal handler. The decoder checks +// the consistency of the compressed data, so the library should never +// crash even in case of corrupted input. +// +// for more info about .ZIP format, see ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip +// PkWare has also a specification at ftp://ftp.pkware.com/probdesc.zip + +#define zmalloc(len) malloc(len) + +#define zfree(p) free(p) + +/* +void *zmalloc(unsigned int len) +{ char *buf = new char[len+32]; + for (int i=0; i<16; i++) + { buf[i]=i; + buf[len+31-i]=i; + } + *((unsigned int*)buf) = len; + char c[1000]; wsprintf(c,"malloc 0x%lx - %lu",buf+16,len); + OutputDebugString(c); + return buf+16; +} + +void zfree(void *buf) +{ char c[1000]; wsprintf(c,"free 0x%lx",buf); + OutputDebugString(c); + char *p = ((char*)buf)-16; + unsigned int len = *((unsigned int*)p); + bool blown=false; + for (int i=0; i<16; i++) + { char lo = p[i]; + char hi = p[len+31-i]; + if (hi!=i || (lo!=i && i>4)) blown=true; + } + if (blown) + { OutputDebugString("BLOWN!!!"); + } + delete[] p; +} +*/ + +#pragma warning(disable : 4702) // unreachable code + +typedef struct tm_unz_s +{ unsigned int tm_sec; // seconds after the minute - [0,59] + unsigned int tm_min; // minutes after the hour - [0,59] + unsigned int tm_hour; // hours since midnight - [0,23] + unsigned int tm_mday; // day of the month - [1,31] + unsigned int tm_mon; // months since January - [0,11] + unsigned int tm_year; // years - [1980..2044] +} tm_unz; + + +// unz_global_info structure contain global data about the ZIPfile +typedef struct unz_global_info_s +{ unsigned long number_entry; // total number of entries in the central dir on this disk + unsigned long size_comment; // size of the global comment of the zipfile +} unz_global_info; + +// unz_file_info contain information about a file in the zipfile +typedef struct unz_file_info_s +{ unsigned long version; // version made by 2 bytes + unsigned long version_needed; // version needed to extract 2 bytes + unsigned long flag; // general purpose bit flag 2 bytes + unsigned long compression_method; // compression method 2 bytes + unsigned long dosDate; // last mod file date in Dos fmt 4 bytes + unsigned long crc; // crc-32 4 bytes + unsigned long compressed_size; // compressed size 4 bytes + unsigned long uncompressed_size; // uncompressed size 4 bytes + unsigned long size_filename; // filename length 2 bytes + unsigned long size_file_extra; // extra field length 2 bytes + unsigned long size_file_comment; // file comment length 2 bytes + unsigned long disk_num_start; // disk number start 2 bytes + unsigned long internal_fa; // internal file attributes 2 bytes + unsigned long external_fa; // external file attributes 4 bytes + tm_unz tmu_date; +} unz_file_info; + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + + + + + + + +#define ZLIB_VERSION "1.1.3" + + +// Allowed flush values; see deflate() for details +#define Z_NO_FLUSH 0 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 + + +// compression levels +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) + +// compression strategy; see deflateInit2() for details +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_DEFAULT_STRATEGY 0 + +// Possible values of the data_type field +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 + +// The deflate compression method (the only one supported in this version) +#define Z_DEFLATED 8 + +// for initializing zalloc, zfree, opaque +#define Z_NULL 0 + +// case sensitivity when searching for filenames +#define CASE_SENSITIVE 1 +#define CASE_INSENSITIVE 2 + + +// Return codes for the compression/decompression functions. Negative +// values are errors, positive values are used for special but normal events. +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) + + + +// Basic data types +typedef unsigned char Byte; // 8 bits +typedef unsigned int uInt; // 16 bits or more +typedef unsigned long uLong; // 32 bits or more +typedef void *voidpf; +typedef void *voidp; +typedef long z_off_t; + + + + + + + + + + + + +typedef voidpf (*alloc_func) (voidpf opaque, uInt items, uInt size); +typedef void (*free_func) (voidpf opaque, voidpf address); + +struct internal_state; + +typedef struct z_stream_s { + Byte *next_in; // next input byte + uInt avail_in; // number of bytes available at next_in + uLong total_in; // total nb of input bytes read so far + + Byte *next_out; // next output byte should be put there + uInt avail_out; // remaining free space at next_out + uLong total_out; // total nb of bytes output so far + + char *msg; // last error message, NULL if no error + struct internal_state *state; // not visible by applications + + alloc_func zalloc; // used to allocate the internal state + free_func zfree; // used to free the internal state + voidpf opaque; // private data object passed to zalloc and zfree + + int data_type; // best guess about the data type: ascii or binary + uLong adler; // adler32 value of the uncompressed data + uLong reserved; // reserved for future use +} z_stream; + +typedef z_stream *z_streamp; + + +// The application must update next_in and avail_in when avail_in has +// dropped to zero. It must update next_out and avail_out when avail_out +// has dropped to zero. The application must initialize zalloc, zfree and +// opaque before calling the init function. All other fields are set by the +// compression library and must not be updated by the application. +// +// The opaque value provided by the application will be passed as the first +// parameter for calls of zalloc and zfree. This can be useful for custom +// memory management. The compression library attaches no meaning to the +// opaque value. +// +// zalloc must return Z_NULL if there is not enough memory for the object. +// If zlib is used in a multi-threaded application, zalloc and zfree must be +// thread safe. +// +// The fields total_in and total_out can be used for statistics or +// progress reports. After compression, total_in holds the total size of +// the uncompressed data and may be saved for use in the decompressor +// (particularly if the decompressor wants to decompress everything in +// a single step). +// + + +// basic functions + +const char *zlibVersion (); +// The application can compare zlibVersion and ZLIB_VERSION for consistency. +// If the first character differs, the library code actually used is +// not compatible with the zlib.h header file used by the application. +// This check is automatically made by inflateInit. + + + + + + +int inflate (z_streamp strm, int flush); +// +// inflate decompresses as much data as possible, and stops when the input +// buffer becomes empty or the output buffer becomes full. It may some +// introduce some output latency (reading input without producing any output) +// except when forced to flush. +// +// The detailed semantics are as follows. inflate performs one or both of the +// following actions: +// +// - Decompress more input starting at next_in and update next_in and avail_in +// accordingly. If not all input can be processed (because there is not +// enough room in the output buffer), next_in is updated and processing +// will resume at this point for the next call of inflate(). +// +// - Provide more output starting at next_out and update next_out and avail_out +// accordingly. inflate() provides as much output as possible, until there +// is no more input data or no more space in the output buffer (see below +// about the flush parameter). +// +// Before the call of inflate(), the application should ensure that at least +// one of the actions is possible, by providing more input and/or consuming +// more output, and updating the next_* and avail_* values accordingly. +// The application can consume the uncompressed output when it wants, for +// example when the output buffer is full (avail_out == 0), or after each +// call of inflate(). If inflate returns Z_OK and with zero avail_out, it +// must be called again after making room in the output buffer because there +// might be more output pending. +// +// If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much +// output as possible to the output buffer. The flushing behavior of inflate is +// not specified for values of the flush parameter other than Z_SYNC_FLUSH +// and Z_FINISH, but the current implementation actually flushes as much output +// as possible anyway. +// +// inflate() should normally be called until it returns Z_STREAM_END or an +// error. However if all decompression is to be performed in a single step +// (a single call of inflate), the parameter flush should be set to +// Z_FINISH. In this case all pending input is processed and all pending +// output is flushed; avail_out must be large enough to hold all the +// uncompressed data. (The size of the uncompressed data may have been saved +// by the compressor for this purpose.) The next operation on this stream must +// be inflateEnd to deallocate the decompression state. The use of Z_FINISH +// is never required, but can be used to inform inflate that a faster routine +// may be used for the single inflate() call. +// +// If a preset dictionary is needed at this point (see inflateSetDictionary +// below), inflate sets strm-adler to the adler32 checksum of the +// dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise +// it sets strm->adler to the adler32 checksum of all output produced +// so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or +// an error code as described below. At the end of the stream, inflate() +// checks that its computed adler32 checksum is equal to that saved by the +// compressor and returns Z_STREAM_END only if the checksum is correct. +// +// inflate() returns Z_OK if some progress has been made (more input processed +// or more output produced), Z_STREAM_END if the end of the compressed data has +// been reached and all uncompressed output has been produced, Z_NEED_DICT if a +// preset dictionary is needed at this point, Z_DATA_ERROR if the input data was +// corrupted (input stream not conforming to the zlib format or incorrect +// adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent +// (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not +// enough memory, Z_BUF_ERROR if no progress is possible or if there was not +// enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR +// case, the application may then call inflateSync to look for a good +// compression block. +// + + +int inflateEnd (z_streamp strm); +// +// All dynamically allocated data structures for this stream are freed. +// This function discards any unprocessed input and does not flush any +// pending output. +// +// inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state +// was inconsistent. In the error case, msg may be set but then points to a +// static string (which must not be deallocated). + + // Advanced functions + +// The following functions are needed only in some special applications. + + + + + +int inflateSetDictionary (z_streamp strm, + const Byte *dictionary, + uInt dictLength); +// +// Initializes the decompression dictionary from the given uncompressed byte +// sequence. This function must be called immediately after a call of inflate +// if this call returned Z_NEED_DICT. The dictionary chosen by the compressor +// can be determined from the Adler32 value returned by this call of +// inflate. The compressor and decompressor must use exactly the same +// dictionary. +// +// inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a +// parameter is invalid (such as NULL dictionary) or the stream state is +// inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the +// expected one (incorrect Adler32 value). inflateSetDictionary does not +// perform any decompression: this will be done by subsequent calls of +// inflate(). + + +int inflateSync (z_streamp strm); +// +// Skips invalid compressed data until a full flush point can be found, or until all +// available input is skipped. No output is provided. +// +// inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR +// if no more input was provided, Z_DATA_ERROR if no flush point has been found, +// or Z_STREAM_ERROR if the stream structure was inconsistent. In the success +// case, the application may save the current current value of total_in which +// indicates where valid compressed data was found. In the error case, the +// application may repeatedly call inflateSync, providing more input each time, +// until success or end of the input data. + + +int inflateReset (z_streamp strm); +// This function is equivalent to inflateEnd followed by inflateInit, +// but does not free and reallocate all the internal decompression state. +// The stream will keep attributes that may have been set by inflateInit2. +// +// inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source +// stream state was inconsistent (such as zalloc or state being NULL). +// + + + +// checksum functions +// These functions are not related to compression but are exported +// anyway because they might be useful in applications using the +// compression library. + +uLong adler32 (uLong adler, const Byte *buf, uInt len); +// Update a running Adler-32 checksum with the bytes buf[0..len-1] and +// return the updated checksum. If buf is NULL, this function returns +// the required initial value for the checksum. +// An Adler-32 checksum is almost as reliable as a CRC32 but can be computed +// much faster. Usage example: +// +// uLong adler = adler32(0L, Z_NULL, 0); +// +// while (read_buffer(buffer, length) != EOF) { +// adler = adler32(adler, buffer, length); +// } +// if (adler != original_adler) error(); + +uLong ucrc32 (uLong crc, const Byte *buf, uInt len); +// Update a running crc with the bytes buf[0..len-1] and return the updated +// crc. If buf is NULL, this function returns the required initial value +// for the crc. Pre- and post-conditioning (one's complement) is performed +// within this function so it shouldn't be done by the application. +// Usage example: +// +// uLong crc = crc32(0L, Z_NULL, 0); +// +// while (read_buffer(buffer, length) != EOF) { +// crc = crc32(crc, buffer, length); +// } +// if (crc != original_crc) error(); + + + + +const char *zError (int err); +int inflateSyncPoint (z_streamp z); +const uLong *get_crc_table (void); + + + +typedef unsigned char uch; +typedef uch uchf; +typedef unsigned short ush; +typedef ush ushf; +typedef unsigned long ulg; + + + +const char * const z_errmsg[10] = { // indexed by 2-zlib_error +"need dictionary", // Z_NEED_DICT 2 +"stream end", // Z_STREAM_END 1 +"", // Z_OK 0 +"file error", // Z_ERRNO (-1) +"stream error", // Z_STREAM_ERROR (-2) +"data error", // Z_DATA_ERROR (-3) +"insufficient memory", // Z_MEM_ERROR (-4) +"buffer error", // Z_BUF_ERROR (-5) +"incompatible version",// Z_VERSION_ERROR (-6) +""}; + + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +// To be used only when the state is known to be valid + + // common constants + + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +// The three kinds of block type + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +// The minimum and maximum match lengths + +#define PRESET_DICT 0x20 // preset dictionary flag in zlib header + + // target dependencies + +#define OS_CODE 0x0b // Window 95 & Windows NT + + + + // functions + +#define zmemzero(dest, len) memset(dest, 0, len) + +// Diagnostic functions +#undef Assert +#undef Trace +#undef Tracev +#undef Tracevv +#undef Tracec +#undef Tracecv + +#ifdef DEBUG + int z_verbose = 0; + void z_error (char *m) {fprintf(stderr, "%s\n", m); exit(1);} +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +typedef uLong (*check_func) (uLong check, const Byte *buf, uInt len); +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size); +void zcfree (voidpf opaque, voidpf ptr); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) + +//void ZFREE(z_streamp strm,voidpf addr) +//{ *((strm)->zfree))((strm)->opaque, addr); +//} + +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + + + + +// Huffman code lookup table entry--this entry is four bytes for machines +// that have 16-bit pointers (e.g. PC's in the small or medium model). + + +typedef struct inflate_huft_s inflate_huft; + +struct inflate_huft_s { + union { + struct { + Byte Exop; // number of extra bits or operation + Byte Bits; // number of bits in this code or subcode + } what; + uInt pad; // pad structure to a power of 2 (4 bytes for + } word; // 16-bit, 8 bytes for 32-bit int's) + uInt base; // literal, length base, distance base, or table offset +}; + +// Maximum size of dynamic tree. The maximum found in a long but non- +// exhaustive search was 1004 huft structures (850 for length/literals +// and 154 for distances, the latter actually the result of an +// exhaustive search). The actual maximum is not known, but the +// value below is more than safe. +#define MANY 1440 + +int inflate_trees_bits ( + uInt *, // 19 code lengths + uInt *, // bits tree desired/actual depth + inflate_huft * *, // bits tree result + inflate_huft *, // space for trees + z_streamp); // for messages + +int inflate_trees_dynamic ( + uInt, // number of literal/length codes + uInt, // number of distance codes + uInt *, // that many (total) code lengths + uInt *, // literal desired/actual bit depth + uInt *, // distance desired/actual bit depth + inflate_huft * *, // literal/length tree result + inflate_huft * *, // distance tree result + inflate_huft *, // space for trees + z_streamp); // for messages + +int inflate_trees_fixed ( + uInt *, // literal desired/actual bit depth + uInt *, // distance desired/actual bit depth + const inflate_huft * *, // literal/length tree result + const inflate_huft * *, // distance tree result + z_streamp); // for memory allocation + + + + + +struct inflate_blocks_state; +typedef struct inflate_blocks_state inflate_blocks_statef; + +inflate_blocks_statef * inflate_blocks_new ( + z_streamp z, + check_func c, // check function + uInt w); // window size + +int inflate_blocks ( + inflate_blocks_statef *, + z_streamp , + int); // initial return code + +void inflate_blocks_reset ( + inflate_blocks_statef *, + z_streamp , + uLong *); // check value on output + +int inflate_blocks_free ( + inflate_blocks_statef *, + z_streamp); + +void inflate_set_dictionary ( + inflate_blocks_statef *s, + const Byte *d, // dictionary + uInt n); // dictionary length + +int inflate_blocks_sync_point ( + inflate_blocks_statef *s); + + + + +struct inflate_codes_state; +typedef struct inflate_codes_state inflate_codes_statef; + +inflate_codes_statef *inflate_codes_new ( + uInt, uInt, + const inflate_huft *, const inflate_huft *, + z_streamp ); + +int inflate_codes ( + inflate_blocks_statef *, + z_streamp , + int); + +void inflate_codes_free ( + inflate_codes_statef *, + z_streamp ); + + + + +typedef enum { + IBM_TYPE, // get type bits (3, including end bit) + IBM_LENS, // get lengths for stored + IBM_STORED, // processing stored block + IBM_TABLE, // get table lengths + IBM_BTREE, // get bit lengths tree for a dynamic block + IBM_DTREE, // get length, distance trees for a dynamic block + IBM_CODES, // processing fixed or dynamic block + IBM_DRY, // output remaining window bytes + IBM_DONE, // finished last block, done + IBM_BAD} // got a data error--stuck here +inflate_block_mode; + +// inflate blocks semi-private state +struct inflate_blocks_state { + + // mode + inflate_block_mode mode; // current inflate_block mode + + // mode dependent information + union { + uInt left; // if STORED, bytes left to copy + struct { + uInt table; // table lengths (14 bits) + uInt index; // index into blens (or border) + uInt *blens; // bit lengths of codes + uInt bb; // bit length tree depth + inflate_huft *tb; // bit length decoding tree + } trees; // if DTREE, decoding info for trees + struct { + inflate_codes_statef + *codes; + } decode; // if CODES, current state + } sub; // submode + uInt last; // true if this block is the last block + + // mode independent information + uInt bitk; // bits in bit buffer + uLong bitb; // bit buffer + inflate_huft *hufts; // single malloc for tree space + Byte *window; // sliding window + Byte *end; // one byte after sliding window + Byte *read; // window read pointer + Byte *write; // window write pointer + check_func checkfn; // check function + uLong check; // check on output + +}; + + +// defines for inflate input/output +// update pointers and return +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=(uLong)(p-z->next_in);z->next_in=p;} +#define UPDOUT {s->write=q;} +#define UPDATE {UPDBITS UPDIN UPDOUT} +#define LEAVE {UPDATE return inflate_flush(s,z,r);} +// get bytes and bits +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} +// output bytes +#define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;m;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} +// load local pointers +#define LOAD {LOADIN LOADOUT} + +// masks for lower bits (size given to avoid silly warnings with Visual C++) +// And'ing with mask[n] masks the lower n bits +const uInt inflate_mask[17] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + +// copy as much as possible from the sliding window to the output area +int inflate_flush (inflate_blocks_statef *, z_streamp, int); + +int inflate_fast (uInt, uInt, const inflate_huft *, const inflate_huft *, inflate_blocks_statef *, z_streamp ); + + + +const uInt fixed_bl = 9; +const uInt fixed_bd = 5; +const inflate_huft fixed_tl[] = { + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} + }; +const inflate_huft fixed_td[] = { + {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, + {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, + {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, + {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, + {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, + {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, + {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, + {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} + }; + + + + + + + +// copy as much as possible from the sliding window to the output area +int inflate_flush(inflate_blocks_statef *s,z_streamp z,int r) +{ + uInt n; + Byte *p; + Byte *q; + + // local copies of source and destination pointers + p = z->next_out; + q = s->read; + + // compute number of bytes to copy as far as end of window + n = (uInt)((q <= s->write ? s->write : s->end) - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + // update counters + z->avail_out -= n; + z->total_out += n; + + // update check information + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + // copy as far as end of window + if (n!=0) // check for n!=0 to avoid waking up CodeGuard + { memcpy(p, q, n); + p += n; + q += n; + } + + // see if more to copy at beginning of window + if (q == s->end) + { + // wrap pointers + q = s->window; + if (s->write == s->end) + s->write = s->window; + + // compute bytes to copy + n = (uInt)(s->write - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + // update counters + z->avail_out -= n; + z->total_out += n; + + // update check information + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + // copy + memcpy(p, q, n); + p += n; + q += n; + } + + // update pointers + z->next_out = p; + s->read = q; + + // done + return r; +} + + + + + + +// simplify the use of the inflate_huft type with some defines +#define exop word.what.Exop +#define bits word.what.Bits + +typedef enum { // waiting for "i:"=input, "o:"=output, "x:"=nothing + START, // x: set up for LEN + LEN, // i: get length/literal/eob next + LENEXT, // i: getting length extra (have base) + DIST, // i: get distance next + DISTEXT, // i: getting distance extra + COPY, // o: copying bytes in window, waiting for space + LIT, // o: got literal, waiting for output space + WASH, // o: got eob, possibly still output waiting + END, // x: got eob and all data flushed + BADCODE} // x: got error +inflate_codes_mode; + +// inflate codes private state +struct inflate_codes_state { + + // mode + inflate_codes_mode mode; // current inflate_codes mode + + // mode dependent information + uInt len; + union { + struct { + const inflate_huft *tree; // pointer into tree + uInt need; // bits needed + } code; // if LEN or DIST, where in tree + uInt lit; // if LIT, literal + struct { + uInt get; // bits to get for extra + uInt dist; // distance back to copy from + } copy; // if EXT or COPY, where and how much + } sub; // submode + + // mode independent information + Byte lbits; // ltree bits decoded per branch + Byte dbits; // dtree bits decoder per branch + const inflate_huft *ltree; // literal/length/eob tree + const inflate_huft *dtree; // distance tree + +}; + + +inflate_codes_statef *inflate_codes_new( +uInt bl, uInt bd, +const inflate_huft *tl, +const inflate_huft *td, // need separate declaration for Borland C++ +z_streamp z) +{ + inflate_codes_statef *c; + + if ((c = (inflate_codes_statef *) + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) + { + c->mode = START; + c->lbits = (Byte)bl; + c->dbits = (Byte)bd; + c->ltree = tl; + c->dtree = td; + Tracev((stderr, "inflate: codes new\n")); + } + return c; +} + + +int inflate_codes(inflate_blocks_statef *s, z_streamp z, int r) +{ + uInt j; // temporary storage + const inflate_huft *t; // temporary pointer + uInt e; // extra bits or operation + uLong b; // bit buffer + uInt k; // bits in bit buffer + Byte *p; // input data pointer + uInt n; // bytes available there + Byte *q; // output window write pointer + uInt m; // bytes to end of window or read pointer + Byte *f; // pointer to copy strings from + inflate_codes_statef *c = s->sub.decode.codes; // codes state + + // copy input/output information to locals (UPDATE macro restores) + LOAD + + // process input and output based on current state + for(;;) switch (c->mode) + { // waiting for "i:"=input, "o:"=output, "x:"=nothing + case START: // x: set up for LEN +#ifndef SLOW + if (m >= 258 && n >= 10) + { + UPDATE + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); + LOAD + if (r != Z_OK) + { + c->mode = r == Z_STREAM_END ? WASH : BADCODE; + break; + } + } +#endif // !SLOW + c->sub.code.need = c->lbits; + c->sub.code.tree = c->ltree; + c->mode = LEN; + case LEN: // i: get length/literal/eob next + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e == 0) // literal + { + c->sub.lit = t->base; + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", t->base)); + c->mode = LIT; + break; + } + if (e & 16) // length + { + c->sub.copy.get = e & 15; + c->len = t->base; + c->mode = LENEXT; + break; + } + if ((e & 64) == 0) // next table + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + if (e & 32) // end of block + { + Tracevv((stderr, "inflate: end of block\n")); + c->mode = WASH; + break; + } + c->mode = BADCODE; // invalid code + z->msg = (char*)"invalid literal/length code"; + r = Z_DATA_ERROR; + LEAVE + case LENEXT: // i: getting length extra (have base) + j = c->sub.copy.get; + NEEDBITS(j) + c->len += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + c->sub.code.need = c->dbits; + c->sub.code.tree = c->dtree; + Tracevv((stderr, "inflate: length %u\n", c->len)); + c->mode = DIST; + case DIST: // i: get distance next + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e & 16) // distance + { + c->sub.copy.get = e & 15; + c->sub.copy.dist = t->base; + c->mode = DISTEXT; + break; + } + if ((e & 64) == 0) // next table + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + c->mode = BADCODE; // invalid code + z->msg = (char*)"invalid distance code"; + r = Z_DATA_ERROR; + LEAVE + case DISTEXT: // i: getting distance extra + j = c->sub.copy.get; + NEEDBITS(j) + c->sub.copy.dist += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); + c->mode = COPY; + case COPY: // o: copying bytes in window, waiting for space + f = (uInt)(q - s->window) < c->sub.copy.dist ? + s->end - (c->sub.copy.dist - (q - s->window)) : + q - c->sub.copy.dist; + while (c->len) + { + NEEDOUT + OUTBYTE(*f++) + if (f == s->end) + f = s->window; + c->len--; + } + c->mode = START; + break; + case LIT: // o: got literal, waiting for output space + NEEDOUT + OUTBYTE(c->sub.lit) + c->mode = START; + break; + case WASH: // o: got eob, possibly more output + if (k > 7) // return unused byte, if any + { + Assert(k < 16, "inflate_codes grabbed too many bytes") + k -= 8; + n++; + p--; // can always return one + } + FLUSH + if (s->read != s->write) + LEAVE + c->mode = END; + case END: + r = Z_STREAM_END; + LEAVE + case BADCODE: // x: got error + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +void inflate_codes_free(inflate_codes_statef *c,z_streamp z) +{ ZFREE(z, c); + Tracev((stderr, "inflate: codes free\n")); +} + + + +// infblock.c -- interpret and process block types to last block +// Copyright (C) 1995-1998 Mark Adler +// For conditions of distribution and use, see copyright notice in zlib.h + +//struct inflate_codes_state {int dummy;}; // for buggy compilers + + + +// Table for deflate from PKZIP's appnote.txt. +const uInt border[] = { // Order of the bit length code lengths + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +// +// Notes beyond the 1.93a appnote.txt: +// +// 1. Distance pointers never point before the beginning of the output stream. +// 2. Distance pointers can point back across blocks, up to 32k away. +// 3. There is an implied maximum of 7 bits for the bit length table and +// 15 bits for the actual data. +// 4. If only one code exists, then it is encoded using one bit. (Zero +// would be more efficient, but perhaps a little confusing.) If two +// codes exist, they are coded using one bit each (0 and 1). +// 5. There is no way of sending zero distance codes--a dummy must be +// sent if there are none. (History: a pre 2.0 version of PKZIP would +// store blocks with no distance codes, but this was discovered to be +// too harsh a criterion.) Valid only for 1.93a. 2.04c does allow +// zero distance codes, which is sent as one code of zero bits in +// length. +// 6. There are up to 286 literal/length codes. Code 256 represents the +// end-of-block. Note however that the static length tree defines +// 288 codes just to fill out the Huffman codes. Codes 286 and 287 +// cannot be used though, since there is no length base or extra bits +// defined for them. Similarily, there are up to 30 distance codes. +// However, static trees define 32 codes (all 5 bits) to fill out the +// Huffman codes, but the last two had better not show up in the data. +// 7. Unzip can check dynamic Huffman blocks for complete code sets. +// The exception is that a single code would not be complete (see #4). +// 8. The five bits following the block type is really the number of +// literal codes sent minus 257. +// 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits +// (1+6+6). Therefore, to output three times the length, you output +// three codes (1+1+1), whereas to output four times the same length, +// you only need two codes (1+3). Hmm. +//10. In the tree reconstruction algorithm, Code = Code + Increment +// only if BitLength(i) is not zero. (Pretty obvious.) +//11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) +//12. Note: length code 284 can represent 227-258, but length code 285 +// really is 258. The last length deserves its own, short code +// since it gets used a lot in very redundant files. The length +// 258 is special since 258 - 3 (the min match length) is 255. +//13. The literal/length and distance code bit lengths are read as a +// single stream of lengths. It is possible (and advantageous) for +// a repeat code (16, 17, or 18) to go across the boundary between +// the two sets of lengths. + + +void inflate_blocks_reset(inflate_blocks_statef *s, z_streamp z, uLong *c) +{ + if (c != Z_NULL) + *c = s->check; + if (s->mode == IBM_BTREE || s->mode == IBM_DTREE) + ZFREE(z, s->sub.trees.blens); + if (s->mode == IBM_CODES) + inflate_codes_free(s->sub.decode.codes, z); + s->mode = IBM_TYPE; + s->bitk = 0; + s->bitb = 0; + s->read = s->write = s->window; + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(0L, (const Byte *)Z_NULL, 0); + Tracev((stderr, "inflate: blocks reset\n")); +} + + +inflate_blocks_statef *inflate_blocks_new(z_streamp z, check_func c, uInt w) +{ + inflate_blocks_statef *s; + + if ((s = (inflate_blocks_statef *)ZALLOC + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) + return s; + if ((s->hufts = + (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) + { + ZFREE(z, s); + return Z_NULL; + } + if ((s->window = (Byte *)ZALLOC(z, 1, w)) == Z_NULL) + { + ZFREE(z, s->hufts); + ZFREE(z, s); + return Z_NULL; + } + s->end = s->window + w; + s->checkfn = c; + s->mode = IBM_TYPE; + Tracev((stderr, "inflate: blocks allocated\n")); + inflate_blocks_reset(s, z, Z_NULL); + return s; +} + + +int inflate_blocks(inflate_blocks_statef *s, z_streamp z, int r) +{ + uInt t; // temporary storage + uLong b; // bit buffer + uInt k; // bits in bit buffer + Byte *p; // input data pointer + uInt n; // bytes available there + Byte *q; // output window write pointer + uInt m; // bytes to end of window or read pointer + + // copy input/output information to locals (UPDATE macro restores) + LOAD + + // process input based on current state + for(;;) switch (s->mode) + { + case IBM_TYPE: + NEEDBITS(3) + t = (uInt)b & 7; + s->last = t & 1; + switch (t >> 1) + { + case 0: // stored + Tracev((stderr, "inflate: stored block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + t = k & 7; // go to byte boundary + DUMPBITS(t) + s->mode = IBM_LENS; // get length of stored block + break; + case 1: // fixed + Tracev((stderr, "inflate: fixed codes block%s\n", + s->last ? " (last)" : "")); + { + uInt bl, bd; + const inflate_huft *tl, *td; + + inflate_trees_fixed(&bl, &bd, &tl, &td, z); + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); + if (s->sub.decode.codes == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + } + DUMPBITS(3) + s->mode = IBM_CODES; + break; + case 2: // dynamic + Tracev((stderr, "inflate: dynamic codes block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + s->mode = IBM_TABLE; + break; + case 3: // illegal + DUMPBITS(3) + s->mode = IBM_BAD; + z->msg = (char*)"invalid block type"; + r = Z_DATA_ERROR; + LEAVE + } + break; + case IBM_LENS: + NEEDBITS(32) + if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) + { + s->mode = IBM_BAD; + z->msg = (char*)"invalid stored block lengths"; + r = Z_DATA_ERROR; + LEAVE + } + s->sub.left = (uInt)b & 0xffff; + b = k = 0; // dump bits + Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); + s->mode = s->sub.left ? IBM_STORED : (s->last ? IBM_DRY : IBM_TYPE); + break; + case IBM_STORED: + if (n == 0) + LEAVE + NEEDOUT + t = s->sub.left; + if (t > n) t = n; + if (t > m) t = m; + memcpy(q, p, t); + p += t; n -= t; + q += t; m -= t; + if ((s->sub.left -= t) != 0) + break; + Tracev((stderr, "inflate: stored end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + s->mode = s->last ? IBM_DRY : IBM_TYPE; + break; + case IBM_TABLE: + NEEDBITS(14) + s->sub.trees.table = t = (uInt)b & 0x3fff; + // remove this section to workaround bug in pkzip + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + s->mode = IBM_BAD; + z->msg = (char*)"too many length or distance symbols"; + r = Z_DATA_ERROR; + LEAVE + } + // end remove + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if ((s->sub.trees.blens = (uInt*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + DUMPBITS(14) + s->sub.trees.index = 0; + Tracev((stderr, "inflate: table sizes ok\n")); + s->mode = IBM_BTREE; + case IBM_BTREE: + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) + { + NEEDBITS(3) + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; + DUMPBITS(3) + } + while (s->sub.trees.index < 19) + s->sub.trees.blens[border[s->sub.trees.index++]] = 0; + s->sub.trees.bb = 7; + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, + &s->sub.trees.tb, s->hufts, z); + if (t != Z_OK) + { + ZFREE(z, s->sub.trees.blens); + r = t; + if (r == Z_DATA_ERROR) + s->mode = IBM_BAD; + LEAVE + } + s->sub.trees.index = 0; + Tracev((stderr, "inflate: bits tree ok\n")); + s->mode = IBM_DTREE; + case IBM_DTREE: + while (t = s->sub.trees.table, + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) + { + inflate_huft *h; + uInt i, j, c; + + t = s->sub.trees.bb; + NEEDBITS(t) + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); + t = h->bits; + c = h->base; + if (c < 16) + { + DUMPBITS(t) + s->sub.trees.blens[s->sub.trees.index++] = c; + } + else // c == 16..18 + { + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + NEEDBITS(t + i) + DUMPBITS(t) + j += (uInt)b & inflate_mask[i]; + DUMPBITS(i) + i = s->sub.trees.index; + t = s->sub.trees.table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)) + { + ZFREE(z, s->sub.trees.blens); + s->mode = IBM_BAD; + z->msg = (char*)"invalid bit length repeat"; + r = Z_DATA_ERROR; + LEAVE + } + c = c == 16 ? s->sub.trees.blens[i - 1] : 0; + do { + s->sub.trees.blens[i++] = c; + } while (--j); + s->sub.trees.index = i; + } + } + s->sub.trees.tb = Z_NULL; + { + uInt bl, bd; + inflate_huft *tl, *td; + inflate_codes_statef *c; + + bl = 9; // must be <= 9 for lookahead assumptions + bd = 6; // must be <= 9 for lookahead assumptions + t = s->sub.trees.table; + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), + s->sub.trees.blens, &bl, &bd, &tl, &td, + s->hufts, z); + ZFREE(z, s->sub.trees.blens); + if (t != Z_OK) + { + if (t == (uInt)Z_DATA_ERROR) + s->mode = IBM_BAD; + r = t; + LEAVE + } + Tracev((stderr, "inflate: trees ok\n")); + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + s->sub.decode.codes = c; + } + s->mode = IBM_CODES; + case IBM_CODES: + UPDATE + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) + return inflate_flush(s, z, r); + r = Z_OK; + inflate_codes_free(s->sub.decode.codes, z); + LOAD + Tracev((stderr, "inflate: codes end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + if (!s->last) + { + s->mode = IBM_TYPE; + break; + } + s->mode = IBM_DRY; + case IBM_DRY: + FLUSH + if (s->read != s->write) + LEAVE + s->mode = IBM_DONE; + case IBM_DONE: + r = Z_STREAM_END; + LEAVE + case IBM_BAD: + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +int inflate_blocks_free(inflate_blocks_statef *s, z_streamp z) +{ + inflate_blocks_reset(s, z, Z_NULL); + ZFREE(z, s->window); + ZFREE(z, s->hufts); + ZFREE(z, s); + Tracev((stderr, "inflate: blocks freed\n")); + return Z_OK; +} + + + +// inftrees.c -- generate Huffman trees for efficient decoding +// Copyright (C) 1995-1998 Mark Adler +// For conditions of distribution and use, see copyright notice in zlib.h +// + + + +extern const char inflate_copyright_XUnzip[] = + " inflate 1.1.3 Copyright 1995-1998 Mark Adler "; +// If you use the zlib library in a product, an acknowledgment is welcome +// in the documentation of your product. If for some reason you cannot +// include such an acknowledgment, I would appreciate that you keep this +// copyright string in the executable of your product. + + + +int huft_build ( + uInt *, // code lengths in bits + uInt, // number of codes + uInt, // number of "simple" codes + const uInt *, // list of base values for non-simple codes + const uInt *, // list of extra bits for non-simple codes + inflate_huft **,// result: starting table + uInt *, // maximum lookup bits (returns actual) + inflate_huft *, // space for trees + uInt *, // hufts used in space + uInt * ); // space for values + +// Tables for deflate from PKZIP's appnote.txt. +const uInt cplens[31] = { // Copy lengths for literal codes 257..285 + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + // see note #13 above about 258 +const uInt cplext[31] = { // Extra bits for literal codes 257..285 + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; // 112==invalid +const uInt cpdist[30] = { // Copy offsets for distance codes 0..29 + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +const uInt cpdext[30] = { // Extra bits for distance codes + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + +// +// Huffman code decoding is performed using a multi-level table lookup. +// The fastest way to decode is to simply build a lookup table whose +// size is determined by the longest code. However, the time it takes +// to build this table can also be a factor if the data being decoded +// is not very long. The most common codes are necessarily the +// shortest codes, so those codes dominate the decoding time, and hence +// the speed. The idea is you can have a shorter table that decodes the +// shorter, more probable codes, and then point to subsidiary tables for +// the longer codes. The time it costs to decode the longer codes is +// then traded against the time it takes to make longer tables. +// +// This results of this trade are in the variables lbits and dbits +// below. lbits is the number of bits the first level table for literal/ +// length codes can decode in one step, and dbits is the same thing for +// the distance codes. Subsequent tables are also less than or equal to +// those sizes. These values may be adjusted either when all of the +// codes are shorter than that, in which case the longest code length in +// bits is used, or when the shortest code is *longer* than the requested +// table size, in which case the length of the shortest code in bits is +// used. +// +// There are two different values for the two tables, since they code a +// different number of possibilities each. The literal/length table +// codes 286 possible values, or in a flat code, a little over eight +// bits. The distance table codes 30 possible values, or a little less +// than five bits, flat. The optimum values for speed end up being +// about one bit more than those, so lbits is 8+1 and dbits is 5+1. +// The optimum values may differ though from machine to machine, and +// possibly even between compilers. Your mileage may vary. +// + + +// If BMAX needs to be larger than 16, then h and x[] should be uLong. +#define BMAX 15 // maximum bit length of any code + +int huft_build( +uInt *b, // code lengths in bits (all assumed <= BMAX) +uInt n, // number of codes (assumed <= 288) +uInt s, // number of simple-valued codes (0..s-1) +const uInt *d, // list of base values for non-simple codes +const uInt *e, // list of extra bits for non-simple codes +inflate_huft * *t, // result: starting table +uInt *m, // maximum lookup bits, returns actual +inflate_huft *hp, // space for trees +uInt *hn, // hufts used in space +uInt *v) // working area: values in order of bit length +// Given a list of code lengths and a maximum table size, make a set of +// tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR +// if the given code set is incomplete (the tables are still built in this +// case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of +// lengths), or Z_MEM_ERROR if not enough memory. +{ + + uInt a; // counter for codes of length k + uInt c[BMAX+1]; // bit length count table + uInt f; // i repeats in table every f entries + int g; // maximum code length + int h; // table level + register uInt i; // counter, current code + register uInt j; // counter + register int k; // number of bits in current code + int l; // bits per table (returned in m) + uInt mask; // (1 << w) - 1, to avoid cc -O bug on HP + register uInt *p; // pointer into c[], b[], or v[] + inflate_huft *q; // points to current table + struct inflate_huft_s r; // table entry for structure assignment + inflate_huft *u[BMAX]; // table stack + register int w; // bits before this table == (l * h) + uInt x[BMAX+1]; // bit offsets, then code stack + uInt *xp; // pointer into x + int y; // number of dummy codes added + uInt z; // number of entries in current table + + + // Generate counts for each bit length + p = c; +#define C0 *p++ = 0; +#define C2 C0 C0 C0 C0 +#define C4 C2 C2 C2 C2 + C4; p; // clear c[]--assume BMAX+1 is 16 + p = b; i = n; + do { + c[*p++]++; // assume all entries <= BMAX + } while (--i); + if (c[0] == n) // null input--all zero length codes + { + *t = (inflate_huft *)Z_NULL; + *m = 0; + return Z_OK; + } + + + // Find minimum and maximum length, bound *m by those + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; // minimum code length + if ((uInt)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; // maximum code length + if ((uInt)l > i) + l = i; + *m = l; + + + // Adjust last length count to fill out codes, if needed + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return Z_DATA_ERROR; + if ((y -= c[i]) < 0) + return Z_DATA_ERROR; + c[i] += y; + + + // Generate starting offsets into the value table for each length + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { // note that i == g from above + *xp++ = (j += *p++); + } + + + // Make a table of values in order of bit lengths + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + n = x[g]; // set n to length of v + + + // Generate the Huffman codes and for each, make the table entries + x[0] = i = 0; // first Huffman code is zero + p = v; // grab values in bit order + h = -1; // no tables yet--level -1 + w = -l; // bits decoded == (l * h) + u[0] = (inflate_huft *)Z_NULL; // just to keep compilers happy + q = (inflate_huft *)Z_NULL; // ditto + z = 0; // ditto + + // go through the bit lengths (k already is bits in shortest code) + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + // here i is the Huffman code of length k bits for value *p + // make tables up to required level + while (k > w + l) + { + h++; + w += l; // previous table always l bits + + // compute minimum size table less than or equal to l bits + z = g - w; + z = z > (uInt)l ? l : z; // table size upper limit + if ((f = 1 << (j = k - w)) > a + 1) // try a k-w bit table + { // too few codes for k-w bit table + f -= a + 1; // deduct codes from patterns left + xp = c + k; + if (j < z) + while (++j < z) // try smaller tables up to z bits + { + if ((f <<= 1) <= *++xp) + break; // enough codes to use up j bits + f -= *xp; // else deduct codes from patterns + } + } + z = 1 << j; // table entries for j-bit table + + // allocate new table + if (*hn + z > MANY) // (note: doesn't matter for fixed) + return Z_MEM_ERROR; // not enough memory + u[h] = q = hp + *hn; + *hn += z; + + // connect to last table, if there is one + if (h) + { + x[h] = i; // save pattern for backing up + r.bits = (Byte)l; // bits to dump before this table + r.exop = (Byte)j; // bits in this table + j = i >> (w - l); + r.base = (uInt)(q - u[h-1] - j); // offset to this table + u[h-1][j] = r; // connect to last table + } + else + *t = q; // first table is returned result + } + + // set up table entry in r + r.bits = (Byte)(k - w); + if (p >= v + n) + r.exop = 128 + 64; // out of values--invalid code + else if (*p < s) + { + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); // 256 is end-of-block + r.base = *p++; // simple code is just the value + } + else + { + r.exop = (Byte)(e[*p - s] + 16 + 64);// non-simple--look up in lists + r.base = d[*p++ - s]; + } + + // fill code-like entries with r + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + // backwards increment the k-bit code i + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + // backup over finished tables + mask = (1 << w) - 1; // needed on HP, cc -O bug + while ((i & mask) != x[h]) + { + h--; // don't need to update q + w -= l; + mask = (1 << w) - 1; + } + } + } + + + // Return Z_BUF_ERROR if we were given an incomplete table + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; +} + + +int inflate_trees_bits( +uInt *c, // 19 code lengths +uInt *bb, // bits tree desired/actual depth +inflate_huft * *tb, // bits tree result +inflate_huft *hp, // space for trees +z_streamp z) // for messages +{ + int r; + uInt hn = 0; // hufts used in space + uInt *v; // work area for huft_build + + if ((v = (uInt*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + r = huft_build(c, 19, 19, (uInt*)Z_NULL, (uInt*)Z_NULL, + tb, bb, hp, &hn, v); + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed dynamic bit lengths tree"; + else if (r == Z_BUF_ERROR || *bb == 0) + { + z->msg = (char*)"incomplete dynamic bit lengths tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; +} + + +int inflate_trees_dynamic( +uInt nl, // number of literal/length codes +uInt nd, // number of distance codes +uInt *c, // that many (total) code lengths +uInt *bl, // literal desired/actual bit depth +uInt *bd, // distance desired/actual bit depth +inflate_huft * *tl, // literal/length tree result +inflate_huft * *td, // distance tree result +inflate_huft *hp, // space for trees +z_streamp z) // for messages +{ + int r; + uInt hn = 0; // hufts used in space + uInt *v; // work area for huft_build + + // allocate work area + if ((v = (uInt*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + + // build literal/length tree + r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); + if (r != Z_OK || *bl == 0) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed literal/length tree"; + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; + } + + // build distance tree + r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); + if (r != Z_OK || (*bd == 0 && nl > 257)) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed distance tree"; + else if (r == Z_BUF_ERROR) { + z->msg = (char*)"incomplete distance tree"; + r = Z_DATA_ERROR; + } + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"empty distance tree with lengths"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; + } + + // done + ZFREE(z, v); + return Z_OK; +} + + + + + +int inflate_trees_fixed( +uInt *bl, // literal desired/actual bit depth +uInt *bd, // distance desired/actual bit depth +const inflate_huft * * tl, // literal/length tree result +const inflate_huft * *td, // distance tree result +z_streamp ) // for memory allocation +{ + *bl = fixed_bl; + *bd = fixed_bd; + *tl = fixed_tl; + *td = fixed_td; + return Z_OK; +} + + +// inffast.c -- process literals and length/distance pairs fast +// Copyright (C) 1995-1998 Mark Adler +// For conditions of distribution and use, see copyright notice in zlib.h +// + + +//struct inflate_codes_state {int dummy;}; // for buggy compilers + + +// macros for bit input with no checking and for returning unused bytes +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3;} + +// Called with number of bytes left to write in window at least 258 +// (the maximum string length) and number of input bytes available +// at least ten. The ten bytes are six bytes for the longest length/ +// distance pair plus four bytes for overloading the bit buffer. + +int inflate_fast( +uInt bl, uInt bd, +const inflate_huft *tl, +const inflate_huft *td, // need separate declaration for Borland C++ +inflate_blocks_statef *s, +z_streamp z) +{ + const inflate_huft *t; // temporary pointer + uInt e; // extra bits or operation + uLong b; // bit buffer + uInt k; // bits in bit buffer + Byte *p; // input data pointer + uInt n; // bytes available there + Byte *q; // output window write pointer + uInt m; // bytes to end of window or read pointer + uInt ml; // mask for literal/length tree + uInt md; // mask for distance tree + uInt c; // bytes to copy + uInt d; // distance back to copy from + Byte *r; // copy source pointer + + // load input, output, bit values + LOAD + + // initialize masks + ml = inflate_mask[bl]; + md = inflate_mask[bd]; + + // do until not enough input or output space for fast loop + do { // assume called with m >= 258 && n >= 10 + // get literal/length code + GRABBITS(20) // max bits for literal/length code + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + continue; + } + for (;;) { + DUMPBITS(t->bits) + if (e & 16) + { + // get extra bits for length + e &= 15; + c = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * length %u\n", c)); + + // decode distance base of block to copy + GRABBITS(15); // max bits for distance code + e = (t = td + ((uInt)b & md))->exop; + for (;;) { + DUMPBITS(t->bits) + if (e & 16) + { + // get extra bits to add to distance base + e &= 15; + GRABBITS(e) // get extra bits (up to 13) + d = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * distance %u\n", d)); + + // do the copy + m -= c; + if ((uInt)(q - s->window) >= d) // offset before dest + { // just copy + r = q - d; + *q++ = *r++; c--; // minimum count is three, + *q++ = *r++; c--; // so unroll loop a little + } + else // else offset after destination + { + e = d - (uInt)(q - s->window); // bytes from offset to end + r = s->end - e; // pointer to offset + if (c > e) // if source crosses, + { + c -= e; // copy to end of window + do { + *q++ = *r++; + } while (--e); + r = s->window; // copy rest from start of window + } + } + do { // copy all or what's left + *q++ = *r++; + } while (--c); + break; + } + else if ((e & 64) == 0) + { + t += t->base; + e = (t += ((uInt)b & inflate_mask[e]))->exop; + } + else + { + z->msg = (char*)"invalid distance code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + }; + break; + } + if ((e & 64) == 0) + { + t += t->base; + if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + break; + } + } + else if (e & 32) + { + Tracevv((stderr, "inflate: * end of block\n")); + UNGRAB + UPDATE + return Z_STREAM_END; + } + else + { + z->msg = (char*)"invalid literal/length code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + }; + } while (m >= 258 && n >= 10); + + // not enough input or output--restore pointers and return + UNGRAB + UPDATE + return Z_OK; +} + + + + + + +// crc32.c -- compute the CRC-32 of a data stream +// Copyright (C) 1995-1998 Mark Adler +// For conditions of distribution and use, see copyright notice in zlib.h + +// @(#) $Id$ + + + + + + +// Table of CRC-32's of all single-byte values (made by make_crc_table) +const uLong crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +const uLong * get_crc_table() +{ return (const uLong *)crc_table; +} + +#define CRC_DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define CRC_DO2(buf) CRC_DO1(buf); CRC_DO1(buf); +#define CRC_DO4(buf) CRC_DO2(buf); CRC_DO2(buf); +#define CRC_DO8(buf) CRC_DO4(buf); CRC_DO4(buf); + +uLong ucrc32(uLong crc, const Byte *buf, uInt len) +{ if (buf == Z_NULL) return 0L; + crc = crc ^ 0xffffffffL; + while (len >= 8) {CRC_DO8(buf); len -= 8;} + if (len) do {CRC_DO1(buf);} while (--len); + return crc ^ 0xffffffffL; +} + + +// adler32.c -- compute the Adler-32 checksum of a data stream +// Copyright (C) 1995-1998 Mark Adler +// For conditions of distribution and use, see copyright notice in zlib.h + +// @(#) $Id$ + + +#define BASE 65521L // largest prime smaller than 65536 +#define NMAX 5552 +// NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 + +#define AD_DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define AD_DO2(buf,i) AD_DO1(buf,i); AD_DO1(buf,i+1); +#define AD_DO4(buf,i) AD_DO2(buf,i); AD_DO2(buf,i+2); +#define AD_DO8(buf,i) AD_DO4(buf,i); AD_DO4(buf,i+4); +#define AD_DO16(buf) AD_DO8(buf,0); AD_DO8(buf,8); + +// ========================================================================= +uLong adler32(uLong adler, const Byte *buf, uInt len) +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == Z_NULL) return 1L; + + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + AD_DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +} + + + +// zutil.c -- target dependent utility functions for the compression library +// Copyright (C) 1995-1998 Jean-loup Gailly. +// For conditions of distribution and use, see copyright notice in zlib.h +// @(#) $Id$ + + + + + + +const char * zlibVersion() +{ + return ZLIB_VERSION; +} + +// exported to allow conversion of error code to string for compress() and +// uncompress() +const char * zError(int err) +{ return ERR_MSG(err); +} + + + + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) items += size - size; // make compiler happy + return (voidpf)calloc(items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + zfree(ptr); + if (opaque) return; // make compiler happy +} + + + +// inflate.c -- zlib interface to inflate modules +// Copyright (C) 1995-1998 Mark Adler +// For conditions of distribution and use, see copyright notice in zlib.h + +//struct inflate_blocks_state {int dummy;}; // for buggy compilers + +typedef enum { + IM_METHOD, // waiting for method byte + IM_FLAG, // waiting for flag byte + IM_DICT4, // four dictionary check bytes to go + IM_DICT3, // three dictionary check bytes to go + IM_DICT2, // two dictionary check bytes to go + IM_DICT1, // one dictionary check byte to go + IM_DICT0, // waiting for inflateSetDictionary + IM_BLOCKS, // decompressing blocks + IM_CHECK4, // four check bytes to go + IM_CHECK3, // three check bytes to go + IM_CHECK2, // two check bytes to go + IM_CHECK1, // one check byte to go + IM_DONE, // finished check, done + IM_BAD} // got an error--stay here +inflate_mode; + +// inflate private state +struct internal_state { + + // mode + inflate_mode mode; // current inflate mode + + // mode dependent information + union { + uInt method; // if IM_FLAGS, method byte + struct { + uLong was; // computed check value + uLong need; // stream check value + } check; // if CHECK, check values to compare + uInt marker; // if IM_BAD, inflateSync's marker bytes count + } sub; // submode + + // mode independent information + int nowrap; // flag for no wrapper + uInt wbits; // log2(window size) (8..15, defaults to 15) + inflate_blocks_statef + *blocks; // current inflate_blocks state + +}; + +int inflateReset(z_streamp z) +{ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + z->total_in = z->total_out = 0; + z->msg = Z_NULL; + z->state->mode = z->state->nowrap ? IM_BLOCKS : IM_METHOD; + inflate_blocks_reset(z->state->blocks, z, Z_NULL); + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int inflateEnd(z_streamp z) +{ + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->blocks != Z_NULL) + inflate_blocks_free(z->state->blocks, z); + ZFREE(z, z->state); + z->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + + +int inflateInit2(z_streamp z) +{ const char *version = ZLIB_VERSION; int stream_size = sizeof(z_stream); + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || stream_size != sizeof(z_stream)) return Z_VERSION_ERROR; + + int w = -15; // MAX_WBITS: 32K LZ77 window. + // Warning: reducing MAX_WBITS makes minigzip unable to extract .gz files created by gzip. + // The memory requirements for deflate are (in bytes): + // (1 << (windowBits+2)) + (1 << (memLevel+9)) + // that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + // plus a few kilobytes for small objects. For example, if you want to reduce + // the default memory requirements from 256K to 128K, compile with + // make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + // Of course this will generally degrade compression (there's no free lunch). + // + // The memory requirements for inflate are (in bytes) 1 << windowBits + // that is, 32K for windowBits=15 (default value) plus a few kilobytes + // for small objects. + + // initialize state + if (z == Z_NULL) return Z_STREAM_ERROR; + z->msg = Z_NULL; + if (z->zalloc == Z_NULL) + { + z->zalloc = zcalloc; + z->opaque = (voidpf)0; + } + if (z->zfree == Z_NULL) z->zfree = zcfree; + if ((z->state = (struct internal_state *) + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) + return Z_MEM_ERROR; + z->state->blocks = Z_NULL; + + // handle undocumented nowrap option (no zlib header or check) + z->state->nowrap = 0; + if (w < 0) + { + w = - w; + z->state->nowrap = 1; + } + + // set window size + if (w < 8 || w > 15) + { + inflateEnd(z); + return Z_STREAM_ERROR; + } + z->state->wbits = (uInt)w; + + // create inflate_blocks state + if ((z->state->blocks = + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) + == Z_NULL) + { + inflateEnd(z); + return Z_MEM_ERROR; + } + Tracev((stderr, "inflate: allocated\n")); + + // reset state + inflateReset(z); + return Z_OK; +} + + + +#define IM_NEEDBYTE {if(z->avail_in==0)return r;r=f;} +#define IM_NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) + +int inflate(z_streamp z, int f) +{ + int r; + uInt b; + + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) + return Z_STREAM_ERROR; + f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; + r = Z_BUF_ERROR; + for (;;) switch (z->state->mode) + { + case IM_METHOD: + IM_NEEDBYTE + if (((z->state->sub.method = IM_NEXTBYTE) & 0xf) != Z_DEFLATED) + { + z->state->mode = IM_BAD; + z->msg = (char*)"unknown compression method"; + z->state->sub.marker = 5; // can't try inflateSync + break; + } + if ((z->state->sub.method >> 4) + 8 > z->state->wbits) + { + z->state->mode = IM_BAD; + z->msg = (char*)"invalid window size"; + z->state->sub.marker = 5; // can't try inflateSync + break; + } + z->state->mode = IM_FLAG; + case IM_FLAG: + IM_NEEDBYTE + b = IM_NEXTBYTE; + if (((z->state->sub.method << 8) + b) % 31) + { + z->state->mode = IM_BAD; + z->msg = (char*)"incorrect header check"; + z->state->sub.marker = 5; // can't try inflateSync + break; + } + Tracev((stderr, "inflate: zlib header ok\n")); + if (!(b & PRESET_DICT)) + { + z->state->mode = IM_BLOCKS; + break; + } + z->state->mode = IM_DICT4; + case IM_DICT4: + IM_NEEDBYTE + z->state->sub.check.need = (uLong)IM_NEXTBYTE << 24; + z->state->mode = IM_DICT3; + case IM_DICT3: + IM_NEEDBYTE + z->state->sub.check.need += (uLong)IM_NEXTBYTE << 16; + z->state->mode = IM_DICT2; + case IM_DICT2: + IM_NEEDBYTE + z->state->sub.check.need += (uLong)IM_NEXTBYTE << 8; + z->state->mode = IM_DICT1; + case IM_DICT1: + IM_NEEDBYTE; r; + z->state->sub.check.need += (uLong)IM_NEXTBYTE; + z->adler = z->state->sub.check.need; + z->state->mode = IM_DICT0; + return Z_NEED_DICT; + case IM_DICT0: + z->state->mode = IM_BAD; + z->msg = (char*)"need dictionary"; + z->state->sub.marker = 0; // can try inflateSync + return Z_STREAM_ERROR; + case IM_BLOCKS: + r = inflate_blocks(z->state->blocks, z, r); + if (r == Z_DATA_ERROR) + { + z->state->mode = IM_BAD; + z->state->sub.marker = 0; // can try inflateSync + break; + } + if (r == Z_OK) + r = f; + if (r != Z_STREAM_END) + return r; + r = f; + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); + if (z->state->nowrap) + { + z->state->mode = IM_DONE; + break; + } + z->state->mode = IM_CHECK4; + case IM_CHECK4: + IM_NEEDBYTE + z->state->sub.check.need = (uLong)IM_NEXTBYTE << 24; + z->state->mode = IM_CHECK3; + case IM_CHECK3: + IM_NEEDBYTE + z->state->sub.check.need += (uLong)IM_NEXTBYTE << 16; + z->state->mode = IM_CHECK2; + case IM_CHECK2: + IM_NEEDBYTE + z->state->sub.check.need += (uLong)IM_NEXTBYTE << 8; + z->state->mode = IM_CHECK1; + case IM_CHECK1: + IM_NEEDBYTE + z->state->sub.check.need += (uLong)IM_NEXTBYTE; + + if (z->state->sub.check.was != z->state->sub.check.need) + { + z->state->mode = IM_BAD; + z->msg = (char*)"incorrect data check"; + z->state->sub.marker = 5; // can't try inflateSync + break; + } + Tracev((stderr, "inflate: zlib check ok\n")); + z->state->mode = IM_DONE; + case IM_DONE: + return Z_STREAM_END; + case IM_BAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } +} + + + +#ifdef _UNICODE + +static int GetAnsiFileName(LPCWSTR name, char * buf, int nBufSize) +{ + memset(buf, 0, nBufSize); + + int n = WideCharToMultiByte(CP_ACP, // code page + 0, // performance and mapping flags + name, // wide-character string + -1, // number of chars in string + buf, // buffer for new string + nBufSize, // size of buffer + NULL, // default for unmappable chars + NULL); // set when default char used + return n; +} + +static int GetUnicodeFileName(const char * name, LPWSTR buf, int nBufSize) +{ + memset(buf, 0, nBufSize*sizeof(TCHAR)); + + int n = MultiByteToWideChar(CP_ACP, // code page + 0, // character-type options + name, // string to map + -1, // number of bytes in string + buf, // wide-character buffer + nBufSize); // size of buffer + + return n; +} + +#endif + + +// unzip.c -- IO on .zip files using zlib +// Version 0.15 beta, Mar 19th, 1998, +// Read unzip.h for more info + + + + +#define UNZ_BUFSIZE (16384) +#define UNZ_MAXFILENAMEINZIP (256) +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + + + +const char unz_copyright[] = " unzip 0.15 Copyright 1998 Gilles Vollant "; + +// unz_file_info_interntal contain internal info about a file in zipfile +typedef struct unz_file_info_internal_s +{ + uLong offset_curfile;// relative offset of local header 4 bytes +} unz_file_info_internal; + + +typedef struct +{ bool is_handle; // either a handle or memory + bool canseek; + // for handles: + HANDLE h; bool herr; unsigned long initial_offset; + // for memory: + void *buf; unsigned int len,pos; // if it's a memory block +} LUFILE; + + +LUFILE *lufopen(void *z,unsigned int len,DWORD flags,ZRESULT *err) +{ + if (flags!=ZIP_HANDLE && flags!=ZIP_FILENAME && flags!=ZIP_MEMORY) + { + *err=ZR_ARGS; + return NULL; + } + // + HANDLE h=0; bool canseek=false; *err=ZR_OK; + if (flags==ZIP_HANDLE||flags==ZIP_FILENAME) + { + if (flags==ZIP_HANDLE) + { + HANDLE hf = z; + bool res; +#ifdef _WIN32 + res = DuplicateHandle(GetCurrentProcess(),hf,GetCurrentProcess(),&h,0,FALSE,DUPLICATE_SAME_ACCESS) == TRUE; +#else + h = (void*) dup( (int)hf ); + res = (int) dup >= 0; +#endif + if (!res) + { + *err=ZR_NODUPH; + return NULL; + } + } + else + { +#ifdef _WIN32 + h = CreateFile((const TCHAR *)z, GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); +#else + h = (void*) open( (const TCHAR *)z, O_RDONLY ); +#endif + if (h == INVALID_HANDLE_VALUE) + { + *err = ZR_NOFILE; + return NULL; + } + } +#ifdef _WIN32 + DWORD type = GetFileType(h); + canseek = (type==FILE_TYPE_DISK); +#else + struct stat buf; + fstat( (int)h, &buf ); + canseek = buf.st_mode & S_IFREG; +#endif + } + LUFILE *lf = new LUFILE; + if (flags==ZIP_HANDLE||flags==ZIP_FILENAME) + { + lf->is_handle=true; + lf->canseek=canseek; + lf->h=h; lf->herr=false; + lf->initial_offset=0; + if (canseek) + { + lf->initial_offset = SetFilePointer(h,0,NULL,FILE_CURRENT); + } + } + else + { + lf->is_handle=false; + lf->canseek=true; + lf->buf=z; + lf->len=len; + lf->pos=0; + lf->initial_offset=0; + } + *err=ZR_OK; + return lf; +} + + +int lufclose(LUFILE *stream) +{ if (stream==NULL) return EOF; + if (stream->is_handle) CloseHandle(stream->h); + delete stream; + return 0; +} + +int luferror(LUFILE *stream) +{ if (stream->is_handle && stream->herr) return 1; + else return 0; +} + +long int luftell(LUFILE *stream) +{ if (stream->is_handle && stream->canseek) return SetFilePointer(stream->h,0,NULL,FILE_CURRENT)-stream->initial_offset; + else if (stream->is_handle) return 0; + else return stream->pos; +} + +int lufseek(LUFILE *stream, long offset, int whence) +{ if (stream->is_handle && stream->canseek) + { if (whence==SEEK_SET) SetFilePointer(stream->h,stream->initial_offset+offset,0,FILE_BEGIN); + else if (whence==SEEK_CUR) SetFilePointer(stream->h,offset,NULL,FILE_CURRENT); + else if (whence==SEEK_END) SetFilePointer(stream->h,offset,NULL,FILE_END); + else return 19; // EINVAL + return 0; + } + else if (stream->is_handle) return 29; // ESPIPE + else + { if (whence==SEEK_SET) stream->pos=offset; + else if (whence==SEEK_CUR) stream->pos+=offset; + else if (whence==SEEK_END) stream->pos=stream->len+offset; + return 0; + } +} + + +size_t lufread(void *ptr,size_t size,size_t n,LUFILE *stream) +{ unsigned int toread = (unsigned int)(size*n); + if (stream->is_handle) + { DWORD red; BOOL res = ReadFile(stream->h,ptr,toread,&red,NULL); + if (!res) stream->herr=true; + return red/size; + } + if (stream->pos+toread > stream->len) toread = stream->len-stream->pos; + memcpy(ptr, (char*)stream->buf + stream->pos, toread); DWORD red = toread; + stream->pos += red; + return red/size; +} + + + + +// file_in_zip_read_info_s contain internal information about a file in zipfile, +// when reading and decompress it +typedef struct +{ + char *read_buffer; // internal buffer for compressed data + z_stream stream; // zLib stream structure for inflate + + uLong pos_in_zipfile; // position in byte on the zipfile, for fseek + uLong stream_initialised; // flag set if stream structure is initialised + + uLong offset_local_extrafield;// offset of the local extra field + uInt size_local_extrafield;// size of the local extra field + uLong pos_local_extrafield; // position in the local extra field in read + + uLong crc32; // crc32 of all data uncompressed + uLong crc32_wait; // crc32 we must obtain after decompress all + uLong rest_read_compressed; // number of byte to be decompressed + uLong rest_read_uncompressed;//number of byte to be obtained after decomp + LUFILE* file; // io structore of the zipfile + uLong compression_method; // compression method (0==store) + uLong byte_before_the_zipfile;// byte before the zipfile, (>0 for sfx) +} file_in_zip_read_info_s; + + +// unz_s contain internal information about the zipfile +typedef struct +{ + LUFILE* file; // io structore of the zipfile + unz_global_info gi; // public global information + uLong byte_before_the_zipfile;// byte before the zipfile, (>0 for sfx) + uLong num_file; // number of the current file in the zipfile + uLong pos_in_central_dir; // pos of the current file in the central dir + uLong current_file_ok; // flag about the usability of the current file + uLong central_pos; // position of the beginning of the central dir + + uLong size_central_dir; // size of the central directory + uLong offset_central_dir; // offset of start of central directory with respect to the starting disk number + + unz_file_info cur_file_info; // public info about the current file in zip + unz_file_info_internal cur_file_info_internal; // private info about it + file_in_zip_read_info_s* pfile_in_zip_read; // structure about the current file if we are decompressing it +} unz_s, *unzFile; + + +int unzStringFileNameCompare (const char* fileName1,const char* fileName2,int iCaseSensitivity); +// Compare two filename (fileName1,fileName2). + +z_off_t unztell (unzFile file); +// Give the current position in uncompressed data + +int unzeof (unzFile file); +// return 1 if the end of file was reached, 0 elsewhere + +int unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len); +// Read extra field from the current file (opened by unzOpenCurrentFile) +// This is the local-header version of the extra field (sometimes, there is +// more info in the local-header version than in the central-header) +// +// if buf==NULL, it return the size of the local extra field +// +// if buf!=NULL, len is the size of the buffer, the extra header is copied in +// buf. +// the return value is the number of bytes copied in buf, or (if <0) +// the error code + + + +// =========================================================================== +// Read a byte from a gz_stream; update next_in and avail_in. Return EOF +// for end of file. +// IN assertion: the stream s has been sucessfully opened for reading. + +int unzlocal_getByte(LUFILE *fin,int *pi) +{ unsigned char c; + int err = (int)lufread(&c, 1, 1, fin); + if (err==1) + { *pi = (int)c; + return UNZ_OK; + } + else + { if (luferror(fin)) return UNZ_ERRNO; + else return UNZ_EOF; + } +} + + +// =========================================================================== +// Reads a long in LSB order from the given gz_stream. Sets +int unzlocal_getShort (LUFILE *fin,uLong *pX) +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(fin,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +int unzlocal_getLong (LUFILE *fin,uLong *pX) +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(fin,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unzlocal_getByte(fin,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + + +// My own strcmpi / strcasecmp +int strcmpcasenosensitive_internal (const char* fileName1,const char *fileName2) +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= (char)0x20; + if ((c2>='a') && (c2<='z')) + c2 -= (char)0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + + + +// +// Compare two filename (fileName1,fileName2). +// If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) +// If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi or strcasecmp) +// +int unzStringFileNameCompare (const char*fileName1,const char*fileName2,int iCaseSensitivity) +{ if (iCaseSensitivity==1) return strcmp(fileName1,fileName2); + else return strcmpcasenosensitive_internal(fileName1,fileName2); +} + +#define BUFREADCOMMENT (0x400) + + +// Locate the Central directory of a zipfile (at the end, just before +// the global comment) +uLong unzlocal_SearchCentralDir(LUFILE *fin) +{ if (lufseek(fin,0,SEEK_END) != 0) return 0; + uLong uSizeFile = luftell(fin); + + uLong uMaxBack=0xffff; // maximum size of global comment + if (uMaxBack>uSizeFile) uMaxBack = uSizeFile; + + unsigned char *buf = (unsigned char*)zmalloc(BUFREADCOMMENT+4); + if (buf==NULL) return 0; + uLong uPosFound=0; + + uLong uBackRead = 4; + while (uBackReaduMaxBack) uBackRead = uMaxBack; + else uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); + if (lufseek(fin,uReadPos,SEEK_SET)!=0) break; + if (lufread(buf,(uInt)uReadSize,1,fin)!=1) break; + for (i=(int)uReadSize-3; (i--)>0;) + { if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { uPosFound = uReadPos+i; break; + } + } + if (uPosFound!=0) break; + } + if (buf) zfree(buf); + return uPosFound; +} + + +int unzGoToFirstFile (unzFile file); +int unzCloseCurrentFile (unzFile file); + +// Open a Zip file. +// If the zipfile cannot be opened (file don't exist or in not valid), return NULL. +// Otherwise, the return value is a unzFile Handle, usable with other unzip functions +unzFile unzOpenInternal(LUFILE *fin) +{ if (fin==NULL) return NULL; + if (unz_copyright[0]!=' ') {lufclose(fin); return NULL;} + + int err=UNZ_OK; + unz_s us; + uLong central_pos,uL; + central_pos = unzlocal_SearchCentralDir(fin); + if (central_pos==0) err=UNZ_ERRNO; + if (lufseek(fin,central_pos,SEEK_SET)!=0) err=UNZ_ERRNO; + // the signature, already checked + if (unzlocal_getLong(fin,&uL)!=UNZ_OK) err=UNZ_ERRNO; + // number of this disk + uLong number_disk; // number of the current dist, used for spanning ZIP, unsupported, always 0 + if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK) err=UNZ_ERRNO; + // number of the disk with the start of the central directory + uLong number_disk_with_CD; // number the the disk with central dir, used for spaning ZIP, unsupported, always 0 + if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK) err=UNZ_ERRNO; + // total number of entries in the central dir on this disk + if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK) err=UNZ_ERRNO; + // total number of entries in the central dir + uLong number_entry_CD; // total number of entries in the central dir (same than number_entry on nospan) + if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK) err=UNZ_ERRNO; + if ((number_entry_CD!=us.gi.number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) err=UNZ_BADZIPFILE; + // size of the central directory + if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK) err=UNZ_ERRNO; + // offset of start of central directory with respect to the starting disk number + if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK) err=UNZ_ERRNO; + // zipfile comment length + if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK) err=UNZ_ERRNO; + if ((central_pos+fin->initial_offsetinitial_offset - (us.offset_central_dir+us.size_central_dir); + us.central_pos = central_pos; + us.pfile_in_zip_read = NULL; + fin->initial_offset = 0; // since the zipfile itself is expected to handle this + + unz_s *s = (unz_s*)zmalloc(sizeof(unz_s)); + *s=us; + unzGoToFirstFile((unzFile)s); + return (unzFile)s; +} + + + +// Close a ZipFile opened with unzipOpen. +// If there is files inside the .Zip opened with unzipOpenCurrentFile (see later), +// these files MUST be closed with unzipCloseCurrentFile before call unzipClose. +// return UNZ_OK if there is no problem. +int unzClose (unzFile file) +{ + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + if (s->pfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + lufclose(s->file); + if (s) zfree(s); // unused s=0; + return UNZ_OK; +} + + +// Write info about the ZipFile in the *pglobal_info structure. +// No preparation of the structure is needed +// return UNZ_OK if there is no problem. +int unzGetGlobalInfo (unzFile file,unz_global_info *pglobal_info) +{ + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + + +// Translate date/time from Dos format to tm_unz (readable more easilty) +void unzlocal_DosDateToTmuDate (uLong ulDosDate, tm_unz* ptm) +{ + uLong uDate; + uDate = (uLong)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +// Get Info about the current file in the zipfile, with internal only info +int unzlocal_GetCurrentFileInfoInternal (unzFile file, + unz_file_info *pfile_info, + unz_file_info_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize); + +int unzlocal_GetCurrentFileInfoInternal (unzFile file, unz_file_info *pfile_info, + unz_file_info_internal *pfile_info_internal, char *szFileName, + uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, + char *szComment, uLong commentBufferSize) +{ + unz_s* s; + unz_file_info file_info; + unz_file_info_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (lufseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0) + err=UNZ_ERRNO; + + + // we check the magic + if (err==UNZ_OK) + { + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + } + + if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (lufread(szFileName,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + + if ((err==UNZ_OK) && (extraField!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_extrafile,lSeek,SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (lufread(extraField,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + lSeek += file_info.size_file_extra - uSizeRead; + } + else + lSeek+=file_info.size_file_extra; + + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentfile,lSeek,SEEK_CUR)==0) + {} // unused lSeek=0; + else + err=UNZ_ERRNO; + } + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (lufread(szComment,(uInt)uSizeRead,1,s->file)!=1) + err=UNZ_ERRNO; + //unused lSeek+=file_info.size_file_comment - uSizeRead; + } + else {} //unused lSeek+=file_info.size_file_comment; + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +// Write info about the ZipFile in the *pglobal_info structure. +// No preparation of the structure is needed +// return UNZ_OK if there is no problem. +int unzGetCurrentFileInfo (unzFile file, unz_file_info *pfile_info, + char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, + char *szComment, uLong commentBufferSize) +{ return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, szComment,commentBufferSize); +} + + +// Set the current file of the zipfile to the first file. +// return UNZ_OK if there is no problem +int unzGoToFirstFile (unzFile file) +{ + int err; + unz_s* s; + if (file==NULL) return UNZ_PARAMERROR; + s=(unz_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +// Set the current file of the zipfile to the next file. +// return UNZ_OK if there is no problem +// return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +int unzGoToNextFile (unzFile file) +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +// Try locate the file szFileName in the zipfile. +// For the iCaseSensitivity signification, see unzStringFileNameCompare +// return value : +// UNZ_OK if the file is found. It becomes the current file. +// UNZ_END_OF_LIST_OF_FILE if the file is not found +int unzLocateFile (unzFile file, const TCHAR *szFileName, int iCaseSensitivity) +{ + unz_s* s; + int err; + + uLong num_fileSaved; + uLong pos_in_central_dirSaved; + + if (file==NULL) + return UNZ_PARAMERROR; + + if (_tcslen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + char szFileNameA[MAX_PATH]; + +#ifdef _UNICODE + GetAnsiFileName(szFileName, szFileNameA, MAX_PATH-1); +#else + strcpy(szFileNameA, szFileName); +#endif + + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + unzGetCurrentFileInfo(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (unzStringFileNameCompare(szCurrentFileName,szFileNameA,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + return err; +} + + +// Read the local header of the current zipfile +// Check the coherency of the local header and info in the end of central +// directory about this file +// store in *piSizeVar the size of extra info in local header +// (filename and size of extra field data) +int unzlocal_CheckCurrentFileCoherencyHeader (unz_s *s,uInt *piSizeVar, + uLong *poffset_local_extrafield, uInt *psize_local_extrafield) +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (lufseek(s->file,s->cur_file_info_internal.offset_curfile + s->byte_before_the_zipfile,SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + { + if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + } + + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) + err=UNZ_ERRNO; +// else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) +// err=UNZ_BADZIPFILE; + if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(s->file,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) // date/time + err=UNZ_ERRNO; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) // crc + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) // size compr + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(s->file,&uData) != UNZ_OK) // size uncompr + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + + if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + + + + + +// Open for reading data the current file in the zipfile. +// If there is no error and the file is opened, the return value is UNZ_OK. +int unzOpenCurrentFile (unzFile file) +{ + int err; + int Store; + uInt iSizeVar; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uLong offset_local_extrafield; // offset of the local extra field + uInt size_local_extrafield; // size of the local extra field + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, + &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip_read_info_s*)zmalloc(sizeof(file_in_zip_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)zmalloc(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + if (pfile_in_zip_read_info!=0) zfree(pfile_in_zip_read_info); //unused pfile_in_zip_read_info=0; + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if ((s->cur_file_info.compression_method!=0) && (s->cur_file_info.compression_method!=Z_DEFLATED)) + { // unused err=UNZ_BADZIPFILE; + } + Store = s->cur_file_info.compression_method==0; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->compression_method = + s->cur_file_info.compression_method; + pfile_in_zip_read_info->file=s->file; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if (!Store) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + + err=inflateInit2(&pfile_in_zip_read_info->stream); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=1; + // windowBits is passed < 0 to tell that there is no zlib header. + // Note that in this case inflate *requires* an extra "dummy" byte + // after the compressed stream in order to complete decompression and + // return Z_STREAM_END. + // In unzip, i don't wait absolutely Z_STREAM_END because I known the + // size of both compressed and uncompressed data + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + + s->pfile_in_zip_read = pfile_in_zip_read_info; + return UNZ_OK; +} + + +// Read bytes from the current file. +// buf contain buffer where data must be copied +// len the size of buf. +// return the number of byte copied if somes bytes are copied +// return 0 if the end of file was reached +// return <0 with error code if there is an error +// (UNZ_ERRNO for IO error, or zLib error for uncompress error) +int unzReadCurrentFile (unzFile file, voidp buf, unsigned len) +{ int err=UNZ_OK; + uInt iRead = 0; + + unz_s *s = (unz_s*)file; + if (s==NULL) return UNZ_PARAMERROR; + + file_in_zip_read_info_s* pfile_in_zip_read_info = s->pfile_in_zip_read; + if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; + if (pfile_in_zip_read_info->read_buffer == NULL) return UNZ_END_OF_LIST_OF_FILE; + if (len==0) return 0; + + pfile_in_zip_read_info->stream.next_out = (Byte*)buf; + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if (len>pfile_in_zip_read_info->rest_read_uncompressed) + { pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + } + + while (pfile_in_zip_read_info->stream.avail_out>0) + { if ((pfile_in_zip_read_info->stream.avail_in==0) && (pfile_in_zip_read_info->rest_read_compressed>0)) + { uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) return UNZ_EOF; + if (lufseek(pfile_in_zip_read_info->file, pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0) return UNZ_ERRNO; + if (lufread(pfile_in_zip_read_info->read_buffer,uReadThis,1,pfile_in_zip_read_info->file)!=1) return UNZ_ERRNO; + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + pfile_in_zip_read_info->stream.next_in = (Byte*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if (pfile_in_zip_read_info->compression_method==0) + { uInt uDoCopy,i ; + if (pfile_in_zip_read_info->stream.avail_out < pfile_in_zip_read_info->stream.avail_in) + { uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + } + else + { uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + } + for (i=0;istream.next_out+i) = *(pfile_in_zip_read_info->stream.next_in+i); + } + pfile_in_zip_read_info->crc32 = ucrc32(pfile_in_zip_read_info->crc32,pfile_in_zip_read_info->stream.next_out,uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else + { uLong uTotalOutBefore,uTotalOutAfter; + const Byte *bufBefore; + uLong uOutThis; + int flush=Z_SYNC_FLUSH; + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + err=inflate(&pfile_in_zip_read_info->stream,flush); + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + pfile_in_zip_read_info->crc32 = ucrc32(pfile_in_zip_read_info->crc32,bufBefore,(uInt)(uOutThis)); + pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + if (err==Z_STREAM_END) return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) break; + } + } + + if (err==Z_OK) return iRead; + return err; +} + + +// Give the current position in uncompressed data +z_off_t unztell (unzFile file) +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + + +// return 1 if the end of file was reached, 0 elsewhere +int unzeof (unzFile file) +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +// Read extra field from the current file (opened by unzOpenCurrentFile) +// This is the local-header version of the extra field (sometimes, there is +// more info in the local-header version than in the central-header) +// if buf==NULL, it return the size of the local extra field that can be read +// if buf!=NULL, len is the size of the buffer, the extra header is copied in buf. +// the return value is the number of bytes copied in buf, or (if <0) the error code +int unzGetLocalExtrafield (unzFile file,voidp buf,unsigned len) +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uInt read_now; + uLong size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (lufseek(pfile_in_zip_read_info->file, pfile_in_zip_read_info->offset_local_extrafield + pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0) + return UNZ_ERRNO; + + if (lufread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1) + return UNZ_ERRNO; + + return (int)read_now; +} + +// Close the file in zip opened with unzipOpenCurrentFile +// Return UNZ_CRCERROR if all the file was read but the CRC is not good +int unzCloseCurrentFile (unzFile file) +{ + int err=UNZ_OK; + + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + if (pfile_in_zip_read_info->read_buffer!=0) + { void *buf = pfile_in_zip_read_info->read_buffer; + zfree(buf); + pfile_in_zip_read_info->read_buffer=0; + } + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised) + inflateEnd(&pfile_in_zip_read_info->stream); + + pfile_in_zip_read_info->stream_initialised = 0; + if (pfile_in_zip_read_info!=0) zfree(pfile_in_zip_read_info); // unused pfile_in_zip_read_info=0; + + s->pfile_in_zip_read=NULL; + + return err; +} + + +// Get the global comment string of the ZipFile, in the szComment buffer. +// uSizeBuf is the size of the szComment buffer. +// return the number of byte copied or an error code <0 +int unzGetGlobalComment (unzFile file, char *szComment, uLong uSizeBuf) +{ //int err=UNZ_OK; + unz_s* s; + uLong uReadThis ; + if (file==NULL) return UNZ_PARAMERROR; + s=(unz_s*)file; + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) uReadThis = s->gi.size_comment; + if (lufseek(s->file,s->central_pos+22,SEEK_SET)!=0) return UNZ_ERRNO; + if (uReadThis>0) + { *szComment='\0'; + if (lufread(szComment,(uInt)uReadThis,1,s->file)!=1) return UNZ_ERRNO; + } + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} + + + + + +int unzOpenCurrentFile (unzFile file); +int unzReadCurrentFile (unzFile file, void *buf, unsigned len); +int unzCloseCurrentFile (unzFile file); + + +#ifdef _WIN32 +FILETIME timet2filetime(const time_t timer) +{ struct tm *tm = gmtime(&timer); + SYSTEMTIME st; + st.wYear = (WORD)(tm->tm_year+1900); + st.wMonth = (WORD)(tm->tm_mon+1); + st.wDay = (WORD)(tm->tm_mday); + st.wHour = (WORD)(tm->tm_hour); + st.wMinute = (WORD)(tm->tm_min); + st.wSecond = (WORD)(tm->tm_sec); + st.wMilliseconds=0; + FILETIME ft; + SystemTimeToFileTime(&st,&ft); + return ft; +} +#endif + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +class TUnzip +{ public: + TUnzip() : uf(0), currentfile(-1), czei(-1) {} + + unzFile uf; int currentfile; ZIPENTRY cze; int czei; + TCHAR rootdir[MAX_PATH]; + + ZRESULT Open(void *z,unsigned int len,DWORD flags); + ZRESULT Get(int index,ZIPENTRY *ze); + ZRESULT Find(const TCHAR *name,bool ic,int *index,ZIPENTRY *ze); + ZRESULT Unzip(int index,void *dst,unsigned int len,DWORD flags); + ZRESULT Close(); +}; + + +ZRESULT TUnzip::Open(void *z,unsigned int len,DWORD flags) +{ + if (uf!=0 || currentfile!=-1) + return ZR_NOTINITED; +#ifdef _WIN32 + GetCurrentDirectory(MAX_PATH,rootdir); + _tcscat(rootdir,_T("\\")); + if (flags==ZIP_HANDLE) + { + DWORD type = GetFileType(z); + if (type!=FILE_TYPE_DISK) + return ZR_SEEK; + } +#endif + ZRESULT e; + LUFILE *f = lufopen(z,len,flags,&e); + if (f==NULL) + return e; + uf = unzOpenInternal(f); + return uf ? ZR_OK : ZR_CORRUPT; +} + +ZRESULT TUnzip::Get(int index,ZIPENTRY *ze) +{ if (index<-1 || index>=(int)uf->gi.number_entry) + return ZR_ARGS; + if (currentfile!=-1) + unzCloseCurrentFile(uf); + currentfile=-1; + if (index==czei && index!=-1) {memcpy(ze,&cze,sizeof(ZIPENTRY)); return ZR_OK;} + if (index==-1) + { ze->index = uf->gi.number_entry; + ze->name[0]=0; + ze->attr=0; +#ifdef _WIN32 + ze->atime.dwLowDateTime=0; ze->atime.dwHighDateTime=0; + ze->ctime.dwLowDateTime=0; ze->ctime.dwHighDateTime=0; + ze->mtime.dwLowDateTime=0; ze->mtime.dwHighDateTime=0; +#else + ze->atime = 0; + ze->ctime = 0; + ze->mtime = 0; +#endif + ze->comp_size=0; + ze->unc_size=0; + return ZR_OK; + } + if (index<(int)uf->num_file) unzGoToFirstFile(uf); + while ((int)uf->num_filefile,offset,SEEK_SET)!=0) return ZR_READ; + char *extra = new char[extralen]; + if (lufread(extra,1,(uInt)extralen,uf->file)!=extralen) {delete[] extra; return ZR_READ;} + // + ze->index=uf->num_file; + strcpy(ze->name,fn); + // zip has an 'attribute' 32bit value. Its lower half is windows stuff + // its upper half is standard unix attr. + unsigned long a = ufi.external_fa; + bool uisdir = (a&0x40000000)!=0; + //bool uwriteable= (a&0x08000000)!=0; + bool uwriteable= (a&0x00800000)!=0; // ***hd*** + //bool ureadable= (a&0x01000000)!=0; + //bool uexecutable=(a&0x00400000)!=0; + bool wreadonly= (a&0x00000001)!=0; + bool whidden= (a&0x00000002)!=0; + bool wsystem= (a&0x00000004)!=0; + bool wisdir= (a&0x00000010)!=0; + bool warchive= (a&0x00000020)!=0; + ze->attr=FILE_ATTRIBUTE_NORMAL; + if (uisdir || wisdir) ze->attr |= FILE_ATTRIBUTE_DIRECTORY; + if (warchive) ze->attr|=FILE_ATTRIBUTE_ARCHIVE; + if (whidden) ze->attr|=FILE_ATTRIBUTE_HIDDEN; + if (!uwriteable||wreadonly) ze->attr|=FILE_ATTRIBUTE_READONLY; + if (wsystem) ze->attr|=FILE_ATTRIBUTE_SYSTEM; + ze->comp_size = ufi.compressed_size; + ze->unc_size = ufi.uncompressed_size; + // +#ifdef _WIN32 + WORD dostime = (WORD)(ufi.dosDate&0xFFFF); + WORD dosdate = (WORD)((ufi.dosDate>>16)&0xFFFF); + FILETIME ft; + DosDateTimeToFileTime(dosdate,dostime,&ft); + ze->atime=ft; ze->ctime=ft; ze->mtime=ft; +#else + ze->atime=ufi.dosDate; ze->ctime=ufi.dosDate; ze->mtime=ufi.dosDate; +#endif + // the zip will always have at least that dostime. But if it also has + // an extra header, then we'll instead get the info from that. + unsigned int epos=0; + while (epos+4mtime = timet2filetime(mtime); +#else + ze->mtime = mtime; +#endif + } + if (hasatime) + { time_t atime = *(time_t*)(extra+epos); epos+=4; +#ifdef _WIN32 + ze->atime = timet2filetime(atime); +#else + ze->atime = atime; +#endif + } + if (hasctime) + { time_t ctime = *(time_t*)(extra+epos); +#ifdef _WIN32 + ze->ctime = timet2filetime(ctime); +#else + ze->ctime = ctime; +#endif + } + break; + } + // + if (extra!=0) delete[] extra; + memcpy(&cze,ze,sizeof(ZIPENTRY)); czei=index; + return ZR_OK; +} + +ZRESULT TUnzip::Find(const TCHAR *name, bool ic, int *index, ZIPENTRY *ze) +{ + int res = unzLocateFile(uf,name,ic?CASE_INSENSITIVE:CASE_SENSITIVE); + if (res!=UNZ_OK) + { + if (index!=0) + *index=-1; + if (ze!=NULL) + { + ZeroMemory(ze,sizeof(ZIPENTRY)); ze->index=-1; + } + return ZR_NOTFOUND; + } + if (currentfile!=-1) + unzCloseCurrentFile(uf); + currentfile=-1; + int i = (int)uf->num_file; + if (index!=NULL) + *index=i; + if (ze!=NULL) + { + ZRESULT zres = Get(i,ze); + if (zres!=ZR_OK) + return zres; + } + return ZR_OK; +} + +void EnsureDirectory(const TCHAR *rootdir, const TCHAR *dir) +{ + if (dir==NULL || dir[0] == _T('\0')) + return; + + TCHAR cd[MAX_PATH]; + _tcscpy(cd,rootdir); + _tcscat(cd,dir); + for ( unsigned int iCD = 0; iCD < _tcslen( cd ); iCD++ ) + { + if ( cd[ iCD ] == _T( '/' ) || cd[ iCD ] == _T( '\\' ) ) + { + cd[ iCD ] = 0; + CreateDirectory(cd,NULL); + cd[ iCD ] = _T( '\\' ); + } + } + CreateDirectory(cd,NULL); +} + +ZRESULT TUnzip::Unzip(int index,void *dst,unsigned int len,DWORD flags) +{ + if (flags!=ZIP_MEMORY && flags!=ZIP_FILENAME && flags!=ZIP_HANDLE) + return ZR_ARGS; + if (flags==ZIP_MEMORY) + { + if (index!=currentfile) + { + if (currentfile!=-1) + unzCloseCurrentFile(uf); + currentfile=-1; + if (index>=(int)uf->gi.number_entry) + return ZR_ARGS; + if (index<(int)uf->num_file) + unzGoToFirstFile(uf); + while ((int)uf->num_file0) + return ZR_MORE; + unzCloseCurrentFile(uf); + currentfile=-1; + if (res==0) + return ZR_OK; + else + return ZR_FLATE; + } + + // otherwise we're writing to a handle or a file + if (currentfile!=-1) + unzCloseCurrentFile(uf); + currentfile=-1; + if (index >= (int)uf->gi.number_entry) + return ZR_ARGS; + if (index < (int)uf->num_file) + unzGoToFirstFile(uf); + while ((int)uf->num_filelen) n=len-1; + memcpy(buf,msg,n); buf[n]=0; + return mlen; +} + + +typedef struct +{ DWORD flag; + TUnzip *unz; +} TUnzipHandleData; + +HZIP OpenZipU(void *z,unsigned int len,DWORD flags) +{ + TUnzip *unz = new TUnzip(); + lasterrorU = unz->Open(z,len,flags); + if (lasterrorU!=ZR_OK) + { + delete unz; + return 0; + } + TUnzipHandleData *han = new TUnzipHandleData; + han->flag=1; + han->unz=unz; + return (HZIP)han; +} + +ZRESULT GetZipItemA(HZIP hz, int index, ZIPENTRY *ze) +{ + if (hz==0) + { + lasterrorU=ZR_ARGS; + return ZR_ARGS; + } + TUnzipHandleData *han = (TUnzipHandleData*)hz; + if (han->flag!=1) + { + lasterrorU=ZR_ZMODE; + return ZR_ZMODE; + } + TUnzip *unz = han->unz; + lasterrorU = unz->Get(index,ze); + return lasterrorU; +} + +ZRESULT GetZipItemW(HZIP hz, int index, ZIPENTRYW *zew) +{ + if (hz==0) + { + lasterrorU=ZR_ARGS; + return ZR_ARGS; + } + TUnzipHandleData *han = (TUnzipHandleData*)hz; + if (han->flag!=1) + { + lasterrorU=ZR_ZMODE; + return ZR_ZMODE; + } + TUnzip *unz = han->unz; + ZIPENTRY ze; + lasterrorU = unz->Get(index,&ze); + if (lasterrorU == ZR_OK) + { + zew->index = ze.index; + zew->attr = ze.attr; + zew->atime = ze.atime; + zew->ctime = ze.ctime; + zew->mtime = ze.mtime; + zew->comp_size = ze.comp_size; + zew->unc_size = ze.unc_size; +#ifdef _UNICODE + GetUnicodeFileName(ze.name, zew->name, MAX_PATH-1); +#else + strcpy(zew->name, ze.name); +#endif + } + return lasterrorU; +} + +ZRESULT FindZipItemA(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRY *ze) +{ + if (hz==0) + { + lasterrorU=ZR_ARGS; + return ZR_ARGS; + } + TUnzipHandleData *han = (TUnzipHandleData*)hz; + if (han->flag!=1) + { + lasterrorU=ZR_ZMODE; + return ZR_ZMODE; + } + TUnzip *unz = han->unz; + lasterrorU = unz->Find(name,ic,index,ze); + return lasterrorU; +} + +ZRESULT FindZipItemW(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRYW *zew) +{ + if (hz==0) + { + lasterrorU=ZR_ARGS; + return ZR_ARGS; + } + TUnzipHandleData *han = (TUnzipHandleData*)hz; + if (han->flag!=1) + { + lasterrorU=ZR_ZMODE; + return ZR_ZMODE; + } + TUnzip *unz = han->unz; + ZIPENTRY ze; + lasterrorU = unz->Find(name,ic,index,&ze); + if (lasterrorU == ZR_OK) + { + zew->index = ze.index; + zew->attr = ze.attr; + zew->atime = ze.atime; + zew->ctime = ze.ctime; + zew->mtime = ze.mtime; + zew->comp_size = ze.comp_size; + zew->unc_size = ze.unc_size; +#ifdef _UNICODE + GetUnicodeFileName(ze.name, zew->name, MAX_PATH-1); +#else + strcpy(zew->name, ze.name); +#endif + } + + return lasterrorU; +} + +ZRESULT UnzipItem(HZIP hz, int index, void *dst, unsigned int len, DWORD flags) +{ + if (hz==0) + { + lasterrorU=ZR_ARGS; + return ZR_ARGS; + } + TUnzipHandleData *han = (TUnzipHandleData*)hz; + if (han->flag!=1) + { + lasterrorU=ZR_ZMODE; + return ZR_ZMODE; + } + TUnzip *unz = han->unz; + lasterrorU = unz->Unzip(index,dst,len,flags); + return lasterrorU; +} + +ZRESULT CloseZipU(HZIP hz) +{ if (hz==0) {lasterrorU=ZR_ARGS;return ZR_ARGS;} + TUnzipHandleData *han = (TUnzipHandleData*)hz; + if (han->flag!=1) {lasterrorU=ZR_ZMODE;return ZR_ZMODE;} + TUnzip *unz = han->unz; + lasterrorU = unz->Close(); + delete unz; + delete han; + return lasterrorU; +} + +bool IsZipHandleU(HZIP hz) +{ if (hz==0) return true; + TUnzipHandleData *han = (TUnzipHandleData*)hz; + return (han->flag==1); +} + +bool SafeUnzipMemory( const void *pvZipped, int cubZipped, void *pvDest, int cubDest /* should be the exact expected unzipped size */ ) +{ + // unzip + HZIP hZip = OpenZip( (void *)pvZipped, cubZipped, ZIP_MEMORY ); + + // UnzipItem is returning ZR_MORE no matter what size buffer is passed in, we know the real size so just accept + int iRes = ZR_CORRUPT; + if ( hZip ) + { + iRes = UnzipItem( hZip, 0, pvDest, cubDest, ZIP_MEMORY ); + CloseZip( hZip ); + } + + // check for failure + if ( ZR_OK != iRes && ZR_MORE != iRes ) + return false; + + return true; +} + diff --git a/sp/src/public/XZip.cpp b/sp/src/public/XZip.cpp new file mode 100644 index 00000000..2b187a85 --- /dev/null +++ b/sp/src/public/XZip.cpp @@ -0,0 +1,3034 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// XZip.cpp Version 1.1 +// +// Authors: Mark Adler et al. (see below) +// +// Modified by: Lucian Wischik +// lu@wischik.com +// +// Version 1.0 - Turned C files into just a single CPP file +// - Made them compile cleanly as C++ files +// - Gave them simpler APIs +// - Added the ability to zip/unzip directly in memory without +// any intermediate files +// +// Modified by: Hans Dietrich +// hdietrich2@hotmail.com +// +// Version 1.1: - Added Unicode support to CreateZip() and ZipAdd() +// - Changed file names to avoid conflicts with Lucian's files +// +/////////////////////////////////////////////////////////////////////////////// +// +// Lucian Wischik's comments: +// -------------------------- +// THIS FILE is almost entirely based upon code by Info-ZIP. +// It has been modified by Lucian Wischik. +// The original code may be found at http://www.info-zip.org +// The original copyright text follows. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Original authors' comments: +// --------------------------- +// This is version 2002-Feb-16 of the Info-ZIP copyright and license. The +// definitive version of this document should be available at +// ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely. +// +// Copyright (c) 1990-2002 Info-ZIP. All rights reserved. +// +// For the purposes of this copyright and license, "Info-ZIP" is defined as +// the following set of individuals: +// +// Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois, +// Jean-loup Gailly, Hunter Goatley, Ian Gorman, Chris Herborth, Dirk Haase, +// Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz, +// David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko, +// Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs, +// Kai Uwe Rommel, Steve Salisbury, Dave Smith, Christian Spieler, +// Antoine Verheijen, Paul von Behren, Rich Wales, Mike White +// +// This software is provided "as is", without warranty of any kind, express +// or implied. In no event shall Info-ZIP or its contributors be held liable +// for any direct, indirect, incidental, special or consequential damages +// arising out of the use of or inability to use this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. Redistributions of source code must retain the above copyright notice, +// definition, disclaimer, and this list of conditions. +// +// 2. Redistributions in binary form (compiled executables) must reproduce +// the above copyright notice, definition, disclaimer, and this list of +// conditions in documentation and/or other materials provided with the +// distribution. The sole exception to this condition is redistribution +// of a standard UnZipSFX binary as part of a self-extracting archive; +// that is permitted without inclusion of this license, as long as the +// normal UnZipSFX banner has not been removed from the binary or disabled. +// +// 3. Altered versions--including, but not limited to, ports to new +// operating systems, existing ports with new graphical interfaces, and +// dynamic, shared, or static library versions--must be plainly marked +// as such and must not be misrepresented as being the original source. +// Such altered versions also must not be misrepresented as being +// Info-ZIP releases--including, but not limited to, labeling of the +// altered versions with the names "Info-ZIP" (or any variation thereof, +// including, but not limited to, different capitalizations), +// "Pocket UnZip", "WiZ" or "MacZip" without the explicit permission of +// Info-ZIP. Such altered versions are further prohibited from +// misrepresentative use of the Zip-Bugs or Info-ZIP e-mail addresses or +// of the Info-ZIP URL(s). +// +// 4. Info-ZIP retains the right to use the names "Info-ZIP", "Zip", "UnZip", +// "UnZipSFX", "WiZ", "Pocket UnZip", "Pocket Zip", and "MacZip" for its +// own source and binary releases. +// +/////////////////////////////////////////////////////////////////////////////// + +#if defined( WIN32) && !defined( _X360 ) +#define STRICT +#define WIN32_LEAN_AND_MEAN +#include +#elif !defined(_X360) +#define far +#define near +#define INVALID_HANDLE_VALUE (void*)-1 +#define _tzset tzset +#endif + +#if defined( _X360 ) +#include "xbox/xbox_win32stubs.h" +#endif + +#include +#include "zip/XZip.h" + +#ifdef __clang__ + // These clang 3.1 warnings don't seem very useful, and cannot easily be + // avoided in this file. + #pragma GCC diagnostic ignored "-Wdangling-else" // warning: add explicit braces to avoid dangling else [-Wdangling-else] +#endif + +#ifdef OSX +#define MAP_ANONYMOUS MAP_ANON +#endif + +#ifdef XZIP_NOT_THREAD_SAFE +static ZRESULT lasterrorZ=ZR_OK; +#else +#include "tier0/threadtools.h" +static CThreadLocalInt lasterrorZ; +#endif + +typedef unsigned char uch; // unsigned 8-bit value +typedef unsigned short ush; // unsigned 16-bit value +typedef unsigned long ulg; // unsigned 32-bit value +typedef size_t extent; // file size +typedef unsigned Pos; // must be at least 32 bits +typedef unsigned IPos; // A Pos is an index in the character window. Pos is used only for parameter passing + +#ifndef EOF +#define EOF (-1) +#endif + + +// Error return values. The values 0..4 and 12..18 follow the conventions +// of PKZIP. The values 4..10 are all assigned to "insufficient memory" +// by PKZIP, so the codes 5..10 are used here for other purposes. +#define ZE_MISS -1 // used by procname(), zipbare() +#define ZE_OK 0 // success +#define ZE_EOF 2 // unexpected end of zip file +#define ZE_FORM 3 // zip file structure error +#define ZE_MEM 4 // out of memory +#define ZE_LOGIC 5 // internal logic error +#define ZE_BIG 6 // entry too large to split +#define ZE_NOTE 7 // invalid comment format +#define ZE_TEST 8 // zip test (-T) failed or out of memory +#define ZE_ABORT 9 // user interrupt or termination +#define ZE_TEMP 10 // error using a temp file +#define ZE_READ 11 // read or seek error +#define ZE_NONE 12 // nothing to do +#define ZE_NAME 13 // missing or empty zip file +#define ZE_WRITE 14 // error writing to a file +#define ZE_CREAT 15 // couldn't open to write +#define ZE_PARMS 16 // bad command line +#define ZE_OPEN 18 // could not open a specified file to read +#define ZE_MAXERR 18 // the highest error number + + +// internal file attribute +#define UNKNOWN (-1) +#define BINARY 0 +#define ASCII 1 + +#define BEST -1 // Use best method (deflation or store) +#define STORE 0 // Store method +#define DEFLATE 8 // Deflation method + +#define CRCVAL_INITIAL 0L + +// MSDOS file or directory attributes +#define MSDOS_HIDDEN_ATTR 0x02 +#define MSDOS_DIR_ATTR 0x10 + +// Lengths of headers after signatures in bytes +#define LOCHEAD 26 +#define CENHEAD 42 +#define ENDHEAD 18 + +// Definitions for extra field handling: +#define EB_HEADSIZE 4 /* length of a extra field block header */ +#define EB_LEN 2 /* offset of data length field in header */ +#define EB_UT_MINLEN 1 /* minimal UT field contains Flags byte */ +#define EB_UT_FLAGS 0 /* byte offset of Flags field */ +#define EB_UT_TIME1 1 /* byte offset of 1st time value */ +#define EB_UT_FL_MTIME (1 << 0) /* mtime present */ +#define EB_UT_FL_ATIME (1 << 1) /* atime present */ +#define EB_UT_FL_CTIME (1 << 2) /* ctime present */ +#define EB_UT_LEN(n) (EB_UT_MINLEN + 4 * (n)) +#define EB_L_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(3)) +#define EB_C_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(1)) + + +// Macros for writing machine integers to little-endian format +#define PUTSH(a,f) {char _putsh_c=(char)((a)&0xff); wfunc(param,&_putsh_c,1); _putsh_c=(char)((a)>>8); wfunc(param,&_putsh_c,1);} +#define PUTLG(a,f) {PUTSH((a) & 0xffff,(f)) PUTSH((a) >> 16,(f))} + + +// -- Structure of a ZIP file -- +// Signatures for zip file information headers +#define LOCSIG 0x04034b50L +#define CENSIG 0x02014b50L +#define ENDSIG 0x06054b50L +#define EXTLOCSIG 0x08074b50L + + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +// The minimum and maximum match lengths + + +#define WSIZE (0x8000) +// Maximum window size = 32K. If you are really short of memory, compile +// with a smaller WSIZE but this reduces the compression ratio for files +// of size > WSIZE. WSIZE must be a power of two in the current implementation. +// + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +// Minimum amount of lookahead, except at the end of the input file. +// See deflate.c for comments about the MIN_MATCH+1. +// + +#define MAX_DIST (WSIZE-MIN_LOOKAHEAD) +// In order to simplify the code, particularly on 16 bit machines, match +// distances are limited to MAX_DIST instead of WSIZE. +// + + + + + +// =========================================================================== +// Constants +// + +#define MAX_BITS 15 +// All codes must not exceed MAX_BITS bits + +#define MAX_BL_BITS 7 +// Bit length codes must not exceed MAX_BL_BITS bits + +#define LENGTH_CODES 29 +// number of length codes, not counting the special END_BLOCK code + +#define LITERALS 256 +// number of literal bytes 0..255 + +#define END_BLOCK 256 +// end of block literal code + +#define L_CODES (LITERALS+1+LENGTH_CODES) +// number of Literal or Length codes, including the END_BLOCK code + +#define D_CODES 30 +// number of distance codes + +#define BL_CODES 19 +// number of codes used to transfer the bit lengths + + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +// The three kinds of block type + +#define LIT_BUFSIZE 0x8000 +#define DIST_BUFSIZE LIT_BUFSIZE +// Sizes of match buffers for literals/lengths and distances. There are +// 4 reasons for limiting LIT_BUFSIZE to 64K: +// - frequencies can be kept in 16 bit counters +// - if compression is not successful for the first block, all input data is +// still in the window so we can still emit a stored block even when input +// comes from standard input. (This can also be done for all blocks if +// LIT_BUFSIZE is not greater than 32K.) +// - if compression is not successful for a file smaller than 64K, we can +// even emit a stored file instead of a stored block (saving 5 bytes). +// - creating new Huffman trees less frequently may not provide fast +// adaptation to changes in the input data statistics. (Take for +// example a binary file with poorly compressible code followed by +// a highly compressible string table.) Smaller buffer sizes give +// fast adaptation but have of course the overhead of transmitting trees +// more frequently. +// - I can't count above 4 +// The current code is general and allows DIST_BUFSIZE < LIT_BUFSIZE (to save +// memory at the expense of compression). Some optimizations would be possible +// if we rely on DIST_BUFSIZE == LIT_BUFSIZE. +// + +#define REP_3_6 16 +// repeat previous bit length 3-6 times (2 bits of repeat count) + +#define REPZ_3_10 17 +// repeat a zero length 3-10 times (3 bits of repeat count) + +#define REPZ_11_138 18 +// repeat a zero length 11-138 times (7 bits of repeat count) + +#define HEAP_SIZE (2*L_CODES+1) +// maximum heap size + + +// =========================================================================== +// Local data used by the "bit string" routines. +// + +#define Buf_size (8 * 2*sizeof(char)) +// Number of bits used within bi_buf. (bi_buf may be implemented on +// more than 16 bits on some systems.) + +// Output a 16 bit value to the bit stream, lower (oldest) byte first +#define PUTSHORT(state,w) \ +{ if (state.bs.out_offset >= state.bs.out_size-1) \ + state.flush_outbuf(state.param,state.bs.out_buf, &state.bs.out_offset); \ + /* flush may fail, so only write into the buffer if there's actually room (same below) */ \ + if (state.bs.out_offset < state.bs.out_size-1) { \ + state.bs.out_buf[state.bs.out_offset++] = (char) ((w) & 0xff); \ + state.bs.out_buf[state.bs.out_offset++] = (char) ((ush)(w) >> 8); \ + } \ +} + +#define PUTBYTE(state,b) \ +{ if (state.bs.out_offset >= state.bs.out_size) \ + state.flush_outbuf(state.param,state.bs.out_buf, &state.bs.out_offset); \ + if (state.bs.out_offset < state.bs.out_size) \ + state.bs.out_buf[state.bs.out_offset++] = (char) (b); \ +} + +// DEFLATE.CPP HEADER + +#define HASH_BITS 15 +// For portability to 16 bit machines, do not use values above 15. + +#define HASH_SIZE (unsigned)(1<= HASH_BITS + +#define max_insert_length max_lazy_match +// Insert new strings in the hash table only if the match length +// is not greater than this length. This saves time but degrades compression. +// max_insert_length is used only for compression levels <= 3. + + + +const int extra_lbits[LENGTH_CODES] // extra bits for each length code + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +const int extra_dbits[D_CODES] // extra bits for each distance code + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +const int extra_blbits[BL_CODES]// extra bits for each bit length code + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +const uch bl_order[BL_CODES] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +// The lengths of the bit length codes are sent in order of decreasing +// probability, to avoid transmitting the lengths for unused bit length codes. + + +typedef struct config { + ush good_length; // reduce lazy search above this match length + ush max_lazy; // do not perform lazy search above this match length + ush nice_length; // quit search above this match length + ush max_chain; +} config; + +// Values for max_lazy_match, good_match, nice_match and max_chain_length, +// depending on the desired pack level (0..9). The values given below have +// been tuned to exclude worst case performance for pathological files. +// Better values may be found for specific files. +// + +const config configuration_table[10] = { +// good lazy nice chain + {0, 0, 0, 0}, // 0 store only + {4, 4, 8, 4}, // 1 maximum speed, no lazy matches + {4, 5, 16, 8}, // 2 + {4, 6, 32, 32}, // 3 + {4, 4, 16, 16}, // 4 lazy matches */ + {8, 16, 32, 32}, // 5 + {8, 16, 128, 128}, // 6 + {8, 32, 128, 256}, // 7 + {32, 128, 258, 1024}, // 8 + {32, 258, 258, 4096}};// 9 maximum compression */ + +// Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 +// For deflate_fast() (levels <= 3) good is ignored and lazy has a different meaning. + + + + + +// Data structure describing a single value and its code string. +typedef struct ct_data { + union { + ush freq; // frequency count + ush code; // bit string + } fc; + union { + ush dad; // father node in Huffman tree + ush len; // length of bit string + } dl; +} ct_data; + +typedef struct tree_desc { + ct_data *dyn_tree; // the dynamic tree + ct_data *static_tree; // corresponding static tree or NULL + const int *extra_bits; // extra bits for each code or NULL + int extra_base; // base index for extra_bits + int elems; // max number of elements in the tree + int max_length; // max bit length for the codes + int max_code; // largest code with non zero frequency +} tree_desc; + + + + +class TTreeState +{ public: + TTreeState(); + + ct_data dyn_ltree[HEAP_SIZE]; // literal and length tree + ct_data dyn_dtree[2*D_CODES+1]; // distance tree + ct_data static_ltree[L_CODES+2]; // the static literal tree... + // ... Since the bit lengths are imposed, there is no need for the L_CODES + // extra codes used during heap construction. However the codes 286 and 287 + // are needed to build a canonical tree (see ct_init below). + ct_data static_dtree[D_CODES]; // the static distance tree... + // ... (Actually a trivial tree since all codes use 5 bits.) + ct_data bl_tree[2*BL_CODES+1]; // Huffman tree for the bit lengths + + tree_desc l_desc; + tree_desc d_desc; + tree_desc bl_desc; + + ush bl_count[MAX_BITS+1]; // number of codes at each bit length for an optimal tree + + int heap[2*L_CODES+1]; // heap used to build the Huffman trees + int heap_len; // number of elements in the heap + int heap_max; // element of largest frequency + // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + // The same heap array is used to build all trees. + + uch depth[2*L_CODES+1]; + // Depth of each subtree used as tie breaker for trees of equal frequency + + uch length_code[MAX_MATCH-MIN_MATCH+1]; + // length code for each normalized match length (0 == MIN_MATCH) + + uch dist_code[512]; + // distance codes. The first 256 values correspond to the distances + // 3 .. 258, the last 256 values correspond to the top 8 bits of + // the 15 bit distances. + + int base_length[LENGTH_CODES]; + // First normalized length for each code (0 = MIN_MATCH) + + int base_dist[D_CODES]; + // First normalized distance for each code (0 = distance of 1) + + uch far l_buf[LIT_BUFSIZE]; // buffer for literals/lengths + ush far d_buf[DIST_BUFSIZE]; // buffer for distances + + uch flag_buf[(LIT_BUFSIZE/8)]; + // flag_buf is a bit array distinguishing literals from lengths in + // l_buf, and thus indicating the presence or absence of a distance. + + unsigned last_lit; // running index in l_buf + unsigned last_dist; // running index in d_buf + unsigned last_flags; // running index in flag_buf + uch flags; // current flags not yet saved in flag_buf + uch flag_bit; // current bit used in flags + // bits are filled in flags starting at bit 0 (least significant). + // Note: these flags are overkill in the current code since we don't + // take advantage of DIST_BUFSIZE == LIT_BUFSIZE. + + ulg opt_len; // bit length of current block with optimal trees + ulg static_len; // bit length of current block with static trees + + ulg cmpr_bytelen; // total byte length of compressed file + ulg cmpr_len_bits; // number of bits past 'cmpr_bytelen' + + ulg input_len; // total byte length of input file + // input_len is for debugging only since we can get it by other means. + + ush *file_type; // pointer to UNKNOWN, BINARY or ASCII +// int *file_method; // pointer to DEFLATE or STORE +}; + +TTreeState::TTreeState() +{ tree_desc a = {dyn_ltree, static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS, 0}; l_desc = a; + tree_desc b = {dyn_dtree, static_dtree, extra_dbits, 0, D_CODES, MAX_BITS, 0}; d_desc = b; + tree_desc c = {bl_tree, NULL, extra_blbits, 0, BL_CODES, MAX_BL_BITS, 0}; bl_desc = c; + last_lit=0; + last_dist=0; + last_flags=0; +} + + + +class TBitState +{ public: + + int flush_flg; + // + unsigned bi_buf; + // Output buffer. bits are inserted starting at the bottom (least significant + // bits). The width of bi_buf must be at least 16 bits. + int bi_valid; + // Number of valid bits in bi_buf. All bits above the last valid bit + // are always zero. + char *out_buf; + // Current output buffer. + unsigned out_offset; + // Current offset in output buffer. + // On 16 bit machines, the buffer is limited to 64K. + unsigned out_size; + // Size of current output buffer + ulg bits_sent; // bit length of the compressed data only needed for debugging??? +}; + + + + + + + +class TDeflateState +{ public: + TDeflateState() {window_size=0;} + + uch window[2L*WSIZE]; + // Sliding window. Input bytes are read into the second half of the window, + // and move to the first half later to keep a dictionary of at least WSIZE + // bytes. With this organization, matches are limited to a distance of + // WSIZE-MAX_MATCH bytes, but this ensures that IO is always + // performed with a length multiple of the block size. Also, it limits + // the window size to 64K, which is quite useful on MSDOS. + // To do: limit the window size to WSIZE+CBSZ if SMALL_MEM (the code would + // be less efficient since the data would have to be copied WSIZE/CBSZ times) + Pos prev[WSIZE]; + // Link to older string with same hash index. To limit the size of this + // array to 64K, this link is maintained only for the last 32K strings. + // An index in this array is thus a window index modulo 32K. + Pos head[HASH_SIZE]; + // Heads of the hash chains or NIL. If your compiler thinks that + // HASH_SIZE is a dynamic value, recompile with -DDYN_ALLOC. + + ulg window_size; + // window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the + // input file length plus MIN_LOOKAHEAD. + + long block_start; + // window position at the beginning of the current output block. Gets + // negative when the window is moved backwards. + + int sliding; + // Set to false when the input file is already in memory + + unsigned ins_h; // hash index of string to be inserted + + unsigned int prev_length; + // Length of the best match at previous step. Matches not greater than this + // are discarded. This is used in the lazy match evaluation. + + unsigned strstart; // start of string to insert + unsigned match_start; // start of matching string + int eofile; // flag set at end of input file + unsigned lookahead; // number of valid bytes ahead in window + + unsigned max_chain_length; + // To speed up deflation, hash chains are never searched beyond this length. + // A higher limit improves compression ratio but degrades the speed. + + unsigned int max_lazy_match; + // Attempt to find a better match only when the current match is strictly + // smaller than this value. This mechanism is used only for compression + // levels >= 4. + + unsigned good_match; + // Use a faster search when the previous match is longer than this + + int nice_match; // Stop searching when current match exceeds this +}; + + +typedef struct iztimes { + time_t atime,mtime,ctime; +} iztimes; // access, modify, create times + +typedef struct zlist { + ush vem, ver, flg, how; // See central header in zipfile.c for what vem..off are + ulg tim, crc, siz, len; + extent nam, ext, cext, com; // offset of ext must be >= LOCHEAD + ush dsk, att, lflg; // offset of lflg must be >= LOCHEAD + ulg atx, off; + char name[MAX_PATH]; // File name in zip file + char *extra; // Extra field (set only if ext != 0) + char *cextra; // Extra in central (set only if cext != 0) + char *comment; // Comment (set only if com != 0) + char iname[MAX_PATH]; // Internal file name after cleanup + char zname[MAX_PATH]; // External version of internal name + int mark; // Marker for files to operate on + int trash; // Marker for files to delete + int dosflag; // Set to force MSDOS file attributes + struct zlist far *nxt; // Pointer to next header in list +} TZipFileInfo; + + +class TState; +typedef unsigned (*READFUNC)(TState &state, char *buf,unsigned size); +typedef unsigned (*FLUSHFUNC)(void *param, const char *buf, unsigned *size); +typedef unsigned (*WRITEFUNC)(void *param, const char *buf, unsigned size); +class TState +{ public: TState() {err=0;} + // + void *param; + int level; bool seekable; + READFUNC readfunc; FLUSHFUNC flush_outbuf; + TTreeState ts; TBitState bs; TDeflateState ds; + const char *err; +}; + + + + + + + + +#undef Assert +void Assert(TState &state,bool cond, const char *msg) +{ if (cond) return; + state.err=msg; +} +void __cdecl Trace(const char *x, ...) {va_list paramList; va_start(paramList, x); paramList; va_end(paramList);} +void __cdecl Tracec(bool ,const char *x, ...) {va_list paramList; va_start(paramList, x); paramList; va_end(paramList);} + + + +// =========================================================================== +// Local (static) routines in this file. +// + +void init_block (TState &); +void pqdownheap (TState &,ct_data *tree, int k); +void gen_bitlen (TState &,tree_desc *desc); +void gen_codes (TState &state,ct_data *tree, int max_code); +void build_tree (TState &,tree_desc *desc); +void scan_tree (TState &,ct_data *tree, int max_code); +void send_tree (TState &state,ct_data *tree, int max_code); +int build_bl_tree (TState &); +void send_all_trees (TState &state,int lcodes, int dcodes, int blcodes); +void compress_block (TState &state,ct_data *ltree, ct_data *dtree); +void set_file_type (TState &); +void send_bits (TState &state, int value, int length); +unsigned bi_reverse (unsigned code, int len); +void bi_windup (TState &state); +void copy_block (TState &state,char *buf, unsigned len, int header); + + +#define send_code(state, c, tree) send_bits(state, tree[c].fc.code, tree[c].dl.len) +// Send a code of the given tree. c and tree must not have side effects + +// alternatively... +//#define send_code(state, c, tree) +// { if (state.verbose>1) fprintf(stderr,"\ncd %3d ",(c)); +// send_bits(state, tree[c].fc.code, tree[c].dl.len); } + +#define d_code(dist) ((dist) < 256 ? state.ts.dist_code[dist] : state.ts.dist_code[256+((dist)>>7)]) +// Mapping from a distance to a distance code. dist is the distance - 1 and +// must not have side effects. dist_code[256] and dist_code[257] are never used. + +#define Max(a,b) (a >= b ? a : b) +/* the arguments must not have side effects */ + +/* =========================================================================== + * Allocate the match buffer, initialize the various tables and save the + * location of the internal file attribute (ascii/binary) and method + * (DEFLATE/STORE). + */ +void ct_init(TState &state, ush *attr) +{ + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + + state.ts.file_type = attr; + //state.ts.file_method = method; + state.ts.cmpr_bytelen = state.ts.cmpr_len_bits = 0L; + state.ts.input_len = 0L; + + if (state.ts.static_dtree[0].dl.len != 0) return; /* ct_init already called */ + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + state.ts.base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + state.ts.base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + state.ts.base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + state.ts.dist_code[256 + dist++] = (uch)code; + } + } + Assert(state,dist == 256, "ct_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) state.ts.bl_count[bits] = 0; + n = 0; + while (n <= 143) state.ts.static_ltree[n++].dl.len = 8, state.ts.bl_count[8]++; + while (n <= 255) state.ts.static_ltree[n++].dl.len = 9, state.ts.bl_count[9]++; + while (n <= 279) state.ts.static_ltree[n++].dl.len = 7, state.ts.bl_count[7]++; + while (n <= 287) state.ts.static_ltree[n++].dl.len = 8, state.ts.bl_count[8]++; + /* fc.codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes(state,(ct_data *)state.ts.static_ltree, L_CODES+1); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + state.ts.static_dtree[n].dl.len = 5; + state.ts.static_dtree[n].fc.code = (ush)bi_reverse(n, 5); + } + + /* Initialize the first block of the first file: */ + init_block(state); +} + +/* =========================================================================== + * Initialize a new block. + */ +void init_block(TState &state) +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) state.ts.dyn_ltree[n].fc.freq = 0; + for (n = 0; n < D_CODES; n++) state.ts.dyn_dtree[n].fc.freq = 0; + for (n = 0; n < BL_CODES; n++) state.ts.bl_tree[n].fc.freq = 0; + + state.ts.dyn_ltree[END_BLOCK].fc.freq = 1; + state.ts.opt_len = state.ts.static_len = 0L; + state.ts.last_lit = state.ts.last_dist = state.ts.last_flags = 0; + state.ts.flags = 0; state.ts.flag_bit = 1; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(tree, top) \ +{\ + top = state.ts.heap[SMALLEST]; \ + state.ts.heap[SMALLEST] = state.ts.heap[state.ts.heap_len--]; \ + pqdownheap(state,tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m) \ + (tree[n].fc.freq < tree[m].fc.freq || \ + (tree[n].fc.freq == tree[m].fc.freq && state.ts.depth[n] <= state.ts.depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +void pqdownheap(TState &state,ct_data *tree, int k) +{ + int v = state.ts.heap[k]; + int j = k << 1; /* left son of k */ + int htemp; /* required because of bug in SASC compiler */ + + while (j <= state.ts.heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < state.ts.heap_len && smaller(tree, state.ts.heap[j+1], state.ts.heap[j])) j++; + + /* Exit if v is smaller than both sons */ + htemp = state.ts.heap[j]; + if (smaller(tree, v, htemp)) break; + + /* Exchange v with the smallest son */ + state.ts.heap[k] = htemp; + k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + state.ts.heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +void gen_bitlen(TState &state,tree_desc *desc) +{ + ct_data *tree = desc->dyn_tree; + const int *extra = desc->extra_bits; + int base = desc->extra_base; + int max_code = desc->max_code; + int max_length = desc->max_length; + ct_data *stree = desc->static_tree; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) state.ts.bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[state.ts.heap[state.ts.heap_max]].dl.len = 0; /* root of the heap */ + + for (h = state.ts.heap_max+1; h < HEAP_SIZE; h++) { + n = state.ts.heap[h]; + bits = tree[tree[n].dl.dad].dl.len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].dl.len = (ush)bits; + /* We overwrite tree[n].dl.dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + state.ts.bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].fc.freq; + state.ts.opt_len += (ulg)f * (bits + xbits); + if (stree) state.ts.static_len += (ulg)f * (stree[n].dl.len + xbits); + } + if (overflow == 0) return; + + Trace("\nbit length overflow\n"); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (state.ts.bl_count[bits] == 0) bits--; + state.ts.bl_count[bits]--; /* move one leaf down the tree */ + state.ts.bl_count[bits+1] += (ush)2; /* move one overflow item as its brother */ + state.ts.bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = state.ts.bl_count[bits]; + while (n != 0) { + m = state.ts.heap[--h]; + if (m > max_code) continue; + if (tree[m].dl.len != (ush)bits) { + Trace("code %d bits %d->%d\n", m, tree[m].dl.len, bits); + state.ts.opt_len += ((long)bits-(long)tree[m].dl.len)*(long)tree[m].fc.freq; + tree[m].dl.len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +void gen_codes (TState &state, ct_data *tree, int max_code) +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (ush)((code + state.ts.bl_count[bits-1]) << 1); + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert(state,code + state.ts.bl_count[MAX_BITS]-1 == (1<< ((ush) MAX_BITS)) - 1, + "inconsistent bit counts"); + Trace("\ngen_codes: max_code %d ", max_code); + + for (n = 0; n <= max_code; n++) { + int len = tree[n].dl.len; + if (len == 0) continue; + /* Now reverse the bits */ + tree[n].fc.code = (ush)bi_reverse(next_code[len]++, len); + + //Tracec(tree != state.ts.static_ltree, "\nn %3d %c l %2d c %4x (%x) ", n, (isgraph(n) ? n : ' '), len, tree[n].fc.code, next_code[len]-1); + } +} + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +void build_tree(TState &state,tree_desc *desc) +{ + ct_data *tree = desc->dyn_tree; + ct_data *stree = desc->static_tree; + int elems = desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node = elems; /* next internal node of the tree */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + state.ts.heap_len = 0, state.ts.heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].fc.freq != 0) { + state.ts.heap[++state.ts.heap_len] = max_code = n; + state.ts.depth[n] = 0; + } else { + tree[n].dl.len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (state.ts.heap_len < 2) { + int newcp = state.ts.heap[++state.ts.heap_len] = (max_code < 2 ? ++max_code : 0); + tree[newcp].fc.freq = 1; + state.ts.depth[newcp] = 0; + state.ts.opt_len--; if (stree) state.ts.static_len -= stree[newcp].dl.len; + /* new is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = state.ts.heap_len/2; n >= 1; n--) pqdownheap(state,tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + do { + pqremove(tree, n); /* n = node of least frequency */ + m = state.ts.heap[SMALLEST]; /* m = node of next least frequency */ + + state.ts.heap[--state.ts.heap_max] = n; /* keep the nodes sorted by frequency */ + state.ts.heap[--state.ts.heap_max] = m; + + /* Create a new node father of n and m */ + tree[node].fc.freq = (ush)(tree[n].fc.freq + tree[m].fc.freq); + state.ts.depth[node] = (uch) (Max(state.ts.depth[n], state.ts.depth[m]) + 1); + tree[n].dl.dad = tree[m].dl.dad = (ush)node; + /* and insert the new node in the heap */ + state.ts.heap[SMALLEST] = node++; + pqdownheap(state,tree, SMALLEST); + + } while (state.ts.heap_len >= 2); + + state.ts.heap[--state.ts.heap_max] = state.ts.heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(state,(tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes (state,(ct_data *)tree, max_code); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. Updates opt_len to take into account the repeat + * counts. (The contribution of the bit length codes will be added later + * during the construction of bl_tree.) + */ +void scan_tree (TState &state,ct_data *tree, int max_code) +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].dl.len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].dl.len = (ush)-1; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].dl.len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + state.ts.bl_tree[curlen].fc.freq = (ush)(state.ts.bl_tree[curlen].fc.freq + count); + } else if (curlen != 0) { + if (curlen != prevlen) state.ts.bl_tree[curlen].fc.freq++; + state.ts.bl_tree[REP_3_6].fc.freq++; + } else if (count <= 10) { + state.ts.bl_tree[REPZ_3_10].fc.freq++; + } else { + state.ts.bl_tree[REPZ_11_138].fc.freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +void send_tree (TState &state, ct_data *tree, int max_code) +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].dl.len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].dl.len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].dl.len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(state, curlen, state.ts.bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(state, curlen, state.ts.bl_tree); count--; + } + Assert(state,count >= 3 && count <= 6, " 3_6?"); + send_code(state,REP_3_6, state.ts.bl_tree); send_bits(state,count-3, 2); + + } else if (count <= 10) { + send_code(state,REPZ_3_10, state.ts.bl_tree); send_bits(state,count-3, 3); + + } else { + send_code(state,REPZ_11_138, state.ts.bl_tree); send_bits(state,count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +int build_bl_tree(TState &state) +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(state,(ct_data *)state.ts.dyn_ltree, state.ts.l_desc.max_code); + scan_tree(state,(ct_data *)state.ts.dyn_dtree, state.ts.d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(state,(tree_desc *)(&state.ts.bl_desc)); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (state.ts.bl_tree[bl_order[max_blindex]].dl.len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + state.ts.opt_len += 3*(max_blindex+1) + 5+5+4; + Trace("\ndyn trees: dyn %ld, stat %ld", state.ts.opt_len, state.ts.static_len); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +void send_all_trees(TState &state,int lcodes, int dcodes, int blcodes) +{ + int rank; /* index in bl_order */ + + Assert(state,lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert(state,lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Trace("\nbl counts: "); + send_bits(state,lcodes-257, 5); + /* not +255 as stated in appnote.txt 1.93a or -256 in 2.04c */ + send_bits(state,dcodes-1, 5); + send_bits(state,blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Trace("\nbl code %2d ", bl_order[rank]); + send_bits(state,state.ts.bl_tree[bl_order[rank]].dl.len, 3); + } + Trace("\nbl tree: sent %ld", state.bs.bits_sent); + + send_tree(state,(ct_data *)state.ts.dyn_ltree, lcodes-1); /* send the literal tree */ + Trace("\nlit tree: sent %ld", state.bs.bits_sent); + + send_tree(state,(ct_data *)state.ts.dyn_dtree, dcodes-1); /* send the distance tree */ + Trace("\ndist tree: sent %ld", state.bs.bits_sent); +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. This function + * returns the total compressed length (in bytes) for the file so far. + */ +ulg flush_block(TState &state,char *buf, ulg stored_len, int eof) +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex; /* index of last bit length code of non zero freq */ + + state.ts.flag_buf[state.ts.last_flags] = state.ts.flags; /* Save the flags for the last 8 items */ + + /* Check if the file is ascii or binary */ + if (*state.ts.file_type == (ush)UNKNOWN) set_file_type(state); + + /* Construct the literal and distance trees */ + build_tree(state,(tree_desc *)(&state.ts.l_desc)); + Trace("\nlit data: dyn %ld, stat %ld", state.ts.opt_len, state.ts.static_len); + + build_tree(state,(tree_desc *)(&state.ts.d_desc)); + Trace("\ndist data: dyn %ld, stat %ld", state.ts.opt_len, state.ts.static_len); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(state); + + /* Determine the best encoding. Compute first the block length in bytes */ + opt_lenb = (state.ts.opt_len+3+7)>>3; + static_lenb = (state.ts.static_len+3+7)>>3; + state.ts.input_len += stored_len; /* for debugging only */ + + Trace("\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", + opt_lenb, state.ts.opt_len, static_lenb, state.ts.static_len, stored_len, + state.ts.last_lit, state.ts.last_dist); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + // Originally, zip allowed the file to be transformed from a compressed + // into a stored file in the case where compression failed, there + // was only one block, and it was allowed to change. I've removed this + // possibility since the code's cleaner if no changes are allowed. + //if (stored_len <= opt_lenb && eof && state.ts.cmpr_bytelen == 0L + // && state.ts.cmpr_len_bits == 0L && state.seekable) + //{ // && state.ts.file_method != NULL + // // Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: + // Assert(state,buf!=NULL,"block vanished"); + // copy_block(state,buf, (unsigned)stored_len, 0); // without header + // state.ts.cmpr_bytelen = stored_len; + // Assert(state,false,"unimplemented *state.ts.file_method = STORE;"); + // //*state.ts.file_method = STORE; + //} + //else + if (stored_len+4 <= opt_lenb && buf != (char*)NULL) { + /* 4: two words for the lengths */ + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + send_bits(state,(STORED_BLOCK<<1)+eof, 3); /* send block type */ + state.ts.cmpr_bytelen += ((state.ts.cmpr_len_bits + 3 + 7) >> 3) + stored_len + 4; + state.ts.cmpr_len_bits = 0L; + + copy_block(state,buf, (unsigned)stored_len, 1); /* with header */ + } + else if (static_lenb == opt_lenb) { + send_bits(state,(STATIC_TREES<<1)+eof, 3); + compress_block(state,(ct_data *)state.ts.static_ltree, (ct_data *)state.ts.static_dtree); + state.ts.cmpr_len_bits += 3 + state.ts.static_len; + state.ts.cmpr_bytelen += state.ts.cmpr_len_bits >> 3; + state.ts.cmpr_len_bits &= 7L; + } + else { + send_bits(state,(DYN_TREES<<1)+eof, 3); + send_all_trees(state,state.ts.l_desc.max_code+1, state.ts.d_desc.max_code+1, max_blindex+1); + compress_block(state,(ct_data *)state.ts.dyn_ltree, (ct_data *)state.ts.dyn_dtree); + state.ts.cmpr_len_bits += 3 + state.ts.opt_len; + state.ts.cmpr_bytelen += state.ts.cmpr_len_bits >> 3; + state.ts.cmpr_len_bits &= 7L; + } + Assert(state,((state.ts.cmpr_bytelen << 3) + state.ts.cmpr_len_bits) == state.bs.bits_sent, "bad compressed size"); + init_block(state); + + if (eof) { + // Assert(state,input_len == isize, "bad input size"); + bi_windup(state); + state.ts.cmpr_len_bits += 7; /* align on byte boundary */ + } + Trace("\n"); + + return state.ts.cmpr_bytelen + (state.ts.cmpr_len_bits >> 3); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ct_tally (TState &state,int dist, int lc) +{ + state.ts.l_buf[state.ts.last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + state.ts.dyn_ltree[lc].fc.freq++; + } else { + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert(state,(ush)dist < (ush)MAX_DIST && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "ct_tally: bad match"); + + state.ts.dyn_ltree[state.ts.length_code[lc]+LITERALS+1].fc.freq++; + state.ts.dyn_dtree[d_code(dist)].fc.freq++; + + state.ts.d_buf[state.ts.last_dist++] = (ush)dist; + state.ts.flags |= state.ts.flag_bit; + } + state.ts.flag_bit <<= 1; + + /* Output the flags if they fill a byte: */ + if ((state.ts.last_lit & 7) == 0) { + state.ts.flag_buf[state.ts.last_flags++] = state.ts.flags; + state.ts.flags = 0, state.ts.flag_bit = 1; + } + /* Try to guess if it is profitable to stop the current block here */ + if (state.level > 2 && (state.ts.last_lit & 0xfff) == 0) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)state.ts.last_lit*8L; + ulg in_length = (ulg)state.ds.strstart-state.ds.block_start; + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)state.ts.dyn_dtree[dcode].fc.freq*(5L+extra_dbits[dcode]); + } + out_length >>= 3; + Trace("\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", + state.ts.last_lit, state.ts.last_dist, in_length, out_length, + 100L - out_length*100L/in_length); + if (state.ts.last_dist < state.ts.last_lit/2 && out_length < in_length/2) return 1; + } + return (state.ts.last_lit == LIT_BUFSIZE-1 || state.ts.last_dist == DIST_BUFSIZE); + /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +void compress_block(TState &state,ct_data *ltree, ct_data *dtree) +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned dx = 0; /* running index in d_buf */ + unsigned fx = 0; /* running index in flag_buf */ + uch flag = 0; /* current flags */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (state.ts.last_lit != 0) do { + if ((lx & 7) == 0) flag = state.ts.flag_buf[fx++]; + lc = state.ts.l_buf[lx++]; + if ((flag & 1) == 0) { + send_code(state,lc, ltree); /* send a literal byte */ + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = state.ts.length_code[lc]; + send_code(state,code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= state.ts.base_length[code]; + send_bits(state,lc, extra); /* send the extra length bits */ + } + dist = state.ts.d_buf[dx++]; + /* Here, dist is the match distance - 1 */ + code = d_code(dist); + Assert(state,code < D_CODES, "bad d_code"); + + send_code(state,code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= state.ts.base_dist[code]; + send_bits(state,dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + flag >>= 1; + } while (lx < state.ts.last_lit); + + send_code(state,END_BLOCK, ltree); +} + +/* =========================================================================== + * Set the file type to ASCII or BINARY, using a crude approximation: + * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + * IN assertion: the fields freq of dyn_ltree are set and the total of all + * frequencies does not exceed 64K (to fit in an int on 16 bit machines). + */ +void set_file_type(TState &state) +{ + int n = 0; + unsigned ascii_freq = 0; + unsigned bin_freq = 0; + while (n < 7) bin_freq += state.ts.dyn_ltree[n++].fc.freq; + while (n < 128) ascii_freq += state.ts.dyn_ltree[n++].fc.freq; + while (n < LITERALS) bin_freq += state.ts.dyn_ltree[n++].fc.freq; + *state.ts.file_type = (ush)(bin_freq > (ascii_freq >> 2) ? BINARY : ASCII); +} + + +/* =========================================================================== + * Initialize the bit string routines. + */ +void bi_init (TState &state,char *tgt_buf, unsigned tgt_size, int flsh_allowed) +{ + state.bs.out_buf = tgt_buf; + state.bs.out_size = tgt_size; + state.bs.out_offset = 0; + state.bs.flush_flg = flsh_allowed; + + state.bs.bi_buf = 0; + state.bs.bi_valid = 0; + state.bs.bits_sent = 0L; +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +void send_bits(TState &state,int value, int length) +{ + Assert(state,length > 0 && length <= 15, "invalid length"); + state.bs.bits_sent += (ulg)length; + /* If not enough room in bi_buf, use (bi_valid) bits from bi_buf and + * (Buf_size - bi_valid) bits from value to flush the filled bi_buf, + * then fill in the rest of (value), leaving (length - (Buf_size-bi_valid)) + * unused bits in bi_buf. + */ + state.bs.bi_buf |= (value << state.bs.bi_valid); + state.bs.bi_valid += length; + if (state.bs.bi_valid > (int)Buf_size) { + PUTSHORT(state,state.bs.bi_buf); + state.bs.bi_valid -= Buf_size; + state.bs.bi_buf = (unsigned)value >> (length - state.bs.bi_valid); + } +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +unsigned bi_reverse(unsigned code, int len) +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Write out any remaining bits in an incomplete byte. + */ +void bi_windup(TState &state) +{ + if (state.bs.bi_valid > 8) { + PUTSHORT(state,state.bs.bi_buf); + } else if (state.bs.bi_valid > 0) { + PUTBYTE(state,state.bs.bi_buf); + } + if (state.bs.flush_flg) { + state.flush_outbuf(state.param, state.bs.out_buf, &state.bs.out_offset); + } + state.bs.bi_buf = 0; + state.bs.bi_valid = 0; + state.bs.bits_sent = (state.bs.bits_sent+7) & ~7; +} + +/* =========================================================================== + * Copy a stored block to the zip file, storing first the length and its + * one's complement if requested. + */ +void copy_block(TState &state, char *block, unsigned len, int header) +{ + bi_windup(state); /* align on byte boundary */ + + if (header) { + PUTSHORT(state,(ush)len); + PUTSHORT(state,(ush)~len); + state.bs.bits_sent += 2*16; + } + if (state.bs.flush_flg) { + state.flush_outbuf(state.param, state.bs.out_buf, &state.bs.out_offset); + state.bs.out_offset = len; + state.flush_outbuf(state.param, block, &state.bs.out_offset); + } else if (state.bs.out_offset + len > state.bs.out_size) { + Assert(state,false,"output buffer too small for in-memory compression"); + } else { + memcpy(state.bs.out_buf + state.bs.out_offset, block, len); + state.bs.out_offset += len; + } + state.bs.bits_sent += (ulg)len<<3; +} + + + + + + + + +/* =========================================================================== + * Prototypes for functions. + */ + +void fill_window (TState &state); +ulg deflate_fast (TState &state); + +int longest_match (TState &state,IPos cur_match); + + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(h,c) (h = (((h)< 0 if the input file is already read or + * mmap'ed in the window[] array, 0 otherwise. In the first case, + * window_size is sufficient to contain the whole input file plus + * MIN_LOOKAHEAD bytes (to avoid referencing memory beyond the end + * of window[] when looking for matches towards the end). + */ +void lm_init (TState &state, int pack_level, ush *flags) +{ + register unsigned j; + + Assert(state,pack_level>=1 && pack_level<=8,"bad pack level"); + + /* Do not slide the window if the whole input is already in memory + * (window_size > 0) + */ + state.ds.sliding = 0; + if (state.ds.window_size == 0L) { + state.ds.sliding = 1; + state.ds.window_size = (ulg)2L*WSIZE; + } + + /* Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ + state.ds.head[HASH_SIZE-1] = NIL; + memset((char*)state.ds.head, NIL, (unsigned)(HASH_SIZE-1)*sizeof(*state.ds.head)); + + /* Set the default configuration parameters: + */ + state.ds.max_lazy_match = configuration_table[pack_level].max_lazy; + state.ds.good_match = configuration_table[pack_level].good_length; + state.ds.nice_match = configuration_table[pack_level].nice_length; + state.ds.max_chain_length = configuration_table[pack_level].max_chain; + if (pack_level <= 2) { + *flags |= FAST; + } else if (pack_level >= 8) { + *flags |= SLOW; + } + /* ??? reduce max_chain_length for binary files */ + + state.ds.strstart = 0; + state.ds.block_start = 0L; + + j = WSIZE; + j <<= 1; // Can read 64K in one step + state.ds.lookahead = state.readfunc(state, (char*)state.ds.window, j); + + if (state.ds.lookahead == 0 || state.ds.lookahead == (unsigned)EOF) { + state.ds.eofile = 1, state.ds.lookahead = 0; + return; + } + state.ds.eofile = 0; + /* Make sure that we always have enough lookahead. This is important + * if input comes from a device such as a tty. + */ + if (state.ds.lookahead < MIN_LOOKAHEAD) fill_window(state); + + state.ds.ins_h = 0; + for (j=0; j= 1 + */ +// For 80x86 and 680x0 and ARM, an optimized version is in match.asm or +// match.S. The code is functionally equivalent, so you can use the C version +// if desired. Which I do so desire! +int longest_match(TState &state,IPos cur_match) +{ + unsigned chain_length = state.ds.max_chain_length; /* max hash chain length */ + register uch far *scan = state.ds.window + state.ds.strstart; /* current string */ + register uch far *match; /* matched string */ + register int len; /* length of current match */ + int best_len = state.ds.prev_length; /* best match length so far */ + IPos limit = state.ds.strstart > (IPos)MAX_DIST ? state.ds.strstart - (IPos)MAX_DIST : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + + // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + // It is easy to get rid of this optimization if necessary. + Assert(state,HASH_BITS>=8 && MAX_MATCH==258,"Code too clever"); + + + + register uch far *strend = state.ds.window + state.ds.strstart + MAX_MATCH; + register uch scan_end1 = scan[best_len-1]; + register uch scan_end = scan[best_len]; + + /* Do not waste too much time if we already have a good match: */ + if (state.ds.prev_length >= state.ds.good_match) { + chain_length >>= 2; + } + + Assert(state,state.ds.strstart <= state.ds.window_size-MIN_LOOKAHEAD, "insufficient lookahead"); + + do { + Assert(state,cur_match < state.ds.strstart, "no future"); + match = state.ds.window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(state,scan <= state.ds.window+(unsigned)(state.ds.window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + + + if (len > best_len) { + state.ds.match_start = cur_match; + best_len = len; + if (len >= state.ds.nice_match) break; + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; + } + } while ((cur_match = state.ds.prev[cur_match & WMASK]) > limit + && --chain_length != 0); + + return best_len; +} + + + +#define check_match(state,start, match, length) +// or alternatively... +//void check_match(TState &state,IPos start, IPos match, int length) +//{ // check that the match is indeed a match +// if (memcmp((char*)state.ds.window + match, +// (char*)state.ds.window + start, length) != EQUAL) { +// fprintf(stderr, +// " start %d, match %d, length %d\n", +// start, match, length); +// error("invalid match"); +// } +// if (state.verbose > 1) { +// fprintf(stderr,"\\[%d,%d]", start-match, length); +// do { fprintf(stdout,"%c",state.ds.window[start++]); } while (--length != 0); +// } +//} + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead, and sets eofile if end of input file. + * + * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0 + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or eofile is set; file reads are + * performed for at least two bytes (required for the translate_eol option). + */ +void fill_window(TState &state) +{ + register unsigned n, m; + unsigned more; /* Amount of free space at the end of the window. */ + + do { + more = (unsigned)(state.ds.window_size - (ulg)state.ds.lookahead - (ulg)state.ds.strstart); + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (more == (unsigned)EOF) { + /* Very unlikely, but possible on 16 bit machine if strstart == 0 + * and lookahead == 1 (input done one byte at time) + */ + more--; + + /* For MMAP or BIG_MEM, the whole input file is already in memory so + * we must not perform sliding. We must however call (*read_buf)() in + * order to compute the crc, update lookahead and possibly set eofile. + */ + } else if (state.ds.strstart >= WSIZE+MAX_DIST && state.ds.sliding) { + + /* By the IN assertion, the window is not empty so we can't confuse + * more == 0 with more == 64K on a 16 bit machine. + */ + memcpy((char*)state.ds.window, (char*)state.ds.window+WSIZE, (unsigned)WSIZE); + state.ds.match_start -= WSIZE; + state.ds.strstart -= WSIZE; /* we now have strstart >= MAX_DIST: */ + + state.ds.block_start -= (long) WSIZE; + + for (n = 0; n < HASH_SIZE; n++) { + m = state.ds.head[n]; + state.ds.head[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL); + } + for (n = 0; n < WSIZE; n++) { + m = state.ds.prev[n]; + state.ds.prev[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } + more += WSIZE; + } + if (state.ds.eofile) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the MMAP or BIG_MEM case (not yet supported in gzip), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(state,more >= 2, "more < 2"); + + n = state.readfunc(state, (char*)state.ds.window+state.ds.strstart+state.ds.lookahead, more); + + if (n == 0 || n == (unsigned)EOF) { + state.ds.eofile = 1; + } else { + state.ds.lookahead += n; + } + } while (state.ds.lookahead < MIN_LOOKAHEAD && !state.ds.eofile); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK(state,eof) \ + flush_block(state,state.ds.block_start >= 0L ? (char*)&state.ds.window[(unsigned)state.ds.block_start] : \ + (char*)NULL, (long)state.ds.strstart - state.ds.block_start, (eof)) + +/* =========================================================================== + * Processes a new input file and return its compressed length. This + * function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +ulg deflate_fast(TState &state) +{ + IPos hash_head = NIL; /* head of the hash chain */ + int flush; /* set if current block must be flushed */ + unsigned match_length = 0; /* length of best match */ + + state.ds.prev_length = MIN_MATCH-1; + while (state.ds.lookahead != 0) { + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (state.ds.lookahead >= MIN_MATCH) + INSERT_STRING(state.ds.strstart, hash_head); + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && state.ds.strstart - hash_head <= MAX_DIST) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + /* Do not look for matches beyond the end of the input. + * This is necessary to make deflate deterministic. + */ + if ((unsigned)state.ds.nice_match > state.ds.lookahead) state.ds.nice_match = (int)state.ds.lookahead; + match_length = longest_match (state,hash_head); + /* longest_match() sets match_start */ + if (match_length > state.ds.lookahead) match_length = state.ds.lookahead; + } + if (match_length >= MIN_MATCH) { + check_match(state,state.ds.strstart, state.ds.match_start, match_length); + + flush = ct_tally(state,state.ds.strstart-state.ds.match_start, match_length - MIN_MATCH); + + state.ds.lookahead -= match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (match_length <= state.ds.max_insert_length + && state.ds.lookahead >= MIN_MATCH) { + match_length--; /* string at strstart already in hash table */ + do { + state.ds.strstart++; + INSERT_STRING(state.ds.strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--match_length != 0); + state.ds.strstart++; + } else { + state.ds.strstart += match_length; + match_length = 0; + state.ds.ins_h = state.ds.window[state.ds.strstart]; + UPDATE_HASH(state.ds.ins_h, state.ds.window[state.ds.strstart+1]); + Assert(state,MIN_MATCH==3,"Call UPDATE_HASH() MIN_MATCH-3 more times"); + } + } else { + /* No match, output a literal byte */ + flush = ct_tally (state,0, state.ds.window[state.ds.strstart]); + state.ds.lookahead--; + state.ds.strstart++; + } + if (flush) FLUSH_BLOCK(state,0), state.ds.block_start = state.ds.strstart; + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (state.ds.lookahead < MIN_LOOKAHEAD) fill_window(state); + } + return FLUSH_BLOCK(state,1); /* eof */ +} + +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +ulg deflate(TState &state) +{ + IPos hash_head = NIL; /* head of hash chain */ + IPos prev_match; /* previous match */ + int flush; /* set if current block must be flushed */ + int match_available = 0; /* set if previous match exists */ + register unsigned match_length = MIN_MATCH-1; /* length of best match */ + + if (state.level <= 3) return deflate_fast(state); /* optimized for speed */ + + /* Process the input block. */ + while (state.ds.lookahead != 0) { + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (state.ds.lookahead >= MIN_MATCH) + INSERT_STRING(state.ds.strstart, hash_head); + + /* Find the longest match, discarding those <= prev_length. + */ + state.ds.prev_length = match_length, prev_match = state.ds.match_start; + match_length = MIN_MATCH-1; + + if (hash_head != NIL && state.ds.prev_length < state.ds.max_lazy_match && + state.ds.strstart - hash_head <= MAX_DIST) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + /* Do not look for matches beyond the end of the input. + * This is necessary to make deflate deterministic. + */ + if ((unsigned)state.ds.nice_match > state.ds.lookahead) state.ds.nice_match = (int)state.ds.lookahead; + match_length = longest_match (state,hash_head); + /* longest_match() sets match_start */ + if (match_length > state.ds.lookahead) match_length = state.ds.lookahead; + + /* Ignore a length 3 match if it is too distant: */ + if (match_length == MIN_MATCH && state.ds.strstart-state.ds.match_start > TOO_FAR){ + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (state.ds.prev_length >= MIN_MATCH && match_length <= state.ds.prev_length) { + unsigned max_insert = state.ds.strstart + state.ds.lookahead - MIN_MATCH; + check_match(state,state.ds.strstart-1, prev_match, state.ds.prev_length); + flush = ct_tally(state,state.ds.strstart-1-prev_match, state.ds.prev_length - MIN_MATCH); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. + */ + state.ds.lookahead -= state.ds.prev_length-1; + state.ds.prev_length -= 2; + do { + if (++state.ds.strstart <= max_insert) { + INSERT_STRING(state.ds.strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } + } while (--state.ds.prev_length != 0); + state.ds.strstart++; + match_available = 0; + match_length = MIN_MATCH-1; + + if (flush) FLUSH_BLOCK(state,0), state.ds.block_start = state.ds.strstart; + + } else if (match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + if (ct_tally (state,0, state.ds.window[state.ds.strstart-1])) { + FLUSH_BLOCK(state,0), state.ds.block_start = state.ds.strstart; + } + state.ds.strstart++; + state.ds.lookahead--; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + match_available = 1; + state.ds.strstart++; + state.ds.lookahead--; + } +// Assert(state,strstart <= isize && lookahead <= isize, "a bit too far"); + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (state.ds.lookahead < MIN_LOOKAHEAD) fill_window(state); + } + if (match_available) ct_tally (state,0, state.ds.window[state.ds.strstart-1]); + + return FLUSH_BLOCK(state,1); /* eof */ +} + + + + + + + + + + + + +int putlocal(struct zlist far *z, WRITEFUNC wfunc,void *param) +{ // Write a local header described by *z to file *f. Return a ZE_ error code. + PUTLG(LOCSIG, f); + PUTSH(z->ver, f); + PUTSH(z->lflg, f); + PUTSH(z->how, f); + PUTLG(z->tim, f); + PUTLG(z->crc, f); + PUTLG(z->siz, f); + PUTLG(z->len, f); + PUTSH(z->nam, f); + PUTSH(z->ext, f); + size_t res = (size_t)wfunc(param, z->iname, (unsigned int)z->nam); + if (res!=z->nam) return ZE_TEMP; + if (z->ext) + { res = (size_t)wfunc(param, z->extra, (unsigned int)z->ext); + if (res!=z->ext) return ZE_TEMP; + } + return ZE_OK; +} + +int putextended(struct zlist far *z, WRITEFUNC wfunc, void *param) +{ // Write an extended local header described by *z to file *f. Returns a ZE_ code + PUTLG(EXTLOCSIG, f); + PUTLG(z->crc, f); + PUTLG(z->siz, f); + PUTLG(z->len, f); + return ZE_OK; +} + +int putcentral(struct zlist far *z, WRITEFUNC wfunc, void *param) +{ // Write a central header entry of *z to file *f. Returns a ZE_ code. + PUTLG(CENSIG, f); + PUTSH(z->vem, f); + PUTSH(z->ver, f); + PUTSH(z->flg, f); + PUTSH(z->how, f); + PUTLG(z->tim, f); + PUTLG(z->crc, f); + PUTLG(z->siz, f); + PUTLG(z->len, f); + PUTSH(z->nam, f); + PUTSH(z->cext, f); + PUTSH(z->com, f); + PUTSH(z->dsk, f); + PUTSH(z->att, f); + PUTLG(z->atx, f); + PUTLG(z->off, f); + if ((size_t)wfunc(param, z->iname, (unsigned int)z->nam) != z->nam || + (z->cext && (size_t)wfunc(param, z->cextra, (unsigned int)z->cext) != z->cext) || + (z->com && (size_t)wfunc(param, z->comment, (unsigned int)z->com) != z->com)) + return ZE_TEMP; + return ZE_OK; +} + + +int putend(int n, ulg s, ulg c, extent m, char *z, WRITEFUNC wfunc, void *param) +{ // write the end of the central-directory-data to file *f. + PUTLG(ENDSIG, f); + PUTSH(0, f); + PUTSH(0, f); + PUTSH(n, f); + PUTSH(n, f); + PUTLG(s, f); + PUTLG(c, f); + PUTSH(m, f); + // Write the comment, if any + if (m && wfunc(param, z, (unsigned int)m) != m) return ZE_TEMP; + return ZE_OK; +} + + + + + + +const ulg crc_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +#define CRC32(c, b) (crc_table[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8)) +#define DO1(buf) crc = CRC32(crc, *buf++) +#define DO2(buf) DO1(buf); DO1(buf) +#define DO4(buf) DO2(buf); DO2(buf) +#define DO8(buf) DO4(buf); DO4(buf) + +ulg crc32(ulg crc, const uch *buf, extent len) +{ if (buf==NULL) return 0L; + crc = crc ^ 0xffffffffL; + while (len >= 8) {DO8(buf); len -= 8;} + if (len) do {DO1(buf);} while (--len); + return crc ^ 0xffffffffL; // (instead of ~c for 64-bit machines) +} + + + + + + + + +bool HasZipSuffix(const char *fn) +{ const char *ext = fn+strlen(fn); + while (ext>fn && *ext!='.') ext--; + if (ext==fn && *ext!='.') return false; + if (_stricmp(ext,".Z")==0) return true; + if (_stricmp(ext,".zip")==0) return true; + if (_stricmp(ext,".zoo")==0) return true; + if (_stricmp(ext,".arc")==0) return true; + if (_stricmp(ext,".lzh")==0) return true; + if (_stricmp(ext,".arj")==0) return true; + if (_stricmp(ext,".gz")==0) return true; + if (_stricmp(ext,".tgz")==0) return true; + return false; +} + +#ifdef _WIN32 +time_t filetime2timet(const FILETIME ft) +{ SYSTEMTIME st; FileTimeToSystemTime(&ft,&st); + if (st.wYear<1970) {st.wYear=1970; st.wMonth=1; st.wDay=1;} + if (st.wYear>=2038) {st.wYear=2037; st.wMonth=12; st.wDay=31;} + struct tm tm; + tm.tm_sec = st.wSecond; + tm.tm_min = st.wMinute; + tm.tm_hour = st.wHour; + tm.tm_mday = st.wDay; + tm.tm_mon = st.wMonth-1; + tm.tm_year = st.wYear-1900; + tm.tm_isdst = 0; + time_t t = mktime(&tm); + return t; +} + +ZRESULT GetFileInfo(HANDLE hf, ulg *attr, long *size, iztimes *times, ulg *timestamp) +{ + DWORD type=GetFileType(hf); + if (type!=FILE_TYPE_DISK) + return ZR_NOTINITED; + // The handle must be a handle to a file + // The date and time is returned in a long with the date most significant to allow + // unsigned integer comparison of absolute times. The attributes have two + // high bytes unix attr, and two low bytes a mapping of that to DOS attr. + //struct stat s; int res=stat(fn,&s); if (res!=0) return false; + // translate windows file attributes into zip ones. + BY_HANDLE_FILE_INFORMATION bhi; + BOOL res=GetFileInformationByHandle(hf,&bhi); + if (!res) + return ZR_NOFILE; + FileTimeToLocalFileTime( &bhi.ftLastAccessTime, &bhi.ftLastAccessTime ); + FileTimeToLocalFileTime( &bhi.ftLastWriteTime, &bhi.ftLastWriteTime ); + FileTimeToLocalFileTime( &bhi.ftCreationTime, &bhi.ftCreationTime ); + DWORD fa=bhi.dwFileAttributes; + ulg a=0; + // Zip uses the lower word for its interpretation of windows stuff + if (fa&FILE_ATTRIBUTE_READONLY) a|=0x01; + if (fa&FILE_ATTRIBUTE_HIDDEN) a|=0x02; + if (fa&FILE_ATTRIBUTE_SYSTEM) a|=0x04; + if (fa&FILE_ATTRIBUTE_DIRECTORY)a|=0x10; + if (fa&FILE_ATTRIBUTE_ARCHIVE) a|=0x20; + // It uses the upper word for standard unix attr, which we must manually construct + if (fa&FILE_ATTRIBUTE_DIRECTORY)a|=0x40000000; // directory + else a|=0x80000000; // normal file + a|=0x01000000; // readable + if (fa&FILE_ATTRIBUTE_READONLY) {} + else a|=0x00800000; // writeable + // now just a small heuristic to check if it's an executable: + DWORD red, hsize=GetFileSize(hf,NULL); if (hsize>40) + { SetFilePointer(hf,0,NULL,FILE_BEGIN); unsigned short magic; ReadFile(hf,&magic,sizeof(magic),&red,NULL); + SetFilePointer(hf,36,NULL,FILE_BEGIN); unsigned long hpos; ReadFile(hf,&hpos,sizeof(hpos),&red,NULL); + if (magic==0x54AD && hsize>hpos+4+20+28) + { SetFilePointer(hf,hpos,NULL,FILE_BEGIN); unsigned long signature; ReadFile(hf,&signature,sizeof(signature),&red,NULL); + if (signature==IMAGE_DOS_SIGNATURE || signature==IMAGE_OS2_SIGNATURE + || signature==IMAGE_OS2_SIGNATURE_LE || signature==IMAGE_NT_SIGNATURE) + { a |= 0x00400000; // executable + } + } + } + // + if (attr!=NULL) *attr = a; + if (size!=NULL) *size = hsize; + if (times!=NULL) + { // time_t is 32bit number of seconds elapsed since 0:0:0GMT, Jan1, 1970. + // but FILETIME is 64bit number of 100-nanosecs since Jan1, 1601 + times->atime = filetime2timet(bhi.ftLastAccessTime); + times->mtime = filetime2timet(bhi.ftLastWriteTime); + times->ctime = filetime2timet(bhi.ftCreationTime); + } + if (timestamp!=NULL) + { WORD dosdate,dostime; + FileTimeToDosDateTime(&bhi.ftLastWriteTime,&dosdate,&dostime); + *timestamp = (WORD)dostime | (((DWORD)dosdate)<<16); + } + return ZR_OK; +} +#endif + +#ifndef _WIN32 +int timet_to_timestamp( time_t time ) +{ + struct tm *tm; + tm = localtime( &time ); + if ( !tm ) + return 0; + + int date = 0; + + date |= ( ( ( tm->tm_year & 0x7f ) + ( 1900 - 1980 ) ) << 9 ); + date |= ( ( ( tm->tm_mon & 0x0f ) + 1 ) << 5 ); + date |= ( ( ( tm->tm_mday & 0x1f ) ) ); + + int timepart = 0; + + timepart |= ( ( ( tm->tm_hour & 0x1f ) ) << 11 ); + timepart |= ( ( ( tm->tm_min & 0x3f ) ) << 5 ); + timepart |= ( ( ( tm->tm_sec & 0x3e ) ) >> 1 ); + + return time | (date << 16 ); +} +#endif + + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +class TZip +{ public: + TZip() : hfout(0),hmapout(0),zfis(0),obuf(0),hfin(0),writ(0),oerr(false),hasputcen(false),ooffset(0) {} + ~TZip() {} + + // These variables say about the file we're writing into + // We can write to pipe, file-by-handle, file-by-name, memory-to-memmapfile + HANDLE hfout; // if valid, we'll write here (for files or pipes) + HANDLE hmapout; // otherwise, we'll write here (for memmap) + unsigned ooffset; // for hfout, this is where the pointer was initially + ZRESULT oerr; // did a write operation give rise to an error? + unsigned writ; // how far have we written. This is maintained by Add, not write(), to avoid confusion over seeks + bool ocanseek; // can we seek? + char *obuf; // this is where we've locked mmap to view. + unsigned int opos; // current pos in the mmap + unsigned int mapsize; // the size of the map we created + bool hasputcen; // have we yet placed the central directory? + // + TZipFileInfo *zfis; // each file gets added onto this list, for writing the table at the end + + ZRESULT Create(void *z,unsigned int len,DWORD flags); + static unsigned sflush(void *param,const char *buf, unsigned *size); + static unsigned swrite(void *param,const char *buf, unsigned size); + unsigned int write(const char *buf,unsigned int size); + bool oseek(unsigned int pos); + ZRESULT GetMemory(void **pbuf, unsigned long *plen); + ZRESULT Close(); + + // some variables to do with the file currently being read: + // I haven't done it object-orientedly here, just put them all + // together, since OO didn't seem to make the design any clearer. + ulg attr; iztimes times; ulg timestamp; // all open_* methods set these + bool iseekable; long isize,ired; // size is not set until close() on pips + ulg crc; // crc is not set until close(). iwrit is cumulative + HANDLE hfin; bool selfclosehf; // for input files and pipes + const char *bufin; unsigned int lenin,posin; // for memory + // and a variable for what we've done with the input: (i.e. compressed it!) + ulg csize; // compressed size, set by the compression routines + // and this is used by some of the compression routines + char buf[16384]; + + + ZRESULT open_file(const TCHAR *fn); + ZRESULT open_handle(HANDLE hf,unsigned int len); + ZRESULT open_mem(void *src,unsigned int len); + ZRESULT open_dir(); + static unsigned sread(TState &s,char *buf,unsigned size); + unsigned read(char *buf, unsigned size); + ZRESULT iclose(); + + ZRESULT ideflate(TZipFileInfo *zfi); + ZRESULT istore(); + + ZRESULT Add(const char *odstzn, void *src,unsigned int len, DWORD flags); + ZRESULT AddCentral(); + +}; + +ZRESULT TZip::Create(void *z,unsigned int len,DWORD flags) +{ + if (hfout!=0 || hmapout!=0 || obuf!=0 || writ!=0 || oerr!=ZR_OK || hasputcen) + return ZR_NOTINITED; + // + if (flags==ZIP_MEMORY) + { + if (len==0) + return ZR_MEMSIZE; + if (z!=0) + obuf=(char*)z; + else + { +#ifdef _WIN32 + hmapout = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,len,NULL); + if (hmapout==NULL) + return ZR_NOALLOC; + obuf = (char*)MapViewOfFile(hmapout,FILE_MAP_ALL_ACCESS,0,0,len); + if (obuf==0) + { + CloseHandle(hmapout); + hmapout=0; + return ZR_NOALLOC; + } +#endif +#ifdef POSIX + obuf = (char*) calloc( len, 1 ); + hmapout = (void*)-1; // sentinel to let close know it's a file in posix. + if ( !obuf ) + return ZR_NOALLOC; +#endif + } + ocanseek=true; + opos=0; + mapsize=len; + return ZR_OK; + } +#ifdef _WIN32 + else if (flags==ZIP_HANDLE) + { + HANDLE hf = (HANDLE)z; + BOOL res = DuplicateHandle(GetCurrentProcess(),hf,GetCurrentProcess(),&hfout,0,FALSE,DUPLICATE_SAME_ACCESS); + if (!res) + return ZR_NODUPH; + // now we have our own hfout, which we must close. And the caller will close hf + DWORD type = GetFileType(hfout); + ocanseek = (type==FILE_TYPE_DISK); + if (type==FILE_TYPE_DISK) + ooffset=SetFilePointer(hfout,0,NULL,FILE_CURRENT); + else + ooffset=0; + return ZR_OK; + } + else if (flags==ZIP_FILENAME) + { +#ifdef _UNICODE + const TCHAR *fn = (const TCHAR*)z; + hfout = CreateFileW(fn,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); +#else + const char *fn = (const char*)z; + hfout = CreateFileA(fn,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); +#endif + + if (hfout==INVALID_HANDLE_VALUE) + { + hfout=0; + return ZR_NOFILE; + } + ocanseek=true; + ooffset=0; + return ZR_OK; + } +#endif + else + return ZR_ARGS; +} + + +unsigned TZip::sflush(void *param,const char *buf, unsigned *size) +{ // static + if (*size==0) return 0; + TZip *zip = (TZip*)param; + unsigned int writ = zip->write(buf,*size); + if (writ!=0) *size=0; + return writ; +} +unsigned TZip::swrite(void *param,const char *buf, unsigned size) +{ // static + if (size==0) return 0; + TZip *zip=(TZip*)param; return zip->write(buf,size); +} +unsigned int TZip::write(const char *buf,unsigned int size) +{ if (obuf!=0) + { if (opos+size>=mapsize) {oerr=ZR_MEMSIZE; return 0;} + memcpy(obuf+opos, buf, size); + opos+=size; + return size; + } +#ifdef _WIN32 + else if (hfout!=0) + { DWORD writ; WriteFile(hfout,buf,size,&writ,NULL); + return writ; + } +#endif + oerr=ZR_NOTINITED; return 0; +} + +bool TZip::oseek(unsigned int pos) +{ if (!ocanseek) {oerr=ZR_SEEK; return false;} + if (obuf!=0) + { if (pos>=mapsize) {oerr=ZR_MEMSIZE; return false;} + opos=pos; + return true; + } +#ifdef _WIN32 + else if (hfout!=0) + { SetFilePointer(hfout,pos+ooffset,NULL,FILE_BEGIN); + return true; + } +#endif + oerr=ZR_NOTINITED; return 0; +} + +ZRESULT TZip::GetMemory(void **pbuf, unsigned long *plen) +{ // When the user calls GetMemory, they're presumably at the end + // of all their adding. In any case, we have to add the central + // directory now, otherwise the memory we tell them won't be complete. + if (!hasputcen) AddCentral(); hasputcen=true; + if (pbuf!=NULL) *pbuf=(void*)obuf; + if (plen!=NULL) *plen=writ; + if (obuf==NULL) return ZR_NOTMMAP; + return ZR_OK; +} + +ZRESULT TZip::Close() +{ // if the directory hadn't already been added through a call to GetMemory, + // then we do it now + ZRESULT res=ZR_OK; if (!hasputcen) res=AddCentral(); hasputcen=true; + if (obuf!=0 && hmapout!=0) +#ifdef _WIN32 + UnmapViewOfFile(obuf); +#elif defined( POSIX ) + free(obuf); +#endif + obuf=0; +#ifdef _WIN32 + if (hmapout!=0) CloseHandle(hmapout); hmapout=0; + if (hfout!=0) CloseHandle(hfout); hfout=0; +#endif + return res; +} + + + + +ZRESULT TZip::open_file(const TCHAR *fn) +{ hfin=0; bufin=0; selfclosehf=false; crc=CRCVAL_INITIAL; isize=0; csize=0; ired=0; + if (fn==0) return ZR_ARGS; + HANDLE hf = INVALID_HANDLE_VALUE; +#ifdef _WIN32 + hf = CreateFile(fn,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL); +#endif + if (hf==INVALID_HANDLE_VALUE) return ZR_NOFILE; + ZRESULT res = open_handle(hf,0); + if (res!=ZR_OK) { +#ifdef _WIN32 + CloseHandle(hf); +#endif + return res; + } + selfclosehf=true; + return ZR_OK; +} +ZRESULT TZip::open_handle(HANDLE hf,unsigned int len) +{ hfin=0; bufin=0; selfclosehf=false; crc=CRCVAL_INITIAL; isize=0; csize=0; ired=0; + if (hf==0 || hf==INVALID_HANDLE_VALUE) return ZR_ARGS; +#ifdef _WIN32 + DWORD type = GetFileType(hf); + if (type==FILE_TYPE_DISK) + { ZRESULT res = GetFileInfo(hf,&attr,&isize,×,×tamp); + if (res!=ZR_OK) return res; + SetFilePointer(hf,0,NULL,FILE_BEGIN); // because GetFileInfo will have screwed it up + iseekable=true; hfin=hf; + return ZR_OK; + } + else + { attr= 0x80000000; // just a normal file + isize = -1; // can't know size until at the end + if (len!=0) isize=len; // unless we were told explicitly! + iseekable=false; + SYSTEMTIME st; GetLocalTime(&st); + FILETIME ft; SystemTimeToFileTime(&st,&ft); + WORD dosdate,dostime; FileTimeToDosDateTime(&ft,&dosdate,&dostime); + times.atime = filetime2timet(ft); + times.mtime = times.atime; + times.ctime = times.atime; + timestamp = (WORD)dostime | (((DWORD)dosdate)<<16); + hfin=hf; + return ZR_OK; + } +#else + return ZR_FAILED; +#endif +} + +ZRESULT TZip::open_mem(void *src,unsigned int len) +{ hfin=0; bufin=(const char*)src; selfclosehf=false; crc=CRCVAL_INITIAL; ired=0; csize=0; ired=0; + lenin=len; posin=0; + if (src==0 || len==0) return ZR_ARGS; +#ifdef _WIN32 + attr= 0x80000000; // just a normal file + isize = len; + iseekable=true; + SYSTEMTIME st; GetLocalTime(&st); + FILETIME ft; SystemTimeToFileTime(&st,&ft); + WORD dosdate,dostime; FileTimeToDosDateTime(&ft,&dosdate,&dostime); + times.atime = filetime2timet(ft); + times.mtime = times.atime; + times.ctime = times.atime; + timestamp = (WORD)dostime | (((DWORD)dosdate)<<16); + return ZR_OK; +#else + times.atime = time(NULL); + times.mtime = times.atime; + times.ctime = times.atime; + timestamp = timet_to_timestamp( times.atime ); + return ZR_OK; +#endif +} + +ZRESULT TZip::open_dir() +{ hfin=0; bufin=0; selfclosehf=false; crc=CRCVAL_INITIAL; isize=0; csize=0; ired=0; +#ifdef _WIN32 + attr= 0x41C00010; // a readable writable directory, and again directory + isize = 0; + iseekable=false; + SYSTEMTIME st; GetLocalTime(&st); + FILETIME ft; SystemTimeToFileTime(&st,&ft); + WORD dosdate,dostime; FileTimeToDosDateTime(&ft,&dosdate,&dostime); + times.atime = filetime2timet(ft); + times.mtime = times.atime; + times.ctime = times.atime; + timestamp = (WORD)dostime | (((DWORD)dosdate)<<16); + return ZR_OK; +#else + times.atime = time(NULL); + times.mtime = times.atime; + times.ctime = times.atime; + timestamp = timet_to_timestamp( times.atime ); + return ZR_OK; +#endif +} + +unsigned TZip::sread(TState &s,char *buf,unsigned size) +{ // static + TZip *zip = (TZip*)s.param; + return zip->read(buf,size); +} + +unsigned TZip::read(char *buf, unsigned size) +{ if (bufin!=0) + { if (posin>=lenin) return 0; // end of input + ulg red = lenin-posin; + if (red>size) red=size; + memcpy(buf, bufin+posin, red); + posin += red; + ired += red; + crc = crc32(crc, (uch*)buf, red); + return red; + } +#ifdef _WIN32 + else if (hfin!=0) + { DWORD red; + BOOL ok = ReadFile(hfin,buf,size,&red,NULL); + if (!ok) return 0; + ired += red; + crc = crc32(crc, (uch*)buf, red); + return red; + } +#endif + else {oerr=ZR_NOTINITED; return 0;} +} + +ZRESULT TZip::iclose() +{ +#ifdef _WIN32 + if (selfclosehf && hfin!=0) CloseHandle(hfin); +#endif + hfin=0; + bool mismatch = (isize!=-1 && isize!=ired); + isize=ired; // and crc has been being updated anyway + if (mismatch) return ZR_MISSIZE; + else return ZR_OK; +} + + + +ZRESULT TZip::ideflate(TZipFileInfo *zfi) +{ TState state; + state.readfunc=sread; state.flush_outbuf=sflush; + state.param=this; state.level=8; state.seekable=iseekable; state.err=NULL; + // the following line will make ct_init realise it has to perform the init + state.ts.static_dtree[0].dl.len = 0; + // It would be nicer if I could figure out precisely which data had to + // be initted each time, and which didn't, but that's kind of difficult. + // Maybe for the next version... + // + bi_init(state,buf, sizeof(buf), TRUE); // it used to be just 1024-size, not 16384 as here + ct_init(state,&zfi->att); + lm_init(state,state.level, &zfi->flg); + ulg sz = deflate(state); + csize=sz; + if (state.err!=NULL) return ZR_FLATE; + else return ZR_OK; +} + +ZRESULT TZip::istore() +{ ulg size=0; + for (;;) + { unsigned int cin=read(buf,16384); if (cin<=0 || cin==(unsigned int)EOF) break; + unsigned int cout = write(buf,cin); if (cout!=cin) return ZR_MISSIZE; + size += cin; + } + csize=size; + return ZR_OK; +} + + + + +ZRESULT TZip::Add(const char *odstzn, void *src,unsigned int len, DWORD flags) +{ + if (oerr) + return ZR_FAILED; + if (hasputcen) + return ZR_ENDED; + + // zip has its own notion of what its names should look like: i.e. dir/file.stuff + char dstzn[MAX_PATH]; + strcpy(dstzn, odstzn); + if (*dstzn == 0) + return ZR_ARGS; + char *d=dstzn; + while (*d != 0) + { + if (*d == '\\') + *d = '/'; + d++; + } + bool isdir = (flags==ZIP_FOLDER); + bool needs_trailing_slash = (isdir && dstzn[strlen(dstzn)-1]!='/'); + int method=DEFLATE; + if (isdir || HasZipSuffix(dstzn)) + method=STORE; + + // now open whatever was our input source: + ZRESULT openres; + if (flags==ZIP_FILENAME) + openres=open_file((const TCHAR*)src); + else if (flags==ZIP_HANDLE) + openres=open_handle((HANDLE)src,len); + else if (flags==ZIP_MEMORY) + openres=open_mem(src,len); + else if (flags==ZIP_FOLDER) + openres=open_dir(); + else return ZR_ARGS; + if (openres!=ZR_OK) + return openres; + + // A zip "entry" consists of a local header (which includes the file name), + // then the compressed data, and possibly an extended local header. + + // Initialize the local header + TZipFileInfo zfi; zfi.nxt=NULL; + strcpy(zfi.name,""); + strcpy(zfi.iname,dstzn); + zfi.nam=strlen(zfi.iname); + if (needs_trailing_slash) + { + strcat(zfi.iname,"/"); + zfi.nam++; + } + strcpy(zfi.zname,""); + zfi.extra=NULL; zfi.ext=0; // extra header to go after this compressed data, and its length + zfi.cextra=NULL; zfi.cext=0; // extra header to go in the central end-of-zip directory, and its length + zfi.comment=NULL; zfi.com=0; // comment, and its length + zfi.mark = 1; + zfi.dosflag = 0; + zfi.att = (ush)BINARY; + zfi.vem = (ush)0xB17; // 0xB00 is win32 os-code. 0x17 is 23 in decimal: zip 2.3 + zfi.ver = (ush)20; // Needs PKUNZIP 2.0 to unzip it + zfi.tim = timestamp; + // Even though we write the header now, it will have to be rewritten, since we don't know compressed size or crc. + zfi.crc = 0; // to be updated later + zfi.flg = 8; // 8 means 'there is an extra header'. Assume for the moment that we need it. + zfi.lflg = zfi.flg; // to be updated later + zfi.how = (ush)method; // to be updated later + zfi.siz = (ulg)(method==STORE && isize>=0 ? isize : 0); // to be updated later + zfi.len = (ulg)(isize); // to be updated later + zfi.dsk = 0; + zfi.atx = attr; + zfi.off = writ+ooffset; // offset within file of the start of this local record + // stuff the 'times' structure into zfi.extra + char xloc[EB_L_UT_SIZE]; + zfi.extra=xloc; + zfi.ext=EB_L_UT_SIZE; + char xcen[EB_C_UT_SIZE]; + zfi.cextra=xcen; + zfi.cext=EB_C_UT_SIZE; + xloc[0] = 'U'; + xloc[1] = 'T'; + xloc[2] = EB_UT_LEN(3); // length of data part of e.f. + xloc[3] = 0; + xloc[4] = EB_UT_FL_MTIME | EB_UT_FL_ATIME | EB_UT_FL_CTIME; + xloc[5] = (char)(times.mtime); + xloc[6] = (char)(times.mtime >> 8); + xloc[7] = (char)(times.mtime >> 16); + xloc[8] = (char)(times.mtime >> 24); + xloc[9] = (char)(times.atime); + xloc[10] = (char)(times.atime >> 8); + xloc[11] = (char)(times.atime >> 16); + xloc[12] = (char)(times.atime >> 24); + xloc[13] = (char)(times.ctime); + xloc[14] = (char)(times.ctime >> 8); + xloc[15] = (char)(times.ctime >> 16); + xloc[16] = (char)(times.ctime >> 24); + memcpy(zfi.cextra,zfi.extra,EB_C_UT_SIZE); + zfi.cextra[EB_LEN] = EB_UT_LEN(1); + + + // (1) Start by writing the local header: + int r = putlocal(&zfi,swrite,this); + if (r!=ZE_OK) + { + iclose(); + return ZR_WRITE; + } + writ += 4 + LOCHEAD + (unsigned int)zfi.nam + (unsigned int)zfi.ext; + if (oerr!=ZR_OK) + { + iclose(); + return oerr; + } + + //(2) Write deflated/stored file to zip file + ZRESULT writeres=ZR_OK; + if (!isdir && method==DEFLATE) + writeres=ideflate(&zfi); + else if (!isdir && method==STORE) + writeres=istore(); + else if (isdir) + csize=0; + iclose(); + writ += csize; + if (oerr!=ZR_OK) + return oerr; + if (writeres!=ZR_OK) + return ZR_WRITE; + + // (3) Either rewrite the local header with correct information... + bool first_header_has_size_right = (zfi.siz==csize); + zfi.crc = crc; + zfi.siz = csize; + zfi.len = isize; + if (ocanseek) + { + zfi.how = (ush)method; + if ((zfi.flg & 1) == 0) + zfi.flg &= ~8; // clear the extended local header flag + zfi.lflg = zfi.flg; + // rewrite the local header: + if (!oseek(zfi.off-ooffset)) + return ZR_SEEK; + if ((r = putlocal(&zfi, swrite,this)) != ZE_OK) + return ZR_WRITE; + if (!oseek(writ)) + return ZR_SEEK; + } + else + { + // (4) ... or put an updated header at the end + if (zfi.how != (ush) method) + return ZR_NOCHANGE; + if (method==STORE && !first_header_has_size_right) + return ZR_NOCHANGE; + if ((r = putextended(&zfi, swrite,this)) != ZE_OK) + return ZR_WRITE; + writ += 16L; + zfi.flg = zfi.lflg; // if flg modified by inflate, for the central index + } + if (oerr!=ZR_OK) + return oerr; + + // Keep a copy of the zipfileinfo, for our end-of-zip directory + char *cextra = new char[zfi.cext]; + memcpy(cextra,zfi.cextra,zfi.cext); zfi.cextra=cextra; + TZipFileInfo *pzfi = new TZipFileInfo; + memcpy(pzfi,&zfi,sizeof(zfi)); + if (zfis==NULL) + zfis=pzfi; + else + { + TZipFileInfo *z=zfis; + while (z->nxt!=NULL) + z=z->nxt; + z->nxt=pzfi; + } + return ZR_OK; +} + +ZRESULT TZip::AddCentral() +{ // write central directory + int numentries = 0; + ulg pos_at_start_of_central = writ; + //ulg tot_unc_size=0, tot_compressed_size=0; + bool okay=true; + for (TZipFileInfo *zfi=zfis; zfi!=NULL; ) + { if (okay) + { int res = putcentral(zfi, swrite,this); + if (res!=ZE_OK) okay=false; + } + writ += 4 + CENHEAD + (unsigned int)zfi->nam + (unsigned int)zfi->cext + (unsigned int)zfi->com; + //tot_unc_size += zfi->len; + //tot_compressed_size += zfi->siz; + numentries++; + // + TZipFileInfo *zfinext = zfi->nxt; + if (zfi->cextra!=0) delete[] zfi->cextra; + delete zfi; + zfi = zfinext; + } + ulg center_size = writ - pos_at_start_of_central; + if (okay) + { int res = putend(numentries, center_size, pos_at_start_of_central+ooffset, 0, NULL, swrite,this); + if (res!=ZE_OK) okay=false; + writ += 4 + ENDHEAD + 0; + } + if (!okay) return ZR_WRITE; + return ZR_OK; +} + + +unsigned int FormatZipMessageZ(ZRESULT code, char *buf,unsigned int len) +{ if (code==ZR_RECENT) code=lasterrorZ; + const char *msg="unknown zip result code"; + switch (code) + { case ZR_OK: msg="Success"; break; + case ZR_NODUPH: msg="Culdn't duplicate handle"; break; + case ZR_NOFILE: msg="Couldn't create/open file"; break; + case ZR_NOALLOC: msg="Failed to allocate memory"; break; + case ZR_WRITE: msg="Error writing to file"; break; + case ZR_NOTFOUND: msg="File not found in the zipfile"; break; + case ZR_MORE: msg="Still more data to unzip"; break; + case ZR_CORRUPT: msg="Zipfile is corrupt or not a zipfile"; break; + case ZR_READ: msg="Error reading file"; break; + case ZR_ARGS: msg="Caller: faulty arguments"; break; + case ZR_PARTIALUNZ: msg="Caller: the file had already been partially unzipped"; break; + case ZR_NOTMMAP: msg="Caller: can only get memory of a memory zipfile"; break; + case ZR_MEMSIZE: msg="Caller: not enough space allocated for memory zipfile"; break; + case ZR_FAILED: msg="Caller: there was a previous error"; break; + case ZR_ENDED: msg="Caller: additions to the zip have already been ended"; break; + case ZR_ZMODE: msg="Caller: mixing creation and opening of zip"; break; + case ZR_NOTINITED: msg="Zip-bug: internal initialisation not completed"; break; + case ZR_SEEK: msg="Zip-bug: trying to seek the unseekable"; break; + case ZR_MISSIZE: msg="Zip-bug: the anticipated size turned out wrong"; break; + case ZR_NOCHANGE: msg="Zip-bug: tried to change mind, but not allowed"; break; + case ZR_FLATE: msg="Zip-bug: an internal error during flation"; break; + } + unsigned int mlen=(unsigned int)strlen(msg); + if (buf==0 || len==0) return mlen; + unsigned int n=mlen; if (n+1>len) n=len-1; + memcpy(buf,msg,n); buf[n]=0; + return mlen; +} + + + +typedef struct +{ DWORD flag; + TZip *zip; +} TZipHandleData; + + +HZIP CreateZipZ(void *z,unsigned int len,DWORD flags) +{ + _tzset(); + TZip *zip = new TZip(); + lasterrorZ = zip->Create(z,len,flags); + if (lasterrorZ != ZR_OK) + { + delete zip; + return 0; + } + TZipHandleData *han = new TZipHandleData; + han->flag = 2; + han->zip = zip; + return (HZIP)han; +} + +ZRESULT ZipAdd(HZIP hz, const TCHAR *dstzn, void *src, unsigned int len, DWORD flags) +{ + if (hz == 0) + { + lasterrorZ = ZR_ARGS; + return ZR_ARGS; + } + TZipHandleData *han = (TZipHandleData*)hz; + if (han->flag != 2) + { + lasterrorZ = ZR_ZMODE; + return ZR_ZMODE; + } + TZip *zip = han->zip; + + + if (flags == ZIP_FILENAME) + { + char szDest[MAX_PATH*2]; + memset(szDest, 0, sizeof(szDest)); + +#ifdef _UNICODE + // need to convert Unicode dest to ANSI + int nActualChars = WideCharToMultiByte(CP_ACP, // code page + 0, // performance and mapping flags + (LPCWSTR) dstzn, // wide-character string + -1, // number of chars in string + szDest, // buffer for new string + MAX_PATH*2-2, // size of buffer + NULL, // default for unmappable chars + NULL); // set when default char used + if (nActualChars == 0) + return ZR_ARGS; +#else + strcpy(szDest, dstzn); +#endif + + lasterrorZ = zip->Add(szDest, src, len, flags); + } + else + { + lasterrorZ = zip->Add((char *)dstzn, src, len, flags); + } + + return lasterrorZ; +} + +ZRESULT ZipGetMemory(HZIP hz, void **buf, unsigned long *len) +{ if (hz==0) {if (buf!=0) *buf=0; if (len!=0) *len=0; lasterrorZ=ZR_ARGS;return ZR_ARGS;} + TZipHandleData *han = (TZipHandleData*)hz; + if (han->flag!=2) {lasterrorZ=ZR_ZMODE;return ZR_ZMODE;} + TZip *zip = han->zip; + lasterrorZ = zip->GetMemory(buf,len); + return lasterrorZ; +} + +ZRESULT CloseZipZ(HZIP hz) +{ if (hz==0) {lasterrorZ=ZR_ARGS;return ZR_ARGS;} + TZipHandleData *han = (TZipHandleData*)hz; + if (han->flag!=2) {lasterrorZ=ZR_ZMODE;return ZR_ZMODE;} + TZip *zip = han->zip; + lasterrorZ = zip->Close(); + delete zip; + delete han; + return lasterrorZ; +} + +bool IsZipHandleZ(HZIP hz) +{ if (hz==0) return true; + TZipHandleData *han = (TZipHandleData*)hz; + return (han->flag==2); +} + + diff --git a/sp/src/public/appframework/AppFramework.h b/sp/src/public/appframework/AppFramework.h new file mode 100644 index 00000000..185d2f33 --- /dev/null +++ b/sp/src/public/appframework/AppFramework.h @@ -0,0 +1,158 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: An application framework +// +// $Revision: $ +// $NoKeywords: $ +//===========================================================================// + +#ifndef APPFRAMEWORK_H +#define APPFRAMEWORK_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "appframework/IAppSystemGroup.h" + + +//----------------------------------------------------------------------------- +// Gets the application instance.. +//----------------------------------------------------------------------------- +void *GetAppInstance(); + + +//----------------------------------------------------------------------------- +// Sets the application instance, should only be used if you're not calling AppMain. +//----------------------------------------------------------------------------- +void SetAppInstance( void* hInstance ); + + +//----------------------------------------------------------------------------- +// Main entry point for the application +//----------------------------------------------------------------------------- +int AppMain( void* hInstance, void* hPrevInstance, const char* lpCmdLine, int nCmdShow, CAppSystemGroup *pAppSystemGroup ); +int AppMain( int argc, char **argv, CAppSystemGroup *pAppSystemGroup ); + + +//----------------------------------------------------------------------------- +// Used to startup/shutdown the application +//----------------------------------------------------------------------------- +int AppStartup( void* hInstance, void* hPrevInstance, const char* lpCmdLine, int nCmdShow, CAppSystemGroup *pAppSystemGroup ); +int AppStartup( int argc, char **argv, CAppSystemGroup *pAppSystemGroup ); +void AppShutdown( CAppSystemGroup *pAppSystemGroup ); + + +//----------------------------------------------------------------------------- +// Macros to create singleton application objects for windowed + console apps +//----------------------------------------------------------------------------- +#if !defined( _X360 ) + +#ifdef WIN32 +#define DEFINE_WINDOWED_APPLICATION_OBJECT_GLOBALVAR( _globalVarName ) \ + int __stdcall WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) \ + { \ + return AppMain( hInstance, hPrevInstance, lpCmdLine, nCmdShow, &_globalVarName ); \ + } +#elif defined( OSX ) +#define DEFINE_WINDOWED_APPLICATION_OBJECT_GLOBALVAR( _globalVarName ) \ + int main( int argc, char **argv ) \ + { \ + extern int ValveCocoaMain( int argc, char **argv, CAppSystemGroup *pAppSystemGroup ); \ + return ValveCocoaMain( argc, argv, &_globalVarName ); \ + } +#elif defined( LINUX ) +#define DEFINE_WINDOWED_APPLICATION_OBJECT_GLOBALVAR( _globalVarName ) \ + int main( int argc, char **argv ) \ + { \ + extern int ValveLinuxWindowedMain( int argc, char **argv, CAppSystemGroup *pAppSystemGroup ); \ + return ValveLinuxWindowedMain( argc, argv, &_globalVarName ); \ + } +#else +#error +#endif + +#else +#define DEFINE_WINDOWED_APPLICATION_OBJECT_GLOBALVAR( _globalVarName ) \ + void __cdecl main() \ + { \ + AppMain( (HINSTANCE)1, (HINSTANCE)0, NULL, 0, &_globalVarName ); \ + } +#endif + +#if !defined( _X360 ) +#define DEFINE_CONSOLE_APPLICATION_OBJECT_GLOBALVAR( _globalVarName ) \ + int main( int argc, char **argv ) \ + { \ + return AppMain( argc, argv, &_globalVarName ); \ + } +#else +#define DEFINE_CONSOLE_APPLICATION_OBJECT_GLOBALVAR( _globalVarName ) \ + void __cdecl main() \ + { \ + AppMain( 0, (char**)NULL, &_globalVarName ); \ + } +#endif + +#define DEFINE_WINDOWED_APPLICATION_OBJECT( _className ) \ + static _className __s_ApplicationObject; \ + DEFINE_WINDOWED_APPLICATION_OBJECT_GLOBALVAR( __s_ApplicationObject ) + +#define DEFINE_CONSOLE_APPLICATION_OBJECT( _className ) \ + static _className __s_ApplicationObject; \ + DEFINE_CONSOLE_APPLICATION_OBJECT_GLOBALVAR( __s_ApplicationObject ) + + +//----------------------------------------------------------------------------- +// This class is a helper class used for steam-based applications. +// It loads up the file system in preparation for using it to load other +// required modules from steam. +//----------------------------------------------------------------------------- +class CSteamApplication : public CAppSystemGroup +{ + typedef CAppSystemGroup BaseClass; + +public: + CSteamApplication( CSteamAppSystemGroup *pAppSystemGroup ); + + // Implementation of IAppSystemGroup + virtual bool Create( ); + virtual bool PreInit( ); + virtual int Main( ); + virtual void PostShutdown(); + virtual void Destroy(); + + // Use this version in cases where you can't control the main loop and + // expect to be ticked + virtual int Startup(); + virtual void Shutdown(); + +protected: + IFileSystem *m_pFileSystem; + CSteamAppSystemGroup *m_pChildAppSystemGroup; + bool m_bSteam; +}; + + +//----------------------------------------------------------------------------- +// Macros to help create singleton application objects for windowed + console steam apps +//----------------------------------------------------------------------------- +#define DEFINE_WINDOWED_STEAM_APPLICATION_OBJECT_GLOBALVAR( _className, _varName ) \ + static CSteamApplication __s_SteamApplicationObject( &_varName ); \ + DEFINE_WINDOWED_APPLICATION_OBJECT_GLOBALVAR( __s_SteamApplicationObject ) + +#define DEFINE_WINDOWED_STEAM_APPLICATION_OBJECT( _className ) \ + static _className __s_ApplicationObject; \ + static CSteamApplication __s_SteamApplicationObject( &__s_ApplicationObject ); \ + DEFINE_WINDOWED_APPLICATION_OBJECT_GLOBALVAR( __s_SteamApplicationObject ) + +#define DEFINE_CONSOLE_STEAM_APPLICATION_OBJECT_GLOBALVAR( _className, _varName ) \ + static CSteamApplication __s_SteamApplicationObject( &_varName ); \ + DEFINE_CONSOLE_APPLICATION_OBJECT_GLOBALVAR( __s_SteamApplicationObject ) + +#define DEFINE_CONSOLE_STEAM_APPLICATION_OBJECT( _className ) \ + static _className __s_ApplicationObject; \ + static CSteamApplication __s_SteamApplicationObject( &__s_ApplicationObject ); \ + DEFINE_CONSOLE_APPLICATION_OBJECT_GLOBALVAR( __s_SteamApplicationObject ) + +#endif // APPFRAMEWORK_H diff --git a/sp/src/public/appframework/IAppSystem.h b/sp/src/public/appframework/IAppSystem.h new file mode 100644 index 00000000..33bcbb2e --- /dev/null +++ b/sp/src/public/appframework/IAppSystem.h @@ -0,0 +1,122 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: An application framework +// +// $Revision: $ +// $NoKeywords: $ +//=============================================================================// + +#ifndef IAPPSYSTEM_H +#define IAPPSYSTEM_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/interface.h" + + +//----------------------------------------------------------------------------- +// Client systems are singleton objects in the client codebase responsible for +// various tasks +// The order in which the client systems appear in this list are the +// order in which they are initialized and updated. They are shut down in +// reverse order from which they are initialized. +//----------------------------------------------------------------------------- + +enum InitReturnVal_t +{ + INIT_FAILED = 0, + INIT_OK, + + INIT_LAST_VAL, +}; + + +abstract_class IAppSystem +{ +public: + // Here's where the app systems get to learn about each other + virtual bool Connect( CreateInterfaceFn factory ) = 0; + virtual void Disconnect() = 0; + + // Here's where systems can access other interfaces implemented by this object + // Returns NULL if it doesn't implement the requested interface + virtual void *QueryInterface( const char *pInterfaceName ) = 0; + + // Init, shutdown + virtual InitReturnVal_t Init() = 0; + virtual void Shutdown() = 0; +}; + + +//----------------------------------------------------------------------------- +// Helper empty implementation of an IAppSystem +//----------------------------------------------------------------------------- +template< class IInterface > +class CBaseAppSystem : public IInterface +{ +public: + // Here's where the app systems get to learn about each other + virtual bool Connect( CreateInterfaceFn factory ) { return true; } + virtual void Disconnect() {} + + // Here's where systems can access other interfaces implemented by this object + // Returns NULL if it doesn't implement the requested interface + virtual void *QueryInterface( const char *pInterfaceName ) { return NULL; } + + // Init, shutdown + virtual InitReturnVal_t Init() { return INIT_OK; } + virtual void Shutdown() {} +}; + + +//----------------------------------------------------------------------------- +// Helper implementation of an IAppSystem for tier0 +//----------------------------------------------------------------------------- +template< class IInterface > +class CTier0AppSystem : public CBaseAppSystem< IInterface > +{ +public: + CTier0AppSystem( bool bIsPrimaryAppSystem = true ) + { + m_bIsPrimaryAppSystem = bIsPrimaryAppSystem; + } + +protected: + // NOTE: a single DLL may have multiple AppSystems it's trying to + // expose. If this is true, you must return true from only + // one of those AppSystems; not doing so will cause all static + // libraries connected to it to connect/disconnect multiple times + + // NOTE: We don't do this as a virtual function to avoid + // having to up the version on all interfaces + bool IsPrimaryAppSystem() { return m_bIsPrimaryAppSystem; } + +private: + bool m_bIsPrimaryAppSystem; +}; + + +//----------------------------------------------------------------------------- +// This is the version of IAppSystem shipped 10/15/04 +// NOTE: Never change this!!! +//----------------------------------------------------------------------------- +abstract_class IAppSystemV0 +{ +public: + // Here's where the app systems get to learn about each other + virtual bool Connect( CreateInterfaceFn factory ) = 0; + virtual void Disconnect() = 0; + + // Here's where systems can access other interfaces implemented by this object + // Returns NULL if it doesn't implement the requested interface + virtual void *QueryInterface( const char *pInterfaceName ) = 0; + + // Init, shutdown + virtual InitReturnVal_t Init() = 0; + virtual void Shutdown() = 0; +}; + +#endif // IAPPSYSTEM_H + diff --git a/sp/src/public/appframework/IAppSystemGroup.h b/sp/src/public/appframework/IAppSystemGroup.h new file mode 100644 index 00000000..5cc32aa8 --- /dev/null +++ b/sp/src/public/appframework/IAppSystemGroup.h @@ -0,0 +1,265 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// The copyright to the contents herein is the property of Valve, L.L.C. +// The contents may be used and/or copied only with the written permission of +// Valve, L.L.C., or in accordance with the terms and conditions stipulated in +// the agreement/contract under which the contents have been supplied. +// +// Purpose: Defines a group of app systems that all have the same lifetime +// that need to be connected/initialized, etc. in a well-defined order +// +// $Revision: $ +// $NoKeywords: $ +//============================================================================= + +#ifndef IAPPSYSTEMGROUP_H +#define IAPPSYSTEMGROUP_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "tier1/interface.h" +#include "tier1/utlvector.h" +#include "tier1/utldict.h" +#include "IAppSystem.h" + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- +class IAppSystem; +class CSysModule; +class IBaseInterface; +class IFileSystem; + +//----------------------------------------------------------------------------- +// Handle to a DLL +//----------------------------------------------------------------------------- +typedef int AppModule_t; + +enum +{ + APP_MODULE_INVALID = (AppModule_t)~0 +}; + + +//----------------------------------------------------------------------------- +// NOTE: The following methods must be implemented in your application +// although they can be empty implementations if you like... +//----------------------------------------------------------------------------- +abstract_class IAppSystemGroup +{ +public: + // An installed application creation function, you should tell the group + // the DLLs and the singleton interfaces you want to instantiate. + // Return false if there's any problems and the app will abort + virtual bool Create( ) = 0; + + // Allow the application to do some work after AppSystems are connected but + // they are all Initialized. + // Return false if there's any problems and the app will abort + virtual bool PreInit() = 0; + + // Main loop implemented by the application + virtual int Main( ) = 0; + + // Allow the application to do some work after all AppSystems are shut down + virtual void PostShutdown() = 0; + + // Call an installed application destroy function, occurring after all modules + // are unloaded + virtual void Destroy() = 0; +}; + + +//----------------------------------------------------------------------------- +// Specifies a module + interface name for initialization +//----------------------------------------------------------------------------- +struct AppSystemInfo_t +{ + const char *m_pModuleName; + const char *m_pInterfaceName; +}; + + +//----------------------------------------------------------------------------- +// This class represents a group of app systems that all have the same lifetime +// that need to be connected/initialized, etc. in a well-defined order +//----------------------------------------------------------------------------- +class CAppSystemGroup : public IAppSystemGroup +{ +public: + // Used to determine where we exited out from the system + enum AppSystemGroupStage_t + { + CREATION = 0, + CONNECTION, + PREINITIALIZATION, + INITIALIZATION, + SHUTDOWN, + POSTSHUTDOWN, + DISCONNECTION, + DESTRUCTION, + + NONE, // This means no error + }; + +public: + // constructor + CAppSystemGroup( CAppSystemGroup *pParentAppSystem = NULL ); + + // Runs the app system group. + // First, modules are loaded, next they are connected, followed by initialization + // Then Main() is run + // Then modules are shut down, disconnected, and unloaded + int Run( ); + + // Use this version in cases where you can't control the main loop and + // expect to be ticked + virtual int Startup(); + virtual void Shutdown(); + + // Returns the stage at which the app system group ran into an error + AppSystemGroupStage_t GetErrorStage() const; + +protected: + // These methods are meant to be called by derived classes of CAppSystemGroup + + // Methods to load + unload DLLs + AppModule_t LoadModule( const char *pDLLName ); + AppModule_t LoadModule( CreateInterfaceFn factory ); + + // Method to add various global singleton systems + IAppSystem *AddSystem( AppModule_t module, const char *pInterfaceName ); + void AddSystem( IAppSystem *pAppSystem, const char *pInterfaceName ); + + // Simpler method of doing the LoadModule/AddSystem thing. + // Make sure the last AppSystemInfo has a NULL module name + bool AddSystems( AppSystemInfo_t *pSystems ); + + // Method to look up a particular named system... + void *FindSystem( const char *pInterfaceName ); + + // Gets at a class factory for the topmost appsystem group in an appsystem stack + static CreateInterfaceFn GetFactory(); + +private: + int OnStartup(); + void OnShutdown(); + + void UnloadAllModules( ); + void RemoveAllSystems(); + + // Method to connect/disconnect all systems + bool ConnectSystems( ); + void DisconnectSystems(); + + // Method to initialize/shutdown all systems + InitReturnVal_t InitSystems(); + void ShutdownSystems(); + + // Gets at the parent appsystem group + CAppSystemGroup *GetParent(); + + // Loads a module the standard way + virtual CSysModule *LoadModuleDLL( const char *pDLLName ); + + void ReportStartupFailure( int nErrorStage, int nSysIndex ); + + struct Module_t + { + CSysModule *m_pModule; + CreateInterfaceFn m_Factory; + char *m_pModuleName; + }; + + CUtlVector m_Modules; + CUtlVector m_Systems; + CUtlDict m_SystemDict; + CAppSystemGroup *m_pParentAppSystem; + AppSystemGroupStage_t m_nErrorStage; + + friend void *AppSystemCreateInterfaceFn(const char *pName, int *pReturnCode); + friend class CSteamAppSystemGroup; +}; + + +//----------------------------------------------------------------------------- +// This class represents a group of app systems that are loaded through steam +//----------------------------------------------------------------------------- +class CSteamAppSystemGroup : public CAppSystemGroup +{ +public: + CSteamAppSystemGroup( IFileSystem *pFileSystem = NULL, CAppSystemGroup *pParentAppSystem = NULL ); + + // Used by CSteamApplication to set up necessary pointers if we can't do it in the constructor + void Setup( IFileSystem *pFileSystem, CAppSystemGroup *pParentAppSystem ); + +protected: + // Sets up the search paths + bool SetupSearchPaths( const char *pStartingDir, bool bOnlyUseStartingDir, bool bIsTool ); + + // Returns the game info path. Only works if you've called SetupSearchPaths first + const char *GetGameInfoPath() const; + +private: + virtual CSysModule *LoadModuleDLL( const char *pDLLName ); + + IFileSystem *m_pFileSystem; + char m_pGameInfoPath[ MAX_PATH ]; +}; + + +//----------------------------------------------------------------------------- +// Helper empty decorator implementation of an IAppSystemGroup +//----------------------------------------------------------------------------- +template< class CBaseClass > +class CDefaultAppSystemGroup : public CBaseClass +{ +public: + virtual bool Create( ) { return true; } + virtual bool PreInit() { return true; } + virtual void PostShutdown() {} + virtual void Destroy() {} +}; + + +//----------------------------------------------------------------------------- +// Special helper for game info directory suggestion +//----------------------------------------------------------------------------- + +class CFSSteamSetupInfo; // Forward declaration + +// +// SuggestGameInfoDirFn_t +// Game info suggestion function. +// Provided by the application to possibly detect the suggested game info +// directory and initialize all the game-info-related systems appropriately. +// Parameters: +// pFsSteamSetupInfo steam file system setup information if available. +// pchPathBuffer buffer to hold game info directory path on return. +// nBufferLength length of the provided buffer to hold game info directory path. +// pbBubbleDirectories should contain "true" on return to bubble the directories up searching for game info file. +// Return values: +// Returns "true" if the game info directory path suggestion is available and +// was successfully copied into the provided buffer. +// Returns "false" otherwise, interpreted that no suggestion will be used. +// +typedef bool ( * SuggestGameInfoDirFn_t ) ( CFSSteamSetupInfo const *pFsSteamSetupInfo, char *pchPathBuffer, int nBufferLength, bool *pbBubbleDirectories ); + +// +// SetSuggestGameInfoDirFn +// Installs the supplied game info directory suggestion function. +// Parameters: +// pfnNewFn the new game info directory suggestion function. +// Returns: +// The previously installed suggestion function or NULL if none was installed before. +// This function never fails. +// +SuggestGameInfoDirFn_t SetSuggestGameInfoDirFn( SuggestGameInfoDirFn_t pfnNewFn ); + + +#endif // APPSYSTEMGROUP_H + + diff --git a/sp/src/public/appframework/VguiMatSysApp.h b/sp/src/public/appframework/VguiMatSysApp.h new file mode 100644 index 00000000..e40793ea --- /dev/null +++ b/sp/src/public/appframework/VguiMatSysApp.h @@ -0,0 +1,71 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// The copyright to the contents herein is the property of Valve, L.L.C. +// The contents may be used and/or copied only with the written permission of +// Valve, L.L.C., or in accordance with the terms and conditions stipulated in +// the agreement/contract under which the contents have been supplied. +// +// $Header: $ +// $NoKeywords: $ +// +// Material editor +//============================================================================= + +#ifndef VGUIMATSYSAPP_H +#define VGUIMATSYSAPP_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "appframework/tier3app.h" + + +//----------------------------------------------------------------------------- +// The application object +//----------------------------------------------------------------------------- +class CVguiMatSysApp : public CVguiSteamApp +{ + typedef CVguiSteamApp BaseClass; + +public: + CVguiMatSysApp(); + + // Methods of IApplication + virtual bool Create(); + virtual bool PreInit(); + virtual void PostShutdown(); + virtual void Destroy(); + + // Returns the window handle (HWND in Win32) + void* GetAppWindow(); + + // Gets the window size + int GetWindowWidth() const; + int GetWindowHeight() const; + +protected: + void AppPumpMessages(); + + // Sets the video mode + bool SetVideoMode( ); + + // Sets up the game path + bool SetupSearchPaths( const char *pStartingDir, bool bOnlyUseStartingDir, bool bIsTool ); + +private: + // Returns the app name + virtual const char *GetAppName() = 0; + virtual bool AppUsesReadPixels() { return false; } + + // Creates the app window + virtual void *CreateAppWindow( char const *pTitle, bool bWindowed, int w, int h ); + + void *m_HWnd; + int m_nWidth; + int m_nHeight; +}; + + +#endif // VGUIMATSYSAPP_H diff --git a/sp/src/public/appframework/ilaunchermgr.h b/sp/src/public/appframework/ilaunchermgr.h new file mode 100644 index 00000000..2498ab36 --- /dev/null +++ b/sp/src/public/appframework/ilaunchermgr.h @@ -0,0 +1,160 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// ilaunchermgr.h +// +//================================================================================================== +#ifndef ILAUNCHERMGR_H +#define ILAUNCHERMGR_H + +#ifdef _WIN32 +#pragma once +#endif + +#if defined( USE_SDL ) + +#include "tier0/threadtools.h" +#include "appframework/IAppSystem.h" + +#if defined( DX_TO_GL_ABSTRACTION ) + #if defined( LINUX ) || defined( _WIN32 ) + #include "togl/linuxwin/glmgrbasics.h" + #include "togl/linuxwin/glmdisplay.h" + #elif defined( OSX ) + #include "togl/osx/glmgrbasics.h" + #include "togl/osx/glmdisplay.h" + #endif + +class GLMDisplayDB; +class CShowPixelsParams; +#endif + +// if you rev this version also update materialsystem/cmaterialsystem.cpp CMaterialSystem::Connect as it defines the string directly +#define SDLMGR_INTERFACE_VERSION "SDLMgrInterface001" + +class CCocoaEvent; +class CStackCrawlParams; + +typedef struct SDL_Cursor SDL_Cursor; + +class ILauncherMgr : public IAppSystem +{ +public: + virtual bool Connect( CreateInterfaceFn factory ) = 0; + virtual void Disconnect() = 0; + + virtual void *QueryInterface( const char *pInterfaceName ) = 0; + + // Init, shutdown + virtual InitReturnVal_t Init() = 0; + virtual void Shutdown() = 0; + + // Create the window. + virtual bool CreateGameWindow( const char *pTitle, bool bWindowed, int width, int height ) = 0; + + virtual void IncWindowRefCount() = 0; + virtual void DecWindowRefCount() = 0; + + // Get the next N events. The function returns the number of events that were filled into your array. + virtual int GetEvents( CCocoaEvent *pEvents, int nMaxEventsToReturn, bool debugEvents = false ) = 0; +#ifdef LINUX + virtual int PeekAndRemoveKeyboardEvents( bool *pbEsc, bool *pbReturn, bool *pbSpace, bool debugEvents = false ) = 0; +#endif + + // Set the mouse cursor position. + virtual void SetCursorPosition( int x, int y ) = 0; + + virtual void SetWindowFullScreen( bool bFullScreen, int nWidth, int nHeight ) = 0; + virtual bool IsWindowFullScreen() = 0; + virtual void MoveWindow( int x, int y ) = 0; + virtual void SizeWindow( int width, int tall ) = 0; + virtual void PumpWindowsMessageLoop() = 0; + + virtual void DestroyGameWindow() = 0; + virtual void SetApplicationIcon( const char *pchAppIconFile ) = 0; + + virtual void GetMouseDelta( int &x, int &y, bool bIgnoreNextMouseDelta = false ) = 0; + + virtual void GetNativeDisplayInfo( int nDisplay, uint &nWidth, uint &nHeight, uint &nRefreshHz ) = 0; // Retrieve the size of the monitor (desktop) + virtual void RenderedSize( uint &width, uint &height, bool set ) = 0; // either set or retrieve rendered size value (from dxabstract) + virtual void DisplayedSize( uint &width, uint &height ) = 0; // query backbuffer size (window size whether FS or windowed) + +#if defined( DX_TO_GL_ABSTRACTION ) + virtual PseudoGLContextPtr GetMainContext() = 0; + // Get the NSGLContext for a window's main view - note this is the carbon windowref as an argument + virtual PseudoGLContextPtr GetGLContextForWindow( void* windowref ) = 0; + virtual PseudoGLContextPtr CreateExtraContext() = 0; + virtual void DeleteContext( PseudoGLContextPtr hContext ) = 0; + virtual bool MakeContextCurrent( PseudoGLContextPtr hContext ) = 0; + virtual GLMDisplayDB *GetDisplayDB( void ) = 0; + virtual void GetDesiredPixelFormatAttribsAndRendererInfo( uint **ptrOut, uint *countOut, GLMRendererInfoFields *rendInfoOut ) = 0; + virtual void ShowPixels( CShowPixelsParams *params ) = 0; +#endif + + virtual void GetStackCrawl( CStackCrawlParams *params ) = 0; + + virtual void WaitUntilUserInput( int msSleepTime ) = 0; + + virtual void *GetWindowRef() = 0; + + virtual void SetMouseVisible( bool bState ) = 0; + virtual void SetMouseCursor( SDL_Cursor *hCursor ) = 0; + virtual void SetForbidMouseGrab( bool bForbidMouseGrab ) = 0; + virtual void OnFrameRendered() = 0; + + virtual void SetGammaRamp( const uint16 *pRed, const uint16 *pGreen, const uint16 *pBlue ) = 0; + + virtual double GetPrevGLSwapWindowTime() = 0; +}; + +extern ILauncherMgr *g_pLauncherMgr; + +enum CocoaEventType_t +{ + CocoaEvent_KeyDown, + CocoaEvent_KeyUp, + CocoaEvent_MouseButtonDown, + CocoaEvent_MouseMove, + CocoaEvent_MouseButtonUp, + CocoaEvent_AppActivate, + CocoaEvent_MouseScroll, + CocoaEvent_AppQuit, + CocoaEvent_Deleted, // Event was one of the above, but has been handled and should be ignored now. +}; + +// enum values need to match bit-shifting logic in CInputSystem::UpdateMouseButtonState and +// the codes from NSEvent pressedMouseButtons, turns out the two are in agreement right now +enum CocoaMouseButton_t +{ + COCOABUTTON_LEFT = 1 << 0, + COCOABUTTON_RIGHT = 1 << 1, + COCOABUTTON_MIDDLE = 1 << 2, + COCOABUTTON_4 = 1 << 3, + COCOABUTTON_5 = 1 << 4, +}; + +enum ECocoaKeyModifier +{ + eCapsLockKey, + eShiftKey, + eControlKey, + eAltKey, // aka option + eCommandKey +}; + +class CCocoaEvent +{ +public: + CocoaEventType_t m_EventType; + int m_VirtualKeyCode; + wchar_t m_UnicodeKey; + wchar_t m_UnicodeKeyUnmodified; + uint m_ModifierKeyMask; // + int m_MousePos[2]; + int m_MouseButtonFlags; // Current state of the mouse buttons. See COCOABUTTON_xxxx. + uint m_nMouseClickCount; + int m_MouseButton; // which of the CocoaMouseButton_t buttons this is for from above +}; + +#endif // defined( USE_SDL ) + +#endif // ILAUNCHERMGR_H diff --git a/sp/src/public/appframework/tier2app.h b/sp/src/public/appframework/tier2app.h new file mode 100644 index 00000000..266fc104 --- /dev/null +++ b/sp/src/public/appframework/tier2app.h @@ -0,0 +1,85 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// The copyright to the contents herein is the property of Valve, L.L.C. +// The contents may be used and/or copied only with the written permission of +// Valve, L.L.C., or in accordance with the terms and conditions stipulated in +// the agreement/contract under which the contents have been supplied. +// +// $Header: $ +// $NoKeywords: $ +// +// The application object for apps that use tier2 +//============================================================================= + +#ifndef TIER2APP_H +#define TIER2APP_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "appframework/AppFramework.h" +#include "tier2/tier2dm.h" +#include "tier1/convar.h" + + +//----------------------------------------------------------------------------- +// The application object for apps that use tier2 +//----------------------------------------------------------------------------- +class CTier2SteamApp : public CSteamAppSystemGroup +{ + typedef CSteamAppSystemGroup BaseClass; + +public: + // Methods of IApplication + virtual bool PreInit() + { + CreateInterfaceFn factory = GetFactory(); + ConnectTier1Libraries( &factory, 1 ); + ConVar_Register( 0 ); + ConnectTier2Libraries( &factory, 1 ); + return true; + } + + virtual void PostShutdown() + { + DisconnectTier2Libraries(); + ConVar_Unregister(); + DisconnectTier1Libraries(); + } +}; + + +//----------------------------------------------------------------------------- +// The application object for apps that use tier2 and datamodel +//----------------------------------------------------------------------------- +class CTier2DmSteamApp : public CTier2SteamApp +{ + typedef CTier2SteamApp BaseClass; + +public: + // Methods of IApplication + virtual bool PreInit() + { + if ( !BaseClass::PreInit() ) + return false; + + CreateInterfaceFn factory = GetFactory(); + if ( !ConnectDataModel( factory ) ) + return false; + + InitReturnVal_t nRetVal = InitDataModel(); + return ( nRetVal == INIT_OK ); + } + + virtual void PostShutdown() + { + ShutdownDataModel(); + DisconnectDataModel(); + BaseClass::PostShutdown(); + } +}; + + +#endif // TIER2APP_H diff --git a/sp/src/public/appframework/tier3app.h b/sp/src/public/appframework/tier3app.h new file mode 100644 index 00000000..d1806472 --- /dev/null +++ b/sp/src/public/appframework/tier3app.h @@ -0,0 +1,121 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// The copyright to the contents herein is the property of Valve, L.L.C. +// The contents may be used and/or copied only with the written permission of +// Valve, L.L.C., or in accordance with the terms and conditions stipulated in +// the agreement/contract under which the contents have been supplied. +// +// $Header: $ +// $NoKeywords: $ +// +// The application objects for apps that use tier3 +//============================================================================= + +#ifndef TIER3APP_H +#define TIER3APP_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "appframework/tier2app.h" +#include "tier3/tier3.h" +#include "vgui_controls/Controls.h" + + +//----------------------------------------------------------------------------- +// The application object for apps that use tier3 +//----------------------------------------------------------------------------- +class CTier3SteamApp : public CTier2SteamApp +{ + typedef CTier2SteamApp BaseClass; + +public: + // Methods of IApplication + virtual bool PreInit() + { + if ( !BaseClass::PreInit() ) + return false; + + CreateInterfaceFn factory = GetFactory(); + ConnectTier3Libraries( &factory, 1 ); + return true; + } + + virtual void PostShutdown() + { + DisconnectTier3Libraries(); + BaseClass::PostShutdown(); + } +}; + + +//----------------------------------------------------------------------------- +// The application object for apps that use tier3 +//----------------------------------------------------------------------------- +class CTier3DmSteamApp : public CTier2DmSteamApp +{ + typedef CTier2DmSteamApp BaseClass; + +public: + // Methods of IApplication + virtual bool PreInit() + { + if ( !BaseClass::PreInit() ) + return false; + + CreateInterfaceFn factory = GetFactory(); + ConnectTier3Libraries( &factory, 1 ); + return true; + } + + virtual void PostShutdown() + { + DisconnectTier3Libraries(); + BaseClass::PostShutdown(); + } +}; + + +//----------------------------------------------------------------------------- +// The application object for apps that use vgui +//----------------------------------------------------------------------------- +class CVguiSteamApp : public CTier3SteamApp +{ + typedef CTier3SteamApp BaseClass; + +public: + // Methods of IApplication + virtual bool PreInit() + { + if ( !BaseClass::PreInit() ) + return false; + + CreateInterfaceFn factory = GetFactory(); + return vgui::VGui_InitInterfacesList( "CVguiSteamApp", &factory, 1 ); + } +}; + + +//----------------------------------------------------------------------------- +// The application object for apps that use vgui +//----------------------------------------------------------------------------- +class CVguiDmSteamApp : public CTier3DmSteamApp +{ + typedef CTier3DmSteamApp BaseClass; + +public: + // Methods of IApplication + virtual bool PreInit() + { + if ( !BaseClass::PreInit() ) + return false; + + CreateInterfaceFn factory = GetFactory(); + return vgui::VGui_InitInterfacesList( "CVguiSteamApp", &factory, 1 ); + } +}; + + +#endif // TIER3APP_H diff --git a/sp/src/public/arraystack.h b/sp/src/public/arraystack.h new file mode 100644 index 00000000..907fb614 --- /dev/null +++ b/sp/src/public/arraystack.h @@ -0,0 +1,69 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef ARRAYSTACK_H +#define ARRAYSTACK_H +#pragma once + +#include +#include "List.h" + +template class ArrayStack +{ +protected: + T *data; + int m_stackDepth; + int m_maxNumElements; + +public: + ArrayStack( int maxNumElements ) + { + data = new T[maxNumElements]; + m_maxNumElements = maxNumElements; + m_stackDepth = 0; + assert( data ); + } + + void Push( T elem ) + { + data[m_stackDepth++] = elem; + if( m_stackDepth > m_maxNumElements ) + { + printf( "ArrayStack overflow\n" ); + assert( 0 ); + } + } + + T Pop( void ) + { + if( m_stackDepth == 0 ) + { + printf( "ArrayStack underflow\n" ); + assert( 0 ); + } + return data[--m_stackDepth]; + } + + bool IsEmpty() + { + return ( m_stackDepth == 0 ); + } + + int GetDepth() + { + return m_stackDepth; + } +}; + + +#endif // ARRAYSTACK_H diff --git a/sp/src/public/avi/iavi.h b/sp/src/public/avi/iavi.h new file mode 100644 index 00000000..11433104 --- /dev/null +++ b/sp/src/public/avi/iavi.h @@ -0,0 +1,134 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// The copyright to the contents herein is the property of Valve, L.L.C. +// The contents may be used and/or copied only with the written permission of +// Valve, L.L.C., or in accordance with the terms and conditions stipulated in +// the agreement/contract under which the contents have been supplied. +// +//============================================================================= + +#ifndef IAVI_H +#define IAVI_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "appframework/IAppSystem.h" + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +struct BGR888_t; +class IMaterial; + + +//----------------------------------------------------------------------------- +// Parameters for creating a new AVI +//----------------------------------------------------------------------------- +struct AVIParams_t +{ + AVIParams_t() : + m_nFrameRate( 0 ), m_nFrameScale( 1 ), m_nWidth( 0 ), m_nHeight( 0 ), + m_nSampleRate( 0 ), m_nSampleBits( 0 ), m_nNumChannels( 0 ), m_bGetCodecFromUser( true ) + { + m_pFileName[ 0 ] = 0; + } + + char m_pFileName[ 256 ]; + char m_pPathID[ 256 ]; + + // fps = m_nFrameRate / m_nFrameScale + // for integer framerates, set framerate to the fps, and framescale to 1 + // for ntsc-style framerates like 29.97 (or 23.976 or 59.94), + // set framerate to 30,000 (or 24,000 or 60,000) and framescale to 1001 + // yes, framescale is an odd naming choice, but it matching MS's AVI api + int m_nFrameRate; + int m_nFrameScale; + + int m_nWidth; + int m_nHeight; + + // Sound/.wav info + int m_nSampleRate; + int m_nSampleBits; + int m_nNumChannels; + + // The user will be asked to select a compressor if true, otherwise the + // previous or default will be used. + bool m_bGetCodecFromUser; +}; + + +//----------------------------------------------------------------------------- +// Handle to an AVI +//----------------------------------------------------------------------------- +typedef unsigned short AVIHandle_t; +enum +{ + AVIHANDLE_INVALID = (AVIHandle_t)~0 +}; + + +//----------------------------------------------------------------------------- +// Handle to an AVI material +//----------------------------------------------------------------------------- +typedef unsigned short AVIMaterial_t; +enum +{ + AVIMATERIAL_INVALID = (AVIMaterial_t)~0 +}; + + +//----------------------------------------------------------------------------- +// Main AVI interface +//----------------------------------------------------------------------------- +#define AVI_INTERFACE_VERSION "VAvi001" + +class IAvi : public IAppSystem +{ +public: + // Necessary to call this before any other AVI interface methods + virtual void SetMainWindow( void* hWnd ) = 0; + + // Start/stop recording an AVI + virtual AVIHandle_t StartAVI( const AVIParams_t& params ) = 0; + virtual void FinishAVI( AVIHandle_t handle ) = 0; + + // Add frames to an AVI + virtual void AppendMovieSound( AVIHandle_t h, short *buf, size_t bufsize ) = 0; + virtual void AppendMovieFrame( AVIHandle_t h, const BGR888_t *pRGBData ) = 0; + + // Create/destroy an AVI material (a materialsystem IMaterial) + virtual AVIMaterial_t CreateAVIMaterial( const char *pMaterialName, const char *pFileName, const char *pPathID ) = 0; + virtual void DestroyAVIMaterial( AVIMaterial_t hMaterial ) = 0; + + // Sets the time for an AVI material + virtual void SetTime( AVIMaterial_t hMaterial, float flTime ) = 0; + + // Gets the IMaterial associated with an AVI material + virtual IMaterial* GetMaterial( AVIMaterial_t hMaterial ) = 0; + + // Returns the max texture coordinate of the AVI + virtual void GetTexCoordRange( AVIMaterial_t hMaterial, float *pMaxU, float *pMaxV ) = 0; + + // Returns the frame size of the AVI (stored in a subrect of the material itself) + virtual void GetFrameSize( AVIMaterial_t hMaterial, int *pWidth, int *pHeight ) = 0; + + // Returns the frame rate of the AVI + virtual int GetFrameRate( AVIMaterial_t hMaterial ) = 0; + + // Returns the total frame count of the AVI + virtual int GetFrameCount( AVIMaterial_t hMaterial ) = 0; + + // Sets the frame for an AVI material (use instead of SetTime) + virtual void SetFrame( AVIMaterial_t hMaterial, float flFrame ) = 0; + + // Plays a given AVI/WMV file until it completes or the user presses ESC, SPACE, or ENTER + virtual void PlayWindowsMediaVideo( const char *filename, void *mainWindow, int width, int height, float forcedMinTime ) = 0; + +}; + + + +#endif // IAVI_H diff --git a/sp/src/public/avi/iquicktime.h b/sp/src/public/avi/iquicktime.h new file mode 100644 index 00000000..83867e74 --- /dev/null +++ b/sp/src/public/avi/iquicktime.h @@ -0,0 +1,174 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// The copyright to the contents herein is the property of Valve, L.L.C. +// The contents may be used and/or copied only with the written permission of +// Valve, L.L.C., or in accordance with the terms and conditions stipulated in +// the agreement/contract under which the contents have been supplied. +// +//============================================================================= + +#ifndef IQUICKTIME_H +#define IQUICKTIME_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "appframework/IAppSystem.h" + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +struct BGR888_t; +class IMaterial; + + +//----------------------------------------------------------------------------- +// Handle to a QUICKTIME +//----------------------------------------------------------------------------- +typedef unsigned short QUICKTIMEHandle_t; +enum +{ + QUICKTIMEHANDLE_INVALID = (QUICKTIMEHandle_t)~0 +}; + + +//----------------------------------------------------------------------------- +// Handle to an QUICKTIME material +//----------------------------------------------------------------------------- +typedef unsigned short QUICKTIMEMaterial_t; +enum +{ + QUICKTIMEMATERIAL_INVALID = (QUICKTIMEMaterial_t)~0 +}; + +typedef unsigned int MovieHandle_t; +const MovieHandle_t cInvalidMovieHandle = (MovieHandle_t) ~0; + +enum eVideoSystemStatus +{ + cVideoSystem_OK = 0, + cVideoSystem_NotInstalled, + cVideoSystem_NotCurrentVersion, + cVideoSystem_InitializationError, + + cVideoSystem_ForceInt32 = 0x7FFFFFFF // Make sure eNum is (at least) an int32 +}; + + +enum eVideoSystemFeatures +{ + cVideoSystem_NoFeatures = 0x00000000, + cVideoSystem_PlayMoviesFromFile = 0x00000001, + cVideoSystem_RenderVideoFrameToMaterial = 0x00000002, + cVideoSystem_EncodeVideoToFile = 0x00000010, + cVideoSystem_EncodeAudioToFile = 0x00000020, + + cVideoSystem_ForceInt32a = 0x7FFFFFFF +}; + +DEFINE_ENUM_BITWISE_OPERATORS( eVideoSystemFeatures ); + +enum eVideoEncodeQuality +{ + cVEQuality_Min = 0, + cVEQuality_Low = 25, + cVEQuality_Normal = 50, + cVEQuality_High = 75, + cVEQuality_Max = 100 +}; + +// ----------------------------------------------------------------------- +// eVideoFrameFormat_t - bit format for quicktime video frames +// ----------------------------------------------------------------------- +enum eVideoFrameFormat_t +{ + cVFF_Undefined = 0, + cVFF_R8G8B8A8_32Bit, + cVFF_R8G8B8_24Bit, + + cVFF_Count, // Auto list counter + cVFF_ForceInt32 = 0x7FFFFFFF // Make sure eNum is (at least) an int32 +}; + +// ----------------------------------------------------------------------- +// eAudioSourceFormat_t - Audio encoding source options +// ----------------------------------------------------------------------- +enum eAudioSourceFormat_t +{ + cASF_Undefined = 0, + cASF_None, + cASF_16BitPCMStereo, + + cASF_Count, // Auto list counter + cASF_ForceInt32 = 0x7FFFFFFF // Make sure eNum is (at least) an int32 +}; + + + +//----------------------------------------------------------------------------- +// IQuickTimeMovieMaker interface +//----------------------------------------------------------------------------- +class IQuickTimeMovieMaker : public IBaseInterface +{ +public: + virtual bool CreateNewMovieFile( MovieHandle_t &theMovie, const char *pFilename, int nWidth, int nHeight, int nFps, eVideoEncodeQuality quality, eAudioSourceFormat_t srcAudioFormat = cASF_None, int audioSampleRate = 0 ) = 0; + virtual bool AppendVideoFrame( MovieHandle_t theMovie, unsigned char *pFrame ) = 0; + virtual bool AppendAudioSamples( MovieHandle_t theMovie, void *sampleBuffer, size_t sampleSize ) = 0; + virtual bool FinishMovie( MovieHandle_t theMovie, bool success = true ) = 0; +}; + +//----------------------------------------------------------------------------- +// Main QUICKTIME interface +//----------------------------------------------------------------------------- +#define QUICKTIME_INTERFACE_VERSION "IQuickTime002" + +class IQuickTime : public IAppSystem +{ +public: + virtual bool IsVideoSystemAvailable() = 0; + virtual eVideoSystemStatus GetVideoSystemStatus() = 0; + virtual eVideoSystemFeatures GetVideoSystemFeatures() = 0; + + // Create/destroy a QUICKTIME material (a materialsystem IMaterial) + virtual QUICKTIMEMaterial_t CreateMaterial( const char *pMaterialName, const char *pFileName, const char *pPathID ) = 0; + virtual void DestroyMaterial( QUICKTIMEMaterial_t hMaterial ) = 0; + + // Create/destroy a quicktime movie maker, which will encode audio/video + virtual IQuickTimeMovieMaker *CreateMovieMaker() = 0; + virtual void DestroyMovieMaker( IQuickTimeMovieMaker *&pMovieMaker ) = 0; + + // Update the frame (if necessary) + virtual bool Update( QUICKTIMEMaterial_t hMaterial ) = 0; + + // Gets the IMaterial associated with an BINK material + virtual IMaterial* GetMaterial( QUICKTIMEMaterial_t hMaterial ) = 0; + + // Returns the max texture coordinate of the BINK + virtual void GetTexCoordRange( QUICKTIMEMaterial_t hMaterial, float *pMaxU, float *pMaxV ) = 0; + + // Returns the frame size of the QUICKTIME Image Frame (stored in a subrect of the material itself) + virtual void GetFrameSize( QUICKTIMEMaterial_t hMaterial, int *pWidth, int *pHeight ) = 0; + + // Returns the frame rate of the QUICKTIME + virtual int GetFrameRate( QUICKTIMEMaterial_t hMaterial ) = 0; + + // Sets the frame for an BINK material (use instead of SetTime) + virtual void SetFrame( QUICKTIMEMaterial_t hMaterial, float flFrame ) = 0; + + // Returns the total frame count of the BINK + virtual int GetFrameCount( QUICKTIMEMaterial_t hMaterial ) = 0; + + virtual bool SetSoundDevice( void *pDevice ) = 0; + + // Plays a given MOV file until it completes or the user presses ESC, SPACE, or ENTER + virtual void PlayQuicktimeVideo( const char *filename, void *mainWindow, int windowWidth, int windowHeight, int desktopWidth, int desktopHeight, bool windowed, float forcedMinTime ) = 0; + + // Estimates the size of a recorded movie + virtual bool EstimateMovieSize( unsigned long &EstSize, int nWidth, int nHeight, int nFps, float duration, eVideoEncodeQuality quality, eAudioSourceFormat_t srcAudioFormat = cASF_None, int audioSampleRate = 0 ) = 0; + +}; + + +#endif // IQUICKTIME_H diff --git a/sp/src/public/basehandle.h b/sp/src/public/basehandle.h new file mode 100644 index 00000000..91eb02d0 --- /dev/null +++ b/sp/src/public/basehandle.h @@ -0,0 +1,177 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef BASEHANDLE_H +#define BASEHANDLE_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "const.h" +#include "tier0/dbg.h" + + +class IHandleEntity; + + +// -------------------------------------------------------------------------------------------------- // +// CBaseHandle. +// -------------------------------------------------------------------------------------------------- // + +class CBaseHandle +{ +friend class CBaseEntityList; + +public: + + CBaseHandle(); + CBaseHandle( const CBaseHandle &other ); + CBaseHandle( unsigned long value ); + CBaseHandle( int iEntry, int iSerialNumber ); + + void Init( int iEntry, int iSerialNumber ); + void Term(); + + // Even if this returns true, Get() still can return return a non-null value. + // This just tells if the handle has been initted with any values. + bool IsValid() const; + + int GetEntryIndex() const; + int GetSerialNumber() const; + + int ToInt() const; + bool operator !=( const CBaseHandle &other ) const; + bool operator ==( const CBaseHandle &other ) const; + bool operator ==( const IHandleEntity* pEnt ) const; + bool operator !=( const IHandleEntity* pEnt ) const; + bool operator <( const CBaseHandle &other ) const; + bool operator <( const IHandleEntity* pEnt ) const; + + // Assign a value to the handle. + const CBaseHandle& operator=( const IHandleEntity *pEntity ); + const CBaseHandle& Set( const IHandleEntity *pEntity ); + + // Use this to dereference the handle. + // Note: this is implemented in game code (ehandle.h) + IHandleEntity* Get() const; + + +protected: + // The low NUM_SERIAL_BITS hold the index. If this value is less than MAX_EDICTS, then the entity is networkable. + // The high NUM_SERIAL_NUM_BITS bits are the serial number. + unsigned long m_Index; +}; + + +#include "ihandleentity.h" + + +inline CBaseHandle::CBaseHandle() +{ + m_Index = INVALID_EHANDLE_INDEX; +} + +inline CBaseHandle::CBaseHandle( const CBaseHandle &other ) +{ + m_Index = other.m_Index; +} + +inline CBaseHandle::CBaseHandle( unsigned long value ) +{ + m_Index = value; +} + +inline CBaseHandle::CBaseHandle( int iEntry, int iSerialNumber ) +{ + Init( iEntry, iSerialNumber ); +} + +inline void CBaseHandle::Init( int iEntry, int iSerialNumber ) +{ + Assert( iEntry >= 0 && iEntry < NUM_ENT_ENTRIES ); + Assert( iSerialNumber >= 0 && iSerialNumber < (1 << NUM_SERIAL_NUM_BITS) ); + + m_Index = iEntry | (iSerialNumber << NUM_ENT_ENTRY_BITS); +} + +inline void CBaseHandle::Term() +{ + m_Index = INVALID_EHANDLE_INDEX; +} + +inline bool CBaseHandle::IsValid() const +{ + return m_Index != INVALID_EHANDLE_INDEX; +} + +inline int CBaseHandle::GetEntryIndex() const +{ + return m_Index & ENT_ENTRY_MASK; +} + +inline int CBaseHandle::GetSerialNumber() const +{ + return m_Index >> NUM_ENT_ENTRY_BITS; +} + +inline int CBaseHandle::ToInt() const +{ + return (int)m_Index; +} + +inline bool CBaseHandle::operator !=( const CBaseHandle &other ) const +{ + return m_Index != other.m_Index; +} + +inline bool CBaseHandle::operator ==( const CBaseHandle &other ) const +{ + return m_Index == other.m_Index; +} + +inline bool CBaseHandle::operator ==( const IHandleEntity* pEnt ) const +{ + return Get() == pEnt; +} + +inline bool CBaseHandle::operator !=( const IHandleEntity* pEnt ) const +{ + return Get() != pEnt; +} + +inline bool CBaseHandle::operator <( const CBaseHandle &other ) const +{ + return m_Index < other.m_Index; +} + +inline bool CBaseHandle::operator <( const IHandleEntity *pEntity ) const +{ + unsigned long otherIndex = (pEntity) ? pEntity->GetRefEHandle().m_Index : INVALID_EHANDLE_INDEX; + return m_Index < otherIndex; +} + +inline const CBaseHandle& CBaseHandle::operator=( const IHandleEntity *pEntity ) +{ + return Set( pEntity ); +} + +inline const CBaseHandle& CBaseHandle::Set( const IHandleEntity *pEntity ) +{ + if ( pEntity ) + { + *this = pEntity->GetRefEHandle(); + } + else + { + m_Index = INVALID_EHANDLE_INDEX; + } + + return *this; +} + + +#endif // BASEHANDLE_H diff --git a/sp/src/public/bitmap/bitmap.h b/sp/src/public/bitmap/bitmap.h new file mode 100644 index 00000000..bc56ed21 --- /dev/null +++ b/sp/src/public/bitmap/bitmap.h @@ -0,0 +1,142 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#ifndef BITMAP_H +#define BITMAP_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "bitmap/imageformat.h" +#include "Color.h" +#include "dbg.h" + +class CUtlBuffer; + +//----------------------------------------------------------------------------- +// A Bitmap +//----------------------------------------------------------------------------- +struct Bitmap_t +{ + Bitmap_t() { Reset(); } + ~Bitmap_t() { Clear(); } + + // + // Accessors + // + inline int Width() const { return m_nWidth; } + inline int Height() const { return m_nHeight; } + inline ImageFormat Format() const { return m_ImageFormat; } + inline unsigned char *GetBits() const { return m_pBits; } + inline int Stride() const { return m_nStride; } + inline bool GetOwnsBuffer() const { return m_bOwnsBuffer; } + + /// Allocate the buffer. Discards existing data, freeing it if we own it + void Init( int nWidth, int nHeight, ImageFormat imageFormat, int nStride = 0 ); + + /// Set the bitmap to the specified buffer. Any existing data is discarded/freed + /// as appropriate. + void SetBuffer( int nWidth, int nHeight, ImageFormat imageFormat, unsigned char *pBits, bool bAssumeOwnership, int nStride = 0 ); + + /// Sets / releases ownershp of the buffer. This does not otherwise alter the + /// state of the bitmap. + void SetOwnsBuffer( bool bOwnsBuffer ) + { + Assert( m_pBits ); + m_bOwnsBuffer = bOwnsBuffer; + } + + /// Free up all memory and reset to default state + void Clear(); + + /// Return true if we have a valid size and buffer + bool IsValid() const; + + /// Get pointer to raw pixel data. + unsigned char *GetPixel( int x, int y ); + const unsigned char *GetPixel( int x, int y ) const; + + /// Get pixel value at specified coordinates + Color GetColor( int x, int y ) const; + + /// Set pixel value at specified coordinates + void SetColor( int x, int y, Color c ); + + /// Set this bitmap to be a logical copy of the specified + /// bitmap. No memory is allocated or copied, just copying + /// some pointers. We can also optionally transfer ownership + /// of the buffer. + void MakeLogicalCopyOf( Bitmap_t &src, bool bTransferBufferOwnership = false ); + + /// Set this bitmap to be a cropped rectangle from the given bitmap. + /// The source pointer can be NULL or point to this, which means to do + /// the crop in place. + void Crop( int x0, int y0, int nWidth, int nHeight, const Bitmap_t *pImgSource = NULL ); + + /// Blit a rectangle of pixel data into this image. + void SetPixelData( const Bitmap_t &src, int nSrcX1, int nSrcY1, int nCopySizeX, int nCopySizeY, int nDestX1, int nDestY1 ); + + /// Blit the entire source image into this image, at the specified offset. + /// the rectangle is clipped if necessary + void SetPixelData( const Bitmap_t &src, int nDestX1 = 0, int nDestY1 = 0 ); + +private: + void Reset(); + + /// Dimensions + int m_nWidth; + int m_nHeight; + + /// Size, in bytes, of one pixel + int m_nPixelSize; + + /// Image row stride, in bytes + int m_nStride; + + // Do we own this buffer? + bool m_bOwnsBuffer; + + /// Pixel format + ImageFormat m_ImageFormat; + + /// Bitmap data. Must be allocated with malloc/free. Don't use + /// new/delete + unsigned char *m_pBits; +}; + +inline void Bitmap_t::Reset() +{ + m_nWidth = 0; + m_nHeight = 0; + m_ImageFormat = IMAGE_FORMAT_UNKNOWN; + m_pBits = NULL; + m_nPixelSize = 0; + m_bOwnsBuffer = false; + m_nStride = 0; +} + +inline unsigned char *Bitmap_t::GetPixel( int x, int y ) +{ + if ( !m_pBits ) + return NULL; + + return m_pBits + (y*m_nStride) + x* m_nPixelSize; +} + +inline const unsigned char *Bitmap_t::GetPixel( int x, int y ) const +{ + if ( !m_pBits ) + return NULL; + + return m_pBits + (y*m_nStride) + x* m_nPixelSize; +} + + +#endif // BITMAP_H diff --git a/sp/src/public/bitmap/cubemap.h b/sp/src/public/bitmap/cubemap.h new file mode 100644 index 00000000..1bda06f3 --- /dev/null +++ b/sp/src/public/bitmap/cubemap.h @@ -0,0 +1,68 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: a class for performing cube-mapped spherical sample lookups. +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//===========================================================================// + +#ifndef CUBEMAP_H +#define CUBEMAP_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier0/platform.h" +#include "tier1/utlmemory.h" +#include "mathlib/mathlib.h" + +template struct CCubeMap +{ + T m_Samples[6][RES][RES]; + +public: + FORCEINLINE void GetCoords( Vector const &vecNormalizedDirection, int &nX, int &nY, int &nFace ) + { + // find largest magnitude component + int nLargest = 0; + int nAxis0 = 1; + int nAxis1 = 2; + if ( fabs( vecNormalizedDirection[1] ) > fabs( vecNormalizedDirection[0] ) ) + { + nLargest = 1; + nAxis0 = 0; + nAxis1 = 2; + } + if ( fabs( vecNormalizedDirection[2] ) > fabs( vecNormalizedDirection[nLargest] ) ) + { + nLargest = 2; + nAxis0 = 0; + nAxis1 = 1; + } + float flZ = vecNormalizedDirection[nLargest]; + if ( flZ < 0 ) + { + flZ = - flZ; + nLargest += 3; + } + nFace = nLargest; + flZ = 1.0 / flZ; + nX = RemapValClamped( vecNormalizedDirection[nAxis0] * flZ, -1, 1, 0, RES - 1 ); + nY = RemapValClamped( vecNormalizedDirection[nAxis1] * flZ, -1, 1, 0, RES - 1 ); + } + + FORCEINLINE T & GetSample( Vector const &vecNormalizedDirection ) + { + int nX, nY, nFace; + GetCoords( vecNormalizedDirection, nX, nY, nFace ); + return m_Samples[nFace][nX][nY]; + } +}; + + + + + +#endif // CUBEMAP_H diff --git a/sp/src/public/bitmap/float_bm.h b/sp/src/public/bitmap/float_bm.h new file mode 100644 index 00000000..b4dfb160 --- /dev/null +++ b/sp/src/public/bitmap/float_bm.h @@ -0,0 +1,363 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#ifndef FLOAT_BM_H +#define FLOAT_BM_H + +#ifdef _WIN32 +#pragma once +#endif + +#include +#include "tier0/dbg.h" +#include + +struct PixRGBAF +{ + float Red; + float Green; + float Blue; + float Alpha; +}; + +struct PixRGBA8 +{ + unsigned char Red; + unsigned char Green; + unsigned char Blue; + unsigned char Alpha; +}; + +inline PixRGBAF PixRGBA8_to_F( PixRGBA8 const &x ) +{ + PixRGBAF f; + f.Red = x.Red / float( 255.0f ); + f.Green = x.Green / float( 255.0f ); + f.Blue = x.Blue / float( 255.0f ); + f.Alpha = x.Alpha / float( 255.0f ); + return f; +} + +inline PixRGBA8 PixRGBAF_to_8( PixRGBAF const &f ) +{ + PixRGBA8 x; + x.Red = max( 0, min( 255.0,255.0*f.Red ) ); + x.Green = max( 0, min( 255.0,255.0*f.Green ) ); + x.Blue = max( 0, min( 255.0,255.0*f.Blue ) ); + x.Alpha = max( 0, min( 255.0,255.0*f.Alpha ) ); + return x; +} + +#define SPFLAGS_MAXGRADIENT 1 + +// bit flag options for ComputeSelfShadowedBumpmapFromHeightInAlphaChannel: +#define SSBUMP_OPTION_NONDIRECTIONAL 1 // generate ambient occlusion only +#define SSBUMP_MOD2X_DETAIL_TEXTURE 2 // scale so that a flat unshadowed + // value is 0.5, and bake rgb luminance + // in. + + + +class FloatBitMap_t +{ +public: + int Width, Height; // bitmap dimensions + float *RGBAData; // actual data + + FloatBitMap_t(void) // empty one + { + Width=Height=0; + RGBAData=0; + } + + + + FloatBitMap_t(int width, int height); // make one and allocate space + FloatBitMap_t(char const *filename); // read one from a file (tga or pfm) + FloatBitMap_t(FloatBitMap_t const *orig); + // quantize one to 8 bits + bool WriteTGAFile(char const *filename) const; + + bool LoadFromPFM(char const *filename); // load from floating point pixmap (.pfm) file + bool WritePFM(char const *filename); // save to floating point pixmap (.pfm) file + + + void InitializeWithRandomPixelsFromAnotherFloatBM(FloatBitMap_t const &other); + + inline float & Pixel(int x, int y, int comp) const + { + Assert((x>=0) && (x=0) && (y= Width) + x -= Width; + + if ( y < 0 ) + y+=Height; + else + if ( y >= Height ) + y -= Height; + + return RGBAData[4*(x+Width*y)+comp]; + } + + inline float & PixelClamped(int x, int y, int comp) const + { + // like Pixel except wraps around to other side + x=clamp(x,0,Width-1); + y=clamp(y,0,Height-1); + return RGBAData[4*(x+Width*y)+comp]; + } + + + inline float & Alpha(int x, int y) const + { + Assert((x>=0) && (x=0) && (y=0) && (x=0) && (y=0) && (x=0) && (y=0) && (x=0) && (y + +enum NormalDecodeMode_t +{ + NORMAL_DECODE_NONE = 0, + NORMAL_DECODE_ATI2N = 1, + NORMAL_DECODE_ATI2N_ALPHA = 2 +}; + +// Forward declaration +#ifdef _WIN32 +typedef enum _D3DFORMAT D3DFORMAT; +#endif + +//----------------------------------------------------------------------------- +// The various image format types +//----------------------------------------------------------------------------- + +// don't bitch that inline functions aren't used!!!! +#pragma warning(disable : 4514) + +enum ImageFormat +{ + IMAGE_FORMAT_UNKNOWN = -1, + IMAGE_FORMAT_RGBA8888 = 0, + IMAGE_FORMAT_ABGR8888, + IMAGE_FORMAT_RGB888, + IMAGE_FORMAT_BGR888, + IMAGE_FORMAT_RGB565, + IMAGE_FORMAT_I8, + IMAGE_FORMAT_IA88, + IMAGE_FORMAT_P8, + IMAGE_FORMAT_A8, + IMAGE_FORMAT_RGB888_BLUESCREEN, + IMAGE_FORMAT_BGR888_BLUESCREEN, + IMAGE_FORMAT_ARGB8888, + IMAGE_FORMAT_BGRA8888, + IMAGE_FORMAT_DXT1, + IMAGE_FORMAT_DXT3, + IMAGE_FORMAT_DXT5, + IMAGE_FORMAT_BGRX8888, + IMAGE_FORMAT_BGR565, + IMAGE_FORMAT_BGRX5551, + IMAGE_FORMAT_BGRA4444, + IMAGE_FORMAT_DXT1_ONEBITALPHA, + IMAGE_FORMAT_BGRA5551, + IMAGE_FORMAT_UV88, + IMAGE_FORMAT_UVWQ8888, + IMAGE_FORMAT_RGBA16161616F, + IMAGE_FORMAT_RGBA16161616, + IMAGE_FORMAT_UVLX8888, + IMAGE_FORMAT_R32F, // Single-channel 32-bit floating point + IMAGE_FORMAT_RGB323232F, + IMAGE_FORMAT_RGBA32323232F, + + // Depth-stencil texture formats for shadow depth mapping + IMAGE_FORMAT_NV_DST16, // + IMAGE_FORMAT_NV_DST24, // + IMAGE_FORMAT_NV_INTZ, // Vendor-specific depth-stencil texture + IMAGE_FORMAT_NV_RAWZ, // formats for shadow depth mapping + IMAGE_FORMAT_ATI_DST16, // + IMAGE_FORMAT_ATI_DST24, // + IMAGE_FORMAT_NV_NULL, // Dummy format which takes no video memory + + // Compressed normal map formats + IMAGE_FORMAT_ATI2N, // One-surface ATI2N / DXN format + IMAGE_FORMAT_ATI1N, // Two-surface ATI1N format + +#if defined( _X360 ) + // Depth-stencil texture formats + IMAGE_FORMAT_X360_DST16, + IMAGE_FORMAT_X360_DST24, + IMAGE_FORMAT_X360_DST24F, + // supporting these specific formats as non-tiled for procedural cpu access + IMAGE_FORMAT_LINEAR_BGRX8888, + IMAGE_FORMAT_LINEAR_RGBA8888, + IMAGE_FORMAT_LINEAR_ABGR8888, + IMAGE_FORMAT_LINEAR_ARGB8888, + IMAGE_FORMAT_LINEAR_BGRA8888, + IMAGE_FORMAT_LINEAR_RGB888, + IMAGE_FORMAT_LINEAR_BGR888, + IMAGE_FORMAT_LINEAR_BGRX5551, + IMAGE_FORMAT_LINEAR_I8, + IMAGE_FORMAT_LINEAR_RGBA16161616, + + IMAGE_FORMAT_LE_BGRX8888, + IMAGE_FORMAT_LE_BGRA8888, +#endif + + NUM_IMAGE_FORMATS +}; + +#if defined( POSIX ) || defined( DX_TO_GL_ABSTRACTION ) +typedef enum _D3DFORMAT + { + D3DFMT_INDEX16, + D3DFMT_D16, + D3DFMT_D24S8, + D3DFMT_A8R8G8B8, + D3DFMT_A4R4G4B4, + D3DFMT_X8R8G8B8, + D3DFMT_R5G6R5, + D3DFMT_X1R5G5B5, + D3DFMT_A1R5G5B5, + D3DFMT_L8, + D3DFMT_A8L8, + D3DFMT_A, + D3DFMT_DXT1, + D3DFMT_DXT3, + D3DFMT_DXT5, + D3DFMT_V8U8, + D3DFMT_Q8W8V8U8, + D3DFMT_X8L8V8U8, + D3DFMT_A16B16G16R16F, + D3DFMT_A16B16G16R16, + D3DFMT_R32F, + D3DFMT_A32B32G32R32F, + D3DFMT_R8G8B8, + D3DFMT_D24X4S4, + D3DFMT_A8, + D3DFMT_R5G6B5, + D3DFMT_D15S1, + D3DFMT_D24X8, + D3DFMT_VERTEXDATA, + D3DFMT_INDEX32, + + // adding fake D3D format names for the vendor specific ones (eases debugging/logging) + + // NV shadow depth tex + D3DFMT_NV_INTZ = 0x5a544e49, // MAKEFOURCC('I','N','T','Z') + D3DFMT_NV_RAWZ = 0x5a574152, // MAKEFOURCC('R','A','W','Z') + + // NV null tex + D3DFMT_NV_NULL = 0x4c4c554e, // MAKEFOURCC('N','U','L','L') + + // ATI shadow depth tex + D3DFMT_ATI_D16 = 0x36314644, // MAKEFOURCC('D','F','1','6') + D3DFMT_ATI_D24S8 = 0x34324644, // MAKEFOURCC('D','F','2','4') + + // ATI 1N and 2N compressed tex + D3DFMT_ATI_2N = 0x32495441, // MAKEFOURCC('A', 'T', 'I', '2') + D3DFMT_ATI_1N = 0x31495441, // MAKEFOURCC('A', 'T', 'I', '1') + + D3DFMT_UNKNOWN + } D3DFORMAT; +#endif + +//----------------------------------------------------------------------------- +// Color structures +//----------------------------------------------------------------------------- + +struct BGRA8888_t +{ + unsigned char b; // change the order of names to change the + unsigned char g; // order of the output ARGB or BGRA, etc... + unsigned char r; // Last one is MSB, 1st is LSB. + unsigned char a; + inline BGRA8888_t& operator=( const BGRA8888_t& in ) + { + *( unsigned int * )this = *( unsigned int * )∈ + return *this; + } +}; + +struct RGBA8888_t +{ + unsigned char r; // change the order of names to change the + unsigned char g; // order of the output ARGB or BGRA, etc... + unsigned char b; // Last one is MSB, 1st is LSB. + unsigned char a; + inline RGBA8888_t& operator=( const BGRA8888_t& in ) + { + r = in.r; + g = in.g; + b = in.b; + a = in.a; + return *this; + } +}; + +struct RGB888_t +{ + unsigned char r; + unsigned char g; + unsigned char b; + inline RGB888_t& operator=( const BGRA8888_t& in ) + { + r = in.r; + g = in.g; + b = in.b; + return *this; + } + inline bool operator==( const RGB888_t& in ) const + { + return ( r == in.r ) && ( g == in.g ) && ( b == in.b ); + } + inline bool operator!=( const RGB888_t& in ) const + { + return ( r != in.r ) || ( g != in.g ) || ( b != in.b ); + } +}; + +struct BGR888_t +{ + unsigned char b; + unsigned char g; + unsigned char r; + inline BGR888_t& operator=( const BGRA8888_t& in ) + { + r = in.r; + g = in.g; + b = in.b; + return *this; + } +}; + +// 360 uses this structure for x86 dxt decoding +#if defined( _X360 ) +#pragma bitfield_order( push, lsb_to_msb ) +#endif +struct BGR565_t +{ + unsigned short b : 5; // order of names changes + unsigned short g : 6; // byte order of output to 32 bit + unsigned short r : 5; + inline BGR565_t& operator=( const BGRA8888_t& in ) + { + r = in.r >> 3; + g = in.g >> 2; + b = in.b >> 3; + return *this; + } + inline BGR565_t &Set( int red, int green, int blue ) + { + r = red >> 3; + g = green >> 2; + b = blue >> 3; + return *this; + } +}; +#if defined( _X360 ) +#pragma bitfield_order( pop ) +#endif + +struct BGRA5551_t +{ + unsigned short b : 5; // order of names changes + unsigned short g : 5; // byte order of output to 32 bit + unsigned short r : 5; + unsigned short a : 1; + inline BGRA5551_t& operator=( const BGRA8888_t& in ) + { + r = in.r >> 3; + g = in.g >> 3; + b = in.b >> 3; + a = in.a >> 7; + return *this; + } +}; + +struct BGRA4444_t +{ + unsigned short b : 4; // order of names changes + unsigned short g : 4; // byte order of output to 32 bit + unsigned short r : 4; + unsigned short a : 4; + inline BGRA4444_t& operator=( const BGRA8888_t& in ) + { + r = in.r >> 4; + g = in.g >> 4; + b = in.b >> 4; + a = in.a >> 4; + return *this; + } +}; + +struct RGBX5551_t +{ + unsigned short r : 5; + unsigned short g : 5; + unsigned short b : 5; + unsigned short x : 1; + inline RGBX5551_t& operator=( const BGRA8888_t& in ) + { + r = in.r >> 3; + g = in.g >> 3; + b = in.b >> 3; + return *this; + } +}; + +//----------------------------------------------------------------------------- +// some important constants +//----------------------------------------------------------------------------- +#define ARTWORK_GAMMA ( 2.2f ) +#define IMAGE_MAX_DIM ( 2048 ) + + +//----------------------------------------------------------------------------- +// information about each image format +//----------------------------------------------------------------------------- +struct ImageFormatInfo_t +{ + const char* m_pName; + int m_NumBytes; + int m_NumRedBits; + int m_NumGreeBits; + int m_NumBlueBits; + int m_NumAlphaBits; + bool m_IsCompressed; +}; + + +//----------------------------------------------------------------------------- +// Various methods related to pixelmaps and color formats +//----------------------------------------------------------------------------- +namespace ImageLoader +{ + + bool GetInfo( const char *fileName, int *width, int *height, enum ImageFormat *imageFormat, float *sourceGamma ); + int GetMemRequired( int width, int height, int depth, ImageFormat imageFormat, bool mipmap ); + int GetMipMapLevelByteOffset( int width, int height, enum ImageFormat imageFormat, int skipMipLevels ); + void GetMipMapLevelDimensions( int *width, int *height, int skipMipLevels ); + int GetNumMipMapLevels( int width, int height, int depth = 1 ); + bool Load( unsigned char *imageData, const char *fileName, int width, int height, enum ImageFormat imageFormat, float targetGamma, bool mipmap ); + bool Load( unsigned char *imageData, FILE *fp, int width, int height, + enum ImageFormat imageFormat, float targetGamma, bool mipmap ); + + // convert from any image format to any other image format. + // return false if the conversion cannot be performed. + // Strides denote the number of bytes per each line, + // by default assumes width * # of bytes per pixel + bool ConvertImageFormat( const unsigned char *src, enum ImageFormat srcImageFormat, + unsigned char *dst, enum ImageFormat dstImageFormat, + int width, int height, int srcStride = 0, int dstStride = 0 ); + + // must be used in conjunction with ConvertImageFormat() to pre-swap and post-swap + void PreConvertSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, int width = 0, int stride = 0 ); + void PostConvertSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, int width = 0, int stride = 0 ); + void ByteSwapImageData( unsigned char *pImageData, int nImageSize, ImageFormat imageFormat, int width = 0, int stride = 0 ); + bool IsFormatValidForConversion( ImageFormat fmt ); + + //----------------------------------------------------------------------------- + // convert back and forth from D3D format to ImageFormat, regardless of + // whether it's supported or not + //----------------------------------------------------------------------------- + ImageFormat D3DFormatToImageFormat( D3DFORMAT format ); + D3DFORMAT ImageFormatToD3DFormat( ImageFormat format ); + + // Flags for ResampleRGBA8888 + enum + { + RESAMPLE_NORMALMAP = 0x1, + RESAMPLE_ALPHATEST = 0x2, + RESAMPLE_NICE_FILTER = 0x4, + RESAMPLE_CLAMPS = 0x8, + RESAMPLE_CLAMPT = 0x10, + RESAMPLE_CLAMPU = 0x20, + }; + + struct ResampleInfo_t + { + + ResampleInfo_t() : m_nFlags(0), m_flAlphaThreshhold(0.4f), m_flAlphaHiFreqThreshhold(0.4f), m_nSrcDepth(1), m_nDestDepth(1) + { + m_flColorScale[0] = 1.0f, m_flColorScale[1] = 1.0f, m_flColorScale[2] = 1.0f, m_flColorScale[3] = 1.0f; + m_flColorGoal[0] = 0.0f, m_flColorGoal[1] = 0.0f, m_flColorGoal[2] = 0.0f, m_flColorGoal[3] = 0.0f; + } + + unsigned char *m_pSrc; + unsigned char *m_pDest; + + int m_nSrcWidth; + int m_nSrcHeight; + int m_nSrcDepth; + + int m_nDestWidth; + int m_nDestHeight; + int m_nDestDepth; + + float m_flSrcGamma; + float m_flDestGamma; + + float m_flColorScale[4]; // Color scale factors RGBA + float m_flColorGoal[4]; // Color goal values RGBA DestColor = ColorGoal + scale * (SrcColor - ColorGoal) + + float m_flAlphaThreshhold; + float m_flAlphaHiFreqThreshhold; + + int m_nFlags; + }; + + bool ResampleRGBA8888( const ResampleInfo_t &info ); + bool ResampleRGBA16161616( const ResampleInfo_t &info ); + bool ResampleRGB323232F( const ResampleInfo_t &info ); + + void ConvertNormalMapRGBA8888ToDUDVMapUVLX8888( const unsigned char *src, int width, int height, + unsigned char *dst_ ); + void ConvertNormalMapRGBA8888ToDUDVMapUVWQ8888( const unsigned char *src, int width, int height, + unsigned char *dst_ ); + void ConvertNormalMapRGBA8888ToDUDVMapUV88( const unsigned char *src, int width, int height, + unsigned char *dst_ ); + + void ConvertIA88ImageToNormalMapRGBA8888( const unsigned char *src, int width, + int height, unsigned char *dst, + float bumpScale ); + + void NormalizeNormalMapRGBA8888( unsigned char *src, int numTexels ); + + + //----------------------------------------------------------------------------- + // Gamma correction + //----------------------------------------------------------------------------- + void GammaCorrectRGBA8888( unsigned char *src, unsigned char* dst, + int width, int height, int depth, float srcGamma, float dstGamma ); + + + //----------------------------------------------------------------------------- + // Makes a gamma table + //----------------------------------------------------------------------------- + void ConstructGammaTable( unsigned char* pTable, float srcGamma, float dstGamma ); + + + //----------------------------------------------------------------------------- + // Gamma corrects using a previously constructed gamma table + //----------------------------------------------------------------------------- + void GammaCorrectRGBA8888( unsigned char* pSrc, unsigned char* pDst, + int width, int height, int depth, unsigned char* pGammaTable ); + + + //----------------------------------------------------------------------------- + // Generates a number of mipmap levels + //----------------------------------------------------------------------------- + void GenerateMipmapLevels( unsigned char* pSrc, unsigned char* pDst, int width, + int height, int depth, ImageFormat imageFormat, float srcGamma, float dstGamma, + int numLevels = 0 ); + + + //----------------------------------------------------------------------------- + // operations on square images (src and dst can be the same) + //----------------------------------------------------------------------------- + bool RotateImageLeft( const unsigned char *src, unsigned char *dst, + int widthHeight, ImageFormat imageFormat ); + bool RotateImage180( const unsigned char *src, unsigned char *dst, + int widthHeight, ImageFormat imageFormat ); + bool FlipImageVertically( void *pSrc, void *pDst, int nWidth, int nHeight, ImageFormat imageFormat, int nDstStride = 0 ); + bool FlipImageHorizontally( void *pSrc, void *pDst, int nWidth, int nHeight, ImageFormat imageFormat, int nDstStride = 0 ); + bool SwapAxes( unsigned char *src, + int widthHeight, ImageFormat imageFormat ); + + + //----------------------------------------------------------------------------- + // Returns info about each image format + //----------------------------------------------------------------------------- + ImageFormatInfo_t const& ImageFormatInfo( ImageFormat fmt ); + + + //----------------------------------------------------------------------------- + // Gets the name of the image format + //----------------------------------------------------------------------------- + inline char const* GetName( ImageFormat fmt ) + { + return ImageFormatInfo(fmt).m_pName; + } + + + //----------------------------------------------------------------------------- + // Gets the size of the image format in bytes + //----------------------------------------------------------------------------- + inline int SizeInBytes( ImageFormat fmt ) + { + return ImageFormatInfo(fmt).m_NumBytes; + } + + //----------------------------------------------------------------------------- + // Does the image format support transparency? + //----------------------------------------------------------------------------- + inline bool IsTransparent( ImageFormat fmt ) + { + return ImageFormatInfo(fmt).m_NumAlphaBits > 0; + } + + + //----------------------------------------------------------------------------- + // Is the image format compressed? + //----------------------------------------------------------------------------- + inline bool IsCompressed( ImageFormat fmt ) + { + return ImageFormatInfo(fmt).m_IsCompressed; + } + + //----------------------------------------------------------------------------- + // Is any channel > 8 bits? + //----------------------------------------------------------------------------- + inline bool HasChannelLargerThan8Bits( ImageFormat fmt ) + { + ImageFormatInfo_t info = ImageFormatInfo(fmt); + return ( info.m_NumRedBits > 8 || info.m_NumGreeBits > 8 || info.m_NumBlueBits > 8 || info.m_NumAlphaBits > 8 ); + } + + +} // end namespace ImageLoader + + +#endif // IMAGEFORMAT_H diff --git a/sp/src/public/bitmap/psd.h b/sp/src/public/bitmap/psd.h new file mode 100644 index 00000000..aae3cbfa --- /dev/null +++ b/sp/src/public/bitmap/psd.h @@ -0,0 +1,105 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Methods relating to saving + loading PSD files (photoshop) +// +// $NoKeywords: $ +//===========================================================================// + +#ifndef PSD_H +#define PSD_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "bitmap/imageformat.h" //ImageFormat enum definition + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CUtlBuffer; +struct Bitmap_t; + +class PSDImageResources +{ +public: + enum Resource { + eResFileInfo = 0x0404 + }; + + struct ResElement { + Resource m_eType; + // unsigned char m_pReserved[4]; + unsigned short m_numBytes; + unsigned char const *m_pvData; + }; + +public: + explicit PSDImageResources( unsigned int numBytes, unsigned char const *pvBuffer ) : m_numBytes( numBytes ), m_pvBuffer( pvBuffer ) {} + +public: + ResElement FindElement( Resource eType ) const; + +protected: + unsigned int m_numBytes; + unsigned char const * m_pvBuffer; +}; + +class PSDResFileInfo +{ +public: + enum ResFileInfo { + eTitle = 0x05, + eAuthor = 0x50, + eAuthorTitle = 0x55, + eDescription = 0x78, + eDescriptionWriter = 0x7A, + eKeywords = 0x19, + eCopyrightNotice = 0x74 + }; + + struct ResFileInfoElement { + ResFileInfo m_eType; + unsigned short m_numBytes; + unsigned char const *m_pvData; + }; + +public: + explicit PSDResFileInfo( PSDImageResources::ResElement res ) : m_res( res ) {} + +public: + ResFileInfoElement FindElement( ResFileInfo eType ) const; + +protected: + PSDImageResources::ResElement m_res; +}; + + +//----------------------------------------------------------------------------- +// Is a file a PSD file? +//----------------------------------------------------------------------------- +bool IsPSDFile( const char *pFileName, const char *pPathID ); +bool IsPSDFile( CUtlBuffer &buf ); + + +//----------------------------------------------------------------------------- +// Returns information about the PSD file +//----------------------------------------------------------------------------- +bool PSDGetInfo( const char *pFileName, const char *pPathID, int *pWidth, int *pHeight, ImageFormat *pImageFormat, float *pSourceGamma ); +bool PSDGetInfo( CUtlBuffer &buf, int *pWidth, int *pHeight, ImageFormat *pImageFormat, float *pSourceGamma ); + + +//----------------------------------------------------------------------------- +// Get PSD file image resources, pointers refer into the utlbuffer +//----------------------------------------------------------------------------- +PSDImageResources PSDGetImageResources( CUtlBuffer &buf ); + + +//----------------------------------------------------------------------------- +// Reads the PSD file into the specified buffer +//----------------------------------------------------------------------------- +bool PSDReadFileRGBA8888( CUtlBuffer &buf, Bitmap_t &bitmap ); +bool PSDReadFileRGBA8888( const char *pFileName, const char *pPathID, Bitmap_t &bitmap ); + + +#endif // PSD_H diff --git a/sp/src/public/bitmap/tgaloader.h b/sp/src/public/bitmap/tgaloader.h new file mode 100644 index 00000000..413eb178 --- /dev/null +++ b/sp/src/public/bitmap/tgaloader.h @@ -0,0 +1,45 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//===========================================================================// + +#ifndef TGALOADER_H +#define TGALOADER_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "bitmap/imageformat.h" +#include "tier1/utlmemory.h" + + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CUtlBuffer; + + +namespace TGALoader +{ + +int TGAHeaderSize(); + +bool GetInfo( const char *fileName, int *width, int *height, ImageFormat *imageFormat, float *sourceGamma ); +bool GetInfo( CUtlBuffer &buf, int *width, int *height, ImageFormat *imageFormat, float *sourceGamma ); + +bool Load( unsigned char *imageData, const char *fileName, int width, int height, + ImageFormat imageFormat, float targetGamma, bool mipmap ); +bool Load( unsigned char *imageData, CUtlBuffer &buf, int width, int height, + ImageFormat imageFormat, float targetGamma, bool mipmap ); + +bool LoadRGBA8888( const char *pFileName, CUtlMemory &outputData, int &outWidth, int &outHeight ); +bool LoadRGBA8888( CUtlBuffer &buf, CUtlMemory &outputData, int &outWidth, int &outHeight ); + +} // end namespace TGALoader + +#endif // TGALOADER_H diff --git a/sp/src/public/bitmap/tgawriter.h b/sp/src/public/bitmap/tgawriter.h new file mode 100644 index 00000000..51854bae --- /dev/null +++ b/sp/src/public/bitmap/tgawriter.h @@ -0,0 +1,40 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#ifndef TGAWRITER_H +#define TGAWRITER_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "tier1/interface.h" +#include "bitmap/imageformat.h" //ImageFormat enum definition + +class CUtlBuffer; + + +namespace TGAWriter +{ + + bool WriteToBuffer( unsigned char *pImageData, CUtlBuffer &buffer, int width, int height, + ImageFormat srcFormat, ImageFormat dstFormat ); + + + // write out a simple tga file from a memory buffer. + bool WriteTGAFile( const char *fileName, int width, int height, enum ImageFormat srcFormat, uint8 const *srcData, int nStride ); + +// A pair of routines for writing to files without allocating any memory in the TGA writer +// Useful for very large files such as posters, which are rendered as sub-rects anyway + bool WriteDummyFileNoAlloc( const char *fileName, int width, int height, ImageFormat dstFormat ); + bool WriteRectNoAlloc( unsigned char *pImageData, const char *fileName, int nXOrigin, int nYOrigin, int width, int height, int nStride, ImageFormat srcFormat ); + + +} // end namespace TGAWriter + +#endif // TGAWRITER_H diff --git a/sp/src/public/bitvec.h b/sp/src/public/bitvec.h new file mode 100644 index 00000000..5095b09c --- /dev/null +++ b/sp/src/public/bitvec.h @@ -0,0 +1,1442 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#ifndef BITVEC_H +#define BITVEC_H +#ifdef _WIN32 +#pragma once +#endif + +#include +#include "tier0/dbg.h" +#include "tier0/basetypes.h" + + +class CBitVecAccessor +{ +public: + CBitVecAccessor(uint32 *pDWords, int iBit); + + void operator=(int val); + operator uint32(); + +private: + uint32 *m_pDWords; + int m_iBit; +}; + + +//----------------------------------------------------------------------------- +// Support functions +//----------------------------------------------------------------------------- + +#define LOG2_BITS_PER_INT 5 +#define BITS_PER_INT 32 + +#if _WIN32 && !defined(_X360) +#include +#pragma intrinsic(_BitScanForward) +#endif + +inline int FirstBitInWord( unsigned int elem, int offset ) +{ +#if _WIN32 + if ( !elem ) + return -1; +#if defined( _X360 ) + // this implements CountTrailingZeros() / BitScanForward() + unsigned int mask = elem-1; + unsigned int comp = ~elem; + elem = mask & comp; + return (32 - _CountLeadingZeros(elem)) + offset; +#else + unsigned long out; + _BitScanForward(&out, elem); + return out + offset; +#endif + +#else + static unsigned firstBitLUT[256] = + { + 0,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0, + 3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0, + 3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0, + 3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0 + }; + unsigned elemByte; + + elemByte = (elem & 0xFF); + if ( elemByte ) + return offset + firstBitLUT[elemByte]; + + elem >>= 8; + offset += 8; + elemByte = (elem & 0xFF); + if ( elemByte ) + return offset + firstBitLUT[elemByte]; + + elem >>= 8; + offset += 8; + elemByte = (elem & 0xFF); + if ( elemByte ) + return offset + firstBitLUT[elemByte]; + + elem >>= 8; + offset += 8; + elemByte = (elem & 0xFF); + if ( elemByte ) + return offset + firstBitLUT[elemByte]; + + return -1; +#endif +} + +//------------------------------------- + +inline unsigned GetEndMask( int numBits ) +{ + static unsigned bitStringEndMasks[] = + { + 0xffffffff, + 0x00000001, + 0x00000003, + 0x00000007, + 0x0000000f, + 0x0000001f, + 0x0000003f, + 0x0000007f, + 0x000000ff, + 0x000001ff, + 0x000003ff, + 0x000007ff, + 0x00000fff, + 0x00001fff, + 0x00003fff, + 0x00007fff, + 0x0000ffff, + 0x0001ffff, + 0x0003ffff, + 0x0007ffff, + 0x000fffff, + 0x001fffff, + 0x003fffff, + 0x007fffff, + 0x00ffffff, + 0x01ffffff, + 0x03ffffff, + 0x07ffffff, + 0x0fffffff, + 0x1fffffff, + 0x3fffffff, + 0x7fffffff, + }; + + return bitStringEndMasks[numBits % BITS_PER_INT]; +} + + +inline int GetBitForBitnum( int bitNum ) +{ + static int bitsForBitnum[] = + { + ( 1 << 0 ), + ( 1 << 1 ), + ( 1 << 2 ), + ( 1 << 3 ), + ( 1 << 4 ), + ( 1 << 5 ), + ( 1 << 6 ), + ( 1 << 7 ), + ( 1 << 8 ), + ( 1 << 9 ), + ( 1 << 10 ), + ( 1 << 11 ), + ( 1 << 12 ), + ( 1 << 13 ), + ( 1 << 14 ), + ( 1 << 15 ), + ( 1 << 16 ), + ( 1 << 17 ), + ( 1 << 18 ), + ( 1 << 19 ), + ( 1 << 20 ), + ( 1 << 21 ), + ( 1 << 22 ), + ( 1 << 23 ), + ( 1 << 24 ), + ( 1 << 25 ), + ( 1 << 26 ), + ( 1 << 27 ), + ( 1 << 28 ), + ( 1 << 29 ), + ( 1 << 30 ), + ( 1 << 31 ), + }; + + return bitsForBitnum[ (bitNum) & (BITS_PER_INT-1) ]; +} + +inline int GetBitForBitnumByte( int bitNum ) +{ + static int bitsForBitnum[] = + { + ( 1 << 0 ), + ( 1 << 1 ), + ( 1 << 2 ), + ( 1 << 3 ), + ( 1 << 4 ), + ( 1 << 5 ), + ( 1 << 6 ), + ( 1 << 7 ), + }; + + return bitsForBitnum[ bitNum & 7 ]; +} + +inline int CalcNumIntsForBits( int numBits ) { return (numBits + (BITS_PER_INT-1)) / BITS_PER_INT; } + +#ifdef _X360 +#define BitVec_Bit( bitNum ) GetBitForBitnum( bitNum ) +#define BitVec_BitInByte( bitNum ) GetBitForBitnumByte( bitNum ) +#else +#define BitVec_Bit( bitNum ) ( 1 << ( (bitNum) & (BITS_PER_INT-1) ) ) +#define BitVec_BitInByte( bitNum ) ( 1 << ( (bitNum) & 7 ) ) +#endif +#define BitVec_Int( bitNum ) ( (bitNum) >> LOG2_BITS_PER_INT ) + + +//----------------------------------------------------------------------------- +// template CBitVecT +// +// Defines the operations relevant to any bit array. Simply requires a base +// class that implements GetNumBits(), Base(), GetNumDWords() & ValidateOperand() +// +// CVarBitVec and CBitVec are the actual classes generally used +// by clients +// + +template +class CBitVecT : public BASE_OPS +{ +public: + CBitVecT(); + CBitVecT(int numBits); // Must be initialized with the number of bits + + void Init(int val = 0); + + // Access the bits like an array. + CBitVecAccessor operator[](int i); + + // Do NOT override bitwise operators (see note in header) + void And(const CBitVecT &andStr, CBitVecT *out) const; + void Or(const CBitVecT &orStr, CBitVecT *out) const; + void Xor(const CBitVecT &orStr, CBitVecT *out) const; + + void Not(CBitVecT *out) const; + + void CopyTo(CBitVecT *out) const; + void Copy( const CBitVecT &other, int nBits=-1 ); + bool Compare( const CBitVecT &other, int nBits=-1 ) const; + + bool IsAllClear(void) const; // Are all bits zero? + bool IsAllSet(void) const; // Are all bits one? + + uint32 Get( uint32 bitNum ) const; + bool IsBitSet( int bitNum ) const; + void Set( int bitNum ); + void Set( int bitNum, bool bNewVal ); + void Clear(int bitNum); + + bool TestAndSet(int bitNum); + + void Set( uint32 offset, uint32 mask ); + void Clear( uint32 offset, uint32 mask ); + uint32 Get( uint32 offset, uint32 mask ); + + void SetAll(void); // Sets all bits + void ClearAll(void); // Clears all bits + + uint32 GetDWord(int i) const; + void SetDWord(int i, uint32 val); + + CBitVecT& operator=(const CBitVecT &other) { other.CopyTo( this ); return *this; } + bool operator==(const CBitVecT &other) { return Compare( other ); } + bool operator!=(const CBitVecT &other) { return !operator==( other ); } + + static void GetOffsetMaskForBit( uint32 bitNum, uint32 *pOffset, uint32 *pMask ) { *pOffset = BitVec_Int( bitNum ); *pMask = BitVec_Bit( bitNum ); } +}; + +//----------------------------------------------------------------------------- +// class CVarBitVecBase +// +// Defines the operations necessary for a variable sized bit array +template +class CVarBitVecBase +{ +public: + bool IsFixedSize() const { return false; } + int GetNumBits(void) const { return m_numBits; } + void Resize( int numBits, bool bClearAll = false ); // resizes bit array + + int GetNumDWords() const { return m_numInts; } + uint32 *Base() { return m_pInt; } + const uint32 *Base() const { return m_pInt; } + + void Attach( uint32 *pBits, int numBits ); + bool Detach( uint32 **ppBits, int *pNumBits ); + + int FindNextSetBit(int iStartBit) const; // returns -1 if no set bit was found + +protected: + CVarBitVecBase(); + CVarBitVecBase(int numBits); + CVarBitVecBase( const CVarBitVecBase &from ); + CVarBitVecBase &operator=( const CVarBitVecBase &from ); + ~CVarBitVecBase(void); + + void ValidateOperand( const CVarBitVecBase &operand ) const { Assert(GetNumBits() == operand.GetNumBits()); } + + unsigned GetEndMask() const { return ::GetEndMask( GetNumBits() ); } + +private: + + BITCOUNTTYPE m_numBits; // Number of bits in the bitstring + BITCOUNTTYPE m_numInts; // Number of ints to needed to store bitstring + uint32 m_iBitStringStorage; // If the bit string fits in one int, it goes here + uint32 * m_pInt; // Array of ints containing the bitstring + + void AllocInts( int numInts ); // Free the allocated bits + void ReallocInts( int numInts ); + void FreeInts( void ); // Free the allocated bits +}; + +//----------------------------------------------------------------------------- +// class CFixedBitVecBase +// +// Defines the operations necessary for a fixed sized bit array. +// + +template struct BitCountToEndMask_t { }; +template <> struct BitCountToEndMask_t< 0> { enum { MASK = 0xffffffff }; }; +template <> struct BitCountToEndMask_t< 1> { enum { MASK = 0x00000001 }; }; +template <> struct BitCountToEndMask_t< 2> { enum { MASK = 0x00000003 }; }; +template <> struct BitCountToEndMask_t< 3> { enum { MASK = 0x00000007 }; }; +template <> struct BitCountToEndMask_t< 4> { enum { MASK = 0x0000000f }; }; +template <> struct BitCountToEndMask_t< 5> { enum { MASK = 0x0000001f }; }; +template <> struct BitCountToEndMask_t< 6> { enum { MASK = 0x0000003f }; }; +template <> struct BitCountToEndMask_t< 7> { enum { MASK = 0x0000007f }; }; +template <> struct BitCountToEndMask_t< 8> { enum { MASK = 0x000000ff }; }; +template <> struct BitCountToEndMask_t< 9> { enum { MASK = 0x000001ff }; }; +template <> struct BitCountToEndMask_t<10> { enum { MASK = 0x000003ff }; }; +template <> struct BitCountToEndMask_t<11> { enum { MASK = 0x000007ff }; }; +template <> struct BitCountToEndMask_t<12> { enum { MASK = 0x00000fff }; }; +template <> struct BitCountToEndMask_t<13> { enum { MASK = 0x00001fff }; }; +template <> struct BitCountToEndMask_t<14> { enum { MASK = 0x00003fff }; }; +template <> struct BitCountToEndMask_t<15> { enum { MASK = 0x00007fff }; }; +template <> struct BitCountToEndMask_t<16> { enum { MASK = 0x0000ffff }; }; +template <> struct BitCountToEndMask_t<17> { enum { MASK = 0x0001ffff }; }; +template <> struct BitCountToEndMask_t<18> { enum { MASK = 0x0003ffff }; }; +template <> struct BitCountToEndMask_t<19> { enum { MASK = 0x0007ffff }; }; +template <> struct BitCountToEndMask_t<20> { enum { MASK = 0x000fffff }; }; +template <> struct BitCountToEndMask_t<21> { enum { MASK = 0x001fffff }; }; +template <> struct BitCountToEndMask_t<22> { enum { MASK = 0x003fffff }; }; +template <> struct BitCountToEndMask_t<23> { enum { MASK = 0x007fffff }; }; +template <> struct BitCountToEndMask_t<24> { enum { MASK = 0x00ffffff }; }; +template <> struct BitCountToEndMask_t<25> { enum { MASK = 0x01ffffff }; }; +template <> struct BitCountToEndMask_t<26> { enum { MASK = 0x03ffffff }; }; +template <> struct BitCountToEndMask_t<27> { enum { MASK = 0x07ffffff }; }; +template <> struct BitCountToEndMask_t<28> { enum { MASK = 0x0fffffff }; }; +template <> struct BitCountToEndMask_t<29> { enum { MASK = 0x1fffffff }; }; +template <> struct BitCountToEndMask_t<30> { enum { MASK = 0x3fffffff }; }; +template <> struct BitCountToEndMask_t<31> { enum { MASK = 0x7fffffff }; }; + +//------------------------------------- + +template +class CFixedBitVecBase +{ +public: + bool IsFixedSize() const { return true; } + int GetNumBits(void) const { return NUM_BITS; } + void Resize( int numBits, bool bClearAll = false ) { Assert(numBits == NUM_BITS); if ( bClearAll ) Plat_FastMemset( m_Ints, 0, NUM_INTS * sizeof(uint32) ); }// for syntatic consistency (for when using templates) + + int GetNumDWords() const { return NUM_INTS; } + uint32 * Base() { return m_Ints; } + const uint32 * Base() const { return m_Ints; } + + int FindNextSetBit(int iStartBit) const; // returns -1 if no set bit was found + +protected: + CFixedBitVecBase() {} + CFixedBitVecBase(int numBits) { Assert( numBits == NUM_BITS ); } // doesn't make sense, really. Supported to simplify templates & allow easy replacement of variable + + void ValidateOperand( const CFixedBitVecBase &operand ) const { } // no need, compiler does so statically + +public: // for test code + unsigned GetEndMask() const { return static_cast( BitCountToEndMask_t::MASK ); } + +private: + enum + { + NUM_INTS = (NUM_BITS + (BITS_PER_INT-1)) / BITS_PER_INT + }; + + uint32 m_Ints[(NUM_BITS + (BITS_PER_INT-1)) / BITS_PER_INT]; +}; + +//----------------------------------------------------------------------------- +// +// The actual classes used +// + +// inheritance instead of typedef to allow forward declarations +class CVarBitVec : public CBitVecT< CVarBitVecBase > +{ +public: + CVarBitVec() + { + } + + CVarBitVec(int numBits) + : CBitVecT< CVarBitVecBase >(numBits) + { + } +}; + +class CLargeVarBitVec : public CBitVecT< CVarBitVecBase > +{ +public: + CLargeVarBitVec() + { + } + + CLargeVarBitVec(int numBits) + : CBitVecT< CVarBitVecBase >(numBits) + { + } +}; + +//----------------------------------------------------------------------------- + +template < int NUM_BITS > +class CBitVec : public CBitVecT< CFixedBitVecBase > +{ +public: + CBitVec() + { + } + + CBitVec(int numBits) + : CBitVecT< CFixedBitVecBase >(numBits) + { + } +}; + + +//----------------------------------------------------------------------------- + +typedef CBitVec<32> CDWordBitVec; + +//----------------------------------------------------------------------------- + +template +inline CVarBitVecBase::CVarBitVecBase() +{ + Plat_FastMemset( this, 0, sizeof( *this ) ); +} + +//----------------------------------------------------------------------------- + +template +inline CVarBitVecBase::CVarBitVecBase(int numBits) +{ + Assert( numBits ); + m_numBits = numBits; + + // Figure out how many ints are needed + m_numInts = CalcNumIntsForBits( numBits ); + m_pInt = NULL; + AllocInts( m_numInts ); +} + +//----------------------------------------------------------------------------- + +template +inline CVarBitVecBase::CVarBitVecBase( const CVarBitVecBase &from ) +{ + if ( from.m_numInts ) + { + m_numBits = from.m_numBits; + m_numInts = from.m_numInts; + m_pInt = NULL; + AllocInts( m_numInts ); + memcpy( m_pInt, from.m_pInt, m_numInts * sizeof(int) ); + } + else + memset( this, 0, sizeof( *this ) ); +} + +//----------------------------------------------------------------------------- + +template +inline CVarBitVecBase &CVarBitVecBase::operator=( const CVarBitVecBase &from ) +{ + Resize( from.GetNumBits() ); + if ( m_pInt ) + memcpy( m_pInt, from.m_pInt, m_numInts * sizeof(int) ); + return (*this); +} + +//----------------------------------------------------------------------------- +// Purpose: Destructor +// Input : +// Output : +//----------------------------------------------------------------------------- + +template +inline CVarBitVecBase::~CVarBitVecBase(void) +{ + FreeInts(); +} + +//----------------------------------------------------------------------------- + +template +inline void CVarBitVecBase::Attach( uint32 *pBits, int numBits ) +{ + FreeInts(); + m_numBits = numBits; + m_numInts = CalcNumIntsForBits( numBits ); + if ( m_numInts > 1 ) + { + m_pInt = pBits; + } + else + { + m_iBitStringStorage = *pBits; + m_pInt = &m_iBitStringStorage; + free( pBits ); + } +} + +//----------------------------------------------------------------------------- + +template +inline bool CVarBitVecBase::Detach( uint32 **ppBits, int *pNumBits ) +{ + if ( !m_numBits ) + { + return false; + } + + *pNumBits = m_numBits; + if ( m_numInts > 1 ) + { + *ppBits = m_pInt; + } + else + { + *ppBits = (uint32 *)malloc( sizeof(uint32) ); + **ppBits = m_iBitStringStorage; + free( m_pInt ); + } + + memset( this, 0, sizeof( *this ) ); + return true; +} + +//----------------------------------------------------------------------------- + +template +inline CBitVecT::CBitVecT() +{ + // undef this is ints are not 4 bytes + // generate a compile error if sizeof(int) is not 4 (HACK: can't use the preprocessor so use the compiler) + + COMPILE_TIME_ASSERT( sizeof(int)==4 ); + + // Initialize bitstring by clearing all bits + ClearAll(); +} + +//----------------------------------------------------------------------------- +template +inline CBitVecT::CBitVecT(int numBits) + : BASE_OPS( numBits ) +{ + // undef this is ints are not 4 bytes + // generate a compile error if sizeof(int) is not 4 (HACK: can't use the preprocessor so use the compiler) + + COMPILE_TIME_ASSERT( sizeof(int)==4 ); + + // Initialize bitstring by clearing all bits + ClearAll(); +} + +//----------------------------------------------------------------------------- + +template +inline CBitVecAccessor CBitVecT::operator[](int i) +{ + Assert(i >= 0 && i < this->GetNumBits()); + return CBitVecAccessor(this->Base(), i); +} + + +//----------------------------------------------------------------------------- + +template +inline void CBitVecT::Init( int val ) +{ + if ( this->Base() ) + Plat_FastMemset( this->Base(), ( val ) ? 0xff : 0, this->GetNumDWords() * sizeof(int) ); +} + +//----------------------------------------------------------------------------- + +template +inline uint32 CBitVecT::Get( uint32 bitNum ) const +{ + Assert( bitNum < (uint32)this->GetNumBits() ); + const uint32 *pInt = this->Base() + BitVec_Int( bitNum ); + return ( *pInt & BitVec_Bit( bitNum ) ); +} + +//----------------------------------------------------------------------------- + +template +inline bool CBitVecT::IsBitSet( int bitNum ) const +{ + Assert( bitNum >= 0 && bitNum < this->GetNumBits() ); + const uint32 *pInt = this->Base() + BitVec_Int( bitNum ); + return ( ( *pInt & BitVec_Bit( bitNum ) ) != 0 ); +} + +//----------------------------------------------------------------------------- + +template +inline void CBitVecT::Set( int bitNum ) +{ + Assert( bitNum >= 0 && bitNum < this->GetNumBits() ); + uint32 *pInt = this->Base() + BitVec_Int( bitNum ); + *pInt |= BitVec_Bit( bitNum ); +} + +//----------------------------------------------------------------------------- + +template +inline bool CBitVecT::TestAndSet(int bitNum) +{ + Assert( bitNum >= 0 && bitNum < this->GetNumBits() ); + uint32 bitVecBit = BitVec_Bit( bitNum ); + uint32 *pInt = this->Base() + BitVec_Int( bitNum ); + bool bResult = ( ( *pInt & bitVecBit) != 0 ); + *pInt |= bitVecBit; + return bResult; +} + +//----------------------------------------------------------------------------- + +template +inline void CBitVecT::Clear(int bitNum) +{ + Assert( bitNum >= 0 && bitNum < this->GetNumBits() ); + uint32 *pInt = this->Base() + BitVec_Int( bitNum ); + *pInt &= ~BitVec_Bit( bitNum ); +} + +//----------------------------------------------------------------------------- + +template +inline void CBitVecT::Set( int bitNum, bool bNewVal ) +{ + uint32 *pInt = this->Base() + BitVec_Int( bitNum ); + uint32 bitMask = BitVec_Bit( bitNum ); + if ( bNewVal ) + { + *pInt |= bitMask; + } + else + { + *pInt &= ~bitMask; + } +} + +//----------------------------------------------------------------------------- + +template +inline void CBitVecT::Set( uint32 offset, uint32 mask ) +{ + uint32 *pInt = this->Base() + offset; + *pInt |= mask; +} + +//----------------------------------------------------------------------------- + +template +inline void CBitVecT::Clear( uint32 offset, uint32 mask ) +{ + uint32 *pInt = this->Base() + offset; + *pInt &= ~mask; +} + +//----------------------------------------------------------------------------- + +template +inline uint32 CBitVecT::Get( uint32 offset, uint32 mask ) +{ + uint32 *pInt = this->Base() + offset; + return ( *pInt & mask ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +template +inline void CBitVecT::And(const CBitVecT &addStr, CBitVecT *out) const +{ + this->ValidateOperand( addStr ); + this->ValidateOperand( *out ); + + uint32 * pDest = out->Base(); + const uint32 *pOperand1 = this->Base(); + const uint32 *pOperand2 = addStr.Base(); + + for (int i = this->GetNumDWords() - 1; i >= 0 ; --i) + { + pDest[i] = pOperand1[i] & pOperand2[i]; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +template +inline void CBitVecT::Or(const CBitVecT &orStr, CBitVecT *out) const +{ + this->ValidateOperand( orStr ); + this->ValidateOperand( *out ); + + uint32 * pDest = out->Base(); + const uint32 *pOperand1 = this->Base(); + const uint32 *pOperand2 = orStr.Base(); + + for (int i = this->GetNumDWords() - 1; i >= 0; --i) + { + pDest[i] = pOperand1[i] | pOperand2[i]; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +template +inline void CBitVecT::Xor(const CBitVecT &xorStr, CBitVecT *out) const +{ + uint32 * pDest = out->Base(); + const uint32 *pOperand1 = this->Base(); + const uint32 *pOperand2 = xorStr.Base(); + + for (int i = this->GetNumDWords() - 1; i >= 0; --i) + { + pDest[i] = pOperand1[i] ^ pOperand2[i]; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : +// Output : +//----------------------------------------------------------------------------- +template +inline void CBitVecT::Not(CBitVecT *out) const +{ + this->ValidateOperand( *out ); + + uint32 * pDest = out->Base(); + const uint32 *pOperand = this->Base(); + + for (int i = this->GetNumDWords() - 1; i >= 0; --i) + { + pDest[i] = ~(pOperand[i]); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Copy a bit string +// Input : +// Output : +//----------------------------------------------------------------------------- +template +inline void CBitVecT::CopyTo(CBitVecT *out) const +{ + out->Resize( this->GetNumBits() ); + + this->ValidateOperand( *out ); + Assert( out != this ); + + memcpy( out->Base(), this->Base(), this->GetNumDWords() * sizeof( int ) ); +} + +//----------------------------------------------------------------------------- +// Purpose: Are all bits zero? +// Input : +// Output : +//----------------------------------------------------------------------------- +template +inline bool CBitVecT::IsAllClear(void) const +{ + // Number of available bits may be more than the number + // actually used, so make sure to mask out unused bits + // before testing for zero + (const_cast(this))->Base()[this->GetNumDWords()-1] &= CBitVecT::GetEndMask(); // external semantics of const retained + + for (int i = this->GetNumDWords() - 1; i >= 0; --i) + { + if ( this->Base()[i] !=0 ) + { + return false; + } + } + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Are all bits set? +// Input : +// Output : +//----------------------------------------------------------------------------- +template +inline bool CBitVecT::IsAllSet(void) const +{ + // Number of available bits may be more than the number + // actually used, so make sure to mask out unused bits + // before testing for set bits + (const_cast(this))->Base()[this->GetNumDWords()-1] |= ~CBitVecT::GetEndMask(); // external semantics of const retained + + for (int i = this->GetNumDWords() - 1; i >= 0; --i) + { + if ( this->Base()[i] != ~0 ) + { + return false; + } + } + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Sets all bits +// Input : +// Output : +//----------------------------------------------------------------------------- +template +inline void CBitVecT::SetAll(void) +{ + if ( this->Base() ) + Plat_FastMemset( this->Base(), 0xff, this->GetNumDWords() * sizeof(int) ); +} + +//----------------------------------------------------------------------------- +// Purpose: Clears all bits +// Input : +// Output : +//----------------------------------------------------------------------------- +template +inline void CBitVecT::ClearAll(void) +{ + if ( this->Base() ) + Plat_FastMemset( this->Base(), 0, this->GetNumDWords() * sizeof(int) ); +} + +//----------------------------------------------------------------------------- +template +inline void CBitVecT::Copy( const CBitVecT &other, int nBits ) +{ + if ( nBits == - 1 ) + { + nBits = other.GetNumBits(); + } + + this->Resize( nBits ); + + this->ValidateOperand( other ); + Assert( &other != this ); + + memcpy( this->Base(), other.Base(), this->GetNumDWords() * sizeof( uint32 ) ); +} + +//----------------------------------------------------------------------------- +template +inline bool CBitVecT::Compare( const CBitVecT &other, int nBits ) const +{ + if ( nBits == - 1 ) + { + if ( other.GetNumBits() != this->GetNumBits() ) + { + return false; + } + + nBits = other.GetNumBits(); + } + + if ( nBits > other.GetNumBits() || nBits > this->GetNumBits() ) + { + return false; + } + + (const_cast(this))->Base()[this->GetNumDWords()-1] &= CBitVecT::GetEndMask(); // external semantics of const retained + (const_cast(&other))->Base()[this->GetNumDWords()-1] &= other.CBitVecT::GetEndMask(); // external semantics of const retained + + int nBytes = PAD_NUMBER( nBits, 8 ) >> 3; + + return ( memcmp( this->Base(), other.Base(), nBytes ) == 0 ); +} + +//----------------------------------------------------------------------------- +template +inline uint32 CBitVecT::GetDWord(int i) const +{ + Assert(i >= 0 && i < this->GetNumDWords()); + return this->Base()[i]; +} + +//----------------------------------------------------------------------------- +template +inline void CBitVecT::SetDWord(int i, uint32 val) +{ + Assert(i >= 0 && i < this->GetNumDWords()); + this->Base()[i] = val; +} + +//----------------------------------------------------------------------------- + +inline unsigned GetStartBitMask( int startBit ) +{ + static unsigned int g_StartMask[32] = + { + 0xffffffff, + 0xfffffffe, + 0xfffffffc, + 0xfffffff8, + 0xfffffff0, + 0xffffffe0, + 0xffffffc0, + 0xffffff80, + 0xffffff00, + 0xfffffe00, + 0xfffffc00, + 0xfffff800, + 0xfffff000, + 0xffffe000, + 0xffffc000, + 0xffff8000, + 0xffff0000, + 0xfffe0000, + 0xfffc0000, + 0xfff80000, + 0xfff00000, + 0xffe00000, + 0xffc00000, + 0xff800000, + 0xff000000, + 0xfe000000, + 0xfc000000, + 0xf8000000, + 0xf0000000, + 0xe0000000, + 0xc0000000, + 0x80000000, + }; + + return g_StartMask[ startBit & 31 ]; +} + +template +inline int CVarBitVecBase::FindNextSetBit( int startBit ) const +{ + if ( startBit < GetNumBits() ) + { + int wordIndex = BitVec_Int(startBit); + unsigned int startMask = GetStartBitMask( startBit ); + int lastWord = GetNumDWords()-1; + + // handle non dword lengths + if ( (GetNumBits() % BITS_PER_INT) != 0 ) + { + unsigned int elem = Base()[wordIndex]; + elem &= startMask; + if ( wordIndex == lastWord) + { + elem &= (GetEndMask()); + // there's a bit remaining in this word + if ( elem ) + return FirstBitInWord(elem, wordIndex << 5); + } + else + { + // there's a bit remaining in this word + if ( elem ) + return FirstBitInWord(elem, wordIndex << 5); + + // iterate the words + for ( int i = wordIndex+1; i < lastWord; i++ ) + { + elem = Base()[i]; + if ( elem ) + return FirstBitInWord(elem, i << 5); + } + elem = Base()[lastWord] & GetEndMask(); + if ( elem ) + return FirstBitInWord(elem, lastWord << 5); + } + } + else + { + const uint32 * RESTRICT pCurElem = Base() + wordIndex; + unsigned int elem = *pCurElem; + elem &= startMask; + do + { + if ( elem ) + return FirstBitInWord(elem, wordIndex << 5); + ++pCurElem; + elem = *pCurElem; + ++wordIndex; + } while( wordIndex <= lastWord ); + } + + } + + return -1; +} + +template +inline int CFixedBitVecBase::FindNextSetBit( int startBit ) const +{ + if ( startBit < NUM_BITS ) + { + int wordIndex = BitVec_Int(startBit); + unsigned int startMask = GetStartBitMask( startBit ); + + // handle non dword lengths + if ( (NUM_BITS % BITS_PER_INT) != 0 ) + { + unsigned int elem = Base()[wordIndex]; + elem &= startMask; + if ( wordIndex == NUM_INTS-1) + { + elem &= (GetEndMask()); + // there's a bit remaining in this word + if ( elem ) + return FirstBitInWord(elem, wordIndex << 5); + } + else + { + // there's a bit remaining in this word + if ( elem ) + return FirstBitInWord(elem, wordIndex << 5); + + // iterate the words + for ( int i = wordIndex+1; i < NUM_INTS-1; i++ ) + { + elem = Base()[i]; + if ( elem ) + return FirstBitInWord(elem, i << 5); + } + elem = Base()[NUM_INTS-1] & GetEndMask(); + if ( elem ) + return FirstBitInWord(elem, (NUM_INTS-1) << 5); + } + } + else + { + const uint32 * RESTRICT pCurElem = Base() + wordIndex; + unsigned int elem = *pCurElem; + elem &= startMask; + do + { + if ( elem ) + return FirstBitInWord(elem, wordIndex << 5); + ++pCurElem; + elem = *pCurElem; + ++wordIndex; + } while( wordIndex <= NUM_INTS-1); + } + + } + + return -1; +} + +//----------------------------------------------------------------------------- +// Unrolled loops for some common sizes + +template<> +FORCEINLINE_TEMPLATE void CBitVecT< CFixedBitVecBase<256> >::And(const CBitVecT &addStr, CBitVecT *out) const +{ + uint32 * pDest = out->Base(); + const uint32 *pOperand1 = Base(); + const uint32 *pOperand2 = addStr.Base(); + + pDest[0] = pOperand1[0] & pOperand2[0]; + pDest[1] = pOperand1[1] & pOperand2[1]; + pDest[2] = pOperand1[2] & pOperand2[2]; + pDest[3] = pOperand1[3] & pOperand2[3]; + pDest[4] = pOperand1[4] & pOperand2[4]; + pDest[5] = pOperand1[5] & pOperand2[5]; + pDest[6] = pOperand1[6] & pOperand2[6]; + pDest[7] = pOperand1[7] & pOperand2[7]; +} + +template<> +FORCEINLINE_TEMPLATE bool CBitVecT< CFixedBitVecBase<256> >::IsAllClear(void) const +{ + const uint32 *pInts = Base(); + return ( pInts[0] == 0 && pInts[1] == 0 && pInts[2] == 0 && pInts[3] == 0 && pInts[4] == 0 && pInts[5] == 0 && pInts[6] == 0 && pInts[7] == 0 ); +} + +template<> +FORCEINLINE_TEMPLATE void CBitVecT< CFixedBitVecBase<256> >::CopyTo(CBitVecT *out) const +{ + uint32 * pDest = out->Base(); + const uint32 *pInts = Base(); + + pDest[0] = pInts[0]; + pDest[1] = pInts[1]; + pDest[2] = pInts[2]; + pDest[3] = pInts[3]; + pDest[4] = pInts[4]; + pDest[5] = pInts[5]; + pDest[6] = pInts[6]; + pDest[7] = pInts[7]; +} + +template<> +FORCEINLINE_TEMPLATE void CBitVecT< CFixedBitVecBase<128> >::And(const CBitVecT &addStr, CBitVecT *out) const +{ + uint32 * pDest = out->Base(); + const uint32 *pOperand1 = Base(); + const uint32 *pOperand2 = addStr.Base(); + + pDest[0] = pOperand1[0] & pOperand2[0]; + pDest[1] = pOperand1[1] & pOperand2[1]; + pDest[2] = pOperand1[2] & pOperand2[2]; + pDest[3] = pOperand1[3] & pOperand2[3]; +} + +template<> +FORCEINLINE_TEMPLATE bool CBitVecT< CFixedBitVecBase<128> >::IsAllClear(void) const +{ + const uint32 *pInts = Base(); + return ( pInts[0] == 0 && pInts[1] == 0 && pInts[2] == 0 && pInts[3] == 0 ); +} + +template<> +FORCEINLINE_TEMPLATE void CBitVecT< CFixedBitVecBase<128> >::CopyTo(CBitVecT *out) const +{ + uint32 * pDest = out->Base(); + const uint32 *pInts = Base(); + + pDest[0] = pInts[0]; + pDest[1] = pInts[1]; + pDest[2] = pInts[2]; + pDest[3] = pInts[3]; +} + +template<> +inline void CBitVecT< CFixedBitVecBase<96> >::And(const CBitVecT &addStr, CBitVecT *out) const +{ + uint32 * pDest = out->Base(); + const uint32 *pOperand1 = Base(); + const uint32 *pOperand2 = addStr.Base(); + + pDest[0] = pOperand1[0] & pOperand2[0]; + pDest[1] = pOperand1[1] & pOperand2[1]; + pDest[2] = pOperand1[2] & pOperand2[2]; +} + +template<> +inline bool CBitVecT< CFixedBitVecBase<96> >::IsAllClear(void) const +{ + const uint32 *pInts = Base(); + return ( pInts[0] == 0 && pInts[1] == 0 && pInts[2] == 0 ); +} + +template<> +inline void CBitVecT< CFixedBitVecBase<96> >::CopyTo(CBitVecT *out) const +{ + uint32 * pDest = out->Base(); + const uint32 *pInts = Base(); + + pDest[0] = pInts[0]; + pDest[1] = pInts[1]; + pDest[2] = pInts[2]; +} + +template<> +inline void CBitVecT< CFixedBitVecBase<64> >::And(const CBitVecT &addStr, CBitVecT *out) const +{ + uint32 * pDest = out->Base(); + const uint32 *pOperand1 = Base(); + const uint32 *pOperand2 = addStr.Base(); + + pDest[0] = pOperand1[0] & pOperand2[0]; + pDest[1] = pOperand1[1] & pOperand2[1]; +} + +template<> +inline bool CBitVecT< CFixedBitVecBase<64> >::IsAllClear(void) const +{ + const uint32 *pInts = Base(); + return ( pInts[0] == 0 && pInts[1] == 0 ); +} + +template<> +inline void CBitVecT< CFixedBitVecBase<64> >::CopyTo(CBitVecT *out) const +{ + uint32 * pDest = out->Base(); + const uint32 *pInts = Base(); + + pDest[0] = pInts[0]; + pDest[1] = pInts[1]; +} + +template<> +inline void CBitVecT< CFixedBitVecBase<32> >::And(const CBitVecT &addStr, CBitVecT *out) const +{ + uint32 * pDest = out->Base(); + const uint32 *pOperand1 = Base(); + const uint32 *pOperand2 = addStr.Base(); + + pDest[0] = pOperand1[0] & pOperand2[0]; +} + +template<> +inline bool CBitVecT< CFixedBitVecBase<32> >::IsAllClear(void) const +{ + const uint32 *pInts = Base(); + + return ( pInts[0] == 0 ); +} + +template<> +inline void CBitVecT< CFixedBitVecBase<32> >::CopyTo(CBitVecT *out) const +{ + uint32 * pDest = out->Base(); + const uint32 *pInts = Base(); + + pDest[0] = pInts[0]; +} + +//----------------------------------------------------------------------------- + +template <> +inline uint32 CBitVecT< CFixedBitVecBase<32> >::Get( uint32 bitNum ) const +{ + return ( *Base() & BitVec_Bit( bitNum ) ); +} + +//----------------------------------------------------------------------------- + +template <> +inline bool CBitVecT< CFixedBitVecBase<32> >::IsBitSet( int bitNum ) const +{ + return ( ( *Base() & BitVec_Bit( bitNum ) ) != 0 ); +} + +//----------------------------------------------------------------------------- + +template <> +inline void CBitVecT< CFixedBitVecBase<32> >::Set( int bitNum ) +{ + *Base() |= BitVec_Bit( bitNum ); +} + +//----------------------------------------------------------------------------- + +template <> +inline void CBitVecT< CFixedBitVecBase<32> >::Clear(int bitNum) +{ + *Base() &= ~BitVec_Bit( bitNum ); +} + +//----------------------------------------------------------------------------- + +template <> +inline void CBitVecT< CFixedBitVecBase<32> >::Set( int bitNum, bool bNewVal ) +{ + uint32 bitMask = BitVec_Bit( bitNum ); + if ( bNewVal ) + { + *Base() |= bitMask; + } + else + { + *Base() &= ~bitMask; + } +} + + +//----------------------------------------------------------------------------- + +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// Purpose: Resizes the bit string to a new number of bits +// Input : resizeNumBits - +//----------------------------------------------------------------------------- +template +inline void CVarBitVecBase::Resize( int resizeNumBits, bool bClearAll ) +{ + Assert( resizeNumBits >= 0 && ((BITCOUNTTYPE)resizeNumBits == resizeNumBits) ); + + int newIntCount = CalcNumIntsForBits( resizeNumBits ); + if ( newIntCount != GetNumDWords() ) + { + if ( Base() ) + { + ReallocInts( newIntCount ); + if ( !bClearAll && resizeNumBits >= GetNumBits() ) + { + Base()[GetNumDWords() - 1] &= GetEndMask(); + Plat_FastMemset( Base() + GetNumDWords(), 0, (newIntCount - GetNumDWords()) * sizeof(int) ); + } + } + else + { + // Figure out how many ints are needed + AllocInts( newIntCount ); + // Initialize bitstring by clearing all bits + bClearAll = true; + } + + m_numInts = newIntCount; + } + else if ( !bClearAll && resizeNumBits >= GetNumBits() && Base() ) + { + Base()[GetNumDWords() - 1] &= GetEndMask(); + } + + if ( bClearAll && Base() ) + { + Plat_FastMemset( Base(), 0, newIntCount * sizeof(int) ); + } + + // store the new size and end mask + m_numBits = resizeNumBits; +} + +//----------------------------------------------------------------------------- +// Purpose: Allocate the storage for the ints +// Input : numInts - +//----------------------------------------------------------------------------- +template +inline void CVarBitVecBase::AllocInts( int numInts ) +{ + Assert( !m_pInt ); + + if ( numInts == 0 ) + return; + + if ( numInts == 1 ) + { + m_pInt = &m_iBitStringStorage; + return; + } + + m_pInt = (uint32 *)malloc( numInts * sizeof(int) ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Reallocate the storage for the ints +// Input : numInts - +//----------------------------------------------------------------------------- +template +inline void CVarBitVecBase::ReallocInts( int numInts ) +{ + Assert( Base() ); + if ( numInts == 0) + { + FreeInts(); + return; + } + + if ( m_pInt == &m_iBitStringStorage ) + { + if ( numInts != 1 ) + { + m_pInt = ((uint32 *)malloc( numInts * sizeof(int) )); + *m_pInt = m_iBitStringStorage; + } + + return; + } + + if ( numInts == 1 ) + { + m_iBitStringStorage = *m_pInt; + free( m_pInt ); + m_pInt = &m_iBitStringStorage; + return; + } + + m_pInt = (uint32 *)realloc( m_pInt, numInts * sizeof(int) ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Free storage allocated with AllocInts +//----------------------------------------------------------------------------- +template +inline void CVarBitVecBase::FreeInts( void ) +{ + if ( m_numInts > 1 ) + { + free( m_pInt ); + } + m_pInt = NULL; +} + +#include "tier0/memdbgoff.h" + +// ------------------------------------------------------------------------ // +// CBitVecAccessor inlines. +// ------------------------------------------------------------------------ // + +inline CBitVecAccessor::CBitVecAccessor(uint32 *pDWords, int iBit) +{ + m_pDWords = pDWords; + m_iBit = iBit; +} + + +inline void CBitVecAccessor::operator=(int val) +{ + if(val) + m_pDWords[m_iBit >> 5] |= (1 << (m_iBit & 31)); + else + m_pDWords[m_iBit >> 5] &= ~(unsigned long)(1 << (m_iBit & 31)); +} + +inline CBitVecAccessor::operator uint32() +{ + return m_pDWords[m_iBit >> 5] & (1 << (m_iBit & 31)); +} + + +//============================================================================= + +#endif // BITVEC_H diff --git a/sp/src/public/blockingudpsocket.cpp b/sp/src/public/blockingudpsocket.cpp new file mode 100644 index 00000000..aefd54f7 --- /dev/null +++ b/sp/src/public/blockingudpsocket.cpp @@ -0,0 +1,150 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#if defined(_WIN32) && !defined(_X360) +#include +#elif POSIX +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#include +#include +#include +#include +#define closesocket close +#endif + +#include "blockingudpsocket.h" +#include "tier0/vcrmode.h" + +class CBlockingUDPSocket::CImpl +{ +public: + struct sockaddr_in m_SocketIP; + fd_set m_FDSet; +}; + +CBlockingUDPSocket::CBlockingUDPSocket() : + m_cserIP(), + m_Socket( 0 ), + m_pImpl( new CImpl ) +{ + CreateSocket(); +} + +CBlockingUDPSocket::~CBlockingUDPSocket() +{ + delete m_pImpl; + closesocket( static_cast( m_Socket )); +} + +bool CBlockingUDPSocket::CreateSocket (void) +{ + struct sockaddr_in address; + + m_Socket = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ); + if ( m_Socket == INVALID_SOCKET ) + { + return false; + } + + address = m_pImpl->m_SocketIP; + + if ( SOCKET_ERROR == bind( m_Socket, ( struct sockaddr * )&address, sizeof( address ) ) ) + { + return false; + } + +#ifdef _WIN32 + if ( m_pImpl->m_SocketIP.sin_addr.S_un.S_addr == INADDR_ANY ) + { + m_pImpl->m_SocketIP.sin_addr.S_un.S_addr = 0L; + } +#elif POSIX + if ( m_pImpl->m_SocketIP.sin_addr.s_addr == INADDR_ANY ) + { + m_pImpl->m_SocketIP.sin_addr.s_addr = 0L; + } +#endif + + return true; +} + +bool CBlockingUDPSocket::WaitForMessage( float timeOutInSeconds ) +{ + struct timeval tv; + + FD_ZERO( &m_pImpl->m_FDSet ); + FD_SET( m_Socket, &m_pImpl->m_FDSet );//lint !e717 + + tv.tv_sec = (int)timeOutInSeconds; + float remainder = timeOutInSeconds - (int)timeOutInSeconds; + tv.tv_usec = (int)( remainder * 1000000 + 0.5f ); /* micro seconds */ + + if ( SOCKET_ERROR == select( ( int )m_Socket + 1, &m_pImpl->m_FDSet, NULL, NULL, &tv ) ) + { + return false; + } + + if ( FD_ISSET( m_Socket, &m_pImpl->m_FDSet) ) + { + return true; + } + + // Timed out + return false; +} + +unsigned int CBlockingUDPSocket::ReceiveSocketMessage( struct sockaddr_in *packet_from, unsigned char *buf, size_t bufsize ) +{ + memset( packet_from, 0, sizeof( *packet_from ) ); + + struct sockaddr fromaddress; + int fromlen = sizeof( fromaddress ); + + int packet_length = VCRHook_recvfrom + ( + m_Socket, + (char *)buf, + (int)bufsize, + 0, + &fromaddress, + &fromlen + ); + + if ( SOCKET_ERROR == packet_length ) + { + return 0; + } + + // In case it's parsed as a string + buf[ packet_length ] = 0; + + // Copy over the receive address + *packet_from = *( struct sockaddr_in * )&fromaddress; + + return ( unsigned int )packet_length; +} + +bool CBlockingUDPSocket::SendSocketMessage( const struct sockaddr_in & rRecipient, const unsigned char *buf, size_t bufsize ) +{ + // Send data + int bytesSent = sendto + ( + m_Socket, + (const char *)buf, + (int)bufsize, + 0, + reinterpret_cast< const sockaddr * >( &rRecipient ), + sizeof( rRecipient ) + ); + + if ( SOCKET_ERROR == bytesSent ) + { + return false; + } + + return true; +} diff --git a/sp/src/public/blockingudpsocket.h b/sp/src/public/blockingudpsocket.h new file mode 100644 index 00000000..2f605550 --- /dev/null +++ b/sp/src/public/blockingudpsocket.h @@ -0,0 +1,39 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef BLOCKINGUDPSOCKET_H +#define BLOCKINGUDPSOCKET_H +#ifdef _WIN32 +#pragma once +#endif + +#include "netadr.h" + +class CBlockingUDPSocket +{ +public: + explicit CBlockingUDPSocket(); + virtual ~CBlockingUDPSocket(); + + bool WaitForMessage( float timeOutInSeconds ); + unsigned int ReceiveSocketMessage( struct sockaddr_in *packet_from, unsigned char *buf, size_t bufsize ); + bool SendSocketMessage( const struct sockaddr_in& rRecipient, const unsigned char *buf, size_t bufsize ); + + bool IsValid() const { return m_Socket != 0; } + +protected: + bool CreateSocket (void); + + class CImpl; + CImpl *m_pImpl; + + netadr_t m_cserIP; + unsigned int m_Socket; + + +}; + +#endif // BLOCKINGUDPSOCKET_H diff --git a/sp/src/public/bone_accessor.cpp b/sp/src/public/bone_accessor.cpp new file mode 100644 index 00000000..f8edd104 --- /dev/null +++ b/sp/src/public/bone_accessor.cpp @@ -0,0 +1,34 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" +#include "bone_accessor.h" + + +#if defined( CLIENT_DLL ) && defined( _DEBUG ) + + void CBoneAccessor::SanityCheckBone( int iBone, bool bReadable ) const + { + if ( m_pAnimating ) + { + CStudioHdr *pHdr = m_pAnimating->GetModelPtr(); + if ( pHdr ) + { + mstudiobone_t *pBone = pHdr->pBone( iBone ); + if ( bReadable ) + { + AssertOnce( pBone->flags & m_ReadableBones ); + } + else + { + AssertOnce( pBone->flags & m_WritableBones ); + } + } + } + } + +#endif + diff --git a/sp/src/public/bone_accessor.h b/sp/src/public/bone_accessor.h new file mode 100644 index 00000000..99e07f9f --- /dev/null +++ b/sp/src/public/bone_accessor.h @@ -0,0 +1,131 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef BONE_ACCESSOR_H +#define BONE_ACCESSOR_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "studio.h" + + +class C_BaseAnimating; + + +class CBoneAccessor +{ +public: + + CBoneAccessor(); + CBoneAccessor( matrix3x4_t *pBones ); // This can be used to allow access to all bones. + + // Initialize. +#if defined( CLIENT_DLL ) + void Init( const C_BaseAnimating *pAnimating, matrix3x4_t *pBones ); +#endif + + int GetReadableBones(); + void SetReadableBones( int flags ); + + int GetWritableBones(); + void SetWritableBones( int flags ); + + // Get bones for read or write access. + const matrix3x4_t& GetBone( int iBone ) const; + const matrix3x4_t& operator[]( int iBone ) const; + matrix3x4_t& GetBoneForWrite( int iBone ); + + matrix3x4_t *GetBoneArrayForWrite( ) const; + +private: + +#if defined( CLIENT_DLL ) && defined( _DEBUG ) + void SanityCheckBone( int iBone, bool bReadable ) const; +#endif + + // Only used in the client DLL for debug verification. + const C_BaseAnimating *m_pAnimating; + + matrix3x4_t *m_pBones; + + int m_ReadableBones; // Which bones can be read. + int m_WritableBones; // Which bones can be written. +}; + + +inline CBoneAccessor::CBoneAccessor() +{ + m_pAnimating = NULL; + m_pBones = NULL; + m_ReadableBones = m_WritableBones = 0; +} + +inline CBoneAccessor::CBoneAccessor( matrix3x4_t *pBones ) +{ + m_pAnimating = NULL; + m_pBones = pBones; +} + +#if defined( CLIENT_DLL ) + inline void CBoneAccessor::Init( const C_BaseAnimating *pAnimating, matrix3x4_t *pBones ) + { + m_pAnimating = pAnimating; + m_pBones = pBones; + } +#endif + +inline int CBoneAccessor::GetReadableBones() +{ + return m_ReadableBones; +} + +inline void CBoneAccessor::SetReadableBones( int flags ) +{ + m_ReadableBones = flags; +} + +inline int CBoneAccessor::GetWritableBones() +{ + return m_WritableBones; +} + +inline void CBoneAccessor::SetWritableBones( int flags ) +{ + m_WritableBones = flags; +} + +inline const matrix3x4_t& CBoneAccessor::GetBone( int iBone ) const +{ +#if defined( CLIENT_DLL ) && defined( _DEBUG ) + SanityCheckBone( iBone, true ); +#endif + return m_pBones[iBone]; +} + +inline const matrix3x4_t& CBoneAccessor::operator[]( int iBone ) const +{ +#if defined( CLIENT_DLL ) && defined( _DEBUG ) + SanityCheckBone( iBone, true ); +#endif + return m_pBones[iBone]; +} + +inline matrix3x4_t& CBoneAccessor::GetBoneForWrite( int iBone ) +{ +#if defined( CLIENT_DLL ) && defined( _DEBUG ) + SanityCheckBone( iBone, false ); +#endif + return m_pBones[iBone]; +} + +inline matrix3x4_t *CBoneAccessor::GetBoneArrayForWrite( void ) const +{ + return m_pBones; +} + +#endif // BONE_ACCESSOR_H diff --git a/sp/src/public/bone_setup.cpp b/sp/src/public/bone_setup.cpp new file mode 100644 index 00000000..250133d5 --- /dev/null +++ b/sp/src/public/bone_setup.cpp @@ -0,0 +1,6048 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#include "tier0/dbg.h" +#include "mathlib/mathlib.h" +#include "bone_setup.h" +#include + +#include "collisionutils.h" +#include "vstdlib/random.h" +#include "tier0/vprof.h" +#include "bone_accessor.h" +#include "mathlib/ssequaternion.h" +#include "bitvec.h" +#include "datamanager.h" +#include "convar.h" +#include "tier0/tslist.h" +#include "vphysics_interface.h" +#ifdef CLIENT_DLL + #include "posedebugger.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +class CBoneSetup +{ +public: + CBoneSetup( const CStudioHdr *pStudioHdr, int boneMask, const float poseParameter[], IPoseDebugger *pPoseDebugger = NULL ); + void InitPose( Vector pos[], Quaternion q[] ); + void AccumulatePose( Vector pos[], Quaternion q[], int sequence, float cycle, float flWeight, float flTime, CIKContext *pIKContext ); + void CalcAutoplaySequences( Vector pos[], Quaternion q[], float flRealTime, CIKContext *pIKContext ); +private: + void AddSequenceLayers( Vector pos[], Quaternion q[], mstudioseqdesc_t &seqdesc, int sequence, float cycle, float flWeight, float flTime, CIKContext *pIKContext ); + void AddLocalLayers( Vector pos[], Quaternion q[], mstudioseqdesc_t &seqdesc, int sequence, float cycle, float flWeight, float flTime, CIKContext *pIKContext ); +public: + const CStudioHdr *m_pStudioHdr; + int m_boneMask; + const float *m_flPoseParameter; + IPoseDebugger *m_pPoseDebugger; +}; + +// ----------------------------------------------------------------- +template +class CBoneSetupMemoryPool +{ +public: + T *Alloc() + { + T *p = (T *)m_FreeBlocks.Pop(); + if ( !p ) + { + p = new T[MAXSTUDIOBONES]; + if ( ((size_t)p) % TSLIST_NODE_ALIGNMENT != 0 ) + { + DebuggerBreak(); + } + } + + return p; + } + + void Free( T *p ) + { + m_FreeBlocks.Push( (TSLNodeBase_t *)p ); + } + +private: + CTSListBase m_FreeBlocks; +}; + +CBoneSetupMemoryPool g_QaternionPool; +CBoneSetupMemoryPool g_VectorPool; +CBoneSetupMemoryPool g_MatrixPool; + +// ----------------------------------------------------------------- +CBoneCache *CBoneCache::CreateResource( const bonecacheparams_t ¶ms ) +{ + short studioToCachedIndex[MAXSTUDIOBONES]; + short cachedToStudioIndex[MAXSTUDIOBONES]; + int cachedBoneCount = 0; + for ( int i = 0; i < params.pStudioHdr->numbones(); i++ ) + { + // skip bones that aren't part of the boneMask (and aren't the root bone) + if (i != 0 && !(params.pStudioHdr->boneFlags(i) & params.boneMask)) + { + studioToCachedIndex[i] = -1; + continue; + } + studioToCachedIndex[i] = cachedBoneCount; + cachedToStudioIndex[cachedBoneCount] = i; + cachedBoneCount++; + } + int tableSizeStudio = sizeof(short) * params.pStudioHdr->numbones(); + int tableSizeCached = sizeof(short) * cachedBoneCount; + int matrixSize = sizeof(matrix3x4_t) * cachedBoneCount; + int size = ( sizeof(CBoneCache) + tableSizeStudio + tableSizeCached + matrixSize + 3 ) & ~3; + + CBoneCache *pMem = (CBoneCache *)malloc( size ); + Construct( pMem ); + pMem->Init( params, size, studioToCachedIndex, cachedToStudioIndex, cachedBoneCount ); + return pMem; +} + +unsigned int CBoneCache::EstimatedSize( const bonecacheparams_t ¶ms ) +{ + // conservative estimate - max size + return ( params.pStudioHdr->numbones() * (sizeof(short) + sizeof(short) + sizeof(matrix3x4_t)) + 3 ) & ~3; +} + +void CBoneCache::DestroyResource() +{ + free( this ); +} + + +CBoneCache::CBoneCache() +{ + m_size = 0; + m_cachedBoneCount = 0; +} + +void CBoneCache::Init( const bonecacheparams_t ¶ms, unsigned int size, short *pStudioToCached, short *pCachedToStudio, int cachedBoneCount ) +{ + m_cachedBoneCount = cachedBoneCount; + m_size = size; + m_timeValid = params.curtime; + m_boneMask = params.boneMask; + + int studioTableSize = params.pStudioHdr->numbones() * sizeof(short); + m_cachedToStudioOffset = studioTableSize; + memcpy( StudioToCached(), pStudioToCached, studioTableSize ); + + int cachedTableSize = cachedBoneCount * sizeof(short); + memcpy( CachedToStudio(), pCachedToStudio, cachedTableSize ); + + m_matrixOffset = ( m_cachedToStudioOffset + cachedTableSize + 3 ) & ~3; + + UpdateBones( params.pBoneToWorld, params.pStudioHdr->numbones(), params.curtime ); +} + +void CBoneCache::UpdateBones( const matrix3x4_t *pBoneToWorld, int numbones, float curtime ) +{ + matrix3x4_t *pBones = BoneArray(); + const short *pCachedToStudio = CachedToStudio(); + + for ( int i = 0; i < m_cachedBoneCount; i++ ) + { + int index = pCachedToStudio[i]; + MatrixCopy( pBoneToWorld[index], pBones[i] ); + } + m_timeValid = curtime; +} + +matrix3x4_t *CBoneCache::GetCachedBone( int studioIndex ) +{ + int cachedIndex = StudioToCached()[studioIndex]; + if ( cachedIndex >= 0 ) + { + return BoneArray() + cachedIndex; + } + return NULL; +} + +void CBoneCache::ReadCachedBones( matrix3x4_t *pBoneToWorld ) +{ + matrix3x4_t *pBones = BoneArray(); + const short *pCachedToStudio = CachedToStudio(); + for ( int i = 0; i < m_cachedBoneCount; i++ ) + { + MatrixCopy( pBones[i], pBoneToWorld[pCachedToStudio[i]] ); + } +} + +void CBoneCache::ReadCachedBonePointers( matrix3x4_t **bones, int numbones ) +{ + memset( bones, 0, sizeof(matrix3x4_t *) * numbones ); + matrix3x4_t *pBones = BoneArray(); + const short *pCachedToStudio = CachedToStudio(); + for ( int i = 0; i < m_cachedBoneCount; i++ ) + { + bones[pCachedToStudio[i]] = pBones + i; + } +} + +bool CBoneCache::IsValid( float curtime, float dt ) +{ + if ( curtime - m_timeValid <= dt ) + return true; + return false; +} + + +// private functions +matrix3x4_t *CBoneCache::BoneArray() +{ + return (matrix3x4_t *)( (char *)(this+1) + m_matrixOffset ); +} + +short *CBoneCache::StudioToCached() +{ + return (short *)( (char *)(this+1) ); +} + +short *CBoneCache::CachedToStudio() +{ + return (short *)( (char *)(this+1) + m_cachedToStudioOffset ); +} + +// Construct a singleton +static CDataManager g_StudioBoneCache( 128 * 1024L ); + +CBoneCache *Studio_GetBoneCache( memhandle_t cacheHandle ) +{ + AUTO_LOCK( g_StudioBoneCache.AccessMutex() ); + return g_StudioBoneCache.GetResource_NoLock( cacheHandle ); +} + +memhandle_t Studio_CreateBoneCache( bonecacheparams_t ¶ms ) +{ + AUTO_LOCK( g_StudioBoneCache.AccessMutex() ); + return g_StudioBoneCache.CreateResource( params ); +} + +void Studio_DestroyBoneCache( memhandle_t cacheHandle ) +{ + AUTO_LOCK( g_StudioBoneCache.AccessMutex() ); + g_StudioBoneCache.DestroyResource( cacheHandle ); +} + +void Studio_InvalidateBoneCache( memhandle_t cacheHandle ) +{ + AUTO_LOCK( g_StudioBoneCache.AccessMutex() ); + CBoneCache *pCache = g_StudioBoneCache.GetResource_NoLock( cacheHandle ); + if ( pCache ) + { + pCache->m_timeValid = -1.0f; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void BuildBoneChain( + const CStudioHdr *pStudioHdr, + const matrix3x4_t &rootxform, + const Vector pos[], + const Quaternion q[], + int iBone, + matrix3x4_t *pBoneToWorld ) +{ + CBoneBitList boneComputed; + BuildBoneChain( pStudioHdr, rootxform, pos, q, iBone, pBoneToWorld, boneComputed ); + return; +} + + +//----------------------------------------------------------------------------- +// Purpose: return a sub frame rotation for a single bone +//----------------------------------------------------------------------------- +void ExtractAnimValue( int frame, mstudioanimvalue_t *panimvalue, float scale, float &v1, float &v2 ) +{ + if ( !panimvalue ) + { + v1 = v2 = 0; + return; + } + + // Avoids a crash reading off the end of the data + // There is probably a better long-term solution; Ken is going to look into it. + if ( ( panimvalue->num.total == 1 ) && ( panimvalue->num.valid == 1 ) ) + { + v1 = v2 = panimvalue[1].value * scale; + return; + } + + int k = frame; + + // find the data list that has the frame + while (panimvalue->num.total <= k) + { + k -= panimvalue->num.total; + panimvalue += panimvalue->num.valid + 1; + if ( panimvalue->num.total == 0 ) + { + Assert( 0 ); // running off the end of the animation stream is bad + v1 = v2 = 0; + return; + } + } + if (panimvalue->num.valid > k) + { + // has valid animation data + v1 = panimvalue[k+1].value * scale; + + if (panimvalue->num.valid > k + 1) + { + // has valid animation blend data + v2 = panimvalue[k+2].value * scale; + } + else + { + if (panimvalue->num.total > k + 1) + { + // data repeats, no blend + v2 = v1; + } + else + { + // pull blend from first data block in next list + v2 = panimvalue[panimvalue->num.valid+2].value * scale; + } + } + } + else + { + // get last valid data block + v1 = panimvalue[panimvalue->num.valid].value * scale; + if (panimvalue->num.total > k + 1) + { + // data repeats, no blend + v2 = v1; + } + else + { + // pull blend from first data block in next list + v2 = panimvalue[panimvalue->num.valid + 2].value * scale; + } + } +} + + +void ExtractAnimValue( int frame, mstudioanimvalue_t *panimvalue, float scale, float &v1 ) +{ + if ( !panimvalue ) + { + v1 = 0; + return; + } + + int k = frame; + + while (panimvalue->num.total <= k) + { + k -= panimvalue->num.total; + panimvalue += panimvalue->num.valid + 1; + if ( panimvalue->num.total == 0 ) + { + Assert( 0 ); // running off the end of the animation stream is bad + v1 = 0; + return; + } + } + if (panimvalue->num.valid > k) + { + v1 = panimvalue[k+1].value * scale; + } + else + { + // get last valid data block + v1 = panimvalue[panimvalue->num.valid].value * scale; + } +} + +//----------------------------------------------------------------------------- +// Purpose: return a sub frame rotation for a single bone +//----------------------------------------------------------------------------- +void CalcBoneQuaternion( int frame, float s, + const Quaternion &baseQuat, const RadianEuler &baseRot, const Vector &baseRotScale, + int iBaseFlags, const Quaternion &baseAlignment, + const mstudioanim_t *panim, Quaternion &q ) +{ + if ( panim->flags & STUDIO_ANIM_RAWROT ) + { + q = *(panim->pQuat48()); + Assert( q.IsValid() ); + return; + } + + if ( panim->flags & STUDIO_ANIM_RAWROT2 ) + { + q = *(panim->pQuat64()); + Assert( q.IsValid() ); + return; + } + + if ( !(panim->flags & STUDIO_ANIM_ANIMROT) ) + { + if (panim->flags & STUDIO_ANIM_DELTA) + { + q.Init( 0.0f, 0.0f, 0.0f, 1.0f ); + } + else + { + q = baseQuat; + } + return; + } + + mstudioanim_valueptr_t *pValuesPtr = panim->pRotV(); + + if (s > 0.001f) + { + QuaternionAligned q1, q2; + RadianEuler angle1, angle2; + + ExtractAnimValue( frame, pValuesPtr->pAnimvalue( 0 ), baseRotScale.x, angle1.x, angle2.x ); + ExtractAnimValue( frame, pValuesPtr->pAnimvalue( 1 ), baseRotScale.y, angle1.y, angle2.y ); + ExtractAnimValue( frame, pValuesPtr->pAnimvalue( 2 ), baseRotScale.z, angle1.z, angle2.z ); + + if (!(panim->flags & STUDIO_ANIM_DELTA)) + { + angle1.x = angle1.x + baseRot.x; + angle1.y = angle1.y + baseRot.y; + angle1.z = angle1.z + baseRot.z; + angle2.x = angle2.x + baseRot.x; + angle2.y = angle2.y + baseRot.y; + angle2.z = angle2.z + baseRot.z; + } + + Assert( angle1.IsValid() && angle2.IsValid() ); + if (angle1.x != angle2.x || angle1.y != angle2.y || angle1.z != angle2.z) + { + AngleQuaternion( angle1, q1 ); + AngleQuaternion( angle2, q2 ); + + #ifdef _X360 + fltx4 q1simd, q2simd, qsimd; + q1simd = LoadAlignedSIMD( q1 ); + q2simd = LoadAlignedSIMD( q2 ); + qsimd = QuaternionBlendSIMD( q1simd, q2simd, s ); + StoreUnalignedSIMD( q.Base(), qsimd ); + #else + QuaternionBlend( q1, q2, s, q ); + #endif + } + else + { + AngleQuaternion( angle1, q ); + } + } + else + { + RadianEuler angle; + + ExtractAnimValue( frame, pValuesPtr->pAnimvalue( 0 ), baseRotScale.x, angle.x ); + ExtractAnimValue( frame, pValuesPtr->pAnimvalue( 1 ), baseRotScale.y, angle.y ); + ExtractAnimValue( frame, pValuesPtr->pAnimvalue( 2 ), baseRotScale.z, angle.z ); + + if (!(panim->flags & STUDIO_ANIM_DELTA)) + { + angle.x = angle.x + baseRot.x; + angle.y = angle.y + baseRot.y; + angle.z = angle.z + baseRot.z; + } + + Assert( angle.IsValid() ); + AngleQuaternion( angle, q ); + } + + Assert( q.IsValid() ); + + // align to unified bone + if (!(panim->flags & STUDIO_ANIM_DELTA) && (iBaseFlags & BONE_FIXED_ALIGNMENT)) + { + QuaternionAlign( baseAlignment, q, q ); + } +} + +inline void CalcBoneQuaternion( int frame, float s, + const mstudiobone_t *pBone, + const mstudiolinearbone_t *pLinearBones, + const mstudioanim_t *panim, Quaternion &q ) +{ + if (pLinearBones) + { + CalcBoneQuaternion( frame, s, pLinearBones->quat(panim->bone), pLinearBones->rot(panim->bone), pLinearBones->rotscale(panim->bone), pLinearBones->flags(panim->bone), pLinearBones->qalignment(panim->bone), panim, q ); + } + else + { + CalcBoneQuaternion( frame, s, pBone->quat, pBone->rot, pBone->rotscale, pBone->flags, pBone->qAlignment, panim, q ); + } +} + + + + + +//----------------------------------------------------------------------------- +// Purpose: return a sub frame position for a single bone +//----------------------------------------------------------------------------- +void CalcBonePosition( int frame, float s, + const Vector &basePos, const Vector &baseBoneScale, + const mstudioanim_t *panim, Vector &pos ) +{ + if (panim->flags & STUDIO_ANIM_RAWPOS) + { + pos = *(panim->pPos()); + Assert( pos.IsValid() ); + + return; + } + else if (!(panim->flags & STUDIO_ANIM_ANIMPOS)) + { + if (panim->flags & STUDIO_ANIM_DELTA) + { + pos.Init( 0.0f, 0.0f, 0.0f ); + } + else + { + pos = basePos; + } + return; + } + + mstudioanim_valueptr_t *pPosV = panim->pPosV(); + int j; + + if (s > 0.001f) + { + float v1, v2; + for (j = 0; j < 3; j++) + { + ExtractAnimValue( frame, pPosV->pAnimvalue( j ), baseBoneScale[j], v1, v2 ); + pos[j] = v1 * (1.0 - s) + v2 * s; + } + } + else + { + for (j = 0; j < 3; j++) + { + ExtractAnimValue( frame, pPosV->pAnimvalue( j ), baseBoneScale[j], pos[j] ); + } + } + + if (!(panim->flags & STUDIO_ANIM_DELTA)) + { + pos.x = pos.x + basePos.x; + pos.y = pos.y + basePos.y; + pos.z = pos.z + basePos.z; + } + + Assert( pos.IsValid() ); +} + + +inline void CalcBonePosition( int frame, float s, + const mstudiobone_t *pBone, + const mstudiolinearbone_t *pLinearBones, + const mstudioanim_t *panim, Vector &pos ) +{ + if (pLinearBones) + { + CalcBonePosition( frame, s, pLinearBones->pos(panim->bone), pLinearBones->posscale(panim->bone), panim, pos ); + } + else + { + CalcBonePosition( frame, s, pBone->pos, pBone->posscale, panim, pos ); + } +} + + + +void SetupSingleBoneMatrix( + CStudioHdr *pOwnerHdr, + int nSequence, + int iFrame, + int iBone, + matrix3x4_t &mBoneLocal ) +{ + mstudioseqdesc_t &seqdesc = pOwnerHdr->pSeqdesc( nSequence ); + mstudioanimdesc_t &animdesc = pOwnerHdr->pAnimdesc( seqdesc.anim( 0, 0 ) ); + int iLocalFrame = iFrame; + mstudioanim_t *panim = animdesc.pAnim( &iLocalFrame ); + float s = 0; + mstudiobone_t *pbone = pOwnerHdr->pBone( iBone ); + + Quaternion boneQuat; + Vector bonePos; + + // search for bone + while (panim && panim->bone != iBone) + { + panim = panim->pNext(); + } + + // look up animation if found, if not, initialize + if (panim && seqdesc.weight(iBone) > 0) + { + CalcBoneQuaternion( iLocalFrame, s, pbone, NULL, panim, boneQuat ); + CalcBonePosition ( iLocalFrame, s, pbone, NULL, panim, bonePos ); + } + else if (animdesc.flags & STUDIO_DELTA) + { + boneQuat.Init( 0.0f, 0.0f, 0.0f, 1.0f ); + bonePos.Init( 0.0f, 0.0f, 0.0f ); + } + else + { + boneQuat = pbone->quat; + bonePos = pbone->pos; + } + + QuaternionMatrix( boneQuat, bonePos, mBoneLocal ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +static void CalcDecompressedAnimation( const mstudiocompressedikerror_t *pCompressed, int iFrame, float fraq, Vector &pos, Quaternion &q ) +{ + if (fraq > 0.0001f) + { + Vector p1, p2; + ExtractAnimValue( iFrame, pCompressed->pAnimvalue( 0 ), pCompressed->scale[0], p1.x, p2.x ); + ExtractAnimValue( iFrame, pCompressed->pAnimvalue( 1 ), pCompressed->scale[1], p1.y, p2.y ); + ExtractAnimValue( iFrame, pCompressed->pAnimvalue( 2 ), pCompressed->scale[2], p1.z, p2.z ); + pos = p1 * (1 - fraq) + p2 * fraq; + + Quaternion q1, q2; + RadianEuler angle1, angle2; + ExtractAnimValue( iFrame, pCompressed->pAnimvalue( 3 ), pCompressed->scale[3], angle1.x, angle2.x ); + ExtractAnimValue( iFrame, pCompressed->pAnimvalue( 4 ), pCompressed->scale[4], angle1.y, angle2.y ); + ExtractAnimValue( iFrame, pCompressed->pAnimvalue( 5 ), pCompressed->scale[5], angle1.z, angle2.z ); + + if (angle1.x != angle2.x || angle1.y != angle2.y || angle1.z != angle2.z) + { + AngleQuaternion( angle1, q1 ); + AngleQuaternion( angle2, q2 ); + QuaternionBlend( q1, q2, fraq, q ); + } + else + { + AngleQuaternion( angle1, q ); + } + } + else + { + ExtractAnimValue( iFrame, pCompressed->pAnimvalue( 0 ), pCompressed->scale[0], pos.x ); + ExtractAnimValue( iFrame, pCompressed->pAnimvalue( 1 ), pCompressed->scale[1], pos.y ); + ExtractAnimValue( iFrame, pCompressed->pAnimvalue( 2 ), pCompressed->scale[2], pos.z ); + + RadianEuler angle; + ExtractAnimValue( iFrame, pCompressed->pAnimvalue( 3 ), pCompressed->scale[3], angle.x ); + ExtractAnimValue( iFrame, pCompressed->pAnimvalue( 4 ), pCompressed->scale[4], angle.y ); + ExtractAnimValue( iFrame, pCompressed->pAnimvalue( 5 ), pCompressed->scale[5], angle.z ); + + AngleQuaternion( angle, q ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: translate animations done in a non-standard parent space +//----------------------------------------------------------------------------- +static void CalcLocalHierarchyAnimation( + const CStudioHdr *pStudioHdr, + matrix3x4_t *boneToWorld, + CBoneBitList &boneComputed, + Vector *pos, + Quaternion *q, + //const mstudioanimdesc_t &animdesc, + const mstudiobone_t *pbone, + mstudiolocalhierarchy_t *pHierarchy, + int iBone, + int iNewParent, + float cycle, + int iFrame, + float flFraq, + int boneMask + ) +{ +#ifdef STAGING_ONLY + Assert( iNewParent == -1 || (iNewParent >= 0 && iNewParent < MAXSTUDIOBONES) ); + Assert( iBone > 0 ); + Assert( iBone < MAXSTUDIOBONES ); +#endif // STAGING_ONLY + + Vector localPos; + Quaternion localQ; + + // make fake root transform + static ALIGN16 matrix3x4_t rootXform ALIGN16_POST ( 1.0f, 0, 0, 0, 0, 1.0f, 0, 0, 0, 0, 1.0f, 0 ); + + // FIXME: missing check to see if seq has a weight for this bone + float weight = 1.0f; + + // check to see if there's a ramp on the influence + if ( pHierarchy->tail - pHierarchy->peak < 1.0f ) + { + float index = cycle; + + if (pHierarchy->end > 1.0f && index < pHierarchy->start) + index += 1.0f; + + if (index < pHierarchy->start) + return; + if (index >= pHierarchy->end) + return; + + if (index < pHierarchy->peak && pHierarchy->start != pHierarchy->peak) + { + weight = (index - pHierarchy->start) / (pHierarchy->peak - pHierarchy->start); + } + else if (index > pHierarchy->tail && pHierarchy->end != pHierarchy->tail) + { + weight = (pHierarchy->end - index) / (pHierarchy->end - pHierarchy->tail); + } + + weight = SimpleSpline( weight ); + } + + CalcDecompressedAnimation( pHierarchy->pLocalAnim(), iFrame - pHierarchy->iStart, flFraq, localPos, localQ ); + + BuildBoneChain( pStudioHdr, rootXform, pos, q, iBone, boneToWorld, boneComputed ); + + matrix3x4_t localXform; + AngleMatrix( localQ, localPos, localXform ); + + if ( iNewParent != -1 ) + { + BuildBoneChain( pStudioHdr, rootXform, pos, q, iNewParent, boneToWorld, boneComputed ); + ConcatTransforms( boneToWorld[iNewParent], localXform, boneToWorld[iBone] ); + } + else + { + boneToWorld[iBone] = localXform; + } + + // back solve + Vector p1; + Quaternion q1; + int n = pbone[iBone].parent; + if (n == -1) + { + if (weight == 1.0f) + { + MatrixAngles( boneToWorld[iBone], q[iBone], pos[iBone] ); + } + else + { + MatrixAngles( boneToWorld[iBone], q1, p1 ); + QuaternionSlerp( q[iBone], q1, weight, q[iBone] ); + pos[iBone] = Lerp( weight, p1, pos[iBone] ); + } + } + else + { + matrix3x4_t worldToBone; + MatrixInvert( boneToWorld[n], worldToBone ); + + matrix3x4_t local; + ConcatTransforms( worldToBone, boneToWorld[iBone], local ); + if (weight == 1.0f) + { + MatrixAngles( local, q[iBone], pos[iBone] ); + } + else + { + MatrixAngles( local, q1, p1 ); + QuaternionSlerp( q[iBone], q1, weight, q[iBone] ); + pos[iBone] = Lerp( weight, p1, pos[iBone] ); + } + } +} + + + +//----------------------------------------------------------------------------- +// Purpose: Calc Zeroframe Data +//----------------------------------------------------------------------------- + +static void CalcZeroframeData( const CStudioHdr *pStudioHdr, const studiohdr_t *pAnimStudioHdr, const virtualgroup_t *pAnimGroup, const mstudiobone_t *pAnimbone, mstudioanimdesc_t &animdesc, float fFrame, Vector *pos, Quaternion *q, int boneMask, float flWeight ) +{ + byte *pData = animdesc.pZeroFrameData(); + + if (!pData) + return; + + int i, j; + + // Msg("zeroframe %s\n", animdesc.pszName() ); + if (animdesc.zeroframecount == 1) + { + for (j = 0; j < pAnimStudioHdr->numbones; j++) + { + if (pAnimGroup) + i = pAnimGroup->masterBone[j]; + else + i = j; + + if (pAnimbone[j].flags & BONE_HAS_SAVEFRAME_POS) + { + if ((i >= 0) && (pStudioHdr->boneFlags(i) & boneMask)) + { + Vector p = *(Vector48 *)pData; + pos[i] = pos[i] * (1.0f - flWeight) + p * flWeight; + Assert( pos[i].IsValid() ); + } + pData += sizeof( Vector48 ); + } + if (pAnimbone[j].flags & BONE_HAS_SAVEFRAME_ROT) + { + if ((i >= 0) && (pStudioHdr->boneFlags(i) & boneMask)) + { + Quaternion q0 = *(Quaternion64 *)pData; + QuaternionBlend( q[i], q0, flWeight, q[i] ); + Assert( q[i].IsValid() ); + } + pData += sizeof( Quaternion64 ); + } + } + } + else + { + float s1; + int index = fFrame / animdesc.zeroframespan; + if (index >= animdesc.zeroframecount - 1) + { + index = animdesc.zeroframecount - 2; + s1 = 1.0f; + } + else + { + s1 = clamp( (fFrame - index * animdesc.zeroframespan) / animdesc.zeroframespan, 0.0f, 1.0f ); + } + int i0 = max( index - 1, 0 ); + int i1 = index; + int i2 = min( index + 1, animdesc.zeroframecount - 1 ); + for (j = 0; j < pAnimStudioHdr->numbones; j++) + { + if (pAnimGroup) + i = pAnimGroup->masterBone[j]; + else + i = j; + + if (pAnimbone[j].flags & BONE_HAS_SAVEFRAME_POS) + { + if ((i >= 0) && (pStudioHdr->boneFlags(i) & boneMask)) + { + Vector p0 = *(((Vector48 *)pData) + i0); + Vector p1 = *(((Vector48 *)pData) + i1); + Vector p2 = *(((Vector48 *)pData) + i2); + Vector p3; + Hermite_Spline( p0, p1, p2, s1, p3 ); + pos[i] = pos[i] * (1.0f - flWeight) + p3 * flWeight; + Assert( pos[i].IsValid() ); + } + pData += sizeof( Vector48 ) * animdesc.zeroframecount; + } + if (pAnimbone[j].flags & BONE_HAS_SAVEFRAME_ROT) + { + if ((i >= 0) && (pStudioHdr->boneFlags(i) & boneMask)) + { + Quaternion q0 = *(((Quaternion64 *)pData) + i0); + Quaternion q1 = *(((Quaternion64 *)pData) + i1); + Quaternion q2 = *(((Quaternion64 *)pData) + i2); + if (flWeight == 1.0f) + { + Hermite_Spline( q0, q1, q2, s1, q[i] ); + } + else + { + Quaternion q3; + Hermite_Spline( q0, q1, q2, s1, q3 ); + QuaternionBlend( q[i], q3, flWeight, q[i] ); + } + Assert( q[i].IsValid() ); + } + pData += sizeof( Quaternion64 ) * animdesc.zeroframecount; + } + } + } +} + + + +//----------------------------------------------------------------------------- +// Purpose: Find and decode a sub-frame of animation, remapping the skeleton bone indexes +//----------------------------------------------------------------------------- +static void CalcVirtualAnimation( virtualmodel_t *pVModel, const CStudioHdr *pStudioHdr, Vector *pos, Quaternion *q, + mstudioseqdesc_t &seqdesc, int sequence, int animation, + float cycle, int boneMask ) +{ + int i, j, k; + + const mstudiobone_t *pbone; + const virtualgroup_t *pSeqGroup; + const studiohdr_t *pSeqStudioHdr; + const mstudiolinearbone_t *pSeqLinearBones; + const mstudiobone_t *pSeqbone; + const mstudioanim_t *panim; + const studiohdr_t *pAnimStudioHdr; + const mstudiolinearbone_t *pAnimLinearBones; + const mstudiobone_t *pAnimbone; + const virtualgroup_t *pAnimGroup; + + pSeqGroup = pVModel->pSeqGroup( sequence ); + int baseanimation = pStudioHdr->iRelativeAnim( sequence, animation ); + mstudioanimdesc_t &animdesc = ((CStudioHdr *)pStudioHdr)->pAnimdesc( baseanimation ); + pSeqStudioHdr = ((CStudioHdr *)pStudioHdr)->pSeqStudioHdr( sequence ); + pSeqLinearBones = pSeqStudioHdr->pLinearBones(); + pSeqbone = pSeqStudioHdr->pBone( 0 ); + pAnimGroup = pVModel->pAnimGroup( baseanimation ); + pAnimStudioHdr = ((CStudioHdr *)pStudioHdr)->pAnimStudioHdr( baseanimation ); + pAnimLinearBones = pAnimStudioHdr->pLinearBones(); + pAnimbone = pAnimStudioHdr->pBone( 0 ); + + int iFrame; + float s; + + float fFrame = cycle * (animdesc.numframes - 1); + + iFrame = (int)fFrame; + s = (fFrame - iFrame); + + int iLocalFrame = iFrame; + float flStall; + panim = animdesc.pAnim( &iLocalFrame, flStall ); + + float *pweight = seqdesc.pBoneweight( 0 ); + pbone = pStudioHdr->pBone( 0 ); + + for (i = 0; i < pStudioHdr->numbones(); i++) + { + if (pStudioHdr->boneFlags(i) & boneMask) + { + int j = pSeqGroup->boneMap[i]; + if (j >= 0 && pweight[j] > 0.0f) + { + if (animdesc.flags & STUDIO_DELTA) + { + q[i].Init( 0.0f, 0.0f, 0.0f, 1.0f ); + pos[i].Init( 0.0f, 0.0f, 0.0f ); + } + else if (pSeqLinearBones) + { + q[i] = pSeqLinearBones->quat(j); + pos[i] = pSeqLinearBones->pos(j); + } + else + { + q[i] = pSeqbone[j].quat; + pos[i] = pSeqbone[j].pos; + } +#ifdef STUDIO_ENABLE_PERF_COUNTERS + pStudioHdr->m_nPerfUsedBones++; +#endif + } + } + } + + // if the animation isn't available, look for the zero frame cache + if (!panim) + { + CalcZeroframeData( ((CStudioHdr *)pStudioHdr), pAnimStudioHdr, pAnimGroup, pAnimbone, animdesc, fFrame, pos, q, boneMask, 1.0 ); + return; + } + + // FIXME: change encoding so that bone -1 is never the case + while (panim && panim->bone < 255) + { + j = pAnimGroup->masterBone[panim->bone]; + if ( j >= 0 && ( pStudioHdr->boneFlags(j) & boneMask ) ) + { + k = pSeqGroup->boneMap[j]; + + if (k >= 0 && pweight[k] > 0.0f) + { + CalcBoneQuaternion( iLocalFrame, s, &pAnimbone[panim->bone], pAnimLinearBones, panim, q[j] ); + CalcBonePosition ( iLocalFrame, s, &pAnimbone[panim->bone], pAnimLinearBones, panim, pos[j] ); +#ifdef STUDIO_ENABLE_PERF_COUNTERS + pStudioHdr->m_nPerfAnimatedBones++; +#endif + } + } + panim = panim->pNext(); + } + + // cross fade in previous zeroframe data + if (flStall > 0.0f) + { + CalcZeroframeData( pStudioHdr, pAnimStudioHdr, pAnimGroup, pAnimbone, animdesc, fFrame, pos, q, boneMask, flStall ); + } + + // calculate a local hierarchy override + if (animdesc.numlocalhierarchy) + { + matrix3x4_t *boneToWorld = g_MatrixPool.Alloc(); + CBoneBitList boneComputed; + + int i; + for (i = 0; i < animdesc.numlocalhierarchy; i++) + { + mstudiolocalhierarchy_t *pHierarchy = animdesc.pHierarchy( i ); + + if ( !pHierarchy ) + break; + + int iBone = pAnimGroup->masterBone[pHierarchy->iBone]; + if (iBone >= 0 && (pStudioHdr->boneFlags(iBone) & boneMask)) + { + if ( pHierarchy->iNewParent != -1 ) + { + int iNewParent = pAnimGroup->masterBone[pHierarchy->iNewParent]; + if (iNewParent >= 0 && (pStudioHdr->boneFlags(iNewParent) & boneMask)) + { + CalcLocalHierarchyAnimation( pStudioHdr, boneToWorld, boneComputed, pos, q, pbone, pHierarchy, iBone, iNewParent, cycle, iFrame, s, boneMask ); + } + } + else + { + CalcLocalHierarchyAnimation( pStudioHdr, boneToWorld, boneComputed, pos, q, pbone, pHierarchy, iBone, -1, cycle, iFrame, s, boneMask ); + } + } + } + + g_MatrixPool.Free( boneToWorld ); + } +} + + + +//----------------------------------------------------------------------------- +// Purpose: Find and decode a sub-frame of animation +//----------------------------------------------------------------------------- + +static void CalcAnimation( const CStudioHdr *pStudioHdr, Vector *pos, Quaternion *q, + mstudioseqdesc_t &seqdesc, + int sequence, int animation, + float cycle, int boneMask ) +{ +#ifdef STUDIO_ENABLE_PERF_COUNTERS + pStudioHdr->m_nPerfAnimationLayers++; +#endif + + virtualmodel_t *pVModel = pStudioHdr->GetVirtualModel(); + + if (pVModel) + { + CalcVirtualAnimation( pVModel, pStudioHdr, pos, q, seqdesc, sequence, animation, cycle, boneMask ); + return; + } + + mstudioanimdesc_t &animdesc = ((CStudioHdr *)pStudioHdr)->pAnimdesc( animation ); + mstudiobone_t *pbone = pStudioHdr->pBone( 0 ); + const mstudiolinearbone_t *pLinearBones = pStudioHdr->pLinearBones(); + + int i; + int iFrame; + float s; + + float fFrame = cycle * (animdesc.numframes - 1); + + iFrame = (int)fFrame; + s = (fFrame - iFrame); + + int iLocalFrame = iFrame; + float flStall; + mstudioanim_t *panim = animdesc.pAnim( &iLocalFrame, flStall ); + + float *pweight = seqdesc.pBoneweight( 0 ); + + // if the animation isn't available, look for the zero frame cache + if (!panim) + { + // Msg("zeroframe %s\n", animdesc.pszName() ); + // pre initialize + for (i = 0; i < pStudioHdr->numbones(); i++, pbone++, pweight++) + { + if (*pweight > 0 && (pStudioHdr->boneFlags(i) & boneMask)) + { + if (animdesc.flags & STUDIO_DELTA) + { + q[i].Init( 0.0f, 0.0f, 0.0f, 1.0f ); + pos[i].Init( 0.0f, 0.0f, 0.0f ); + } + else + { + q[i] = pbone->quat; + pos[i] = pbone->pos; + } + } + } + + CalcZeroframeData( pStudioHdr, pStudioHdr->GetRenderHdr(), NULL, pStudioHdr->pBone( 0 ), animdesc, fFrame, pos, q, boneMask, 1.0 ); + + return; + } + + // BUGBUG: the sequence, the anim, and the model can have all different bone mappings. + for (i = 0; i < pStudioHdr->numbones(); i++, pbone++, pweight++) + { + if (panim && panim->bone == i) + { + if (*pweight > 0 && (pStudioHdr->boneFlags(i) & boneMask)) + { + CalcBoneQuaternion( iLocalFrame, s, pbone, pLinearBones, panim, q[i] ); + CalcBonePosition ( iLocalFrame, s, pbone, pLinearBones, panim, pos[i] ); +#ifdef STUDIO_ENABLE_PERF_COUNTERS + pStudioHdr->m_nPerfAnimatedBones++; + pStudioHdr->m_nPerfUsedBones++; +#endif + } + panim = panim->pNext(); + } + else if (*pweight > 0 && (pStudioHdr->boneFlags(i) & boneMask)) + { + if (animdesc.flags & STUDIO_DELTA) + { + q[i].Init( 0.0f, 0.0f, 0.0f, 1.0f ); + pos[i].Init( 0.0f, 0.0f, 0.0f ); + } + else + { + q[i] = pbone->quat; + pos[i] = pbone->pos; + } +#ifdef STUDIO_ENABLE_PERF_COUNTERS + pStudioHdr->m_nPerfUsedBones++; +#endif + } + } + + // cross fade in previous zeroframe data + if (flStall > 0.0f) + { + CalcZeroframeData( pStudioHdr, pStudioHdr->GetRenderHdr(), NULL, pStudioHdr->pBone( 0 ), animdesc, fFrame, pos, q, boneMask, flStall ); + } + + if (animdesc.numlocalhierarchy) + { + matrix3x4_t *boneToWorld = g_MatrixPool.Alloc(); + CBoneBitList boneComputed; + + int i; + for (i = 0; i < animdesc.numlocalhierarchy; i++) + { + mstudiolocalhierarchy_t *pHierarchy = animdesc.pHierarchy( i ); + + if ( !pHierarchy ) + break; + + if (pStudioHdr->boneFlags(pHierarchy->iBone) & boneMask) + { + if (pStudioHdr->boneFlags(pHierarchy->iNewParent) & boneMask) + { + CalcLocalHierarchyAnimation( pStudioHdr, boneToWorld, boneComputed, pos, q, pbone, pHierarchy, pHierarchy->iBone, pHierarchy->iNewParent, cycle, iFrame, s, boneMask ); + } + } + } + + g_MatrixPool.Free( boneToWorld ); + } + +} + + +//----------------------------------------------------------------------------- +// Purpose: qt = ( s * p ) * q +//----------------------------------------------------------------------------- +void QuaternionSM( float s, const Quaternion &p, const Quaternion &q, Quaternion &qt ) +{ + Quaternion p1, q1; + + QuaternionScale( p, s, p1 ); + QuaternionMult( p1, q, q1 ); + QuaternionNormalize( q1 ); + qt[0] = q1[0]; + qt[1] = q1[1]; + qt[2] = q1[2]; + qt[3] = q1[3]; +} + +#if ALLOW_SIMD_QUATERNION_MATH +FORCEINLINE fltx4 QuaternionSMSIMD( float s, const fltx4 &p, const fltx4 &q ) +{ + fltx4 p1, q1, result; + p1 = QuaternionScaleSIMD( p, s ); + q1 = QuaternionMultSIMD( p1, q ); + result = QuaternionNormalizeSIMD( q1 ); + return result; +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: qt = p * ( s * q ) +//----------------------------------------------------------------------------- +void QuaternionMA( const Quaternion &p, float s, const Quaternion &q, Quaternion &qt ) +{ + Quaternion p1, q1; + + QuaternionScale( q, s, q1 ); + QuaternionMult( p, q1, p1 ); + QuaternionNormalize( p1 ); + qt[0] = p1[0]; + qt[1] = p1[1]; + qt[2] = p1[2]; + qt[3] = p1[3]; +} + +#if ALLOW_SIMD_QUATERNION_MATH +FORCEINLINE fltx4 QuaternionMASIMD( const fltx4 &p, float s, const fltx4 &q ) +{ + fltx4 p1, q1, result; + q1 = QuaternionScaleSIMD( q, s ); + p1 = QuaternionMultSIMD( p, q1 ); + result = QuaternionNormalizeSIMD( p1 ); + return result; +} +#endif + + +//----------------------------------------------------------------------------- +// Purpose: qt = p + s * q +//----------------------------------------------------------------------------- +void QuaternionAccumulate( const Quaternion &p, float s, const Quaternion &q, Quaternion &qt ) +{ + Quaternion q2; + QuaternionAlign( p, q, q2 ); + + qt[0] = p[0] + s * q2[0]; + qt[1] = p[1] + s * q2[1]; + qt[2] = p[2] + s * q2[2]; + qt[3] = p[3] + s * q2[3]; +} + +#if ALLOW_SIMD_QUATERNION_MATH +FORCEINLINE fltx4 QuaternionAccumulateSIMD( const fltx4 &p, float s, const fltx4 &q ) +{ + fltx4 q2, s4, result; + q2 = QuaternionAlignSIMD( p, q ); + s4 = ReplicateX4( s ); + result = MaddSIMD( s4, q2, p ); + return result; +} +#endif + + + +//----------------------------------------------------------------------------- +// Purpose: blend together in world space q1,pos1 with q2,pos2. Return result in q1,pos1. +// 0 returns q1, pos1. 1 returns q2, pos2 +//----------------------------------------------------------------------------- + +void WorldSpaceSlerp( + const CStudioHdr *pStudioHdr, + Quaternion q1[MAXSTUDIOBONES], + Vector pos1[MAXSTUDIOBONES], + mstudioseqdesc_t &seqdesc, + int sequence, + const Quaternion q2[MAXSTUDIOBONES], + const Vector pos2[MAXSTUDIOBONES], + float s, + int boneMask ) +{ + int i, j; + float s1; // weight of parent for q2, pos2 + float s2; // weight for q2, pos2 + + // make fake root transform + matrix3x4_t rootXform; + SetIdentityMatrix( rootXform ); + + // matrices for q2, pos2 + matrix3x4_t *srcBoneToWorld = g_MatrixPool.Alloc(); + CBoneBitList srcBoneComputed; + + matrix3x4_t *destBoneToWorld = g_MatrixPool.Alloc(); + CBoneBitList destBoneComputed; + + matrix3x4_t *targetBoneToWorld = g_MatrixPool.Alloc(); + CBoneBitList targetBoneComputed; + + virtualmodel_t *pVModel = pStudioHdr->GetVirtualModel(); + const virtualgroup_t *pSeqGroup = NULL; + if (pVModel) + { + pSeqGroup = pVModel->pSeqGroup( sequence ); + } + + mstudiobone_t *pbone = pStudioHdr->pBone( 0 ); + + for (i = 0; i < pStudioHdr->numbones(); i++) + { + // skip unused bones + if (!(pStudioHdr->boneFlags(i) & boneMask)) + { + continue; + } + + int n = pbone[i].parent; + s1 = 0.0; + if (pSeqGroup) + { + j = pSeqGroup->boneMap[i]; + if (j >= 0) + { + s2 = s * seqdesc.weight( j ); // blend in based on this bones weight + if (n != -1) + { + s1 = s * seqdesc.weight( pSeqGroup->boneMap[n] ); + } + } + else + { + s2 = 0.0; + } + } + else + { + s2 = s * seqdesc.weight( i ); // blend in based on this bones weight + if (n != -1) + { + s1 = s * seqdesc.weight( n ); + } + } + + if (s1 == 1.0 && s2 == 1.0) + { + pos1[i] = pos2[i]; + q1[i] = q2[i]; + } + else if (s2 > 0.0) + { + Quaternion srcQ, destQ; + Vector srcPos, destPos; + Quaternion targetQ; + Vector targetPos; + Vector tmp; + + BuildBoneChain( pStudioHdr, rootXform, pos1, q1, i, destBoneToWorld, destBoneComputed ); + BuildBoneChain( pStudioHdr, rootXform, pos2, q2, i, srcBoneToWorld, srcBoneComputed ); + + MatrixAngles( destBoneToWorld[i], destQ, destPos ); + MatrixAngles( srcBoneToWorld[i], srcQ, srcPos ); + + QuaternionSlerp( destQ, srcQ, s2, targetQ ); + AngleMatrix( targetQ, destPos, targetBoneToWorld[i] ); + + // back solve + if (n == -1) + { + MatrixAngles( targetBoneToWorld[i], q1[i], tmp ); + } + else + { + matrix3x4_t worldToBone; + MatrixInvert( targetBoneToWorld[n], worldToBone ); + + matrix3x4_t local; + ConcatTransforms( worldToBone, targetBoneToWorld[i], local ); + MatrixAngles( local, q1[i], tmp ); + + // blend bone lengths (local space) + pos1[i] = Lerp( s2, pos1[i], pos2[i] ); + } + } + } + g_MatrixPool.Free( srcBoneToWorld ); + g_MatrixPool.Free( destBoneToWorld ); + g_MatrixPool.Free( targetBoneToWorld ); +} + + + +//----------------------------------------------------------------------------- +// Purpose: blend together q1,pos1 with q2,pos2. Return result in q1,pos1. +// 0 returns q1, pos1. 1 returns q2, pos2 +//----------------------------------------------------------------------------- +void SlerpBones( + const CStudioHdr *pStudioHdr, + Quaternion q1[MAXSTUDIOBONES], + Vector pos1[MAXSTUDIOBONES], + mstudioseqdesc_t &seqdesc, // source of q2 and pos2 + int sequence, + const QuaternionAligned q2[MAXSTUDIOBONES], + const Vector pos2[MAXSTUDIOBONES], + float s, + int boneMask ) +{ + if (s <= 0.0f) + return; + if (s > 1.0f) + { + s = 1.0f; + } + + if (seqdesc.flags & STUDIO_WORLD) + { + WorldSpaceSlerp( pStudioHdr, q1, pos1, seqdesc, sequence, q2, pos2, s, boneMask ); + return; + } + + int i, j; + virtualmodel_t *pVModel = pStudioHdr->GetVirtualModel(); + const virtualgroup_t *pSeqGroup = NULL; + if (pVModel) + { + pSeqGroup = pVModel->pSeqGroup( sequence ); + } + + // Build weightlist for all bones + int nBoneCount = pStudioHdr->numbones(); + float *pS2 = (float*)stackalloc( nBoneCount * sizeof(float) ); + for (i = 0; i < nBoneCount; i++) + { + // skip unused bones + if (!(pStudioHdr->boneFlags(i) & boneMask)) + { + pS2[i] = 0.0f; + continue; + } + + if ( !pSeqGroup ) + { + pS2[i] = s * seqdesc.weight( i ); // blend in based on this bones weight + continue; + } + + j = pSeqGroup->boneMap[i]; + if ( j >= 0 ) + { + pS2[i] = s * seqdesc.weight( j ); // blend in based on this bones weight + } + else + { + pS2[i] = 0.0; + } + } + + float s1, s2; + if ( seqdesc.flags & STUDIO_DELTA ) + { + for ( i = 0; i < nBoneCount; i++ ) + { + s2 = pS2[i]; + if ( s2 <= 0.0f ) + continue; + + if ( seqdesc.flags & STUDIO_POST ) + { +#ifndef _X360 + QuaternionMA( q1[i], s2, q2[i], q1[i] ); +#else + fltx4 q1simd = LoadUnalignedSIMD( q1[i].Base() ); + fltx4 q2simd = LoadAlignedSIMD( q2[i] ); + fltx4 result = QuaternionMASIMD( q1simd, s2, q2simd ); + StoreUnalignedSIMD( q1[i].Base(), result ); +#endif + // FIXME: are these correct? + pos1[i][0] = pos1[i][0] + pos2[i][0] * s2; + pos1[i][1] = pos1[i][1] + pos2[i][1] * s2; + pos1[i][2] = pos1[i][2] + pos2[i][2] * s2; + } + else + { +#ifndef _X360 + QuaternionSM( s2, q2[i], q1[i], q1[i] ); +#else + fltx4 q1simd = LoadUnalignedSIMD( q1[i].Base() ); + fltx4 q2simd = LoadAlignedSIMD( q2[i] ); + fltx4 result = QuaternionSMSIMD( s2, q2simd, q1simd ); + StoreUnalignedSIMD( q1[i].Base(), result ); +#endif + + // FIXME: are these correct? + pos1[i][0] = pos1[i][0] + pos2[i][0] * s2; + pos1[i][1] = pos1[i][1] + pos2[i][1] * s2; + pos1[i][2] = pos1[i][2] + pos2[i][2] * s2; + } + } + return; + } + + QuaternionAligned q3; + for (i = 0; i < nBoneCount; i++) + { + s2 = pS2[i]; + if ( s2 <= 0.0f ) + continue; + + s1 = 1.0 - s2; + +#ifdef _X360 + fltx4 q1simd, q2simd, result; + q1simd = LoadUnalignedSIMD( q1[i].Base() ); + q2simd = LoadAlignedSIMD( q2[i] ); +#endif + if ( pStudioHdr->boneFlags(i) & BONE_FIXED_ALIGNMENT ) + { +#ifndef _X360 + QuaternionSlerpNoAlign( q2[i], q1[i], s1, q3 ); +#else + result = QuaternionSlerpNoAlignSIMD( q2simd, q1simd, s1 ); +#endif + } + else + { +#ifndef _X360 + QuaternionSlerp( q2[i], q1[i], s1, q3 ); +#else + result = QuaternionSlerpSIMD( q2simd, q1simd, s1 ); +#endif + } + +#ifndef _X360 + q1[i][0] = q3[0]; + q1[i][1] = q3[1]; + q1[i][2] = q3[2]; + q1[i][3] = q3[3]; +#else + StoreUnalignedSIMD( q1[i].Base(), result ); +#endif + + pos1[i][0] = pos1[i][0] * s1 + pos2[i][0] * s2; + pos1[i][1] = pos1[i][1] * s1 + pos2[i][1] * s2; + pos1[i][2] = pos1[i][2] * s1 + pos2[i][2] * s2; + } +} + + + +//----------------------------------------------------------------------------- +// Purpose: Inter-animation blend. Assumes both types are identical. +// blend together q1,pos1 with q2,pos2. Return result in q1,pos1. +// 0 returns q1, pos1. 1 returns q2, pos2 +//----------------------------------------------------------------------------- +void BlendBones( + const CStudioHdr *pStudioHdr, + Quaternion q1[MAXSTUDIOBONES], + Vector pos1[MAXSTUDIOBONES], + mstudioseqdesc_t &seqdesc, + int sequence, + const Quaternion q2[MAXSTUDIOBONES], + const Vector pos2[MAXSTUDIOBONES], + float s, + int boneMask ) +{ + int i, j; + Quaternion q3; + + virtualmodel_t *pVModel = pStudioHdr->GetVirtualModel(); + const virtualgroup_t *pSeqGroup = NULL; + if (pVModel) + { + pSeqGroup = pVModel->pSeqGroup( sequence ); + } + + if (s <= 0) + { + Assert(0); // shouldn't have been called + return; + } + else if (s >= 1.0) + { + Assert(0); // shouldn't have been called + for (i = 0; i < pStudioHdr->numbones(); i++) + { + // skip unused bones + if (!(pStudioHdr->boneFlags(i) & boneMask)) + { + continue; + } + + if (pSeqGroup) + { + j = pSeqGroup->boneMap[i]; + } + else + { + j = i; + } + + if (j >= 0 && seqdesc.weight( j ) > 0.0) + { + q1[i] = q2[i]; + pos1[i] = pos2[i]; + } + } + return; + } + + float s2 = s; + float s1 = 1.0 - s2; + + for (i = 0; i < pStudioHdr->numbones(); i++) + { + // skip unused bones + if (!(pStudioHdr->boneFlags(i) & boneMask)) + { + continue; + } + + if (pSeqGroup) + { + j = pSeqGroup->boneMap[i]; + } + else + { + j = i; + } + + if (j >= 0 && seqdesc.weight( j ) > 0.0) + { + if (pStudioHdr->boneFlags(i) & BONE_FIXED_ALIGNMENT) + { + QuaternionBlendNoAlign( q2[i], q1[i], s1, q3 ); + } + else + { + QuaternionBlend( q2[i], q1[i], s1, 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] * s2; + pos1[i][1] = pos1[i][1] * s1 + pos2[i][1] * s2; + pos1[i][2] = pos1[i][2] * s1 + pos2[i][2] * s2; + } + } +} + + + +//----------------------------------------------------------------------------- +// Purpose: Scale a set of bones. Must be of type delta +//----------------------------------------------------------------------------- +void ScaleBones( + const CStudioHdr *pStudioHdr, + Quaternion q1[MAXSTUDIOBONES], + Vector pos1[MAXSTUDIOBONES], + int sequence, + float s, + int boneMask ) +{ + int i, j; + Quaternion q3; + + mstudioseqdesc_t &seqdesc = ((CStudioHdr *)pStudioHdr)->pSeqdesc( sequence ); + + virtualmodel_t *pVModel = pStudioHdr->GetVirtualModel(); + const virtualgroup_t *pSeqGroup = NULL; + if (pVModel) + { + pSeqGroup = pVModel->pSeqGroup( sequence ); + } + + float s2 = s; + float s1 = 1.0 - s2; + + for (i = 0; i < pStudioHdr->numbones(); i++) + { + // skip unused bones + if (!(pStudioHdr->boneFlags(i) & boneMask)) + { + continue; + } + + if (pSeqGroup) + { + j = pSeqGroup->boneMap[i]; + } + else + { + j = i; + } + + if (j >= 0 && seqdesc.weight( j ) > 0.0) + { + QuaternionIdentityBlend( q1[i], s1, q1[i] ); + VectorScale( pos1[i], s2, pos1[i] ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: resolve a global pose parameter to the specific setting for this sequence +//----------------------------------------------------------------------------- +void Studio_LocalPoseParameter( const CStudioHdr *pStudioHdr, const float poseParameter[], mstudioseqdesc_t &seqdesc, int iSequence, int iLocalIndex, float &flSetting, int &index ) +{ + int iPose = pStudioHdr->GetSharedPoseParameter( iSequence, seqdesc.paramindex[iLocalIndex] ); + + if (iPose == -1) + { + flSetting = 0; + index = 0; + return; + } + + const mstudioposeparamdesc_t &Pose = ((CStudioHdr *)pStudioHdr)->pPoseParameter( iPose ); + + float flValue = poseParameter[iPose]; + + if (Pose.loop) + { + float wrap = (Pose.start + Pose.end) / 2.0 + Pose.loop / 2.0; + float shift = Pose.loop - wrap; + + flValue = flValue - Pose.loop * floor((flValue + shift) / Pose.loop); + } + + if (seqdesc.posekeyindex == 0) + { + float flLocalStart = ((float)seqdesc.paramstart[iLocalIndex] - Pose.start) / (Pose.end - Pose.start); + float flLocalEnd = ((float)seqdesc.paramend[iLocalIndex] - Pose.start) / (Pose.end - Pose.start); + + // convert into local range + flSetting = (flValue - flLocalStart) / (flLocalEnd - flLocalStart); + + // clamp. This shouldn't ever need to happen if it's looping. + if (flSetting < 0) + flSetting = 0; + if (flSetting > 1) + flSetting = 1; + + index = 0; + if (seqdesc.groupsize[iLocalIndex] > 2 ) + { + // estimate index + index = (int)(flSetting * (seqdesc.groupsize[iLocalIndex] - 1)); + if (index == seqdesc.groupsize[iLocalIndex] - 1) index = seqdesc.groupsize[iLocalIndex] - 2; + flSetting = flSetting * (seqdesc.groupsize[iLocalIndex] - 1) - index; + } + } + else + { + flValue = flValue * (Pose.end - Pose.start) + Pose.start; + index = 0; + + // FIXME: this needs to be 2D + // FIXME: this shouldn't be a linear search + + while (1) + { + flSetting = (flValue - seqdesc.poseKey( iLocalIndex, index )) / (seqdesc.poseKey( iLocalIndex, index + 1 ) - seqdesc.poseKey( iLocalIndex, index )); + /* + if (index > 0 && flSetting < 0.0) + { + index--; + continue; + } + else + */ + if (index < seqdesc.groupsize[iLocalIndex] - 2 && flSetting > 1.0) + { + index++; + continue; + } + break; + } + + // clamp. + if (flSetting < 0.0f) + flSetting = 0.0f; + if (flSetting > 1.0f) + flSetting = 1.0f; + } +} + +void Studio_CalcBoneToBoneTransform( const CStudioHdr *pStudioHdr, int inputBoneIndex, int outputBoneIndex, matrix3x4_t& matrixOut ) +{ + mstudiobone_t *pbone = pStudioHdr->pBone( inputBoneIndex ); + + matrix3x4_t inputToPose; + MatrixInvert( pbone->poseToBone, inputToPose ); + ConcatTransforms( pStudioHdr->pBone( outputBoneIndex )->poseToBone, inputToPose, matrixOut ); +} + +//----------------------------------------------------------------------------- +// Purpose: calculate a pose for a single sequence +//----------------------------------------------------------------------------- +void InitPose( + const CStudioHdr *pStudioHdr, + Vector pos[], + Quaternion q[], + int boneMask + ) +{ + if (!pStudioHdr->pLinearBones()) + { + for (int i = 0; i < pStudioHdr->numbones(); i++) + { + if (pStudioHdr->boneFlags( i ) & boneMask ) + { + mstudiobone_t *pbone = pStudioHdr->pBone( i ); + pos[i] = pbone->pos; + q[i] = pbone->quat; + } + } + } + else + { + mstudiolinearbone_t *pLinearBones = pStudioHdr->pLinearBones(); + for (int i = 0; i < pStudioHdr->numbones(); i++) + { + if (pStudioHdr->boneFlags( i ) & boneMask ) + { + pos[i] = pLinearBones->pos(i); + q[i] = pLinearBones->quat(i); + } + } + } +} + + +inline bool PoseIsAllZeros( + const CStudioHdr *pStudioHdr, + int sequence, + mstudioseqdesc_t &seqdesc, + int i0, + int i1 + ) +{ + int baseanim; + + // remove "zero" positional blends + baseanim = pStudioHdr->iRelativeAnim( sequence, seqdesc.anim(i0 ,i1 ) ); + mstudioanimdesc_t &anim = ((CStudioHdr *)pStudioHdr)->pAnimdesc( baseanim ); + return (anim.flags & STUDIO_ALLZEROS) != 0; +} + +//----------------------------------------------------------------------------- +// Purpose: turn a 2x2 blend into a 3 way triangle blend +// Returns: returns the animination indices and barycentric coordinates of a triangle +// the triangle is a right triangle, and the diagonal is between elements [0] and [2] +//----------------------------------------------------------------------------- + +static ConVar anim_3wayblend( "anim_3wayblend", "1", FCVAR_REPLICATED, "Toggle the 3-way animation blending code." ); + +void Calc3WayBlendIndices( int i0, int i1, float s0, float s1, const mstudioseqdesc_t &seqdesc, int *pAnimIndices, float *pWeight ) +{ + // Figure out which bi-section direction we are using to make triangles. + bool bEven = ( ( ( i0 + i1 ) & 0x1 ) == 0 ); + + int x1, y1; + int x2, y2; + int x3, y3; + + // diagonal is between elements 1 & 3 + // TL to BR + if ( bEven ) + { + if ( s0 > s1 ) + { + // B + x1 = 0; y1 = 0; + x2 = 1; y2 = 0; + x3 = 1; y3 = 1; + pWeight[0] = (1.0f - s0); + pWeight[1] = s0 - s1; + } + else + { + // C + x1 = 1; y1 = 1; + x2 = 0; y2 = 1; + x3 = 0; y3 = 0; + pWeight[0] = s0; + pWeight[1] = s1 - s0; + } + } + // BL to TR + else + { + float flTotal = s0 + s1; + + if( flTotal > 1.0f ) + { + // D + x1 = 1; y1 = 0; + x2 = 1; y2 = 1; + x3 = 0; y3 = 1; + pWeight[0] = (1.0f - s1); + pWeight[1] = s0 - 1.0f + s1; + } + else + { + // A + x1 = 0; y1 = 1; + x2 = 0; y2 = 0; + x3 = 1; y3 = 0; + pWeight[0] = s1; + pWeight[1] = 1.0f - s0 - s1; + } + } + + pAnimIndices[0] = seqdesc.anim( i0 + x1, i1 + y1 ); + pAnimIndices[1] = seqdesc.anim( i0 + x2, i1 + y2 ); + pAnimIndices[2] = seqdesc.anim( i0 + x3, i1 + y3 ); + + /* + float w0 = ((x2-x3)*(y3-s1) - (x3-s0)*(y2-y3)) / ((x1-x3)*(y2-y3) - (x2-x3)*(y1-y3)); + float w1 = ((x1-x3)*(y3-s1) - (x3-s0)*(y1-y3)) / ((x2-x3)*(y1-y3) - (x1-x3)*(y2-y3)); + Assert( pWeight[0] == w0 && pWeight[1] == w1 ); + */ + + // clamp the diagonal + if (pWeight[1] < 0.001f) + pWeight[1] = 0.0f; + pWeight[2] = 1.0f - pWeight[0] - pWeight[1]; + + Assert( pWeight[0] >= 0.0f && pWeight[0] <= 1.0f ); + Assert( pWeight[1] >= 0.0f && pWeight[1] <= 1.0f ); + Assert( pWeight[2] >= 0.0f && pWeight[2] <= 1.0f ); +} + + + +//----------------------------------------------------------------------------- +// Purpose: calculate a pose for a single sequence +//----------------------------------------------------------------------------- +bool CalcPoseSingle( + const CStudioHdr *pStudioHdr, + Vector pos[], + Quaternion q[], + mstudioseqdesc_t &seqdesc, + int sequence, + float cycle, + const float poseParameter[], + int boneMask, + float flTime + ) +{ + bool bResult = true; + + Vector *pos2 = g_VectorPool.Alloc(); + Quaternion *q2 = g_QaternionPool.Alloc(); + Vector *pos3= g_VectorPool.Alloc(); + Quaternion *q3 = g_QaternionPool.Alloc(); + + if (sequence >= pStudioHdr->GetNumSeq()) + { + sequence = 0; + seqdesc = ((CStudioHdr *)pStudioHdr)->pSeqdesc( sequence ); + } + + + int i0 = 0, i1 = 0; + float s0 = 0, s1 = 0; + + Studio_LocalPoseParameter( pStudioHdr, poseParameter, seqdesc, sequence, 0, s0, i0 ); + Studio_LocalPoseParameter( pStudioHdr, poseParameter, seqdesc, sequence, 1, s1, i1 ); + + + if (seqdesc.flags & STUDIO_REALTIME) + { + float cps = Studio_CPS( pStudioHdr, seqdesc, sequence, poseParameter ); + cycle = flTime * cps; + cycle = cycle - (int)cycle; + } + else if (seqdesc.flags & STUDIO_CYCLEPOSE) + { + int iPose = pStudioHdr->GetSharedPoseParameter( sequence, seqdesc.cycleposeindex ); + if (iPose != -1) + { + /* + const mstudioposeparamdesc_t &Pose = ((CStudioHdr *)pStudioHdr)->pPoseParameter( iPose ); + cycle = poseParameter[ iPose ] * (Pose.end - Pose.start) + Pose.start; + */ + cycle = poseParameter[ iPose ]; + } + else + { + cycle = 0.0f; + } + } + else if (cycle < 0 || cycle >= 1) + { + if (seqdesc.flags & STUDIO_LOOPING) + { + cycle = cycle - (int)cycle; + if (cycle < 0) cycle += 1; + } + else + { + cycle = clamp( cycle, 0.0f, 1.0f ); + } + } + + if (s0 < 0.001) + { + if (s1 < 0.001) + { + if (PoseIsAllZeros( pStudioHdr, sequence, seqdesc, i0, i1 )) + { + bResult = false; + } + else + { + CalcAnimation( pStudioHdr, pos, q, seqdesc, sequence, seqdesc.anim( i0 , i1 ), cycle, boneMask ); + } + } + else if (s1 > 0.999) + { + CalcAnimation( pStudioHdr, pos, q, seqdesc, sequence, seqdesc.anim( i0 , i1+1 ), cycle, boneMask ); + } + else + { + CalcAnimation( pStudioHdr, pos, q, seqdesc, sequence, seqdesc.anim( i0 , i1 ), cycle, boneMask ); + CalcAnimation( pStudioHdr, pos2, q2, seqdesc, sequence, seqdesc.anim( i0 , i1+1 ), cycle, boneMask ); + BlendBones( pStudioHdr, q, pos, seqdesc, sequence, q2, pos2, s1, boneMask ); + } + } + else if (s0 > 0.999) + { + if (s1 < 0.001) + { + if (PoseIsAllZeros( pStudioHdr, sequence, seqdesc, i0+1, i1 )) + { + bResult = false; + } + else + { + CalcAnimation( pStudioHdr, pos, q, seqdesc, sequence, seqdesc.anim( i0+1, i1 ), cycle, boneMask ); + } + } + else if (s1 > 0.999) + { + CalcAnimation( pStudioHdr, pos, q, seqdesc, sequence, seqdesc.anim( i0+1, i1+1 ), cycle, boneMask ); + } + else + { + CalcAnimation( pStudioHdr, pos, q, seqdesc, sequence, seqdesc.anim( i0+1, i1 ), cycle, boneMask ); + CalcAnimation( pStudioHdr, pos2, q2, seqdesc, sequence, seqdesc.anim( i0+1, i1+1 ), cycle, boneMask ); + BlendBones( pStudioHdr, q, pos, seqdesc, sequence, q2, pos2, s1, boneMask ); + } + } + else + { + if (s1 < 0.001) + { + if (PoseIsAllZeros( pStudioHdr, sequence, seqdesc, i0+1, i1 )) + { + CalcAnimation( pStudioHdr, pos, q, seqdesc, sequence, seqdesc.anim( i0 ,i1 ), cycle, boneMask ); + ScaleBones( pStudioHdr, q, pos, sequence, 1.0 - s0, boneMask ); + } + else if (PoseIsAllZeros( pStudioHdr, sequence, seqdesc, i0, i1 )) + { + CalcAnimation( pStudioHdr, pos, q, seqdesc, sequence, seqdesc.anim( i0+1 ,i1 ), cycle, boneMask ); + ScaleBones( pStudioHdr, q, pos, sequence, s0, boneMask ); + } + else + { + CalcAnimation( pStudioHdr, pos, q, seqdesc, sequence, seqdesc.anim( i0 ,i1 ), cycle, boneMask ); + CalcAnimation( pStudioHdr, pos2, q2, seqdesc, sequence, seqdesc.anim( i0+1,i1 ), cycle, boneMask ); + + BlendBones( pStudioHdr, q, pos, seqdesc, sequence, q2, pos2, s0, boneMask ); + } + } + else if (s1 > 0.999) + { + CalcAnimation( pStudioHdr, pos, q, seqdesc, sequence, seqdesc.anim( i0 ,i1+1 ), cycle, boneMask ); + CalcAnimation( pStudioHdr, pos2, q2, seqdesc, sequence, seqdesc.anim( i0+1,i1+1 ), cycle, boneMask ); + BlendBones( pStudioHdr, q, pos, seqdesc, sequence, q2, pos2, s0, boneMask ); + } + else if ( !anim_3wayblend.GetBool() ) + { + CalcAnimation( pStudioHdr, pos, q, seqdesc, sequence, seqdesc.anim( i0 ,i1 ), cycle, boneMask ); + CalcAnimation( pStudioHdr, pos2, q2, seqdesc, sequence, seqdesc.anim( i0+1,i1 ), cycle, boneMask ); + BlendBones( pStudioHdr, q, pos, seqdesc, sequence, q2, pos2, s0, boneMask ); + + CalcAnimation( pStudioHdr, pos2, q2, seqdesc, sequence, seqdesc.anim( i0 , i1+1), cycle, boneMask ); + CalcAnimation( pStudioHdr, pos3, q3, seqdesc, sequence, seqdesc.anim( i0+1, i1+1), cycle, boneMask ); + BlendBones( pStudioHdr, q2, pos2, seqdesc, sequence, q3, pos3, s0, boneMask ); + + BlendBones( pStudioHdr, q, pos, seqdesc, sequence, q2, pos2, s1, boneMask ); + } + else + { + int iAnimIndices[3]; + float weight[3]; + + Calc3WayBlendIndices( i0, i1, s0, s1, seqdesc, iAnimIndices, weight ); + + /* + char buf[256]; + sprintf( buf, "%d %6.2f %d %6.2f : %6.2f %6.2f %6.2f\n", i0, s0, i1, s1, weight[0], weight[1], weight[2] ); + OutputDebugString( buf ); + */ + + if (weight[1] < 0.001) + { + // on diagonal + CalcAnimation( pStudioHdr, pos, q, seqdesc, sequence, iAnimIndices[0], cycle, boneMask ); + CalcAnimation( pStudioHdr, pos2, q2, seqdesc, sequence, iAnimIndices[2], cycle, boneMask ); + BlendBones( pStudioHdr, q, pos, seqdesc, sequence, q2, pos2, weight[2] / (weight[0] + weight[2]), boneMask ); + } + else + { + CalcAnimation( pStudioHdr, pos, q, seqdesc, sequence, iAnimIndices[0], cycle, boneMask ); + CalcAnimation( pStudioHdr, pos2, q2, seqdesc, sequence, iAnimIndices[1], cycle, boneMask ); + BlendBones( pStudioHdr, q, pos, seqdesc, sequence, q2, pos2, weight[1] / (weight[0] + weight[1]), boneMask ); + + CalcAnimation( pStudioHdr, pos3, q3, seqdesc, sequence, iAnimIndices[2], cycle, boneMask ); + BlendBones( pStudioHdr, q, pos, seqdesc, sequence, q3, pos3, weight[2], boneMask ); + } + } + } + + g_VectorPool.Free( pos2 ); + g_QaternionPool.Free( q2 ); + g_VectorPool.Free( pos3 ); + g_QaternionPool.Free( q3 ); + + return bResult; +} + + + + +//----------------------------------------------------------------------------- +// Purpose: calculate a pose for a single sequence +// adds autolayers, runs local ik rukes +//----------------------------------------------------------------------------- +void CBoneSetup::AddSequenceLayers( + Vector pos[], + Quaternion q[], + mstudioseqdesc_t &seqdesc, + int sequence, + float cycle, + float flWeight, + float flTime, + CIKContext *pIKContext + ) +{ + for (int i = 0; i < seqdesc.numautolayers; i++) + { + mstudioautolayer_t *pLayer = seqdesc.pAutolayer( i ); + + if (pLayer->flags & STUDIO_AL_LOCAL) + continue; + + float layerCycle = cycle; + float layerWeight = flWeight; + + if (pLayer->start != pLayer->end) + { + float s = 1.0; + float index; + + if (!(pLayer->flags & STUDIO_AL_POSE)) + { + index = cycle; + } + else + { + int iSequence = m_pStudioHdr->iRelativeSeq( sequence, pLayer->iSequence ); + int iPose = m_pStudioHdr->GetSharedPoseParameter( iSequence, pLayer->iPose ); + if (iPose != -1) + { + const mstudioposeparamdesc_t &Pose = ((CStudioHdr *)m_pStudioHdr)->pPoseParameter( iPose ); + index = m_flPoseParameter[ iPose ] * (Pose.end - Pose.start) + Pose.start; + } + else + { + index = 0; + } + } + + if (index < pLayer->start) + continue; + if (index >= pLayer->end) + continue; + + if (index < pLayer->peak && pLayer->start != pLayer->peak) + { + s = (index - pLayer->start) / (pLayer->peak - pLayer->start); + } + else if (index > pLayer->tail && pLayer->end != pLayer->tail) + { + s = (pLayer->end - index) / (pLayer->end - pLayer->tail); + } + + if (pLayer->flags & STUDIO_AL_SPLINE) + { + s = SimpleSpline( s ); + } + + if ((pLayer->flags & STUDIO_AL_XFADE) && (index > pLayer->tail)) + { + layerWeight = ( s * flWeight ) / ( 1 - flWeight + s * flWeight ); + } + else if (pLayer->flags & STUDIO_AL_NOBLEND) + { + layerWeight = s; + } + else + { + layerWeight = flWeight * s; + } + + if (!(pLayer->flags & STUDIO_AL_POSE)) + { + layerCycle = (cycle - pLayer->start) / (pLayer->end - pLayer->start); + } + } + + int iSequence = m_pStudioHdr->iRelativeSeq( sequence, pLayer->iSequence ); + AccumulatePose( pos, q, iSequence, layerCycle, layerWeight, flTime, pIKContext ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: calculate a pose for a single sequence +// adds autolayers, runs local ik rukes +//----------------------------------------------------------------------------- +void CBoneSetup::AddLocalLayers( + Vector pos[], + Quaternion q[], + mstudioseqdesc_t &seqdesc, + int sequence, + float cycle, + float flWeight, + float flTime, + CIKContext *pIKContext + ) +{ + if (!(seqdesc.flags & STUDIO_LOCAL)) + { + return; + } + + for (int i = 0; i < seqdesc.numautolayers; i++) + { + mstudioautolayer_t *pLayer = seqdesc.pAutolayer( i ); + + if (!(pLayer->flags & STUDIO_AL_LOCAL)) + continue; + + float layerCycle = cycle; + float layerWeight = flWeight; + + if (pLayer->start != pLayer->end) + { + float s = 1.0; + + if (cycle < pLayer->start) + continue; + if (cycle >= pLayer->end) + continue; + + if (cycle < pLayer->peak && pLayer->start != pLayer->peak) + { + s = (cycle - pLayer->start) / (pLayer->peak - pLayer->start); + } + else if (cycle > pLayer->tail && pLayer->end != pLayer->tail) + { + s = (pLayer->end - cycle) / (pLayer->end - pLayer->tail); + } + + if (pLayer->flags & STUDIO_AL_SPLINE) + { + s = SimpleSpline( s ); + } + + if ((pLayer->flags & STUDIO_AL_XFADE) && (cycle > pLayer->tail)) + { + layerWeight = ( s * flWeight ) / ( 1 - flWeight + s * flWeight ); + } + else if (pLayer->flags & STUDIO_AL_NOBLEND) + { + layerWeight = s; + } + else + { + layerWeight = flWeight * s; + } + + layerCycle = (cycle - pLayer->start) / (pLayer->end - pLayer->start); + } + + int iSequence = m_pStudioHdr->iRelativeSeq( sequence, pLayer->iSequence ); + AccumulatePose( pos, q, iSequence, layerCycle, layerWeight, flTime, pIKContext ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: my sleezy attempt at an interface only class +//----------------------------------------------------------------------------- + +IBoneSetup::IBoneSetup( const CStudioHdr *pStudioHdr, int boneMask, const float poseParameter[], IPoseDebugger *pPoseDebugger ) +{ + m_pBoneSetup = new CBoneSetup( pStudioHdr, boneMask, poseParameter, pPoseDebugger ); +} + +IBoneSetup::~IBoneSetup( void ) +{ + if ( m_pBoneSetup ) + { + delete m_pBoneSetup; + } +} + +void IBoneSetup::InitPose( Vector pos[], Quaternion q[] ) +{ + ::InitPose( m_pBoneSetup->m_pStudioHdr, pos, q, m_pBoneSetup->m_boneMask ); +} + +void IBoneSetup::AccumulatePose( Vector pos[], Quaternion q[], int sequence, float cycle, float flWeight, float flTime, CIKContext *pIKContext ) +{ + m_pBoneSetup->AccumulatePose( pos, q, sequence, cycle, flWeight, flTime, pIKContext ); +} + +void IBoneSetup::CalcAutoplaySequences( Vector pos[], Quaternion q[], float flRealTime, CIKContext *pIKContext ) +{ + m_pBoneSetup->CalcAutoplaySequences( pos, q, flRealTime, pIKContext ); +} + +void CalcBoneAdj( const CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], const float controllers[], int boneMask ); + +// takes a "controllers[]" array normalized to 0..1 and adds in the adjustments to pos[], and q[]. +void IBoneSetup::CalcBoneAdj( Vector pos[], Quaternion q[], const float controllers[] ) +{ + ::CalcBoneAdj( m_pBoneSetup->m_pStudioHdr, pos, q, controllers, m_pBoneSetup->m_boneMask ); +} + +CStudioHdr *IBoneSetup::GetStudioHdr() +{ + return (CStudioHdr *)m_pBoneSetup->m_pStudioHdr; +} + +CBoneSetup::CBoneSetup( const CStudioHdr *pStudioHdr, int boneMask, const float poseParameter[], IPoseDebugger *pPoseDebugger ) +{ + m_pStudioHdr = pStudioHdr; + m_boneMask = boneMask; + m_flPoseParameter = poseParameter; + m_pPoseDebugger = pPoseDebugger; +} + +#if 0 +//----------------------------------------------------------------------------- +// Purpose: calculate a pose for a single sequence +// adds autolayers, runs local ik rukes +//----------------------------------------------------------------------------- +void CalcPose( + const CStudioHdr *pStudioHdr, + CIKContext *pIKContext, + Vector pos[], + Quaternion q[], + int sequence, + float cycle, + const float poseParameter[], + int boneMask, + float flWeight, + float flTime + ) +{ + mstudioseqdesc_t &seqdesc = ((CStudioHdr *)pStudioHdr)->pSeqdesc( sequence ); + + Assert( flWeight >= 0.0f && flWeight <= 1.0f ); + // This shouldn't be necessary, but the Assert should help us catch whoever is screwing this up + flWeight = clamp( flWeight, 0.0f, 1.0f ); + + // add any IK locks to prevent numautolayers from moving extremities + CIKContext seq_ik; + if (seqdesc.numiklocks) + { + seq_ik.Init( pStudioHdr, vec3_angle, vec3_origin, 0.0, 0, boneMask ); // local space relative so absolute position doesn't mater + seq_ik.AddSequenceLocks( seqdesc, pos, q ); + } + + CalcPoseSingle( pStudioHdr, pos, q, seqdesc, sequence, cycle, poseParameter, boneMask, flTime ); + + if ( pIKContext ) + { + pIKContext->AddDependencies( seqdesc, sequence, cycle, poseParameter, flWeight ); + } + + AddSequenceLayers( pStudioHdr, pIKContext, pos, q, seqdesc, sequence, cycle, poseParameter, boneMask, flWeight, flTime ); + + if (seqdesc.numiklocks) + { + seq_ik.SolveSequenceLocks( seqdesc, pos, q ); + } +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: accumulate a pose for a single sequence on top of existing animation +// adds autolayers, runs local ik rukes +//----------------------------------------------------------------------------- +void CBoneSetup::AccumulatePose( + Vector pos[], + Quaternion q[], + int sequence, + float cycle, + float flWeight, + float flTime, + CIKContext *pIKContext + ) +{ + Vector pos2[MAXSTUDIOBONES]; + QuaternionAligned q2[MAXSTUDIOBONES]; + + Assert( flWeight >= 0.0f && flWeight <= 1.0f ); + // This shouldn't be necessary, but the Assert should help us catch whoever is screwing this up + flWeight = clamp( flWeight, 0.0f, 1.0f ); + + if ( sequence < 0 ) + return; + +#ifdef CLIENT_DLL + // Trigger pose debugger + if (m_pPoseDebugger) + { + m_pPoseDebugger->AccumulatePose( m_pStudioHdr, pIKContext, pos, q, sequence, cycle, m_flPoseParameter, m_boneMask, flWeight, flTime ); + } +#endif + + mstudioseqdesc_t &seqdesc = ((CStudioHdr *)m_pStudioHdr)->pSeqdesc( sequence ); + + // add any IK locks to prevent extremities from moving + CIKContext seq_ik; + if (seqdesc.numiklocks) + { + seq_ik.Init( m_pStudioHdr, vec3_angle, vec3_origin, 0.0, 0, m_boneMask ); // local space relative so absolute position doesn't mater + seq_ik.AddSequenceLocks( seqdesc, pos, q ); + } + + if (seqdesc.flags & STUDIO_LOCAL) + { + ::InitPose( m_pStudioHdr, pos2, q2, m_boneMask ); + } + + if (CalcPoseSingle( m_pStudioHdr, pos2, q2, seqdesc, sequence, cycle, m_flPoseParameter, m_boneMask, flTime )) + { + // this weight is wrong, the IK rules won't composite at the correct intensity + AddLocalLayers( pos2, q2, seqdesc, sequence, cycle, 1.0, flTime, pIKContext ); + SlerpBones( m_pStudioHdr, q, pos, seqdesc, sequence, q2, pos2, flWeight, m_boneMask ); + } + + + if ( pIKContext ) + { + pIKContext->AddDependencies( seqdesc, sequence, cycle, m_flPoseParameter, flWeight ); + } + + AddSequenceLayers( pos, q, seqdesc, sequence, cycle, flWeight, flTime, pIKContext ); + + if (seqdesc.numiklocks) + { + seq_ik.SolveSequenceLocks( seqdesc, pos, q ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: blend together q1,pos1 with q2,pos2. Return result in q1,pos1. +// 0 returns q1, pos1. 1 returns q2, pos2 +//----------------------------------------------------------------------------- +void CalcBoneAdj( + const CStudioHdr *pStudioHdr, + Vector pos[], + Quaternion q[], + const float controllers[], + int boneMask + ) +{ + int i, j, k; + float value; + mstudiobonecontroller_t *pbonecontroller; + Vector p0; + RadianEuler a0; + Quaternion q0; + + for (j = 0; j < pStudioHdr->numbonecontrollers(); j++) + { + pbonecontroller = pStudioHdr->pBonecontroller( j ); + k = pbonecontroller->bone; + + if (pStudioHdr->boneFlags( k ) & boneMask) + { + i = pbonecontroller->inputfield; + value = controllers[i]; + if (value < 0) value = 0; + if (value > 1.0) value = 1.0; + value = (1.0 - value) * pbonecontroller->start + value * pbonecontroller->end; + + switch(pbonecontroller->type & STUDIO_TYPES) + { + case STUDIO_XR: + a0.Init( value * (M_PI / 180.0), 0, 0 ); + AngleQuaternion( a0, q0 ); + QuaternionSM( 1.0, q0, q[k], q[k] ); + break; + case STUDIO_YR: + a0.Init( 0, value * (M_PI / 180.0), 0 ); + AngleQuaternion( a0, q0 ); + QuaternionSM( 1.0, q0, q[k], q[k] ); + break; + case STUDIO_ZR: + a0.Init( 0, 0, value * (M_PI / 180.0) ); + AngleQuaternion( a0, q0 ); + QuaternionSM( 1.0, q0, q[k], q[k] ); + break; + case STUDIO_X: + pos[k].x += value; + break; + case STUDIO_Y: + pos[k].y += value; + break; + case STUDIO_Z: + pos[k].z += value; + break; + } + } + } +} + + +void CalcBoneDerivatives( Vector &velocity, AngularImpulse &angVel, const matrix3x4_t &prev, const matrix3x4_t ¤t, float dt ) +{ + float scale = 1.0; + if ( dt > 0 ) + { + scale = 1.0 / dt; + } + + Vector endPosition, startPosition, deltaAxis; + QAngle endAngles, startAngles; + float deltaAngle; + + MatrixAngles( prev, startAngles, startPosition ); + MatrixAngles( current, endAngles, endPosition ); + + velocity.x = (endPosition.x - startPosition.x) * scale; + velocity.y = (endPosition.y - startPosition.y) * scale; + velocity.z = (endPosition.z - startPosition.z) * scale; + RotationDeltaAxisAngle( startAngles, endAngles, deltaAxis, deltaAngle ); + VectorScale( deltaAxis, (deltaAngle * scale), angVel ); +} + +void CalcBoneVelocityFromDerivative( const QAngle &vecAngles, Vector &velocity, AngularImpulse &angVel, const matrix3x4_t ¤t ) +{ + Vector vecLocalVelocity; + AngularImpulse LocalAngVel; + Quaternion q; + float angle; + MatrixAngles( current, q, vecLocalVelocity ); + QuaternionAxisAngle( q, LocalAngVel, angle ); + LocalAngVel *= angle; + + matrix3x4_t matAngles; + AngleMatrix( vecAngles, matAngles ); + VectorTransform( vecLocalVelocity, matAngles, velocity ); + VectorTransform( LocalAngVel, matAngles, angVel ); +} + + + + +class CIKSolver +{ +public: +//-------- SOLVE TWO LINK INVERSE KINEMATICS ------------- +// Author: Ken Perlin +// +// Given a two link joint from [0,0,0] to end effector position P, +// let link lengths be a and b, and let norm |P| = c. Clearly a+b <= c. +// +// Problem: find a "knee" position Q such that |Q| = a and |P-Q| = b. +// +// In the case of a point on the x axis R = [c,0,0], there is a +// closed form solution S = [d,e,0], where |S| = a and |R-S| = b: +// +// d2+e2 = a2 -- because |S| = a +// (c-d)2+e2 = b2 -- because |R-S| = b +// +// c2-2cd+d2+e2 = b2 -- combine the two equations +// c2-2cd = b2 - a2 +// c-2d = (b2-a2)/c +// d - c/2 = (a2-b2)/c / 2 +// +// d = (c + (a2-b2/c) / 2 -- to solve for d and e. +// e = sqrt(a2-d2) + + static float findD(float a, float b, float c) { + return (c + (a*a-b*b)/c) / 2; + } + static float findE(float a, float d) { return sqrt(a*a-d*d); } + +// This leads to a solution to the more general problem: +// +// (1) R = Mfwd(P) -- rotate P onto the x axis +// (2) Solve for S +// (3) Q = Minv(S) -- rotate back again + + float Mfwd[3][3]; + float Minv[3][3]; + + bool solve(float A, float B, float const P[], float const D[], float Q[]) { + float R[3]; + defineM(P,D); + rot(Minv,P,R); + float r = length(R); + float d = findD(A,B,r); + float e = findE(A,d); + float S[3] = {d,e,0}; + rot(Mfwd,S,Q); + return d > (r - B) && d < A; + } + +// If "knee" position Q needs to be as close as possible to some point D, +// then choose M such that M(D) is in the y>0 half of the z=0 plane. +// +// Given that constraint, define the forward and inverse of M as follows: + + void defineM(float const P[], float const D[]) { + float *X = Minv[0], *Y = Minv[1], *Z = Minv[2]; + +// Minv defines a coordinate system whose x axis contains P, so X = unit(P). + int i; + for (i = 0 ; i < 3 ; i++) + X[i] = P[i]; + normalize(X); + +// Its y axis is perpendicular to P, so Y = unit( E - X(E·X) ). + + float dDOTx = dot(D,X); + for (i = 0 ; i < 3 ; i++) + Y[i] = D[i] - dDOTx * X[i]; + normalize(Y); + +// Its z axis is perpendicular to both X and Y, so Z = X×Y. + + cross(X,Y,Z); + +// Mfwd = (Minv)T, since transposing inverts a rotation matrix. + + for (i = 0 ; i < 3 ; i++) { + Mfwd[i][0] = Minv[0][i]; + Mfwd[i][1] = Minv[1][i]; + Mfwd[i][2] = Minv[2][i]; + } + } + +//------------ GENERAL VECTOR MATH SUPPORT ----------- + + static float dot(float const a[], float const b[]) { return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; } + + static float length(float const v[]) { return sqrt( dot(v,v) ); } + + static void normalize(float v[]) { + float norm = length(v); + for (int i = 0 ; i < 3 ; i++) + v[i] /= norm; + } + + static void cross(float const a[], float const b[], float c[]) { + c[0] = a[1] * b[2] - a[2] * b[1]; + c[1] = a[2] * b[0] - a[0] * b[2]; + c[2] = a[0] * b[1] - a[1] * b[0]; + } + + static void rot(float const M[3][3], float const src[], float dst[]) { + for (int i = 0 ; i < 3 ; i++) + dst[i] = dot(M[i],src); + } +}; + + + +//----------------------------------------------------------------------------- +// Purpose: visual debugging code +//----------------------------------------------------------------------------- +#if 1 +inline void debugLine(const Vector& origin, const Vector& dest, int r, int g, int b, bool noDepthTest, float duration) { }; +#else +extern void drawLine( const Vector &p1, const Vector &p2, int r = 0, int g = 0, int b = 1, bool noDepthTest = true, float duration = 0.1 ); +void debugLine(const Vector& origin, const Vector& dest, int r, int g, int b, bool noDepthTest, float duration) +{ + drawLine( origin, dest, r, g, b, noDepthTest, duration ); +} +#endif + + +//----------------------------------------------------------------------------- +// Purpose: for a 2 bone chain, find the IK solution and reset the matrices +//----------------------------------------------------------------------------- +bool Studio_SolveIK( mstudioikchain_t *pikchain, Vector &targetFoot, matrix3x4_t *pBoneToWorld ) +{ + if (pikchain->pLink(0)->kneeDir.LengthSqr() > 0.0) + { + Vector targetKneeDir, targetKneePos; + // FIXME: knee length should be as long as the legs + Vector tmp = pikchain->pLink( 0 )->kneeDir; + VectorRotate( tmp, pBoneToWorld[ pikchain->pLink( 0 )->bone ], targetKneeDir ); + MatrixPosition( pBoneToWorld[ pikchain->pLink( 1 )->bone ], targetKneePos ); + return Studio_SolveIK( pikchain->pLink( 0 )->bone, pikchain->pLink( 1 )->bone, pikchain->pLink( 2 )->bone, targetFoot, targetKneePos, targetKneeDir, pBoneToWorld ); + } + else + { + return Studio_SolveIK( pikchain->pLink( 0 )->bone, pikchain->pLink( 1 )->bone, pikchain->pLink( 2 )->bone, targetFoot, pBoneToWorld ); + } +} + + +#define KNEEMAX_EPSILON 0.9998 // (0.9998 is about 1 degree) + +//----------------------------------------------------------------------------- +// Purpose: Solve Knee position for a known hip and foot location, but no specific knee direction preference +//----------------------------------------------------------------------------- + +bool Studio_SolveIK( int iThigh, int iKnee, int iFoot, Vector &targetFoot, matrix3x4_t *pBoneToWorld ) +{ + Vector worldFoot, worldKnee, worldThigh; + + MatrixPosition( pBoneToWorld[ iThigh ], worldThigh ); + MatrixPosition( pBoneToWorld[ iKnee ], worldKnee ); + MatrixPosition( pBoneToWorld[ iFoot ], worldFoot ); + + //debugLine( worldThigh, worldKnee, 0, 0, 255, true, 0 ); + //debugLine( worldKnee, worldFoot, 0, 0, 255, true, 0 ); + + Vector ikFoot, ikKnee; + + ikFoot = targetFoot - worldThigh; + ikKnee = worldKnee - worldThigh; + + float l1 = (worldKnee-worldThigh).Length(); + float l2 = (worldFoot-worldKnee).Length(); + float l3 = (worldFoot-worldThigh).Length(); + + // leg too straight to figure out knee? + if (l3 > (l1 + l2) * KNEEMAX_EPSILON) + { + return false; + } + + Vector ikHalf = (worldFoot-worldThigh) * (l1 / l3); + + // FIXME: what to do when the knee completely straight? + Vector ikKneeDir = ikKnee - ikHalf; + VectorNormalize( ikKneeDir ); + + return Studio_SolveIK( iThigh, iKnee, iFoot, targetFoot, worldKnee, ikKneeDir, pBoneToWorld ); +} + +//----------------------------------------------------------------------------- +// Purpose: Realign the matrix so that its X axis points along the desired axis. +//----------------------------------------------------------------------------- +void Studio_AlignIKMatrix( matrix3x4_t &mMat, const Vector &vAlignTo ) +{ + Vector tmp1, tmp2, tmp3; + + // Column 0 (X) becomes the vector. + tmp1 = vAlignTo; + VectorNormalize( tmp1 ); + MatrixSetColumn( tmp1, 0, mMat ); + + // Column 1 (Y) is the cross of the vector and column 2 (Z). + MatrixGetColumn( mMat, 2, tmp3 ); + tmp2 = tmp3.Cross( tmp1 ); + VectorNormalize( tmp2 ); + // FIXME: check for X being too near to Z + MatrixSetColumn( tmp2, 1, mMat ); + + // Column 2 (Z) is the cross of columns 0 (X) and 1 (Y). + tmp3 = tmp1.Cross( tmp2 ); + MatrixSetColumn( tmp3, 2, mMat ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Solve Knee position for a known hip and foot location, and a known knee direction +//----------------------------------------------------------------------------- + +bool Studio_SolveIK( int iThigh, int iKnee, int iFoot, Vector &targetFoot, Vector &targetKneePos, Vector &targetKneeDir, matrix3x4_t *pBoneToWorld ) +{ + Vector worldFoot, worldKnee, worldThigh; + + MatrixPosition( pBoneToWorld[ iThigh ], worldThigh ); + MatrixPosition( pBoneToWorld[ iKnee ], worldKnee ); + MatrixPosition( pBoneToWorld[ iFoot ], worldFoot ); + + //debugLine( worldThigh, worldKnee, 0, 0, 255, true, 0 ); + //debugLine( worldThigh, worldThigh + targetKneeDir, 0, 0, 255, true, 0 ); + // debugLine( worldKnee, targetKnee, 0, 0, 255, true, 0 ); + + Vector ikFoot, ikTargetKnee, ikKnee; + + ikFoot = targetFoot - worldThigh; + ikKnee = targetKneePos - worldThigh; + + float l1 = (worldKnee-worldThigh).Length(); + float l2 = (worldFoot-worldKnee).Length(); + + // exaggerate knee targets for legs that are nearly straight + // FIXME: should be configurable, and the ikKnee should be from the original animation, not modifed + float d = (targetFoot-worldThigh).Length() - min( l1, l2 ); + d = max( l1 + l2, d ); + // FIXME: too short knee directions cause trouble + d = d * 100; + + ikTargetKnee = ikKnee + targetKneeDir * d; + + // debugLine( worldKnee, worldThigh + ikTargetKnee, 0, 0, 255, true, 0 ); + + int color[3] = { 0, 255, 0 }; + + // too far away? (0.9998 is about 1 degree) + if (ikFoot.Length() > (l1 + l2) * KNEEMAX_EPSILON) + { + VectorNormalize( ikFoot ); + VectorScale( ikFoot, (l1 + l2) * KNEEMAX_EPSILON, ikFoot ); + color[0] = 255; color[1] = 0; color[2] = 0; + } + + // too close? + // limit distance to about an 80 degree knee bend + float minDist = max( fabs(l1 - l2) * 1.15, min( l1, l2 ) * 0.15 ); + if (ikFoot.Length() < minDist) + { + // too close to get an accurate vector, just use original vector + ikFoot = (worldFoot - worldThigh); + VectorNormalize( ikFoot ); + VectorScale( ikFoot, minDist, ikFoot ); + } + + CIKSolver ik; + if (ik.solve( l1, l2, ikFoot.Base(), ikTargetKnee.Base(), ikKnee.Base() )) + { + matrix3x4_t& mWorldThigh = pBoneToWorld[ iThigh ]; + matrix3x4_t& mWorldKnee = pBoneToWorld[ iKnee ]; + matrix3x4_t& mWorldFoot = pBoneToWorld[ iFoot ]; + + //debugLine( worldThigh, ikKnee + worldThigh, 255, 0, 0, true, 0 ); + //debugLine( ikKnee + worldThigh, ikFoot + worldThigh, 255, 0, 0, true,0 ); + + // debugLine( worldThigh, ikKnee + worldThigh, color[0], color[1], color[2], true, 0 ); + // debugLine( ikKnee + worldThigh, ikFoot + worldThigh, color[0], color[1], color[2], true,0 ); + + + // build transformation matrix for thigh + Studio_AlignIKMatrix( mWorldThigh, ikKnee ); + Studio_AlignIKMatrix( mWorldKnee, ikFoot - ikKnee ); + + + mWorldKnee[0][3] = ikKnee.x + worldThigh.x; + mWorldKnee[1][3] = ikKnee.y + worldThigh.y; + mWorldKnee[2][3] = ikKnee.z + worldThigh.z; + + mWorldFoot[0][3] = ikFoot.x + worldThigh.x; + mWorldFoot[1][3] = ikFoot.y + worldThigh.y; + mWorldFoot[2][3] = ikFoot.z + worldThigh.z; + + return true; + } + else + { + /* + debugLine( worldThigh, worldThigh + ikKnee, 255, 0, 0, true, 0 ); + debugLine( worldThigh + ikKnee, worldThigh + ikFoot, 255, 0, 0, true, 0 ); + debugLine( worldThigh + ikFoot, worldThigh, 255, 0, 0, true, 0 ); + debugLine( worldThigh + ikKnee, worldThigh + ikTargetKnee, 255, 0, 0, true, 0 ); + */ + return false; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +float Studio_IKRuleWeight( mstudioikrule_t &ikRule, const mstudioanimdesc_t *panim, float flCycle, int &iFrame, float &fraq ) +{ + if (ikRule.end > 1.0f && flCycle < ikRule.start) + { + flCycle = flCycle + 1.0f; + } + + float value = 0.0f; + fraq = (panim->numframes - 1) * (flCycle - ikRule.start) + ikRule.iStart; + iFrame = (int)fraq; + fraq = fraq - iFrame; + + if (flCycle < ikRule.start) + { + iFrame = ikRule.iStart; + fraq = 0.0f; + return 0.0f; + } + else if (flCycle < ikRule.peak ) + { + value = (flCycle - ikRule.start) / (ikRule.peak - ikRule.start); + } + else if (flCycle < ikRule.tail ) + { + return 1.0f; + } + else if (flCycle < ikRule.end ) + { + value = 1.0f - ((flCycle - ikRule.tail) / (ikRule.end - ikRule.tail)); + } + else + { + fraq = (panim->numframes - 1) * (ikRule.end - ikRule.start) + ikRule.iStart; + iFrame = (int)fraq; + fraq = fraq - iFrame; + } + return SimpleSpline( value ); +} + + +float Studio_IKRuleWeight( ikcontextikrule_t &ikRule, float flCycle ) +{ + if (ikRule.end > 1.0f && flCycle < ikRule.start) + { + flCycle = flCycle + 1.0f; + } + + float value = 0.0f; + if (flCycle < ikRule.start) + { + return 0.0f; + } + else if (flCycle < ikRule.peak ) + { + value = (flCycle - ikRule.start) / (ikRule.peak - ikRule.start); + } + else if (flCycle < ikRule.tail ) + { + return 1.0f; + } + else if (flCycle < ikRule.end ) + { + value = 1.0f - ((flCycle - ikRule.tail) / (ikRule.end - ikRule.tail)); + } + return 3.0f * value * value - 2.0f * value * value * value; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +bool Studio_IKShouldLatch( ikcontextikrule_t &ikRule, float flCycle ) +{ + if (ikRule.end > 1.0f && flCycle < ikRule.start) + { + flCycle = flCycle + 1.0f; + } + + if (flCycle < ikRule.peak ) + { + return false; + } + else if (flCycle < ikRule.end ) + { + return true; + } + return false; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +float Studio_IKTail( ikcontextikrule_t &ikRule, float flCycle ) +{ + if (ikRule.end > 1.0f && flCycle < ikRule.start) + { + flCycle = flCycle + 1.0f; + } + + if (flCycle <= ikRule.tail ) + { + return 0.0f; + } + else if (flCycle < ikRule.end ) + { + return ((flCycle - ikRule.tail) / (ikRule.end - ikRule.tail)); + } + return 0.0; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + + +bool Studio_IKAnimationError( const CStudioHdr *pStudioHdr, mstudioikrule_t *pRule, const mstudioanimdesc_t *panim, float flCycle, Vector &pos, Quaternion &q, float &flWeight ) +{ + float fraq; + int iFrame; + + flWeight = Studio_IKRuleWeight( *pRule, panim, flCycle, iFrame, fraq ); + Assert( fraq >= 0.0 && fraq < 1.0 ); + Assert( flWeight >= 0.0f && flWeight <= 1.0f ); + + // This shouldn't be necessary, but the Assert should help us catch whoever is screwing this up + flWeight = clamp( flWeight, 0.0f, 1.0f ); + + if (pRule->type != IK_GROUND && flWeight < 0.0001) + return false; + + mstudioikerror_t *pError = pRule->pError( iFrame ); + if (pError != NULL) + { + if (fraq < 0.001) + { + q = pError[0].q; + pos = pError[0].pos; + } + else + { + QuaternionBlend( pError[0].q, pError[1].q, fraq, q ); + pos = pError[0].pos * (1.0f - fraq) + pError[1].pos * fraq; + } + return true; + } + + mstudiocompressedikerror_t *pCompressed = pRule->pCompressedError(); + if (pCompressed != NULL) + { + CalcDecompressedAnimation( pCompressed, iFrame - pRule->iStart, fraq, pos, q ); + return true; + } + // no data, disable IK rule + Assert( 0 ); + flWeight = 0.0f; + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: For a specific sequence:rule, find where it starts, stops, and what +// the estimated offset from the connection point is. +// return true if the rule is within bounds. +//----------------------------------------------------------------------------- + +bool Studio_IKSequenceError( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int iSequence, float flCycle, int iRule, const float poseParameter[], mstudioanimdesc_t *panim[4], float weight[4], ikcontextikrule_t &ikRule ) +{ + int i; + + memset( &ikRule, 0, sizeof(ikRule) ); + ikRule.start = ikRule.peak = ikRule.tail = ikRule.end = 0; + + + mstudioikrule_t *prevRule = NULL; + + // find overall influence + for (i = 0; i < 4; i++) + { + if (weight[i]) + { + if (iRule >= panim[i]->numikrules || panim[i]->numikrules != panim[0]->numikrules) + { + Assert( 0 ); + return false; + } + + mstudioikrule_t *pRule = panim[i]->pIKRule( iRule ); + if (pRule == NULL) + return false; + + float dt = 0.0; + if (prevRule != NULL) + { + if (pRule->start - prevRule->start > 0.5) + { + dt = -1.0; + } + else if (pRule->start - prevRule->start < -0.5) + { + dt = 1.0; + } + } + else + { + prevRule = pRule; + } + + ikRule.start += (pRule->start + dt) * weight[i]; + ikRule.peak += (pRule->peak + dt) * weight[i]; + ikRule.tail += (pRule->tail + dt) * weight[i]; + ikRule.end += (pRule->end + dt) * weight[i]; + } + } + if (ikRule.start > 1.0) + { + ikRule.start -= 1.0; + ikRule.peak -= 1.0; + ikRule.tail -= 1.0; + ikRule.end -= 1.0; + } + else if (ikRule.start < 0.0) + { + ikRule.start += 1.0; + ikRule.peak += 1.0; + ikRule.tail += 1.0; + ikRule.end += 1.0; + } + + ikRule.flWeight = Studio_IKRuleWeight( ikRule, flCycle ); + if (ikRule.flWeight <= 0.001f) + { + // go ahead and allow IK_GROUND rules a virtual looping section + if ( panim[0]->pIKRule( iRule ) == NULL ) + return false; + if ((panim[0]->flags & STUDIO_LOOPING) && panim[0]->pIKRule( iRule )->type == IK_GROUND && ikRule.end - ikRule.start > 0.75 ) + { + ikRule.flWeight = 0.001; + flCycle = ikRule.end - 0.001; + } + else + { + return false; + } + } + + Assert( ikRule.flWeight > 0.0f ); + + ikRule.pos.Init(); + ikRule.q.Init(); + + // find target error + float total = 0.0f; + for (i = 0; i < 4; i++) + { + if (weight[i]) + { + Vector pos1; + Quaternion q1; + float w; + + mstudioikrule_t *pRule = panim[i]->pIKRule( iRule ); + if (pRule == NULL) + return false; + + ikRule.chain = pRule->chain; // FIXME: this is anim local + ikRule.bone = pRule->bone; // FIXME: this is anim local + ikRule.type = pRule->type; + ikRule.slot = pRule->slot; + + ikRule.height += pRule->height * weight[i]; + ikRule.floor += pRule->floor * weight[i]; + ikRule.radius += pRule->radius * weight[i]; + ikRule.drop += pRule->drop * weight[i]; + ikRule.top += pRule->top * weight[i]; + + // keep track of tail condition + ikRule.release += Studio_IKTail( ikRule, flCycle ) * weight[i]; + + // only check rules with error values + switch( ikRule.type ) + { + case IK_SELF: + case IK_WORLD: + case IK_GROUND: + case IK_ATTACHMENT: + { + int bResult = Studio_IKAnimationError( pStudioHdr, pRule, panim[i], flCycle, pos1, q1, w ); + + if (bResult) + { + ikRule.pos = ikRule.pos + pos1 * weight[i]; + QuaternionAccumulate( ikRule.q, weight[i], q1, ikRule.q ); + total += weight[i]; + } + } + break; + default: + total += weight[i]; + break; + } + + ikRule.latched = Studio_IKShouldLatch( ikRule, flCycle ) * ikRule.flWeight; + + if (ikRule.type == IK_ATTACHMENT) + { + ikRule.szLabel = pRule->pszAttachment(); + } + } + } + + if (total <= 0.0001f) + { + return false; + } + + if (total < 0.999f) + { + VectorScale( ikRule.pos, 1.0f / total, ikRule.pos ); + QuaternionScale( ikRule.q, 1.0f / total, ikRule.q ); + } + + if (ikRule.type == IK_SELF && ikRule.bone != -1) + { + // FIXME: this is anim local, not seq local! + ikRule.bone = pStudioHdr->RemapSeqBone( iSequence, ikRule.bone ); + if (ikRule.bone == -1) + return false; + } + + QuaternionNormalize( ikRule.q ); + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + + +CIKContext::CIKContext() +{ + m_target.EnsureCapacity( 12 ); // FIXME: this sucks, shouldn't it be grown? + m_iFramecounter = -1; + m_pStudioHdr = NULL; + m_flTime = -1.0f; + m_target.SetSize( 0 ); +} + + +void CIKContext::Init( const CStudioHdr *pStudioHdr, const QAngle &angles, const Vector &pos, float flTime, int iFramecounter, int boneMask ) +{ + m_pStudioHdr = pStudioHdr; + m_ikChainRule.RemoveAll(); // m_numikrules = 0; + if (pStudioHdr->numikchains()) + { + m_ikChainRule.SetSize( pStudioHdr->numikchains() ); + + // FIXME: Brutal hackery to prevent a crash + if (m_target.Count() == 0) + { + m_target.SetSize(12); + memset( m_target.Base(), 0, sizeof(m_target[0])*m_target.Count() ); + ClearTargets(); + } + + } + else + { + m_target.SetSize( 0 ); + } + AngleMatrix( angles, pos, m_rootxform ); + m_iFramecounter = iFramecounter; + m_flTime = flTime; + m_boneMask = boneMask; +} + +void CIKContext::AddDependencies( mstudioseqdesc_t &seqdesc, int iSequence, float flCycle, const float poseParameters[], float flWeight ) +{ + int i; + + if ( m_pStudioHdr->numikchains() == 0) + return; + + if (seqdesc.numikrules == 0) + return; + + ikcontextikrule_t ikrule; + + Assert( flWeight >= 0.0f && flWeight <= 1.0f ); + // This shouldn't be necessary, but the Assert should help us catch whoever is screwing this up + flWeight = clamp( flWeight, 0.0f, 1.0f ); + + // unify this + if (seqdesc.flags & STUDIO_REALTIME) + { + float cps = Studio_CPS( m_pStudioHdr, seqdesc, iSequence, poseParameters ); + flCycle = m_flTime * cps; + flCycle = flCycle - (int)flCycle; + } + else if (flCycle < 0 || flCycle >= 1) + { + if (seqdesc.flags & STUDIO_LOOPING) + { + flCycle = flCycle - (int)flCycle; + if (flCycle < 0) flCycle += 1; + } + else + { + flCycle = max( 0.0, min( flCycle, 0.9999 ) ); + } + } + + mstudioanimdesc_t *panim[4]; + float weight[4]; + + Studio_SeqAnims( m_pStudioHdr, seqdesc, iSequence, poseParameters, panim, weight ); + + // FIXME: add proper number of rules!!! + for (i = 0; i < seqdesc.numikrules; i++) + { + if ( !Studio_IKSequenceError( m_pStudioHdr, seqdesc, iSequence, flCycle, i, poseParameters, panim, weight, ikrule ) ) + continue; + + // don't add rule if the bone isn't going to be calculated + int bone = m_pStudioHdr->pIKChain( ikrule.chain )->pLink( 2 )->bone; + if ( !(m_pStudioHdr->boneFlags( bone ) & m_boneMask)) + continue; + + // or if its relative bone isn't going to be calculated + if ( ikrule.bone >= 0 && !(m_pStudioHdr->boneFlags( ikrule.bone ) & m_boneMask)) + continue; + + // FIXME: Brutal hackery to prevent a crash + if (m_target.Count() == 0) + { + m_target.SetSize(12); + memset( m_target.Base(), 0, sizeof(m_target[0])*m_target.Count() ); + ClearTargets(); + } + + ikrule.flRuleWeight = flWeight; + + if (ikrule.flRuleWeight * ikrule.flWeight > 0.999) + { + if ( ikrule.type != IK_UNLATCH) + { + // clear out chain if rule is 100% + m_ikChainRule.Element( ikrule.chain ).RemoveAll( ); + if ( ikrule.type == IK_RELEASE) + { + continue; + } + } + } + + int nIndex = m_ikChainRule.Element( ikrule.chain ).AddToTail( ); + m_ikChainRule.Element( ikrule.chain ).Element( nIndex ) = ikrule; + } +} + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void CIKContext::AddAutoplayLocks( Vector pos[], Quaternion q[] ) +{ + // skip all array access if no autoplay locks. + if (m_pStudioHdr->GetNumIKAutoplayLocks() == 0) + { + return; + } + + matrix3x4_t *boneToWorld = g_MatrixPool.Alloc(); + CBoneBitList boneComputed; + + int ikOffset = m_ikLock.AddMultipleToTail( m_pStudioHdr->GetNumIKAutoplayLocks() ); + memset( &m_ikLock[ikOffset], 0, sizeof(ikcontextikrule_t)*m_pStudioHdr->GetNumIKAutoplayLocks() ); + + for (int i = 0; i < m_pStudioHdr->GetNumIKAutoplayLocks(); i++) + { + const mstudioiklock_t &lock = ((CStudioHdr *)m_pStudioHdr)->pIKAutoplayLock( i ); + mstudioikchain_t *pchain = m_pStudioHdr->pIKChain( lock.chain ); + int bone = pchain->pLink( 2 )->bone; + + // don't bother with iklock if the bone isn't going to be calculated + if ( !(m_pStudioHdr->boneFlags( bone ) & m_boneMask)) + continue; + + // eval current ik'd bone + BuildBoneChain( pos, q, bone, boneToWorld, boneComputed ); + + ikcontextikrule_t &ikrule = m_ikLock[ i + ikOffset ]; + + ikrule.chain = lock.chain; + ikrule.slot = i; + ikrule.type = IK_WORLD; + + MatrixAngles( boneToWorld[bone], ikrule.q, ikrule.pos ); + + // save off current knee direction + if (pchain->pLink(0)->kneeDir.LengthSqr() > 0.0) + { + Vector tmp = pchain->pLink( 0 )->kneeDir; + VectorRotate( pchain->pLink( 0 )->kneeDir, boneToWorld[ pchain->pLink( 0 )->bone ], ikrule.kneeDir ); + MatrixPosition( boneToWorld[ pchain->pLink( 1 )->bone ], ikrule.kneePos ); + } + else + { + ikrule.kneeDir.Init( ); + } + } + g_MatrixPool.Free( boneToWorld ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void CIKContext::AddSequenceLocks( mstudioseqdesc_t &seqdesc, Vector pos[], Quaternion q[] ) +{ + if ( m_pStudioHdr->numikchains() == 0) + { + return; + } + + if ( seqdesc.numiklocks == 0 ) + { + return; + } + + matrix3x4_t *boneToWorld = g_MatrixPool.Alloc(); + CBoneBitList boneComputed; + + int ikOffset = m_ikLock.AddMultipleToTail( seqdesc.numiklocks ); + memset( &m_ikLock[ikOffset], 0, sizeof(ikcontextikrule_t) * seqdesc.numiklocks ); + + for (int i = 0; i < seqdesc.numiklocks; i++) + { + mstudioiklock_t *plock = seqdesc.pIKLock( i ); + mstudioikchain_t *pchain = m_pStudioHdr->pIKChain( plock->chain ); + int bone = pchain->pLink( 2 )->bone; + + // don't bother with iklock if the bone isn't going to be calculated + if ( !(m_pStudioHdr->boneFlags( bone ) & m_boneMask)) + continue; + + // eval current ik'd bone + BuildBoneChain( pos, q, bone, boneToWorld, boneComputed ); + + ikcontextikrule_t &ikrule = m_ikLock[i+ikOffset]; + ikrule.chain = i; + ikrule.slot = i; + ikrule.type = IK_WORLD; + + MatrixAngles( boneToWorld[bone], ikrule.q, ikrule.pos ); + + // save off current knee direction + if (pchain->pLink(0)->kneeDir.LengthSqr() > 0.0) + { + VectorRotate( pchain->pLink( 0 )->kneeDir, boneToWorld[ pchain->pLink( 0 )->bone ], ikrule.kneeDir ); + } + else + { + ikrule.kneeDir.Init( ); + } + } + g_MatrixPool.Free( boneToWorld ); +} + +//----------------------------------------------------------------------------- +// Purpose: build boneToWorld transforms for a specific bone +//----------------------------------------------------------------------------- +void CIKContext::BuildBoneChain( + const Vector pos[], + const Quaternion q[], + int iBone, + matrix3x4_t *pBoneToWorld, + CBoneBitList &boneComputed ) +{ + Assert( m_pStudioHdr->boneFlags( iBone ) & m_boneMask ); + ::BuildBoneChain( m_pStudioHdr, m_rootxform, pos, q, iBone, pBoneToWorld, boneComputed ); +} + + + +//----------------------------------------------------------------------------- +// Purpose: build boneToWorld transforms for a specific bone +//----------------------------------------------------------------------------- +void BuildBoneChain( + const CStudioHdr *pStudioHdr, + const matrix3x4_t &rootxform, + const Vector pos[], + const Quaternion q[], + int iBone, + matrix3x4_t *pBoneToWorld, + CBoneBitList &boneComputed ) +{ + if ( boneComputed.IsBoneMarked(iBone) ) + return; + + matrix3x4_t bonematrix; + QuaternionMatrix( q[iBone], pos[iBone], bonematrix ); + + int parent = pStudioHdr->boneParent( iBone ); + if (parent == -1) + { + ConcatTransforms( rootxform, bonematrix, pBoneToWorld[iBone] ); + } + else + { + // evil recursive!!! + BuildBoneChain( pStudioHdr, rootxform, pos, q, parent, pBoneToWorld, boneComputed ); + ConcatTransforms( pBoneToWorld[parent], bonematrix, pBoneToWorld[iBone]); + } + boneComputed.MarkBone(iBone); +} + + +//----------------------------------------------------------------------------- +// Purpose: turn a specific bones boneToWorld transform into a pos and q in parents bonespace +//----------------------------------------------------------------------------- +void SolveBone( + const CStudioHdr *pStudioHdr, + int iBone, + matrix3x4_t *pBoneToWorld, + Vector pos[], + Quaternion q[] + ) +{ + int iParent = pStudioHdr->boneParent( iBone ); + + matrix3x4_t worldToBone; + MatrixInvert( pBoneToWorld[iParent], worldToBone ); + + matrix3x4_t local; + ConcatTransforms( worldToBone, pBoneToWorld[iBone], local ); + + MatrixAngles( local, q[iBone], pos[iBone] ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void CIKTarget::SetOwner( int entindex, const Vector &pos, const QAngle &angles ) +{ + latched.owner = entindex; + latched.absOrigin = pos; + latched.absAngles = angles; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void CIKTarget::ClearOwner( void ) +{ + latched.owner = -1; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int CIKTarget::GetOwner( void ) +{ + return latched.owner; +} + +//----------------------------------------------------------------------------- +// Purpose: update the latched IK values that are in a moving frame of reference +//----------------------------------------------------------------------------- + +void CIKTarget::UpdateOwner( int entindex, const Vector &pos, const QAngle &angles ) +{ + if (pos == latched.absOrigin && angles == latched.absAngles) + return; + + matrix3x4_t in, out; + AngleMatrix( angles, pos, in ); + AngleIMatrix( latched.absAngles, latched.absOrigin, out ); + + matrix3x4_t tmp1, tmp2; + QuaternionMatrix( latched.q, latched.pos, tmp1 ); + ConcatTransforms( out, tmp1, tmp2 ); + ConcatTransforms( in, tmp2, tmp1 ); + MatrixAngles( tmp1, latched.q, latched.pos ); +} + + +//----------------------------------------------------------------------------- +// Purpose: sets the ground position of an ik target +//----------------------------------------------------------------------------- + +void CIKTarget::SetPos( const Vector &pos ) +{ + est.pos = pos; +} + +//----------------------------------------------------------------------------- +// Purpose: sets the ground "identity" orientation of an ik target +//----------------------------------------------------------------------------- + +void CIKTarget::SetAngles( const QAngle &angles ) +{ + AngleQuaternion( angles, est.q ); +} + +//----------------------------------------------------------------------------- +// Purpose: sets the ground "identity" orientation of an ik target +//----------------------------------------------------------------------------- + +void CIKTarget::SetQuaternion( const Quaternion &q ) +{ + est.q = q; +} + +//----------------------------------------------------------------------------- +// Purpose: calculates a ground "identity" orientation based on the surface +// normal of the ground and the desired ground identity orientation +//----------------------------------------------------------------------------- + +void CIKTarget::SetNormal( const Vector &normal ) +{ + // recalculate foot angle based on slope of surface + matrix3x4_t m1; + Vector forward, right; + QuaternionMatrix( est.q, m1 ); + + MatrixGetColumn( m1, 1, right ); + forward = CrossProduct( right, normal ); + right = CrossProduct( normal, forward ); + MatrixSetColumn( forward, 0, m1 ); + MatrixSetColumn( right, 1, m1 ); + MatrixSetColumn( normal, 2, m1 ); + QAngle a1; + Vector p1; + MatrixAngles( m1, est.q, p1 ); +} + + +//----------------------------------------------------------------------------- +// Purpose: estimates the ground impact at the center location assuming a the edge of +// an Z axis aligned disc collided with it the surface. +//----------------------------------------------------------------------------- + +void CIKTarget::SetPosWithNormalOffset( const Vector &pos, const Vector &normal ) +{ + // assume it's a disc edge intersecting with the floor, so try to estimate the z location of the center + est.pos = pos; + if (normal.z > 0.9999) + { + return; + } + // clamp at 45 degrees + else if (normal.z > 0.707) + { + // tan == sin / cos + float tan = sqrt( 1 - normal.z * normal.z ) / normal.z; + est.pos.z = est.pos.z - est.radius * tan; + } + else + { + est.pos.z = est.pos.z - est.radius; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void CIKTarget::SetOnWorld( bool bOnWorld ) +{ + est.onWorld = bOnWorld; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +bool CIKTarget::IsActive() +{ + return (est.flWeight > 0.0f); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void CIKTarget::IKFailed( void ) +{ + latched.deltaPos.Init(); + latched.deltaQ.Init(); + latched.pos = ideal.pos; + latched.q = ideal.q; + est.latched = 0.0; + est.flWeight = 0.0; + est.onWorld = false; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void CIKTarget::MoveReferenceFrame( Vector &deltaPos, QAngle &deltaAngles ) +{ + est.pos -= deltaPos; + latched.pos -= deltaPos; + offset.pos -= deltaPos; + ideal.pos -= deltaPos; +} + + + +//----------------------------------------------------------------------------- +// Purpose: Invalidate any IK locks. +//----------------------------------------------------------------------------- + +void CIKContext::ClearTargets( void ) +{ + int i; + for (i = 0; i < m_target.Count(); i++) + { + m_target[i].latched.iFramecounter = -9999; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Run through the rules that survived and turn a specific bones boneToWorld +// transform into a pos and q in parents bonespace +//----------------------------------------------------------------------------- + +void CIKContext::UpdateTargets( Vector pos[], Quaternion q[], matrix3x4_t boneToWorld[], CBoneBitList &boneComputed ) +{ + int i, j; + + for (i = 0; i < m_target.Count(); i++) + { + m_target[i].est.flWeight = 0.0f; + m_target[i].est.latched = 1.0f; + m_target[i].est.release = 1.0f; + m_target[i].est.height = 0.0f; + m_target[i].est.floor = 0.0f; + m_target[i].est.radius = 0.0f; + m_target[i].offset.pos.Init(); + m_target[i].offset.q.Init(); + } + + AutoIKRelease( ); + + for (j = 0; j < m_ikChainRule.Count(); j++) + { + for (i = 0; i < m_ikChainRule.Element( j ).Count(); i++) + { + ikcontextikrule_t *pRule = &m_ikChainRule.Element( j ).Element( i ); + + // ikchainresult_t *pChainRule = &chainRule[ m_ikRule[i].chain ]; + + switch( pRule->type ) + { + case IK_ATTACHMENT: + case IK_GROUND: + // case IK_SELF: + { + matrix3x4_t footTarget; + CIKTarget *pTarget = &m_target[pRule->slot]; + pTarget->chain = pRule->chain; + pTarget->type = pRule->type; + + if (pRule->type == IK_ATTACHMENT) + { + pTarget->offset.pAttachmentName = pRule->szLabel; + } + else + { + pTarget->offset.pAttachmentName = NULL; + } + + if (pRule->flRuleWeight == 1.0f || pTarget->est.flWeight == 0.0f) + { + pTarget->offset.q = pRule->q; + pTarget->offset.pos = pRule->pos; + pTarget->est.height = pRule->height; + pTarget->est.floor = pRule->floor; + pTarget->est.radius = pRule->radius; + pTarget->est.latched = pRule->latched * pRule->flRuleWeight; + pTarget->est.release = pRule->release; + pTarget->est.flWeight = pRule->flWeight * pRule->flRuleWeight; + } + else + { + QuaternionSlerp( pTarget->offset.q, pRule->q, pRule->flRuleWeight, pTarget->offset.q ); + pTarget->offset.pos = Lerp( pRule->flRuleWeight, pTarget->offset.pos, pRule->pos ); + pTarget->est.height = Lerp( pRule->flRuleWeight, pTarget->est.height, pRule->height ); + pTarget->est.floor = Lerp( pRule->flRuleWeight, pTarget->est.floor, pRule->floor ); + pTarget->est.radius = Lerp( pRule->flRuleWeight, pTarget->est.radius, pRule->radius ); + //pTarget->est.latched = Lerp( pRule->flRuleWeight, pTarget->est.latched, pRule->latched ); + pTarget->est.latched = min( pTarget->est.latched, pRule->latched ); + pTarget->est.release = Lerp( pRule->flRuleWeight, pTarget->est.release, pRule->release ); + pTarget->est.flWeight = Lerp( pRule->flRuleWeight, pTarget->est.flWeight, pRule->flWeight ); + } + + if ( pRule->type == IK_GROUND ) + { + pTarget->latched.deltaPos.z = 0; + pTarget->est.pos.z = pTarget->est.floor + m_rootxform[2][3]; + } + } + break; + case IK_UNLATCH: + { + CIKTarget *pTarget = &m_target[pRule->slot]; + if (pRule->latched > 0.0) + pTarget->est.latched = 0.0; + else + pTarget->est.latched = min( pTarget->est.latched, 1.0f - pRule->flWeight ); + } + break; + case IK_RELEASE: + { + CIKTarget *pTarget = &m_target[pRule->slot]; + if (pRule->latched > 0.0) + pTarget->est.latched = 0.0; + else + pTarget->est.latched = min( pTarget->est.latched, 1.0f - pRule->flWeight ); + + pTarget->est.flWeight = (pTarget->est.flWeight) * (1 - pRule->flWeight * pRule->flRuleWeight); + } + break; + } + } + } + + for (i = 0; i < m_target.Count(); i++) + { + CIKTarget *pTarget = &m_target[i]; + if (pTarget->est.flWeight > 0.0) + { + mstudioikchain_t *pchain = m_pStudioHdr->pIKChain( pTarget->chain ); + // ikchainresult_t *pChainRule = &chainRule[ i ]; + int bone = pchain->pLink( 2 )->bone; + + // eval current ik'd bone + BuildBoneChain( pos, q, bone, boneToWorld, boneComputed ); + + // xform IK target error into world space + matrix3x4_t local; + matrix3x4_t worldFootpad; + QuaternionMatrix( pTarget->offset.q, pTarget->offset.pos, local ); + MatrixInvert( local, local ); + ConcatTransforms( boneToWorld[bone], local, worldFootpad ); + + if (pTarget->est.latched == 1.0) + { + pTarget->latched.bNeedsLatch = true; + } + else + { + pTarget->latched.bNeedsLatch = false; + } + + // disable latched position if it looks invalid + if (m_iFramecounter < 0 || pTarget->latched.iFramecounter < m_iFramecounter - 1 || pTarget->latched.iFramecounter > m_iFramecounter) + { + pTarget->latched.bHasLatch = false; + pTarget->latched.influence = 0.0; + } + pTarget->latched.iFramecounter = m_iFramecounter; + + // find ideal contact position + MatrixAngles( worldFootpad, pTarget->ideal.q, pTarget->ideal.pos ); + pTarget->est.q = pTarget->ideal.q; + pTarget->est.pos = pTarget->ideal.pos; + + float latched = pTarget->est.latched; + + if (pTarget->latched.bHasLatch) + { + if (pTarget->est.latched == 1.0) + { + // keep track of latch position error from ideal contact position + pTarget->latched.deltaPos = pTarget->latched.pos - pTarget->est.pos; + QuaternionSM( -1, pTarget->est.q, pTarget->latched.q, pTarget->latched.deltaQ ); + pTarget->est.q = pTarget->latched.q; + pTarget->est.pos = pTarget->latched.pos; + } + else if (pTarget->est.latched > 0.0) + { + // ramp out latch differences during decay phase of rule + if (latched > 0 && latched < pTarget->latched.influence) + { + // latching has decreased + float dt = pTarget->latched.influence - latched; + if (pTarget->latched.influence > 0.0) + dt = dt / pTarget->latched.influence; + + VectorScale( pTarget->latched.deltaPos, (1-dt), pTarget->latched.deltaPos ); + QuaternionScale( pTarget->latched.deltaQ, (1-dt), pTarget->latched.deltaQ ); + } + + // move ideal contact position by latched error factor + pTarget->est.pos = pTarget->est.pos + pTarget->latched.deltaPos; + QuaternionMA( pTarget->est.q, 1, pTarget->latched.deltaQ, pTarget->est.q ); + pTarget->latched.q = pTarget->est.q; + pTarget->latched.pos = pTarget->est.pos; + } + else + { + pTarget->latched.bHasLatch = false; + pTarget->latched.q = pTarget->est.q; + pTarget->latched.pos = pTarget->est.pos; + pTarget->latched.deltaPos.Init(); + pTarget->latched.deltaQ.Init(); + } + pTarget->latched.influence = latched; + } + + // check for illegal requests + Vector p1, p2, p3; + MatrixPosition( boneToWorld[pchain->pLink( 0 )->bone], p1 ); // hip + MatrixPosition( boneToWorld[pchain->pLink( 1 )->bone], p2 ); // knee + MatrixPosition( boneToWorld[pchain->pLink( 2 )->bone], p3 ); // foot + + float d1 = (p2 - p1).Length(); + float d2 = (p3 - p2).Length(); + + if (pTarget->latched.bHasLatch) + { + //float d3 = (p3 - p1).Length(); + float d4 = (p3 + pTarget->latched.deltaPos - p1).Length(); + + // unstick feet when distance is too great + if ((d4 < fabs( d1 - d2 ) || d4 * 0.95 > d1 + d2) && pTarget->est.latched > 0.2) + { + pTarget->error.flTime = m_flTime; + } + + // unstick feet when angle is too great + if (pTarget->est.latched > 0.2) + { + float d = fabs( pTarget->latched.deltaQ.w ) * 2.0f - 1.0f; // QuaternionDotProduct( pTarget->latched.q, pTarget->est.q ); + + // FIXME: cos(45), make property of chain + if (d < 0.707) + { + pTarget->error.flTime = m_flTime; + } + } + } + + Vector dt = pTarget->est.pos - p1; + pTarget->trace.hipToFoot = VectorNormalize( dt ); + pTarget->trace.hipToKnee = d1; + pTarget->trace.kneeToFoot = d2; + pTarget->trace.hip = p1; + pTarget->trace.knee = p2; + pTarget->trace.closest = p1 + dt * (fabs( d1 - d2 ) * 1.01); + pTarget->trace.farthest = p1 + dt * (d1 + d2) * 0.99; + pTarget->trace.lowest = p1 + Vector( 0, 0, -1 ) * (d1 + d2) * 0.99; + // pTarget->trace.endpos = pTarget->est.pos; + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: insert release rules if the ik rules were in error +//----------------------------------------------------------------------------- + +void CIKContext::AutoIKRelease( void ) +{ + int i; + + for (i = 0; i < m_target.Count(); i++) + { + CIKTarget *pTarget = &m_target[i]; + + float dt = m_flTime - pTarget->error.flTime; + if (pTarget->error.bInError || dt < 0.5) + { + if (!pTarget->error.bInError) + { + pTarget->error.ramp = 0.0; + pTarget->error.flErrorTime = pTarget->error.flTime; + pTarget->error.bInError = true; + } + + float ft = m_flTime - pTarget->error.flErrorTime; + if (dt < 0.25) + { + pTarget->error.ramp = min( pTarget->error.ramp + ft * 4.0, 1.0 ); + } + else + { + pTarget->error.ramp = max( pTarget->error.ramp - ft * 4.0, 0.0 ); + } + if (pTarget->error.ramp > 0.0) + { + ikcontextikrule_t ikrule; + + ikrule.chain = pTarget->chain; + ikrule.bone = 0; + ikrule.type = IK_RELEASE; + ikrule.slot = i; + ikrule.flWeight = SimpleSpline( pTarget->error.ramp ); + ikrule.flRuleWeight = 1.0; + ikrule.latched = dt < 0.25 ? 0.0 : ikrule.flWeight; + + // don't bother with AutoIKRelease if the bone isn't going to be calculated + // this code is crashing for some unknown reason. + if ( pTarget->chain >= 0 && pTarget->chain < m_pStudioHdr->numikchains()) + { + mstudioikchain_t *pchain = m_pStudioHdr->pIKChain( pTarget->chain ); + if (pchain != NULL) + { + int bone = pchain->pLink( 2 )->bone; + if (bone >= 0 && bone < m_pStudioHdr->numbones()) + { + mstudiobone_t *pBone = m_pStudioHdr->pBone( bone ); + if (pBone != NULL) + { + if ( !(m_pStudioHdr->boneFlags( bone ) & m_boneMask)) + { + pTarget->error.bInError = false; + continue; + } + /* + char buf[256]; + sprintf( buf, "dt %.4f ft %.4f weight %.4f latched %.4f\n", dt, ft, ikrule.flWeight, ikrule.latched ); + OutputDebugString( buf ); + */ + + int nIndex = m_ikChainRule.Element( ikrule.chain ).AddToTail( ); + m_ikChainRule.Element( ikrule.chain ).Element( nIndex ) = ikrule; + } + else + { + DevWarning( 1, "AutoIKRelease (%s) got a NULL pBone %d\n", m_pStudioHdr->pszName(), bone ); + } + } + else + { + DevWarning( 1, "AutoIKRelease (%s) got an out of range bone %d (%d)\n", m_pStudioHdr->pszName(), bone, m_pStudioHdr->numbones() ); + } + } + else + { + DevWarning( 1, "AutoIKRelease (%s) got a NULL pchain %d\n", m_pStudioHdr->pszName(), pTarget->chain ); + } + } + else + { + DevWarning( 1, "AutoIKRelease (%s) got an out of range chain %d (%d)\n", m_pStudioHdr->pszName(), pTarget->chain, m_pStudioHdr->numikchains()); + } + } + else + { + pTarget->error.bInError = false; + } + pTarget->error.flErrorTime = m_flTime; + } + } +} + + + +void CIKContext::SolveDependencies( Vector pos[], Quaternion q[], matrix3x4_t boneToWorld[], CBoneBitList &boneComputed ) +{ +// ASSERT_NO_REENTRY(); + + matrix3x4_t worldTarget; + int i, j; + + ikchainresult_t chainResult[32]; // allocate!!! + + // init chain rules + for (i = 0; i < m_pStudioHdr->numikchains(); i++) + { + mstudioikchain_t *pchain = m_pStudioHdr->pIKChain( i ); + ikchainresult_t *pChainResult = &chainResult[ i ]; + int bone = pchain->pLink( 2 )->bone; + + pChainResult->target = -1; + pChainResult->flWeight = 0.0; + + // don't bother with chain if the bone isn't going to be calculated + if ( !(m_pStudioHdr->boneFlags( bone ) & m_boneMask)) + continue; + + // eval current ik'd bone + BuildBoneChain( pos, q, bone, boneToWorld, boneComputed ); + + MatrixAngles( boneToWorld[bone], pChainResult->q, pChainResult->pos ); + } + + for (j = 0; j < m_ikChainRule.Count(); j++) + { + for (i = 0; i < m_ikChainRule.Element( j ).Count(); i++) + { + ikcontextikrule_t *pRule = &m_ikChainRule.Element( j ).Element( i ); + ikchainresult_t *pChainResult = &chainResult[ pRule->chain ]; + pChainResult->target = -1; + + + switch( pRule->type ) + { + case IK_SELF: + { + // xform IK target error into world space + matrix3x4_t local; + QuaternionMatrix( pRule->q, pRule->pos, local ); + // eval target bone space + if (pRule->bone != -1) + { + BuildBoneChain( pos, q, pRule->bone, boneToWorld, boneComputed ); + ConcatTransforms( boneToWorld[pRule->bone], local, worldTarget ); + } + else + { + ConcatTransforms( m_rootxform, local, worldTarget ); + } + + float flWeight = pRule->flWeight * pRule->flRuleWeight; + pChainResult->flWeight = pChainResult->flWeight * (1 - flWeight) + flWeight; + + Vector p2; + Quaternion q2; + + // target p and q + MatrixAngles( worldTarget, q2, p2 ); + + // debugLine( pChainResult->pos, p2, 0, 0, 255, true, 0.1 ); + + // blend in position and angles + pChainResult->pos = pChainResult->pos * (1.0 - flWeight) + p2 * flWeight; + QuaternionSlerp( pChainResult->q, q2, flWeight, pChainResult->q ); + } + break; + case IK_WORLD: + Assert( 0 ); + break; + + case IK_ATTACHMENT: + break; + + case IK_GROUND: + break; + + case IK_RELEASE: + { + // move target back towards original location + float flWeight = pRule->flWeight * pRule->flRuleWeight; + mstudioikchain_t *pchain = m_pStudioHdr->pIKChain( pRule->chain ); + int bone = pchain->pLink( 2 )->bone; + + Vector p2; + Quaternion q2; + + BuildBoneChain( pos, q, bone, boneToWorld, boneComputed ); + MatrixAngles( boneToWorld[bone], q2, p2 ); + + // blend in position and angles + pChainResult->pos = pChainResult->pos * (1.0 - flWeight) + p2 * flWeight; + QuaternionSlerp( pChainResult->q, q2, flWeight, pChainResult->q ); + } + break; + case IK_UNLATCH: + { + /* + pChainResult->flWeight = pChainResult->flWeight * (1 - pRule->flWeight) + pRule->flWeight; + + pChainResult->pos = pChainResult->pos * (1.0 - pRule->flWeight ) + pChainResult->local.pos * pRule->flWeight; + QuaternionSlerp( pChainResult->q, pChainResult->local.q, pRule->flWeight, pChainResult->q ); + */ + } + break; + } + } + } + + for (i = 0; i < m_target.Count(); i++) + { + CIKTarget *pTarget = &m_target[i]; + + if (m_target[i].est.flWeight > 0.0) + { + matrix3x4_t worldFootpad; + matrix3x4_t local; + //mstudioikchain_t *pchain = m_pStudioHdr->pIKChain( m_target[i].chain ); + ikchainresult_t *pChainResult = &chainResult[ pTarget->chain ]; + + AngleMatrix(pTarget->offset.q, pTarget->offset.pos, local ); + + AngleMatrix( pTarget->est.q, pTarget->est.pos, worldFootpad ); + + ConcatTransforms( worldFootpad, local, worldTarget ); + + Vector p2; + Quaternion q2; + // target p and q + MatrixAngles( worldTarget, q2, p2 ); + // MatrixAngles( worldTarget, pChainResult->q, pChainResult->pos ); + + // blend in position and angles + pChainResult->flWeight = pTarget->est.flWeight; + pChainResult->pos = pChainResult->pos * (1.0 - pChainResult->flWeight ) + p2 * pChainResult->flWeight; + QuaternionSlerp( pChainResult->q, q2, pChainResult->flWeight, pChainResult->q ); + } + + if (pTarget->latched.bNeedsLatch) + { + // keep track of latch position + pTarget->latched.bHasLatch = true; + pTarget->latched.q = pTarget->est.q; + pTarget->latched.pos = pTarget->est.pos; + } + } + + for (i = 0; i < m_pStudioHdr->numikchains(); i++) + { + ikchainresult_t *pChainResult = &chainResult[ i ]; + mstudioikchain_t *pchain = m_pStudioHdr->pIKChain( i ); + + if (pChainResult->flWeight > 0.0) + { + Vector tmp; + MatrixPosition( boneToWorld[pchain->pLink( 2 )->bone], tmp ); + // debugLine( pChainResult->pos, tmp, 255, 255, 255, true, 0.1 ); + + // do exact IK solution + // FIXME: once per link! + if (Studio_SolveIK(pchain, pChainResult->pos, boneToWorld )) + { + Vector p3; + MatrixGetColumn( boneToWorld[pchain->pLink( 2 )->bone], 3, p3 ); + QuaternionMatrix( pChainResult->q, p3, boneToWorld[pchain->pLink( 2 )->bone] ); + + // rebuild chain + // FIXME: is this needed if everyone past this uses the boneToWorld array? + SolveBone( m_pStudioHdr, pchain->pLink( 2 )->bone, boneToWorld, pos, q ); + SolveBone( m_pStudioHdr, pchain->pLink( 1 )->bone, boneToWorld, pos, q ); + SolveBone( m_pStudioHdr, pchain->pLink( 0 )->bone, boneToWorld, pos, q ); + } + else + { + // FIXME: need to invalidate the targets that forced this... + if (pChainResult->target != -1) + { + CIKTarget *pTarget = &m_target[pChainResult->target]; + VectorScale( pTarget->latched.deltaPos, 0.8, pTarget->latched.deltaPos ); + QuaternionScale( pTarget->latched.deltaQ, 0.8, pTarget->latched.deltaQ ); + } + } + } + } + +#if 0 + Vector p1, p2, p3; + Quaternion q1, q2, q3; + + // current p and q + MatrixAngles( boneToWorld[bone], q1, p1 ); + + + // target p and q + MatrixAngles( worldTarget, q2, p2 ); + + // blend in position and angles + p3 = p1 * (1.0 - m_ikRule[i].flWeight ) + p2 * m_ikRule[i].flWeight; + + // do exact IK solution + // FIXME: once per link! + Studio_SolveIK(pchain, p3, boneToWorld ); + + // force angle (bad?) + QuaternionSlerp( q1, q2, m_ikRule[i].flWeight, q3 ); + MatrixGetColumn( boneToWorld[bone], 3, p3 ); + QuaternionMatrix( q3, p3, boneToWorld[bone] ); + + // rebuild chain + SolveBone( m_pStudioHdr, pchain->pLink( 2 )->bone, boneToWorld, pos, q ); + SolveBone( m_pStudioHdr, pchain->pLink( 1 )->bone, boneToWorld, pos, q ); + SolveBone( m_pStudioHdr, pchain->pLink( 0 )->bone, boneToWorld, pos, q ); +#endif +} + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void CIKContext::SolveAutoplayLocks( + Vector pos[], + Quaternion q[] + ) +{ + matrix3x4_t *boneToWorld = g_MatrixPool.Alloc(); + CBoneBitList boneComputed; + int i; + + for (i = 0; i < m_ikLock.Count(); i++) + { + const mstudioiklock_t &lock = ((CStudioHdr *)m_pStudioHdr)->pIKAutoplayLock( i ); + SolveLock( &lock, i, pos, q, boneToWorld, boneComputed ); + } + g_MatrixPool.Free( boneToWorld ); +} + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void CIKContext::SolveSequenceLocks( + mstudioseqdesc_t &seqdesc, + Vector pos[], + Quaternion q[] + ) +{ + matrix3x4_t *boneToWorld = g_MatrixPool.Alloc(); + CBoneBitList boneComputed; + int i; + + for (i = 0; i < m_ikLock.Count(); i++) + { + mstudioiklock_t *plock = seqdesc.pIKLock( i ); + SolveLock( plock, i, pos, q, boneToWorld, boneComputed ); + } + g_MatrixPool.Free( boneToWorld ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void CIKContext::AddAllLocks( Vector pos[], Quaternion q[] ) +{ + // skip all array access if no autoplay locks. + if (m_pStudioHdr->GetNumIKChains() == 0) + { + return; + } + + matrix3x4_t *boneToWorld = g_MatrixPool.Alloc(); + CBoneBitList boneComputed; + + int ikOffset = m_ikLock.AddMultipleToTail( m_pStudioHdr->GetNumIKChains() ); + memset( &m_ikLock[ikOffset], 0, sizeof(ikcontextikrule_t)*m_pStudioHdr->GetNumIKChains() ); + + for (int i = 0; i < m_pStudioHdr->GetNumIKChains(); i++) + { + mstudioikchain_t *pchain = m_pStudioHdr->pIKChain( i ); + int bone = pchain->pLink( 2 )->bone; + + // don't bother with iklock if the bone isn't going to be calculated + if ( !(m_pStudioHdr->boneFlags( bone ) & m_boneMask)) + continue; + + // eval current ik'd bone + BuildBoneChain( pos, q, bone, boneToWorld, boneComputed ); + + ikcontextikrule_t &ikrule = m_ikLock[ i + ikOffset ]; + + ikrule.chain = i; + ikrule.slot = i; + ikrule.type = IK_WORLD; + + MatrixAngles( boneToWorld[bone], ikrule.q, ikrule.pos ); + + // save off current knee direction + if (pchain->pLink(0)->kneeDir.LengthSqr() > 0.0) + { + Vector tmp = pchain->pLink( 0 )->kneeDir; + VectorRotate( pchain->pLink( 0 )->kneeDir, boneToWorld[ pchain->pLink( 0 )->bone ], ikrule.kneeDir ); + MatrixPosition( boneToWorld[ pchain->pLink( 1 )->bone ], ikrule.kneePos ); + } + else + { + ikrule.kneeDir.Init( ); + } + } + g_MatrixPool.Free( boneToWorld ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + + +void CIKContext::SolveAllLocks( + Vector pos[], + Quaternion q[] + ) +{ + matrix3x4_t *boneToWorld = g_MatrixPool.Alloc(); + CBoneBitList boneComputed; + int i; + + mstudioiklock_t lock; + + for (i = 0; i < m_ikLock.Count(); i++) + { + lock.chain = i; + lock.flPosWeight = 1.0; + lock.flLocalQWeight = 0.0; + lock.flags = 0; + + SolveLock( &lock, i, pos, q, boneToWorld, boneComputed ); + } + g_MatrixPool.Free( boneToWorld ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + + +void CIKContext::SolveLock( + const mstudioiklock_t *plock, + int i, + Vector pos[], + Quaternion q[], + matrix3x4_t boneToWorld[], + CBoneBitList &boneComputed + ) +{ + mstudioikchain_t *pchain = m_pStudioHdr->pIKChain( plock->chain ); + int bone = pchain->pLink( 2 )->bone; + + // don't bother with iklock if the bone isn't going to be calculated + if ( !(m_pStudioHdr->boneFlags( bone ) & m_boneMask)) + return; + + // eval current ik'd bone + BuildBoneChain( pos, q, bone, boneToWorld, boneComputed ); + + Vector p1, p2, p3; + Quaternion q2, q3; + + // current p and q + MatrixPosition( boneToWorld[bone], p1 ); + + // blend in position + p3 = p1 * (1.0 - plock->flPosWeight ) + m_ikLock[i].pos * plock->flPosWeight; + + // do exact IK solution + if (m_ikLock[i].kneeDir.LengthSqr() > 0) + { + Studio_SolveIK(pchain->pLink( 0 )->bone, pchain->pLink( 1 )->bone, pchain->pLink( 2 )->bone, p3, m_ikLock[i].kneePos, m_ikLock[i].kneeDir, boneToWorld ); + } + else + { + Studio_SolveIK(pchain, p3, boneToWorld ); + } + + // slam orientation + MatrixPosition( boneToWorld[bone], p3 ); + QuaternionMatrix( m_ikLock[i].q, p3, boneToWorld[bone] ); + + // rebuild chain + q2 = q[ bone ]; + SolveBone( m_pStudioHdr, pchain->pLink( 2 )->bone, boneToWorld, pos, q ); + QuaternionSlerp( q[bone], q2, plock->flLocalQWeight, q[bone] ); + + SolveBone( m_pStudioHdr, pchain->pLink( 1 )->bone, boneToWorld, pos, q ); + SolveBone( m_pStudioHdr, pchain->pLink( 0 )->bone, boneToWorld, pos, q ); +} + + +//----------------------------------------------------------------------------- +// Purpose: run all animations that automatically play and are driven off of poseParameters +//----------------------------------------------------------------------------- +void CBoneSetup::CalcAutoplaySequences( + Vector pos[], + Quaternion q[], + float flRealTime, + CIKContext *pIKContext + ) +{ + // ASSERT_NO_REENTRY(); + + int i; + if ( pIKContext ) + { + pIKContext->AddAutoplayLocks( pos, q ); + } + + unsigned short *pList = NULL; + int count = m_pStudioHdr->GetAutoplayList( &pList ); + for (i = 0; i < count; i++) + { + int sequenceIndex = pList[i]; + mstudioseqdesc_t &seqdesc = ((CStudioHdr *)m_pStudioHdr)->pSeqdesc( sequenceIndex ); + if (seqdesc.flags & STUDIO_AUTOPLAY) + { + float cycle = 0; + float cps = Studio_CPS( m_pStudioHdr, seqdesc, sequenceIndex, m_flPoseParameter ); + cycle = flRealTime * cps; + cycle = cycle - (int)cycle; + + AccumulatePose( pos, q, sequenceIndex, cycle, 1.0, flRealTime, pIKContext ); + } + } + + if ( pIKContext ) + { + pIKContext->SolveAutoplayLocks( pos, q ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void Studio_BuildMatrices( + const CStudioHdr *pStudioHdr, + const QAngle& angles, + const Vector& origin, + const Vector pos[], + const Quaternion q[], + int iBone, + float flScale, + matrix3x4_t bonetoworld[MAXSTUDIOBONES], + int boneMask + ) +{ + int i, j; + + int chain[MAXSTUDIOBONES] = {}; + int chainlength = 0; + + if (iBone < -1 || iBone >= pStudioHdr->numbones()) + iBone = 0; + + // build list of what bones to use + if (iBone == -1) + { + // all bones + chainlength = pStudioHdr->numbones(); + for (i = 0; i < pStudioHdr->numbones(); i++) + { + chain[chainlength - i - 1] = i; + } + } + else + { + // only the parent bones + i = iBone; + while (i != -1) + { + chain[chainlength++] = i; + i = pStudioHdr->boneParent( i ); + } + } + + matrix3x4_t bonematrix; + matrix3x4_t rotationmatrix; // model to world transformation + AngleMatrix( angles, origin, rotationmatrix ); + + // Account for a change in scale + if ( flScale < 1.0f-FLT_EPSILON || flScale > 1.0f+FLT_EPSILON ) + { + Vector vecOffset; + MatrixGetColumn( rotationmatrix, 3, vecOffset ); + vecOffset -= origin; + vecOffset *= flScale; + vecOffset += origin; + MatrixSetColumn( vecOffset, 3, rotationmatrix ); + + // Scale it uniformly + VectorScale( rotationmatrix[0], flScale, rotationmatrix[0] ); + VectorScale( rotationmatrix[1], flScale, rotationmatrix[1] ); + VectorScale( rotationmatrix[2], flScale, rotationmatrix[2] ); + } + + for (j = chainlength - 1; j >= 0; j--) + { + i = chain[j]; + if (pStudioHdr->boneFlags(i) & boneMask) + { + QuaternionMatrix( q[i], pos[i], bonematrix ); + + if (pStudioHdr->boneParent(i) == -1) + { + ConcatTransforms (rotationmatrix, bonematrix, bonetoworld[i]); + } + else + { + ConcatTransforms (bonetoworld[pStudioHdr->boneParent(i)], bonematrix, bonetoworld[i]); + } + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: look at single column vector of another bones local transformation +// and generate a procedural transformation based on how that column +// points down the 6 cardinal axis (all negative weights are clamped to 0). +//----------------------------------------------------------------------------- + +void DoAxisInterpBone( + mstudiobone_t *pbones, + int ibone, + CBoneAccessor &bonetoworld + ) +{ + matrix3x4_t bonematrix; + Vector control; + + mstudioaxisinterpbone_t *pProc = (mstudioaxisinterpbone_t *)pbones[ibone].pProcedure( ); + const matrix3x4_t &controlBone = bonetoworld.GetBone( pProc->control ); + if (pProc && pbones[pProc->control].parent != -1) + { + Vector tmp; + // pull out the control column + tmp.x = controlBone[0][pProc->axis]; + tmp.y = controlBone[1][pProc->axis]; + tmp.z = controlBone[2][pProc->axis]; + + // invert it back into parent's space. + VectorIRotate( tmp, bonetoworld.GetBone( pbones[pProc->control].parent ), control ); +#if 0 + matrix3x4_t tmpmatrix; + matrix3x4_t controlmatrix; + MatrixInvert( bonetoworld.GetBone( pbones[pProc->control].parent ), tmpmatrix ); + ConcatTransforms( tmpmatrix, bonetoworld.GetBone( pProc->control ), controlmatrix ); + + // pull out the control column + control.x = controlmatrix[0][pProc->axis]; + control.y = controlmatrix[1][pProc->axis]; + control.z = controlmatrix[2][pProc->axis]; +#endif + } + else + { + // pull out the control column + control.x = controlBone[0][pProc->axis]; + control.y = controlBone[1][pProc->axis]; + control.z = controlBone[2][pProc->axis]; + } + + Quaternion *q1, *q2, *q3; + Vector *p1, *p2, *p3; + + // find axial control inputs + float a1 = control.x; + float a2 = control.y; + float a3 = control.z; + if (a1 >= 0) + { + q1 = &pProc->quat[0]; + p1 = &pProc->pos[0]; + } + else + { + a1 = -a1; + q1 = &pProc->quat[1]; + p1 = &pProc->pos[1]; + } + + if (a2 >= 0) + { + q2 = &pProc->quat[2]; + p2 = &pProc->pos[2]; + } + else + { + a2 = -a2; + q2 = &pProc->quat[3]; + p2 = &pProc->pos[3]; + } + + if (a3 >= 0) + { + q3 = &pProc->quat[4]; + p3 = &pProc->pos[4]; + } + else + { + a3 = -a3; + q3 = &pProc->quat[5]; + p3 = &pProc->pos[5]; + } + + // do a three-way blend + Vector p; + Quaternion v, tmp; + if (a1 + a2 > 0) + { + float t = 1.0 / (a1 + a2 + a3); + // FIXME: do a proper 3-way Quat blend! + QuaternionSlerp( *q2, *q1, a1 / (a1 + a2), tmp ); + QuaternionSlerp( tmp, *q3, a3 * t, v ); + VectorScale( *p1, a1 * t, p ); + VectorMA( p, a2 * t, *p2, p ); + VectorMA( p, a3 * t, *p3, p ); + } + else + { + QuaternionSlerp( *q3, *q3, 0, v ); // ??? no quat copy? + p = *p3; + } + + QuaternionMatrix( v, p, bonematrix ); + + ConcatTransforms (bonetoworld.GetBone( pbones[ibone].parent ), bonematrix, bonetoworld.GetBoneForWrite( ibone )); +} + + + +//----------------------------------------------------------------------------- +// Purpose: Generate a procedural transformation based on how that another bones +// local transformation matches a set of target orientations. +//----------------------------------------------------------------------------- +void DoQuatInterpBone( + mstudiobone_t *pbones, + int ibone, + CBoneAccessor &bonetoworld + ) +{ + matrix3x4_t bonematrix; + Vector control; + + mstudioquatinterpbone_t *pProc = (mstudioquatinterpbone_t *)pbones[ibone].pProcedure( ); + if (pProc && pbones[pProc->control].parent != -1) + { + Quaternion src; + float weight[32]; + float scale = 0.0; + Quaternion quat; + Vector pos; + + matrix3x4_t tmpmatrix; + matrix3x4_t controlmatrix; + MatrixInvert( bonetoworld.GetBone( pbones[pProc->control].parent), tmpmatrix ); + ConcatTransforms( tmpmatrix, bonetoworld.GetBone( pProc->control ), controlmatrix ); + + MatrixAngles( controlmatrix, src, pos ); // FIXME: make a version without pos + + int i; + for (i = 0; i < pProc->numtriggers; i++) + { + float dot = fabs( QuaternionDotProduct( pProc->pTrigger( i )->trigger, src ) ); + // FIXME: a fast acos should be acceptable + dot = clamp( dot, -1.f, 1.f ); + weight[i] = 1 - (2 * acos( dot ) * pProc->pTrigger( i )->inv_tolerance ); + weight[i] = max( 0, weight[i] ); + scale += weight[i]; + } + + if (scale <= 0.001) // EPSILON? + { + AngleMatrix( pProc->pTrigger( 0 )->quat, pProc->pTrigger( 0 )->pos, bonematrix ); + ConcatTransforms ( bonetoworld.GetBone( pbones[ibone].parent ), bonematrix, bonetoworld.GetBoneForWrite( ibone ) ); + return; + } + + scale = 1.0 / scale; + + quat.Init( 0, 0, 0, 0); + pos.Init( ); + + for (i = 0; i < pProc->numtriggers; i++) + { + if (weight[i]) + { + float s = weight[i] * scale; + mstudioquatinterpinfo_t *pTrigger = pProc->pTrigger( i ); + + QuaternionAlign( pTrigger->quat, quat, quat ); + + quat.x = quat.x + s * pTrigger->quat.x; + quat.y = quat.y + s * pTrigger->quat.y; + quat.z = quat.z + s * pTrigger->quat.z; + quat.w = quat.w + s * pTrigger->quat.w; + pos.x = pos.x + s * pTrigger->pos.x; + pos.y = pos.y + s * pTrigger->pos.y; + pos.z = pos.z + s * pTrigger->pos.z; + } + } + Assert( QuaternionNormalize( quat ) != 0); + QuaternionMatrix( quat, pos, bonematrix ); + } + + ConcatTransforms (bonetoworld.GetBone( pbones[ibone].parent ), bonematrix, bonetoworld.GetBoneForWrite( ibone )); +} + +/* + * This is for DoAimAtBone below, was just for testing, not needed in general + * but to turn it back on, uncomment this and the section in DoAimAtBone() below + * + +static ConVar aim_constraint( "aim_constraint", "1", FCVAR_REPLICATED, "Toggle Helper Bones" ); + +*/ + +//----------------------------------------------------------------------------- +// Purpose: Generate a procedural transformation so that one bone points at +// another point on the model +//----------------------------------------------------------------------------- +void DoAimAtBone( + mstudiobone_t *pBones, + int iBone, + CBoneAccessor &bonetoworld, + const CStudioHdr *pStudioHdr + ) +{ + mstudioaimatbone_t *pProc = (mstudioaimatbone_t *)pBones[iBone].pProcedure(); + + if ( !pProc ) + { + return; + } + + /* + * Uncomment this if the ConVar above is uncommented + * + + if ( !aim_constraint.GetBool() ) + { + // If the aim constraint is turned off then just copy the parent transform + // plus the offset value + + matrix3x4_t boneToWorldSpace; + MatrixCopy ( bonetoworld.GetBone( pProc->parent ), boneToWorldSpace ); + Vector boneWorldPosition; + VectorTransform( pProc->basepos, boneToWorldSpace, boneWorldPosition ); + MatrixSetColumn( boneWorldPosition, 3, boneToWorldSpace ); + MatrixCopy( boneToWorldSpace, bonetoworld.GetBoneForWrite( iBone ) ); + + return; + } + + */ + + // The world matrix of the bone to change + matrix3x4_t boneMatrix; + + // Guaranteed to be unit length + const Vector &userAimVector( pProc->aimvector ); + + // Guaranteed to be unit length + const Vector &userUpVector( pProc->upvector ); + + // Get to get position of bone but also for up reference + matrix3x4_t parentSpace; + MatrixCopy ( bonetoworld.GetBone( pProc->parent ), parentSpace ); + + // World space position of the bone to aim + Vector aimWorldPosition; + VectorTransform( pProc->basepos, parentSpace, aimWorldPosition ); + + // The worldspace matrix of the bone to aim at + matrix3x4_t aimAtSpace; + if ( pStudioHdr ) + { + // This means it's AIMATATTACH + const mstudioattachment_t &attachment( ((CStudioHdr *)pStudioHdr)->pAttachment( pProc->aim ) ); + ConcatTransforms( + bonetoworld.GetBone( attachment.localbone ), + attachment.local, + aimAtSpace ); + } + else + { + MatrixCopy( bonetoworld.GetBone( pProc->aim ), aimAtSpace ); + } + + Vector aimAtWorldPosition; + MatrixGetColumn( aimAtSpace, 3, aimAtWorldPosition ); + + // make sure the redundant parent info is correct + Assert( pProc->parent == pBones[iBone].parent ); + // make sure the redundant position info is correct + Assert( pProc->basepos.DistToSqr( pBones[iBone].pos ) < 0.1 ); + + // The aim and up data is relative to this bone, not the parent bone + matrix3x4_t bonematrix, boneLocalToWorld; + AngleMatrix( pBones[iBone].quat, pProc->basepos, bonematrix ); + ConcatTransforms( bonetoworld.GetBone( pProc->parent ), bonematrix, boneLocalToWorld ); + + Vector aimVector; + VectorSubtract( aimAtWorldPosition, aimWorldPosition, aimVector ); + VectorNormalizeFast( aimVector ); + + Vector axis; + CrossProduct( userAimVector, aimVector, axis ); + VectorNormalizeFast( axis ); + Assert( 1.0f - fabs( DotProduct( userAimVector, aimVector ) ) > FLT_EPSILON ); + float angle( acosf( DotProduct( userAimVector, aimVector ) ) ); + Quaternion aimRotation; + AxisAngleQuaternion( axis, RAD2DEG( angle ), aimRotation ); + + if ( ( 1.0f - fabs( DotProduct( userUpVector, userAimVector ) ) ) > FLT_EPSILON ) + { + matrix3x4_t aimRotationMatrix; + QuaternionMatrix( aimRotation, aimRotationMatrix ); + + Vector tmpV; + + Vector tmp_pUp; + VectorRotate( userUpVector, aimRotationMatrix, tmp_pUp ); + VectorScale( aimVector, DotProduct( aimVector, tmp_pUp ), tmpV ); + Vector pUp; + VectorSubtract( tmp_pUp, tmpV, pUp ); + VectorNormalizeFast( pUp ); + + Vector tmp_pParentUp; + VectorRotate( userUpVector, boneLocalToWorld, tmp_pParentUp ); + VectorScale( aimVector, DotProduct( aimVector, tmp_pParentUp ), tmpV ); + Vector pParentUp; + VectorSubtract( tmp_pParentUp, tmpV, pParentUp ); + VectorNormalizeFast( pParentUp ); + + Quaternion upRotation; + //Assert( 1.0f - fabs( DotProduct( pUp, pParentUp ) ) > FLT_EPSILON ); + if( 1.0f - fabs( DotProduct( pUp, pParentUp ) ) > FLT_EPSILON ) + { + angle = acos( DotProduct( pUp, pParentUp ) ); + CrossProduct( pUp, pParentUp, axis ); + } + else + { + angle = 0; + axis = pUp; + } + + VectorNormalizeFast( axis ); + AxisAngleQuaternion( axis, RAD2DEG( angle ), upRotation ); + + Quaternion boneRotation; + QuaternionMult( upRotation, aimRotation, boneRotation ); + QuaternionMatrix( boneRotation, aimWorldPosition, boneMatrix ); + } + else + { + QuaternionMatrix( aimRotation, aimWorldPosition, boneMatrix ); + } + + MatrixCopy( boneMatrix, bonetoworld.GetBoneForWrite( iBone ) ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +bool CalcProceduralBone( + const CStudioHdr *pStudioHdr, + int iBone, + CBoneAccessor &bonetoworld + ) +{ + mstudiobone_t *pbones = pStudioHdr->pBone( 0 ); + + if ( pStudioHdr->boneFlags(iBone) & BONE_ALWAYS_PROCEDURAL ) + { + switch( pbones[iBone].proctype ) + { + case STUDIO_PROC_AXISINTERP: + DoAxisInterpBone( pbones, iBone, bonetoworld ); + return true; + + case STUDIO_PROC_QUATINTERP: + DoQuatInterpBone( pbones, iBone, bonetoworld ); + return true; + + case STUDIO_PROC_AIMATBONE: + DoAimAtBone( pbones, iBone, bonetoworld, NULL ); + return true; + + case STUDIO_PROC_AIMATATTACH: + DoAimAtBone( pbones, iBone, bonetoworld, pStudioHdr ); + return true; + + default: + return false; + } + } + return false; +} + + + +//----------------------------------------------------------------------------- +// Purpose: Lookup a bone controller +//----------------------------------------------------------------------------- + + + +static mstudiobonecontroller_t* FindController( const CStudioHdr *pStudioHdr, int iController) +{ + // find first controller that matches the index + for (int i = 0; i < pStudioHdr->numbonecontrollers(); i++) + { + if (pStudioHdr->pBonecontroller( i )->inputfield == iController) + return pStudioHdr->pBonecontroller( i ); + } + + return NULL; +} + + +//----------------------------------------------------------------------------- +// Purpose: converts a ranged bone controller value into a 0..1 encoded value +// Output: ctlValue contains 0..1 encoding. +// returns clamped ranged value +//----------------------------------------------------------------------------- + +float Studio_SetController( const CStudioHdr *pStudioHdr, int iController, float flValue, float &ctlValue ) +{ + if (! pStudioHdr) + return flValue; + + mstudiobonecontroller_t *pbonecontroller = FindController(pStudioHdr, iController); + if(!pbonecontroller) + { + ctlValue = 0; + 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; + } + } + + ctlValue = (flValue - pbonecontroller->start) / (pbonecontroller->end - pbonecontroller->start); + if (ctlValue < 0) ctlValue = 0; + if (ctlValue > 1) ctlValue = 1; + + float flReturnVal = ((1.0 - ctlValue)*pbonecontroller->start + ctlValue *pbonecontroller->end); + + // ugly hack, invert value if a rotational controller and end < start + if (pbonecontroller->type & (STUDIO_XR | STUDIO_YR | STUDIO_ZR) && + pbonecontroller->end < pbonecontroller->start ) + { + flReturnVal *= -1; + } + + return flReturnVal; +} + + +//----------------------------------------------------------------------------- +// Purpose: converts a 0..1 encoded bone controller value into a ranged value +// Output: returns ranged value +//----------------------------------------------------------------------------- + +float Studio_GetController( const CStudioHdr *pStudioHdr, int iController, float ctlValue ) +{ + if (!pStudioHdr) + return 0.0; + + mstudiobonecontroller_t *pbonecontroller = FindController(pStudioHdr, iController); + if(!pbonecontroller) + return 0; + + return ctlValue * (pbonecontroller->end - pbonecontroller->start) + pbonecontroller->start; +} + + +//----------------------------------------------------------------------------- +// Purpose: Calculates default values for the pose parameters +// Output: fills in an array +//----------------------------------------------------------------------------- + +void Studio_CalcDefaultPoseParameters( const CStudioHdr *pStudioHdr, float flPoseParameter[], int nCount ) +{ + int nPoseCount = pStudioHdr->GetNumPoseParameters(); + int nNumParams = MIN( nCount, MAXSTUDIOPOSEPARAM ); + + for ( int i = 0; i < nNumParams; ++i ) + { + // Default to middle of the pose parameter range + flPoseParameter[ i ] = 0.5f; + if ( i < nPoseCount ) + { + const mstudioposeparamdesc_t &Pose = ((CStudioHdr *)pStudioHdr)->pPoseParameter( i ); + + // Want to try for a zero state. If one doesn't exist set it to .5 by default. + if ( Pose.start < 0.0f && Pose.end > 0.0f ) + { + float flPoseDelta = Pose.end - Pose.start; + flPoseParameter[i] = -Pose.start / flPoseDelta; + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: converts a ranged pose parameter value into a 0..1 encoded value +// Output: ctlValue contains 0..1 encoding. +// returns clamped ranged value +//----------------------------------------------------------------------------- + +float Studio_SetPoseParameter( const CStudioHdr *pStudioHdr, int iParameter, float flValue, float &ctlValue ) +{ + if (iParameter < 0 || iParameter >= pStudioHdr->GetNumPoseParameters()) + { + return 0; + } + + const mstudioposeparamdesc_t &PoseParam = ((CStudioHdr *)pStudioHdr)->pPoseParameter( iParameter ); + + Assert( IsFinite( flValue ) ); + + if (PoseParam.loop) + { + float wrap = (PoseParam.start + PoseParam.end) / 2.0 + PoseParam.loop / 2.0; + float shift = PoseParam.loop - wrap; + + flValue = flValue - PoseParam.loop * floor((flValue + shift) / PoseParam.loop); + } + + ctlValue = (flValue - PoseParam.start) / (PoseParam.end - PoseParam.start); + + if (ctlValue < 0) ctlValue = 0; + if (ctlValue > 1) ctlValue = 1; + + Assert( IsFinite( ctlValue ) ); + + return ctlValue * (PoseParam.end - PoseParam.start) + PoseParam.start; +} + + +//----------------------------------------------------------------------------- +// Purpose: converts a 0..1 encoded pose parameter value into a ranged value +// Output: returns ranged value +//----------------------------------------------------------------------------- + +float Studio_GetPoseParameter( const CStudioHdr *pStudioHdr, int iParameter, float ctlValue ) +{ + if (iParameter < 0 || iParameter >= pStudioHdr->GetNumPoseParameters()) + { + return 0; + } + + const mstudioposeparamdesc_t &PoseParam = ((CStudioHdr *)pStudioHdr)->pPoseParameter( iParameter ); + + return ctlValue * (PoseParam.end - PoseParam.start) + PoseParam.start; +} + + +#pragma warning (disable : 4701) + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +static int ClipRayToHitbox( const Ray_t &ray, mstudiobbox_t *pbox, matrix3x4_t& matrix, trace_t &tr ) +{ + const float flProjEpsilon = 0.01f; + // scale by current t so hits shorten the ray and increase the likelihood of early outs + Vector delta2; + VectorScale( ray.m_Delta, (0.5f * tr.fraction), delta2 ); + + // OPTIMIZE: Store this in the box instead of computing it here + // compute center in local space + Vector boxextents; + boxextents.x = (pbox->bbmin.x + pbox->bbmax.x) * 0.5; + boxextents.y = (pbox->bbmin.y + pbox->bbmax.y) * 0.5; + boxextents.z = (pbox->bbmin.z + pbox->bbmax.z) * 0.5; + Vector boxCenter; + // transform to world space + VectorTransform( boxextents, matrix, boxCenter ); + // calc extents from local center + boxextents.x = pbox->bbmax.x - boxextents.x; + boxextents.y = pbox->bbmax.y - boxextents.y; + boxextents.z = pbox->bbmax.z - boxextents.z; + // OPTIMIZE: This is optimized for world space. If the transform is fast enough, it may make more + // sense to just xform and call UTIL_ClipToBox() instead. MEASURE THIS. + + // save the extents of the ray along + Vector extent, uextent; + Vector segmentCenter; + segmentCenter.x = ray.m_Start.x + delta2.x - boxCenter.x; + segmentCenter.y = ray.m_Start.y + delta2.y - boxCenter.y; + segmentCenter.z = ray.m_Start.z + delta2.z - boxCenter.z; + + extent.Init(); + + // check box axes for separation + for ( int j = 0; j < 3; j++ ) + { + extent[j] = delta2.x * matrix[0][j] + delta2.y * matrix[1][j] + delta2.z * matrix[2][j]; + uextent[j] = fabsf(extent[j]); + float coord = segmentCenter.x * matrix[0][j] + segmentCenter.y * matrix[1][j] + segmentCenter.z * matrix[2][j]; + coord = fabsf(coord); + + if ( coord > (boxextents[j] + uextent[j]) ) + return -1; + } + + // now check cross axes for separation + float tmp, tmpfix, cextent; + Vector cross; + CrossProduct( delta2, segmentCenter, cross ); + cextent = cross.x * matrix[0][0] + cross.y * matrix[1][0] + cross.z * matrix[2][0]; + cextent = fabsf(cextent); + tmp = boxextents[1]*uextent[2] + boxextents[2]*uextent[1]; + tmpfix = MAX(tmp, flProjEpsilon); + if ( cextent > tmpfix ) + return -1; + +// if ( cextent > tmp && cextent <= tmpfix ) +// DevWarning( "ClipRayToHitbox trace precision error case\n" ); + + cextent = cross.x * matrix[0][1] + cross.y * matrix[1][1] + cross.z * matrix[2][1]; + cextent = fabsf(cextent); + tmp = boxextents[0]*uextent[2] + boxextents[2]*uextent[0]; + tmpfix = MAX(tmp, flProjEpsilon); + if ( cextent > tmpfix ) + return -1; + +// if ( cextent > tmp && cextent <= tmpfix ) +// DevWarning( "ClipRayToHitbox trace precision error case\n" ); + + cextent = cross.x * matrix[0][2] + cross.y * matrix[1][2] + cross.z * matrix[2][2]; + cextent = fabsf(cextent); + tmp = boxextents[0]*uextent[1] + boxextents[1]*uextent[0]; + tmpfix = MAX(tmp, flProjEpsilon); + if ( cextent > tmpfix ) + return -1; + +// if ( cextent > tmp && cextent <= tmpfix ) +// DevWarning( "ClipRayToHitbox trace precision error case\n" ); + + // !!! We hit this box !!! compute intersection point and return + Vector start; + + // Compute ray start in bone space + VectorITransform( ray.m_Start, matrix, start ); + // extent is delta2 in bone space, recompute delta in bone space + VectorScale( extent, 2, extent ); + + // delta was prescaled by the current t, so no need to see if this intersection + // is closer + trace_t boxTrace; + if ( !IntersectRayWithBox( start, extent, pbox->bbmin, pbox->bbmax, 0.0f, &boxTrace ) ) + return -1; + + Assert( IsFinite(boxTrace.fraction) ); + tr.fraction *= boxTrace.fraction; + tr.startsolid = boxTrace.startsolid; + int hitside = boxTrace.plane.type; + if ( boxTrace.plane.normal[hitside] >= 0 ) + { + hitside += 3; + } + return hitside; +} + +#pragma warning (default : 4701) + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool SweepBoxToStudio( IPhysicsSurfaceProps *pProps, const Ray_t& ray, CStudioHdr *pStudioHdr, mstudiohitboxset_t *set, + matrix3x4_t **hitboxbones, int fContentsMask, trace_t &tr ) +{ + tr.fraction = 1.0; + tr.startsolid = false; + + // OPTIMIZE: Partition these? + Ray_t clippedRay = ray; + int hitbox = -1; + for ( int i = 0; i < set->numhitboxes; i++ ) + { + mstudiobbox_t *pbox = set->pHitbox(i); + + // Filter based on contents mask + int fBoneContents = pStudioHdr->pBone( pbox->bone )->contents; + if ( ( fBoneContents & fContentsMask ) == 0 ) + continue; + + //FIXME: Won't work with scaling! + trace_t obbTrace; + if ( IntersectRayWithOBB( clippedRay, *hitboxbones[pbox->bone], pbox->bbmin, pbox->bbmax, 0.0f, &obbTrace ) ) + { + tr.startpos = obbTrace.startpos; + tr.endpos = obbTrace.endpos; + tr.plane = obbTrace.plane; + tr.startsolid = obbTrace.startsolid; + tr.allsolid = obbTrace.allsolid; + + // This logic here is to shorten the ray each time to get more early outs + tr.fraction *= obbTrace.fraction; + clippedRay.m_Delta *= obbTrace.fraction; + hitbox = i; + if (tr.startsolid) + break; + } + } + + if ( hitbox >= 0 ) + { + tr.hitgroup = set->pHitbox(hitbox)->group; + tr.hitbox = hitbox; + const mstudiobone_t *pBone = pStudioHdr->pBone( set->pHitbox(hitbox)->bone ); + tr.contents = pBone->contents | CONTENTS_HITBOX; + tr.physicsbone = pBone->physicsbone; + tr.surface.name = "**studio**"; + tr.surface.flags = SURF_HITBOX; + tr.surface.surfaceProps = pProps->GetSurfaceIndex( pBone->pszSurfaceProp() ); + + Assert( tr.physicsbone >= 0 ); + return true; + } + return false; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool TraceToStudio( IPhysicsSurfaceProps *pProps, const Ray_t& ray, CStudioHdr *pStudioHdr, mstudiohitboxset_t *set, + matrix3x4_t **hitboxbones, int fContentsMask, const Vector &vecOrigin, float flScale, trace_t &tr ) +{ + if ( !ray.m_IsRay ) + { + return SweepBoxToStudio( pProps, ray, pStudioHdr, set, hitboxbones, fContentsMask, tr ); + } + + tr.fraction = 1.0; + tr.startsolid = false; + + // no hit yet + int hitbox = -1; + int hitside = -1; + + // OPTIMIZE: Partition these? + for ( int i = 0; i < set->numhitboxes; i++ ) + { + mstudiobbox_t *pbox = set->pHitbox(i); + + // Filter based on contents mask + int fBoneContents = pStudioHdr->pBone( pbox->bone )->contents; + if ( ( fBoneContents & fContentsMask ) == 0 ) + continue; + + // columns are axes of the bones in world space, translation is in world space + matrix3x4_t& matrix = *hitboxbones[pbox->bone]; + + // Because we're sending in a matrix with scale data, and because the matrix inversion in the hitbox + // code does not handle that case, we pre-scale the bones and ray down here and do our collision checks + // in unscaled space. We can then rescale the results afterwards. + + int side = -1; + if ( flScale < 1.0f-FLT_EPSILON || flScale > 1.0f+FLT_EPSILON ) + { + matrix3x4_t matScaled; + MatrixCopy( matrix, matScaled ); + + float invScale = 1.0f / flScale; + + Vector vecBoneOrigin; + MatrixGetColumn( matScaled, 3, vecBoneOrigin ); + + // Pre-scale the origin down + Vector vecNewOrigin = vecBoneOrigin - vecOrigin; + vecNewOrigin *= invScale; + vecNewOrigin += vecOrigin; + MatrixSetColumn( vecNewOrigin, 3, matScaled ); + + // Scale it uniformly + VectorScale( matScaled[0], invScale, matScaled[0] ); + VectorScale( matScaled[1], invScale, matScaled[1] ); + VectorScale( matScaled[2], invScale, matScaled[2] ); + + // Pre-scale our ray as well + Vector vecRayStart = ray.m_Start - vecOrigin; + vecRayStart *= invScale; + vecRayStart += vecOrigin; + + Vector vecRayDelta = ray.m_Delta * invScale; + + Ray_t newRay; + newRay.Init( vecRayStart, vecRayStart + vecRayDelta ); + + side = ClipRayToHitbox( newRay, pbox, matScaled, tr ); + } + else + { + side = ClipRayToHitbox( ray, pbox, matrix, tr ); + } + + if ( side >= 0 ) + { + hitbox = i; + hitside = side; + } + } + + if ( hitbox >= 0 ) + { + mstudiobbox_t *pbox = set->pHitbox(hitbox); + VectorMA( ray.m_Start, tr.fraction, ray.m_Delta, tr.endpos ); + tr.hitgroup = set->pHitbox(hitbox)->group; + tr.hitbox = hitbox; + const mstudiobone_t *pBone = pStudioHdr->pBone( pbox->bone ); + tr.contents = pBone->contents | CONTENTS_HITBOX; + tr.physicsbone = pBone->physicsbone; + tr.surface.name = "**studio**"; + tr.surface.flags = SURF_HITBOX; + tr.surface.surfaceProps = pProps->GetSurfaceIndex( pBone->pszSurfaceProp() ); + + Assert( tr.physicsbone >= 0 ); + matrix3x4_t& matrix = *hitboxbones[pbox->bone]; + if ( hitside >= 3 ) + { + hitside -= 3; + tr.plane.normal[0] = matrix[0][hitside]; + tr.plane.normal[1] = matrix[1][hitside]; + tr.plane.normal[2] = matrix[2][hitside]; + //tr.plane.dist = DotProduct( tr.plane.normal, Vector(matrix[0][3], matrix[1][3], matrix[2][3] ) ) + pbox->bbmax[hitside]; + } + else + { + tr.plane.normal[0] = -matrix[0][hitside]; + tr.plane.normal[1] = -matrix[1][hitside]; + tr.plane.normal[2] = -matrix[2][hitside]; + //tr.plane.dist = DotProduct( tr.plane.normal, Vector(matrix[0][3], matrix[1][3], matrix[2][3] ) ) - pbox->bbmin[hitside]; + } + // simpler plane constant equation + tr.plane.dist = DotProduct( tr.endpos, tr.plane.normal ); + tr.plane.type = 3; + return true; + } + return false; +} + + +//----------------------------------------------------------------------------- +// Purpose: returns array of animations and weightings for a sequence based on current pose parameters +//----------------------------------------------------------------------------- + +void Studio_SeqAnims( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int iSequence, const float poseParameter[], mstudioanimdesc_t *panim[4], float *weight ) +{ +#if _DEBUG + VPROF_INCREMENT_COUNTER("SEQ_ANIMS",1); +#endif + if (!pStudioHdr || iSequence >= pStudioHdr->GetNumSeq()) + { + weight[0] = weight[1] = weight[2] = weight[3] = 0.0; + return; + } + + int i0 = 0, i1 = 0; + float s0 = 0, s1 = 0; + + Studio_LocalPoseParameter( pStudioHdr, poseParameter, seqdesc, iSequence, 0, s0, i0 ); + Studio_LocalPoseParameter( pStudioHdr, poseParameter, seqdesc, iSequence, 1, s1, i1 ); + + panim[0] = &((CStudioHdr *)pStudioHdr)->pAnimdesc( pStudioHdr->iRelativeAnim( iSequence, seqdesc.anim( i0 , i1 ) ) ); + weight[0] = (1 - s0) * (1 - s1); + + panim[1] = &((CStudioHdr *)pStudioHdr)->pAnimdesc( pStudioHdr->iRelativeAnim( iSequence, seqdesc.anim( i0+1, i1 ) ) ); + weight[1] = (s0) * (1 - s1); + + panim[2] = &((CStudioHdr *)pStudioHdr)->pAnimdesc( pStudioHdr->iRelativeAnim( iSequence, seqdesc.anim( i0 , i1+1 ) ) ); + weight[2] = (1 - s0) * (s1); + + panim[3] = &((CStudioHdr *)pStudioHdr)->pAnimdesc( pStudioHdr->iRelativeAnim( iSequence, seqdesc.anim( i0+1, i1+1 ) ) ); + weight[3] = (s0) * (s1); + + Assert( weight[0] >= 0.0f && weight[1] >= 0.0f && weight[2] >= 0.0f && weight[3] >= 0.0f ); +} + +//----------------------------------------------------------------------------- +// Purpose: returns max frame number for a sequence +//----------------------------------------------------------------------------- + +int Studio_MaxFrame( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] ) +{ + mstudioanimdesc_t *panim[4]; + float weight[4]; + + mstudioseqdesc_t &seqdesc = ((CStudioHdr *)pStudioHdr)->pSeqdesc( iSequence ); + Studio_SeqAnims( pStudioHdr, seqdesc, iSequence, poseParameter, panim, weight ); + + float maxFrame = 0; + for (int i = 0; i < 4; i++) + { + if (weight[i] > 0) + { + maxFrame += panim[i]->numframes * weight[i]; + } + } + + if ( maxFrame > 1 ) + maxFrame -= 1; + + + // FIXME: why does the weights sometimes not exactly add it 1.0 and this sometimes rounds down? + return (maxFrame + 0.01); +} + + +//----------------------------------------------------------------------------- +// Purpose: returns frames per second of a sequence +//----------------------------------------------------------------------------- + +float Studio_FPS( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] ) +{ + mstudioanimdesc_t *panim[4]; + float weight[4]; + + mstudioseqdesc_t &seqdesc = ((CStudioHdr *)pStudioHdr)->pSeqdesc( iSequence ); + Studio_SeqAnims( pStudioHdr, seqdesc, iSequence, poseParameter, panim, weight ); + + float t = 0; + + for (int i = 0; i < 4; i++) + { + if (weight[i] > 0) + { + t += panim[i]->fps * weight[i]; + } + } + return t; +} + + +//----------------------------------------------------------------------------- +// Purpose: returns cycles per second of a sequence (cycles/second) +//----------------------------------------------------------------------------- + +float Studio_CPS( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int iSequence, const float poseParameter[] ) +{ + mstudioanimdesc_t *panim[4]; + float weight[4]; + + Studio_SeqAnims( pStudioHdr, seqdesc, iSequence, poseParameter, panim, weight ); + + float t = 0; + + for (int i = 0; i < 4; i++) + { + if (weight[i] > 0 && panim[i]->numframes > 1) + { + t += (panim[i]->fps / (panim[i]->numframes - 1)) * weight[i]; + } + } + return t; +} + +//----------------------------------------------------------------------------- +// Purpose: returns length (in seconds) of a sequence (seconds/cycle) +//----------------------------------------------------------------------------- + +float Studio_Duration( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] ) +{ + mstudioseqdesc_t &seqdesc = ((CStudioHdr *)pStudioHdr)->pSeqdesc( iSequence ); + float cps = Studio_CPS( pStudioHdr, seqdesc, iSequence, poseParameter ); + + if( cps == 0 ) + return 0.0f; + + return 1.0f/cps; +} + + +//----------------------------------------------------------------------------- +// Purpose: calculate changes in position and angle relative to the start of an animations cycle +// Output: updated position and angle, relative to the origin +// returns false if animation is not a movement animation +//----------------------------------------------------------------------------- + +bool Studio_AnimPosition( mstudioanimdesc_t *panim, float flCycle, Vector &vecPos, QAngle &vecAngle ) +{ + float prevframe = 0; + vecPos.Init( ); + vecAngle.Init( ); + + if (panim->nummovements == 0) + return false; + + int iLoops = 0; + if (flCycle > 1.0) + { + iLoops = (int)flCycle; + } + else if (flCycle < 0.0) + { + iLoops = (int)flCycle - 1; + } + flCycle = flCycle - iLoops; + + float flFrame = flCycle * (panim->numframes - 1); + + for (int i = 0; i < panim->nummovements; i++) + { + mstudiomovement_t *pmove = panim->pMovement( i ); + + if (pmove->endframe >= flFrame) + { + float f = (flFrame - prevframe) / (pmove->endframe - prevframe); + + float d = pmove->v0 * f + 0.5 * (pmove->v1 - pmove->v0) * f * f; + + vecPos = vecPos + d * pmove->vector; + vecAngle.y = vecAngle.y * (1 - f) + pmove->angle * f; + if (iLoops != 0) + { + mstudiomovement_t *pmove = panim->pMovement( panim->nummovements - 1 ); + vecPos = vecPos + iLoops * pmove->position; + vecAngle.y = vecAngle.y + iLoops * pmove->angle; + } + return true; + } + else + { + prevframe = pmove->endframe; + vecPos = pmove->position; + vecAngle.y = pmove->angle; + } + } + + return false; +} + + +//----------------------------------------------------------------------------- +// Purpose: calculate instantaneous velocity in ips at a given point +// in the animations cycle +// Output: velocity vector, relative to identity orientation +// returns false if animation is not a movement animation +//----------------------------------------------------------------------------- + +bool Studio_AnimVelocity( mstudioanimdesc_t *panim, float flCycle, Vector &vecVelocity ) +{ + float prevframe = 0; + + float flFrame = flCycle * (panim->numframes - 1); + flFrame = flFrame - (int)(flFrame / (panim->numframes - 1)); + + for (int i = 0; i < panim->nummovements; i++) + { + mstudiomovement_t *pmove = panim->pMovement( i ); + + if (pmove->endframe >= flFrame) + { + float f = (flFrame - prevframe) / (pmove->endframe - prevframe); + + float vel = pmove->v0 * (1 - f) + pmove->v1 * f; + // scale from per block to per sec velocity + vel = vel * panim->fps / (pmove->endframe - prevframe); + + vecVelocity = pmove->vector * vel; + return true; + } + else + { + prevframe = pmove->endframe; + } + } + return false; +} + + +//----------------------------------------------------------------------------- +// Purpose: calculate changes in position and angle between two points in an animation cycle +// Output: updated position and angle, relative to CycleFrom being at the origin +// returns false if animation is not a movement animation +//----------------------------------------------------------------------------- + +bool Studio_AnimMovement( mstudioanimdesc_t *panim, float flCycleFrom, float flCycleTo, Vector &deltaPos, QAngle &deltaAngle ) +{ + if (panim->nummovements == 0) + return false; + + Vector startPos; + QAngle startA; + Studio_AnimPosition( panim, flCycleFrom, startPos, startA ); + + Vector endPos; + QAngle endA; + Studio_AnimPosition( panim, flCycleTo, endPos, endA ); + + Vector tmp = endPos - startPos; + deltaAngle.y = endA.y - startA.y; + VectorYawRotate( tmp, -startA.y, deltaPos ); + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: finds how much of an animation to play to move given linear distance +//----------------------------------------------------------------------------- + +float Studio_FindAnimDistance( mstudioanimdesc_t *panim, float flDist ) +{ + float prevframe = 0; + + if (flDist <= 0) + return 0.0; + + for (int i = 0; i < panim->nummovements; i++) + { + mstudiomovement_t *pmove = panim->pMovement( i ); + + float flMove = (pmove->v0 + pmove->v1) * 0.5; + + if (flMove >= flDist) + { + float root1, root2; + + // d = V0 * t + 1/2 (V1-V0) * t^2 + if (SolveQuadratic( 0.5 * (pmove->v1 - pmove->v0), pmove->v0, -flDist, root1, root2 )) + { + float cpf = 1.0 / (panim->numframes - 1); // cycles per frame + + return (prevframe + root1 * (pmove->endframe - prevframe)) * cpf; + } + return 0.0; + } + else + { + flDist -= flMove; + prevframe = pmove->endframe; + } + } + return 1.0; +} + + +//----------------------------------------------------------------------------- +// Purpose: calculate changes in position and angle between two points in a sequences cycle +// Output: updated position and angle, relative to CycleFrom being at the origin +// returns false if sequence is not a movement sequence +//----------------------------------------------------------------------------- + +bool Studio_SeqMovement( const CStudioHdr *pStudioHdr, int iSequence, float flCycleFrom, float flCycleTo, const float poseParameter[], Vector &deltaPos, QAngle &deltaAngles ) +{ + mstudioanimdesc_t *panim[4]; + float weight[4]; + + mstudioseqdesc_t &seqdesc = ((CStudioHdr *)pStudioHdr)->pSeqdesc( iSequence ); + + Studio_SeqAnims( pStudioHdr, seqdesc, iSequence, poseParameter, panim, weight ); + + deltaPos.Init( ); + deltaAngles.Init( ); + + bool found = false; + + for (int i = 0; i < 4; i++) + { + if (weight[i]) + { + Vector localPos; + QAngle localAngles; + + localPos.Init(); + localAngles.Init(); + + if (Studio_AnimMovement( panim[i], flCycleFrom, flCycleTo, localPos, localAngles )) + { + found = true; + deltaPos = deltaPos + localPos * weight[i]; + // FIXME: this makes no sense + deltaAngles = deltaAngles + localAngles * weight[i]; + } + else if (!(panim[i]->flags & STUDIO_DELTA) && panim[i]->nummovements == 0 && seqdesc.weight(0) > 0.0) + { + found = true; + } + } + } + return found; +} + + +//----------------------------------------------------------------------------- +// Purpose: calculate instantaneous velocity in ips at a given point in the sequence's cycle +// Output: velocity vector, relative to identity orientation +// returns false if sequence is not a movement sequence +//----------------------------------------------------------------------------- + +bool Studio_SeqVelocity( const CStudioHdr *pStudioHdr, int iSequence, float flCycle, const float poseParameter[], Vector &vecVelocity ) +{ + mstudioanimdesc_t *panim[4]; + float weight[4]; + + mstudioseqdesc_t &seqdesc = ((CStudioHdr *)pStudioHdr)->pSeqdesc( iSequence ); + Studio_SeqAnims( pStudioHdr, seqdesc, iSequence, poseParameter, panim, weight ); + + vecVelocity.Init( ); + + bool found = false; + + for (int i = 0; i < 4; i++) + { + if (weight[i]) + { + Vector vecLocalVelocity; + + if (Studio_AnimVelocity( panim[i], flCycle, vecLocalVelocity )) + { + vecVelocity = vecVelocity + vecLocalVelocity * weight[i]; + found = true; + } + } + } + return found; +} + +//----------------------------------------------------------------------------- +// Purpose: finds how much of an sequence to play to move given linear distance +//----------------------------------------------------------------------------- + +float Studio_FindSeqDistance( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], float flDist ) +{ + mstudioanimdesc_t *panim[4]; + float weight[4]; + + mstudioseqdesc_t &seqdesc = ((CStudioHdr *)pStudioHdr)->pSeqdesc( iSequence ); + Studio_SeqAnims( pStudioHdr, seqdesc, iSequence, poseParameter, panim, weight ); + + float flCycle = 0; + + for (int i = 0; i < 4; i++) + { + if (weight[i]) + { + float flLocalCycle = Studio_FindAnimDistance( panim[i], flDist ); + flCycle = flCycle + flLocalCycle * weight[i]; + } + } + return flCycle; +} + +//----------------------------------------------------------------------------- +// Purpose: lookup attachment by name +//----------------------------------------------------------------------------- + +int Studio_FindAttachment( const CStudioHdr *pStudioHdr, const char *pAttachmentName ) +{ + if ( pStudioHdr && pStudioHdr->SequencesAvailable() ) + { + // Extract the bone index from the name + for (int i = 0; i < pStudioHdr->GetNumAttachments(); i++) + { + if (!V_stricmp(pAttachmentName,((CStudioHdr *)pStudioHdr)->pAttachment(i).pszName( ))) + { + return i; + } + } + } + + return -1; +} + +//----------------------------------------------------------------------------- +// Purpose: lookup attachments by substring. Randomly return one of the matching attachments. +//----------------------------------------------------------------------------- + +int Studio_FindRandomAttachment( const CStudioHdr *pStudioHdr, const char *pAttachmentName ) +{ + if ( pStudioHdr ) + { + // First move them all matching attachments into a list + CUtlVector matchingAttachments; + + // Extract the bone index from the name + for (int i = 0; i < pStudioHdr->GetNumAttachments(); i++) + { + if ( strstr( ((CStudioHdr *)pStudioHdr)->pAttachment(i).pszName(), pAttachmentName ) ) + { + matchingAttachments.AddToTail(i); + } + } + + // Then randomly return one of the attachments + if ( matchingAttachments.Size() > 0 ) + return matchingAttachments[ RandomInt( 0, matchingAttachments.Size()-1 ) ]; + } + + return -1; +} + +//----------------------------------------------------------------------------- +// Purpose: lookup bone by name +//----------------------------------------------------------------------------- + +int Studio_BoneIndexByName( const CStudioHdr *pStudioHdr, const char *pName ) +{ + // binary search for the bone matching pName + int start = 0, end = pStudioHdr->numbones()-1; + const byte *pBoneTable = pStudioHdr->GetBoneTableSortedByName(); + mstudiobone_t *pbones = pStudioHdr->pBone( 0 ); + while (start <= end) + { + int mid = (start + end) >> 1; + int cmp = Q_stricmp( pbones[pBoneTable[mid]].pszName(), pName ); + + if ( cmp < 0 ) + { + start = mid + 1; + } + else if ( cmp > 0 ) + { + end = mid - 1; + } + else + { + return pBoneTable[mid]; + } + } + return -1; +} + +const char *Studio_GetDefaultSurfaceProps( CStudioHdr *pstudiohdr ) +{ + return pstudiohdr->pszSurfaceProp(); +} + +float Studio_GetMass( CStudioHdr *pstudiohdr ) +{ + return pstudiohdr->mass(); +} + +//----------------------------------------------------------------------------- +// Purpose: return pointer to sequence key value buffer +//----------------------------------------------------------------------------- + +const char *Studio_GetKeyValueText( const CStudioHdr *pStudioHdr, int iSequence ) +{ + if (pStudioHdr && pStudioHdr->SequencesAvailable()) + { + if (iSequence >= 0 && iSequence < pStudioHdr->GetNumSeq()) + { + return ((CStudioHdr *)pStudioHdr)->pSeqdesc( iSequence ).KeyValueText(); + } + } + return NULL; +} + +bool Studio_PrefetchSequence( const CStudioHdr *pStudioHdr, int iSequence ) +{ + bool pendingload = false; + mstudioseqdesc_t &seqdesc = ((CStudioHdr *)pStudioHdr)->pSeqdesc( iSequence ); + int size0 = seqdesc.groupsize[ 0 ]; + int size1 = seqdesc.groupsize[ 1 ]; + for ( int i = 0; i < size0; ++i ) + { + for ( int j = 0; j < size1; ++j ) + { + mstudioanimdesc_t &animdesc = ((CStudioHdr *)pStudioHdr)->pAnimdesc( seqdesc.anim( i, j ) ); + int iFrame = 0; + mstudioanim_t *panim = animdesc.pAnim( &iFrame ); + if ( !panim ) + { + pendingload = true; + } + } + } + + // Everything for this sequence is resident? + return !pendingload; +} + + +//----------------------------------------------------------------------------- +// Purpose: Drive a flex controller from a component of a bone +//----------------------------------------------------------------------------- +void Studio_RunBoneFlexDrivers( float *pflFlexControllerWeights, const CStudioHdr *pStudioHdr, const Vector *pvPositions, const matrix3x4_t *pBoneToWorld, const matrix3x4_t &mRootToWorld ) +{ + bool bRootToWorldInvComputed = false; + matrix3x4_t mRootToWorldInv; + matrix3x4_t mParentInv; + matrix3x4_t mBoneLocal; + + const int nBoneFlexDriverCount = pStudioHdr->BoneFlexDriverCount(); + + for ( int i = 0; i < nBoneFlexDriverCount; ++i ) + { + const mstudioboneflexdriver_t *pBoneFlexDriver = pStudioHdr->BoneFlexDriver( i ); + const mstudiobone_t *pStudioBone = pStudioHdr->pBone( pBoneFlexDriver->m_nBoneIndex ); + + const int nControllerCount = pBoneFlexDriver->m_nControlCount; + + if ( pStudioBone->flags & BONE_USED_BY_BONE_MERGE ) + { + // The local space version of the bone is not available if this is a bonemerged bone + // so do the slow computation of the local version of the bone from boneToWorld + + if ( pStudioBone->parent < 0 ) + { + if ( !bRootToWorldInvComputed ) + { + MatrixInvert( mRootToWorld, mRootToWorldInv ); + bRootToWorldInvComputed = true; + } + + MatrixMultiply( mRootToWorldInv, pBoneToWorld[ pBoneFlexDriver->m_nBoneIndex ], mBoneLocal ); + } + else + { + MatrixInvert( pBoneToWorld[ pStudioBone->parent ], mParentInv ); + MatrixMultiply( mParentInv, pBoneToWorld[ pBoneFlexDriver->m_nBoneIndex ], mBoneLocal ); + } + + for ( int j = 0; j < nControllerCount; ++j ) + { + const mstudioboneflexdrivercontrol_t *pController = pBoneFlexDriver->pBoneFlexDriverControl( j ); + const mstudioflexcontroller_t *pFlexController = pStudioHdr->pFlexcontroller( static_cast< LocalFlexController_t >( pController->m_nFlexControllerIndex ) ); + + if ( pFlexController->localToGlobal < 0 ) + continue; + + Assert( pController->m_nFlexControllerIndex >= 0 && pController->m_nFlexControllerIndex < pStudioHdr->numflexcontrollers() ); + Assert( pController->m_nBoneComponent >= 0 && pController->m_nBoneComponent <= 2 ); + pflFlexControllerWeights[pFlexController->localToGlobal] = + RemapValClamped( mBoneLocal[pController->m_nBoneComponent][3], pController->m_flMin, pController->m_flMax, 0.0f, 1.0f ); + } + } + else + { + // Use the local space version of the bone directly for non-bonemerged bones + + const Vector &position = pvPositions[ pBoneFlexDriver->m_nBoneIndex ]; + + for ( int j = 0; j < nControllerCount; ++j ) + { + const mstudioboneflexdrivercontrol_t *pController = pBoneFlexDriver->pBoneFlexDriverControl( j ); + const mstudioflexcontroller_t *pFlexController = pStudioHdr->pFlexcontroller( static_cast< LocalFlexController_t >( pController->m_nFlexControllerIndex ) ); + + if ( pFlexController->localToGlobal < 0 ) + continue; + + Assert( pController->m_nFlexControllerIndex >= 0 && pController->m_nFlexControllerIndex < pStudioHdr->numflexcontrollers() ); + Assert( pController->m_nBoneComponent >= 0 && pController->m_nBoneComponent <= 2 ); + pflFlexControllerWeights[pFlexController->localToGlobal] = + RemapValClamped( position[pController->m_nBoneComponent], pController->m_flMin, pController->m_flMax, 0.0f, 1.0f ); + } + } + } +} diff --git a/sp/src/public/bone_setup.h b/sp/src/public/bone_setup.h new file mode 100644 index 00000000..76f00a66 --- /dev/null +++ b/sp/src/public/bone_setup.h @@ -0,0 +1,449 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef BONE_SETUP_H +#define BONE_SETUP_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "studio.h" +#include "cmodel.h" +#include "bitvec.h" + + +class CBoneToWorld; +class CIKContext; +class CBoneAccessor; +class IPoseDebugger; + + +// This provides access to networked arrays, so if this code actually changes a value, +// the entity is marked as changed. +abstract_class IParameterAccess +{ +public: + virtual float GetParameter( int iParam ) = 0; + virtual void SetParameter( int iParam, float flValue ) = 0; +}; + + + +class CBoneBitList : public CBitVec +{ +public: + inline void MarkBone(int iBone) + { + Set(iBone); + } + inline bool IsBoneMarked(int iBone) + { + return Get(iBone) != 0 ? true : false; + } +}; + +class CBoneSetup; +class IBoneSetup +{ +public: + IBoneSetup( const CStudioHdr *pStudioHdr, int boneMask, const float poseParameter[], IPoseDebugger *pPoseDebugger = NULL ); + ~IBoneSetup( void ); + void InitPose( Vector pos[], Quaternion[] ); + void AccumulatePose( Vector pos[], Quaternion q[], int sequence, float cycle, float flWeight, float flTime, CIKContext *pIKContext ); + void CalcAutoplaySequences( Vector pos[], Quaternion q[], float flRealTime, CIKContext *pIKContext ); + void CalcBoneAdj( Vector pos[], Quaternion q[], const float controllers[] ); + CStudioHdr *GetStudioHdr(); +private: + CBoneSetup *m_pBoneSetup; +}; + +//----------------------------------------------------------------------------- +// Purpose: blends together all the bones from two p:q lists +// +// p1 = p1 * (1 - s) + p2 * s +// q1 = q1 * (1 - s) + q2 * s +//----------------------------------------------------------------------------- +void SlerpBones( + const CStudioHdr *pStudioHdr, + Quaternion q1[MAXSTUDIOBONES], + Vector pos1[MAXSTUDIOBONES], + mstudioseqdesc_t &seqdesc, // source of q2 and pos2 + int sequence, + const Quaternion q2[MAXSTUDIOBONES], + const Vector pos2[MAXSTUDIOBONES], + float s, + int boneMask + ); + +// Given two samples of a bone separated in time by dt, +// compute the velocity and angular velocity of that bone +void CalcBoneDerivatives( Vector &velocity, AngularImpulse &angVel, const matrix3x4_t &prev, const matrix3x4_t ¤t, float dt ); +// Give a derivative of a bone, compute the velocity & angular velocity of that bone +void CalcBoneVelocityFromDerivative( const QAngle &vecAngles, Vector &velocity, AngularImpulse &angVel, const matrix3x4_t ¤t ); + +// This function sets up the local transform for a single frame of animation. It doesn't handle +// pose parameters or interpolation between frames. +void SetupSingleBoneMatrix( + CStudioHdr *pOwnerHdr, + int nSequence, + int iFrame, + int iBone, + matrix3x4_t &mBoneLocal ); + + +// Purpose: build boneToWorld transforms for a specific bone +void BuildBoneChain( + const CStudioHdr *pStudioHdr, + const matrix3x4_t &rootxform, + const Vector pos[], + const Quaternion q[], + int iBone, + matrix3x4_t *pBoneToWorld ); + +void BuildBoneChain( + const CStudioHdr *pStudioHdr, + const matrix3x4_t &rootxform, + const Vector pos[], + const Quaternion q[], + int iBone, + matrix3x4_t *pBoneToWorld, + CBoneBitList &boneComputed ); + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +// ik info +class CIKTarget +{ +public: + void SetOwner( int entindex, const Vector &pos, const QAngle &angles ); + void ClearOwner( void ); + int GetOwner( void ); + void UpdateOwner( int entindex, const Vector &pos, const QAngle &angles ); + void SetPos( const Vector &pos ); + void SetAngles( const QAngle &angles ); + void SetQuaternion( const Quaternion &q ); + void SetNormal( const Vector &normal ); + void SetPosWithNormalOffset( const Vector &pos, const Vector &normal ); + void SetOnWorld( bool bOnWorld = true ); + + bool IsActive( void ); + void IKFailed( void ); + int chain; + int type; + void MoveReferenceFrame( Vector &deltaPos, QAngle &deltaAngles ); + // accumulated offset from ideal footplant location +public: + struct x2 { + char *pAttachmentName; + Vector pos; + Quaternion q; + } offset; +private: + struct x3 { + Vector pos; + Quaternion q; + } ideal; +public: + struct x4 { + float latched; + float release; + float height; + float floor; + float radius; + float flTime; + float flWeight; + Vector pos; + Quaternion q; + bool onWorld; + } est; // estimate contact position + struct x5 { + float hipToFoot; // distance from hip + float hipToKnee; // distance from hip to knee + float kneeToFoot; // distance from knee to foot + Vector hip; // location of hip + Vector closest; // closest valid location from hip to foot that the foot can move to + Vector knee; // pre-ik location of knee + Vector farthest; // farthest valid location from hip to foot that the foot can move to + Vector lowest; // lowest position directly below hip that the foot can drop to + } trace; +private: + // internally latched footset, position + struct x1 { + // matrix3x4_t worldTarget; + bool bNeedsLatch; + bool bHasLatch; + float influence; + int iFramecounter; + int owner; + Vector absOrigin; + QAngle absAngles; + Vector pos; + Quaternion q; + Vector deltaPos; // acculated error + Quaternion deltaQ; + Vector debouncePos; + Quaternion debounceQ; + } latched; + struct x6 { + float flTime; // time last error was detected + float flErrorTime; + float ramp; + bool bInError; + } error; + + friend class CIKContext; +}; + + +struct ikchainresult_t +{ + // accumulated offset from ideal footplant location + int target; + Vector pos; + Quaternion q; + float flWeight; +}; + + + +struct ikcontextikrule_t +{ + int index; + + int type; + int chain; + + int bone; + + int slot; // iktarget slot. Usually same as chain. + float height; + float radius; + float floor; + Vector pos; + Quaternion q; + + float start; // beginning of influence + float peak; // start of full influence + float tail; // end of full influence + float end; // end of all influence + + float top; + float drop; + + float commit; // frame footstep target should be committed + float release; // frame ankle should end rotation from latched orientation + + float flWeight; // processed version of start-end cycle + float flRuleWeight; // blending weight + float latched; // does the IK rule use a latched value? + char *szLabel; + + Vector kneeDir; + Vector kneePos; + + ikcontextikrule_t() {} + +private: + // No copy constructors allowed + ikcontextikrule_t(const ikcontextikrule_t& vOther); +}; + + +void Studio_AlignIKMatrix( matrix3x4_t &mMat, const Vector &vAlignTo ); + +bool Studio_SolveIK( int iThigh, int iKnee, int iFoot, Vector &targetFoot, matrix3x4_t* pBoneToWorld ); + +bool Studio_SolveIK( int iThigh, int iKnee, int iFoot, Vector &targetFoot, Vector &targetKneePos, Vector &targetKneeDir, matrix3x4_t* pBoneToWorld ); + + + +class CIKContext +{ +public: + CIKContext( ); + void Init( const CStudioHdr *pStudioHdr, const QAngle &angles, const Vector &pos, float flTime, int iFramecounter, int boneMask ); + void AddDependencies( mstudioseqdesc_t &seqdesc, int iSequence, float flCycle, const float poseParameters[], float flWeight = 1.0f ); + + void ClearTargets( void ); + void UpdateTargets( Vector pos[], Quaternion q[], matrix3x4_t boneToWorld[], CBoneBitList &boneComputed ); + void AutoIKRelease( void ); + void SolveDependencies( Vector pos[], Quaternion q[], matrix3x4_t boneToWorld[], CBoneBitList &boneComputed ); + + void AddAutoplayLocks( Vector pos[], Quaternion q[] ); + void SolveAutoplayLocks( Vector pos[], Quaternion q[] ); + + void AddSequenceLocks( mstudioseqdesc_t &SeqDesc, Vector pos[], Quaternion q[] ); + void SolveSequenceLocks( mstudioseqdesc_t &SeqDesc, Vector pos[], Quaternion q[] ); + + void AddAllLocks( Vector pos[], Quaternion q[] ); + void SolveAllLocks( Vector pos[], Quaternion q[] ); + + void SolveLock( const mstudioiklock_t *plock, int i, Vector pos[], Quaternion q[], matrix3x4_t boneToWorld[], CBoneBitList &boneComputed ); + + CUtlVectorFixed< CIKTarget, 12 > m_target; + +private: + + CStudioHdr const *m_pStudioHdr; + + bool Estimate( int iSequence, float flCycle, int iTarget, const float poseParameter[], float flWeight = 1.0f ); + void BuildBoneChain( const Vector pos[], const Quaternion q[], int iBone, matrix3x4_t *pBoneToWorld, CBoneBitList &boneComputed ); + + // virtual IK rules, filtered and combined from each sequence + CUtlVector< CUtlVector< ikcontextikrule_t > > m_ikChainRule; + CUtlVector< ikcontextikrule_t > m_ikLock; + matrix3x4_t m_rootxform; + + int m_iFramecounter; + float m_flTime; + int m_boneMask; +}; + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +// replaces the bonetoworld transforms for all bones that are procedural +bool CalcProceduralBone( + const CStudioHdr *pStudioHdr, + int iBone, + CBoneAccessor &bonetoworld + ); + +void Studio_BuildMatrices( + const CStudioHdr *pStudioHdr, + const QAngle& angles, + const Vector& origin, + const Vector pos[], + const Quaternion q[], + int iBone, + float flScale, + matrix3x4_t bonetoworld[MAXSTUDIOBONES], + int boneMask + ); + + +// Get a bone->bone relative transform +void Studio_CalcBoneToBoneTransform( const CStudioHdr *pStudioHdr, int inputBoneIndex, int outputBoneIndex, matrix3x4_t &matrixOut ); + +// Given a bone rotation value, figures out the value you need to give to the controller +// to have the bone at that value. +// [in] flValue = the desired bone rotation value +// [out] ctlValue = the (0-1) value to set the controller t. +// return value = flValue, unwrapped to lie between the controller's start and end. +float Studio_SetController( const CStudioHdr *pStudioHdr, int iController, float flValue, float &ctlValue ); + + +// Given a 0-1 controller value, maps it into the controller's start and end and returns the bone rotation angle. +// [in] ctlValue = value in controller space (0-1). +// return value = value in bone space +float Studio_GetController( const CStudioHdr *pStudioHdr, int iController, float ctlValue ); + +void Studio_CalcDefaultPoseParameters( const CStudioHdr *pStudioHdr, float flPoseParameter[MAXSTUDIOPOSEPARAM], int nCount ); +float Studio_GetPoseParameter( const CStudioHdr *pStudioHdr, int iParameter, float ctlValue ); +float Studio_SetPoseParameter( const CStudioHdr *pStudioHdr, int iParameter, float flValue, float &ctlValue ); + +// converts a global 0..1 pose parameter into the local sequences blending value +void Studio_LocalPoseParameter( const CStudioHdr *pStudioHdr, const float poseParameter[], mstudioseqdesc_t &seqdesc, int iSequence, int iLocalIndex, float &flSetting, int &index ); + +void Studio_SeqAnims( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int iSequence, const float poseParameter[], mstudioanimdesc_t *panim[4], float *weight ); +int Studio_MaxFrame( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] ); +float Studio_FPS( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] ); +float Studio_CPS( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int iSequence, const float poseParameter[] ); +float Studio_Duration( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[] ); +void Studio_MovementRate( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], Vector *pVec ); + +// void Studio_Movement( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], Vector *pVec ); + +//void Studio_AnimPosition( mstudioanimdesc_t *panim, float flCycle, Vector &vecPos, Vector &vecAngle ); +//void Studio_AnimVelocity( mstudioanimdesc_t *panim, float flCycle, Vector &vecVelocity ); +//float Studio_FindAnimDistance( mstudioanimdesc_t *panim, float flDist ); +bool Studio_AnimMovement( mstudioanimdesc_t *panim, float flCycleFrom, float flCycleTo, Vector &deltaPos, QAngle &deltaAngle ); +bool Studio_SeqMovement( const CStudioHdr *pStudioHdr, int iSequence, float flCycleFrom, float flCycleTo, const float poseParameter[], Vector &deltaMovement, QAngle &deltaAngle ); +bool Studio_SeqVelocity( const CStudioHdr *pStudioHdr, int iSequence, float flCycle, const float poseParameter[], Vector &vecVelocity ); +float Studio_FindSeqDistance( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], float flDist ); +float Studio_FindSeqVelocity( const CStudioHdr *pStudioHdr, int iSequence, const float poseParameter[], float flVelocity ); +int Studio_FindAttachment( const CStudioHdr *pStudioHdr, const char *pAttachmentName ); +int Studio_FindRandomAttachment( const CStudioHdr *pStudioHdr, const char *pAttachmentName ); +int Studio_BoneIndexByName( const CStudioHdr *pStudioHdr, const char *pName ); +const char *Studio_GetDefaultSurfaceProps( CStudioHdr *pstudiohdr ); +float Studio_GetMass( CStudioHdr *pstudiohdr ); +const char *Studio_GetKeyValueText( const CStudioHdr *pStudioHdr, int iSequence ); + +FORWARD_DECLARE_HANDLE( memhandle_t ); +struct bonecacheparams_t +{ + CStudioHdr *pStudioHdr; + matrix3x4_t *pBoneToWorld; + float curtime; + int boneMask; +}; + +class CBoneCache +{ +public: + + // you must implement these static functions for the ResourceManager + // ----------------------------------------------------------- + static CBoneCache *CreateResource( const bonecacheparams_t ¶ms ); + static unsigned int EstimatedSize( const bonecacheparams_t ¶ms ); + // ----------------------------------------------------------- + // member functions that must be present for the ResourceManager + void DestroyResource(); + CBoneCache *GetData() { return this; } + unsigned int Size() { return m_size; } + // ----------------------------------------------------------- + + CBoneCache(); + + // was constructor, but placement new is messy wrt memdebug - so cast & init instead + void Init( const bonecacheparams_t ¶ms, unsigned int size, short *pStudioToCached, short *pCachedToStudio, int cachedBoneCount ); + + void UpdateBones( const matrix3x4_t *pBoneToWorld, int numbones, float curtime ); + matrix3x4_t *GetCachedBone( int studioIndex ); + void ReadCachedBones( matrix3x4_t *pBoneToWorld ); + void ReadCachedBonePointers( matrix3x4_t **bones, int numbones ); + + bool IsValid( float curtime, float dt = 0.1f ); + +public: + float m_timeValid; + int m_boneMask; + +private: + matrix3x4_t *BoneArray(); + short *StudioToCached(); + short *CachedToStudio(); + + unsigned int m_size; + unsigned short m_cachedBoneCount; + unsigned short m_matrixOffset; + unsigned short m_cachedToStudioOffset; + unsigned short m_boneOutOffset; +}; + +CBoneCache *Studio_GetBoneCache( memhandle_t cacheHandle ); +memhandle_t Studio_CreateBoneCache( bonecacheparams_t ¶ms ); +void Studio_DestroyBoneCache( memhandle_t cacheHandle ); +void Studio_InvalidateBoneCache( memhandle_t cacheHandle ); + +// Given a ray, trace for an intersection with this studiomodel. Get the array of bones from StudioSetupHitboxBones +bool TraceToStudio( class IPhysicsSurfaceProps *pProps, const Ray_t& ray, CStudioHdr *pStudioHdr, mstudiohitboxset_t *set, matrix3x4_t **hitboxbones, int fContentsMask, const Vector &vecOrigin, float flScale, trace_t &trace ); + +void QuaternionSM( float s, const Quaternion &p, const Quaternion &q, Quaternion &qt ); +void QuaternionMA( const Quaternion &p, float s, const Quaternion &q, Quaternion &qt ); + +bool Studio_PrefetchSequence( const CStudioHdr *pStudioHdr, int iSequence ); + +void Studio_RunBoneFlexDrivers( float *pFlexController, const CStudioHdr *pStudioHdr, const Vector *pPositions, const matrix3x4_t *pBoneToWorld, const matrix3x4_t &mRootToWorld ); + +#endif // BONE_SETUP_H diff --git a/sp/src/public/bspfile.h b/sp/src/public/bspfile.h new file mode 100644 index 00000000..bff7b20a --- /dev/null +++ b/sp/src/public/bspfile.h @@ -0,0 +1,1166 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Defines and structures for the BSP file format. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef BSPFILE_H +#define BSPFILE_H +#pragma once + +#ifndef MATHLIB_H +#include "mathlib/mathlib.h" +#endif + +#include "datamap.h" +#include "mathlib/bumpvects.h" +#include "mathlib/compressed_light_cube.h" + +// little-endian "VBSP" +#define IDBSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'V') + +// MINBSPVERSION is the minimum acceptable version. The engine will load MINBSPVERSION through BSPVERSION +#define MINBSPVERSION 19 +#define BSPVERSION 20 + + +// This needs to match the value in gl_lightmap.h +// Need to dynamically allocate the weights and light values in radial_t to make this variable. +#define MAX_BRUSH_LIGHTMAP_DIM_WITHOUT_BORDER 32 +// This is one more than what vbsp cuts for to allow for rounding errors +#define MAX_BRUSH_LIGHTMAP_DIM_INCLUDING_BORDER 35 + +// We can have larger lightmaps on displacements +#define MAX_DISP_LIGHTMAP_DIM_WITHOUT_BORDER 125 +#define MAX_DISP_LIGHTMAP_DIM_INCLUDING_BORDER 128 + + +// This is the actual max.. (change if you change the brush lightmap dim or disp lightmap dim +#define MAX_LIGHTMAP_DIM_WITHOUT_BORDER MAX_DISP_LIGHTMAP_DIM_WITHOUT_BORDER +#define MAX_LIGHTMAP_DIM_INCLUDING_BORDER MAX_DISP_LIGHTMAP_DIM_INCLUDING_BORDER + +#define MAX_LIGHTSTYLES 64 + + +// upper design bounds +#define MIN_MAP_DISP_POWER 2 // Minimum and maximum power a displacement can be. +#define MAX_MAP_DISP_POWER 4 + +// Max # of neighboring displacement touching a displacement's corner. +#define MAX_DISP_CORNER_NEIGHBORS 4 + +#define NUM_DISP_POWER_VERTS(power) ( ((1 << (power)) + 1) * ((1 << (power)) + 1) ) +#define NUM_DISP_POWER_TRIS(power) ( (1 << (power)) * (1 << (power)) * 2 ) + +#if !defined( BSP_USE_LESS_MEMORY ) +// Common limits +// leaffaces, leafbrushes, planes, and verts are still bounded by +// 16 bit short limits +#define MAX_MAP_MODELS 1024 +#define MAX_MAP_BRUSHES 8192 +#ifdef MAPBASE +#define MAX_MAP_ENTITIES 65536 // According to ficool2, this limit is bogus/not enforced by the engine and can be "safely" raised. +#else +#define MAX_MAP_ENTITIES 8192 +#endif +#define MAX_MAP_TEXINFO 12288 +#define MAX_MAP_TEXDATA 2048 +#define MAX_MAP_DISPINFO 2048 +#define MAX_MAP_DISP_VERTS ( MAX_MAP_DISPINFO * ((1< x --------------> 2 +// +// ^ ^ +// | | +// | | +// M2C | | M2C +// | | +// | | +// +// x x x +// +// ^ ^ +// | | +// | | +// C2M | | C2M +// | | +// | | +// +// 0 --------------> x --------------> 3 +// +// C2M M2C +// +// +// The CHILDNODE_ defines can be used to refer to a node's child nodes (this is for when you're +// recursing into the node tree inside a displacement): +// +// --------- +// | | | +// | 1 | 0 | +// | | | +// |---x---| +// | | | +// | 2 | 3 | +// | | | +// --------- +// +// ------------------------------------------------------------------------------------------------ // + +// These can be used to index g_ChildNodeIndexMul. +enum +{ + CHILDNODE_UPPER_RIGHT=0, + CHILDNODE_UPPER_LEFT=1, + CHILDNODE_LOWER_LEFT=2, + CHILDNODE_LOWER_RIGHT=3 +}; + + +// Corner indices. Used to index m_CornerNeighbors. +enum +{ + CORNER_LOWER_LEFT=0, + CORNER_UPPER_LEFT=1, + CORNER_UPPER_RIGHT=2, + CORNER_LOWER_RIGHT=3 +}; + + +// These edge indices must match the edge indices of the CCoreDispSurface. +enum +{ + NEIGHBOREDGE_LEFT=0, + NEIGHBOREDGE_TOP=1, + NEIGHBOREDGE_RIGHT=2, + NEIGHBOREDGE_BOTTOM=3 +}; + + +// These denote where one dispinfo fits on another. +// Note: tables are generated based on these indices so make sure to update +// them if these indices are changed. +typedef enum +{ + CORNER_TO_CORNER=0, + CORNER_TO_MIDPOINT=1, + MIDPOINT_TO_CORNER=2 +} NeighborSpan; + + +// These define relative orientations of displacement neighbors. +typedef enum +{ + ORIENTATION_CCW_0=0, + ORIENTATION_CCW_90=1, + ORIENTATION_CCW_180=2, + ORIENTATION_CCW_270=3 +} NeighborOrientation; + + +//============================================================================= + +enum +{ + LUMP_ENTITIES = 0, // * + LUMP_PLANES = 1, // * + LUMP_TEXDATA = 2, // * + LUMP_VERTEXES = 3, // * + LUMP_VISIBILITY = 4, // * + LUMP_NODES = 5, // * + LUMP_TEXINFO = 6, // * + LUMP_FACES = 7, // * + LUMP_LIGHTING = 8, // * + LUMP_OCCLUSION = 9, + LUMP_LEAFS = 10, // * + LUMP_FACEIDS = 11, + LUMP_EDGES = 12, // * + LUMP_SURFEDGES = 13, // * + LUMP_MODELS = 14, // * + LUMP_WORLDLIGHTS = 15, // + LUMP_LEAFFACES = 16, // * + LUMP_LEAFBRUSHES = 17, // * + LUMP_BRUSHES = 18, // * + LUMP_BRUSHSIDES = 19, // * + LUMP_AREAS = 20, // * + LUMP_AREAPORTALS = 21, // * + LUMP_UNUSED0 = 22, + LUMP_UNUSED1 = 23, + LUMP_UNUSED2 = 24, + LUMP_UNUSED3 = 25, + LUMP_DISPINFO = 26, + LUMP_ORIGINALFACES = 27, + LUMP_PHYSDISP = 28, + LUMP_PHYSCOLLIDE = 29, + LUMP_VERTNORMALS = 30, + LUMP_VERTNORMALINDICES = 31, + LUMP_DISP_LIGHTMAP_ALPHAS = 32, + LUMP_DISP_VERTS = 33, // CDispVerts + LUMP_DISP_LIGHTMAP_SAMPLE_POSITIONS = 34, // For each displacement + // For each lightmap sample + // byte for index + // if 255, then index = next byte + 255 + // 3 bytes for barycentric coordinates + // The game lump is a method of adding game-specific lumps + // FIXME: Eventually, all lumps could use the game lump system + LUMP_GAME_LUMP = 35, + LUMP_LEAFWATERDATA = 36, + LUMP_PRIMITIVES = 37, + LUMP_PRIMVERTS = 38, + LUMP_PRIMINDICES = 39, + // A pak file can be embedded in a .bsp now, and the file system will search the pak + // file first for any referenced names, before deferring to the game directory + // file system/pak files and finally the base directory file system/pak files. + LUMP_PAKFILE = 40, + LUMP_CLIPPORTALVERTS = 41, + // A map can have a number of cubemap entities in it which cause cubemap renders + // to be taken after running vrad. + LUMP_CUBEMAPS = 42, + LUMP_TEXDATA_STRING_DATA = 43, + LUMP_TEXDATA_STRING_TABLE = 44, + LUMP_OVERLAYS = 45, + LUMP_LEAFMINDISTTOWATER = 46, + LUMP_FACE_MACRO_TEXTURE_INFO = 47, + LUMP_DISP_TRIS = 48, + LUMP_PHYSCOLLIDESURFACE = 49, // deprecated. We no longer use win32-specific havok compression on terrain + LUMP_WATEROVERLAYS = 50, + LUMP_LEAF_AMBIENT_INDEX_HDR = 51, // index of LUMP_LEAF_AMBIENT_LIGHTING_HDR + LUMP_LEAF_AMBIENT_INDEX = 52, // index of LUMP_LEAF_AMBIENT_LIGHTING + + // optional lumps for HDR + LUMP_LIGHTING_HDR = 53, + LUMP_WORLDLIGHTS_HDR = 54, + LUMP_LEAF_AMBIENT_LIGHTING_HDR = 55, // NOTE: this data overrides part of the data stored in LUMP_LEAFS. + LUMP_LEAF_AMBIENT_LIGHTING = 56, // NOTE: this data overrides part of the data stored in LUMP_LEAFS. + + LUMP_XZIPPAKFILE = 57, // deprecated. xbox 1: xzip version of pak file + LUMP_FACES_HDR = 58, // HDR maps may have different face data. + LUMP_MAP_FLAGS = 59, // extended level-wide flags. not present in all levels + LUMP_OVERLAY_FADES = 60, // Fade distances for overlays +}; + + +// Lumps that have versions are listed here +enum +{ + LUMP_LIGHTING_VERSION = 1, + LUMP_FACES_VERSION = 1, + LUMP_OCCLUSION_VERSION = 2, + LUMP_LEAFS_VERSION = 1, + LUMP_LEAF_AMBIENT_LIGHTING_VERSION = 1, +}; + + +#define HEADER_LUMPS 64 + +#include "zip_uncompressed.h" + +struct lump_t +{ + DECLARE_BYTESWAP_DATADESC(); + int fileofs, filelen; + int version; // default to zero + char fourCC[4]; // default to ( char )0, ( char )0, ( char )0, ( char )0 +}; + + +struct dheader_t +{ + DECLARE_BYTESWAP_DATADESC(); + int ident; + int version; + lump_t lumps[HEADER_LUMPS]; + int mapRevision; // the map's revision (iteration, version) number (added BSPVERSION 6) +}; + +// level feature flags +#define LVLFLAGS_BAKED_STATIC_PROP_LIGHTING_NONHDR 0x00000001 // was processed by vrad with -staticproplighting, no hdr data +#define LVLFLAGS_BAKED_STATIC_PROP_LIGHTING_HDR 0x00000002 // was processed by vrad with -staticproplighting, in hdr + +struct dflagslump_t +{ + DECLARE_BYTESWAP_DATADESC(); + uint32 m_LevelFlags; // LVLFLAGS_xxx +}; + +struct lumpfileheader_t +{ + int lumpOffset; + int lumpID; + int lumpVersion; + int lumpLength; + int mapRevision; // the map's revision (iteration, version) number (added BSPVERSION 6) +}; + +struct dgamelumpheader_t +{ + DECLARE_BYTESWAP_DATADESC(); + int lumpCount; + + // dgamelump_t follow this +}; + +// This is expected to be a four-CC code ('lump') +typedef int GameLumpId_t; + +// 360 only: game lump is compressed, filelen reflects original size +// use next entry fileofs to determine actual disk lump compressed size +// compression stage ensures a terminal null dictionary entry +#define GAMELUMPFLAG_COMPRESSED 0x0001 + +struct dgamelump_t +{ + DECLARE_BYTESWAP_DATADESC(); + GameLumpId_t id; + unsigned short flags; + unsigned short version; + int fileofs; + int filelen; +}; + +extern int g_MapRevision; + +struct dmodel_t +{ + DECLARE_BYTESWAP_DATADESC(); + Vector mins, maxs; + Vector origin; // for sounds or lights + int headnode; + int firstface, numfaces; // submodels just draw faces without walking the bsp tree +}; + +struct dphysmodel_t +{ + DECLARE_BYTESWAP_DATADESC() + int modelIndex; + int dataSize; + int keydataSize; + int solidCount; +}; + +// contains the binary blob for each displacement surface's virtual hull +struct dphysdisp_t +{ + DECLARE_BYTESWAP_DATADESC() + unsigned short numDisplacements; + //unsigned short dataSize[numDisplacements]; +}; + +struct dvertex_t +{ + DECLARE_BYTESWAP_DATADESC(); + Vector point; +}; + +// planes (x&~1) and (x&~1)+1 are always opposites +struct dplane_t +{ + DECLARE_BYTESWAP_DATADESC(); + Vector normal; + float dist; + int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate +}; + +#ifndef BSPFLAGS_H +#include "bspflags.h" +#endif + +struct dnode_t +{ + DECLARE_BYTESWAP_DATADESC(); + int planenum; + int children[2]; // negative numbers are -(leafs+1), not nodes + short mins[3]; // for frustom culling + short maxs[3]; + unsigned short firstface; + unsigned short numfaces; // counting both sides + short area; // If all leaves below this node are in the same area, then + // this is the area index. If not, this is -1. +}; + +typedef struct texinfo_s +{ + DECLARE_BYTESWAP_DATADESC(); + float textureVecsTexelsPerWorldUnits[2][4]; // [s/t][xyz offset] + float lightmapVecsLuxelsPerWorldUnits[2][4]; // [s/t][xyz offset] - length is in units of texels/area + int flags; // miptex flags + overrides + int texdata; // Pointer to texture name, size, etc. +} texinfo_t; + +#define TEXTURE_NAME_LENGTH 128 // changed from 64 BSPVERSION 8 + +struct dtexdata_t +{ + DECLARE_BYTESWAP_DATADESC(); + Vector reflectivity; + int nameStringTableID; // index into g_StringTable for the texture name + int width, height; // source image + int view_width, view_height; // +}; + + +//----------------------------------------------------------------------------- +// Occluders are simply polygons +//----------------------------------------------------------------------------- +// Flags field of doccluderdata_t +enum +{ + OCCLUDER_FLAGS_INACTIVE = 0x1, +}; + +struct doccluderdata_t +{ + DECLARE_BYTESWAP_DATADESC(); + int flags; + int firstpoly; // index into doccluderpolys + int polycount; + Vector mins; + Vector maxs; + int area; +}; + +struct doccluderdataV1_t +{ + int flags; + int firstpoly; // index into doccluderpolys + int polycount; + Vector mins; + Vector maxs; +}; + +struct doccluderpolydata_t +{ + DECLARE_BYTESWAP_DATADESC(); + int firstvertexindex; // index into doccludervertindices + int vertexcount; + int planenum; +}; + + +// NOTE: see the section above titled "displacement neighbor rules". +struct CDispSubNeighbor +{ +public: + DECLARE_BYTESWAP_DATADESC(); + unsigned short GetNeighborIndex() const { return m_iNeighbor; } + NeighborSpan GetSpan() const { return (NeighborSpan)m_Span; } + NeighborSpan GetNeighborSpan() const { return (NeighborSpan)m_NeighborSpan; } + NeighborOrientation GetNeighborOrientation() const { return (NeighborOrientation)m_NeighborOrientation; } + + bool IsValid() const { return m_iNeighbor != 0xFFFF; } + void SetInvalid() { m_iNeighbor = 0xFFFF; } + + +public: + unsigned short m_iNeighbor; // This indexes into ddispinfos. + // 0xFFFF if there is no neighbor here. + + unsigned char m_NeighborOrientation; // (CCW) rotation of the neighbor wrt this displacement. + + // These use the NeighborSpan type. + unsigned char m_Span; // Where the neighbor fits onto this side of our displacement. + unsigned char m_NeighborSpan; // Where we fit onto our neighbor. +}; + + +// NOTE: see the section above titled "displacement neighbor rules". +class CDispNeighbor +{ +public: + DECLARE_BYTESWAP_DATADESC(); + void SetInvalid() { m_SubNeighbors[0].SetInvalid(); m_SubNeighbors[1].SetInvalid(); } + + // Returns false if there isn't anything touching this edge. + bool IsValid() { return m_SubNeighbors[0].IsValid() || m_SubNeighbors[1].IsValid(); } + + +public: + // Note: if there is a neighbor that fills the whole side (CORNER_TO_CORNER), + // then it will always be in CDispNeighbor::m_Neighbors[0] + CDispSubNeighbor m_SubNeighbors[2]; +}; + + +class CDispCornerNeighbors +{ +public: + DECLARE_BYTESWAP_DATADESC(); + void SetInvalid() { m_nNeighbors = 0; } + + +public: + unsigned short m_Neighbors[MAX_DISP_CORNER_NEIGHBORS]; // indices of neighbors. + unsigned char m_nNeighbors; +}; + + +class CDispVert +{ +public: + DECLARE_BYTESWAP_DATADESC(); + Vector m_vVector; // Vector field defining displacement volume. + float m_flDist; // Displacement distances. + float m_flAlpha; // "per vertex" alpha values. +}; + +#define DISPTRI_TAG_SURFACE (1<<0) +#define DISPTRI_TAG_WALKABLE (1<<1) +#define DISPTRI_TAG_BUILDABLE (1<<2) +#define DISPTRI_FLAG_SURFPROP1 (1<<3) +#define DISPTRI_FLAG_SURFPROP2 (1<<4) +#define DISPTRI_TAG_REMOVE (1<<5) + +class CDispTri +{ +public: + DECLARE_BYTESWAP_DATADESC(); + unsigned short m_uiTags; // Displacement triangle tags. +}; + +class ddispinfo_t +{ +public: + DECLARE_BYTESWAP_DATADESC(); + int NumVerts() const { return NUM_DISP_POWER_VERTS(power); } + int NumTris() const { return NUM_DISP_POWER_TRIS(power); } + +public: + Vector startPosition; // start position used for orientation -- (added BSPVERSION 6) + int m_iDispVertStart; // Index into LUMP_DISP_VERTS. + int m_iDispTriStart; // Index into LUMP_DISP_TRIS. + + int power; // power - indicates size of map (2^power + 1) + int minTess; // minimum tesselation allowed + float smoothingAngle; // lighting smoothing angle + int contents; // surface contents + + unsigned short m_iMapFace; // Which map face this displacement comes from. + + int m_iLightmapAlphaStart; // Index into ddisplightmapalpha. + // The count is m_pParent->lightmapTextureSizeInLuxels[0]*m_pParent->lightmapTextureSizeInLuxels[1]. + + int m_iLightmapSamplePositionStart; // Index into LUMP_DISP_LIGHTMAP_SAMPLE_POSITIONS. + + CDispNeighbor m_EdgeNeighbors[4]; // Indexed by NEIGHBOREDGE_ defines. + CDispCornerNeighbors m_CornerNeighbors[4]; // Indexed by CORNER_ defines. + + enum unnamed { ALLOWEDVERTS_SIZE = PAD_NUMBER( MAX_DISPVERTS, 32 ) / 32 }; + unsigned long m_AllowedVerts[ALLOWEDVERTS_SIZE]; // This is built based on the layout and sizes of our neighbors + // and tells us which vertices are allowed to be active. +}; + + +// note that edge 0 is never used, because negative edge nums are used for +// counterclockwise use of the edge in a face +struct dedge_t +{ + DECLARE_BYTESWAP_DATADESC(); + unsigned short v[2]; // vertex numbers +}; + +#define MAXLIGHTMAPS 4 + +enum dprimitive_type +{ + PRIM_TRILIST=0, + PRIM_TRISTRIP=1, +}; + +struct dprimitive_t +{ + DECLARE_BYTESWAP_DATADESC(); + unsigned char type; + unsigned short firstIndex; + unsigned short indexCount; + unsigned short firstVert; + unsigned short vertCount; +}; + +struct dprimvert_t +{ + DECLARE_BYTESWAP_DATADESC(); + Vector pos; +}; + +struct dface_t +{ + DECLARE_BYTESWAP_DATADESC(); + unsigned short planenum; + byte side; // faces opposite to the node's plane direction + byte onNode; // 1 of on node, 0 if in leaf + + int firstedge; // we must support > 64k edges + short numedges; + short texinfo; + // This is a union under the assumption that a fog volume boundary (ie. water surface) + // isn't a displacement map. + // FIXME: These should be made a union with a flags or type field for which one it is + // if we can add more to this. +// union +// { + short dispinfo; + // This is only for surfaces that are the boundaries of fog volumes + // (ie. water surfaces) + // All of the rest of the surfaces can look at their leaf to find out + // what fog volume they are in. + short surfaceFogVolumeID; +// }; + + // lighting info + byte styles[MAXLIGHTMAPS]; + int lightofs; // start of [numstyles*surfsize] samples + float area; + + // TODO: make these unsigned chars? + int m_LightmapTextureMinsInLuxels[2]; + int m_LightmapTextureSizeInLuxels[2]; + + int origFace; // reference the original face this face was derived from + + +public: + + unsigned short GetNumPrims() const; + void SetNumPrims( unsigned short nPrims ); + bool AreDynamicShadowsEnabled(); + void SetDynamicShadowsEnabled( bool bEnabled ); + + // non-polygon primitives (strips and lists) +private: + unsigned short m_NumPrims; // Top bit, if set, disables shadows on this surface (this is why there are accessors). + +public: + unsigned short firstPrimID; + + unsigned int smoothingGroups; +}; + + +inline unsigned short dface_t::GetNumPrims() const +{ + return m_NumPrims & 0x7FFF; +} + +inline void dface_t::SetNumPrims( unsigned short nPrims ) +{ + Assert( (nPrims & 0x8000) == 0 ); + m_NumPrims &= ~0x7FFF; + m_NumPrims |= (nPrims & 0x7FFF); +} + +inline bool dface_t::AreDynamicShadowsEnabled() +{ + return (m_NumPrims & 0x8000) == 0; +} + +inline void dface_t::SetDynamicShadowsEnabled( bool bEnabled ) +{ + if ( bEnabled ) + m_NumPrims &= ~0x8000; + else + m_NumPrims |= 0x8000; +} + +struct dfaceid_t +{ + DECLARE_BYTESWAP_DATADESC(); + unsigned short hammerfaceid; +}; + + +// NOTE: Only 7-bits stored!!! +#define LEAF_FLAGS_SKY 0x01 // This leaf has 3D sky in its PVS +#define LEAF_FLAGS_RADIAL 0x02 // This leaf culled away some portals due to radial vis +#define LEAF_FLAGS_SKY2D 0x04 // This leaf has 2D sky in its PVS + +#if defined( _X360 ) +#pragma bitfield_order( push, lsb_to_msb ) +#endif +#pragma warning( disable:4201 ) // C4201: nonstandard extension used: nameless struct/union +struct dleaf_version_0_t +{ + DECLARE_BYTESWAP_DATADESC(); + int contents; // OR of all brushes (not needed?) + + short cluster; + + BEGIN_BITFIELD( bf ); + short area:9; + short flags:7; // Per leaf flags. + END_BITFIELD(); + + short mins[3]; // for frustum culling + short maxs[3]; + + unsigned short firstleafface; + unsigned short numleaffaces; + + unsigned short firstleafbrush; + unsigned short numleafbrushes; + short leafWaterDataID; // -1 for not in water + + // Precaculated light info for entities. + CompressedLightCube m_AmbientLighting; +}; + +// version 1 +struct dleaf_t +{ + DECLARE_BYTESWAP_DATADESC(); + int contents; // OR of all brushes (not needed?) + + short cluster; + + BEGIN_BITFIELD( bf ); + short area:9; + short flags:7; // Per leaf flags. + END_BITFIELD(); + + short mins[3]; // for frustum culling + short maxs[3]; + + unsigned short firstleafface; + unsigned short numleaffaces; + + unsigned short firstleafbrush; + unsigned short numleafbrushes; + short leafWaterDataID; // -1 for not in water + + // NOTE: removed this for version 1 and moved into separate lump "LUMP_LEAF_AMBIENT_LIGHTING" or "LUMP_LEAF_AMBIENT_LIGHTING_HDR" + // Precaculated light info for entities. +// CompressedLightCube m_AmbientLighting; +}; +#pragma warning( default:4201 ) // C4201: nonstandard extension used: nameless struct/union +#if defined( _X360 ) +#pragma bitfield_order( pop ) +#endif + +// each leaf contains N samples of the ambient lighting +// each sample contains a cube of ambient light projected on to each axis +// and a sampling position encoded as a 0.8 fraction (mins=0,maxs=255) of the leaf's bounding box +struct dleafambientlighting_t +{ + DECLARE_BYTESWAP_DATADESC(); + CompressedLightCube cube; + byte x; // fixed point fraction of leaf bounds + byte y; // fixed point fraction of leaf bounds + byte z; // fixed point fraction of leaf bounds + byte pad; // unused +}; + +struct dleafambientindex_t +{ + DECLARE_BYTESWAP_DATADESC(); + + unsigned short ambientSampleCount; + unsigned short firstAmbientSample; +}; + +struct dbrushside_t +{ + DECLARE_BYTESWAP_DATADESC(); + unsigned short planenum; // facing out of the leaf + short texinfo; + short dispinfo; // displacement info (BSPVERSION 7) + short bevel; // is the side a bevel plane? (BSPVERSION 7) +}; + +struct dbrush_t +{ + DECLARE_BYTESWAP_DATADESC(); + int firstside; + int numsides; + int contents; +}; + +#define ANGLE_UP -1 +#define ANGLE_DOWN -2 + + +// the visibility lump consists of a header with a count, then +// byte offsets for the PVS and PHS of each cluster, then the raw +// compressed bit vectors +#define DVIS_PVS 0 +#define DVIS_PAS 1 +struct dvis_t +{ + int numclusters; + int bitofs[8][2]; // bitofs[numclusters][2] +}; + +// each area has a list of portals that lead into other areas +// when portals are closed, other areas may not be visible or +// hearable even if the vis info says that it should be +struct dareaportal_t +{ + DECLARE_BYTESWAP_DATADESC(); + unsigned short m_PortalKey; // Entities have a key called portalnumber (and in vbsp a variable + // called areaportalnum) which is used + // to bind them to the area portals by comparing with this value. + + unsigned short otherarea; // The area this portal looks into. + + unsigned short m_FirstClipPortalVert; // Portal geometry. + unsigned short m_nClipPortalVerts; + + int planenum; +}; + + +struct darea_t +{ + DECLARE_BYTESWAP_DATADESC(); + int numareaportals; + int firstareaportal; +}; + +struct dleafwaterdata_t +{ + DECLARE_BYTESWAP_DATADESC(); + float surfaceZ; + float minZ; + short surfaceTexInfoID; +}; + +class CFaceMacroTextureInfo +{ +public: + DECLARE_BYTESWAP_DATADESC(); + // This looks up into g_TexDataStringTable, which looks up into g_TexDataStringData. + // 0xFFFF if the face has no macro texture. + unsigned short m_MacroTextureNameID; +}; + +// lights that were used to illuminate the world +enum emittype_t +{ + emit_surface, // 90 degree spotlight + emit_point, // simple point light source + emit_spotlight, // spotlight with penumbra + emit_skylight, // directional light with no falloff (surface must trace to SKY texture) + emit_quakelight, // linear falloff, non-lambertian + emit_skyambient, // spherical light source with no falloff (surface must trace to SKY texture) +}; + + +// Flags for dworldlight_t::flags +#define DWL_FLAGS_INAMBIENTCUBE 0x0001 // This says that the light was put into the per-leaf ambient cubes. + + +struct dworldlight_t +{ + DECLARE_BYTESWAP_DATADESC(); + Vector origin; + Vector intensity; + Vector normal; // for surfaces and spotlights + int cluster; + emittype_t type; + int style; + float stopdot; // start of penumbra for emit_spotlight + float stopdot2; // end of penumbra for emit_spotlight + float exponent; // + float radius; // cutoff distance + // falloff for emit_spotlight + emit_point: + // 1 / (constant_attn + linear_attn * dist + quadratic_attn * dist^2) + float constant_attn; + float linear_attn; + float quadratic_attn; + int flags; // Uses a combination of the DWL_FLAGS_ defines. + int texinfo; // + int owner; // entity that this light it relative to +}; + +struct dcubemapsample_t +{ + DECLARE_BYTESWAP_DATADESC(); + int origin[3]; // position of light snapped to the nearest integer + // the filename for the vtf file is derived from the position + unsigned char size; // 0 - default + // otherwise, 1<<(size-1) +}; + +#define OVERLAY_BSP_FACE_COUNT 64 + +#define OVERLAY_NUM_RENDER_ORDERS (1<> (16 - OVERLAY_RENDER_ORDER_NUM_BITS)); +} + + +struct doverlayfade_t +{ + DECLARE_BYTESWAP_DATADESC(); + + float flFadeDistMinSq; + float flFadeDistMaxSq; +}; + + +#define WATEROVERLAY_BSP_FACE_COUNT 256 +#define WATEROVERLAY_RENDER_ORDER_NUM_BITS 2 +#define WATEROVERLAY_NUM_RENDER_ORDERS (1<> ( 16 - WATEROVERLAY_RENDER_ORDER_NUM_BITS ) ); +} + +#ifndef _DEF_BYTE_ +#define _DEF_BYTE_ +typedef unsigned char byte; +typedef unsigned short word; +#endif + + +#define ANGLE_UP -1 +#define ANGLE_DOWN -2 + + +//=============== + + +struct epair_t +{ + epair_t *next; + char *key; + char *value; +}; + +// finalized page of surface's lightmaps +#define MAX_LIGHTMAPPAGE_WIDTH 256 +#define MAX_LIGHTMAPPAGE_HEIGHT 128 +typedef struct nameForDatadesc_dlightmappage_t // unnamed structs collide in the datadesc macros +{ + DECLARE_BYTESWAP_DATADESC(); + byte data[MAX_LIGHTMAPPAGE_WIDTH*MAX_LIGHTMAPPAGE_HEIGHT]; + byte palette[256*4]; +} dlightmappage_t; + +typedef struct nameForDatadesc_dlightmappageinfo_t // unnamed structs collide in the datadesc macros +{ + DECLARE_BYTESWAP_DATADESC(); + byte page; // lightmap page [0..?] + byte offset[2]; // offset into page (s,t) + byte pad; // unused + ColorRGBExp32 avgColor; // average used for runtime lighting calcs +} dlightmappageinfo_t; + +#endif // BSPFILE_H diff --git a/sp/src/public/bspflags.h b/sp/src/public/bspflags.h new file mode 100644 index 00000000..01070abe --- /dev/null +++ b/sp/src/public/bspflags.h @@ -0,0 +1,149 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//=============================================================================// + +#ifndef BSPFLAGS_H +#define BSPFLAGS_H + +#ifdef _WIN32 +#pragma once +#endif + +// contents flags are seperate bits +// a given brush can contribute multiple content bits +// multiple brushes can be in a single leaf + +// these definitions also need to be in q_shared.h! + +// lower bits are stronger, and will eat weaker brushes completely +#define CONTENTS_EMPTY 0 // No contents + +#define CONTENTS_SOLID 0x1 // an eye is never valid in a solid +#define CONTENTS_WINDOW 0x2 // translucent, but not watery (glass) +#define CONTENTS_AUX 0x4 +#define CONTENTS_GRATE 0x8 // alpha-tested "grate" textures. Bullets/sight pass through, but solids don't +#define CONTENTS_SLIME 0x10 +#define CONTENTS_WATER 0x20 +#define CONTENTS_BLOCKLOS 0x40 // block AI line of sight +#define CONTENTS_OPAQUE 0x80 // things that cannot be seen through (may be non-solid though) +#define LAST_VISIBLE_CONTENTS 0x80 + +#define ALL_VISIBLE_CONTENTS (LAST_VISIBLE_CONTENTS | (LAST_VISIBLE_CONTENTS-1)) + +#define CONTENTS_TESTFOGVOLUME 0x100 +#define CONTENTS_UNUSED 0x200 + +// unused +// NOTE: If it's visible, grab from the top + update LAST_VISIBLE_CONTENTS +// if not visible, then grab from the bottom. +#define CONTENTS_UNUSED6 0x400 + +#define CONTENTS_TEAM1 0x800 // per team contents used to differentiate collisions +#define CONTENTS_TEAM2 0x1000 // between players and objects on different teams + +// ignore CONTENTS_OPAQUE on surfaces that have SURF_NODRAW +#define CONTENTS_IGNORE_NODRAW_OPAQUE 0x2000 + +// hits entities which are MOVETYPE_PUSH (doors, plats, etc.) +#define CONTENTS_MOVEABLE 0x4000 + +// remaining contents are non-visible, and don't eat brushes +#define CONTENTS_AREAPORTAL 0x8000 + +#define CONTENTS_PLAYERCLIP 0x10000 +#define CONTENTS_MONSTERCLIP 0x20000 + +// currents can be added to any other contents, and may be mixed +#define CONTENTS_CURRENT_0 0x40000 +#define CONTENTS_CURRENT_90 0x80000 +#define CONTENTS_CURRENT_180 0x100000 +#define CONTENTS_CURRENT_270 0x200000 +#define CONTENTS_CURRENT_UP 0x400000 +#define CONTENTS_CURRENT_DOWN 0x800000 + +#define CONTENTS_ORIGIN 0x1000000 // removed before bsping an entity + +#define CONTENTS_MONSTER 0x2000000 // should never be on a brush, only in game +#define CONTENTS_DEBRIS 0x4000000 +#define CONTENTS_DETAIL 0x8000000 // brushes to be added after vis leafs +#define CONTENTS_TRANSLUCENT 0x10000000 // auto set if any surface has trans +#define CONTENTS_LADDER 0x20000000 +#define CONTENTS_HITBOX 0x40000000 // use accurate hitboxes on trace + + +// NOTE: These are stored in a short in the engine now. Don't use more than 16 bits +#define SURF_LIGHT 0x0001 // value will hold the light strength +#define SURF_SKY2D 0x0002 // don't draw, indicates we should skylight + draw 2d sky but not draw the 3D skybox +#define SURF_SKY 0x0004 // don't draw, but add to skybox +#define SURF_WARP 0x0008 // turbulent water warp +#define SURF_TRANS 0x0010 +#define SURF_NOPORTAL 0x0020 // the surface can not have a portal placed on it +#define SURF_TRIGGER 0x0040 // FIXME: This is an xbox hack to work around elimination of trigger surfaces, which breaks occluders +#define SURF_NODRAW 0x0080 // don't bother referencing the texture + +#define SURF_HINT 0x0100 // make a primary bsp splitter + +#define SURF_SKIP 0x0200 // completely ignore, allowing non-closed brushes +#define SURF_NOLIGHT 0x0400 // Don't calculate light +#define SURF_BUMPLIGHT 0x0800 // calculate three lightmaps for the surface for bumpmapping +#define SURF_NOSHADOWS 0x1000 // Don't receive shadows +#define SURF_NODECALS 0x2000 // Don't receive decals +#define SURF_NOCHOP 0x4000 // Don't subdivide patches on this surface +#define SURF_HITBOX 0x8000 // surface is part of a hitbox + + + +// ----------------------------------------------------- +// spatial content masks - used for spatial queries (traceline,etc.) +// ----------------------------------------------------- +#define MASK_ALL (0xFFFFFFFF) +// everything that is normally solid +#define MASK_SOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) +// everything that blocks player movement +#define MASK_PLAYERSOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) +// blocks npc movement +#define MASK_NPCSOLID (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) +// water physics in these contents +#define MASK_WATER (CONTENTS_WATER|CONTENTS_MOVEABLE|CONTENTS_SLIME) +// everything that blocks lighting +#define MASK_OPAQUE (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_OPAQUE) +// everything that blocks lighting, but with monsters added. +#define MASK_OPAQUE_AND_NPCS (MASK_OPAQUE|CONTENTS_MONSTER) +// everything that blocks line of sight for AI +#define MASK_BLOCKLOS (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_BLOCKLOS) +// everything that blocks line of sight for AI plus NPCs +#define MASK_BLOCKLOS_AND_NPCS (MASK_BLOCKLOS|CONTENTS_MONSTER) +// everything that blocks line of sight for players +#define MASK_VISIBLE (MASK_OPAQUE|CONTENTS_IGNORE_NODRAW_OPAQUE) +// everything that blocks line of sight for players, but with monsters added. +#define MASK_VISIBLE_AND_NPCS (MASK_OPAQUE_AND_NPCS|CONTENTS_IGNORE_NODRAW_OPAQUE) +// bullets see these as solid +#define MASK_SHOT (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_HITBOX) +// non-raycasted weapons see this as solid (includes grates) +#define MASK_SHOT_HULL (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_GRATE) +// hits solids (not grates) and passes through everything else +#define MASK_SHOT_PORTAL (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTER) +// everything normally solid, except monsters (world+brush only) +#define MASK_SOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_GRATE) +// everything normally solid for player movement, except monsters (world+brush only) +#define MASK_PLAYERSOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_PLAYERCLIP|CONTENTS_GRATE) +// everything normally solid for npc movement, except monsters (world+brush only) +#define MASK_NPCSOLID_BRUSHONLY (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE) +// just the world, used for route rebuilding +#define MASK_NPCWORLDSTATIC (CONTENTS_SOLID|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE) +// These are things that can split areaportals +#define MASK_SPLITAREAPORTAL (CONTENTS_WATER|CONTENTS_SLIME) + +// UNDONE: This is untested, any moving water +#define MASK_CURRENT (CONTENTS_CURRENT_0|CONTENTS_CURRENT_90|CONTENTS_CURRENT_180|CONTENTS_CURRENT_270|CONTENTS_CURRENT_UP|CONTENTS_CURRENT_DOWN) + +// everything that blocks corpse movement +// UNDONE: Not used yet / may be deleted +#define MASK_DEADSOLID (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_GRATE) + +#endif // BSPFLAGS_H diff --git a/sp/src/public/bsptreedata.cpp b/sp/src/public/bsptreedata.cpp new file mode 100644 index 00000000..e03dd2c5 --- /dev/null +++ b/sp/src/public/bsptreedata.cpp @@ -0,0 +1,352 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Revision: $ +// $NoKeywords: $ +// +// The BSP tree leaf data system +// +//=============================================================================// + +#include "basetypes.h" +#include "bsptreedata.h" +#include "utllinkedlist.h" +#include "utlvector.h" +#include "tier0/dbg.h" +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// The BSP tree leaf data system +//----------------------------------------------------------------------------- +class CBSPTreeData : public IBSPTreeData, public ISpatialLeafEnumerator +{ +public: + // constructor, destructor + CBSPTreeData(); + virtual ~CBSPTreeData(); + + // Methods of IBSPTreeData + void Init( ISpatialQuery* pBSPTree ); + void Shutdown(); + + BSPTreeDataHandle_t Insert( int userId, Vector const& mins, Vector const& maxs ); + void Remove( BSPTreeDataHandle_t handle ); + void ElementMoved( BSPTreeDataHandle_t handle, Vector const& mins, Vector const& maxs ); + + // Enumerate elements in a particular leaf + bool EnumerateElementsInLeaf( int leaf, IBSPTreeDataEnumerator* pEnum, int context ); + + // For convenience, enumerates the leaves along a ray, box, etc. + bool EnumerateLeavesAtPoint( Vector const& pt, ISpatialLeafEnumerator* pEnum, int context ); + bool EnumerateLeavesInBox( Vector const& mins, Vector const& maxs, ISpatialLeafEnumerator* pEnum, int context ); + bool EnumerateLeavesInSphere( Vector const& center, float radius, ISpatialLeafEnumerator* pEnum, int context ); + bool EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, int context ); + + // methods of IBSPLeafEnumerator + bool EnumerateLeaf( int leaf, int context ); + + // Is the element in any leaves at all? + bool IsElementInTree( BSPTreeDataHandle_t handle ) const; + +private: + // Creates a new handle + BSPTreeDataHandle_t NewHandle( int userId ); + + // Adds a handle to the list of handles + void AddHandleToLeaf( int leaf, BSPTreeDataHandle_t handle ); + + // insert, remove handles from leaves + void InsertIntoTree( BSPTreeDataHandle_t handle, Vector const& mins, Vector const& maxs ); + void RemoveFromTree( BSPTreeDataHandle_t handle ); + + // Returns the number of elements in a leaf + int CountElementsInLeaf( int leaf ); + +private: + // All the information associated with a particular handle + struct HandleInfo_t + { + int m_UserId; // Client-defined id + unsigned short m_LeafList; // What leafs is it in? + }; + + // The leaf contains an index into a list of elements + struct Leaf_t + { + unsigned short m_FirstElement; + }; + + // The handle knows about the leaves it lies in + struct HandleInLeaf_t + { + int m_Leaf; // what leaf is the handle in? + unsigned short m_LeafElementIndex; // what's the m_LeafElements index of the entry? + }; + + // Stores data associated with each leaf. + CUtlVector< Leaf_t > m_Leaf; + + // Stores all unique handles + CUtlLinkedList< HandleInfo_t, unsigned short > m_Handles; + + // Maintains the list of all handles in a particular leaf + CUtlLinkedList< BSPTreeDataHandle_t, unsigned short, true > m_LeafElements; + + // Maintains the list of all leaves a particular handle spans + CUtlLinkedList< HandleInLeaf_t, unsigned short, true > m_HandleLeafList; + + // Interface to BSP tree + ISpatialQuery* m_pBSPTree; +}; + + +//----------------------------------------------------------------------------- +// Class factory +//----------------------------------------------------------------------------- + +IBSPTreeData* CreateBSPTreeData() +{ + return new CBSPTreeData; +} + +void DestroyBSPTreeData( IBSPTreeData* pTreeData ) +{ + if (pTreeData) + delete pTreeData; +} + + +//----------------------------------------------------------------------------- +// constructor, destructor +//----------------------------------------------------------------------------- + +CBSPTreeData::CBSPTreeData() +{ +} + +CBSPTreeData::~CBSPTreeData() +{ +} + + +//----------------------------------------------------------------------------- +// Level init, shutdown +//----------------------------------------------------------------------------- + +void CBSPTreeData::Init( ISpatialQuery* pBSPTree ) +{ + Assert( pBSPTree ); + m_pBSPTree = pBSPTree; + + m_Handles.EnsureCapacity( 1024 ); + m_LeafElements.EnsureCapacity( 1024 ); + m_HandleLeafList.EnsureCapacity( 1024 ); + + // Add all the leaves we'll need + int leafCount = m_pBSPTree->LeafCount(); + m_Leaf.EnsureCapacity( leafCount ); + + Leaf_t newLeaf; + newLeaf.m_FirstElement = m_LeafElements.InvalidIndex(); + while ( --leafCount >= 0 ) + { + m_Leaf.AddToTail( newLeaf ); + } +} + +void CBSPTreeData::Shutdown() +{ + m_Handles.Purge(); + m_LeafElements.Purge(); + m_HandleLeafList.Purge(); + m_Leaf.Purge(); +} + + +//----------------------------------------------------------------------------- +// Creates a new handle +//----------------------------------------------------------------------------- + +BSPTreeDataHandle_t CBSPTreeData::NewHandle( int userId ) +{ + BSPTreeDataHandle_t handle = m_Handles.AddToTail(); + m_Handles[handle].m_UserId = userId; + m_Handles[handle].m_LeafList = m_HandleLeafList.InvalidIndex(); + + return handle; +} + +//----------------------------------------------------------------------------- +// Add/remove handle +//----------------------------------------------------------------------------- + +BSPTreeDataHandle_t CBSPTreeData::Insert( int userId, Vector const& mins, Vector const& maxs ) +{ + BSPTreeDataHandle_t handle = NewHandle( userId ); + InsertIntoTree( handle, mins, maxs ); + return handle; +} + +void CBSPTreeData::Remove( BSPTreeDataHandle_t handle ) +{ + if (!m_Handles.IsValidIndex(handle)) + return; + + RemoveFromTree( handle ); + m_Handles.Free( handle ); +} + + +//----------------------------------------------------------------------------- +// Adds a handle to a leaf +//----------------------------------------------------------------------------- +void CBSPTreeData::AddHandleToLeaf( int leaf, BSPTreeDataHandle_t handle ) +{ + // Got to a leaf baby! Add the handle to the leaf's list of elements + unsigned short leafElement = m_LeafElements.Alloc( true ); + if (m_Leaf[leaf].m_FirstElement != m_LeafElements.InvalidIndex() ) + m_LeafElements.LinkBefore( m_Leaf[leaf].m_FirstElement, leafElement ); + m_Leaf[leaf].m_FirstElement = leafElement; + m_LeafElements[leafElement] = handle; + + // Insert the leaf into the handles's list of leaves + unsigned short handleElement = m_HandleLeafList.Alloc( true ); + if (m_Handles[handle].m_LeafList != m_HandleLeafList.InvalidIndex() ) + m_HandleLeafList.LinkBefore( m_Handles[handle].m_LeafList, handleElement ); + m_Handles[handle].m_LeafList = handleElement; + m_HandleLeafList[handleElement].m_Leaf = leaf; + m_HandleLeafList[handleElement].m_LeafElementIndex = leafElement; +} + + +//----------------------------------------------------------------------------- +// Inserts an element into the tree +//----------------------------------------------------------------------------- +bool CBSPTreeData::EnumerateLeaf( int leaf, int context ) +{ + BSPTreeDataHandle_t handle = (BSPTreeDataHandle_t)context; + AddHandleToLeaf( leaf, handle ); + return true; +} + +void CBSPTreeData::InsertIntoTree( BSPTreeDataHandle_t handle, Vector const& mins, Vector const& maxs ) +{ + m_pBSPTree->EnumerateLeavesInBox( mins, maxs, this, handle ); +} + +//----------------------------------------------------------------------------- +// Removes an element from the tree +//----------------------------------------------------------------------------- + +void CBSPTreeData::RemoveFromTree( BSPTreeDataHandle_t handle ) +{ + // Iterate over the list of all leaves the handle is in + unsigned short i = m_Handles[handle].m_LeafList; + while (i != m_HandleLeafList.InvalidIndex()) + { + int leaf = m_HandleLeafList[i].m_Leaf; + unsigned short leafElement = m_HandleLeafList[i].m_LeafElementIndex; + + // Unhook the handle from the leaf handle list + if (leafElement == m_Leaf[leaf].m_FirstElement) + m_Leaf[leaf].m_FirstElement = m_LeafElements.Next(leafElement); + m_LeafElements.Free(leafElement); + + unsigned short prevNode = i; + i = m_HandleLeafList.Next(i); + m_HandleLeafList.Free(prevNode); + } + + m_Handles[handle].m_LeafList = m_HandleLeafList.InvalidIndex(); +} + + +//----------------------------------------------------------------------------- +// Call this when the element moves +//----------------------------------------------------------------------------- +void CBSPTreeData::ElementMoved( BSPTreeDataHandle_t handle, Vector const& mins, Vector const& maxs ) +{ + if (handle != TREEDATA_INVALID_HANDLE) + { + RemoveFromTree( handle ); + InsertIntoTree( handle, mins, maxs ); + } +} + + +//----------------------------------------------------------------------------- +// Is the element in any leaves at all? +//----------------------------------------------------------------------------- +bool CBSPTreeData::IsElementInTree( BSPTreeDataHandle_t handle ) const +{ + return m_Handles[handle].m_LeafList != m_HandleLeafList.InvalidIndex(); +} + + +//----------------------------------------------------------------------------- +// Enumerate elements in a particular leaf +//----------------------------------------------------------------------------- +int CBSPTreeData::CountElementsInLeaf( int leaf ) +{ + int i; + int nCount = 0; + for( i = m_Leaf[leaf].m_FirstElement; i != m_LeafElements.InvalidIndex(); i = m_LeafElements.Next(i) ) + { + ++nCount; + } + + return nCount; +} + +//----------------------------------------------------------------------------- +// Enumerate elements in a particular leaf +//----------------------------------------------------------------------------- +bool CBSPTreeData::EnumerateElementsInLeaf( int leaf, IBSPTreeDataEnumerator* pEnum, int context ) +{ +#ifdef DBGFLAG_ASSERT + // The enumeration method better damn well not change this list... + int nCount = CountElementsInLeaf(leaf); +#endif + + unsigned short idx = m_Leaf[leaf].m_FirstElement; + while (idx != m_LeafElements.InvalidIndex()) + { + BSPTreeDataHandle_t handle = m_LeafElements[idx]; + if (!pEnum->EnumerateElement( m_Handles[handle].m_UserId, context )) + { + Assert( CountElementsInLeaf(leaf) == nCount ); + return false; + } + idx = m_LeafElements.Next(idx); + } + + Assert( CountElementsInLeaf(leaf) == nCount ); + + return true; +} + + +//----------------------------------------------------------------------------- +// For convenience, enumerates the leaves along a ray, box, etc. +//----------------------------------------------------------------------------- +bool CBSPTreeData::EnumerateLeavesAtPoint( Vector const& pt, ISpatialLeafEnumerator* pEnum, int context ) +{ + return m_pBSPTree->EnumerateLeavesAtPoint( pt, pEnum, context ); +} + +bool CBSPTreeData::EnumerateLeavesInBox( Vector const& mins, Vector const& maxs, ISpatialLeafEnumerator* pEnum, int context ) +{ + return m_pBSPTree->EnumerateLeavesInBox( mins, maxs, pEnum, context ); +} + +bool CBSPTreeData::EnumerateLeavesInSphere( Vector const& center, float radius, ISpatialLeafEnumerator* pEnum, int context ) +{ + return m_pBSPTree->EnumerateLeavesInSphere( center, radius, pEnum, context ); +} + +bool CBSPTreeData::EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, int context ) +{ + return m_pBSPTree->EnumerateLeavesAlongRay( ray, pEnum, context ); +} + diff --git a/sp/src/public/bsptreedata.h b/sp/src/public/bsptreedata.h new file mode 100644 index 00000000..2132dfbf --- /dev/null +++ b/sp/src/public/bsptreedata.h @@ -0,0 +1,136 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Revision: $ +// $NoKeywords: $ +// +// The BSP tree leaf data system +// +//=============================================================================// + +#include "tier0/platform.h" + +#if !defined( BSPTREEDATA ) +#define BSPTREEDATA +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- + +class Vector; +struct Ray_t; + + +//----------------------------------------------------------------------------- +// Handle to an renderable in the client leaf system +//----------------------------------------------------------------------------- + +typedef unsigned short BSPTreeDataHandle_t; + +enum +{ + TREEDATA_INVALID_HANDLE = (BSPTreeDataHandle_t)~0 +}; + + +//----------------------------------------------------------------------------- +// Interface needed by tree data to do its job +// +// Note that anything that has convex spatial regions with leaves identified +// by indices can implement the ISpatialQuery. All you have to do is to implement +// a class that can answer the 5 questions in the Query interface about the +// spatial subdivision. For example, a K-D tree or a BSP tree could implement +// this interface +// +//----------------------------------------------------------------------------- + +abstract_class ISpatialLeafEnumerator +{ +public: + // call back with a leaf and a context + // The context is completely user defined; it's passed into the enumeration + // function of ISpatialQuery. + // This gets called by the enumeration methods with each leaf + // that passes the test; return true to continue enumerating, + // false to stop + + virtual bool EnumerateLeaf( int leaf, int context ) = 0; +}; + +abstract_class ISpatialQuery +{ +public: + // Returns the number of leaves + virtual int LeafCount() const = 0; + + // Enumerates the leaves along a ray, box, etc. + virtual bool EnumerateLeavesAtPoint( Vector const& pt, ISpatialLeafEnumerator* pEnum, int context ) = 0; + virtual bool EnumerateLeavesInBox( Vector const& mins, Vector const& maxs, ISpatialLeafEnumerator* pEnum, int context ) = 0; + virtual bool EnumerateLeavesInSphere( Vector const& center, float radius, ISpatialLeafEnumerator* pEnum, int context ) = 0; + virtual bool EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, int context ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Data associated with leaves. +// +// This is a parasitic class that attaches data to the leaves specified by the +// ISpatialQuery sent in to the initialization function. It can't exist without +// a spatial partition of some sort to hold onto. +//----------------------------------------------------------------------------- + +abstract_class IBSPTreeDataEnumerator +{ +public: + // call back with a userId and a context + virtual bool FASTCALL EnumerateElement( int userId, int context ) = 0; +}; + +abstract_class IBSPTreeData +{ +public: + // Add a virtual destructor so that the derived class destructors will + // be called. + virtual ~IBSPTreeData() {} + + // Initializes, shuts down + virtual void Init( ISpatialQuery* pBSPTree ) = 0; + virtual void Shutdown() = 0; + + // Adds and removes data from the leaf lists + virtual BSPTreeDataHandle_t Insert( int userId, Vector const& mins, Vector const& maxs ) = 0; + virtual void Remove( BSPTreeDataHandle_t handle ) = 0; + + // Call this when a element moves + virtual void ElementMoved( BSPTreeDataHandle_t handle, Vector const& mins, Vector const& maxs ) = 0; + + // Enumerate elements in a particular leaf + virtual bool EnumerateElementsInLeaf( int leaf, IBSPTreeDataEnumerator* pEnum, int context ) = 0; + + // Is the element in any leaves at all? + virtual bool IsElementInTree( BSPTreeDataHandle_t handle ) const = 0; + + // NOTE: These methods call through to the functions in the attached + // ISpatialQuery + // For convenience, enumerates the leaves along a ray, box, etc. + virtual bool EnumerateLeavesAtPoint( Vector const& pt, ISpatialLeafEnumerator* pEnum, int context ) = 0; + virtual bool EnumerateLeavesInBox( Vector const& mins, Vector const& maxs, ISpatialLeafEnumerator* pEnum, int context ) = 0; + virtual bool EnumerateLeavesInSphere( Vector const& center, float radius, ISpatialLeafEnumerator* pEnum, int context ) = 0; + virtual bool EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, int context ) = 0; +}; + +//----------------------------------------------------------------------------- +// Class factory +//----------------------------------------------------------------------------- + +IBSPTreeData* CreateBSPTreeData(); +void DestroyBSPTreeData( IBSPTreeData* pTreeData ); + + +#endif // BSPTREEDATA + + diff --git a/sp/src/public/builddisp.cpp b/sp/src/public/builddisp.cpp new file mode 100644 index 00000000..9f821829 --- /dev/null +++ b/sp/src/public/builddisp.cpp @@ -0,0 +1,3116 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//=============================================================================// + +//#include +#include +#include +#include "builddisp.h" +#include "collisionutils.h" +#include "tier1/strtools.h" +#include "tier0/dbg.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// +// Node Functions (friend functions) +// + +//----------------------------------------------------------------------------- +// should make this more programatic and extensible! +//----------------------------------------------------------------------------- +int GetNodeLevel( int index ) +{ + // root + if( index == 0 ) + return 1; + + // [1...4] + if( index < 5 ) + return 2; + + // [5....20] + if( index < 21 ) + return 3; + + // [21....84] + if( index < 85 ) + return 4; + + // error!!! + return -1; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int GetNodeCount( int power ) +{ + return ( ( 1 << ( power << 1 ) ) / 3 ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int GetNodeParent( int index ) +{ + // ( index - 1 ) / 4 + return ( ( index - 1 ) >> 2 ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int GetNodeChild( int power, int index, int direction ) +{ + // ( index * 4 ) + direction + return ( ( index << 2 ) + ( direction - 3 ) ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int GetNodeMinNodeAtLevel( int level ) +{ + switch( level ) + { + case 1: return 0; + case 2: return 1; + case 3: return 5; + case 4: return 21; + default: return -99999; + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void GetComponentsFromNodeIndex( int index, int *x, int *y ) +{ + *x = 0; + *y = 0; + + for( int shift = 0; index != 0; shift++ ) + { + *x |= ( index & 1 ) << shift; + index >>= 1; + + *y |= ( index & 1 ) << shift; + index >>= 1; + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int GetNodeIndexFromComponents( int x, int y ) +{ + int index = 0; + + // Interleave bits from the x and y values to create the index: + + int shift; + for( shift = 0; x != 0; shift += 2, x >>= 1 ) + { + index |= ( x & 1 ) << shift; + } + + for( shift = 1; y != 0; shift += 2, y >>= 1 ) + { + index |= ( y & 1 ) << shift; + } + + return index; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool CalcBarycentricCooefs( Vector const &v0, Vector const &v1, Vector const &v2, + Vector const &pt, float &c0, float &c1, float &c2 ) +{ + Vector vSeg0, vSeg1, vCross; + vSeg0 = v1 - v0; + vSeg1 = v2 - v0; + + // get the area of the triangle + vCross = vSeg0.Cross( vSeg1 ); + float totalArea = vCross.Length() * 0.5f; + float ooTotalArea = totalArea ? 1.0f / totalArea : 0.0f; + + // get the area for cooeficient 0 (pt, v1, v2) + vSeg0 = v1 - pt; + vSeg1 = v2 - pt; + vCross = vSeg0.Cross( vSeg1 ); + float subArea = vCross.Length() * 0.5f; + c0 = subArea * ooTotalArea; + + // get the area for cooeficient 1 (v0, pt, v2) + vSeg0 = v2 - pt; + vSeg1 = v0 - pt; + vCross = vSeg0.Cross( vSeg1 ); + subArea = vCross.Length() * 0.5f; + c1 = subArea * ooTotalArea; + + // get the area for cooeficient 2 (v0, v1, pt) + vSeg0 = v0 - pt; + vSeg1 = v1 - pt; + vCross = vSeg0.Cross( vSeg1 ); + subArea = vCross.Length() * 0.5f; + c2 = subArea * ooTotalArea; + + float cTotal = c0 + c1 + c2; + if ( FloatMakePositive( 1.0f - cTotal ) < 1e-3 ) + return true; + + return false; +} + +// For some reason, the global optimizer screws up the recursion here. disable the global optimizations to fix this. +// IN VC++ 6.0 +#pragma optimize( "g", off ) + +CCoreDispSurface::CCoreDispSurface() +{ + Init(); +} + + +//============================================================================= +// +// CDispSurface Functions +// + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispSurface::Init( void ) +{ + m_Index = -1; + + m_PointCount = 0; + int i; + for( i = 0; i < QUAD_POINT_COUNT; i++ ) + { + VectorClear( m_Points[i] ); + VectorClear( m_Normals[i] ); + Vector2DClear( m_TexCoords[i] ); + + for( int j = 0; j < NUM_BUMP_VECTS+1; j++ ) + { + Vector2DClear( m_LuxelCoords[i][j] ); + } + + m_Alphas[i] = 1.0f; + } + + m_PointStartIndex = -1; + VectorClear( m_PointStart ); + VectorClear( sAxis ); + VectorClear( tAxis ); + + for( i = 0; i < 4; i++ ) + { + m_EdgeNeighbors[i].SetInvalid(); + m_CornerNeighbors[i].SetInvalid(); + } + + m_Flags = 0; + m_Contents = 0; +} + + +void CCoreDispSurface::SetNeighborData( const CDispNeighbor edgeNeighbors[4], const CDispCornerNeighbors cornerNeighbors[4] ) +{ + for ( int i=0; i < 4; i++ ) + { + m_EdgeNeighbors[i] = edgeNeighbors[i]; + m_CornerNeighbors[i] = cornerNeighbors[i]; + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispSurface::GeneratePointStartIndexFromMappingAxes( Vector const &sAxis, Vector const &tAxis ) +{ + if( m_PointStartIndex != -1 ) + return; + + int numIndices = 0; + int indices[4]; + int offsetIndex; + + // + // project all points on to the v-axis first and find the minimum + // + float minValue = DotProduct( tAxis, m_Points[0] ); + indices[numIndices] = 0; + numIndices++; + + int i; + for( i = 1; i < m_PointCount; i++ ) + { + float value = DotProduct( tAxis, m_Points[i] ); + float delta = ( value - minValue ); + delta = FloatMakePositive( delta ); + if( delta < 0.1 ) + { + indices[numIndices] = i; + numIndices++; + } + else if( value < minValue ) + { + minValue = value; + indices[0] = i; + numIndices = 1; + } + } + + // + // break ties with the u-axis projection + // + minValue = DotProduct( sAxis, m_Points[indices[0]] ); + offsetIndex = indices[0]; + + for( i = 1; i < numIndices; i++ ) + { + float value = DotProduct( sAxis, m_Points[indices[i]] ); + if( ( value < minValue ) ) + { + minValue = value; + offsetIndex = indices[i]; + } + } + + m_PointStartIndex = offsetIndex; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CCoreDispSurface::GenerateSurfPointStartIndex( void ) +{ + // + // get the minimum surface component values + // + Vector bMin; + VectorFill( bMin, 99999.0f ); + + int i; + for( i = 0; i < QUAD_POINT_COUNT; i++ ) + { + for( int j = 0; j < 3; j++ ) + { + if( m_Points[i][j] < bMin[j] ) + { + bMin[j] = m_Points[i][j]; + } + } + } + + // + // find the point closest to the minimum, that is the start point + // + int minIndex = -1; + float minDistance = 999999999.0f; + for( i = 0; i < QUAD_POINT_COUNT; i++ ) + { + Vector segment; + segment = m_Points[i] - bMin; + float distanceSq = segment.LengthSqr(); + if( distanceSq < minDistance ) + { + minDistance = distanceSq; + minIndex = i; + } + } + + m_PointStartIndex = minIndex; + + return minIndex; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CCoreDispSurface::FindSurfPointStartIndex( void ) +{ + if( m_PointStartIndex != -1 ) + return m_PointStartIndex; + + int minIndex = -1; + float minDistance = 999999999.0f; + + for( int i = 0; i < QUAD_POINT_COUNT; i++ ) + { + Vector segment; + VectorSubtract( m_PointStart, m_Points[i], segment ); + float distanceSq = segment.LengthSqr(); + if( distanceSq < minDistance ) + { + minDistance = distanceSq; + minIndex = i; + } + } + + m_PointStartIndex = minIndex; + + return minIndex; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispSurface::AdjustSurfPointData( void ) +{ + Vector tmpPoints[4]; + Vector tmpNormals[4]; + Vector2D tmpTexCoords[4]; + float tmpAlphas[4]; + + int i; + for( i = 0; i < QUAD_POINT_COUNT; i++ ) + { + VectorCopy( m_Points[i], tmpPoints[i] ); + VectorCopy( m_Normals[i], tmpNormals[i] ); + Vector2DCopy( m_TexCoords[i], tmpTexCoords[i] ); + + tmpAlphas[i] = m_Alphas[i]; + } + + for( i = 0; i < QUAD_POINT_COUNT; i++ ) + { + VectorCopy( tmpPoints[(i+m_PointStartIndex)%4], m_Points[i] ); + VectorCopy( tmpNormals[(i+m_PointStartIndex)%4], m_Normals[i] ); + Vector2DCopy( tmpTexCoords[(i+m_PointStartIndex)%4], m_TexCoords[i] ); + + m_Alphas[i] = tmpAlphas[i]; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CCoreDispSurface::LongestInU( const Vector &vecU, const Vector &vecV ) +{ + Vector vecNormU = vecU; + Vector vecNormV = vecV; + VectorNormalize( vecNormU ); + VectorNormalize( vecNormV ); + + float flDistU[4]; + float flDistV[4]; + for ( int iPoint = 0; iPoint < 4; ++iPoint ) + { + flDistU[iPoint] = vecNormU.Dot( m_Points[iPoint] ); + flDistV[iPoint] = vecNormV.Dot( m_Points[iPoint] ); + } + + float flULength = 0.0f; + float flVLength = 0.0f; + for ( int iPoint = 0; iPoint < 4; ++iPoint ) + { + float flTestDist = fabs( flDistU[(iPoint+1)%4] - flDistU[iPoint] ); + if ( flTestDist > flULength ) + { + flULength = flTestDist; + } + + flTestDist = fabs( flDistV[(iPoint+1)%4] - flDistV[iPoint] ); + if ( flTestDist > flVLength ) + { + flVLength = flTestDist; + } + } + + if ( flULength < flVLength ) + { + return false; + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : - +//----------------------------------------------------------------------------- +bool CCoreDispSurface::CalcLuxelCoords( int nLuxels, bool bAdjust, const Vector &vecU, const Vector &vecV ) +{ + // Valid value? + if ( nLuxels <= 0.0f ) + return false; + + // Get the start point offset. + int iOffset = 0; + if ( bAdjust ) + { + iOffset = GetPointStartIndex(); + } + + // Does projecting along U or V create the longest edge? + bool bLongU = LongestInU( vecU, vecV ); + + float flLengthTemp = 0.0f; + float flULength = ( m_Points[(3+iOffset)%4] - m_Points[(0+iOffset)%4] ).Length(); + flLengthTemp = ( m_Points[(2+iOffset)%4] - m_Points[(1+iOffset)%4] ).Length(); + if ( flLengthTemp > flULength ) + { + flULength = flLengthTemp; + } + + // Find the largest edge in V. + float flVLength = ( m_Points[(1+iOffset)%4] - m_Points[(0+iOffset)%4] ).Length(); + flLengthTemp = ( m_Points[(2+iOffset)%4] - m_Points[(3+iOffset)%4] ).Length(); + if ( flLengthTemp > flVLength ) + { + flVLength = flLengthTemp; + } + + float flOOLuxelScale = 1.0f / static_cast( nLuxels ); + float flUValue = static_cast( static_cast( flULength * flOOLuxelScale ) + 1 ); + if ( flUValue > MAX_DISP_LIGHTMAP_DIM_WITHOUT_BORDER ) + { + flUValue = MAX_DISP_LIGHTMAP_DIM_WITHOUT_BORDER; + } + + float flVValue = static_cast( static_cast( flVLength * flOOLuxelScale ) + 1 ); + if ( flVValue > MAX_DISP_LIGHTMAP_DIM_WITHOUT_BORDER ) + { + flVValue = MAX_DISP_LIGHTMAP_DIM_WITHOUT_BORDER; + } + + // Swap if necessary. + bool bSwapped = false; + if ( bLongU ) + { + if ( flVValue > flUValue ) + { + bSwapped = true; + } + } + else + { + if ( flUValue > flVValue ) + { + bSwapped = true; + } + } + + m_nLuxelU = static_cast( flUValue ); + m_nLuxelV = static_cast( flVValue ); + + // Generate luxel coordinates. + for( int iBump = 0; iBump < NUM_BUMP_VECTS+1; ++iBump ) + { + m_LuxelCoords[iBump][(0+iOffset)%4].Init( 0.5f, 0.5f ); + m_LuxelCoords[iBump][(1+iOffset)%4].Init( 0.5f, flVValue + 0.5 ); + m_LuxelCoords[iBump][(2+iOffset)%4].Init( flUValue + 0.5, flVValue + 0.5 ); + m_LuxelCoords[iBump][(3+iOffset)%4].Init( flUValue + 0.5, 0.5f ); + } + + return bSwapped; +} + +//============================================================================= +// +// CDispNode Functions +// + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispNode::Init( void ) +{ + VectorClear( m_BBox[0] ); + VectorClear( m_BBox[1] ); + + m_ErrorTerm = 0.0f; + + m_VertIndex = -1; + + int j; + for( j = 0; j < MAX_NEIGHBOR_NODE_COUNT; j++ ) + { + m_NeighborVertIndices[j] = -1; + } + + for( j = 0; j < MAX_SURF_AT_NODE_COUNT; j++ ) + { + VectorClear( m_SurfBBoxes[j][0] ); + VectorClear( m_SurfBBoxes[j][1] ); + VectorClear( m_SurfPlanes[j].normal ); + m_SurfPlanes[j].dist = 0.0f; + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void GetDispNodeTriVerts( CCoreDispInfo *pDisp, int nodeIndex, int triIndex, Vector& v1, Vector& v2, Vector& v3 ) +{ + // get the node + CCoreDispNode *pNode = pDisp->GetNode( nodeIndex ); + + switch( triIndex ) + { + case 0: + { + pDisp->GetVert( pNode->GetNeighborVertIndex( 4 ), v1 ); + pDisp->GetVert( pNode->GetNeighborVertIndex( 0 ), v2 ); + pDisp->GetVert( pNode->GetNeighborVertIndex( 3 ), v3 ); + return; + } + case 1: + { + pDisp->GetVert( pNode->GetNeighborVertIndex( 3 ), v1 ); + pDisp->GetVert( pNode->GetNeighborVertIndex( 0 ), v2 ); + pDisp->GetVert( pNode->GetCenterVertIndex(), v3 ); + return; + } + case 2: + { + pDisp->GetVert( pNode->GetNeighborVertIndex( 3 ), v1 ); + pDisp->GetVert( pNode->GetCenterVertIndex(), v2 ); + pDisp->GetVert( pNode->GetNeighborVertIndex( 5 ), v3 ); + return; + } + case 3: + { + pDisp->GetVert( pNode->GetNeighborVertIndex( 5 ), v1 ); + pDisp->GetVert( pNode->GetCenterVertIndex(), v2 ); + pDisp->GetVert( pNode->GetNeighborVertIndex( 2 ), v3 ); + return; + } + case 4: + { + pDisp->GetVert( pNode->GetNeighborVertIndex( 0 ), v1 ); + pDisp->GetVert( pNode->GetNeighborVertIndex( 6 ), v2 ); + pDisp->GetVert( pNode->GetCenterVertIndex(), v3 ); + return; + } + case 5: + { + pDisp->GetVert( pNode->GetCenterVertIndex(), v1 ); + pDisp->GetVert( pNode->GetNeighborVertIndex( 6 ), v2 ); + pDisp->GetVert( pNode->GetNeighborVertIndex( 1 ), v3 ); + return; + } + case 6: + { + pDisp->GetVert( pNode->GetCenterVertIndex(), v1 ); + pDisp->GetVert( pNode->GetNeighborVertIndex( 1 ), v2 ); + pDisp->GetVert( pNode->GetNeighborVertIndex( 2 ), v3 ); + return; + } + case 7: + { + pDisp->GetVert( pNode->GetNeighborVertIndex( 2 ), v1 ); + pDisp->GetVert( pNode->GetNeighborVertIndex( 1 ), v2 ); + pDisp->GetVert( pNode->GetNeighborVertIndex( 7 ), v3 ); + return; + } + default: { return; } + } +} + + +//============================================================================= +// +// CCoreDispInfo Functions +// + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +CCoreDispInfo::CCoreDispInfo() +{ + m_pVerts = NULL; + m_RenderIndices = NULL; + m_Nodes = NULL; + m_pTris = NULL; + + // initialize the base surface data + m_Surf.Init(); + + // + // initialize the disp info + // + m_Power = 0; + m_Elevation = 0.0f; + m_RenderIndexCount = 0; + m_RenderCounter = 0; + m_bTouched = false; + + m_pNext = NULL; + + m_ppListBase = NULL; + m_ListSize = 0; + m_nListIndex = -1; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +CCoreDispInfo::~CCoreDispInfo() +{ + if (m_pVerts) + delete [] m_pVerts; + if (m_RenderIndices) + delete [] m_RenderIndices; + if (m_Nodes) + delete [] m_Nodes; + if (m_pTris) + delete [] m_pTris; +} + + +#if 0 +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::InitSurf( int parentIndex, Vector points[4], Vector normals[4], + Vector2D texCoords[4], Vector2D lightCoords[4][4], int contents, int flags, + bool bGenerateSurfPointStart, Vector& startPoint, + bool bHasMappingAxes, Vector& uAxis, Vector& vAxis ) +{ + // save the "parent" index + m_Surf.m_Index = parentIndex; + + // + // save the surface points and point normals, texture coordinates, and + // lightmap coordinates + // + m_Surf.m_PointCount = CSurface::QUAD_POINT_COUNT; + for( int i = 0; i < CSurface::QUAD_POINT_COUNT; i++ ) + { + VectorCopy( points[i], m_Surf.m_Points[i] ); + + if( normals ) + { + VectorCopy( normals[i], m_Surf.m_pVerts[i].m_Normal ); + } + + if( texCoords ) + { + Vector2DCopy( texCoords[i], m_Surf.m_TexCoords[i] ); + } + + if( lightCoords ) + { + Assert( NUM_BUMP_VECTS == 3 ); + Vector2DCopy( lightCoords[0][i], m_Surf.m_LightCoords[i][0] ); + Vector2DCopy( lightCoords[1][i], m_Surf.m_LightCoords[i][1] ); + Vector2DCopy( lightCoords[2][i], m_Surf.m_LightCoords[i][2] ); + Vector2DCopy( lightCoords[3][i], m_Surf.m_LightCoords[i][3] ); + } + } + + // save the starting point + if( startPoint ) + { + VectorCopy( startPoint, m_Surf.m_PointStart ); + } + + // + // save the surface contents and flags + // + m_Contents = contents; + m_Flags = flags; + + // + // adjust surface points, texture coordinates, etc.... + // + if( bHasMappingAxes && ( m_Surf.m_PointStartIndex == -1 ) ) + { + GeneratePointStartIndexFromMappingAxes( uAxis, vAxis ); + } + else + { + // + // adjust the surf data + // + if( bGenerateSurfPointStart ) + { + GenerateSurfPointStartIndex(); + } + else + { + FindSurfPointStartIndex(); + } + } + + AdjustSurfPointData(); +} +#endif + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::InitDispInfo( int power, int minTess, float smoothingAngle, + float *alphas, Vector *dispVectorField, float *dispDistances ) +{ + Assert( power >= MIN_MAP_DISP_POWER && power <= MAX_MAP_DISP_POWER ); + + // + // general displacement data + // + m_Power = power; + + if ( ( minTess & 0x80000000 ) != 0 ) + { + // If the high bit is set, this represents FLAGS (SURF_NOPHYSICS_COLL, etc.) flags. + int nFlags = minTess; + nFlags &= ~0x80000000; + GetSurface()->SetFlags( nFlags ); + } + + // Allocate + initialize verts + int size = GetSize(); + m_pVerts = new CoreDispVert_t[size]; + + int nIndexCount = size * 2 * 3; + m_RenderIndices = new unsigned short[nIndexCount]; + + int nNodeCount = GetNodeCount(power); + m_Nodes = new CCoreDispNode[nNodeCount]; + + int i; + for( i = 0; i < size; i++ ) + { + m_pVerts[i].m_FieldVector.Init(); + m_pVerts[i].m_SubdivPos.Init(); + m_pVerts[i].m_SubdivNormal.Init(); + + m_pVerts[i].m_FieldDistance = 0.0f; + + m_pVerts[i].m_Vert.Init(); + m_pVerts[i].m_FlatVert.Init(); + m_pVerts[i].m_Normal.Init(); + m_pVerts[i].m_TangentS.Init(); + m_pVerts[i].m_TangentT.Init(); + m_pVerts[i].m_TexCoord.Init(); + + for( int j = 0; j < ( NUM_BUMP_VECTS + 1 ); j++ ) + { + m_pVerts[i].m_LuxelCoords[j].Init(); + } + + m_pVerts[i].m_Alpha = 0.0f; + } + + for( i = 0; i < nIndexCount; i++ ) + { + m_RenderIndices[i] = 0; + } + + for( i = 0; i < nNodeCount; i++ ) + { + m_Nodes[i].Init(); + } + + // + // save the displacement vector field and distances within the field + // offset have been combined with fieldvectors at this point!!! + // + if (alphas && dispVectorField && dispDistances) + { + for( i = 0; i < size; i++ ) + { + VectorCopy( dispVectorField[i], m_pVerts[i].m_FieldVector ); + m_pVerts[i].m_FieldDistance = dispDistances[i]; + m_pVerts[i].m_Alpha = alphas[i]; + } + } + + // Init triangle information. + int nTriCount = GetTriCount(); + if ( nTriCount != 0 ) + { + m_pTris = new CoreDispTri_t[nTriCount]; + if ( m_pTris ) + { + InitTris(); + } + } +} + + +void CCoreDispInfo::InitDispInfo( int power, int minTess, float smoothingAngle, const CDispVert *pVerts, + const CDispTri *pTris ) +{ + Vector vectors[MAX_DISPVERTS]; + float dists[MAX_DISPVERTS]; + float alphas[MAX_DISPVERTS]; + + int nVerts = NUM_DISP_POWER_VERTS( power ); + for ( int i=0; i < nVerts; i++ ) + { + vectors[i] = pVerts[i].m_vVector; + dists[i] = pVerts[i].m_flDist; + alphas[i] = pVerts[i].m_flAlpha; + } + + InitDispInfo( power, minTess, smoothingAngle, alphas, vectors, dists ); + + int nTris = NUM_DISP_POWER_TRIS( power ); + for ( int iTri = 0; iTri < nTris; ++iTri ) + { + m_pTris[iTri].m_uiTags = pTris[iTri].m_uiTags; + } +} + + +void CCoreDispInfo::SetDispUtilsHelperInfo( CCoreDispInfo **ppListBase, int listSize ) +{ + m_ppListBase = ppListBase; + m_ListSize = listSize; +} + +const CPowerInfo* CCoreDispInfo::GetPowerInfo() const +{ + return ::GetPowerInfo( GetPower() ); +} + +CDispNeighbor* CCoreDispInfo::GetEdgeNeighbor( int index ) +{ + return GetSurface()->GetEdgeNeighbor( index ); +} + +CDispCornerNeighbors* CCoreDispInfo::GetCornerNeighbors( int index ) +{ + return GetSurface()->GetCornerNeighbors( index ); +} + +CDispUtilsHelper* CCoreDispInfo::GetDispUtilsByIndex( int index ) +{ + Assert( m_ppListBase ); + return index == 0xFFFF ? 0 : m_ppListBase[index]; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::BuildTriTLtoBR( int ndx ) +{ + // get width and height of displacement maps + int nWidth = ( ( 1 << m_Power ) + 1 ); + + m_RenderIndices[m_RenderIndexCount] = ndx; + m_RenderIndices[m_RenderIndexCount+1] = ndx + nWidth; + m_RenderIndices[m_RenderIndexCount+2] = ndx + 1; + m_RenderIndexCount += 3; + + m_RenderIndices[m_RenderIndexCount] = ndx + 1; + m_RenderIndices[m_RenderIndexCount+1] = ndx + nWidth; + m_RenderIndices[m_RenderIndexCount+2] = ndx + nWidth + 1; + m_RenderIndexCount += 3; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::BuildTriBLtoTR( int ndx ) +{ + // get width and height of displacement maps + int nWidth = ( ( 1 << m_Power ) + 1 ); + + m_RenderIndices[m_RenderIndexCount] = ndx; + m_RenderIndices[m_RenderIndexCount+1] = ndx + nWidth; + m_RenderIndices[m_RenderIndexCount+2] = ndx + nWidth + 1; + m_RenderIndexCount += 3; + + m_RenderIndices[m_RenderIndexCount] = ndx; + m_RenderIndices[m_RenderIndexCount+1] = ndx + nWidth + 1; + m_RenderIndices[m_RenderIndexCount+2] = ndx + 1; + m_RenderIndexCount += 3; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::GenerateCollisionSurface( void ) +{ + // get width and height of displacement maps + int nWidth = ( ( 1 << m_Power ) + 1 ); + int nHeight = ( ( 1 << m_Power ) + 1 ); + + // + // generate a fan tesselated (at quadtree node) rendering index list + // + m_RenderIndexCount = 0; + for ( int iV = 0; iV < ( nHeight - 1 ); iV++ ) + { + for ( int iU = 0; iU < ( nWidth - 1 ); iU++ ) + { + int ndx = ( iV * nWidth ) + iU; + + // test whether or not the index is odd + bool bOdd = ( ( ndx %2 ) == 1 ); + + // Top Left to Bottom Right + if( bOdd ) + { + BuildTriTLtoBR( ndx ); + } + // Bottom Left to Top Right + else + { + BuildTriBLtoTR( ndx ); + } + } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::GenerateCollisionData( void ) +{ + GenerateCollisionSurface(); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::CalcTriSurfPlanes( int nodeIndex, int indices[8][3] ) +{ + // + // calculate plane info for each face + // + for( int i = 0; i < 8; i++ ) + { + Vector v[3]; + VectorCopy( m_pVerts[indices[i][0]].m_Vert, v[0] ); + VectorCopy( m_pVerts[indices[i][1]].m_Vert, v[1] ); + VectorCopy( m_pVerts[indices[i][2]].m_Vert, v[2] ); + + Vector seg[2]; + VectorSubtract( v[1], v[0], seg[0] ); + VectorSubtract( v[2], v[0], seg[1] ); + + Vector normal; + CrossProduct( seg[1], seg[0], normal ); + VectorNormalize( normal ); + float dist = DotProduct( v[0], normal ); + + m_Nodes[nodeIndex].SetTriPlane( i, normal, dist ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::CalcRayBoundingBoxes( int nodeIndex, int indices[8][3] ) +{ + Vector triMin, triMax; + + for( int i = 0; i < 4; i++ ) + { + triMin[0] = triMax[0] = m_pVerts[indices[(i*2)][0]].m_Vert[0]; + triMin[1] = triMax[1] = m_pVerts[indices[(i*2)][0]].m_Vert[1]; + triMin[2] = triMax[2] = m_pVerts[indices[(i*2)][0]].m_Vert[2]; + + for( int j = 0; j < 3; j++ ) + { + // + // minimum + // + if( triMin[0] > m_pVerts[indices[(i*2)][j]].m_Vert[0] ) + triMin[0] = m_pVerts[indices[(i*2)][j]].m_Vert[0]; + if( triMin[0] > m_pVerts[indices[(i*2+1)][j]].m_Vert[0] ) + triMin[0] = m_pVerts[indices[(i*2+1)][j]].m_Vert[0]; + + if( triMin[1] > m_pVerts[indices[(i*2)][j]].m_Vert[1] ) + triMin[1] = m_pVerts[indices[(i*2)][j]].m_Vert[1]; + if( triMin[1] > m_pVerts[indices[(i*2+1)][j]].m_Vert[1] ) + triMin[1] = m_pVerts[indices[(i*2+1)][j]].m_Vert[1]; + + if( triMin[2] > m_pVerts[indices[(i*2)][j]].m_Vert[2] ) + triMin[2] = m_pVerts[indices[(i*2)][j]].m_Vert[2]; + if( triMin[2] > m_pVerts[indices[(i*2+1)][j]].m_Vert[2] ) + triMin[2] = m_pVerts[indices[(i*2+1)][j]].m_Vert[2]; + + // + // maximum + // + if( triMax[0] < m_pVerts[indices[(i*2)][j]].m_Vert[0] ) + triMax[0] = m_pVerts[indices[(i*2)][j]].m_Vert[0]; + if( triMax[0] < m_pVerts[indices[(i*2+1)][j]].m_Vert[0] ) + triMax[0] = m_pVerts[indices[(i*2+1)][j]].m_Vert[0]; + + if( triMax[1] < m_pVerts[indices[(i*2)][j]].m_Vert[1] ) + triMax[1] = m_pVerts[indices[(i*2)][j]].m_Vert[1]; + if( triMax[1] < m_pVerts[indices[(i*2+1)][j]].m_Vert[1] ) + triMax[1] = m_pVerts[indices[(i*2+1)][j]].m_Vert[1]; + + if( triMax[2] < m_pVerts[indices[(i*2)][j]].m_Vert[2] ) + triMax[2] = m_pVerts[indices[(i*2)][j]].m_Vert[2]; + if( triMax[2] < m_pVerts[indices[(i*2+1)][j]].m_Vert[2] ) + triMax[2] = m_pVerts[indices[(i*2+1)][j]].m_Vert[2]; + } + + m_Nodes[nodeIndex].SetRayBoundingBox( i, triMin, triMax ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::CalcTriSurfBoundingBoxes( int nodeIndex, int indices[8][3] ) +{ + Vector triMin, triMax; + + for( int i = 0; i < 8; i++ ) + { + m_Nodes[nodeIndex].GetTriBoundingBox( i, triMin, triMax ); + + for( int j = 0; j < 3; j++ ) + { + // + // minimum + // + if( triMin[0] > m_pVerts[indices[i][j]].m_Vert[0] ) + triMin[0] = m_pVerts[indices[i][j]].m_Vert[0]; + + if( triMin[1] > m_pVerts[indices[i][j]].m_Vert[1] ) + triMin[1] = m_pVerts[indices[i][j]].m_Vert[1]; + + if( triMin[2] > m_pVerts[indices[i][j]].m_Vert[2] ) + triMin[2] = m_pVerts[indices[i][j]].m_Vert[2]; + + // + // maximum + // + if( triMax[0] < m_pVerts[indices[i][j]].m_Vert[0] ) + triMax[0] = m_pVerts[indices[i][j]].m_Vert[0]; + + if( triMax[1] < m_pVerts[indices[i][j]].m_Vert[1] ) + triMax[1] = m_pVerts[indices[i][j]].m_Vert[1]; + + if( triMax[2] < m_pVerts[indices[i][j]].m_Vert[2] ) + triMax[2] = m_pVerts[indices[i][j]].m_Vert[2]; + } + + m_Nodes[nodeIndex].SetTriBoundingBox( i, triMin, triMax ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::CalcTriSurfIndices( int nodeIndex, int indices[8][3] ) +{ + indices[0][0] = m_Nodes[nodeIndex].GetNeighborVertIndex( 4 ); + indices[0][1] = m_Nodes[nodeIndex].GetNeighborVertIndex( 0 ); + indices[0][2] = m_Nodes[nodeIndex].GetNeighborVertIndex( 3 ); + + indices[1][0] = m_Nodes[nodeIndex].GetNeighborVertIndex( 3 ); + indices[1][1] = m_Nodes[nodeIndex].GetNeighborVertIndex( 0 ); + indices[1][2] = m_Nodes[nodeIndex].GetCenterVertIndex(); + + indices[2][0] = m_Nodes[nodeIndex].GetNeighborVertIndex( 3 ); + indices[2][1] = m_Nodes[nodeIndex].GetCenterVertIndex(); + indices[2][2] = m_Nodes[nodeIndex].GetNeighborVertIndex( 5 ); + + indices[3][0] = m_Nodes[nodeIndex].GetNeighborVertIndex( 5 ); + indices[3][1] = m_Nodes[nodeIndex].GetCenterVertIndex(); + indices[3][2] = m_Nodes[nodeIndex].GetNeighborVertIndex( 2 ); + + indices[4][0] = m_Nodes[nodeIndex].GetNeighborVertIndex( 0 ); + indices[4][1] = m_Nodes[nodeIndex].GetNeighborVertIndex( 6 ); + indices[4][2] = m_Nodes[nodeIndex].GetCenterVertIndex(); + + indices[5][0] = m_Nodes[nodeIndex].GetCenterVertIndex(); + indices[5][1] = m_Nodes[nodeIndex].GetNeighborVertIndex( 6 ); + indices[5][2] = m_Nodes[nodeIndex].GetNeighborVertIndex( 1 ); + + indices[6][0] = m_Nodes[nodeIndex].GetCenterVertIndex(); + indices[6][1] = m_Nodes[nodeIndex].GetNeighborVertIndex( 1 ); + indices[6][2] = m_Nodes[nodeIndex].GetNeighborVertIndex( 2 ); + + indices[7][0] = m_Nodes[nodeIndex].GetNeighborVertIndex( 2 ); + indices[7][1] = m_Nodes[nodeIndex].GetNeighborVertIndex( 1 ); + indices[7][2] = m_Nodes[nodeIndex].GetNeighborVertIndex( 7 ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::CalcTriSurfInfoAtNode( int nodeIndex ) +{ + int indices[8][3]; + + CalcTriSurfIndices( nodeIndex, indices ); + CalcTriSurfBoundingBoxes( nodeIndex, indices ); + CalcRayBoundingBoxes( nodeIndex, indices ); + CalcTriSurfPlanes( nodeIndex, indices ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::CalcMinMaxBoundingBoxAtNode( int nodeIndex, Vector& bMin, Vector& bMax ) +{ + // get the child node index + int childNodeIndex = GetNodeChild( m_Power, nodeIndex, 4 ); + + // get initial bounding box values + m_Nodes[childNodeIndex].GetBoundingBox( bMin, bMax ); + + Vector nodeMin, nodeMax; + for( int i = 1, j = 5; i < 4; i++, j++ ) + { + // + // get the child node bounding box + // + childNodeIndex = GetNodeChild( m_Power, nodeIndex, j ); + m_Nodes[childNodeIndex].GetBoundingBox( nodeMin, nodeMax ); + + // minimum + if( bMin[0] > nodeMin[0] ) + bMin[0] = nodeMin[0]; + + if( bMin[1] > nodeMin[1] ) + bMin[1] = nodeMin[1]; + + if( bMin[2] > nodeMin[2] ) + bMin[2] = nodeMin[2]; + + // maximum + if( bMax[0] < nodeMax[0] ) + bMax[0] = nodeMax[0]; + + if( bMax[1] < nodeMax[1] ) + bMax[1] = nodeMax[1]; + + if( bMax[2] < nodeMax[2] ) + bMax[2] = nodeMax[2]; + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::CalcBoundingBoxAtNode( int nodeIndex ) +{ + Vector bMin, bMax; + + // + // initialize the minimum and maximum values for the bounding box + // + int level = GetNodeLevel( nodeIndex ); + + int vertIndex = m_Nodes[nodeIndex].GetCenterVertIndex(); + if( level == m_Power ) + { + VectorCopy( m_pVerts[vertIndex].m_Vert, bMin ); + VectorCopy( m_pVerts[vertIndex].m_Vert, bMax ); + } + else + { + CalcMinMaxBoundingBoxAtNode( nodeIndex, bMin, bMax ); + + if( bMin[0] > m_pVerts[vertIndex].m_Vert[0] ) + bMin[0] = m_pVerts[vertIndex].m_Vert[0]; + + if( bMin[1] > m_pVerts[vertIndex].m_Vert[1] ) + bMin[1] = m_pVerts[vertIndex].m_Vert[1]; + + if( bMin[2] > m_pVerts[vertIndex].m_Vert[2] ) + bMin[2] = m_pVerts[vertIndex].m_Vert[2]; + + + if( bMax[0] < m_pVerts[vertIndex].m_Vert[0] ) + bMax[0] = m_pVerts[vertIndex].m_Vert[0]; + + if( bMax[1] < m_pVerts[vertIndex].m_Vert[1] ) + bMax[1] = m_pVerts[vertIndex].m_Vert[1]; + + if( bMax[2] < m_pVerts[vertIndex].m_Vert[2] ) + bMax[2] = m_pVerts[vertIndex].m_Vert[2]; + } + + for( int i = 0; i < 8; i++ ) + { + int neighborVertIndex = m_Nodes[nodeIndex].GetNeighborVertIndex( i ); + + // + // minimum + // + if( bMin[0] > m_pVerts[neighborVertIndex].m_Vert[0] ) + bMin[0] = m_pVerts[neighborVertIndex].m_Vert[0]; + + if( bMin[1] > m_pVerts[neighborVertIndex].m_Vert[1] ) + bMin[1] = m_pVerts[neighborVertIndex].m_Vert[1]; + + if( bMin[2] > m_pVerts[neighborVertIndex].m_Vert[2] ) + bMin[2] = m_pVerts[neighborVertIndex].m_Vert[2]; + + // + // maximum + // + if( bMax[0] < m_pVerts[neighborVertIndex].m_Vert[0] ) + bMax[0] = m_pVerts[neighborVertIndex].m_Vert[0]; + + if( bMax[1] < m_pVerts[neighborVertIndex].m_Vert[1] ) + bMax[1] = m_pVerts[neighborVertIndex].m_Vert[1]; + + if( bMax[2] < m_pVerts[neighborVertIndex].m_Vert[2] ) + bMax[2] = m_pVerts[neighborVertIndex].m_Vert[2]; + } + + m_Nodes[nodeIndex].SetBoundingBox( bMin, bMax ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +float CCoreDispInfo::GetMaxErrorFromChildren( int nodeIndex, int level ) +{ + // + // check for children nodes + // + if( level == m_Power ) + return 0.0f; + + // + // get the child's error term and save the greatest error -- SW, SE, NW, NE + // + float errorTerm = 0.0f; + for( int i = 4; i < 8; i++ ) + { + int childIndex = GetNodeChild( m_Power, nodeIndex, i ); + + float nodeErrorTerm = m_Nodes[childIndex].GetErrorTerm(); + if( errorTerm < nodeErrorTerm ) + { + errorTerm = nodeErrorTerm; + } + } + + return errorTerm; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::CalcErrorTermAtNode( int nodeIndex, int level ) +{ + if( level == m_Power ) + return; + + // + // get the vertex indices + // + int neighborVertIndices[9]; + for( int i = 0; i < 8; i++ ) + { + neighborVertIndices[i] = m_Nodes[nodeIndex].GetNeighborVertIndex( i ); + } + neighborVertIndices[8] = m_Nodes[nodeIndex].GetCenterVertIndex(); + + + // + // calculate the error terms + // + Vector segment; + Vector v; + + VectorAdd( m_pVerts[neighborVertIndices[5]].m_Vert, m_pVerts[neighborVertIndices[4]].m_Vert, v ); + VectorScale( v, 0.5f, v ); + VectorSubtract( m_pVerts[neighborVertIndices[0]].m_Vert, v, segment ); + float errorTerm = ( float )VectorLength( segment ); + + VectorAdd( m_pVerts[neighborVertIndices[5]].m_Vert, m_pVerts[neighborVertIndices[6]].m_Vert, v ); + VectorScale( v, 0.5f, v ); + VectorSubtract( m_pVerts[neighborVertIndices[1]].m_Vert, v, segment ); + if( errorTerm < ( float )VectorLength( segment ) ) + errorTerm = ( float )VectorLength( segment ); + + VectorAdd( m_pVerts[neighborVertIndices[6]].m_Vert, m_pVerts[neighborVertIndices[7]].m_Vert, v ); + VectorScale( v, 0.5f, v ); + VectorSubtract( m_pVerts[neighborVertIndices[2]].m_Vert, v, segment ); + if( errorTerm < ( float )VectorLength( segment ) ) + errorTerm = ( float )VectorLength( segment ); + + VectorAdd( m_pVerts[neighborVertIndices[7]].m_Vert, m_pVerts[neighborVertIndices[4]].m_Vert, v ); + VectorScale( v, 0.5f, v ); + VectorSubtract( m_pVerts[neighborVertIndices[3]].m_Vert, v, segment ); + if( errorTerm < ( float )VectorLength( segment ) ) + errorTerm = ( float )VectorLength( segment ); + + VectorAdd( m_pVerts[neighborVertIndices[4]].m_Vert, m_pVerts[neighborVertIndices[6]].m_Vert, v ); + VectorScale( v, 0.5f, v ); + VectorSubtract( m_pVerts[neighborVertIndices[8]].m_Vert, v, segment ); + if( errorTerm < ( float )VectorLength( segment ) ) + errorTerm = ( float )VectorLength( segment ); + + VectorAdd( m_pVerts[neighborVertIndices[5]].m_Vert, m_pVerts[neighborVertIndices[7]].m_Vert, v ); + VectorScale( v, 0.5f, v ); + VectorSubtract( m_pVerts[neighborVertIndices[8]].m_Vert, v, segment ); + if( errorTerm < ( float )VectorLength( segment ) ) + errorTerm = ( float )VectorLength( segment ); + + // + // add the max child's error term + // + errorTerm += GetMaxErrorFromChildren( nodeIndex, level ); + + // set the error term + m_Nodes[nodeIndex].SetErrorTerm( errorTerm ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::CalcNeighborVertIndicesAtNode( int nodeIndex, int level ) +{ + // calculate the shift in direction in the matrix + int shift = ( 1 << ( m_Power - level ) ); + + // calculate the width, height of the displacement surface (are uniform) + int extent = ( ( 1 << m_Power ) + 1 ); + + // + // get the neighbor vertex indices (defining the surface at the node level) + // + for( int direction = 0; direction < 8; direction++ ) + { + // + // get the parent vertex index in component form + // + int posX = m_Nodes[nodeIndex].GetCenterVertIndex() % extent; + int posY = m_Nodes[nodeIndex].GetCenterVertIndex() / extent; + + // + // calculate the neighboring vertex indices for surface rendering + // + bool bError = false; + switch( direction ) + { + case WEST: { posX -= shift; break; } + case NORTH: { posY += shift; break; } + case EAST: { posX += shift; break; } + case SOUTH: { posY -= shift; break; } + case SOUTHWEST: { posX -= shift; posY -= shift; break; } + case SOUTHEAST: { posX += shift; posY -= shift; break; } + case NORTHWEST: { posX -= shift; posY += shift; break; } + case NORTHEAST: { posX += shift; posY += shift; break; } + default: { bError = true; break; } + } + + if( bError ) + { + m_Nodes[nodeIndex].SetNeighborVertIndex( direction, -99999 ); + } + else + { + m_Nodes[nodeIndex].SetNeighborVertIndex( direction, ( ( posY * extent ) + posX ) ); + } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::CalcNodeInfo( int nodeIndex, int terminationLevel ) +{ + // get the level of the current node + int level = GetNodeLevel( nodeIndex ); + + // + // get the node data at the termination level + // + if( level == terminationLevel ) + { + // get the neighbor vertex indices (used to create surface at node level) + CalcNeighborVertIndicesAtNode( nodeIndex, level ); + + // get the neighbor node indices + //CalcNeighborNodeIndicesAtNode( nodeIndex, level ); + + // calculate the error term at the node + CalcErrorTermAtNode( nodeIndex, level ); + + // calcluate the axial-aligned bounding box at the node + CalcBoundingBoxAtNode( nodeIndex ); + + // calculate the triangular surface info at the node + CalcTriSurfInfoAtNode( nodeIndex ); + + return; + } + + // + // continue recursion (down to nodes "children") + // + for( int i = 4; i < 8; i++ ) + { + int childIndex = GetNodeChild( m_Power, nodeIndex, i ); + CalcNodeInfo( childIndex, terminationLevel ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CCoreDispInfo::GetNodeVertIndexFromParentIndex( int level, int parentVertIndex, int direction ) +{ + // calculate the "shift" + int shift = ( 1 << ( m_Power - ( level + 1 ) ) ); + + // calculate the width and height of displacement (is uniform) + int extent = ( ( 1 << m_Power ) + 1 ); + + // get the parent vertex index in component form + int posX = parentVertIndex % extent; + int posY = parentVertIndex / extent; + + // + // calculate the child index based on the parent index and child + // direction + // + switch( direction ) + { + case SOUTHWEST: { posX -= shift; posY -= shift; break; } + case SOUTHEAST: { posX += shift; posY -= shift; break; } + case NORTHWEST: { posX -= shift; posY += shift; break; } + case NORTHEAST: { posX += shift; posY += shift; break; } + default: return -99999; + } + + // return the child vertex index + return ( ( posY * extent ) + posX ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::CalcVertIndicesAtNodes( int nodeIndex ) +{ + // + // check for recursion termination ( node level = power ) + // + int level = GetNodeLevel( nodeIndex ); + if( level == m_Power ) + return; + + // + // get the children indices - SW, SE, NW, NE + // + int childIndices[4]; + int i, j; + for( i = 0, j = 4; i < 4; i++, j++ ) + { + childIndices[i] = GetNodeChild( m_Power, nodeIndex, j ); + int centerIndex = GetNodeVertIndexFromParentIndex( level, m_Nodes[nodeIndex].GetCenterVertIndex(), j ); + m_Nodes[childIndices[i]].SetCenterVertIndex( centerIndex ); + } + + // + // calculate the children's node vertex indices + // + for( i = 0; i < 4; i++ ) + { + CalcVertIndicesAtNodes( childIndices[i] ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::GenerateLODTree( void ) +{ + // + // calculate the displacement surface's vertex index at each quad-tree node + // centroid + // + int size = GetSize(); + int initialIndex = ( ( size - 1 ) >> 1 ); + m_Nodes[0].SetCenterVertIndex( initialIndex ); + CalcVertIndicesAtNodes( 0 ); + + // + // calculate the error terms, bounding boxes, and neighboring vertex indices + // at each node + // + for( int i = m_Power; i > 0; i-- ) + { + CalcNodeInfo( 0, i ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::CalcDispSurfCoords( bool bLightMap, int lightmapID ) +{ + // + // get base surface texture coords + // + Vector2D texCoords[4]; + Vector2D luxelCoords[4]; + CCoreDispSurface *pSurf = GetSurface(); + + int i; + for( i = 0; i < 4; i++ ) + { + pSurf->GetTexCoord( i, texCoords[i] ); + pSurf->GetLuxelCoord( lightmapID, i, luxelCoords[i] ); + } + + // + // get images width and intervals along the edge + // + int postSpacing = GetPostSpacing(); + float ooInt = ( 1.0f / ( float )( postSpacing - 1 ) ); + + // + // calculate the parallel edge intervals + // + Vector2D edgeInt[2]; + if( !bLightMap ) + { + Vector2DSubtract( texCoords[1], texCoords[0], edgeInt[0] ); + Vector2DSubtract( texCoords[2], texCoords[3], edgeInt[1] ); + } + else + { + Vector2DSubtract( luxelCoords[1], luxelCoords[0], edgeInt[0] ); + Vector2DSubtract( luxelCoords[2], luxelCoords[3], edgeInt[1] ); + } + Vector2DMultiply( edgeInt[0], ooInt, edgeInt[0] ); + Vector2DMultiply( edgeInt[1], ooInt, edgeInt[1] ); + + // + // calculate the displacement points + // + for( i = 0; i < postSpacing; i++ ) + { + // + // position along parallel edges (start and end for a perpendicular segment) + // + Vector2D endPts[2]; + Vector2DMultiply( edgeInt[0], ( float )i, endPts[0] ); + Vector2DMultiply( edgeInt[1], ( float )i, endPts[1] ); + if( !bLightMap ) + { + Vector2DAdd( endPts[0], texCoords[0], endPts[0] ); + Vector2DAdd( endPts[1], texCoords[3], endPts[1] ); + } + else + { + Vector2DAdd( endPts[0], luxelCoords[0], endPts[0] ); + Vector2DAdd( endPts[1], luxelCoords[3], endPts[1] ); + } + + // + // interval length for perpendicular edge + // + Vector2D seg, segInt; + Vector2DSubtract( endPts[1], endPts[0], seg ); + Vector2DMultiply( seg, ooInt, segInt ); + + // + // calculate the material (texture or light) coordinate at each point + // + for( int j = 0; j < postSpacing; j++ ) + { + Vector2DMultiply( segInt, ( float )j, seg ); + + if( !bLightMap ) + { + Vector2DAdd( endPts[0], seg, m_pVerts[i*postSpacing+j].m_TexCoord ); + } + else + { + Vector2DAdd( endPts[0], seg, m_pVerts[i*postSpacing+j].m_LuxelCoords[lightmapID] ); + } + } + } +} + +#if 0 +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::CalcDispSurfAlphas( void ) +{ + // + // get images width and intervals along the edge + // + int postSpacing = GetPostSpacing(); + float ooInt = ( 1.0f / ( float )( postSpacing - 1 ) ); + + // + // calculate the parallel edge intervals + // + float edgeInt[2]; + edgeInt[0] = m_Surf.m_Alpha[1] - m_Surf.m_Alpha[0]; + edgeInt[1] = m_Surf.m_Alpha[2] - m_Surf.m_Alpha[3]; + edgeInt[0] *= ooInt; + edgeInt[1] *= ooInt; + + // + // calculate the displacement points + // + for( int i = 0; i < postSpacing; i++ ) + { + // + // position along parallel edges (start and end for a perpendicular segment) + // + float endValues[2]; + + endValues[0] = edgeInt[0] * ( float )i; + endValues[1] = edgeInt[1] * ( float )i; + endValues[0] += m_Surf.m_Alpha[0]; + endValues[1] += m_Surf.m_Alpha[3]; + + // + // interval length for perpendicular edge + // + float seg, segInt; + seg = endValues[1] - endValues[0]; + segInt = seg * ooInt; + + // + // calculate the alpha value at each point + // + for( int j = 0; j < postSpacing; j++ ) + { + seg = segInt * ( float )j; + m_Alphas[i*postSpacing+j] = endValues[0] + seg; + } + } +} +#endif + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::GenerateDispSurfTangentSpaces( void ) +{ + // + // get texture axes from base surface + // + CCoreDispSurface *pSurf = GetSurface(); + Vector sAxis, tAxis; + pSurf->GetSAxis( sAxis ); + pSurf->GetTAxis( tAxis ); + + // + // calculate the tangent spaces + // + int size = GetSize(); + for( int i = 0; i < size; i++ ) + { + // + // create the axes - normals, tangents, and binormals + // + VectorCopy( tAxis, m_pVerts[i].m_TangentT ); + VectorNormalize( m_pVerts[i].m_TangentT ); + CrossProduct( m_pVerts[i].m_Normal, m_pVerts[i].m_TangentT, m_pVerts[i].m_TangentS ); + VectorNormalize( m_pVerts[i].m_TangentS ); + CrossProduct( m_pVerts[i].m_TangentS, m_pVerts[i].m_Normal, m_pVerts[i].m_TangentT ); + VectorNormalize( m_pVerts[i].m_TangentT ); + + Vector tmpVect; + Vector planeNormal; + pSurf->GetNormal( planeNormal ); + CrossProduct( sAxis, tAxis, tmpVect ); + if( DotProduct( planeNormal, tmpVect ) > 0.0f ) + { + VectorScale( m_pVerts[i].m_TangentS, -1.0f, m_pVerts[i].m_TangentS ); + } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::CalcNormalFromEdges( int indexRow, int indexCol, bool bIsEdge[4], + Vector& normal ) +{ + // get the post spacing (size/interval of displacement surface) + int postSpacing = ( ( 1 << m_Power ) + 1 ); + + // initialize the normal accumulator - counter + Vector accumNormal; + int normalCount = 0; + + VectorClear( accumNormal ); + + Vector tmpVect[2]; + Vector tmpNormal; + + // + // check quadrant I (posX, posY) + // + if( bIsEdge[1] && bIsEdge[2] ) + { + // tri i + VectorSubtract( m_pVerts[(indexCol+1)*postSpacing+indexRow].m_Vert, m_pVerts[indexCol*postSpacing+indexRow].m_Vert, tmpVect[0] ); + VectorSubtract( m_pVerts[indexCol*postSpacing+(indexRow+1)].m_Vert, m_pVerts[indexCol*postSpacing+indexRow].m_Vert, tmpVect[1] ); + CrossProduct( tmpVect[1], tmpVect[0], tmpNormal ); + VectorNormalize( tmpNormal ); + VectorAdd( accumNormal, tmpNormal, accumNormal ); + normalCount++; + + // tri 2 + VectorSubtract( m_pVerts[(indexCol+1)*postSpacing+indexRow].m_Vert, m_pVerts[indexCol*postSpacing+(indexRow+1)].m_Vert, tmpVect[0] ); + VectorSubtract( m_pVerts[(indexCol+1)*postSpacing+(indexRow+1)].m_Vert, m_pVerts[indexCol*postSpacing+(indexRow+1)].m_Vert, tmpVect[1] ); + CrossProduct( tmpVect[1], tmpVect[0], tmpNormal ); + VectorNormalize( tmpNormal ); + VectorAdd( accumNormal, tmpNormal, accumNormal ); + normalCount++; + } + + // + // check quadrant II (negX, posY) + // + if( bIsEdge[0] && bIsEdge[1] ) + { + // tri i + VectorSubtract( m_pVerts[(indexCol+1)*postSpacing+(indexRow-1)].m_Vert, m_pVerts[indexCol*postSpacing+(indexRow-1)].m_Vert, tmpVect[0] ); + VectorSubtract( m_pVerts[indexCol*postSpacing+indexRow].m_Vert, m_pVerts[indexCol*postSpacing+(indexRow-1)].m_Vert, tmpVect[1] ); + CrossProduct( tmpVect[1], tmpVect[0], tmpNormal ); + VectorNormalize( tmpNormal ); + VectorAdd( accumNormal, tmpNormal, accumNormal ); + normalCount++; + + // tri 2 + VectorSubtract( m_pVerts[(indexCol+1)*postSpacing+(indexRow-1)].m_Vert, m_pVerts[indexCol*postSpacing+indexRow].m_Vert, tmpVect[0] ); + VectorSubtract( m_pVerts[(indexCol+1)*postSpacing+indexRow].m_Vert, m_pVerts[indexCol*postSpacing+indexRow].m_Vert, tmpVect[1] ); + CrossProduct( tmpVect[1], tmpVect[0], tmpNormal ); + VectorNormalize( tmpNormal ); + VectorAdd( accumNormal, tmpNormal, accumNormal ); + normalCount++; + } + + // + // check quadrant III (negX, negY) + // + if( bIsEdge[0] && bIsEdge[3] ) + { + // tri i + VectorSubtract( m_pVerts[indexCol*postSpacing+(indexRow-1)].m_Vert, m_pVerts[(indexCol-1)*postSpacing+(indexRow-1)].m_Vert, tmpVect[0] ); + VectorSubtract( m_pVerts[(indexCol-1)*postSpacing+indexRow].m_Vert, m_pVerts[(indexCol-1)*postSpacing+(indexRow-1)].m_Vert, tmpVect[1] ); + CrossProduct( tmpVect[1], tmpVect[0], tmpNormal ); + VectorNormalize( tmpNormal ); + VectorAdd( accumNormal, tmpNormal, accumNormal ); + normalCount++; + + // tri 2 + VectorSubtract( m_pVerts[indexCol*postSpacing+(indexRow-1)].m_Vert, m_pVerts[(indexCol-1)*postSpacing+indexRow].m_Vert, tmpVect[0] ); + VectorSubtract( m_pVerts[indexCol*postSpacing+indexRow].m_Vert, m_pVerts[(indexCol-1)*postSpacing+indexRow].m_Vert, tmpVect[1] ); + CrossProduct( tmpVect[1], tmpVect[0], tmpNormal ); + VectorNormalize( tmpNormal ); + VectorAdd( accumNormal, tmpNormal, accumNormal ); + normalCount++; + } + + // + // check quadrant IV (posX, negY) + // + if( bIsEdge[2] && bIsEdge[3] ) + { + // tri i + VectorSubtract( m_pVerts[indexCol*postSpacing+indexRow].m_Vert, m_pVerts[(indexCol-1)*postSpacing+indexRow].m_Vert, tmpVect[0] ); + VectorSubtract( m_pVerts[(indexCol-1)*postSpacing+(indexRow+1)].m_Vert, m_pVerts[(indexCol-1)*postSpacing+indexRow].m_Vert, tmpVect[1] ); + CrossProduct( tmpVect[1], tmpVect[0], tmpNormal ); + VectorNormalize( tmpNormal ); + VectorAdd( accumNormal, tmpNormal, accumNormal ); + normalCount++; + + // tri 2 + VectorSubtract( m_pVerts[indexCol*postSpacing+indexRow].m_Vert, m_pVerts[(indexCol-1)*postSpacing+(indexRow+1)].m_Vert, tmpVect[0] ); + VectorSubtract( m_pVerts[indexCol*postSpacing+(indexRow+1)].m_Vert, m_pVerts[(indexCol-1)*postSpacing+(indexRow+1)].m_Vert, tmpVect[1] ); + CrossProduct( tmpVect[1], tmpVect[0], tmpNormal ); + VectorNormalize( tmpNormal ); + VectorAdd( accumNormal, tmpNormal, accumNormal ); + normalCount++; + } + + VectorScale( accumNormal, ( 1.0f / ( float )normalCount ), normal ); +} + + +//----------------------------------------------------------------------------- +// Purpose: This function determines if edges exist in each of the directions +// off of the given point (given in component form). We know ahead of +// time that there are only 4 possibilities. +// +// 1 "directions" +// 0 + 2 +// 3 +// +// Input: indexRow - row position +// indexCol - col position +// direction - the direction (edge) currently being evaluated +// postSpacing - the number of intervals in the row and col directions +// Output: the edge existed? (true/false) +//----------------------------------------------------------------------------- +bool CCoreDispInfo::DoesEdgeExist( int indexRow, int indexCol, int direction, int postSpacing ) +{ + switch( direction ) + { + case 0: + // left edge + if( ( indexRow - 1 ) < 0 ) + return false; + return true; + case 1: + // top edge + if( ( indexCol + 1 ) > ( postSpacing - 1 ) ) + return false; + return true; + case 2: + // right edge + if( ( indexRow + 1 ) > ( postSpacing - 1 ) ) + return false; + return true; + case 3: + // bottom edge + if( ( indexCol - 1 ) < 0 ) + return false; + return true; + default: + return false; + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::GenerateDispSurfNormals( void ) +{ + // get the post spacing (size/interval of displacement surface) + int postSpacing = GetPostSpacing(); + + // + // generate the normals at each displacement surface vertex + // + for( int i = 0; i < postSpacing; i++ ) + { + for( int j = 0; j < postSpacing; j++ ) + { + bool bIsEdge[4]; + + // edges + for( int k = 0; k < 4; k++ ) + { + bIsEdge[k] = DoesEdgeExist( j, i, k, postSpacing ); + } + + Vector normal; + CalcNormalFromEdges( j, i, bIsEdge, normal ); + + // save generated normal + VectorCopy( normal, m_pVerts[i*postSpacing+j].m_Normal ); + } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::GenerateDispSurf( void ) +{ + int i; + CCoreDispSurface *pSurf = GetSurface(); + Vector points[4]; + for( i = 0; i < 4; i++ ) + { + pSurf->GetPoint( i, points[i] ); + } + + // + // get the spacing (interval = width/height, are equal because it is uniform) along the edge + // + int postSpacing = GetPostSpacing(); + float ooInt = 1.0f / ( float )( postSpacing - 1 ); + + // + // calculate the opposite edge intervals + // + Vector edgeInt[2]; + VectorSubtract( points[1], points[0], edgeInt[0] ); + VectorScale( edgeInt[0], ooInt, edgeInt[0] ); + VectorSubtract( points[2], points[3], edgeInt[1] ); + VectorScale( edgeInt[1], ooInt, edgeInt[1] ); + + Vector elevNormal; + elevNormal.Init(); + if( m_Elevation != 0.0f ) + { + pSurf->GetNormal( elevNormal ); + VectorScale( elevNormal, m_Elevation, elevNormal ); + } + + // + // calculate the displaced vertices + // + for( i = 0; i < postSpacing; i++ ) + { + // + // calculate segment interval between opposite edges + // + Vector endPts[2]; + VectorScale( edgeInt[0], ( float )i, endPts[0] ); + VectorAdd( endPts[0], points[0], endPts[0] ); + VectorScale( edgeInt[1], ( float )i, endPts[1] ); + VectorAdd( endPts[1], points[3], endPts[1] ); + + Vector seg, segInt; + VectorSubtract( endPts[1], endPts[0], seg ); + VectorScale( seg, ooInt, segInt ); + + // + // calculate the surface vertices + // + for( int j = 0; j < postSpacing; j++ ) + { + int ndx = i * postSpacing + j; + + CoreDispVert_t *pVert = &m_pVerts[ndx]; + + // calculate the flat surface position -- saved separately + pVert->m_FlatVert = endPts[0] + ( segInt * ( float )j ); + + // start with the base surface position + pVert->m_Vert = pVert->m_FlatVert; + + // add the elevation vector -- if it exists + if( m_Elevation != 0.0f ) + { + pVert->m_Vert += elevNormal; + } + + // add the subdivision surface position + pVert->m_Vert += pVert->m_SubdivPos; + + // add the displacement field direction(normalized) and distance + pVert->m_Vert += pVert->m_FieldVector * pVert->m_FieldDistance; + } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//bool CCoreDispInfo::Create( int creationFlags ) +bool CCoreDispInfo::Create( void ) +{ + // sanity check + CCoreDispSurface *pSurf = GetSurface(); + if( pSurf->GetPointCount() != 4 ) + return false; + + // generate the displacement surface + GenerateDispSurf(); + + GenerateDispSurfNormals(); + + GenerateDispSurfTangentSpaces(); + + CalcDispSurfCoords( false, 0 ); + + for( int bumpID = 0; bumpID < ( NUM_BUMP_VECTS + 1 ); bumpID++ ) + { + CalcDispSurfCoords( true, bumpID ); + } + + GenerateLODTree(); + + GenerateCollisionData(); + + CreateTris(); + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Create a displacement surface without generating the LOD for it. +//----------------------------------------------------------------------------- +bool CCoreDispInfo::CreateWithoutLOD( void ) +{ + // sanity check + CCoreDispSurface *pSurf = GetSurface(); + if( pSurf->GetPointCount() != 4 ) + return false; + + GenerateDispSurf(); + + GenerateDispSurfNormals(); + + GenerateDispSurfTangentSpaces(); + + CalcDispSurfCoords( false, 0 ); + + for( int bumpID = 0; bumpID < ( NUM_BUMP_VECTS + 1 ); bumpID++ ) + { + CalcDispSurfCoords( true, bumpID ); + } + GenerateCollisionData(); + + CreateTris(); + + return true; +} + + + +//----------------------------------------------------------------------------- +// Purpose: This function calculates the neighbor node index given the base +// node and direction of the neighbor node in the tree. +// Input: power - the size in one dimension of the displacement map (2^power + 1 ) +// index - the "base" node index +// direction - the direction of the neighbor { W = 1, N = 2, E = 3, S = 4 } +// Output: returns the index of the neighbor node +//----------------------------------------------------------------------------- +int GetNodeNeighborNode( int power, int index, int direction, int level ) +{ + // adjust the index to range [0...?] + int minNodeIndex = GetNodeMinNodeAtLevel( level ); + + // get node extent (uniform: height = width) + int nodeExtent = ( 1 << ( level - 1 ) ); + + // + // get node's component positions in quad-tree + // + int posX, posY; + GetComponentsFromNodeIndex( ( index - minNodeIndex ), &posX, &posY ); + + // + // find the neighbor in the "direction" + // + switch( direction ) + { + case CCoreDispInfo::WEST: + { + if( ( posX - 1 ) < 0 ) + { + return -( CCoreDispInfo::WEST + 1 ); + } + else + { + return ( GetNodeIndexFromComponents( ( posX - 1 ), posY ) + minNodeIndex ); + } + } + case CCoreDispInfo::NORTH: + { + if( ( posY + 1 ) == nodeExtent ) + { + return -( CCoreDispInfo::NORTH + 1 ); + } + else + { + return ( GetNodeIndexFromComponents( posX, ( posY + 1 ) ) + minNodeIndex ); + } + } + case CCoreDispInfo::EAST: + { + if( ( posX + 1 ) == nodeExtent ) + { + return -( CCoreDispInfo::EAST + 1 ); + } + else + { + return ( GetNodeIndexFromComponents( ( posX + 1 ), posY ) + minNodeIndex ); + } + } + case CCoreDispInfo::SOUTH: + { + if( ( posY - 1 ) < 0 ) + { + return -( CCoreDispInfo::SOUTH + 1 ); + } + else + { + return ( GetNodeIndexFromComponents( posX, ( posY - 1 ) ) + minNodeIndex ); + } + } + default: + { + return -99999; + } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int GetNodeNeighborNodeFromNeighborSurf( int power, int index, int direction, int level, int neighborOrient ) +{ + // adjust the index to range [0...?] + int minNodeIndex = GetNodeMinNodeAtLevel( level ); + + // get node extent (uniform: height = width) + int nodeExtent = ( 1 << ( level - 1 ) ); + + // + // get node's component positions in quad-tree + // + int posX, posY; + GetComponentsFromNodeIndex( ( index - minNodeIndex ), &posX, &posY ); + + switch( direction ) + { + case CCoreDispInfo::WEST: + { + switch( neighborOrient ) + { + case CCoreDispInfo::WEST: return -( ( GetNodeIndexFromComponents( posX, ( ( nodeExtent - 1 ) - posY ) ) ) + minNodeIndex ); + case CCoreDispInfo::NORTH: return -( ( GetNodeIndexFromComponents( ( nodeExtent - 1 ) - posY, ( nodeExtent - 1 ) ) ) + minNodeIndex ); + case CCoreDispInfo::EAST: return -( ( GetNodeIndexFromComponents( ( nodeExtent - 1 ), posY ) ) + minNodeIndex ); + case CCoreDispInfo::SOUTH: return -( ( GetNodeIndexFromComponents( posY, posX ) ) + minNodeIndex ); + default: return -99999; + } + } + case CCoreDispInfo::NORTH: + { + switch( neighborOrient ) + { + case CCoreDispInfo::WEST: return -( ( GetNodeIndexFromComponents( ( ( nodeExtent - 1 ) - posY ), ( ( nodeExtent - 1 ) - posX ) ) ) + minNodeIndex ); + case CCoreDispInfo::NORTH: return -( ( GetNodeIndexFromComponents( ( ( nodeExtent - 1 ) - posX ), posY ) ) + minNodeIndex ); + case CCoreDispInfo::EAST: return -( ( GetNodeIndexFromComponents( posY, posX ) ) + minNodeIndex ); + case CCoreDispInfo::SOUTH: return -( ( GetNodeIndexFromComponents( posX, ( ( nodeExtent - 1 ) - posY ) ) ) + minNodeIndex ); + default: return -99999; + } + } + case CCoreDispInfo::EAST: + { + switch( neighborOrient ) + { + case CCoreDispInfo::WEST: return -( ( GetNodeIndexFromComponents( ( ( nodeExtent - 1 ) - posX ), posY ) ) + minNodeIndex ); + case CCoreDispInfo::NORTH: return -( ( GetNodeIndexFromComponents( posY, posX ) ) + minNodeIndex ); + case CCoreDispInfo::EAST: return -( ( GetNodeIndexFromComponents( posX, ( ( nodeExtent - 1 ) - posY ) ) ) + minNodeIndex ); + case CCoreDispInfo::SOUTH: return -( ( GetNodeIndexFromComponents( ( ( nodeExtent - 1 ) - posY ), ( ( nodeExtent - 1 ) - posX ) ) ) + minNodeIndex ); + default: return -99999; + } + } + case CCoreDispInfo::SOUTH: + { + switch( neighborOrient ) + { + case CCoreDispInfo::WEST: return -( ( GetNodeIndexFromComponents( posY, posX ) ) + minNodeIndex ); + case CCoreDispInfo::NORTH: return -( ( GetNodeIndexFromComponents( posX, ( nodeExtent - 1 ) ) ) + minNodeIndex ); + case CCoreDispInfo::EAST: return -( ( GetNodeIndexFromComponents( ( nodeExtent - 1 ), ( ( nodeExtent - 1 ) - posX ) ) ) + minNodeIndex ); + case CCoreDispInfo::SOUTH: return -( ( GetNodeIndexFromComponents( ( ( nodeExtent - 1 ) - posX ), posY ) ) + minNodeIndex ); + default: return -99999; + } + } + default: + { + return -99999; + } + } +} + + + +// Turn the optimizer back on +#pragma optimize( "", on ) + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::GetPositionOnSurface( float u, float v, Vector &vPos, + Vector *pNormal, float *pAlpha ) +{ + Vector2D dispUV( u, v ); + DispUVToSurf( dispUV, vPos, pNormal, pAlpha ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::BaseFacePlaneToDispUV( Vector const &planePt, Vector2D &dispUV ) +{ + // Get the base surface points. + CCoreDispSurface *pSurf = GetSurface(); + Vector vecPoints[4]; + for( int iPoint = 0; iPoint < 4; ++iPoint ) + { + pSurf->GetPoint( iPoint, vecPoints[iPoint] ); + } + + PointInQuadToBarycentric( vecPoints[0], vecPoints[3], vecPoints[2], vecPoints[1], planePt, dispUV ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCoreDispInfo::DispUVToSurf_TriTLToBR_1( const Vector &vecIntersectPoint, + int nSnapU, int nNextU, int nSnapV, int nNextV, + Vector &vecPoint, Vector *pNormal, float *pAlpha, + bool bBackup ) +{ + int nWidth = GetWidth(); + + int nIndices[3]; + nIndices[0] = nNextV * nWidth + nSnapU; + nIndices[1] = nNextV * nWidth + nNextU; + nIndices[2] = nSnapV * nWidth + nNextU; + + Vector vecFlatVerts[3], vecVerts[3]; + float flAlphas[3]; + for ( int iVert = 0; iVert < 3; ++iVert ) + { + vecFlatVerts[iVert] = m_pVerts[nIndices[iVert]].m_FlatVert; + vecVerts[iVert] = m_pVerts[nIndices[iVert]].m_Vert; + flAlphas[iVert] = m_pVerts[nIndices[iVert]].m_Alpha; + } + + if ( nSnapU == nNextU ) + { + if ( nSnapV == nNextV ) + { + vecPoint = vecVerts[0]; + *pAlpha = flAlphas[0]; + } + else + { + float flFrac = ( vecIntersectPoint - vecFlatVerts[0] ).Length() / ( vecFlatVerts[2] - vecFlatVerts[0] ).Length(); + vecPoint = vecVerts[0] + ( flFrac * ( vecVerts[2] - vecVerts[0] ) ); + + if ( pAlpha ) + { + *pAlpha = flAlphas[0] + ( flFrac * ( flAlphas[2] - flAlphas[0] ) ); + } + } + + if( pNormal ) + { + Vector edgeU = vecVerts[0] - vecVerts[1]; + Vector edgeV = vecVerts[2] - vecVerts[1]; + *pNormal = CrossProduct( edgeU, edgeV ); + VectorNormalize( *pNormal ); + } + } + else if ( nSnapV == nNextV ) + { + if ( nSnapU == nNextU ) + { + vecPoint = vecVerts[0]; + *pAlpha = flAlphas[0]; + } + else + { + float flFrac = ( vecIntersectPoint - vecFlatVerts[0] ).Length() / ( vecFlatVerts[2] - vecFlatVerts[0] ).Length(); + vecPoint = vecVerts[0] + ( flFrac * ( vecVerts[2] - vecVerts[0] ) ); + + if ( pAlpha ) + { + *pAlpha = flAlphas[0] + ( flFrac * ( flAlphas[2] - flAlphas[0] ) ); + } + } + + if( pNormal ) + { + Vector edgeU = vecVerts[0] - vecVerts[1]; + Vector edgeV = vecVerts[2] - vecVerts[1]; + *pNormal = CrossProduct( edgeU, edgeV ); + VectorNormalize( *pNormal ); + } + } + else + { + float flCfs[3]; + if ( CalcBarycentricCooefs( vecFlatVerts[0], vecFlatVerts[1], vecFlatVerts[2], vecIntersectPoint, flCfs[0], flCfs[1], flCfs[2] ) ) + { + vecPoint = ( vecVerts[0] * flCfs[0] ) + ( vecVerts[1] * flCfs[1] ) + ( vecVerts[2] * flCfs[2] ); + + if( pAlpha ) + { + *pAlpha = ( flAlphas[0] * flCfs[0] ) + ( flAlphas[1] * flCfs[1] ) + ( flAlphas[2] * flCfs[2] ); + } + + if( pNormal ) + { + Vector edgeU = vecVerts[0] - vecVerts[1]; + Vector edgeV = vecVerts[2] - vecVerts[1]; + *pNormal = CrossProduct( edgeU, edgeV ); + VectorNormalize( *pNormal ); + } + } + else + { + if ( !bBackup ) + { + DispUVToSurf_TriTLToBR_2( vecIntersectPoint, nSnapU, nNextU, nSnapV, nNextV, vecPoint, pNormal, pAlpha, true ); + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCoreDispInfo::DispUVToSurf_TriTLToBR_2( const Vector &vecIntersectPoint, + int nSnapU, int nNextU, int nSnapV, int nNextV, + Vector &vecPoint, Vector *pNormal, float *pAlpha, + bool bBackup ) +{ + int nWidth = GetWidth(); + + int nIndices[3]; + nIndices[0] = nSnapV * nWidth + nSnapU; + nIndices[1] = nNextV * nWidth + nSnapU; + nIndices[2] = nSnapV * nWidth + nNextU; + + Vector vecFlatVerts[3], vecVerts[3]; + float flAlphas[3]; + for ( int iVert = 0; iVert < 3; ++iVert ) + { + vecFlatVerts[iVert] = m_pVerts[nIndices[iVert]].m_FlatVert; + vecVerts[iVert] = m_pVerts[nIndices[iVert]].m_Vert; + flAlphas[iVert] = m_pVerts[nIndices[iVert]].m_Alpha; + } + + if ( nSnapU == nNextU ) + { + if ( nSnapV == nNextV ) + { + vecPoint = vecVerts[0]; + *pAlpha = flAlphas[0]; + } + else + { + float flFrac = ( vecIntersectPoint - vecFlatVerts[0] ).Length() / ( vecFlatVerts[1] - vecFlatVerts[0] ).Length(); + vecPoint = vecVerts[0] + ( flFrac * ( vecVerts[1] - vecVerts[0] ) ); + + if ( pAlpha ) + { + *pAlpha = flAlphas[0] + ( flFrac * ( flAlphas[1] - flAlphas[0] ) ); + } + } + + if( pNormal ) + { + Vector edgeU = vecVerts[2] - vecVerts[0]; + Vector edgeV = vecVerts[1] - vecVerts[0]; + *pNormal = CrossProduct( edgeU, edgeV ); + VectorNormalize( *pNormal ); + } + } + else if ( nSnapV == nNextV ) + { + if ( nSnapU == nNextU ) + { + vecPoint = vecVerts[0]; + *pAlpha = flAlphas[0]; + } + else + { + float flFrac = ( vecIntersectPoint - vecFlatVerts[0] ).Length() / ( vecFlatVerts[2] - vecFlatVerts[0] ).Length(); + vecPoint = vecVerts[0] + ( flFrac * ( vecVerts[2] - vecVerts[0] ) ); + + if ( pAlpha ) + { + *pAlpha = flAlphas[0] + ( flFrac * ( flAlphas[2] - flAlphas[0] ) ); + } + } + + if( pNormal ) + { + Vector edgeU = vecVerts[2] - vecVerts[0]; + Vector edgeV = vecVerts[1] - vecVerts[0]; + *pNormal = CrossProduct( edgeU, edgeV ); + VectorNormalize( *pNormal ); + } + } + else + { + float flCfs[3]; + if ( CalcBarycentricCooefs( vecFlatVerts[0], vecFlatVerts[1], vecFlatVerts[2], vecIntersectPoint, flCfs[0], flCfs[1], flCfs[2] ) ) + { + vecPoint = ( vecVerts[0] * flCfs[0] ) + ( vecVerts[1] * flCfs[1] ) + ( vecVerts[2] * flCfs[2] ); + + if( pAlpha ) + { + *pAlpha = ( flAlphas[0] * flCfs[0] ) + ( flAlphas[1] * flCfs[1] ) + ( flAlphas[2] * flCfs[2] ); + } + + if( pNormal ) + { + Vector edgeU = vecVerts[2] - vecVerts[0]; + Vector edgeV = vecVerts[1] - vecVerts[0]; + *pNormal = CrossProduct( edgeU, edgeV ); + VectorNormalize( *pNormal ); + } + } + else + { + if ( !bBackup ) + { + DispUVToSurf_TriTLToBR_1( vecIntersectPoint, nSnapU, nNextU, nSnapV, nNextV, vecPoint, pNormal, pAlpha, true ); + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCoreDispInfo::DispUVToSurf_TriTLToBR( Vector &vecPoint, Vector *pNormal, float *pAlpha, + float flU, float flV, const Vector &vecIntersectPoint ) +{ + const float TRIEDGE_EPSILON = 0.00001f; + + int nWidth = GetWidth(); + int nHeight = GetHeight(); + + int nSnapU = static_cast( flU ); + int nSnapV = static_cast( flV ); + int nNextU = nSnapU + 1; + int nNextV = nSnapV + 1; + if ( nNextU == nWidth) { --nNextU; } + if ( nNextV == nHeight ) { --nNextV; } + + float flFracU = flU - static_cast( nSnapU ); + float flFracV = flV - static_cast( nSnapV ); + + if ( ( flFracU + flFracV ) >= ( 1.0f + TRIEDGE_EPSILON ) ) + { + DispUVToSurf_TriTLToBR_1( vecIntersectPoint, nSnapU, nNextU, nSnapV, nNextV, vecPoint, pNormal, pAlpha, false ); + } + else + { + DispUVToSurf_TriTLToBR_2( vecIntersectPoint, nSnapU, nNextU, nSnapV, nNextV, vecPoint, pNormal, pAlpha, false ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCoreDispInfo::DispUVToSurf_TriBLToTR_1( const Vector &vecIntersectPoint, + int nSnapU, int nNextU, int nSnapV, int nNextV, + Vector &vecPoint, Vector *pNormal, float *pAlpha, + bool bBackup ) +{ + int nWidth = GetWidth(); + + int nIndices[3]; + nIndices[0] = nSnapV * nWidth + nSnapU; + nIndices[1] = nNextV * nWidth + nSnapU; + nIndices[2] = nNextV * nWidth + nNextU; + + Vector vecFlatVerts[3], vecVerts[3]; + float flAlphas[3]; + for ( int iVert = 0; iVert < 3; ++iVert ) + { + vecFlatVerts[iVert] = m_pVerts[nIndices[iVert]].m_FlatVert; + vecVerts[iVert] = m_pVerts[nIndices[iVert]].m_Vert; + flAlphas[iVert] = m_pVerts[nIndices[iVert]].m_Alpha; + } + + if ( nSnapU == nNextU ) + { + if ( nSnapV == nNextV ) + { + vecPoint = vecVerts[0]; + *pAlpha = flAlphas[0]; + } + else + { + float flFrac = ( vecIntersectPoint - vecFlatVerts[0] ).Length() / ( vecFlatVerts[2] - vecFlatVerts[0] ).Length(); + vecPoint = vecVerts[0] + ( flFrac * ( vecVerts[2] - vecVerts[0] ) ); + + if ( pAlpha ) + { + *pAlpha = flAlphas[0] + ( flFrac * ( flAlphas[2] - flAlphas[0] ) ); + } + } + + if( pNormal ) + { + Vector edgeU = vecVerts[2] - vecVerts[1]; + Vector edgeV = vecVerts[0] - vecVerts[1]; + *pNormal = CrossProduct( edgeU, edgeV ); + VectorNormalize( *pNormal ); + } + } + else if ( nSnapV == nNextV ) + { + if ( nSnapU == nNextU ) + { + vecPoint = vecVerts[0]; + *pAlpha = flAlphas[0]; + } + else + { + float flFrac = ( vecIntersectPoint - vecFlatVerts[0] ).Length() / ( vecFlatVerts[2] - vecFlatVerts[0] ).Length(); + vecPoint = vecVerts[0] + ( flFrac * ( vecVerts[2] - vecVerts[0] ) ); + + if ( pAlpha ) + { + *pAlpha = flAlphas[0] + ( flFrac * ( flAlphas[2] - flAlphas[0] ) ); + } + } + + if( pNormal ) + { + Vector edgeU = vecVerts[2] - vecVerts[1]; + Vector edgeV = vecVerts[0] - vecVerts[1]; + *pNormal = CrossProduct( edgeV, edgeU ); + VectorNormalize( *pNormal ); + } + } + else + { + float flCfs[3]; + if ( CalcBarycentricCooefs( vecFlatVerts[0], vecFlatVerts[1], vecFlatVerts[2], vecIntersectPoint, flCfs[0], flCfs[1], flCfs[2] ) ) + { + vecPoint = ( vecVerts[0] * flCfs[0] ) + ( vecVerts[1] * flCfs[1] ) + ( vecVerts[2] * flCfs[2] ); + + if( pAlpha ) + { + *pAlpha = ( flAlphas[0] * flCfs[0] ) + ( flAlphas[1] * flCfs[1] ) + ( flAlphas[2] * flCfs[2] ); + } + + if( pNormal ) + { + Vector edgeU = vecVerts[2] - vecVerts[1]; + Vector edgeV = vecVerts[0] - vecVerts[1]; + *pNormal = CrossProduct( edgeV, edgeU ); + VectorNormalize( *pNormal ); + } + } + else + { + if ( !bBackup ) + { + DispUVToSurf_TriBLToTR_2( vecIntersectPoint, nSnapU, nNextU, nSnapV, nNextV, vecPoint, pNormal, pAlpha, true ); + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCoreDispInfo::DispUVToSurf_TriBLToTR_2( const Vector &vecIntersectPoint, + int nSnapU, int nNextU, int nSnapV, int nNextV, + Vector &vecPoint, Vector *pNormal, float *pAlpha, + bool bBackup ) +{ + int nWidth = GetWidth(); + + int nIndices[3]; + nIndices[0] = nSnapV * nWidth + nSnapU; + nIndices[1] = nNextV * nWidth + nNextU; + nIndices[2] = nSnapV * nWidth + nNextU; + + Vector vecFlatVerts[3], vecVerts[3]; + float flAlphas[3]; + for ( int iVert = 0; iVert < 3; ++iVert ) + { + vecFlatVerts[iVert] = m_pVerts[nIndices[iVert]].m_FlatVert; + vecVerts[iVert] = m_pVerts[nIndices[iVert]].m_Vert; + flAlphas[iVert] = m_pVerts[nIndices[iVert]].m_Alpha; + } + + if ( nSnapU == nNextU ) + { + if ( nSnapV == nNextV ) + { + vecPoint = vecVerts[0]; + *pAlpha = flAlphas[0]; + } + else + { + float flFrac = ( vecIntersectPoint - vecFlatVerts[0] ).Length() / ( vecFlatVerts[1] - vecFlatVerts[0] ).Length(); + vecPoint = vecVerts[0] + ( flFrac * ( vecVerts[1] - vecVerts[0] ) ); + + if ( pAlpha ) + { + *pAlpha = flAlphas[0] + ( flFrac * ( flAlphas[1] - flAlphas[0] ) ); + } + } + + if( pNormal ) + { + Vector edgeU = vecVerts[0] - vecVerts[2]; + Vector edgeV = vecVerts[1] - vecVerts[2]; + *pNormal = CrossProduct( edgeV, edgeU ); + VectorNormalize( *pNormal ); + } + } + else if ( nSnapV == nNextV ) + { + if ( nSnapU == nNextU ) + { + vecPoint = vecVerts[0]; + *pAlpha = flAlphas[0]; + } + else + { + float flFrac = ( vecIntersectPoint - vecFlatVerts[0] ).Length() / ( vecFlatVerts[2] - vecFlatVerts[0] ).Length(); + vecPoint = vecVerts[0] + ( flFrac * ( vecVerts[2] - vecVerts[0] ) ); + + if ( pAlpha ) + { + *pAlpha = flAlphas[0] + ( flFrac * ( flAlphas[2] - flAlphas[0] ) ); + } + } + + if( pNormal ) + { + Vector edgeU = vecVerts[0] - vecVerts[2]; + Vector edgeV = vecVerts[1] - vecVerts[2]; + *pNormal = CrossProduct( edgeV, edgeU ); + VectorNormalize( *pNormal ); + } + } + else + { + float flCfs[3]; + if ( CalcBarycentricCooefs( vecFlatVerts[0], vecFlatVerts[1], vecFlatVerts[2], vecIntersectPoint, flCfs[0], flCfs[1], flCfs[2] ) ) + { + vecPoint = ( vecVerts[0] * flCfs[0] ) + ( vecVerts[1] * flCfs[1] ) + ( vecVerts[2] * flCfs[2] ); + + if( pAlpha ) + { + *pAlpha = ( flAlphas[0] * flCfs[0] ) + ( flAlphas[1] * flCfs[1] ) + ( flAlphas[2] * flCfs[2] ); + } + + if( pNormal ) + { + Vector edgeU = vecVerts[0] - vecVerts[2]; + Vector edgeV = vecVerts[1] - vecVerts[2]; + *pNormal = CrossProduct( edgeV, edgeU ); + VectorNormalize( *pNormal ); + } + } + else + { + if ( !bBackup ) + { + DispUVToSurf_TriBLToTR_1( vecIntersectPoint, nSnapU, nNextU, nSnapV, nNextV, vecPoint, pNormal, pAlpha, true ); + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCoreDispInfo::DispUVToSurf_TriBLToTR( Vector &vecPoint, Vector *pNormal, float *pAlpha, + float flU, float flV, const Vector &vecIntersectPoint ) +{ + int nWidth = GetWidth(); + int nHeight = GetHeight(); + + int nSnapU = static_cast( flU ); + int nSnapV = static_cast( flV ); + int nNextU = nSnapU + 1; + int nNextV = nSnapV + 1; + if ( nNextU == nWidth) { --nNextU; } + if ( nNextV == nHeight ) { --nNextV; } + + float flFracU = flU - static_cast( nSnapU ); + float flFracV = flV - static_cast( nSnapV ); + + if( flFracU < flFracV ) + { + DispUVToSurf_TriBLToTR_1( vecIntersectPoint, nSnapU, nNextU, nSnapV, nNextV, vecPoint, pNormal, pAlpha, false ); + } + else + { + DispUVToSurf_TriBLToTR_2( vecIntersectPoint, nSnapU, nNextU, nSnapV, nNextV, vecPoint, pNormal, pAlpha, false ); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::DispUVToSurf( Vector2D const &dispUV, Vector &vecPoint, + Vector *pNormal, float *pAlpha ) +{ + // Check to see that the point is on the surface. + if ( dispUV.x < 0.0f || dispUV.x > 1.0f || dispUV.y < 0.0f || dispUV.y > 1.0f ) + return; + + // Get the base surface points. + Vector vecIntersectPoint; + CCoreDispSurface *pSurf = GetSurface(); + PointInQuadFromBarycentric( pSurf->GetPoint( 0 ), pSurf->GetPoint( 3 ), pSurf->GetPoint( 2 ), pSurf->GetPoint( 1 ), dispUV, vecIntersectPoint ); + + // Get the displacement power. + int nWidth = GetWidth(); + int nHeight = GetHeight(); + + // Scale the U, V coordinates to the displacement grid size. + float flU = dispUV.x * ( static_cast( nWidth ) - 1.000001f ); + float flV = dispUV.y * ( static_cast( nHeight ) - 1.000001f ); + + // Find the base U, V. + int nSnapU = static_cast( flU ); + int nSnapV = static_cast( flV ); + + // Use this to get the triangle orientation. + bool bOdd = ( ( ( nSnapV * nWidth ) + nSnapU ) % 2 == 1 ); + + // Top Left to Bottom Right + if( bOdd ) + { + DispUVToSurf_TriTLToBR( vecPoint, pNormal, pAlpha, flU, flV, vecIntersectPoint ); + } + // Bottom Left to Top Right + else + { + DispUVToSurf_TriBLToTR( vecPoint, pNormal, pAlpha, flU, flV, vecIntersectPoint ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Create bounding boxes around pairs of triangles (in a grid-like) +// fashion; used for culling +//----------------------------------------------------------------------------- +void CCoreDispInfo::CreateBoundingBoxes( CoreDispBBox_t *pBBox, int count ) +{ + // + // Initialize the bounding boxes. + // + int iBox; + for( iBox = 0; iBox < count; ++iBox ) + { + pBBox[iBox].vMin.Init( FLT_MAX, FLT_MAX, FLT_MAX ); + pBBox[iBox].vMax.Init( FLT_MIN, FLT_MIN, FLT_MIN ); + } + + // Get the width and height of the displacement surface. + int nHeight = GetHeight(); + int nWidth = GetWidth(); + + // Find bounding box of every two consecutive triangles + iBox = 0; + int nIndex = 0; + for( int iHgt = 0; iHgt < ( nHeight - 1 ); ++iHgt ) + { + for( int iWid = 0; iWid < ( nWidth - 1 ); ++iWid ) + { + for( int iPoint = 0; iPoint < 4; ++iPoint ) + { + switch( iPoint ) + { + case 0: { nIndex = ( nHeight * iHgt ) + iWid; break; } + case 1: { nIndex = ( nHeight * ( iHgt + 1 ) ) + iWid; break; } + case 2: { nIndex = ( nHeight * ( iHgt + 1 ) ) + ( iWid + 1 ); break; } + case 3: { nIndex = ( nHeight * iHgt ) + ( iWid + 1 ); break; } + default: { break; } + } + + Vector vecPoint; + GetVert( nIndex, vecPoint ); + if( vecPoint[0] < pBBox[iBox].vMin[0] ) { pBBox[iBox].vMin[0] = vecPoint[0]; } + if( vecPoint[1] < pBBox[iBox].vMin[1] ) { pBBox[iBox].vMin[1] = vecPoint[1]; } + if( vecPoint[2] < pBBox[iBox].vMin[2] ) { pBBox[iBox].vMin[2] = vecPoint[2]; } + + if( vecPoint[0] > pBBox[iBox].vMax[0] ) { pBBox[iBox].vMax[0] = vecPoint[0]; } + if( vecPoint[1] > pBBox[iBox].vMax[1] ) { pBBox[iBox].vMax[1] = vecPoint[1]; } + if( vecPoint[2] > pBBox[iBox].vMax[2] ) { pBBox[iBox].vMax[2] = vecPoint[2]; } + } + + iBox++; + } + } + + // Verify. + Assert( iBox == count ); + + // Bloat. + for ( iBox = 0; iBox < count; ++iBox ) + { + for( int iAxis = 0; iAxis < 3; ++iAxis ) + { + pBBox[iBox].vMin[iAxis] -= 1.0f; + pBBox[iBox].vMax[iAxis] += 1.0f; + } + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline bool PointInDispBBox( CoreDispBBox_t *pBox, const Vector &vecPoint ) +{ + // Check to see if point lies in box + if( ( vecPoint.x < pBox->vMin.x ) || ( vecPoint.x > pBox->vMax.x ) ) + return false; + + if( ( vecPoint.y < pBox->vMin.y ) || ( vecPoint.y > pBox->vMax.y ) ) + return false; + + if( ( vecPoint.z < pBox->vMin.z ) || ( vecPoint.z > pBox->vMax.z ) ) + return false; + + return true; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CCoreDispInfo::GetTriangleIndicesForDispBBox( int nIndex, int nTris[2][3] ) +{ + // Test to see whether or not the index is odd. + bool bOdd = ( ( nIndex % 2 ) == 1 ); + + int nWidth = GetWidth(); + + // Tris for TLtoBR + if ( bOdd ) + { + nTris[0][0] = nIndex; + nTris[0][1] = nIndex + nWidth; + nTris[0][2] = nIndex + 1; + + nTris[1][0] = nIndex + 1; + nTris[1][1] = nIndex + nWidth; + nTris[1][2] = nIndex + nWidth + 1; + } + // Tris for BLtoTR + else + { + nTris[0][0] = nIndex; + nTris[0][1] = nIndex + nWidth; + nTris[0][2] = nIndex + nWidth + 1; + + nTris[1][0] = nIndex; + nTris[1][1] = nIndex + nWidth + 1; + nTris[1][2] = nIndex + 1; + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool CCoreDispInfo::SurfToBaseFacePlane( Vector const &surfPt, Vector &planePt ) +{ + // Create bounding boxes + int nBoxCount = ( GetHeight() - 1 ) * ( GetWidth() - 1 ); + CoreDispBBox_t *pBBox = new CoreDispBBox_t[nBoxCount]; + CreateBoundingBoxes( pBBox, nBoxCount ); + + // Use the boxes as a first-pass culling mechanism. + for( int iBox = 0; iBox < nBoxCount; ++iBox ) + { + // Get the current displacement triangle-pair bounding-box. + CoreDispBBox_t *pBox = &pBBox[iBox]; + if( !pBox ) + continue; + + // Check the point against the current displacement bounding-box. + if ( !PointInDispBBox( pBox, surfPt ) ) + continue; + + // Point lies within the bounding box. + int nIndex = iBox + ( iBox / ( GetWidth() - 1 ) ); + + // Get the triangle coordinates for this box. + int aTris[2][3]; + GetTriangleIndicesForDispBBox( nIndex, aTris ); + + // Barycentrically test the triangles on the displacement surface. + Vector vecPoints[3]; + for ( int iTri = 0; iTri < 2; ++iTri ) + { + for ( int iVert = 0; iVert < 3; ++iVert ) + { + GetVert( aTris[iTri][iVert], vecPoints[iVert] ); + } + + float c[3]; + if ( CalcBarycentricCooefs( vecPoints[0], vecPoints[1], vecPoints[2], surfPt, c[0], c[1], c[2] ) ) + { + Vector vecFlatPoints[3]; + for ( int iVert = 0; iVert < 3; ++iVert ) + { + GetFlatVert( aTris[iTri][iVert], vecFlatPoints[iVert] ); + } + + planePt = ( vecFlatPoints[0] * c[0] ) + ( vecFlatPoints[1] * c[1] ) + ( vecFlatPoints[2] * c[2] ); + + // Delete temporary memory. + delete [] pBBox; + return true; + } + } + } + + // Delete temporary memory + delete [] pBBox; + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CCoreDispInfo::GetTriCount( void ) +{ + return ( ( GetHeight() - 1 ) * ( GetWidth() -1 ) * 2 ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCoreDispInfo::GetTriIndices( int iTri, unsigned short &v1, unsigned short &v2, unsigned short &v3 ) +{ + // Verify we have the correct data (only build when collision data is built). + if ( !m_pTris || ( iTri < 0 ) || ( iTri >= GetTriCount() ) ) + { + Assert( iTri >= 0 ); + Assert( iTri < GetTriCount() ); + Assert( m_pTris ); + return; + } + + CoreDispTri_t *pTri = &m_pTris[iTri]; + v1 = pTri->m_iIndex[0]; + v2 = pTri->m_iIndex[1]; + v3 = pTri->m_iIndex[2]; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCoreDispInfo::SetTriIndices( int iTri, unsigned short v1, unsigned short v2, unsigned short v3 ) +{ + // Verify we have the correct data (only build when collision data is built). + if ( !m_pTris || ( iTri < 0 ) || ( iTri >= GetTriCount() ) ) + { + Assert( iTri >= 0 ); + Assert( iTri < GetTriCount() ); + Assert( m_pTris ); + return; + } + + CoreDispTri_t *pTri = &m_pTris[iTri]; + pTri->m_iIndex[0] = v1; + pTri->m_iIndex[1] = v2; + pTri->m_iIndex[2] = v3; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCoreDispInfo::GetTriPos( int iTri, Vector &v1, Vector &v2, Vector &v3 ) +{ + // Verify we have the correct data (only build when collision data is built). + if ( !m_pTris || ( iTri < 0 ) || ( iTri >= GetTriCount() ) ) + { + Assert( iTri >= 0 ); + Assert( iTri < GetTriCount() ); + Assert( m_pTris ); + return; + } + + CoreDispTri_t *pTri = &m_pTris[iTri]; + v1 = m_pVerts[pTri->m_iIndex[0]].m_Vert; + v2 = m_pVerts[pTri->m_iIndex[1]].m_Vert; + v3 = m_pVerts[pTri->m_iIndex[2]].m_Vert; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCoreDispInfo::InitTris( void ) +{ + // Verify we have the correct data (only build when collision data is built). + if ( !m_pTris ) + { + Assert( m_pTris ); + return; + } + + int nTriCount = GetTriCount(); + for ( int iTri = 0; iTri < nTriCount; ++iTri ) + { + m_pTris[iTri].m_uiTags = 0; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCoreDispInfo::CreateTris( void ) +{ + // Verify we have the correct data (only build when collision data is built). + if ( !m_pTris ) + { + Assert( m_pTris ); + return; + } + + // Extra sanity check if wanted! + Assert( GetTriCount() == ( m_RenderIndexCount / 3 ) ); + + int nTriCount = GetTriCount(); + for ( int iTri = 0, iRender = 0; iTri < nTriCount; ++iTri, iRender += 3 ) + { + m_pTris[iTri].m_iIndex[0] = m_RenderIndices[iRender]; + m_pTris[iTri].m_iIndex[1] = m_RenderIndices[iRender+1]; + m_pTris[iTri].m_iIndex[2] = m_RenderIndices[iRender+2]; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CCoreDispInfo::IsTriWalkable( int iTri ) +{ + if ( IsTriTag( iTri, COREDISPTRI_TAG_FORCE_WALKABLE_BIT ) ) + { + return IsTriTag( iTri, COREDISPTRI_TAG_FORCE_WALKABLE_VAL ); + } + + return IsTriTag( iTri, COREDISPTRI_TAG_WALKABLE ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CCoreDispInfo::IsTriBuildable( int iTri ) +{ + if ( IsTriTag( iTri, COREDISPTRI_TAG_FORCE_BUILDABLE_BIT ) ) + { + return IsTriTag( iTri, COREDISPTRI_TAG_FORCE_BUILDABLE_VAL ); + } + + return IsTriTag( iTri, COREDISPTRI_TAG_BUILDABLE ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CCoreDispInfo::IsTriRemove( int iTri ) +{ + return IsTriTag( iTri, COREDISPTRI_TAG_FORCE_REMOVE_BIT ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCoreDispInfo::Position_Update( int iVert, Vector vecPos ) +{ + Vector vSPos, vFlat; + GetFlatVert( iVert, vFlat ); + GetSubdivPosition( iVert, vSPos ); + + Vector vSeg; + vSeg = vecPos - vFlat; + vSeg -= vSPos; + + // Subtract out the elevation. + float elev = GetElevation(); + if( elev != 0.0 ) + { + Vector vNormal; + GetSurface()->GetNormal( vNormal ); + vNormal *= elev; + + vSeg -= vNormal; + } + + float flDistance = VectorNormalize( vSeg ); + + SetFieldVector( iVert, vSeg ); + SetFieldDistance( iVert, flDistance ); +} diff --git a/sp/src/public/builddisp.h b/sp/src/public/builddisp.h new file mode 100644 index 00000000..c6ef149e --- /dev/null +++ b/sp/src/public/builddisp.h @@ -0,0 +1,1460 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//=============================================================================// + +#ifndef BUILDDISP_H +#define BUILDDISP_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "commonmacros.h" +#include "tier0/dbg.h" +#include "bspfile.h" +#include "mathlib/mathlib.h" +#include "mathlib/bumpvects.h" +#include "disp_common.h" +#include "bitvec.h" + +#define DISP_ALPHA_PROP_DELTA 382.5f + +class CCoreDispInfo; + +struct CoreDispBBox_t +{ + Vector vMin, vMax; +}; + +//========================================================================= +// +// Surface Class - interfacing class (fill in with MapFace, dface_t, and +// msurface_t) +// +class CCoreDispSurface +{ +public: + + enum { QUAD_POINT_COUNT = 4 }; + enum { MAX_CORNER_NEIGHBOR_COUNT = 16 }; + + CCoreDispSurface(); + + //========================================================================= + // + // initialization + // + void Init( void ); + + //========================================================================= + // + // parent surface id - index to CMapFace, dface_t, or msurface_t + // + inline void SetHandle( int handle ); + inline int GetHandle( void ); + + //========================================================================= + // + // vertex data - pos, normal, texture, lightmap, alpha, etc... + // + inline void SetPointCount( int count ); + inline int GetPointCount( void ) const; + + inline void SetPoint( int index, Vector const &pt ); + inline void GetPoint( int index, Vector& pt ) const; + inline Vector const& GetPoint( int index ) const; + + inline void SetPointNormal( int index, Vector const &normal ); + inline void GetPointNormal( int index, Vector &normal ); + inline void SetTexCoord( int index, Vector2D const& texCoord ); + inline void GetTexCoord( int index, Vector2D& texCoord ) const; + + inline void SetLuxelCoord( int bumpIndex, int index, Vector2D const& luxelCoord ); + inline void GetLuxelCoord( int bumpIndex, int index, Vector2D& luxelCoord ) const; + inline void SetLuxelCoords( int bumpIndex, Vector2D const coords[4] ); + inline void GetLuxelCoords( int bumpIndex, Vector2D coords[4] ) const; + + inline void SetLuxelU( int nU ) { m_nLuxelU = nU; } + inline int GetLuxelU( void ) { return m_nLuxelU; } + inline void SetLuxelV( int nV ) { m_nLuxelV = nV; } + inline int GetLuxelV( void ) { return m_nLuxelV; } + bool CalcLuxelCoords( int nLuxels, bool bAdjust, const Vector &vecU, const Vector &vecV ); + + inline void SetAlpha( int index, float alpha ); + inline float GetAlpha( int const index ) const; + + //========================================================================= + // + // utils + // + inline void GetNormal( Vector& normal ); + inline void SetFlags( int flag ); + inline int GetFlags( void ); + inline void SetContents( int contents ); + inline int GetContents( void ); + + //========================================================================= + // + // create utils (texture axis not use anymore but here to support older maps) + // + inline void SetSAxis( Vector const &axis ); + inline void GetSAxis( Vector &axis ); + inline void SetTAxis( Vector const &axis ); + inline void GetTAxis( Vector &axis ); + + inline void SetPointStartIndex( int index ); + inline int GetPointStartIndex( void ); + inline void SetPointStart( Vector const &pt ); + inline void GetPointStart( Vector &pt ); + + // Used by the tools to set the neighbor data from the BSP file. + void SetNeighborData( const CDispNeighbor edgeNeighbors[4], const CDispCornerNeighbors cornerNeighbors[4] ); + + void GeneratePointStartIndexFromMappingAxes( Vector const &sAxis, Vector const &tAxis ); + int GenerateSurfPointStartIndex( void ); + int FindSurfPointStartIndex( void ); + void AdjustSurfPointData( void ); + + // Indexed by CORNER_ defines. + CDispCornerNeighbors* GetCornerNeighbors( int iCorner ) { Assert( iCorner >= 0 && iCorner < ARRAYSIZE( m_CornerNeighbors ) ); return &m_CornerNeighbors[iCorner]; } + const CDispCornerNeighbors* GetCornerNeighbors( int iCorner ) const { Assert( iCorner >= 0 && iCorner < ARRAYSIZE( m_CornerNeighbors ) ); return &m_CornerNeighbors[iCorner]; } + + // Indexed by CORNER_ defines. + int GetCornerNeighborCount( int iCorner ) const { return GetCornerNeighbors( iCorner )->m_nNeighbors; } + int GetCornerNeighbor( int iCorner, int iNeighbor ) const { Assert( iNeighbor >= 0 && iNeighbor < GetCornerNeighbors(iCorner)->m_nNeighbors ); return GetCornerNeighbors( iCorner )->m_Neighbors[iNeighbor]; } + + CDispNeighbor* GetEdgeNeighbor( int iEdge ) { Assert( iEdge >= 0 && iEdge < ARRAYSIZE( m_EdgeNeighbors ) ); return &m_EdgeNeighbors[iEdge]; } + const CDispNeighbor* GetEdgeNeighbor( int iEdge ) const { Assert( iEdge >= 0 && iEdge < ARRAYSIZE( m_EdgeNeighbors ) ); return &m_EdgeNeighbors[iEdge]; } + + +protected: + + // Utility + bool LongestInU( const Vector &vecU, const Vector &vecV ); + + + int m_Index; // parent face (CMapFace, dface_t, msurface_t) index "handle" + + int m_PointCount; // number of points in the face (should be 4!) + Vector m_Points[QUAD_POINT_COUNT]; // points + Vector m_Normals[QUAD_POINT_COUNT]; // normals at points + Vector2D m_TexCoords[QUAD_POINT_COUNT]; // texture coordinates at points + Vector2D m_LuxelCoords[NUM_BUMP_VECTS+1][QUAD_POINT_COUNT]; // lightmap coordinates at points + float m_Alphas[QUAD_POINT_COUNT]; // alpha at points + + // Luxels sizes + int m_nLuxelU; + int m_nLuxelV; + + // Straight from the BSP file. + CDispNeighbor m_EdgeNeighbors[4]; + CDispCornerNeighbors m_CornerNeighbors[4]; + + int m_Flags; // surface flags - inherited from the "parent" face + int m_Contents; // contents flags - inherited from the "parent" face + + Vector sAxis; // used to generate start disp orientation (old method) + Vector tAxis; // used to generate start disp orientation (old method) + int m_PointStartIndex; // index to the starting point -- for saving starting point + Vector m_PointStart; // starting point used to determine the orientation of the displacement map on the surface +}; + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::SetHandle( int handle ) +{ + m_Index = handle; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int CCoreDispSurface::GetHandle( void ) +{ + return m_Index; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::SetPointCount( int count ) +{ + // quad only -- currently! + if( count != 4 ) + return; + m_PointCount = count; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int CCoreDispSurface::GetPointCount( void ) const +{ + return m_PointCount; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::SetPoint( int index, Vector const &pt ) +{ + Assert( index >= 0 ); + Assert( index < QUAD_POINT_COUNT ); + VectorCopy( pt, m_Points[index] ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::GetPoint( int index, Vector &pt ) const +{ + Assert( index >= 0 ); + Assert( index < QUAD_POINT_COUNT ); + VectorCopy( m_Points[index], pt ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline Vector const& CCoreDispSurface::GetPoint( int index ) const +{ + Assert( index >= 0 ); + Assert( index < QUAD_POINT_COUNT ); + return m_Points[index]; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::SetPointNormal( int index, Vector const &normal ) +{ + Assert( index >= 0 ); + Assert( index < QUAD_POINT_COUNT ); + VectorCopy( normal, m_Normals[index] ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::GetPointNormal( int index, Vector& normal ) +{ + Assert( index >= 0 ); + Assert( index < QUAD_POINT_COUNT ); + VectorCopy( m_Normals[index], normal ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::SetTexCoord( int index, Vector2D const& texCoord ) +{ + Assert( index >= 0 ); + Assert( index < QUAD_POINT_COUNT ); + Vector2DCopy( texCoord, m_TexCoords[index] ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::GetTexCoord( int index, Vector2D& texCoord ) const +{ + Assert( index >= 0 ); + Assert( index < QUAD_POINT_COUNT ); + Vector2DCopy( m_TexCoords[index], texCoord ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::SetLuxelCoord( int bumpIndex, int index, Vector2D const& luxelCoord ) +{ + Assert( index >= 0 ); + Assert( index < QUAD_POINT_COUNT ); + Assert( bumpIndex >= 0 ); + Assert( bumpIndex < NUM_BUMP_VECTS + 1 ); + Vector2DCopy( luxelCoord, m_LuxelCoords[bumpIndex][index] ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::GetLuxelCoord( int bumpIndex, int index, Vector2D& luxelCoord ) const +{ + Assert( index >= 0 ); + Assert( index < QUAD_POINT_COUNT ); + Assert( bumpIndex >= 0 ); + Assert( bumpIndex < NUM_BUMP_VECTS + 1 ); + Vector2DCopy( m_LuxelCoords[bumpIndex][index], luxelCoord ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::SetLuxelCoords( int bumpIndex, Vector2D const luxelCoords[4] ) +{ + Assert( bumpIndex >= 0 ); + Assert( bumpIndex < NUM_BUMP_VECTS + 1 ); + for( int i=0; i < 4; i++ ) + Vector2DCopy( luxelCoords[i], m_LuxelCoords[bumpIndex][i] ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::GetLuxelCoords( int bumpIndex, Vector2D luxelCoords[4] ) const +{ + Assert( bumpIndex >= 0 ); + Assert( bumpIndex < NUM_BUMP_VECTS + 1 ); + for( int i=0; i < 4; i++ ) + Vector2DCopy( m_LuxelCoords[bumpIndex][i], luxelCoords[i] ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::SetAlpha( int index, float alpha ) +{ + Assert( index >= 0 ); + Assert( index < QUAD_POINT_COUNT ); + m_Alphas[index] = alpha; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline float CCoreDispSurface::GetAlpha( int const index ) const +{ + Assert( index >= 0 ); + Assert( index < QUAD_POINT_COUNT ); + return m_Alphas[index]; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::SetFlags( int flag ) +{ + m_Flags = flag; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int CCoreDispSurface::GetFlags( void ) +{ + return m_Flags; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::SetContents( int contents ) +{ + m_Contents = contents; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int CCoreDispSurface::GetContents( void ) +{ + return m_Contents; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::SetSAxis( Vector const &axis ) +{ + VectorCopy( axis, sAxis ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::GetSAxis( Vector& axis ) +{ + VectorCopy( sAxis, axis ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::SetTAxis( Vector const &axis ) +{ + VectorCopy( axis, tAxis ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::GetTAxis( Vector& axis ) +{ + VectorCopy( tAxis, axis ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::SetPointStartIndex( int index ) +{ + Assert( index >= 0 ); + Assert( index < QUAD_POINT_COUNT ); + m_PointStartIndex = index; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int CCoreDispSurface::GetPointStartIndex( void ) +{ + return m_PointStartIndex; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::SetPointStart( Vector const& pt ) +{ + VectorCopy( pt, m_PointStart ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::GetPointStart( Vector& pt ) +{ + VectorCopy( m_PointStart, pt ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispSurface::GetNormal( Vector& normal ) +{ + // + // calculate the displacement surface normal + // + Vector tmp[2]; + VectorSubtract( m_Points[1], m_Points[0], tmp[0] ); + VectorSubtract( m_Points[3], m_Points[0], tmp[1] ); + CrossProduct( tmp[1], tmp[0], normal ); + VectorNormalize( normal ); +} + + +//========================================================================= +// +// Node Class (for displacement quad-tree) +// +class CCoreDispNode +{ +public: + + enum { MAX_NEIGHBOR_NODE_COUNT = 4 }; + enum { MAX_NEIGHBOR_VERT_COUNT = 8 }; + enum { MAX_SURF_AT_NODE_COUNT = 8 }; + + //========================================================================= + // + // Initialization + // + void Init( void ); + + //========================================================================= + // + // + // + inline void SetBoundingBox( Vector const& bMin, Vector const& bMax ); + inline void GetBoundingBox( Vector& bMin, Vector& bMax ); + + inline void SetErrorTerm( float errorTerm ); + inline float GetErrorTerm( void ); + + inline void SetNeighborNodeIndex( int dir, int index ); + inline int GetNeighborNodeIndex( int dir ); + + inline void SetCenterVertIndex( int index ); + inline int GetCenterVertIndex( void ); + inline void SetNeighborVertIndex( int dir, int index ); + inline int GetNeighborVertIndex( int dir ); + + inline void SetTriBoundingBox( int index, Vector const& bMin, Vector const& bMax ); + inline void GetTriBoundingBox( int index, Vector& bMin, Vector& bMax ); + inline void SetTriPlane( int index, Vector const& normal, float dist ); + inline void GetTriPlane( int index, cplane_t *plane ); + + inline void SetRayBoundingBox( int index, Vector const& bMin, Vector const& bMax ); + inline void GetRayBoundingBox( int index, Vector& bMin, Vector& bMax ); + + //========================================================================= + // + // Node Functions (friend functions) + // + friend int GetNodeLevel( int index ); + friend int GetNodeCount( int power ); + friend int GetNodeParent( int index ); + friend int GetNodeChild( int power, int index, int direction ); + friend int GetNodeNeighborNode( int power, int index, int direction, int level ); + friend int GetNodeNeighborNodeFromNeighborSurf( int power, int index, int direction, int level, int neighborOrient ); + friend int GetNodeMinNodeAtLevel( int level ); + + friend void GetDispNodeTriVerts( CCoreDispInfo *pDisp, int nodeIndex, int triIndex, float *v1, float *v2, float *v3 ); + + friend void GetComponentsFromNodeIndex( int index, int *x, int *y ); + friend int GetNodeIndexFromComponents( int x, int y ); + +protected: + + Vector m_BBox[2]; // displacement node bounding box (take into account size of children) + float m_ErrorTerm; // LOD error term (the "precision" of the representation of the surface at this node's level) + int m_VertIndex; // the node's vertex index (center vertex of node) + int m_NeighborVertIndices[MAX_NEIGHBOR_VERT_COUNT]; // all other vertex indices in node (maximally creates 8 trianglar surfaces) + Vector m_SurfBBoxes[MAX_SURF_AT_NODE_COUNT][2]; // surface bounding boxes - old method + cplane_t m_SurfPlanes[MAX_SURF_AT_NODE_COUNT]; // surface plane info - old method + + Vector m_RayBBoxes[4][2]; // bounding boxes for ray traces +}; + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispNode::SetBoundingBox( Vector const& bMin, Vector const& bMax ) +{ + VectorCopy( bMin, m_BBox[0] ); + VectorCopy( bMax, m_BBox[1] ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispNode::GetBoundingBox( Vector& bMin, Vector& bMax ) +{ + VectorCopy( m_BBox[0], bMin ); + VectorCopy( m_BBox[1], bMax ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispNode::SetErrorTerm( float errorTerm ) +{ + m_ErrorTerm = errorTerm; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline float CCoreDispNode::GetErrorTerm( void ) +{ + return m_ErrorTerm; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispNode::SetCenterVertIndex( int index ) +{ + m_VertIndex = index; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int CCoreDispNode::GetCenterVertIndex( void ) +{ + return m_VertIndex; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispNode::SetNeighborVertIndex( int dir, int index ) +{ + Assert( dir >= 0 ); + Assert( dir < MAX_NEIGHBOR_VERT_COUNT ); + m_NeighborVertIndices[dir] = index; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int CCoreDispNode::GetNeighborVertIndex( int dir ) +{ + Assert( dir >= 0 ); + Assert( dir < MAX_NEIGHBOR_VERT_COUNT ); + return m_NeighborVertIndices[dir]; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispNode::SetTriBoundingBox( int index, Vector const& bMin, Vector const& bMax ) +{ + Assert( index >= 0 ); + Assert( index < MAX_SURF_AT_NODE_COUNT ); + VectorCopy( bMin, m_SurfBBoxes[index][0] ); + VectorCopy( bMax, m_SurfBBoxes[index][1] ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispNode::GetTriBoundingBox( int index, Vector& bMin, Vector& bMax ) +{ + Assert( index >= 0 ); + Assert( index < MAX_SURF_AT_NODE_COUNT ); + VectorCopy( m_SurfBBoxes[index][0], bMin ); + VectorCopy( m_SurfBBoxes[index][1], bMax ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispNode::SetTriPlane( int index, Vector const &normal, float dist ) +{ + Assert( index >= 0 ); + Assert( index < MAX_SURF_AT_NODE_COUNT ); + VectorCopy( normal, m_SurfPlanes[index].normal ); + m_SurfPlanes[index].dist = dist; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispNode::GetTriPlane( int index, cplane_t *plane ) +{ + Assert( index >= 0 ); + Assert( index < MAX_SURF_AT_NODE_COUNT ); + VectorCopy( m_SurfPlanes[index].normal, plane->normal ); + plane->dist = m_SurfPlanes[index].dist; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispNode::SetRayBoundingBox( int index, Vector const &bMin, Vector const &bMax ) +{ + Assert( index >= 0 ); + Assert( index < 4 ); + VectorCopy( bMin, m_RayBBoxes[index][0] ); + VectorCopy( bMax, m_RayBBoxes[index][1] ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispNode::GetRayBoundingBox( int index, Vector& bMin, Vector& bMax ) +{ + Assert( index >= 0 ); + Assert( index < 4 ); + VectorCopy( m_RayBBoxes[index][0], bMin ); + VectorCopy( m_RayBBoxes[index][1], bMax ); +} + + +//============================================================================= +// +// CCoreInfoBuilder - the primary data necessay to derive a displacement surface +// used by WorldCraft (CMapFace, CMapDisp), VRAD (dface_t, ddispinto_t), +// and the engine (msurface_t, CDispInfo) +// + +struct CoreDispVert_t +{ + Vector m_FieldVector; // displacement vector field + float m_FieldDistance; // the distances along the displacement vector normal + + Vector m_SubdivNormal; + Vector m_SubdivPos; // used the create curvature of displacements + + // generated displacement surface data + Vector m_Vert; // displacement surface vertices + Vector m_FlatVert; + Vector m_Normal; // displacement surface normals + Vector m_TangentS; // use in calculating the tangent space axes + Vector m_TangentT; // use in calculating the tangent space axes + Vector2D m_TexCoord; // displacement surface texture coordinates + Vector2D m_LuxelCoords[NUM_BUMP_VECTS+1]; // displacement surface lightmap coordinates + + // additional per-vertex data + float m_Alpha; // displacement alpha values (per displacement vertex) +}; + +// New, need to use this at the node level +#define COREDISPTRI_TAG_WALKABLE (1<<0) +#define COREDISPTRI_TAG_FORCE_WALKABLE_BIT (1<<1) +#define COREDISPTRI_TAG_FORCE_WALKABLE_VAL (1<<2) +#define COREDISPTRI_TAG_BUILDABLE (1<<3) +#define COREDISPTRI_TAG_FORCE_BUILDABLE_BIT (1<<4) +#define COREDISPTRI_TAG_FORCE_BUILDABLE_VAL (1<<5) +#define COREDISPTRI_TAG_FORCE_REMOVE_BIT (1<<6) + +struct CoreDispTri_t +{ + unsigned short m_iIndex[3]; // the three indices that make up a triangle + unsigned short m_uiTags; // walkable, buildable, etc. +}; + +class CCoreDispInfo : public CDispUtilsHelper +{ +public: + + // + // tree and displacement surface directions + // + enum { WEST = 0, + NORTH = 1, + EAST = 2, + SOUTH = 3, + SOUTHWEST = 4, + SOUTHEAST = 5, + NORTHWEST = 6, + NORTHEAST = 7 }; + +#if 0 + // + // building parameters + // + enum { BUILD_NORMALS = 0x1, + BUILD_TEXCOORDS = 0x2, + BUILD_LIGHTCOORDS = 0x4, + BUILD_LODTREE = 0x8, + BUILD_COLLISION = 0x10, + BUILD_TANGENTSPACE = 0x20 }; +#endif + + // + // surface info flags + // + enum { SURF_BUMPED = 0x1, + SURF_NOPHYSICS_COLL = 0x2, + SURF_NOHULL_COLL = 0x4, + SURF_NORAY_COLL = 0x8 }; + + enum { MAX_DISP_POWER = MAX_MAP_DISP_POWER }; + enum { MAX_VERT_COUNT = MAX_DISPVERTS }; + enum { MAX_NODE_COUNT = 85 }; + + +// Convert from a CDispUtilsHelper. +public: + + static CCoreDispInfo* FromDispUtils( CDispUtilsHelper *p ) { return (CCoreDispInfo*)p; } + + +// CDispUtilsHelper implementation. +public: + + virtual CDispNeighbor* GetEdgeNeighbor( int index ); + virtual CDispCornerNeighbors* GetCornerNeighbors( int index ); + virtual const CPowerInfo* GetPowerInfo() const; + virtual CDispUtilsHelper* GetDispUtilsByIndex( int index ); + + +public: + + //========================================================================= + // + // Creation/Destruction + // + CCoreDispInfo(); + ~CCoreDispInfo(); + + void InitSurf( int parentIndex, Vector points[4], Vector normals[4], + Vector2D texCoords[4], Vector2D lightCoords[4][4], int contents, int flags, + bool bGenerateSurfPointStart, Vector& startPoint, + bool bHasMappingAxes, Vector& uAxis, Vector& vAxis ); + + void InitDispInfo( int power, int minTess, float smoothingAngle, + float *alphas, Vector *dispVectorField, float *dispDistances ); + + // This just unpacks the contents of the verts into arrays and calls InitDispInfo. + void InitDispInfo( int power, int minTess, float smoothingAngle, const CDispVert *pVerts, const CDispTri *pTris ); + +// bool Create( int creationFlags ); + bool Create( void ); + bool CreateWithoutLOD( void ); + + //========================================================================= + // + // Parameter "Wrappers" + // + CCoreDispSurface* GetSurface() { return &m_Surf; } + const CCoreDispSurface* GetSurface() const { return &m_Surf; } + + inline CCoreDispNode *GetNode( int index ); + + inline void SetPower( int power ); + inline int GetPower( void ) const; + inline int GetPostSpacing( void ); + inline int GetWidth( void ); + inline int GetHeight( void ); + inline int GetSize( void ) const; + + // Use this disp as a CDispUtils. + void SetDispUtilsHelperInfo( CCoreDispInfo **ppListBase, int listSize ); + + void SetNeighborData( const CDispNeighbor edgeNeighbors[4], const CDispCornerNeighbors cornerNeighbors[4] ) { GetSurface()->SetNeighborData( edgeNeighbors, cornerNeighbors ); } + + // Get a corner point. Indexed by the CORNER_ defines. + const CVertIndex& GetCornerPointIndex( int index ) const { return GetPowerInfo()->GetCornerPointIndex( index ); } + const Vector& GetCornerPoint( int index ) const { return GetVert( VertIndexToInt( GetCornerPointIndex( index ) ) ); } + + inline void SetVert( int index, Vector const& vert ); + inline void GetVert( int index, Vector& vert ) const; + + inline const Vector& GetVert( int index ) const; + inline const Vector& GetVert( const CVertIndex &index ) const; + + inline void GetFlatVert( int index, Vector& vert ) const; + inline void SetFlatVert( int index, const Vector &vert ); + + inline void GetNormal( int index, Vector& normal ) const; + inline const Vector& GetNormal( int index ) const; + inline const Vector& GetNormal( const CVertIndex &index ) const; + inline void SetNormal( int index, Vector const& normal ); + inline void SetNormal( const CVertIndex &index, Vector const& normal ); + + inline void GetTangentS( int index, Vector& tangentS ) const; + inline const Vector &GetTangentS( int index ) const; + inline const Vector &GetTangentS( const CVertIndex &index ) const { return GetTangentS(VertIndexToInt(index)); } + inline void GetTangentT( int index, Vector& tangentT ) const; + inline void SetTangentS( int index, Vector const& vTangentS ) { m_pVerts[index].m_TangentS = vTangentS; } + inline void SetTangentT( int index, Vector const& vTangentT ) { m_pVerts[index].m_TangentT = vTangentT; } + + inline void SetTexCoord( int index, Vector2D const& texCoord ); + inline void GetTexCoord( int index, Vector2D& texCoord ) const; + + inline void SetLuxelCoord( int bumpIndex, int index, Vector2D const& luxelCoord ); + inline void GetLuxelCoord( int bumpIndex, int index, Vector2D& luxelCoord ) const; + + inline void SetAlpha( int index, float alpha ); + inline float GetAlpha( int index ); + + int GetTriCount( void ); + void GetTriIndices( int iTri, unsigned short &v1, unsigned short &v2, unsigned short &v3 ); + void SetTriIndices( int iTri, unsigned short v1, unsigned short v2, unsigned short v3 ); + void GetTriPos( int iTri, Vector &v1, Vector &v2, Vector &v3 ); + inline void SetTriTag( int iTri, unsigned short nTag ) { m_pTris[iTri].m_uiTags |= nTag; } + inline void ResetTriTag( int iTri, unsigned short nTag ) { m_pTris[iTri].m_uiTags &= ~nTag; } + inline void ToggleTriTag( int iTri, unsigned short nTag ) { m_pTris[iTri].m_uiTags ^= nTag; } + inline bool IsTriTag( int iTri, unsigned short nTag ) { return ( ( m_pTris[iTri].m_uiTags & nTag ) != 0 ); } + inline unsigned short GetTriTagValue( int iTri ) { return m_pTris[iTri].m_uiTags; } + inline void SetTriTagValue( int iTri, unsigned short nVal ) { m_pTris[iTri].m_uiTags = nVal; } + + bool IsTriWalkable( int iTri ); + bool IsTriBuildable( int iTri ); + bool IsTriRemove( int iTri ); + + inline void SetElevation( float elevation ); + inline float GetElevation( void ); + + inline void ResetFieldVectors( void ); + inline void SetFieldVector( int index, Vector const &v ); + inline void GetFieldVector( int index, Vector& v ); + inline void ResetFieldDistances( void ); + inline void SetFieldDistance( int index, float dist ); + inline float GetFieldDistance( int index ); + + inline void ResetSubdivPositions( void ); + inline void SetSubdivPosition( int ndx, Vector const &v ); + inline void GetSubdivPosition( int ndx, Vector& v ); + + inline void ResetSubdivNormals( void ); + inline void SetSubdivNormal( int ndx, Vector const &v ); + inline void GetSubdivNormal( int ndx, Vector &v ); + + inline void SetRenderIndexCount( int count ); + inline int GetRenderIndexCount( void ); + inline void SetRenderIndex( int index, int triIndex ); + inline int GetRenderIndex( int index ); + + inline CoreDispVert_t *GetDispVert( int iVert ) { return &m_pVerts[iVert]; } + inline CoreDispVert_t *GetDispVertList(); + inline unsigned short *GetRenderIndexList( void ); + + inline void SetTouched( bool touched ); + inline bool IsTouched( void ); + + void CalcDispSurfCoords( bool bLightMap, int lightmapID ); + void GetPositionOnSurface( float u, float v, Vector &vPos, Vector *pNormal, float *pAlpha ); + + void DispUVToSurf( Vector2D const &dispUV, Vector &vecPoint, Vector *pNormal, float *pAlpha ); + void BaseFacePlaneToDispUV( Vector const &planePt, Vector2D &dispUV ); + bool SurfToBaseFacePlane( Vector const &surfPt, Vector &planePt ); + + const CDispCornerNeighbors* GetCornerNeighbors( int iCorner ) const { return GetSurface()->GetCornerNeighbors( iCorner ); } + const CDispNeighbor* GetEdgeNeighbor( int iEdge ) const { return GetSurface()->GetEdgeNeighbor( iEdge ); } + + void SetListIndex( int nIndex ) { m_nListIndex = nIndex; } + int GetListIndex( void ) { return m_nListIndex; } + + CBitVec& GetAllowedVerts() { return m_AllowedVerts; } + const CBitVec& GetAllowedVerts() const { return m_AllowedVerts; } + void AllowedVerts_Clear( void ) { m_AllowedVerts.SetAll(); } + int AllowedVerts_GetNumDWords() const { return m_AllowedVerts.GetNumDWords(); } + unsigned long AllowedVerts_GetDWord(int i) const { return m_AllowedVerts.GetDWord( i ); } + void AllowedVerts_SetDWord(int i, unsigned long val) { m_AllowedVerts.SetDWord( i, val ); } + + + void Position_Update( int iVert, Vector vecPos ); + + //========================================================================= + // + // friend functions + // + friend void SmoothNeighboringDispSurfNormals( CCoreDispInfo **ppCoreDispInfoList, int listSize ); + +private: + // be changed to match the paint normal next pass) + // LOD/collision node data + CCoreDispNode *m_Nodes; // LOD quad-tree nodes + + float m_Elevation; // distance along the subdivision normal (should + + // defines the size of the displacement surface + int m_Power; // "size" of the displacement map + + // base surface data + CCoreDispSurface m_Surf; // surface containing displacement data + // be changed to match the paint normal next pass) + // Vertex data.. + CoreDispVert_t *m_pVerts; + + // Triangle data.. + CoreDispTri_t *m_pTris; + + // render specific data + int m_RenderIndexCount; // number of indices used in rendering + unsigned short *m_RenderIndices; // rendering index list (list of triangles) + int m_RenderCounter; // counter to verify surfaces are renderered/collided with only once per frame + + // utility data + bool m_bTouched; // touched flag + CCoreDispInfo *m_pNext; // used for chaining + + // The list that this disp is in (used for CDispUtils::IHelper implementation). + CCoreDispInfo **m_ppListBase; + int m_ListSize; + + CBitVec m_AllowedVerts; // Built in VBSP. Defines which verts are allowed to exist based on what the neighbors are. + + int m_nListIndex; + + //========================================================================= + // + // Creation Functions + // + + void GenerateDispSurf( void ); + void GenerateDispSurfNormals( void ); + void GenerateDispSurfTangentSpaces( void ); + bool DoesEdgeExist( int indexRow, int indexCol, int direction, int postSpacing ); + void CalcNormalFromEdges( int indexRow, int indexCol, bool bIsEdge[4], Vector& normal ); + void CalcDispSurfAlphas( void ); + void GenerateLODTree( void ); + void CalcVertIndicesAtNodes( int nodeIndex ); + int GetNodeVertIndexFromParentIndex( int level, int parentVertIndex, int direction ); + void CalcNodeInfo( int nodeIndex, int terminationLevel ); + void CalcNeighborVertIndicesAtNode( int nodeIndex, int level ); + void CalcNeighborNodeIndicesAtNode( int nodeIndex, int level ); + void CalcErrorTermAtNode( int nodeIndex, int level ); + float GetMaxErrorFromChildren( int nodeIndex, int level ); + void CalcBoundingBoxAtNode( int nodeIndex ); + void CalcMinMaxBoundingBoxAtNode( int nodeIndex, Vector& bMin, Vector& bMax ); + void CalcTriSurfInfoAtNode( int nodeIndex ); + void CalcTriSurfIndices( int nodeIndex, int indices[8][3] ); + void CalcTriSurfBoundingBoxes( int nodeIndex, int indices[8][3] ); + void CalcRayBoundingBoxes( int nodeIndex, int indices[8][3] ); + void CalcTriSurfPlanes( int nodeIndex, int indices[8][3] ); + void GenerateCollisionData( void ); + void GenerateCollisionSurface( void ); + + void CreateBoundingBoxes( CoreDispBBox_t *pBBox, int count ); + + void DispUVToSurf_TriTLToBR( Vector &vecPoint, Vector *pNormal, float *pAlpha, float flU, float flV, const Vector &vecIntersectPoint ); + void DispUVToSurf_TriBLToTR( Vector &vecPoint, Vector *pNormal, float *pAlpha, float flU, float flV, const Vector &vecIntersectPoint ); + void DispUVToSurf_TriTLToBR_1( const Vector &vecIntersectPoint, int nSnapU, int nNextU, int nSnapV, int nNextV, Vector &vecPoint, Vector *pNormal, float *pAlpha, bool bBackup ); + void DispUVToSurf_TriTLToBR_2( const Vector &vecIntersectPoint, int nSnapU, int nNextU, int nSnapV, int nNextV, Vector &vecPoint, Vector *pNormal, float *pAlpha, bool bBackup ); + void DispUVToSurf_TriBLToTR_1( const Vector &vecIntersectPoint, int nSnapU, int nNextU, int nSnapV, int nNextV, Vector &vecPoint, Vector *pNormal, float *pAlpha, bool bBackup ); + void DispUVToSurf_TriBLToTR_2( const Vector &vecIntersectPoint, int nSnapU, int nNextU, int nSnapV, int nNextV, Vector &vecPoint, Vector *pNormal, float *pAlpha, bool bBackup ); + + void GetTriangleIndicesForDispBBox( int nIndex, int nTris[2][3] ); + + void BuildTriTLtoBR( int ndx ); + void BuildTriBLtoTR( int ndx ); + + void InitTris( void ); + void CreateTris( void ); +}; + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::SetPower( int power ) +{ + m_Power = power; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int CCoreDispInfo::GetPower( void ) const +{ + return m_Power; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int CCoreDispInfo::GetPostSpacing( void ) +{ + return ( ( 1 << m_Power ) + 1 ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int CCoreDispInfo::GetWidth( void ) +{ + return ( ( 1 << m_Power ) + 1 ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int CCoreDispInfo::GetHeight( void ) +{ + return ( ( 1 << m_Power ) + 1 ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int CCoreDispInfo::GetSize( void ) const +{ + return ( ( ( 1 << m_Power ) + 1 ) * ( ( 1 << m_Power ) + 1 ) ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::SetVert( int index, Vector const &vert ) +{ + Assert( index >= 0 ); + Assert( index < MAX_VERT_COUNT ); + VectorCopy( vert, m_pVerts[index].m_Vert ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::GetVert( int index, Vector& vert ) const +{ + Assert( index >= 0 ); + Assert( index < MAX_VERT_COUNT ); + VectorCopy( m_pVerts[index].m_Vert, vert ); +} + + +inline const Vector& CCoreDispInfo::GetVert( int index ) const +{ + Assert( index >= 0 ); + Assert( index < MAX_VERT_COUNT ); + return m_pVerts[index].m_Vert; +} + +inline const Vector& CCoreDispInfo::GetVert( const CVertIndex &index ) const +{ + return GetVert( VertIndexToInt( index ) ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::GetFlatVert( int index, Vector& vert ) const +{ + Assert( index >= 0 ); + Assert( index < MAX_VERT_COUNT ); + VectorCopy( m_pVerts[index].m_FlatVert, vert ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::SetFlatVert( int index, const Vector &vert ) +{ + Assert( index >= 0 ); + Assert( index < MAX_VERT_COUNT ); + VectorCopy( vert, m_pVerts[index].m_FlatVert ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::SetNormal( int index, Vector const &normal ) +{ + Assert( index >= 0 ); + Assert( index < MAX_VERT_COUNT ); + VectorCopy( normal, m_pVerts[index].m_Normal ); +} + + +inline void CCoreDispInfo::SetNormal( const CVertIndex &index, Vector const &normal ) +{ + SetNormal( VertIndexToInt( index ), normal ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::GetNormal( int index, Vector& normal ) const +{ + Assert( index >= 0 ); + Assert( index < MAX_VERT_COUNT ); + VectorCopy( m_pVerts[index].m_Normal, normal ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline const Vector& CCoreDispInfo::GetNormal( int index ) const +{ + Assert( index >= 0 ); + Assert( index < MAX_VERT_COUNT ); + return m_pVerts[index].m_Normal; +} + + +inline const Vector& CCoreDispInfo::GetNormal( const CVertIndex &index ) const +{ + return GetNormal( VertIndexToInt( index ) ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::GetTangentS( int index, Vector& tangentS ) const +{ + Assert( index >= 0 ); + Assert( index < GetSize() ); + VectorCopy( m_pVerts[index].m_TangentS, tangentS ); +} + +inline const Vector &CCoreDispInfo::GetTangentS( int index ) const +{ + Assert( index >= 0 ); + Assert( index < GetSize() ); + return m_pVerts[index].m_TangentS; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::GetTangentT( int index, Vector& tangentT ) const +{ + Assert( index >= 0 ); + Assert( index < GetSize() ); + VectorCopy( m_pVerts[index].m_TangentT, tangentT ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::SetTexCoord( int index, Vector2D const& texCoord ) +{ + Assert( index >= 0 ); + Assert( index < GetSize() ); + Vector2DCopy( texCoord, m_pVerts[index].m_TexCoord ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::GetTexCoord( int index, Vector2D& texCoord ) const +{ + Assert( index >= 0 ); + Assert( index < GetSize() ); + Vector2DCopy( m_pVerts[index].m_TexCoord, texCoord ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::SetLuxelCoord( int bumpIndex, int index, Vector2D const& luxelCoord ) +{ + Assert( index >= 0 ); + Assert( index < GetSize() ); + Assert( bumpIndex >= 0 ); + Assert( bumpIndex < NUM_BUMP_VECTS + 1 ); + Vector2DCopy( luxelCoord, m_pVerts[index].m_LuxelCoords[bumpIndex] ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::GetLuxelCoord( int bumpIndex, int index, Vector2D& luxelCoord ) const +{ + Assert( index >= 0 ); + Assert( index < MAX_VERT_COUNT ); + Assert( bumpIndex >= 0 ); + Assert( bumpIndex < NUM_BUMP_VECTS + 1 ); + Vector2DCopy( m_pVerts[index].m_LuxelCoords[bumpIndex], luxelCoord ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::SetAlpha( int index, float alpha ) +{ + Assert( index >= 0 ); + Assert( index < MAX_VERT_COUNT ); + m_pVerts[index].m_Alpha = alpha; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline float CCoreDispInfo::GetAlpha( int index ) +{ + Assert( index >= 0 ); + Assert( index < MAX_VERT_COUNT ); + return m_pVerts[index].m_Alpha; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::SetElevation( float elevation ) +{ + m_Elevation = elevation; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline float CCoreDispInfo::GetElevation( void ) +{ + return m_Elevation; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::ResetFieldVectors( void ) +{ +// Vector normal; +// m_Surf.GetNormal( normal ); + + int size = GetSize(); + for( int i = 0; i < size; i++ ) + { + m_pVerts[i].m_FieldVector.Init(); +// m_FieldVectors[i] = normal; + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::SetFieldVector( int index, Vector const &v ) +{ + Assert( index >= 0 ); + Assert( index < MAX_VERT_COUNT ); + VectorCopy( v, m_pVerts[index].m_FieldVector ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::GetFieldVector( int index, Vector& v ) +{ + Assert( index >= 0 ); + Assert( index < MAX_VERT_COUNT ); + VectorCopy( m_pVerts[index].m_FieldVector, v ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::ResetSubdivPositions( void ) +{ + int size = GetSize(); + for( int i = 0; i < size; i++ ) + { + m_pVerts[i].m_SubdivPos.Init(); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::SetSubdivPosition( int ndx, Vector const &v ) +{ + Assert( ndx >= 0 ); + Assert( ndx < MAX_VERT_COUNT ); + m_pVerts[ndx].m_SubdivPos = v; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::GetSubdivPosition( int ndx, Vector& v ) +{ + Assert( ndx >= 0 ); + Assert( ndx < MAX_VERT_COUNT ); + v = m_pVerts[ndx].m_SubdivPos; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::ResetSubdivNormals( void ) +{ + Vector normal; + m_Surf.GetNormal( normal ); + + int size = GetSize(); + for( int i = 0; i < size; i++ ) + { + m_pVerts[i].m_SubdivNormal = normal; + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::SetSubdivNormal( int ndx, Vector const &v ) +{ + Assert( ndx >= 0 ); + Assert( ndx < MAX_VERT_COUNT ); + m_pVerts[ndx].m_SubdivNormal = v; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::GetSubdivNormal( int ndx, Vector &v ) +{ + Assert( ndx >= 0 ); + Assert( ndx < MAX_VERT_COUNT ); + v = m_pVerts[ndx].m_SubdivNormal; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::ResetFieldDistances( void ) +{ + int size = GetSize(); + for( int i = 0; i < size; i++ ) + { + m_pVerts[i].m_FieldDistance = 0.0f; + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::SetFieldDistance( int index, float dist ) +{ + Assert( index >= 0 ); + Assert( index < GetSize() ); + m_pVerts[index].m_FieldDistance = dist; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline float CCoreDispInfo::GetFieldDistance( int index ) +{ + Assert( index >= 0 ); + Assert( index < GetSize() ); + return m_pVerts[index].m_FieldDistance; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::SetRenderIndexCount( int count ) +{ + m_RenderIndexCount = count; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int CCoreDispInfo::GetRenderIndexCount( void ) +{ + return m_RenderIndexCount; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::SetRenderIndex( int index, int triIndex ) +{ + Assert( index >= 0 ); + Assert( index < ( MAX_VERT_COUNT*2*3) ); + m_RenderIndices[index] = triIndex; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int CCoreDispInfo::GetRenderIndex( int index ) +{ + Assert( index >= 0 ); + Assert( index < ( MAX_VERT_COUNT*2*3) ); + return m_RenderIndices[index]; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline CoreDispVert_t *CCoreDispInfo::GetDispVertList() +{ + return m_pVerts; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline unsigned short *CCoreDispInfo::GetRenderIndexList( void ) +{ + return &m_RenderIndices[0]; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CCoreDispInfo::SetTouched( bool touched ) +{ + m_bTouched = touched; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline bool CCoreDispInfo::IsTouched( void ) +{ + return m_bTouched; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline CCoreDispNode *CCoreDispInfo::GetNode( int index ) +{ + Assert( index >= 0 ); + Assert( index < MAX_NODE_COUNT ); + return &m_Nodes[index]; +} + +bool CalcBarycentricCooefs( Vector const &v0, Vector const &v1, Vector const &v2, + Vector const &pt, float &c0, float &c1, float &c2 ); + +#endif // BUILDDISP_H diff --git a/sp/src/public/captioncompiler.h b/sp/src/public/captioncompiler.h new file mode 100644 index 00000000..1b723dc6 --- /dev/null +++ b/sp/src/public/captioncompiler.h @@ -0,0 +1,77 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef CAPTIONCOMPILER_H +#define CAPTIONCOMPILER_H +#ifdef _WIN32 +#pragma once +#endif + +#include "datamap.h" +#include "checksum_crc.h" + +#define MAX_BLOCK_BITS 13 + +#define MAX_BLOCK_SIZE (1<deleteThis() + virtual void ServerCmdKeyValues( KeyValues *pKeyValues ) = 0; + + virtual bool IsSkippingPlayback( void ) = 0; + virtual bool IsLoadingDemo( void ) = 0; + + // Returns true if the engine is playing back a "locally recorded" demo, which includes + // both SourceTV and replay demos, since they're recorded locally (on servers), as opposed + // to a client recording a demo while connected to a remote server. + virtual bool IsPlayingDemoALocallyRecordedDemo() = 0; + + // Given the string pBinding which may be bound to a key, + // returns the string name of the key to which this string is bound. Returns NULL if no such binding exists + // Unlike Key_LookupBinding, leading '+' characters are not stripped from bindings. + virtual const char *Key_LookupBindingExact( const char *pBinding ) = 0; +}; + +abstract_class IVEngineClient : public IVEngineClient013 +{ +public: + virtual uint GetProtocolVersion() = 0; + virtual bool IsWindowedMode() = 0; + + // Flash the window (os specific) + virtual void FlashWindow() = 0; + + // Client version from the steam.inf, this will be compared to the GC version + virtual int GetClientVersion() const = 0; // engines build + + // Is App Active + virtual bool IsActiveApp() = 0; + + virtual void DisconnectInternal() = 0; + + virtual int GetInstancesRunningCount( ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Purpose: Interface exposed from the client .dll back to the engine +//----------------------------------------------------------------------------- +abstract_class IBaseClientDLL +{ +public: + // Called once when the client DLL is loaded + virtual int Init( CreateInterfaceFn appSystemFactory, + CreateInterfaceFn physicsFactory, + CGlobalVarsBase *pGlobals ) = 0; + + virtual void PostInit() = 0; + + // Called once when the client DLL is being unloaded + virtual void Shutdown( void ) = 0; + + // Called once the client is initialized to setup client-side replay interface pointers + virtual bool ReplayInit( CreateInterfaceFn replayFactory ) = 0; + virtual bool ReplayPostInit() = 0; + + // Called at the start of each level change + virtual void LevelInitPreEntity( char const* pMapName ) = 0; + // Called at the start of a new level, after the entities have been received and created + virtual void LevelInitPostEntity( ) = 0; + // Called at the end of a level + virtual void LevelShutdown( void ) = 0; + + // Request a pointer to the list of client datatable classes + virtual ClientClass *GetAllClasses( void ) = 0; + + // Called once per level to re-initialize any hud element drawing stuff + virtual int HudVidInit( void ) = 0; + // Called by the engine when gathering user input + virtual void HudProcessInput( bool bActive ) = 0; + // Called oncer per frame to allow the hud elements to think + virtual void HudUpdate( bool bActive ) = 0; + // Reset the hud elements to their initial states + virtual void HudReset( void ) = 0; + // Display a hud text message + virtual void HudText( const char * message ) = 0; + + // Mouse Input Interfaces + // Activate the mouse (hides the cursor and locks it to the center of the screen) + virtual void IN_ActivateMouse( void ) = 0; + // Deactivates the mouse (shows the cursor and unlocks it) + virtual void IN_DeactivateMouse( void ) = 0; + // This is only called during extra sound updates and just accumulates mouse x, y offets and recenters the mouse. + // This call is used to try to prevent the mouse from appearing out of the side of a windowed version of the engine if + // rendering or other processing is taking too long + virtual void IN_Accumulate (void) = 0; + // Reset all key and mouse states to their initial, unpressed state + virtual void IN_ClearStates (void) = 0; + // If key is found by name, returns whether it's being held down in isdown, otherwise function returns false + virtual bool IN_IsKeyDown( const char *name, bool& isdown ) = 0; + // Notify the client that the mouse was wheeled while in game - called prior to executing any bound commands. + virtual void IN_OnMouseWheeled( int nDelta ) = 0; + // Raw keyboard signal, if the client .dll returns 1, the engine processes the key as usual, otherwise, + // if the client .dll returns 0, the key is swallowed. + virtual int IN_KeyEvent( int eventcode, ButtonCode_t keynum, const char *pszCurrentBinding ) = 0; + + // This function is called once per tick to create the player CUserCmd (used for prediction/physics simulation of the player) + // Because the mouse can be sampled at greater than the tick interval, there is a separate input_sample_frametime, which + // specifies how much additional mouse / keyboard simulation to perform. + virtual void CreateMove ( + int sequence_number, // sequence_number of this cmd + float input_sample_frametime, // Frametime for mouse input sampling + bool active ) = 0; // True if the player is active (not paused) + + // If the game is running faster than the tick_interval framerate, then we do extra mouse sampling to avoid jittery input + // This code path is much like the normal move creation code, except no move is created + virtual void ExtraMouseSample( float frametime, bool active ) = 0; + + // Encode the delta (changes) between the CUserCmd in slot from vs the one in slot to. The game code will have + // matching logic to read the delta. + virtual bool WriteUsercmdDeltaToBuffer( bf_write *buf, int from, int to, bool isnewcommand ) = 0; + // Demos need to be able to encode/decode CUserCmds to memory buffers, so these functions wrap that + virtual void EncodeUserCmdToBuffer( bf_write& buf, int slot ) = 0; + virtual void DecodeUserCmdFromBuffer( bf_read& buf, int slot ) = 0; + + // Set up and render one or more views (e.g., rear view window, etc.). This called into RenderView below + virtual void View_Render( vrect_t *rect ) = 0; + + // Allow engine to expressly render a view (e.g., during timerefresh) + // See IVRenderView.h, PushViewFlags_t for nFlags values + virtual void RenderView( const CViewSetup &view, int nClearFlags, int whatToDraw ) = 0; + + // Apply screen fade directly from engine + virtual void View_Fade( ScreenFade_t *pSF ) = 0; + + // The engine has parsed a crosshair angle message, this function is called to dispatch the new crosshair angle + virtual void SetCrosshairAngle( const QAngle& angle ) = 0; + + // Sprite (.spr) model handling code + // Load a .spr file by name + virtual void InitSprite( CEngineSprite *pSprite, const char *loadname ) = 0; + // Shutdown a .spr file + virtual void ShutdownSprite( CEngineSprite *pSprite ) = 0; + // Returns sizeof( CEngineSprite ) so the engine can allocate appropriate memory + virtual int GetSpriteSize( void ) const = 0; + + // Called when a player starts or stops talking. + // entindex is -1 to represent the local client talking (before the data comes back from the server). + // entindex is -2 to represent the local client's voice being acked by the server. + // entindex is GetPlayer() when the server acknowledges that the local client is talking. + virtual void VoiceStatus( int entindex, qboolean bTalking ) = 0; + + // Networked string table definitions have arrived, allow client .dll to + // hook string changes with a callback function ( see INetworkStringTableClient.h ) + virtual void InstallStringTableCallback( char const *tableName ) = 0; + + // Notification that we're moving into another stage during the frame. + virtual void FrameStageNotify( ClientFrameStage_t curStage ) = 0; + + // The engine has received the specified user message, this code is used to dispatch the message handler + virtual bool DispatchUserMessage( int msg_type, bf_read &msg_data ) = 0; + + // Save/restore system hooks + virtual CSaveRestoreData *SaveInit( int size ) = 0; + virtual void SaveWriteFields( CSaveRestoreData *, const char *, void *, datamap_t *, typedescription_t *, int ) = 0; + virtual void SaveReadFields( CSaveRestoreData *, const char *, void *, datamap_t *, typedescription_t *, int ) = 0; + virtual void PreSave( CSaveRestoreData * ) = 0; + virtual void Save( CSaveRestoreData * ) = 0; + virtual void WriteSaveHeaders( CSaveRestoreData * ) = 0; + virtual void ReadRestoreHeaders( CSaveRestoreData * ) = 0; + virtual void Restore( CSaveRestoreData *, bool ) = 0; + virtual void DispatchOnRestore() = 0; + + // Hand over the StandardRecvProxies in the client DLL's module. + virtual CStandardRecvProxies* GetStandardRecvProxies() = 0; + + // save game screenshot writing + virtual void WriteSaveGameScreenshot( const char *pFilename ) = 0; + + // Given a list of "S(wavname) S(wavname2)" tokens, look up the localized text and emit + // the appropriate close caption if running with closecaption = 1 + virtual void EmitSentenceCloseCaption( char const *tokenstream ) = 0; + // Emits a regular close caption by token name + virtual void EmitCloseCaption( char const *captionname, float duration ) = 0; + + // Returns true if the client can start recording a demo now. If the client returns false, + // an error message of up to length bytes should be returned in errorMsg. + virtual bool CanRecordDemo( char *errorMsg, int length ) const = 0; + + // Give the Client a chance to do setup/cleanup. + virtual void OnDemoRecordStart( char const* pDemoBaseName ) = 0; + virtual void OnDemoRecordStop() = 0; + virtual void OnDemoPlaybackStart( char const* pDemoBaseName ) = 0; + virtual void OnDemoPlaybackStop() = 0; + + // Draw the console overlay? + virtual bool ShouldDrawDropdownConsole() = 0; + + // Get client screen dimensions + virtual int GetScreenWidth() = 0; + virtual int GetScreenHeight() = 0; + + // Added interface + + // save game screenshot writing + virtual void WriteSaveGameScreenshotOfSize( const char *pFilename, int width, int height, bool bCreatePowerOf2Padded = false, bool bWriteVTF = false ) = 0; + + // Gets the current view + virtual bool GetPlayerView( CViewSetup &playerView ) = 0; + + // Matchmaking + virtual void SetupGameProperties( CUtlVector< XUSER_CONTEXT > &contexts, CUtlVector< XUSER_PROPERTY > &properties ) = 0; + virtual uint GetPresenceID( const char *pIDName ) = 0; + virtual const char *GetPropertyIdString( const uint id ) = 0; + virtual void GetPropertyDisplayString( uint id, uint value, char *pOutput, int nBytes ) = 0; + +#ifdef WIN32 + virtual void StartStatsReporting( HANDLE handle, bool bArbitrated ) = 0; +#endif + + virtual void InvalidateMdlCache() = 0; + + virtual void IN_SetSampleTime( float frametime ) = 0; + + + // For sv_pure mode. The filesystem figures out which files the client needs to reload to be "pure" ala the server's preferences. + virtual void ReloadFilesInList( IFileList *pFilesToReload ) = 0; +#ifdef POSIX + // AR: Same as above win32 defn but down here at the end of the vtable for back compat + virtual void StartStatsReporting( HANDLE handle, bool bArbitrated ) = 0; +#endif + + // Let the client handle UI toggle - if this function returns false, the UI will toggle, otherwise it will not. + virtual bool HandleUiToggle() = 0; + + // Allow the console to be shown? + virtual bool ShouldAllowConsole() = 0; + + // Get renamed recv tables + virtual CRenamedRecvTableInfo *GetRenamedRecvTableInfos() = 0; + + // Get the mouthinfo for the sound being played inside UI panels + virtual CMouthInfo *GetClientUIMouthInfo() = 0; + + // Notify the client that a file has been received from the game server + virtual void FileReceived( const char * fileName, unsigned int transferID ) = 0; + + virtual const char* TranslateEffectForVisionFilter( const char *pchEffectType, const char *pchEffectName ) = 0; + + // Give the client a chance to modify sound settings however they want before the sound plays. This is used for + // things like adjusting pitch of voice lines in Pyroland in TF2. + virtual void ClientAdjustStartSoundParams( struct StartSoundParams_t& params ) = 0; + + // Returns true if the disconnect command has been handled by the client + virtual bool DisconnectAttempt( void ) = 0; + + virtual bool IsConnectedUserInfoChangeAllowed( IConVar *pCvar ) = 0; +}; + +#define CLIENT_DLL_INTERFACE_VERSION "VClient017" + +//----------------------------------------------------------------------------- +// Purpose: Interface exposed from the client .dll back to the engine for specifying shared .dll IAppSystems (e.g., ISoundEmitterSystem) +//----------------------------------------------------------------------------- +abstract_class IClientDLLSharedAppSystems +{ +public: + virtual int Count() = 0; + virtual char const *GetDllName( int idx ) = 0; + virtual char const *GetInterfaceName( int idx ) = 0; +}; + +#define CLIENT_DLL_SHARED_APPSYSTEMS "VClientDllSharedAppSystems001" + +#endif // CDLL_INT_H diff --git a/sp/src/public/chunkfile.cpp b/sp/src/public/chunkfile.cpp new file mode 100644 index 00000000..81a77dd3 --- /dev/null +++ b/sp/src/public/chunkfile.cpp @@ -0,0 +1,985 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Implements an interface for reading and writing heirarchical +// text files of key value pairs. The format of the file is as follows: +// +// chunkname0 +// { +// "key0" "value0" +// "key1" "value1" +// ... +// "keyN" "valueN" +// chunkname1 +// { +// "key0" "value0" +// "key1" "value1" +// ... +// "keyN" "valueN" +// } +// } +// ... +// chunknameN +// { +// "key0" "value0" +// "key1" "value1" +// ... +// "keyN" "valueN" +// } +// +// The chunk names are not necessarily unique, nor are the key names, unless the +// parsing application requires them to be. +// +// $NoKeywords: $ +//=============================================================================// + +#include +#ifdef _WIN32 +#include +#endif +#include +#include +#include +#include +#include +#include "chunkfile.h" +#include "mathlib/vector.h" +#include "mathlib/vector4d.h" +#include "tier1/strtools.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +//----------------------------------------------------------------------------- +// Purpose: Constructor. +//----------------------------------------------------------------------------- +CChunkHandlerMap::CChunkHandlerMap(void) +{ + m_pHandlers = NULL; +} + + +//----------------------------------------------------------------------------- +// Purpose: Destructor. Frees handler list. +//----------------------------------------------------------------------------- +CChunkHandlerMap::~CChunkHandlerMap(void) +{ + ChunkHandlerInfoNode_t *pNode = m_pHandlers; + while (pNode != NULL) + { + ChunkHandlerInfoNode_t *pPrev = pNode; + pNode = pNode->pNext; + + delete pPrev; + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Adds a chunk handler to the handler list. +// Input : pszChunkName - Name of chunk to be handled. +// pfnHandler - Address of handler callback function. +// pData - Data to pass to the handler callback. +//----------------------------------------------------------------------------- +void CChunkHandlerMap::AddHandler(const char *pszChunkName, ChunkHandler_t pfnHandler, void *pData) +{ + ChunkHandlerInfoNode_t *pNew = new ChunkHandlerInfoNode_t; + + Q_strncpy(pNew->Handler.szChunkName, pszChunkName, sizeof( pNew->Handler.szChunkName )); + pNew->Handler.pfnHandler = pfnHandler; + pNew->Handler.pData = pData; + pNew->pNext = NULL; + + if (m_pHandlers == NULL) + { + m_pHandlers = pNew; + } + else + { + ChunkHandlerInfoNode_t *pNode = m_pHandlers; + while (pNode->pNext != NULL) + { + pNode = pNode->pNext; + } + pNode->pNext = pNew; + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Sets the callback for error handling within this chunk's scope. +// Input : pfnHandler - +// pData - +//----------------------------------------------------------------------------- +void CChunkHandlerMap::SetErrorHandler(ChunkErrorHandler_t pfnHandler, void *pData) +{ + m_pfnErrorHandler = pfnHandler; + m_pErrorData = pData; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : ppData - +// Output : ChunkErrorHandler_t +//----------------------------------------------------------------------------- +ChunkErrorHandler_t CChunkHandlerMap::GetErrorHandler(void **ppData) +{ + *ppData = m_pErrorData; + return(m_pfnErrorHandler); +} + + +//----------------------------------------------------------------------------- +// Purpose: Gets the handler for a given chunk name, if one has been set. +// Input : pszChunkName - Name of chunk. +// ppfnHandler - Receives the address of the callback function. +// ppData - Receives the context data for the given chunk. +// Output : Returns true if a handler was found, false if not. +//----------------------------------------------------------------------------- +ChunkHandler_t CChunkHandlerMap::GetHandler(const char *pszChunkName, void **ppData) +{ + ChunkHandlerInfoNode_t *pNode = m_pHandlers; + while (pNode != NULL) + { + if (!stricmp(pNode->Handler.szChunkName, pszChunkName)) + { + *ppData = pNode->Handler.pData; + return(pNode->Handler.pfnHandler); + } + + pNode = pNode->pNext; + } + + return(false); +} + + +//----------------------------------------------------------------------------- +// Purpose: Constructor. Initializes data members. +//----------------------------------------------------------------------------- +CChunkFile::CChunkFile(void) +{ + m_hFile = NULL; + m_nCurrentDepth = 0; + m_szIndent[0] = '\0'; + m_nHandlerStackDepth = 0; + m_DefaultChunkHandler = 0; +} + + +//----------------------------------------------------------------------------- +// Purpose: Destructor. Closes the file if it is currently open. +//----------------------------------------------------------------------------- +CChunkFile::~CChunkFile(void) +{ + if (m_hFile != NULL) + { + fclose(m_hFile); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pszChunkName - +// Output : ChunkFileResult_t +//----------------------------------------------------------------------------- +ChunkFileResult_t CChunkFile::BeginChunk(const char *pszChunkName) +{ + // + // Write the chunk name and open curly. + // + char szBuf[MAX_KEYVALUE_LEN]; + Q_snprintf(szBuf, sizeof( szBuf ), "%s\r\n%s{", pszChunkName, m_szIndent); + ChunkFileResult_t eResult = WriteLine(szBuf); + + // + // Update the indentation depth. + // + if (eResult == ChunkFile_Ok) + { + m_nCurrentDepth++; + BuildIndentString(m_szIndent, m_nCurrentDepth); + } + + return(eResult); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CChunkFile::BuildIndentString(char *pszDest, int nDepth) +{ + if (nDepth >= 0) + { + for (int i = 0; i < nDepth; i++) + { + pszDest[i] = '\t'; + } + + pszDest[nDepth] = '\0'; + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Output : ChunkFileResult_t +//----------------------------------------------------------------------------- +ChunkFileResult_t CChunkFile::Close(void) +{ + if (m_hFile != NULL) + { + fclose(m_hFile); + m_hFile = NULL; + } + + return(ChunkFile_Ok); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Output : ChunkFileResult_t +//----------------------------------------------------------------------------- +ChunkFileResult_t CChunkFile::EndChunk(void) +{ + if (m_nCurrentDepth > 0) + { + m_nCurrentDepth--; + BuildIndentString(m_szIndent, m_nCurrentDepth); + } + + WriteLine("}"); + + return(ChunkFile_Ok); +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns a string explaining the last error that occurred. +//----------------------------------------------------------------------------- +const char *CChunkFile::GetErrorText(ChunkFileResult_t eResult) +{ + static char szError[MAX_KEYVALUE_LEN]; + + switch (eResult) + { + case ChunkFile_UnexpectedEOF: + { + Q_strncpy(szError, "unexpected end of file", sizeof( szError ) ); + break; + } + + case ChunkFile_UnexpectedSymbol: + { + Q_snprintf(szError, sizeof( szError ), "unexpected symbol '%s'", m_szErrorToken); + break; + } + + case ChunkFile_OpenFail: + { + Q_snprintf(szError, sizeof( szError ), "%s", strerror(errno)) ; + break; + } + + case ChunkFile_StringTooLong: + { + Q_strncpy(szError, "unterminated string or string too long", sizeof( szError ) ); + break; + } + + default: + { + Q_snprintf(szError, sizeof( szError ), "error %d", eResult); + } + } + + return(m_TokenReader.Error(szError)); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : eError - +//----------------------------------------------------------------------------- +void CChunkFile::HandleError(const char *szChunkName, ChunkFileResult_t eError) +{ + // UNDONE: dispatch errors to the error handler. + // - keep track of current chunkname for reporting errors + // - use the last non-NULL handler that was pushed onto the stack? + // - need a return code to determine whether to abort parsing? +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Output : ChunkFileResult_t +//----------------------------------------------------------------------------- +ChunkFileResult_t CChunkFile::HandleChunk(const char *szChunkName) +{ + // See if the default handler wants it? + if( m_DefaultChunkHandler ) + { + ChunkFileResult_t testResult = m_DefaultChunkHandler( this, m_pDefaultChunkHandlerData, szChunkName ); + if( testResult == ChunkFile_Ok ) + { + return ChunkFile_Ok; + } + } + + // + // If there is an active handler map... + // + if (m_nHandlerStackDepth > 0) + { + CChunkHandlerMap *pHandler = m_HandlerStack[m_nHandlerStackDepth - 1]; + + // + // If a chunk handler was found in the handler map... + // + void *pData; + ChunkHandler_t pfnHandler = pHandler->GetHandler(szChunkName, &pData); + if (pfnHandler != NULL) + { + // Dispatch this chunk to the handler. + ChunkFileResult_t eResult = pfnHandler(this, pData); + if (eResult != ChunkFile_Ok) + { + return(eResult); + } + } + else + { + // + // No handler for this chunk. Skip to the matching close curly brace. + // + int nDepth = 1; + ChunkFileResult_t eResult; + + do + { + ChunkType_t eChunkType; + char szKey[MAX_KEYVALUE_LEN]; + char szValue[MAX_KEYVALUE_LEN]; + + while ((eResult = ReadNext(szKey, szValue, sizeof(szValue), eChunkType)) == ChunkFile_Ok) + { + if (eChunkType == ChunkType_Chunk) + { + nDepth++; + } + } + + if (eResult == ChunkFile_EndOfChunk) + { + eResult = ChunkFile_Ok; + nDepth--; + } + else if (eResult == ChunkFile_EOF) + { + return(ChunkFile_UnexpectedEOF); + } + + } while ((nDepth) && (eResult == ChunkFile_Ok)); + } + } + + return(ChunkFile_Ok); +} + + +//----------------------------------------------------------------------------- +// Purpose: Opens the chunk file for reading or writing. +// Input : pszFileName - Path of file to open. +// eMode - ChunkFile_Read or ChunkFile_Write. +// Output : Returns ChunkFile_Ok on success, ChunkFile_Fail on failure. +// UNDONE: boolean return value? +//----------------------------------------------------------------------------- +ChunkFileResult_t CChunkFile::Open(const char *pszFileName, ChunkFileOpenMode_t eMode) +{ + if (eMode == ChunkFile_Read) + { + // UNDONE: TokenReader encapsulates file - unify reading and writing to use the same file I/O. + // UNDONE: Support in-memory parsing. + if (m_TokenReader.Open(pszFileName)) + { + m_nCurrentDepth = 0; + } + else + { + return(ChunkFile_OpenFail); + } + } + else if (eMode == ChunkFile_Write) + { + m_hFile = fopen(pszFileName, "wb"); + + if (m_hFile == NULL) + { + return(ChunkFile_OpenFail); + } + + m_nCurrentDepth = 0; + } + + return(ChunkFile_Ok); +} + + +//----------------------------------------------------------------------------- +// Purpose: Removes the topmost set of chunk handlers. +//----------------------------------------------------------------------------- +void CChunkFile::PopHandlers(void) +{ + if (m_nHandlerStackDepth > 0) + { + m_nHandlerStackDepth--; + } +} + + +void CChunkFile::SetDefaultChunkHandler( DefaultChunkHandler_t pHandler, void *pData ) +{ + m_DefaultChunkHandler = pHandler; + m_pDefaultChunkHandlerData = pData;} + + +//----------------------------------------------------------------------------- +// Purpose: Adds a set of chunk handlers to the top of the handler stack. +// Input : pHandlerMap - Object containing the list of chunk handlers. +//----------------------------------------------------------------------------- +void CChunkFile::PushHandlers(CChunkHandlerMap *pHandlerMap) +{ + if (m_nHandlerStackDepth < MAX_INDENT_DEPTH) + { + m_HandlerStack[m_nHandlerStackDepth] = pHandlerMap; + m_nHandlerStackDepth++; + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Reads the next term from the chunk file. The type of term read is +// returned in the eChunkType parameter. +// Input : szName - Name of key or chunk. +// szValue - If eChunkType is ChunkType_Key, contains the value of the key. +// nValueSize - Size of the buffer pointed to by szValue. +// eChunkType - ChunkType_Key or ChunkType_Chunk. +// Output : Returns ChunkFile_Ok on success, an error code if a parsing error occurs. +//----------------------------------------------------------------------------- +ChunkFileResult_t CChunkFile::ReadNext(char *szName, char *szValue, int nValueSize, ChunkType_t &eChunkType) +{ + // HACK: pass in buffer sizes? + trtoken_t eTokenType = m_TokenReader.NextToken(szName, MAX_KEYVALUE_LEN); + + if (eTokenType != TOKENEOF) + { + switch (eTokenType) + { + case IDENT: + case STRING: + { + char szNext[MAX_KEYVALUE_LEN]; + trtoken_t eNextTokenType; + + // + // Read the next token to determine what we have. + // + eNextTokenType = m_TokenReader.NextToken(szNext, sizeof(szNext)); + + switch (eNextTokenType) + { + case OPERATOR: + { + if (!stricmp(szNext, "{")) + { + // Beginning of new chunk. + m_nCurrentDepth++; + eChunkType = ChunkType_Chunk; + szValue[0] = '\0'; + return(ChunkFile_Ok); + } + else + { + // Unexpected symbol. + Q_strncpy(m_szErrorToken, szNext, sizeof( m_szErrorToken ) ); + return(ChunkFile_UnexpectedSymbol); + } + } + + case STRING: + case IDENT: + { + // Key value pair. + Q_strncpy(szValue, szNext, nValueSize ); + eChunkType = ChunkType_Key; + return(ChunkFile_Ok); + } + + case TOKENEOF: + { + // Unexpected end of file. + return(ChunkFile_UnexpectedEOF); + } + + case TOKENSTRINGTOOLONG: + { + // String too long or unterminated string. + return ChunkFile_StringTooLong; + } + } + } + + case OPERATOR: + { + if (!stricmp(szName, "}")) + { + // End of current chunk. + m_nCurrentDepth--; + return(ChunkFile_EndOfChunk); + } + else + { + // Unexpected symbol. + Q_strncpy(m_szErrorToken, szName, sizeof( m_szErrorToken ) ); + return(ChunkFile_UnexpectedSymbol); + } + } + + case TOKENSTRINGTOOLONG: + { + return ChunkFile_StringTooLong; + } + } + } + + if (m_nCurrentDepth != 0) + { + // End of file while within the scope of a chunk. + return(ChunkFile_UnexpectedEOF); + } + + return(ChunkFile_EOF); +} + + +//----------------------------------------------------------------------------- +// Purpose: Reads the current chunk and dispatches keys and sub-chunks to the +// appropriate handler callbacks. +// Input : pfnKeyHandler - Callback for any key values in this chunk. +// pData - Data to pass to the key value callback function. +// Output : Normally returns ChunkFile_Ok or ChunkFile_EOF. Otherwise, returns +// a ChunkFile_xxx error code. +//----------------------------------------------------------------------------- +ChunkFileResult_t CChunkFile::ReadChunk(KeyHandler_t pfnKeyHandler, void *pData) +{ + // + // Read the keys and sub-chunks. + // + ChunkFileResult_t eResult; + do + { + char szName[MAX_KEYVALUE_LEN]; + char szValue[MAX_KEYVALUE_LEN]; + ChunkType_t eChunkType; + + eResult = ReadNext(szName, szValue, sizeof(szValue), eChunkType); + + if (eResult == ChunkFile_Ok) + { + if (eChunkType == ChunkType_Chunk) + { + // + // Dispatch sub-chunks to the appropriate handler. + // + eResult = HandleChunk(szName); + } + else if ((eChunkType == ChunkType_Key) && (pfnKeyHandler != NULL)) + { + // + // Dispatch keys to the key value handler. + // + eResult = pfnKeyHandler(szName, szValue, pData); + } + } + } while (eResult == ChunkFile_Ok); + + // + // Cover up ChunkFile_EndOfChunk results because the caller doesn't want to see them. + // + if (eResult == ChunkFile_EndOfChunk) + { + eResult = ChunkFile_Ok; + } + + // + // Dispatch errors to the handler. + // + if ((eResult != ChunkFile_Ok) && (eResult != ChunkFile_EOF)) + { + //HandleError("chunkname", eResult); + } + + return(eResult); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : pszValue - +// pbBool - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CChunkFile::ReadKeyValueBool(const char *pszValue, bool &bBool) +{ + int nValue = atoi(pszValue); + + if (nValue > 0) + { + bBool = true; + } + else + { + bBool = false; + } + + return(true); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : pszValue - +// pfFloat - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CChunkFile::ReadKeyValueFloat(const char *pszValue, float &flFloat) +{ + flFloat = (float)atof(pszValue); + return(true); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : pszValue - +// pnInt - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CChunkFile::ReadKeyValueInt(const char *pszValue, int &nInt) +{ + nInt = atoi(pszValue); + return(true); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : pszKey - +// r - +// g - +// b - +// Output : +//----------------------------------------------------------------------------- +bool CChunkFile::ReadKeyValueColor(const char *pszValue, unsigned char &chRed, unsigned char &chGreen, unsigned char &chBlue) +{ + if (pszValue != NULL) + { + int r = 0; + int g = 0; + int b = 0; + + if (sscanf(pszValue, "%d %d %d", &r, &g, &b) == 3) + { + chRed = r; + chGreen = g; + chBlue = b; + + return(true); + } + } + + return(false); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : pszValue - +// pfPoint - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CChunkFile::ReadKeyValuePoint(const char *pszValue, Vector &Point) +{ + if (pszValue != NULL) + { + return(sscanf(pszValue, "(%f %f %f)", &Point.x, &Point.y, &Point.z) == 3); + } + + return(false); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : pszValue - +// pfVector - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CChunkFile::ReadKeyValueVector2(const char *pszValue, Vector2D &vec) +{ + if (pszValue != NULL) + { + return ( sscanf( pszValue, "[%f %f]", &vec.x, &vec.y) == 2 ); + } + + return(false); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : pszValue - +// pfVector - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CChunkFile::ReadKeyValueVector3(const char *pszValue, Vector &vec) +{ + if (pszValue != NULL) + { + return(sscanf(pszValue, "[%f %f %f]", &vec.x, &vec.y, &vec.z) == 3); + } + + return(false); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : pszValue - +// pfVector - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CChunkFile::ReadKeyValueVector4(const char *pszValue, Vector4D &vec) +{ + if( pszValue != NULL ) + { + return(sscanf(pszValue, "[%f %f %f %f]", &vec[0], &vec[1], &vec[2], &vec[3]) == 4); + } + + return false; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : pszLine - +// Output : +//----------------------------------------------------------------------------- +ChunkFileResult_t CChunkFile::WriteKeyValue(const char *pszKey, const char *pszValue) +{ + if ((pszKey != NULL) && (pszValue != NULL)) + { + char szTemp[MAX_KEYVALUE_LEN]; + Q_snprintf(szTemp, sizeof( szTemp ), "\"%s\" \"%s\"", pszKey, pszValue); + return(WriteLine(szTemp)); + } + + return(ChunkFile_Ok); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : pszKey - +// bValue - +// Output : +//----------------------------------------------------------------------------- +ChunkFileResult_t CChunkFile::WriteKeyValueBool(const char *pszKey, bool bValue) +{ + if (pszKey != NULL) + { + char szBuf[MAX_KEYVALUE_LEN]; + Q_snprintf(szBuf, sizeof( szBuf ), "\"%s\" \"%d\"", pszKey, (int)bValue); + return(WriteLine(szBuf)); + } + + return(ChunkFile_Ok); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : pszKey - +// nValue - +// Output : +//----------------------------------------------------------------------------- +ChunkFileResult_t CChunkFile::WriteKeyValueInt(const char *pszKey, int nValue) +{ + if (pszKey != NULL) + { + char szBuf[MAX_KEYVALUE_LEN]; + Q_snprintf(szBuf, sizeof( szBuf ), "\"%s\" \"%d\"", pszKey, nValue); + return(WriteLine(szBuf)); + } + + return(ChunkFile_Ok); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : pszKey - +// fValue - +// Output : +//----------------------------------------------------------------------------- +ChunkFileResult_t CChunkFile::WriteKeyValueFloat(const char *pszKey, float fValue) +{ + if (pszKey != NULL) + { + char szBuf[MAX_KEYVALUE_LEN]; + Q_snprintf(szBuf, sizeof( szBuf ), "\"%s\" \"%g\"", pszKey, (double)fValue); + return(WriteLine(szBuf)); + } + + return(ChunkFile_Ok); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : pszKey - +// r - +// g - +// b - +// Output : +//----------------------------------------------------------------------------- +ChunkFileResult_t CChunkFile::WriteKeyValueColor(const char *pszKey, unsigned char r, unsigned char g, unsigned char b) +{ + if (pszKey != NULL) + { + char szBuf[MAX_KEYVALUE_LEN]; + Q_snprintf(szBuf, sizeof( szBuf ), "\"%s\" \"%d %d %d\"", pszKey, (int)r, (int)g, (int)b); + return(WriteLine(szBuf)); + } + + return(ChunkFile_Ok); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : pszKey - +// fVector - +// Output : +//----------------------------------------------------------------------------- +ChunkFileResult_t CChunkFile::WriteKeyValuePoint(const char *pszKey, const Vector &Point) +{ + if (pszKey != NULL) + { + char szBuf[MAX_KEYVALUE_LEN]; + Q_snprintf(szBuf, sizeof( szBuf ), "\"%s\" \"(%g %g %g)\"", pszKey, (double)Point[0], (double)Point[1], (double)Point[2]); + return(WriteLine(szBuf)); + } + + return(ChunkFile_Ok); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +ChunkFileResult_t CChunkFile::WriteKeyValueVector2(const char *pszKey, const Vector2D &vec) +{ + if (pszKey != NULL) + { + char szBuf[MAX_KEYVALUE_LEN]; + Q_snprintf( szBuf, sizeof( szBuf ), "\"%s\" \"[%g %g]\"", pszKey, (double)vec.x, (double)vec.y ); + return(WriteLine(szBuf)); + } + + return(ChunkFile_Ok); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +ChunkFileResult_t CChunkFile::WriteKeyValueVector3(const char *pszKey, const Vector &vec) +{ + if (pszKey != NULL) + { + char szBuf[MAX_KEYVALUE_LEN]; + Q_snprintf(szBuf, sizeof( szBuf ), "\"%s\" \"[%g %g %g]\"", pszKey, (double)vec.x, (double)vec.y, (double)vec.z); + return(WriteLine(szBuf)); + } + + return(ChunkFile_Ok); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : pszKey - +// fVector - +// Output : +//----------------------------------------------------------------------------- +ChunkFileResult_t CChunkFile::WriteKeyValueVector4(const char *pszKey, const Vector4D &vec) +{ + if (pszKey != NULL) + { + char szBuf[MAX_KEYVALUE_LEN]; + Q_snprintf(szBuf, sizeof( szBuf ), "\"%s\" \"[%g %g %g %g]\"", pszKey, (double)vec.x, (double)vec.y, (double)vec.z, (double)vec.w); + return( WriteLine( szBuf ) ); + } + + return( ChunkFile_Ok ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pszLine - +// Output : +//----------------------------------------------------------------------------- +ChunkFileResult_t CChunkFile::WriteLine(const char *pszLine) +{ + if (pszLine != NULL) + { + // + // Write the indentation string. + // + if (m_nCurrentDepth > 0) + { + int nWritten = fwrite(m_szIndent, 1, m_nCurrentDepth, m_hFile); + if (nWritten != m_nCurrentDepth) + { + return(ChunkFile_Fail); + } + } + + // + // Write the string. + // + int nLen = strlen(pszLine); + int nWritten = fwrite(pszLine, 1, nLen, m_hFile); + if (nWritten != nLen) + { + return(ChunkFile_Fail); + } + + // + // Write the linefeed. + // + if (fwrite("\r\n", 1, 2, m_hFile) != 2) + { + return(ChunkFile_Fail); + } + } + + return(ChunkFile_Ok); +} + diff --git a/sp/src/public/chunkfile.h b/sp/src/public/chunkfile.h new file mode 100644 index 00000000..6359ace9 --- /dev/null +++ b/sp/src/public/chunkfile.h @@ -0,0 +1,197 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#ifndef CHUNKFILE_H +#define CHUNKFILE_H + +#ifdef _WIN32 +#pragma once +#endif + +#include +#include "tokenreader.h" + + +#define MAX_INDENT_DEPTH 80 +#define MAX_KEYVALUE_LEN 1024 + + +class CChunkFile; +class Vector2D; +class Vector; +class Vector4D; + + +// +// Modes for Open. +// +enum ChunkFileOpenMode_t +{ + ChunkFile_Read = 0, + ChunkFile_Write, +}; + + +// +// Return codes. +// +enum ChunkFileResult_t +{ + ChunkFile_Ok = 0, + ChunkFile_Fail, + ChunkFile_OpenFail, + ChunkFile_EndOfChunk, + ChunkFile_EOF, + ChunkFile_UnexpectedEOF, + ChunkFile_UnexpectedSymbol, + ChunkFile_OutOfMemory, + ChunkFile_StringTooLong, + ChunkFile_NotHandled +}; + + +enum ChunkType_t +{ + ChunkType_Key = 0, + ChunkType_Chunk, +}; + + +typedef ChunkFileResult_t (*DefaultChunkHandler_t)(CChunkFile *pFile, void *pData, char const *pChunkName); + +typedef ChunkFileResult_t (*ChunkHandler_t)(CChunkFile *pFile, void *pData); +typedef ChunkFileResult_t (*KeyHandler_t)(const char *szKey, const char *szValue, void *pData); +typedef bool (*ChunkErrorHandler_t)(CChunkFile *pFile, const char *szChunkName, void *pData); + + +struct ChunkHandlerInfo_t +{ + char szChunkName[80]; + ChunkHandler_t pfnHandler; + void *pData; +}; + + +struct ChunkHandlerInfoNode_t +{ + ChunkHandlerInfo_t Handler; + struct ChunkHandlerInfoNode_t *pNext; +}; + + +// +// Consider handling chunks with handler objects instead of callbacks. +// +//class CChunkHandler +//{ +// virtual ChunkFileResult_t HandleChunk(const char *szName); +// virtual ChunkFileResult_t HandleKey(const char *szKey, const char *szValue); +// virtual bool HandleError(const char *szChunkName, ChunkFileResult_t eError); +//}; + + +class CChunkHandlerMap +{ + public: + + CChunkHandlerMap(void); + ~CChunkHandlerMap(void); + + void AddHandler(const char *pszChunkName, ChunkHandler_t pfnHandler, void *pData); + ChunkHandler_t GetHandler(const char *pszChunkName, void **pData); + + void SetErrorHandler(ChunkErrorHandler_t pfnHandler, void *pData); + ChunkErrorHandler_t GetErrorHandler(void **pData); + + protected: + + ChunkHandlerInfoNode_t *m_pHandlers; + ChunkErrorHandler_t m_pfnErrorHandler; + void *m_pErrorData; +}; + + +class CChunkFile +{ + public: + + CChunkFile(void); + ~CChunkFile(void); + + ChunkFileResult_t Open(const char *pszFileName, ChunkFileOpenMode_t eMode); + ChunkFileResult_t Close(void); + const char *GetErrorText(ChunkFileResult_t eResult); + + // + // Functions for writing chunk files. + // + ChunkFileResult_t BeginChunk(const char *pszChunkName); + ChunkFileResult_t EndChunk(void); + + ChunkFileResult_t WriteKeyValue(const char *pszKey, const char *pszValue); + ChunkFileResult_t WriteKeyValueBool(const char *pszKey, bool bValue); + ChunkFileResult_t WriteKeyValueColor(const char *pszKey, unsigned char r, unsigned char g, unsigned char b); + ChunkFileResult_t WriteKeyValueFloat(const char *pszKey, float fValue); + ChunkFileResult_t WriteKeyValueInt(const char *pszKey, int nValue); + ChunkFileResult_t WriteKeyValuePoint(const char *pszKey, const Vector &Point); + ChunkFileResult_t WriteKeyValueVector2(const char *pszKey, const Vector2D &vec); + ChunkFileResult_t WriteKeyValueVector3(const char *pszKey, const Vector &vec); + ChunkFileResult_t WriteKeyValueVector4( const char *pszKey, const Vector4D &vec); + + ChunkFileResult_t WriteLine(const char *pszLine); + + // + // Functions for reading chunk files. + // + ChunkFileResult_t ReadChunk(KeyHandler_t pfnKeyHandler = NULL, void *pData = NULL); + ChunkFileResult_t ReadNext(char *szKey, char *szValue, int nValueSize, ChunkType_t &eChunkType); + ChunkFileResult_t HandleChunk(const char *szChunkName); + void HandleError(const char *szChunkName, ChunkFileResult_t eError); + + // These functions should more really be named Parsexxx and possibly moved elsewhere. + static bool ReadKeyValueBool(const char *pszValue, bool &bBool); + static bool ReadKeyValueColor(const char *pszValue, unsigned char &chRed, unsigned char &chGreen, unsigned char &chBlue); + static bool ReadKeyValueInt(const char *pszValue, int &nInt); + static bool ReadKeyValueFloat(const char *pszValue, float &flFloat); + static bool ReadKeyValuePoint(const char *pszValue, Vector &Point); + static bool ReadKeyValueVector2(const char *pszValue, Vector2D &vec); + static bool ReadKeyValueVector3(const char *pszValue, Vector &vec); + static bool ReadKeyValueVector4( const char *pszValue, Vector4D &vec); + + // The default chunk handler gets called before any other chunk handlers. + // + // If the handler returns ChunkFile_Ok, then it goes into the chunk. + // If the handler returns ChunkFile_NotHandled, then the chunk is + // passed to the regular handlers. + // + // If you pass NULL in here, then it disables the default chunk handler. + void SetDefaultChunkHandler( DefaultChunkHandler_t pHandler, void *pData ); + + void PushHandlers(CChunkHandlerMap *pHandlerMap); + void PopHandlers(void); + + protected: + + void BuildIndentString(char *pszDest, int nDepth); + + TokenReader m_TokenReader; + + FILE *m_hFile; + char m_szErrorToken[80]; + char m_szIndent[MAX_INDENT_DEPTH]; + int m_nCurrentDepth; + + // See SetDefaultChunkHandler.. + DefaultChunkHandler_t m_DefaultChunkHandler; + void *m_pDefaultChunkHandlerData; + + CChunkHandlerMap *m_HandlerStack[MAX_INDENT_DEPTH]; + int m_nHandlerStackDepth; +}; + + +#endif // CHUNKFILE_H diff --git a/sp/src/public/client_class.cpp b/sp/src/public/client_class.cpp new file mode 100644 index 00000000..bbb5bc09 --- /dev/null +++ b/sp/src/public/client_class.cpp @@ -0,0 +1,16 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "client_class.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +ClientClass *g_pClientClassHead=0; + + diff --git a/sp/src/public/client_class.h b/sp/src/public/client_class.h new file mode 100644 index 00000000..77827d8d --- /dev/null +++ b/sp/src/public/client_class.h @@ -0,0 +1,180 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// +#if !defined( CLIENT_CLASS_H ) +#define CLIENT_CLASS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "interface.h" +#include "dt_recv.h" + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- + +class Vector; +class CMouthInfo; + + +//----------------------------------------------------------------------------- +// represents a handle used only by the client DLL +//----------------------------------------------------------------------------- + +#include "iclientrenderable.h" +#include "iclientnetworkable.h" + + +class ClientClass; +// Linked list of all known client classes +extern ClientClass *g_pClientClassHead; + +// The serial number that gets passed in is used for ehandles. +typedef IClientNetworkable* (*CreateClientClassFn)( int entnum, int serialNum ); +typedef IClientNetworkable* (*CreateEventFn)(); + +//----------------------------------------------------------------------------- +// Purpose: Client side class definition +//----------------------------------------------------------------------------- +class ClientClass +{ +public: + ClientClass( const char *pNetworkName, CreateClientClassFn createFn, CreateEventFn createEventFn, RecvTable *pRecvTable ) + { + m_pNetworkName = pNetworkName; + m_pCreateFn = createFn; + m_pCreateEventFn= createEventFn; + m_pRecvTable = pRecvTable; + + // Link it in + m_pNext = g_pClientClassHead; + g_pClientClassHead = this; + } + + const char* GetName() + { + return m_pNetworkName; + } + +public: + CreateClientClassFn m_pCreateFn; + CreateEventFn m_pCreateEventFn; // Only called for event objects. + const char *m_pNetworkName; + RecvTable *m_pRecvTable; + ClientClass *m_pNext; + int m_ClassID; // Managed by the engine. +}; + +#define DECLARE_CLIENTCLASS() \ + virtual int YouForgotToImplementOrDeclareClientClass();\ + virtual ClientClass* GetClientClass();\ + static RecvTable *m_pClassRecvTable; \ + DECLARE_CLIENTCLASS_NOBASE() + + +// This can be used to give all datatables access to protected and private members of the class. +#define ALLOW_DATATABLES_PRIVATE_ACCESS() \ + template friend int ClientClassInit(T *); + + +#define DECLARE_CLIENTCLASS_NOBASE ALLOW_DATATABLES_PRIVATE_ACCESS + +// This macro adds a ClientClass to the linked list in g_pClientClassHead (so +// the list can be given to the engine). +// Use this macro to expose your client class to the engine. +// networkName must match the network name of a class registered on the server. +#define IMPLEMENT_CLIENTCLASS(clientClassName, dataTable, serverClassName) \ + INTERNAL_IMPLEMENT_CLIENTCLASS_PROLOGUE(clientClassName, dataTable, serverClassName) \ + static IClientNetworkable* _##clientClassName##_CreateObject( int entnum, int serialNum ) \ + { \ + clientClassName *pRet = new clientClassName; \ + if ( !pRet ) \ + return 0; \ + pRet->Init( entnum, serialNum ); \ + return pRet; \ + } \ + ClientClass __g_##clientClassName##ClientClass(#serverClassName, \ + _##clientClassName##_CreateObject, \ + NULL,\ + &dataTable::g_RecvTable); + +// Implement a client class and provide a factory so you can allocate and delete it yourself +// (or make it a singleton). +#define IMPLEMENT_CLIENTCLASS_FACTORY(clientClassName, dataTable, serverClassName, factory) \ + INTERNAL_IMPLEMENT_CLIENTCLASS_PROLOGUE(clientClassName, dataTable, serverClassName) \ + ClientClass __g_##clientClassName##ClientClass(#serverClassName, \ + factory, \ + NULL,\ + &dataTable::g_RecvTable); + +// The IMPLEMENT_CLIENTCLASS_DT macros do IMPLEMENT_CLIENT_CLASS and also do BEGIN_RECV_TABLE. +#define IMPLEMENT_CLIENTCLASS_DT(clientClassName, dataTable, serverClassName)\ + IMPLEMENT_CLIENTCLASS(clientClassName, dataTable, serverClassName)\ + BEGIN_RECV_TABLE(clientClassName, dataTable) + +#define IMPLEMENT_CLIENTCLASS_DT_NOBASE(clientClassName, dataTable, serverClassName)\ + IMPLEMENT_CLIENTCLASS(clientClassName, dataTable, serverClassName)\ + BEGIN_RECV_TABLE_NOBASE(clientClassName, dataTable) + + +// Using IMPLEMENT_CLIENTCLASS_EVENT means the engine thinks the entity is an event so the entity +// is responsible for freeing itself. +#define IMPLEMENT_CLIENTCLASS_EVENT(clientClassName, dataTable, serverClassName)\ + INTERNAL_IMPLEMENT_CLIENTCLASS_PROLOGUE(clientClassName, dataTable, serverClassName)\ + static clientClassName __g_##clientClassName; \ + static IClientNetworkable* _##clientClassName##_CreateObject() {return &__g_##clientClassName;}\ + ClientClass __g_##clientClassName##ClientClass(#serverClassName, \ + NULL,\ + _##clientClassName##_CreateObject, \ + &dataTable::g_RecvTable); + +#define IMPLEMENT_CLIENTCLASS_EVENT_DT(clientClassName, dataTable, serverClassName)\ + namespace dataTable {extern RecvTable g_RecvTable;}\ + IMPLEMENT_CLIENTCLASS_EVENT(clientClassName, dataTable, serverClassName)\ + BEGIN_RECV_TABLE(clientClassName, dataTable) + + +// Register a client event singleton but specify a pointer to give to the engine rather than +// have a global instance. This is useful if you're using Initializers and your object's constructor +// uses some other global object (so you must use Initializers so you're constructed afterwards). +#define IMPLEMENT_CLIENTCLASS_EVENT_POINTER(clientClassName, dataTable, serverClassName, ptr)\ + INTERNAL_IMPLEMENT_CLIENTCLASS_PROLOGUE(clientClassName, dataTable, serverClassName)\ + static IClientNetworkable* _##clientClassName##_CreateObject() {return ptr;}\ + ClientClass __g_##clientClassName##ClientClass(#serverClassName, \ + NULL,\ + _##clientClassName##_CreateObject, \ + &dataTable::g_RecvTable); + +#define IMPLEMENT_CLIENTCLASS_EVENT_NONSINGLETON(clientClassName, dataTable, serverClassName)\ + static IClientNetworkable* _##clientClassName##_CreateObject() \ + { \ + clientClassName *p = new clientClassName; \ + if ( p ) \ + p->Init( -1, 0 ); \ + return p; \ + } \ + ClientClass __g_##clientClassName##ClientClass(#serverClassName, \ + NULL,\ + _##clientClassName##_CreateObject, \ + &dataTable::g_RecvTable); + + +// Used internally.. +#define INTERNAL_IMPLEMENT_CLIENTCLASS_PROLOGUE(clientClassName, dataTable, serverClassName) \ + namespace dataTable {extern RecvTable g_RecvTable;}\ + extern ClientClass __g_##clientClassName##ClientClass;\ + RecvTable* clientClassName::m_pClassRecvTable = &dataTable::g_RecvTable;\ + int clientClassName::YouForgotToImplementOrDeclareClientClass() {return 0;}\ + ClientClass* clientClassName::GetClientClass() {return &__g_##clientClassName##ClientClass;} + +#endif // CLIENT_CLASS_H diff --git a/sp/src/public/client_render_handle.h b/sp/src/public/client_render_handle.h new file mode 100644 index 00000000..81625406 --- /dev/null +++ b/sp/src/public/client_render_handle.h @@ -0,0 +1,31 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef CLIENT_RENDER_HANDLE_H +#define CLIENT_RENDER_HANDLE_H +#ifdef _WIN32 +#pragma once +#endif + + +//----------------------------------------------------------------------------- +// Foward declarations +//----------------------------------------------------------------------------- +class IClientRenderable; + + +//----------------------------------------------------------------------------- +// Handle to an renderable in the client leaf system +//----------------------------------------------------------------------------- +typedef unsigned short ClientRenderHandle_t; + +enum +{ + INVALID_CLIENT_RENDER_HANDLE = (ClientRenderHandle_t)0xffff, +}; + + +#endif // CLIENT_RENDER_HANDLE_H diff --git a/sp/src/public/client_textmessage.h b/sp/src/public/client_textmessage.h new file mode 100644 index 00000000..a48490ba --- /dev/null +++ b/sp/src/public/client_textmessage.h @@ -0,0 +1,33 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef CLIENT_TEXTMESSAGE_H +#define CLIENT_TEXTMESSAGE_H +#ifdef _WIN32 +#pragma once +#endif + +struct client_textmessage_t +{ + int effect; + byte r1, g1, b1, a1; // 2 colors for effects + byte r2, g2, b2, a2; + float x; + float y; + float fadein; + float fadeout; + float holdtime; + float fxtime; + const char *pVGuiSchemeFontName; // If null, use default font for messages + const char *pName; + const char *pMessage; + bool bRoundedRectBackdropBox; + float flBoxSize; // as a function of font height + byte boxcolor[4]; + char const *pClearMessage; // message to clear +}; + +#endif // CLIENT_TEXTMESSAGE_H diff --git a/sp/src/public/clientstats.h b/sp/src/public/clientstats.h new file mode 100644 index 00000000..c3340696 --- /dev/null +++ b/sp/src/public/clientstats.h @@ -0,0 +1,198 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#if !defined( CLIENTSTATS_H ) +#define CLIENTSTATS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "interface.h" +#include +#include "tier0/dbg.h" + +#define INTERFACEVERSION_CLIENTSTATS "ClientStats004" + +//----------------------------------------------------------------------------- +// An interface used to help the client stats implementation tell time +//----------------------------------------------------------------------------- + +struct IClientStatsTime +{ + virtual float GetTime() = 0; +}; + +//----------------------------------------------------------------------------- +// Allows clients to draw their own stats text, will be passed by the +// engine into DisplayStats of the IClientStats interface. +//----------------------------------------------------------------------------- + +struct IClientStatsTextDisplay +{ + // Draws the stats + virtual void DrawStatsText( PRINTF_FORMAT_STRING const char *fmt, ... ) = 0; + + virtual void SetDrawColor( unsigned char r, unsigned char g, unsigned char b ) = 0; + + // Sets a color based on a value and its max acceptable limit + virtual void SetDrawColorFromStatValues( float limit, float value ) = 0; +}; + + +//----------------------------------------------------------------------------- +// This will exist as a singleton within the client DLL and will be hooked into +// the engine to allow clients to render their own stats. +//----------------------------------------------------------------------------- + +abstract_class IClientStats +{ +public: + // This is called at startup to tell the stats about time + virtual void Init( IClientStatsTime* pTime ) = 0; + + // These methods are called at the beginning and the end of each run + virtual void BeginRun() = 0; + virtual void EndRun() = 0; + + // These methods are called at the beginning and the end of each frame + virtual void BeginFrame() = 0; + virtual void EndFrame() = 0; + + // --------------------------------------------------------------- + // All this stuff is used to prop stats for gathering r_speeds data during timedemo. + // --------------------------------------------------------------- + virtual int GetNumTimesStats( void ) const = 0; + + // returns timed stats + virtual double TimedStatInFrame( int statID ) const = 0; + virtual double TotalTimedStat( int statID ) const = 0; +}; + + +//----------------------------------------------------------------------------- +// This is a templatized implementation which can be instantiated anywhere +// Note that you still have to install it and display it though. +//----------------------------------------------------------------------------- + +template +abstract_class CBaseClientStats : public IClientStats +{ +public: + void Init( IClientStatsTime* pTime ); + void BeginRun(); + void EndRun(); + void BeginFrame(); + void EndFrame(); + + // Timed stat gathering + void BeginTimedStat( int stat ); + void EndTimedStat( int stat ); + + // --------------------------------------------------------------- + // All this stuff is used to prop stats for gathering r_speeds data during timedemo. + // --------------------------------------------------------------- + // returns timed stats + double TimedStatInFrame( int statID ) const + { + Assert( statID >= 0 && statID < timedStatCount ); + Assert( m_StatFrameTime[statID] >= 0.0 ); + return m_StatFrameTime[statID]; + } + + double TotalTimedStat( int statID ) const + { + Assert( statID >= 0 && statID < timedStatCount ); + return m_TotalStatTime[statID]; + } + virtual const char *GetCountedStatName( int statID ) const = 0; + virtual const char *GetTimedStatName( int statID ) const = 0; + +protected: + + // Timed statistics + double m_StatFrameTime[timedStatCount]; + double m_StatStartTime[timedStatCount]; + double m_TotalStatTime[timedStatCount]; + +private: + IClientStatsTime* m_pTime; +}; + + +//----------------------------------------------------------------------------- +// Initializes client stats +//----------------------------------------------------------------------------- + +template +void CBaseClientStats::Init( IClientStatsTime* pTime ) +{ + Assert( pTime ); + m_pTime = pTime; +} + +//----------------------------------------------------------------------------- +// These methods are called at the beginning and the end of each run +//----------------------------------------------------------------------------- + +template +void CBaseClientStats::BeginRun() +{ + int i; + + for (i = 0; i < timedStatCount; ++i) + m_TotalStatTime[i] = 0.0; + +} + +template +void CBaseClientStats::EndRun() +{ +} + + +//----------------------------------------------------------------------------- +// These methods are called at the beginning and the end of each frame +//----------------------------------------------------------------------------- + +template +void CBaseClientStats::BeginFrame() +{ + int i; + for (i = 0; i < timedStatCount; ++i) + m_StatFrameTime[i] = 0.0; +} + +template +void CBaseClientStats::EndFrame() +{ + int i; + for (i = 0; i < timedStatCount; ++i) + m_TotalStatTime[i] += m_StatFrameTime[i]; +} + + +//----------------------------------------------------------------------------- +// Inlined stat gathering methods +//----------------------------------------------------------------------------- + +template +void CBaseClientStats::BeginTimedStat( int stat ) +{ + if (m_pTime) + m_StatStartTime[stat] = m_pTime->GetTime(); +} + +template +void CBaseClientStats::EndTimedStat( int stat ) +{ + if (m_pTime) + m_StatFrameTime[stat] += m_pTime->GetTime() - m_StatStartTime[stat]; +} + + +#endif // CLIENTSTATS_H diff --git a/sp/src/public/cmodel.h b/sp/src/public/cmodel.h new file mode 100644 index 00000000..3e13cb56 --- /dev/null +++ b/sp/src/public/cmodel.h @@ -0,0 +1,129 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//=============================================================================// + +#ifndef CMODEL_H +#define CMODEL_H +#ifdef _WIN32 +#pragma once +#endif + +#include "trace.h" +#include "tier0/dbg.h" +#include "basehandle.h" + +struct edict_t; +struct model_t; + +/* +============================================================== + +COLLISION DETECTION + +============================================================== +*/ + +#include "bspflags.h" +//#include "mathlib/vector.h" + +// gi.BoxEdicts() can return a list of either solid or trigger entities +// FIXME: eliminate AREA_ distinction? +#define AREA_SOLID 1 +#define AREA_TRIGGERS 2 + +#include "vcollide.h" + +struct cmodel_t +{ + Vector mins, maxs; + Vector origin; // for sounds or lights + int headnode; + + vcollide_t vcollisionData; +}; + +struct csurface_t +{ + const char *name; + short surfaceProps; + unsigned short flags; // BUGBUG: These are declared per surface, not per material, but this database is per-material now +}; + +//----------------------------------------------------------------------------- +// A ray... +//----------------------------------------------------------------------------- + +struct Ray_t +{ + VectorAligned m_Start; // starting point, centered within the extents + VectorAligned m_Delta; // direction + length of the ray + VectorAligned m_StartOffset; // Add this to m_Start to get the actual ray start + VectorAligned m_Extents; // Describes an axis aligned box extruded along a ray + bool m_IsRay; // are the extents zero? + bool m_IsSwept; // is delta != 0? + + void Init( Vector const& start, Vector const& end ) + { + Assert( &end ); + VectorSubtract( end, start, m_Delta ); + + m_IsSwept = (m_Delta.LengthSqr() != 0); + + VectorClear( m_Extents ); + m_IsRay = true; + + // Offset m_Start to be in the center of the box... + VectorClear( m_StartOffset ); + VectorCopy( start, m_Start ); + } + + void Init( Vector const& start, Vector const& end, Vector const& mins, Vector const& maxs ) + { + Assert( &end ); + VectorSubtract( end, start, m_Delta ); + + m_IsSwept = (m_Delta.LengthSqr() != 0); + + VectorSubtract( maxs, mins, m_Extents ); + m_Extents *= 0.5f; + m_IsRay = (m_Extents.LengthSqr() < 1e-6); + + // Offset m_Start to be in the center of the box... + VectorAdd( mins, maxs, m_StartOffset ); + m_StartOffset *= 0.5f; + VectorAdd( start, m_StartOffset, m_Start ); + m_StartOffset *= -1.0f; + } + + // compute inverse delta + Vector InvDelta() const + { + Vector vecInvDelta; + for ( int iAxis = 0; iAxis < 3; ++iAxis ) + { + if ( m_Delta[iAxis] != 0.0f ) + { + vecInvDelta[iAxis] = 1.0f / m_Delta[iAxis]; + } + else + { + vecInvDelta[iAxis] = FLT_MAX; + } + } + return vecInvDelta; + } + +private: +}; + + +#endif // CMODEL_H + + +#include "gametrace.h" + diff --git a/sp/src/public/collisionutils.cpp b/sp/src/public/collisionutils.cpp new file mode 100644 index 00000000..d26db4ab --- /dev/null +++ b/sp/src/public/collisionutils.cpp @@ -0,0 +1,3262 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Common collision utility methods +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#if !defined(_STATIC_LINKED) || defined(_SHARED_LIB) + +#include "collisionutils.h" +#include "cmodel.h" +#include "mathlib/mathlib.h" +#include "mathlib/vector.h" +#include "tier0/dbg.h" +#include +#include "mathlib/vector4d.h" +#include "trace.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define UNINIT -99999.0 + +//----------------------------------------------------------------------------- +// Clears the trace +//----------------------------------------------------------------------------- +static void Collision_ClearTrace( const Vector &vecRayStart, const Vector &vecRayDelta, CBaseTrace *pTrace ) +{ + pTrace->startpos = vecRayStart; + pTrace->endpos = vecRayStart; + pTrace->endpos += vecRayDelta; + pTrace->startsolid = false; + pTrace->allsolid = false; + pTrace->fraction = 1.0f; + pTrace->contents = 0; +} + + +//----------------------------------------------------------------------------- +// Compute the offset in t along the ray that we'll use for the collision +//----------------------------------------------------------------------------- +static float ComputeBoxOffset( const Ray_t& ray ) +{ + if (ray.m_IsRay) + return 1e-3f; + + // Find the projection of the box diagonal along the ray... + float offset = FloatMakePositive(ray.m_Extents[0] * ray.m_Delta[0]) + + FloatMakePositive(ray.m_Extents[1] * ray.m_Delta[1]) + + FloatMakePositive(ray.m_Extents[2] * ray.m_Delta[2]); + + // We need to divide twice: Once to normalize the computation above + // so we get something in units of extents, and the second to normalize + // that with respect to the entire raycast. + offset *= InvRSquared( ray.m_Delta ); + + // 1e-3 is an epsilon + return offset + 1e-3; +} + + +//----------------------------------------------------------------------------- +// Intersects a swept box against a triangle +//----------------------------------------------------------------------------- +float IntersectRayWithTriangle( const Ray_t& ray, + const Vector& v1, const Vector& v2, const Vector& v3, bool oneSided ) +{ + // This is cute: Use barycentric coordinates to represent the triangle + // Vo(1-u-v) + V1u + V2v and intersect that with a line Po + Dt + // This gives us 3 equations + 3 unknowns, which we can solve with + // Cramer's rule... + // E1x u + E2x v - Dx t = Pox - Vox + // There's a couple of other optimizations, Cramer's rule involves + // computing the determinant of a matrix which has been constructed + // by three vectors. It turns out that + // det | A B C | = -( A x C ) dot B or -(C x B) dot A + // which we'll use below.. + + Vector edge1, edge2, org; + VectorSubtract( v2, v1, edge1 ); + VectorSubtract( v3, v1, edge2 ); + + // Cull out one-sided stuff + if (oneSided) + { + Vector normal; + CrossProduct( edge1, edge2, normal ); + if (DotProduct( normal, ray.m_Delta ) >= 0.0f) + return -1.0f; + } + + // FIXME: This is inaccurate, but fast for boxes + // We want to do a fast separating axis implementation here + // with a swept triangle along the reverse direction of the ray. + + // Compute some intermediary terms + Vector dirCrossEdge2, orgCrossEdge1; + CrossProduct( ray.m_Delta, edge2, dirCrossEdge2 ); + + // Compute the denominator of Cramer's rule: + // | -Dx E1x E2x | + // det | -Dy E1y E2y | = (D x E2) dot E1 + // | -Dz E1z E2z | + float denom = DotProduct( dirCrossEdge2, edge1 ); + if( FloatMakePositive( denom ) < 1e-6 ) + return -1.0f; + denom = 1.0f / denom; + + // Compute u. It's gotta lie in the range of 0 to 1. + // | -Dx orgx E2x | + // u = denom * det | -Dy orgy E2y | = (D x E2) dot org + // | -Dz orgz E2z | + VectorSubtract( ray.m_Start, v1, org ); + float u = DotProduct( dirCrossEdge2, org ) * denom; + if ((u < 0.0f) || (u > 1.0f)) + return -1.0f; + + // Compute t and v the same way... + // In barycentric coords, u + v < 1 + CrossProduct( org, edge1, orgCrossEdge1 ); + float v = DotProduct( orgCrossEdge1, ray.m_Delta ) * denom; + if ((v < 0.0f) || (v + u > 1.0f)) + return -1.0f; + + // Compute the distance along the ray direction that we need to fudge + // when using swept boxes + float boxt = ComputeBoxOffset( ray ); + float t = DotProduct( orgCrossEdge1, edge2 ) * denom; + if ((t < -boxt) || (t > 1.0f + boxt)) + return -1.0f; + + return clamp( t, 0.f, 1.f ); +} + +//----------------------------------------------------------------------------- +// computes the barycentric coordinates of an intersection +//----------------------------------------------------------------------------- + +bool ComputeIntersectionBarycentricCoordinates( const Ray_t& ray, + const Vector& v1, const Vector& v2, const Vector& v3, float& u, float& v, + float *t ) +{ + Vector edge1, edge2, org; + VectorSubtract( v2, v1, edge1 ); + VectorSubtract( v3, v1, edge2 ); + + // Compute some intermediary terms + Vector dirCrossEdge2, orgCrossEdge1; + CrossProduct( ray.m_Delta, edge2, dirCrossEdge2 ); + + // Compute the denominator of Cramer's rule: + // | -Dx E1x E2x | + // det | -Dy E1y E2y | = (D x E2) dot E1 + // | -Dz E1z E2z | + float denom = DotProduct( dirCrossEdge2, edge1 ); + if( FloatMakePositive( denom ) < 1e-6 ) + return false; + denom = 1.0f / denom; + + // Compute u. It's gotta lie in the range of 0 to 1. + // | -Dx orgx E2x | + // u = denom * det | -Dy orgy E2y | = (D x E2) dot org + // | -Dz orgz E2z | + VectorSubtract( ray.m_Start, v1, org ); + u = DotProduct( dirCrossEdge2, org ) * denom; + + // Compute t and v the same way... + // In barycentric coords, u + v < 1 + CrossProduct( org, edge1, orgCrossEdge1 ); + v = DotProduct( orgCrossEdge1, ray.m_Delta ) * denom; + + // Compute the distance along the ray direction that we need to fudge + // when using swept boxes + if( t ) + { + float boxt = ComputeBoxOffset( ray ); + *t = DotProduct( orgCrossEdge1, edge2 ) * denom; + if( ( *t < -boxt ) || ( *t > 1.0f + boxt ) ) + return false; + } + + return true; +} + +//----------------------------------------------------------------------------- +// Intersects a plane with a triangle (requires barycentric definition) +//----------------------------------------------------------------------------- + +int IntersectTriangleWithPlaneBarycentric( const Vector& org, const Vector& edgeU, + const Vector& edgeV, const Vector4D& plane, Vector2D* pIntersection ) +{ + // This uses a barycentric method, since we need that to determine + // interpolated points, alphas, and normals + // Given the plane equation P dot N + d = 0 + // and the barycentric coodinate equation P = Org + EdgeU * u + EdgeV * v + // Plug em in. Intersection occurs at u = 0 or v = 0 or u + v = 1 + + float orgDotNormal = DotProduct( org, plane.AsVector3D() ); + float edgeUDotNormal = DotProduct( edgeU, plane.AsVector3D() ); + float edgeVDotNormal = DotProduct( edgeV, plane.AsVector3D() ); + + int ptIdx = 0; + + // u = 0 + if ( edgeVDotNormal != 0.0f ) + { + pIntersection[ptIdx].x = 0.0f; + pIntersection[ptIdx].y = - ( orgDotNormal - plane.w ) / edgeVDotNormal; + if ((pIntersection[ptIdx].y >= 0.0f) && (pIntersection[ptIdx].y <= 1.0f)) + ++ptIdx; + } + + // v = 0 + if ( edgeUDotNormal != 0.0f ) + { + pIntersection[ptIdx].x = - ( orgDotNormal - plane.w ) / edgeUDotNormal; + pIntersection[ptIdx].y = 0.0f; + if ((pIntersection[ptIdx].x >= 0.0f) && (pIntersection[ptIdx].x <= 1.0f)) + ++ptIdx; + } + + // u + v = 1 + if (ptIdx == 2) + return ptIdx; + + if ( edgeVDotNormal != edgeUDotNormal ) + { + pIntersection[ptIdx].x = - ( orgDotNormal - plane.w + edgeVDotNormal) / + ( edgeUDotNormal - edgeVDotNormal); + pIntersection[ptIdx].y = 1.0f - pIntersection[ptIdx].x;; + if ((pIntersection[ptIdx].x >= 0.0f) && (pIntersection[ptIdx].x <= 1.0f) && + (pIntersection[ptIdx].y >= 0.0f) && (pIntersection[ptIdx].y <= 1.0f)) + ++ptIdx; + } + + Assert( ptIdx < 3 ); + return ptIdx; +} + + +//----------------------------------------------------------------------------- +// Returns true if a box intersects with a sphere +//----------------------------------------------------------------------------- +bool IsSphereIntersectingSphere( const Vector& center1, float radius1, + const Vector& center2, float radius2 ) +{ + Vector delta; + VectorSubtract( center2, center1, delta ); + float distSq = delta.LengthSqr(); + float radiusSum = radius1 + radius2; + return (distSq <= (radiusSum * radiusSum)); +} + + +//----------------------------------------------------------------------------- +// Returns true if a box intersects with a sphere +//----------------------------------------------------------------------------- +bool IsBoxIntersectingSphere( const Vector& boxMin, const Vector& boxMax, + const Vector& center, float radius ) +{ + // See Graphics Gems, box-sphere intersection + float dmin = 0.0f; + float flDelta; + + // Unrolled the loop.. this is a big cycle stealer... + if (center[0] < boxMin[0]) + { + flDelta = center[0] - boxMin[0]; + dmin += flDelta * flDelta; + } + else if (center[0] > boxMax[0]) + { + flDelta = boxMax[0] - center[0]; + dmin += flDelta * flDelta; + } + + if (center[1] < boxMin[1]) + { + flDelta = center[1] - boxMin[1]; + dmin += flDelta * flDelta; + } + else if (center[1] > boxMax[1]) + { + flDelta = boxMax[1] - center[1]; + dmin += flDelta * flDelta; + } + + if (center[2] < boxMin[2]) + { + flDelta = center[2] - boxMin[2]; + dmin += flDelta * flDelta; + } + else if (center[2] > boxMax[2]) + { + flDelta = boxMax[2] - center[2]; + dmin += flDelta * flDelta; + } + + return dmin < radius * radius; +} + +bool IsBoxIntersectingSphereExtents( const Vector& boxCenter, const Vector& boxHalfDiag, + const Vector& center, float radius ) +{ + // See Graphics Gems, box-sphere intersection + float dmin = 0.0f; + float flDelta, flDiff; + + // Unrolled the loop.. this is a big cycle stealer... + flDiff = FloatMakePositive( center.x - boxCenter.x ); + if (flDiff > boxHalfDiag.x) + { + flDelta = flDiff - boxHalfDiag.x; + dmin += flDelta * flDelta; + } + + flDiff = FloatMakePositive( center.y - boxCenter.y ); + if (flDiff > boxHalfDiag.y) + { + flDelta = flDiff - boxHalfDiag.y; + dmin += flDelta * flDelta; + } + + flDiff = FloatMakePositive( center.z - boxCenter.z ); + if (flDiff > boxHalfDiag.z) + { + flDelta = flDiff - boxHalfDiag.z; + dmin += flDelta * flDelta; + } + + return dmin < radius * radius; +} + + +//----------------------------------------------------------------------------- +// Returns true if a rectangle intersects with a circle +//----------------------------------------------------------------------------- +bool IsCircleIntersectingRectangle( const Vector2D& boxMin, const Vector2D& boxMax, + const Vector2D& center, float radius ) +{ + // See Graphics Gems, box-sphere intersection + float dmin = 0.0f; + float flDelta; + + if (center[0] < boxMin[0]) + { + flDelta = center[0] - boxMin[0]; + dmin += flDelta * flDelta; + } + else if (center[0] > boxMax[0]) + { + flDelta = boxMax[0] - center[0]; + dmin += flDelta * flDelta; + } + + if (center[1] < boxMin[1]) + { + flDelta = center[1] - boxMin[1]; + dmin += flDelta * flDelta; + } + else if (center[1] > boxMax[1]) + { + flDelta = boxMax[1] - center[1]; + dmin += flDelta * flDelta; + } + + return dmin < radius * radius; +} + + +//----------------------------------------------------------------------------- +// returns true if there's an intersection between ray and sphere +//----------------------------------------------------------------------------- +bool IsRayIntersectingSphere( const Vector &vecRayOrigin, const Vector &vecRayDelta, + const Vector& vecCenter, float flRadius, float flTolerance ) +{ + // For this algorithm, find a point on the ray which is closest to the sphere origin + // Do this by making a plane passing through the sphere origin + // whose normal is parallel to the ray. Intersect that plane with the ray. + // Plane: N dot P = I, N = D (ray direction), I = C dot N = C dot D + // Ray: P = O + D * t + // D dot ( O + D * t ) = C dot D + // D dot O + D dot D * t = C dot D + // t = (C - O) dot D / D dot D + // Clamp t to (0,1) + // Find distance of the point on the ray to the sphere center. + Assert( flTolerance >= 0.0f ); + flRadius += flTolerance; + + Vector vecRayToSphere; + VectorSubtract( vecCenter, vecRayOrigin, vecRayToSphere ); + float flNumerator = DotProduct( vecRayToSphere, vecRayDelta ); + + float t; + if (flNumerator <= 0.0f) + { + t = 0.0f; + } + else + { + float flDenominator = DotProduct( vecRayDelta, vecRayDelta ); + if ( flNumerator > flDenominator ) + t = 1.0f; + else + t = flNumerator / flDenominator; + } + + Vector vecClosestPoint; + VectorMA( vecRayOrigin, t, vecRayDelta, vecClosestPoint ); + return ( vecClosestPoint.DistToSqr( vecCenter ) <= flRadius * flRadius ); + + // NOTE: This in an alternate algorithm which I didn't use because I'd have to use a sqrt + // So it's probably faster to do this other algorithm. I'll leave the comments here + // for how to go back if we want to + + // Solve using the ray equation + the sphere equation + // P = o + dt + // (x - xc)^2 + (y - yc)^2 + (z - zc)^2 = r^2 + // (ox + dx * t - xc)^2 + (oy + dy * t - yc)^2 + (oz + dz * t - zc)^2 = r^2 + // (ox - xc)^2 + 2 * (ox-xc) * dx * t + dx^2 * t^2 + + // (oy - yc)^2 + 2 * (oy-yc) * dy * t + dy^2 * t^2 + + // (oz - zc)^2 + 2 * (oz-zc) * dz * t + dz^2 * t^2 = r^2 + // (dx^2 + dy^2 + dz^2) * t^2 + 2 * ((ox-xc)dx + (oy-yc)dy + (oz-zc)dz) t + + // (ox-xc)^2 + (oy-yc)^2 + (oz-zc)^2 - r^2 = 0 + // or, t = (-b +/- sqrt( b^2 - 4ac)) / 2a + // a = DotProduct( vecRayDelta, vecRayDelta ); + // b = 2 * DotProduct( vecRayOrigin - vecCenter, vecRayDelta ) + // c = DotProduct(vecRayOrigin - vecCenter, vecRayOrigin - vecCenter) - flRadius * flRadius; + // Valid solutions are possible only if b^2 - 4ac >= 0 + // Therefore, compute that value + see if we got it +} + + +//----------------------------------------------------------------------------- +// +// IntersectInfiniteRayWithSphere +// +// Returns whether or not there was an intersection. +// Returns the two intersection points +// +//----------------------------------------------------------------------------- +bool IntersectInfiniteRayWithSphere( const Vector &vecRayOrigin, const Vector &vecRayDelta, + const Vector &vecSphereCenter, float flRadius, float *pT1, float *pT2 ) +{ + // Solve using the ray equation + the sphere equation + // P = o + dt + // (x - xc)^2 + (y - yc)^2 + (z - zc)^2 = r^2 + // (ox + dx * t - xc)^2 + (oy + dy * t - yc)^2 + (oz + dz * t - zc)^2 = r^2 + // (ox - xc)^2 + 2 * (ox-xc) * dx * t + dx^2 * t^2 + + // (oy - yc)^2 + 2 * (oy-yc) * dy * t + dy^2 * t^2 + + // (oz - zc)^2 + 2 * (oz-zc) * dz * t + dz^2 * t^2 = r^2 + // (dx^2 + dy^2 + dz^2) * t^2 + 2 * ((ox-xc)dx + (oy-yc)dy + (oz-zc)dz) t + + // (ox-xc)^2 + (oy-yc)^2 + (oz-zc)^2 - r^2 = 0 + // or, t = (-b +/- sqrt( b^2 - 4ac)) / 2a + // a = DotProduct( vecRayDelta, vecRayDelta ); + // b = 2 * DotProduct( vecRayOrigin - vecCenter, vecRayDelta ) + // c = DotProduct(vecRayOrigin - vecCenter, vecRayOrigin - vecCenter) - flRadius * flRadius; + + Vector vecSphereToRay; + VectorSubtract( vecRayOrigin, vecSphereCenter, vecSphereToRay ); + + float a = DotProduct( vecRayDelta, vecRayDelta ); + + // This would occur in the case of a zero-length ray + if ( a == 0.0f ) + { + *pT1 = *pT2 = 0.0f; + return vecSphereToRay.LengthSqr() <= flRadius * flRadius; + } + + float b = 2 * DotProduct( vecSphereToRay, vecRayDelta ); + float c = DotProduct( vecSphereToRay, vecSphereToRay ) - flRadius * flRadius; + float flDiscrim = b * b - 4 * a * c; + if ( flDiscrim < 0.0f ) + return false; + + flDiscrim = sqrt( flDiscrim ); + float oo2a = 0.5f / a; + *pT1 = ( - b - flDiscrim ) * oo2a; + *pT2 = ( - b + flDiscrim ) * oo2a; + return true; +} + + + +//----------------------------------------------------------------------------- +// +// IntersectRayWithSphere +// +// Returns whether or not there was an intersection. +// Returns the two intersection points, clamped to (0,1) +// +//----------------------------------------------------------------------------- +bool IntersectRayWithSphere( const Vector &vecRayOrigin, const Vector &vecRayDelta, + const Vector &vecSphereCenter, float flRadius, float *pT1, float *pT2 ) +{ + if ( !IntersectInfiniteRayWithSphere( vecRayOrigin, vecRayDelta, vecSphereCenter, flRadius, pT1, pT2 ) ) + return false; + + if (( *pT1 > 1.0f ) || ( *pT2 < 0.0f )) + return false; + + // Clamp it! + if ( *pT1 < 0.0f ) + *pT1 = 0.0f; + if ( *pT2 > 1.0f ) + *pT2 = 1.0f; + + return true; +} + + +// returns true if the sphere and cone intersect +// NOTE: cone sine/cosine are the half angle of the cone +bool IsSphereIntersectingCone( const Vector &sphereCenter, float sphereRadius, const Vector &coneOrigin, const Vector &coneNormal, float coneSine, float coneCosine ) +{ + Vector backCenter = coneOrigin - (sphereRadius / coneSine) * coneNormal; + Vector delta = sphereCenter - backCenter; + float deltaLen = delta.Length(); + if ( DotProduct(coneNormal, delta) >= deltaLen*coneCosine ) + { + delta = sphereCenter - coneOrigin; + deltaLen = delta.Length(); + if ( -DotProduct(coneNormal, delta) >= deltaLen * coneSine ) + { + return ( deltaLen <= sphereRadius ) ? true : false; + } + return true; + } + return false; +} + + + +//----------------------------------------------------------------------------- +// returns true if the point is in the box +//----------------------------------------------------------------------------- +bool IsPointInBox( const Vector& pt, const Vector& boxMin, const Vector& boxMax ) +{ + Assert( boxMin[0] <= boxMax[0] ); + Assert( boxMin[1] <= boxMax[1] ); + Assert( boxMin[2] <= boxMax[2] ); + + // on x360, force use of SIMD version. + if (IsX360()) + { + return IsPointInBox( LoadUnaligned3SIMD(pt.Base()), LoadUnaligned3SIMD(boxMin.Base()), LoadUnaligned3SIMD(boxMax.Base()) ) ; + } + + if ( (pt[0] > boxMax[0]) || (pt[0] < boxMin[0]) ) + return false; + if ( (pt[1] > boxMax[1]) || (pt[1] < boxMin[1]) ) + return false; + if ( (pt[2] > boxMax[2]) || (pt[2] < boxMin[2]) ) + return false; + return true; +} + + +bool IsPointInCone( const Vector &pt, const Vector &origin, const Vector &axis, float cosAngle, float length ) +{ + Vector delta = pt - origin; + float dist = VectorNormalize( delta ); + float dot = DotProduct( delta, axis ); + if ( dot < cosAngle ) + return false; + if ( dist * dot > length ) + return false; + + return true; +} + + +//----------------------------------------------------------------------------- +// returns true if there's an intersection between two boxes +//----------------------------------------------------------------------------- +bool IsBoxIntersectingBox( const Vector& boxMin1, const Vector& boxMax1, + const Vector& boxMin2, const Vector& boxMax2 ) +{ + Assert( boxMin1[0] <= boxMax1[0] ); + Assert( boxMin1[1] <= boxMax1[1] ); + Assert( boxMin1[2] <= boxMax1[2] ); + Assert( boxMin2[0] <= boxMax2[0] ); + Assert( boxMin2[1] <= boxMax2[1] ); + Assert( boxMin2[2] <= boxMax2[2] ); + + if ( (boxMin1[0] > boxMax2[0]) || (boxMax1[0] < boxMin2[0]) ) + return false; + if ( (boxMin1[1] > boxMax2[1]) || (boxMax1[1] < boxMin2[1]) ) + return false; + if ( (boxMin1[2] > boxMax2[2]) || (boxMax1[2] < boxMin2[2]) ) + return false; + return true; +} + +bool IsBoxIntersectingBoxExtents( const Vector& boxCenter1, const Vector& boxHalfDiagonal1, + const Vector& boxCenter2, const Vector& boxHalfDiagonal2 ) +{ + Vector vecDelta, vecSize; + VectorSubtract( boxCenter1, boxCenter2, vecDelta ); + VectorAdd( boxHalfDiagonal1, boxHalfDiagonal2, vecSize ); + return ( FloatMakePositive( vecDelta.x ) <= vecSize.x ) && + ( FloatMakePositive( vecDelta.y ) <= vecSize.y ) && + ( FloatMakePositive( vecDelta.z ) <= vecSize.z ); +} + + +//----------------------------------------------------------------------------- +// +// IsOBBIntersectingOBB +// +// returns true if there's an intersection between two OBBs +// +//----------------------------------------------------------------------------- +bool IsOBBIntersectingOBB( const Vector &vecOrigin1, const QAngle &vecAngles1, const Vector& boxMin1, const Vector& boxMax1, + const Vector &vecOrigin2, const QAngle &vecAngles2, const Vector& boxMin2, const Vector& boxMax2, float flTolerance ) +{ + // FIXME: Simple case AABB check doesn't work because the min and max extents are not oriented based on the angle + // this fast check would only be good for cubes. + /*if ( vecAngles1 == vecAngles2 ) + { + const Vector &vecDelta = vecOrigin2 - vecOrigin1; + Vector vecOtherMins, vecOtherMaxs; + VectorAdd( boxMin2, vecDelta, vecOtherMins ); + VectorAdd( boxMax2, vecDelta, vecOtherMaxs ); + return IsBoxIntersectingBox( boxMin1, boxMax1, vecOtherMins, vecOtherMaxs ); + }*/ + + // OBB test... + cplane_t plane; + bool bFoundPlane = ComputeSeparatingPlane( vecOrigin1, vecAngles1, boxMin1, boxMax1, + vecOrigin2, vecAngles2, boxMin2, boxMax2, flTolerance, &plane ); + return (bFoundPlane == false); +} + +// NOTE: This is only very slightly faster on high end PCs and x360 +#define USE_SIMD_RAY_CHECKS 1 +//----------------------------------------------------------------------------- +// returns true if there's an intersection between box and ray +//----------------------------------------------------------------------------- +bool FASTCALL IsBoxIntersectingRay( const Vector& boxMin, const Vector& boxMax, + const Vector& origin, const Vector& vecDelta, float flTolerance ) +{ + +#if USE_SIMD_RAY_CHECKS + // Load the unaligned ray/box parameters into SIMD registers + fltx4 start = LoadUnaligned3SIMD(origin.Base()); + fltx4 delta = LoadUnaligned3SIMD(vecDelta.Base()); + fltx4 boxMins = LoadUnaligned3SIMD( boxMin.Base() ); + fltx4 boxMaxs = LoadUnaligned3SIMD( boxMax.Base() ); + fltx4 epsilon = ReplicateX4(flTolerance); + // compute the mins/maxs of the box expanded by the ray extents + // relocate the problem so that the ray start is at the origin. + fltx4 offsetMins = SubSIMD(boxMins, start); + fltx4 offsetMaxs = SubSIMD(boxMaxs, start); + fltx4 offsetMinsExpanded = SubSIMD(offsetMins, epsilon); + fltx4 offsetMaxsExpanded = AddSIMD(offsetMaxs, epsilon); + + // Check to see if both the origin (start point) and the end point (delta) are on the front side + // of any of the box sides - if so there can be no intersection + fltx4 startOutMins = CmpLtSIMD(Four_Zeros, offsetMinsExpanded); + fltx4 endOutMins = CmpLtSIMD(delta,offsetMinsExpanded); + fltx4 minsMask = AndSIMD( startOutMins, endOutMins ); + fltx4 startOutMaxs = CmpGtSIMD(Four_Zeros, offsetMaxsExpanded); + fltx4 endOutMaxs = CmpGtSIMD(delta,offsetMaxsExpanded); + fltx4 maxsMask = AndSIMD( startOutMaxs, endOutMaxs ); + if ( IsAnyNegative(SetWToZeroSIMD(OrSIMD(minsMask,maxsMask)))) + return false; + + // now build the per-axis interval of t for intersections + fltx4 invDelta = ReciprocalSaturateSIMD(delta); + fltx4 tmins = MulSIMD( offsetMinsExpanded, invDelta ); + fltx4 tmaxs = MulSIMD( offsetMaxsExpanded, invDelta ); + fltx4 crossPlane = OrSIMD(XorSIMD(startOutMins,endOutMins), XorSIMD(startOutMaxs,endOutMaxs)); + + // only consider axes where we crossed a plane + tmins = MaskedAssign( crossPlane, tmins, Four_Negative_FLT_MAX ); + tmaxs = MaskedAssign( crossPlane, tmaxs, Four_FLT_MAX ); + + // now sort the interval per axis + fltx4 mint = MinSIMD( tmins, tmaxs ); + fltx4 maxt = MaxSIMD( tmins, tmaxs ); + + // now find the intersection of the intervals on all axes + fltx4 firstOut = FindLowestSIMD3(maxt); + fltx4 lastIn = FindHighestSIMD3(mint); + // NOTE: This is really a scalar quantity now [t0,t1] == [lastIn,firstOut] + firstOut = MinSIMD(firstOut, Four_Ones); + lastIn = MaxSIMD(lastIn, Four_Zeros); + + // If the final interval is valid lastIn boxMax[i] + flTolerance) ) + return false; + + continue; + } + + // non-parallel case + // Find the t's corresponding to the entry and exit of + // the ray along x, y, and z. The find the furthest entry + // point, and the closest exit point. Once that is done, + // we know we don't collide if the closest exit point + // is behind the starting location. We also don't collide if + // the closest exit point is in front of the furthest entry point + + float invDelta = 1.0f / vecDelta[i]; + float t1 = (boxMin[i] - flTolerance - origin[i]) * invDelta; + float t2 = (boxMax[i] + flTolerance - origin[i]) * invDelta; + if (t1 > t2) + { + float temp = t1; + t1 = t2; + t2 = temp; + } + if (t1 > tmin) + tmin = t1; + if (t2 < tmax) + tmax = t2; + if (tmin > tmax) + return false; + if (tmax < 0) + return false; + if (tmin > 1) + return false; + } + + return true; +#endif +} + +//----------------------------------------------------------------------------- +// returns true if there's an intersection between box and ray +//----------------------------------------------------------------------------- +bool FASTCALL IsBoxIntersectingRay( const Vector& boxMin, const Vector& boxMax, + const Vector& origin, const Vector& vecDelta, + const Vector& vecInvDelta, float flTolerance ) +{ +#if USE_SIMD_RAY_CHECKS + // Load the unaligned ray/box parameters into SIMD registers + fltx4 start = LoadUnaligned3SIMD(origin.Base()); + fltx4 delta = LoadUnaligned3SIMD(vecDelta.Base()); + fltx4 boxMins = LoadUnaligned3SIMD( boxMin.Base() ); + fltx4 boxMaxs = LoadUnaligned3SIMD( boxMax.Base() ); + // compute the mins/maxs of the box expanded by the ray extents + // relocate the problem so that the ray start is at the origin. + boxMins = SubSIMD(boxMins, start); + boxMaxs = SubSIMD(boxMaxs, start); + + // Check to see if both the origin (start point) and the end point (delta) are on the front side + // of any of the box sides - if so there can be no intersection + fltx4 startOutMins = CmpLtSIMD(Four_Zeros, boxMins); + fltx4 endOutMins = CmpLtSIMD(delta,boxMins); + fltx4 minsMask = AndSIMD( startOutMins, endOutMins ); + fltx4 startOutMaxs = CmpGtSIMD(Four_Zeros, boxMaxs); + fltx4 endOutMaxs = CmpGtSIMD(delta,boxMaxs); + fltx4 maxsMask = AndSIMD( startOutMaxs, endOutMaxs ); + if ( IsAnyNegative(SetWToZeroSIMD(OrSIMD(minsMask,maxsMask)))) + return false; + + // now build the per-axis interval of t for intersections + fltx4 epsilon = ReplicateX4(flTolerance); + fltx4 invDelta = LoadUnaligned3SIMD(vecInvDelta.Base()); + boxMins = SubSIMD(boxMins, epsilon); + boxMaxs = AddSIMD(boxMaxs, epsilon); + + boxMins = MulSIMD( boxMins, invDelta ); + boxMaxs = MulSIMD( boxMaxs, invDelta ); + + fltx4 crossPlane = OrSIMD(XorSIMD(startOutMins,endOutMins), XorSIMD(startOutMaxs,endOutMaxs)); + // only consider axes where we crossed a plane + boxMins = MaskedAssign( crossPlane, boxMins, Four_Negative_FLT_MAX ); + boxMaxs = MaskedAssign( crossPlane, boxMaxs, Four_FLT_MAX ); + + // now sort the interval per axis + fltx4 mint = MinSIMD( boxMins, boxMaxs ); + fltx4 maxt = MaxSIMD( boxMins, boxMaxs ); + + // now find the intersection of the intervals on all axes + fltx4 firstOut = FindLowestSIMD3(maxt); + fltx4 lastIn = FindHighestSIMD3(mint); + // NOTE: This is really a scalar quantity now [t0,t1] == [lastIn,firstOut] + firstOut = MinSIMD(firstOut, Four_Ones); + lastIn = MaxSIMD(lastIn, Four_Zeros); + + // If the final interval is valid lastIn boxMax[i] + flTolerance ) ) + return false; + + continue; + } + + // Non-parallel case + // Find the t's corresponding to the entry and exit of + // the ray along x, y, and z. The find the furthest entry + // point, and the closest exit point. Once that is done, + // we know we don't collide if the closest exit point + // is behind the starting location. We also don't collide if + // the closest exit point is in front of the furthest entry point + float t1 = ( boxMin[i] - flTolerance - origin[i] ) * vecInvDelta[i]; + float t2 = ( boxMax[i] + flTolerance - origin[i] ) * vecInvDelta[i]; + if ( t1 > t2 ) + { + float temp = t1; + t1 = t2; + t2 = temp; + } + + if (t1 > tmin) + tmin = t1; + + if (t2 < tmax) + tmax = t2; + + if (tmin > tmax) + return false; + + if (tmax < 0) + return false; + + if (tmin > 1) + return false; + } + + return true; +#endif +} + +//----------------------------------------------------------------------------- +// Intersects a ray with a aabb, return true if they intersect +//----------------------------------------------------------------------------- +bool FASTCALL IsBoxIntersectingRay( const Vector& vecBoxMin, const Vector& vecBoxMax, const Ray_t& ray, float flTolerance ) +{ + // On the x360, we force use of the SIMD functions. +#if defined(_X360) + if (IsX360()) + { + return IsBoxIntersectingRay( + LoadUnaligned3SIMD(vecBoxMin.Base()), LoadUnaligned3SIMD(vecBoxMax.Base()), + ray, flTolerance); + } +#endif + + if ( !ray.m_IsSwept ) + { + Vector rayMins, rayMaxs; + VectorSubtract( ray.m_Start, ray.m_Extents, rayMins ); + VectorAdd( ray.m_Start, ray.m_Extents, rayMaxs ); + if ( flTolerance != 0.0f ) + { + rayMins.x -= flTolerance; rayMins.y -= flTolerance; rayMins.z -= flTolerance; + rayMaxs.x += flTolerance; rayMaxs.y += flTolerance; rayMaxs.z += flTolerance; + } + return IsBoxIntersectingBox( vecBoxMin, vecBoxMax, rayMins, rayMaxs ); + } + + Vector vecExpandedBoxMin, vecExpandedBoxMax; + VectorSubtract( vecBoxMin, ray.m_Extents, vecExpandedBoxMin ); + VectorAdd( vecBoxMax, ray.m_Extents, vecExpandedBoxMax ); + return IsBoxIntersectingRay( vecExpandedBoxMin, vecExpandedBoxMax, ray.m_Start, ray.m_Delta, flTolerance ); +} + + +//----------------------------------------------------------------------------- +// returns true if there's an intersection between box and ray (SIMD version) +//----------------------------------------------------------------------------- + + +#ifdef _X360 +bool FASTCALL IsBoxIntersectingRay( fltx4 boxMin, fltx4 boxMax, + fltx4 origin, fltx4 delta, fltx4 invDelta, // ray parameters + fltx4 vTolerance ///< eg from ReplicateX4(flTolerance) + ) +#else +bool FASTCALL IsBoxIntersectingRay( const fltx4 &inBoxMin, const fltx4 & inBoxMax, + const fltx4 & origin, const fltx4 & delta, const fltx4 & invDelta, // ray parameters + const fltx4 & vTolerance ///< eg from ReplicateX4(flTolerance) + ) +#endif +{ + // Load the unaligned ray/box parameters into SIMD registers + // compute the mins/maxs of the box expanded by the ray extents + // relocate the problem so that the ray start is at the origin. + +#ifdef _X360 + boxMin = SubSIMD(boxMin, origin); + boxMax = SubSIMD(boxMax, origin); +#else + fltx4 boxMin = SubSIMD(inBoxMin, origin); + fltx4 boxMax = SubSIMD(inBoxMax, origin); +#endif + + // Check to see if the origin (start point) and the end point (delta) are on the same side + // of any of the box sides - if so there can be no intersection + fltx4 startOutMins = AndSIMD( CmpLtSIMD(Four_Zeros, boxMin), CmpLtSIMD(delta,boxMin) ); + fltx4 startOutMaxs = AndSIMD( CmpGtSIMD(Four_Zeros, boxMax), CmpGtSIMD(delta,boxMax) ); + if ( IsAnyNegative(SetWToZeroSIMD(OrSIMD(startOutMaxs,startOutMins)))) + return false; + + // now build the per-axis interval of t for intersections + boxMin = SubSIMD(boxMin, vTolerance); + boxMax = AddSIMD(boxMax, vTolerance); + + boxMin = MulSIMD( boxMin, invDelta ); + boxMax = MulSIMD( boxMax, invDelta ); + + // now sort the interval per axis + fltx4 mint = MinSIMD( boxMin, boxMax ); + fltx4 maxt = MaxSIMD( boxMin, boxMax ); + + // now find the intersection of the intervals on all axes + fltx4 firstOut = FindLowestSIMD3(maxt); + fltx4 lastIn = FindHighestSIMD3(mint); + // NOTE: This is really a scalar quantity now [t0,t1] == [lastIn,firstOut] + firstOut = MinSIMD(firstOut, Four_Ones); + lastIn = MaxSIMD(lastIn, Four_Zeros); + + // If the final interval is valid lastInt1 = -1.0f; + pTrace->t2 = 1.0f; + pTrace->hitside = -1; + + // UNDONE: This makes this code a little messy + pTrace->startsolid = true; + + for ( i = 0; i < 6; ++i ) + { + if ( i >= 3 ) + { + d1 = vecRayStart[i-3] - boxMaxs[i-3]; + d2 = d1 + vecRayDelta[i-3]; + } + else + { + d1 = -vecRayStart[i] + boxMins[i]; + d2 = d1 - vecRayDelta[i]; + } + + // if completely in front of face, no intersection + if (d1 > 0 && d2 > 0) + { + // UNDONE: Have to revert this in case it's still set + // UNDONE: Refactor to have only 2 return points (true/false) from this function + pTrace->startsolid = false; + return false; + } + + // completely inside, check next face + if (d1 <= 0 && d2 <= 0) + continue; + + if (d1 > 0) + { + pTrace->startsolid = false; + } + + // crosses face + if (d1 > d2) + { + f = d1 - flTolerance; + if ( f < 0 ) + { + f = 0; + } + f = f / (d1-d2); + if (f > pTrace->t1) + { + pTrace->t1 = f; + pTrace->hitside = i; + } + } + else + { + // leave + f = (d1 + flTolerance) / (d1-d2); + if (f < pTrace->t2) + { + pTrace->t2 = f; + } + } + } + + return pTrace->startsolid || (pTrace->t1 < pTrace->t2 && pTrace->t1 >= 0.0f); +} + + +//----------------------------------------------------------------------------- +// Intersects a ray against a box +//----------------------------------------------------------------------------- +bool IntersectRayWithBox( const Vector &vecRayStart, const Vector &vecRayDelta, + const Vector &boxMins, const Vector &boxMaxs, float flTolerance, CBaseTrace *pTrace, float *pFractionLeftSolid ) +{ + Collision_ClearTrace( vecRayStart, vecRayDelta, pTrace ); + + BoxTraceInfo_t trace; + + if ( IntersectRayWithBox( vecRayStart, vecRayDelta, boxMins, boxMaxs, flTolerance, &trace ) ) + { + pTrace->startsolid = trace.startsolid; + if (trace.t1 < trace.t2 && trace.t1 >= 0.0f) + { + pTrace->fraction = trace.t1; + VectorMA( pTrace->startpos, trace.t1, vecRayDelta, pTrace->endpos ); + pTrace->contents = CONTENTS_SOLID; + pTrace->plane.normal = vec3_origin; + if ( trace.hitside >= 3 ) + { + trace.hitside -= 3; + pTrace->plane.dist = boxMaxs[trace.hitside]; + pTrace->plane.normal[trace.hitside] = 1.0f; + pTrace->plane.type = trace.hitside; + } + else + { + pTrace->plane.dist = -boxMins[trace.hitside]; + pTrace->plane.normal[trace.hitside] = -1.0f; + pTrace->plane.type = trace.hitside; + } + return true; + } + + if ( pTrace->startsolid ) + { + pTrace->allsolid = (trace.t2 <= 0.0f) || (trace.t2 >= 1.0f); + pTrace->fraction = 0; + if ( pFractionLeftSolid ) + { + *pFractionLeftSolid = trace.t2; + } + pTrace->endpos = pTrace->startpos; + pTrace->contents = CONTENTS_SOLID; + pTrace->plane.dist = pTrace->startpos[0]; + pTrace->plane.normal.Init( 1.0f, 0.0f, 0.0f ); + pTrace->plane.type = 0; + pTrace->startpos = vecRayStart + (trace.t2 * vecRayDelta); + return true; + } + } + + return false; +} + + +//----------------------------------------------------------------------------- +// Intersects a ray against a box +//----------------------------------------------------------------------------- +bool IntersectRayWithBox( const Ray_t &ray, const Vector &boxMins, const Vector &boxMaxs, + float flTolerance, CBaseTrace *pTrace, float *pFractionLeftSolid ) +{ + if ( !ray.m_IsRay ) + { + Vector vecExpandedMins = boxMins - ray.m_Extents; + Vector vecExpandedMaxs = boxMaxs + ray.m_Extents; + bool bIntersects = IntersectRayWithBox( ray.m_Start, ray.m_Delta, vecExpandedMins, vecExpandedMaxs, flTolerance, pTrace, pFractionLeftSolid ); + pTrace->startpos += ray.m_StartOffset; + pTrace->endpos += ray.m_StartOffset; + return bIntersects; + } + return IntersectRayWithBox( ray.m_Start, ray.m_Delta, boxMins, boxMaxs, flTolerance, pTrace, pFractionLeftSolid ); +} + + +//----------------------------------------------------------------------------- +// Intersects a ray against an OBB, returns t1 and t2 +//----------------------------------------------------------------------------- +bool IntersectRayWithOBB( const Vector &vecRayStart, const Vector &vecRayDelta, + const matrix3x4_t &matOBBToWorld, const Vector &vecOBBMins, const Vector &vecOBBMaxs, + float flTolerance, BoxTraceInfo_t *pTrace ) +{ + // FIXME: Two transforms is pretty expensive. Should we optimize this? + Vector start, delta; + VectorITransform( vecRayStart, matOBBToWorld, start ); + VectorIRotate( vecRayDelta, matOBBToWorld, delta ); + + return IntersectRayWithBox( start, delta, vecOBBMins, vecOBBMaxs, flTolerance, pTrace ); +} + + + +//----------------------------------------------------------------------------- +// Intersects a ray against an OBB +//----------------------------------------------------------------------------- +bool IntersectRayWithOBB( const Vector &vecRayStart, const Vector &vecRayDelta, + const matrix3x4_t &matOBBToWorld, const Vector &vecOBBMins, const Vector &vecOBBMaxs, + float flTolerance, CBaseTrace *pTrace ) +{ + Collision_ClearTrace( vecRayStart, vecRayDelta, pTrace ); + + // FIXME: Make it work with tolerance + Assert( flTolerance == 0.0f ); + + // OPTIMIZE: Store this in the box instead of computing it here + // compute center in local space + Vector vecBoxExtents = (vecOBBMins + vecOBBMaxs) * 0.5; + Vector vecBoxCenter; + + // transform to world space + VectorTransform( vecBoxExtents, matOBBToWorld, vecBoxCenter ); + + // calc extents from local center + vecBoxExtents = vecOBBMaxs - vecBoxExtents; + + // OPTIMIZE: This is optimized for world space. If the transform is fast enough, it may make more + // sense to just xform and call UTIL_ClipToBox() instead. MEASURE THIS. + + // save the extents of the ray along + Vector extent, uextent; + Vector segmentCenter = vecRayStart + vecRayDelta - vecBoxCenter; + + extent.Init(); + + // check box axes for separation + for ( int j = 0; j < 3; j++ ) + { + extent[j] = vecRayDelta.x * matOBBToWorld[0][j] + vecRayDelta.y * matOBBToWorld[1][j] + vecRayDelta.z * matOBBToWorld[2][j]; + uextent[j] = fabsf(extent[j]); + float coord = segmentCenter.x * matOBBToWorld[0][j] + segmentCenter.y * matOBBToWorld[1][j] + segmentCenter.z * matOBBToWorld[2][j]; + coord = fabsf(coord); + + if ( coord > (vecBoxExtents[j] + uextent[j]) ) + return false; + } + + // now check cross axes for separation + float tmp, cextent; + Vector cross = vecRayDelta.Cross( segmentCenter ); + cextent = cross.x * matOBBToWorld[0][0] + cross.y * matOBBToWorld[1][0] + cross.z * matOBBToWorld[2][0]; + cextent = fabsf(cextent); + tmp = vecBoxExtents[1]*uextent[2] + vecBoxExtents[2]*uextent[1]; + if ( cextent > tmp ) + return false; + + cextent = cross.x * matOBBToWorld[0][1] + cross.y * matOBBToWorld[1][1] + cross.z * matOBBToWorld[2][1]; + cextent = fabsf(cextent); + tmp = vecBoxExtents[0]*uextent[2] + vecBoxExtents[2]*uextent[0]; + if ( cextent > tmp ) + return false; + + cextent = cross.x * matOBBToWorld[0][2] + cross.y * matOBBToWorld[1][2] + cross.z * matOBBToWorld[2][2]; + cextent = fabsf(cextent); + tmp = vecBoxExtents[0]*uextent[1] + vecBoxExtents[1]*uextent[0]; + if ( cextent > tmp ) + return false; + + // !!! We hit this box !!! compute intersection point and return + // Compute ray start in bone space + Vector start; + VectorITransform( vecRayStart, matOBBToWorld, start ); + + // extent is ray.m_Delta in bone space, recompute delta in bone space + extent *= 2.0f; + + // delta was prescaled by the current t, so no need to see if this intersection + // is closer + trace_t boxTrace; + if ( !IntersectRayWithBox( start, extent, vecOBBMins, vecOBBMaxs, flTolerance, pTrace ) ) + return false; + + // Fix up the start/end pos and fraction + Vector vecTemp; + VectorTransform( pTrace->endpos, matOBBToWorld, vecTemp ); + pTrace->endpos = vecTemp; + + pTrace->startpos = vecRayStart; + pTrace->fraction *= 2.0f; + + // Fix up the plane information + float flSign = pTrace->plane.normal[ pTrace->plane.type ]; + pTrace->plane.normal[0] = flSign * matOBBToWorld[0][pTrace->plane.type]; + pTrace->plane.normal[1] = flSign * matOBBToWorld[1][pTrace->plane.type]; + pTrace->plane.normal[2] = flSign * matOBBToWorld[2][pTrace->plane.type]; + pTrace->plane.dist = DotProduct( pTrace->endpos, pTrace->plane.normal ); + pTrace->plane.type = 3; + + return true; +} + + +//----------------------------------------------------------------------------- +// Intersects a ray against an OBB +//----------------------------------------------------------------------------- +bool IntersectRayWithOBB( const Vector &vecRayOrigin, const Vector &vecRayDelta, + const Vector &vecBoxOrigin, const QAngle &angBoxRotation, + const Vector &vecOBBMins, const Vector &vecOBBMaxs, float flTolerance, CBaseTrace *pTrace ) +{ + if (angBoxRotation == vec3_angle) + { + Vector vecAbsMins, vecAbsMaxs; + VectorAdd( vecBoxOrigin, vecOBBMins, vecAbsMins ); + VectorAdd( vecBoxOrigin, vecOBBMaxs, vecAbsMaxs ); + return IntersectRayWithBox( vecRayOrigin, vecRayDelta, vecAbsMins, vecAbsMaxs, flTolerance, pTrace ); + } + + matrix3x4_t obbToWorld; + AngleMatrix( angBoxRotation, vecBoxOrigin, obbToWorld ); + return IntersectRayWithOBB( vecRayOrigin, vecRayDelta, obbToWorld, vecOBBMins, vecOBBMaxs, flTolerance, pTrace ); +} + + +//----------------------------------------------------------------------------- +// Box support map +//----------------------------------------------------------------------------- +inline void ComputeSupportMap( const Vector &vecDirection, const Vector &vecBoxMins, + const Vector &vecBoxMaxs, float pDist[2] ) +{ + int nIndex = (vecDirection.x > 0.0f); + pDist[nIndex] = vecBoxMaxs.x * vecDirection.x; + pDist[1 - nIndex] = vecBoxMins.x * vecDirection.x; + + nIndex = (vecDirection.y > 0.0f); + pDist[nIndex] += vecBoxMaxs.y * vecDirection.y; + pDist[1 - nIndex] += vecBoxMins.y * vecDirection.y; + + nIndex = (vecDirection.z > 0.0f); + pDist[nIndex] += vecBoxMaxs.z * vecDirection.z; + pDist[1 - nIndex] += vecBoxMins.z * vecDirection.z; +} + +inline void ComputeSupportMap( const Vector &vecDirection, int i1, int i2, + const Vector &vecBoxMins, const Vector &vecBoxMaxs, float pDist[2] ) +{ + int nIndex = (vecDirection[i1] > 0.0f); + pDist[nIndex] = vecBoxMaxs[i1] * vecDirection[i1]; + pDist[1 - nIndex] = vecBoxMins[i1] * vecDirection[i1]; + + nIndex = (vecDirection[i2] > 0.0f); + pDist[nIndex] += vecBoxMaxs[i2] * vecDirection[i2]; + pDist[1 - nIndex] += vecBoxMins[i2] * vecDirection[i2]; +} + +//----------------------------------------------------------------------------- +// Intersects a ray against an OBB +//----------------------------------------------------------------------------- +static int s_ExtIndices[3][2] = +{ + { 2, 1 }, + { 0, 2 }, + { 0, 1 }, +}; + +static int s_MatIndices[3][2] = +{ + { 1, 2 }, + { 2, 0 }, + { 1, 0 }, +}; + +bool IntersectRayWithOBB( const Ray_t &ray, const matrix3x4_t &matOBBToWorld, + const Vector &vecOBBMins, const Vector &vecOBBMaxs, float flTolerance, CBaseTrace *pTrace ) +{ + if ( ray.m_IsRay ) + { + return IntersectRayWithOBB( ray.m_Start, ray.m_Delta, matOBBToWorld, + vecOBBMins, vecOBBMaxs, flTolerance, pTrace ); + } + + Collision_ClearTrace( ray.m_Start + ray.m_StartOffset, ray.m_Delta, pTrace ); + + // Compute a bounding sphere around the bloated OBB + Vector vecOBBCenter; + VectorAdd( vecOBBMins, vecOBBMaxs, vecOBBCenter ); + vecOBBCenter *= 0.5f; + vecOBBCenter.x += matOBBToWorld[0][3]; + vecOBBCenter.y += matOBBToWorld[1][3]; + vecOBBCenter.z += matOBBToWorld[2][3]; + + Vector vecOBBHalfDiagonal; + VectorSubtract( vecOBBMaxs, vecOBBMins, vecOBBHalfDiagonal ); + vecOBBHalfDiagonal *= 0.5f; + + float flRadius = vecOBBHalfDiagonal.Length() + ray.m_Extents.Length(); + if ( !IsRayIntersectingSphere( ray.m_Start, ray.m_Delta, vecOBBCenter, flRadius, flTolerance ) ) + return false; + + // Ok, we passed the trivial reject, so lets do the dirty deed. + // Basically we're going to do the GJK thing explicitly. We'll shrink the ray down + // to a point, and bloat the OBB by the ray's extents. This will generate facet + // planes which are perpendicular to all of the separating axes typically seen in + // a standard seperating axis implementation. + + // We're going to create a number of planes through various vertices in the OBB + // which represent all of the separating planes. Then we're going to bloat the planes + // by the ray extents. + + // We're going to do all work in OBB-space because it's easier to do the + // support-map in this case + + // First, transform the ray into the space of the OBB + Vector vecLocalRayOrigin, vecLocalRayDirection; + VectorITransform( ray.m_Start, matOBBToWorld, vecLocalRayOrigin ); + VectorIRotate( ray.m_Delta, matOBBToWorld, vecLocalRayDirection ); + + // Next compute all separating planes + Vector pPlaneNormal[15]; + float ppPlaneDist[15][2]; + + int i; + for ( i = 0; i < 3; ++i ) + { + // Each plane needs to be bloated an amount = to the abs dot product of + // the ray extents with the plane normal + // For the OBB planes, do it in world space; + // and use the direction of the OBB (the ith column of matOBBToWorld) in world space vs extents + pPlaneNormal[i].Init( ); + pPlaneNormal[i][i] = 1.0f; + + float flExtentDotNormal = + FloatMakePositive( matOBBToWorld[0][i] * ray.m_Extents.x ) + + FloatMakePositive( matOBBToWorld[1][i] * ray.m_Extents.y ) + + FloatMakePositive( matOBBToWorld[2][i] * ray.m_Extents.z ); + + ppPlaneDist[i][0] = vecOBBMins[i] - flExtentDotNormal; + ppPlaneDist[i][1] = vecOBBMaxs[i] + flExtentDotNormal; + + // For the ray-extents planes, they are bloated by the extents + // Use the support map to determine which + VectorCopy( matOBBToWorld[i], pPlaneNormal[i+3].Base() ); + ComputeSupportMap( pPlaneNormal[i+3], vecOBBMins, vecOBBMaxs, ppPlaneDist[i+3] ); + ppPlaneDist[i+3][0] -= ray.m_Extents[i]; + ppPlaneDist[i+3][1] += ray.m_Extents[i]; + + // Now the edge cases... (take the cross product of x,y,z axis w/ ray extent axes + // given by the rows of the obb to world matrix. + // Compute the ray extent bloat in world space because it's easier... + + // These are necessary to compute the world-space versions of + // the edges so we can compute the extent dot products + float flRayExtent0 = ray.m_Extents[s_ExtIndices[i][0]]; + float flRayExtent1 = ray.m_Extents[s_ExtIndices[i][1]]; + const float *pMatRow0 = matOBBToWorld[s_MatIndices[i][0]]; + const float *pMatRow1 = matOBBToWorld[s_MatIndices[i][1]]; + + // x axis of the OBB + world ith axis + pPlaneNormal[i+6].Init( 0.0f, -matOBBToWorld[i][2], matOBBToWorld[i][1] ); + ComputeSupportMap( pPlaneNormal[i+6], 1, 2, vecOBBMins, vecOBBMaxs, ppPlaneDist[i+6] ); + flExtentDotNormal = + FloatMakePositive( pMatRow0[0] ) * flRayExtent0 + + FloatMakePositive( pMatRow1[0] ) * flRayExtent1; + ppPlaneDist[i+6][0] -= flExtentDotNormal; + ppPlaneDist[i+6][1] += flExtentDotNormal; + + // y axis of the OBB + world ith axis + pPlaneNormal[i+9].Init( matOBBToWorld[i][2], 0.0f, -matOBBToWorld[i][0] ); + ComputeSupportMap( pPlaneNormal[i+9], 0, 2, vecOBBMins, vecOBBMaxs, ppPlaneDist[i+9] ); + flExtentDotNormal = + FloatMakePositive( pMatRow0[1] ) * flRayExtent0 + + FloatMakePositive( pMatRow1[1] ) * flRayExtent1; + ppPlaneDist[i+9][0] -= flExtentDotNormal; + ppPlaneDist[i+9][1] += flExtentDotNormal; + + // z axis of the OBB + world ith axis + pPlaneNormal[i+12].Init( -matOBBToWorld[i][1], matOBBToWorld[i][0], 0.0f ); + ComputeSupportMap( pPlaneNormal[i+12], 0, 1, vecOBBMins, vecOBBMaxs, ppPlaneDist[i+12] ); + flExtentDotNormal = + FloatMakePositive( pMatRow0[2] ) * flRayExtent0 + + FloatMakePositive( pMatRow1[2] ) * flRayExtent1; + ppPlaneDist[i+12][0] -= flExtentDotNormal; + ppPlaneDist[i+12][1] += flExtentDotNormal; + } + + float enterfrac, leavefrac; + float d1[2], d2[2]; + float f; + + int hitplane = -1; + int hitside = -1; + enterfrac = -1.0f; + leavefrac = 1.0f; + + pTrace->startsolid = true; + + Vector vecLocalRayEnd; + VectorAdd( vecLocalRayOrigin, vecLocalRayDirection, vecLocalRayEnd ); + + for ( i = 0; i < 15; ++i ) + { + // FIXME: Not particularly optimal since there's a lot of 0's in the plane normals + float flStartDot = DotProduct( pPlaneNormal[i], vecLocalRayOrigin ); + float flEndDot = DotProduct( pPlaneNormal[i], vecLocalRayEnd ); + + // NOTE: Negative here is because the plane normal + dist + // are defined in negative terms for the far plane (plane dist index 0) + d1[0] = -(flStartDot - ppPlaneDist[i][0]); + d2[0] = -(flEndDot - ppPlaneDist[i][0]); + + d1[1] = flStartDot - ppPlaneDist[i][1]; + d2[1] = flEndDot - ppPlaneDist[i][1]; + + int j; + for ( j = 0; j < 2; ++j ) + { + // if completely in front near plane or behind far plane no intersection + if (d1[j] > 0 && d2[j] > 0) + return false; + + // completely inside, check next plane set + if (d1[j] <= 0 && d2[j] <= 0) + continue; + + if (d1[j] > 0) + { + pTrace->startsolid = false; + } + + // crosses face + float flDenom = 1.0f / (d1[j] - d2[j]); + if (d1[j] > d2[j]) + { + f = d1[j] - flTolerance; + if ( f < 0 ) + { + f = 0; + } + f *= flDenom; + if (f > enterfrac) + { + enterfrac = f; + hitplane = i; + hitside = j; + } + } + else + { + // leave + f = (d1[j] + flTolerance) * flDenom; + if (f < leavefrac) + { + leavefrac = f; + } + } + } + } + + if (enterfrac < leavefrac && enterfrac >= 0.0f) + { + pTrace->fraction = enterfrac; + VectorMA( pTrace->startpos, enterfrac, ray.m_Delta, pTrace->endpos ); + pTrace->contents = CONTENTS_SOLID; + + // Need to transform the plane into world space... + cplane_t temp; + temp.normal = pPlaneNormal[hitplane]; + temp.dist = ppPlaneDist[hitplane][hitside]; + if (hitside == 0) + { + temp.normal *= -1.0f; + temp.dist *= -1.0f; + } + temp.type = 3; + + MatrixITransformPlane( matOBBToWorld, temp, pTrace->plane ); + return true; + } + + if ( pTrace->startsolid ) + { + pTrace->allsolid = (leavefrac <= 0.0f) || (leavefrac >= 1.0f); + pTrace->fraction = 0; + pTrace->endpos = pTrace->startpos; + pTrace->contents = CONTENTS_SOLID; + pTrace->plane.dist = pTrace->startpos[0]; + pTrace->plane.normal.Init( 1.0f, 0.0f, 0.0f ); + pTrace->plane.type = 0; + return true; + } + + return false; +} + + +//----------------------------------------------------------------------------- +// Intersects a ray against an OBB +//----------------------------------------------------------------------------- +bool IntersectRayWithOBB( const Ray_t &ray, const Vector &vecBoxOrigin, const QAngle &angBoxRotation, + const Vector &vecOBBMins, const Vector &vecOBBMaxs, float flTolerance, CBaseTrace *pTrace ) +{ + if ( angBoxRotation == vec3_angle ) + { + Vector vecWorldMins, vecWorldMaxs; + VectorAdd( vecBoxOrigin, vecOBBMins, vecWorldMins ); + VectorAdd( vecBoxOrigin, vecOBBMaxs, vecWorldMaxs ); + return IntersectRayWithBox( ray, vecWorldMins, vecWorldMaxs, flTolerance, pTrace ); + } + + if ( ray.m_IsRay ) + { + return IntersectRayWithOBB( ray.m_Start, ray.m_Delta, vecBoxOrigin, angBoxRotation, vecOBBMins, vecOBBMaxs, flTolerance, pTrace ); + } + + matrix3x4_t matOBBToWorld; + AngleMatrix( angBoxRotation, vecBoxOrigin, matOBBToWorld ); + return IntersectRayWithOBB( ray, matOBBToWorld, vecOBBMins, vecOBBMaxs, flTolerance, pTrace ); +} + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +void GetNonMajorAxes( const Vector &vNormal, Vector2D &axes ) +{ + axes[0] = 0; + axes[1] = 1; + + if( FloatMakePositive( vNormal.x ) > FloatMakePositive( vNormal.y ) ) + { + if( FloatMakePositive( vNormal.x ) > FloatMakePositive( vNormal.z ) ) + { + axes[0] = 1; + axes[1] = 2; + } + } + else + { + if( FloatMakePositive( vNormal.y ) > FloatMakePositive( vNormal.z ) ) + { + axes[0] = 0; + axes[1] = 2; + } + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +QuadBarycentricRetval_t QuadWithParallelEdges( const Vector &vecOrigin, + const Vector &vecU, float lengthU, const Vector &vecV, float lengthV, + const Vector &pt, Vector2D &vecUV ) +{ + Ray_t rayAxis; + Ray_t rayPt; + + // + // handle the u axis + // + rayAxis.m_Start = vecOrigin; + rayAxis.m_Delta = vecU; + rayAxis.m_IsRay = true; + + rayPt.m_Start = pt; + rayPt.m_Delta = vecV * -( lengthV * 10.0f ); + rayPt.m_IsRay = true; + + float s, t; + IntersectRayWithRay( rayAxis, rayPt, t, s ); + vecUV[0] = t / lengthU; + + // + // handle the v axis + // + rayAxis.m_Delta = vecV; + + rayPt.m_Delta = vecU * -( lengthU * 10.0f ); + + IntersectRayWithRay( rayAxis, rayPt, t, s ); + vecUV[1] = t / lengthV; + + // inside of the quad?? + if( ( vecUV[0] < 0.0f ) || ( vecUV[0] > 1.0f ) || + ( vecUV[1] < 0.0f ) || ( vecUV[1] > 1.0f ) ) + return BARY_QUADRATIC_FALSE; + + return BARY_QUADRATIC_TRUE; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void ResolveQuadratic( double tPlus, double tMinus, + const Vector axisU0, const Vector axisU1, + const Vector axisV0, const Vector axisV1, + const Vector axisOrigin, const Vector pt, + int projU, double &s, double &t ) +{ + // calculate the sPlus, sMinus pair(s) + double sDenomPlus = ( axisU0[projU] * ( 1 - tPlus ) ) + ( axisU1[projU] * tPlus ); + double sDenomMinus = ( axisU0[projU] * ( 1 - tMinus ) ) + ( axisU1[projU] * tMinus ); + + double sPlus = UNINIT, sMinus = UNINIT; + if( FloatMakePositive( sDenomPlus ) >= 1e-5 ) + { + sPlus = ( pt[projU] - axisOrigin[projU] - ( axisV0[projU] * tPlus ) ) / sDenomPlus; + } + + if( FloatMakePositive( sDenomMinus ) >= 1e-5 ) + { + sMinus = ( pt[projU] - axisOrigin[projU] - ( axisV0[projU] * tMinus ) ) / sDenomMinus; + } + + if( ( tPlus >= 0.0 ) && ( tPlus <= 1.0 ) && ( sPlus >= 0.0 ) && ( sPlus <= 1.0 ) ) + { + s = sPlus; + t = tPlus; + return; + } + + if( ( tMinus >= 0.0 ) && ( tMinus <= 1.0 ) && ( sMinus >= 0.0 ) && ( sMinus <= 1.0 ) ) + { + s = sMinus; + t = tMinus; + return; + } + + double s0, t0, s1, t1; + + s0 = sPlus; + t0 = tPlus; + if( s0 >= 1.0 ) { s0 -= 1.0; } + if( t0 >= 1.0 ) { t0 -= 1.0; } + + s1 = sMinus; + t1 = tMinus; + if( s1 >= 1.0 ) { s1 -= 1.0; } + if( t1 >= 1.0 ) { t1 -= 1.0; } + + s0 = FloatMakePositive( s0 ); + t0 = FloatMakePositive( t0 ); + s1 = FloatMakePositive( s1 ); + t1 = FloatMakePositive( t1 ); + + double max0, max1; + max0 = s0; + if( t0 > max0 ) { max0 = t0; } + max1 = s1; + if( t1 > max1 ) { max1 = t1; } + + if( max0 > max1 ) + { + s = sMinus; + t = tMinus; + } + else + { + s = sPlus; + t = tPlus; + } +} + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +QuadBarycentricRetval_t PointInQuadToBarycentric( const Vector &v1, const Vector &v2, + const Vector &v3, const Vector &v4, const Vector &point, Vector2D &uv ) +{ +#define PIQ_TEXTURE_EPSILON 0.001 +#define PIQ_PLANE_EPSILON 0.1 +#define PIQ_DOT_EPSILON 0.99f + + // + // Think of a quad with points v1, v2, v3, v4 and u, v line segments + // u0 = v2 - v1 + // u1 = v3 - v4 + // v0 = v4 - v1 + // v1 = v3 - v2 + // + Vector axisU[2], axisV[2]; + Vector axisUNorm[2], axisVNorm[2]; + axisU[0] = axisUNorm[0] = v2 - v1; + axisU[1] = axisUNorm[1] = v3 - v4; + axisV[0] = axisVNorm[0] = v4 - v1; + axisV[1] = axisVNorm[1] = v3 - v2; + + float lengthU[2], lengthV[2]; + lengthU[0] = VectorNormalize( axisUNorm[0] ); + lengthU[1] = VectorNormalize( axisUNorm[1] ); + lengthV[0] = VectorNormalize( axisVNorm[0] ); + lengthV[1] = VectorNormalize( axisVNorm[1] ); + + // + // check for an early out - parallel opposite edges! + // NOTE: quad property if 1 set of opposite edges is parallel and equal + // in length, then the other set of edges is as well + // + if( axisUNorm[0].Dot( axisUNorm[1] ) > PIQ_DOT_EPSILON ) + { + if( FloatMakePositive( lengthU[0] - lengthU[1] ) < PIQ_PLANE_EPSILON ) + { + return QuadWithParallelEdges( v1, axisUNorm[0], lengthU[0], axisVNorm[0], lengthV[0], point, uv ); + } + } + + // + // since we are solving for s in our equations below we need to ensure that + // the v axes are non-parallel + // + bool bFlipped = false; + if( axisVNorm[0].Dot( axisVNorm[1] ) > PIQ_DOT_EPSILON ) + { + Vector tmp[2]; + tmp[0] = axisV[0]; + tmp[1] = axisV[1]; + axisV[0] = axisU[0]; + axisV[1] = axisU[1]; + axisU[0] = tmp[0]; + axisU[1] = tmp[1]; + bFlipped = true; + } + + // + // get the "projection" axes + // + Vector2D projAxes; + Vector vNormal = axisU[0].Cross( axisV[0] ); + GetNonMajorAxes( vNormal, projAxes ); + + // + // NOTE: axisU[0][projAxes[0]] < axisU[0][projAxes[1]], + // this is done to decrease error when dividing later + // + if( FloatMakePositive( axisU[0][projAxes[0]] ) < FloatMakePositive( axisU[0][projAxes[1]] ) ) + { + int tmp = projAxes[0]; + projAxes[0] = projAxes[1]; + projAxes[1] = tmp; + } + + // Here's how we got these equations: + // + // Given the points and u,v line segments above... + // + // Then: + // + // (1.0) PT = P0 + U0 * s + V * t + // + // where + // + // (1.1) V = V0 + s * (V1 - V0) + // (1.2) U = U0 + t * (U1 - U0) + // + // Therefore (from 1.1 + 1.0): + // PT - P0 = U0 * s + (V0 + s * (V1-V0)) * t + // Group s's: + // PT - P0 - t * V0 = s * (U0 + t * (V1-V0)) + // Two equations and two unknowns in x and y get you the following quadratic: + // + // solve the quadratic + // + double s = 0.0, t = 0.0; + double A, negB, C; + + A = ( axisU[0][projAxes[1]] * axisV[0][projAxes[0]] ) - + ( axisU[0][projAxes[0]] * axisV[0][projAxes[1]] ) - + ( axisU[1][projAxes[1]] * axisV[0][projAxes[0]] ) + + ( axisU[1][projAxes[0]] * axisV[0][projAxes[1]] ); + C = ( v1[projAxes[1]] * axisU[0][projAxes[0]] ) - + ( point[projAxes[1]] * axisU[0][projAxes[0]] ) - + ( v1[projAxes[0]] * axisU[0][projAxes[1]] ) + + ( point[projAxes[0]] * axisU[0][projAxes[1]] ); + negB = C - + ( v1[projAxes[1]] * axisU[1][projAxes[0]] ) + + ( point[projAxes[1]] * axisU[1][projAxes[0]] ) + + ( v1[projAxes[0]] * axisU[1][projAxes[1]] ) - + ( point[projAxes[0]] * axisU[1][projAxes[1]] ) + + ( axisU[0][projAxes[1]] * axisV[0][projAxes[0]] ) - + ( axisU[0][projAxes[0]] * axisV[0][projAxes[1]] ); + + if( ( A > -PIQ_PLANE_EPSILON ) && ( A < PIQ_PLANE_EPSILON ) ) + { + // shouldn't be here -- this should have been take care of in the "early out" +// Assert( 0 ); + + Vector vecUAvg, vecVAvg; + vecUAvg = ( axisUNorm[0] + axisUNorm[1] ) * 0.5f; + vecVAvg = ( axisVNorm[0] + axisVNorm[1] ) * 0.5f; + + float fLengthUAvg = ( lengthU[0] + lengthU[1] ) * 0.5f; + float fLengthVAvg = ( lengthV[0] + lengthV[1] ) * 0.5f; + + return QuadWithParallelEdges( v1, vecUAvg, fLengthUAvg, vecVAvg, fLengthVAvg, point, uv ); + +#if 0 + // legacy code -- kept here for completeness! + + // not a quadratic -- solve linearly + t = C / negB; + + // See (1.2) above + float ui = axisU[0][projAxes[0]] + t * ( axisU[1][projAxes[0]] - axisU[0][projAxes[0]] ); + if( FloatMakePositive( ui ) >= 1e-5 ) + { + // See (1.0) above + s = ( point[projAxes[0]] - v1[projAxes[0]] - axisV[0][projAxes[0]] * t ) / ui; + } +#endif + } + else + { + // (-b +/- sqrt( b^2 - 4ac )) / 2a + double discriminant = (negB*negB) - (4.0f * A * C); + if( discriminant < 0.0f ) + { + uv[0] = -99999.0f; + uv[1] = -99999.0f; + return BARY_QUADRATIC_NEGATIVE_DISCRIMINANT; + } + + double quad = sqrt( discriminant ); + double QPlus = ( negB + quad ) / ( 2.0f * A ); + double QMinus = ( negB - quad ) / ( 2.0f * A ); + + ResolveQuadratic( QPlus, QMinus, axisU[0], axisU[1], axisV[0], axisV[1], v1, point, projAxes[0], s, t ); + } + + if( !bFlipped ) + { + uv[0] = ( float )s; + uv[1] = ( float )t; + } + else + { + uv[0] = ( float )t; + uv[1] = ( float )s; + } + + // inside of the quad?? + if( ( uv[0] < 0.0f ) || ( uv[0] > 1.0f ) || ( uv[1] < 0.0f ) || ( uv[1] > 1.0f ) ) + return BARY_QUADRATIC_FALSE; + + return BARY_QUADRATIC_TRUE; + +#undef PIQ_TEXTURE_EPSILON +#undef PIQ_PLANE_EPSILON +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void PointInQuadFromBarycentric( const Vector &v1, const Vector &v2, const Vector &v3, const Vector &v4, + const Vector2D &uv, Vector &point ) +{ + // + // Think of a quad with points v1, v2, v3, v4 and u, v line segments + // find the ray from v0 edge to v1 edge at v + // + Vector vPts[2]; + VectorLerp( v1, v4, uv[1], vPts[0] ); + VectorLerp( v2, v3, uv[1], vPts[1] ); + VectorLerp( vPts[0], vPts[1], uv[0], point ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void TexCoordInQuadFromBarycentric( const Vector2D &v1, const Vector2D &v2, const Vector2D &v3, const Vector2D &v4, + const Vector2D &uv, Vector2D &texCoord ) +{ + // + // Think of a quad with points v1, v2, v3, v4 and u, v line segments + // find the ray from v0 edge to v1 edge at v + // + Vector2D vCoords[2]; + Vector2DLerp( v1, v4, uv[1], vCoords[0] ); + Vector2DLerp( v2, v3, uv[1], vCoords[1] ); + Vector2DLerp( vCoords[0], vCoords[1], uv[0], texCoord ); +} + + +//----------------------------------------------------------------------------- +// Compute point from barycentric specification +// Edge u goes from v0 to v1, edge v goes from v0 to v2 +//----------------------------------------------------------------------------- +void ComputePointFromBarycentric( const Vector& v0, const Vector& v1, const Vector& v2, + float u, float v, Vector& pt ) +{ + Vector edgeU, edgeV; + VectorSubtract( v1, v0, edgeU ); + VectorSubtract( v2, v0, edgeV ); + VectorMA( v0, u, edgeU, pt ); + VectorMA( pt, v, edgeV, pt ); +} + +void ComputePointFromBarycentric( const Vector2D& v0, const Vector2D& v1, const Vector2D& v2, + float u, float v, Vector2D& pt ) +{ + Vector2D edgeU, edgeV; + Vector2DSubtract( v1, v0, edgeU ); + Vector2DSubtract( v2, v0, edgeV ); + Vector2DMA( v0, u, edgeU, pt ); + Vector2DMA( pt, v, edgeV, pt ); +} + + +//----------------------------------------------------------------------------- +// Compute a matrix that has the correct orientation but which has an origin at +// the center of the bounds +//----------------------------------------------------------------------------- +static void ComputeCenterMatrix( const Vector& origin, const QAngle& angles, + const Vector& mins, const Vector& maxs, matrix3x4_t& matrix ) +{ + Vector centroid; + VectorAdd( mins, maxs, centroid ); + centroid *= 0.5f; + AngleMatrix( angles, matrix ); + + Vector worldCentroid; + VectorRotate( centroid, matrix, worldCentroid ); + worldCentroid += origin; + MatrixSetColumn( worldCentroid, 3, matrix ); +} + +static void ComputeCenterIMatrix( const Vector& origin, const QAngle& angles, + const Vector& mins, const Vector& maxs, matrix3x4_t& matrix ) +{ + Vector centroid; + VectorAdd( mins, maxs, centroid ); + centroid *= -0.5f; + AngleIMatrix( angles, matrix ); + + // For the translational component here, note that the origin in world space + // is T = R * C + O, (R = rotation matrix, C = centroid in local space, O = origin in world space) + // The IMatrix translation = - transpose(R) * T = -C - transpose(R) * 0 + Vector localOrigin; + VectorRotate( origin, matrix, localOrigin ); + centroid -= localOrigin; + MatrixSetColumn( centroid, 3, matrix ); +} + + +//----------------------------------------------------------------------------- +// Compute a matrix which is the absolute value of another +//----------------------------------------------------------------------------- +static inline void ComputeAbsMatrix( const matrix3x4_t& in, matrix3x4_t& out ) +{ + FloatBits(out[0][0]) = FloatAbsBits(in[0][0]); + FloatBits(out[0][1]) = FloatAbsBits(in[0][1]); + FloatBits(out[0][2]) = FloatAbsBits(in[0][2]); + FloatBits(out[1][0]) = FloatAbsBits(in[1][0]); + FloatBits(out[1][1]) = FloatAbsBits(in[1][1]); + FloatBits(out[1][2]) = FloatAbsBits(in[1][2]); + FloatBits(out[2][0]) = FloatAbsBits(in[2][0]); + FloatBits(out[2][1]) = FloatAbsBits(in[2][1]); + FloatBits(out[2][2]) = FloatAbsBits(in[2][2]); +} + + +//----------------------------------------------------------------------------- +// Compute a separating plane between two boxes (expensive!) +// Returns false if no separating plane exists +//----------------------------------------------------------------------------- +static bool ComputeSeparatingPlane( const matrix3x4_t &worldToBox1, const matrix3x4_t &box2ToWorld, + const Vector& box1Size, const Vector& box2Size, float tolerance, cplane_t* pPlane ) +{ + // The various separating planes can be either + // 1) A plane parallel to one of the box face planes + // 2) A plane parallel to the cross-product of an edge from each box + + // First, compute the basis of second box in the space of the first box + // NOTE: These basis place the origin at the centroid of each box! + matrix3x4_t box2ToBox1; + ConcatTransforms( worldToBox1, box2ToWorld, box2ToBox1 ); + + // We're going to be using the origin of box2 in the space of box1 alot, + // lets extract it from the matrix.... + Vector box2Origin; + MatrixGetColumn( box2ToBox1, 3, box2Origin ); + + // Next get the absolute values of these entries and store in absbox2ToBox1. + matrix3x4_t absBox2ToBox1; + ComputeAbsMatrix( box2ToBox1, absBox2ToBox1 ); + + // There are 15 tests to make. The first 3 involve trying planes parallel + // to the faces of the first box. + + // NOTE: The algorithm here involves finding the projections of the two boxes + // onto a particular line. If the projections on the line do not overlap, + // that means that there's a plane perpendicular to the line which separates + // the two boxes; and we've therefore found a separating plane. + + // The way we check for overlay is we find the projections of the two boxes + // onto the line, and add them up. We compare the sum with the projection + // of the relative center of box2 onto the same line. + + Vector tmp; + float boxProjectionSum; + float originProjection; + + // NOTE: For these guys, we're taking advantage of the fact that the ith + // row of the box2ToBox1 is the direction of the box1 (x,y,z)-axis + // transformed into the space of box2. + + // First side of box 1 + boxProjectionSum = box1Size.x + MatrixRowDotProduct( absBox2ToBox1, 0, box2Size ); + originProjection = FloatMakePositive( box2Origin.x ) + tolerance; + if ( FloatBits(originProjection) > FloatBits(boxProjectionSum) ) + { + VectorCopy( worldToBox1[0], pPlane->normal.Base() ); + return true; + } + + // Second side of box 1 + boxProjectionSum = box1Size.y + MatrixRowDotProduct( absBox2ToBox1, 1, box2Size ); + originProjection = FloatMakePositive( box2Origin.y ) + tolerance; + if ( FloatBits(originProjection) > FloatBits(boxProjectionSum) ) + { + VectorCopy( worldToBox1[1], pPlane->normal.Base() ); + return true; + } + + // Third side of box 1 + boxProjectionSum = box1Size.z + MatrixRowDotProduct( absBox2ToBox1, 2, box2Size ); + originProjection = FloatMakePositive( box2Origin.z ) + tolerance; + if ( FloatBits(originProjection) > FloatBits(boxProjectionSum) ) + { + VectorCopy( worldToBox1[2], pPlane->normal.Base() ); + return true; + } + + // The next three involve checking splitting planes parallel to the + // faces of the second box. + + // NOTE: For these guys, we're taking advantage of the fact that the 0th + // column of the box2ToBox1 is the direction of the box2 x-axis + // transformed into the space of box1. + // Here, we're determining the distance of box2's center from box1's center + // by projecting it onto a line parallel to box2's axis + + // First side of box 2 + boxProjectionSum = box2Size.x + MatrixColumnDotProduct( absBox2ToBox1, 0, box1Size ); + originProjection = FloatMakePositive( MatrixColumnDotProduct( box2ToBox1, 0, box2Origin ) ) + tolerance; + if ( FloatBits(originProjection) > FloatBits(boxProjectionSum) ) + { + MatrixGetColumn( box2ToWorld, 0, pPlane->normal ); + return true; + } + + // Second side of box 2 + boxProjectionSum = box2Size.y + MatrixColumnDotProduct( absBox2ToBox1, 1, box1Size ); + originProjection = FloatMakePositive( MatrixColumnDotProduct( box2ToBox1, 1, box2Origin ) ) + tolerance; + if ( FloatBits(originProjection) > FloatBits(boxProjectionSum) ) + { + MatrixGetColumn( box2ToWorld, 1, pPlane->normal ); + return true; + } + + // Third side of box 2 + boxProjectionSum = box2Size.z + MatrixColumnDotProduct( absBox2ToBox1, 2, box1Size ); + originProjection = FloatMakePositive( MatrixColumnDotProduct( box2ToBox1, 2, box2Origin ) ) + tolerance; + if ( FloatBits(originProjection) > FloatBits(boxProjectionSum) ) + { + MatrixGetColumn( box2ToWorld, 2, pPlane->normal ); + return true; + } + + // Next check the splitting planes which are orthogonal to the pairs + // of edges, one from box1 and one from box2. As only direction matters, + // there are 9 pairs since each box has 3 distinct edge directions. + + // Here, we take advantage of the fact that the edges from box 1 are all + // axis aligned; therefore the crossproducts are simplified. Let's walk through + // the example of b1e1 x b2e1: + + // In this example, the line to check is perpendicular to b1e1 + b2e2 + // we can compute this line by taking the cross-product: + // + // [ i j k ] + // [ 1 0 0 ] = - ez j + ey k = l1 + // [ ex ey ez ] + + // Where ex, ey, ez is the components of box2's x axis in the space of box 1, + // which is == to the 0th column of of box2toBox1 + + // The projection of box1 onto this line = the absolute dot product of the box size + // against the line, which = + // AbsDot( box1Size, l1 ) = abs( -ez * box1.y ) + abs( ey * box1.z ) + + // To compute the projection of box2 onto this line, we'll do it in the space of box 2 + // + // [ i j k ] + // [ fx fy fz ] = fz j - fy k = l2 + // [ 1 0 0 ] + + // Where fx, fy, fz is the components of box1's x axis in the space of box 2, + // which is == to the 0th row of of box2toBox1 + + // The projection of box2 onto this line = the absolute dot product of the box size + // against the line, which = + // AbsDot( box2Size, l2 ) = abs( fz * box2.y ) + abs ( fy * box2.z ) + + // The projection of the relative origin position on this line is done in the + // space of box 1: + // + // originProjection = DotProduct( <-ez j + ey k>, box2Origin ) = + // -ez * box2Origin.y + ey * box2Origin.z + + // NOTE: These checks can be bogus if both edges are parallel. The if + // checks at the beginning of each block are designed to catch that case + + // b1e1 x b2e1 + if ( absBox2ToBox1[0][0] < 1.0f - 1e-3f ) + { + boxProjectionSum = + box1Size.y * absBox2ToBox1[2][0] + box1Size.z * absBox2ToBox1[1][0] + + box2Size.y * absBox2ToBox1[0][2] + box2Size.z * absBox2ToBox1[0][1]; + originProjection = FloatMakePositive( -box2Origin.y * box2ToBox1[2][0] + box2Origin.z * box2ToBox1[1][0] ) + tolerance; + if ( FloatBits(originProjection) > FloatBits(boxProjectionSum) ) + { + MatrixGetColumn( box2ToWorld, 0, tmp ); + CrossProduct( worldToBox1[0], tmp.Base(), pPlane->normal.Base() ); + return true; + } + } + + // b1e1 x b2e2 + if ( absBox2ToBox1[0][1] < 1.0f - 1e-3f ) + { + boxProjectionSum = + box1Size.y * absBox2ToBox1[2][1] + box1Size.z * absBox2ToBox1[1][1] + + box2Size.x * absBox2ToBox1[0][2] + box2Size.z * absBox2ToBox1[0][0]; + originProjection = FloatMakePositive( -box2Origin.y * box2ToBox1[2][1] + box2Origin.z * box2ToBox1[1][1] ) + tolerance; + if ( FloatBits(originProjection) > FloatBits(boxProjectionSum) ) + { + MatrixGetColumn( box2ToWorld, 1, tmp ); + CrossProduct( worldToBox1[0], tmp.Base(), pPlane->normal.Base() ); + return true; + } + } + + // b1e1 x b2e3 + if ( absBox2ToBox1[0][2] < 1.0f - 1e-3f ) + { + boxProjectionSum = + box1Size.y * absBox2ToBox1[2][2] + box1Size.z * absBox2ToBox1[1][2] + + box2Size.x * absBox2ToBox1[0][1] + box2Size.y * absBox2ToBox1[0][0]; + originProjection = FloatMakePositive( -box2Origin.y * box2ToBox1[2][2] + box2Origin.z * box2ToBox1[1][2] ) + tolerance; + if ( FloatBits(originProjection) > FloatBits(boxProjectionSum) ) + { + MatrixGetColumn( box2ToWorld, 2, tmp ); + CrossProduct( worldToBox1[0], tmp.Base(), pPlane->normal.Base() ); + return true; + } + } + + // b1e2 x b2e1 + if ( absBox2ToBox1[1][0] < 1.0f - 1e-3f ) + { + boxProjectionSum = + box1Size.x * absBox2ToBox1[2][0] + box1Size.z * absBox2ToBox1[0][0] + + box2Size.y * absBox2ToBox1[1][2] + box2Size.z * absBox2ToBox1[1][1]; + originProjection = FloatMakePositive( box2Origin.x * box2ToBox1[2][0] - box2Origin.z * box2ToBox1[0][0] ) + tolerance; + if ( FloatBits(originProjection) > FloatBits(boxProjectionSum) ) + { + MatrixGetColumn( box2ToWorld, 0, tmp ); + CrossProduct( worldToBox1[1], tmp.Base(), pPlane->normal.Base() ); + return true; + } + } + + // b1e2 x b2e2 + if ( absBox2ToBox1[1][1] < 1.0f - 1e-3f ) + { + boxProjectionSum = + box1Size.x * absBox2ToBox1[2][1] + box1Size.z * absBox2ToBox1[0][1] + + box2Size.x * absBox2ToBox1[1][2] + box2Size.z * absBox2ToBox1[1][0]; + originProjection = FloatMakePositive( box2Origin.x * box2ToBox1[2][1] - box2Origin.z * box2ToBox1[0][1] ) + tolerance; + if ( FloatBits(originProjection) > FloatBits(boxProjectionSum) ) + { + MatrixGetColumn( box2ToWorld, 1, tmp ); + CrossProduct( worldToBox1[1], tmp.Base(), pPlane->normal.Base() ); + return true; + } + } + + // b1e2 x b2e3 + if ( absBox2ToBox1[1][2] < 1.0f - 1e-3f ) + { + boxProjectionSum = + box1Size.x * absBox2ToBox1[2][2] + box1Size.z * absBox2ToBox1[0][2] + + box2Size.x * absBox2ToBox1[1][1] + box2Size.y * absBox2ToBox1[1][0]; + originProjection = FloatMakePositive( box2Origin.x * box2ToBox1[2][2] - box2Origin.z * box2ToBox1[0][2] ) + tolerance; + if ( FloatBits(originProjection) > FloatBits(boxProjectionSum) ) + { + MatrixGetColumn( box2ToWorld, 2, tmp ); + CrossProduct( worldToBox1[1], tmp.Base(), pPlane->normal.Base() ); + return true; + } + } + + // b1e3 x b2e1 + if ( absBox2ToBox1[2][0] < 1.0f - 1e-3f ) + { + boxProjectionSum = + box1Size.x * absBox2ToBox1[1][0] + box1Size.y * absBox2ToBox1[0][0] + + box2Size.y * absBox2ToBox1[2][2] + box2Size.z * absBox2ToBox1[2][1]; + originProjection = FloatMakePositive( -box2Origin.x * box2ToBox1[1][0] + box2Origin.y * box2ToBox1[0][0] ) + tolerance; + if ( FloatBits(originProjection) > FloatBits(boxProjectionSum) ) + { + MatrixGetColumn( box2ToWorld, 0, tmp ); + CrossProduct( worldToBox1[2], tmp.Base(), pPlane->normal.Base() ); + return true; + } + } + + // b1e3 x b2e2 + if ( absBox2ToBox1[2][1] < 1.0f - 1e-3f ) + { + boxProjectionSum = + box1Size.x * absBox2ToBox1[1][1] + box1Size.y * absBox2ToBox1[0][1] + + box2Size.x * absBox2ToBox1[2][2] + box2Size.z * absBox2ToBox1[2][0]; + originProjection = FloatMakePositive( -box2Origin.x * box2ToBox1[1][1] + box2Origin.y * box2ToBox1[0][1] ) + tolerance; + if ( FloatBits(originProjection) > FloatBits(boxProjectionSum) ) + { + MatrixGetColumn( box2ToWorld, 1, tmp ); + CrossProduct( worldToBox1[2], tmp.Base(), pPlane->normal.Base() ); + return true; + } + } + + // b1e3 x b2e3 + if ( absBox2ToBox1[2][2] < 1.0f - 1e-3f ) + { + boxProjectionSum = + box1Size.x * absBox2ToBox1[1][2] + box1Size.y * absBox2ToBox1[0][2] + + box2Size.x * absBox2ToBox1[2][1] + box2Size.y * absBox2ToBox1[2][0]; + originProjection = FloatMakePositive( -box2Origin.x * box2ToBox1[1][2] + box2Origin.y * box2ToBox1[0][2] ) + tolerance; + if ( FloatBits(originProjection) > FloatBits(boxProjectionSum) ) + { + MatrixGetColumn( box2ToWorld, 2, tmp ); + CrossProduct( worldToBox1[2], tmp.Base(), pPlane->normal.Base() ); + return true; + } + } + return false; +} + + +//----------------------------------------------------------------------------- +// Compute a separating plane between two boxes (expensive!) +// Returns false if no separating plane exists +//----------------------------------------------------------------------------- +bool ComputeSeparatingPlane( const Vector& org1, const QAngle& angles1, const Vector& min1, const Vector& max1, + const Vector& org2, const QAngle& angles2, const Vector& min2, const Vector& max2, + float tolerance, cplane_t* pPlane ) +{ + matrix3x4_t worldToBox1, box2ToWorld; + ComputeCenterIMatrix( org1, angles1, min1, max1, worldToBox1 ); + ComputeCenterMatrix( org2, angles2, min2, max2, box2ToWorld ); + + // Then compute the size of the two boxes + Vector box1Size, box2Size; + VectorSubtract( max1, min1, box1Size ); + VectorSubtract( max2, min2, box2Size ); + box1Size *= 0.5f; + box2Size *= 0.5f; + + return ComputeSeparatingPlane( worldToBox1, box2ToWorld, box1Size, box2Size, tolerance, pPlane ); +} + + +//----------------------------------------------------------------------------- +// Swept OBB test +//----------------------------------------------------------------------------- +bool IsRayIntersectingOBB( const Ray_t &ray, const Vector& org, const QAngle& angles, + const Vector& mins, const Vector& maxs ) +{ + if ( angles == vec3_angle ) + { + Vector vecWorldMins, vecWorldMaxs; + VectorAdd( org, mins, vecWorldMins ); + VectorAdd( org, maxs, vecWorldMaxs ); + return IsBoxIntersectingRay( vecWorldMins, vecWorldMaxs, ray ); + } + + if ( ray.m_IsRay ) + { + matrix3x4_t worldToBox; + AngleIMatrix( angles, org, worldToBox ); + + Ray_t rotatedRay; + VectorTransform( ray.m_Start, worldToBox, rotatedRay.m_Start ); + VectorRotate( ray.m_Delta, worldToBox, rotatedRay.m_Delta ); + rotatedRay.m_StartOffset = vec3_origin; + rotatedRay.m_Extents = vec3_origin; + rotatedRay.m_IsRay = ray.m_IsRay; + rotatedRay.m_IsSwept = ray.m_IsSwept; + + return IsBoxIntersectingRay( mins, maxs, rotatedRay ); + } + + if ( !ray.m_IsSwept ) + { + cplane_t plane; + return ComputeSeparatingPlane( ray.m_Start, vec3_angle, -ray.m_Extents, ray.m_Extents, + org, angles, mins, maxs, 0.0f, &plane ) == false; + } + + // NOTE: See the comments in ComputeSeparatingPlane to understand this math + + // First, compute the basis of box in the space of the ray + // NOTE: These basis place the origin at the centroid of each box! + matrix3x4_t worldToBox1, box2ToWorld; + ComputeCenterMatrix( org, angles, mins, maxs, box2ToWorld ); + + // Find the center + extents of an AABB surrounding the ray + Vector vecRayCenter; + VectorMA( ray.m_Start, 0.5, ray.m_Delta, vecRayCenter ); + vecRayCenter *= -1.0f; + SetIdentityMatrix( worldToBox1 ); + MatrixSetColumn( vecRayCenter, 3, worldToBox1 ); + + Vector box1Size; + box1Size.x = ray.m_Extents.x + FloatMakePositive( ray.m_Delta.x ) * 0.5f; + box1Size.y = ray.m_Extents.y + FloatMakePositive( ray.m_Delta.y ) * 0.5f; + box1Size.z = ray.m_Extents.z + FloatMakePositive( ray.m_Delta.z ) * 0.5f; + + // Then compute the size of the box + Vector box2Size; + VectorSubtract( maxs, mins, box2Size ); + box2Size *= 0.5f; + + // Do an OBB test of the box with the AABB surrounding the ray + cplane_t plane; + if ( ComputeSeparatingPlane( worldToBox1, box2ToWorld, box1Size, box2Size, 0.0f, &plane ) ) + return false; + + // Now deal with the planes which are the cross products of the ray sweep direction vs box edges + Vector vecRayDirection = ray.m_Delta; + VectorNormalize( vecRayDirection ); + + // Need a vector between ray center vs box center measured in the space of the ray (world) + Vector vecCenterDelta; + vecCenterDelta.x = box2ToWorld[0][3] - ray.m_Start.x; + vecCenterDelta.y = box2ToWorld[1][3] - ray.m_Start.y; + vecCenterDelta.z = box2ToWorld[2][3] - ray.m_Start.z; + + // Rotate the ray direction into the space of the OBB + Vector vecAbsRayDirBox2; + VectorIRotate( vecRayDirection, box2ToWorld, vecAbsRayDirBox2 ); + + // Make abs versions of the ray in world space + ray in box2 space + VectorAbs( vecAbsRayDirBox2, vecAbsRayDirBox2 ); + + // Now do the work for the planes which are perpendicular to the edges of the AABB + // and the sweep direction edges... + + // In this example, the line to check is perpendicular to box edge x + ray delta + // we can compute this line by taking the cross-product: + // + // [ i j k ] + // [ 1 0 0 ] = - dz j + dy k = l1 + // [ dx dy dz ] + + // Where dx, dy, dz is the ray delta (normalized) + + // The projection of the box onto this line = the absolute dot product of the box size + // against the line, which = + // AbsDot( vecBoxHalfDiagonal, l1 ) = abs( -dz * vecBoxHalfDiagonal.y ) + abs( dy * vecBoxHalfDiagonal.z ) + + // Because the plane contains the sweep direction, the sweep will produce + // no extra projection onto the line normal to the plane. + // Therefore all we need to do is project the ray extents onto this line also: + // AbsDot( ray.m_Extents, l1 ) = abs( -dz * ray.m_Extents.y ) + abs( dy * ray.m_Extents.z ) + + Vector vecPlaneNormal; + + // box x x ray delta + CrossProduct( vecRayDirection, Vector( box2ToWorld[0][0], box2ToWorld[1][0], box2ToWorld[2][0] ), vecPlaneNormal ); + float flCenterDeltaProjection = FloatMakePositive( DotProduct( vecPlaneNormal, vecCenterDelta ) ); + float flBoxProjectionSum = + vecAbsRayDirBox2.z * box2Size.y + vecAbsRayDirBox2.y * box2Size.z + + DotProductAbs( vecPlaneNormal, ray.m_Extents ); + if ( FloatBits(flCenterDeltaProjection) > FloatBits(flBoxProjectionSum) ) + return false; + + // box y x ray delta + CrossProduct( vecRayDirection, Vector( box2ToWorld[0][1], box2ToWorld[1][1], box2ToWorld[2][1] ), vecPlaneNormal ); + flCenterDeltaProjection = FloatMakePositive( DotProduct( vecPlaneNormal, vecCenterDelta ) ); + flBoxProjectionSum = + vecAbsRayDirBox2.z * box2Size.x + vecAbsRayDirBox2.x * box2Size.z + + DotProductAbs( vecPlaneNormal, ray.m_Extents ); + if ( FloatBits(flCenterDeltaProjection) > FloatBits(flBoxProjectionSum) ) + return false; + + // box z x ray delta + CrossProduct( vecRayDirection, Vector( box2ToWorld[0][2], box2ToWorld[1][2], box2ToWorld[2][2] ), vecPlaneNormal ); + flCenterDeltaProjection = FloatMakePositive( DotProduct( vecPlaneNormal, vecCenterDelta ) ); + flBoxProjectionSum = + vecAbsRayDirBox2.y * box2Size.x + vecAbsRayDirBox2.x * box2Size.y + + DotProductAbs( vecPlaneNormal, ray.m_Extents ); + if ( FloatBits(flCenterDeltaProjection) > FloatBits(flBoxProjectionSum) ) + return false; + + return true; +} + +//-------------------------------------------------------------------------- +// Purpose: +// +// NOTE: +// triangle points are given in clockwise order (aabb-triangle test) +// +// 1 edge0 = 1 - 0 +// | \ edge1 = 2 - 1 +// | \ edge2 = 0 - 2 +// | \ . +// | \ . +// 0-----2 . +// +//-------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Purpose: find the minima and maxima of the 3 given values +//----------------------------------------------------------------------------- +inline void FindMinMax( float v1, float v2, float v3, float &min, float &max ) +{ + min = max = v1; + if ( v2 < min ) { min = v2; } + if ( v2 > max ) { max = v2; } + if ( v3 < min ) { min = v3; } + if ( v3 > max ) { max = v3; } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline bool AxisTestEdgeCrossX2( float flEdgeZ, float flEdgeY, float flAbsEdgeZ, float flAbsEdgeY, + const Vector &p1, const Vector &p3, const Vector &vecExtents, + float flTolerance ) +{ + // Cross Product( axialX(1,0,0) x edge ): x = 0.0f, y = edge.z, z = -edge.y + // Triangle Point Distances: dist(x) = normal.y * pt(x).y + normal.z * pt(x).z + float flDist1 = flEdgeZ * p1.y - flEdgeY * p1.z; + float flDist3 = flEdgeZ * p3.y - flEdgeY * p3.z; + + // Extents are symmetric: dist = abs( normal.y ) * extents.y + abs( normal.z ) * extents.z + float flDistBox = flAbsEdgeZ * vecExtents.y + flAbsEdgeY * vecExtents.z; + + // Either dist1, dist3 is the closest point to the box, determine which and test of overlap with box(AABB). + if ( flDist1 < flDist3 ) + { + if ( ( flDist1 > ( flDistBox + flTolerance ) ) || ( flDist3 < -( flDistBox + flTolerance ) ) ) + return false; + } + else + { + if ( ( flDist3 > ( flDistBox + flTolerance ) ) || ( flDist1 < -( flDistBox + flTolerance ) ) ) + return false; + } + + return true; +} + +//-------------------------------------------------------------------------- +// Purpose: +//-------------------------------------------------------------------------- +inline bool AxisTestEdgeCrossX3( float flEdgeZ, float flEdgeY, float flAbsEdgeZ, float flAbsEdgeY, + const Vector &p1, const Vector &p2, const Vector &vecExtents, + float flTolerance ) +{ + // Cross Product( axialX(1,0,0) x edge ): x = 0.0f, y = edge.z, z = -edge.y + // Triangle Point Distances: dist(x) = normal.y * pt(x).y + normal.z * pt(x).z + float flDist1 = flEdgeZ * p1.y - flEdgeY * p1.z; + float flDist2 = flEdgeZ * p2.y - flEdgeY * p2.z; + + // Extents are symmetric: dist = abs( normal.y ) * extents.y + abs( normal.z ) * extents.z + float flDistBox = flAbsEdgeZ * vecExtents.y + flAbsEdgeY * vecExtents.z; + + // Either dist1, dist2 is the closest point to the box, determine which and test of overlap with box(AABB). + if ( flDist1 < flDist2 ) + { + if ( ( flDist1 > ( flDistBox + flTolerance ) ) || ( flDist2 < -( flDistBox + flTolerance ) ) ) + return false; + } + else + { + if ( ( flDist2 > ( flDistBox + flTolerance ) ) || ( flDist1 < -( flDistBox + flTolerance ) ) ) + return false; + } + + return true; +} + +//-------------------------------------------------------------------------- +//-------------------------------------------------------------------------- +inline bool AxisTestEdgeCrossY2( float flEdgeZ, float flEdgeX, float flAbsEdgeZ, float flAbsEdgeX, + const Vector &p1, const Vector &p3, const Vector &vecExtents, + float flTolerance ) +{ + // Cross Product( axialY(0,1,0) x edge ): x = -edge.z, y = 0.0f, z = edge.x + // Triangle Point Distances: dist(x) = normal.x * pt(x).x + normal.z * pt(x).z + float flDist1 = -flEdgeZ * p1.x + flEdgeX * p1.z; + float flDist3 = -flEdgeZ * p3.x + flEdgeX * p3.z; + + // Extents are symmetric: dist = abs( normal.x ) * extents.x + abs( normal.z ) * extents.z + float flDistBox = flAbsEdgeZ * vecExtents.x + flAbsEdgeX * vecExtents.z; + + // Either dist1, dist3 is the closest point to the box, determine which and test of overlap with box(AABB). + if ( flDist1 < flDist3 ) + { + if ( ( flDist1 > ( flDistBox + flTolerance ) ) || ( flDist3 < -( flDistBox + flTolerance ) ) ) + return false; + } + else + { + if ( ( flDist3 > ( flDistBox + flTolerance ) ) || ( flDist1 < -( flDistBox + flTolerance ) ) ) + return false; + } + + return true; +} + +//-------------------------------------------------------------------------- +//-------------------------------------------------------------------------- +inline bool AxisTestEdgeCrossY3( float flEdgeZ, float flEdgeX, float flAbsEdgeZ, float flAbsEdgeX, + const Vector &p1, const Vector &p2, const Vector &vecExtents, + float flTolerance ) +{ + // Cross Product( axialY(0,1,0) x edge ): x = -edge.z, y = 0.0f, z = edge.x + // Triangle Point Distances: dist(x) = normal.x * pt(x).x + normal.z * pt(x).z + float flDist1 = -flEdgeZ * p1.x + flEdgeX * p1.z; + float flDist2 = -flEdgeZ * p2.x + flEdgeX * p2.z; + + // Extents are symmetric: dist = abs( normal.x ) * extents.x + abs( normal.z ) * extents.z + float flDistBox = flAbsEdgeZ * vecExtents.x + flAbsEdgeX * vecExtents.z; + + // Either dist1, dist2 is the closest point to the box, determine which and test of overlap with box(AABB). + if ( flDist1 < flDist2 ) + { + if ( ( flDist1 > ( flDistBox + flTolerance ) ) || ( flDist2 < -( flDistBox + flTolerance ) ) ) + return false; + } + else + { + if ( ( flDist2 > ( flDistBox + flTolerance ) ) || ( flDist1 < -( flDistBox + flTolerance ) ) ) + return false; + } + + return true; +} + +//-------------------------------------------------------------------------- +//-------------------------------------------------------------------------- +inline bool AxisTestEdgeCrossZ1( float flEdgeY, float flEdgeX, float flAbsEdgeY, float flAbsEdgeX, + const Vector &p2, const Vector &p3, const Vector &vecExtents, + float flTolerance ) +{ + // Cross Product( axialZ(0,0,1) x edge ): x = edge.y, y = -edge.x, z = 0.0f + // Triangle Point Distances: dist(x) = normal.x * pt(x).x + normal.y * pt(x).y + float flDist2 = flEdgeY * p2.x - flEdgeX * p2.y; + float flDist3 = flEdgeY * p3.x - flEdgeX * p3.y; + + // Extents are symmetric: dist = abs( normal.x ) * extents.x + abs( normal.y ) * extents.y + float flDistBox = flAbsEdgeY * vecExtents.x + flAbsEdgeX * vecExtents.y; + + // Either dist2, dist3 is the closest point to the box, determine which and test of overlap with box(AABB). + if ( flDist3 < flDist2 ) + { + if ( ( flDist3 > ( flDistBox + flTolerance ) ) || ( flDist2 < -( flDistBox + flTolerance ) ) ) + return false; + } + else + { + if ( ( flDist2 > ( flDistBox + flTolerance ) ) || ( flDist3 < -( flDistBox + flTolerance ) ) ) + return false; + } + + return true; +} + +//-------------------------------------------------------------------------- +//-------------------------------------------------------------------------- +inline bool AxisTestEdgeCrossZ2( float flEdgeY, float flEdgeX, float flAbsEdgeY, float flAbsEdgeX, + const Vector &p1, const Vector &p3, const Vector &vecExtents, + float flTolerance ) +{ + // Cross Product( axialZ(0,0,1) x edge ): x = edge.y, y = -edge.x, z = 0.0f + // Triangle Point Distances: dist(x) = normal.x * pt(x).x + normal.y * pt(x).y + float flDist1 = flEdgeY * p1.x - flEdgeX * p1.y; + float flDist3 = flEdgeY * p3.x - flEdgeX * p3.y; + + // Extents are symmetric: dist = abs( normal.x ) * extents.x + abs( normal.y ) * extents.y + float flDistBox = flAbsEdgeY * vecExtents.x + flAbsEdgeX * vecExtents.y; + + // Either dist1, dist3 is the closest point to the box, determine which and test of overlap with box(AABB). + if ( flDist1 < flDist3 ) + { + if ( ( flDist1 > ( flDistBox + flTolerance ) ) || ( flDist3 < -( flDistBox + flTolerance ) ) ) + return false; + } + else + { + if ( ( flDist3 > ( flDistBox + flTolerance ) ) || ( flDist1 < -( flDistBox + flTolerance ) ) ) + return false; + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Test for an intersection (overlap) between an axial-aligned bounding +// box (AABB) and a triangle. +// +// Using the "Separating-Axis Theorem" to test for intersections between +// a triangle and an axial-aligned bounding box (AABB). +// 1. 3 Axis Planes - x, y, z +// 2. 9 Edge Planes Tests - the 3 edges of the triangle crossed with all 3 axial +// planes (x, y, z) +// 3. 1 Face Plane - the triangle plane (cplane_t plane below) +// Output: false = separating axis (no intersection) +// true = intersection +//----------------------------------------------------------------------------- +bool IsBoxIntersectingTriangle( const Vector &vecBoxCenter, const Vector &vecBoxExtents, + const Vector &v1, const Vector &v2, const Vector &v3, + const cplane_t &plane, float flTolerance ) +{ + // Test the axial planes (x,y,z) against the min, max of the triangle. + float flMin, flMax; + Vector p1, p2, p3; + + // x plane + p1.x = v1.x - vecBoxCenter.x; + p2.x = v2.x - vecBoxCenter.x; + p3.x = v3.x - vecBoxCenter.x; + FindMinMax( p1.x, p2.x, p3.x, flMin, flMax ); + if ( ( flMin > ( vecBoxExtents.x + flTolerance ) ) || ( flMax < -( vecBoxExtents.x + flTolerance ) ) ) + return false; + + // y plane + p1.y = v1.y - vecBoxCenter.y; + p2.y = v2.y - vecBoxCenter.y; + p3.y = v3.y - vecBoxCenter.y; + FindMinMax( p1.y, p2.y, p3.y, flMin, flMax ); + if ( ( flMin > ( vecBoxExtents.y + flTolerance ) ) || ( flMax < -( vecBoxExtents.y + flTolerance ) ) ) + return false; + + // z plane + p1.z = v1.z - vecBoxCenter.z; + p2.z = v2.z - vecBoxCenter.z; + p3.z = v3.z - vecBoxCenter.z; + FindMinMax( p1.z, p2.z, p3.z, flMin, flMax ); + if ( ( flMin > ( vecBoxExtents.z + flTolerance ) ) || ( flMax < -( vecBoxExtents.z + flTolerance ) ) ) + return false; + + // Test the 9 edge cases. + Vector vecEdge, vecAbsEdge; + + // edge 0 (cross x,y,z) + vecEdge = p2 - p1; + vecAbsEdge.y = FloatMakePositive( vecEdge.y ); + vecAbsEdge.z = FloatMakePositive( vecEdge.z ); + if ( !AxisTestEdgeCrossX2( vecEdge.z, vecEdge.y, vecAbsEdge.z, vecAbsEdge.y, p1, p3, vecBoxExtents, flTolerance ) ) + return false; + + vecAbsEdge.x = FloatMakePositive( vecEdge.x ); + if ( !AxisTestEdgeCrossY2( vecEdge.z, vecEdge.x, vecAbsEdge.z, vecAbsEdge.x, p1, p3, vecBoxExtents, flTolerance ) ) + return false; + + if ( !AxisTestEdgeCrossZ1( vecEdge.y, vecEdge.x, vecAbsEdge.y, vecAbsEdge.x, p2, p3, vecBoxExtents, flTolerance ) ) + return false; + + // edge 1 (cross x,y,z) + vecEdge = p3 - p2; + vecAbsEdge.y = FloatMakePositive( vecEdge.y ); + vecAbsEdge.z = FloatMakePositive( vecEdge.z ); + if ( !AxisTestEdgeCrossX2( vecEdge.z, vecEdge.y, vecAbsEdge.z, vecAbsEdge.y, p1, p2, vecBoxExtents, flTolerance ) ) + return false; + + vecAbsEdge.x = FloatMakePositive( vecEdge.x ); + if ( !AxisTestEdgeCrossY2( vecEdge.z, vecEdge.x, vecAbsEdge.z, vecAbsEdge.x, p1, p2, vecBoxExtents, flTolerance ) ) + return false; + + if ( !AxisTestEdgeCrossZ2( vecEdge.y, vecEdge.x, vecAbsEdge.y, vecAbsEdge.x, p1, p3, vecBoxExtents, flTolerance ) ) + return false; + + // edge 2 (cross x,y,z) + vecEdge = p1 - p3; + vecAbsEdge.y = FloatMakePositive( vecEdge.y ); + vecAbsEdge.z = FloatMakePositive( vecEdge.z ); + if ( !AxisTestEdgeCrossX3( vecEdge.z, vecEdge.y, vecAbsEdge.z, vecAbsEdge.y, p1, p2, vecBoxExtents, flTolerance ) ) + return false; + + vecAbsEdge.x = FloatMakePositive( vecEdge.x ); + if ( !AxisTestEdgeCrossY3( vecEdge.z, vecEdge.x, vecAbsEdge.z, vecAbsEdge.x, p1, p2, vecBoxExtents, flTolerance ) ) + return false; + + if ( !AxisTestEdgeCrossZ1( vecEdge.y, vecEdge.x, vecAbsEdge.y, vecAbsEdge.x, p2, p3, vecBoxExtents, flTolerance ) ) + return false; + + // Test against the triangle face plane. + Vector vecMin, vecMax; + VectorSubtract( vecBoxCenter, vecBoxExtents, vecMin ); + VectorAdd( vecBoxCenter, vecBoxExtents, vecMax ); + if ( BoxOnPlaneSide( vecMin, vecMax, &plane ) != 3 ) + return false; + + return true; +} + +// NOTE: JAY: This is untested code based on Real-time Collision Detection by Ericson +#if 0 +Vector CalcClosestPointOnTriangle( const Vector &P, const Vector &v0, const Vector &v1, const Vector &v2 ) +{ + Vector e0 = v1 - v0; + Vector e1 = v2 - v0; + Vector p0 = P - v0; + + // voronoi region of v0 + float d1 = DotProduct( e0, p0 ); + float d2 = DotProduct( e1, p0 ); + if (d1 <= 0.0f && d2 <= 0.0f) + return v0; + + // voronoi region of v1 + Vector p1 = P - v1; + float d3 = DotProduct( e0, p1 ); + float d4 = DotProduct( e1, p1 ); + if (d3 >=0.0f && d4 <= d3) + return v1; + + // voronoi region of e0 (v0-v1) + float ve2 = d1*d4 - d3*d2; + if ( ve2 <= 0.0f && d1 >= 0.0f && d3 <= 0.0f ) + { + float v = d1 / (d1-d3); + return v0 + v * e0; + } + // voronoi region of v2 + Vector p2 = P - v2; + float d5 = DotProduct( e0, p2 ); + float d6 = DotProduct( e1, p2 ); + if (d6 >= 0.0f && d5 <= d6) + return v2; + // voronoi region of e1 + float ve1 = d5*d2 - d1*d6; + if (ve1 <= 0.0f && d2 >= 0.0f && d6 >= 0.0f) + { + float w = d2 / (d2-d6); + return v0 + w * e1; + } + // voronoi region on e2 + float ve0 = d3*d6 - d5*d4; + if ( ve0 <= 0.0f && (d4-d3) >= 0.0f && (d5-d6) >= 0.0f ) + { + float w = (d4-d3)/((d4-d3) + (d5-d6)); + return v1 + w * (v2-v1); + } + // voronoi region of v0v1v2 triangle + float denom = 1.0f / (ve0+ve1+ve2); + float v = ve1*denom; + float w = ve2 * denom; + return v0 + e0 * v + e1 * w; +} +#endif + + +bool OBBHasFullyContainedIntersectionWithQuad( const Vector &vOBBExtent1_Scaled, const Vector &vOBBExtent2_Scaled, const Vector &vOBBExtent3_Scaled, const Vector &ptOBBCenter, + const Vector &vQuadNormal, float fQuadPlaneDist, const Vector &ptQuadCenter, + const Vector &vQuadExtent1_Normalized, float fQuadExtent1Length, + const Vector &vQuadExtent2_Normalized, float fQuadExtent2Length ) +{ + Vector ptOBB[8]; //this specific ordering helps us web out from a point to its 3 connecting points with some bit math (most importantly, no if's) + ptOBB[0] = ptOBBCenter - vOBBExtent1_Scaled - vOBBExtent2_Scaled - vOBBExtent3_Scaled; + ptOBB[1] = ptOBBCenter - vOBBExtent1_Scaled - vOBBExtent2_Scaled + vOBBExtent3_Scaled; + ptOBB[2] = ptOBBCenter - vOBBExtent1_Scaled + vOBBExtent2_Scaled + vOBBExtent3_Scaled; + ptOBB[3] = ptOBBCenter - vOBBExtent1_Scaled + vOBBExtent2_Scaled - vOBBExtent3_Scaled; + ptOBB[4] = ptOBBCenter + vOBBExtent1_Scaled - vOBBExtent2_Scaled - vOBBExtent3_Scaled; + ptOBB[5] = ptOBBCenter + vOBBExtent1_Scaled - vOBBExtent2_Scaled + vOBBExtent3_Scaled; + ptOBB[6] = ptOBBCenter + vOBBExtent1_Scaled + vOBBExtent2_Scaled + vOBBExtent3_Scaled; + ptOBB[7] = ptOBBCenter + vOBBExtent1_Scaled + vOBBExtent2_Scaled - vOBBExtent3_Scaled; + + float fDists[8]; + for( int i = 0; i != 8; ++i ) + fDists[i] = vQuadNormal.Dot( ptOBB[i] ) - fQuadPlaneDist; + + int iSides[8]; + int iSideMask = 0; + for( int i = 0; i != 8; ++i ) + { + if( fDists[i] > 0.0f ) + { + iSides[i] = 1; + iSideMask |= 1; + } + else + { + iSides[i] = 2; + iSideMask |= 2; + } + } + + if( iSideMask != 3 ) //points reside entirely on one side of the quad's plane + return false; + + Vector ptPlaneIntersections[12]; //only have 12 lines, can only possibly generate 12 split points + int iPlaneIntersectionsCount = 0; + + for( int i = 0; i != 8; ++i ) + { + if( iSides[i] == 2 ) //point behind the plane + { + int iAxisCrossings[3]; + iAxisCrossings[0] = i ^ 4; //upper 4 vs lower 4 crosses vOBBExtent1 axis + iAxisCrossings[1] = ((i + 1) & 3) + (i & 4); //cycle to the next element while staying within the upper 4 or lower 4, this will cross either vOBBExtent2 or vOBBExtent3 axis, we don't care which + iAxisCrossings[2] = ((i - 1) & 3) + (i & 4); //cylce to the previous element while staying within the upper 4 or lower 4, this will cross the axis iAxisCrossings[1] didn't cross + + for( int j = 0; j != 3; ++j ) + { + if( iSides[iAxisCrossings[j]] == 1 ) //point in front of the plane + { + //line between ptOBB[i] and ptOBB[iAxisCrossings[j]] intersects the plane, generate a point at the intersection for further testing + float fTotalDist = fDists[iAxisCrossings[j]] - fDists[i]; //remember that fDists[i] is a negative value + ptPlaneIntersections[iPlaneIntersectionsCount] = (ptOBB[iAxisCrossings[j]] * (-fDists[i]/fTotalDist)) + (ptOBB[i] * (fDists[iAxisCrossings[j]]/fTotalDist)); + + Assert( fabs( ptPlaneIntersections[iPlaneIntersectionsCount].Dot( vQuadNormal ) - fQuadPlaneDist ) < 0.1f ); //intersection point is on plane + + ++iPlaneIntersectionsCount; + } + } + } + } + + Assert( iPlaneIntersectionsCount != 0 ); + + for( int i = 0; i != iPlaneIntersectionsCount; ++i ) + { + //these points are guaranteed to be on the plane, now just check to see if they're within the quad's extents + Vector vToPointFromQuadCenter = ptPlaneIntersections[i] - ptQuadCenter; + + float fExt1Dist = vQuadExtent1_Normalized.Dot( vToPointFromQuadCenter ); + if( fabs( fExt1Dist ) > fQuadExtent1Length ) + return false; //point is outside boundaries + + //vToPointFromQuadCenter -= vQuadExtent1_Normalized * fExt1Dist; //to handle diamond shaped quads + + float fExt2Dist = vQuadExtent2_Normalized.Dot( vToPointFromQuadCenter ); + if( fabs( fExt2Dist ) > fQuadExtent2Length ) + return false; //point is outside boundaries + } + + return true; //there were lines crossing the quad plane, and every line crossing that plane had its intersection with the plane within the quad's boundaries +} + +//----------------------------------------------------------------------------- +// Compute if the Ray intersects the quad plane, and whether the entire +// Ray/Quad intersection is contained within the quad itself +// +// False if no intersection exists, or if part of the intersection is +// outside the quad's extents +//----------------------------------------------------------------------------- +bool RayHasFullyContainedIntersectionWithQuad( const Ray_t &ray, + const Vector &vQuadNormal, float fQuadPlaneDist, const Vector &ptQuadCenter, + const Vector &vQuadExtent1_Normalized, float fQuadExtent1Length, + const Vector &vQuadExtent2_Normalized, float fQuadExtent2Length ) +{ + Vector ptPlaneIntersections[(12 + 12 + 8)]; //absolute max possible: 12 lines to connect the start box, 12 more to connect the end box, 8 to connect the boxes to eachother + + //8 points to make an AABB, 8 lines to connect each point from it's start to end point along the ray, 8 possible intersections + int iPlaneIntersectionsCount = 0; + + if( ray.m_IsRay ) + { + //just 1 line + if( ray.m_IsSwept ) + { + Vector ptEndPoints[2]; + ptEndPoints[0] = ray.m_Start; + ptEndPoints[1] = ptEndPoints[0] + ray.m_Delta; + + int i; + float fDists[2]; + for( i = 0; i != 2; ++i ) + fDists[i] = vQuadNormal.Dot( ptEndPoints[i] ) - fQuadPlaneDist; + + for( i = 0; i != 2; ++i ) + { + if( fDists[i] <= 0.0f ) + { + int j = 1-i; + if( fDists[j] >= 0.0f ) + { + float fInvTotalDist = 1.0f / (fDists[j] - fDists[i]); //fDists[i] <= 0, ray is swept so no chance that the denom was 0 + ptPlaneIntersections[0] = (ptEndPoints[i] * (fDists[j] * fInvTotalDist)) - (ptEndPoints[j] * (fDists[i] * fInvTotalDist)); //fDists[i] <= 0 + Assert( fabs( ptPlaneIntersections[iPlaneIntersectionsCount].Dot( vQuadNormal ) - fQuadPlaneDist ) < 0.1f ); //intersection point is on plane + iPlaneIntersectionsCount = 1; + } + else + { + return false; + } + break; + } + } + + if( i == 2 ) + return false; + } + else //not swept, so this is actually a point on quad question + { + if( fabs( vQuadNormal.Dot( ray.m_Start ) - fQuadPlaneDist ) < 1e-6 ) + { + ptPlaneIntersections[0] = ray.m_Start; + iPlaneIntersectionsCount = 1; + } + else + { + return false; + } + } + } + else + { + Vector ptEndPoints[2][8]; + //this specific ordering helps us web out from a point to its 3 connecting points with some bit math (most importantly, no if's) + ptEndPoints[0][0] = ray.m_Start; ptEndPoints[0][0].x -= ray.m_Extents.x; ptEndPoints[0][0].y -= ray.m_Extents.y; ptEndPoints[0][0].z -= ray.m_Extents.z; + ptEndPoints[0][1] = ray.m_Start; ptEndPoints[0][1].x -= ray.m_Extents.x; ptEndPoints[0][1].y -= ray.m_Extents.y; ptEndPoints[0][1].z += ray.m_Extents.z; + ptEndPoints[0][2] = ray.m_Start; ptEndPoints[0][2].x -= ray.m_Extents.x; ptEndPoints[0][2].y += ray.m_Extents.y; ptEndPoints[0][2].z += ray.m_Extents.z; + ptEndPoints[0][3] = ray.m_Start; ptEndPoints[0][3].x -= ray.m_Extents.x; ptEndPoints[0][3].y += ray.m_Extents.y; ptEndPoints[0][3].z -= ray.m_Extents.z; + ptEndPoints[0][4] = ray.m_Start; ptEndPoints[0][4].x += ray.m_Extents.x; ptEndPoints[0][4].y -= ray.m_Extents.y; ptEndPoints[0][4].z -= ray.m_Extents.z; + ptEndPoints[0][5] = ray.m_Start; ptEndPoints[0][5].x += ray.m_Extents.x; ptEndPoints[0][5].y -= ray.m_Extents.y; ptEndPoints[0][5].z += ray.m_Extents.z; + ptEndPoints[0][6] = ray.m_Start; ptEndPoints[0][6].x += ray.m_Extents.x; ptEndPoints[0][6].y += ray.m_Extents.y; ptEndPoints[0][6].z += ray.m_Extents.z; + ptEndPoints[0][7] = ray.m_Start; ptEndPoints[0][7].x += ray.m_Extents.x; ptEndPoints[0][7].y += ray.m_Extents.y; ptEndPoints[0][7].z -= ray.m_Extents.z; + + float fDists[2][8]; + int iSides[2][8]; + int iSideMask[2] = { 0, 0 }; + for( int i = 0; i != 8; ++i ) + { + fDists[0][i] = vQuadNormal.Dot( ptEndPoints[0][i] ) - fQuadPlaneDist; + if( fDists[0][i] > 0.0f ) + { + iSides[0][i] = 1; + iSideMask[0] |= 1; + } + else + { + iSides[0][i] = 2; + iSideMask[0] |= 2; + } + } + + if( ray.m_IsSwept ) + { + for( int i = 0; i != 8; ++i ) + ptEndPoints[1][i] = ptEndPoints[0][i] + ray.m_Delta; + + for( int i = 0; i != 8; ++i ) + { + fDists[1][i] = vQuadNormal.Dot( ptEndPoints[1][i] ) - fQuadPlaneDist; + if( fDists[1][i] > 0.0f ) + { + iSides[1][i] = 1; + iSideMask[1] |= 1; + } + else + { + iSides[1][i] = 2; + iSideMask[1] |= 2; + } + } + } + + if( (iSideMask[0] | iSideMask[1]) != 3 ) + { + //Assert( (iSideMask[0] | iSideMask[1]) != 2 ); + return false; //all points resides entirely on one side of the quad + } + + + //generate intersections for boxes split by the plane at either end of the ray + for( int k = 0; k != 2; ++k ) + { + if( iSideMask[k] == 3 ) //box is split by the plane + { + for( int i = 0; i != 8; ++i ) + { + if( iSides[k][i] == 2 ) //point behind the plane + { + int iAxisCrossings[3]; + iAxisCrossings[0] = i ^ 4; //upper 4 vs lower 4 crosses X axis + iAxisCrossings[1] = ((i + 1) & 3) + (i & 4); //cycle to the next element while staying within the upper 4 or lower 4, this will cross either Y or Z axis, we don't care which + iAxisCrossings[2] = ((i - 1) & 3) + (i & 4); //cylce to the previous element while staying within the upper 4 or lower 4, this will cross the axis iAxisCrossings[1] didn't cross + + for( int j = 0; j != 3; ++j ) + { + if( iSides[k][iAxisCrossings[j]] == 1 ) //point in front of the plane + { + //line between ptEndPoints[i] and ptEndPoints[iAxisCrossings[j]] intersects the plane, generate a point at the intersection for further testing + float fInvTotalDist = 1.0f / (fDists[k][iAxisCrossings[j]] - fDists[k][i]); //remember that fDists[k][i] is a negative value + ptPlaneIntersections[iPlaneIntersectionsCount] = (ptEndPoints[k][iAxisCrossings[j]] * (-fDists[k][i] * fInvTotalDist)) + (ptEndPoints[k][i] * (fDists[k][iAxisCrossings[j]] * fInvTotalDist)); + + Assert( fabs( ptPlaneIntersections[iPlaneIntersectionsCount].Dot( vQuadNormal ) - fQuadPlaneDist ) < 0.1f ); //intersection point is on plane + + ++iPlaneIntersectionsCount; + } + } + } + } + } + } + + if( ray.m_IsSwept ) + { + for( int i = 0; i != 8; ++i ) + { + if( iSides[0][i] != iSides[1][i] ) + { + int iPosSide, iNegSide; + if( iSides[0][i] == 1 ) + { + iPosSide = 0; + iNegSide = 1; + } + else + { + iPosSide = 1; + iNegSide = 0; + } + + Assert( (fDists[iPosSide][i] >= 0.0f) && (fDists[iNegSide][i] <= 0.0f) ); + + float fInvTotalDist = 1.0f / (fDists[iPosSide][i] - fDists[iNegSide][i]); //remember that fDists[iNegSide][i] is a negative value + ptPlaneIntersections[iPlaneIntersectionsCount] = (ptEndPoints[iPosSide][i] * (-fDists[iNegSide][i] * fInvTotalDist)) + (ptEndPoints[iNegSide][i] * (fDists[iPosSide][i] * fInvTotalDist)); + + Assert( fabs( ptPlaneIntersections[iPlaneIntersectionsCount].Dot( vQuadNormal ) - fQuadPlaneDist ) < 0.1f ); //intersection point is on plane + + ++iPlaneIntersectionsCount; + } + } + } + } + + //down here, we should simply have a collection of plane intersections, now we see if they reside within the quad + Assert( iPlaneIntersectionsCount != 0 ); + + for( int i = 0; i != iPlaneIntersectionsCount; ++i ) + { + //these points are guaranteed to be on the plane, now just check to see if they're within the quad's extents + Vector vToPointFromQuadCenter = ptPlaneIntersections[i] - ptQuadCenter; + + float fExt1Dist = vQuadExtent1_Normalized.Dot( vToPointFromQuadCenter ); + if( fabs( fExt1Dist ) > fQuadExtent1Length ) + return false; //point is outside boundaries + + //vToPointFromQuadCenter -= vQuadExtent1_Normalized * fExt1Dist; //to handle diamond shaped quads + + float fExt2Dist = vQuadExtent2_Normalized.Dot( vToPointFromQuadCenter ); + if( fabs( fExt2Dist ) > fQuadExtent2Length ) + return false; //point is outside boundaries + } + + return true; //there were lines crossing the quad plane, and every line crossing that plane had its intersection with the plane within the quad's boundaries +} + +#endif // !_STATIC_LINKED || _SHARED_LIB diff --git a/sp/src/public/collisionutils.h b/sp/src/public/collisionutils.h new file mode 100644 index 00000000..50f87046 --- /dev/null +++ b/sp/src/public/collisionutils.h @@ -0,0 +1,450 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Common collision utility methods +// +// $Header: $ +// $NoKeywords: $ +//=============================================================================// + +#ifndef COLLISIONUTILS_H +#define COLLISIONUTILS_H + +#include "tier0/platform.h" + +#ifdef _WIN32 +#pragma once +#endif + +#include "mathlib/ssemath.h" + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- +struct Ray_t; +class Vector; +class Vector2D; +class Vector4D; +struct cplane_t; +class QAngle; +class CBaseTrace; +struct matrix3x4_t; + + +//----------------------------------------------------------------------------- +// +// IntersectRayWithTriangle +// +// Intersects a ray with a triangle, returns distance t along ray. +// t will be less than zero if no intersection occurred +// oneSided will cull collisions which approach the triangle from the back +// side, assuming the vertices are specified in counter-clockwise order +// The vertices need not be specified in that order if oneSided is not used +// +//----------------------------------------------------------------------------- +float IntersectRayWithTriangle( const Ray_t& ray, + const Vector& v1, const Vector& v2, const Vector& v3, + bool oneSided ); + +//----------------------------------------------------------------------------- +// +// ComputeIntersectionBarycentricCoordinates +// +// Figures out the barycentric coordinates (u,v) where a ray hits a +// triangle. Note that this will ignore the ray extents, and it also ignores +// the ray length. Note that the edge from v1->v2 represents u (v2: u = 1), +// and the edge from v1->v3 represents v (v3: v = 1). It returns false +// if the ray is parallel to the triangle (or when t is specified if t is less +// than zero). +// +//----------------------------------------------------------------------------- +bool ComputeIntersectionBarycentricCoordinates( const Ray_t& ray, + const Vector& v1, const Vector& v2, const Vector& v3, float& u, float& v, + float *t = 0 ); + +//----------------------------------------------------------------------------- +// +// IntersectRayWithRay +// +// Returns whether or not there was an intersection. The "t" paramter is the +// distance along ray0 and the "s" parameter is the distance along ray1. If +// the two lines to not intersect the "t" and "s" represent the closest approach. +// "t" and "s" will not change if the rays are parallel. +// +//----------------------------------------------------------------------------- +bool IntersectRayWithRay( const Ray_t &ray0, const Ray_t &ray1, float &t, float &s ); + + +//----------------------------------------------------------------------------- +// +// IntersectRayWithSphere +// +// Returns whether or not there was an intersection. Returns the two intersection points. +// NOTE: The point of closest approach can be found at the average t value. +// +//----------------------------------------------------------------------------- +bool IntersectRayWithSphere( const Vector &vecRayOrigin, const Vector &vecRayDelta, const Vector &vecSphereCenter, float flRadius, float *pT1, float *pT2 ); + + +//----------------------------------------------------------------------------- +// +// IntersectInfiniteRayWithSphere +// +// Returns whether or not there was an intersection of a sphere against an infinitely +// extending ray. +// Returns the two intersection points +// +//----------------------------------------------------------------------------- +bool IntersectInfiniteRayWithSphere( const Vector &vecRayOrigin, const Vector &vecRayDelta, + const Vector &vecSphereCenter, float flRadius, float *pT1, float *pT2 ); + + +// returns true if the sphere and cone intersect +// NOTE: cone sine/cosine are the half angle of the cone +bool IsSphereIntersectingCone( const Vector &sphereCenter, float sphereRadius, const Vector &coneOrigin, const Vector &coneNormal, float coneSine, float coneCosine ); + +//----------------------------------------------------------------------------- +// +// IntersectRayWithPlane +// +// Intersects a ray with a plane, returns distance t along ray. +// t will be less than zero the intersection occurs in the opposite direction of the ray. +// +//----------------------------------------------------------------------------- +float IntersectRayWithPlane( const Ray_t& ray, const cplane_t& plane ); +float IntersectRayWithPlane( const Vector& org, const Vector& dir, const cplane_t& plane ); +float IntersectRayWithPlane( const Vector& org, const Vector& dir, const Vector& normal, float dist ); + +// This version intersects a ray with an axis-aligned plane +float IntersectRayWithAAPlane( const Vector& vecStart, const Vector& vecEnd, int nAxis, float flSign, float flDist ); + + +//----------------------------------------------------------------------------- +// IntersectRayWithBox +// +// Purpose: Computes the intersection of a ray with a box (AABB) +// Output : Returns true if there is an intersection + trace information +//----------------------------------------------------------------------------- +bool IntersectRayWithBox( const Vector &rayStart, const Vector &rayDelta, const Vector &boxMins, const Vector &boxMaxs, float epsilon, CBaseTrace *pTrace, float *pFractionLeftSolid = NULL ); +bool IntersectRayWithBox( const Ray_t &ray, const Vector &boxMins, const Vector &boxMaxs, float epsilon, CBaseTrace *pTrace, float *pFractionLeftSolid = NULL ); + +//----------------------------------------------------------------------------- +// Intersects a ray against a box +//----------------------------------------------------------------------------- +struct BoxTraceInfo_t +{ + float t1; + float t2; + int hitside; + bool startsolid; +}; + +bool IntersectRayWithBox( const Vector &vecRayStart, const Vector &vecRayDelta, + const Vector &boxMins, const Vector &boxMaxs, float flTolerance, BoxTraceInfo_t *pTrace ); + + +//----------------------------------------------------------------------------- +// IntersectRayWithOBB +// +// Purpose: Computes the intersection of a ray with a oriented box (OBB) +// Output : Returns true if there is an intersection + trace information +//----------------------------------------------------------------------------- +bool IntersectRayWithOBB( const Vector &vecRayStart, const Vector &vecRayDelta, + const matrix3x4_t &matOBBToWorld, const Vector &vecOBBMins, const Vector &vecOBBMaxs, + float flTolerance, CBaseTrace *pTrace ); + +bool IntersectRayWithOBB( const Vector &vecRayOrigin, const Vector &vecRayDelta, + const Vector &vecBoxOrigin, const QAngle &angBoxRotation, + const Vector &vecOBBMins, const Vector &vecOBBMaxs, float flTolerance, CBaseTrace *pTrace ); + +bool IntersectRayWithOBB( const Ray_t &ray, const Vector &vecBoxOrigin, const QAngle &angBoxRotation, + const Vector &vecOBBMins, const Vector &vecOBBMaxs, float flTolerance, CBaseTrace *pTrace ); + +bool IntersectRayWithOBB( const Ray_t &ray, const matrix3x4_t &matOBBToWorld, + const Vector &vecOBBMins, const Vector &vecOBBMaxs, float flTolerance, CBaseTrace *pTrace ); + +bool IntersectRayWithOBB( const Vector &vecRayStart, const Vector &vecRayDelta, + const matrix3x4_t &matOBBToWorld, const Vector &vecOBBMins, const Vector &vecOBBMaxs, + float flTolerance, BoxTraceInfo_t *pTrace ); + +//----------------------------------------------------------------------------- +// +// IsSphereIntersectingSphere +// +// returns true if there's an intersection between sphere and sphere +// +//----------------------------------------------------------------------------- +bool IsSphereIntersectingSphere( const Vector& center1, float radius1, + const Vector& center2, float radius2 ); + + +//----------------------------------------------------------------------------- +// +// IsBoxIntersectingSphere +// +// returns true if there's an intersection between box and sphere +// +//----------------------------------------------------------------------------- +bool IsBoxIntersectingSphere( const Vector& boxMin, const Vector& boxMax, + const Vector& center, float radius ); + +bool IsBoxIntersectingSphereExtents( const Vector& boxCenter, const Vector& boxHalfDiag, + const Vector& center, float radius ); + +//----------------------------------------------------------------------------- +// returns true if there's an intersection between ray and sphere +//----------------------------------------------------------------------------- +bool IsRayIntersectingSphere( const Vector &vecRayOrigin, const Vector &vecRayDelta, + const Vector &vecSphereCenter, float flRadius, float flTolerance = 0.0f ); + + +//----------------------------------------------------------------------------- +// +// IsCircleIntersectingRectangle +// +// returns true if there's an intersection between rectangle and circle +// +//----------------------------------------------------------------------------- +bool IsCircleIntersectingRectangle( const Vector2D& boxMin, const Vector2D& boxMax, + const Vector2D& center, float radius ); + + +//----------------------------------------------------------------------------- +// +// IsBoxIntersectingBox +// +// returns true if there's an intersection between two boxes +// +//----------------------------------------------------------------------------- +bool IsBoxIntersectingBox( const Vector& boxMin1, const Vector& boxMax1, + const Vector& boxMin2, const Vector& boxMax2 ); + +bool IsBoxIntersectingBoxExtents( const Vector& boxCenter1, const Vector& boxHalfDiagonal1, + const Vector& boxCenter2, const Vector& boxHalfDiagonal2 ); + + +#ifdef _X360 +// inline version: +#include "mathlib/ssemath.h" +inline bool IsBoxIntersectingBoxExtents( const fltx4 boxCenter1, const fltx4 boxHalfDiagonal1, + const fltx4 boxCenter2, const fltx4 boxHalfDiagonal2 ); +#endif + +//----------------------------------------------------------------------------- +// +// IsOBBIntersectingOBB +// +// returns true if there's an intersection between two OBBs +// +//----------------------------------------------------------------------------- +bool IsOBBIntersectingOBB( const Vector &vecOrigin1, const QAngle &vecAngles1, const Vector& boxMin1, const Vector& boxMax1, + const Vector &vecOrigin2, const QAngle &vecAngles2, const Vector& boxMin2, const Vector& boxMax2, float flTolerance = 0.0f ); + + +//----------------------------------------------------------------------------- +// +// IsBoxIntersectingRay +// +// returns true if there's an intersection between box and ray +// +//----------------------------------------------------------------------------- + +bool FASTCALL IsBoxIntersectingRay( const Vector& boxMin, const Vector& boxMax, + const Vector& origin, const Vector& delta, float flTolerance = 0.0f ); + +bool FASTCALL IsBoxIntersectingRay( const Vector& boxMin, const Vector& boxMax, + const Ray_t& ray, float flTolerance = 0.0f ); + +bool FASTCALL IsBoxIntersectingRay( const Vector& boxMin, const Vector& boxMax, + const Vector& origin, const Vector& delta, + const Vector& invDelta, float flTolerance = 0.0f ); + + +// On the PC, we can't pass fltx4's in registers like this. On the x360, it is +// much better if we do. +#ifdef _X360 +bool FASTCALL IsBoxIntersectingRay( fltx4 boxMin, fltx4 boxMax, + fltx4 origin, fltx4 delta, fltx4 invDelta, // ray parameters + fltx4 vTolerance = LoadZeroSIMD() ///< eg from ReplicateX4(flTolerance) + ); +#else +bool FASTCALL IsBoxIntersectingRay( const fltx4 &boxMin, const fltx4 &boxMax, + const fltx4 & origin, const fltx4 & delta, const fltx4 & invDelta, // ray parameters + const fltx4 & vTolerance = Four_Zeros ///< eg from ReplicateX4(flTolerance) + ); +#endif + +bool inline FASTCALL IsBoxIntersectingRay( const fltx4& boxMin, const fltx4& boxMax, + const fltx4& origin, const fltx4& delta, float flTolerance = 0.0f ) +{ + return IsBoxIntersectingRay( boxMin, boxMax, origin, delta, ReciprocalSIMD(delta), ReplicateX4(flTolerance) ); +} + + +bool FASTCALL IsBoxIntersectingRay( const fltx4& boxMin, const fltx4& boxMax, + const Ray_t& ray, float flTolerance = 0.0f ); + + + +//----------------------------------------------------------------------------- +// +// IsPointInBox +// +// returns true if the point is in the box +// +//----------------------------------------------------------------------------- +bool IsPointInBox( const Vector& pt, const Vector& boxMin, const Vector& boxMax ); + + +// SIMD version +FORCEINLINE bool IsPointInBox( const fltx4& pt, const fltx4& boxMin, const fltx4& boxMax ) +{ + fltx4 greater = CmpGtSIMD( pt,boxMax ); + fltx4 less = CmpLtSIMD( pt, boxMin ); + return (IsAllZeros(SetWToZeroSIMD(OrSIMD(greater,less)))); +} + + + +//----------------------------------------------------------------------------- +// Purpose: returns true if pt intersects the truncated cone +// origin - cone tip, axis unit cone axis, cosAngle - cosine of cone axis to surface angle +//----------------------------------------------------------------------------- +bool IsPointInCone( const Vector &pt, const Vector &origin, const Vector &axis, float cosAngle, float length ); + +//----------------------------------------------------------------------------- +// Intersects a plane with a triangle (using barycentric definition) +// The return value, in pIntersection, is an array of barycentric coordinates +// describing at most 2 intersection points. +// The return value is the number of intersection points +//----------------------------------------------------------------------------- +int IntersectTriangleWithPlaneBarycentric( const Vector& org, const Vector& edgeU, const Vector& edgeV, + const Vector4D& plane, Vector2D* pIntersection ); + +//----------------------------------------------------------------------------- +// +// PointInQuadBarycentric +// +// Given a point and a quad in a plane return the u and v (barycentric) positions +// of the point relative to the quad. The points (v1,v2,v3,v4) should be given +// in a counter-clockwise order with v1 acting as the primary corner (u=0, v=0). +// Thus, u0 = v2 - v1, and v0 = v4 - v1. +// +//----------------------------------------------------------------------------- + +enum QuadBarycentricRetval_t +{ + BARY_QUADRATIC_FALSE = 0, + BARY_QUADRATIC_TRUE = 1, + BARY_QUADRATIC_NEGATIVE_DISCRIMINANT = 2 +}; + +QuadBarycentricRetval_t PointInQuadToBarycentric( const Vector &v1, const Vector &v2, + const Vector &v3, const Vector &v4, const Vector &point, Vector2D &uv ); + + +void PointInQuadFromBarycentric( const Vector &v1, const Vector &v2, const Vector &v3, const Vector &v4, + const Vector2D &uv, Vector &point ); +void TexCoordInQuadFromBarycentric( const Vector2D &v1, const Vector2D &v2, const Vector2D &v3, const Vector2D &v4, + const Vector2D &uv, Vector2D &texCoord ); + + +//----------------------------------------------------------------------------- +// Compute point from barycentric specification +// Edge u goes from v0 to v1, edge v goes from v0 to v2 +//----------------------------------------------------------------------------- +void ComputePointFromBarycentric( const Vector& v0, const Vector& v1, const Vector& v2, + float u, float v, Vector& pt ); +void ComputePointFromBarycentric( const Vector2D& v0, const Vector2D& v1, const Vector2D& v2, + float u, float v, Vector2D& pt ); + + +//----------------------------------------------------------------------------- +// Swept OBB test +//----------------------------------------------------------------------------- +bool IsRayIntersectingOBB( const Ray_t &ray, const Vector& org, const QAngle& angles, + const Vector& mins, const Vector& maxs ); + + +//----------------------------------------------------------------------------- +// Compute a separating plane between two boxes (expensive!) +// Returns false if no separating plane exists +//----------------------------------------------------------------------------- +bool ComputeSeparatingPlane( const Vector& org1, const QAngle& angles1, const Vector& min1, const Vector& max1, + const Vector& org2, const QAngle& angles2, const Vector& min2, const Vector& max2, + float tolerance, cplane_t* pPlane ); + +//----------------------------------------------------------------------------- +// IsBoxIntersectingTriangle +// +// Test for an intersection (overlap) between an axial-aligned bounding +// box (AABB) and a triangle. +// +// Triangle points are in counter-clockwise order with the normal facing "out." +// +// Using the "Separating-Axis Theorem" to test for intersections between +// a triangle and an axial-aligned bounding box (AABB). +// 1. 3 Axis Plane Tests - x, y, z +// 2. 9 Edge Planes Tests - the 3 edges of the triangle crossed with all 3 axial +// planes (x, y, z) +// 3. 1 Face Plane Test - the plane the triangle resides in (cplane_t plane) +//----------------------------------------------------------------------------- +bool IsBoxIntersectingTriangle( const Vector &vecBoxCenter, const Vector &vecBoxExtents, + const Vector &v1, const Vector &v2, const Vector &v3, + const cplane_t &plane, float flTolerance ); + + +Vector CalcClosestPointOnTriangle( const Vector &P, const Vector &v0, const Vector &v1, const Vector &v2 ); + + +//----------------------------------------------------------------------------- +// Compute if the OBB intersects the quad plane, and whether the entire +// OBB/Quad intersection is contained within the quad itself +// +// False if no intersection exists, or if part of the intersection is +// outside the quad's extents +//----------------------------------------------------------------------------- +bool OBBHasFullyContainedIntersectionWithQuad( const Vector &vOBBExtent1_Scaled, const Vector &vOBBExtent2_Scaled, const Vector &vOBBExtent3_Scaled, const Vector &ptOBBCenter, + const Vector &vQuadNormal, float fQuadPlaneDist, const Vector &ptQuadCenter, + const Vector &vQuadExtent1_Normalized, float fQuadExtent1Length, + const Vector &vQuadExtent2_Normalized, float fQuadExtent2Length ); + + +//----------------------------------------------------------------------------- +// Compute if the Ray intersects the quad plane, and whether the entire +// Ray/Quad intersection is contained within the quad itself +// +// False if no intersection exists, or if part of the intersection is +// outside the quad's extents +//----------------------------------------------------------------------------- +bool RayHasFullyContainedIntersectionWithQuad( const Ray_t &ray, + const Vector &vQuadNormal, float fQuadPlaneDist, const Vector &ptQuadCenter, + const Vector &vQuadExtent1_Normalized, float fQuadExtent1Length, + const Vector &vQuadExtent2_Normalized, float fQuadExtent2Length ); + + + +//----------------------------------------------------------------------------- +// INLINES +//----------------------------------------------------------------------------- + + +#ifdef _X360 +inline bool IsBoxIntersectingBoxExtents( const fltx4 boxCenter1, const fltx4 boxHalfDiagonal1, + const fltx4 boxCenter2, const fltx4 boxHalfDiagonal2 ) +{ + fltx4 vecDelta, vecSize; + + vecDelta = SubSIMD(boxCenter1, boxCenter2); + vecSize = AddSIMD(boxHalfDiagonal1, boxHalfDiagonal2); + + uint condition; + XMVectorInBoundsR(&condition, vecDelta, vecSize); + // we want the top three words to be all 1's ; that means in bounds + + + return XMComparisonAllInBounds( condition ); +} +#endif + + +#endif // COLLISIONUTILS_H diff --git a/sp/src/public/con_nprint.h b/sp/src/public/con_nprint.h new file mode 100644 index 00000000..8e866528 --- /dev/null +++ b/sp/src/public/con_nprint.h @@ -0,0 +1,31 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Debug overlay / notfication printing +// +//=============================================================================// + +#ifndef CON_NPRINT_H +#define CON_NPRINT_H + +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +// Purpose: Debug overlay / notfication printing +// NOTE: Structure cannot be changed by mods +//----------------------------------------------------------------------------- +typedef struct con_nprint_s +{ + int index; // Row # + float time_to_live; // # of seconds before it disappears. -1 means to display for 1 frame then go away. + float color[ 3 ]; // RGB colors ( 0.0 -> 1.0 scale ) + bool fixed_width_font; +} con_nprint_t; + +// Print string on line idx +void Con_NPrintf( int idx, PRINTF_FORMAT_STRING const char *fmt, ... ); +// Customized printout +void Con_NXPrintf( const con_nprint_t *info, PRINTF_FORMAT_STRING const char *fmt, ... ); + +#endif // CON_NPRINT_H diff --git a/sp/src/public/const.h b/sp/src/public/const.h new file mode 100644 index 00000000..105c0ef9 --- /dev/null +++ b/sp/src/public/const.h @@ -0,0 +1,456 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef CONST_H +#define CONST_H + +#ifdef _WIN32 +#pragma once +#endif + +// the command line param that tells the engine to use steam +#define STEAM_PARM "-steam" +// the command line param to tell dedicated server to restart +// if they are out of date +#define AUTO_RESTART "-autoupdate" + +// the message a server sends when a clients steam login is expired +#define INVALID_STEAM_TICKET "Invalid STEAM UserID Ticket\n" +#define INVALID_STEAM_VACBANSTATE "VAC banned from secure server\n" +#define INVALID_STEAM_LOGGED_IN_ELSEWHERE "This Steam account is being used in another location\n" +#define INVALID_STEAM_LOGON_NOT_CONNECTED "Client not connected to Steam\n" +#define INVALID_STEAM_LOGON_TICKET_CANCELED "Client left game (Steam auth ticket has been canceled)\n" + +#define CLIENTNAME_TIMED_OUT "%s timed out" + +// This is the default, see shareddefs.h for mod-specific value, which can override this +#define DEFAULT_TICK_INTERVAL (0.015) // 15 msec is the default +#define MINIMUM_TICK_INTERVAL (0.001) +#define MAXIMUM_TICK_INTERVAL (0.1) + +// This is the max # of players the engine can handle +#define ABSOLUTE_PLAYER_LIMIT 255 // not 256, so we can send the limit as a byte +#define ABSOLUTE_PLAYER_LIMIT_DW ( (ABSOLUTE_PLAYER_LIMIT/32) + 1 ) + +// a player name may have 31 chars + 0 on the PC. +// the 360 only allows 15 char + 0, but stick with the larger PC size for cross-platform communication +#define MAX_PLAYER_NAME_LENGTH 32 + +#ifdef _X360 +#define MAX_PLAYERS_PER_CLIENT XUSER_MAX_COUNT // Xbox 360 supports 4 players per console +#else +#define MAX_PLAYERS_PER_CLIENT 1 // One player per PC +#endif + +#define MAX_MAP_NAME 32 +#define MAX_NETWORKID_LENGTH 64 // num chars for a network (i.e steam) ID + +// BUGBUG: Reconcile with or derive this from the engine's internal definition! +// FIXME: I added an extra bit because I needed to make it signed +#define SP_MODEL_INDEX_BITS 13 + +// How many bits to use to encode an edict. +#define MAX_EDICT_BITS 11 // # of bits needed to represent max edicts +// Max # of edicts in a level +#define MAX_EDICTS (1<movetype values +enum MoveType_t +{ + MOVETYPE_NONE = 0, // never moves + MOVETYPE_ISOMETRIC, // For players -- in TF2 commander view, etc. + MOVETYPE_WALK, // Player only - moving on the ground + MOVETYPE_STEP, // gravity, special edge handling -- monsters use this + MOVETYPE_FLY, // No gravity, but still collides with stuff + MOVETYPE_FLYGRAVITY, // flies through the air + is affected by gravity + MOVETYPE_VPHYSICS, // uses VPHYSICS for simulation + MOVETYPE_PUSH, // no clip to world, push and crush + MOVETYPE_NOCLIP, // No gravity, no collisions, still do velocity/avelocity + MOVETYPE_LADDER, // Used by players only when going onto a ladder + MOVETYPE_OBSERVER, // Observer movement, depends on player's observer mode + MOVETYPE_CUSTOM, // Allows the entity to describe its own physics + + // should always be defined as the last item in the list + MOVETYPE_LAST = MOVETYPE_CUSTOM, + + MOVETYPE_MAX_BITS = 4 +}; + +// edict->movecollide values +enum MoveCollide_t +{ + MOVECOLLIDE_DEFAULT = 0, + + // These ones only work for MOVETYPE_FLY + MOVETYPE_FLYGRAVITY + MOVECOLLIDE_FLY_BOUNCE, // bounces, reflects, based on elasticity of surface and object - applies friction (adjust velocity) + MOVECOLLIDE_FLY_CUSTOM, // Touch() will modify the velocity however it likes + MOVECOLLIDE_FLY_SLIDE, // slides along surfaces (no bounce) - applies friciton (adjusts velocity) + + MOVECOLLIDE_COUNT, // Number of different movecollides + + // When adding new movecollide types, make sure this is correct + MOVECOLLIDE_MAX_BITS = 3 +}; + +// edict->solid values +// NOTE: Some movetypes will cause collisions independent of SOLID_NOT/SOLID_TRIGGER when the entity moves +// SOLID only effects OTHER entities colliding with this one when they move - UGH! + +// Solid type basically describes how the bounding volume of the object is represented +// NOTE: SOLID_BBOX MUST BE 2, and SOLID_VPHYSICS MUST BE 6 +// NOTE: These numerical values are used in the FGD by the prop code (see prop_dynamic) +enum SolidType_t +{ + SOLID_NONE = 0, // no solid model + SOLID_BSP = 1, // a BSP tree + SOLID_BBOX = 2, // an AABB + SOLID_OBB = 3, // an OBB (not implemented yet) + SOLID_OBB_YAW = 4, // an OBB, constrained so that it can only yaw + SOLID_CUSTOM = 5, // Always call into the entity for tests + SOLID_VPHYSICS = 6, // solid vphysics object, get vcollide from the model and collide with that + SOLID_LAST, +}; + +enum SolidFlags_t +{ + FSOLID_CUSTOMRAYTEST = 0x0001, // Ignore solid type + always call into the entity for ray tests + FSOLID_CUSTOMBOXTEST = 0x0002, // Ignore solid type + always call into the entity for swept box tests + FSOLID_NOT_SOLID = 0x0004, // Are we currently not solid? + FSOLID_TRIGGER = 0x0008, // This is something may be collideable but fires touch functions + // even when it's not collideable (when the FSOLID_NOT_SOLID flag is set) + FSOLID_NOT_STANDABLE = 0x0010, // You can't stand on this + FSOLID_VOLUME_CONTENTS = 0x0020, // Contains volumetric contents (like water) + FSOLID_FORCE_WORLD_ALIGNED = 0x0040, // Forces the collision rep to be world-aligned even if it's SOLID_BSP or SOLID_VPHYSICS + FSOLID_USE_TRIGGER_BOUNDS = 0x0080, // Uses a special trigger bounds separate from the normal OBB + FSOLID_ROOT_PARENT_ALIGNED = 0x0100, // Collisions are defined in root parent's local coordinate space + FSOLID_TRIGGER_TOUCH_DEBRIS = 0x0200, // This trigger will touch debris objects + +#ifdef MAPBASE + // From https://developer.valvesoftware.com/wiki/Owner + FSOLID_COLLIDE_WITH_OWNER = 0X0400, +#endif + + FSOLID_MAX_BITS = 11 +}; + +//----------------------------------------------------------------------------- +// A couple of inline helper methods +//----------------------------------------------------------------------------- +inline bool IsSolid( SolidType_t solidType, int nSolidFlags ) +{ + return (solidType != SOLID_NONE) && ((nSolidFlags & FSOLID_NOT_SOLID) == 0); +} + + +// m_lifeState values +#define LIFE_ALIVE 0 // alive +#define LIFE_DYING 1 // playing death animation or still falling off of a ledge waiting to hit ground +#define LIFE_DEAD 2 // dead. lying still. +#define LIFE_RESPAWNABLE 3 +#define LIFE_DISCARDBODY 4 + +// entity effects +enum +{ + EF_BONEMERGE = 0x001, // Performs bone merge on client side + EF_BRIGHTLIGHT = 0x002, // DLIGHT centered at entity origin + EF_DIMLIGHT = 0x004, // player flashlight + EF_NOINTERP = 0x008, // don't interpolate the next frame + EF_NOSHADOW = 0x010, // Don't cast no shadow + EF_NODRAW = 0x020, // don't draw entity + EF_NORECEIVESHADOW = 0x040, // Don't receive no shadow + EF_BONEMERGE_FASTCULL = 0x080, // For use with EF_BONEMERGE. If this is set, then it places this ent's origin at its + // parent and uses the parent's bbox + the max extents of the aiment. + // Otherwise, it sets up the parent's bones every frame to figure out where to place + // the aiment, which is inefficient because it'll setup the parent's bones even if + // the parent is not in the PVS. + EF_ITEM_BLINK = 0x100, // blink an item so that the user notices it. + EF_PARENT_ANIMATES = 0x200, // always assume that the parent entity is animating + EF_MAX_BITS = 10 +}; + +#define EF_PARITY_BITS 3 +#define EF_PARITY_MASK ((1< +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +void CheckHeap( void ) +{ +#ifdef USECRTMEMDEBUG + _CrtCheckMemory(); +#endif +} + +// undone: this needs to be somehow made to construct before everything else. +// see http://msdn.microsoft.com/library/periodic/period97/dembugs.htm for info +void InitCRTMemDebug( void ) +{ +#ifdef USECRTMEMDEBUG + _CrtSetDbgFlag( +// _CRTDBG_ALLOC_MEM_DF | + _CRTDBG_CHECK_ALWAYS_DF | + _CRTDBG_CHECK_CRT_DF | + _CRTDBG_DELAY_FREE_MEM_DF ); +#endif +} + +#endif // !_STATIC_LINKED || _SHARED_LIB diff --git a/sp/src/public/crtmemdebug.h b/sp/src/public/crtmemdebug.h new file mode 100644 index 00000000..15ed5ff7 --- /dev/null +++ b/sp/src/public/crtmemdebug.h @@ -0,0 +1,33 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef CRTMEMDEBUG_H +#define CRTMEMDEBUG_H +#pragma once + +#ifdef USECRTMEMDEBUG + +#include +#define MEMCHECK CheckHeap() +void CheckHeap( void ); + +#else + +#define MEMCHECK + +#endif + +void InitCRTMemDebug( void ); + + +#endif // CRTMEMDEBUG_H diff --git a/sp/src/public/datacache/idatacache.h b/sp/src/public/datacache/idatacache.h new file mode 100644 index 00000000..c21937fd --- /dev/null +++ b/sp/src/public/datacache/idatacache.h @@ -0,0 +1,545 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//=============================================================================// + +#ifndef IDATACACHE_H +#define IDATACACHE_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "tier0/dbg.h" +#include "appframework/IAppSystem.h" + +class IDataCache; + +//----------------------------------------------------------------------------- +// +// Shared Data Cache API +// +//----------------------------------------------------------------------------- + +#define DATACACHE_INTERFACE_VERSION "VDataCache003" + +//----------------------------------------------------------------------------- +// Support types and enums +//----------------------------------------------------------------------------- + +//--------------------------------------------------------- +// Unique (per section) identifier for a cache item defined by client +//--------------------------------------------------------- +typedef uint32 DataCacheClientID_t; + + +//--------------------------------------------------------- +// Cache-defined handle for a cache item +//--------------------------------------------------------- +FORWARD_DECLARE_HANDLE( memhandle_t ); +typedef memhandle_t DataCacheHandle_t; +#define DC_INVALID_HANDLE ((DataCacheHandle_t)0) + +//--------------------------------------------------------- +// Cache Limits +//--------------------------------------------------------- +struct DataCacheLimits_t +{ + DataCacheLimits_t( unsigned _nMaxBytes = (unsigned)-1, unsigned _nMaxItems = (unsigned)-1, unsigned _nMinBytes = 0, unsigned _nMinItems = 0 ) + : nMaxBytes(_nMaxBytes), + nMaxItems(_nMaxItems), + nMinBytes(_nMinBytes), + nMinItems(_nMinItems) + { + } + + // Maximum levels permitted + unsigned nMaxBytes; + unsigned nMaxItems; + + // Minimum levels permitted + unsigned nMinBytes; + unsigned nMinItems; +}; + +//--------------------------------------------------------- +// Cache status +//--------------------------------------------------------- +struct DataCacheStatus_t +{ + // Current state of the cache + unsigned nBytes; + unsigned nItems; + + unsigned nBytesLocked; + unsigned nItemsLocked; + + // Diagnostics + unsigned nFindRequests; + unsigned nFindHits; +}; + +//--------------------------------------------------------- +// Cache options +//--------------------------------------------------------- +enum DataCacheOptions_t +{ + DC_TRACE_ACTIVITY = (1 << 0), + DC_FORCE_RELOCATE = (1 << 1), + DC_ALWAYS_MISS = (1 << 2), + DC_VALIDATE = (1 << 3), +}; + + +//--------------------------------------------------------- +// Cache report types +//--------------------------------------------------------- +enum DataCacheReportType_t +{ + DC_SUMMARY_REPORT, + DC_DETAIL_REPORT, + DC_DETAIL_REPORT_LRU, +}; + + +//--------------------------------------------------------- +// Notifications to section clients on cache events +//--------------------------------------------------------- +enum DataCacheNotificationType_t +{ + // Used internally to prohibit notifications + DC_NONE, + + // Item is falling off the LRU and should be deleted, return false to block + DC_AGE_DISCARD, + + // Item is being explicitly flushed and should be deleted, return false to block + DC_FLUSH_DISCARD, + + // Item is being explicitly removed and should be deleted. Failure is not an option + DC_REMOVED, + + // Cache is requesting item be relocated for debugging purposes + DC_RELOCATE, + + // Item info should be output to console, return false to accept default handling + DC_PRINT_INF0, +}; + +//------------------------------------- + +struct DataCacheNotification_t +{ + DataCacheNotificationType_t type; + const char * pszSectionName; + DataCacheClientID_t clientId; + const void * pItemData; + unsigned nItemSize; +}; + +//--------------------------------------------------------- + +const int DC_MAX_CLIENT_NAME = 15; +const int DC_MAX_ITEM_NAME = 511; + +//--------------------------------------------------------- +// Result codes +//--------------------------------------------------------- +enum DataCacheRemoveResult_t +{ + DC_OK, + DC_NOT_FOUND, + DC_LOCKED, +}; + +//--------------------------------------------------------- +// Add flags +//--------------------------------------------------------- +enum DataCacheAddFlags_t +{ + DCAF_LOCK = ( 1 << 0 ), + DCAF_DEFAULT = 0, +}; + + + +//----------------------------------------------------------------------------- +// IDataCacheSection +// +// Purpose: Implements a sub-section of the global cache. Subsections are +// areas of the cache with thier own memory constraints and common +// management. +//----------------------------------------------------------------------------- +abstract_class IDataCacheSection +{ +public: + //-------------------------------------------------------- + + virtual IDataCache *GetSharedCache() = 0; + virtual const char *GetName() = 0; + + //-------------------------------------------------------- + // Purpose: Controls cache size & options + //-------------------------------------------------------- + virtual void SetLimits( const DataCacheLimits_t &limits ) = 0; + virtual void SetOptions( unsigned options ) = 0; + + + //-------------------------------------------------------- + // Purpose: Get the current state of the section + //-------------------------------------------------------- + virtual void GetStatus( DataCacheStatus_t *pStatus, DataCacheLimits_t *pLimits = NULL ) = 0; + + + //-------------------------------------------------------- + // Purpose: Add an item to the cache. Purges old items if over budget, returns false if item was already in cache. + //-------------------------------------------------------- + virtual void EnsureCapacity( unsigned nBytes, unsigned nItems = 1 ) = 0; + + + //-------------------------------------------------------- + // Purpose: Add an item to the cache. Purges old items if over budget, returns false if item was already in cache. + //-------------------------------------------------------- + virtual bool Add( DataCacheClientID_t clientId, const void *pItemData, unsigned size, DataCacheHandle_t *pHandle ) = 0; + + //-------------------------------------------------------- + // Purpose: Finds an item in the cache, returns NULL if item is not in cache. Not a cheap operation if section not configured for fast find. + //-------------------------------------------------------- + virtual DataCacheHandle_t Find( DataCacheClientID_t clientId ) = 0; + + + //-------------------------------------------------------- + // Purpose: Get an item out of the cache and remove it. No callbacks are executed unless explicity specified. + //-------------------------------------------------------- + virtual DataCacheRemoveResult_t Remove( DataCacheHandle_t handle, const void **ppItemData, unsigned *pItemSize = NULL, bool bNotify = false ) = 0; + DataCacheRemoveResult_t Remove( DataCacheHandle_t handle, bool bNotify = false ) { return Remove( handle, NULL, NULL, bNotify ); } + + + //-------------------------------------------------------- + // Purpose: Returns if the data is currently in memory, but does *not* change its location in the LRU + //-------------------------------------------------------- + virtual bool IsPresent( DataCacheHandle_t handle ) = 0; + + + //-------------------------------------------------------- + // Purpose: Lock an item in the cache, returns NULL if item is not in the cache. + //-------------------------------------------------------- + virtual void *Lock( DataCacheHandle_t handle ) = 0; + + + //-------------------------------------------------------- + // Purpose: Unlock a previous lock. + //-------------------------------------------------------- + virtual int Unlock( DataCacheHandle_t handle ) = 0; + + + //-------------------------------------------------------- + // Purpose: Get an item without locking it, returns NULL if item is not in the cache. Use with care! + //-------------------------------------------------------- + virtual void *Get( DataCacheHandle_t handle, bool bFrameLock = false ) = 0; + virtual void *GetNoTouch( DataCacheHandle_t handle, bool bFrameLock = false ) = 0; + + //-------------------------------------------------------- + // Purpose: "Frame locking" (not game frame). A crude way to manage locks over relatively + // short periods. Does not affect normal locks/unlocks + //-------------------------------------------------------- + virtual int BeginFrameLocking() = 0; + virtual bool IsFrameLocking() = 0; + virtual void *FrameLock( DataCacheHandle_t handle ) = 0; + virtual int EndFrameLocking() = 0; + virtual int *GetFrameUnlockCounterPtr() = 0; + + + //-------------------------------------------------------- + // Purpose: Lock management, not for the feint of heart + //-------------------------------------------------------- + virtual int GetLockCount( DataCacheHandle_t handle ) = 0; + virtual int BreakLock( DataCacheHandle_t handle ) = 0; + + + //-------------------------------------------------------- + // Purpose: Explicitly mark an item as "recently used" + //-------------------------------------------------------- + virtual bool Touch( DataCacheHandle_t handle ) = 0; + + + //-------------------------------------------------------- + // Purpose: Explicitly mark an item as "least recently used". + //-------------------------------------------------------- + virtual bool Age( DataCacheHandle_t handle ) = 0; + + + //-------------------------------------------------------- + // Purpose: Empty the cache. Returns bytes released, will remove locked items if force specified + //-------------------------------------------------------- + virtual unsigned Flush( bool bUnlockedOnly = true, bool bNotify = true ) = 0; + + + //-------------------------------------------------------- + // Purpose: Dump the oldest items to free the specified amount of memory. Returns amount actually freed + //-------------------------------------------------------- + virtual unsigned Purge( unsigned nBytes ) = 0; + + + //-------------------------------------------------------- + // Purpose: Output the state of the section + //-------------------------------------------------------- + virtual void OutputReport( DataCacheReportType_t reportType = DC_SUMMARY_REPORT ) = 0; + + //-------------------------------------------------------- + // Purpose: Updates the size used by a specific item (locks the item, kicks + // other items out to make room as necessary, unlocks the item). + //-------------------------------------------------------- + virtual void UpdateSize( DataCacheHandle_t handle, unsigned int nNewSize ) = 0; + + + //-------------------------------------------------------- + // Purpose: Access to the mutex. More explicit control during get-then-lock sequences + // to ensure object stays valid during "then" + //-------------------------------------------------------- + virtual void LockMutex() = 0; + virtual void UnlockMutex() = 0; + + //-------------------------------------------------------- + // Purpose: Add an item to the cache. Purges old items if over budget, returns false if item was already in cache. + //-------------------------------------------------------- + virtual bool AddEx( DataCacheClientID_t clientId, const void *pItemData, unsigned size, unsigned flags, DataCacheHandle_t *pHandle ) = 0; +}; + + +//----------------------------------------------------------------------------- +// IDataCacheClient +// +// Purpose: Connection between the cache and the owner of a cache section +// +//----------------------------------------------------------------------------- +abstract_class IDataCacheClient +{ +public: + //-------------------------------------------------------- + // + //-------------------------------------------------------- + virtual bool HandleCacheNotification( const DataCacheNotification_t ¬ification ) = 0; + + + //-------------------------------------------------------- + // + //-------------------------------------------------------- + virtual bool GetItemName( DataCacheClientID_t clientId, const void *pItem, char *pDest, unsigned nMaxLen ) = 0; +}; + +//------------------------------------- + +class CDefaultDataCacheClient : public IDataCacheClient +{ +public: + virtual bool HandleCacheNotification( const DataCacheNotification_t ¬ification ) + { + switch ( notification.type ) + { + case DC_AGE_DISCARD: + case DC_FLUSH_DISCARD: + case DC_REMOVED: + default: + Assert ( 0 ); + return false; + } + return false; + } + + virtual bool GetItemName( DataCacheClientID_t clientId, const void *pItem, char *pDest, unsigned nMaxLen ) + { + return false; + } +}; + + +//----------------------------------------------------------------------------- +// IDataCache +// +// Purpose: The global shared cache. Manages sections and overall budgets. +// +//----------------------------------------------------------------------------- +abstract_class IDataCache : public IAppSystem +{ +public: + //-------------------------------------------------------- + // Purpose: Controls cache size. + //-------------------------------------------------------- + virtual void SetSize( int nMaxBytes ) = 0; + virtual void SetOptions( unsigned options ) = 0; + virtual void SetSectionLimits( const char *pszSectionName, const DataCacheLimits_t &limits ) = 0; + + + //-------------------------------------------------------- + // Purpose: Get the current state of the cache + //-------------------------------------------------------- + virtual void GetStatus( DataCacheStatus_t *pStatus, DataCacheLimits_t *pLimits = NULL ) = 0; + + + //-------------------------------------------------------- + // Purpose: Add a section to the cache + //-------------------------------------------------------- + virtual IDataCacheSection *AddSection( IDataCacheClient *pClient, const char *pszSectionName, const DataCacheLimits_t &limits = DataCacheLimits_t(), bool bSupportFastFind = false ) = 0; + + + //-------------------------------------------------------- + // Purpose: Remove a section from the cache + //-------------------------------------------------------- + virtual void RemoveSection( const char *pszClientName, bool bCallFlush = true ) = 0; + void RemoveSection( IDataCacheSection *pSection, bool bCallFlush = true ) { if ( pSection) RemoveSection( pSection->GetName() ); } + + + //-------------------------------------------------------- + // Purpose: Find a section of the cache + //-------------------------------------------------------- + virtual IDataCacheSection *FindSection( const char *pszClientName ) = 0; + + + //-------------------------------------------------------- + // Purpose: Dump the oldest items to free the specified amount of memory. Returns amount actually freed + //-------------------------------------------------------- + virtual unsigned Purge( unsigned nBytes ) = 0; + + + //-------------------------------------------------------- + // Purpose: Empty the cache. Returns bytes released, will remove locked items if force specified + //-------------------------------------------------------- + virtual unsigned Flush( bool bUnlockedOnly = true, bool bNotify = true ) = 0; + + + //-------------------------------------------------------- + // Purpose: Output the state of the cache + //-------------------------------------------------------- + virtual void OutputReport( DataCacheReportType_t reportType = DC_SUMMARY_REPORT, const char *pszSection = NULL ) = 0; +}; + +//----------------------------------------------------------------------------- +// Helper class to support usage pattern similar to CDataManager +//----------------------------------------------------------------------------- + +template< class STORAGE_TYPE, class CREATE_PARAMS, class LOCK_TYPE = STORAGE_TYPE * > +class CManagedDataCacheClient : public CDefaultDataCacheClient +{ +public: + typedef CManagedDataCacheClient CCacheClientBaseClass; + + CManagedDataCacheClient() + : m_pCache( NULL ) + { + } + + void Init( IDataCache *pSharedCache, const char *pszSectionName, const DataCacheLimits_t &limits = DataCacheLimits_t(), bool bSupportFastFind = false ) + { + if ( !m_pCache ) + { + m_pCache = pSharedCache->AddSection( this, pszSectionName, limits, bSupportFastFind ); + } + } + + void Shutdown() + { + if ( m_pCache ) + { + m_pCache->GetSharedCache()->RemoveSection( m_pCache ); + m_pCache = NULL; + } + } + + LOCK_TYPE CacheGet( DataCacheHandle_t handle, bool bFrameLock = true ) + { + return (LOCK_TYPE)(((STORAGE_TYPE *)m_pCache->Get( handle, bFrameLock ))->GetData()); + } + + LOCK_TYPE CacheGetNoTouch( DataCacheHandle_t handle ) + { + return (LOCK_TYPE)(((STORAGE_TYPE *)m_pCache->GetNoTouch( handle ))->GetData()); + } + + LOCK_TYPE CacheLock( DataCacheHandle_t handle ) + { + return (LOCK_TYPE)(((STORAGE_TYPE *)m_pCache->Lock( handle ))->GetData()); + } + + int CacheUnlock( DataCacheHandle_t handle ) + { + return m_pCache->Unlock( handle ); + } + + void CacheTouch( DataCacheHandle_t handle ) + { + m_pCache->Touch( handle ); + } + + void CacheRemove( DataCacheHandle_t handle, bool bNotify = true ) + { + m_pCache->Remove( handle, bNotify ); + } + + void CacheFlush() + { + m_pCache->Flush(); + } + + DataCacheHandle_t CacheCreate( const CREATE_PARAMS &createParams, unsigned flags = DCAF_DEFAULT ) + { + m_pCache->EnsureCapacity(STORAGE_TYPE::EstimatedSize(createParams)); + STORAGE_TYPE *pStore = STORAGE_TYPE::CreateResource( createParams ); + DataCacheHandle_t handle; + m_pCache->AddEx( (DataCacheClientID_t)pStore, pStore, pStore->Size(), flags, &handle); + return handle; + } + + void CacheLockMutex() + { + m_pCache->LockMutex(); + } + + void CacheUnlockMutex() + { + m_pCache->UnlockMutex(); + } + + bool HandleCacheNotification( const DataCacheNotification_t ¬ification ) + { + switch ( notification.type ) + { + case DC_AGE_DISCARD: + case DC_FLUSH_DISCARD: + case DC_REMOVED: + { + STORAGE_TYPE *p = (STORAGE_TYPE *)notification.clientId; + p->DestroyResource(); + } + return true; + default: + return CDefaultDataCacheClient::HandleCacheNotification( notification ); + } + } + + +protected: + + ~CManagedDataCacheClient() + { + Shutdown(); + } + + IDataCacheSection *GetCacheSection() + { + return m_pCache; + } + +private: + IDataCacheSection *m_pCache; + +}; + +//----------------------------------------------------------------------------- + +#endif // IDataCache diff --git a/sp/src/public/datacache/imdlcache.h b/sp/src/public/datacache/imdlcache.h new file mode 100644 index 00000000..0f7093ab --- /dev/null +++ b/sp/src/public/datacache/imdlcache.h @@ -0,0 +1,297 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// The copyright to the contents herein is the property of Valve, L.L.C. +// The contents may be used and/or copied only with the written permission of +// Valve, L.L.C., or in accordance with the terms and conditions stipulated in +// the agreement/contract under which the contents have been supplied. +// +// $Header: $ +// $NoKeywords: $ +// +// model loading and caching +// +//============================================================================= + +#ifndef IMDLCACHE_H +#define IMDLCACHE_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "appframework/IAppSystem.h" + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +struct studiohdr_t; +struct studiohwdata_t; +struct vcollide_t; +struct virtualmodel_t; +struct vertexFileHeader_t; + +namespace OptimizedModel +{ + struct FileHeader_t; +} + + +//----------------------------------------------------------------------------- +// Reference to a loaded studiomdl +//----------------------------------------------------------------------------- +typedef unsigned short MDLHandle_t; + +enum +{ + MDLHANDLE_INVALID = (MDLHandle_t)~0 +}; + + +//----------------------------------------------------------------------------- +// Cache data types +//----------------------------------------------------------------------------- +enum MDLCacheDataType_t +{ + // Callbacks to get called when data is loaded or unloaded for these: + MDLCACHE_STUDIOHDR = 0, + MDLCACHE_STUDIOHWDATA, + MDLCACHE_VCOLLIDE, + + // Callbacks NOT called when data is loaded or unloaded for these: + MDLCACHE_ANIMBLOCK, + MDLCACHE_VIRTUALMODEL, + MDLCACHE_VERTEXES, + MDLCACHE_DECODEDANIMBLOCK, +}; + +abstract_class IMDLCacheNotify +{ +public: + // Called right after the data is loaded + virtual void OnDataLoaded( MDLCacheDataType_t type, MDLHandle_t handle ) = 0; + + // Called right before the data is unloaded + virtual void OnDataUnloaded( MDLCacheDataType_t type, MDLHandle_t handle ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Flags for flushing +//----------------------------------------------------------------------------- +enum MDLCacheFlush_t +{ + MDLCACHE_FLUSH_STUDIOHDR = 0x01, + MDLCACHE_FLUSH_STUDIOHWDATA = 0x02, + MDLCACHE_FLUSH_VCOLLIDE = 0x04, + MDLCACHE_FLUSH_ANIMBLOCK = 0x08, + MDLCACHE_FLUSH_VIRTUALMODEL = 0x10, + MDLCACHE_FLUSH_AUTOPLAY = 0x20, + MDLCACHE_FLUSH_VERTEXES = 0x40, + + MDLCACHE_FLUSH_IGNORELOCK = 0x80000000, + MDLCACHE_FLUSH_ALL = 0xFFFFFFFF +}; + +/* +#define MDLCACHE_INTERFACE_VERSION_4 "MDLCache004" + +namespace MDLCacheV4 +{ + +abstract_class IMDLCache : public IAppSystem +{ +public: + // Used to install callbacks for when data is loaded + unloaded + virtual void SetCacheNotify( IMDLCacheNotify *pNotify ) = 0; + // NOTE: This assumes the "GAME" path if you don't use + // the UNC method of specifying files. This will also increment + // the reference count of the MDL + virtual MDLHandle_t FindMDL( const char *pMDLRelativePath ) = 0; + + // Reference counting + virtual int AddRef( MDLHandle_t handle ) = 0; + virtual int Release( MDLHandle_t handle ) = 0; + + // Gets at the various data associated with a MDL + virtual studiohdr_t *GetStudioHdr( MDLHandle_t handle ) = 0; + virtual studiohwdata_t *GetHardwareData( MDLHandle_t handle ) = 0; + virtual vcollide_t *GetVCollide( MDLHandle_t handle ) = 0; + virtual unsigned char *GetAnimBlock( MDLHandle_t handle, int nBlock ) = 0; + virtual virtualmodel_t *GetVirtualModel( MDLHandle_t handle ) = 0; + virtual int GetAutoplayList( MDLHandle_t handle, unsigned short **pOut ) = 0; + virtual vertexFileHeader_t *GetVertexData( MDLHandle_t handle ) = 0; + + // Brings all data associated with an MDL into memory + virtual void TouchAllData( MDLHandle_t handle ) = 0; + + // Gets/sets user data associated with the MDL + virtual void SetUserData( MDLHandle_t handle, void* pData ) = 0; + virtual void *GetUserData( MDLHandle_t handle ) = 0; + + // Is this MDL using the error model? + virtual bool IsErrorModel( MDLHandle_t handle ) = 0; + + // Flushes the cache, force a full discard + virtual void Flush( int nFlushFlags = MDLCACHE_FLUSH_ALL ) = 0; + + // Flushes a particular model out of memory + virtual void Flush( MDLHandle_t handle, int nFlushFlags = MDLCACHE_FLUSH_ALL ) = 0; + + // Returns the name of the model (its relative path) + virtual const char *GetModelName( MDLHandle_t handle ) = 0; + + // faster access when you already have the studiohdr + virtual virtualmodel_t *GetVirtualModelFast( const studiohdr_t *pStudioHdr, MDLHandle_t handle ) = 0; + + // all cache entries that subsequently allocated or successfully checked + // are considered "locked" and will not be freed when additional memory is needed + virtual void BeginLock() = 0; + + // reset all protected blocks to normal + virtual void EndLock() = 0; + + // returns a pointer to a counter that is incremented every time the cache has been out of the locked state (EVIL) + virtual int *GetFrameUnlockCounterPtr() = 0; + + // Finish all pending async operations + virtual void FinishPendingLoads() = 0; +}; + + +} +*/ + +//----------------------------------------------------------------------------- +// The main MDL cacher +//----------------------------------------------------------------------------- +#define MDLCACHE_INTERFACE_VERSION "MDLCache004" + +abstract_class IMDLCache : public IAppSystem +{ +public: + // Used to install callbacks for when data is loaded + unloaded + // Returns the prior notify + virtual void SetCacheNotify( IMDLCacheNotify *pNotify ) = 0; + + // NOTE: This assumes the "GAME" path if you don't use + // the UNC method of specifying files. This will also increment + // the reference count of the MDL + virtual MDLHandle_t FindMDL( const char *pMDLRelativePath ) = 0; + + // Reference counting + virtual int AddRef( MDLHandle_t handle ) = 0; + virtual int Release( MDLHandle_t handle ) = 0; + virtual int GetRef( MDLHandle_t handle ) = 0; + + // Gets at the various data associated with a MDL + virtual studiohdr_t *GetStudioHdr( MDLHandle_t handle ) = 0; + virtual studiohwdata_t *GetHardwareData( MDLHandle_t handle ) = 0; + virtual vcollide_t *GetVCollide( MDLHandle_t handle ) = 0; + virtual unsigned char *GetAnimBlock( MDLHandle_t handle, int nBlock ) = 0; + virtual virtualmodel_t *GetVirtualModel( MDLHandle_t handle ) = 0; + virtual int GetAutoplayList( MDLHandle_t handle, unsigned short **pOut ) = 0; + virtual vertexFileHeader_t *GetVertexData( MDLHandle_t handle ) = 0; + + // Brings all data associated with an MDL into memory + virtual void TouchAllData( MDLHandle_t handle ) = 0; + + // Gets/sets user data associated with the MDL + virtual void SetUserData( MDLHandle_t handle, void* pData ) = 0; + virtual void *GetUserData( MDLHandle_t handle ) = 0; + + // Is this MDL using the error model? + virtual bool IsErrorModel( MDLHandle_t handle ) = 0; + + // Flushes the cache, force a full discard + virtual void Flush( MDLCacheFlush_t nFlushFlags = MDLCACHE_FLUSH_ALL ) = 0; + + // Flushes a particular model out of memory + virtual void Flush( MDLHandle_t handle, int nFlushFlags = MDLCACHE_FLUSH_ALL ) = 0; + + // Returns the name of the model (its relative path) + virtual const char *GetModelName( MDLHandle_t handle ) = 0; + + // faster access when you already have the studiohdr + virtual virtualmodel_t *GetVirtualModelFast( const studiohdr_t *pStudioHdr, MDLHandle_t handle ) = 0; + + // all cache entries that subsequently allocated or successfully checked + // are considered "locked" and will not be freed when additional memory is needed + virtual void BeginLock() = 0; + + // reset all protected blocks to normal + virtual void EndLock() = 0; + + // returns a pointer to a counter that is incremented every time the cache has been out of the locked state (EVIL) + virtual int *GetFrameUnlockCounterPtrOLD() = 0; + + // Finish all pending async operations + virtual void FinishPendingLoads() = 0; + + virtual vcollide_t *GetVCollideEx( MDLHandle_t handle, bool synchronousLoad = true ) = 0; + virtual bool GetVCollideSize( MDLHandle_t handle, int *pVCollideSize ) = 0; + + virtual bool GetAsyncLoad( MDLCacheDataType_t type ) = 0; + virtual bool SetAsyncLoad( MDLCacheDataType_t type, bool bAsync ) = 0; + + virtual void BeginMapLoad() = 0; + virtual void EndMapLoad() = 0; + virtual void MarkAsLoaded( MDLHandle_t handle ) = 0; + + virtual void InitPreloadData( bool rebuild ) = 0; + virtual void ShutdownPreloadData() = 0; + + virtual bool IsDataLoaded( MDLHandle_t handle, MDLCacheDataType_t type ) = 0; + + virtual int *GetFrameUnlockCounterPtr( MDLCacheDataType_t type ) = 0; + + virtual studiohdr_t *LockStudioHdr( MDLHandle_t handle ) = 0; + virtual void UnlockStudioHdr( MDLHandle_t handle ) = 0; + + virtual bool PreloadModel( MDLHandle_t handle ) = 0; + + // Hammer uses this. If a model has an error loading in GetStudioHdr, then it is flagged + // as an error model and any further attempts to load it will just get the error model. + // That is, until you call this function. Then it will load the correct model. + virtual void ResetErrorModelStatus( MDLHandle_t handle ) = 0; + + virtual void MarkFrame() = 0; +}; + + +//----------------------------------------------------------------------------- +// Critical section helper code +//----------------------------------------------------------------------------- +class CMDLCacheCriticalSection +{ +public: + CMDLCacheCriticalSection( IMDLCache *pCache ) : m_pCache( pCache ) + { + m_pCache->BeginLock(); + } + + ~CMDLCacheCriticalSection() + { + m_pCache->EndLock(); + } + +private: + IMDLCache *m_pCache; +}; + +#define MDCACHE_FINE_GRAINED 1 + +#if defined(MDCACHE_FINE_GRAINED) +#define MDLCACHE_CRITICAL_SECTION_( pCache ) CMDLCacheCriticalSection cacheCriticalSection(pCache) +#define MDLCACHE_COARSE_LOCK_( pCache ) ((void)(0)) +#elif defined(MDLCACHE_LEVEL_LOCKED) +#define MDLCACHE_CRITICAL_SECTION_( pCache ) ((void)(0)) +#define MDLCACHE_COARSE_LOCK_( pCache ) ((void)(0)) +#else +#define MDLCACHE_CRITICAL_SECTION_( pCache ) ((void)(0)) +#define MDLCACHE_COARSE_LOCK_( pCache ) CMDLCacheCriticalSection cacheCriticalSection(pCache) +#endif +#define MDLCACHE_CRITICAL_SECTION() MDLCACHE_CRITICAL_SECTION_(mdlcache) +#define MDLCACHE_COARSE_LOCK() MDLCACHE_COARSE_LOCK_(mdlcache) + +#endif // IMDLCACHE_H + diff --git a/sp/src/public/datamap.h b/sp/src/public/datamap.h new file mode 100644 index 00000000..34a1caf8 --- /dev/null +++ b/sp/src/public/datamap.h @@ -0,0 +1,455 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef DATAMAP_H +#define DATAMAP_H +#ifdef _WIN32 +#pragma once +#endif + +#ifndef VECTOR_H +#include "mathlib/vector.h" +#endif + +#include "tier1/utlvector.h" + +#include "tier0/memdbgon.h" + +// SINGLE_INHERITANCE restricts the size of CBaseEntity pointers-to-member-functions to 4 bytes +class SINGLE_INHERITANCE CBaseEntity; +struct inputdata_t; + +#define INVALID_TIME (FLT_MAX * -1.0) // Special value not rebased on save/load + +typedef enum _fieldtypes +{ + FIELD_VOID = 0, // No type or value + FIELD_FLOAT, // Any floating point value + FIELD_STRING, // A string ID (return from ALLOC_STRING) + FIELD_VECTOR, // Any vector, QAngle, or AngularImpulse + FIELD_QUATERNION, // A quaternion + FIELD_INTEGER, // Any integer or enum + FIELD_BOOLEAN, // boolean, implemented as an int, I may use this as a hint for compression + FIELD_SHORT, // 2 byte integer + FIELD_CHARACTER, // a byte + FIELD_COLOR32, // 8-bit per channel r,g,b,a (32bit color) + FIELD_EMBEDDED, // an embedded object with a datadesc, recursively traverse and embedded class/structure based on an additional typedescription + FIELD_CUSTOM, // special type that contains function pointers to it's read/write/parse functions + + FIELD_CLASSPTR, // CBaseEntity * + FIELD_EHANDLE, // Entity handle + FIELD_EDICT, // edict_t * + + FIELD_POSITION_VECTOR, // A world coordinate (these are fixed up across level transitions automagically) + FIELD_TIME, // a floating point time (these are fixed up automatically too!) + FIELD_TICK, // an integer tick count( fixed up similarly to time) + FIELD_MODELNAME, // Engine string that is a model name (needs precache) + FIELD_SOUNDNAME, // Engine string that is a sound name (needs precache) + + FIELD_INPUT, // a list of inputed data fields (all derived from CMultiInputVar) + FIELD_FUNCTION, // A class function pointer (Think, Use, etc) + + FIELD_VMATRIX, // a vmatrix (output coords are NOT worldspace) + + // NOTE: Use float arrays for local transformations that don't need to be fixed up. + FIELD_VMATRIX_WORLDSPACE,// A VMatrix that maps some local space to world space (translation is fixed up on level transitions) + FIELD_MATRIX3X4_WORLDSPACE, // matrix3x4_t that maps some local space to world space (translation is fixed up on level transitions) + + FIELD_INTERVAL, // a start and range floating point interval ( e.g., 3.2->3.6 == 3.2 and 0.4 ) + FIELD_MODELINDEX, // a model index + FIELD_MATERIALINDEX, // a material index (using the material precache string table) + + FIELD_VECTOR2D, // 2 floats + + FIELD_TYPECOUNT, // MUST BE LAST +} fieldtype_t; + + +//----------------------------------------------------------------------------- +// Field sizes... +//----------------------------------------------------------------------------- +template +class CDatamapFieldSizeDeducer +{ +public: + enum + { + SIZE = 0 + }; + + static int FieldSize( ) + { + return 0; + } +}; + +#define DECLARE_FIELD_SIZE( _fieldType, _fieldSize ) \ + template< > class CDatamapFieldSizeDeducer<_fieldType> { public: enum { SIZE = _fieldSize }; static int FieldSize() { return _fieldSize; } }; +#define FIELD_SIZE( _fieldType ) CDatamapFieldSizeDeducer<_fieldType>::SIZE +#define FIELD_BITS( _fieldType ) (FIELD_SIZE( _fieldType ) * 8) + +DECLARE_FIELD_SIZE( FIELD_FLOAT, sizeof(float) ) +DECLARE_FIELD_SIZE( FIELD_STRING, sizeof(int) ) +DECLARE_FIELD_SIZE( FIELD_VECTOR, 3 * sizeof(float) ) +DECLARE_FIELD_SIZE( FIELD_VECTOR2D, 2 * sizeof(float) ) +DECLARE_FIELD_SIZE( FIELD_QUATERNION, 4 * sizeof(float)) +DECLARE_FIELD_SIZE( FIELD_INTEGER, sizeof(int)) +DECLARE_FIELD_SIZE( FIELD_BOOLEAN, sizeof(char)) +DECLARE_FIELD_SIZE( FIELD_SHORT, sizeof(short)) +DECLARE_FIELD_SIZE( FIELD_CHARACTER, sizeof(char)) +DECLARE_FIELD_SIZE( FIELD_COLOR32, sizeof(int)) +DECLARE_FIELD_SIZE( FIELD_CLASSPTR, sizeof(int)) +DECLARE_FIELD_SIZE( FIELD_EHANDLE, sizeof(int)) +DECLARE_FIELD_SIZE( FIELD_EDICT, sizeof(int)) +DECLARE_FIELD_SIZE( FIELD_POSITION_VECTOR, 3 * sizeof(float)) +DECLARE_FIELD_SIZE( FIELD_TIME, sizeof(float)) +DECLARE_FIELD_SIZE( FIELD_TICK, sizeof(int)) +DECLARE_FIELD_SIZE( FIELD_MODELNAME, sizeof(int)) +DECLARE_FIELD_SIZE( FIELD_SOUNDNAME, sizeof(int)) +DECLARE_FIELD_SIZE( FIELD_INPUT, sizeof(int)) +#ifdef POSIX +// pointer to members under gnuc are 8bytes if you have a virtual func +DECLARE_FIELD_SIZE( FIELD_FUNCTION, sizeof(uint64)) +#else +DECLARE_FIELD_SIZE( FIELD_FUNCTION, sizeof(int *)) +#endif +DECLARE_FIELD_SIZE( FIELD_VMATRIX, 16 * sizeof(float)) +DECLARE_FIELD_SIZE( FIELD_VMATRIX_WORLDSPACE, 16 * sizeof(float)) +DECLARE_FIELD_SIZE( FIELD_MATRIX3X4_WORLDSPACE, 12 * sizeof(float)) +DECLARE_FIELD_SIZE( FIELD_INTERVAL, 2 * sizeof( float) ) // NOTE: Must match interval.h definition +DECLARE_FIELD_SIZE( FIELD_MODELINDEX, sizeof(int) ) +DECLARE_FIELD_SIZE( FIELD_MATERIALINDEX, sizeof(int) ) + + +#define ARRAYSIZE2D(p) (sizeof(p)/sizeof(p[0][0])) +#define SIZE_OF_ARRAY(p) _ARRAYSIZE(p) + +#define _FIELD(name,fieldtype,count,flags,mapname,tolerance) { fieldtype, #name, { offsetof(classNameTypedef, name), 0 }, count, flags, mapname, NULL, NULL, NULL, sizeof( ((classNameTypedef *)0)->name ), NULL, 0, tolerance } +#define DEFINE_FIELD_NULL { FIELD_VOID,0, {0,0},0,0,0,0,0,0} +#define DEFINE_FIELD(name,fieldtype) _FIELD(name, fieldtype, 1, FTYPEDESC_SAVE, NULL, 0 ) +#define DEFINE_KEYFIELD(name,fieldtype, mapname) _FIELD(name, fieldtype, 1, FTYPEDESC_KEY | FTYPEDESC_SAVE, mapname, 0 ) +#define DEFINE_KEYFIELD_NOT_SAVED(name,fieldtype, mapname)_FIELD(name, fieldtype, 1, FTYPEDESC_KEY, mapname, 0 ) +#define DEFINE_AUTO_ARRAY(name,fieldtype) _FIELD(name, fieldtype, SIZE_OF_ARRAY(((classNameTypedef *)0)->name), FTYPEDESC_SAVE, NULL, 0 ) +#define DEFINE_AUTO_ARRAY_KEYFIELD(name,fieldtype,mapname) _FIELD(name, fieldtype, SIZE_OF_ARRAY(((classNameTypedef *)0)->name), FTYPEDESC_SAVE, mapname, 0 ) +#define DEFINE_ARRAY(name,fieldtype, count) _FIELD(name, fieldtype, count, FTYPEDESC_SAVE, NULL, 0 ) +#define DEFINE_ENTITY_FIELD(name,fieldtype) _FIELD(edict_t, name, fieldtype, 1, FTYPEDESC_KEY | FTYPEDESC_SAVE, #name, 0 ) +#define DEFINE_ENTITY_GLOBAL_FIELD(name,fieldtype) _FIELD(edict_t, name, fieldtype, 1, FTYPEDESC_KEY | FTYPEDESC_SAVE | FTYPEDESC_GLOBAL, #name, 0 ) +#define DEFINE_GLOBAL_FIELD(name,fieldtype) _FIELD(name, fieldtype, 1, FTYPEDESC_GLOBAL | FTYPEDESC_SAVE, NULL, 0 ) +#define DEFINE_GLOBAL_KEYFIELD(name,fieldtype, mapname) _FIELD(name, fieldtype, 1, FTYPEDESC_GLOBAL | FTYPEDESC_KEY | FTYPEDESC_SAVE, mapname, 0 ) +#define DEFINE_CUSTOM_FIELD(name,datafuncs) { FIELD_CUSTOM, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE, NULL, datafuncs, NULL } +#define DEFINE_CUSTOM_KEYFIELD(name,datafuncs,mapname) { FIELD_CUSTOM, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE | FTYPEDESC_KEY, mapname, datafuncs, NULL } +#define DEFINE_AUTO_ARRAY2D(name,fieldtype) _FIELD(name, fieldtype, ARRAYSIZE2D(((classNameTypedef *)0)->name), FTYPEDESC_SAVE, NULL, 0 ) +// Used by byteswap datadescs +#define DEFINE_BITFIELD(name,fieldtype,bitcount) DEFINE_ARRAY(name,fieldtype,((bitcount+FIELD_BITS(fieldtype)-1)&~(FIELD_BITS(fieldtype)-1)) / FIELD_BITS(fieldtype) ) +#define DEFINE_INDEX(name,fieldtype) _FIELD(name, fieldtype, 1, FTYPEDESC_INDEX, NULL, 0 ) + +#define DEFINE_EMBEDDED( name ) \ + { FIELD_EMBEDDED, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name.m_DataMap), sizeof( ((classNameTypedef *)0)->name ), NULL, 0, 0.0f } + +#define DEFINE_EMBEDDED_OVERRIDE( name, overridetype ) \ + { FIELD_EMBEDDED, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE, NULL, NULL, NULL, &((overridetype *)0)->m_DataMap, sizeof( ((classNameTypedef *)0)->name ), NULL, 0, 0.0f } + +#define DEFINE_EMBEDDEDBYREF( name ) \ + { FIELD_EMBEDDED, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE | FTYPEDESC_PTR, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( *(((classNameTypedef *)0)->name) ), NULL, 0, 0.0f } + +#define DEFINE_EMBEDDED_ARRAY( name, count ) \ + { FIELD_EMBEDDED, #name, { offsetof(classNameTypedef, name), 0 }, count, FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( ((classNameTypedef *)0)->name[0] ), NULL, 0, 0.0f } + +#define DEFINE_EMBEDDED_AUTO_ARRAY( name ) \ + { FIELD_EMBEDDED, #name, { offsetof(classNameTypedef, name), 0 }, SIZE_OF_ARRAY( ((classNameTypedef *)0)->name ), FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( ((classNameTypedef *)0)->name[0] ), NULL, 0, 0.0f } + +#ifndef NO_ENTITY_PREDICTION + +#define DEFINE_PRED_TYPEDESCRIPTION( name, fieldtype ) \ + { FIELD_EMBEDDED, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE, NULL, NULL, NULL, &fieldtype::m_PredMap } + +#define DEFINE_PRED_TYPEDESCRIPTION_PTR( name, fieldtype ) \ + { FIELD_EMBEDDED, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE | FTYPEDESC_PTR, NULL, NULL, NULL, &fieldtype::m_PredMap } + +#else + +#define DEFINE_PRED_TYPEDESCRIPTION( name, fieldtype ) DEFINE_FIELD_NULL +#define DEFINE_PRED_TYPEDESCRIPTION_PTR( name, fieldtype ) DEFINE_FIELD_NULL + +#endif + +// Extensions to datamap.h macros for predicted entities only +#define DEFINE_PRED_FIELD(name,fieldtype, flags) _FIELD(name, fieldtype, 1, flags, NULL, 0.0f ) +#define DEFINE_PRED_ARRAY(name,fieldtype, count,flags) _FIELD(name, fieldtype, count, flags, NULL, 0.0f ) +#define DEFINE_FIELD_NAME(localname,netname,fieldtype) _FIELD(localname, fieldtype, 1, 0, #netname, 0.0f ) +// Predictable macros, which include a tolerance for floating point values... +#define DEFINE_PRED_FIELD_TOL(name,fieldtype, flags,tolerance) _FIELD(name, fieldtype, 1, flags, NULL, tolerance ) +#define DEFINE_PRED_ARRAY_TOL(name,fieldtype, count,flags,tolerance) _FIELD(name, fieldtype, count, flags, NULL, tolerance) +#define DEFINE_FIELD_NAME_TOL(localname,netname,fieldtolerance) _FIELD(localname, fieldtype, 1, 0, #netname, tolerance ) + +//#define DEFINE_DATA( name, fieldextname, flags ) _FIELD(name, fieldtype, 1, flags, extname ) + +// INPUTS +#define DEFINE_INPUT( name, fieldtype, inputname ) { fieldtype, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_INPUT | FTYPEDESC_SAVE | FTYPEDESC_KEY, inputname, NULL, NULL, NULL, sizeof( ((classNameTypedef *)0)->name ) } +#define DEFINE_INPUTFUNC( fieldtype, inputname, inputfunc ) { fieldtype, #inputfunc, { NULL, NULL }, 1, FTYPEDESC_INPUT, inputname, NULL, static_cast (&classNameTypedef::inputfunc) } + +// OUTPUTS +// the variable 'name' MUST BE derived from CBaseOutput +// we know the output type from the variable itself, so it doesn't need to be specified here +class ISaveRestoreOps; +extern ISaveRestoreOps *eventFuncs; +#define DEFINE_OUTPUT( name, outputname ) { FIELD_CUSTOM, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_OUTPUT | FTYPEDESC_SAVE | FTYPEDESC_KEY, outputname, eventFuncs } + +// replaces EXPORT table for portability and non-DLL based systems (xbox) +#define DEFINE_FUNCTION_RAW( function, func_type ) { FIELD_VOID, nameHolder.GenerateName(#function), { NULL, NULL }, 1, FTYPEDESC_FUNCTIONTABLE, NULL, NULL, (inputfunc_t)((func_type)(&classNameTypedef::function)) } +#define DEFINE_FUNCTION( function ) DEFINE_FUNCTION_RAW( function, inputfunc_t ) + + +#define FTYPEDESC_GLOBAL 0x0001 // This field is masked for global entity save/restore +#define FTYPEDESC_SAVE 0x0002 // This field is saved to disk +#define FTYPEDESC_KEY 0x0004 // This field can be requested and written to by string name at load time +#define FTYPEDESC_INPUT 0x0008 // This field can be written to by string name at run time, and a function called +#define FTYPEDESC_OUTPUT 0x0010 // This field propogates it's value to all targets whenever it changes +#define FTYPEDESC_FUNCTIONTABLE 0x0020 // This is a table entry for a member function pointer +#define FTYPEDESC_PTR 0x0040 // This field is a pointer, not an embedded object +#define FTYPEDESC_OVERRIDE 0x0080 // The field is an override for one in a base class (only used by prediction system for now) + +// Flags used by other systems (e.g., prediction system) +#define FTYPEDESC_INSENDTABLE 0x0100 // This field is present in a network SendTable +#define FTYPEDESC_PRIVATE 0x0200 // The field is local to the client or server only (not referenced by prediction code and not replicated by networking) +#define FTYPEDESC_NOERRORCHECK 0x0400 // The field is part of the prediction typedescription, but doesn't get compared when checking for errors + +#define FTYPEDESC_MODELINDEX 0x0800 // The field is a model index (used for debugging output) + +#define FTYPEDESC_INDEX 0x1000 // The field is an index into file data, used for byteswapping. + +// These flags apply to C_BasePlayer derived objects only +#define FTYPEDESC_VIEW_OTHER_PLAYER 0x2000 // By default you can only view fields on the local player (yourself), + // but if this is set, then we allow you to see fields on other players +#define FTYPEDESC_VIEW_OWN_TEAM 0x4000 // Only show this data if the player is on the same team as the local player +#define FTYPEDESC_VIEW_NEVER 0x8000 // Never show this field to anyone, even the local player (unusual) + +#define TD_MSECTOLERANCE 0.001f // This is a FIELD_FLOAT and should only be checked to be within 0.001 of the networked info + +struct typedescription_t; + + +class ISaveRestoreOps; + +// +// Function prototype for all input handlers. +// +typedef void (CBaseEntity::*inputfunc_t)(inputdata_t &data); + +struct datamap_t; +struct typedescription_t; + +enum +{ + TD_OFFSET_NORMAL = 0, + TD_OFFSET_PACKED = 1, + + // Must be last + TD_OFFSET_COUNT, +}; + +struct typedescription_t +{ + fieldtype_t fieldType; + const char *fieldName; + int fieldOffset[ TD_OFFSET_COUNT ]; // 0 == normal, 1 == packed offset + unsigned short fieldSize; + short flags; + // the name of the variable in the map/fgd data, or the name of the action + const char *externalName; + // pointer to the function set for save/restoring of custom data types + ISaveRestoreOps *pSaveRestoreOps; + // for associating function with string names + inputfunc_t inputFunc; + // For embedding additional datatables inside this one + datamap_t *td; + + // Stores the actual member variable size in bytes + int fieldSizeInBytes; + + // FTYPEDESC_OVERRIDE point to first baseclass instance if chains_validated has occurred + struct typedescription_t *override_field; + + // Used to track exclusion of baseclass fields + int override_count; + + // Tolerance for field errors for float fields + float fieldTolerance; +}; + + +//----------------------------------------------------------------------------- +// Purpose: stores the list of objects in the hierarchy +// used to iterate through an object's data descriptions +//----------------------------------------------------------------------------- +struct datamap_t +{ + typedescription_t *dataDesc; + int dataNumFields; + char const *dataClassName; + datamap_t *baseMap; + + bool chains_validated; + // Have the "packed" offsets been computed + bool packed_offsets_computed; + int packed_size; + +#if defined( _DEBUG ) + bool bValidityChecked; +#endif // _DEBUG +}; + + +//----------------------------------------------------------------------------- +// +// Macros used to implement datadescs +// +#define DECLARE_SIMPLE_DATADESC() \ + static datamap_t m_DataMap; \ + static datamap_t *GetBaseMap(); \ + template friend void DataMapAccess(T *, datamap_t **p); \ + template friend datamap_t *DataMapInit(T *); + +#define DECLARE_DATADESC() \ + DECLARE_SIMPLE_DATADESC() \ + virtual datamap_t *GetDataDescMap( void ); + +#define BEGIN_DATADESC( className ) \ + datamap_t className::m_DataMap = { 0, 0, #className, NULL }; \ + datamap_t *className::GetDataDescMap( void ) { return &m_DataMap; } \ + datamap_t *className::GetBaseMap() { datamap_t *pResult; DataMapAccess((BaseClass *)NULL, &pResult); return pResult; } \ + BEGIN_DATADESC_GUTS( className ) + +#define BEGIN_DATADESC_NO_BASE( className ) \ + datamap_t className::m_DataMap = { 0, 0, #className, NULL }; \ + datamap_t *className::GetDataDescMap( void ) { return &m_DataMap; } \ + datamap_t *className::GetBaseMap() { return NULL; } \ + BEGIN_DATADESC_GUTS( className ) + +#define BEGIN_SIMPLE_DATADESC( className ) \ + datamap_t className::m_DataMap = { 0, 0, #className, NULL }; \ + datamap_t *className::GetBaseMap() { return NULL; } \ + BEGIN_DATADESC_GUTS( className ) + +#define BEGIN_SIMPLE_DATADESC_( className, BaseClass ) \ + datamap_t className::m_DataMap = { 0, 0, #className, NULL }; \ + datamap_t *className::GetBaseMap() { datamap_t *pResult; DataMapAccess((BaseClass *)NULL, &pResult); return pResult; } \ + BEGIN_DATADESC_GUTS( className ) + +#define BEGIN_DATADESC_GUTS( className ) \ + template datamap_t *DataMapInit(T *); \ + template <> datamap_t *DataMapInit( className * ); \ + namespace className##_DataDescInit \ + { \ + datamap_t *g_DataMapHolder = DataMapInit( (className *)NULL ); /* This can/will be used for some clean up duties later */ \ + } \ + \ + template <> datamap_t *DataMapInit( className * ) \ + { \ + typedef className classNameTypedef; \ + static CDatadescGeneratedNameHolder nameHolder(#className); \ + className::m_DataMap.baseMap = className::GetBaseMap(); \ + static typedescription_t dataDesc[] = \ + { \ + { FIELD_VOID,0, {0,0},0,0,0,0,0,0}, /* so you can define "empty" tables */ + +#define END_DATADESC() \ + }; \ + \ + if ( sizeof( dataDesc ) > sizeof( dataDesc[0] ) ) \ + { \ + classNameTypedef::m_DataMap.dataNumFields = SIZE_OF_ARRAY( dataDesc ) - 1; \ + classNameTypedef::m_DataMap.dataDesc = &dataDesc[1]; \ + } \ + else \ + { \ + classNameTypedef::m_DataMap.dataNumFields = 1; \ + classNameTypedef::m_DataMap.dataDesc = dataDesc; \ + } \ + return &classNameTypedef::m_DataMap; \ + } + +// used for when there is no data description +#define IMPLEMENT_NULL_SIMPLE_DATADESC( derivedClass ) \ + BEGIN_SIMPLE_DATADESC( derivedClass ) \ + END_DATADESC() + +#define IMPLEMENT_NULL_SIMPLE_DATADESC_( derivedClass, baseClass ) \ + BEGIN_SIMPLE_DATADESC_( derivedClass, baseClass ) \ + END_DATADESC() + +#define IMPLEMENT_NULL_DATADESC( derivedClass ) \ + BEGIN_DATADESC( derivedClass ) \ + END_DATADESC() + +// helps get the offset of a bitfield +#define BEGIN_BITFIELD( name ) \ + union \ + { \ + char name; \ + struct \ + { + +#define END_BITFIELD() \ + }; \ + }; + +//----------------------------------------------------------------------------- +// Forward compatability with potential seperate byteswap datadescs + +#define DECLARE_BYTESWAP_DATADESC() DECLARE_SIMPLE_DATADESC() +#define BEGIN_BYTESWAP_DATADESC(name) BEGIN_SIMPLE_DATADESC(name) +#define BEGIN_BYTESWAP_DATADESC_(name,base) BEGIN_SIMPLE_DATADESC_(name,base) +#define END_BYTESWAP_DATADESC() END_DATADESC() + +//----------------------------------------------------------------------------- + +template +inline void DataMapAccess(T *ignored, datamap_t **p) +{ + *p = &T::m_DataMap; +} + +//----------------------------------------------------------------------------- + +class CDatadescGeneratedNameHolder +{ +public: + CDatadescGeneratedNameHolder( const char *pszBase ) + : m_pszBase(pszBase) + { + m_nLenBase = strlen( m_pszBase ); + } + + ~CDatadescGeneratedNameHolder() + { + for ( int i = 0; i < m_Names.Count(); i++ ) + { + delete m_Names[i]; + } + } + + const char *GenerateName( const char *pszIdentifier ) + { + char *pBuf = new char[m_nLenBase + strlen(pszIdentifier) + 1]; + strcpy( pBuf, m_pszBase ); + strcat( pBuf, pszIdentifier ); + m_Names.AddToTail( pBuf ); + return pBuf; + } + +private: + const char *m_pszBase; + size_t m_nLenBase; + CUtlVector m_Names; +}; + +//----------------------------------------------------------------------------- + +#include "tier0/memdbgoff.h" + +#endif // DATAMAP_H diff --git a/sp/src/public/datamodel/attributeflags.h b/sp/src/public/datamodel/attributeflags.h new file mode 100644 index 00000000..8cacdb4e --- /dev/null +++ b/sp/src/public/datamodel/attributeflags.h @@ -0,0 +1,35 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef ATTRIBUTEFLAGS_H +#define ATTRIBUTEFLAGS_H + +#ifdef _WIN32 +#pragma once +#endif + +enum +{ + // NOTE: The first 5 flags bits are reserved for attribute type + FATTRIB_TYPEMASK = 0x1F, + + FATTRIB_READONLY = (1<<5), // Don't allow editing value in editors + FATTRIB_DONTSAVE = (1<<6), // Don't persist to .dmx file + FATTRIB_DIRTY = (1<<7), // Indicates the attribute has been changed since the resolve phase + FATTRIB_HAS_CALLBACK = (1<<8), // Indicates that this will notify its owner and/or other elements when it changes + FATTRIB_EXTERNAL = (1<<9), // Indicates this attribute's data is externally owned (in a CDmElement somewhere) + FATTRIB_TOPOLOGICAL = (1<<10), // Indicates this attribute effects the scene's topology (ie it's an attribute name or element) + FATTRIB_MUSTCOPY = (1<<11), // parent element must make a new copy during CopyInto, even for shallow copy + FATTRIB_NEVERCOPY = (1<<12), // parent element shouldn't make a new copy during CopyInto, even for deep copy + FATTRIB_STANDARD = (1<<13), // This flag is set if it's a "standard" attribute, namely "name" + FATTRIB_USERDEFINED = (1<<14), // This flag is used to sort attributes in the element properties view. User defined flags come last. + FATTRIB_NODUPLICATES = (1<<15),// For element array types, disallows duplicate values from being inserted into the array. + FATTRIB_HAS_ARRAY_CALLBACK = (1<<16), // Indicates that this will notify its owner and/or other elements array elements changes. Note that when elements shift (say, inserting at head, or fast remove), callbacks are not executed for these elements. + FATTRIB_HAS_PRE_CALLBACK = (1<<17), // Indicates that this will notify its owner and/or other elements right before it changes + FATTRIB_OPERATOR_DIRTY = (1<<18),// Used and cleared only by operator phase of datamodel +}; + +#endif // ATTRIBUTEFLAGS_H diff --git a/sp/src/public/datamodel/dmattribute.h b/sp/src/public/datamodel/dmattribute.h new file mode 100644 index 00000000..e4441ff9 --- /dev/null +++ b/sp/src/public/datamodel/dmattribute.h @@ -0,0 +1,768 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef DMATTRIBUTE_H +#define DMATTRIBUTE_H +#ifdef _WIN32 +#pragma once +#endif + +#include "datamodel/attributeflags.h" +#include "datamodel/idatamodel.h" +#include "datamodel/dmattributetypes.h" +#include "datamodel/dmelement.h" +#include "datamodel/dmvar.h" +#include "tier1/utlhash.h" + +//----------------------------------------------------------------------------- +// Fast dynamic cast +//----------------------------------------------------------------------------- +template< class E > +inline E *CastElement( CDmElement *pElement ) +{ + if ( pElement && pElement->IsA( E::GetStaticTypeSymbol() ) ) + return static_cast< E* >( pElement ); + return NULL; +} + + +//----------------------------------------------------------------------------- +// type-safe element creation and accessor helpers - infers type name string from actual type +//----------------------------------------------------------------------------- +template< class E > +inline E *GetElement( DmElementHandle_t hElement ) +{ + CDmElement *pElement = g_pDataModel->GetElement( hElement ); + return CastElement< E >( pElement ); +} + +//----------------------------------------------------------------------------- +// Typesafe element creation + destruction +//----------------------------------------------------------------------------- +template< class E > +inline E *CreateElement( const char *pObjectName, DmFileId_t fileid = DMFILEID_INVALID, const DmObjectId_t *pObjectID = NULL ) +{ + return GetElement< E >( g_pDataModel->CreateElement( E::GetStaticTypeSymbol(), pObjectName, fileid, pObjectID ) ); +} + +template< class E > +inline E *CreateElement( const char *pElementType, const char *pObjectName, DmFileId_t fileid = DMFILEID_INVALID, const DmObjectId_t *pObjectID = NULL ) +{ + return GetElement< E >( g_pDataModel->CreateElement( pElementType, pObjectName, fileid, pObjectID ) ); +} + + +//----------------------------------------------------------------------------- +// Used for attribute change callbacks +//----------------------------------------------------------------------------- +typedef unsigned short DmMailingList_t; +enum +{ + DMMAILINGLIST_INVALID = (DmMailingList_t)~0 +}; + + +//----------------------------------------------------------------------------- +// Purpose: A general purpose pAttribute. Eventually will be extensible to arbitrary user types +//----------------------------------------------------------------------------- +class CDmAttribute +{ +public: + // Returns the type + DmAttributeType_t GetType() const; + const char *GetTypeString() const; + template< class T > bool IsA() const; + + // Returns the name. NOTE: The utlsymbol + // can be turned into a string by using g_pDataModel->String(); + const char *GetName() const; + UtlSymId_t GetNameSymbol() const; + void SetName( const char *newName ); + + // Gets the attribute value + // NOTE: GetValueUntyped is used with GetType() for use w/ SetValue( type, void* ) + template< class T > const T& GetValue() const; + template< class T > const T& GetValue( const T& defaultValue ) const; + const char *GetValueString() const; + template< class E > E *GetValueElement() const; + const void *GetValueUntyped() const; + + // Sets the attribute value + template< class T > void SetValue( const T &value ); + template< class E > void SetValue( E* pValue ); + void SetValue( const void *pValue, size_t nSize ); + + // Copies w/ type conversion (if possible) from another attribute + void SetValue( const CDmAttribute *pAttribute ); + void SetValue( CDmAttribute *pAttribute ); + void SetValue( DmAttributeType_t valueType, const void *pValue ); + + // Sets the attribute to its default value based on its type + void SetToDefaultValue(); + + // Convert to and from string + void SetValueFromString( const char *pValue ); + const char *GetValueAsString( char *pBuffer, size_t nBufLen ) const; + + // Used for element and element array attributes; it specifies which type of + // elements are valid to be referred to by this attribute + void SetElementTypeSymbol( UtlSymId_t typeSymbol ); + UtlSymId_t GetElementTypeSymbol() const; + + // Returns the next attribute + CDmAttribute *NextAttribute(); + const CDmAttribute *NextAttribute() const; + + // Returns the owner + CDmElement *GetOwner(); + + // Methods related to flags + void AddFlag( int flags ); + void RemoveFlag( int flags ); + void ClearFlags(); + int GetFlags() const; + bool IsFlagSet( int flags ) const; + + // Serialization + bool Serialize( CUtlBuffer &buf ) const; + bool Unserialize( CUtlBuffer &buf ); + + // Serialization of a single element. + // First version of UnserializeElement adds to tail if it worked + // Second version overwrites, but does not add, the element at the specified index + bool SerializeElement( int nElement, CUtlBuffer &buf ) const; + bool UnserializeElement( CUtlBuffer &buf ); + bool UnserializeElement( int nElement, CUtlBuffer &buf ); + + // Does this attribute serialize on multiple lines? + bool SerializesOnMultipleLines() const; + + // Get the attribute/create an attribute handle + DmAttributeHandle_t GetHandle( bool bCreate = true ); + + // Notify external elements upon change ( Calls OnAttributeChanged ) + // Pass false here to stop notification + void NotifyWhenChanged( DmElementHandle_t h, bool bNotify ); + + // estimate memory overhead + int EstimateMemoryUsage( TraversalDepth_t depth ) const; + +private: + // Class factory + static CDmAttribute *CreateAttribute( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName ); + static CDmAttribute *CreateExternalAttribute( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName, void *pExternalMemory ); + static void DestroyAttribute( CDmAttribute *pAttribute ); + + // Constructor, destructor + CDmAttribute( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName ); + CDmAttribute( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName, void *pMemory ); + ~CDmAttribute(); + + // Used when constructing CDmAttributes + void Init( CDmElement *pOwner, DmAttributeType_t type, const char *pAttributeName ); + + // Used when shutting down, indicates DmAttributeHandle_t referring to this are invalid + void InvalidateHandle(); + + // Used when shutting down, indicates no more change notifications will be sent to listening elements + void CleanupMailingList(); + + // Called when the attribute changes + void PreChanged(); + void OnChanged( bool bArrayCountChanged = false, bool bIsTopological = false ); + + // Is modification allowed in this phase? + bool ModificationAllowed() const; + + // Mark the attribute as being dirty + bool MarkDirty(); + + // Is the data inline in a containing element class? + bool IsDataInline() const; + + // Allocates, frees internal data storage + void CreateAttributeData(); + void DeleteAttributeData(); + + // Gets at the internal data storage + void* GetAttributeData(); + const void* GetAttributeData() const; + template < class T > typename CDmAttributeInfo< T >::StorageType_t* GetData(); + template < class T > const typename CDmAttributeInfo< T >::StorageType_t* GetData() const; + template < class T > typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* GetArrayData(); + template < class T > const typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* GetArrayData() const; + + // Used by CDmElement to manage the list of attributes it owns + CDmAttribute **GetNextAttributeRef(); + + // Implementational function used for memory consumption estimation computation + int EstimateMemoryUsageInternal( CUtlHash< DmElementHandle_t > &visited, TraversalDepth_t depth, int *pCategories ) const; + + // Called by elements after unserialization of their attributes is complete + void OnUnserializationFinished(); + + template< class T > bool IsTypeConvertable() const; + template< class T > bool ShouldModify( const T& src ); + template< class T > void CopyData( const T& src ); + template< class T > void CopyDataOut( T& dest ) const; + +private: + CDmAttribute *m_pNext; + void *m_pData; + CDmElement *m_pOwner; + int m_nFlags; + DmAttributeHandle_t m_Handle; + CUtlSymbol m_Name; + DmMailingList_t m_hMailingList; + + friend class CDmElement; + friend class CDmAttributeAccessor; + template< class T > friend class CDmrElementArray; + template< class E > friend class CDmrElementArrayConst; + template< class T > friend class CDmaArrayAccessor; + template< class T, class B > friend class CDmrDecorator; + template< class T, class B > friend class CDmrDecoratorConst; + template< class T > friend class CDmArrayAttributeOp; +}; + + +//----------------------------------------------------------------------------- +// Inline methods +//----------------------------------------------------------------------------- +inline DmAttributeType_t CDmAttribute::GetType() const +{ + return (DmAttributeType_t)( m_nFlags & FATTRIB_TYPEMASK ); +} + +template< class T > inline bool CDmAttribute::IsA() const +{ + return GetType() == CDmAttributeInfo< T >::AttributeType(); +} + +inline const char *CDmAttribute::GetName() const +{ + return g_pDataModel->GetString( m_Name ); +} + +inline UtlSymId_t CDmAttribute::GetNameSymbol() const +{ + return m_Name; +} + + +//----------------------------------------------------------------------------- +// Iteration +//----------------------------------------------------------------------------- +inline CDmAttribute *CDmAttribute::NextAttribute() +{ + return m_pNext; +} + +inline const CDmAttribute *CDmAttribute::NextAttribute() const +{ + return m_pNext; +} + + +//----------------------------------------------------------------------------- +// Returns the owner +//----------------------------------------------------------------------------- +inline CDmElement *CDmAttribute::GetOwner() +{ + return m_pOwner; +} + + +//----------------------------------------------------------------------------- +// Value getting methods +//----------------------------------------------------------------------------- +template< class T > +inline const T& CDmAttribute::GetValue( const T& defaultValue ) const +{ + if ( GetType() == ( DmAttributeType_t )( CDmAttributeInfo< T >::ATTRIBUTE_TYPE ) ) + return *reinterpret_cast< const T* >( m_pData ); + + if ( IsTypeConvertable< T >() ) + { + static T tempVal; + CopyDataOut( tempVal ); + return tempVal; + } + + Assert( 0 ); + return defaultValue; +} + +template< class T > +inline const T& CDmAttribute::GetValue() const +{ + static CDmaVar< T > defaultVal; + return GetValue( defaultVal.Get() ); +} + +inline const char *CDmAttribute::GetValueString() const +{ + Assert( GetType() == AT_STRING ); + if ( GetType() != AT_STRING ) + return NULL; + + return GetValue< CUtlString >(); +} + +// used with GetType() for use w/ SetValue( type, void* ) +inline const void* CDmAttribute::GetValueUntyped() const +{ + return m_pData; +} + +template< class E > +inline E* CDmAttribute::GetValueElement() const +{ + Assert( GetType() == AT_ELEMENT ); + if ( GetType() == AT_ELEMENT ) + return GetElement( this->GetValue< DmElementHandle_t >() ); + return NULL; +} + + +//----------------------------------------------------------------------------- +// Value setting methods +//----------------------------------------------------------------------------- +template< class E > +inline void CDmAttribute::SetValue( E* pValue ) +{ + Assert( GetType() == AT_ELEMENT ); + if ( GetType() == AT_ELEMENT ) + { + SetValue( pValue ? pValue->GetHandle() : DMELEMENT_HANDLE_INVALID ); + } +} + +template<> +inline void CDmAttribute::SetValue( const char *pValue ) +{ + int nLen = pValue ? Q_strlen( pValue ) + 1 : 0; + CUtlString str( pValue, nLen ); + return SetValue( str ); +} + +template<> +inline void CDmAttribute::SetValue( char *pValue ) +{ + return SetValue( (const char *)pValue ); +} + +inline void CDmAttribute::SetValue( const void *pValue, size_t nSize ) +{ + CUtlBinaryBlock buf( pValue, nSize ); + return SetValue( buf ); +} + + +//----------------------------------------------------------------------------- +// Methods related to flags +//----------------------------------------------------------------------------- +inline void CDmAttribute::AddFlag( int nFlags ) +{ + m_nFlags |= nFlags; +} + +inline void CDmAttribute::RemoveFlag( int nFlags ) +{ + m_nFlags &= ~nFlags; +} + +inline void CDmAttribute::ClearFlags() +{ + m_nFlags = 0; +} + +inline int CDmAttribute::GetFlags() const +{ + return m_nFlags; +} + +inline bool CDmAttribute::IsFlagSet( int nFlags ) const +{ + return ( nFlags & m_nFlags ) ? true : false; +} + +inline bool CDmAttribute::IsDataInline() const +{ + return !IsFlagSet(FATTRIB_EXTERNAL); +} + + +//----------------------------------------------------------------------------- +// Gets at the internal data storage +//----------------------------------------------------------------------------- +inline void* CDmAttribute::GetAttributeData() +{ + return m_pData; +} + +inline const void* CDmAttribute::GetAttributeData() const +{ + return m_pData; +} + +template < class T > +inline typename CDmAttributeInfo< T >::StorageType_t* CDmAttribute::GetData() +{ + return ( typename CDmAttributeInfo< T >::StorageType_t* )m_pData; +} + +template < class T > +inline typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* CDmAttribute::GetArrayData() +{ + return ( typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* )m_pData; +} + +template < class T > +inline const typename CDmAttributeInfo< T >::StorageType_t* CDmAttribute::GetData() const +{ + return ( const typename CDmAttributeInfo< T >::StorageType_t* )m_pData; +} + +template < class T > +inline const typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* CDmAttribute::GetArrayData() const +{ + return ( const typename CDmAttributeInfo< CUtlVector< T > >::StorageType_t* )m_pData; +} + + +//----------------------------------------------------------------------------- +// Used by CDmElement to manage the list of attributes it owns +//----------------------------------------------------------------------------- +inline CDmAttribute **CDmAttribute::GetNextAttributeRef() +{ + return &m_pNext; +} + + +//----------------------------------------------------------------------------- +// helper function for determining which attributes/elements to traverse during copy/find/save/etc. +//----------------------------------------------------------------------------- +inline bool ShouldTraverse( const CDmAttribute *pAttr, TraversalDepth_t depth ) +{ + switch ( depth ) + { + case TD_NONE: + return false; + + case TD_SHALLOW: + if ( !pAttr->IsFlagSet( FATTRIB_MUSTCOPY ) ) + return false; + // fall-through intentional + case TD_DEEP: + if ( pAttr->IsFlagSet( FATTRIB_NEVERCOPY ) ) + return false; + // fall-through intentional + case TD_ALL: + return true; + } + + Assert( 0 ); + return false; +} + + +//----------------------------------------------------------------------------- +// Gets attributes +//----------------------------------------------------------------------------- +inline CDmAttribute *CDmElement::GetAttribute( const char *pAttributeName, DmAttributeType_t type ) +{ + CDmAttribute *pAttribute = FindAttribute( pAttributeName ); + if ( ( type != AT_UNKNOWN ) && pAttribute && ( pAttribute->GetType() != type ) ) + return NULL; + return pAttribute; +} + +inline const CDmAttribute *CDmElement::GetAttribute( const char *pAttributeName, DmAttributeType_t type ) const +{ + CDmAttribute *pAttribute = FindAttribute( pAttributeName ); + if ( ( type != AT_UNKNOWN ) && pAttribute && ( pAttribute->GetType() != type ) ) + return NULL; + return pAttribute; +} + + +//----------------------------------------------------------------------------- +// AddAttribute calls +//----------------------------------------------------------------------------- +inline CDmAttribute *CDmElement::AddAttribute( const char *pAttributeName, DmAttributeType_t type ) +{ + CDmAttribute *pAttribute = FindAttribute( pAttributeName ); + if ( pAttribute ) + return ( pAttribute->GetType() == type ) ? pAttribute : NULL; + pAttribute = CreateAttribute( pAttributeName, type ); + return pAttribute; +} + +template< class E > inline CDmAttribute *CDmElement::AddAttributeElement( const char *pAttributeName ) +{ + CDmAttribute *pAttribute = AddAttribute( pAttributeName, AT_ELEMENT ); + if ( !pAttribute ) + return NULL; + + // FIXME: If the attribute exists but has a different element type symbol, should we complain? + pAttribute->SetElementTypeSymbol( E::GetStaticTypeSymbol() ); + return pAttribute; +} + +template< class E > inline CDmAttribute *CDmElement::AddAttributeElementArray( const char *pAttributeName ) +{ + CDmAttribute *pAttribute = AddAttribute( pAttributeName, AT_ELEMENT_ARRAY ); + if ( !pAttribute ) + return NULL; + + // FIXME: If the attribute exists but has a different element type symbol, should we complain? + pAttribute->SetElementTypeSymbol( E::GetStaticTypeSymbol() ); + return pAttribute; +} + +//----------------------------------------------------------------------------- +// GetValue methods +//----------------------------------------------------------------------------- + +template< class T > +inline const T& CDmElement::GetValue( const char *pAttributeName ) const +{ + static CDmaVar defaultVal; + return GetValue( pAttributeName, defaultVal.Get() ); +} + +inline const char *CDmElement::GetValueString( const char *pAttributeName ) const +{ + return GetValue( pAttributeName ).Get(); +} + +template< class E > +inline E* CDmElement::GetValueElement( const char *pAttributeName ) const +{ + DmElementHandle_t h = GetValue< DmElementHandle_t >( pAttributeName ); + return GetElement( h ); +} + + +template< class T > +inline const T& CDmElement::GetValue( const char *pAttributeName, const T& defaultVal ) const +{ + const CDmAttribute *pAttribute = FindAttribute( pAttributeName ); + if ( pAttribute != NULL ) + return pAttribute->GetValue(); + return defaultVal; +} + +//----------------------------------------------------------------------------- +// SetValue methods +//----------------------------------------------------------------------------- +template< class T > +inline CDmAttribute* CDmElement::SetValue( const char *pAttributeName, const T& value ) +{ + CDmAttribute *pAttribute = FindAttribute( pAttributeName ); + if ( !pAttribute ) + { + pAttribute = CreateAttribute( pAttributeName, CDmAttributeInfo::AttributeType() ); + } + if ( pAttribute ) + { + pAttribute->SetValue( value ); + return pAttribute; + } + return NULL; +} + +template< class E > +inline CDmAttribute* CDmElement::SetValue( const char *pAttributeName, E* pElement ) +{ + DmElementHandle_t hElement = pElement ? pElement->GetHandle() : DMELEMENT_HANDLE_INVALID; + return SetValue( pAttributeName, hElement ); +} + +template<> +inline CDmAttribute* CDmElement::SetValue( const char *pAttributeName, const char *pValue ) +{ + int nLen = pValue ? Q_strlen( pValue ) + 1 : 0; + CUtlString str( pValue, nLen ); + return SetValue( pAttributeName, str ); +} + +template<> +inline CDmAttribute* CDmElement::SetValue( const char *pAttributeName, char *pValue ) +{ + return SetValue( pAttributeName, (const char *)pValue ); +} + +inline CDmAttribute* CDmElement::SetValue( const char *pAttributeName, const void *pValue, size_t nSize ) +{ + CUtlBinaryBlock buf( pValue, nSize ); + return SetValue( pAttributeName, buf ); +} + + +//----------------------------------------------------------------------------- +// AddValue methods( set value if not found ) +//----------------------------------------------------------------------------- +template< class T > +inline CDmAttribute* CDmElement::InitValue( const char *pAttributeName, const T& value ) +{ + CDmAttribute *pAttribute = GetAttribute( pAttributeName ); + if ( !pAttribute ) + return SetValue( pAttributeName, value ); + return pAttribute; +} + +template< class E > +inline CDmAttribute* CDmElement::InitValue( const char *pAttributeName, E* pElement ) +{ + DmElementHandle_t hElement = pElement ? pElement->GetHandle() : DMELEMENT_HANDLE_INVALID; + return InitValue( pAttributeName, hElement ); +} + +inline CDmAttribute* CDmElement::InitValue( const char *pAttributeName, const void *pValue, size_t size ) +{ + CDmAttribute *pAttribute = GetAttribute( pAttributeName ); + if ( !pAttribute ) + return SetValue( pAttributeName, pValue, size ); + return pAttribute; +} + +template< class T > +T *FindReferringElement( CDmElement *pElement, UtlSymId_t symAttrName, bool bMustBeInSameFile = true ) +{ + DmAttributeReferenceIterator_t i = g_pDataModel->FirstAttributeReferencingElement( pElement->GetHandle() ); + while ( i != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID ) + { + CDmAttribute *pAttribute = g_pDataModel->GetAttribute( i ); + CDmElement *pDmeParent = pAttribute->GetOwner(); + if ( pDmeParent && pAttribute->GetNameSymbol() == symAttrName ) + { + T *pParent = CastElement< T >( pDmeParent ); + if ( pParent ) + { + if ( !bMustBeInSameFile || ( pParent->GetFileId() == pElement->GetFileId() ) ) + return pParent; + } + } + i = g_pDataModel->NextAttributeReferencingElement( i ); + } + + return NULL; +} + +template< class T > +T *FindAncestorReferencingElement( CDmElement *target ) +{ + if ( !target ) + return NULL; + + for ( DmAttributeReferenceIterator_t it = g_pDataModel->FirstAttributeReferencingElement( target->GetHandle() ); + it != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID; + it = g_pDataModel->NextAttributeReferencingElement( it ) ) + { + CDmAttribute *attr = g_pDataModel->GetAttribute( it ); + Assert( attr ); + CDmElement *element = attr->GetOwner(); + Assert( element ); + if ( !element ) + continue; + T *t = CastElement< T >( element ); + if ( !t ) + continue; + + return t; + } + return NULL; +} + +template< class T > +T *FindAncestorReferencingElement_R_Impl( CUtlRBTree< CDmElement * >& visited, CDmElement *check ) +{ + if ( visited.Find( check ) != visited.InvalidIndex() ) + return NULL; + + visited.Insert( check ); + + // Pass one, see if it's in this ancestor list + DmAttributeReferenceIterator_t it; + for ( it = g_pDataModel->FirstAttributeReferencingElement( check->GetHandle() ); + it != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID; + it = g_pDataModel->NextAttributeReferencingElement( it ) ) + { + CDmAttribute *attr = g_pDataModel->GetAttribute( it ); + Assert( attr ); + CDmElement *element = attr->GetOwner(); + Assert( element ); + if ( !element ) + continue; + T *t = CastElement< T >( element ); + if ( !t ) + continue; + + return t; + } + + for ( it = g_pDataModel->FirstAttributeReferencingElement( check->GetHandle() ); + it != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID; + it = g_pDataModel->NextAttributeReferencingElement( it ) ) + { + CDmAttribute *attr = g_pDataModel->GetAttribute( it ); + Assert( attr ); + CDmElement *element = attr->GetOwner(); + Assert( element ); + if ( !element ) + continue; + + T *found = FindAncestorReferencingElement_R_Impl< T >( visited, element ); + if ( found ) + return found; + } + return NULL; +} + + +template< class T > +void FindAncestorsReferencingElement( CDmElement *target, CUtlVector< T* >& list ) +{ + if ( !target ) + return; + + list.RemoveAll(); + for ( DmAttributeReferenceIterator_t it = g_pDataModel->FirstAttributeReferencingElement( target->GetHandle() ); + it != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID; + it = g_pDataModel->NextAttributeReferencingElement( it ) ) + { + CDmAttribute *attr = g_pDataModel->GetAttribute( it ); + Assert( attr ); + CDmElement *element = attr->GetOwner(); + Assert( element ); + if ( !element ) + continue; + T* t = CastElement< T >( element ); + if ( !t ) + continue; + + if ( list.Find( t ) != list.InvalidIndex() ) + continue; + + list.AddToTail( t ); + } +} + + +template< class T > +T *FindAncestorReferencingElement_R( CDmElement *target ) +{ + if ( !target ) + return NULL; + + CUtlRBTree< CDmElement * > visited( 0, 0, DefLessFunc( CDmElement * ) ); + return FindAncestorReferencingElement_R_Impl< T >( visited, target ); +} + + +#endif // DMATTRIBUTE_H diff --git a/sp/src/public/datamodel/dmattributetypes.h b/sp/src/public/datamodel/dmattributetypes.h new file mode 100644 index 00000000..fbff3ef7 --- /dev/null +++ b/sp/src/public/datamodel/dmattributetypes.h @@ -0,0 +1,316 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef DMATTRIBUTETYPES_H +#define DMATTRIBUTETYPES_H +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/utlvector.h" +#include "tier1/utlstring.h" +#include "tier1/uniqueid.h" +#include "Color.h" +#include "mathlib/vector2d.h" +#include "mathlib/vector.h" +#include "mathlib/vector4d.h" +#include "mathlib/vmatrix.h" +#include "datamodel/dmelementhandle.h" +#include "tier1/utlsymbol.h" + + +//----------------------------------------------------------------------------- +// Object Id +//----------------------------------------------------------------------------- +typedef UniqueId_t DmObjectId_t; + + +//----------------------------------------------------------------------------- +// Necessary for template specialization for AT_UNKNOWN +//----------------------------------------------------------------------------- +struct DmUnknownAttribute_t +{ + bool operator==( const DmUnknownAttribute_t& src ) const { return true; } +}; + + +//----------------------------------------------------------------------------- +// Element array +//----------------------------------------------------------------------------- +struct DmElementAttribute_t +{ + DmElementAttribute_t() : m_ElementType( UTL_INVAL_SYMBOL ) {} + + operator DmElementHandle_t&() { return m_Handle; } + operator const DmElementHandle_t&() const { return m_Handle; } + + DmElementHandle_t m_Handle; + UtlSymId_t m_ElementType; +}; + +struct DmElementArray_t : public CUtlVector< DmElementHandle_t > +{ + DmElementArray_t() : m_ElementType( UTL_INVAL_SYMBOL ) {} + + UtlSymId_t m_ElementType; +}; + + +//----------------------------------------------------------------------------- +// Attribute chunk type enum +//----------------------------------------------------------------------------- +enum DmAttributeType_t +{ + AT_UNKNOWN = 0, + + AT_FIRST_VALUE_TYPE, + + AT_ELEMENT = AT_FIRST_VALUE_TYPE, + AT_INT, + AT_FLOAT, + AT_BOOL, + AT_STRING, + AT_VOID, + AT_OBJECTID, + AT_COLOR, //rgba + AT_VECTOR2, + AT_VECTOR3, + AT_VECTOR4, + AT_QANGLE, + AT_QUATERNION, + AT_VMATRIX, + + AT_FIRST_ARRAY_TYPE, + + AT_ELEMENT_ARRAY = AT_FIRST_ARRAY_TYPE, + AT_INT_ARRAY, + AT_FLOAT_ARRAY, + AT_BOOL_ARRAY, + AT_STRING_ARRAY, + AT_VOID_ARRAY, + AT_OBJECTID_ARRAY, + AT_COLOR_ARRAY, + AT_VECTOR2_ARRAY, + AT_VECTOR3_ARRAY, + AT_VECTOR4_ARRAY, + AT_QANGLE_ARRAY, + AT_QUATERNION_ARRAY, + AT_VMATRIX_ARRAY, + AT_TYPE_COUNT, +}; + +const char *GetTypeString( DmAttributeType_t type ); + +inline bool IsValueType( DmAttributeType_t type ) +{ + return type >= AT_FIRST_VALUE_TYPE && type < AT_FIRST_ARRAY_TYPE; +} + +inline bool IsArrayType( DmAttributeType_t type ) +{ + return type >= AT_FIRST_ARRAY_TYPE && type < AT_TYPE_COUNT; +} + +inline bool IsTopological( DmAttributeType_t type ) +{ + return type == AT_ELEMENT || type == AT_ELEMENT_ARRAY; +} + +inline DmAttributeType_t ValueTypeToArrayType( DmAttributeType_t type ) +{ + Assert( IsValueType( type ) ); + return ( DmAttributeType_t )( ( type - AT_FIRST_VALUE_TYPE ) + AT_FIRST_ARRAY_TYPE ); +} + +inline DmAttributeType_t ArrayTypeToValueType( DmAttributeType_t type ) +{ + Assert( IsArrayType( type ) ); + return ( DmAttributeType_t )( ( type - AT_FIRST_ARRAY_TYPE ) + AT_FIRST_VALUE_TYPE ); +} + +inline int NumComponents( DmAttributeType_t type ) +{ + switch ( type ) + { + case AT_BOOL: + case AT_INT: + case AT_FLOAT: + return 1; + + case AT_VECTOR2: + return 2; + + case AT_VECTOR3: + case AT_QANGLE: + return 3; + + case AT_COLOR: //rgba + case AT_VECTOR4: + case AT_QUATERNION: + return 4; + + case AT_VMATRIX: + return 16; + + case AT_ELEMENT: + case AT_STRING: + case AT_VOID: + case AT_OBJECTID: + default: + return 0; + } +} + +template< typename T > +inline float GetComponent( const T &value, int i ) +{ + Assert( 0 ); + return 0.0f; +} + +template <> inline float GetComponent( const bool &value, int i ) +{ + Assert( i == 0 ); + return value ? 1.0f : 0.0f; +} + +template <> inline float GetComponent( const int &value, int i ) +{ + Assert( i == 0 ); + return float( value ); +} + +template <> inline float GetComponent( const float &value, int i ) +{ + Assert( i == 0 ); + return value; +} + +template <> inline float GetComponent( const Vector2D &value, int i ) +{ + return value[ i ]; +} + +template <> inline float GetComponent( const Vector &value, int i ) +{ + return value[ i ]; +} + +template <> inline float GetComponent( const QAngle &value, int i ) +{ + return value[ i ]; +} + +template <> inline float GetComponent( const Color &value, int i ) +{ + return value[ i ]; +} + +template <> inline float GetComponent( const Vector4D &value, int i ) +{ + return value[ i ]; +} + +template <> inline float GetComponent( const Quaternion &value, int i ) +{ + return value[ i ]; +} + +template <> inline float GetComponent( const VMatrix &value, int i ) +{ + return value.Base()[ i ]; +} + + +//----------------------------------------------------------------------------- +// Attribute info... +//----------------------------------------------------------------------------- +template +class CDmAttributeInfo +{ +public: + enum { ATTRIBUTE_TYPE = AT_UNKNOWN }; + + typedef T StorageType_t; + + static DmAttributeType_t AttributeType() + { + return AT_UNKNOWN; + } + + static const char *AttributeTypeName() + { + return "unknown"; + } + + static void SetDefaultValue( T& value ) + { + Assert(0); + } +}; + + +#define DECLARE_ATTRIBUTE_TYPE_INTERNAL( _className, _storageType, _attributeType, _attributeName, _defaultSetStatement ) \ + template< > class CDmAttributeInfo< _className > \ + { \ + public: \ + enum { ATTRIBUTE_TYPE = _attributeType }; \ + typedef _storageType StorageType_t; \ + static DmAttributeType_t AttributeType() { return _attributeType; } \ + static const char *AttributeTypeName() { return _attributeName; } \ + static void SetDefaultValue( _className& value ) { _defaultSetStatement } \ + }; \ + +#define DECLARE_ATTRIBUTE_ARRAY_TYPE_INTERNAL( _className, _storageType, _attributeType, _attributeName ) \ + template< > class CDmAttributeInfo< CUtlVector<_className> > \ + { \ + public: \ + enum { ATTRIBUTE_TYPE = _attributeType }; \ + typedef _storageType StorageType_t; \ + static DmAttributeType_t AttributeType() { return _attributeType; } \ + static const char *AttributeTypeName() { return _attributeName; } \ + static void SetDefaultValue( CUtlVector< _className >& value ) { value.RemoveAll(); } \ + }; \ + +#define DECLARE_ATTRIBUTE_TYPE( _className, _attributeType, _attributeName, _defaultSetStatement ) \ + DECLARE_ATTRIBUTE_TYPE_INTERNAL( _className, _className, _attributeType, _attributeName, _defaultSetStatement ) + +#define DECLARE_ATTRIBUTE_ARRAY_TYPE( _className, _attributeType, _attributeName )\ + DECLARE_ATTRIBUTE_ARRAY_TYPE_INTERNAL( _className, CUtlVector< _className >, _attributeType, _attributeName ) + +// NOTE: If you add an attribute type here, also add it to the list of DEFINE_ATTRIBUTE_TYPES in dmattribute.cpp +DECLARE_ATTRIBUTE_TYPE( int, AT_INT, "int", value = 0; ) +DECLARE_ATTRIBUTE_TYPE( float, AT_FLOAT, "float", value = 0.0f; ) +DECLARE_ATTRIBUTE_TYPE( bool, AT_BOOL, "bool", value = false; ) +DECLARE_ATTRIBUTE_TYPE( Color, AT_COLOR, "color", value.SetColor( 0, 0, 0, 255 ); ) +DECLARE_ATTRIBUTE_TYPE( Vector2D, AT_VECTOR2, "vector2", value.Init( 0.0f, 0.0f ); ) +DECLARE_ATTRIBUTE_TYPE( Vector, AT_VECTOR3, "vector3", value.Init( 0.0f, 0.0f, 0.0f ); ) +DECLARE_ATTRIBUTE_TYPE( Vector4D, AT_VECTOR4, "vector4", value.Init( 0.0f, 0.0f, 0.0f, 0.0f ); ) +DECLARE_ATTRIBUTE_TYPE( QAngle, AT_QANGLE, "qangle", value.Init( 0.0f, 0.0f, 0.0f ); ) +DECLARE_ATTRIBUTE_TYPE( Quaternion, AT_QUATERNION, "quaternion", value.Init( 0.0f, 0.0f, 0.0f, 1.0f ); ) +DECLARE_ATTRIBUTE_TYPE( VMatrix, AT_VMATRIX, "matrix", MatrixSetIdentity( value ); ) +DECLARE_ATTRIBUTE_TYPE( CUtlString, AT_STRING, "string", value.Set( NULL ); ) +DECLARE_ATTRIBUTE_TYPE( CUtlBinaryBlock, AT_VOID, "binary", value.Set( NULL, 0 ); ) +DECLARE_ATTRIBUTE_TYPE( DmObjectId_t, AT_OBJECTID, "elementid", InvalidateUniqueId( &value ); ) +DECLARE_ATTRIBUTE_TYPE_INTERNAL( DmElementHandle_t, DmElementAttribute_t, AT_ELEMENT, "element", value = DMELEMENT_HANDLE_INVALID; ) + +DECLARE_ATTRIBUTE_ARRAY_TYPE( int, AT_INT_ARRAY, "int_array" ) +DECLARE_ATTRIBUTE_ARRAY_TYPE( float, AT_FLOAT_ARRAY, "float_array" ) +DECLARE_ATTRIBUTE_ARRAY_TYPE( bool, AT_BOOL_ARRAY, "bool_array" ) +DECLARE_ATTRIBUTE_ARRAY_TYPE( Color, AT_COLOR_ARRAY, "color_array" ) +DECLARE_ATTRIBUTE_ARRAY_TYPE( Vector2D, AT_VECTOR2_ARRAY, "vector2_array" ) +DECLARE_ATTRIBUTE_ARRAY_TYPE( Vector, AT_VECTOR3_ARRAY, "vector3_array" ) +DECLARE_ATTRIBUTE_ARRAY_TYPE( Vector4D, AT_VECTOR4_ARRAY, "vector4_array" ) +DECLARE_ATTRIBUTE_ARRAY_TYPE( QAngle, AT_QANGLE_ARRAY, "qangle_array" ) +DECLARE_ATTRIBUTE_ARRAY_TYPE( Quaternion, AT_QUATERNION_ARRAY, "quaternion_array" ) +DECLARE_ATTRIBUTE_ARRAY_TYPE( VMatrix, AT_VMATRIX_ARRAY, "matrix_array" ) +DECLARE_ATTRIBUTE_ARRAY_TYPE( CUtlString, AT_STRING_ARRAY, "string_array" ) +DECLARE_ATTRIBUTE_ARRAY_TYPE( CUtlBinaryBlock, AT_VOID_ARRAY, "binary_array" ) +DECLARE_ATTRIBUTE_ARRAY_TYPE( DmObjectId_t, AT_OBJECTID_ARRAY, "elementid_array" ) +DECLARE_ATTRIBUTE_ARRAY_TYPE_INTERNAL( DmElementHandle_t, DmElementArray_t, AT_ELEMENT_ARRAY, "element_array" ) + + +#endif // DMATTRIBUTETYPES_H diff --git a/sp/src/public/datamodel/dmattributevar.h b/sp/src/public/datamodel/dmattributevar.h new file mode 100644 index 00000000..4bf2a23a --- /dev/null +++ b/sp/src/public/datamodel/dmattributevar.h @@ -0,0 +1,1481 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef DMATTRIBUTEVAR_H +#define DMATTRIBUTEVAR_H +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/utlvector.h" +#include "Color.h" +#include "mathlib/vector2d.h" +#include "mathlib/vector.h" +#include "mathlib/vector4d.h" +#include "mathlib/vmatrix.h" +#include "datamodel/dmelement.h" +#include "datamodel/dmattribute.h" + +template< class C, bool D > class CDmeHandle; + +//----------------------------------------------------------------------------- +// Specialization for color +//----------------------------------------------------------------------------- +class CDmaColor : public CDmaVar< Color > +{ +public: + // Set methods + void SetColor( int r, int g, int b, int a = 0 ); + void SetRed( int r ); + void SetGreen( int g ); + void SetBlue( int b ); + void SetAlpha( int a ); + + // Sets the color as a 32-bit integer + void SetRawColor( int color ); + + // Get methods + unsigned char r() const; + unsigned char g() const; + unsigned char b() const; + unsigned char a() const; + const unsigned char &operator[]( int index ) const; +}; + + +//----------------------------------------------------------------------------- +// Specialization for object ids +//----------------------------------------------------------------------------- +class CDmaObjectId : public CDmaVar< DmObjectId_t > +{ +public: + void CreateObjectId( ); + void Invalidate( ); + bool IsValid( ) const; + bool IsEqual( const DmObjectId_t &id ) const; + const DmObjectId_t &operator=( const DmObjectId_t& src ); + const CDmaObjectId& operator=( const CDmaObjectId& src ); + const DmObjectId_t& Set( const DmObjectId_t &src ); +}; + + +//----------------------------------------------------------------------------- +// Specialization for binary block +//----------------------------------------------------------------------------- +class CDmaBinaryBlock : public CDmaVar< CUtlBinaryBlock > +{ +public: + void Get( void *pValue, int nMaxLen ) const; + void Set( const void *pValue, int nLen ); + const void *Get() const; + const unsigned char& operator[]( int i ) const; + + // Returns buffer length + int Length() const; +}; + + +//----------------------------------------------------------------------------- +// Specialization for elements +//----------------------------------------------------------------------------- +template +class CDmaElement : public CDmaVar< DmElementHandle_t > +{ + typedef CDmaVar< DmElementHandle_t > BaseClass; + +public: + // Used to initialize the attribute in an element's OnConstruction method + void InitAndCreate( CDmElement *pOwner, const char *pAttributeName, const char *pElementName = NULL, int flags = 0 ); + void Init( CDmElement *pOwner, const char *pAttributeName, int flags = 0 ); + + // Returns the type of elements allowed into this attribute. UTL_INVAL_SYMBOL allows everything. + UtlSymId_t GetElementType() const; + + // Get/set + void Set( T* pElement ); + T* GetElement() const; + + // Cast + T* operator->() const; + operator T*() const; + + // NULL check + bool operator!() const; + + // Assignment.. wish I knew how to un-inline these methods + template CDmaElement &operator=( S* pElement ) + { + Set( static_cast( pElement ) ); + return *this; + } + + template CDmaElement &operator=( const CDmaElement& src ) + { + Set( static_cast( src.Get() ) ); + return *this; + } + + template bool operator==( const CDmaElement& src ) const + { + return Value() == src.Value(); + } + + template bool operator!=( const CDmaElement& src ) const + { + return Value() != src.Value(); + } +}; + + +//----------------------------------------------------------------------------- +// Can access any array attribute, regardless of type +// See below for type-specific array accessors which have more features +//----------------------------------------------------------------------------- +class CDmrGenericArrayConst +{ +public: + CDmrGenericArrayConst( const CDmAttribute* pAttribute ); + CDmrGenericArrayConst( const CDmElement *pElement, const char *pAttributeName ); + + // Array count + int Count() const; + + // Gets + const void* GetUntyped( int i ) const; + + // String conversion + const char* GetAsString( int i, char *pBuffer, size_t nBufLen ) const; + + const CDmAttribute *GetAttribute() const; + bool IsValid() const; + +protected: + CDmrGenericArrayConst(); + void Init( const CDmAttribute *pAttribute ); + void Init( const CDmElement *pElement, const char *pAttributeName ); + + CDmAttribute *m_pAttribute; +}; + +class CDmrGenericArray : public CDmrGenericArrayConst +{ +public: + CDmrGenericArray( CDmAttribute* pAttribute ); + CDmrGenericArray( CDmElement *pElement, const char *pAttributeName ); + + void EnsureCount( int num ); + + // Sets multiple elements at the same time + int AddToTail(); + void Remove( int elem ); // preserves order, shifts elements + void RemoveAll(); // doesn't deallocate memory + void SetMultiple( int i, int nCount, DmAttributeType_t valueType, const void *pValue ); + void Set( int i, DmAttributeType_t valueType, const void *pValue ); + + // String conversion + void SetFromString( int i, const char *pValue ); + + CDmAttribute *GetAttribute(); + const CDmAttribute *GetAttribute() const; +}; + + +//----------------------------------------------------------------------------- +// Helper template for external array attribute vars +// NOTE: To use this class, don't use CDmaArrayBase directly. Instead, use +// CDmaArray var; <- Instantiate an array attribute var as a member of a element class +// CDmrArray var; <- Used to reference an existing array attribute + read/modify it +// CDmrArrayConst var; <- Used to reference an existing array attribute + read it (no modify) +// +// Also, there is a CDmaStringArray/CDmrStringArray/CDmrStringArrayConst for strings +// and a CDmaElementArray/CDmrElementArray/CDmrElementArrayConst for elements +//----------------------------------------------------------------------------- +template< class T, class B > +class CDmaArrayConstBase : public B +{ +public: + // Accessors + const CUtlVector &Get() const; + const T *Base() const; + + // Iteration + int Count() const; + const T& operator[]( int i ) const; + const T& Element( int i ) const; + const T& Get( int i ) const; + const void* GetUntyped( int i ) const; + bool IsValidIndex( int i ) const; + int InvalidIndex( void ) const; + + // Search + int Find( const T &value ) const; + + // Attribute-related methods + const CDmAttribute *GetAttribute() const; + CDmElement *GetOwner(); + bool IsDirty() const; + +protected: + CDmaArrayConstBase( ); + + CDmAttribute *m_pAttribute; +}; + +template< class T, class B > +class CDmaArrayBase : public CDmaArrayConstBase< T, B > +{ +public: + // Insertion + int AddToTail(); + int InsertBefore( int elem ); + int AddToTail( const T& src ); + int InsertBefore( int elem, const T& src ); + int AddMultipleToTail( int num ); + int InsertMultipleBefore( int elem, int num ); + void EnsureCount( int num ); + + // Element Modification + void Set( int i, const T& value ); + void SetMultiple( int i, int nCount, const T* pValue ); + void Swap( int i, int j ); + + // Copy related methods + void CopyArray( const T *pArray, int size ); + + // this is basically just a faster version of CopyArray which uses pointer swap + // NOTE: This doesn't work for element arrays + void SwapArray( CUtlVector< T > &array ); + + // Removal + void FastRemove( int elem ); + void Remove( int elem ); + void RemoveMultiple( int elem, int num ); + void RemoveAll(); + + // Memory management + void EnsureCapacity( int num ); + void Purge(); + + // Attribute-related methods + CDmAttribute *GetAttribute(); + const CDmAttribute *GetAttribute() const; +}; + + +//----------------------------------------------------------------------------- +// Specialization for string arrays +// NOTE: To use this class, don't use CDmaStringArrayBase directly. Instead, use +// CDmaStringArray var; <- Instantiate an array attribute var as a member of a element class +// CDmrStringArray var; <- Used to reference an existing array attribute + read/modify it +// CDmrStringArrayConst var; <- Used to reference an existing array attribute + read it (no modify) +//----------------------------------------------------------------------------- +template< class BaseClass > +class CDmaStringArrayConstBase : public BaseClass +{ +public: + const char *operator[]( int i ) const; + const char *Element( int i ) const; + const char *Get( int i ) const; + const CUtlVector< CUtlString > &Get() const; + + // Returns strlen of element i + int Length( int i ) const; +}; + +template< class B > +class CDmaStringArrayBase : public CDmaStringArrayConstBase< CDmaArrayBase< CUtlString, B > > +{ + typedef CDmaStringArrayConstBase< CDmaArrayBase< CUtlString, B > > BaseClass; + +public: + // Sets an element in the array + void Set( int i, const char * pValue ); + + // Adds an element, uses copy constructor + int AddToTail( const char *pValue ); + int InsertBefore( int elem, const char *pValue ); +}; + + +//----------------------------------------------------------------------------- +// Specialization for elements +// NOTE: To use this class, don't use CDmaElementArrayBase directly. Instead, use +// CDmaElementArray< element_type > var; <- Instantiate an array attribute var as a member of a element class +// CDmrElementArray< element_type > var; <- Used to reference an existing array attribute + read/modify it +// CDmrElementArrayConst< element_type > var; <- Used to reference an existing array attribute + read it (no modify) +//----------------------------------------------------------------------------- +template< class E, class BaseClass > +class CDmaElementArrayConstBase : public BaseClass +{ +public: + // Returns the element type + UtlSymId_t GetElementType() const; + + // Array access + E *operator[]( int i ) const; + E *Element( int i ) const; + E *Get( int i ) const; + const DmElementHandle_t& GetHandle( int i ) const; + const CUtlVector< DmElementHandle_t > &Get() const; + + // Search + int Find( const E *pValue ) const; + int Find( DmElementHandle_t h ) const; +}; + +template < class E, class B > +class CDmaElementArrayBase : public CDmaElementArrayConstBase< E, CDmaArrayBase< DmElementHandle_t, B > > +{ + typedef CDmaElementArrayConstBase< E, CDmaArrayBase< DmElementHandle_t, B > > BaseClass; + +public: + void SetHandle( int i, DmElementHandle_t h ); + void Set( int i, E *pElement ); + + // Insertion + int AddToTail( ); + int AddToTail( DmElementHandle_t src ); + int AddToTail( E *pValue ); + int InsertBefore( int elem ); + int InsertBefore( int elem, DmElementHandle_t src ); + int InsertBefore( int elem, E *pValue ); + + template< class C, bool D > int AddToTail( const CDmeHandle& value ) + { + return BaseClass::AddToTail( value.GetHandle() ); + } + + template< class C, bool D > int InsertBefore( int elem, const CDmeHandle& value ) + { + return BaseClass::InsertBefore( elem, value.GetHandle() ); + } +}; + + +// NOTE: The next couple classes are implementation details used to create CDmrAray/CDmaArray + +//----------------------------------------------------------------------------- +// Base classes that contain data or refer to it; used for array accessor classes +//----------------------------------------------------------------------------- +template< typename T > +class CDmaDataInternal +{ +protected: + typedef typename CDmAttributeInfo< T >::StorageType_t D; + + const T& Value() const { return m_Storage; } + T& Value( ) { return m_Storage; } + const D& Data() const { return m_Storage; } + D& Data( ) { return m_Storage; } + +private: + D m_Storage; +}; + +template< typename T > +class CDmaDataExternal +{ +protected: + typedef typename CDmAttributeInfo< T >::StorageType_t D; + + CDmaDataExternal() : m_pStorage(0) {} + void Attach( void *pData ) { m_pStorage = (D*)pData; } + const T& Value() const { return *m_pStorage; } + T& Value( ) { return *m_pStorage; } + const D& Data() const { return *m_pStorage; } + D& Data( ) { return *m_pStorage; } + +private: + D* m_pStorage; +}; + + +//----------------------------------------------------------------------------- +// Versions for access, or for attribute vars +//----------------------------------------------------------------------------- +template< class T, class B > +class CDmaDecorator : public B +{ +public: + void Init( CDmElement *pOwner, const char *pAttributeName, int flags = 0 ); +}; + + +template< class T, class BaseClass > +class CDmrDecoratorConst : public BaseClass +{ +public: + void Init( const CDmAttribute* pAttribute ); + void Init( const CDmElement *pElement, const char *pAttributeName ); + + bool IsValid() const; +}; + +template< class T, class BaseClass > +class CDmrDecorator : public BaseClass +{ +public: + void Init( CDmAttribute* pAttribute ); + void Init( CDmElement *pElement, const char *pAttributeName, bool bAddAttribute = false ); + + bool IsValid() const; +}; + + +#define DECLARE_ATTRIBUTE_ARRAY_VARIABLE( _className, _elementType ) \ + public: \ + _className() {} + +#define DECLARE_ATTRIBUTE_ARRAY_REFERENCE( _className, _elementType ) \ + public: \ + _className() {} \ + _className( CDmAttribute* pAttribute ) { BaseClass::Init( pAttribute ); } \ + _className( CDmElement *pElement, const char *pAttributeName, bool bAddAttribute = false ) { BaseClass::Init( pElement, pAttributeName, bAddAttribute ); } \ + _className( CDmaArray<_className>& var ) { BaseClass::Init( var.GetAttribute() ); } \ + _className( CDmrArray<_className>& var ) { BaseClass::Init( var.GetAttribute() ); } + +#define DECLARE_ATTRIBUTE_ARRAY_CONST_REFERENCE( _className, _elementType ) \ + public: \ + _className() {} \ + _className( const CDmAttribute* pAttribute ) { BaseClass::Init( pAttribute ); } \ + _className( const CDmElement *pElement, const char *pAttributeName ) { BaseClass::Init( pElement, pAttributeName ); } \ + _className( const CDmaArray<_className>& var ) { BaseClass::Init( var.GetAttribute() ); } \ + _className( const CDmrArrayConst<_className>& var ) { BaseClass::Init( var.GetAttribute() ); } \ + _className( const CDmrArray<_className>& var ) { BaseClass::Init( var.GetAttribute() ); } + +template class CDmrArray; +template class CDmrArrayConst; +template class CDmaArray; + +//----------------------------------------------------------------------------- +// Versions for access, or for attribute vars +//----------------------------------------------------------------------------- +template +class CDmaArray : public CDmaDecorator< T, CDmaArrayBase< T, CDmaDataInternal< CUtlVector< T > > > > +{ + DECLARE_ATTRIBUTE_ARRAY_VARIABLE( CDmaArray, T ); + +public: + const CDmaArray& operator=( const CDmaArray &val ) + { + CopyArray( val.Base(), val.Count() ); + return *this; + } + + template< class C > const CDmaArray& operator=( const C &val ) + { + CopyArray( val.Base(), val.Count() ); + return *this; + } + +private: + CDmaArray( const CDmaArray& array ) {} +}; + + +template +class CDmrArrayConst : public CDmrDecoratorConst< T, CDmaArrayConstBase< T, CDmaDataExternal< CUtlVector< T > > > > +{ + typedef CDmrDecoratorConst< T, CDmaArrayConstBase< T, CDmaDataExternal< CUtlVector< T > > > > BaseClass; + DECLARE_ATTRIBUTE_ARRAY_CONST_REFERENCE( CDmrArrayConst, T ); +}; + + +template +class CDmrArray : public CDmrDecorator< T, CDmaArrayBase< T, CDmaDataExternal< CUtlVector< T > > > > +{ + typedef CDmrDecorator< T, CDmaArrayBase< T, CDmaDataExternal< CUtlVector< T > > > > BaseClass; + DECLARE_ATTRIBUTE_ARRAY_REFERENCE( CDmrArray, T ); + +public: + const CDmrArray& operator=( const CDmrArray &val ) + { + CopyArray( val.Base(), val.Count() ); + return *this; + } + + template< class C > const CDmrArray& operator=( const C &val ) + { + CopyArray( val.Base(), val.Count() ); + return *this; + } +}; + +class CDmrStringArray; + +class CDmaStringArray : public CDmaDecorator< CUtlString, CDmaStringArrayBase< CDmaDataInternal< CUtlVector< CUtlString > > > > +{ + DECLARE_ATTRIBUTE_ARRAY_VARIABLE( CDmaStringArray, CUtlString ); + +public: + const CDmaStringArray& operator=( const CDmaStringArray &val ) + { + CopyArray( val.Base(), val.Count() ); + return *this; + } + + template< class C > const CDmaStringArray& operator=( const C &val ) + { + CopyArray( val.Base(), val.Count() ); + return *this; + } + +private: + CDmaStringArray( const CDmaStringArray& array ) {} +}; + +class CDmrStringArray : public CDmrDecorator< CUtlString, CDmaStringArrayBase< CDmaDataExternal< CUtlVector< CUtlString > > > > +{ + typedef CDmrDecorator< CUtlString, CDmaStringArrayBase< CDmaDataExternal< CUtlVector< CUtlString > > > > BaseClass; + DECLARE_ATTRIBUTE_ARRAY_REFERENCE( CDmrStringArray, CUtlString ); + +public: + CDmrStringArray( CDmaStringArray& var ) { Init( var.GetAttribute() ); } + CDmrStringArray( CDmrStringArray& var ) { Init( var.GetAttribute() ); } + + const CDmrStringArray& operator=( const CDmrStringArray &val ) + { + CopyArray( val.Base(), val.Count() ); + return *this; + } + + template< class C > const CDmrStringArray& operator=( const C &val ) + { + CopyArray( val.Base(), val.Count() ); + return *this; + } +}; + +class CDmrStringArrayConst : public CDmrDecoratorConst< CUtlString, CDmaStringArrayConstBase< CDmaArrayConstBase< CUtlString, CDmaDataExternal< CUtlVector< CUtlString > > > > > +{ + typedef CDmrDecoratorConst< CUtlString, CDmaStringArrayConstBase< CDmaArrayConstBase< CUtlString, CDmaDataExternal< CUtlVector< CUtlString > > > > > BaseClass; + DECLARE_ATTRIBUTE_ARRAY_CONST_REFERENCE( CDmrStringArrayConst, CUtlString ); + +public: + CDmrStringArrayConst( const CDmaStringArray& var ) { Init( var.GetAttribute() ); } + CDmrStringArrayConst( const CDmrStringArray& var ) { Init( var.GetAttribute() ); } + CDmrStringArrayConst( const CDmrStringArrayConst& var ) { Init( var.GetAttribute() ); } +}; + + +//----------------------------------------------------------------------------- +// Prevent CDmaArray for DmElementHandle_t +//----------------------------------------------------------------------------- +template<> class CDmaArray { private: CDmaArray(); }; + + +template< class E > class CDmrElementArray; + +template< class E = CDmElement > +class CDmaElementArray : public CDmaElementArrayBase< E, CDmaDataInternal< CUtlVector< DmElementHandle_t > > > +{ + DECLARE_ATTRIBUTE_ARRAY_VARIABLE( CDmaElementArray, DmElementHandle_t ); + +public: + void Init( CDmElement *pOwner, const char *pAttributeName, int flags = 0 ) + { + Assert( pOwner ); + this->m_pAttribute = pOwner->AddExternalAttribute( pAttributeName, AT_ELEMENT_ARRAY, &CDmaElementArrayBase< E, CDmaDataInternal< CUtlVector< DmElementHandle_t > > >::Value() ); + this->m_pAttribute->SetElementTypeSymbol( E::GetStaticTypeSymbol() ); + if ( flags ) + { + this->m_pAttribute->AddFlag( flags ); + } + } + + template< typename C > CDmaElementArray& operator=( const C &val ) + { + CopyArray( val.Base(), val.Count() ); + return *this; + } + + // NOTE: The copy operator= must be defined in addition to the generic one + const CDmaElementArray& operator=( const CDmaElementArray &val ) + { + CopyArray( val.Base(), val.Count() ); + return *this; + } + +private: + template< class C > CDmaElementArray( const CDmaElementArray& var ); +}; + +template< class E = CDmElement > +class CDmrElementArrayConst : public CDmaElementArrayConstBase< E, CDmaArrayConstBase< DmElementHandle_t, CDmaDataExternal< CUtlVector< DmElementHandle_t > > > > +{ +public: + CDmrElementArrayConst() + { + this->m_pAttribute = NULL; + } + + CDmrElementArrayConst( const CDmAttribute* pAttribute ) + { + Init( pAttribute ); + } + + CDmrElementArrayConst( const CDmElement *pElement, const char *pAttributeName ) + { + Init( pElement, pAttributeName ); + } + + template< typename C > CDmrElementArrayConst( const CDmaElementArray& var ) + { + Init( var.GetAttribute() ); + } + + template< typename C > CDmrElementArrayConst( const CDmrElementArray& var ) + { + Init( var.GetAttribute() ); + } + + template< typename C > CDmrElementArrayConst( const CDmrElementArrayConst& var ) + { + Init( var.GetAttribute() ); + } + + void Init( const CDmAttribute* pAttribute ) + { + if ( pAttribute && pAttribute->GetType() == AT_ELEMENT_ARRAY ) + { + this->m_pAttribute = const_cast( pAttribute ); + this->Attach( this->m_pAttribute->GetAttributeData() ); + } + else + { + this->m_pAttribute = NULL; + this->Attach( NULL ); + } + } + + void Init( const CDmElement *pElement, const char *pAttributeName ) + { + const CDmAttribute *pAttribute = NULL; + if ( pElement && pAttributeName && pAttributeName[0] ) + { + pAttribute = (CDmAttribute*)pElement->GetAttribute( pAttributeName ); + } + Init( pAttribute ); + } + + bool IsValid() const + { + return this->m_pAttribute != NULL; + } +}; + +template< class T = CDmElement > +class CDmrElementArray : public CDmaElementArrayBase< T, CDmaDataExternal< CUtlVector< DmElementHandle_t > > > +{ +public: + CDmrElementArray() + { + this->m_pAttribute = NULL; + } + + CDmrElementArray( CDmAttribute* pAttribute ) + { + Init( pAttribute ); + } + + CDmrElementArray( CDmElement *pElement, const char *pAttributeName, bool bAddAttribute = false ) + { + Init( pElement, pAttributeName, bAddAttribute ); + } + + template< typename C > CDmrElementArray( CDmaElementArray& var ) + { + Init( var.GetAttribute() ); + } + + template< typename C > CDmrElementArray( CDmrElementArray& var ) + { + Init( var.GetAttribute() ); + } + + void Init( CDmAttribute* pAttribute ) + { + if ( pAttribute && pAttribute->GetType() == AT_ELEMENT_ARRAY ) + { + this->m_pAttribute = pAttribute; + this->Attach( this->m_pAttribute->GetAttributeData() ); + } + else + { + this->m_pAttribute = NULL; + this->Attach( NULL ); + } + } + + void Init( CDmElement *pElement, const char *pAttributeName, bool bAddAttribute = false ) + { + CDmAttribute *pAttribute = NULL; + if ( pElement && pAttributeName && pAttributeName[0] ) + { + pAttribute = pElement->GetAttribute( pAttributeName ); + if ( bAddAttribute && !pAttribute ) + { + pAttribute = pElement->CreateAttribute( pAttributeName, AT_ELEMENT_ARRAY ); + + // FIXME: Should we do this? + pAttribute->SetElementTypeSymbol( T::GetStaticTypeSymbol() ); + } + } + Init( pAttribute ); + } + + bool IsValid() const + { + return this->m_pAttribute != NULL; + } + + template< typename C > CDmrElementArray& operator=( const C &val ) + { + CopyArray( val.Base(), val.Count() ); + return *this; + } + + // NOTE: The copy operator= must be defined in addition to the generic one + const CDmrElementArray& operator=( const CDmrElementArray &val ) + { + CopyArray( val.Base(), val.Count() ); + return *this; + } +}; + + +//----------------------------------------------------------------------------- +// +// Inline methods for CDmaVar +// +//----------------------------------------------------------------------------- +template< class T > inline CDmaVar::CDmaVar( ) +{ + m_pAttribute = NULL; + CDmAttributeInfo::SetDefaultValue( m_Storage ); +} + +template< class T > inline void CDmaVar::Init( CDmElement *pOwner, const char *pAttributeName, int flags ) +{ + Assert( pOwner ); + m_pAttribute = pOwner->AddExternalAttribute( pAttributeName, CDmAttributeInfo::AttributeType(), &m_Storage ); + Assert( m_pAttribute ); + if ( flags ) + { + m_pAttribute->AddFlag( flags ); + } +} + +template< class T > inline void CDmaVar::InitAndSet( CDmElement *pOwner, const char *pAttributeName, const T &value, int flags ) +{ + Init( pOwner, pAttributeName ); + Set( value ); + + // this has to happen AFTER set so the set happens before FATTRIB_READONLY + if ( flags ) + { + m_pAttribute->AddFlag( flags ); + } +} + +template< class T > inline const T& CDmaVar::Set( const T &val ) +{ + Assert( m_pAttribute ); + m_pAttribute->SetValue( val ); + return m_Storage; +} + +template< class T > inline const T& CDmaVar::operator=( const T &val ) +{ + return Set( val ); +} + +template< class T > inline const CDmaVar& CDmaVar::operator=( const CDmaVar& src ) +{ + Set( src.Get() ); + return *this; +} + +template< class T > inline const T& CDmaVar::operator+=( const T &val ) +{ + return Set( Value() + val ); +} + +template< class T > inline const T& CDmaVar::operator-=( const T &val ) +{ + return Set( Value() - val ); +} + +template< class T > inline const T& CDmaVar::operator/=( const T &val ) +{ + return Set( Value() / val ); +} + +template< class T > inline const T& CDmaVar::operator*=( const T &val ) +{ + return Set( Value() * val ); +} + +template< class T > inline const T& CDmaVar::operator^=( const T &val ) +{ + return Set( Value() ^ val ); +} + +template< class T > inline const T& CDmaVar::operator|=( const T &val ) +{ + return Set( Value() | val ); +} + +template< class T > inline const T& CDmaVar::operator&=( const T &val ) +{ + return Set( Value() & val ); +} + +template< class T > inline T CDmaVar::operator++() +{ + return Set( Value() + 1 ); +} + +template< class T > inline T CDmaVar::operator--() +{ + return Set( Value() - 1 ); +} + +template< class T > inline T CDmaVar::operator++( int ) // postfix version.. +{ + T oldValue = Value(); + Set( Value() + 1 ); + return oldValue; +} + +template< class T > inline T CDmaVar::operator--( int ) // postfix version.. +{ + T oldValue = Value(); + Set( Value() - 1 ); + return oldValue; +} + +template< class T > inline CDmaVar::operator const T&() const +{ + return Value(); +} + +template< class T > inline const T& CDmaVar::Get() const +{ + return Value(); +} + +template< class T > inline const T* CDmaVar::operator->() const +{ + return &Value(); +} + +template< class T > inline CDmAttribute *CDmaVar::GetAttribute() +{ + Assert( m_pAttribute ); + return m_pAttribute; +} + +template< class T > inline const CDmAttribute *CDmaVar::GetAttribute() const +{ + Assert( m_pAttribute ); + return m_pAttribute; +} + +template< class T > inline bool CDmaVar::IsDirty() const +{ + Assert( m_pAttribute ); + return m_pAttribute->IsFlagSet( FATTRIB_DIRTY ); +} + +template< class T > inline const T& CDmaVar::Value() const +{ + return m_Storage; +} + +template< class T > inline T& CDmaVar::Value() +{ + return m_Storage; +} + +template<> inline const DmElementHandle_t& CDmaVar< DmElementHandle_t >::Value() const +{ + return m_Storage.m_Handle; +} + +template<> inline DmElementHandle_t& CDmaVar< DmElementHandle_t >::Value() +{ + return m_Storage.m_Handle; +} + +template< class T > inline const typename CDmaVar::D& CDmaVar::Storage() const +{ + return m_Storage; +} + +template< class T > inline typename CDmaVar::D& CDmaVar::Storage() +{ + return m_Storage; +} + + +//----------------------------------------------------------------------------- +// +// Inline methods for CDmaColor +// +//----------------------------------------------------------------------------- +inline void CDmaColor::SetColor( int r, int g, int b, int a ) +{ + Color clr( r, g, b, a ); + m_pAttribute->SetValue( clr ); +} + +inline void CDmaColor::SetRed( int r ) +{ + Color org = Value(); + org[ 0 ] = r; + m_pAttribute->SetValue( org ); +} + +inline void CDmaColor::SetGreen( int g ) +{ + Color org = Value(); + org[ 1 ] = g; + m_pAttribute->SetValue( org ); +} + +inline void CDmaColor::SetBlue( int b ) +{ + Color org = Value(); + org[ 2 ] = b; + m_pAttribute->SetValue( org ); +} + +inline void CDmaColor::SetAlpha( int a ) +{ + Color org = Value(); + org[ 3 ] = a; + m_pAttribute->SetValue( org ); +} + +inline unsigned char CDmaColor::r() const +{ + return (unsigned char)Value().r(); +} + +inline unsigned char CDmaColor::g() const +{ + return (unsigned char)Value().g(); +} + +inline unsigned char CDmaColor::b() const +{ + return (unsigned char)Value().b(); +} + +inline unsigned char CDmaColor::a() const +{ + return (unsigned char)Value().a(); +} + +inline const unsigned char &CDmaColor::operator[](int index) const +{ + return Value()[index]; +} + +inline void CDmaColor::SetRawColor( int color ) +{ + Color clr; + clr.SetRawColor( color ); + m_pAttribute->SetValue( clr ); +} + + +//----------------------------------------------------------------------------- +// +// Inline methods for CDmaObjectId +// +//----------------------------------------------------------------------------- +inline void CDmaObjectId::CreateObjectId( ) +{ + DmObjectId_t id; + CreateUniqueId( &id ); + m_pAttribute->SetValue( id ); +} + +inline void CDmaObjectId::Invalidate( ) +{ + DmObjectId_t id; + InvalidateUniqueId( &id ); + m_pAttribute->SetValue( id ); +} + +inline bool CDmaObjectId::IsValid( ) const +{ + return IsUniqueIdValid( Value() ); +} + +inline bool CDmaObjectId::IsEqual( const DmObjectId_t &id ) const +{ + return IsUniqueIdEqual( Value(), id ); +} + +inline const DmObjectId_t &CDmaObjectId::operator=( const DmObjectId_t& src ) +{ + m_pAttribute->SetValue( src ); + return Value(); +} + +inline const CDmaObjectId& CDmaObjectId::operator=( const CDmaObjectId& src ) +{ + m_pAttribute->SetValue( src.Get() ); + return *this; +} + +inline const DmObjectId_t& CDmaObjectId::Set( const DmObjectId_t &src ) +{ + m_pAttribute->SetValue( src ); + return Value(); +} + + +//----------------------------------------------------------------------------- +// +// Inline methods for CDmaString +// +//----------------------------------------------------------------------------- +inline const char *CDmaString::Get( ) const +{ + return Value().Get(); +} + +inline CDmaString::operator const char*() const +{ + return Value().Get(); +} + +inline void CDmaString::Set( const char *pValue ) +{ + CUtlString str( pValue, pValue ? Q_strlen( pValue ) + 1 : 0 ); + m_pAttribute->SetValue( str ); +} + +// Returns strlen +inline int CDmaString::Length() const +{ + return Value().Length(); +} + +inline CDmaString &CDmaString::operator=( const char *src ) +{ + Set( src ); + return *this; +} + +inline const CDmaString& CDmaString::operator=( const CDmaString& src ) +{ + Set( src.Get() ); + return *this; +} + + +//----------------------------------------------------------------------------- +// +// Inline methods for CDmaBinaryBlock +// +//----------------------------------------------------------------------------- +inline void CDmaBinaryBlock::Get( void *pValue, int nMaxLen ) const +{ + Value().Get( pValue, nMaxLen ); +} + +inline void CDmaBinaryBlock::Set( const void *pValue, int nLen ) +{ + CUtlBinaryBlock block( pValue, nLen ); + m_pAttribute->SetValue( block ); +} + +inline const void *CDmaBinaryBlock::Get() const +{ + return Value().Get(); +} + +inline const unsigned char& CDmaBinaryBlock::operator[]( int i ) const +{ + return Value()[i]; +} + +inline int CDmaBinaryBlock::Length() const +{ + return Value().Length(); +} + + +//----------------------------------------------------------------------------- +// +// Inline methods for CDmaElement +// +//----------------------------------------------------------------------------- +template +inline void CDmaElement::InitAndCreate( CDmElement *pOwner, const char *pAttributeName, const char *pElementName, int flags ) +{ + Init( pOwner, pAttributeName ); + + DmElementHandle_t hElement = DMELEMENT_HANDLE_INVALID; + if ( !g_pDataModel->IsUnserializing() ) + { + hElement = g_pDataModel->CreateElement( T::GetStaticTypeSymbol(), pElementName, pOwner->GetFileId() ); + } + Assert( m_pAttribute ); + m_pAttribute->SetValue( hElement ); + + // this has to happen AFTER set so the set happens before FATTRIB_READONLY + m_pAttribute->AddFlag( flags | FATTRIB_MUSTCOPY ); +} + +template +inline void CDmaElement::Init( CDmElement *pOwner, const char *pAttributeName, int flags ) +{ + BaseClass::Init( pOwner, pAttributeName ); + + Assert( m_pAttribute ); + m_pAttribute->SetElementTypeSymbol( T::GetStaticTypeSymbol() ); + if ( flags ) + { + m_pAttribute->AddFlag( flags ); + } +} + +template +inline UtlSymId_t CDmaElement::GetElementType() const +{ + return this->Data().m_ElementType; +} + +template +inline T* CDmaElement::GetElement() const +{ + CDmElement *pElement = g_pDataModel->GetElement( Value() ); + Assert( !pElement || pElement->IsA( T::GetStaticTypeSymbol() ) ); + return static_cast< T* >( pElement ); +} + +template +inline T* CDmaElement::operator->() const +{ + return GetElement(); +} + +template +inline CDmaElement::operator T*() const +{ + return GetElement(); +} + +template +inline void CDmaElement::Set( T* pElement ) +{ + Assert( m_pAttribute ); + m_pAttribute->SetValue( pElement ? pElement->GetHandle() : DMELEMENT_HANDLE_INVALID ); +} + +template +inline bool CDmaElement::operator!() const +{ + return ( GetElement() == NULL ); +} + + +//----------------------------------------------------------------------------- +// +// Inline methods for CDmaArrayBase +// +//----------------------------------------------------------------------------- +template< class T, class B > +inline const CUtlVector& CDmaArrayConstBase::Get() const +{ + return this->Value(); +} + +template< class T, class B > +inline const T *CDmaArrayConstBase::Base() const +{ + return this->Value().Base(); +} + +template< class T, class B > +inline const T& CDmaArrayConstBase::operator[]( int i ) const +{ + return this->Value()[ i ]; +} + +template< class T, class B > +const T& CDmaArrayConstBase::Element( int i ) const +{ + return this->Value()[ i ]; +} + +template< class T, class B > +inline const T& CDmaArrayConstBase::Get( int i ) const +{ + return this->Value()[ i ]; +} + +template< class T, class B > +const void* CDmaArrayConstBase::GetUntyped( int i ) const +{ + return &( this->Value()[ i ] ); +} + +template< class T, class B > +inline int CDmaArrayConstBase::Count() const +{ + return this->Value().Count(); +} + +template< class T, class B > +inline bool CDmaArrayConstBase::IsValidIndex( int i ) const +{ + return this->Value().IsValidIndex( i ); +} + +template< class T, class B > +inline int CDmaArrayConstBase::InvalidIndex( void ) const +{ + return this->Value().InvalidIndex(); +} + +template< class T, class B > +inline const CDmAttribute *CDmaArrayConstBase::GetAttribute() const +{ + Assert( m_pAttribute ); + return m_pAttribute; +} + +template< class T, class B > +inline CDmElement *CDmaArrayConstBase::GetOwner() +{ + return m_pAttribute->GetOwner(); +} + +template< class T, class B > +inline bool CDmaArrayConstBase::IsDirty() const +{ + return m_pAttribute->IsFlagSet( FATTRIB_DIRTY ); +} + + +template< class T, class B > +inline CDmAttribute *CDmaArrayBase::GetAttribute() +{ + Assert( this->m_pAttribute ); + return this->m_pAttribute; +} + +template< class T, class B > +inline const CDmAttribute *CDmaArrayBase::GetAttribute() const +{ + Assert( this->m_pAttribute ); + return this->m_pAttribute; +} + + +//----------------------------------------------------------------------------- +// +// Inline methods for CDmaStringArrayBase +// +//----------------------------------------------------------------------------- +template< class B > +inline const char *CDmaStringArrayConstBase::operator[]( int i ) const +{ + return this->Value()[ i ].Get(); +} + +template< class B > +inline const char *CDmaStringArrayConstBase::Element( int i ) const +{ + return this->Value()[ i ].Get(); +} + +template< class B > +inline const char *CDmaStringArrayConstBase::Get( int i ) const +{ + return this->Value()[ i ].Get(); +} + +template< class B > +inline const CUtlVector< CUtlString > &CDmaStringArrayConstBase::Get() const +{ + return this->Value(); +} + +// Returns strlen of element i +template< class B > +inline int CDmaStringArrayConstBase::Length( int i ) const +{ + return this->Value()[i].Length(); +} + +template< class B > +inline void CDmaStringArrayBase::Set( int i, const char * pValue ) +{ + CUtlString str( pValue, Q_strlen( pValue ) + 1 ); + BaseClass::Set( i, str ); +} + +// Adds an element, uses copy constructor +template< class B > +inline int CDmaStringArrayBase::AddToTail( const char *pValue ) +{ + CUtlString str( pValue, Q_strlen( pValue ) + 1 ); + return BaseClass::AddToTail( str ); +} + +template< class B > +inline int CDmaStringArrayBase::InsertBefore( int elem, const char *pValue ) +{ + CUtlString str( pValue, Q_strlen( pValue ) + 1 ); + return BaseClass::InsertBefore( elem, str ); +} + + +//----------------------------------------------------------------------------- +// +// Inline methods for CDmaElementArrayBase +// +//----------------------------------------------------------------------------- +template< class E, class B > +inline UtlSymId_t CDmaElementArrayConstBase::GetElementType() const +{ + return this->Data().m_ElementType; +} + +template< class E, class B > +inline E *CDmaElementArrayConstBase::operator[]( int i ) const +{ + return GetElement( this->Value()[i] ); +} + +template< class E, class B > +inline E *CDmaElementArrayConstBase::Element( int i ) const +{ + return GetElement( this->Value()[i] ); +} + +template< class E, class B > +inline E *CDmaElementArrayConstBase::Get( int i ) const +{ + return GetElement( this->Value()[i] ); +} + +template< class E, class B > +inline const DmElementHandle_t& CDmaElementArrayConstBase::GetHandle( int i ) const +{ + return this->Value()[i]; +} + +template< class E, class B > +inline const CUtlVector< DmElementHandle_t > &CDmaElementArrayConstBase::Get() const +{ + return this->Value(); +} + +// Search +template< class E, class B > +inline int CDmaElementArrayConstBase::Find( const E *pValue ) const +{ + if ( !pValue ) + return -1; + return B::Find( pValue->GetHandle() ); +} + +template< class E, class B > +inline int CDmaElementArrayConstBase::Find( DmElementHandle_t h ) const +{ + return B::Find( h ); +} + +template< class E, class B > +inline void CDmaElementArrayBase::SetHandle( int i, DmElementHandle_t h ) +{ + BaseClass::Set( i, h ); +} + +template< class E, class B > +inline void CDmaElementArrayBase::Set( int i, E *pElement ) +{ + BaseClass::Set( i, pElement ? pElement->GetHandle() : DMELEMENT_HANDLE_INVALID ); +} + +// Adds an element, uses copy constructor +template< class E, class B > +inline int CDmaElementArrayBase::AddToTail( ) +{ + return BaseClass::AddToTail( ); +} + +template< class E, class B > +inline int CDmaElementArrayBase::AddToTail( E *pValue ) +{ + return BaseClass::AddToTail( pValue ? pValue->GetHandle() : DMELEMENT_HANDLE_INVALID ); +} + +template< class E, class B > +inline int CDmaElementArrayBase::AddToTail( DmElementHandle_t src ) +{ + return BaseClass::AddToTail( src ); +} + +template< class E, class B > +inline int CDmaElementArrayBase::InsertBefore( int elem ) +{ + return BaseClass::InsertBefore( elem ); +} + +template< class E, class B > +inline int CDmaElementArrayBase::InsertBefore( int elem, E *pValue ) +{ + return BaseClass::InsertBefore( elem, pValue ? pValue->GetHandle() : DMELEMENT_HANDLE_INVALID ); +} + +template< class E, class B > +inline int CDmaElementArrayBase::InsertBefore( int elem, DmElementHandle_t src ) +{ + return BaseClass::InsertBefore( elem, src ); +} + + + +//----------------------------------------------------------------------------- +// +// Inline methods for CDmrGenericArray +// +//----------------------------------------------------------------------------- +inline const CDmAttribute *CDmrGenericArrayConst::GetAttribute() const +{ + Assert( m_pAttribute ); + return m_pAttribute; +} + +inline bool CDmrGenericArrayConst::IsValid() const +{ + return m_pAttribute != NULL; +} + +inline CDmAttribute *CDmrGenericArray::GetAttribute() +{ + Assert( m_pAttribute ); + return m_pAttribute; +} + +inline const CDmAttribute *CDmrGenericArray::GetAttribute() const +{ + Assert( m_pAttribute ); + return m_pAttribute; +} + + +#endif // DMATTRIBUTEVAR_H diff --git a/sp/src/public/datamodel/dmehandle.h b/sp/src/public/datamodel/dmehandle.h new file mode 100644 index 00000000..f2b78987 --- /dev/null +++ b/sp/src/public/datamodel/dmehandle.h @@ -0,0 +1,243 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// The copyright to the contents herein is the property of Valve, L.L.C. +// The contents may be used and/or copied only with the written permission of +// Valve, L.L.C., or in accordance with the terms and conditions stipulated in +// the agreement/contract under which the contents have been supplied. +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + +#ifndef DMEHANDLE_H +#define DMEHANDLE_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "datamodel/idatamodel.h" +#include "datamodel/dmelement.h" +#include "datamodel/dmattribute.h" +#include "datamodel/dmattributevar.h" + + +//----------------------------------------------------------------------------- +// Purpose: CDmeHandle is a templatized wrapper around DmElementHandle_t +//----------------------------------------------------------------------------- +template< class DmeType, bool Counted = false > +class CDmeHandle : public CDmeElementRefHelper +{ +public: + CDmeHandle() : m_handle( DMELEMENT_HANDLE_INVALID ) + { + } + + explicit CDmeHandle( CDmElement *pObject ) : m_handle( DMELEMENT_HANDLE_INVALID ) + { + Set( pObject ); + } + + CDmeHandle( DmElementHandle_t h ) : m_handle( DMELEMENT_HANDLE_INVALID ) + { + Set( h ); + } + + CDmeHandle( const CDmeHandle< DmeType, Counted > &handle ) : m_handle( DMELEMENT_HANDLE_INVALID ) + { + Set( handle.m_handle ); + } + + template < class T, bool B > + CDmeHandle( const CDmeHandle< T, B > &handle ) : m_handle( DMELEMENT_HANDLE_INVALID ) + { + DmeType *p = ( T* )NULL; // triggers compiler error if converting from invalid handle type + NOTE_UNUSED( p ); + + Set( handle.GetHandle() ); + } + + ~CDmeHandle() + { + if ( !g_pDataModel ) + return; // some handles are static, and don't get destroyed until program termination + + Unref( m_handle, Counted ); + } + + template < class T, bool B > + CDmeHandle& operator=( const CDmeHandle< T, B > &handle ) + { + DmeType *p = ( T* )NULL; // triggers compiler error if converting from invalid handle type + NOTE_UNUSED( p ); + + Set( handle.GetHandle() ); + return *this; + } + + DmeType *Get() + { + return static_cast< DmeType* >( g_pDataModel->GetElement( m_handle ) ); + } + + const DmeType *Get() const + { + return static_cast< DmeType* >( g_pDataModel->GetElement( m_handle ) ); + } + + DmElementHandle_t GetHandle() const + { + return m_handle; + } + + void Set( CDmElement *pObject ) + { + Set( pObject ? pObject->GetHandle() : DMELEMENT_HANDLE_INVALID ); + } + + void Set( DmElementHandle_t h ) + { + if ( h == m_handle ) + return; + + Unref( m_handle, Counted ); + + m_handle = h; + if ( h != DMELEMENT_HANDLE_INVALID ) + { + CDmElement *pElement = g_pDataModel->GetElement( m_handle ); + Assert( pElement ); + if ( pElement && !pElement->IsA( DmeType::GetStaticTypeSymbol() ) ) + { + m_handle = DMELEMENT_HANDLE_INVALID; + } + } + + Ref( m_handle, Counted ); + } + + operator DmeType*() + { + return Get(); + } + + operator const DmeType*() const + { + return Get(); + } + + operator DmElementHandle_t() const + { + return m_handle; + } + + DmeType* operator->() + { + return Get(); + } + + const DmeType* operator->() const + { + return Get(); + } + + CDmeHandle& operator=( DmElementHandle_t h ) + { + Set( h ); + return *this; + } + + CDmeHandle& operator=( CDmElement *pObject ) + { + Set( pObject ); + return *this; + } + + bool operator==( const CDmeHandle< DmeType > &h ) const + { + return m_handle == h.m_handle; + } + + bool operator!=( const CDmeHandle< DmeType > &h ) const + { + return !operator==( h ); + } + + bool operator<( const CDmeHandle< DmeType > &h ) const + { + return m_handle < h.m_handle; + } + + bool operator==( DmeType *pObject ) const + { + DmElementHandle_t h = pObject ? pObject->GetHandle() : DMELEMENT_HANDLE_INVALID; + return m_handle == h; + } + + bool operator!=( DmeType *pObject ) const + { + return !operator==( pObject ); + } + + bool operator==( DmElementHandle_t h ) const + { + return ( m_handle == h ); + } + + bool operator!=( DmElementHandle_t h ) const + { + return ( m_handle != h ); + } + + operator bool() const + { + return ( Get() != NULL ); + } + + bool operator!() const + { + return ( Get() == NULL ); + } + +private: + DmElementHandle_t m_handle; +}; + +typedef CDmeHandle< CDmElement, true > CDmeCountedHandle; + + +//----------------------------------------------------------------------------- +// Vector of element handles +//----------------------------------------------------------------------------- +typedef CUtlVector< CDmeHandle > DmeHandleVec_t; + + + +//----------------------------------------------------------------------------- +// helper class for undo classes to allow them to hold onto refcounted element handles +//----------------------------------------------------------------------------- + +template< typename T > +class CDmAttributeUndoStorageType +{ +public: + typedef T UndoStorageType; +}; + +template<> +class CDmAttributeUndoStorageType< DmElementHandle_t > +{ +public: + typedef CDmeCountedHandle UndoStorageType; +}; + +template<> +class CDmAttributeUndoStorageType< CUtlVector< DmElementHandle_t > > +{ +public: + typedef CUtlVector< CDmeCountedHandle > UndoStorageType; +}; + +#endif // DMEHANDLE_H diff --git a/sp/src/public/datamodel/dmelement.h b/sp/src/public/datamodel/dmelement.h new file mode 100644 index 00000000..13a8becd --- /dev/null +++ b/sp/src/public/datamodel/dmelement.h @@ -0,0 +1,618 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef DMELEMENT_H +#define DMELEMENT_H +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/utlmap.h" +#include "tier1/utlhash.h" +#include "tier1/utlvector.h" +#include "tier1/utlsymbol.h" +#include "datamodel/attributeflags.h" +#include "datamodel/idatamodel.h" +#include "datamodel/dmvar.h" + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +typedef bool (CDmElement::*pfnCommandMethod)( const char *command, const char *args ); + +// element/element array traversal path item - assumes the full path does NOT contain cycles +struct ElementPathItem_t +{ + ElementPathItem_t( DmElementHandle_t hElem = DMELEMENT_HANDLE_INVALID, + DmAttributeHandle_t hAttr = DMATTRIBUTE_HANDLE_INVALID, + int idx = -1 ) + : hElement( hElem ), hAttribute( hAttr ), nIndex( idx ) + { + } + + // only uses hElement so that it can be used to search for elements + bool operator==( const ElementPathItem_t &that ) const + { + return hElement == that.hElement; + } + + DmElementHandle_t hElement; + DmAttributeHandle_t hAttribute; + int nIndex; +}; + + +//----------------------------------------------------------------------------- +// singly-linked attribute list +//----------------------------------------------------------------------------- +struct DmAttributeList_t +{ + DmAttributeList_t() : m_hAttribute( DMATTRIBUTE_HANDLE_INVALID ), m_pNext( NULL ) {} + DmAttributeHandle_t m_hAttribute; + DmAttributeList_t *m_pNext; +}; + +//----------------------------------------------------------------------------- +// helper class to allow CDmeHandle access to g_pDataModelImp +//----------------------------------------------------------------------------- +class CDmeElementRefHelper +{ +protected: + void Ref ( DmElementHandle_t hElement, bool bStrong ); + void Unref( DmElementHandle_t hElement, bool bStrong ); +}; + +//----------------------------------------------------------------------------- +// element reference struct - containing attribute referrers and handle refcount +//----------------------------------------------------------------------------- +struct DmElementReference_t +{ + explicit DmElementReference_t( DmElementHandle_t hElement = DMELEMENT_HANDLE_INVALID ) : + m_hElement( hElement ), m_nWeakHandleCount( 0 ), m_nStrongHandleCount( 0 ) + { + } + DmElementReference_t( const DmElementReference_t &that ) : + m_hElement( that.m_hElement ), m_nWeakHandleCount( that.m_nWeakHandleCount ), + m_nStrongHandleCount( that.m_nStrongHandleCount ), m_attributes( that.m_attributes ) + { + } + DmElementReference_t &operator=( const DmElementReference_t &that ) + { + m_hElement = that.m_hElement; + m_nWeakHandleCount = that.m_nWeakHandleCount; + m_nStrongHandleCount = that.m_nStrongHandleCount; + m_attributes.m_hAttribute = that.m_attributes.m_hAttribute; + m_attributes.m_pNext = that.m_attributes.m_pNext; + return *this; + } + ~DmElementReference_t() + { + // Assert( !IsStronglyReferenced() ); + } + + void AddAttribute( CDmAttribute *pAttribute ); + void RemoveAttribute( CDmAttribute *pAttribute ); + + bool IsStronglyReferenced() // should this element be kept around (even if it's DmElementHandle_t is invalidated) + { + return m_attributes.m_hAttribute != DMATTRIBUTE_HANDLE_INVALID || m_nStrongHandleCount > 0; + } + + bool IsWeaklyReferenced() // should we keep this element's DmElementHandle_t mapped to it's id (even if the element is deleted) + { + return IsStronglyReferenced() || m_nWeakHandleCount > 0; + } + + int EstimateMemoryOverhead() + { + int nBytes = 0; + for ( DmAttributeList_t *pLink = m_attributes.m_pNext; pLink; pLink = pLink->m_pNext ) + { + nBytes += sizeof( DmAttributeList_t ); + } + return nBytes; + } + + DmElementHandle_t m_hElement; + unsigned short m_nWeakHandleCount; // CDmeHandle - for auto-hookup once the element comes back, mainly used by UI + unsigned short m_nStrongHandleCount; // CDmeCountedElementRef - for preventing elements from being truly deleted, mainly used by undo and file root + DmAttributeList_t m_attributes; +}; + + +//----------------------------------------------------------------------------- +// Base DmElement we inherit from in higher-level classes +//----------------------------------------------------------------------------- +class CDmElement +{ +public: + // Can be overridden by derived classes + virtual void OnAttributeChanged( CDmAttribute *pAttribute ) {} + virtual void PreAttributeChanged( CDmAttribute *pAttribute ) {} + virtual void OnAttributeArrayElementAdded( CDmAttribute *pAttribute, int nFirstElem, int nLastElem ) {} + virtual void OnAttributeArrayElementRemoved( CDmAttribute *pAttribute, int nFirstElem, int nLastElem ) {} + virtual void Resolve() {} + virtual bool IsA( UtlSymId_t typeSymbol ) const; + virtual int GetInheritanceDepth( UtlSymId_t typeSymbol ) const; + virtual void OnElementUnserialized() {} + virtual int AllocatedSize() const { return sizeof( CDmElement ); } + + // Returns the element handle + DmElementHandle_t GetHandle() const; + + // Attribute iteration, finding + // NOTE: Passing a type into GetAttribute will return NULL if the attribute exists but isn't that type + bool HasAttribute( const char *pAttributeName, DmAttributeType_t type = AT_UNKNOWN ) const; + CDmAttribute *GetAttribute( const char *pAttributeName, DmAttributeType_t type = AT_UNKNOWN ); + const CDmAttribute *GetAttribute( const char *pAttributeName, DmAttributeType_t type = AT_UNKNOWN ) const; + int AttributeCount() const; + CDmAttribute* FirstAttribute(); + const CDmAttribute* FirstAttribute() const; + + // Element name, type, ID + // WARNING: SetType() should only be used by format conversion methods (dmxconvert) + UtlSymId_t GetType() const; + const char * GetTypeString() const; + const char * GetName() const; + const DmObjectId_t& GetId() const; + void SetType( const char *pType ); + void SetName( const char* pName ); + + // Attribute management + CDmAttribute * AddAttribute( const char *pAttributeName, DmAttributeType_t type ); + template< class E > CDmAttribute* AddAttributeElement( const char *pAttributeName ); + template< class E > CDmAttribute* AddAttributeElementArray( const char *pAttributeName ); + void RemoveAttribute( const char *pAttributeName ); + void RemoveAttributeByPtr( CDmAttribute *pAttributeName ); + void RenameAttribute( const char *pAttributeName, const char *pNewName ); + + // get attribute value + template< class T > const T& GetValue( const char *pAttributeName ) const; + template< class T > const T& GetValue( const char *pAttributeName, const T& defaultValue ) const; + const char * GetValueString( const char *pAttributeName ) const; + template< class E > E* GetValueElement( const char *pAttributeName ) const; + + // set attribute value + CDmAttribute* SetValue( const char *pAttributeName, const void *value, size_t size ); + template< class T > CDmAttribute* SetValue( const char *pAttributeName, const T& value ); + template< class E > CDmAttribute* SetValue( const char *pAttributeName, E* value ); + + // set attribute value if the attribute doesn't already exist + CDmAttribute* InitValue( const char *pAttributeName, const void *value, size_t size ); + template< class T > CDmAttribute* InitValue( const char *pAttributeName, const T& value ); + template< class E > CDmAttribute* InitValue( const char *pAttributeName, E* value ); + + // Parses an attribute from a string + // Doesn't create an attribute if it doesn't exist and always preserves attribute type + void SetValueFromString( const char *pAttributeName, const char *value ); + const char *GetValueAsString( const char *pAttributeName, char *pBuffer, size_t buflen ) const; + + // Helpers for our RTTI + template< class E > bool IsA() const; + bool IsA( const char *pTypeName ) const; + int GetInheritanceDepth( const char *pTypeName ) const; + static CUtlSymbol GetStaticTypeSymbol(); + + // Indicates whether this element should be copied or not + void SetShared( bool bShared ); + bool IsShared() const; + + // Copies an element and all its attributes + CDmElement* Copy( TraversalDepth_t depth = TD_DEEP ) const; + + // Copies attributes from a specified element + void CopyAttributesTo( CDmElement *pCopy, TraversalDepth_t depth = TD_DEEP ) const; + + // recursively set fileid's, with option to only change elements in the matched file + void SetFileId( DmFileId_t fileid, TraversalDepth_t depth, bool bOnlyIfMatch = false ); + DmFileId_t GetFileId() const; + + bool IsAccessible() const; + void MarkAccessible( bool bAccessible ); + void MarkAccessible( TraversalDepth_t depth = TD_ALL ); + + // returns the first path to the element found traversing all element/element + // array attributes - not necessarily the shortest. + // cycle-safe (skips any references to elements in the current path) + // but may re-traverse elements via different paths + bool FindElement( const CDmElement *pElement, CUtlVector< ElementPathItem_t > &elementPath, TraversalDepth_t depth ) const; + bool FindReferer( DmElementHandle_t hElement, CUtlVector< ElementPathItem_t > &elementPath, TraversalDepth_t depth ) const; + void RemoveAllReferencesToElement( CDmElement *pElement ); + bool IsStronglyReferenced() { return m_ref.IsStronglyReferenced(); } + + // Estimates the memory usage of the element, its attributes, and child elements + int EstimateMemoryUsage( TraversalDepth_t depth = TD_DEEP ); + +protected: + // NOTE: These are protected to ensure that the factory is the only thing that can create these + CDmElement( DmElementHandle_t handle, const char *objectType, const DmObjectId_t &id, const char *objectName, DmFileId_t fileid ); + virtual ~CDmElement(); + + // Used by derived classes to do construction and setting up CDmaVars + void OnConstruction() { } + void OnDestruction() { } + virtual void PerformConstruction(); + virtual void PerformDestruction(); + + // Internal methods related to RTII + static void SetTypeSymbol( CUtlSymbol sym ); + static bool IsA_Implementation( CUtlSymbol typeSymbol ); + static int GetInheritanceDepth_Implementation( CUtlSymbol typeSymbol, int nCurrentDepth ); + + // Internal method for creating a copy of this element + CDmElement* CopyInternal( TraversalDepth_t depth = TD_DEEP ) const; + + // helper for making attributevarelementarray cleanup easier + template< class T > static void DeleteAttributeVarElementArray( T &array ); + +private: + typedef CUtlMap< DmElementHandle_t, DmElementHandle_t, int > CRefMap; + + // Bogus constructor + CDmElement(); + + // internal recursive copy method - builds refmap of old element's handle -> copy's handle, and uses it to fixup references + void CopyAttributesTo( CDmElement *pCopy, CRefMap &refmap, TraversalDepth_t depth ) const; + void CopyElementAttribute( const CDmAttribute *pAttr, CDmAttribute *pCopyAttr, CRefMap &refmap, TraversalDepth_t depth ) const; + void CopyElementArrayAttribute( const CDmAttribute *pAttr, CDmAttribute *pCopyAttr, CRefMap &refmap, TraversalDepth_t depth ) const; + void FixupReferences( CUtlHashFast< DmElementHandle_t > &visited, const CRefMap &refmap, TraversalDepth_t depth ); + + void SetFileId( DmFileId_t fileid ); + void SetFileId_R( CUtlHashFast< DmElementHandle_t > &visited, DmFileId_t fileid, TraversalDepth_t depth, DmFileId_t match, bool bOnlyIfMatch ); + + CDmAttribute* CreateAttribute( const char *pAttributeName, DmAttributeType_t type ); + void RemoveAttribute( CDmAttribute **pAttrRef ); + CDmAttribute* AddExternalAttribute( const char *pAttributeName, DmAttributeType_t type, void *pMemory ); + CDmAttribute *FindAttribute( const char *pAttributeName ) const; + + void Purge(); + void SetId( const DmObjectId_t &id ); + + bool IsDirty() const; + void MarkDirty( bool dirty = true ); + void MarkAttributesClean(); + void MarkBeingUnserialized( bool beingUnserialized = true ); + bool IsBeingUnserialized() const; + + // Used by the undo system only. + void AddAttributeByPtr( CDmAttribute *ptr ); + void RemoveAttributeByPtrNoDelete( CDmAttribute *ptr ); + + // Should only be called from datamodel, who will take care of changing the fileset entry as well + void ChangeHandle( DmElementHandle_t handle ); + + // returns element reference struct w/ list of referrers and handle count + DmElementReference_t* GetReference(); + void SetReference( const DmElementReference_t &ref ); + + // Estimates memory usage + int EstimateMemoryUsage( CUtlHash< DmElementHandle_t > &visited, TraversalDepth_t depth, int *pCategories ); + +protected: + CDmaString m_Name; + +private: + CDmAttribute *m_pAttributes; + DmElementReference_t m_ref; + UtlSymId_t m_Type; + bool m_bDirty : 1; + bool m_bBeingUnserialized : 1; + bool m_bIsAcessible : 1; + unsigned char m_nReserved; // Makes Id be quad aligned + DmObjectId_t m_Id; + DmFileId_t m_fileId; + + // Stores the type symbol + static CUtlSymbol m_classType; + + // Factories can access our constructors + template friend class CDmElementFactory; + template friend class CDmAbstractElementFactory; + template< class T > friend class CDmaVar; + template< class T > friend class CDmaArray; + template< class T > friend class CDmaElementArray; + template< class T, class B > friend class CDmaDecorator; + template< class T > friend class CDmrElementArray; + + friend class CDmElementFactoryDefault; + friend class CDmeElementAccessor; + friend class CDmeOperator; + + friend void CopyElements( const CUtlVector< CDmElement* > &from, CUtlVector< CDmElement* > &to, TraversalDepth_t depth ); +}; + + + +inline void DestroyElement( CDmElement *pElement ) +{ + if ( pElement ) + { + g_pDataModel->DestroyElement( pElement->GetHandle() ); + } +} + +void DestroyElement( CDmElement *pElement, TraversalDepth_t depth ); + + +//----------------------------------------------------------------------------- +// copy groups of elements together so that references between them are maintained +//----------------------------------------------------------------------------- +void CopyElements( const CUtlVector< CDmElement* > &from, CUtlVector< CDmElement* > &to, TraversalDepth_t depth = TD_DEEP ); + + +//----------------------------------------------------------------------------- +// allows elements to chain OnAttributeChanged up to their parents (or at least, referrers) +//----------------------------------------------------------------------------- +void InvokeOnAttributeChangedOnReferrers( DmElementHandle_t hElement, CDmAttribute *pChangedAttr ); + + + + + +//----------------------------------------------------------------------------- +// Returns the type, name, id, fileId +//----------------------------------------------------------------------------- +inline UtlSymId_t CDmElement::GetType() const +{ + return m_Type; +} + +inline const char *CDmElement::GetTypeString() const +{ + return g_pDataModel->GetString( m_Type ); +} + +inline const char *CDmElement::GetName() const +{ + return m_Name.Get(); +} + +inline void CDmElement::SetName( const char* pName ) +{ + m_Name.Set( pName ); +} + +inline const DmObjectId_t& CDmElement::GetId() const +{ + return m_Id; +} + +inline DmFileId_t CDmElement::GetFileId() const +{ + return m_fileId; +} + + +//----------------------------------------------------------------------------- +// Controls whether the element should be copied by default +//----------------------------------------------------------------------------- +inline void CDmElement::SetShared( bool bShared ) +{ + if ( bShared ) + { + SetValue< bool >( "shared", true ); + } + else + { + RemoveAttribute( "shared" ); + } +} + +inline bool CDmElement::IsShared() const +{ + return GetValue< bool >( "shared" ); // if attribute doesn't exist, returns default bool value, which is false +} + + +//----------------------------------------------------------------------------- +// Copies attributes from a specified element +//----------------------------------------------------------------------------- +inline CDmElement* CDmElement::Copy( TraversalDepth_t depth ) const +{ + return CopyInternal( depth ); +} + + +//----------------------------------------------------------------------------- +// RTTI +//----------------------------------------------------------------------------- +inline bool CDmElement::IsA_Implementation( CUtlSymbol typeSymbol ) +{ + return ( m_classType == typeSymbol ) || ( UTL_INVAL_SYMBOL == typeSymbol ); +} + +inline int CDmElement::GetInheritanceDepth_Implementation( CUtlSymbol typeSymbol, int nCurrentDepth ) +{ + return IsA_Implementation( typeSymbol ) ? nCurrentDepth : -1; +} + +inline CUtlSymbol CDmElement::GetStaticTypeSymbol() +{ + return m_classType; +} + +inline bool CDmElement::IsA( const char *pTypeName ) const +{ + CUtlSymbol typeSymbol = g_pDataModel->GetSymbol( pTypeName ); + return IsA( typeSymbol ); +} + +template< class E > inline bool CDmElement::IsA() const +{ + return IsA( E::GetStaticTypeSymbol() ); +} + + +//----------------------------------------------------------------------------- +// Helper for finding elements that refer to this element +//----------------------------------------------------------------------------- +template< class T > +T *FindReferringElement( CDmElement *pElement, const char *pAttrName, bool bMustBeInSameFile = true ) +{ + return FindReferringElement< T >( pElement, g_pDataModel->GetSymbol( pAttrName ), bMustBeInSameFile ); +} + + +void RemoveElementFromRefereringAttributes( CDmElement *pElement, bool bPreserveOrder = true ); + + + +//----------------------------------------------------------------------------- +// +// element-specific unique name generation methods +// +//----------------------------------------------------------------------------- + +// returns startindex if none found, 2 if only "prefix" found, and n+1 if "prefixn" found +int GenerateUniqueNameIndex( const char *prefix, const CUtlVector< DmElementHandle_t > &array, int startindex = -1 ); + +bool GenerateUniqueName( char *name, int memsize, const char *prefix, const CUtlVector< DmElementHandle_t > &array ); + +void MakeElementNameUnique( CDmElement *pElement, const char *prefix, const CUtlVector< DmElementHandle_t > &array, bool forceIndex = false ); + + +//----------------------------------------------------------------------------- +// helper for making attributevarelementarray cleanup easier +//----------------------------------------------------------------------------- +template< class T > +inline void CDmElement::DeleteAttributeVarElementArray( T &array ) +{ + int nElements = array.Count(); + for ( int i = 0; i < nElements; ++i ) + { + g_pDataModel->DestroyElement( array.GetHandle( i ) ); + } + array.RemoveAll(); +} + + +//----------------------------------------------------------------------------- +// Default size computation +//----------------------------------------------------------------------------- +template< class T > +int DmeEstimateMemorySize( T* pElement ) +{ + return sizeof( T ); +} + + +//----------------------------------------------------------------------------- +// Helper macro to create an element; this is used for elements that are helper base classes +//----------------------------------------------------------------------------- +#define DEFINE_UNINSTANCEABLE_ELEMENT( className, baseClassName ) \ + protected: \ + className( DmElementHandle_t handle, const char *pElementTypeName, const DmObjectId_t &id, const char *pElementName, DmFileId_t fileid ) : \ + baseClassName( handle, pElementTypeName, id, pElementName, fileid ) \ + { \ + } \ + virtual ~className() \ + { \ + } \ + void OnConstruction(); \ + void OnDestruction(); \ + virtual void PerformConstruction() \ + { \ + BaseClass::PerformConstruction(); \ + OnConstruction(); \ + } \ + virtual void PerformDestruction() \ + { \ + OnDestruction(); \ + BaseClass::PerformDestruction(); \ + } \ + virtual int AllocatedSize() const { return DmeEstimateMemorySize( this ); } \ + \ + private: \ + typedef baseClassName BaseClass; \ + + +//----------------------------------------------------------------------------- +// Helper macro to create the class factory +//----------------------------------------------------------------------------- +#define DEFINE_ELEMENT( className, baseClassName ) \ + public: \ + virtual bool IsA( UtlSymId_t typeSymbol ) const \ + { \ + return IsA_Implementation( typeSymbol );\ + } \ + \ + bool IsA( const char *pTypeName ) const \ + { \ + CUtlSymbol typeSymbol = g_pDataModel->GetSymbol( pTypeName ); \ + return IsA( typeSymbol ); \ + } \ + \ + template< class T > bool IsA() const \ + { \ + return IsA( T::GetStaticTypeSymbol() ); \ + } \ + \ + virtual int GetInheritanceDepth( UtlSymId_t typeSymbol ) const \ + { \ + return GetInheritanceDepth_Implementation( typeSymbol, 0 ); \ + } \ + \ + static CUtlSymbol GetStaticTypeSymbol( ) \ + { \ + return m_classType; \ + } \ + \ + className* Copy( TraversalDepth_t depth = TD_DEEP ) const \ + { \ + return static_cast< className* >( CopyInternal( depth ) ); \ + } \ + protected: \ + className( DmElementHandle_t handle, const char *pElementTypeName, const DmObjectId_t &id, const char *pElementName, DmFileId_t fileid ) : \ + baseClassName( handle, pElementTypeName, id, pElementName, fileid ) \ + { \ + } \ + virtual ~className() \ + { \ + } \ + void OnConstruction(); \ + void OnDestruction(); \ + virtual void PerformConstruction() \ + { \ + BaseClass::PerformConstruction(); \ + OnConstruction(); \ + } \ + virtual void PerformDestruction() \ + { \ + OnDestruction(); \ + BaseClass::PerformDestruction(); \ + } \ + static void SetTypeSymbol( CUtlSymbol typeSymbol ) \ + { \ + m_classType = typeSymbol; \ + } \ + \ + static bool IsA_Implementation( CUtlSymbol typeSymbol ) \ + { \ + if ( typeSymbol == m_classType ) \ + return true; \ + return BaseClass::IsA_Implementation( typeSymbol ); \ + } \ + \ + static int GetInheritanceDepth_Implementation( CUtlSymbol typeSymbol, int nCurrentDepth ) \ + { \ + if ( typeSymbol == m_classType ) \ + return nCurrentDepth; \ + return BaseClass::GetInheritanceDepth_Implementation( typeSymbol, nCurrentDepth+1 );\ + } \ + virtual int AllocatedSize() const { return DmeEstimateMemorySize( this ); } \ + \ + private: \ + typedef baseClassName BaseClass; \ + template friend class CDmElementFactory; \ + template friend class CDmAbstractElementFactory; \ + static CUtlSymbol m_classType + +#define IMPLEMENT_ELEMENT( className ) \ + CUtlSymbol className::m_classType = UTL_INVAL_SYMBOL; + + +#endif // DMELEMENT_H diff --git a/sp/src/public/datamodel/dmelementfactoryhelper.h b/sp/src/public/datamodel/dmelementfactoryhelper.h new file mode 100644 index 00000000..c4847ccf --- /dev/null +++ b/sp/src/public/datamodel/dmelementfactoryhelper.h @@ -0,0 +1,190 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef DMELEMENTFACTORYHELPER_H +#define DMELEMENTFACTORYHELPER_H +#ifdef _WIN32 +#pragma once +#endif + +#include "datamodel/idatamodel.h" +#include "datamodel/dmelement.h" +#include "datamodel/dmattribute.h" +#include "datamodel/dmattributevar.h" +#include "tier1/utlvector.h" +#include "tier1/utlsymbol.h" + + +//----------------------------------------------------------------------------- +// Internal interface for IDmElementFactory +//----------------------------------------------------------------------------- +class IDmElementFactoryInternal : public IDmElementFactory +{ +public: + virtual void SetElementTypeSymbol( CUtlSymbol sym ) = 0; + virtual bool IsAbstract() const = 0; +}; + + +//----------------------------------------------------------------------------- +// Class used to register factories into a global list +//----------------------------------------------------------------------------- +class CDmElementFactoryHelper +{ +public: + // Static list of helpers + static CDmElementFactoryHelper *s_pHelpers[2]; + + // Create all the hud elements + static void InstallFactories( ); + +public: + // Construction + CDmElementFactoryHelper( const char *pClassName, IDmElementFactoryInternal *pFactory, bool bIsStandardFactory ); + + // Accessors + CDmElementFactoryHelper *GetNext( void ); + + const char *GetClassname(); + IDmElementFactoryInternal *GetFactory(); + +private: + // Next factory in list + CDmElementFactoryHelper *m_pNext; + // Creation function to use for this technology + IDmElementFactoryInternal *m_pFactory; + const char *m_pszClassname; +}; + + +//----------------------------------------------------------------------------- +// Inline methods +//----------------------------------------------------------------------------- +inline const char *CDmElementFactoryHelper::GetClassname() +{ + return m_pszClassname; +} + +inline IDmElementFactoryInternal *CDmElementFactoryHelper::GetFactory() +{ + return m_pFactory; +} + + +//----------------------------------------------------------------------------- +// Helper Template factory for simple creation of factories +//----------------------------------------------------------------------------- +template +class CDmElementFactory : public IDmElementFactoryInternal +{ +public: + CDmElementFactory( const char *pLookupName ) : m_pLookupName( pLookupName ) {} + + // Creation, destruction + virtual CDmElement* Create( DmElementHandle_t handle, const char *pElementType, const char *pElementName, DmFileId_t fileid, const DmObjectId_t &id ) + { + return new T( handle, m_pLookupName, id, pElementName, fileid ); + } + + virtual void Destroy( DmElementHandle_t hElement ) + { + CDmElement *pElement = g_pDataModel->GetElement( hElement ); + if ( pElement ) + { + T *pActualElement = static_cast< T* >( pElement ); + delete pActualElement; + } + } + + // Sets the type symbol, used for "isa" implementation + virtual void SetElementTypeSymbol( CUtlSymbol sym ) + { + T::SetTypeSymbol( sym ); + } + + virtual bool IsAbstract() const { return false; } + +private: + const char *m_pLookupName; +}; + + +template < class T > +class CDmAbstractElementFactory : public IDmElementFactoryInternal +{ +public: + CDmAbstractElementFactory() {} + + // Creation, destruction + virtual CDmElement* Create( DmElementHandle_t handle, const char *pElementType, const char *pElementName, DmFileId_t fileid, const DmObjectId_t &id ) + { + return NULL; + } + + virtual void Destroy( DmElementHandle_t hElement ) + { + } + + // Sets the type symbol, used for "isa" implementation + virtual void SetElementTypeSymbol( CUtlSymbol sym ) + { + T::SetTypeSymbol( sym ); + } + + virtual bool IsAbstract() const { return true; } + +private: +}; + + +//----------------------------------------------------------------------------- +// Helper macro to create the class factory +//----------------------------------------------------------------------------- +#if defined( MOVIEOBJECTS_LIB ) || defined ( DATAMODEL_LIB ) || defined ( DMECONTROLS_LIB ) + +#define IMPLEMENT_ELEMENT_FACTORY( lookupName, className ) \ + IMPLEMENT_ELEMENT( className ) \ + CDmElementFactory< className > g_##className##_Factory( #lookupName ); \ + CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, true ); \ + className *g_##className##LinkerHack = NULL; + +#define IMPLEMENT_ABSTRACT_ELEMENT( lookupName, className ) \ + IMPLEMENT_ELEMENT( className ) \ + CDmAbstractElementFactory< className > g_##className##_Factory; \ + CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, true ); \ + className *g_##className##LinkerHack = NULL; + +#else + +#define IMPLEMENT_ELEMENT_FACTORY( lookupName, className ) \ + IMPLEMENT_ELEMENT( className ) \ + CDmElementFactory< className > g_##className##_Factory( #lookupName ); \ + CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, false ); \ + className *g_##className##LinkerHack = NULL; + +#define IMPLEMENT_ABSTRACT_ELEMENT( lookupName, className ) \ + IMPLEMENT_ELEMENT( className ) \ + CDmAbstractElementFactory< className > g_##className##_Factory; \ + CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, false ); \ + className *g_##className##LinkerHack = NULL; + +#endif + + +// Used by classes defined in movieobjects or scenedatabase that must be explicitly installed +#define IMPLEMENT_ELEMENT_FACTORY_INSTALL_EXPLICITLY( lookupName, className ) \ + IMPLEMENT_ELEMENT( className ) \ + CDmElementFactory< className > g_##className##_Factory( #lookupName ); \ + CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, false ); \ + className *g_##className##LinkerHack = NULL; + +//----------------------------------------------------------------------------- +// Installs dm element factories +//----------------------------------------------------------------------------- +void InstallDmElementFactories( ); + + +#endif // DMELEMENTFACTORYHELPER_H diff --git a/sp/src/public/datamodel/dmelementhandle.h b/sp/src/public/datamodel/dmelementhandle.h new file mode 100644 index 00000000..319f308c --- /dev/null +++ b/sp/src/public/datamodel/dmelementhandle.h @@ -0,0 +1,47 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef DMELEMENTHANDLE_H +#define DMELEMENTHANDLE_H + +#ifdef _WIN32 +#pragma once +#endif + + +//----------------------------------------------------------------------------- +// handle to an CDmElement +//----------------------------------------------------------------------------- +#define PERFORM_HANDLE_TYPECHECKING 0 +#if PERFORM_HANDLE_TYPECHECKING + +// this is here to make sure we're being type-safe about element handles +// otherwise, the compiler lets us cast to bool incorrectly +// the other solution would be to redefine DmElementHandle_t s.t. DMELEMENT_HANDLE_INVALID==0 +struct DmElementHandle_t +{ + DmElementHandle_t() : handle( 0xffffffff ) {} + explicit DmElementHandle_t( int h ) : handle( h ) {} + inline bool operator==( const DmElementHandle_t &h ) const { return handle == h.handle; } + inline bool operator!=( const DmElementHandle_t &h ) const { return handle != h.handle; } + inline bool operator<( const DmElementHandle_t &h ) const { return handle < h.handle; } +// inline operator int() const { return handle; } // if we're okay with implicit int casts, uncomment this method + int handle; +}; +const DmElementHandle_t DMELEMENT_HANDLE_INVALID; + +#else // PERFORM_HANDLE_TYPECHECKING + +enum DmElementHandle_t +{ + DMELEMENT_HANDLE_INVALID = 0xffffffff +}; + +#endif // PERFORM_HANDLE_TYPECHECKING + + + +#endif // DMELEMENTHANDLE_H diff --git a/sp/src/public/datamodel/dmvar.h b/sp/src/public/datamodel/dmvar.h new file mode 100644 index 00000000..940e138b --- /dev/null +++ b/sp/src/public/datamodel/dmvar.h @@ -0,0 +1,93 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef DMVAR_H +#define DMVAR_H +#ifdef _WIN32 +#pragma once +#endif + + +class CDmAttribute; + +//----------------------------------------------------------------------------- +// Helper template for external attributes +//----------------------------------------------------------------------------- +template< typename T > +class CDmaVar +{ + typedef typename CDmAttributeInfo< T >::StorageType_t D; + +public: + CDmaVar( ); + + // Setup to be used in OnConstruction methods of DmElements + void Init( CDmElement *pOwner, const char *pAttributeName, int flags = 0 ); + void InitAndSet( CDmElement *pOwner, const char *pAttributeName, const T &value, int flags = 0 ); + + // Set/get + const T& Set( const T &val ); + const T& Get() const; + + // Cast operators + operator const T&() const; + const T* operator->() const; + + // Assignment operator + const CDmaVar& operator=( const CDmaVar& src ); + + // Math utility operations + const T& operator=( const T &val ); + const T& operator+=( const T &val ); + const T& operator-=( const T &val ); + const T& operator/=( const T &val ); + const T& operator*=( const T &val ); + const T& operator^=( const T &val ); + const T& operator|=( const T &val ); + const T& operator&=( const T &val ); + T operator++(); + T operator--(); + T operator++( int ); // postfix version.. + T operator--( int ); // postfix version.. + + // Returns the attribute associated with the var + CDmAttribute *GetAttribute(); + const CDmAttribute *GetAttribute() const; + + // Is the attribute dirty? + bool IsDirty() const; + +protected: + const T& Value() const; + T& Value(); + const D& Storage() const; + D& Storage(); + +private: + D m_Storage; + +protected: + CDmAttribute *m_pAttribute; +}; + +//----------------------------------------------------------------------------- +// Specialization for string +//----------------------------------------------------------------------------- +class CDmaString : public CDmaVar< CUtlString > +{ +public: + const char *Get( ) const; + operator const char*() const; + + void Set( const char *pValue ); + CDmaString &operator=( const char *src ); + const CDmaString& operator=( const CDmaString& src ); + + // Returns strlen + int Length() const; +}; + +#endif // DMVAR_H diff --git a/sp/src/public/datamodel/idatamodel.h b/sp/src/public/datamodel/idatamodel.h new file mode 100644 index 00000000..16f2c73c --- /dev/null +++ b/sp/src/public/datamodel/idatamodel.h @@ -0,0 +1,938 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef IDATAMODEL_H +#define IDATAMODEL_H +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/interface.h" +#include "tier1/utlvector.h" +#include "tier1/utlsymbol.h" +#include "appframework/IAppSystem.h" +#include "datamodel/dmattributetypes.h" + + +//----------------------------------------------------------------------------- +// Forward declarations: +//----------------------------------------------------------------------------- +class CDmAttribute; +class CDmElement; +class IDmeOperator; +class IElementForKeyValueCallback; + +struct DmValueBase_t; +class CUtlBuffer; +class KeyValues; +class CUtlSymbolTable; +class CUtlCharConversion; + + +//----------------------------------------------------------------------------- +// data file format info +//----------------------------------------------------------------------------- +#define DMX_LEGACY_VERSION_STARTING_TOKEN "" + +#define DMX_VERSION_STARTING_TOKEN "" + +#define GENERIC_DMX_FORMAT "dmx" + + +enum +{ + DMX_MAX_FORMAT_NAME_MAX_LENGTH = 64, + DMX_MAX_HEADER_LENGTH = 40 + 2 * DMX_MAX_FORMAT_NAME_MAX_LENGTH, +}; + +struct DmxHeader_t +{ + char encodingName[ DMX_MAX_FORMAT_NAME_MAX_LENGTH ]; + int nEncodingVersion; + char formatName[ DMX_MAX_FORMAT_NAME_MAX_LENGTH ]; + int nFormatVersion; + + DmxHeader_t() : nEncodingVersion( -1 ), nFormatVersion( -1 ) + { + encodingName[ 0 ] = formatName[ 0 ] = '\0'; + } +}; + + +//----------------------------------------------------------------------------- +// element framework phases +//----------------------------------------------------------------------------- +enum DmPhase_t +{ + PH_EDIT, + PH_EDIT_APPLY, + PH_EDIT_RESOLVE, + PH_DEPENDENCY, + PH_OPERATE, + PH_OPERATE_RESOLVE, + PH_OUTPUT, +}; + + +//----------------------------------------------------------------------------- +// file id - also used to refer to elements that don't have file associations +//----------------------------------------------------------------------------- +enum DmFileId_t +{ + DMFILEID_INVALID = 0xffffffff +}; + +//----------------------------------------------------------------------------- +// Handle to an CDmAttribute +//----------------------------------------------------------------------------- +enum DmAttributeHandle_t +{ + DMATTRIBUTE_HANDLE_INVALID = 0xffffffff +}; + +//----------------------------------------------------------------------------- +// Handle to an DmAttributeList_t +//----------------------------------------------------------------------------- +enum DmAttributeReferenceIterator_t +{ + DMATTRIBUTE_REFERENCE_ITERATOR_INVALID = 0 +}; + +//----------------------------------------------------------------------------- +// element framework interface +//----------------------------------------------------------------------------- +abstract_class IDmElementFramework : public IAppSystem +{ +public: + // Methods of IAppSystem + virtual bool Connect( CreateInterfaceFn factory ) = 0; + virtual void Disconnect() = 0; + virtual void *QueryInterface( const char *pInterfaceName ) = 0; + virtual InitReturnVal_t Init() = 0; + virtual void Shutdown() = 0; + + virtual DmPhase_t GetPhase() = 0; + + virtual void SetOperators( const CUtlVector< IDmeOperator* > &operators ) = 0; + + virtual void BeginEdit() = 0; // ends in edit phase, forces apply/resolve if from edit phase + virtual void Operate( bool bResolve ) = 0; // ends in output phase + virtual void Resolve() = 0; +}; + + +//----------------------------------------------------------------------------- +// Used only by aplpications to hook in the element framework +//----------------------------------------------------------------------------- +#define VDMELEMENTFRAMEWORK_VERSION "VDmElementFrameworkVersion001" + + +//----------------------------------------------------------------------------- +// Main interface +//----------------------------------------------------------------------------- +extern IDmElementFramework *g_pDmElementFramework; + + +//----------------------------------------------------------------------------- +// datamodel operator interface - for all elements that need to be sorted in the operator dependency graph +//----------------------------------------------------------------------------- +abstract_class IDmeOperator +{ +public: + virtual bool IsDirty() = 0; // ie needs to operate + virtual void Operate() = 0; + + virtual void GetInputAttributes ( CUtlVector< CDmAttribute * > &attrs ) = 0; + virtual void GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs ) = 0; +}; + +//----------------------------------------------------------------------------- +// Class factory methods: +//----------------------------------------------------------------------------- +class IDmElementFactory +{ +public: + // Creation, destruction + virtual CDmElement* Create( DmElementHandle_t handle, const char *pElementType, const char *pElementName, DmFileId_t fileid, const DmObjectId_t &id ) = 0; + virtual void Destroy( DmElementHandle_t hElement ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Various serialization methods can be installed into the data model factory +//----------------------------------------------------------------------------- +enum DmConflictResolution_t +{ + CR_DELETE_NEW, + CR_DELETE_OLD, + CR_COPY_NEW, + CR_FORCE_COPY, +}; + +// convert files to elements and back +// current file encodings supported: binary, xml, xml_flat, keyvalues2, keyvalues2_flat, keyvalues (vmf/vmt/actbusy), text? (qc/obj) +class IDmSerializer +{ +public: + virtual const char *GetName() const = 0; + virtual const char *GetDescription() const = 0; + virtual bool IsBinaryFormat() const = 0; + virtual bool StoresVersionInFile() const = 0; + virtual int GetCurrentVersion() const = 0; + + // Write into the UtlBuffer, return true if successful + // if we decide to implement non-identity conversions between formats on write, then the source and dest format will need to be passed in here + virtual bool Serialize( CUtlBuffer &buf, CDmElement *pRoot ) = 0; + + // Read from the UtlBuffer, return true if successful, and return the read-in root in ppRoot. + virtual bool Unserialize( CUtlBuffer &buf, const char *pEncodingName, int nEncodingVersion, + const char *pSourceFormatName, int nSourceFormatVersion, + DmFileId_t fileid, DmConflictResolution_t idConflictResolution, CDmElement **ppRoot ) = 0; +}; + +// convert legacy elements to non-legacy elements +// legacy formats include: sfm_vN, binary_vN, keyvalues2_v1, keyvalues2_flat_v1, xml, xml_flat +// where N is a version number (1..9 for sfm, 1..2 for binary) +class IDmLegacyUpdater +{ +public: + virtual const char *GetName() const = 0; + virtual bool IsLatestVersion() const = 0; + + // Updates ppRoot to first non-legacy generic dmx format, returns false if the conversion fails + virtual bool Update( CDmElement **ppRoot ) = 0; +}; + +// converts old elements to new elements +// current formats include: sfm session, animset presets, particle definitions, exported maya character, etc. +class IDmFormatUpdater +{ +public: + virtual const char *GetName() const = 0; + virtual const char *GetDescription() const = 0; + virtual const char *GetExtension() const = 0; + virtual int GetCurrentVersion() const = 0; + virtual const char *GetDefaultEncoding() const = 0; + + // Converts pSourceRoot from nSourceVersion to the current version, returns false if the conversion fails + virtual bool Update( CDmElement **pRoot, int nSourceVersion ) = 0; +}; + +//----------------------------------------------------------------------------- +// Interface for callbacks to supply element types for specific keys inside keyvalues files +//----------------------------------------------------------------------------- +class IElementForKeyValueCallback +{ +public: + virtual const char *GetElementForKeyValue( const char *pszKeyName, int iNestingLevel ) = 0; +}; + +//----------------------------------------------------------------------------- +// Purpose: Optional helper passed in with clipboard data which is called when it's time to clean up the clipboard data in case the application +// had some dynamically allocated data attached to a KV SetPtr object... +//----------------------------------------------------------------------------- +abstract_class IClipboardCleanup +{ +public: + virtual void ReleaseClipboardData( CUtlVector< KeyValues * >& list ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Purpose: Can be installed to be called back when data changes +//----------------------------------------------------------------------------- +enum DmNotifySource_t +{ + // Sources + NOTIFY_SOURCE_APPLICATION = 0, + NOTIFY_SOURCE_UNDO, + NOTIFY_SOURCE_FIRST_DME_CONTROL_SOURCE = 4, // Sources from dme_controls starts here + NOTIFY_SOURCE_FIRST_APPLICATION_SOURCE = 8, // Sources from applications starts here +}; + +enum DmNotifyFlags_t +{ + // Does this dirty the document? + NOTIFY_SOURCE_BITS = 8, + NOTIFY_SETDIRTYFLAG = (1<& list ) = 0; + + virtual void AddUndoElement( IUndoElement *pElement ) = 0; + virtual UtlSymId_t GetUndoDescInternal( const char *context ) = 0; + virtual UtlSymId_t GetRedoDescInternal( const char *context ) = 0; + + virtual void EmptyClipboard() = 0; + virtual void SetClipboardData( CUtlVector< KeyValues * >& data, IClipboardCleanup *pfnOptionalCleanuFunction = 0 ) = 0; + virtual void AddToClipboardData( KeyValues *add ) = 0; + virtual void GetClipboardData( CUtlVector< KeyValues * >& data ) = 0; + virtual bool HasClipboardData() const = 0; + + // Handles to attributes + virtual CDmAttribute * GetAttribute( DmAttributeHandle_t h ) = 0; + virtual bool IsAttributeHandleValid( DmAttributeHandle_t h ) const = 0; + + // file id reference methods + virtual int NumFileIds() = 0; + virtual DmFileId_t GetFileId( int i ) = 0; + virtual DmFileId_t FindOrCreateFileId( const char *pFilename ) = 0; + virtual void RemoveFileId( DmFileId_t fileid ) = 0; + virtual DmFileId_t GetFileId( const char *pFilename ) = 0; + virtual const char * GetFileName( DmFileId_t fileid ) = 0; + virtual void SetFileName( DmFileId_t fileid, const char *pFileName ) = 0; + virtual const char * GetFileFormat( DmFileId_t fileid ) = 0; + virtual void SetFileFormat( DmFileId_t fileid, const char *pFormat ) = 0; + virtual DmElementHandle_t GetFileRoot( DmFileId_t fileid ) = 0; + virtual void SetFileRoot( DmFileId_t fileid, DmElementHandle_t hRoot ) = 0; + virtual bool IsFileLoaded( DmFileId_t fileid ) = 0; + virtual void MarkFileLoaded( DmFileId_t fileid ) = 0; + virtual void UnloadFile( DmFileId_t fileid ) = 0; + virtual int NumElementsInFile( DmFileId_t fileid ) = 0; + + virtual void DontAutoDelete( DmElementHandle_t hElement ) = 0; + + // handle validity methods - these shouldn't really be here, but the undo system needs them... + virtual void MarkHandleInvalid( DmElementHandle_t hElement ) = 0; + virtual void MarkHandleValid( DmElementHandle_t hElement ) = 0; + + virtual DmElementHandle_t FindElement( const DmObjectId_t &id ) = 0; + + virtual DmAttributeReferenceIterator_t FirstAttributeReferencingElement( DmElementHandle_t hElement ) = 0; + virtual DmAttributeReferenceIterator_t NextAttributeReferencingElement( DmAttributeReferenceIterator_t hAttrIter ) = 0; + virtual CDmAttribute * GetAttribute( DmAttributeReferenceIterator_t hAttrIter ) = 0; + + // Install, remove notify callbacks associated w/ undo contexts + virtual bool InstallNotificationCallback( IDmNotify *pNotify ) = 0; + virtual void RemoveNotificationCallback( IDmNotify *pNotify ) = 0; + virtual bool IsSuppressingNotify( ) const = 0; + virtual void SetSuppressingNotify( bool bSuppress ) = 0; + virtual void PushNotificationScope( const char *pReason, int nNotifySource, int nNotifyFlags ) = 0; + virtual void PopNotificationScope( bool bAbort = false ) = 0; + virtual const char *GetUndoString( UtlSymId_t sym ) = 0; + + virtual bool HasElementFactory( const char *pElementType ) const = 0; + + // Call before you make any undo records + virtual void SetUndoDepth( int nSize ) = 0; + + // Displats memory stats to the console + virtual void DisplayMemoryStats() = 0; +}; + + +//----------------------------------------------------------------------------- +// Used only by applications to hook in the data model +//----------------------------------------------------------------------------- +#define VDATAMODEL_INTERFACE_VERSION "VDataModelVersion001" + + +//----------------------------------------------------------------------------- +// Main interface accessor +//----------------------------------------------------------------------------- +extern IDataModel *g_pDataModel; + + +//----------------------------------------------------------------------------- +// Allows clients to implement customized undo elements +//----------------------------------------------------------------------------- +class CUndoElement : public IUndoElement +{ +public: + CUndoElement( const char *pDesc ) + { + m_UndoDesc = g_pDataModel->GetUndoDescInternal( pDesc ); + m_RedoDesc = g_pDataModel->GetRedoDescInternal( pDesc ); + m_pDesc = pDesc; + m_bEndOfStream = false; + } + + virtual void Release() + { + delete this; + } + + virtual const char *UndoDesc() const + { + return g_pDataModel->GetUndoString( m_UndoDesc ); + } + + virtual const char *RedoDesc() const + { + return g_pDataModel->GetUndoString( m_RedoDesc ); + } + + virtual const char *GetDesc() const + { + return m_pDesc; + } + +protected: + virtual bool IsEndOfStream() const + { + return m_bEndOfStream; + } + + virtual void SetEndOfStream( bool end ) + { + m_bEndOfStream = end; + } + + const char *m_pDesc; + CUtlSymbol m_UndoDesc; + CUtlSymbol m_RedoDesc; + bool m_bEndOfStream; + +private: + friend class CUndoManager; +}; + + +//----------------------------------------------------------------------------- +// Purpose: Simple helper class +//----------------------------------------------------------------------------- +class CUndoScopeGuard +{ +public: + explicit CUndoScopeGuard( const char *udesc, const char *rdesc = NULL ) + { + m_bReleased = false; + m_bNotify = false; + m_pNotify = NULL; + g_pDataModel->StartUndo( udesc, rdesc ? rdesc : udesc ); + } + + explicit CUndoScopeGuard( int nChainingID, char const *udesc ) + { + m_bReleased = false; + m_bNotify = false; + m_pNotify = NULL; + g_pDataModel->StartUndo( udesc, udesc, nChainingID ); + } + + explicit CUndoScopeGuard( int nNotifySource, int nNotifyFlags, const char *udesc, const char *rdesc = NULL, int nChainingID = 0 ) + { + m_bReleased = false; + m_bNotify = true; + m_pNotify = NULL; + g_pDataModel->StartUndo( udesc, rdesc ? rdesc : udesc, nChainingID ); + g_pDataModel->PushNotificationScope( udesc, nNotifySource, nNotifyFlags ); + } + + explicit CUndoScopeGuard( int nNotifySource, int nNotifyFlags, IDmNotify *pNotify, const char *udesc, const char *rdesc = NULL, int nChainingID = 0 ) + { + m_bReleased = false; + m_bNotify = true; + m_pNotify = NULL; + g_pDataModel->StartUndo( udesc, rdesc ? rdesc : udesc, nChainingID ); + if ( pNotify ) + { + if ( g_pDataModel->InstallNotificationCallback( pNotify ) ) + { + m_pNotify = pNotify; + } + } + g_pDataModel->PushNotificationScope( udesc, nNotifySource, nNotifyFlags ); + } + + ~CUndoScopeGuard() + { + Release(); + } + + void Release() + { + if ( !m_bReleased ) + { + g_pDataModel->FinishUndo(); + if ( m_bNotify ) + { + g_pDataModel->PopNotificationScope( ); + m_bNotify = false; + } + if ( m_pNotify ) + { + g_pDataModel->RemoveNotificationCallback( m_pNotify ); + m_pNotify = NULL; + } + m_bReleased = true; + } + } + + void Abort() + { + if ( !m_bReleased ) + { + g_pDataModel->AbortUndoableOperation(); + if ( m_bNotify ) + { + g_pDataModel->PopNotificationScope( true ); + m_bNotify = false; + } + if ( m_pNotify ) + { + g_pDataModel->RemoveNotificationCallback( m_pNotify ); + m_pNotify = NULL; + } + m_bReleased = true; + } + } + +private: + IDmNotify *m_pNotify; + bool m_bReleased; + bool m_bNotify; +}; + + +//----------------------------------------------------------------------------- +// Purpose: Simple helper class to disable Undo/Redo operations when in scope +//----------------------------------------------------------------------------- +class CChangeUndoScopeGuard +{ +public: + CChangeUndoScopeGuard( bool bNewState ) + { + m_bReleased = false; + m_bNotify = false; + m_pNotify = NULL; + m_bOldValue = g_pDataModel->IsUndoEnabled(); + g_pDataModel->SetUndoEnabled( bNewState ); + }; + + CChangeUndoScopeGuard( bool bNewState, const char *pDesc, int nNotifySource, int nNotifyFlags, IDmNotify *pNotify = NULL ) + { + m_bReleased = false; + m_bOldValue = g_pDataModel->IsUndoEnabled(); + g_pDataModel->SetUndoEnabled( bNewState ); + + m_bNotify = true; + m_pNotify = NULL; + if ( pNotify ) + { + if ( g_pDataModel->InstallNotificationCallback( pNotify ) ) + { + m_pNotify = pNotify; + } + } + g_pDataModel->PushNotificationScope( pDesc, nNotifySource, nNotifyFlags ); + }; + + ~CChangeUndoScopeGuard() + { + Release(); + } + + void Release() + { + // Releases the guard... + if ( !m_bReleased ) + { + g_pDataModel->SetUndoEnabled( m_bOldValue ); + m_bReleased = true; + if ( m_bNotify ) + { + g_pDataModel->PopNotificationScope( ); + m_bNotify = false; + } + if ( m_pNotify ) + { + g_pDataModel->RemoveNotificationCallback( m_pNotify ); + m_pNotify = NULL; + } + } + } + +private: + IDmNotify *m_pNotify; + bool m_bOldValue; + bool m_bReleased; + bool m_bNotify; +}; + +class CDisableUndoScopeGuard : public CChangeUndoScopeGuard +{ + typedef CChangeUndoScopeGuard BaseClass; + +public: + CDisableUndoScopeGuard() : BaseClass( false ) { } + CDisableUndoScopeGuard( const char *pDesc, int nNotifySource, int nNotifyFlags, IDmNotify *pNotify = NULL ) : + BaseClass( false, pDesc, nNotifySource, nNotifyFlags, pNotify ) {} +}; + +class CEnableUndoScopeGuard : public CChangeUndoScopeGuard +{ + typedef CChangeUndoScopeGuard BaseClass; + +public: + CEnableUndoScopeGuard( ) : BaseClass( true ) { } + CEnableUndoScopeGuard( const char *pDesc, int nNotifySource, int nNotifyFlags, IDmNotify *pNotify = NULL ) : + BaseClass( true, pDesc, nNotifySource, nNotifyFlags, pNotify ) {} +}; + + +#define DEFINE_SOURCE_UNDO_SCOPE_GUARD( _classnameprefix, _source ) \ + class C ## _classnameprefix ## UndoScopeGuard : public CUndoScopeGuard \ + { \ + typedef CUndoScopeGuard BaseClass; \ + \ + public: \ + C ## _classnameprefix ## UndoScopeGuard( int nNotifyFlags, const char *pUndoDesc, const char *pRedoDesc = NULL, int nChainingID = 0 ) : \ + BaseClass( _source, nNotifyFlags, pUndoDesc, pRedoDesc, nChainingID ) \ + { \ + } \ + C ## _classnameprefix ## UndoScopeGuard( int nNotifyFlags, IDmNotify *pNotify, const char *pUndoDesc, const char *pRedoDesc = NULL, int nChainingID = 0 ) : \ + BaseClass( _source, nNotifyFlags, pNotify, pUndoDesc, pRedoDesc, nChainingID ) \ + { \ + } \ + C ## _classnameprefix ## UndoScopeGuard( int nNotifyFlags, const char *pUndoDesc, int nChainingID ) : \ + BaseClass( _source, nNotifyFlags, pUndoDesc, pUndoDesc, nChainingID ) \ + { \ + } \ + }; \ + class C ## _classnameprefix ## DisableUndoScopeGuard : public CDisableUndoScopeGuard \ + { \ + typedef CDisableUndoScopeGuard BaseClass; \ + \ + public: \ + C ## _classnameprefix ## DisableUndoScopeGuard( const char *pDesc, int nNotifyFlags, IDmNotify *pNotify = NULL ) : \ + BaseClass( pDesc, _source, nNotifyFlags, pNotify ) \ + { \ + } \ + }; \ + class C ## _classnameprefix ## EnableUndoScopeGuard : public CEnableUndoScopeGuard \ + { \ + typedef CEnableUndoScopeGuard BaseClass; \ + \ + public: \ + C ## _classnameprefix ## EnableUndoScopeGuard( const char *pDesc, int nNotifyFlags, IDmNotify *pNotify = NULL ) : \ + BaseClass( pDesc, _source, nNotifyFlags, pNotify ) \ + { \ + } \ + } + + +//----------------------------------------------------------------------------- +// Purpose: Simple helper class to disable NotifyDataChanged from current scope +//----------------------------------------------------------------------------- +class CNotifyScopeGuard +{ +public: + CNotifyScopeGuard( const char *pReason, int nNotifySource, int nNotifyFlags, IDmNotify *pNotify = NULL ) + { + m_bReleased = false; + m_pNotify = NULL; + g_pDataModel->PushNotificationScope( pReason, nNotifySource, nNotifyFlags ); + if ( pNotify ) + { + if ( g_pDataModel->InstallNotificationCallback( pNotify ) ) + { + m_pNotify = pNotify; + } + } + }; + + ~CNotifyScopeGuard() + { + Release(); + } + + void Release() + { + // Releases the guard... + if ( !m_bReleased ) + { + g_pDataModel->PopNotificationScope( ); + if ( m_pNotify ) + { + g_pDataModel->RemoveNotificationCallback( m_pNotify ); + m_pNotify = NULL; + } + m_bReleased = true; + } + } + +private: + CNotifyScopeGuard( const CNotifyScopeGuard& g ); + +private: + IDmNotify *m_pNotify; + bool m_bReleased; +}; + + +#define DEFINE_SOURCE_NOTIFY_SCOPE_GUARD( _classnameprefix, _source ) \ + class C ## _classnameprefix ## NotifyScopeGuard : public CNotifyScopeGuard \ + { \ + typedef CNotifyScopeGuard BaseClass; \ + \ + public: \ + C ## _classnameprefix ## NotifyScopeGuard( const char *pReason, int nNotifyFlags, IDmNotify *pNotify = NULL ) : \ + BaseClass( pReason, _source, nNotifyFlags, pNotify )\ + { \ + } \ + } + + +//----------------------------------------------------------------------------- +// Purpose: Simple helper class to disable notifications when in scope +//----------------------------------------------------------------------------- +class CChangeNotifyScopeGuard +{ +public: + CChangeNotifyScopeGuard( bool bNewState ) + { + m_bReleased = false; + m_bOldValue = g_pDataModel->IsSuppressingNotify(); + g_pDataModel->SetSuppressingNotify( bNewState ); + }; + + ~CChangeNotifyScopeGuard() + { + Release(); + } + + void Release() + { + // Releases the guard... + if ( !m_bReleased ) + { + g_pDataModel->SetSuppressingNotify( m_bOldValue ); + m_bReleased = true; + } + } + +private: + bool m_bOldValue; + bool m_bReleased; +}; + +class CDisableNotifyScopeGuard : public CChangeNotifyScopeGuard +{ + typedef CChangeNotifyScopeGuard BaseClass; + +public: + CDisableNotifyScopeGuard() : BaseClass( true ) { } + +private: + CDisableNotifyScopeGuard( const CDisableNotifyScopeGuard& g ); +}; + +class CEnableNotifyScopeGuard : public CChangeNotifyScopeGuard +{ + typedef CChangeNotifyScopeGuard BaseClass; + +public: + CEnableNotifyScopeGuard( ) : BaseClass( false ) { } + +private: + CEnableNotifyScopeGuard( const CEnableNotifyScopeGuard& g ); +}; + + +//----------------------------------------------------------------------------- +// Standard undo/notify guards for the application +//----------------------------------------------------------------------------- +DEFINE_SOURCE_UNDO_SCOPE_GUARD( App, NOTIFY_SOURCE_APPLICATION ); +DEFINE_SOURCE_NOTIFY_SCOPE_GUARD( App, NOTIFY_SOURCE_APPLICATION ); + + + +#endif // IDATAMODEL_H diff --git a/sp/src/public/demofile/demoformat.h b/sp/src/public/demofile/demoformat.h new file mode 100644 index 00000000..6ddbe56e --- /dev/null +++ b/sp/src/public/demofile/demoformat.h @@ -0,0 +1,250 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef DEMOFORMAT_H +#define DEMOFORMAT_H +#ifdef _WIN32 +#pragma once +#endif + +#include "mathlib/vector.h" +#include "utlvector.h" +#include "tier0/platform.h" + +#define DEMO_HEADER_ID "HL2DEMO" +#define DEMO_PROTOCOL 3 + +#if !defined( MAX_OSPATH ) +#define MAX_OSPATH 260 // max length of a filesystem pathname +#endif + +// Demo messages +enum +{ + // it's a startup message, process as fast as possible + dem_signon = 1, + // it's a normal network packet that we stored off + dem_packet, + // sync client clock to demo tick + dem_synctick, + // console command + dem_consolecmd, + // user input command + dem_usercmd, + // network data tables + dem_datatables, + // end of time. + dem_stop, + + dem_stringtables, + + // Last command + dem_lastcmd = dem_stringtables +}; + +struct demoheader_t +{ + char demofilestamp[8]; // Should be HL2DEMO + int demoprotocol; // Should be DEMO_PROTOCOL + int networkprotocol; // Should be PROTOCOL_VERSION + char servername[ MAX_OSPATH ]; // Name of server + char clientname[ MAX_OSPATH ]; // Name of client who recorded the game + char mapname[ MAX_OSPATH ]; // Name of map + char gamedirectory[ MAX_OSPATH ]; // Name of game directory (com_gamedir) + float playback_time; // Time of track + int playback_ticks; // # of ticks in track + int playback_frames; // # of frames in track + int signonlength; // length of sigondata in bytes +}; + +inline void ByteSwap_demoheader_t( demoheader_t &swap ) +{ + swap.demoprotocol = LittleDWord( swap.demoprotocol ); + swap.networkprotocol = LittleDWord( swap.networkprotocol ); + LittleFloat( &swap.playback_time, &swap.playback_time ); + swap.playback_ticks = LittleDWord( swap.playback_ticks ); + swap.playback_frames = LittleDWord( swap.playback_frames ); + swap.signonlength = LittleDWord( swap.signonlength ); +} + +#define FDEMO_NORMAL 0 +#define FDEMO_USE_ORIGIN2 (1<<0) +#define FDEMO_USE_ANGLES2 (1<<1) +#define FDEMO_NOINTERP (1<<2) // don't interpolate between this an last view + +struct democmdinfo_t +{ + // Default constructor + democmdinfo_t() + { + flags = FDEMO_NORMAL; + viewOrigin.Init(); + viewAngles.Init(); + localViewAngles.Init(); + + // Resampled origin/angles + viewOrigin2.Init(); + viewAngles2.Init(); + localViewAngles2.Init(); + } + + // Copy constructor + // Assignment + democmdinfo_t& operator=(const democmdinfo_t& src ) + { + if ( this == &src ) + return *this; + + flags = src.flags; + viewOrigin = src.viewOrigin; + viewAngles = src.viewAngles; + localViewAngles = src.localViewAngles; + viewOrigin2 = src.viewOrigin2; + viewAngles2 = src.viewAngles2; + localViewAngles2 = src.localViewAngles2; + + return *this; + } + + const Vector& GetViewOrigin() + { + if ( flags & FDEMO_USE_ORIGIN2 ) + { + return viewOrigin2; + } + return viewOrigin; + } + + const QAngle& GetViewAngles() + { + if ( flags & FDEMO_USE_ANGLES2 ) + { + return viewAngles2; + } + return viewAngles; + } + const QAngle& GetLocalViewAngles() + { + if ( flags & FDEMO_USE_ANGLES2 ) + { + return localViewAngles2; + } + return localViewAngles; + } + + void Reset( void ) + { + flags = 0; + viewOrigin2 = viewOrigin; + viewAngles2 = viewAngles; + localViewAngles2 = localViewAngles; + } + + int flags; + + // original origin/viewangles + Vector viewOrigin; + QAngle viewAngles; + QAngle localViewAngles; + + // Resampled origin/viewangles + Vector viewOrigin2; + QAngle viewAngles2; + QAngle localViewAngles2; +}; + +struct demosmoothing_t +{ + demosmoothing_t() + { + file_offset = 0; + frametick = 0; + selected = false; + samplepoint = false; + + vecmoved.Init(); + angmoved.Init(); + + targetpoint = false; + vectarget.Init(); + } + + demosmoothing_t& operator=(const demosmoothing_t& src ) + { + if ( this == &src ) + return *this; + + file_offset = src.file_offset; + frametick = src.frametick; + selected = src.selected; + samplepoint = src.samplepoint; + vecmoved = src.vecmoved; + angmoved = src.angmoved; + + targetpoint = src.targetpoint; + vectarget = src.vectarget; + + info = src.info; + + return *this; + } + + int file_offset; + + int frametick; + + bool selected; + + // For moved sample points + bool samplepoint; + Vector vecmoved; + QAngle angmoved; + + bool targetpoint; + Vector vectarget; + + democmdinfo_t info; +}; + +struct CSmoothingContext +{ + CSmoothingContext() + { + active = false; + filename[ 0 ] = 0; + m_nFirstSelectableSample = 0; + } + + CSmoothingContext& operator=(const CSmoothingContext& src ) + { + if ( this == &src ) + return *this; + + active = src.active; + Q_strncpy( filename, src.filename, sizeof( filename ) ); + + smooth.RemoveAll(); + int c = src.smooth.Count(); + int i; + for ( i = 0; i < c; i++ ) + { + demosmoothing_t newitem; + newitem = src.smooth[ i ]; + smooth.AddToTail( newitem ); + } + + m_nFirstSelectableSample = src.m_nFirstSelectableSample; + + return *this; + } + + bool active; + char filename[ 512 ]; + CUtlVector< demosmoothing_t > smooth; + int m_nFirstSelectableSample; +}; + +#endif // DEMOFORMAT_H diff --git a/sp/src/public/discord_register.h b/sp/src/public/discord_register.h new file mode 100644 index 00000000..16fb42f3 --- /dev/null +++ b/sp/src/public/discord_register.h @@ -0,0 +1,26 @@ +#pragma once + +#if defined(DISCORD_DYNAMIC_LIB) +#if defined(_WIN32) +#if defined(DISCORD_BUILDING_SDK) +#define DISCORD_EXPORT __declspec(dllexport) +#else +#define DISCORD_EXPORT __declspec(dllimport) +#endif +#else +#define DISCORD_EXPORT __attribute__((visibility("default"))) +#endif +#else +#define DISCORD_EXPORT +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command); +DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, const char* steamId); + +#ifdef __cplusplus +} +#endif diff --git a/sp/src/public/discord_rpc.h b/sp/src/public/discord_rpc.h new file mode 100644 index 00000000..3e1441e0 --- /dev/null +++ b/sp/src/public/discord_rpc.h @@ -0,0 +1,87 @@ +#pragma once +#include + +// clang-format off + +#if defined(DISCORD_DYNAMIC_LIB) +# if defined(_WIN32) +# if defined(DISCORD_BUILDING_SDK) +# define DISCORD_EXPORT __declspec(dllexport) +# else +# define DISCORD_EXPORT __declspec(dllimport) +# endif +# else +# define DISCORD_EXPORT __attribute__((visibility("default"))) +# endif +#else +# define DISCORD_EXPORT +#endif + +// clang-format on + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DiscordRichPresence { + const char* state; /* max 128 bytes */ + const char* details; /* max 128 bytes */ + int64_t startTimestamp; + int64_t endTimestamp; + const char* largeImageKey; /* max 32 bytes */ + const char* largeImageText; /* max 128 bytes */ + const char* smallImageKey; /* max 32 bytes */ + const char* smallImageText; /* max 128 bytes */ + const char* partyId; /* max 128 bytes */ + int partySize; + int partyMax; + const char* matchSecret; /* max 128 bytes */ + const char* joinSecret; /* max 128 bytes */ + const char* spectateSecret; /* max 128 bytes */ + int8_t instance; +} DiscordRichPresence; + +typedef struct DiscordUser { + const char* userId; + const char* username; + const char* discriminator; + const char* avatar; +} DiscordUser; + +typedef struct DiscordEventHandlers { + void (*ready)(const DiscordUser* request); + void (*disconnected)(int errorCode, const char* message); + void (*errored)(int errorCode, const char* message); + void (*joinGame)(const char* joinSecret); + void (*spectateGame)(const char* spectateSecret); + void (*joinRequest)(const DiscordUser* request); +} DiscordEventHandlers; + +#define DISCORD_REPLY_NO 0 +#define DISCORD_REPLY_YES 1 +#define DISCORD_REPLY_IGNORE 2 + +DISCORD_EXPORT void Discord_Initialize(const char* applicationId, + DiscordEventHandlers* handlers, + int autoRegister, + const char* optionalSteamId); +DISCORD_EXPORT void Discord_Shutdown(void); + +/* checks for incoming messages, dispatches callbacks */ +DISCORD_EXPORT void Discord_RunCallbacks(void); + +/* If you disable the lib starting its own io thread, you'll need to call this from your own */ +#ifdef DISCORD_DISABLE_IO_THREAD +DISCORD_EXPORT void Discord_UpdateConnection(void); +#endif + +DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence); +DISCORD_EXPORT void Discord_ClearPresence(void); + +DISCORD_EXPORT void Discord_Respond(const char* userid, /* DISCORD_REPLY_ */ int reply); + +DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* handlers); + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/sp/src/public/disp_common.cpp b/sp/src/public/disp_common.cpp new file mode 100644 index 00000000..0c2ac51b --- /dev/null +++ b/sp/src/public/disp_common.cpp @@ -0,0 +1,1296 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "disp_common.h" +#include "disp_powerinfo.h" +#include "builddisp.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +class CNodeVert +{ +public: + CNodeVert() {} + CNodeVert( int ix, int iy ) {x=ix; y=iy;} + + inline int& operator[]( int i ) {return ((int*)this)[i];} + inline int const& operator[]( int i ) const {return ((int*)this)[i];} + + int x, y; +}; + +static CNodeVert const g_NodeChildLookup[4][2] = +{ + {CNodeVert(0,0), CNodeVert(1,1)}, + {CNodeVert(1,0), CNodeVert(2,1)}, + {CNodeVert(0,1), CNodeVert(1,2)}, + {CNodeVert(1,1), CNodeVert(2,2)} +}; + +static CNodeVert const g_NodeTriWinding[9] = +{ + CNodeVert(0, 1), + CNodeVert(0, 0), + CNodeVert(1, 0), + CNodeVert(2, 0), + CNodeVert(2, 1), + CNodeVert(2, 2), + CNodeVert(1, 2), + CNodeVert(0, 2), + CNodeVert(0, 1) +}; + +// Indexed by CORNER_. These store NEIGHBOREDGE_ defines and tell which edges butt up against the corner. +static int g_CornerEdges[4][2] = +{ + { NEIGHBOREDGE_BOTTOM, NEIGHBOREDGE_LEFT }, // CORNER_LOWER_LEFT + { NEIGHBOREDGE_TOP, NEIGHBOREDGE_LEFT }, // CORNER_UPPER_LEFT + { NEIGHBOREDGE_TOP, NEIGHBOREDGE_RIGHT }, // CORNER_UPPER_RIGHT + { NEIGHBOREDGE_BOTTOM, NEIGHBOREDGE_RIGHT } // CORNER_LOWER_RIGHT +}; + +int g_EdgeDims[4] = +{ + 0, // NEIGHBOREDGE_LEFT = X + 1, // NEIGHBOREDGE_TOP = Y + 0, // NEIGHBOREDGE_RIGHT = X + 1 // NEIGHBOREDGE_BOTTOM = Y +}; + +CShiftInfo g_ShiftInfos[3][3] = +{ + { + {0, 0, true}, // CORNER_TO_CORNER -> CORNER_TO_CORNER + {0, -1, true}, // CORNER_TO_CORNER -> CORNER_TO_MIDPOINT + {2, -1, true} // CORNER_TO_CORNER -> MIDPOINT_TO_CORNER + }, + + { + {0, 1, true}, // CORNER_TO_MIDPOINT -> CORNER_TO_CORNER + {0, 0, false}, // CORNER_TO_MIDPOINT -> CORNER_TO_MIDPOINT (invalid) + {0, 0, false} // CORNER_TO_MIDPOINT -> MIDPOINT_TO_CORNER (invalid) + }, + + { + {-1, 1, true}, // MIDPOINT_TO_CORNER -> CORNER_TO_CORNER + {0, 0, false}, // MIDPOINT_TO_CORNER -> CORNER_TO_MIDPOINT (invalid) + {0, 0, false} // MIDPOINT_TO_CORNER -> MIDPOINT_TO_CORNER (invalid) + } +}; + +int g_EdgeSideLenMul[4] = +{ + 0, + 1, + 1, + 0 +}; + + +// --------------------------------------------------------------------------------- // +// Helper functions. +// --------------------------------------------------------------------------------- // + +inline int SignedBitShift( int val, int shift ) +{ + if( shift > 0 ) + return val << shift; + else + return val >> -shift; +} + +static inline void RotateVertIndex( + NeighborOrientation neighor, + int sideLengthMinus1, + CVertIndex const &in, + CVertIndex &out ) +{ + if( neighor == ORIENTATION_CCW_0 ) + { + out = in; + } + else if( neighor == ORIENTATION_CCW_90 ) + { + out.x = in.y; + out.y = sideLengthMinus1 - in.x; + } + else if( neighor == ORIENTATION_CCW_180 ) + { + out.x = sideLengthMinus1 - in.x; + out.y = sideLengthMinus1 - in.y; + } + else + { + out.x = sideLengthMinus1 - in.y; + out.y = in.x; + } +} + +static inline void RotateVertIncrement( + NeighborOrientation neighor, + CVertIndex const &in, + CVertIndex &out ) +{ + if( neighor == ORIENTATION_CCW_0 ) + { + out = in; + } + else if( neighor == ORIENTATION_CCW_90 ) + { + out.x = in.y; + out.y = -in.x; + } + else if( neighor == ORIENTATION_CCW_180 ) + { + out.x = -in.x; + out.y = -in.y; + } + else + { + out.x = -in.y; + out.y = in.x; + } +} + + +// --------------------------------------------------------------------------------- // +// CDispHelper functions. +// --------------------------------------------------------------------------------- // + +int GetEdgeIndexFromPoint( CVertIndex const &index, int iMaxPower ) +{ + int sideLengthMinus1 = 1 << iMaxPower; + + if( index.x == 0 ) + return NEIGHBOREDGE_LEFT; + else if( index.y == sideLengthMinus1 ) + return NEIGHBOREDGE_TOP; + else if( index.x == sideLengthMinus1 ) + return NEIGHBOREDGE_RIGHT; + else if( index.y == 0 ) + return NEIGHBOREDGE_BOTTOM; + else + return -1; +} + + +int GetCornerIndexFromPoint( CVertIndex const &index, int iPower ) +{ + int sideLengthMinus1 = 1 << iPower; + + if( index.x == 0 && index.y == 0 ) + return CORNER_LOWER_LEFT; + + else if( index.x == 0 && index.y == sideLengthMinus1 ) + return CORNER_UPPER_LEFT; + + else if( index.x == sideLengthMinus1 && index.y == sideLengthMinus1 ) + return CORNER_UPPER_RIGHT; + + else if( index.x == sideLengthMinus1 && index.y == 0 ) + return CORNER_LOWER_RIGHT; + + else + return -1; +} + + +int GetNeighborEdgePower( CDispUtilsHelper *pDisp, int iEdge, int iSub ) +{ + CDispNeighbor *pEdge = pDisp->GetEdgeNeighbor( iEdge ); + CDispSubNeighbor *pSub = &pEdge->m_SubNeighbors[iSub]; + if ( !pSub->IsValid() ) + return -1; + + CDispUtilsHelper *pNeighbor = pDisp->GetDispUtilsByIndex( pSub->GetNeighborIndex() ); + + CShiftInfo *pInfo = &g_ShiftInfos[pSub->m_Span][pSub->m_NeighborSpan]; + Assert( pInfo->m_bValid ); + + return pNeighbor->GetPower() + pInfo->m_PowerShiftAdd; +} + + +CDispUtilsHelper* SetupEdgeIncrements( + CDispUtilsHelper *pDisp, + int iEdge, + int iSub, + CVertIndex &myIndex, + CVertIndex &myInc, + CVertIndex &nbIndex, + CVertIndex &nbInc, + int &myEnd, + int &iFreeDim ) +{ + int iEdgeDim = g_EdgeDims[iEdge]; + iFreeDim = !iEdgeDim; + + CDispNeighbor *pSide = pDisp->GetEdgeNeighbor( iEdge ); + CDispSubNeighbor *pSub = &pSide->m_SubNeighbors[iSub]; + if ( !pSub->IsValid() ) + return NULL; + + CDispUtilsHelper *pNeighbor = pDisp->GetDispUtilsByIndex( pSub->m_iNeighbor ); + + CShiftInfo *pShiftInfo = &g_ShiftInfos[pSub->m_Span][pSub->m_NeighborSpan]; + Assert( pShiftInfo->m_bValid ); + + // Setup a start point and edge increment (NOTE: just precalculate these + // and store them in the CDispSubNeighbors). + CVertIndex tempInc; + + const CPowerInfo *pPowerInfo = pDisp->GetPowerInfo(); + myIndex[iEdgeDim] = g_EdgeSideLenMul[iEdge] * pPowerInfo->m_SideLengthM1; + myIndex[iFreeDim] = pPowerInfo->m_MidPoint * iSub; + TransformIntoSubNeighbor( pDisp, iEdge, iSub, myIndex, nbIndex ); + + int myPower = pDisp->GetPowerInfo()->m_Power; + int nbPower = pNeighbor->GetPowerInfo()->m_Power + pShiftInfo->m_PowerShiftAdd; + + myInc[iEdgeDim] = tempInc[iEdgeDim] = 0; + if( nbPower > myPower ) + { + myInc[iFreeDim] = 1; + tempInc[iFreeDim] = 1 << (nbPower - myPower); + } + else + { + myInc[iFreeDim] = 1 << (myPower - nbPower); + tempInc[iFreeDim] = 1; + } + RotateVertIncrement( pSub->GetNeighborOrientation(), tempInc, nbInc ); + + // Walk along the edge. + if( pSub->m_Span == CORNER_TO_MIDPOINT ) + myEnd = pDisp->GetPowerInfo()->m_SideLength >> 1; + else + myEnd = pDisp->GetPowerInfo()->m_SideLength - 1; + + return pNeighbor; +} + + +int GetSubNeighborIndex( + CDispUtilsHelper *pDisp, + int iEdge, + CVertIndex const &nodeIndex ) +{ + const CPowerInfo *pPowerInfo = pDisp->GetPowerInfo(); + const CDispNeighbor *pSide = pDisp->GetEdgeNeighbor( iEdge ); + + // Figure out if this is a vertical or horizontal edge. + int iEdgeDim = g_EdgeDims[iEdge]; + int iFreeDim = !iEdgeDim; + + int iFreeIndex = nodeIndex[iFreeDim]; + + // Figure out which of the (up to two) neighbors it lies in. + int iSub = 0; + if( iFreeIndex == pPowerInfo->m_MidPoint ) + { + // If it's in the middle, we only are interested if there's one neighbor + // next to us (so we can enable its middle vert). If there are any neighbors + // that touch the midpoint, then we have no need to return them because it would + // touch their corner verts which are always active. + if( pSide->m_SubNeighbors[0].m_Span != CORNER_TO_CORNER ) + return -1; + } + else if ( iFreeIndex > pPowerInfo->m_MidPoint ) + { + iSub = 1; + } + + // Make sure we get a valid neighbor. + if( !pSide->m_SubNeighbors[iSub].IsValid() ) + { + if( iSub == 1 && + pSide->m_SubNeighbors[0].IsValid() && + pSide->m_SubNeighbors[0].m_Span == CORNER_TO_CORNER ) + { + iSub = 0; + } + else + { + return -1; + } + } + + return iSub; +} + + +void SetupSpan( int iPower, int iEdge, NeighborSpan span, CVertIndex &viStart, CVertIndex &viEnd ) +{ + int iFreeDim = !g_EdgeDims[iEdge]; + const CPowerInfo *pPowerInfo = GetPowerInfo( iPower ); + + viStart = pPowerInfo->GetCornerPointIndex( iEdge ); + viEnd = pPowerInfo->GetCornerPointIndex( (iEdge+1) & 3 );; + + if ( iEdge == NEIGHBOREDGE_RIGHT || iEdge == NEIGHBOREDGE_BOTTOM ) + { + // CORNER_TO_MIDPOINT and MIDPOINT_CORNER are defined where the edge moves up or right, + // but pPowerInfo->GetCornerPointIndex walks around the edges clockwise, so on the + // bottom and right edges (where GetCornerPointIndex has us moving down and left) we need to + // reverse the sense here to make sure we return the right span. + if ( span == CORNER_TO_MIDPOINT ) + viStart[iFreeDim] = pPowerInfo->GetMidPoint(); + else if ( span == MIDPOINT_TO_CORNER ) + viEnd[iFreeDim] = pPowerInfo->GetMidPoint(); + } + else + { + if ( span == CORNER_TO_MIDPOINT ) + viEnd[iFreeDim] = pPowerInfo->GetMidPoint(); + else if ( span == MIDPOINT_TO_CORNER ) + viStart[iFreeDim] = pPowerInfo->GetMidPoint(); + } +} + + +CDispUtilsHelper* TransformIntoSubNeighbor( + CDispUtilsHelper *pDisp, + int iEdge, + int iSub, + CVertIndex const &nodeIndex, + CVertIndex &out + ) +{ + const CDispSubNeighbor *pSub = &pDisp->GetEdgeNeighbor( iEdge )->m_SubNeighbors[iSub]; + + // Find the part of pDisp's edge that this neighbor covers. + CVertIndex viSrcStart, viSrcEnd; + SetupSpan( pDisp->GetPower(), iEdge, pSub->GetSpan(), viSrcStart, viSrcEnd ); + + // Find the corresponding parts on the neighbor. + CDispUtilsHelper *pNeighbor = pDisp->GetDispUtilsByIndex( pSub->GetNeighborIndex() ); + int iNBEdge = (iEdge + 2 + pSub->GetNeighborOrientation()) & 3; + + CVertIndex viDestStart, viDestEnd; + SetupSpan( pNeighbor->GetPower(), iNBEdge, pSub->GetNeighborSpan(), viDestEnd, viDestStart ); + + + // Now map the one into the other. + int iFreeDim = !g_EdgeDims[iEdge]; + int fixedPercent = ((nodeIndex[iFreeDim] - viSrcStart[iFreeDim]) * (1<<16)) / (viSrcEnd[iFreeDim] - viSrcStart[iFreeDim]); + Assert( fixedPercent >= 0 && fixedPercent <= (1<<16) ); + + int nbDim = g_EdgeDims[iNBEdge]; + out[nbDim] = viDestStart[nbDim]; + out[!nbDim] = viDestStart[!nbDim] + ((viDestEnd[!nbDim] - viDestStart[!nbDim]) * fixedPercent) / (1<<16); + + Assert( out.x >= 0 && out.x < pNeighbor->GetSideLength() ); + Assert( out.y >= 0 && out.y < pNeighbor->GetSideLength() ); + + return pNeighbor; +} + + +CDispUtilsHelper* TransformIntoNeighbor( + CDispUtilsHelper *pDisp, + int iEdge, + CVertIndex const &nodeIndex, + CVertIndex &out + ) +{ + if ( iEdge == -1 ) + iEdge = GetEdgeIndexFromPoint( nodeIndex, pDisp->GetPower() ); + + int iSub = GetSubNeighborIndex( pDisp, iEdge, nodeIndex ); + if ( iSub == -1 ) + return NULL; + + CDispUtilsHelper *pRet = TransformIntoSubNeighbor( pDisp, iEdge, iSub, nodeIndex, out ); + +#if 0 + // Debug check.. make sure it comes back to the same point from the other side. + #if defined( _DEBUG ) + static bool bTesting = false; + if ( pRet && !bTesting ) + { + bTesting = true; + + // We could let TransformIntoNeighbor figure out the index but if this is a corner vert, then + // it may pick the wrong edge and we'd get a benign assert. + int nbOrientation = pDisp->GetEdgeNeighbor( iEdge )->m_SubNeighbors[iSub].GetNeighborOrientation(); + int iNeighborEdge = (iEdge + 2 + nbOrientation) & 3; + + CVertIndex testIndex; + CDispUtilsHelper *pTest = TransformIntoNeighbor( pRet, iNeighborEdge, out, testIndex ); + Assert( pTest == pDisp ); + Assert( testIndex == nodeIndex ); + + bTesting = false; + } + #endif +#endif + + return pRet; +} + + +bool DoesPointHaveAnyNeighbors( + CDispUtilsHelper *pDisp, + const CVertIndex &index ) +{ + // See if it connects to a neighbor on the edge. + CVertIndex dummy; + if ( TransformIntoNeighbor( pDisp, -1, index, dummy ) ) + return true; + + // See if it connects to a neighbor on a corner. + int iCorner = GetCornerIndexFromPoint( index, pDisp->GetPower() ); + if ( iCorner == -1 ) + return false; + + // If there are any neighbors on the specified corner, then the point has neighbors. + if ( pDisp->GetCornerNeighbors( iCorner )->m_nNeighbors > 0 ) + return true; + + // Since points on corners touch two edges, we actually want to test two edges to see + // if the point has a neighbor on either edge. + for ( int i=0; i < 2; i++ ) + { + if ( TransformIntoNeighbor( pDisp, g_CornerEdges[iCorner][i], index, dummy ) ) + return true; + } + + return false; +} + + +// ------------------------------------------------------------------------------------ // +// CDispSubEdgeIterator. +// ------------------------------------------------------------------------------------ // + +CDispSubEdgeIterator::CDispSubEdgeIterator() +{ + m_pNeighbor = 0; + m_FreeDim = m_Index.x = m_Inc.x = m_End = 0; // Setup so Next returns false. +} + + +void CDispSubEdgeIterator::Start( CDispUtilsHelper *pDisp, int iEdge, int iSub, bool bTouchCorners ) +{ + m_pNeighbor = SetupEdgeIncrements( pDisp, iEdge, iSub, m_Index, m_Inc, m_NBIndex, m_NBInc, m_End, m_FreeDim ); + if ( m_pNeighbor ) + { + if ( bTouchCorners ) + { + // Back up our current position by 1 so we hit the corner first, and extend the endpoint + // so we hit the other corner too. + m_Index -= m_Inc; + m_NBIndex -= m_NBInc; + + m_End += m_Inc[m_FreeDim]; + } + } + else + { + m_FreeDim = m_Index.x = m_Inc.x = m_End = 0; // Setup so Next returns false. + } +} + + +bool CDispSubEdgeIterator::Next() +{ + m_Index += m_Inc; + m_NBIndex += m_NBInc; + + // Were we just at the last point on the edge? + return m_Index[m_FreeDim] < m_End; +} + + +bool CDispSubEdgeIterator::IsLastVert() const +{ + return (m_Index[m_FreeDim] + m_Inc[m_FreeDim]) >= m_End; +} + + +// ------------------------------------------------------------------------------------ // +// CDispEdgeIterator. +// ------------------------------------------------------------------------------------ // + +CDispEdgeIterator::CDispEdgeIterator( CDispUtilsHelper *pDisp, int iEdge ) +{ + m_pDisp = pDisp; + m_iEdge = iEdge; + m_iCurSub = -1; +} + + +bool CDispEdgeIterator::Next() +{ + while ( !m_It.Next() ) + { + // Ok, move up to the next sub. + if ( m_iCurSub == 1 ) + return false; + + ++m_iCurSub; + m_It.Start( m_pDisp, m_iEdge, m_iCurSub ); + } + return true; +} + + +// ------------------------------------------------------------------------------------ // +// CDispCircumferenceIterator. +// ------------------------------------------------------------------------------------ // + +CDispCircumferenceIterator::CDispCircumferenceIterator( int sideLength ) +{ + m_iCurEdge = -1; + m_SideLengthM1 = sideLength - 1; +} + + +bool CDispCircumferenceIterator::Next() +{ + switch ( m_iCurEdge ) + { + case -1: + { + m_iCurEdge = NEIGHBOREDGE_LEFT; + m_VertIndex.Init( 0, 0 ); + } + break; + + case NEIGHBOREDGE_LEFT: + { + ++m_VertIndex.y; + if ( m_VertIndex.y == m_SideLengthM1 ) + m_iCurEdge = NEIGHBOREDGE_TOP; + } + break; + + case NEIGHBOREDGE_TOP: + { + ++m_VertIndex.x; + if ( m_VertIndex.x == m_SideLengthM1 ) + m_iCurEdge = NEIGHBOREDGE_RIGHT; + } + break; + + case NEIGHBOREDGE_RIGHT: + { + --m_VertIndex.y; + if ( m_VertIndex.y == 0 ) + m_iCurEdge = NEIGHBOREDGE_BOTTOM; + } + break; + + case NEIGHBOREDGE_BOTTOM: + { + --m_VertIndex.x; + if ( m_VertIndex.x == 0 ) + return false; // Done! + } + break; + } + + return true; +} + + + +// Helper function to setup an index either on the edges or the center +// of the box defined by [bottomleft,topRight]. +static inline void SetupCoordXY( CNodeVert &out, CNodeVert const &bottomLeft, CNodeVert const &topRight, CNodeVert const &info ) +{ + for( int i=0; i < 2; i++ ) + { + if( info[i] == 0 ) + out[i] = bottomLeft[i]; + else if( info[i] == 1 ) + out[i] = (bottomLeft[i] + topRight[i]) >> 1; + else + out[i] = topRight[i]; + } +} + + +static unsigned short* DispCommon_GenerateTriIndices_R( + CNodeVert const &bottomLeft, + CNodeVert const &topRight, + unsigned short *indices, + int power, + int sideLength ) +{ + if( power == 1 ) + { + // Ok, add triangles. All we do here is follow a list of verts (g_NodeTriWinding) + // around the center vert of this node and make triangles. + int iCurTri = 0; + CNodeVert verts[3]; + + // verts[0] is always the center vert. + SetupCoordXY( verts[0], bottomLeft, topRight, CNodeVert(1,1) ); + int iCurVert = 1; + + for( int i=0; i < 9; i++ ) + { + SetupCoordXY( verts[iCurVert], bottomLeft, topRight, g_NodeTriWinding[i] ); + ++iCurVert; + + if( iCurVert == 3 ) + { + for( int iTriVert=2; iTriVert >= 0; iTriVert-- ) + { + int index = verts[iTriVert].y * sideLength + verts[iTriVert].x; + *indices = index; + ++indices; + } + + // Setup for the next triangle. + verts[1] = verts[2]; + iCurVert = 2; + iCurTri++; + } + } + } + else + { + // Recurse into the children. + for( int i=0; i < 4; i++ ) + { + CNodeVert childBottomLeft, childTopRight; + SetupCoordXY( childBottomLeft, bottomLeft, topRight, g_NodeChildLookup[i][0] ); + SetupCoordXY( childTopRight, bottomLeft, topRight, g_NodeChildLookup[i][1] ); + + indices = DispCommon_GenerateTriIndices_R( childBottomLeft, childTopRight, indices, power-1, sideLength ); + } + } + + return indices; +} + + +// ------------------------------------------------------------------------------------------- // +// CDispUtilsHelper functions. +// ------------------------------------------------------------------------------------------- // + +int CDispUtilsHelper::GetPower() const +{ + return GetPowerInfo()->GetPower(); +} + +int CDispUtilsHelper::GetSideLength() const +{ + return GetPowerInfo()->GetSideLength(); +} + +const CVertIndex& CDispUtilsHelper::GetCornerPointIndex( int iCorner ) const +{ + return GetPowerInfo()->GetCornerPointIndex( iCorner ); +} + +int CDispUtilsHelper::VertIndexToInt( const CVertIndex &i ) const +{ + Assert( i.x >= 0 && i.x < GetSideLength() && i.y >= 0 && i.y < GetSideLength() ); + return i.y * GetSideLength() + i.x; +} + +CVertIndex CDispUtilsHelper::GetEdgeMidPoint( int iEdge ) const +{ + int end = GetSideLength() - 1; + int mid = GetPowerInfo()->GetMidPoint(); + + if ( iEdge == NEIGHBOREDGE_LEFT ) + return CVertIndex( 0, mid ); + + else if ( iEdge == NEIGHBOREDGE_TOP ) + return CVertIndex( mid, end ); + + else if ( iEdge == NEIGHBOREDGE_RIGHT ) + return CVertIndex( end, mid ); + + else if ( iEdge == NEIGHBOREDGE_BOTTOM ) + return CVertIndex( mid, 0 ); + + Assert( false ); + return CVertIndex( 0, 0 ); +} + +int DispCommon_GetNumTriIndices( int power ) +{ + return (1<GetEdgeNeighbor( i )->SetInvalid(); + pDisp->GetCornerNeighbors( i )->SetInvalid(); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void GetDispBox( CCoreDispInfo *pDisp, CDispBox &box ) +{ + // Calculate the bbox for this displacement. + Vector vMin( 1e24, 1e24, 1e24 ); + Vector vMax( -1e24, -1e24, -1e24 ); + + for ( int iVert = 0; iVert < 4; ++iVert ) + { + const Vector &vTest = pDisp->GetSurface()->GetPoint( iVert ); + VectorMin( vTest, vMin, vMin ); + VectorMax( vTest, vMax, vMax ); + } + + // Puff the box out a little. + static float flPuff = 0.1f; + vMin -= Vector( flPuff, flPuff, flPuff ); + vMax += Vector( flPuff, flPuff, flPuff ); + + box.m_Min = vMin; + box.m_Max = vMax; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void SetupDispBoxes( CCoreDispInfo **ppListBase, int nListSize, CUtlVector &out ) +{ + out.SetSize( nListSize ); + for ( int iDisp = 0; iDisp < nListSize; ++iDisp ) + { + CCoreDispInfo *pDisp = ppListBase[iDisp]; + GetDispBox( pDisp, out[iDisp] ); + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline bool DoBBoxesTouch( const CDispBox &a, const CDispBox &b ) +{ + for ( int i=0; i < 3; i++ ) + { + if ( a.m_Max[i] < b.m_Min[i] ) + return false; + + if ( a.m_Min[i] > b.m_Max[i] ) + return false; + } + + return true; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool FindEdge( CCoreDispInfo *pInfo, Vector const &vPoint1, Vector const &vPoint2, int &iEdge ) +{ + CCoreDispSurface *pSurface = pInfo->GetSurface(); + + for( iEdge=0; iEdge < 4; iEdge++ ) + { + if( VectorsAreEqual( vPoint1, pSurface->GetPoint( iEdge ), 0.01f ) && + VectorsAreEqual( vPoint2, pSurface->GetPoint( (iEdge+1) & 3), 0.01f ) ) + { + return true; + } + } + + return false; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +NeighborSpan NeighborSpanFlip( int iEdge, NeighborSpan span ) +{ + if ( g_bEdgeNeighborFlip[iEdge] ) + return g_SpanFlip[span]; + else + return span; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void AddNeighbor( CCoreDispInfo *pMain, + int iEdge, // Which of pMain's sides this is on. + int iSub, // Which sub neighbor this takes up in pSide. + NeighborSpan span, // What span this fills in pMain. + CCoreDispInfo *pOther, int iNeighborEdge, NeighborSpan nbSpan ) +{ + // The edge iteration before coming in here goes 0-1, 1-2, 2-3, 3-4. + // This flips the sense of CORNER_TO_MIDPOINT/MIDPOINT_TO_CORNER on the right and + // bottom edges and is undone here. + span = NeighborSpanFlip( iEdge, span ); + nbSpan = NeighborSpanFlip( iNeighborEdge, nbSpan ); + + // Get the subspan this fills on our displacement. + CDispSubNeighbor *pSub = &pMain->GetEdgeNeighbor(iEdge)->m_SubNeighbors[iSub]; + + // Which subspan does this use in the neighbor? + CDispSubNeighbor *pNeighborSub; + if ( nbSpan == MIDPOINT_TO_CORNER ) + { + pNeighborSub = &pOther->GetEdgeNeighbor(iNeighborEdge)->m_SubNeighbors[1]; + } + else + { + pNeighborSub = &pOther->GetEdgeNeighbor(iNeighborEdge)->m_SubNeighbors[0]; + } + + // Make sure this slot isn't used on either displacement. + if ( pSub->IsValid() || pNeighborSub->IsValid() ) + { + ExecuteOnce( Warning( "Found a displacement edge abutting multiple other edges.\n" ) ); + return; + } + + // Now just copy the data into each displacement. + pSub->m_iNeighbor = pOther->GetListIndex(); + pSub->m_NeighborOrientation = g_CoreDispNeighborOrientationMap[iEdge][iNeighborEdge]; + pSub->m_Span = span; + pSub->m_NeighborSpan = nbSpan; + + pNeighborSub->m_iNeighbor = pMain->GetListIndex(); + pNeighborSub->m_NeighborOrientation = g_CoreDispNeighborOrientationMap[iNeighborEdge][iEdge]; + pNeighborSub->m_Span = nbSpan; + pNeighborSub->m_NeighborSpan = span; + +#if defined( _DEBUG ) + // Walk an iterator over the new connection to make sure it works. + CDispSubEdgeIterator it; + it.Start( pMain, iEdge, iSub ); + while ( it.Next() ) + { + CVertIndex nbIndex; + TransformIntoNeighbor( pMain, iEdge, it.GetVertIndex(), nbIndex ); + } +#endif +} + +//----------------------------------------------------------------------------- +// This function is symmetric wrt pMain and pOther. It sets up valid neighboring data for +// the relationship between both of them. +//----------------------------------------------------------------------------- +void SetupEdgeNeighbors( CCoreDispInfo *pMain, CCoreDispInfo *pOther ) +{ + // Initialize.. + for( int iEdge=0; iEdge < 4; iEdge++ ) + { + // Setup the edge points and the midpoint. + Vector pt[2], mid; + pMain->GetSurface()->GetPoint( iEdge, pt[0] ); + pMain->GetSurface()->GetPoint( (iEdge + 1) & 3, pt[1] ); + mid = (pt[0] + pt[1]) * 0.5f; + + // Find neighbors. + int iNBEdge; + if( FindEdge( pOther, pt[1], pt[0], iNBEdge ) ) + { + AddNeighbor( pMain, iEdge, 0, CORNER_TO_CORNER, pOther, iNBEdge, CORNER_TO_CORNER ); + } + else + { + // Look for one that takes up our whole side. + if( FindEdge( pOther, pt[1], pt[0]*2 - pt[1], iNBEdge ) ) + { + AddNeighbor( pMain, iEdge, 0, CORNER_TO_CORNER, pOther, iNBEdge, CORNER_TO_MIDPOINT ); + } + else if( FindEdge( pOther, pt[1]*2 - pt[0], pt[0], iNBEdge ) ) + { + AddNeighbor( pMain, iEdge, 0, CORNER_TO_CORNER, pOther, iNBEdge, MIDPOINT_TO_CORNER ); + } + else + { + // Ok, look for 1 or two that abut this side. + if( FindEdge( pOther, mid, pt[0], iNBEdge ) ) + { + AddNeighbor( pMain, iEdge, g_bEdgeNeighborFlip[iEdge], CORNER_TO_MIDPOINT, pOther, iNBEdge, CORNER_TO_CORNER ); + } + + if( FindEdge( pOther, pt[1], mid, iNBEdge ) ) + { + AddNeighbor( pMain, iEdge, !g_bEdgeNeighborFlip[iEdge], MIDPOINT_TO_CORNER, pOther, iNBEdge, CORNER_TO_CORNER ); + } + } + } + } +} + +//----------------------------------------------------------------------------- +// Returns true if the displacement has an edge neighbor with the given index. +//----------------------------------------------------------------------------- +bool HasEdgeNeighbor( const CCoreDispInfo *pMain, int iNeighbor ) +{ + for ( int i=0; i < 4; i++ ) + { + const CDispCornerNeighbors *pCorner = pMain->GetCornerNeighbors( i ); + for ( int iNB=0; iNB < pCorner->m_nNeighbors; iNB++ ) + if ( pCorner->m_Neighbors[iNB] == iNeighbor ) + return true; + + const CDispNeighbor *pEdge = pMain->GetEdgeNeighbor( i ); + if ( pEdge->m_SubNeighbors[0].GetNeighborIndex() == iNeighbor || + pEdge->m_SubNeighbors[1].GetNeighborIndex() == iNeighbor ) + { + return true; + } + } + return false; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void SetupCornerNeighbors( CCoreDispInfo *pMain, CCoreDispInfo *pOther, int *nOverflows ) +{ + if ( HasEdgeNeighbor( pMain, pOther->GetListIndex() ) ) + return; + + // Do these two share a vertex? + int nShared = 0; + int iMainSharedCorner = -1; + int iOtherSharedCorner = -1; + + for ( int iMainCorner=0; iMainCorner < 4; iMainCorner++ ) + { + Vector const &vMainCorner = pMain->GetCornerPoint( iMainCorner ); + + for ( int iOtherCorner=0; iOtherCorner < 4; iOtherCorner++ ) + { + Vector const &vOtherCorner = pOther->GetCornerPoint( iOtherCorner ); + + if ( VectorsAreEqual( vMainCorner, vOtherCorner, 0.001f ) ) + { + iMainSharedCorner = iMainCorner; + iOtherSharedCorner = iOtherCorner; + ++nShared; + } + } + } + + if ( nShared == 1 ) + { + CDispCornerNeighbors *pMainCorner = pMain->GetCornerNeighbors( iMainSharedCorner ); + CDispCornerNeighbors *pOtherCorner = pOther->GetCornerNeighbors( iOtherSharedCorner ); + + if ( pMainCorner->m_nNeighbors < MAX_DISP_CORNER_NEIGHBORS && + pOtherCorner->m_nNeighbors < MAX_DISP_CORNER_NEIGHBORS ) + { + pMainCorner->m_Neighbors[pMainCorner->m_nNeighbors++] = pOther->GetListIndex(); + pOtherCorner->m_Neighbors[pOtherCorner->m_nNeighbors++] = pMain->GetListIndex(); + } + else + { + ++(*nOverflows); + } + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool VerifyNeighborVertConnection( CDispUtilsHelper *pDisp, const CVertIndex &nodeIndex, + const CDispUtilsHelper *pTestNeighbor, const CVertIndex &testNeighborIndex, + int mySide ) +{ + CVertIndex nbIndex( -1, -1 ); + CDispUtilsHelper *pNeighbor = NULL; + if( (pNeighbor = TransformIntoNeighbor( pDisp, mySide, nodeIndex, nbIndex ) ) != NULL ) + { + if ( pTestNeighbor != pNeighbor || nbIndex != testNeighborIndex ) + return false; + + CVertIndex testIndex( -1, -1 ); + int iSide = GetEdgeIndexFromPoint( nbIndex, pNeighbor->GetPowerInfo()->m_Power ); + if ( iSide == -1 ) + { + return false; + } + + CDispUtilsHelper *pTest = TransformIntoNeighbor( pNeighbor, iSide, nbIndex, testIndex ); + + if( pTest != pDisp || nodeIndex != testIndex ) + { + return false; + } + } + + return true; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void VerifyNeighborConnections( CCoreDispInfo **ppListBase, int nDisps ) +{ + while ( 1 ) + { + bool bHappy = true; + + int iDisp; + for ( iDisp = 0; iDisp < nDisps; ++iDisp ) + { + CCoreDispInfo *pDisp = ppListBase[iDisp]; + CDispUtilsHelper *pHelper = pDisp; + + for ( int iEdge=0; iEdge < 4; iEdge++ ) + { + CDispEdgeIterator it( pHelper, iEdge ); + while ( it.Next() ) + { + if ( !VerifyNeighborVertConnection( pHelper, it.GetVertIndex(), it.GetCurrentNeighbor(), it.GetNBVertIndex(), iEdge ) ) + { + pDisp->GetEdgeNeighbor( iEdge )->SetInvalid(); + Warning( "Warning: invalid neighbor connection on displacement near (%.2f %.2f %.2f)\n", VectorExpand( pDisp->GetCornerPoint(0) ) ); + bHappy = false; + } + } + } + } + + if ( bHappy ) + break; + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void FindNeighboringDispSurfs( CCoreDispInfo **ppListBase, int nListSize ) +{ + // First, clear all neighboring data. + int iDisp; + for ( iDisp = 0; iDisp < nListSize; ++iDisp ) + { + ClearNeighborData( ppListBase[iDisp] ); + } + + CUtlVector boxes; + SetupDispBoxes( ppListBase, nListSize, boxes ); + + int nCornerOverflows = 0; + + // Now test all pairs of displacements and setup neighboring relations between them. + for( iDisp = 0; iDisp < nListSize; ++iDisp ) + { + CCoreDispInfo *pMain = ppListBase[iDisp]; + + for ( int iDisp2 = iDisp+1; iDisp2 < nListSize; ++iDisp2 ) + { + CCoreDispInfo *pOther = ppListBase[iDisp2]; + + // Trivial reject. + if ( !DoBBoxesTouch( boxes[iDisp], boxes[iDisp2] ) ) + continue; + + SetupEdgeNeighbors( pMain, pOther ); + + // NOTE: this must come after SetupEdgeNeighbors because it makes sure not to add + // corner neighbors for disps that are already edge neighbors. + SetupCornerNeighbors( pMain, pOther, &nCornerOverflows ); + } + } + + if ( nCornerOverflows ) + { + Warning( "Warning: overflowed %d displacement corner-neighbor lists.", nCornerOverflows ); + } + + // Debug check.. make sure the neighbor connections are intact (make sure that any + // edge vert that gets mapped into a neighbor gets mapped back the same way). + VerifyNeighborConnections( ppListBase, nListSize ); +} + +//============================================================================= +// +// Allowable verts. +// + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int IsCorner( CVertIndex const &index, int sideLength ) +{ + if ( index.x == 0 ) + { + if ( index.y == 0 ) + return true; + else if ( index.y == sideLength-1 ) + return true; + } + else if ( index.x == sideLength-1 ) + { + if ( index.y == 0 ) + return true; + else if ( index.y == sideLength-1 ) + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool IsVertAllowed( CDispUtilsHelper *pDisp, CVertIndex const &sideVert, int iLevel ) +{ + if ( IsCorner( sideVert, pDisp->GetPowerInfo()->GetSideLength() ) ) + return true; + + int iSide = GetEdgeIndexFromPoint( sideVert, pDisp->GetPowerInfo()->GetPower() ); + if ( iSide == -1 ) + return true; + + int iSub = GetSubNeighborIndex( pDisp, iSide, sideVert ); + if ( iSub == -1 ) + return true; + + CDispSubNeighbor *pSub = &pDisp->GetEdgeNeighbor( iSide )->m_SubNeighbors[iSub]; + CDispUtilsHelper *pNeighbor = pDisp->GetDispUtilsByIndex( pSub->m_iNeighbor ); + Assert( pNeighbor ); + + // Ok, there is a neighbor.. see if this vertex exists in the neighbor. + CShiftInfo *pShiftInfo = &g_ShiftInfos[pSub->m_Span][pSub->m_NeighborSpan]; + Assert( pShiftInfo->m_bValid ); + + if ( ( pNeighbor->GetPowerInfo()->GetPower() + pShiftInfo->m_PowerShiftAdd ) < ( iLevel+1 ) ) + { + return false; + } + + // Ok, it exists. Make sure the neighbor hasn't disallowed it. + CVertIndex nbIndex; + TransformIntoSubNeighbor( pDisp, iSide, iSub, sideVert, nbIndex ); + + CBitVec &allowedVerts = CCoreDispInfo::FromDispUtils( pNeighbor )->GetAllowedVerts(); + return !!allowedVerts.Get( pNeighbor->VertIndexToInt( nbIndex ) ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void UnallowVerts_R( CDispUtilsHelper *pDisp, CVertIndex const &nodeIndex, int &nUnallowed ) +{ + int iNodeIndex = pDisp->VertIndexToInt( nodeIndex ); + + CCoreDispInfo *pCoreDisp = CCoreDispInfo::FromDispUtils( pDisp ); + if ( !pCoreDisp->GetAllowedVerts().Get( iNodeIndex ) ) + return; + + nUnallowed++; + pCoreDisp->GetAllowedVerts().Clear( iNodeIndex ); + + for ( int iDep=0; iDep < CVertInfo::NUM_REVERSE_DEPENDENCIES; iDep++ ) + { + CVertDependency &dep = pDisp->GetPowerInfo()->m_pVertInfo[iNodeIndex].m_ReverseDependencies[iDep]; + + if( dep.m_iVert.x != -1 && dep.m_iNeighbor == -1 ) + { + UnallowVerts_R( pDisp, dep.m_iVert, nUnallowed ); + } + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void DisableUnallowedVerts_R( CDispUtilsHelper *pDisp, CVertIndex const &nodeIndex, int iLevel, int &nUnallowed ) +{ + int iNodeIndex = pDisp->VertIndexToInt( nodeIndex ); + + // This vertex is not allowed if it is on an edge with a neighbor + // that does not have this vertex. + + // Test side verts. + for( int iSide=0; iSide < 4; iSide++ ) + { + CVertIndex const &sideVert = pDisp->GetPowerInfo()->m_pSideVerts[iNodeIndex].m_Verts[iSide]; + + if( !IsVertAllowed( pDisp, sideVert, iLevel ) ) + { + // This vert (and its dependencies) can't exist. + UnallowVerts_R( pDisp, sideVert, nUnallowed ); + } + } + +#if 0 + // Test dependencies. + for( int iDep=0; iDep < 2; iDep++ ) + { + CVertDependency const &dep = pDisp->GetPowerInfo()->m_pVertInfo[iNodeIndex].m_Dependencies[iDep]; + + if( dep.m_iNeighbor == -1 && !IsVertAllowed( pDisp, dep.m_iVert, iLevel ) ) + { + UnallowVerts_R( pDisp, nodeIndex, nUnallowed ); + } + } +#endif + + // Recurse. + if( iLevel+1 < pDisp->GetPower() ) + { + for( int iChild=0; iChild < 4; iChild++ ) + { + DisableUnallowedVerts_R( pDisp, pDisp->GetPowerInfo()->m_pChildVerts[iNodeIndex].m_Verts[iChild], iLevel+1, nUnallowed ); + } + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void SetupAllowedVerts( CCoreDispInfo **ppListBase, int nListSize ) +{ + // Set all verts to allowed to start with. + int iDisp; + for ( iDisp = 0; iDisp < nListSize; ++iDisp ) + { + ppListBase[iDisp]->GetAllowedVerts().SetAll(); + } + + // Disable verts that need to be disabled so higher-powered displacements remove + // the necessary triangles when bordering lower-powered displacements. + // It is necessary to loop around here because disabling verts can accumulate into + // neighbors. + bool bContinue; + do + { + bContinue = false; + for( iDisp = 0; iDisp < nListSize; ++iDisp ) + { + CDispUtilsHelper *pDisp = ppListBase[iDisp]; + + int nUnallowed = 0; + DisableUnallowedVerts_R( pDisp, pDisp->GetPowerInfo()->m_RootNode, 0, nUnallowed ); + if ( nUnallowed ) + bContinue = true; + } + } while( bContinue ); +} diff --git a/sp/src/public/disp_common.h b/sp/src/public/disp_common.h new file mode 100644 index 00000000..6dd5561b --- /dev/null +++ b/sp/src/public/disp_common.h @@ -0,0 +1,262 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef DISP_COMMON_H +#define DISP_COMMON_H +#ifdef _WIN32 +#pragma once +#endif + +#include "disp_vertindex.h" +#include "bspfile.h" +#include "utlvector.h" + +class CPowerInfo; +class CCoreDispInfo; + +// ----------------------------------------------------------------------------- // +// Classes. +// ----------------------------------------------------------------------------- // + +// This class provides a set of utility functions for displacements that work in the tools and the engine. +abstract_class CDispUtilsHelper +{ +// Derived classes must implement these. +public: + virtual const CPowerInfo* GetPowerInfo() const = 0; + virtual CDispNeighbor* GetEdgeNeighbor( int index ) = 0; + virtual CDispCornerNeighbors* GetCornerNeighbors( int index ) = 0; + virtual CDispUtilsHelper* GetDispUtilsByIndex( int index ) = 0; + +// Helper functions. +public: + + int GetPower() const; + int GetSideLength() const; + const CVertIndex& GetCornerPointIndex( int iCorner ) const; + int VertIndexToInt( const CVertIndex &i ) const; + CVertIndex GetEdgeMidPoint( int iEdge ) const; +}; + + +// Use this to walk along two neighboring displacements and touch all the +// common vertices. +class CDispSubEdgeIterator +{ +public: + + CDispSubEdgeIterator(); + + // Normally, this will iterate all shared verts along the edge except the corners. + // If you want the corners to be touched too, then pass in bTouchCorners=true. + void Start( CDispUtilsHelper *pDisp, int iEdge, int iSub, bool bTouchCorners = false ); + bool Next(); + + const CVertIndex& GetVertIndex() const { return m_Index; } // Get the vert index for the displacement in pUtils. + const CVertIndex& GetNBVertIndex() const { return m_NBIndex; } // Get the neighbor's vert index. + CDispUtilsHelper* GetNeighbor() const { return m_pNeighbor; } + + // Returns true if you're on the last vert (ie: the next Next() call will return false).ssssss + bool IsLastVert() const; + + +private: + CDispUtilsHelper *m_pNeighbor; // The neighbor to the edge we were setup on. + + CVertIndex m_Index; + CVertIndex m_Inc; + + CVertIndex m_NBIndex; + CVertIndex m_NBInc; + + int m_End; + int m_FreeDim; +}; + + +// Use this to walk along the edge of a displacement, touching the points in common +// between the two neighbors. Note: this won't hit the corner points of any of the displacements. +// (As a result, it won't hit the midpoint of pDisps's edge if there are 2 neighbors). +class CDispEdgeIterator +{ +public: + CDispEdgeIterator( CDispUtilsHelper *pDisp, int iEdge ); + + // Seek to the next point on the edge. + bool Next(); + + const CVertIndex& GetVertIndex() const { return m_It.GetVertIndex(); } // Get the vert index for the displacement in pUtils. + const CVertIndex& GetNBVertIndex() const { return m_It.GetNBVertIndex(); } // Get the neighbor's vert index. + + // What is the current neighbor? + CDispUtilsHelper* GetCurrentNeighbor() const { return m_It.GetNeighbor(); } + + +private: + CDispUtilsHelper *m_pDisp; + int m_iEdge; + int m_iCurSub; + + CDispSubEdgeIterator m_It; +}; + + +// Use this to walk all the corners and edge verts in the displacement. +// It walks the edges in the order of the NEIGHBOREDGE_ defines. +// Iterate like this: +// CDispCircumferenceIterator iterator( pDisp->GetSideLength() ); +// while ( iterator.Next() ) +// ... +class CDispCircumferenceIterator +{ +public: + CDispCircumferenceIterator( int sideLength ); + + // Seek to the next point. Returns false when there are no more points. + bool Next(); + + const CVertIndex& GetVertIndex() const { return m_VertIndex; } + + +private: + int m_SideLengthM1; + int m_iCurEdge; + CVertIndex m_VertIndex; +}; + + +// These store info about how to scale and shift coordinates between neighbors +// of different relations (in g_ShiftInfos). +class CShiftInfo +{ +public: + int m_MidPointScale; + int m_PowerShiftAdd; + bool m_bValid; +}; + +class CDispBox +{ +public: + Vector m_Min, m_Max; +}; + +// ----------------------------------------------------------------------------- // +// Globals. +// ----------------------------------------------------------------------------- // + + +extern int g_EdgeDims[4]; // This tells which dimension (0 or 1) is locked on an edge for each NEIGHBOREDGE_ enum. +extern CShiftInfo g_ShiftInfos[3][3]; // See CShiftInfo. +extern int g_EdgeSideLenMul[4];// Multiply these by the side length to get the index of the edge. + + +// ----------------------------------------------------------------------------- // +// Helper functions. +// ----------------------------------------------------------------------------- // + +// Reference implementation to generate triangle indices for a displacement. +int DispCommon_GetNumTriIndices( int power ); +void DispCommon_GenerateTriIndices( int power, unsigned short *indices ); + +// Returns a NEIGHBOREDGE_ value for the edge that the index is on. +// Returns -1 if the index is not on a side. +// If the point is on a corner, the edges are tested in the order of the NEIGHBOREDGE_ defines. +int GetEdgeIndexFromPoint( CVertIndex const &index, int iPower ); + +// Returns a CORNER_ value for the corner the point is on, or -1 if it's not on a corner. +int GetEdgeIndexFromPoint( CVertIndex const &index, int iPower ); + +// This returns the neighbor's power, possibly +1 or -1. +// +// It will add one if the neighbor takes up half of your edge (ie: if it took up your +// whole edge, its resolution would be twice what it really is). +// +// It will subtract one if you take up half of its edge (ie: you only touch half of its verts). +// +// Returns -1 if the edge connection is invalid. +int GetNeighborEdgePower( CDispUtilsHelper *pDisp, int iEdge, int iSub ); + +// This function sets you up so you can walk along an edge that joins two neighbors. +// Add myInc to myIndex and nbInc to nbIndex until myIndex[iFreeDim] >= myEnd. +// +// Returns the neighbor displacement, or NULL if the specified sub neighbor isn't valid. +CDispUtilsHelper* SetupEdgeIncrements( + CDispUtilsHelper *pDisp, + int iEdge, + int iSub, + CVertIndex &myIndex, + CVertIndex &myInc, + CVertIndex &nbIndex, + CVertIndex &nbInc, + int &myEnd, + int &iFreeDim ); + +// Figure out which sub neighbor nodeIndex touches. +// Returns -1 if there is no valid sub neighbor at the specified index. +int GetSubNeighborIndex( + CDispUtilsHelper *pDisp, + int iEdge, + CVertIndex const &nodeIndex + ); + +// Given a vert index and the CSubNeighbor the vert lies on, this +// transforms the specified vert into the neighbor's space. +// +// Note: for corner verts, there may be multiple neighbors touching the same vert, so the +// result you get depends on the edge you specify in iEdge (ie: if you specify the same +// node index but a different edge, you may get a different neighbor). +// +// Note: This only returns a point if the point at nodeIndex actually touches a neighbor point. +// An example where this might be unexpected is if pDisp is power 4 and its neighbor on iEdge +// is power 3, and nodeIndex points at a vert in between two of its neighbor's verts. +// In that case, even though there is a neighbor displacement, nodeIndex doesn't touch +// any points on it, so NULL is returned. +CDispUtilsHelper* TransformIntoSubNeighbor( + CDispUtilsHelper *pDisp, + int iEdge, + int iSub, + CVertIndex const &nodeIndex, + CVertIndex &out + ); + +// Transform pDisp's node at nodeIndex into its neighboring connection. +// Returns the neighbor displacement and sets out to the index in the neighbor. +// +// Note: for corner verts, there may be multiple neighbors touching the same vert, so the +// result you get depends on the edge you specify in iEdge (ie: if you specify the same +// node index but a different edge, you may get a different neighbor). +// +// Note: This only returns a point if the point at nodeIndex actually touches a neighbor point. +// An example where this might surprise you is if pDisp is power 4 and its neighbor on iEdge +// is power 3, and nodeIndex points at a vert in between two of its neighbor's verts. +// In that case, even though there is a neighbor displacement, nodeIndex doesn't touch +// any points on it, so NULL is returned. +CDispUtilsHelper* TransformIntoNeighbor( + CDispUtilsHelper *pDisp, + int iEdge, + CVertIndex const &nodeIndex, + CVertIndex &out ); + +// Returns true if the specified point has one or more neighbors. +bool DoesPointHaveAnyNeighbors( + CDispUtilsHelper *pDisp, + const CVertIndex &index ); + + +void FindNeighboringDispSurfs( CCoreDispInfo **ppListBase, int nListSize ); +void SetupAllowedVerts( CCoreDispInfo **ppListBase, int nListSize ); +void GetDispBox( CCoreDispInfo *pDisp, CDispBox &box ); + +// ----------------------------------------------------------------------------- // +// Inlines. +// ----------------------------------------------------------------------------- // + +#include "disp_powerinfo.h" + + +#endif // DISP_COMMON_H diff --git a/sp/src/public/disp_powerinfo.cpp b/sp/src/public/disp_powerinfo.cpp new file mode 100644 index 00000000..47119a91 --- /dev/null +++ b/sp/src/public/disp_powerinfo.cpp @@ -0,0 +1,580 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "disp_powerinfo.h" +#include "disp_common.h" +#include "commonmacros.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// ------------------------------------------------------------------------ // +// Internal classes. +// ------------------------------------------------------------------------ // + +// These point at the vertices connecting to each of the [north,south,east,west] vertices. +class CVertCorners +{ +public: + short m_Corner1[2]; + short m_Corner2[2]; +}; + + +// ------------------------------------------------------------------------ // +// Globals. +// ------------------------------------------------------------------------ // + +// This points at vertices to the side of a node (north, south, east, west). +static short g_SideVertMul[4][2] = { {1,0}, {0,1}, {-1,0}, {0,-1} }; + +static CVertCorners g_SideVertCorners[4] = +{ + { {1,-1}, {1,1} }, + { {1,1}, {-1,1} }, + { {-1,1}, {-1,-1} }, + { {-1,-1}, {1,-1} } +}; + +// This is used in loops on child nodes. The indices point at the nodes: +// 0 = upper-right +// 1 = upper-left +// 2 = lower-left +// 3 = lower-right +static CVertIndex g_ChildNodeIndexMul[4] = +{ + CVertIndex(1,1), + CVertIndex(-1,1), + CVertIndex(-1,-1), + CVertIndex(1,-1) +}; + +// These are multipliers on vertMul (not nodeMul). +static CVertIndex g_ChildNodeDependencies[4][2] = +{ + { CVertIndex(1,0), CVertIndex(0,1) }, + { CVertIndex(0,1), CVertIndex(-1,0) }, + { CVertIndex(-1,0), CVertIndex(0,-1) }, + { CVertIndex(0,-1), CVertIndex(1,0) } +}; + +// 2x2 rotation matrices for each orientation. +static int g_OrientationRotations[4][2][2] = +{ + {{1, 0}, // CCW_0 + {0, 1}}, + + {{0, 1}, // CCW_90 + {-1,0}}, + + {{-1,0}, // CCW_180 + {0,-1}}, + + {{0, -1}, // CCW_270 + {1, 0}} +}; + + +// ------------------------------------------------------------------------ // +// Helper functions. +// ------------------------------------------------------------------------ // + +// Apply a 2D rotation to the specified CVertIndex around the specified centerpoint. +static CVertIndex Transform2D( + int const mat[2][2], + CVertIndex const &vert, + CVertIndex const ¢erPoint ) +{ + CVertIndex translated = vert - centerPoint; + + CVertIndex transformed( + translated.x*mat[0][0] + translated.y*mat[0][1], + translated.x*mat[1][0] + translated.y*mat[1][1] ); + + return transformed + centerPoint; +} + + +// Rotate a given CVertIndex with a specified orientation. +// Do this with a lookup table eventually! +static void GetEdgeVertIndex( int sideLength, int iEdge, int iVert, CVertIndex &out ) +{ + if( iEdge == NEIGHBOREDGE_RIGHT ) + { + out.x = sideLength - 1; + out.y = iVert; + } + else if( iEdge == NEIGHBOREDGE_TOP ) + { + out.x = iVert; + out.y = sideLength - 1; + } + else if( iEdge == NEIGHBOREDGE_LEFT ) + { + out.x = 0; + out.y = iVert; + } + else + { + out.x = iVert; + out.y = 0; + } +} + + +// Generate an index given a CVertIndex and the size of the displacement it resides in. +static int VertIndex( CVertIndex const &vert, int iMaxPower ) +{ + return vert.y * ((1 << iMaxPower) + 1) + vert.x; +} + + +static CVertIndex WrapVertIndex( CVertIndex const &in, int sideLength ) +{ + int out[2]; + + for( int i=0; i < 2; i++ ) + { + if( in[i] < 0 ) + out[i] = sideLength - 1 - (-in[i] % sideLength); + else if( in[i] >= sideLength ) + out[i] = in[i] % sideLength; + else + out[i] = in[i]; + } + + return CVertIndex( out[0], out[1] ); +} + + +static int GetFreeDependency( CVertDependency *pDep, int nElements ) +{ + for( int i=0; i < nElements; i++ ) + { + if( !pDep[i].IsValid() ) + return i; + } + + Assert( false ); + return 0; +} + + +static void AddDependency( + CVertInfo *dependencies, + int sideLength, + CVertIndex const &nodeIndex, + CVertIndex const &dependency, + int iMaxPower, + bool bCheckNeighborDependency, + bool bAddReverseDependency ) +{ + int iNodeIndex = VertIndex( nodeIndex, iMaxPower ); + CVertInfo *pNode = &dependencies[iNodeIndex]; + + int iDep = GetFreeDependency( pNode->m_Dependencies, sizeof(pNode->m_Dependencies)/sizeof(pNode->m_Dependencies[0]) ); + pNode->m_Dependencies[iDep].m_iVert = dependency; + pNode->m_Dependencies[iDep].m_iNeighbor = -1; + + if( bAddReverseDependency ) + { + CVertInfo *pDep = &dependencies[VertIndex( dependency, iMaxPower )]; + iDep = GetFreeDependency( pDep->m_ReverseDependencies, CVertInfo::NUM_REVERSE_DEPENDENCIES ); + pDep->m_ReverseDependencies[iDep].m_iVert = nodeIndex; + pDep->m_ReverseDependencies[iDep].m_iNeighbor = -1; + } + + // Edge verts automatically add a dependency for the neighbor. + // Internal verts wind up in here twice anyway so it doesn't need to + if( bCheckNeighborDependency ) + { + int iConnection = GetEdgeIndexFromPoint( nodeIndex, iMaxPower ); + if( iConnection != -1 ) + { + Assert( !pNode->m_Dependencies[1].IsValid() ); + + CVertIndex delta( nodeIndex.x - dependency.x, nodeIndex.y - dependency.y ); + CVertIndex newIndex( nodeIndex.x + delta.x, nodeIndex.y + delta.y ); + + int fullSideLength = (1 << iMaxPower) + 1; + pNode->m_Dependencies[1].m_iVert = WrapVertIndex( CVertIndex( newIndex.x, newIndex.y ), fullSideLength ); + pNode->m_Dependencies[1].m_iNeighbor = iConnection; + } + } +} + + +// --------------------------------------------------------------------------------- // +// CTesselateWinding stuff. +// --------------------------------------------------------------------------------- // + +CTesselateVert::CTesselateVert( CVertIndex const &index, int iNode ) + : m_Index( index ) +{ + m_iNode = iNode; +} + + +CVertInfo::CVertInfo() +{ + int i; + for( i=0; i < sizeof(m_Dependencies)/sizeof(m_Dependencies[0]); i++ ) + { + m_Dependencies[i].m_iVert = CVertIndex( -1, -1 ); + m_Dependencies[i].m_iNeighbor = -1; + } + + for( i=0; i < sizeof(m_ReverseDependencies)/sizeof(m_ReverseDependencies[0]); i++ ) + { + m_ReverseDependencies[i].m_iVert = CVertIndex( -1, -1 ); + m_ReverseDependencies[i].m_iNeighbor = -1; + } + + m_iParent.x = m_iParent.y = -1; + m_iNodeLevel = -1; +} + + +CTesselateVert g_TesselateVerts[] = +{ + CTesselateVert( CVertIndex(1,-1), CHILDNODE_LOWER_RIGHT), + CTesselateVert( CVertIndex(0,-1), -1), + CTesselateVert( CVertIndex(-1,-1), CHILDNODE_LOWER_LEFT), + CTesselateVert( CVertIndex(-1, 0), -1), + CTesselateVert( CVertIndex(-1, 1), CHILDNODE_UPPER_LEFT), + CTesselateVert( CVertIndex(0, 1), -1), + CTesselateVert( CVertIndex(1, 1), CHILDNODE_UPPER_RIGHT), + CTesselateVert( CVertIndex(1, 0), -1), + CTesselateVert( CVertIndex(1,-1), CHILDNODE_LOWER_RIGHT) +}; + +CTesselateWinding g_TWinding = +{ + g_TesselateVerts, + sizeof( g_TesselateVerts ) / sizeof( g_TesselateVerts[0] ) +}; + + + +// --------------------------------------------------------------------------------- // +// CPowerInfo stuff. +// --------------------------------------------------------------------------------- // + +// Precalculated info about each particular displacement size. +#define DECLARE_TABLES( size ) \ + static CVertInfo g_VertInfo_##size##x##size[ size*size ]; \ + static CFourVerts g_SideVerts_##size##x##size[ size*size ]; \ + static CFourVerts g_ChildVerts_##size##x##size[ size*size ]; \ + static CFourVerts g_SideVertCorners_##size##x##size[ size*size ]; \ + static CTwoUShorts g_ErrorEdges_##size##x##size[ size*size ]; \ + static CTriInfo g_TriInfos_##size##x##size[ (size-1)*(size-1)*2 ]; \ + static CPowerInfo g_PowerInfo_##size##x##size( \ + g_VertInfo_##size##x##size, \ + g_SideVerts_##size##x##size, \ + g_ChildVerts_##size##x##size, \ + g_SideVertCorners_##size##x##size,\ + g_ErrorEdges_##size##x##size, \ + g_TriInfos_##size##x##size \ + ) + +#define POWERINFO_ENTRY( size ) \ + (&g_PowerInfo_##size##x##size) + +DECLARE_TABLES( 5 ); +DECLARE_TABLES( 9 ); +DECLARE_TABLES( 17 ); + + +// Index by m_Power. +CPowerInfo *g_PowerInfos[NUM_POWERINFOS] = +{ + NULL, + NULL, + POWERINFO_ENTRY(5), + POWERINFO_ENTRY(9), + POWERINFO_ENTRY(17) +}; + + +CPowerInfo::CPowerInfo( + CVertInfo *pVertInfo, + CFourVerts *pSideVerts, + CFourVerts *pChildVerts, + CFourVerts *pSideVertCorners, + CTwoUShorts *pErrorEdges, + CTriInfo *pTriInfos ) +{ + m_pVertInfo = pVertInfo; + m_pSideVerts = pSideVerts; + m_pChildVerts = pChildVerts; + m_pSideVertCorners = pSideVertCorners; + m_pErrorEdges = pErrorEdges; + m_pTriInfos = pTriInfos; +} + +static void InitPowerInfoTriInfos_R( + CPowerInfo *pInfo, + CVertIndex const &nodeIndex, + CTriInfo* &pTriInfo, + int iMaxPower, + int iLevel ) +{ + int iNodeIndex = VertIndex( nodeIndex, iMaxPower ); + + if( iLevel+1 < iMaxPower ) + { + // Recurse into children. + for( int iChild=0; iChild < 4; iChild++ ) + { + InitPowerInfoTriInfos_R( + pInfo, + pInfo->m_pChildVerts[iNodeIndex].m_Verts[iChild], + pTriInfo, + iMaxPower, + iLevel+1 ); + } + } + else + { + unsigned short indices[3]; + + int vertInc = 1 << ((iMaxPower - iLevel) - 1); + + // We're at a leaf, generate the tris. + CTesselateWinding *pWinding = &g_TWinding; + + // Starting at the bottom-left, wind clockwise picking up vertices and + // generating triangles. + int iCurTriVert = 0; + for( int iVert=0; iVert < pWinding->m_nVerts; iVert++ ) + { + CVertIndex sideVert = BuildOffsetVertIndex( nodeIndex, pWinding->m_Verts[iVert].m_Index, vertInc ); + + if( iCurTriVert == 1 ) + { + // Add this vert and finish the tri. + pTriInfo->m_Indices[0] = indices[0]; + pTriInfo->m_Indices[1] = VertIndex( sideVert, iMaxPower ); + pTriInfo->m_Indices[2] = iNodeIndex; + ++pTriInfo; + } + + indices[0] = VertIndex( sideVert, iMaxPower ); + iCurTriVert = 1; + } + } +} + + +static void InitPowerInfo_R( + CPowerInfo *pPowerInfo, + int iMaxPower, + CVertIndex const &nodeIndex, + CVertIndex const &dependency1, + CVertIndex const &dependency2, + CVertIndex const &nodeEdge1, + CVertIndex const &nodeEdge2, + CVertIndex const &iParent, + int iLevel ) +{ + int sideLength = ((1 << iMaxPower) + 1); + int iNodeIndex = VertIndex( nodeIndex, iMaxPower ); + + pPowerInfo->m_pVertInfo[iNodeIndex].m_iParent = iParent; + pPowerInfo->m_pVertInfo[iNodeIndex].m_iNodeLevel = iLevel + 1; + + pPowerInfo->m_pErrorEdges[iNodeIndex].m_Values[0] = (unsigned short)(VertIndex( nodeEdge1, iMaxPower )); + pPowerInfo->m_pErrorEdges[iNodeIndex].m_Values[1] = (unsigned short)(VertIndex( nodeEdge2, iMaxPower )); + + // Add this node's dependencies. + AddDependency( pPowerInfo->m_pVertInfo, sideLength, nodeIndex, dependency1, iMaxPower, false, true ); + AddDependency( pPowerInfo->m_pVertInfo, sideLength, nodeIndex, dependency2, iMaxPower, false, true ); + + // The 4 side vertices depend on this node. + int iPower = iMaxPower - iLevel; + int vertInc = 1 << (iPower - 1); + + for( int iSide=0; iSide < 4; iSide++ ) + { + // Store the side vert index. + CVertIndex sideVert( nodeIndex.x + g_SideVertMul[iSide][0]*vertInc, nodeIndex.y + g_SideVertMul[iSide][1]*vertInc ); + int iSideVert = VertIndex( sideVert, iMaxPower ); + + pPowerInfo->m_pSideVerts[iNodeIndex].m_Verts[iSide] = sideVert; + + // Store the side vert corners. + CVertIndex sideVertCorner0 = CVertIndex( nodeIndex.x + g_SideVertCorners[iSide].m_Corner1[0]*vertInc, nodeIndex.y + g_SideVertCorners[iSide].m_Corner1[1]*vertInc ); + CVertIndex sideVertCorner1 = CVertIndex( nodeIndex.x + g_SideVertCorners[iSide].m_Corner2[0]*vertInc, nodeIndex.y + g_SideVertCorners[iSide].m_Corner2[1]*vertInc ); + + pPowerInfo->m_pSideVertCorners[iNodeIndex].m_Verts[iSide] = sideVertCorner0; + + // Write the side vert corners into the error-edges list. + pPowerInfo->m_pErrorEdges[iSideVert].m_Values[0] = (unsigned short)VertIndex( sideVertCorner0, iMaxPower ); + pPowerInfo->m_pErrorEdges[iSideVert].m_Values[1] = (unsigned short)VertIndex( sideVertCorner1, iMaxPower ); + + AddDependency( + pPowerInfo->m_pVertInfo, + sideLength, + sideVert, + nodeIndex, + iMaxPower, + true, + true ); + } + + // Recurse into the children. + int nodeInc = vertInc >> 1; + if( nodeInc ) + { + for( int iChild=0; iChild < 4; iChild++ ) + { + CVertIndex childVert( nodeIndex.x + g_ChildNodeIndexMul[iChild].x * nodeInc, nodeIndex.y + g_ChildNodeIndexMul[iChild].y * nodeInc ); + + pPowerInfo->m_pChildVerts[iNodeIndex].m_Verts[iChild] = childVert; + + InitPowerInfo_R( pPowerInfo, + iMaxPower, + childVert, + + CVertIndex(nodeIndex.x + g_ChildNodeDependencies[iChild][0].x*vertInc, nodeIndex.y + g_ChildNodeDependencies[iChild][0].y*vertInc), + CVertIndex(nodeIndex.x + g_ChildNodeDependencies[iChild][1].x*vertInc, nodeIndex.y + g_ChildNodeDependencies[iChild][1].y*vertInc), + + nodeIndex, + CVertIndex( nodeIndex.x + g_ChildNodeIndexMul[iChild].x * vertInc, nodeIndex.y + g_ChildNodeIndexMul[iChild].y * vertInc ), + + nodeIndex, + iLevel + 1 ); + } + } +} + + +void InitPowerInfo( CPowerInfo *pInfo, int iMaxPower ) +{ + int sideLength = (1 << iMaxPower) + 1; + + // Precalculate the dependency graph. + CVertIndex nodeDependency1( sideLength-1, sideLength-1 ); + CVertIndex nodeDependency2( 0, 0 ); + + pInfo->m_RootNode = CVertIndex( sideLength/2, sideLength/2 ); + pInfo->m_SideLength = sideLength; + pInfo->m_SideLengthM1 = sideLength - 1; + pInfo->m_MidPoint = sideLength / 2; + pInfo->m_MaxVerts = sideLength * sideLength; + + // Setup the corner indices. + pInfo->m_CornerPointIndices[CORNER_LOWER_LEFT].Init( 0, 0 ); + pInfo->m_CornerPointIndices[CORNER_UPPER_LEFT].Init( 0, sideLength-1 ); + pInfo->m_CornerPointIndices[CORNER_UPPER_RIGHT].Init( sideLength-1, sideLength-1 ); + pInfo->m_CornerPointIndices[CORNER_LOWER_RIGHT].Init( sideLength-1, 0 ); + + InitPowerInfo_R( + pInfo, + iMaxPower, + pInfo->m_RootNode, + + nodeDependency1, // dependencies + nodeDependency2, + + CVertIndex(0,0), // error edge + CVertIndex(sideLength-1, sideLength-1), + + CVertIndex(-1,-1), // parent + 0 ); + + pInfo->m_Power = iMaxPower; + + CTriInfo *pTriInfo = pInfo->m_pTriInfos; + InitPowerInfoTriInfos_R( pInfo, pInfo->m_RootNode, pTriInfo, iMaxPower, 0 ); + + for( int iEdge=0; iEdge < 4; iEdge++ ) + { + // Figure out the start vert and increment. + CVertIndex nextVert; + GetEdgeVertIndex( sideLength, iEdge, 0, pInfo->m_EdgeStartVerts[iEdge] ); + GetEdgeVertIndex( sideLength, iEdge, 1, nextVert ); + pInfo->m_EdgeIncrements[iEdge] = nextVert - pInfo->m_EdgeStartVerts[iEdge]; + + // Now get the neighbor's start vert and increment. + CVertIndex nbStartVert, nbNextVert, nbDelta; + GetEdgeVertIndex( sideLength, (iEdge+2)&3, 0, nbStartVert ); + GetEdgeVertIndex( sideLength, (iEdge+2)&3, 1, nbNextVert ); + nbDelta = nbNextVert - nbStartVert; + + // Rotate it for each orientation. + for( int orient=0; orient < 4; orient++ ) + { + pInfo->m_NeighborStartVerts[iEdge][orient] = Transform2D( + g_OrientationRotations[orient], + nbStartVert, + CVertIndex( sideLength/2, sideLength/2 ) ); + + pInfo->m_NeighborIncrements[iEdge][orient] = Transform2D( + g_OrientationRotations[orient], + nbDelta, + CVertIndex(0,0) ); + } + } + + + // Init the node index increments. + int curPowerOf4 = 1; + int curTotal = 0; + for( int i=0; i < iMaxPower-1; i++ ) + { + curTotal += curPowerOf4; + + pInfo->m_NodeIndexIncrements[iMaxPower-i-2] = curTotal; + + curPowerOf4 *= 4; + } + + // Store off the total node count + pInfo->m_NodeCount = curTotal + curPowerOf4; + + pInfo->m_nTriInfos = Square( 1 << iMaxPower ) * 2; +} + +class CPowerInfoInitializer +{ +public: + CPowerInfoInitializer() + { + Assert( MAX_MAP_DISP_POWER+1 == NUM_POWERINFOS ); + + for( int i=0; i <= MAX_MAP_DISP_POWER; i++ ) + { + if( g_PowerInfos[i] ) + { + InitPowerInfo( g_PowerInfos[i], i ); + } + } + } +}; + +static CPowerInfoInitializer g_PowerInfoInitializer; + + +const CPowerInfo* GetPowerInfo( int iPower ) +{ + Assert( iPower >= 0 && iPower < ARRAYSIZE( g_PowerInfos ) ); + Assert( g_PowerInfos[iPower] ); + return g_PowerInfos[iPower]; +} + + +// ------------------------------------------------------------------------------------------------ // +// CPowerInfo member function initialization. +// ------------------------------------------------------------------------------------------------ // + +const CVertIndex& CPowerInfo::GetCornerPointIndex( int iCorner ) const +{ + Assert( iCorner >= 0 && iCorner < 4 ); + return m_CornerPointIndices[iCorner]; +} + diff --git a/sp/src/public/disp_powerinfo.h b/sp/src/public/disp_powerinfo.h new file mode 100644 index 00000000..0abd0357 --- /dev/null +++ b/sp/src/public/disp_powerinfo.h @@ -0,0 +1,213 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: This module defines the CPowerInfo class, which contains a +// whole bunch of precalculated data for each displacement power. +// It holds data that indicates how to tesselate, how to access +// neighbor displacements, etc. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef DISP_POWERINFO_H +#define DISP_POWERINFO_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "disp_vertindex.h" +#include "bspfile.h" + + +#define NUM_POWERINFOS (MAX_MAP_DISP_POWER+1) + + +struct DispNodeInfo_t +{ + enum + { + // Indicates if any children at all have triangles + CHILDREN_HAVE_TRIANGLES = 0x1 + }; + + + // Indicates which tesselation indices are associated with a node + unsigned short m_FirstTesselationIndex; + unsigned char m_Count; + unsigned char m_Flags; +}; + + +// ------------------------------------------------------------------------ // +// CTesselateWindings are used to tell what order a node needs to visit +// vertices while tesselating. +// ------------------------------------------------------------------------ // +class CTesselateVert +{ +public: + CTesselateVert( CVertIndex const &index, int iNode ); + + CVertIndex m_Index; + short m_iNode; // Which node this vert is a part of (-1 on left, right, up, and down). +}; + + +class CTesselateWinding +{ +public: + CTesselateVert *m_Verts; + short m_nVerts; // (includes the last vert) +}; + + +class CVertDependency +{ +public: + + // Returns false if there is no dependency stored here. + bool IsValid() { return m_iVert.x != -1; } + + +public: + + // The vert index is in the same power as the source displacement. + // It is also wrapped, so for example, on the middle of the right edge + // of a 3x3, it will have a dependency on the 3x3's root node (1,1), and it + // will have another (1,1) entry that references a neighbor. + CVertIndex m_iVert; + + // This is -1 if the vert exists inside the source displacement. + // It is one of the NEIGHBOREDGE_ codes above if it reaches into a neighbor. + short m_iNeighbor; +}; + + +// Precalculated data about displacement vertices. +class CVertInfo +{ +public: + CVertInfo(); + + // These are the vertices that this vertex depends on (vertices that must be + // active for this vert to exist). + CVertDependency m_Dependencies[2]; + + // These are the vertices that have this vert in their m_Dependencies. + enum { NUM_REVERSE_DEPENDENCIES=4 }; + CVertDependency m_ReverseDependencies[NUM_REVERSE_DEPENDENCIES]; + + short m_iNodeLevel; // -1 if this is not a node. Otherwise, the recursion level + // of this node (root node = 1). + CVertIndex m_iParent; // x=-1 if this is a not a node or if it's the root node. +}; + + +class CTwoUShorts +{ +public: + unsigned short m_Values[2]; +}; + + +class CFourVerts +{ +public: + CVertIndex m_Verts[4]; +}; + + +// Used for referencing triangles in the fully-tesselated displacement by index. +class CTriInfo +{ +public: + unsigned short m_Indices[3]; +}; + + +// Precalculated data for displacements of a certain power. +class CPowerInfo +{ +public: + CPowerInfo( + CVertInfo *pVertInfo, + CFourVerts *pSideVerts, + CFourVerts *pChildVerts, + CFourVerts *pSideVertCorners, + CTwoUShorts *pErrorEdges, + CTriInfo *pTriInfos ); + + int GetPower() const { return m_Power; } + int GetSideLength() const { return m_SideLength; } + const CVertIndex& GetRootNode() const { return m_RootNode; } + int GetMidPoint() const { return m_MidPoint; } // Half the edge length. + + // Get at the tri list. + int GetNumTriInfos() const { return m_nTriInfos; } + const CTriInfo* GetTriInfo( int i ) const { return &m_pTriInfos[i]; } + + // Get the number of vertices in a displacement of this power. + int GetNumVerts() const { return m_MaxVerts; } + + // Return a corner point index. Indexed by the CORNER_ defines. + const CVertIndex& GetCornerPointIndex( int iCorner ) const; + + +public: + + CVertInfo *m_pVertInfo; + CFourVerts *m_pSideVerts; // The 4 side verts for each node. + CFourVerts *m_pChildVerts; // The 4 children for each node. + CFourVerts *m_pSideVertCorners; + CTwoUShorts *m_pErrorEdges; // These are the edges + // that are used to measure the screenspace + // error with respect to each vert. + + CTriInfo *m_pTriInfos; + int m_nTriInfos; + + int m_Power; + + CVertIndex m_RootNode; + int m_SideLength; + int m_SideLengthM1; // Side length minus 1. + int m_MidPoint; // Side length / 2. + int m_MaxVerts; // m_SideLength * m_SideLength + int m_NodeCount; // total # of nodes, including children + + // Precalculated increments if you're using a bit vector to represent nodes. + // Starting at level 0 of the tree, this stores the increment between the nodes at this + // level. Vectors holding node data are stored in preorder traversal, and these + // increments tell the number of elements between nodes at each level. + int m_NodeIndexIncrements[MAX_MAP_DISP_POWER]; + + CVertIndex m_EdgeStartVerts[4]; + CVertIndex m_EdgeIncrements[4]; + + CVertIndex m_NeighborStartVerts[4][4]; // [side][orientation] + CVertIndex m_NeighborIncrements[4][4]; // [side][orientation] + + +private: + friend void InitPowerInfo( CPowerInfo *pInfo, int iMaxPower ); + + CVertIndex m_CornerPointIndices[4]; +}; + + +// ----------------------------------------------------------------------------- // +// Globals. +// ----------------------------------------------------------------------------- // + +// Indexed by the TWINDING_ enums. +extern CTesselateWinding g_TWinding; + + +// ----------------------------------------------------------------------------- // +// Functions. +// ----------------------------------------------------------------------------- // + +// Valid indices are MIN_MAP_DISP_POWER through (and including) MAX_MAP_DISP_POWER. +const CPowerInfo* GetPowerInfo( int iPower ); + + +#endif // DISP_POWERINFO_H diff --git a/sp/src/public/disp_tesselate.h b/sp/src/public/disp_tesselate.h new file mode 100644 index 00000000..d2d3caf2 --- /dev/null +++ b/sp/src/public/disp_tesselate.h @@ -0,0 +1,206 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef DISP_TESSELATE_H +#define DISP_TESSELATE_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "disp_powerinfo.h" + + +inline int InternalVertIndex( const CPowerInfo *pInfo, const CVertIndex &vert ) +{ + return vert.y * pInfo->m_SideLength + vert.x; +} + + +template< class TesselateHelper > +inline void InternalEndTriangle( + TesselateHelper *pHelper, + CVertIndex const &nodeIndex, + int &iCurTriVert ) +{ + // End our current triangle here. + Assert( iCurTriVert == 2 ); + + // Finish the triangle. + pHelper->m_TempIndices[2] = (unsigned short)InternalVertIndex( pHelper->m_pPowerInfo, nodeIndex ); + + pHelper->EndTriangle(); + + // Add on the last vertex to join to the next triangle. + pHelper->m_TempIndices[0] = pHelper->m_TempIndices[1]; + iCurTriVert = 1; +} + + +//----------------------------------------------------------------------------- +// Tesselates a single node, doesn't deal with hierarchy +//----------------------------------------------------------------------------- +template< class TesselateHelper > +inline void TesselateDisplacementNode( + TesselateHelper *pHelper, + CVertIndex const &nodeIndex, + int iLevel, + int *pActiveChildren ) +{ + int iPower = pHelper->m_pPowerInfo->m_Power - iLevel; + int vertInc = 1 << (iPower - 1); + + CTesselateWinding *pWinding = &g_TWinding; + + // Starting at the bottom-left, wind clockwise picking up vertices and + // generating triangles. + int iCurTriVert = 0; + for( int iVert=0; iVert < pWinding->m_nVerts; iVert++ ) + { + CVertIndex sideVert = BuildOffsetVertIndex( nodeIndex, pWinding->m_Verts[iVert].m_Index, vertInc ); + + int iVertNode = pWinding->m_Verts[iVert].m_iNode; + bool bNode = (iVertNode != -1) && pActiveChildren[iVertNode]; + if( bNode ) + { + if( iCurTriVert == 2 ) + InternalEndTriangle( pHelper, nodeIndex, iCurTriVert ); + + iCurTriVert = 0; + } + else + { + int iVertBit = InternalVertIndex( pHelper->m_pPowerInfo, sideVert ); + if( pHelper->m_pActiveVerts[iVertBit>>5] & (1 << (iVertBit & 31)) ) + { + // Ok, add a vert here. + pHelper->m_TempIndices[iCurTriVert] = (unsigned short)InternalVertIndex( pHelper->m_pPowerInfo, sideVert ); + iCurTriVert++; + if( iCurTriVert == 2 ) + InternalEndTriangle( pHelper, nodeIndex, iCurTriVert ); + } + } + } +} + + +//----------------------------------------------------------------------------- +// Tesselates in a *breadth first* fashion +//----------------------------------------------------------------------------- +template< class T > +inline void TesselateDisplacement_R( + T *pHelper, + const CVertIndex &nodeIndex, + int iNodeBitIndex, + int iLevel + ) +{ + // Here's the node info for our current node + Assert( iNodeBitIndex < pHelper->m_pPowerInfo->m_NodeCount ); + DispNodeInfo_t& nodeInfo = pHelper->GetNodeInfo( iNodeBitIndex ); + + // Store off the current number of indices + int oldIndexCount = pHelper->m_nIndices; + + // Go through each quadrant. If there is an active child node, recurse down. + int bActiveChildren[4]; + if( iLevel >= pHelper->m_pPowerInfo->m_Power - 1 ) + { + // This node has no children. + bActiveChildren[0] = bActiveChildren[1] = bActiveChildren[2] = bActiveChildren[3] = false; + } + else + { + int iNodeIndex = InternalVertIndex( pHelper->m_pPowerInfo, nodeIndex ); + + int iChildNodeBit = iNodeBitIndex + 1; + for( int iChild=0; iChild < 4; iChild++ ) + { + CVertIndex const &childNode = pHelper->m_pPowerInfo->m_pChildVerts[iNodeIndex].m_Verts[iChild]; + + // Make sure we really can tesselate here (a smaller neighbor displacement could + // have inactivated certain edge verts. + int iVertBit = InternalVertIndex( pHelper->m_pPowerInfo, childNode ); + bActiveChildren[iChild] = ( pHelper->m_pActiveVerts[iVertBit>>5] & (1 << (iVertBit & 31)) ); + + if( bActiveChildren[iChild] ) + { + TesselateDisplacement_R( pHelper, childNode, iChildNodeBit, iLevel+1 ); + } + else + { + // Make sure the triangle counts are cleared on this one because it may visit this + // node in GenerateDecalFragments_R if nodeInfo's CHILDREN_HAVE_TRIANGLES flag is set. + DispNodeInfo_t &childInfo = pHelper->GetNodeInfo( iChildNodeBit ); + childInfo.m_Count = 0; + childInfo.m_Flags = 0; + } + + iChildNodeBit += pHelper->m_pPowerInfo->m_NodeIndexIncrements[iLevel]; + } + } + + // Set the child field + if ( pHelper->m_nIndices != oldIndexCount ) + { + nodeInfo.m_Flags = DispNodeInfo_t::CHILDREN_HAVE_TRIANGLES; + oldIndexCount = pHelper->m_nIndices; + } + else + { + nodeInfo.m_Flags = 0; + } + + // Now tesselate the node itself... + TesselateDisplacementNode( pHelper, nodeIndex, iLevel, bActiveChildren ); + + // Now that we've tesselated, figure out how many indices we've added at this node + nodeInfo.m_Count = pHelper->m_nIndices - oldIndexCount; + nodeInfo.m_FirstTesselationIndex = oldIndexCount; + Assert( nodeInfo.m_Count % 3 == 0 ); +} + + +class CBaseTesselateHelper +{ +public: + + // Functions your derived class must implement: + // void EndTriangle(); // (the 3 indices are in m_TempIndices). + // DispNodeInfo_t& GetNodeInfo( int iNodeBit ); + + + // Set these before calling TesselateDisplacement. + uint32 *m_pActiveVerts; // These bits control the tesselation. + const CPowerInfo *m_pPowerInfo; // Lots of precalculated data about a displacement this size. + + + // Used internally by TesselateDisplacement. + int m_nIndices; // After calling TesselateDisplacement, this is set to the # of indices generated. + unsigned short m_TempIndices[6]; +}; + + + +// This interface is shared betwixt VBSP and the engine. VBSP uses it to build the +// physics mesh and the engine uses it to render. +// +// To use this function, derive a class from CBaseTesselateHelper that supports the TesselateHelper functions. +template< class TesselateHelper > +inline void TesselateDisplacement( TesselateHelper *pHelper ) +{ + pHelper->m_nIndices = 0; + + TesselateDisplacement_R( + pHelper, + pHelper->m_pPowerInfo->m_RootNode, + 0, // node bit indexing CDispDecal::m_NodeIntersects + 0 ); +} + + +#endif // DISP_TESSELATE_H diff --git a/sp/src/public/disp_vertindex.h b/sp/src/public/disp_vertindex.h new file mode 100644 index 00000000..4d82cf25 --- /dev/null +++ b/sp/src/public/disp_vertindex.h @@ -0,0 +1,150 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef DISP_VERTINDEX_H +#define DISP_VERTINDEX_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "tier0/dbg.h" + + +// ------------------------------------------------------------------------ // +// Helper class used for indexing vertices in the 2D grid. +// ------------------------------------------------------------------------ // + +class CVertIndex +{ +public: + CVertIndex(); + CVertIndex( short ix, short iy ); + + void Init( short ix, short iy ); + + short& operator[]( short i ); + short const& operator[]( short i ) const; + void operator+=( CVertIndex const &other ); + void operator-=( CVertIndex const &other ); + CVertIndex operator+( CVertIndex const &other ) const; + CVertIndex operator-( CVertIndex const &other ) const; + void operator<<=( int shift ); + void operator>>=( int shift ); + bool operator==( CVertIndex const &other ) const; + bool operator!=( CVertIndex const &other ) const; + + +public: + + short x, y; +}; + + +// ------------------------------------------------------------------ // +// Helper functions. +// ------------------------------------------------------------------ // + +inline CVertIndex BuildOffsetVertIndex( + CVertIndex const &nodeIndex, + CVertIndex const &offset, + int mul ) +{ + return CVertIndex( nodeIndex.x + offset.x * mul, nodeIndex.y + offset.y * mul ); +} + + +// ------------------------------------------------------------------ // +// CVertIndex inlines. +// ------------------------------------------------------------------ // + +inline CVertIndex::CVertIndex() +{ +} + + +inline CVertIndex::CVertIndex( short ix, short iy ) +{ + x = ix; + y = iy; +} + + +inline void CVertIndex::Init( short ix, short iy ) +{ + x = ix; + y = iy; +} + + +inline short& CVertIndex::operator[]( short i ) +{ + Assert( i >= 0 && i <= 1 ); + return ((short*)this)[i]; +} + + +inline short const& CVertIndex::operator[]( short i ) const +{ + Assert( i >= 0 && i <= 1 ); + return ((short*)this)[i]; +} + + +inline void CVertIndex::operator+=( CVertIndex const &other ) +{ + x += other.x; + y += other.y; +} + + +inline void CVertIndex::operator-=( CVertIndex const &other ) +{ + x -= other.x; + y -= other.y; +} + + +inline CVertIndex CVertIndex::operator+( CVertIndex const &other ) const +{ + return CVertIndex( x + other.x, y + other.y ); +} + + +inline CVertIndex CVertIndex::operator-( CVertIndex const &other ) const +{ + return CVertIndex( x - other.x, y - other.y ); +} + + +inline void CVertIndex::operator<<=( int shift ) +{ + x <<= shift; + y <<= shift; +} + + +inline void CVertIndex::operator>>=( int shift ) +{ + x >>= shift; + y >>= shift; +} + + +inline bool CVertIndex::operator==( CVertIndex const &other ) const +{ + return x==other.x && y==other.y; +} + + +inline bool CVertIndex::operator!=( CVertIndex const &other ) const +{ + return x!=other.x || y!=other.y; +} + + +#endif // DISP_VERTINDEX_H diff --git a/sp/src/public/dispcoll.cpp b/sp/src/public/dispcoll.cpp new file mode 100644 index 00000000..3583d4a2 --- /dev/null +++ b/sp/src/public/dispcoll.cpp @@ -0,0 +1,1994 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "BuildDisp.h" +#include "DispColl.h" +#include "tier0/dbg.h" + +//============================================================================= + +const float CDispCollTree::COLLISION_EPSILON = 0.01f; +const float CDispCollTree::ONE_MINUS_COLLISION_EPSILON = 1.0f - COLLISION_EPSILON; + +//============================================================================= +// +// Displacement Collision Triangle Functions +// + + +//----------------------------------------------------------------------------- +// Purpose: initialize the displacement triangles +//----------------------------------------------------------------------------- +void CDispCollTri::Init( void ) +{ + for( int i = 0; i < 3; i++ ) + { + m_Points[i].x = 0.0f; m_Points[i].y = 0.0f; m_Points[i].z = 0.0f; + m_PointNormals[i].x = 0.0f; m_PointNormals[i].y = 0.0f; m_PointNormals[i].z = 0.0f; + } + + m_Normal.x = 0.0f; m_Normal.y = 0.0f; m_Normal.z = 0.0f; + m_Distance = 0.0f; + + m_ProjAxes[0] = -1; + m_ProjAxes[1] = -1; + + m_bIntersect = false; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline void CDispCollTri::SetPoint( int index, Vector const &vert ) +{ + Assert( index >= 0 ); + Assert( index < 3 ); + + m_Points[index].x = vert[0]; + m_Points[index].y = vert[1]; + m_Points[index].z = vert[2]; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline void CDispCollTri::SetPointNormal( int index, Vector const &normal ) +{ + Assert( index >= 0 ); + Assert( index < 3 ); + + m_PointNormals[index].x = normal[0]; + m_PointNormals[index].y = normal[1]; + m_PointNormals[index].z = normal[2]; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTri::CalcPlane( void ) +{ + // + // calculate the plane normal and distance + // + Vector segment1, segment2, cross; + + segment1 = m_Points[1] - m_Points[0]; + segment2 = m_Points[2] - m_Points[0]; + cross = segment1.Cross( segment2 ); + m_Normal = cross; + VectorNormalize(m_Normal); + + m_Distance = m_Normal.Dot( m_Points[0] ); + + // + // calculate the projection axes + // + if( FloatMakePositive( m_Normal[0] ) > FloatMakePositive( m_Normal[1] ) ) + { + if( FloatMakePositive( m_Normal[0] ) > FloatMakePositive( m_Normal[2] ) ) + { + m_ProjAxes[0] = 1; + m_ProjAxes[1] = 2; + } + else + { + m_ProjAxes[0] = 0; + m_ProjAxes[1] = 1; + } + } + else + { + if( FloatMakePositive( m_Normal[1] ) > FloatMakePositive( m_Normal[2] ) ) + { + m_ProjAxes[0] = 0; + m_ProjAxes[1] = 2; + } + else + { + m_ProjAxes[0] = 0; + m_ProjAxes[1] = 1; + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline void CDispCollTri::SetIntersect( bool bIntersect ) +{ + m_bIntersect = bIntersect; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline bool CDispCollTri::IsIntersect( void ) +{ + return m_bIntersect; +} + + +//============================================================================= +// +// Displacement Collision Node Functions +// + + +//----------------------------------------------------------------------------- +// Purpose: constructor +//----------------------------------------------------------------------------- +CDispCollNode::CDispCollNode() +{ + m_Bounds[0].x = m_Bounds[0].y = m_Bounds[0].z = 99999.9f; + m_Bounds[1].x = m_Bounds[1].y = m_Bounds[1].z = -99999.9f; + + m_Tris[0].Init(); + m_Tris[1].Init(); + + m_bIsLeaf = false; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline bool CDispCollNode::IsLeaf( void ) +{ + return m_bIsLeaf; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline void CDispCollNode::SetBounds( Vector const &bMin, Vector const &bMax ) +{ + m_Bounds[0] = bMin; + m_Bounds[1] = bMax; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline void CDispCollNode::GetBounds( Vector &bMin, Vector &bMax ) +{ + bMin = m_Bounds[0]; + bMax = m_Bounds[1]; +} + + +//============================================================================= +// +// Displacement Collision Tree Functions +// + +//----------------------------------------------------------------------------- +// Purpose: constructor +//----------------------------------------------------------------------------- +CDispCollTree::CDispCollTree() +{ + m_Power = 0; + + m_NodeCount = 0; + m_pNodes = NULL; + + InitAABBData(); +} + + +//----------------------------------------------------------------------------- +// Purpose: deconstructor +//----------------------------------------------------------------------------- +CDispCollTree::~CDispCollTree() +{ + FreeNodes(); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTree::InitAABBData( void ) +{ + m_AABBNormals[0].x = -1.0f; m_AABBNormals[0].y = 0.0f; m_AABBNormals[0].z = 0.0f; + m_AABBNormals[1].x = 1.0f; m_AABBNormals[1].y = 0.0f; m_AABBNormals[1].z = 0.0f; + + m_AABBNormals[2].x = 0.0f; m_AABBNormals[2].y = -1.0f; m_AABBNormals[2].z = 0.0f; + m_AABBNormals[3].x = 0.0f; m_AABBNormals[3].y = 1.0f; m_AABBNormals[3].z = 0.0f; + + m_AABBNormals[4].x = 0.0f; m_AABBNormals[4].y = 0.0f; m_AABBNormals[4].z = -1.0f; + m_AABBNormals[5].x = 0.0f; m_AABBNormals[5].y = 0.0f; m_AABBNormals[5].z = 1.0f; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTree::CalcBounds( CDispCollNode *pNode, int nodeIndex ) +{ + Vector bounds[2]; + bounds[0].Init( 99999.9f, 99999.9f, 99999.9f ); + bounds[1].Init( -99999.9f, -99999.9f, -99999.9f ); + + // + // handle leaves differently -- bounding volume defined by triangles + // + if( pNode->IsLeaf() ) + { + for( int i = 0; i < 2; i++ ) + { + for( int j = 0; j < 3; j++ ) + { + // + // minimum + // + if( bounds[0].x > pNode->m_Tris[i].m_Points[j].x ) { bounds[0].x = pNode->m_Tris[i].m_Points[j].x; } + if( bounds[0].y > pNode->m_Tris[i].m_Points[j].y ) { bounds[0].y = pNode->m_Tris[i].m_Points[j].y; } + if( bounds[0].z > pNode->m_Tris[i].m_Points[j].z ) { bounds[0].z = pNode->m_Tris[i].m_Points[j].z; } + + // + // maximum + // + if( bounds[1].x < pNode->m_Tris[i].m_Points[j].x ) { bounds[1].x = pNode->m_Tris[i].m_Points[j].x; } + if( bounds[1].y < pNode->m_Tris[i].m_Points[j].y ) { bounds[1].y = pNode->m_Tris[i].m_Points[j].y; } + if( bounds[1].z < pNode->m_Tris[i].m_Points[j].z ) { bounds[1].z = pNode->m_Tris[i].m_Points[j].z; } + } + } + } + // + // bounding volume defined by maxima and minima of children volumes + // + else + { + for( int i = 0; i < 4; i++ ) + { + int childIndex = GetChildNode( nodeIndex, i ); + CDispCollNode *pChildNode = &m_pNodes[childIndex]; + + Vector childBounds[2]; + pChildNode->GetBounds( childBounds[0], childBounds[1] ); + + // + // minimum + // + if( bounds[0].x > childBounds[0].x ) { bounds[0].x = childBounds[0].x; } + if( bounds[0].y > childBounds[0].y ) { bounds[0].y = childBounds[0].y; } + if( bounds[0].z > childBounds[0].z ) { bounds[0].z = childBounds[0].z; } + + // + // maximum + // + if( bounds[1].x < childBounds[1].x ) { bounds[1].x = childBounds[1].x; } + if( bounds[1].y < childBounds[1].y ) { bounds[1].y = childBounds[1].y; } + if( bounds[1].z < childBounds[1].z ) { bounds[1].z = childBounds[1].z; } + } + } + + pNode->SetBounds( bounds[0], bounds[1] ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTree::CreateNodes_r( CCoreDispInfo *pDisp, int nodeIndex, int termLevel ) +{ + int nodeLevel = GetNodeLevel( nodeIndex ); + + // + // terminating condition -- set node info (leaf or otherwise) + // + if( nodeLevel == termLevel ) + { + CDispCollNode *pNode = &m_pNodes[nodeIndex]; + CalcBounds( pNode, nodeIndex ); + + return; + } + + // + // recurse into children + // + for( int i = 0; i < 4; i++ ) + { + CreateNodes_r( pDisp, GetChildNode( nodeIndex, i ), termLevel ); + } +} + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTree::CreateNodes( CCoreDispInfo *pDisp ) +{ + // + // create all nodes in tree + // + int power = pDisp->GetPower() + 1; + for( int level = power; level > 0; level-- ) + { + CreateNodes_r( pDisp, 0 /* rootIndex */, level ); + } +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CDispCollTree::GetNodeIndexFromComponents( int x, int y ) +{ + int index = 0; + + // Interleave bits from the x and y values to create the index: + + for( int shift = 0; x != 0; shift += 2, x >>= 1 ) + { + index |= ( x & 1 ) << shift; + } + + for( shift = 1; y != 0; shift += 2, y >>= 1 ) + { + index |= ( y & 1 ) << shift; + } + + return index; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTree::InitLeaves( CCoreDispInfo *pDisp ) +{ + // + // get power and width and displacement surface + // + int power = pDisp->GetPower(); + int width = pDisp->GetWidth(); + + // + // get leaf indices + // + int startIndex = CalcNodeCount( power - 1 ); + int endIndex = CalcNodeCount( power ); + + for( int index = startIndex; index < endIndex; index++ ) + { + // + // create triangles at leaves + // + int x = ( index - startIndex ) % ( width - 1 ); + int y = ( index - startIndex ) / ( width - 1 ); + + int nodeIndex = GetNodeIndexFromComponents( x, y ); + nodeIndex += startIndex; + + Vector vert; + Vector normal; + + // + // tri 1 + // + pDisp->GetVert( x + ( y * width ), vert ); + pDisp->GetNormal( x + ( y * width ), normal ); + m_pNodes[nodeIndex].m_Tris[0].SetPoint( 0, vert ); + m_pNodes[nodeIndex].m_Tris[0].SetPointNormal( 0, normal ); + + pDisp->GetVert( x + ( ( y + 1 ) * width ), vert ); + pDisp->GetNormal( x + ( ( y + 1 ) * width ), normal ); + m_pNodes[nodeIndex].m_Tris[0].SetPoint( 1, vert ); + m_pNodes[nodeIndex].m_Tris[0].SetPointNormal( 1, normal ); + + pDisp->GetVert( ( x + 1 ) + ( y * width ), vert ); + pDisp->GetNormal( ( x + 1 ) + ( y * width ), normal ); + m_pNodes[nodeIndex].m_Tris[0].SetPoint( 2, vert ); + m_pNodes[nodeIndex].m_Tris[0].SetPointNormal( 2, normal ); + + m_pNodes[nodeIndex].m_Tris[0].CalcPlane(); + + // + // tri 2 + // + pDisp->GetVert( ( x + 1 ) + ( y * width ), vert ); + pDisp->GetNormal( ( x + 1 ) + ( y * width ), normal ); + m_pNodes[nodeIndex].m_Tris[1].SetPoint( 0, vert ); + m_pNodes[nodeIndex].m_Tris[1].SetPointNormal( 0, normal ); + + pDisp->GetVert( x + ( ( y + 1 ) * width ), vert ); + pDisp->GetNormal( x + ( ( y + 1 ) * width ), normal ); + m_pNodes[nodeIndex].m_Tris[1].SetPoint( 1, vert ); + m_pNodes[nodeIndex].m_Tris[1].SetPointNormal( 1, normal ); + + pDisp->GetVert( ( x + 1 ) + ( ( y + 1 ) * width ), vert ); + pDisp->GetNormal( ( x + 1 ) + ( ( y + 1 ) * width ), normal ); + m_pNodes[nodeIndex].m_Tris[1].SetPoint( 2, vert ); + m_pNodes[nodeIndex].m_Tris[1].SetPointNormal( 2, normal ); + + m_pNodes[nodeIndex].m_Tris[1].CalcPlane(); + + // set node as leaf + m_pNodes[nodeIndex].m_bIsLeaf = true; + } +} + + +//----------------------------------------------------------------------------- +// Purpose: allocate and initialize the displacement collision tree +// Input: power - size of the displacement surface +// Output: bool - success? (true/false) +//----------------------------------------------------------------------------- +bool CDispCollTree::Create( CCoreDispInfo *pDisp ) +{ + // + // calculate the number of nodes needed given the size of the displacement + // + m_Power = pDisp->GetPower(); + m_NodeCount = CalcNodeCount( m_Power ); + + // + // allocate tree space + // + if( !AllocNodes( m_NodeCount ) ) + return false; + + // initialize leaves + InitLeaves( pDisp ); + + // create tree nodes + CreateNodes( pDisp ); + + // tree successfully created! + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: allocate memory for the displacement collision tree +// Input: nodeCount - number of nodes to allocate +// Output: bool - success? (true/false) +//----------------------------------------------------------------------------- +bool CDispCollTree::AllocNodes( int nodeCount ) +{ + // sanity check + Assert( nodeCount != 0 ); + + m_pNodes = new CDispCollNode[nodeCount]; + if( !m_pNodes ) + return false; + + // tree successfully allocated! + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: release allocated memory for displacement collision tree +//----------------------------------------------------------------------------- +void CDispCollTree::FreeNodes( void ) +{ + if( m_pNodes ) + { + delete [] m_pNodes; + m_pNodes = NULL; + } +} + + +//----------------------------------------------------------------------------- +// Purpose: calculate the number of tree nodes given the size of the +// displacement surface +// Input: power - size of the displacement surface +// Output: int - the number of tree nodes +//----------------------------------------------------------------------------- +inline int CDispCollTree::CalcNodeCount( int power ) +{ + // power range [2...4] + Assert( power > 0 ); + Assert( power < 5 ); + + return ( ( 1 << ( ( power + 1 ) << 1 ) ) / 3 ); +} + + +//----------------------------------------------------------------------------- +// Purpose: get the parent node index given the current node +// Input: nodeIndex - current node index +// Output: int - the index of the parent node +//----------------------------------------------------------------------------- +inline int CDispCollTree::GetParentNode( int nodeIndex ) +{ + // node range [0...m_NodeCount) + Assert( nodeIndex >= 0 ); + Assert( nodeIndex < m_NodeCount ); + + // ( nodeIndex - 1 ) / 4 + return ( ( nodeIndex - 1 ) >> 2 ); +} + + +//----------------------------------------------------------------------------- +// Purpose: get the child node index given the current node index and direction +// of the child (1 of 4) +// Input: nodeIndex - current node index +// direction - direction of the child ( [0...3] - SW, SE, NW, NE ) +// Output: int - the index of the child node +//----------------------------------------------------------------------------- +inline int CDispCollTree::GetChildNode( int nodeIndex, int direction ) +{ + // node range [0...m_NodeCount) + Assert( nodeIndex >= 0 ); + Assert( nodeIndex < m_NodeCount ); + + // ( nodeIndex * 4 ) + ( direction + 1 ) + return ( ( nodeIndex << 2 ) + ( direction + 1 ) ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline int CDispCollTree::GetNodeLevel( int nodeIndex ) +{ + // node range [0...m_NodeCount) + Assert( nodeIndex >= 0 ); + Assert( nodeIndex < m_NodeCount ); + + // level = 2^n + 1 + if( nodeIndex == 0 ) { return 1; } + if( nodeIndex < 5 ) { return 2; } + if( nodeIndex < 21 ) { return 3; } + if( nodeIndex < 85 ) { return 4; } + if( nodeIndex < 341 ) { return 5; } + + return -1; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool CDispCollTree::RayTriTest( Vector const &rayStart, Vector const &rayDir, float const rayLength, + CDispCollTri const *pTri, float *fraction ) +{ + const float DET_EPSILON = 0.001f; + const float DIST_EPSILON = 0.001f; + + // + // calculate the edges + // + Vector edge1 = pTri->m_Points[1] - pTri->m_Points[0]; + Vector edge2 = pTri->m_Points[2] - pTri->m_Points[0]; + +// Vector faceNormal = edge1.Cross( edge2 ); +// Vector normNormal = faceNormal.Normalize(); + + // + // calculate the triangle's determinant + // + Vector pVec = rayDir.Cross( edge2 ); + float det = pVec.Dot( edge1 ); + + // if determinant is zero -- ray lies in plane + if( ( det > -DET_EPSILON ) && ( det < DET_EPSILON ) ) + return false; + + // + // utility calculations - inverse determinant and distance from v0 to ray start + // + double invDet = 1.0f / det; + Vector tVec = rayStart - pTri->m_Points[0]; + + // + // calculate the U parameter and test bounds + // + double u = pVec.Dot( tVec ) * invDet; + if( ( u < 0.0f ) || ( u > 1.0f ) ) + return false; + + Vector qVec = tVec.Cross( edge1 ); + + // + // calculate the V parameter and test bounds + // + double v = qVec.Dot( rayDir ) * invDet; + if( ( v < 0.0f ) || ( ( u + v ) > 1.0f ) ) + return false; + + // calculate where ray intersects triangle + *fraction = qVec.Dot( edge2 ) * invDet; + *fraction /= rayLength; + + if( ( *fraction < DIST_EPSILON ) || ( *fraction > ( 1.0f - DIST_EPSILON ) ) ) + return false; + + return true; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool CDispCollTree::RayTriListTest( CDispCollTreeTempData *pTemp, CDispCollData *pData ) +{ + // save starting fraction -- to test for collision + float startFraction = pData->m_Fraction; + + // + // calculate the ray + // + Vector seg = pData->m_EndPos - pData->m_StartPos; + Vector rayDir = seg; + float rayLength = VectorNormalize( rayDir ); + + // + // test ray against all triangles in list + // + for( int i = 0; i < pTemp->m_TriListCount; i++ ) + { + float fraction = 1.0f; + bool bResult = RayTriTest( pData->m_StartPos, rayDir, rayLength, pTemp->m_ppTriList[i], &fraction ); + if( !bResult ) + continue; + + if( pData->m_bOcclude ) + { + return true; + } + + if( fraction < pData->m_Fraction ) + { + pData->m_Fraction = fraction; + pData->m_Normal = pTemp->m_ppTriList[i]->m_Normal; + pData->m_Distance = pTemp->m_ppTriList[i]->m_Distance; + } + } + + // collision! + if( pData->m_Fraction < startFraction ) + return true; + + // no collision! + return false; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::RayAABBTest( CDispCollTreeTempData *pTemp, Vector &rayStart, Vector &rayEnd ) +{ + const float MY_DIST_EPSILON = 0.01f; + + for( int i = 0; i < 6; i++ ) + { + float dist1 = m_AABBNormals[i].Dot( rayStart ) - pTemp->m_AABBDistances[i]; + float dist2 = m_AABBNormals[i].Dot( rayEnd ) - pTemp->m_AABBDistances[i]; + + // + // entry intersection point - move ray start up to intersection + // + if( ( dist1 > MY_DIST_EPSILON ) && ( dist2 < -MY_DIST_EPSILON ) ) + { + float fraction = ( dist1 / ( dist1 - dist2 ) ); + + Vector segment, increment; + segment = ( rayEnd - rayStart ) * fraction; + increment = segment; + VectorNormalize(increment); + segment += increment; + rayStart += segment; + } + else if( ( dist1 > MY_DIST_EPSILON ) && ( dist2 > MY_DIST_EPSILON ) ) + { + return false; + } + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTree::CreatePlanesFromBounds( CDispCollTreeTempData *pTemp, Vector const &bbMin, Vector const &bbMax ) +{ + // + // note -- these never change! + // +// m_AABBNormals[0].x = -1; +// m_AABBNormals[1].x = 1; + +// m_AABBNormals[2].y = -1; +// m_AABBNormals[3].y = 1; + +// m_AABBNormals[4].z = -1; +// m_AABBNormals[5].z = 1; + + pTemp->m_AABBDistances[0] = -bbMin.x; + pTemp->m_AABBDistances[1] = bbMax.x; + + pTemp->m_AABBDistances[2] = -bbMin.y; + pTemp->m_AABBDistances[3] = bbMax.y; + + pTemp->m_AABBDistances[4] = -bbMin.z; + pTemp->m_AABBDistances[5] = bbMax.z; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTree::RayNodeTest_r( CDispCollTreeTempData *pTemp, int nodeIndex, Vector rayStart, Vector rayEnd ) +{ + // get the current node + CDispCollNode *pNode = &m_pNodes[nodeIndex]; + + // + // get node bounding box and create collision planes + // + Vector bounds[2]; + pNode->GetBounds( bounds[0], bounds[1] ); + CreatePlanesFromBounds( pTemp, bounds[0], bounds[1] ); + + bool bIntersect = RayAABBTest( pTemp, rayStart, rayEnd ); + if( bIntersect ) + { + // done -- add triangles to triangle list + if( pNode->IsLeaf() ) + { + // Assert for now -- flush cache later!!!!! + Assert( pTemp->m_TriListCount >= 0 ); + Assert( pTemp->m_TriListCount < TRILIST_CACHE_SIZE ); + + pTemp->m_ppTriList[pTemp->m_TriListCount] = &pNode->m_Tris[0]; + pTemp->m_ppTriList[pTemp->m_TriListCount+1] = &pNode->m_Tris[1]; + pTemp->m_TriListCount += 2; + } + // continue recursion + else + { + for( int i = 0; i < 4; i++ ) + { + RayNodeTest_r( pTemp, GetChildNode( nodeIndex, i ), rayStart, rayEnd ); + } + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::RayTestAllTris( CDispCollData *pData, int power ) +{ + // + // get leaf indices + // + int startIndex = CalcNodeCount( power - 1 ); + int endIndex = CalcNodeCount( power ); + + // save incoming fraction + float startFraction = pData->m_Fraction; + float fraction = pData->m_Fraction; + + Vector ray = pData->m_EndPos - pData->m_StartPos; + Vector rayDir = ray; + float rayLength = VectorNormalize(rayDir); + + // + // test ray against all triangles in list + // + for( int index = startIndex; index < endIndex; index++ ) + { + for( int j = 0; j < 2; j++ ) + { + bool bResult = RayTriTest( pData->m_StartPos, rayDir, rayLength, &m_pNodes[index].m_Tris[j], &fraction ); + if( !bResult ) + continue; + + if( pData->m_bOcclude ) + { + return true; + } + + if( fraction < pData->m_Fraction ) + { + pData->m_Fraction = fraction; + pData->m_Normal = m_pNodes[index].m_Tris[j].m_Normal; + pData->m_Distance = m_pNodes[index].m_Tris[j].m_Distance; + } + } + } + + // collision! + if( pData->m_Fraction < startFraction ) + return true; + + // no collision! + return false; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::RayTest( CDispCollData *pData ) +{ + // reset the triangle list count + CDispCollTreeTempData tmp; + tmp.m_TriListCount = 0; + + // trace against nodes (copy start, end because they change) + RayNodeTest_r( &tmp, 0, pData->m_StartPos, pData->m_EndPos ); + + // + // trace against tris (if need be) + // + if( tmp.m_TriListCount != 0 ) + { + bool result = RayTriListTest( &tmp, pData ); + return result; + } + + return false; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::SweptAABBTriIntersect( Vector &rayStart, Vector &rayEnd, Vector &extents, + CDispCollTri const *pTri, Vector &plNormal, float *plDist, + float *fraction ) +{ + + // + // PUT A COPY HERE OF START AND END -- SINCE I CHANGE THEM!!!!!! + // + + + + + + int dir, ptIndex; + float closeValue; + float distStart, distEnd; + float t; + Vector rayPt; + + // get ray direction + Vector rayDir = rayEnd - rayStart; + + // initialize fraction + *fraction = 1.0f; + + // + // test for collision with axial planes (x, y, z) + // + for( dir = 0; dir < 3; dir++ ) + { + if( rayDir[dir] < 0.0f ) + { + closeValue = -99999.9f; + for( ptIndex = 0; ptIndex < 3; ptIndex++ ) + { + if( pTri->m_Points[ptIndex][dir] > closeValue ) + { + closeValue = pTri->m_Points[ptIndex][dir]; + } + } + + closeValue += extents[dir]; + + distStart = rayStart[dir] - closeValue; + distEnd = rayEnd[dir] - closeValue; + } + else + { + closeValue = 99999.9f; + for( ptIndex = 0; ptIndex < 3; ptIndex++ ) + { + if( pTri->m_Points[ptIndex][dir] < closeValue ) + { + closeValue = pTri->m_Points[ptIndex][dir]; + } + } + + closeValue -= extents[dir]; + + distStart = -( rayStart[dir] - closeValue ); + distEnd = -( rayEnd[dir] - closeValue ); + } + + if( ( distStart > COLLISION_EPSILON ) && ( distEnd < -COLLISION_EPSILON ) ) + { + t = ( distStart - COLLISION_EPSILON ) / ( distStart - distEnd ); + if( t > *fraction ) + { + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayStart ); + *fraction = t; + plNormal.Init(); + plNormal[dir] = 1.0f; + *plDist = closeValue; + } + } + else if( ( distStart < -COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + t = ( distStart + COLLISION_EPSILON ) / ( distStart - distEnd ); + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayEnd ); + } + else if( ( distStart > COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + return false; + } + } + + // + // check for an early out + // + if( ( pTri->m_Normal[0] > ONE_MINUS_COLLISION_EPSILON ) || + ( pTri->m_Normal[1] > ONE_MINUS_COLLISION_EPSILON ) || + ( pTri->m_Normal[2] > ONE_MINUS_COLLISION_EPSILON ) ) + { + if( *fraction == 1.0f ) + return false; + + return true; + } + + // + // handle 9 edge tests + // + Vector normal; + Vector edge; + float dist; + + // find the closest box point + Vector boxPt( 0.0f, 0.0f, 0.0f ); + for( dir = 0; dir < 3; dir++ ) + { + if( rayDir[dir] < 0.0f ) + { + boxPt[dir] = extents[dir]; + } + else + { + boxPt[dir] = -extents[dir]; + } + } + + // + // edge 0 + // + edge = pTri->m_Points[1] - pTri->m_Points[0]; + + // cross x-edge + normal.x = 0.0f; + normal.y = -edge.z; + normal.z = edge.y; + + // extents adjusted dist + dist = ( normal.y * ( boxPt.y - pTri->m_Points[0].y ) ) + ( normal.z * ( boxPt.z - pTri->m_Points[0].z ) ); + + // find distances from plane (start, end) + distStart = ( normal.y * rayStart.y ) + ( normal.z * rayStart.z ) - dist; + distEnd = ( normal.y * rayEnd.y ) + ( normal.z * rayEnd.z ) - dist; + + if( ( distStart > COLLISION_EPSILON ) && ( distEnd < -COLLISION_EPSILON ) ) + { + t = ( distStart - COLLISION_EPSILON ) / ( distStart - distEnd ); + if( t > *fraction ) + { + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayStart ); + *fraction = t; + plNormal = normal; + *plDist = dist; + } + } + else if( ( distStart < -COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + t = ( distStart + COLLISION_EPSILON ) / ( distStart - distEnd ); + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayEnd ); + } + else if( ( distStart > COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + return false; + } + + // cross y-edge + normal.x = edge.z; + normal.y = 0.0f; + normal.z = edge.y; + + // extents adjusted dist + dist = ( normal.x * ( boxPt.x - pTri->m_Points[0].x ) ) + ( normal.z * ( boxPt.z - pTri->m_Points[0].z ) ); + + // find distances from plane (start, end) + distStart = ( normal.x * rayStart.x ) + ( normal.z * rayStart.z ) - dist; + distEnd = ( normal.x * rayEnd.x ) + ( normal.z * rayEnd.z ) - dist; + + if( ( distStart > COLLISION_EPSILON ) && ( distEnd < -COLLISION_EPSILON ) ) + { + t = ( distStart - COLLISION_EPSILON ) / ( distStart - distEnd ); + if( t > *fraction ) + { + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayStart ); + *fraction = t; + plNormal = normal; + *plDist = dist; + } + } + else if( ( distStart < -COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + t = ( distStart + COLLISION_EPSILON ) / ( distStart - distEnd ); + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayEnd ); + } + else if( ( distStart > COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + return false; + } + + // cross z-edge + normal.x = -edge.y; + normal.y = edge.x; + normal.z = 0.0f; + + // extents adjusted dist + dist = ( normal.x * ( boxPt.x - pTri->m_Points[0].x ) ) + ( normal.y * ( boxPt.y - pTri->m_Points[0].y ) ); + + // find distances from plane (start, end) + distStart = ( normal.x * rayStart.x ) + ( normal.y * rayStart.y ) - dist; + distEnd = ( normal.x * rayEnd.x ) + ( normal.y * rayEnd.y ) - dist; + + if( ( distStart > COLLISION_EPSILON ) && ( distEnd < -COLLISION_EPSILON ) ) + { + t = ( distStart - COLLISION_EPSILON ) / ( distStart - distEnd ); + if( t > *fraction ) + { + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayStart ); + *fraction = t; + plNormal = normal; + *plDist = dist; + } + } + else if( ( distStart < -COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + t = ( distStart + COLLISION_EPSILON ) / ( distStart - distEnd ); + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayEnd ); + } + else if( ( distStart > COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + return false; + } + + // + // edge 1 + // + edge = pTri->m_Points[2] - pTri->m_Points[1]; + + // cross x-edge + normal.x = 0.0f; + normal.y = -edge.z; + normal.z = edge.y; + + // extents adjusted dist + dist = ( normal.y * ( boxPt.y - pTri->m_Points[0].y ) ) + ( normal.z * ( boxPt.z - pTri->m_Points[0].z ) ); + + // find distances from plane (start, end) + distStart = ( normal.y * rayStart.y ) + ( normal.z * rayStart.z ) - dist; + distEnd = ( normal.y * rayEnd.y ) + ( normal.z * rayEnd.z ) - dist; + + if( ( distStart > COLLISION_EPSILON ) && ( distEnd < -COLLISION_EPSILON ) ) + { + t = ( distStart - COLLISION_EPSILON ) / ( distStart - distEnd ); + if( t > *fraction ) + { + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayStart ); + *fraction = t; + plNormal = normal; + *plDist = dist; + } + } + else if( ( distStart < -COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + t = ( distStart + COLLISION_EPSILON ) / ( distStart - distEnd ); + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayEnd ); + } + else if( ( distStart > COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + return false; + } + + // cross y-edge + normal.x = edge.z; + normal.y = 0.0f; + normal.z = edge.y; + + // extents adjusted dist + dist = ( normal.x * ( boxPt.x - pTri->m_Points[0].x ) ) + ( normal.z * ( boxPt.z - pTri->m_Points[0].z ) ); + + // find distances from plane (start, end) + distStart = ( normal.x * rayStart.x ) + ( normal.z * rayStart.z ) - dist; + distEnd = ( normal.x * rayEnd.x ) + ( normal.z * rayEnd.z ) - dist; + + if( ( distStart > COLLISION_EPSILON ) && ( distEnd < -COLLISION_EPSILON ) ) + { + t = ( distStart - COLLISION_EPSILON ) / ( distStart - distEnd ); + if( t > *fraction ) + { + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayStart ); + *fraction = t; + plNormal = normal; + *plDist = dist; + } + } + else if( ( distStart < -COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + t = ( distStart + COLLISION_EPSILON ) / ( distStart - distEnd ); + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayEnd ); + } + else if( ( distStart > COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + return false; + } + + // cross z-edge + normal.x = -edge.y; + normal.y = edge.x; + normal.z = 0.0f; + + // extents adjusted dist + dist = ( normal.x * ( boxPt.x - pTri->m_Points[0].x ) ) + ( normal.y * ( boxPt.y - pTri->m_Points[0].y ) ); + + // find distances from plane (start, end) + distStart = ( normal.x * rayStart.x ) + ( normal.y * rayStart.y ) - dist; + distEnd = ( normal.x * rayEnd.x ) + ( normal.y * rayEnd.y ) - dist; + + if( ( distStart > COLLISION_EPSILON ) && ( distEnd < -COLLISION_EPSILON ) ) + { + t = ( distStart - COLLISION_EPSILON ) / ( distStart - distEnd ); + if( t > *fraction ) + { + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayStart ); + *fraction = t; + plNormal = normal; + *plDist = dist; + } + } + else if( ( distStart < -COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + t = ( distStart + COLLISION_EPSILON ) / ( distStart - distEnd ); + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayEnd ); + } + else if( ( distStart > COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + return false; + } + + // + // edge 2 + // + edge = pTri->m_Points[0] - pTri->m_Points[2]; + + // cross x-edge + normal.x = 0.0f; + normal.y = -edge.z; + normal.z = edge.y; + + // extents adjusted dist + dist = ( normal.y * ( boxPt.y - pTri->m_Points[0].y ) ) + ( normal.z * ( boxPt.z - pTri->m_Points[0].z ) ); + + // find distances from plane (start, end) + distStart = ( normal.y * rayStart.y ) + ( normal.z * rayStart.z ) - dist; + distEnd = ( normal.y * rayEnd.y ) + ( normal.z * rayEnd.z ) - dist; + + if( ( distStart > COLLISION_EPSILON ) && ( distEnd < -COLLISION_EPSILON ) ) + { + t = ( distStart - COLLISION_EPSILON ) / ( distStart - distEnd ); + if( t > *fraction ) + { + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayStart ); + *fraction = t; + plNormal = normal; + *plDist = dist; + } + } + else if( ( distStart < -COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + t = ( distStart + COLLISION_EPSILON ) / ( distStart - distEnd ); + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayEnd ); + } + else if( ( distStart > COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + return false; + } + + // cross y-edge + normal.x = edge.z; + normal.y = 0.0f; + normal.z = edge.y; + + // extents adjusted dist + dist = ( normal.x * ( boxPt.x - pTri->m_Points[0].x ) ) + ( normal.z * ( boxPt.z - pTri->m_Points[0].z ) ); + + // find distances from plane (start, end) + distStart = ( normal.x * rayStart.x ) + ( normal.z * rayStart.z ) - dist; + distEnd = ( normal.x * rayEnd.x ) + ( normal.z * rayEnd.z ) - dist; + + if( ( distStart > COLLISION_EPSILON ) && ( distEnd < -COLLISION_EPSILON ) ) + { + t = ( distStart - COLLISION_EPSILON ) / ( distStart - distEnd ); + if( t > *fraction ) + { + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayStart ); + *fraction = t; + plNormal = normal; + *plDist = dist; + } + } + else if( ( distStart < -COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + t = ( distStart + COLLISION_EPSILON ) / ( distStart - distEnd ); + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayEnd ); + } + else if( ( distStart > COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + return false; + } + + // cross z-edge + normal.x = -edge.y; + normal.y = edge.x; + normal.z = 0.0f; + + // extents adjusted dist + dist = ( normal.x * ( boxPt.x - pTri->m_Points[0].x ) ) + ( normal.y * ( boxPt.y - pTri->m_Points[0].y ) ); + + // find distances from plane (start, end) + distStart = ( normal.x * rayStart.x ) + ( normal.y * rayStart.y ) - dist; + distEnd = ( normal.x * rayEnd.x ) + ( normal.y * rayEnd.y ) - dist; + + if( ( distStart > COLLISION_EPSILON ) && ( distEnd < -COLLISION_EPSILON ) ) + { + t = ( distStart - COLLISION_EPSILON ) / ( distStart - distEnd ); + if( t > *fraction ) + { + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayStart ); + *fraction = t; + plNormal = normal; + *plDist = dist; + } + } + else if( ( distStart < -COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + t = ( distStart + COLLISION_EPSILON ) / ( distStart - distEnd ); + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayEnd ); + } + else if( ( distStart > COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + return false; + } + + // + // test face plane + // + dist = ( pTri->m_Normal.x * ( boxPt.x - pTri->m_Points[0].x ) ) + + ( pTri->m_Normal.y * ( boxPt.y - pTri->m_Points[0].y ) ) + + ( pTri->m_Normal.z * ( boxPt.z - pTri->m_Points[0].z ) ); + + distStart = pTri->m_Normal.Dot( rayStart ) - dist; + distEnd = pTri->m_Normal.Dot( rayEnd ) - dist; + + if( ( distStart > COLLISION_EPSILON ) && ( distEnd < -COLLISION_EPSILON ) ) + { + t = ( distStart - COLLISION_EPSILON ) / ( distStart - distEnd ); + if( t > *fraction ) + { + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayStart ); + *fraction = t; + plNormal = normal; + *plDist = dist; + } + } + else if( ( distStart < -COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + t = ( distStart + COLLISION_EPSILON ) / ( distStart - distEnd ); + VectorScale( rayDir, t, rayPt ); + VectorAdd( rayStart, rayPt, rayEnd ); + } + else if( ( distStart > COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + return false; + } + + if( *fraction == 1.0f ) + return false; + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::AABBTriIntersect( CDispCollTreeTempData *pTemp, CDispCollData *pData ) +{ + bool bResult = false; + + Vector normal; + float fraction, dist; + + // + // sweep ABB against all triangles in list + // + for( int i = 0; i < pTemp->m_TriListCount; i++ ) + { + if( pTemp->m_ppTriList[i]->IsIntersect() ) + { + bResult = SweptAABBTriIntersect( pData->m_StartPos, pData->m_EndPos, pData->m_Extents, + pTemp->m_ppTriList[i], normal, &dist, &fraction ); + if( bResult ) + { + if( fraction < pData->m_Fraction ) + { + pData->m_Fraction = fraction; + pData->m_Normal = normal; + pData->m_Distance = dist; + } + } + } + } + + return bResult; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::IntersectAABBTriTest( Vector &rayStart, Vector &extents, + CDispCollTri const *pTri ) +{ + int dir, ptIndex; + float dist; + + // + // test axail planes (x, y, z) + // + + for( dir = 0; dir < 3; dir++ ) + { + // + // negative axial plane, component = dir + // + dist = rayStart[dir] - extents[dir]; + for( ptIndex = 0; ptIndex < 3; ptIndex++ ) + { + if( pTri->m_Points[ptIndex][dir] > dist ) + break; + } + + if( ptIndex == 3 ) + return false; + + // + // positive axial plane, component = dir + // + dist = rayStart[dir] + extents[dir]; + for( ptIndex = 0; ptIndex < 3; ptIndex++ ) + { + if( pTri->m_Points[ptIndex][dir] < dist ) + break; + } + + if( ptIndex == 3 ) + return false; + } + + // + // add a test here to see if triangle face normal is close to axial -- done if so!!! + // + if( ( pTri->m_Normal[0] > ONE_MINUS_COLLISION_EPSILON ) || + ( pTri->m_Normal[1] > ONE_MINUS_COLLISION_EPSILON ) || + ( pTri->m_Normal[2] > ONE_MINUS_COLLISION_EPSILON ) ) + return true; + + // find the closest point on the box (use negated tri face noraml) + Vector boxPt( 0.0f, 0.0f, 0.0f ); + for( dir = 0; dir < 3; dir++ ) + { + if( pTri->m_Normal[dir] < 0.0f ) + { + boxPt[dir] = extents[dir]; + } + else + { + boxPt[dir] = -extents[dir]; + } + } + + // + // triangle plane test + // + // do the opposite because the ray has been negated + if( ( ( pTri->m_Normal.x * ( boxPt.x - pTri->m_Points[0].x ) ) + + ( pTri->m_Normal.y * ( boxPt.y - pTri->m_Points[0].y ) ) + + ( pTri->m_Normal.z * ( boxPt.z - pTri->m_Points[0].z ) ) ) > 0.0f ) + return false; + + // + // test edge planes - 9 of them + // + Vector normal; + Vector edge; + + // + // edge 0 + // + edge = pTri->m_Points[1] - pTri->m_Points[0]; + + // cross x + normal.x = 0.0f; + normal.y = -edge.z; + normal.z = edge.y; + if( ( ( normal.y * ( boxPt.y - pTri->m_Points[0].y ) ) + ( normal.z * ( boxPt.z - pTri->m_Points[0].z ) ) ) > 0.0f ) + return false; + + // cross y + normal.x = edge.z; + normal.y = 0.0f; + normal.z = edge.y; + if( ( ( normal.x * ( boxPt.x - pTri->m_Points[0].x ) ) + ( normal.z * ( boxPt.z - pTri->m_Points[0].z ) ) ) > 0.0f ) + return false; + + // cross z + normal.x = -edge.y; + normal.y = edge.x; + normal.z = 0.0f; + if( ( ( normal.x * ( boxPt.x - pTri->m_Points[0].x ) ) + ( normal.y * ( boxPt.y - pTri->m_Points[0].y ) ) ) > 0.0f ) + return false; + + // + // edge 1 + // + edge = pTri->m_Points[2] - pTri->m_Points[1]; + + // cross x + normal.x = 0.0f; + normal.y = -edge.z; + normal.z = edge.y; + if( ( ( normal.y * ( boxPt.y - pTri->m_Points[0].y ) ) + ( normal.z * ( boxPt.z - pTri->m_Points[0].z ) ) ) > 0.0f ) + return false; + + // cross y + normal.x = edge.z; + normal.y = 0.0f; + normal.z = edge.y; + if( ( ( normal.x * ( boxPt.x - pTri->m_Points[0].x ) ) + ( normal.z * ( boxPt.z - pTri->m_Points[0].z ) ) ) > 0.0f ) + return false; + + // cross z + normal.x = -edge.y; + normal.y = edge.x; + normal.z = 0.0f; + if( ( ( normal.x * ( boxPt.x - pTri->m_Points[0].x ) ) + ( normal.y * ( boxPt.y - pTri->m_Points[0].y ) ) ) > 0.0f ) + return false; + + // + // edge 2 + // + edge = pTri->m_Points[0] - pTri->m_Points[2]; + + // cross x + normal.x = 0.0f; + normal.y = -edge.z; + normal.z = edge.y; + if( ( ( normal.y * ( boxPt.y - pTri->m_Points[0].y ) ) + ( normal.z * ( boxPt.z - pTri->m_Points[0].z ) ) ) > 0.0f ) + return false; + + // cross y + normal.x = edge.z; + normal.y = 0.0f; + normal.z = edge.y; + if( ( ( normal.x * ( boxPt.x - pTri->m_Points[0].x ) ) + ( normal.z * ( boxPt.z - pTri->m_Points[0].z ) ) ) > 0.0f ) + return false; + + // cross z + normal.x = -edge.y; + normal.y = edge.x; + normal.z = 0.0f; + if( ( ( normal.x * ( boxPt.x - pTri->m_Points[0].x ) ) + ( normal.y * ( boxPt.y - pTri->m_Points[0].y ) ) ) > 0.0f ) + return false; + + return true; +} + + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::SweptAABBTriTest( Vector &rayStart, Vector &rayEnd, Vector &extents, + CDispCollTri const *pTri ) +{ + // get ray direction + Vector rayDir = rayEnd - rayStart; + + // + // quick and dirty test -- test to see if the object is traveling away from triangle surface??? + // + if( pTri->m_Normal.Dot( rayDir ) > 0.0f ) + return false; + + // + // calc the swept triangle face (negate the ray -- opposite direction of box travel) + // + rayDir.Negate(); + + Vector points[3]; + points[0] = pTri->m_Points[0] + rayDir; + points[1] = pTri->m_Points[1] + rayDir; + points[2] = pTri->m_Points[2] + rayDir; + + // + // handle 4 faces tests (3 axial planes and triangle face) + // + int dir; + float dist; + + // + // axial planes tests (x, y, z) + // + for( dir = 0; dir < 3; dir++ ) + { + bool bOutside = true; + + if( rayDir[dir] < 0.0f ) + { + dist = rayStart[dir] - extents[dir]; + for( int ptIndex = 0; ptIndex < 3; ptIndex ) + { + if( points[ptIndex][dir] > dist ) + { + bOutside = false; + break; + } + } + } + else + { + dist = rayStart[dir] + extents[dir]; + for( int ptIndex = 0; ptIndex < 3; ptIndex ) + { + if( pTri->m_Points[ptIndex][dir] < dist ) + { + bOutside = false; + break; + } + } + } + + if( bOutside ) + return false; + } + + // + // add a test here to see if triangle face normal is close to axial -- done if so!!! + // + if( ( pTri->m_Normal[0] > ONE_MINUS_COLLISION_EPSILON ) || + ( pTri->m_Normal[1] > ONE_MINUS_COLLISION_EPSILON ) || + ( pTri->m_Normal[2] > ONE_MINUS_COLLISION_EPSILON ) ) + return true; + + // + // handle 9 edge tests - always use the newly swept face for this + // + Vector normal; + Vector edge; + + // find the closest box point - (is written opposite to normal due to negating ray) + Vector boxPt( 0.0f, 0.0f, 0.0f ); + for( dir = 0; dir < 3; dir++ ) + { + if( rayDir[dir] < 0.0f ) + { + boxPt[dir] = rayStart[dir] - extents[dir]; + } + else + { + boxPt[dir] = rayStart[dir] + extents[dir]; + } + } + + // + // edge 0 + // + edge = points[1] - points[0]; + + // cross x-edge + normal.x = 0.0f; + normal.y = -edge.z; + normal.z = edge.y; + if( ( ( normal.y * ( boxPt.y - points[0].y ) ) + ( normal.z * ( boxPt.z - points[0].z ) ) ) > 0.0f ) + return false; + + // cross, y-edge + normal.x = edge.z; + normal.y = 0.0f; + normal.z = edge.y; + if( ( ( normal.x * ( boxPt.x - points[0].x ) ) + ( normal.z * ( boxPt.z - points[0].z ) ) ) > 0.0f ) + return false; + + // cross z-edge + normal.x = -edge.y; + normal.y = edge.x; + normal.z = 0.0f; + if( ( ( normal.x * ( boxPt.x - points[0].x ) ) + ( normal.y * ( boxPt.y - points[0].y ) ) ) > 0.0f ) + return false; + + // + // edge 1 + // + edge = points[2] - points[1]; + + // cross x-edge + normal.x = 0.0f; + normal.y = -edge.z; + normal.z = edge.y; + if( ( ( normal.y * ( boxPt.y - points[0].y ) ) + ( normal.z * ( boxPt.z - points[0].z ) ) ) > 0.0f ) + return false; + + // cross, y-edge + normal.x = edge.z; + normal.y = 0.0f; + normal.z = edge.y; + if( ( ( normal.x * ( boxPt.x - points[0].x ) ) + ( normal.z * ( boxPt.z - points[0].z ) ) ) > 0.0f ) + return false; + + // cross z-edge + normal.x = -edge.y; + normal.y = edge.x; + normal.z = 0.0f; + if( ( ( normal.x * ( boxPt.x - points[0].x ) ) + ( normal.y * ( boxPt.y - points[0].y ) ) ) > 0.0f ) + return false; + + // + // edge 2 + // + edge = points[0] - points[2]; + + // cross x-edge + normal.x = 0.0f; + normal.y = -edge.z; + normal.z = edge.y; + if( ( ( normal.y * ( boxPt.y - points[0].y ) ) + ( normal.z * ( boxPt.z - points[0].z ) ) ) > 0.0f ) + return false; + + // cross, y-edge + normal.x = edge.z; + normal.y = 0.0f; + normal.z = edge.y; + if( ( ( normal.x * ( boxPt.x - points[0].x ) ) + ( normal.z * ( boxPt.z - points[0].z ) ) ) > 0.0f ) + return false; + + // cross z-edge + normal.x = -edge.y; + normal.y = edge.x; + normal.z = 0.0f; + if( ( ( normal.x * ( boxPt.x - points[0].x ) ) + ( normal.y * ( boxPt.y - points[0].y ) ) ) > 0.0f ) + return false; + + // + // triangle plane test + // + // do the opposite because the ray has been negated + if( ( ( pTri->m_Normal.x * ( boxPt.x - points[0].x ) ) + + ( pTri->m_Normal.y * ( boxPt.y - points[0].y ) ) + + ( pTri->m_Normal.z * ( boxPt.z - points[0].z ) ) ) > 0.0f ) + return false; + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::CullTriList( CDispCollTreeTempData *pTemp, Vector &rayStart, Vector &rayEnd, Vector &extents, bool bIntersect ) +{ + // + // intersect AABB with all triangles in list + // + if( bIntersect ) + { + for( int i = 0; i < pTemp->m_TriListCount; i++ ) + { + if( IntersectAABBTriTest( rayStart, extents, pTemp->m_ppTriList[i] ) ) + return true; + } + + return false; + } + // + // sweep AABB against all triangles in list + // + else + { + bool bResult = false; + + for( int i = 0; i < pTemp->m_TriListCount; i++ ) + { + if( SweptAABBTriTest( rayStart, rayEnd, extents, pTemp->m_ppTriList[i] ) ) + { + pTemp->m_ppTriList[i]->SetIntersect( true ); + bResult = true; + } + } + + return bResult; + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::IntersectAABBAABBTest( CDispCollTreeTempData *pTemp, const Vector &pos, const Vector &extents ) +{ + float dist; + + for( int dir = 0; dir < 3; dir++ ) + { + // negative direction + dist = -( pos[dir] - ( pTemp->m_AABBDistances[(dir>>1)] - extents[dir] ) ); + if( dist > COLLISION_EPSILON ) + return false; + + // positive direction + dist = pos[dir] - ( pTemp->m_AABBDistances[(dir>>1)+1] + extents[dir] ); + if( dist > COLLISION_EPSILON ) + return false; + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::SweptAABBAABBTest( CDispCollTreeTempData *pTemp, const Vector &rayStart, const Vector &rayEnd, const Vector &extents ) +{ + int dir; + float distStart, distEnd; + float fraction; + float deltas[3]; + float scalers[3]; + + // + // enter and exit fractions + // + float enterFraction = 0.0f; + float exitFraction = 0.0f; + + // + // de-normalize the paramter space so that we don't have to divide + // to find the fractional amount later (clamped for precision) + // + deltas[0] = rayEnd.x - rayStart.x; + deltas[1] = rayEnd.y - rayStart.y; + deltas[2] = rayEnd.z - rayStart.z; + if( ( deltas[0] < COLLISION_EPSILON ) && ( deltas[0] > -COLLISION_EPSILON ) ) { deltas[0] = 1.0f; } + if( ( deltas[1] < COLLISION_EPSILON ) && ( deltas[1] > -COLLISION_EPSILON ) ) { deltas[0] = 1.0f; } + if( ( deltas[2] < COLLISION_EPSILON ) && ( deltas[2] > -COLLISION_EPSILON ) ) { deltas[0] = 1.0f; } + scalers[0] = deltas[1] * deltas[2]; + scalers[1] = deltas[0] * deltas[2]; + scalers[2] = deltas[0] * deltas[1]; + + for( dir = 0; dir < 3; dir++ ) + { + // + // negative direction + // + distStart = -( rayStart[dir] - ( pTemp->m_AABBDistances[(dir>>1)] - extents[dir] ) ); + distEnd = -( rayEnd[dir] - ( pTemp->m_AABBDistances[(dir>>1)] - extents[dir] ) ); + + if( ( distStart > COLLISION_EPSILON ) && ( distEnd < -COLLISION_EPSILON ) ) + { + fraction = distStart * scalers[dir]; + if( fraction > enterFraction ) + { + enterFraction = fraction; + } + } + else if( ( distStart < -COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + fraction = distStart * scalers[dir]; + if( fraction < exitFraction ) + { + exitFraction = fraction; + } + } + else if( ( distStart > COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + return false; + } + + // + // positive direction + // + distStart = rayStart[dir] - ( pTemp->m_AABBDistances[(dir>>1)+1] + extents[dir] ); + distEnd = rayEnd[dir] - ( pTemp->m_AABBDistances[(dir>>1)+1] + extents[dir] ); + + if( ( distStart > COLLISION_EPSILON ) && ( distEnd < -COLLISION_EPSILON ) ) + { + fraction = distStart * scalers[dir]; + if( fraction > enterFraction ) + { + enterFraction = fraction; + } + } + else if( ( distStart < -COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + fraction = distStart * scalers[dir]; + if( fraction < exitFraction ) + { + exitFraction = fraction; + } + } + else if( ( distStart > COLLISION_EPSILON ) && ( distEnd > COLLISION_EPSILON ) ) + { + return false; + } + } + + if( exitFraction < enterFraction ) + return false; + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTree::BuildTriList_r( CDispCollTreeTempData *pTemp, int nodeIndex, Vector &rayStart, Vector &rayEnd, Vector &extents, + bool bIntersect ) +{ + // + // get the current nodes bounds and create collision test planes + // (saved in the in class cache m_AABBNormals, m_AABBDistances) + // + Vector bounds[2]; + CDispCollNode *pNode = &m_pNodes[nodeIndex]; + pNode->GetBounds( bounds[0], bounds[1] ); + CreatePlanesFromBounds( pTemp, bounds[0], bounds[1] ); + + // + // interesect/sweep test + // + bool bResult; + if( bIntersect ) + { + bResult = IntersectAABBAABBTest( pTemp, rayStart, extents ); + } + else + { + bResult = SweptAABBAABBTest( pTemp, rayStart, rayEnd, extents ); + } + + if( bResult ) + { + // if leaf node -- add triangles to interstection test list + if( pNode->IsLeaf() ) + { + // Assert for now -- flush cache later!!!!! + Assert( pTemp->m_TriListCount >= 0 ); + Assert( pTemp->m_TriListCount < TRILIST_CACHE_SIZE ); + + pTemp->m_ppTriList[pTemp->m_TriListCount] = &pNode->m_Tris[0]; + pTemp->m_ppTriList[pTemp->m_TriListCount+1] = &pNode->m_Tris[1]; + pTemp->m_TriListCount += 2; + } + // continue recursion + else + { + BuildTriList_r( pTemp, GetChildNode( nodeIndex, 0 ), rayStart, rayEnd, extents, bIntersect ); + BuildTriList_r( pTemp, GetChildNode( nodeIndex, 1 ), rayStart, rayEnd, extents, bIntersect ); + BuildTriList_r( pTemp, GetChildNode( nodeIndex, 2 ), rayStart, rayEnd, extents, bIntersect ); + BuildTriList_r( pTemp, GetChildNode( nodeIndex, 3 ), rayStart, rayEnd, extents, bIntersect ); + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::AABBSweep( CDispCollData *pData ) +{ + // reset the triangle lists counts + CDispCollTreeTempData tmp; + tmp.m_TriListCount = 0; + + // sweep the AABB against the tree + BuildTriList_r( &tmp, 0, pData->m_StartPos, pData->m_EndPos, pData->m_Extents, false ); + + // find collision triangles + if( CullTriList( &tmp, pData->m_StartPos, pData->m_EndPos, pData->m_Extents, false ) ) + { + // find closest intersection + return AABBTriIntersect( &tmp, pData ); + } + + return false; +} + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::AABBIntersect( CDispCollData *pData ) +{ + // reset the triangle lists counts + CDispCollTreeTempData tmp; + tmp.m_TriListCount = 0; + + // sweep the AABB against the tree + BuildTriList_r( &tmp, 0, pData->m_StartPos, pData->m_StartPos, pData->m_Extents, true ); + + // find collision triangles + return CullTriList( &tmp, pData->m_StartPos, pData->m_StartPos, pData->m_Extents, true ); +} diff --git a/sp/src/public/dispcoll.h b/sp/src/public/dispcoll.h new file mode 100644 index 00000000..55b6d0b3 --- /dev/null +++ b/sp/src/public/dispcoll.h @@ -0,0 +1,249 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef DISPCOLL_H +#define DISPCOLL_H +#pragma once + +#include "mathlib/vector.h" + +class CCoreDispInfo; + +//============================================================================= +// +// Displacement Collision Triangle Data +// +class CDispCollTri +{ +public: + + void Init( void ); + inline void SetPoint( int index, Vector const& vert ); + inline void SetPointNormal( int index, Vector const& normal ); + void CalcPlane( void ); + + inline void SetIntersect( bool bIntersect ); + inline bool IsIntersect( void ); + + Vector m_Points[3]; // polygon points + Vector m_PointNormals[3]; // polygon point normals + Vector m_Normal; // plane normal + float m_Distance; // plane distance + short m_ProjAxes[2]; // projection axes (2 minor axes) + bool m_bIntersect; // intersected triangle??? +}; + +//============================================================================= +// +// Displacement Collision Node Data +// +class CDispCollNode +{ +public: + + CDispCollNode(); + inline bool IsLeaf( void ); + inline void SetBounds( Vector const &bMin, Vector const &bMax ); + inline void GetBounds( Vector &bMin, Vector &bMax ); + + Vector m_Bounds[2]; // node minimum and maximum + + bool m_bIsLeaf; // is the node a leaf? ( may have to make this an int for alignment!) + CDispCollTri m_Tris[2]; // two triangles contained in leaf node +}; + + +//============================================================================= +// +// Displacement Collision Data +// +class CDispCollData +{ +public: + + Vector m_StartPos; + Vector m_EndPos; + Vector m_Extents; + float m_Fraction; + int m_Contents; + Vector m_Normal; + float m_Distance; + bool m_bOcclude; +}; + + + +// HACKHACK: JAY: Moved this out of CDispCollTree to be thread safe in vrad +enum { TRILIST_CACHE_SIZE = 128 }; + +class CDispCollTreeTempData +{ +public: + // + // temps + // + int m_TriListCount; + CDispCollTri *m_ppTriList[TRILIST_CACHE_SIZE]; + + // collision tree node cache + float m_AABBDistances[6]; +}; + + +//============================================================================= +// +// Displacement Collision Tree +// +class CDispCollTree +{ +public: + + static const float COLLISION_EPSILON; + static const float ONE_MINUS_COLLISION_EPSILON; + + //========================================================================= + // + // Creation/Destruction + // + CDispCollTree(); + ~CDispCollTree(); + + virtual bool Create( CCoreDispInfo *pDisp ); + + //========================================================================= + // + // Collision Functions + // + bool RayTest( CDispCollData *pData ); + bool RayTestAllTris( CDispCollData *pData, int power ); + + bool AABBIntersect( CDispCollData *pData ); + bool AABBSweep( CDispCollData *pData ); + + //========================================================================= + // + // Attrib Functions + // + inline void SetPower( int power ); + inline int GetPower( void ); + + inline void SetCheckCount( int count ); + inline int GetCheckCount( void ); + + inline void GetBounds( Vector& boundMin, Vector& boundMax ); + +protected: + + int m_Power; + + int m_NodeCount; + CDispCollNode *m_pNodes; + + int m_CheckCount; + + // collision tree node cache + Vector m_AABBNormals[6]; + //========================================================================= + // + // Creation/Destruction + // + void InitAABBData( void ); + void InitLeaves( CCoreDispInfo *pDisp ); + void CreateNodes( CCoreDispInfo *pDisp ); + void CreateNodes_r( CCoreDispInfo *pDisp, int nodeIndex, int termLevel ); + void CalcBounds( CDispCollNode *pNode, int nodeIndex ); + + //========================================================================= + // + // Collision Functions + // + void CreatePlanesFromBounds( CDispCollTreeTempData *pTemp, Vector const &bbMin, Vector const &bbMax ); + +// void RayNodeTest_r( int nodeIndex, Vector &rayStart, Vector &rayEnd ); + void RayNodeTest_r( CDispCollTreeTempData *pTemp, int nodeIndex, Vector rayStart, Vector rayEnd ); + bool RayAABBTest( CDispCollTreeTempData *pTemp, Vector &rayStart, Vector &rayEnd ); + bool RayTriListTest( CDispCollTreeTempData *pTemp, CDispCollData *pData ); + bool RayTriTest( Vector const &rayStart, Vector const &rayDir, float const rayLength, CDispCollTri const *pTri, float *fraction ); + + void BuildTriList_r( CDispCollTreeTempData *pTemp, int nodeIndex, Vector &rayStart, Vector &rayEnd, Vector &extents, bool bIntersect ); + bool IntersectAABBAABBTest( CDispCollTreeTempData *pTemp, const Vector &pos, const Vector &extents ); + bool SweptAABBAABBTest( CDispCollTreeTempData *pTemp, const Vector &rayStart, const Vector &rayEnd, const Vector &extents ); + + bool CullTriList( CDispCollTreeTempData *pTemp, Vector &rayStart, Vector &rayEnd, Vector &extents, bool bIntersect ); + bool SweptAABBTriTest( Vector &rayStart, Vector &rayEnd, Vector &extents, CDispCollTri const *pTri ); + bool AABBTriIntersect( CDispCollTreeTempData *pTemp, CDispCollData *pData ); + bool IntersectAABBTriTest( Vector &rayStart, Vector &extents, CDispCollTri const *pTri ); + bool SweptAABBTriIntersect( Vector &rayStart, Vector &rayEnd, Vector &extents, + CDispCollTri const *pTri, Vector &plNormal, float *plDist, + float *fraction ); + + //========================================================================= + // + // Memory Functions + // + bool AllocNodes( int nodeCount ); + void FreeNodes( void ); + + //========================================================================= + // + // Utility Functions + // + inline int CalcNodeCount( int power ); + inline int GetParentNode( int nodeIndex ); + inline int GetChildNode( int nodeIndex, int direction ); + inline int GetNodeLevel( int nodeIndex ); + int GetNodeIndexFromComponents( int x, int y ); +}; + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CDispCollTree::SetPower( int power ) +{ + m_Power = power; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int CDispCollTree::GetPower( void ) +{ + return m_Power; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CDispCollTree::SetCheckCount( int count ) +{ + m_CheckCount = count; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int CDispCollTree::GetCheckCount( void ) +{ + return m_CheckCount; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void CDispCollTree::GetBounds( Vector& boundMin, Vector& boundMax ) +{ + boundMin[0] = m_pNodes[0].m_Bounds[0].x; + boundMin[1] = m_pNodes[0].m_Bounds[0].y; + boundMin[2] = m_pNodes[0].m_Bounds[0].z; + + boundMax[0] = m_pNodes[0].m_Bounds[1].x; + boundMax[1] = m_pNodes[0].m_Bounds[1].y; + boundMax[2] = m_pNodes[0].m_Bounds[1].z; +} + + +#endif // DISPCOLL_H \ No newline at end of file diff --git a/sp/src/public/dispcoll_common.cpp b/sp/src/public/dispcoll_common.cpp new file mode 100644 index 00000000..9122d645 --- /dev/null +++ b/sp/src/public/dispcoll_common.cpp @@ -0,0 +1,1540 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "cmodel.h" +#include "dispcoll_common.h" +#include "collisionutils.h" +#include "tier1/strtools.h" +#include "tier0/vprof.h" +#include "tier1/fmtstr.h" +#include "tier1/utlhash.h" +#include "tier1/generichash.h" +#include "tier0/fasttimer.h" +#include "vphysics/virtualmesh.h" +#include "tier1/datamanager.h" +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//============================================================================= +// Cache + +#ifdef ENGINE_DLL +CDataManager g_DispCollTriCache( 2048*1024 ); +#endif + + +struct DispCollPlaneIndex_t +{ + Vector vecPlane; + int index; +}; + +class CPlaneIndexHashFuncs +{ +public: + CPlaneIndexHashFuncs( int ) {} + + // Compare + bool operator()( const DispCollPlaneIndex_t &lhs, const DispCollPlaneIndex_t &rhs ) const + { + return ( lhs.vecPlane == rhs.vecPlane || lhs.vecPlane == -rhs.vecPlane ); + } + + // Hash + unsigned int operator()( const DispCollPlaneIndex_t &item ) const + { + return HashItem( item.vecPlane ) ^ HashItem( -item.vecPlane ); + } +}; + +CUtlHash g_DispCollPlaneIndexHash( 512 ); + + +//============================================================================= +// Displacement Collision Triangle + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CDispCollTri::CDispCollTri() +{ + Init(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTri::Init( void ) +{ + m_vecNormal.Init(); + m_flDist = 0.0f; + m_TriData[0].m_IndexDummy = m_TriData[1].m_IndexDummy = m_TriData[2].m_IndexDummy = 0; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTri::CalcPlane( CDispVector &m_aVerts ) +{ + Vector vecEdges[2]; + vecEdges[0] = m_aVerts[GetVert( 1 )] - m_aVerts[GetVert( 0 )]; + vecEdges[1] = m_aVerts[GetVert( 2 )] - m_aVerts[GetVert( 0 )]; + + m_vecNormal = vecEdges[1].Cross( vecEdges[0] ); + VectorNormalize( m_vecNormal ); + m_flDist = m_vecNormal.Dot( m_aVerts[GetVert( 0 )] ); + + // Calculate the signbits for the plane - fast test. + m_ucSignBits = 0; + m_ucPlaneType = PLANE_ANYZ; + for ( int iAxis = 0; iAxis < 3 ; ++iAxis ) + { + if ( m_vecNormal[iAxis] < 0.0f ) + { + m_ucSignBits |= 1 << iAxis; + } + + if ( m_vecNormal[iAxis] == 1.0f ) + { + m_ucPlaneType = iAxis; + } + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void FindMin( float v1, float v2, float v3, int &iMin ) +{ + float flMin = v1; + iMin = 0; + if( v2 < flMin ) { flMin = v2; iMin = 1; } + if( v3 < flMin ) { flMin = v3; iMin = 2; } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline void FindMax( float v1, float v2, float v3, int &iMax ) +{ + float flMax = v1; + iMax = 0; + if( v2 > flMax ) { flMax = v2; iMax = 1; } + if( v3 > flMax ) { flMax = v3; iMax = 2; } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTri::FindMinMax( CDispVector &m_aVerts ) +{ + int iMin, iMax; + FindMin( m_aVerts[GetVert(0)].x, m_aVerts[GetVert(1)].x, m_aVerts[GetVert(2)].x, iMin ); + FindMax( m_aVerts[GetVert(0)].x, m_aVerts[GetVert(1)].x, m_aVerts[GetVert(2)].x, iMax ); + SetMin( 0, iMin ); + SetMax( 0, iMax ); + + FindMin( m_aVerts[GetVert(0)].y, m_aVerts[GetVert(1)].y, m_aVerts[GetVert(2)].y, iMin ); + FindMax( m_aVerts[GetVert(0)].y, m_aVerts[GetVert(1)].y, m_aVerts[GetVert(2)].y, iMax ); + SetMin( 1, iMin ); + SetMax( 1, iMax ); + + FindMin( m_aVerts[GetVert(0)].z, m_aVerts[GetVert(1)].z, m_aVerts[GetVert(2)].z, iMin ); + FindMax( m_aVerts[GetVert(0)].z, m_aVerts[GetVert(1)].z, m_aVerts[GetVert(2)].z, iMax ); + SetMin( 2, iMin ); + SetMax( 2, iMax ); +} + + +// SIMD Routines for intersecting with the quad tree +FORCEINLINE int IntersectRayWithFourBoxes( const FourVectors &rayStart, const FourVectors &invDelta, const FourVectors &rayExtents, const FourVectors &boxMins, const FourVectors &boxMaxs ) +{ + // SIMD Test ray against all four boxes at once + // each node stores the bboxes of its four children + FourVectors hitMins = boxMins; + hitMins -= rayStart; + FourVectors hitMaxs = boxMaxs; + hitMaxs -= rayStart; + + // adjust for swept box by enlarging the child bounds to shrink the sweep down to a point + hitMins -= rayExtents; + hitMaxs += rayExtents; + + // compute the parametric distance along the ray of intersection in each dimension + hitMins *= invDelta; + hitMaxs *= invDelta; + + // Find the exit parametric intersection distance in each dimesion, for each box + FourVectors exitT = maximum(hitMins,hitMaxs); + // Find the entry parametric intersection distance in each dimesion, for each box + FourVectors entryT = minimum(hitMins,hitMaxs); + + // now find the max overall entry distance across all dimensions for each box + fltx4 minTemp = MaxSIMD(entryT.x, entryT.y); + fltx4 boxEntryT = MaxSIMD(minTemp, entryT.z); + + // now find the min overall exit distance across all dimensions for each box + fltx4 maxTemp = MinSIMD(exitT.x, exitT.y); + fltx4 boxExitT = MinSIMD(maxTemp, exitT.z); + + boxEntryT = MaxSIMD(boxEntryT,Four_Zeros); + boxExitT = MinSIMD(boxExitT,Four_Ones); + + // if entry<=exit for the box, we've got a hit + fltx4 active = CmpLeSIMD(boxEntryT,boxExitT); // mask of which boxes are active + + // hit at least one box? + return TestSignSIMD(active); +} + +// This does 4 simultaneous box intersections +// NOTE: This can be used as a 1 vs 4 test by replicating a single box into the one side +FORCEINLINE int IntersectFourBoxPairs( const FourVectors &mins0, const FourVectors &maxs0, const FourVectors &mins1, const FourVectors &maxs1 ) +{ + // find the max mins and min maxs in each dimension + FourVectors intersectMins = maximum(mins0,mins1); + FourVectors intersectMaxs = minimum(maxs0,maxs1); + + // if intersectMins <= intersectMaxs then the boxes overlap in this dimension + fltx4 overlapX = CmpLeSIMD(intersectMins.x,intersectMaxs.x); + fltx4 overlapY = CmpLeSIMD(intersectMins.y,intersectMaxs.y); + fltx4 overlapZ = CmpLeSIMD(intersectMins.z,intersectMaxs.z); + + // if the boxes overlap in all three dimensions, they intersect + fltx4 tmp = AndSIMD( overlapX, overlapY ); + fltx4 active = AndSIMD( tmp, overlapZ ); + + // hit at least one box? + return TestSignSIMD(active); +} + +// This does 4 simultaneous box vs. sphere intersections +// NOTE: This can be used as a 1 vs 4 test by replicating a single sphere/box into one side +FORCEINLINE int IntersectFourBoxSpherePairs( const FourVectors ¢er, const fltx4 &radiusSq, const FourVectors &mins, const FourVectors &maxs ) +{ + // for each dimension of each box, compute the clamped distance from the mins side to the center (must be >= 0) + FourVectors minDist = mins; + minDist -= center; + FourVectors dist; + dist.x = MaxSIMD(Four_Zeros, minDist.x); + dist.y = MaxSIMD(Four_Zeros, minDist.y); + dist.z = MaxSIMD(Four_Zeros, minDist.z); + + // now compute the distance from the maxs side to the center + FourVectors maxDist = center; + maxDist -= maxs; + // NOTE: Don't need to clamp here because we clamp against the minDist which must be >= 0, so the two clamps + // get folded together + FourVectors totalDist; + totalDist.x = MaxSIMD(dist.x, maxDist.x); + totalDist.y = MaxSIMD(dist.y, maxDist.y); + totalDist.z = MaxSIMD(dist.z, maxDist.z); + // get the total squred distance between each box & sphere center by summing the squares of each + // component/dimension + fltx4 distSq = totalDist * totalDist; + + // if squared distance between each sphere center & box is less than the radiusSquared for that sphere + // we have an intersection + fltx4 active = CmpLeSIMD(distSq,radiusSq); + + // at least one intersection? + return TestSignSIMD(active); +} + + +int FORCEINLINE CDispCollTree::BuildRayLeafList( int iNode, rayleaflist_t &list ) +{ + list.nodeList[0] = iNode; + int listIndex = 0; + list.maxIndex = 0; + while ( listIndex <= list.maxIndex ) + { + iNode = list.nodeList[listIndex]; + // the rest are all leaves + if ( IsLeafNode(iNode) ) + return listIndex; + listIndex++; + const CDispCollNode &node = m_nodes[iNode]; + int mask = IntersectRayWithFourBoxes( list.rayStart, list.invDelta, list.rayExtents, node.m_mins, node.m_maxs ); + if ( mask ) + { + int child = Nodes_GetChild( iNode, 0 ); + if ( mask & 1 ) + { + ++list.maxIndex; + list.nodeList[list.maxIndex] = child; + } + if ( mask & 2 ) + { + ++list.maxIndex; + list.nodeList[list.maxIndex] = child+1; + } + if ( mask & 4 ) + { + ++list.maxIndex; + list.nodeList[list.maxIndex] = child+2; + } + if ( mask & 8 ) + { + ++list.maxIndex; + list.nodeList[list.maxIndex] = child+3; + } + Assert(list.maxIndex < MAX_AABB_LIST); + } + } + + return listIndex; +} + + +//----------------------------------------------------------------------------- +// Purpose: Create the AABB tree. +//----------------------------------------------------------------------------- +bool CDispCollTree::AABBTree_Create( CCoreDispInfo *pDisp ) +{ + // Copy the flags. + m_nFlags = pDisp->GetSurface()->GetFlags(); + + // Copy necessary displacement data. + AABBTree_CopyDispData( pDisp ); + + // Setup/create the leaf nodes first so the recusion can use this data to stop. + AABBTree_CreateLeafs(); + + // Create the bounding box of the displacement surface + the base face. + AABBTree_CalcBounds(); + + // Successful. + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTree::AABBTree_CopyDispData( CCoreDispInfo *pDisp ) +{ + // Displacement size. + m_nPower = pDisp->GetPower(); + + // Displacement base surface data. + CCoreDispSurface *pSurf = pDisp->GetSurface(); + m_nContents = pSurf->GetContents(); + pSurf->GetNormal( m_vecStabDir ); + for ( int iPoint = 0; iPoint < 4; iPoint++ ) + { + pSurf->GetPoint( iPoint, m_vecSurfPoints[iPoint] ); + } + + // Allocate collision tree data. + { + MEM_ALLOC_CREDIT(); + m_aVerts.SetSize( GetSize() ); + } + + { + MEM_ALLOC_CREDIT(); + m_aTris.SetSize( GetTriSize() ); + } + + { + MEM_ALLOC_CREDIT(); + int numLeaves = (GetWidth()-1) * (GetHeight()-1); + m_leaves.SetCount(numLeaves); + int numNodes = Nodes_CalcCount( m_nPower ); + numNodes -= numLeaves; + m_nodes.SetCount(numNodes); + } + + + // Setup size. + m_nSize = sizeof( this ); + m_nSize += sizeof( Vector ) * GetSize(); + m_nSize += sizeof( CDispCollTri ) * GetTriSize(); +#if OLD_DISP_AABB + m_nSize += sizeof( CDispCollAABBNode ) * Nodes_CalcCount( m_nPower ); +#endif + m_nSize += sizeof(m_nodes[0]) * m_nodes.Count(); + m_nSize += sizeof(m_leaves[0]) * m_leaves.Count(); + m_nSize += sizeof( CDispCollTri* ) * DISPCOLL_TREETRI_SIZE; + + // Copy vertex data. + for ( int iVert = 0; iVert < m_aVerts.Count(); iVert++ ) + { + pDisp->GetVert( iVert, m_aVerts[iVert] ); + } + + // Copy and setup triangle data. + unsigned short iVerts[3]; + for ( int iTri = 0; iTri < m_aTris.Count(); ++iTri ) + { + pDisp->GetTriIndices( iTri, iVerts[0], iVerts[1], iVerts[2] ); + m_aTris[iTri].SetVert( 0, iVerts[0] ); + m_aTris[iTri].SetVert( 1, iVerts[1] ); + m_aTris[iTri].SetVert( 2, iVerts[2] ); + m_aTris[iTri].m_uiFlags = pDisp->GetTriTagValue( iTri ); + + // Calculate the surface props and set flags. + float flTotalAlpha = 0.0f; + for ( int iVert = 0; iVert < 3; ++iVert ) + { + flTotalAlpha += pDisp->GetAlpha( m_aTris[iTri].GetVert( iVert ) ); + } + + if ( flTotalAlpha > DISP_ALPHA_PROP_DELTA ) + { + m_aTris[iTri].m_uiFlags |= DISPSURF_FLAG_SURFPROP2; + } + else + { + m_aTris[iTri].m_uiFlags |= DISPSURF_FLAG_SURFPROP1; + } + + // Add the displacement surface flag. + m_aTris[iTri].m_uiFlags |= DISPSURF_FLAG_SURFACE; + + // Calculate the plane normal and the min max. + m_aTris[iTri].CalcPlane( m_aVerts ); + m_aTris[iTri].FindMinMax( m_aVerts ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTree::AABBTree_CreateLeafs( void ) +{ + int numLeaves = (GetWidth()-1) * (GetHeight()-1); + m_leaves.SetCount(numLeaves); + int numNodes = Nodes_CalcCount( m_nPower ); + numNodes -= numLeaves; + m_nodes.SetCount(numNodes); + + // Get the width and height of the displacement. + int nWidth = GetWidth() - 1; + int nHeight = GetHeight() - 1; + + for ( int iHgt = 0; iHgt < nHeight; ++iHgt ) + { + for ( int iWid = 0; iWid < nWidth; ++iWid ) + { + int iLeaf = Nodes_GetIndexFromComponents( iWid, iHgt ); + int iIndex = iHgt * nWidth + iWid; + int iTri = iIndex * 2; + + m_leaves[iLeaf].m_tris[0] = iTri; + m_leaves[iLeaf].m_tris[1] = iTri + 1; + } + } +} + +void CDispCollTree::AABBTree_GenerateBoxes_r( int nodeIndex, Vector *pMins, Vector *pMaxs ) +{ + // leaf + ClearBounds( *pMins, *pMaxs ); + if ( nodeIndex >= m_nodes.Count() ) + { + int iLeaf = nodeIndex - m_nodes.Count(); + + for ( int iTri = 0; iTri < 2; ++iTri ) + { + int triIndex = m_leaves[iLeaf].m_tris[iTri]; + const CDispCollTri &tri = m_aTris[triIndex]; + AddPointToBounds( m_aVerts[tri.GetVert( 0 )], *pMins, *pMaxs ); + AddPointToBounds( m_aVerts[tri.GetVert( 1 )], *pMins, *pMaxs ); + AddPointToBounds( m_aVerts[tri.GetVert( 2 )], *pMins, *pMaxs ); + } + } + else // node + { + Vector childMins[4], childMaxs[4]; + for ( int i = 0; i < 4; i++ ) + { + int child = Nodes_GetChild( nodeIndex, i ); + AABBTree_GenerateBoxes_r( child, &childMins[i], &childMaxs[i] ); + AddPointToBounds( childMins[i], *pMins, *pMaxs ); + AddPointToBounds( childMaxs[i], *pMins, *pMaxs ); + } + m_nodes[nodeIndex].m_mins.LoadAndSwizzle( childMins[0], childMins[1], childMins[2], childMins[3] ); + m_nodes[nodeIndex].m_maxs.LoadAndSwizzle( childMaxs[0], childMaxs[1], childMaxs[2], childMaxs[3] ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTree::AABBTree_CalcBounds( void ) +{ + // Check data. + if ( ( m_aVerts.Count() == 0 ) || ( m_nodes.Count() == 0 ) ) + return; + + AABBTree_GenerateBoxes_r( 0, &m_mins, &m_maxs ); + +#if INCLUDE_SURFACE_IN_BOUNDS + // Add surface points to bounds. + for ( int iPoint = 0; iPoint < 4; ++iPoint ) + { + VectorMin( m_vecSurfPoints[iPoint], m_mins, m_mins ); + VectorMax( m_vecSurfPoints[iPoint], m_maxs, m_maxs ); + } +#endif + + // Bloat a little. + for ( int iAxis = 0; iAxis < 3; ++iAxis ) + { + m_mins[iAxis] -= 1.0f; + m_maxs[iAxis] += 1.0f; + } +} + +static CThreadFastMutex s_CacheMutex; +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline void CDispCollTree::LockCache() +{ +#ifdef ENGINE_DLL + if ( !g_DispCollTriCache.LockResource( m_hCache ) ) + { + AUTO_LOCK_FM( s_CacheMutex ); + + // Cache may have just been created, so check once more + if ( !g_DispCollTriCache.LockResource( m_hCache ) ) + { + Cache(); + m_hCache = g_DispCollTriCache.CreateResource( this ); + g_DispCollTriCache.LockResource( m_hCache ); + //Msg( "Adding 0x%x to cache (actual %d) [%d, %d --> %.2f] %d total, %d unique\n", this, GetCacheMemorySize(), GetTriSize(), m_aEdgePlanes.Count(), (float)m_aEdgePlanes.Count()/(float)GetTriSize(), totals, uniques ); + } + } +#else + Cache(); +#endif +} + +inline void CDispCollTree::UnlockCache() +{ +#ifdef ENGINE_DLL + g_DispCollTriCache.UnlockResource( m_hCache ); +#endif +} +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTree::Cache( void ) +{ + if ( m_aTrisCache.Count() == GetTriSize() ) + { + return; + } + + VPROF( "CDispCollTree::Cache" ); + + // Alloc. +// int nSize = sizeof( CDispCollTriCache ) * GetTriSize(); + int nTriCount = GetTriSize(); + { + MEM_ALLOC_CREDIT(); + m_aTrisCache.SetSize( nTriCount ); + } + + for ( int iTri = 0; iTri < nTriCount; ++iTri ) + { + Cache_Create( &m_aTris[iTri], iTri ); + } + + g_DispCollPlaneIndexHash.Purge(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::AABBTree_Ray( const Ray_t &ray, RayDispOutput_t &output ) +{ + if ( IsBoxIntersectingRay( m_mins, m_maxs, ray.m_Start, ray.m_Delta, DISPCOLL_DIST_EPSILON ) ) + { + return AABBTree_Ray( ray, ray.InvDelta(), output ); + } + return false; +} + +bool CDispCollTree::AABBTree_Ray( const Ray_t &ray, const Vector &vecInvDelta, RayDispOutput_t &output ) +{ + VPROF( "DispRayTest" ); + + // Check for ray test. + if ( CheckFlags( CCoreDispInfo::SURF_NORAY_COLL ) ) + return false; + + // Check for opacity. + if ( !( m_nContents & MASK_OPAQUE ) ) + return false; + + // Pre-calc the inverse delta for perf. + CDispCollTri *pImpactTri = NULL; + + AABBTree_TreeTrisRayBarycentricTest( ray, vecInvDelta, DISPCOLL_ROOTNODE_INDEX, output, &pImpactTri ); + + if ( pImpactTri ) + { + // Collision. + output.ndxVerts[0] = pImpactTri->GetVert( 0 ); + output.ndxVerts[1] = pImpactTri->GetVert( 2 ); + output.ndxVerts[2] = pImpactTri->GetVert( 1 ); + + Assert( (output.u <= 1.0f ) && ( output.v <= 1.0f ) ); + Assert( (output.u >= 0.0f ) && ( output.v >= 0.0f ) ); + + return true; + } + + // No collision. + return false; +} + +void CDispCollTree::AABBTree_TreeTrisRayBarycentricTest( const Ray_t &ray, const Vector &vecInvDelta, int iNode, RayDispOutput_t &output, CDispCollTri **pImpactTri ) +{ + rayleaflist_t list; + // NOTE: This part is loop invariant - should be hoisted up as far as possible + list.invDelta.DuplicateVector(vecInvDelta); + list.rayStart.DuplicateVector(ray.m_Start); + Vector ext = ray.m_Extents + Vector(DISPCOLL_DIST_EPSILON,DISPCOLL_DIST_EPSILON,DISPCOLL_DIST_EPSILON); + list.rayExtents.DuplicateVector(ext); + int listIndex = BuildRayLeafList( iNode, list ); + + float flU, flV, flT; + for ( ; listIndex <= list.maxIndex; listIndex++ ) + { + int leafIndex = list.nodeList[listIndex] - m_nodes.Count(); + CDispCollTri *pTri0 = &m_aTris[m_leaves[leafIndex].m_tris[0]]; + CDispCollTri *pTri1 = &m_aTris[m_leaves[leafIndex].m_tris[1]]; + + if ( ComputeIntersectionBarycentricCoordinates( ray, m_aVerts[pTri0->GetVert( 0 )], m_aVerts[pTri0->GetVert( 2 )], m_aVerts[pTri0->GetVert( 1 )], flU, flV, &flT ) ) + { + // Make sure it's inside the range + if ( ( flU >= 0.0f ) && ( flV >= 0.0f ) && ( ( flU + flV ) <= 1.0f ) ) + { + if( ( flT > 0.0f ) && ( flT < output.dist ) ) + { + (*pImpactTri) = pTri0; + output.u = flU; + output.v = flV; + output.dist = flT; + } + } + } + if ( ComputeIntersectionBarycentricCoordinates( ray, m_aVerts[pTri1->GetVert( 0 )], m_aVerts[pTri1->GetVert( 2 )], m_aVerts[pTri1->GetVert( 1 )], flU, flV, &flT ) ) + { + // Make sure it's inside the range + if ( ( flU >= 0.0f ) && ( flV >= 0.0f ) && ( ( flU + flV ) <= 1.0f ) ) + { + if( ( flT > 0.0f ) && ( flT < output.dist ) ) + { + (*pImpactTri) = pTri1; + output.u = flU; + output.v = flV; + output.dist = flT; + } + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::AABBTree_Ray( const Ray_t &ray, const Vector &vecInvDelta, CBaseTrace *pTrace, bool bSide ) +{ + VPROF("AABBTree_Ray"); + +// VPROF_BUDGET( "DispRayTraces", VPROF_BUDGETGROUP_DISP_RAYTRACES ); + + // Check for ray test. + if ( CheckFlags( CCoreDispInfo::SURF_NORAY_COLL ) ) + return false; + + // Check for opacity. + if ( !( m_nContents & MASK_OPAQUE ) ) + return false; + + // Pre-calc the inverse delta for perf. + CDispCollTri *pImpactTri = NULL; + + AABBTree_TreeTrisRayTest( ray, vecInvDelta, DISPCOLL_ROOTNODE_INDEX, pTrace, bSide, &pImpactTri ); + + if ( pImpactTri ) + { + // Collision. + VectorCopy( pImpactTri->m_vecNormal, pTrace->plane.normal ); + pTrace->plane.dist = pImpactTri->m_flDist; + pTrace->dispFlags = pImpactTri->m_uiFlags; + return true; + } + + // No collision. + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTree::AABBTree_TreeTrisRayTest( const Ray_t &ray, const Vector &vecInvDelta, int iNode, CBaseTrace *pTrace, bool bSide, CDispCollTri **pImpactTri ) +{ + rayleaflist_t list; + // NOTE: This part is loop invariant - should be hoisted up as far as possible + list.invDelta.DuplicateVector(vecInvDelta); + list.rayStart.DuplicateVector(ray.m_Start); + Vector ext = ray.m_Extents + Vector(DISPCOLL_DIST_EPSILON,DISPCOLL_DIST_EPSILON,DISPCOLL_DIST_EPSILON); + list.rayExtents.DuplicateVector(ext); + int listIndex = BuildRayLeafList( iNode, list ); + + for ( ;listIndex <= list.maxIndex; listIndex++ ) + { + int leafIndex = list.nodeList[listIndex] - m_nodes.Count(); + CDispCollTri *pTri0 = &m_aTris[m_leaves[leafIndex].m_tris[0]]; + CDispCollTri *pTri1 = &m_aTris[m_leaves[leafIndex].m_tris[1]]; + float flFrac = IntersectRayWithTriangle( ray, m_aVerts[pTri0->GetVert( 0 )], m_aVerts[pTri0->GetVert( 2 )], m_aVerts[pTri0->GetVert( 1 )], bSide ); + if( ( flFrac >= 0.0f ) && ( flFrac < pTrace->fraction ) ) + { + pTrace->fraction = flFrac; + (*pImpactTri) = pTri0; + } + + flFrac = IntersectRayWithTriangle( ray, m_aVerts[pTri1->GetVert( 0 )], m_aVerts[pTri1->GetVert( 2 )], m_aVerts[pTri1->GetVert( 1 )], bSide ); + if( ( flFrac >= 0.0f ) && ( flFrac < pTrace->fraction ) ) + { + pTrace->fraction = flFrac; + (*pImpactTri) = pTri1; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CDispCollTree::AABBTree_GetTrisInSphere( const Vector ¢er, float radius, unsigned short *pIndexOut, int indexMax ) +{ + return AABBTree_BuildTreeTrisInSphere_r( center, radius, DISPCOLL_ROOTNODE_INDEX, pIndexOut, indexMax ); +} + +int CDispCollTree::AABBTree_BuildTreeTrisInSphere_r( const Vector ¢er, float radius, int iNode, unsigned short *pIndexOut, unsigned short indexMax ) +{ + int nodeList[MAX_AABB_LIST]; + nodeList[0] = iNode; + int nTriCount = 0; + int listIndex = 0; + int maxIndex = 0; + // NOTE: This part is loop invariant - should be hoisted up as far as possible + FourVectors sphereCenters; + sphereCenters.DuplicateVector(center); + float radiusSq = radius * radius; + fltx4 sphereRadSq = ReplicateX4(radiusSq); + while ( listIndex <= maxIndex ) + { + iNode = nodeList[listIndex]; + listIndex++; + // the rest are all leaves + if ( IsLeafNode(iNode) ) + { + VPROF("Tris"); + for ( --listIndex; listIndex <= maxIndex; listIndex++ ) + { + if ( (nTriCount+2) <= indexMax ) + { + int leafIndex = nodeList[listIndex] - m_nodes.Count(); + pIndexOut[nTriCount] = m_leaves[leafIndex].m_tris[0]; + pIndexOut[nTriCount+1] = m_leaves[leafIndex].m_tris[1]; + nTriCount += 2; + } + } + break; + } + else + { + const CDispCollNode &node = m_nodes[iNode]; + int mask = IntersectFourBoxSpherePairs( sphereCenters, sphereRadSq, node.m_mins, node.m_maxs ); + if ( mask ) + { + int child = Nodes_GetChild( iNode, 0 ); + if ( mask & 1 ) + { + ++maxIndex; + nodeList[maxIndex] = child; + } + if ( mask & 2 ) + { + ++maxIndex; + nodeList[maxIndex] = child+1; + } + if ( mask & 4 ) + { + ++maxIndex; + nodeList[maxIndex] = child+2; + } + if ( mask & 8 ) + { + ++maxIndex; + nodeList[maxIndex] = child+3; + } + Assert(maxIndex < MAX_AABB_LIST); + } + } + } + return nTriCount; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::AABBTree_IntersectAABB( const Vector &absMins, const Vector &absMaxs ) +{ + // Check for hull test. + if ( CheckFlags( CCoreDispInfo::SURF_NOHULL_COLL ) ) + return false; + + cplane_t plane; + Vector center = 0.5f *(absMins + absMaxs); + Vector extents = absMaxs - center; + + int nodeList[MAX_AABB_LIST]; + nodeList[0] = 0; + int listIndex = 0; + int maxIndex = 0; + + // NOTE: This part is loop invariant - should be hoisted up as far as possible + FourVectors mins0; + mins0.DuplicateVector(absMins); + FourVectors maxs0; + maxs0.DuplicateVector(absMaxs); + FourVectors rayExtents; + while ( listIndex <= maxIndex ) + { + int iNode = nodeList[listIndex]; + listIndex++; + // the rest are all leaves + if ( IsLeafNode(iNode) ) + { + VPROF("Tris"); + for ( --listIndex; listIndex <= maxIndex; listIndex++ ) + { + int leafIndex = nodeList[listIndex] - m_nodes.Count(); + CDispCollTri *pTri0 = &m_aTris[m_leaves[leafIndex].m_tris[0]]; + CDispCollTri *pTri1 = &m_aTris[m_leaves[leafIndex].m_tris[1]]; + + VectorCopy( pTri0->m_vecNormal, plane.normal ); + plane.dist = pTri0->m_flDist; + plane.signbits = pTri0->m_ucSignBits; + plane.type = pTri0->m_ucPlaneType; + + if ( IsBoxIntersectingTriangle( center, extents, + m_aVerts[pTri0->GetVert( 0 )], + m_aVerts[pTri0->GetVert( 2 )], + m_aVerts[pTri0->GetVert( 1 )], + plane, 0.0f ) ) + return true; + VectorCopy( pTri1->m_vecNormal, plane.normal ); + plane.dist = pTri1->m_flDist; + plane.signbits = pTri1->m_ucSignBits; + plane.type = pTri1->m_ucPlaneType; + + if ( IsBoxIntersectingTriangle( center, extents, + m_aVerts[pTri1->GetVert( 0 )], + m_aVerts[pTri1->GetVert( 2 )], + m_aVerts[pTri1->GetVert( 1 )], + plane, 0.0f ) ) + return true; + } + break; + } + else + { + const CDispCollNode &node = m_nodes[iNode]; + int mask = IntersectFourBoxPairs( mins0, maxs0, node.m_mins, node.m_maxs ); + if ( mask ) + { + int child = Nodes_GetChild( iNode, 0 ); + if ( mask & 1 ) + { + ++maxIndex; + nodeList[maxIndex] = child; + } + if ( mask & 2 ) + { + ++maxIndex; + nodeList[maxIndex] = child+1; + } + if ( mask & 4 ) + { + ++maxIndex; + nodeList[maxIndex] = child+2; + } + if ( mask & 8 ) + { + ++maxIndex; + nodeList[maxIndex] = child+3; + } + Assert(maxIndex < MAX_AABB_LIST); + } + } + } + + // no collision + return false; +} + +static const Vector g_Vec3DispCollEpsilons(DISPCOLL_DIST_EPSILON,DISPCOLL_DIST_EPSILON,DISPCOLL_DIST_EPSILON); +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::AABBTree_SweepAABB( const Ray_t &ray, const Vector &vecInvDelta, CBaseTrace *pTrace ) +{ + VPROF( "DispHullTest" ); + // VPROF_BUDGET( "DispHullTraces", VPROF_BUDGETGROUP_DISP_HULLTRACES ); + // Check for hull test. + if ( CheckFlags( CCoreDispInfo::SURF_NOHULL_COLL ) ) + return false; + + // Test ray against the triangles in the list. + Vector rayDir; + VectorCopy( ray.m_Delta, rayDir ); + VectorNormalize( rayDir ); + // Save fraction. + float flFrac = pTrace->fraction; + + rayleaflist_t list; + // NOTE: This part is loop invariant - should be hoisted up as far as possible + list.invDelta.DuplicateVector(vecInvDelta); + list.rayStart.DuplicateVector(ray.m_Start); + Vector ext = ray.m_Extents + g_Vec3DispCollEpsilons; + list.rayExtents.DuplicateVector(ext); + int listIndex = BuildRayLeafList( 0, list ); + + if ( listIndex <= list.maxIndex ) + { + LockCache(); + for ( ; listIndex <= list.maxIndex; listIndex++ ) + { + int leafIndex = list.nodeList[listIndex] - m_nodes.Count(); + int iTri0 = m_leaves[leafIndex].m_tris[0]; + int iTri1 = m_leaves[leafIndex].m_tris[1]; + CDispCollTri *pTri0 = &m_aTris[iTri0]; + CDispCollTri *pTri1 = &m_aTris[iTri1]; + + SweepAABBTriIntersect( ray, rayDir, iTri0, pTri0, pTrace ); + SweepAABBTriIntersect( ray, rayDir, iTri1, pTri1, pTrace ); + } + UnlockCache(); + } + + // Collision. + if ( pTrace->fraction < flFrac ) + return true; + + // No collision. + return false; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +bool CDispCollTree::ResolveRayPlaneIntersect( float flStart, float flEnd, const Vector &vecNormal, float flDist, CDispCollHelper *pHelper ) +{ + if( ( flStart > 0.0f ) && ( flEnd > 0.0f ) ) + return false; + + if( ( flStart < 0.0f ) && ( flEnd < 0.0f ) ) + return true; + + float flDenom = flStart - flEnd; + bool bDenomIsZero = ( flDenom == 0.0f ); + if( ( flStart >= 0.0f ) && ( flEnd <= 0.0f ) ) + { + // Find t - the parametric distance along the trace line. + float t = ( !bDenomIsZero ) ? ( flStart - DISPCOLL_DIST_EPSILON ) / flDenom : 0.0f; + if( t > pHelper->m_flStartFrac ) + { + pHelper->m_flStartFrac = t; + VectorCopy( vecNormal, pHelper->m_vecImpactNormal ); + pHelper->m_flImpactDist = flDist; + } + } + else + { + // Find t - the parametric distance along the trace line. + float t = ( !bDenomIsZero ) ? ( flStart + DISPCOLL_DIST_EPSILON ) / flDenom : 0.0f; + if( t < pHelper->m_flEndFrac ) + { + pHelper->m_flEndFrac = t; + } + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline bool CDispCollTree::FacePlane( const Ray_t &ray, const Vector &rayDir, CDispCollTri *pTri, CDispCollHelper *pHelper ) +{ + // Calculate the closest point on box to plane (get extents in that direction). + Vector vecExtent; + CalcClosestExtents( pTri->m_vecNormal, ray.m_Extents, vecExtent ); + + float flExpandDist = pTri->m_flDist - pTri->m_vecNormal.Dot( vecExtent ); + + float flStart = pTri->m_vecNormal.Dot( ray.m_Start ) - flExpandDist; + float flEnd = pTri->m_vecNormal.Dot( ( ray.m_Start + ray.m_Delta ) ) - flExpandDist; + + return ResolveRayPlaneIntersect( flStart, flEnd, pTri->m_vecNormal, pTri->m_flDist, pHelper ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool FORCEINLINE CDispCollTree::AxisPlanesXYZ( const Ray_t &ray, CDispCollTri *pTri, CDispCollHelper *pHelper ) +{ + static const TableVector g_ImpactNormalVecs[2][3] = + { + { + { -1, 0, 0 }, + { 0, -1, 0 }, + { 0, 0, -1 }, + }, + + { + { 1, 0, 0 }, + { 0, 1, 0 }, + { 0, 0, 1 }, + } + }; + + Vector vecImpactNormal; + float flDist, flExpDist, flStart, flEnd; + + int iAxis; + for ( iAxis = 2; iAxis >= 0; --iAxis ) + { + const float rayStart = ray.m_Start[iAxis]; + const float rayExtent = ray.m_Extents[iAxis]; + const float rayDelta = ray.m_Delta[iAxis]; + + // Min + flDist = m_aVerts[pTri->GetVert(pTri->GetMin(iAxis))][iAxis]; + flExpDist = flDist - rayExtent; + flStart = flExpDist - rayStart; + flEnd = flStart - rayDelta; + + if ( !ResolveRayPlaneIntersect( flStart, flEnd, g_ImpactNormalVecs[0][iAxis], flDist, pHelper ) ) + return false; + + // Max + flDist = m_aVerts[pTri->GetVert(pTri->GetMax(iAxis))][iAxis]; + flExpDist = flDist + rayExtent; + flStart = rayStart - flExpDist; + flEnd = flStart + rayDelta; + + if ( !ResolveRayPlaneIntersect( flStart, flEnd, g_ImpactNormalVecs[1][iAxis], flDist, pHelper ) ) + return false; + } + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: Testing! +//----------------------------------------------------------------------------- +void CDispCollTree::Cache_Create( CDispCollTri *pTri, int iTri ) +{ + MEM_ALLOC_CREDIT(); + Vector *pVerts[3]; + pVerts[0] = &m_aVerts[pTri->GetVert( 0 )]; + pVerts[1] = &m_aVerts[pTri->GetVert( 1 )]; + pVerts[2] = &m_aVerts[pTri->GetVert( 2 )]; + + CDispCollTriCache *pCache = &m_aTrisCache[iTri]; + + Vector vecEdge; + + // Edge 1 + VectorSubtract( *pVerts[1], *pVerts[0], vecEdge ); + Cache_EdgeCrossAxisX( vecEdge, *pVerts[0], *pVerts[2], pTri, pCache->m_iCrossX[0] ); + Cache_EdgeCrossAxisY( vecEdge, *pVerts[0], *pVerts[2], pTri, pCache->m_iCrossY[0] ); + Cache_EdgeCrossAxisZ( vecEdge, *pVerts[0], *pVerts[2], pTri, pCache->m_iCrossZ[0] ); + + // Edge 2 + VectorSubtract( *pVerts[2], *pVerts[1], vecEdge ); + Cache_EdgeCrossAxisX( vecEdge, *pVerts[1], *pVerts[0], pTri, pCache->m_iCrossX[1] ); + Cache_EdgeCrossAxisY( vecEdge, *pVerts[1], *pVerts[0], pTri, pCache->m_iCrossY[1] ); + Cache_EdgeCrossAxisZ( vecEdge, *pVerts[1], *pVerts[0], pTri, pCache->m_iCrossZ[1] ); + + // Edge 3 + VectorSubtract( *pVerts[0], *pVerts[2], vecEdge ); + Cache_EdgeCrossAxisX( vecEdge, *pVerts[2], *pVerts[1], pTri, pCache->m_iCrossX[2] ); + Cache_EdgeCrossAxisY( vecEdge, *pVerts[2], *pVerts[1], pTri, pCache->m_iCrossY[2] ); + Cache_EdgeCrossAxisZ( vecEdge, *pVerts[2], *pVerts[1], pTri, pCache->m_iCrossZ[2] ); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CDispCollTree::AddPlane( const Vector &vecNormal ) +{ + UtlHashHandle_t handle; + DispCollPlaneIndex_t planeIndex; + bool bDidInsert; + + planeIndex.vecPlane = vecNormal; + planeIndex.index = m_aEdgePlanes.Count(); + + handle = g_DispCollPlaneIndexHash.Insert( planeIndex, &bDidInsert ); + + if ( !bDidInsert ) + { + DispCollPlaneIndex_t &existingEntry = g_DispCollPlaneIndexHash[handle]; + if ( existingEntry.vecPlane == vecNormal ) + { + return existingEntry.index; + } + else + { + return ( existingEntry.index | 0x8000 ); + } + } + + return m_aEdgePlanes.AddToTail( vecNormal ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// NOTE: The plane distance get stored in the normal x position since it isn't +// used. +//----------------------------------------------------------------------------- +bool CDispCollTree::Cache_EdgeCrossAxisX( const Vector &vecEdge, const Vector &vecOnEdge, + const Vector &vecOffEdge, CDispCollTri *pTri, + unsigned short &iPlane ) +{ + // Calculate the normal - edge x axisX = ( 0.0, edgeZ, -edgeY ) + Vector vecNormal( 0.0f, vecEdge.z, -vecEdge.y ); + VectorNormalize( vecNormal ); + + // Check for zero length normals. + if( ( vecNormal.y == 0.0f ) || ( vecNormal.z == 0.0f ) ) + { + iPlane = DISPCOLL_NORMAL_UNDEF; + return false; + } + +// if ( pTri->m_vecNormal.Dot( vecNormal ) ) +// { +// iPlane = DISPCOLL_NORMAL_UNDEF; +// return false; +// } + + // Finish the plane definition - get distance. + float flDist = ( vecNormal.y * vecOnEdge.y ) + ( vecNormal.z * vecOnEdge.z ); + + // Special case the point off edge in plane + float flOffDist = ( vecNormal.y * vecOffEdge.y ) + ( vecNormal.z * vecOffEdge.z ); + if ( !( FloatMakePositive( flOffDist - flDist ) < DISPCOLL_DIST_EPSILON ) && ( flOffDist > flDist ) ) + { + // Adjust plane facing - triangle should be behind the plane. + vecNormal.x = -flDist; + vecNormal.y = -vecNormal.y; + vecNormal.z = -vecNormal.z; + } + else + { + vecNormal.x = flDist; + } + + // Add edge plane to edge plane list. + iPlane = static_cast( AddPlane( vecNormal ) ); + + // Created the cached edge. + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +// NOTE: The plane distance get stored in the normal y position since it isn't +// used. +//----------------------------------------------------------------------------- +bool CDispCollTree::Cache_EdgeCrossAxisY( const Vector &vecEdge, const Vector &vecOnEdge, + const Vector &vecOffEdge, CDispCollTri *pTri, + unsigned short &iPlane ) +{ + // Calculate the normal - edge x axisY = ( -edgeZ, 0.0, edgeX ) + Vector vecNormal( -vecEdge.z, 0.0f, vecEdge.x ); + VectorNormalize( vecNormal ); + + // Check for zero length normals + if( ( vecNormal.x == 0.0f ) || ( vecNormal.z == 0.0f ) ) + { + iPlane = DISPCOLL_NORMAL_UNDEF; + return false; + } + +// if ( pTri->m_vecNormal.Dot( vecNormal ) ) +// { +// iPlane = DISPCOLL_NORMAL_UNDEF; +// return false; +// } + + // Finish the plane definition - get distance. + float flDist = ( vecNormal.x * vecOnEdge.x ) + ( vecNormal.z * vecOnEdge.z ); + + // Special case the point off edge in plane + float flOffDist = ( vecNormal.x * vecOffEdge.x ) + ( vecNormal.z * vecOffEdge.z ); + if ( !( FloatMakePositive( flOffDist - flDist ) < DISPCOLL_DIST_EPSILON ) && ( flOffDist > flDist ) ) + { + // Adjust plane facing if necessay - triangle should be behind the plane. + vecNormal.x = -vecNormal.x; + vecNormal.y = -flDist; + vecNormal.z = -vecNormal.z; + } + else + { + vecNormal.y = flDist; + } + + // Add edge plane to edge plane list. + iPlane = static_cast( AddPlane( vecNormal ) ); + + // Created the cached edge. + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::Cache_EdgeCrossAxisZ( const Vector &vecEdge, const Vector &vecOnEdge, + const Vector &vecOffEdge, CDispCollTri *pTri, + unsigned short &iPlane ) +{ + // Calculate the normal - edge x axisY = ( edgeY, -edgeX, 0.0 ) + Vector vecNormal( vecEdge.y, -vecEdge.x, 0.0f ); + VectorNormalize( vecNormal ); + + // Check for zero length normals + if( ( vecNormal.x == 0.0f ) || ( vecNormal.y == 0.0f ) ) + { + iPlane = DISPCOLL_NORMAL_UNDEF; + return false; + } + +// if ( pTri->m_vecNormal.Dot( vecNormal ) ) +// { +// iPlane = DISPCOLL_NORMAL_UNDEF; +// return false; +// } + + // Finish the plane definition - get distance. + float flDist = ( vecNormal.x * vecOnEdge.x ) + ( vecNormal.y * vecOnEdge.y ); + + // Special case the point off edge in plane + float flOffDist = ( vecNormal.x * vecOffEdge.x ) + ( vecNormal.y * vecOffEdge.y ); + if ( !( FloatMakePositive( flOffDist - flDist ) < DISPCOLL_DIST_EPSILON ) && ( flOffDist > flDist ) ) + { + // Adjust plane facing if necessay - triangle should be behind the plane. + vecNormal.x = -vecNormal.x; + vecNormal.y = -vecNormal.y; + vecNormal.z = -flDist; + } + else + { + vecNormal.z = flDist; + } + + // Add edge plane to edge plane list. + iPlane = static_cast( AddPlane( vecNormal ) ); + + // Created the cached edge. + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +template +bool CDispCollTree::EdgeCrossAxis( const Ray_t &ray, unsigned short iPlane, CDispCollHelper *pHelper ) +{ + if ( iPlane == DISPCOLL_NORMAL_UNDEF ) + return true; + + // Get the edge plane. + Vector vecNormal; + if ( ( iPlane & 0x8000 ) != 0 ) + { + VectorCopy( m_aEdgePlanes[(iPlane&0x7fff)], vecNormal ); + vecNormal.Negate(); + } + else + { + VectorCopy( m_aEdgePlanes[iPlane], vecNormal ); + } + + const int OTHER_AXIS1 = ( AXIS + 1 ) % 3; + const int OTHER_AXIS2 = ( AXIS + 2 ) % 3; + + // Get the pland distance are "fix" the normal. + float flDist = vecNormal[AXIS]; + vecNormal[AXIS] = 0.0f; + + // Calculate the closest point on box to plane (get extents in that direction). + Vector vecExtent; + //vecExtent[AXIS] = 0.0f; + vecExtent[OTHER_AXIS1] = ( vecNormal[OTHER_AXIS1] < 0.0f ) ? ray.m_Extents[OTHER_AXIS1] : -ray.m_Extents[OTHER_AXIS1]; + vecExtent[OTHER_AXIS2] = ( vecNormal[OTHER_AXIS2] < 0.0f ) ? ray.m_Extents[OTHER_AXIS2] : -ray.m_Extents[OTHER_AXIS2]; + + // Expand the plane by the extents of the box to reduce the swept box/triangle + // test to a ray/extruded triangle test (one of the triangles extruded planes + // was just calculated above). + Vector vecEnd; + vecEnd[AXIS] = 0; + vecEnd[OTHER_AXIS1] = ray.m_Start[OTHER_AXIS1] + ray.m_Delta[OTHER_AXIS1]; + vecEnd[OTHER_AXIS2] = ray.m_Start[OTHER_AXIS2] + ray.m_Delta[OTHER_AXIS2]; + + float flExpandDist = flDist - ( ( vecNormal[OTHER_AXIS1] * vecExtent[OTHER_AXIS1] ) + ( vecNormal[OTHER_AXIS2] * vecExtent[OTHER_AXIS2] ) ); + float flStart = ( vecNormal[OTHER_AXIS1] * ray.m_Start[OTHER_AXIS1] ) + ( vecNormal[OTHER_AXIS2] * ray.m_Start[OTHER_AXIS2] ) - flExpandDist; + float flEnd = ( vecNormal[OTHER_AXIS1] * vecEnd[OTHER_AXIS1] ) + ( vecNormal[OTHER_AXIS2] * vecEnd[OTHER_AXIS2] ) - flExpandDist; + + return ResolveRayPlaneIntersect( flStart, flEnd, vecNormal, flDist, pHelper ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline bool CDispCollTree::EdgeCrossAxisX( const Ray_t &ray, unsigned short iPlane, CDispCollHelper *pHelper ) +{ + return EdgeCrossAxis<0>( ray, iPlane, pHelper ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline bool CDispCollTree::EdgeCrossAxisY( const Ray_t &ray, unsigned short iPlane, CDispCollHelper *pHelper ) +{ + return EdgeCrossAxis<1>( ray, iPlane, pHelper ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline bool CDispCollTree::EdgeCrossAxisZ( const Ray_t &ray, unsigned short iPlane, CDispCollHelper *pHelper ) +{ + return EdgeCrossAxis<2>( ray, iPlane, pHelper ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDispCollTree::SweepAABBTriIntersect( const Ray_t &ray, const Vector &rayDir, int iTri, CDispCollTri *pTri, CBaseTrace *pTrace ) +{ + // Init test data. + CDispCollHelper helper; + helper.m_flEndFrac = 1.0f; + helper.m_flStartFrac = DISPCOLL_INVALID_FRAC; + + // Make sure objects are traveling toward one another. + float flDistAlongNormal = pTri->m_vecNormal.Dot( ray.m_Delta ); + if( flDistAlongNormal > DISPCOLL_DIST_EPSILON ) + return; + + // Test against the axis planes. + if ( !AxisPlanesXYZ( ray, pTri, &helper ) ) + { + return; + } + + // + // There are 9 edge tests - edges 1, 2, 3 cross with the box edges (symmetry) 1, 2, 3. However, the box + // is axis-aligned resulting in axially directional edges -- thus each test is edges 1, 2, and 3 vs. + // axial planes x, y, and z + // + // There are potentially 9 more tests with edges, the edge's edges and the direction of motion! + // NOTE: I don't think these tests are necessary for a manifold surface. + // + + CDispCollTriCache *pCache = &m_aTrisCache[iTri]; + + // Edges 1-3, interleaved - axis tests are 2d tests + if ( !EdgeCrossAxisX( ray, pCache->m_iCrossX[0], &helper ) ) { return; } + if ( !EdgeCrossAxisX( ray, pCache->m_iCrossX[1], &helper ) ) { return; } + if ( !EdgeCrossAxisX( ray, pCache->m_iCrossX[2], &helper ) ) { return; } + + if ( !EdgeCrossAxisY( ray, pCache->m_iCrossY[0], &helper ) ) { return; } + if ( !EdgeCrossAxisY( ray, pCache->m_iCrossY[1], &helper ) ) { return; } + if ( !EdgeCrossAxisY( ray, pCache->m_iCrossY[2], &helper ) ) { return; } + + if ( !EdgeCrossAxisZ( ray, pCache->m_iCrossZ[0], &helper ) ) { return; } + if ( !EdgeCrossAxisZ( ray, pCache->m_iCrossZ[1], &helper ) ) { return; } + if ( !EdgeCrossAxisZ( ray, pCache->m_iCrossZ[2], &helper ) ) { return; } + + // Test against the triangle face plane. + if ( !FacePlane( ray, rayDir, pTri, &helper ) ) + return; + + if ( ( helper.m_flStartFrac < helper.m_flEndFrac ) || ( FloatMakePositive( helper.m_flStartFrac - helper.m_flEndFrac ) < 0.001f ) ) + { + if ( ( helper.m_flStartFrac != DISPCOLL_INVALID_FRAC ) && ( helper.m_flStartFrac < pTrace->fraction ) ) + { + // Clamp -- shouldn't really ever be here!??? + if ( helper.m_flStartFrac < 0.0f ) + { + helper.m_flStartFrac = 0.0f; + } + + pTrace->fraction = helper.m_flStartFrac; + VectorCopy( helper.m_vecImpactNormal, pTrace->plane.normal ); + pTrace->plane.dist = helper.m_flImpactDist; + pTrace->dispFlags = pTri->m_uiFlags; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: constructor +//----------------------------------------------------------------------------- +CDispCollTree::CDispCollTree() +{ + m_nPower = 0; + m_nFlags = 0; + + for ( int iPoint = 0; iPoint < 4; ++iPoint ) + { + m_vecSurfPoints[iPoint].Init(); + } + m_nContents = -1; + m_nSurfaceProps[0] = 0; + m_nSurfaceProps[1] = 0; + + m_vecStabDir.Init(); + m_mins.Init( FLT_MAX, FLT_MAX, FLT_MAX ); + m_maxs.Init( -FLT_MAX, -FLT_MAX, -FLT_MAX ); + + m_iCounter = 0; + + m_aVerts.Purge(); + m_aTris.Purge(); + m_aEdgePlanes.Purge(); +#ifdef ENGINE_DLL + m_hCache = INVALID_MEMHANDLE; +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: deconstructor +//----------------------------------------------------------------------------- +CDispCollTree::~CDispCollTree() +{ +#ifdef ENGINE_DLL + if ( m_hCache != INVALID_MEMHANDLE ) + g_DispCollTriCache.DestroyResource( m_hCache ); +#endif + m_aVerts.Purge(); + m_aTris.Purge(); + m_aEdgePlanes.Purge(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::Create( CCoreDispInfo *pDisp ) +{ + // Create the AABB Tree. + return AABBTree_Create( pDisp ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CDispCollTree::PointInBounds( const Vector &vecBoxCenter, const Vector &vecBoxMin, + const Vector &vecBoxMax, bool bPoint ) +{ + // Point test inside bounds. + if( bPoint ) + { + return IsPointInBox( vecBoxCenter, m_mins, m_maxs ); + } + + // Box test inside bounds + Vector vecExtents; + VectorSubtract( vecBoxMax, vecBoxMin, vecExtents ); + vecExtents *= 0.5f; + + Vector vecExpandBounds[2]; + vecExpandBounds[0] = m_mins - vecExtents; + vecExpandBounds[1] = m_maxs + vecExtents; + + return IsPointInBox( vecBoxCenter, vecExpandBounds[0], vecExpandBounds[1] ); +} + +void CDispCollTree::GetVirtualMeshList( virtualmeshlist_t *pList ) +{ + int i; + int triangleCount = GetTriSize(); + pList->indexCount = triangleCount * 3; + pList->triangleCount = triangleCount; + pList->vertexCount = m_aVerts.Count(); + pList->pVerts = m_aVerts.Base(); + pList->pHull = NULL; + pList->surfacePropsIndex = GetSurfaceProps(0); + int index = 0; + for ( i = 0 ; i < triangleCount; i++ ) + { + pList->indices[index+0] = m_aTris[i].GetVert(0); + pList->indices[index+1] = m_aTris[i].GetVert(1); + pList->indices[index+2] = m_aTris[i].GetVert(2); + index += 3; + } +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#ifdef ENGINE_DLL +static int g_nTrees; +#endif +CDispCollTree *DispCollTrees_Alloc( int count ) +{ + CDispCollTree *pTrees = NULL; +#ifdef ENGINE_DLL + pTrees = (CDispCollTree *)Hunk_Alloc( count * sizeof(CDispCollTree), false ); + g_nTrees = count; + for ( int i = 0; i < g_nTrees; i++ ) + { + Construct( pTrees + i ); + } +#else + pTrees = new CDispCollTree[count]; +#endif + if( !pTrees ) + return NULL; + + for ( int i = 0; i < count; i++ ) + { + pTrees[i].m_iCounter = i; + } + return pTrees; +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void DispCollTrees_Free( CDispCollTree *pTrees ) +{ +#ifdef ENGINE_DLL + for ( int i = 0; i < g_nTrees; i++ ) + { + Destruct( pTrees + i ); + } + g_nTrees = 0; +#else + if( pTrees ) + { + delete [] pTrees; + pTrees = NULL; + } +#endif +} + diff --git a/sp/src/public/dlight.h b/sp/src/public/dlight.h new file mode 100644 index 00000000..032cae64 --- /dev/null +++ b/sp/src/public/dlight.h @@ -0,0 +1,84 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#if !defined ( DLIGHTH ) +#define DLIGHTH +#ifdef _WIN32 +#pragma once +#endif + +#include "mathlib/vector.h" + +//----------------------------------------------------------------------------- +// Dynamic light structure +//----------------------------------------------------------------------------- + +enum +{ + DLIGHT_NO_WORLD_ILLUMINATION = 0x1, + DLIGHT_NO_MODEL_ILLUMINATION = 0x2, + + // NOTE: These two features are used to dynamically tweak the alpha on displacements + // which is a special effect for selecting which texture to use. If + // we ever change how alpha is stored for displacements, we'll have to kill this feature + DLIGHT_ADD_DISPLACEMENT_ALPHA = 0x4, + DLIGHT_SUBTRACT_DISPLACEMENT_ALPHA = 0x8, + DLIGHT_DISPLACEMENT_MASK = (DLIGHT_ADD_DISPLACEMENT_ALPHA | DLIGHT_SUBTRACT_DISPLACEMENT_ALPHA), +}; + +// This is the lighting value that is used to determine when something can be +// culle from lighting because it is close enough to black to be virtually black. +//#define MIN_LIGHTING_VALUE (1.0f/256.0f) + +// This is the broken value of MIN_LIGHTING_VALUE that we have to take into consideration +// to make sure that the lighting for dlights look the same as they did in HL2. +// We'll use the real MIN_LIGHTING_VALUE above to calculate larger radii for dynamic +// light sources. +//#define HL2_BROKEN_MIN_LIGHTING_VALUE (20.0f/256.0f) + +struct dlight_t +{ + int flags; + Vector origin; + float radius; + ColorRGBExp32 color; // Light color with exponent + float die; // stop lighting after this time + float decay; // drop this each second + float minlight; // don't add when contributing less + int key; + int style; // lightstyle + + // For spotlights. Use m_OuterAngle == 0 for point lights + Vector m_Direction; // center of the light cone + float m_InnerAngle; + float m_OuterAngle; + + // see comments above about HL2_BROKEN_MIN_LIGHTING_VALUE and MIN_LIGHTING_VALUE + // THIS SHOULD ONLY GET CALLED FROM THE ENGINE + float GetRadius() const + { +// return FastSqrt( radius * radius * ( HL2_BROKEN_MIN_LIGHTING_VALUE / MIN_LIGHTING_VALUE ) ); + return radius; + } + + // see comments above about HL2_BROKEN_MIN_LIGHTING_VALUE and MIN_LIGHTING_VALUE + // THIS SHOULD ONLY GET CALLED FROM THE ENGINE + float GetRadiusSquared() const + { +// return radius * radius * ( HL2_BROKEN_MIN_LIGHTING_VALUE / MIN_LIGHTING_VALUE ); + return radius * radius; + } + + // THIS SHOULD ONLY GET CALLED FROM THE ENGINE + float IsRadiusGreaterThanZero() const + { + // don't bother calculating the new radius if you just want to know if it is greater than zero. + return radius > 0.0f; + } +}; + +#endif diff --git a/sp/src/public/dmserializers/idmserializers.h b/sp/src/public/dmserializers/idmserializers.h new file mode 100644 index 00000000..f50f8dee --- /dev/null +++ b/sp/src/public/dmserializers/idmserializers.h @@ -0,0 +1,47 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// The copyright to the contents herein is the property of Valve, L.L.C. +// The contents may be used and/or copied only with the written permission of +// Valve, L.L.C., or in accordance with the terms and conditions stipulated in +// the agreement/contract under which the contents have been supplied. +// +// $Header: $ +// $NoKeywords: $ +// +// Main header file for the serializers DLL +// +//============================================================================= + +#ifndef IDMSERIALIZERS_H +#define IDMSERIALIZERS_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "appframework/IAppSystem.h" + + +//----------------------------------------------------------------------------- +// Interface +//----------------------------------------------------------------------------- +class IDmSerializers : public IAppSystem +{ +}; + + +//----------------------------------------------------------------------------- +// Used only by applications to hook in DmSerializers +//----------------------------------------------------------------------------- +#define DMSERIALIZERS_INTERFACE_VERSION "VDmSerializers001" + + +//----------------------------------------------------------------------------- +// Singleton +//----------------------------------------------------------------------------- +extern IDmSerializers *g_pDmSerializers; + + +#endif // DMSERIALIZERS_H + + diff --git a/sp/src/public/dmxloader/dmxattribute.h b/sp/src/public/dmxloader/dmxattribute.h new file mode 100644 index 00000000..17523660 --- /dev/null +++ b/sp/src/public/dmxloader/dmxattribute.h @@ -0,0 +1,183 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef DMXATTRIBUTE_H +#define DMXATTRIBUTE_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "datamodel/dmattributetypes.h" +#include "tier1/utlvector.h" +#include "tier1/utlrbtree.h" +#include "tier1/utlsymbol.h" +#include "tier1/mempool.h" +#include "dmxloader/dmxloader.h" + + +//----------------------------------------------------------------------------- +// Forward declarations: +//----------------------------------------------------------------------------- +class CDmxElement; + + +//----------------------------------------------------------------------------- +// Attribute info, modified for use in mod code +//----------------------------------------------------------------------------- +DECLARE_ATTRIBUTE_TYPE( CDmxElement*, AT_ELEMENT, "element", value = 0; ) +DECLARE_ATTRIBUTE_ARRAY_TYPE( CDmxElement*, AT_ELEMENT_ARRAY, "element_array" ) + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CDmxAttribute +{ + DECLARE_DMX_ALLOCATOR( ); + +public: + // Returns attribute name and type + DmAttributeType_t GetType() const; + const char *GetTypeString() const; + template< class T > bool IsA() const; + + // Returns the name. NOTE: The utlsymbol + // can be turned into a string by using g_pDataModel->String(); + const char *GetName() const; + CUtlSymbol GetNameSymbol() const; + void SetName( const char *pName ); + + // Gets values + template< class T > const T& GetValue( ) const; + template< class T > const CUtlVector< T >& GetArray( ) const; + const char *GetValueString() const; + + // Sets values (+ type) + template< class T > void SetValue( const T& value ); + void SetValue( const char *pString ); + void SetValue( const void *pBuffer, size_t nLen ); + void SetValue( const CDmxAttribute *pAttribute ); + + // Method to set values in an array (just directly operate on the array) + // NOTE: This will create a new array of the appropriate type if + // the type doesn't match the current type + template< class T > CUtlVector< T >& GetArrayForEdit(); + + // Sets the attribute to its default value based on its type + void SetToDefaultValue(); + + // Convert to and from string + void SetValueFromString( const char *pValue ); + const char *GetValueAsString( char *pBuffer, size_t nBufLen ) const; + + // Gets the size of an array, returns 0 if it's not an array type + int GetArrayCount() const; + + // Read from file + bool Unserialize( DmAttributeType_t type, CUtlBuffer &buf ); + bool UnserializeElement( DmAttributeType_t type, CUtlBuffer &buf ); + bool Serialize( CUtlBuffer &buf ) const; + bool SerializeElement( int nIndex, CUtlBuffer &buf ) const; + bool SerializesOnMultipleLines() const; + + // Returns the size of the variables storing the various attribute types + static int AttributeDataSize( DmAttributeType_t type ); + +private: + CDmxAttribute( const char *pAttributeName ); + CDmxAttribute( CUtlSymbol attributeName ); + ~CDmxAttribute(); + + // Allocate, free memory for data + void AllocateDataMemory( DmAttributeType_t type ); + void FreeDataMemory( ); + + // Untyped method for setting used by unpack + void SetValue( DmAttributeType_t type, const void *pSrc, int nLen ); + + DmAttributeType_t m_Type; + CUtlSymbol m_Name; + void *m_pData; + + static CUtlSymbolTableMT s_AttributeNameSymbols; + + friend class CDmxElement; +}; + + +//----------------------------------------------------------------------------- +// Inline methods +//----------------------------------------------------------------------------- +inline DmAttributeType_t CDmxAttribute::GetType() const +{ + return m_Type; +} + +template< class T > inline bool CDmxAttribute::IsA() const +{ + return GetType() == CDmAttributeInfo< T >::ATTRIBUTE_TYPE; +} + +inline CUtlSymbol CDmxAttribute::GetNameSymbol() const +{ + return m_Name; +} + + +//----------------------------------------------------------------------------- +// Sets a value in the attribute +//----------------------------------------------------------------------------- +template< class T > void CDmxAttribute::SetValue( const T& value ) +{ + AllocateDataMemory( CDmAttributeInfo::AttributeType() ); + CopyConstruct( (T*)m_pData, value ); +} + + +//----------------------------------------------------------------------------- +// Returns data in the attribute +//----------------------------------------------------------------------------- +inline const char *CDmxAttribute::GetValueString() const +{ + if ( m_Type == AT_STRING ) + return *(CUtlString*)m_pData; + return ""; +} + +template< class T > +inline const T& CDmxAttribute::GetValue( ) const +{ + if ( CDmAttributeInfo::AttributeType() == m_Type ) + return *(T*)m_pData; + + static T defaultValue; + CDmAttributeInfo::SetDefaultValue( defaultValue ); + return defaultValue; +} + +template< class T > +inline const CUtlVector< T >& CDmxAttribute::GetArray( ) const +{ + if ( CDmAttributeInfo< CUtlVector< T > >::AttributeType() == m_Type ) + return *( CUtlVector< T > *)m_pData; + + static CUtlVector defaultArray; + return defaultArray; +} + +template< class T > +inline CUtlVector< T >& CDmxAttribute::GetArrayForEdit( ) +{ + if ( CDmAttributeInfo< CUtlVector< T > >::AttributeType() == m_Type ) + return *( CUtlVector< T > *)m_pData; + + AllocateDataMemory( CDmAttributeInfo< CUtlVector< T > >::AttributeType() ); + Construct( (CUtlVector*)m_pData ); + return *(CUtlVector< T > *)m_pData; +} + +#endif // DMXATTRIBUTE_H diff --git a/sp/src/public/dmxloader/dmxelement.h b/sp/src/public/dmxloader/dmxelement.h new file mode 100644 index 00000000..666a1171 --- /dev/null +++ b/sp/src/public/dmxloader/dmxelement.h @@ -0,0 +1,310 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef DMXELEMENT_H +#define DMXELEMENT_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "datamodel/dmattributetypes.h" +#include "tier1/utlvector.h" +#include "tier1/utlrbtree.h" +#include "tier1/utlsymbol.h" +#include "tier1/mempool.h" +#include "tier1/UtlSortVector.h" +#include "dmxloader/dmxattribute.h" + + +//----------------------------------------------------------------------------- +// Sort functor class for attributes +//----------------------------------------------------------------------------- +class CDmxAttributeLess +{ +public: + bool Less( const CDmxAttribute * pAttribute1, const CDmxAttribute *pAttribute2, void *pContext ) + { + return pAttribute1->GetNameSymbol() < pAttribute2->GetNameSymbol(); + } +}; + + +//----------------------------------------------------------------------------- +// Used to unpack elements into a structure. Does not recurse +// Also does not work with arrays. +//----------------------------------------------------------------------------- +struct DmxElementUnpackStructure_t +{ + const char *m_pAttributeName; + const char *m_pDefaultString; + DmAttributeType_t m_AttributeType; + int m_nOffset; + int m_nSize; + const void *m_pUserData; // If you want to associate some app-specific data with each field +}; + +#define DECLARE_DMXELEMENT_UNPACK() \ + template friend DmxElementUnpackStructure_t *DmxElementUnpackInit(T *); + +#define BEGIN_DMXELEMENT_UNPACK( _structName ) \ + template DmxElementUnpackStructure_t *DmxElementUnpackInit(T *); \ + template <> DmxElementUnpackStructure_t *DmxElementUnpackInit<_structName>( _structName * ); \ + namespace _structName##_UnpackInit \ + { \ + static DmxElementUnpackStructure_t *s_pUnpack = DmxElementUnpackInit( (_structName *)NULL ); \ + } \ + \ + template <> DmxElementUnpackStructure_t *DmxElementUnpackInit<_structName>( _structName * ) \ + { \ + typedef _structName DestStructType_t; \ + static DmxElementUnpackStructure_t unpack[] = \ + { \ + +#define DMXELEMENT_UNPACK_FLTX4( _attributeName, _defaultString, _varName ) \ + { _attributeName, _defaultString, CDmAttributeInfo::AttributeType(), offsetof( DestStructType_t, _varName ), sizeof( fltx4 ), NULL }, +#define DMXELEMENT_UNPACK_FIELD( _attributeName, _defaultString, _type, _varName ) \ + { _attributeName, _defaultString, CDmAttributeInfo<_type>::AttributeType(), offsetof( DestStructType_t, _varName ), sizeof( ((DestStructType_t *)0)->_varName), NULL }, +#define DMXELEMENT_UNPACK_FIELD_STRING( _attributeName, _defaultString, _varName ) \ + { _attributeName, _defaultString, AT_STRING, offsetof( DestStructType_t, _varName ), sizeof( ((DestStructType_t *)0)->_varName), NULL }, + +#define DMXELEMENT_UNPACK_FIELD_USERDATA( _attributeName, _defaultString, _type, _varName, _userData ) \ + { _attributeName, _defaultString, CDmAttributeInfo<_type>::AttributeType(), offsetof( DestStructType_t, _varName ), sizeof( ((DestStructType_t *)0)->_varName), _userData }, +#define DMXELEMENT_UNPACK_FIELD_STRING_USERDATA( _attributeName, _defaultString, _varName, _userData ) \ + { _attributeName, _defaultString, AT_STRING, offsetof( DestStructType_t, _varName ), sizeof( ((DestStructType_t *)0)->_varName), _userData }, + +#define END_DMXELEMENT_UNPACK( _structName, _varName ) \ + { NULL, NULL, AT_UNKNOWN, 0, 0, NULL } \ + }; \ + return unpack; \ + } \ + DmxElementUnpackStructure_t *_varName = _structName##_UnpackInit::s_pUnpack; + +#define END_DMXELEMENT_UNPACK_TEMPLATE( _structName, _varName ) \ + { NULL, NULL, AT_UNKNOWN, 0, 0, NULL } \ + }; \ + return unpack; \ + } \ + template<> DmxElementUnpackStructure_t *_varName = _structName##_UnpackInit::s_pUnpack; + + +//----------------------------------------------------------------------------- +// Element used to read dmx files from mod code. Similar to keyvalues. +//----------------------------------------------------------------------------- +class CDmxElement +{ + DECLARE_DMX_ALLOCATOR( ); + +public: + bool HasAttribute( const char *pAttributeName ) const; + CDmxAttribute *GetAttribute( const char *pAttributeName ); + const CDmxAttribute *GetAttribute( const char *pAttributeName ) const; + int AttributeCount() const; + CDmxAttribute *GetAttribute( int nIndex ); + const CDmxAttribute *GetAttribute( int nIndex ) const; + CUtlSymbol GetType() const; + const char* GetTypeString() const; + const char* GetName() const; + const DmObjectId_t &GetId() const; + + // Add+remove+rename can only occur during lock + // NOTE: AddAttribute will find or add; returning an existing attribute if + // one with the appropriate name exists + void LockForChanges( bool bLock ); + CDmxAttribute *AddAttribute( const char *pAttributeName ); + void RemoveAttribute( const char *pAttributeName ); + void RemoveAttributeByPtr( CDmxAttribute *pAttribute ); + void RemoveAllAttributes(); + void RenameAttribute( const char *pAttributeName, const char *pNewName ); + + // Simple methods to read attributes + const char *GetValueString( const char *pAttributeName ) const; + template< class T > const T& GetValue( const char *pAttributeName ) const; + template< class T > const T& GetValue( const char *pAttributeName, const T& defaultValue ) const; + + template< class T > const CUtlVector& GetArray( const char *pAttributeName ) const; + template< class T > const CUtlVector& GetArray( const char *pAttributeName, const CUtlVector& defaultValue ) const; + + // Set methods + CDmxAttribute* SetValue( const char *pAttributeName, const char *pString ); + CDmxAttribute* SetValue( const char *pAttributeName, void *pBuffer, int nLen ); + template< class T > CDmxAttribute* SetValue( const char *pAttributeName, const T& value ); + + // Method to unpack data into a structure + void UnpackIntoStructure( void *pData, size_t DataSizeInBytes, const DmxElementUnpackStructure_t *pUnpack ) const; + + // Creates attributes based on the unpack structure + template + void AddAttributesFromStructure( const T *pData, const DmxElementUnpackStructure_t *pUnpack ) + { + AddAttributesFromStructure_Internal( pData, sizeof(T), pUnpack ); + } + +private: + void AddAttributesFromStructure_Internal( const void *pData, size_t byteCount, const DmxElementUnpackStructure_t *pUnpack ); + typedef CUtlSortVector< CDmxAttribute*, CDmxAttributeLess > AttributeList_t; + + CDmxElement( const char *pType ); + ~CDmxElement(); + + // Removes all elements recursively + void RemoveAllElementsRecursive(); + + // Adds elements to delete to the deletion list + void AddElementsToDelete( CUtlVector< CDmxElement * >& elementsToDelete ); + + // Sorts the vector when a change has occurred + void Resort( ) const; + + // Finds an attribute by name + int FindAttribute( const char *pAttributeName ) const; + int FindAttribute( CUtlSymbol attributeName ) const; + + // Sets the object id + void SetId( const DmObjectId_t &id ); + + // Are we locked? + bool IsLocked() const; + + AttributeList_t m_Attributes; + DmObjectId_t m_Id; // We need this strictly because we support serialization + CUtlSymbol m_Type; + char m_nLockCount; + mutable bool m_bResortNeeded : 1; + bool m_bIsMarkedForDeletion : 1; + + static CUtlSymbolTableMT s_TypeSymbols; + + friend class CDmxSerializer; + friend class CDmxSerializerKeyValues2; + friend void CleanupDMX( CDmxElement* pElement ); + friend CDmxElement* CreateDmxElement( const char *pType ); +}; + + +//----------------------------------------------------------------------------- +// inline methods +//----------------------------------------------------------------------------- + +// Are we locked? +inline bool CDmxElement::IsLocked() const +{ + return m_nLockCount > 0; +} + +inline const char *CDmxElement::GetValueString( const char *pAttributeName ) const +{ + const CDmxAttribute* pAttribute = GetAttribute( pAttributeName ); + if ( pAttribute ) + return pAttribute->GetValueString(); + return ""; +} + +template< class T > +inline const T& CDmxElement::GetValue( const char *pAttributeName ) const +{ + const CDmxAttribute* pAttribute = GetAttribute( pAttributeName ); + if ( pAttribute ) + return pAttribute->GetValue(); + + static T defaultValue; + CDmAttributeInfo::SetDefaultValue( defaultValue ); + return defaultValue; +} + +template< class T > +inline const T& CDmxElement::GetValue( const char *pAttributeName, const T& defaultValue ) const +{ + const CDmxAttribute* pAttribute = GetAttribute( pAttributeName ); + if ( pAttribute ) + return pAttribute->GetValue(); + return defaultValue; +} + +template< class T > +inline const CUtlVector& CDmxElement::GetArray( const char *pAttributeName ) const +{ + const CDmxAttribute* pAttribute = GetAttribute( pAttributeName ); + if ( pAttribute ) + return pAttribute->GetArray(); + + static CUtlVector defaultValue; + return defaultValue; +} + +template< class T > +inline const CUtlVector& CDmxElement::GetArray( const char *pAttributeName, const CUtlVector& defaultValue ) const +{ + const CDmxAttribute* pAttribute = GetAttribute( pAttributeName ); + if ( pAttribute ) + return pAttribute->GetArray(); + return defaultValue; +} + + +//----------------------------------------------------------------------------- +// Creates a dmx element +//----------------------------------------------------------------------------- +CDmxElement* CreateDmxElement( const char *pType ); + + +//----------------------------------------------------------------------------- +// Helper class to lock elements for changes +//----------------------------------------------------------------------------- +class CDmxElementModifyScope +{ +public: + CDmxElementModifyScope( CDmxElement *pElement ) : m_pElement( pElement ) + { + m_pElement->LockForChanges( true ); + } + ~CDmxElementModifyScope() + { + Release(); + } + void Release() + { + if ( m_pElement ) + { + m_pElement->LockForChanges( false ); + m_pElement = NULL; + } + } +private: + CDmxElement *m_pElement; +}; + + +//----------------------------------------------------------------------------- +// Set methods +//----------------------------------------------------------------------------- +inline CDmxAttribute* CDmxElement::SetValue( const char *pAttributeName, const char *pString ) +{ + CDmxElementModifyScope modify( this ); + CDmxAttribute *pAttribute = AddAttribute( pAttributeName ); + pAttribute->SetValue( pString ); + return pAttribute; +} + +inline CDmxAttribute* CDmxElement::SetValue( const char *pAttributeName, void *pBuffer, int nLen ) +{ + CDmxElementModifyScope modify( this ); + CDmxAttribute *pAttribute = AddAttribute( pAttributeName ); + pAttribute->SetValue( pBuffer, nLen ); + return pAttribute; +} + +template< class T > +inline CDmxAttribute* CDmxElement::SetValue( const char *pAttributeName, const T& value ) +{ + CDmxElementModifyScope modify( this ); + CDmxAttribute *pAttribute = AddAttribute( pAttributeName ); + pAttribute->SetValue( value ); + return pAttribute; +} + + +#endif // DMXELEMENT_H diff --git a/sp/src/public/dmxloader/dmxloader.h b/sp/src/public/dmxloader/dmxloader.h new file mode 100644 index 00000000..54815ae5 --- /dev/null +++ b/sp/src/public/dmxloader/dmxloader.h @@ -0,0 +1,72 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef DMXLOADER_H +#define DMXLOADER_H + +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CUtlBuffer; +class CDmxElement; + + +//----------------------------------------------------------------------------- +// Serialization/Unserialization +//----------------------------------------------------------------------------- +bool SerializeDMX( CUtlBuffer &buf, CDmxElement *pRoot, const char *pFileName = NULL ); +bool SerializeDMX( const char *pFileName, const char *pPathID, bool bTextMode, CDmxElement *pRoot ); + +bool UnserializeDMX( CUtlBuffer &buf, CDmxElement **ppRoot, const char *pFileName = NULL ); +bool UnserializeDMX( const char *pFileName, const char *pPathID, bool bTextMode, CDmxElement **ppRoot ); + +//----------------------------------------------------------------------------- +// DMX elements/attributes can only be accessed inside a dmx context +//----------------------------------------------------------------------------- +void BeginDMXContext( ); +void EndDMXContext( bool bDecommitMemory ); +void DecommitDMXMemory(); + + +//----------------------------------------------------------------------------- +// Helper macro +//----------------------------------------------------------------------------- +class CDMXContextHelper +{ +public: + CDMXContextHelper( bool bDecommitMemory ) { m_bDecommitMemory = bDecommitMemory; BeginDMXContext(); } + ~CDMXContextHelper() { EndDMXContext( m_bDecommitMemory ); } + +private: + bool m_bDecommitMemory; +}; + +#define DECLARE_DMX_CONTEXT( ) CDMXContextHelper __dmxContextHelper( true ); +#define DECLARE_DMX_CONTEXT_NODECOMMIT( ) CDMXContextHelper __dmxContextHelper( false ); +#define DECLARE_DMX_CONTEXT_DECOMMIT( _decommit ) CDMXContextHelper __dmxContextHelper( _decommit ); + + +//----------------------------------------------------------------------------- +// Used for allocation. All will be freed when we leave the DMX context +//----------------------------------------------------------------------------- +void* DMXAlloc( size_t size ); + + +//----------------------------------------------------------------------------- +// Helper macro +//----------------------------------------------------------------------------- +#define DECLARE_DMX_ALLOCATOR( ) \ + public: \ + inline void* operator new( size_t size ) { MEM_ALLOC_CREDIT_( "DMXAlloc" ); return DMXAlloc(size); } \ + inline void* operator new( size_t size, int nBlockUse, const char *pFileName, int nLine ) { MEM_ALLOC_CREDIT_( "DMXAlloc" ); return DMXAlloc(size); } \ + inline void operator delete( void* p ) { } \ + inline void operator delete( void* p, int nBlockUse, const char *pFileName, int nLine ) { } \ + +#endif // DMXLOADER_H \ No newline at end of file diff --git a/sp/src/public/dt_common.h b/sp/src/public/dt_common.h new file mode 100644 index 00000000..cee40133 --- /dev/null +++ b/sp/src/public/dt_common.h @@ -0,0 +1,223 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#ifndef DATATABLE_COMMON_H +#define DATATABLE_COMMON_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "basetypes.h" +#include "tier0/dbg.h" +#include "tier1/strtools.h" +#include + +#ifdef LINUX +#undef offsetof +#define offsetof(s,m) (size_t)&(((s *)0)->m) +#endif + +// Max number of properties in a datatable and its children. +#define MAX_DATATABLES 1024 // must be a power of 2. +#define MAX_DATATABLE_PROPS 4096 + +#define MAX_ARRAY_ELEMENTS 2048 // a network array should have more that 1024 elements + +#define HIGH_DEFAULT -121121.121121f + +#define BITS_FULLRES -1 // Use the full resolution of the type being encoded. +#define BITS_WORLDCOORD -2 // Encode as a world coordinate. + +#define DT_MAX_STRING_BITS 9 +#define DT_MAX_STRING_BUFFERSIZE (1<varName ) + +// Gets the size of a variable in a class. +#define PROPSIZEOF(className, varName) sizeof(((className*)0)->varName) + + +// SendProp::m_Flags. +#define SPROP_UNSIGNED (1<<0) // Unsigned integer data. + +#define SPROP_COORD (1<<1) // If this is set, the float/vector is treated like a world coordinate. + // Note that the bit count is ignored in this case. + +#define SPROP_NOSCALE (1<<2) // For floating point, don't scale into range, just take value as is. + +#define SPROP_ROUNDDOWN (1<<3) // For floating point, limit high value to range minus one bit unit + +#define SPROP_ROUNDUP (1<<4) // For floating point, limit low value to range minus one bit unit + +#define SPROP_NORMAL (1<<5) // If this is set, the vector is treated like a normal (only valid for vectors) + +#define SPROP_EXCLUDE (1<<6) // This is an exclude prop (not excludED, but it points at another prop to be excluded). + +#define SPROP_XYZE (1<<7) // Use XYZ/Exponent encoding for vectors. + +#define SPROP_INSIDEARRAY (1<<8) // This tells us that the property is inside an array, so it shouldn't be put into the + // flattened property list. Its array will point at it when it needs to. + +#define SPROP_PROXY_ALWAYS_YES (1<<9) // Set for datatable props using one of the default datatable proxies like + // SendProxy_DataTableToDataTable that always send the data to all clients. + +#define SPROP_CHANGES_OFTEN (1<<10) // this is an often changed field, moved to head of sendtable so it gets a small index + +#define SPROP_IS_A_VECTOR_ELEM (1<<11) // Set automatically if SPROP_VECTORELEM is used. + +#define SPROP_COLLAPSIBLE (1<<12) // Set automatically if it's a datatable with an offset of 0 that doesn't change the pointer + // (ie: for all automatically-chained base classes). + // In this case, it can get rid of this SendPropDataTable altogether and spare the + // trouble of walking the hierarchy more than necessary. + +#define SPROP_COORD_MP (1<<13) // Like SPROP_COORD, but special handling for multiplayer games +#define SPROP_COORD_MP_LOWPRECISION (1<<14) // Like SPROP_COORD, but special handling for multiplayer games where the fractional component only gets a 3 bits instead of 5 +#define SPROP_COORD_MP_INTEGRAL (1<<15) // SPROP_COORD_MP, but coordinates are rounded to integral boundaries + +#define SPROP_VARINT SPROP_NORMAL // reuse existing flag so we don't break demo. note you want to include SPROP_UNSIGNED if needed, its more efficient + +#define SPROP_NUMFLAGBITS_NETWORKED 16 + +// This is server side only, it's used to mark properties whose SendProxy_* functions encode against gpGlobals->tickcount (the only ones that currently do this are +// m_flAnimTime and m_flSimulationTime. MODs shouldn't need to mess with this probably +#define SPROP_ENCODED_AGAINST_TICKCOUNT (1<<16) + +// See SPROP_NUMFLAGBITS_NETWORKED for the ones which are networked +#define SPROP_NUMFLAGBITS 17 + +// Used by the SendProp and RecvProp functions to disable debug checks on type sizes. +#define SIZEOF_IGNORE -1 + + +// Use this to extern send and receive datatables, and reference them. +#define EXTERN_SEND_TABLE(tableName) namespace tableName {extern SendTable g_SendTable;} +#define EXTERN_RECV_TABLE(tableName) namespace tableName {extern RecvTable g_RecvTable;} + +#define REFERENCE_SEND_TABLE(tableName) tableName::g_SendTable +#define REFERENCE_RECV_TABLE(tableName) tableName::g_RecvTable + + +class SendProp; + +// The day we do this, we break all mods until they recompile. +//#define SUPPORTS_INT64 + +typedef enum +{ + DPT_Int=0, + DPT_Float, + DPT_Vector, + DPT_VectorXY, // Only encodes the XY of a vector, ignores Z + DPT_String, + DPT_Array, // An array of the base types (can't be of datatables). + DPT_DataTable, +#if 0 // We can't ship this since it changes the size of DTVariant to be 20 bytes instead of 16 and that breaks MODs!!! + DPT_Quaternion, +#endif + +#ifdef SUPPORTS_INT64 + DPT_Int64, +#endif + + DPT_NUMSendPropTypes + +} SendPropType; + + +class DVariant +{ +public: + DVariant() {m_Type = DPT_Float;} + DVariant(float val) {m_Type = DPT_Float; m_Float = val;} + + const char *ToString() + { + static char text[128]; + + switch ( m_Type ) + { + case DPT_Int : + Q_snprintf( text, sizeof(text), "%i", m_Int ); + break; + case DPT_Float : + Q_snprintf( text, sizeof(text), "%.3f", m_Float ); + break; + case DPT_Vector : + Q_snprintf( text, sizeof(text), "(%.3f,%.3f,%.3f)", + m_Vector[0], m_Vector[1], m_Vector[2] ); + break; + case DPT_VectorXY : + Q_snprintf( text, sizeof(text), "(%.3f,%.3f)", + m_Vector[0], m_Vector[1] ); + break; +#if 0 // We can't ship this since it changes the size of DTVariant to be 20 bytes instead of 16 and that breaks MODs!!! + case DPT_Quaternion : + Q_snprintf( text, sizeof(text), "(%.3f,%.3f,%.3f %.3f)", + m_Vector[0], m_Vector[1], m_Vector[2], m_Vector[3] ); + break; +#endif + case DPT_String : + if ( m_pString ) + return m_pString; + else + return "NULL"; + break; + case DPT_Array : + Q_snprintf( text, sizeof(text), "Array" ); + break; + case DPT_DataTable : + Q_snprintf( text, sizeof(text), "DataTable" ); + break; +#ifdef SUPPORTS_INT64 + case DPT_Int64: + Q_snprintf( text, sizeof(text), "%I64d", m_Int64 ); + break; +#endif + default : + Q_snprintf( text, sizeof(text), "DVariant type %i unknown", m_Type ); + break; + } + + return text; + } + + union + { + float m_Float; + int m_Int; + const char *m_pString; + void *m_pData; // For DataTables. +#if 0 // We can't ship this since it changes the size of DTVariant to be 20 bytes instead of 16 and that breaks MODs!!! + float m_Vector[4]; +#else + float m_Vector[3]; +#endif + +#ifdef SUPPORTS_INT64 + int64 m_Int64; +#endif + }; + SendPropType m_Type; +}; + + +// This can be used to set the # of bits used to transmit a number between 0 and nMaxElements-1. +inline int NumBitsForCount( int nMaxElements ) +{ + int nBits = 0; + while ( nMaxElements > 0 ) + { + ++nBits; + nMaxElements >>= 1; + } + return nBits; +} + + +#endif // DATATABLE_COMMON_H diff --git a/sp/src/public/dt_recv.cpp b/sp/src/public/dt_recv.cpp new file mode 100644 index 00000000..8411b1d1 --- /dev/null +++ b/sp/src/public/dt_recv.cpp @@ -0,0 +1,534 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=====================================================================================// + +#include "dt_recv.h" +#include "mathlib/vector.h" +#include "tier1/strtools.h" +#include "dt_utlvector_common.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#if !defined(_STATIC_LINKED) || defined(CLIENT_DLL) + +const char *s_ClientElementNames[MAX_ARRAY_ELEMENTS] = +{ + "000", "001", "002", "003", "004", "005", "006", "007", "008", "009", + "010", "011", "012", "013", "014", "015", "016", "017", "018", "019", + "020", "021", "022", "023", "024", "025", "026", "027", "028", "029", + "030", "031", "032", "033", "034", "035", "036", "037", "038", "039", + "040", "041", "042", "043", "044", "045", "046", "047", "048", "049", + "050", "051", "052", "053", "054", "055", "056", "057", "058", "059", + "060", "061", "062", "063", "064", "065", "066", "067", "068", "069", + "070", "071", "072", "073", "074", "075", "076", "077", "078", "079", + "080", "081", "082", "083", "084", "085", "086", "087", "088", "089", + "090", "091", "092", "093", "094", "095", "096", "097", "098", "099", + "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", + "110", "111", "112", "113", "114", "115", "116", "117", "118", "119", + "120", "121", "122", "123", "124", "125", "126", "127", "128", "129", + "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", + "140", "141", "142", "143", "144", "145", "146", "147", "148", "149", + "150", "151", "152", "153", "154", "155", "156", "157", "158", "159", + "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", + "170", "171", "172", "173", "174", "175", "176", "177", "178", "179", + "180", "181", "182", "183", "184", "185", "186", "187", "188", "189", + "190", "191", "192", "193", "194", "195", "196", "197", "198", "199", + "200", "201", "202", "203", "204", "205", "206", "207", "208", "209", + "210", "211", "212", "213", "214", "215", "216", "217", "218", "219", + "220", "221", "222", "223", "224", "225", "226", "227", "228", "229", + "230", "231", "232", "233", "234", "235", "236", "237", "238", "239", + "240", "241", "242", "243", "244", "245", "246", "247", "248", "249", + "250", "251", "252", "253", "254", "255", "256", "257", "258", "259", + "260", "261", "262", "263", "264", "265", "266", "267", "268", "269", + "270", "271", "272", "273", "274", "275", "276", "277", "278", "279", + "280", "281", "282", "283", "284", "285", "286", "287", "288", "289", + "290", "291", "292", "293", "294", "295", "296", "297", "298", "299", + "300", "301", "302", "303", "304", "305", "306", "307", "308", "309", + "310", "311", "312", "313", "314", "315", "316", "317", "318", "319", + "320", "321", "322", "323", "324", "325", "326", "327", "328", "329", + "330", "331", "332", "333", "334", "335", "336", "337", "338", "339", + "340", "341", "342", "343", "344", "345", "346", "347", "348", "349", + "350", "351", "352", "353", "354", "355", "356", "357", "358", "359", + "360", "361", "362", "363", "364", "365", "366", "367", "368", "369", + "370", "371", "372", "373", "374", "375", "376", "377", "378", "379", + "380", "381", "382", "383", "384", "385", "386", "387", "388", "389", + "390", "391", "392", "393", "394", "395", "396", "397", "398", "399", + "400", "401", "402", "403", "404", "405", "406", "407", "408", "409", + "410", "411", "412", "413", "414", "415", "416", "417", "418", "419", + "420", "421", "422", "423", "424", "425", "426", "427", "428", "429", + "430", "431", "432", "433", "434", "435", "436", "437", "438", "439", + "440", "441", "442", "443", "444", "445", "446", "447", "448", "449", + "450", "451", "452", "453", "454", "455", "456", "457", "458", "459", + "460", "461", "462", "463", "464", "465", "466", "467", "468", "469", + "470", "471", "472", "473", "474", "475", "476", "477", "478", "479", + "480", "481", "482", "483", "484", "485", "486", "487", "488", "489", + "490", "491", "492", "493", "494", "495", "496", "497", "498", "499", + "500", "501", "502", "503", "504", "505", "506", "507", "508", "509", + "510", "511", "512", "513", "514", "515", "516", "517", "518", "519", + "520", "521", "522", "523", "524", "525", "526", "527", "528", "529", + "530", "531", "532", "533", "534", "535", "536", "537", "538", "539", + "540", "541", "542", "543", "544", "545", "546", "547", "548", "549", + "550", "551", "552", "553", "554", "555", "556", "557", "558", "559", + "560", "561", "562", "563", "564", "565", "566", "567", "568", "569", + "570", "571", "572", "573", "574", "575", "576", "577", "578", "579", + "580", "581", "582", "583", "584", "585", "586", "587", "588", "589", + "590", "591", "592", "593", "594", "595", "596", "597", "598", "599", + "600", "601", "602", "603", "604", "605", "606", "607", "608", "609", + "610", "611", "612", "613", "614", "615", "616", "617", "618", "619", + "620", "621", "622", "623", "624", "625", "626", "627", "628", "629", + "630", "631", "632", "633", "634", "635", "636", "637", "638", "639", + "640", "641", "642", "643", "644", "645", "646", "647", "648", "649", + "650", "651", "652", "653", "654", "655", "656", "657", "658", "659", + "660", "661", "662", "663", "664", "665", "666", "667", "668", "669", + "670", "671", "672", "673", "674", "675", "676", "677", "678", "679", + "680", "681", "682", "683", "684", "685", "686", "687", "688", "689", + "690", "691", "692", "693", "694", "695", "696", "697", "698", "699", + "700", "701", "702", "703", "704", "705", "706", "707", "708", "709", + "710", "711", "712", "713", "714", "715", "716", "717", "718", "719", + "720", "721", "722", "723", "724", "725", "726", "727", "728", "729", + "730", "731", "732", "733", "734", "735", "736", "737", "738", "739", + "740", "741", "742", "743", "744", "745", "746", "747", "748", "749", + "750", "751", "752", "753", "754", "755", "756", "757", "758", "759", + "760", "761", "762", "763", "764", "765", "766", "767", "768", "769", + "770", "771", "772", "773", "774", "775", "776", "777", "778", "779", + "780", "781", "782", "783", "784", "785", "786", "787", "788", "789", + "790", "791", "792", "793", "794", "795", "796", "797", "798", "799", + "800", "801", "802", "803", "804", "805", "806", "807", "808", "809", + "810", "811", "812", "813", "814", "815", "816", "817", "818", "819", + "820", "821", "822", "823", "824", "825", "826", "827", "828", "829", + "830", "831", "832", "833", "834", "835", "836", "837", "838", "839", + "840", "841", "842", "843", "844", "845", "846", "847", "848", "849", + "850", "851", "852", "853", "854", "855", "856", "857", "858", "859", + "860", "861", "862", "863", "864", "865", "866", "867", "868", "869", + "870", "871", "872", "873", "874", "875", "876", "877", "878", "879", + "880", "881", "882", "883", "884", "885", "886", "887", "888", "889", + "890", "891", "892", "893", "894", "895", "896", "897", "898", "899", + "900", "901", "902", "903", "904", "905", "906", "907", "908", "909", + "910", "911", "912", "913", "914", "915", "916", "917", "918", "919", + "920", "921", "922", "923", "924", "925", "926", "927", "928", "929", + "930", "931", "932", "933", "934", "935", "936", "937", "938", "939", + "940", "941", "942", "943", "944", "945", "946", "947", "948", "949", + "950", "951", "952", "953", "954", "955", "956", "957", "958", "959", + "960", "961", "962", "963", "964", "965", "966", "967", "968", "969", + "970", "971", "972", "973", "974", "975", "976", "977", "978", "979", + "980", "981", "982", "983", "984", "985", "986", "987", "988", "989", + "990", "991", "992", "993", "994", "995", "996", "997", "998", "999", + "1000", "1001", "1002", "1003", "1004", "1005", "1006", "1007", "1008", "1009", + "1010", "1011", "1012", "1013", "1014", "1015", "1016", "1017", "1018", "1019", + "1020", "1021", "1022", "1023" + +}; + +CStandardRecvProxies::CStandardRecvProxies() +{ + m_Int32ToInt8 = RecvProxy_Int32ToInt8; + m_Int32ToInt16 = RecvProxy_Int32ToInt16; + m_Int32ToInt32 = RecvProxy_Int32ToInt32; +#ifdef SUPPORTS_INT64 + m_Int64ToInt64 = RecvProxy_Int64ToInt64; +#endif + m_FloatToFloat = RecvProxy_FloatToFloat; + m_VectorToVector = RecvProxy_VectorToVector; +} + +CStandardRecvProxies g_StandardRecvProxies; + + +// ---------------------------------------------------------------------- // +// RecvProp. +// ---------------------------------------------------------------------- // +RecvProp::RecvProp() +{ + m_pExtraData = NULL; + m_pVarName = NULL; + m_Offset = 0; + m_RecvType = DPT_Int; + m_Flags = 0; + m_ProxyFn = NULL; + m_DataTableProxyFn = NULL; + m_pDataTable = NULL; + m_nElements = 1; + m_ElementStride = -1; + m_pArrayProp = NULL; + m_ArrayLengthProxy = NULL; + m_bInsideArray = false; +} + +// ---------------------------------------------------------------------- // +// RecvTable. +// ---------------------------------------------------------------------- // +RecvTable::RecvTable() +{ + Construct( NULL, 0, NULL ); +} + +RecvTable::RecvTable(RecvProp *pProps, int nProps, const char *pNetTableName) +{ + Construct( pProps, nProps, pNetTableName ); +} + +RecvTable::~RecvTable() +{ +} + +void RecvTable::Construct( RecvProp *pProps, int nProps, const char *pNetTableName ) +{ + m_pProps = pProps; + m_nProps = nProps; + m_pDecoder = NULL; + m_pNetTableName = pNetTableName; + m_bInitialized = false; + m_bInMainList = false; +} + + +// ---------------------------------------------------------------------- // +// Prop setup functions (for building tables). +// ---------------------------------------------------------------------- // + +RecvProp RecvPropFloat( + const char *pVarName, + int offset, + int sizeofVar, + int flags, + RecvVarProxyFn varProxy + ) +{ + RecvProp ret; + +#ifdef _DEBUG + if ( varProxy == RecvProxy_FloatToFloat ) + { + Assert( sizeofVar == 0 || sizeofVar == 4 ); + } +#endif + + ret.m_pVarName = pVarName; + ret.SetOffset( offset ); + ret.m_RecvType = DPT_Float; + ret.m_Flags = flags; + ret.SetProxyFn( varProxy ); + + return ret; +} + +RecvProp RecvPropVector( + const char *pVarName, + int offset, + int sizeofVar, + int flags, + RecvVarProxyFn varProxy + ) +{ + RecvProp ret; + +#ifdef _DEBUG + if ( varProxy == RecvProxy_VectorToVector ) + { + Assert( sizeofVar == sizeof( Vector ) ); + } +#endif + + ret.m_pVarName = pVarName; + ret.SetOffset( offset ); + ret.m_RecvType = DPT_Vector; + ret.m_Flags = flags; + ret.SetProxyFn( varProxy ); + + return ret; +} + +RecvProp RecvPropVectorXY( + const char *pVarName, + int offset, + int sizeofVar, + int flags, + RecvVarProxyFn varProxy + ) +{ + RecvProp ret; + +#ifdef _DEBUG + if ( varProxy == RecvProxy_VectorToVector ) + { + Assert( sizeofVar == sizeof( Vector ) ); + } +#endif + + ret.m_pVarName = pVarName; + ret.SetOffset( offset ); + ret.m_RecvType = DPT_VectorXY; + ret.m_Flags = flags; + ret.SetProxyFn( varProxy ); + + return ret; +} + +#if 0 // We can't ship this since it changes the size of DTVariant to be 20 bytes instead of 16 and that breaks MODs!!! + +RecvProp RecvPropQuaternion( + const char *pVarName, + int offset, + int sizeofVar, // Handled by RECVINFO macro, but set to SIZEOF_IGNORE if you don't want to bother. + int flags, + RecvVarProxyFn varProxy + ) +{ + RecvProp ret; + +#ifdef _DEBUG + if ( varProxy == RecvProxy_QuaternionToQuaternion ) + { + Assert( sizeofVar == sizeof( Quaternion ) ); + } +#endif + + ret.m_pVarName = pVarName; + ret.SetOffset( offset ); + ret.m_RecvType = DPT_Quaternion; + ret.m_Flags = flags; + ret.SetProxyFn( varProxy ); + + return ret; +} +#endif + +RecvProp RecvPropInt( + const char *pVarName, + int offset, + int sizeofVar, + int flags, + RecvVarProxyFn varProxy + ) +{ + RecvProp ret; + + // If they didn't specify a proxy, then figure out what type we're writing to. + if (varProxy == NULL) + { + if (sizeofVar == 1) + { + varProxy = RecvProxy_Int32ToInt8; + } + else if (sizeofVar == 2) + { + varProxy = RecvProxy_Int32ToInt16; + } + else if (sizeofVar == 4) + { + varProxy = RecvProxy_Int32ToInt32; + } +#ifdef SUPPORTS_INT64 + else if (sizeofVar == 8) + { + varProxy = RecvProxy_Int64ToInt64; + } +#endif + else + { + Assert(!"RecvPropInt var has invalid size"); + varProxy = RecvProxy_Int32ToInt8; // safest one... + } + } + + ret.m_pVarName = pVarName; + ret.SetOffset( offset ); +#ifdef SUPPORTS_INT64 + ret.m_RecvType = (sizeofVar == 8) ? DPT_Int64 : DPT_Int; +#else + ret.m_RecvType = DPT_Int; +#endif + ret.m_Flags = flags; + ret.SetProxyFn( varProxy ); + + return ret; +} + +RecvProp RecvPropString( + const char *pVarName, + int offset, + int bufferSize, + int flags, + RecvVarProxyFn varProxy + ) +{ + RecvProp ret; + + ret.m_pVarName = pVarName; + ret.SetOffset( offset ); + ret.m_RecvType = DPT_String; + ret.m_Flags = flags; + ret.m_StringBufferSize = bufferSize; + ret.SetProxyFn( varProxy ); + + return ret; +} + +RecvProp RecvPropDataTable( + const char *pVarName, + int offset, + int flags, + RecvTable *pTable, + DataTableRecvVarProxyFn varProxy + ) +{ + RecvProp ret; + + ret.m_pVarName = pVarName; + ret.SetOffset( offset ); + ret.m_RecvType = DPT_DataTable; + ret.m_Flags = flags; + ret.SetDataTableProxyFn( varProxy ); + ret.SetDataTable( pTable ); + + return ret; +} + +RecvProp RecvPropArray3( + const char *pVarName, + int offset, + int sizeofVar, + int elements, + RecvProp pArrayProp, + DataTableRecvVarProxyFn varProxy + ) +{ + RecvProp ret; + + Assert( elements <= MAX_ARRAY_ELEMENTS ); + + ret.m_pVarName = pVarName; + ret.SetOffset( offset ); + ret.m_RecvType = DPT_DataTable; + ret.SetDataTableProxyFn( varProxy ); + + RecvProp *pProps = new RecvProp[elements]; // TODO free that again + + const char *pParentArrayPropName = AllocateStringHelper( "%s", pVarName ); + + for ( int i=0; i < elements; i++ ) + { + pProps[i] = pArrayProp; // copy basic property settings + pProps[i].SetOffset( i * sizeofVar ); // adjust offset + pProps[i].m_pVarName = s_ClientElementNames[i]; // give unique name + pProps[i].SetParentArrayPropName( pParentArrayPropName ); // For debugging... + } + + RecvTable *pTable = new RecvTable( pProps, elements, pVarName ); // TODO free that again + + ret.SetDataTable( pTable ); + + return ret; +} + +RecvProp InternalRecvPropArray( + const int elementCount, + const int elementStride, + const char *pName, + ArrayLengthRecvProxyFn proxy + ) +{ + RecvProp ret; + + ret.InitArray( elementCount, elementStride ); + ret.m_pVarName = pName; + ret.SetArrayLengthProxy( proxy ); + + return ret; +} + + +// ---------------------------------------------------------------------- // +// Proxies. +// ---------------------------------------------------------------------- // + +void RecvProxy_FloatToFloat( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + Assert( IsFinite( pData->m_Value.m_Float ) ); + *((float*)pOut) = pData->m_Value.m_Float; +} + +void RecvProxy_VectorToVector( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + const float *v = pData->m_Value.m_Vector; + + Assert( IsFinite( v[0] ) && IsFinite( v[1] ) && IsFinite( v[2] ) ); + ((float*)pOut)[0] = v[0]; + ((float*)pOut)[1] = v[1]; + ((float*)pOut)[2] = v[2]; +} + +void RecvProxy_VectorXYToVectorXY( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + const float *v = pData->m_Value.m_Vector; + + Assert( IsFinite( v[0] ) && IsFinite( v[1] ) ); + ((float*)pOut)[0] = v[0]; + ((float*)pOut)[1] = v[1]; +} + +void RecvProxy_QuaternionToQuaternion( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + const float *v = pData->m_Value.m_Vector; + + Assert( IsFinite( v[0] ) && IsFinite( v[1] ) && IsFinite( v[2] ) && IsFinite( v[3] ) ); + ((float*)pOut)[0] = v[0]; + ((float*)pOut)[1] = v[1]; + ((float*)pOut)[2] = v[2]; + ((float*)pOut)[3] = v[3]; +} + +void RecvProxy_Int32ToInt8( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + *((unsigned char*)pOut) = (unsigned char)pData->m_Value.m_Int; +} + +void RecvProxy_Int32ToInt16( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + *((unsigned short*)pOut) = (unsigned short)pData->m_Value.m_Int; +} + +void RecvProxy_Int32ToInt32( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + *((unsigned long*)pOut) = (unsigned long)pData->m_Value.m_Int; +} + +#ifdef SUPPORTS_INT64 +void RecvProxy_Int64ToInt64( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + *((int64*)pOut) = (int64)pData->m_Value.m_Int64; +} +#endif + +void RecvProxy_StringToString( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + char *pStrOut = (char*)pOut; + if ( pData->m_pRecvProp->m_StringBufferSize <= 0 ) + { + return; + } + + for ( int i=0; i < pData->m_pRecvProp->m_StringBufferSize; i++ ) + { + pStrOut[i] = pData->m_Value.m_pString[i]; + if ( pStrOut[i] == 0 ) + break; + } + + pStrOut[pData->m_pRecvProp->m_StringBufferSize-1] = 0; +} + +void DataTableRecvProxy_StaticDataTable( const RecvProp *pProp, void **pOut, void *pData, int objectID ) +{ + *pOut = pData; +} + +void DataTableRecvProxy_PointerDataTable( const RecvProp *pProp, void **pOut, void *pData, int objectID ) +{ + *pOut = *((void**)pData); +} + +#endif diff --git a/sp/src/public/dt_recv.h b/sp/src/public/dt_recv.h new file mode 100644 index 00000000..883b8f75 --- /dev/null +++ b/sp/src/public/dt_recv.h @@ -0,0 +1,573 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#ifndef DATATABLE_RECV_H +#define DATATABLE_RECV_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "dt_common.h" +#include "tier0/dbg.h" + + +#define ADDRESSPROXY_NONE -1 + + +class RecvTable; +class RecvProp; + + +// This is passed into RecvProxy functions. +class CRecvProxyData +{ +public: + const RecvProp *m_pRecvProp; // The property it's receiving. + + DVariant m_Value; // The value given to you to store. + + int m_iElement; // Which array element you're getting. + + int m_ObjectID; // The object being referred to. +}; + + +//----------------------------------------------------------------------------- +// pStruct = the base structure of the datatable this variable is in (like C_BaseEntity) +// pOut = the variable that this this proxy represents (like C_BaseEntity::m_SomeValue). +// +// Convert the network-standard-type value in m_Value into your own format in pStruct/pOut. +//----------------------------------------------------------------------------- +typedef void (*RecvVarProxyFn)( const CRecvProxyData *pData, void *pStruct, void *pOut ); + +// ------------------------------------------------------------------------ // +// ArrayLengthRecvProxies are optionally used to get the length of the +// incoming array when it changes. +// ------------------------------------------------------------------------ // +typedef void (*ArrayLengthRecvProxyFn)( void *pStruct, int objectID, int currentArrayLength ); + + +// NOTE: DataTable receive proxies work differently than the other proxies. +// pData points at the object + the recv table's offset. +// pOut should be set to the location of the object to unpack the data table into. +// If the parent object just contains the child object, the default proxy just does *pOut = pData. +// If the parent object points at the child object, you need to dereference the pointer here. +// NOTE: don't ever return null from a DataTable receive proxy function. Bad things will happen. +typedef void (*DataTableRecvVarProxyFn)(const RecvProp *pProp, void **pOut, void *pData, int objectID); + + +// This is used to fork over the standard proxy functions to the engine so it can +// make some optimizations. +class CStandardRecvProxies +{ +public: + CStandardRecvProxies(); + + RecvVarProxyFn m_Int32ToInt8; + RecvVarProxyFn m_Int32ToInt16; + RecvVarProxyFn m_Int32ToInt32; + RecvVarProxyFn m_FloatToFloat; + RecvVarProxyFn m_VectorToVector; +#ifdef SUPPORTS_INT64 + RecvVarProxyFn m_Int64ToInt64; +#endif +}; +extern CStandardRecvProxies g_StandardRecvProxies; + + +class CRecvDecoder; + + +class RecvProp +{ +// This info comes from the receive data table. +public: + RecvProp(); + + void InitArray( int nElements, int elementStride ); + + int GetNumElements() const; + void SetNumElements( int nElements ); + + int GetElementStride() const; + void SetElementStride( int stride ); + + int GetFlags() const; + + const char* GetName() const; + SendPropType GetType() const; + + RecvTable* GetDataTable() const; + void SetDataTable( RecvTable *pTable ); + + RecvVarProxyFn GetProxyFn() const; + void SetProxyFn( RecvVarProxyFn fn ); + + DataTableRecvVarProxyFn GetDataTableProxyFn() const; + void SetDataTableProxyFn( DataTableRecvVarProxyFn fn ); + + int GetOffset() const; + void SetOffset( int o ); + + // Arrays only. + RecvProp* GetArrayProp() const; + void SetArrayProp( RecvProp *pProp ); + + // Arrays only. + void SetArrayLengthProxy( ArrayLengthRecvProxyFn proxy ); + ArrayLengthRecvProxyFn GetArrayLengthProxy() const; + + bool IsInsideArray() const; + void SetInsideArray(); + + // Some property types bind more data to the prop in here. + const void* GetExtraData() const; + void SetExtraData( const void *pData ); + + // If it's one of the numbered "000", "001", etc properties in an array, then + // these can be used to get its array property name for debugging. + const char* GetParentArrayPropName(); + void SetParentArrayPropName( const char *pArrayPropName ); + +public: + + const char *m_pVarName; + SendPropType m_RecvType; + int m_Flags; + int m_StringBufferSize; + + +private: + + bool m_bInsideArray; // Set to true by the engine if this property sits inside an array. + + // Extra data that certain special property types bind to the property here. + const void *m_pExtraData; + + // If this is an array (DPT_Array). + RecvProp *m_pArrayProp; + ArrayLengthRecvProxyFn m_ArrayLengthProxy; + + RecvVarProxyFn m_ProxyFn; + DataTableRecvVarProxyFn m_DataTableProxyFn; // For RDT_DataTable. + + RecvTable *m_pDataTable; // For RDT_DataTable. + int m_Offset; + + int m_ElementStride; + int m_nElements; + + // If it's one of the numbered "000", "001", etc properties in an array, then + // these can be used to get its array property name for debugging. + const char *m_pParentArrayPropName; +}; + + +class RecvTable +{ +public: + + typedef RecvProp PropType; + + RecvTable(); + RecvTable( RecvProp *pProps, int nProps, const char *pNetTableName ); + ~RecvTable(); + + void Construct( RecvProp *pProps, int nProps, const char *pNetTableName ); + + int GetNumProps(); + RecvProp* GetProp( int i ); + + const char* GetName(); + + // Used by the engine while initializing array props. + void SetInitialized( bool bInitialized ); + bool IsInitialized() const; + + // Used by the engine. + void SetInMainList( bool bInList ); + bool IsInMainList() const; + + +public: + + // Properties described in a table. + RecvProp *m_pProps; + int m_nProps; + + // The decoder. NOTE: this covers each RecvTable AND all its children (ie: its children + // will have their own decoders that include props for all their children). + CRecvDecoder *m_pDecoder; + + const char *m_pNetTableName; // The name matched between client and server. + + +private: + + bool m_bInitialized; + bool m_bInMainList; +}; + + +inline int RecvTable::GetNumProps() +{ + return m_nProps; +} + +inline RecvProp* RecvTable::GetProp( int i ) +{ + Assert( i >= 0 && i < m_nProps ); + return &m_pProps[i]; +} + +inline const char* RecvTable::GetName() +{ + return m_pNetTableName; +} + +inline void RecvTable::SetInitialized( bool bInitialized ) +{ + m_bInitialized = bInitialized; +} + +inline bool RecvTable::IsInitialized() const +{ + return m_bInitialized; +} + +inline void RecvTable::SetInMainList( bool bInList ) +{ + m_bInMainList = bInList; +} + +inline bool RecvTable::IsInMainList() const +{ + return m_bInMainList; +} + + +// ------------------------------------------------------------------------------------------------------ // +// See notes on BEGIN_SEND_TABLE for a description. These macros work similarly. +// ------------------------------------------------------------------------------------------------------ // +#define BEGIN_RECV_TABLE(className, tableName) \ + BEGIN_RECV_TABLE_NOBASE(className, tableName) \ + RecvPropDataTable("baseclass", 0, 0, className::BaseClass::m_pClassRecvTable, DataTableRecvProxy_StaticDataTable), + +#define BEGIN_RECV_TABLE_NOBASE(className, tableName) \ + template int ClientClassInit(T *); \ + namespace tableName { \ + struct ignored; \ + } \ + template <> int ClientClassInit(tableName::ignored *); \ + namespace tableName { \ + RecvTable g_RecvTable; \ + int g_RecvTableInit = ClientClassInit((tableName::ignored *)NULL); \ + } \ + template <> int ClientClassInit(tableName::ignored *) \ + { \ + typedef className currentRecvDTClass; \ + const char *pRecvTableName = #tableName; \ + RecvTable &RecvTable = tableName::g_RecvTable; \ + static RecvProp RecvProps[] = { \ + RecvPropInt("should_never_see_this", 0, sizeof(int)), // It adds a dummy property at the start so you can define "empty" SendTables. + +#define END_RECV_TABLE() \ + }; \ + RecvTable.Construct(RecvProps+1, sizeof(RecvProps) / sizeof(RecvProp) - 1, pRecvTableName); \ + return 1; \ + } + + +#define RECVINFO(varName) #varName, offsetof(currentRecvDTClass, varName), sizeof(((currentRecvDTClass*)0)->varName) +#define RECVINFO_NAME(varName, remoteVarName) #remoteVarName, offsetof(currentRecvDTClass, varName), sizeof(((currentRecvDTClass*)0)->varName) +#define RECVINFO_STRING(varName) #varName, offsetof(currentRecvDTClass, varName), STRINGBUFSIZE(currentRecvDTClass, varName) +#define RECVINFO_BASECLASS(tableName) RecvPropDataTable("this", 0, 0, &REFERENCE_RECV_TABLE(tableName)) +#define RECVINFO_ARRAY(varName) #varName, offsetof(currentRecvDTClass, varName), sizeof(((currentRecvDTClass*)0)->varName[0]), sizeof(((currentRecvDTClass*)0)->varName)/sizeof(((currentRecvDTClass*)0)->varName[0]) + +// Just specify the name and offset. Used for strings and data tables. +#define RECVINFO_NOSIZE(varName) #varName, offsetof(currentRecvDTClass, varName) +#define RECVINFO_DT(varName) RECVINFO_NOSIZE(varName) +#define RECVINFO_DTNAME(varName,remoteVarName) #remoteVarName, offsetof(currentRecvDTClass, varName) + + +void RecvProxy_FloatToFloat ( const CRecvProxyData *pData, void *pStruct, void *pOut ); +void RecvProxy_VectorToVector( const CRecvProxyData *pData, void *pStruct, void *pOut ); +void RecvProxy_VectorXYToVectorXY( const CRecvProxyData *pData, void *pStruct, void *pOut ); +void RecvProxy_QuaternionToQuaternion( const CRecvProxyData *pData, void *pStruct, void *pOut ); +void RecvProxy_Int32ToInt8 ( const CRecvProxyData *pData, void *pStruct, void *pOut ); +void RecvProxy_Int32ToInt16 ( const CRecvProxyData *pData, void *pStruct, void *pOut ); +void RecvProxy_StringToString( const CRecvProxyData *pData, void *pStruct, void *pOut ); +void RecvProxy_Int32ToInt32 ( const CRecvProxyData *pData, void *pStruct, void *pOut ); +#ifdef SUPPORTS_INT64 +void RecvProxy_Int64ToInt64 ( const CRecvProxyData *pData, void *pStruct, void *pOut ); +#endif + +// StaticDataTable does *pOut = pData. +void DataTableRecvProxy_StaticDataTable(const RecvProp *pProp, void **pOut, void *pData, int objectID); + +// PointerDataTable does *pOut = *((void**)pData) (ie: pData is a pointer to the object to decode into). +void DataTableRecvProxy_PointerDataTable(const RecvProp *pProp, void **pOut, void *pData, int objectID); + + +RecvProp RecvPropFloat( + const char *pVarName, + int offset, + int sizeofVar=SIZEOF_IGNORE, // Handled by RECVINFO macro, but set to SIZEOF_IGNORE if you don't want to bother. + int flags=0, + RecvVarProxyFn varProxy=RecvProxy_FloatToFloat + ); + +RecvProp RecvPropVector( + const char *pVarName, + int offset, + int sizeofVar=SIZEOF_IGNORE, // Handled by RECVINFO macro, but set to SIZEOF_IGNORE if you don't want to bother. + int flags=0, + RecvVarProxyFn varProxy=RecvProxy_VectorToVector + ); + +RecvProp RecvPropVectorXY( + const char *pVarName, + int offset, + int sizeofVar=SIZEOF_IGNORE, // Handled by RECVINFO macro, but set to SIZEOF_IGNORE if you don't want to bother. + int flags=0, + RecvVarProxyFn varProxy=RecvProxy_VectorXYToVectorXY + ); + +// This is here so the RecvTable can look more like the SendTable. +#define RecvPropQAngles RecvPropVector + +#if 0 // We can't ship this since it changes the size of DTVariant to be 20 bytes instead of 16 and that breaks MODs!!! + +RecvProp RecvPropQuaternion( + const char *pVarName, + int offset, + int sizeofVar=SIZEOF_IGNORE, // Handled by RECVINFO macro, but set to SIZEOF_IGNORE if you don't want to bother. + int flags=0, + RecvVarProxyFn varProxy=RecvProxy_QuaternionToQuaternion + ); +#endif + +RecvProp RecvPropInt( + const char *pVarName, + int offset, + int sizeofVar=SIZEOF_IGNORE, // Handled by RECVINFO macro, but set to SIZEOF_IGNORE if you don't want to bother. + int flags=0, + RecvVarProxyFn varProxy=0 + ); + +RecvProp RecvPropString( + const char *pVarName, + int offset, + int bufferSize, + int flags=0, + RecvVarProxyFn varProxy=RecvProxy_StringToString + ); + +RecvProp RecvPropDataTable( + const char *pVarName, + int offset, + int flags, + RecvTable *pTable, + DataTableRecvVarProxyFn varProxy=DataTableRecvProxy_StaticDataTable + ); + +RecvProp RecvPropArray3( + const char *pVarName, + int offset, + int sizeofVar, + int elements, + RecvProp pArrayProp, + DataTableRecvVarProxyFn varProxy=DataTableRecvProxy_StaticDataTable + ); + +// Use the macro to let it automatically generate a table name. You shouldn't +// ever need to reference the table name. If you want to exclude this array, then +// reference the name of the variable in varTemplate. +RecvProp InternalRecvPropArray( + const int elementCount, + const int elementStride, + const char *pName, + ArrayLengthRecvProxyFn proxy + ); + + +// +// Use this if you want to completely manage the way the array data is stored. +// You'll need to provide a proxy inside varTemplate that looks for 'iElement' +// to figure out where to store the specified element. +// +#define RecvPropVirtualArray( arrayLengthProxy, maxArrayLength, varTemplate, propertyName ) \ + varTemplate, \ + InternalRecvPropArray( \ + maxArrayLength, \ + 0, \ + #propertyName, \ + arrayLengthProxy \ + ) + + +// Use this and pass the array name and it will figure out the count and stride automatically. +#define RecvPropVariableLengthArray( arrayLengthProxy, varTemplate, arrayName ) \ + varTemplate, \ + InternalRecvPropArray( \ + sizeof(((currentRecvDTClass*)0)->arrayName) / PROPSIZEOF(currentRecvDTClass, arrayName[0]), \ + PROPSIZEOF(currentRecvDTClass, arrayName[0]), \ + #arrayName, \ + arrayLengthProxy \ + ) + + +// Use this and pass the array name and it will figure out the count and stride automatically. +#define RecvPropArray( varTemplate, arrayName ) \ + RecvPropVariableLengthArray( 0, varTemplate, arrayName ) + + +// Use this one to specify the element count and stride manually. +#define RecvPropArray2( arrayLengthProxy, varTemplate, elementCount, elementStride, arrayName ) \ + varTemplate, \ + InternalRecvPropArray( elementCount, elementStride, #arrayName, arrayLengthProxy ) + + +// ---------------------------------------------------------------------------------------- // +// Inlines. +// ---------------------------------------------------------------------------------------- // + +inline void RecvProp::InitArray( int nElements, int elementStride ) +{ + m_RecvType = DPT_Array; + m_nElements = nElements; + m_ElementStride = elementStride; +} + +inline int RecvProp::GetNumElements() const +{ + return m_nElements; +} + +inline void RecvProp::SetNumElements( int nElements ) +{ + m_nElements = nElements; +} + +inline int RecvProp::GetElementStride() const +{ + return m_ElementStride; +} + +inline void RecvProp::SetElementStride( int stride ) +{ + m_ElementStride = stride; +} + +inline int RecvProp::GetFlags() const +{ + return m_Flags; +} + +inline const char* RecvProp::GetName() const +{ + return m_pVarName; +} + +inline SendPropType RecvProp::GetType() const +{ + return m_RecvType; +} + +inline RecvTable* RecvProp::GetDataTable() const +{ + return m_pDataTable; +} + +inline void RecvProp::SetDataTable( RecvTable *pTable ) +{ + m_pDataTable = pTable; +} + +inline RecvVarProxyFn RecvProp::GetProxyFn() const +{ + return m_ProxyFn; +} + +inline void RecvProp::SetProxyFn( RecvVarProxyFn fn ) +{ + m_ProxyFn = fn; +} + +inline DataTableRecvVarProxyFn RecvProp::GetDataTableProxyFn() const +{ + return m_DataTableProxyFn; +} + +inline void RecvProp::SetDataTableProxyFn( DataTableRecvVarProxyFn fn ) +{ + m_DataTableProxyFn = fn; +} + +inline int RecvProp::GetOffset() const +{ + return m_Offset; +} + +inline void RecvProp::SetOffset( int o ) +{ + m_Offset = o; +} + +inline RecvProp* RecvProp::GetArrayProp() const +{ + return m_pArrayProp; +} + +inline void RecvProp::SetArrayProp( RecvProp *pProp ) +{ + m_pArrayProp = pProp; +} + +inline void RecvProp::SetArrayLengthProxy( ArrayLengthRecvProxyFn proxy ) +{ + m_ArrayLengthProxy = proxy; +} + +inline ArrayLengthRecvProxyFn RecvProp::GetArrayLengthProxy() const +{ + return m_ArrayLengthProxy; +} + +inline bool RecvProp::IsInsideArray() const +{ + return m_bInsideArray; +} + +inline void RecvProp::SetInsideArray() +{ + m_bInsideArray = true; +} + +inline const void* RecvProp::GetExtraData() const +{ + return m_pExtraData; +} + +inline void RecvProp::SetExtraData( const void *pData ) +{ + m_pExtraData = pData; +} + +inline const char* RecvProp::GetParentArrayPropName() +{ + return m_pParentArrayPropName; +} + +inline void RecvProp::SetParentArrayPropName( const char *pArrayPropName ) +{ + m_pParentArrayPropName = pArrayPropName; +} + +#endif // DATATABLE_RECV_H diff --git a/sp/src/public/dt_send.cpp b/sp/src/public/dt_send.cpp new file mode 100644 index 00000000..caad4191 --- /dev/null +++ b/sp/src/public/dt_send.cpp @@ -0,0 +1,881 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + + +#include "dt_send.h" +#include "mathlib/mathlib.h" +#include "mathlib/vector.h" +#include "tier0/dbg.h" +#include "dt_utlvector_common.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#if !defined(_STATIC_LINKED) || defined(GAME_DLL) + + +static CNonModifiedPointerProxy *s_pNonModifiedPointerProxyHead = NULL; + + +void SendProxy_UInt8ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID); +void SendProxy_UInt16ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID); +void SendProxy_UInt32ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID); +#ifdef SUPPORTS_INT64 +void SendProxy_UInt64ToInt64( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID); +#endif +const char *s_ElementNames[MAX_ARRAY_ELEMENTS] = +{ + "000", "001", "002", "003", "004", "005", "006", "007", "008", "009", + "010", "011", "012", "013", "014", "015", "016", "017", "018", "019", + "020", "021", "022", "023", "024", "025", "026", "027", "028", "029", + "030", "031", "032", "033", "034", "035", "036", "037", "038", "039", + "040", "041", "042", "043", "044", "045", "046", "047", "048", "049", + "050", "051", "052", "053", "054", "055", "056", "057", "058", "059", + "060", "061", "062", "063", "064", "065", "066", "067", "068", "069", + "070", "071", "072", "073", "074", "075", "076", "077", "078", "079", + "080", "081", "082", "083", "084", "085", "086", "087", "088", "089", + "090", "091", "092", "093", "094", "095", "096", "097", "098", "099", + "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", + "110", "111", "112", "113", "114", "115", "116", "117", "118", "119", + "120", "121", "122", "123", "124", "125", "126", "127", "128", "129", + "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", + "140", "141", "142", "143", "144", "145", "146", "147", "148", "149", + "150", "151", "152", "153", "154", "155", "156", "157", "158", "159", + "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", + "170", "171", "172", "173", "174", "175", "176", "177", "178", "179", + "180", "181", "182", "183", "184", "185", "186", "187", "188", "189", + "190", "191", "192", "193", "194", "195", "196", "197", "198", "199", + "200", "201", "202", "203", "204", "205", "206", "207", "208", "209", + "210", "211", "212", "213", "214", "215", "216", "217", "218", "219", + "220", "221", "222", "223", "224", "225", "226", "227", "228", "229", + "230", "231", "232", "233", "234", "235", "236", "237", "238", "239", + "240", "241", "242", "243", "244", "245", "246", "247", "248", "249", + "250", "251", "252", "253", "254", "255", "256", "257", "258", "259", + "260", "261", "262", "263", "264", "265", "266", "267", "268", "269", + "270", "271", "272", "273", "274", "275", "276", "277", "278", "279", + "280", "281", "282", "283", "284", "285", "286", "287", "288", "289", + "290", "291", "292", "293", "294", "295", "296", "297", "298", "299", + "300", "301", "302", "303", "304", "305", "306", "307", "308", "309", + "310", "311", "312", "313", "314", "315", "316", "317", "318", "319", + "320", "321", "322", "323", "324", "325", "326", "327", "328", "329", + "330", "331", "332", "333", "334", "335", "336", "337", "338", "339", + "340", "341", "342", "343", "344", "345", "346", "347", "348", "349", + "350", "351", "352", "353", "354", "355", "356", "357", "358", "359", + "360", "361", "362", "363", "364", "365", "366", "367", "368", "369", + "370", "371", "372", "373", "374", "375", "376", "377", "378", "379", + "380", "381", "382", "383", "384", "385", "386", "387", "388", "389", + "390", "391", "392", "393", "394", "395", "396", "397", "398", "399", + "400", "401", "402", "403", "404", "405", "406", "407", "408", "409", + "410", "411", "412", "413", "414", "415", "416", "417", "418", "419", + "420", "421", "422", "423", "424", "425", "426", "427", "428", "429", + "430", "431", "432", "433", "434", "435", "436", "437", "438", "439", + "440", "441", "442", "443", "444", "445", "446", "447", "448", "449", + "450", "451", "452", "453", "454", "455", "456", "457", "458", "459", + "460", "461", "462", "463", "464", "465", "466", "467", "468", "469", + "470", "471", "472", "473", "474", "475", "476", "477", "478", "479", + "480", "481", "482", "483", "484", "485", "486", "487", "488", "489", + "490", "491", "492", "493", "494", "495", "496", "497", "498", "499", + "500", "501", "502", "503", "504", "505", "506", "507", "508", "509", + "510", "511", "512", "513", "514", "515", "516", "517", "518", "519", + "520", "521", "522", "523", "524", "525", "526", "527", "528", "529", + "530", "531", "532", "533", "534", "535", "536", "537", "538", "539", + "540", "541", "542", "543", "544", "545", "546", "547", "548", "549", + "550", "551", "552", "553", "554", "555", "556", "557", "558", "559", + "560", "561", "562", "563", "564", "565", "566", "567", "568", "569", + "570", "571", "572", "573", "574", "575", "576", "577", "578", "579", + "580", "581", "582", "583", "584", "585", "586", "587", "588", "589", + "590", "591", "592", "593", "594", "595", "596", "597", "598", "599", + "600", "601", "602", "603", "604", "605", "606", "607", "608", "609", + "610", "611", "612", "613", "614", "615", "616", "617", "618", "619", + "620", "621", "622", "623", "624", "625", "626", "627", "628", "629", + "630", "631", "632", "633", "634", "635", "636", "637", "638", "639", + "640", "641", "642", "643", "644", "645", "646", "647", "648", "649", + "650", "651", "652", "653", "654", "655", "656", "657", "658", "659", + "660", "661", "662", "663", "664", "665", "666", "667", "668", "669", + "670", "671", "672", "673", "674", "675", "676", "677", "678", "679", + "680", "681", "682", "683", "684", "685", "686", "687", "688", "689", + "690", "691", "692", "693", "694", "695", "696", "697", "698", "699", + "700", "701", "702", "703", "704", "705", "706", "707", "708", "709", + "710", "711", "712", "713", "714", "715", "716", "717", "718", "719", + "720", "721", "722", "723", "724", "725", "726", "727", "728", "729", + "730", "731", "732", "733", "734", "735", "736", "737", "738", "739", + "740", "741", "742", "743", "744", "745", "746", "747", "748", "749", + "750", "751", "752", "753", "754", "755", "756", "757", "758", "759", + "760", "761", "762", "763", "764", "765", "766", "767", "768", "769", + "770", "771", "772", "773", "774", "775", "776", "777", "778", "779", + "780", "781", "782", "783", "784", "785", "786", "787", "788", "789", + "790", "791", "792", "793", "794", "795", "796", "797", "798", "799", + "800", "801", "802", "803", "804", "805", "806", "807", "808", "809", + "810", "811", "812", "813", "814", "815", "816", "817", "818", "819", + "820", "821", "822", "823", "824", "825", "826", "827", "828", "829", + "830", "831", "832", "833", "834", "835", "836", "837", "838", "839", + "840", "841", "842", "843", "844", "845", "846", "847", "848", "849", + "850", "851", "852", "853", "854", "855", "856", "857", "858", "859", + "860", "861", "862", "863", "864", "865", "866", "867", "868", "869", + "870", "871", "872", "873", "874", "875", "876", "877", "878", "879", + "880", "881", "882", "883", "884", "885", "886", "887", "888", "889", + "890", "891", "892", "893", "894", "895", "896", "897", "898", "899", + "900", "901", "902", "903", "904", "905", "906", "907", "908", "909", + "910", "911", "912", "913", "914", "915", "916", "917", "918", "919", + "920", "921", "922", "923", "924", "925", "926", "927", "928", "929", + "930", "931", "932", "933", "934", "935", "936", "937", "938", "939", + "940", "941", "942", "943", "944", "945", "946", "947", "948", "949", + "950", "951", "952", "953", "954", "955", "956", "957", "958", "959", + "960", "961", "962", "963", "964", "965", "966", "967", "968", "969", + "970", "971", "972", "973", "974", "975", "976", "977", "978", "979", + "980", "981", "982", "983", "984", "985", "986", "987", "988", "989", + "990", "991", "992", "993", "994", "995", "996", "997", "998", "999", + "1000", "1001", "1002", "1003", "1004", "1005", "1006", "1007", "1008", "1009", + "1010", "1011", "1012", "1013", "1014", "1015", "1016", "1017", "1018", "1019", + "1020", "1021", "1022", "1023" + +}; + + +CNonModifiedPointerProxy::CNonModifiedPointerProxy( SendTableProxyFn fn ) +{ + m_pNext = s_pNonModifiedPointerProxyHead; + s_pNonModifiedPointerProxyHead = this; + m_Fn = fn; +} + + +CStandardSendProxiesV1::CStandardSendProxiesV1() +{ + m_Int8ToInt32 = SendProxy_Int8ToInt32; + m_Int16ToInt32 = SendProxy_Int16ToInt32; + m_Int32ToInt32 = SendProxy_Int32ToInt32; +#ifdef SUPPORTS_INT64 + m_Int64ToInt64 = SendProxy_Int64ToInt64; +#endif + + m_UInt8ToInt32 = SendProxy_UInt8ToInt32; + m_UInt16ToInt32 = SendProxy_UInt16ToInt32; + m_UInt32ToInt32 = SendProxy_UInt32ToInt32; +#ifdef SUPPORTS_INT64 + m_UInt64ToInt64 = SendProxy_UInt64ToInt64; +#endif + + m_FloatToFloat = SendProxy_FloatToFloat; + m_VectorToVector = SendProxy_VectorToVector; +} + +CStandardSendProxies::CStandardSendProxies() +{ + m_DataTableToDataTable = SendProxy_DataTableToDataTable; + m_SendLocalDataTable = SendProxy_SendLocalDataTable; + m_ppNonModifiedPointerProxies = &s_pNonModifiedPointerProxyHead; + +} +CStandardSendProxies g_StandardSendProxies; + + +// ---------------------------------------------------------------------- // +// Proxies. +// ---------------------------------------------------------------------- // +void SendProxy_AngleToFloat( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) +{ + float angle; + + angle = *((float*)pData); + pOut->m_Float = anglemod( angle ); + + Assert( IsFinite( pOut->m_Float ) ); +} + +void SendProxy_FloatToFloat( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) +{ + pOut->m_Float = *((float*)pData); + Assert( IsFinite( pOut->m_Float ) ); +} + +void SendProxy_QAngles( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID ) +{ + QAngle *v = (QAngle*)pData; + pOut->m_Vector[0] = anglemod( v->x ); + pOut->m_Vector[1] = anglemod( v->y ); + pOut->m_Vector[2] = anglemod( v->z ); +} + +void SendProxy_VectorToVector( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) +{ + Vector& v = *(Vector*)pData; + Assert( v.IsValid() ); + pOut->m_Vector[0] = v[0]; + pOut->m_Vector[1] = v[1]; + pOut->m_Vector[2] = v[2]; +} + +void SendProxy_VectorXYToVectorXY( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) +{ + Vector& v = *(Vector*)pData; + Assert( v.IsValid() ); + pOut->m_Vector[0] = v[0]; + pOut->m_Vector[1] = v[1]; +} + +#if 0 // We can't ship this since it changes the size of DTVariant to be 20 bytes instead of 16 and that breaks MODs!!! +void SendProxy_QuaternionToQuaternion( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) +{ + Quaternion& q = *(Quaternion*)pData; + Assert( q.IsValid() ); + pOut->m_Vector[0] = q[0]; + pOut->m_Vector[1] = q[1]; + pOut->m_Vector[2] = q[2]; + pOut->m_Vector[3] = q[3]; +} +#endif + +void SendProxy_Int8ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) +{ + pOut->m_Int = *((const char*)pData); +} + +void SendProxy_Int16ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) +{ + pOut->m_Int = *((short*)pData); +} + +void SendProxy_Int32ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) +{ + pOut->m_Int = *((int*)pData); +} + +#ifdef SUPPORTS_INT64 +void SendProxy_Int64ToInt64( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) +{ + pOut->m_Int64 = *((int64*)pData); +} +#endif + +void SendProxy_UInt8ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) +{ + pOut->m_Int = *((const unsigned char*)pData); +} + +void SendProxy_UInt16ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) +{ + pOut->m_Int = *((unsigned short*)pData); +} + +void SendProxy_UInt32ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) +{ + *((unsigned long*)&pOut->m_Int) = *((unsigned long*)pData); +} +#ifdef SUPPORTS_INT64 +void SendProxy_UInt64ToInt64( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) +{ + *((int64*)&pOut->m_Int64) = *((uint64*)pData); +} +#endif + +void SendProxy_StringToString( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) +{ + pOut->m_pString = (const char*)pData; +} + +void* SendProxy_DataTableToDataTable( const SendProp *pProp, const void *pStructBase, const void *pData, CSendProxyRecipients *pRecipients, int objectID ) +{ + return (void*)pData; +} + +void* SendProxy_DataTablePtrToDataTable( const SendProp *pProp, const void *pStructBase, const void *pData, CSendProxyRecipients *pRecipients, int objectID ) +{ + return *((void**)pData); +} + +static void SendProxy_Empty( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: If the recipient is the same as objectID, go ahead and iterate down +// the m_Local stuff, otherwise, act like it wasn't there at all. +// This way, only the local player receives information about him/herself. +// Input : *pVarData - +// *pOut - +// objectID - +//----------------------------------------------------------------------------- + +void* SendProxy_SendLocalDataTable( const SendProp *pProp, const void *pStruct, const void *pVarData, CSendProxyRecipients *pRecipients, int objectID ) +{ + pRecipients->SetOnly( objectID - 1 ); + return ( void * )pVarData; +} + + + + + +// ---------------------------------------------------------------------- // +// Prop setup functions (for building tables). +// ---------------------------------------------------------------------- // +float AssignRangeMultiplier( int nBits, double range ) +{ + unsigned long iHighValue; + if ( nBits == 32 ) + iHighValue = 0xFFFFFFFE; + else + iHighValue = ((1 << (unsigned long)nBits) - 1); + + float fHighLowMul = iHighValue / range; + if ( CloseEnough( range, 0 ) ) + fHighLowMul = iHighValue; + + // If the precision is messing us up, then adjust it so it won't. + if ( (unsigned long)(fHighLowMul * range) > iHighValue || + (fHighLowMul * range) > (double)iHighValue ) + { + // Squeeze it down smaller and smaller until it's going to produce an integer + // in the valid range when given the highest value. + float multipliers[] = { 0.9999, 0.99, 0.9, 0.8, 0.7 }; + int i; + for ( i=0; i < ARRAYSIZE( multipliers ); i++ ) + { + fHighLowMul = (float)( iHighValue / range ) * multipliers[i]; + if ( (unsigned long)(fHighLowMul * range) > iHighValue || + (fHighLowMul * range) > (double)iHighValue ) + { + } + else + { + break; + } + } + + if ( i == ARRAYSIZE( multipliers ) ) + { + // Doh! We seem to be unable to represent this range. + Assert( false ); + return 0; + } + } + + return fHighLowMul; +} + + + +SendProp SendPropFloat( + const char *pVarName, + // Variable name. + int offset, // Offset into container structure. + int sizeofVar, + int nBits, // Number of bits to use when encoding. + int flags, + float fLowValue, // For floating point, low and high values. + float fHighValue, // High value. If HIGH_DEFAULT, it's (1<m_Int = atoi(pUserStr); + +// pProp : the SendProp that has the proxy +// pStructBase : the base structure (like CBaseEntity*). +// pData : the address of the variable to proxy. +// pOut : where to output the proxied value. +// iElement : the element index if this data is part of an array (or 0 if not). +// objectID : entity index for debugging purposes. + +// Return false if you don't want the engine to register and send a delta to +// the clients for this property (regardless of whether it actually changed or not). +// ------------------------------------------------------------------------ // +typedef void (*SendVarProxyFn)( const SendProp *pProp, const void *pStructBase, const void *pData, DVariant *pOut, int iElement, int objectID ); + +// Return the pointer to the data for the datatable. +// If the proxy returns null, it's the same as if pRecipients->ClearAllRecipients() was called. +class CSendProxyRecipients; + +typedef void* (*SendTableProxyFn)( + const SendProp *pProp, + const void *pStructBase, + const void *pData, + CSendProxyRecipients *pRecipients, + int objectID ); + + +class CNonModifiedPointerProxy +{ +public: + CNonModifiedPointerProxy( SendTableProxyFn fn ); + +public: + + SendTableProxyFn m_Fn; + CNonModifiedPointerProxy *m_pNext; +}; + + +// This tells the engine that the send proxy will not modify the pointer +// - it only plays with the recipients. This must be set on proxies that work +// this way, otherwise the engine can't track which properties changed +// in NetworkStateChanged(). +#define REGISTER_SEND_PROXY_NON_MODIFIED_POINTER( sendProxyFn ) static CNonModifiedPointerProxy __proxy_##sendProxyFn( sendProxyFn ); + + +class CStandardSendProxiesV1 +{ +public: + CStandardSendProxiesV1(); + + SendVarProxyFn m_Int8ToInt32; + SendVarProxyFn m_Int16ToInt32; + SendVarProxyFn m_Int32ToInt32; + + SendVarProxyFn m_UInt8ToInt32; + SendVarProxyFn m_UInt16ToInt32; + SendVarProxyFn m_UInt32ToInt32; + + SendVarProxyFn m_FloatToFloat; + SendVarProxyFn m_VectorToVector; + +#ifdef SUPPORTS_INT64 + SendVarProxyFn m_Int64ToInt64; + SendVarProxyFn m_UInt64ToInt64; +#endif +}; + +class CStandardSendProxies : public CStandardSendProxiesV1 +{ +public: + CStandardSendProxies(); + + SendTableProxyFn m_DataTableToDataTable; + SendTableProxyFn m_SendLocalDataTable; + CNonModifiedPointerProxy **m_ppNonModifiedPointerProxies; +}; + +extern CStandardSendProxies g_StandardSendProxies; + + +// Max # of datatable send proxies you can have in a tree. +#define MAX_DATATABLE_PROXIES 32 + +// ------------------------------------------------------------------------ // +// Datatable send proxies are used to tell the engine where the datatable's +// data is and to specify which clients should get the data. +// +// pRecipients is the object that allows you to specify which clients will +// receive the data. +// ------------------------------------------------------------------------ // +class CSendProxyRecipients +{ +public: + void SetAllRecipients(); // Note: recipients are all set by default when each proxy is called. + void ClearAllRecipients(); + + void SetRecipient( int iClient ); // Note: these are CLIENT indices, not entity indices (so the first player's index is 0). + void ClearRecipient( int iClient ); + + // Clear all recipients and set only the specified one. + void SetOnly( int iClient ); + +public: + // Make sure we have enough room for the max possible player count + CBitVec< ABSOLUTE_PLAYER_LIMIT > m_Bits; +}; + +inline void CSendProxyRecipients::SetAllRecipients() +{ + m_Bits.SetAll(); +} + +inline void CSendProxyRecipients::ClearAllRecipients() +{ + m_Bits.ClearAll(); +} + +inline void CSendProxyRecipients::SetRecipient( int iClient ) +{ + m_Bits.Set( iClient ); +} + +inline void CSendProxyRecipients::ClearRecipient( int iClient ) +{ + m_Bits.Clear( iClient ); +} + +inline void CSendProxyRecipients::SetOnly( int iClient ) +{ + m_Bits.ClearAll(); + m_Bits.Set( iClient ); +} + + + +// ------------------------------------------------------------------------ // +// ArrayLengthSendProxies are used when you want to specify an array's length +// dynamically. +// ------------------------------------------------------------------------ // +typedef int (*ArrayLengthSendProxyFn)( const void *pStruct, int objectID ); + + + +class RecvProp; +class SendTable; +class CSendTablePrecalc; + + +// -------------------------------------------------------------------------------------------------------------- // +// SendProp. +// -------------------------------------------------------------------------------------------------------------- // + +// If SendProp::GetDataTableProxyIndex() returns this, then the proxy is one that always sends +// the data to all clients, so we don't need to store the results. +#define DATATABLE_PROXY_INDEX_NOPROXY 255 +#define DATATABLE_PROXY_INDEX_INVALID 254 + +class SendProp +{ +public: + SendProp(); + virtual ~SendProp(); + + void Clear(); + + int GetOffset() const; + void SetOffset( int i ); + + SendVarProxyFn GetProxyFn() const; + void SetProxyFn( SendVarProxyFn f ); + + SendTableProxyFn GetDataTableProxyFn() const; + void SetDataTableProxyFn( SendTableProxyFn f ); + + SendTable* GetDataTable() const; + void SetDataTable( SendTable *pTable ); + + char const* GetExcludeDTName() const; + + // If it's one of the numbered "000", "001", etc properties in an array, then + // these can be used to get its array property name for debugging. + const char* GetParentArrayPropName() const; + void SetParentArrayPropName( char *pArrayPropName ); + + const char* GetName() const; + + bool IsSigned() const; + + bool IsExcludeProp() const; + + bool IsInsideArray() const; // Returns true if SPROP_INSIDEARRAY is set. + void SetInsideArray(); + + // Arrays only. + void SetArrayProp( SendProp *pProp ); + SendProp* GetArrayProp() const; + + // Arrays only. + void SetArrayLengthProxy( ArrayLengthSendProxyFn fn ); + ArrayLengthSendProxyFn GetArrayLengthProxy() const; + + int GetNumElements() const; + void SetNumElements( int nElements ); + + // Return the # of bits to encode an array length (must hold GetNumElements()). + int GetNumArrayLengthBits() const; + + int GetElementStride() const; + + SendPropType GetType() const; + + int GetFlags() const; + void SetFlags( int flags ); + + // Some property types bind more data to the SendProp in here. + const void* GetExtraData() const; + void SetExtraData( const void *pData ); + +public: + + RecvProp *m_pMatchingRecvProp; // This is temporary and only used while precalculating + // data for the decoders. + + SendPropType m_Type; + int m_nBits; + float m_fLowValue; + float m_fHighValue; + + SendProp *m_pArrayProp; // If this is an array, this is the property that defines each array element. + ArrayLengthSendProxyFn m_ArrayLengthProxy; // This callback returns the array length. + + int m_nElements; // Number of elements in the array (or 1 if it's not an array). + int m_ElementStride; // Pointer distance between array elements. + + const char *m_pExcludeDTName; // If this is an exclude prop, then this is the name of the datatable to exclude a prop from. + const char *m_pParentArrayPropName; + + const char *m_pVarName; + float m_fHighLowMul; + +private: + + int m_Flags; // SPROP_ flags. + + SendVarProxyFn m_ProxyFn; // NULL for DPT_DataTable. + SendTableProxyFn m_DataTableProxyFn; // Valid for DPT_DataTable. + + SendTable *m_pDataTable; + + // SENDPROP_VECTORELEM makes this negative to start with so we can detect that and + // set the SPROP_IS_VECTOR_ELEM flag. + int m_Offset; + + // Extra data bound to this property. + const void *m_pExtraData; +}; + + +inline int SendProp::GetOffset() const +{ + return m_Offset; +} + +inline void SendProp::SetOffset( int i ) +{ + m_Offset = i; +} + +inline SendVarProxyFn SendProp::GetProxyFn() const +{ + Assert( m_Type != DPT_DataTable ); + return m_ProxyFn; +} + +inline void SendProp::SetProxyFn( SendVarProxyFn f ) +{ + m_ProxyFn = f; +} + +inline SendTableProxyFn SendProp::GetDataTableProxyFn() const +{ + Assert( m_Type == DPT_DataTable ); + return m_DataTableProxyFn; +} + +inline void SendProp::SetDataTableProxyFn( SendTableProxyFn f ) +{ + m_DataTableProxyFn = f; +} + +inline SendTable* SendProp::GetDataTable() const +{ + return m_pDataTable; +} + +inline void SendProp::SetDataTable( SendTable *pTable ) +{ + m_pDataTable = pTable; +} + +inline char const* SendProp::GetExcludeDTName() const +{ + return m_pExcludeDTName; +} + +inline const char* SendProp::GetParentArrayPropName() const +{ + return m_pParentArrayPropName; +} + +inline void SendProp::SetParentArrayPropName( char *pArrayPropName ) +{ + Assert( !m_pParentArrayPropName ); + m_pParentArrayPropName = pArrayPropName; +} + +inline const char* SendProp::GetName() const +{ + return m_pVarName; +} + + +inline bool SendProp::IsSigned() const +{ + return !(m_Flags & SPROP_UNSIGNED); +} + +inline bool SendProp::IsExcludeProp() const +{ + return (m_Flags & SPROP_EXCLUDE) != 0; +} + +inline bool SendProp::IsInsideArray() const +{ + return (m_Flags & SPROP_INSIDEARRAY) != 0; +} + +inline void SendProp::SetInsideArray() +{ + m_Flags |= SPROP_INSIDEARRAY; +} + +inline void SendProp::SetArrayProp( SendProp *pProp ) +{ + m_pArrayProp = pProp; +} + +inline SendProp* SendProp::GetArrayProp() const +{ + return m_pArrayProp; +} + +inline void SendProp::SetArrayLengthProxy( ArrayLengthSendProxyFn fn ) +{ + m_ArrayLengthProxy = fn; +} + +inline ArrayLengthSendProxyFn SendProp::GetArrayLengthProxy() const +{ + return m_ArrayLengthProxy; +} + +inline int SendProp::GetNumElements() const +{ + return m_nElements; +} + +inline void SendProp::SetNumElements( int nElements ) +{ + m_nElements = nElements; +} + +inline int SendProp::GetElementStride() const +{ + return m_ElementStride; +} + +inline SendPropType SendProp::GetType() const +{ + return m_Type; +} + +inline int SendProp::GetFlags() const +{ + return m_Flags; +} + +inline void SendProp::SetFlags( int flags ) +{ + // Make sure they're using something from the valid set of flags. + Assert( !( flags & ~((1 << SPROP_NUMFLAGBITS) - 1) ) ); + m_Flags = flags; +} + +inline const void* SendProp::GetExtraData() const +{ + return m_pExtraData; +} + +inline void SendProp::SetExtraData( const void *pData ) +{ + m_pExtraData = pData; +} + + +// -------------------------------------------------------------------------------------------------------------- // +// SendTable. +// -------------------------------------------------------------------------------------------------------------- // + +class SendTable +{ +public: + + typedef SendProp PropType; + + SendTable(); + SendTable( SendProp *pProps, int nProps, const char *pNetTableName ); + ~SendTable(); + + void Construct( SendProp *pProps, int nProps, const char *pNetTableName ); + + const char* GetName() const; + + int GetNumProps() const; + SendProp* GetProp( int i ); + + // Used by the engine. + bool IsInitialized() const; + void SetInitialized( bool bInitialized ); + + // Used by the engine while writing info into the signon. + void SetWriteFlag(bool bHasBeenWritten); + bool GetWriteFlag() const; + + bool HasPropsEncodedAgainstTickCount() const; + void SetHasPropsEncodedAgainstTickcount( bool bState ); + +public: + + SendProp *m_pProps; + int m_nProps; + + const char *m_pNetTableName; // The name matched between client and server. + + // The engine hooks the SendTable here. + CSendTablePrecalc *m_pPrecalc; + + +protected: + bool m_bInitialized : 1; + bool m_bHasBeenWritten : 1; + bool m_bHasPropsEncodedAgainstCurrentTickCount : 1; // m_flSimulationTime and m_flAnimTime, e.g. +}; + + +inline const char* SendTable::GetName() const +{ + return m_pNetTableName; +} + + +inline int SendTable::GetNumProps() const +{ + return m_nProps; +} + + +inline SendProp* SendTable::GetProp( int i ) +{ + Assert( i >= 0 && i < m_nProps ); + return &m_pProps[i]; +} + + +inline bool SendTable::IsInitialized() const +{ + return m_bInitialized; +} + + +inline void SendTable::SetInitialized( bool bInitialized ) +{ + m_bInitialized = bInitialized; +} + + +inline bool SendTable::GetWriteFlag() const +{ + return m_bHasBeenWritten; +} + + +inline void SendTable::SetWriteFlag(bool bHasBeenWritten) +{ + m_bHasBeenWritten = bHasBeenWritten; +} + +inline bool SendTable::HasPropsEncodedAgainstTickCount() const +{ + return m_bHasPropsEncodedAgainstCurrentTickCount; +} + +inline void SendTable::SetHasPropsEncodedAgainstTickcount( bool bState ) +{ + m_bHasPropsEncodedAgainstCurrentTickCount = bState; +} + +// ------------------------------------------------------------------------------------------------------ // +// Use BEGIN_SEND_TABLE if you want to declare a SendTable and have it inherit all the properties from +// its base class. There are two requirements for this to work: + +// 1. Its base class must have a static SendTable pointer member variable called m_pClassSendTable which +// points to its send table. The DECLARE_SERVERCLASS and IMPLEMENT_SERVERCLASS macros do this automatically. + +// 2. Your class must typedef its base class as BaseClass. So it would look like this: +// class Derived : public CBaseEntity +// { +// typedef CBaseEntity BaseClass; +// }; + +// If you don't want to interit a base class's properties, use BEGIN_SEND_TABLE_NOBASE. +// ------------------------------------------------------------------------------------------------------ // +#define BEGIN_SEND_TABLE(className, tableName) \ + BEGIN_SEND_TABLE_NOBASE(className, tableName) \ + SendPropDataTable("baseclass", 0, className::BaseClass::m_pClassSendTable, SendProxy_DataTableToDataTable), + +#define BEGIN_SEND_TABLE_NOBASE(className, tableName) \ + template int ServerClassInit(T *); \ + namespace tableName { \ + struct ignored; \ + } \ + template <> int ServerClassInit(tableName::ignored *); \ + namespace tableName { \ + SendTable g_SendTable;\ + int g_SendTableInit = ServerClassInit((tableName::ignored *)NULL); \ + } \ + template <> int ServerClassInit(tableName::ignored *) \ + { \ + typedef className currentSendDTClass; \ + static const char *g_pSendTableName = #tableName; \ + SendTable &sendTable = tableName::g_SendTable; \ + static SendProp g_SendProps[] = { \ + SendPropInt("should_never_see_this", 0, sizeof(int)), // It adds a dummy property at the start so you can define "empty" SendTables. + +#define END_SEND_TABLE() \ + };\ + sendTable.Construct(g_SendProps+1, sizeof(g_SendProps) / sizeof(SendProp) - 1, g_pSendTableName);\ + return 1; \ + } + + +// These can simplify creating the variables. +// Note: currentSendDTClass::MakeANetworkVar_##varName equates to currentSendDTClass. It's +// there as a check to make sure all networked variables use the CNetworkXXXX macros in network_var.h. +#define SENDINFO(varName) #varName, offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName), sizeof(((currentSendDTClass*)0)->varName) +#define SENDINFO_ARRAY(varName) #varName, offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName), sizeof(((currentSendDTClass*)0)->varName[0]) +#define SENDINFO_ARRAY3(varName) #varName, offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName), sizeof(((currentSendDTClass*)0)->varName[0]), sizeof(((currentSendDTClass*)0)->varName)/sizeof(((currentSendDTClass*)0)->varName[0]) +#define SENDINFO_ARRAYELEM(varName, i) #varName "[" #i "]", offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName[i]), sizeof(((currentSendDTClass*)0)->varName[0]) +#define SENDINFO_NETWORKARRAYELEM(varName, i)#varName "[" #i "]", offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName.m_Value[i]), sizeof(((currentSendDTClass*)0)->varName.m_Value[0]) + +// NOTE: Be VERY careful to specify any other vector elems for the same vector IN ORDER and +// right after each other, otherwise it might miss the Y or Z component in SP. +// +// Note: this macro specifies a negative offset so the engine can detect it and setup m_pNext +#define SENDINFO_VECTORELEM(varName, i) #varName "[" #i "]", -(int)offsetof(currentSendDTClass::MakeANetworkVar_##varName, varName.m_Value[i]), sizeof(((currentSendDTClass*)0)->varName.m_Value[0]) + +#define SENDINFO_STRUCTELEM(varName) #varName, offsetof(currentSendDTClass, varName), sizeof(((currentSendDTClass*)0)->varName.m_Value) +#define SENDINFO_STRUCTARRAYELEM(varName, i)#varName "[" #i "]", offsetof(currentSendDTClass, varName.m_Value[i]), sizeof(((currentSendDTClass*)0)->varName.m_Value[0]) + +// Use this when you're not using a CNetworkVar to represent the data you're sending. +#define SENDINFO_NOCHECK(varName) #varName, offsetof(currentSendDTClass, varName), sizeof(((currentSendDTClass*)0)->varName) +#define SENDINFO_STRING_NOCHECK(varName) #varName, offsetof(currentSendDTClass, varName) +#define SENDINFO_DT(varName) #varName, offsetof(currentSendDTClass, varName) +#define SENDINFO_DT_NAME(varName, remoteVarName) #remoteVarName, offsetof(currentSendDTClass, varName) +#define SENDINFO_NAME(varName,remoteVarName) #remoteVarName, offsetof(currentSendDTClass, varName), sizeof(((currentSendDTClass*)0)->varName) + + + + +// ------------------------------------------------------------------------ // +// Built-in proxy types. +// See the definition of SendVarProxyFn for information about these. +// ------------------------------------------------------------------------ // +void SendProxy_QAngles ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID ); +void SendProxy_AngleToFloat ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID ); +void SendProxy_FloatToFloat ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID ); +void SendProxy_VectorToVector ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID ); +void SendProxy_VectorXYToVectorXY( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID ); +#if 0 // We can't ship this since it changes the size of DTVariant to be 20 bytes instead of 16 and that breaks MODs!!! +void SendProxy_QuaternionToQuaternion( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID ); +#endif + +void SendProxy_Int8ToInt32 ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID ); +void SendProxy_Int16ToInt32 ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID ); +void SendProxy_Int32ToInt32 ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID ); +#ifdef SUPPORTS_INT64 +void SendProxy_Int64ToInt64 ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID ); +#endif +void SendProxy_StringToString ( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID ); + +// pData is the address of a data table. +void* SendProxy_DataTableToDataTable( const SendProp *pProp, const void *pStructBase, const void *pData, CSendProxyRecipients *pRecipients, int objectID ); + +// pData is the address of a pointer to a data table. +void* SendProxy_DataTablePtrToDataTable( const SendProp *pProp, const void *pStructBase, const void *pData, CSendProxyRecipients *pRecipients, int objectID ); + +// Used on player entities - only sends the data to the local player (objectID-1). +void* SendProxy_SendLocalDataTable( const SendProp *pProp, const void *pStruct, const void *pVarData, CSendProxyRecipients *pRecipients, int objectID ); + + +// ------------------------------------------------------------------------ // +// Use these functions to setup your data tables. +// ------------------------------------------------------------------------ // +SendProp SendPropFloat( + const char *pVarName, // Variable name. + int offset, // Offset into container structure. + int sizeofVar=SIZEOF_IGNORE, + int nBits=32, // Number of bits to use when encoding. + int flags=0, + float fLowValue=0.0f, // For floating point, low and high values. + float fHighValue=HIGH_DEFAULT, // High value. If HIGH_DEFAULT, it's (1<arrayName) / PROPSIZEOF(currentSendDTClass, arrayName[0]), \ + PROPSIZEOF(currentSendDTClass, arrayName[0]), \ + #arrayName, \ + arrayLengthSendProxy \ + ) + +// Use this one to specify the element count and stride manually. +#define SendPropArray2( arrayLengthSendProxy, varTemplate, elementCount, elementStride, arrayName ) \ + varTemplate, \ + InternalSendPropArray( elementCount, elementStride, #arrayName, arrayLengthSendProxy ) + + + + +// Use these to create properties that exclude other properties. This is useful if you want to use most of +// a base class's datatable data, but you want to override some of its variables. +SendProp SendPropExclude( + const char *pDataTableName, // Data table name (given to BEGIN_SEND_TABLE and BEGIN_RECV_TABLE). + const char *pPropName // Name of the property to exclude. + ); + + +#endif // DATATABLE_SEND_H diff --git a/sp/src/public/dt_shared.cpp b/sp/src/public/dt_shared.cpp new file mode 100644 index 00000000..3508d214 --- /dev/null +++ b/sp/src/public/dt_shared.cpp @@ -0,0 +1,113 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "dt_shared.h" + +#if !defined (CLIENT_DLL) +#include "sendproxy.h" +#else +#include "recvproxy.h" +#endif + + +// ------------------------------------------------------------------------ // +// Just wrappers to make shared code look easier... +// ------------------------------------------------------------------------ // + +// Use these functions to setup your data tables. +DataTableProp PropFloat( + char *pVarName, // Variable name. + int offset, // Offset into container structure. + int sizeofVar, + int nBits, // Number of bits to use when encoding. + int flags, + float fLowValue, // For floating point, low and high values. + float fHighValue // High value. If HIGH_DEFAULT, it's (1< *g_STDict = 0; +static CUtlDict *g_RTDict = 0; + + +char* AllocateStringHelper2( const char *pFormat, va_list marker ) +{ + char str[512]; + _vsnprintf( str, sizeof( str ), pFormat, marker ); + str[ ARRAYSIZE(str) - 1 ] = 0; + + int len = strlen( str ) + 1; + char *pRet = new char[len]; + memcpy( pRet, str, len ); + + return pRet; +} + + +char* AllocateStringHelper( const char *pFormat, ... ) +{ + va_list marker; + va_start( marker, pFormat ); + char *pRet = AllocateStringHelper2( pFormat, marker ); + va_end( marker ); + + return pRet; +} + + +char* AllocateUniqueDataTableName( bool bSendTable, const char *pFormat, ... ) +{ + // Setup the string. + va_list marker; + va_start( marker, pFormat ); + char *pRet = AllocateStringHelper2( pFormat, marker ); + va_end( marker ); + + // Make sure it's unique. +#ifdef _DEBUG + // Have to allocate them here because if they're declared as straight global variables, + // their constructors won't have been called yet by the time we get in here. + if ( !g_STDict ) + { + g_STDict = new CUtlDict; + g_RTDict = new CUtlDict; + } + + CUtlDict *pDict = bSendTable ? g_STDict : g_RTDict; + if ( pDict->Find( pRet ) != pDict->InvalidIndex() ) + { + // If it hits this, then they have 2 utlvectors in different data tables with the same name and the + // same size limit. The names of + Assert( false ); + } + pDict->Insert( pRet, 0 ); +#endif + + return pRet; +} diff --git a/sp/src/public/dt_utlvector_common.h b/sp/src/public/dt_utlvector_common.h new file mode 100644 index 00000000..681ce046 --- /dev/null +++ b/sp/src/public/dt_utlvector_common.h @@ -0,0 +1,85 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef DT_UTLVECTOR_COMMON_H +#define DT_UTLVECTOR_COMMON_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "utlvector.h" + + +typedef void (*EnsureCapacityFn)( void *pVoid, int offsetToUtlVector, int len ); +typedef void (*ResizeUtlVectorFn)( void *pVoid, int offsetToUtlVector, int len ); + +template< class T > +void UtlVector_InitializeAllocatedElements( T *pBase, int count ) +{ + memset( reinterpret_cast( pBase ), 0, count * sizeof( T ) ); +} + +template< class T, class A > +class UtlVectorTemplate +{ +public: + static void ResizeUtlVector( void *pStruct, int offsetToUtlVector, int len ) + { + CUtlVector *pVec = (CUtlVector*)((char*)pStruct + offsetToUtlVector); + if ( pVec->Count() < len ) + pVec->AddMultipleToTail( len - pVec->Count() ); + else if ( pVec->Count() > len ) + pVec->RemoveMultiple( len, pVec->Count()-len ); + + // Ensure capacity + pVec->EnsureCapacity( len ); + + int nNumAllocated = pVec->NumAllocated(); + + // This is important to do because EnsureCapacity doesn't actually call the constructors + // on the elements, but we need them to be initialized, otherwise it'll have out-of-range + // values which will piss off the datatable encoder. + UtlVector_InitializeAllocatedElements( pVec->Base() + pVec->Count(), nNumAllocated - pVec->Count() ); + } + + static void EnsureCapacity( void *pStruct, int offsetToUtlVector, int len ) + { + CUtlVector *pVec = (CUtlVector*)((char*)pStruct + offsetToUtlVector); + + pVec->EnsureCapacity( len ); + + int nNumAllocated = pVec->NumAllocated(); + + // This is important to do because EnsureCapacity doesn't actually call the constructors + // on the elements, but we need them to be initialized, otherwise it'll have out-of-range + // values which will piss off the datatable encoder. + UtlVector_InitializeAllocatedElements( pVec->Base() + pVec->Count(), nNumAllocated - pVec->Count() ); + } +}; + +template< class T, class A > +inline ResizeUtlVectorFn GetResizeUtlVectorTemplate( CUtlVector &vec ) +{ + return &UtlVectorTemplate::ResizeUtlVector; +} + +template< class T, class A > +inline EnsureCapacityFn GetEnsureCapacityTemplate( CUtlVector &vec ) +{ + return &UtlVectorTemplate::EnsureCapacity; +} + + +// Format and allocate a string. +char* AllocateStringHelper( PRINTF_FORMAT_STRING const char *pFormat, ... ); + +// Allocates a string for a data table name. Data table names must be unique, so this will +// assert if you try to allocate a duplicate. +char* AllocateUniqueDataTableName( bool bSendTable, PRINTF_FORMAT_STRING const char *pFormat, ... ); + + +#endif // DT_UTLVECTOR_COMMON_H diff --git a/sp/src/public/dt_utlvector_recv.cpp b/sp/src/public/dt_utlvector_recv.cpp new file mode 100644 index 00000000..7fa86fdc --- /dev/null +++ b/sp/src/public/dt_utlvector_recv.cpp @@ -0,0 +1,157 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "dt_utlvector_recv.h" + +#include "tier0/memdbgon.h" + + +extern const char *s_ClientElementNames[MAX_ARRAY_ELEMENTS]; + + +class CRecvPropExtra_UtlVector +{ +public: + DataTableRecvVarProxyFn m_DataTableProxyFn; // If it's a datatable, then this is the proxy they specified. + RecvVarProxyFn m_ProxyFn; // If it's a non-datatable, then this is the proxy they specified. + ResizeUtlVectorFn m_ResizeFn; // The function used to resize the CUtlVector. + EnsureCapacityFn m_EnsureCapacityFn; + int m_ElementStride; // Distance between each element in the array. + int m_Offset; // Offset of the CUtlVector from its parent structure. + int m_nMaxElements; // For debugging... +}; + +void RecvProxy_UtlVectorLength( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + CRecvPropExtra_UtlVector *pExtra = (CRecvPropExtra_UtlVector*)pData->m_pRecvProp->GetExtraData(); + pExtra->m_ResizeFn( pStruct, pExtra->m_Offset, pData->m_Value.m_Int ); +} + +void RecvProxy_UtlVectorElement( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + CRecvPropExtra_UtlVector *pExtra = (CRecvPropExtra_UtlVector*)pData->m_pRecvProp->GetExtraData(); + + // Kind of lame overloading element stride to hold the element index, + // but we can easily move it into its SetExtraData stuff if we need to. + int iElement = pData->m_pRecvProp->GetElementStride(); + + // NOTE: this is cheesy, but it does the trick. + CUtlVector *pUtlVec = (CUtlVector*)((char*)pStruct + pExtra->m_Offset); + + // Call through to the proxy they passed in, making pStruct=the CUtlVector. + // Note: there should be space here as long as the element is < the max # elements + // that we ensured capacity for in DataTableRecvProxy_LengthProxy. + pExtra->m_ProxyFn( pData, pOut, (char*)pUtlVec->Base() + iElement*pExtra->m_ElementStride ); +} + +void RecvProxy_UtlVectorElement_DataTable( const RecvProp *pProp, void **pOut, void *pData, int objectID ) +{ + CRecvPropExtra_UtlVector *pExtra = (CRecvPropExtra_UtlVector*)pProp->GetExtraData(); + + int iElement = pProp->GetElementStride(); + Assert( iElement < pExtra->m_nMaxElements ); + + // NOTE: this is cheesy, but it does the trick. + CUtlVector *pUtlVec = (CUtlVector*)((char*)pData + pExtra->m_Offset); + + // Call through to the proxy they passed in, making pStruct=the CUtlVector and forcing iElement to 0. + pExtra->m_DataTableProxyFn( pProp, pOut, (char*)pUtlVec->Base() + iElement*pExtra->m_ElementStride, objectID ); +} + + +void DataTableRecvProxy_LengthProxy( const RecvProp *pProp, void **pOut, void *pData, int objectID ) +{ + // This is VERY important - since it calls all the datatable proxies in the tree first, + // particularly BEFORE it calls our array length proxy, we need to make sure we return + // valid pointers that aren't going to change when it starts to copy the data into + // the datatable elements. + CRecvPropExtra_UtlVector *pExtra = (CRecvPropExtra_UtlVector*)pProp->GetExtraData(); + pExtra->m_EnsureCapacityFn( pData, pExtra->m_Offset, pExtra->m_nMaxElements ); + + *pOut = pData; +} + + +RecvProp RecvPropUtlVector( + const char *pVarName, // Use RECVINFO_UTLVECTOR to generate these 4. + int offset, // Used to generate pData in the function specified in varProxy. + int sizeofVar, // The size of each element in the utlvector. + ResizeUtlVectorFn fn, + EnsureCapacityFn ensureFn, + int nMaxElements, // Max # of elements in the array. Keep this as low as possible. + RecvProp pArrayProp + ) +{ + RecvProp ret; + + Assert( nMaxElements <= MAX_ARRAY_ELEMENTS ); + + ret.m_RecvType = DPT_DataTable; + ret.m_pVarName = pVarName; + ret.SetOffset( 0 ); + ret.SetDataTableProxyFn( DataTableRecvProxy_StaticDataTable ); + + RecvProp *pProps = new RecvProp[nMaxElements+1]; // TODO free that again + + + // Extra data bound to each of the properties. + CRecvPropExtra_UtlVector *pExtraData = new CRecvPropExtra_UtlVector; + + pExtraData->m_nMaxElements = nMaxElements; + pExtraData->m_ElementStride = sizeofVar; + pExtraData->m_ResizeFn = fn; + pExtraData->m_EnsureCapacityFn = ensureFn; + pExtraData->m_Offset = offset; + + if ( pArrayProp.m_RecvType == DPT_DataTable ) + pExtraData->m_DataTableProxyFn = pArrayProp.GetDataTableProxyFn(); + else + pExtraData->m_ProxyFn = pArrayProp.GetProxyFn(); + + + // The first property is datatable with an int that tells the length of the array. + // It has to go in a datatable, otherwise if this array holds datatable properties, it will be received last. + RecvProp *pLengthProp = new RecvProp; + *pLengthProp = RecvPropInt( AllocateStringHelper( "lengthprop%d", nMaxElements ), 0, 0, 0, RecvProxy_UtlVectorLength ); + pLengthProp->SetExtraData( pExtraData ); + + char *pLengthProxyTableName = AllocateUniqueDataTableName( false, "_LPT_%s_%d", pVarName, nMaxElements ); + RecvTable *pLengthTable = new RecvTable( pLengthProp, 1, pLengthProxyTableName ); + pProps[0] = RecvPropDataTable( "lengthproxy", 0, 0, pLengthTable, DataTableRecvProxy_LengthProxy ); + pProps[0].SetExtraData( pExtraData ); + + // The first element is a sub-datatable. + for ( int i = 1; i < nMaxElements+1; i++ ) + { + pProps[i] = pArrayProp; // copy array element property setting + pProps[i].SetOffset( 0 ); // leave offset at 0 so pStructBase is always a pointer to the CUtlVector + pProps[i].m_pVarName = s_ClientElementNames[i-1]; // give unique name + pProps[i].SetExtraData( pExtraData ); + pProps[i].SetElementStride( i-1 ); // Kind of lame overloading element stride to hold the element index, + // but we can easily move it into its SetExtraData stuff if we need to. + + // We provide our own proxy here. + if ( pArrayProp.m_RecvType == DPT_DataTable ) + { + pProps[i].SetDataTableProxyFn( RecvProxy_UtlVectorElement_DataTable ); + } + else + { + pProps[i].SetProxyFn( RecvProxy_UtlVectorElement ); + } + } + + RecvTable *pTable = new RecvTable( + pProps, + nMaxElements+1, + AllocateUniqueDataTableName( false, "_ST_%s_%d", pVarName, nMaxElements ) + ); // TODO free that again + + ret.SetDataTable( pTable ); + return ret; +} diff --git a/sp/src/public/dt_utlvector_recv.h b/sp/src/public/dt_utlvector_recv.h new file mode 100644 index 00000000..6b27057a --- /dev/null +++ b/sp/src/public/dt_utlvector_recv.h @@ -0,0 +1,60 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Player for HL1. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef DT_UTLVECTOR_RECV_H +#define DT_UTLVECTOR_RECV_H +#pragma once + + +#include "dt_recv.h" +#include "dt_utlvector_common.h" + + + +#define RECVINFO_UTLVECTOR( varName ) #varName, \ + offsetof(currentRecvDTClass, varName), \ + sizeof(((currentRecvDTClass*)0)->varName[0]), \ + GetResizeUtlVectorTemplate( ((currentRecvDTClass*)0)->varName ), \ + GetEnsureCapacityTemplate( ((currentRecvDTClass*)0)->varName ) + +// Use this macro to specify a utlvector where you specify the function +// that gets called to make sure the size of the utlvector is correct. +// The size function looks like this: void ResizeUtlVector( void *pVoid, int len ) +#define RECVINFO_UTLVECTOR_SIZEFN( varName, resizeFn ) #varName, \ + offsetof(currentRecvDTClass, varName), \ + sizeof(((currentRecvDTClass*)0)->varName[0]), \ + resizeFn, \ + GetEnsureCapacityTemplate( ((currentRecvDTClass*)0)->varName ) + + +#define RecvPropUtlVectorDataTable( varName, nMaxElements, dataTableName ) \ + RecvPropUtlVector( RECVINFO_UTLVECTOR( varName ), nMaxElements, RecvPropDataTable(NULL,0,0, &REFERENCE_RECV_TABLE( dataTableName ) ) ) + + +// +// Receive a property sent with SendPropUtlVector. +// +// Example usage: +// +// RecvPropUtlVectorDataTable( m_StructArray, 11, DT_StructArray ) +// +// RecvPropUtlVector( RECVINFO_UTLVECTOR( m_FloatArray ), 16, RecvPropFloat(NULL,0,0) ) +// +RecvProp RecvPropUtlVector( + const char *pVarName, // Use RECVINFO_UTLVECTOR to generate these first 5 parameters. + int offset, + int sizeofVar, + ResizeUtlVectorFn fn, + EnsureCapacityFn ensureFn, + + int nMaxElements, // Max # of elements in the array. Keep this as low as possible. + RecvProp pArrayProp // The definition of the property you're receiving into. + // You can leave all of its parameters at 0 (name, offset, size, etc). + ); + + +#endif // DT_UTLVECTOR_RECV_H diff --git a/sp/src/public/dt_utlvector_send.cpp b/sp/src/public/dt_utlvector_send.cpp new file mode 100644 index 00000000..b10170de --- /dev/null +++ b/sp/src/public/dt_utlvector_send.cpp @@ -0,0 +1,224 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "dt_utlvector_send.h" + +#include "tier0/memdbgon.h" + + +extern const char *s_ElementNames[MAX_ARRAY_ELEMENTS]; + +// This gets associated with SendProps inside a utlvector and stores extra data needed to make it work. +class CSendPropExtra_UtlVector +{ +public: + CSendPropExtra_UtlVector() : + m_DataTableProxyFn( NULL ), + m_ProxyFn( NULL ), + m_EnsureCapacityFn( NULL ), + m_ElementStride( 0 ), + m_Offset( 0 ), + m_nMaxElements( 0 ) + { + } + + SendTableProxyFn m_DataTableProxyFn; // If it's a datatable, then this is the proxy they specified. + SendVarProxyFn m_ProxyFn; // If it's a non-datatable, then this is the proxy they specified. + EnsureCapacityFn m_EnsureCapacityFn; + int m_ElementStride; // Distance between each element in the array. + int m_Offset; // # bytes from the parent structure to its utlvector. + int m_nMaxElements; // For debugging... +}; + + +void SendProxy_UtlVectorElement( + const SendProp *pProp, + const void *pStruct, + const void *pData, + DVariant *pOut, + int iElement, + int objectID ) +{ + CSendPropExtra_UtlVector *pExtra = (CSendPropExtra_UtlVector*)pProp->GetExtraData(); + Assert( pExtra ); + + // Kind of lame overloading element stride to hold the element index, + // but we can easily move it into its SetExtraData stuff if we need to. + iElement = pProp->GetElementStride(); + + // NOTE: this is cheesy, but it does the trick. + CUtlVector *pUtlVec = (CUtlVector*)((char*)pStruct + pExtra->m_Offset); + if ( iElement >= pUtlVec->Count() ) + { + // Pass in zero value. + memset( pOut, 0, sizeof( *pOut ) ); + } + else + { + // Call through to the proxy they passed in, making pStruct=the CUtlVector and forcing iElement to 0. + pExtra->m_ProxyFn( pProp, pData, (char*)pUtlVec->Base() + iElement*pExtra->m_ElementStride, pOut, 0, objectID ); + } +} + +void* SendProxy_UtlVectorElement_DataTable( + const SendProp *pProp, + const void *pStructBase, + const void *pData, + CSendProxyRecipients *pRecipients, + int objectID ) +{ + CSendPropExtra_UtlVector *pExtra = (CSendPropExtra_UtlVector*)pProp->GetExtraData(); + + int iElement = pProp->m_ElementStride; + Assert( iElement < pExtra->m_nMaxElements ); + + // This should have gotten called in SendProxy_LengthTable before we get here, so + // the capacity should be correct. +#ifdef _DEBUG + pExtra->m_EnsureCapacityFn( (void*)pStructBase, pExtra->m_Offset, pExtra->m_nMaxElements ); +#endif + + // NOTE: this is cheesy because we're assuming the type of the template class, but it does the trick. + CUtlVector *pUtlVec = (CUtlVector*)((char*)pStructBase + pExtra->m_Offset); + + // Call through to the proxy they passed in, making pStruct=the CUtlVector and forcing iElement to 0. + return pExtra->m_DataTableProxyFn( pProp, pData, (char*)pUtlVec->Base() + iElement*pExtra->m_ElementStride, pRecipients, objectID ); +} + +void SendProxy_UtlVectorLength( + const SendProp *pProp, + const void *pStruct, + const void *pData, + DVariant *pOut, + int iElement, + int objectID ) +{ + CSendPropExtra_UtlVector *pExtra = (CSendPropExtra_UtlVector*)pProp->GetExtraData(); + + // NOTE: this is cheesy because we're assuming the type of the template class, but it does the trick. + CUtlVector *pUtlVec = (CUtlVector*)((char*)pStruct + pExtra->m_Offset); + + // Don't let them overflow the buffer because they might expect that to get transmitted to the client. + pOut->m_Int = pUtlVec->Count(); + if ( pOut->m_Int > pExtra->m_nMaxElements ) + { + Assert( false ); + pOut->m_Int = pExtra->m_nMaxElements; + } +} + + +void* SendProxy_LengthTable( const SendProp *pProp, const void *pStructBase, const void *pData, CSendProxyRecipients *pRecipients, int objectID ) +{ + // Make sure the array has space to hold all the elements. + CSendPropExtra_UtlVector *pExtra = (CSendPropExtra_UtlVector*)pProp->GetExtraData(); + pExtra->m_EnsureCapacityFn( (void*)pStructBase, pExtra->m_Offset, pExtra->m_nMaxElements ); + return (void*)pData; +} + + +// Note: your pArrayProp will NOT get iElement set to anything other than 0, because this function installs its +// own proxy in front of yours. pStruct will point at the CUtlVector and pData will point at the element in the CUtlVector.It will pass you the direct pointer to the element inside the CUtlVector. +// +// You can skip the first 3 parameters in pArrayProp because they're ignored. So your array specification +// could look like this: +// SendPropUtlVector( +// SENDINFO_UTLVECTOR( m_FloatArray ), +// SendPropFloat( NULL, 0, 0, 0 [# bits], SPROP_NOSCALE [flags] ) ); +// +// Note: you have to be DILIGENT about calling NetworkStateChanged whenever an element in your CUtlVector changes +// since CUtlVector doesn't do this automatically. +SendProp SendPropUtlVector( + char *pVarName, // Use SENDINFO_UTLVECTOR to generate these 4. + int offset, // Used to generate pData in the function specified in varProxy. + int sizeofVar, // The size of each element in the utlvector. + EnsureCapacityFn ensureFn, // This is the value returned for elements out of the array's current range. + int nMaxElements, // Max # of elements in the array. Keep this as low as possible. + SendProp pArrayProp, // Describe the data inside of each element in the array. + SendTableProxyFn varProxy // This can be overridden to control who the array is sent to. + ) +{ + SendProp ret; + + Assert( nMaxElements <= MAX_ARRAY_ELEMENTS ); + + ret.m_Type = DPT_DataTable; + ret.m_pVarName = pVarName; + ret.SetOffset( 0 ); + ret.SetDataTableProxyFn( varProxy ); + + // Handle special proxy types where they always let all clients get the results. + if ( varProxy == SendProxy_DataTableToDataTable || varProxy == SendProxy_DataTablePtrToDataTable ) + { + ret.SetFlags( SPROP_PROXY_ALWAYS_YES ); + } + + + // Extra data bound to each of the properties. + CSendPropExtra_UtlVector *pExtraData = new CSendPropExtra_UtlVector; + + pExtraData->m_nMaxElements = nMaxElements; + pExtraData->m_ElementStride = sizeofVar; + pExtraData->m_EnsureCapacityFn = ensureFn; + pExtraData->m_Offset = offset; + + if ( pArrayProp.m_Type == DPT_DataTable ) + pExtraData->m_DataTableProxyFn = pArrayProp.GetDataTableProxyFn(); + else + pExtraData->m_ProxyFn = pArrayProp.GetProxyFn(); + + + SendProp *pProps = new SendProp[nMaxElements+1]; // TODO free that again + + // The first property is datatable with an int that tells the length of the array. + // It has to go in a datatable, otherwise if this array holds datatable properties, it will be received last. + SendProp *pLengthProp = new SendProp; + *pLengthProp = SendPropInt( AllocateStringHelper( "lengthprop%d", nMaxElements ), 0, 0, NumBitsForCount( nMaxElements ), SPROP_UNSIGNED, SendProxy_UtlVectorLength ); + pLengthProp->SetExtraData( pExtraData ); + + char *pLengthProxyTableName = AllocateUniqueDataTableName( true, "_LPT_%s_%d", pVarName, nMaxElements ); + SendTable *pLengthTable = new SendTable( pLengthProp, 1, pLengthProxyTableName ); + pProps[0] = SendPropDataTable( "lengthproxy", 0, pLengthTable, SendProxy_LengthTable ); + pProps[0].SetExtraData( pExtraData ); + + // TERROR: + char *pParentArrayPropName = AllocateStringHelper( "%s", pVarName ); + Assert( pParentArrayPropName && *pParentArrayPropName ); // TERROR + + // The first element is a sub-datatable. + for ( int i = 1; i < nMaxElements+1; i++ ) + { + pProps[i] = pArrayProp; // copy array element property setting + pProps[i].SetOffset( 0 ); // leave offset at 0 so pStructBase is always a pointer to the CUtlVector + pProps[i].m_pVarName = s_ElementNames[i-1]; // give unique name + pProps[i].m_pParentArrayPropName = pParentArrayPropName; // TERROR: For debugging... + pProps[i].SetExtraData( pExtraData ); + pProps[i].m_ElementStride = i-1; // Kind of lame overloading element stride to hold the element index, + // but we can easily move it into its SetExtraData stuff if we need to. + + // We provide our own proxy here. + if ( pArrayProp.m_Type == DPT_DataTable ) + { + pProps[i].SetDataTableProxyFn( SendProxy_UtlVectorElement_DataTable ); + pProps[i].SetFlags( SPROP_PROXY_ALWAYS_YES ); + } + else + { + pProps[i].SetProxyFn( SendProxy_UtlVectorElement ); + } + } + + SendTable *pTable = new SendTable( + pProps, + nMaxElements+1, + AllocateUniqueDataTableName( true, "_ST_%s_%d", pVarName, nMaxElements ) + ); + + ret.SetDataTable( pTable ); + return ret; +} diff --git a/sp/src/public/dt_utlvector_send.h b/sp/src/public/dt_utlvector_send.h new file mode 100644 index 00000000..f2ba68c3 --- /dev/null +++ b/sp/src/public/dt_utlvector_send.h @@ -0,0 +1,57 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Player for HL1. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef DT_UTLVECTOR_SEND_H +#define DT_UTLVECTOR_SEND_H +#pragma once + + +#include "dt_send.h" +#include "dt_utlvector_common.h" + + +#define SENDINFO_UTLVECTOR( varName ) #varName, \ + offsetof(currentSendDTClass, varName), \ + sizeof(((currentSendDTClass*)0)->varName[0]), \ + GetEnsureCapacityTemplate( ((currentSendDTClass*)0)->varName ) + + + +#define SendPropUtlVectorDataTable( varName, nMaxElements, dataTableName ) \ + SendPropUtlVector( \ + SENDINFO_UTLVECTOR( varName ), \ + nMaxElements, \ + SendPropDataTable( NULL, 0, &REFERENCE_SEND_TABLE( dataTableName ) ) \ + ) + +// +// Set it up to transmit a CUtlVector of basic types or of structures. +// +// pArrayProp doesn't need a name, offset, or size. You can pass 0 for all those. +// Example usage: +// +// SendPropUtlVectorDataTable( m_StructArray, 11, DT_TestStruct ) +// +// SendPropUtlVector( +// SENDINFO_UTLVECTOR( m_FloatArray ), +// 16, // max elements +// SendPropFloat( NULL, 0, 0, 0, SPROP_NOSCALE ) +// ) +// +SendProp SendPropUtlVector( + char *pVarName, // Use SENDINFO_UTLVECTOR to generate these first 4 parameters. + int offset, + int sizeofVar, + EnsureCapacityFn ensureFn, + + int nMaxElements, // Max # of elements in the array. Keep this as low as possible. + SendProp pArrayProp, // Describe the data inside of each element in the array. + SendTableProxyFn varProxy=SendProxy_DataTableToDataTable // This can be overridden to control who the array is sent to. + ); + + +#endif // DT_UTLVECTOR_SEND_H diff --git a/sp/src/public/edict.h b/sp/src/public/edict.h new file mode 100644 index 00000000..67c558cd --- /dev/null +++ b/sp/src/public/edict.h @@ -0,0 +1,446 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef EDICT_H +#define EDICT_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "mathlib/vector.h" +#include "cmodel.h" +#include "const.h" +#include "iserverentity.h" +#include "globalvars_base.h" +#include "engine/ICollideable.h" +#include "iservernetworkable.h" +#include "bitvec.h" + +struct edict_t; + + +//----------------------------------------------------------------------------- +// Purpose: Defines the ways that a map can be loaded. +//----------------------------------------------------------------------------- +enum MapLoadType_t +{ + MapLoad_NewGame = 0, + MapLoad_LoadGame, + MapLoad_Transition, + MapLoad_Background, +}; + + +//----------------------------------------------------------------------------- +// Purpose: Global variables shared between the engine and the game .dll +//----------------------------------------------------------------------------- +class CGlobalVars : public CGlobalVarsBase +{ +public: + + CGlobalVars( bool bIsClient ); + +public: + + // Current map + string_t mapname; + int mapversion; + string_t startspot; + MapLoadType_t eLoadType; // How the current map was loaded + bool bMapLoadFailed; // Map has failed to load, we need to kick back to the main menu + + // game specific flags + bool deathmatch; + bool coop; + bool teamplay; + // current maxentities + int maxEntities; + + int serverCount; +}; + +inline CGlobalVars::CGlobalVars( bool bIsClient ) : + CGlobalVarsBase( bIsClient ) +{ + serverCount = 0; +} + + +class CPlayerState; +class IServerNetworkable; +class IServerEntity; + + +#define FL_EDICT_CHANGED (1<<0) // Game DLL sets this when the entity state changes + // Mutually exclusive with FL_EDICT_PARTIAL_CHANGE. + +#define FL_EDICT_FREE (1<<1) // this edict if free for reuse +#define FL_EDICT_FULL (1<<2) // this is a full server entity + +#define FL_EDICT_FULLCHECK (0<<0) // call ShouldTransmit() each time, this is a fake flag +#define FL_EDICT_ALWAYS (1<<3) // always transmit this entity +#define FL_EDICT_DONTSEND (1<<4) // don't transmit this entity +#define FL_EDICT_PVSCHECK (1<<5) // always transmit entity, but cull against PVS + +// Used by local network backdoor. +#define FL_EDICT_PENDING_DORMANT_CHECK (1<<6) + +// This is always set at the same time EFL_DIRTY_PVS_INFORMATION is set, but it +// gets cleared in a different place. +#define FL_EDICT_DIRTY_PVS_INFORMATION (1<<7) + +// This is used internally to edict_t to remember that it's carrying a +// "full change list" - all its properties might have changed their value. +#define FL_FULL_EDICT_CHANGED (1<<8) + + +// Max # of variable changes we'll track in an entity before we treat it +// like they all changed. +#define MAX_CHANGE_OFFSETS 19 +#define MAX_EDICT_CHANGE_INFOS 100 + + +class CEdictChangeInfo +{ +public: + // Edicts remember the offsets of properties that change + unsigned short m_ChangeOffsets[MAX_CHANGE_OFFSETS]; + unsigned short m_nChangeOffsets; +}; + +// Shared between engine and game DLL. +class CSharedEdictChangeInfo +{ +public: + CSharedEdictChangeInfo() + { + m_iSerialNumber = 1; + } + + // Matched against edict_t::m_iChangeInfoSerialNumber to determine if its + // change info is valid. + unsigned short m_iSerialNumber; + + CEdictChangeInfo m_ChangeInfos[MAX_EDICT_CHANGE_INFOS]; + unsigned short m_nChangeInfos; // How many are in use this frame. +}; +extern CSharedEdictChangeInfo *g_pSharedChangeInfo; + +class IChangeInfoAccessor +{ +public: + inline void SetChangeInfo( unsigned short info ) + { + m_iChangeInfo = info; + } + + inline void SetChangeInfoSerialNumber( unsigned short sn ) + { + m_iChangeInfoSerialNumber = sn; + } + + inline unsigned short GetChangeInfo() const + { + return m_iChangeInfo; + } + + inline unsigned short GetChangeInfoSerialNumber() const + { + return m_iChangeInfoSerialNumber; + } + +private: + unsigned short m_iChangeInfo; + unsigned short m_iChangeInfoSerialNumber; +}; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +// NOTE: YOU CAN'T CHANGE THE LAYOUT OR SIZE OF CBASEEDICT AND REMAIN COMPATIBLE WITH HL2_VC6!!!!! +class CBaseEdict +{ +public: + + // Returns an IServerEntity if FL_FULLEDICT is set or NULL if this + // is a lightweight networking entity. + IServerEntity* GetIServerEntity(); + const IServerEntity* GetIServerEntity() const; + + IServerNetworkable* GetNetworkable(); + IServerUnknown* GetUnknown(); + + // Set when initting an entity. If it's only a networkable, this is false. + void SetEdict( IServerUnknown *pUnk, bool bFullEdict ); + + int AreaNum() const; + const char * GetClassName() const; + + bool IsFree() const; + void SetFree(); + void ClearFree(); + + bool HasStateChanged() const; + void ClearStateChanged(); + void StateChanged(); + void StateChanged( unsigned short offset ); + + void ClearTransmitState(); + + void SetChangeInfo( unsigned short info ); + void SetChangeInfoSerialNumber( unsigned short sn ); + unsigned short GetChangeInfo() const; + unsigned short GetChangeInfoSerialNumber() const; + +public: + + // NOTE: this is in the edict instead of being accessed by a virtual because the engine needs fast access to it. + // NOTE: YOU CAN'T CHANGE THE LAYOUT OR SIZE OF CBASEEDICT AND REMAIN COMPATIBLE WITH HL2_VC6!!!!! +#ifdef _XBOX + unsigned short m_fStateFlags; +#else + int m_fStateFlags; +#endif + + // NOTE: this is in the edict instead of being accessed by a virtual because the engine needs fast access to it. + // int m_NetworkSerialNumber; + + // NOTE: m_EdictIndex is an optimization since computing the edict index + // from a CBaseEdict* pointer otherwise requires divide-by-20. values for + // m_NetworkSerialNumber all fit within a 16-bit integer range, so we're + // repurposing the other 16 bits to cache off the index without changing + // the overall layout or size of this struct. existing mods compiled with + // a full 32-bit serial number field should still work. henryg 8/17/2011 +#if VALVE_LITTLE_ENDIAN + short m_NetworkSerialNumber; + short m_EdictIndex; +#else + short m_EdictIndex; + short m_NetworkSerialNumber; +#endif + + // NOTE: this is in the edict instead of being accessed by a virtual because the engine needs fast access to it. + IServerNetworkable *m_pNetworkable; + +protected: + IServerUnknown *m_pUnk; + + +public: + + IChangeInfoAccessor *GetChangeAccessor(); // The engine implements this and the game .dll implements as + const IChangeInfoAccessor *GetChangeAccessor() const; // The engine implements this and the game .dll implements as + // as callback through to the engine!!! + + // NOTE: YOU CAN'T CHANGE THE LAYOUT OR SIZE OF CBASEEDICT AND REMAIN COMPATIBLE WITH HL2_VC6!!!!! + // This breaks HL2_VC6!!!!! + // References a CEdictChangeInfo with a list of modified network props. + //unsigned short m_iChangeInfo; + //unsigned short m_iChangeInfoSerialNumber; + + friend void InitializeEntityDLLFields( edict_t *pEdict ); +}; + + +//----------------------------------------------------------------------------- +// CBaseEdict inlines. +//----------------------------------------------------------------------------- +inline IServerEntity* CBaseEdict::GetIServerEntity() +{ + if ( m_fStateFlags & FL_EDICT_FULL ) + return (IServerEntity*)m_pUnk; + else + return 0; +} + +inline bool CBaseEdict::IsFree() const +{ + return (m_fStateFlags & FL_EDICT_FREE) != 0; +} + + + +inline bool CBaseEdict::HasStateChanged() const +{ + return (m_fStateFlags & FL_EDICT_CHANGED) != 0; +} + +inline void CBaseEdict::ClearStateChanged() +{ + m_fStateFlags &= ~(FL_EDICT_CHANGED | FL_FULL_EDICT_CHANGED); + SetChangeInfoSerialNumber( 0 ); +} + +inline void CBaseEdict::StateChanged() +{ + // Note: this should only happen for properties in data tables that used some + // kind of pointer dereference. If the data is directly offsetable + m_fStateFlags |= (FL_EDICT_CHANGED | FL_FULL_EDICT_CHANGED); + SetChangeInfoSerialNumber( 0 ); +} + +inline void CBaseEdict::StateChanged( unsigned short offset ) +{ + if ( m_fStateFlags & FL_FULL_EDICT_CHANGED ) + return; + + m_fStateFlags |= FL_EDICT_CHANGED; + + IChangeInfoAccessor *accessor = GetChangeAccessor(); + + if ( accessor->GetChangeInfoSerialNumber() == g_pSharedChangeInfo->m_iSerialNumber ) + { + // Ok, I still own this one. + CEdictChangeInfo *p = &g_pSharedChangeInfo->m_ChangeInfos[accessor->GetChangeInfo()]; + + // Now add this offset to our list of changed variables. + for ( unsigned short i=0; i < p->m_nChangeOffsets; i++ ) + if ( p->m_ChangeOffsets[i] == offset ) + return; + + if ( p->m_nChangeOffsets == MAX_CHANGE_OFFSETS ) + { + // Invalidate our change info. + accessor->SetChangeInfoSerialNumber( 0 ); + m_fStateFlags |= FL_FULL_EDICT_CHANGED; // So we don't get in here again. + } + else + { + p->m_ChangeOffsets[p->m_nChangeOffsets++] = offset; + } + } + else + { + if ( g_pSharedChangeInfo->m_nChangeInfos == MAX_EDICT_CHANGE_INFOS ) + { + // Shucks.. have to mark the edict as fully changed because we don't have room to remember this change. + accessor->SetChangeInfoSerialNumber( 0 ); + m_fStateFlags |= FL_FULL_EDICT_CHANGED; + } + else + { + // Get a new CEdictChangeInfo and fill it out. + accessor->SetChangeInfo( g_pSharedChangeInfo->m_nChangeInfos ); + g_pSharedChangeInfo->m_nChangeInfos++; + + accessor->SetChangeInfoSerialNumber( g_pSharedChangeInfo->m_iSerialNumber ); + + CEdictChangeInfo *p = &g_pSharedChangeInfo->m_ChangeInfos[accessor->GetChangeInfo()]; + p->m_ChangeOffsets[0] = offset; + p->m_nChangeOffsets = 1; + } + } +} + + + +inline void CBaseEdict::SetFree() +{ + m_fStateFlags |= FL_EDICT_FREE; +} + +inline void CBaseEdict::ClearFree() +{ + m_fStateFlags &= ~FL_EDICT_FREE; +} + +inline void CBaseEdict::ClearTransmitState() +{ + m_fStateFlags &= ~(FL_EDICT_ALWAYS|FL_EDICT_PVSCHECK|FL_EDICT_DONTSEND); +} + +inline const IServerEntity* CBaseEdict::GetIServerEntity() const +{ + if ( m_fStateFlags & FL_EDICT_FULL ) + return (IServerEntity*)m_pUnk; + else + return 0; +} + +inline IServerUnknown* CBaseEdict::GetUnknown() +{ + return m_pUnk; +} + +inline IServerNetworkable* CBaseEdict::GetNetworkable() +{ + return m_pNetworkable; +} + +inline void CBaseEdict::SetEdict( IServerUnknown *pUnk, bool bFullEdict ) +{ + m_pUnk = pUnk; + if ( (pUnk != NULL) && bFullEdict ) + { + m_fStateFlags = FL_EDICT_FULL; + } + else + { + m_fStateFlags = 0; + } +} + +inline int CBaseEdict::AreaNum() const +{ + if ( !m_pUnk ) + return 0; + + return m_pNetworkable->AreaNum(); +} + +inline const char * CBaseEdict::GetClassName() const +{ + if ( !m_pUnk ) + return ""; + return m_pNetworkable->GetClassName(); +} + +inline void CBaseEdict::SetChangeInfo( unsigned short info ) +{ + GetChangeAccessor()->SetChangeInfo( info ); +} + +inline void CBaseEdict::SetChangeInfoSerialNumber( unsigned short sn ) +{ + GetChangeAccessor()->SetChangeInfoSerialNumber( sn ); +} + +inline unsigned short CBaseEdict::GetChangeInfo() const +{ + return GetChangeAccessor()->GetChangeInfo(); +} + +inline unsigned short CBaseEdict::GetChangeInfoSerialNumber() const +{ + return GetChangeAccessor()->GetChangeInfoSerialNumber(); +} + +//----------------------------------------------------------------------------- +// Purpose: The engine's internal representation of an entity, including some +// basic collision and position info and a pointer to the class wrapped on top +// of the structure +//----------------------------------------------------------------------------- +struct edict_t : public CBaseEdict +{ +public: + ICollideable *GetCollideable(); + + // The server timestampe at which the edict was freed (so we can try to use other edicts before reallocating this one) + float freetime; +}; + +inline ICollideable *edict_t::GetCollideable() +{ + IServerEntity *pEnt = GetIServerEntity(); + if ( pEnt ) + return pEnt->GetCollideable(); + else + return NULL; +} + + +#endif // EDICT_H diff --git a/sp/src/public/editor_sendcommand.cpp b/sp/src/public/editor_sendcommand.cpp new file mode 100644 index 00000000..c08b5f5b --- /dev/null +++ b/sp/src/public/editor_sendcommand.cpp @@ -0,0 +1,228 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Implements an interface to the map editor for the execution of +// editor shell commands from another application. Commands allow the +// creation and deletion of entities, AI nodes, and AI node connections. +// +// $NoKeywords: $ +//=============================================================================// + +#if !defined(_STATIC_LINKED) || defined(_SHARED_LIB) + +#if !defined(_X360) && defined(_WIN32) +#include +#endif +#include +#include "editor_sendcommand.h" +#include "tier1/strtools.h" +#include "mathlib/vector.h" + +#if defined( _X360 ) +#include "xbox/xbox_win32stubs.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +const int MAX_COMMAND_BUFFER = 2048; +//----------------------------------------------------------------------------- +// Purpose: Sends a command to the editor (if running) to begin an editing session +// of a given map. +// Input : pszMapName - Name of the bsp, without the path or extension: "c1a3a_port" +// nMapVersion - Map version number, from the BSP file. +// Output : Returns Editor_OK on success, an error code if the session was rejected. +//----------------------------------------------------------------------------- +EditorSendResult_t Editor_BeginSession(const char *pszMapName, int nMapVersion, bool bShowUI) +{ + char szCommand[MAX_COMMAND_BUFFER]; + Q_snprintf(szCommand,sizeof(szCommand), "session_begin %s %d", pszMapName, nMapVersion); + return(Editor_SendCommand(szCommand, bShowUI)); +} + + +//----------------------------------------------------------------------------- +// Purpose: Sends a command to the editor (if running) to verify the version and +// map name being edited. +// Input : pszMapName - Name of the bsp, without the path or extension: "c1a3a_port" +// nMapVersion - Map version number, from the BSP file. +// Output : Returns Editor_OK on success, an error code if the session was rejected. +//----------------------------------------------------------------------------- +EditorSendResult_t Editor_CheckVersion(const char *pszMapName, int nMapVersion, bool bShowUI) +{ + char szCommand[MAX_COMMAND_BUFFER]; + Q_snprintf(szCommand,sizeof(szCommand), "map_check_version %s %d", pszMapName, nMapVersion); + return(Editor_SendCommand(szCommand, bShowUI)); +} + + +//----------------------------------------------------------------------------- +// Purpose: Sends a command to the editor (if running) to create an entity at +// a given (x, y, z) coordinate. +// Input : pszEntity - Class name of entity to create, ie "info_player_start". +// x, y, z - World coordinates at which to create entity. +// Output : Returns Editor_OK on success, an error code on failure. +//----------------------------------------------------------------------------- +EditorSendResult_t Editor_CreateEntity(const char *pszEntity, float x, float y, float z, bool bShowUI) +{ + char szCommand[MAX_COMMAND_BUFFER]; + Q_snprintf(szCommand,sizeof(szCommand), "entity_create %s %g %g %g", pszEntity, x, y, z); + return(Editor_SendCommand(szCommand, bShowUI)); +} + + +//----------------------------------------------------------------------------- +// Purpose: Sends a command to the editor (if running) to create an entity at +// a given (x, y, z) coordinate. +// Input : pszNodeClass - Class name of node to create, ie "info_node". +// nID - Unique ID to assign the node. +// x, y, z - World coordinates at which to create node. +// Output : Returns Editor_OK on success, an error code on failure. +//----------------------------------------------------------------------------- +EditorSendResult_t Editor_CreateNode(const char *pszNodeClass, int nID, float x, float y, float z, bool bShowUI) +{ + char szCommand[MAX_COMMAND_BUFFER]; + Q_snprintf(szCommand,sizeof(szCommand), "node_create %s %d %g %g %g", pszNodeClass, nID, x, y, z); + return(Editor_SendCommand(szCommand, bShowUI)); +} + + +//----------------------------------------------------------------------------- +// Purpose: Sends a command to the editor (if running) to create an entity at +// a given (x, y, z) coordinate. +// Input : pszNodeClass - Class name of node to create, ie "info_node". +// nID - Unique ID to assign the node. +// x, y, z - World coordinates at which to create node. +// Output : Returns Editor_OK on success, an error code on failure. +//----------------------------------------------------------------------------- +EditorSendResult_t Editor_CreateNodeLink(int nStartID, int nEndID, bool bShowUI) +{ + char szCommand[MAX_COMMAND_BUFFER]; + Q_snprintf(szCommand,sizeof(szCommand), "nodelink_create %d %d", nStartID, nEndID); + return(Editor_SendCommand(szCommand, bShowUI)); +} + + +//----------------------------------------------------------------------------- +// Purpose: Sends a command to the editor (if running) to delete an entity at +// a given (x, y, z) coordinate. +// Input : pszEntity - Class name of entity to delete, ie "info_player_start". +// x, y, z - World coordinates of entity to delete. +// Output : Returns Editor_OK on success, an error code on failure. +//----------------------------------------------------------------------------- +EditorSendResult_t Editor_DeleteEntity(const char *pszEntity, float x, float y, float z, bool bShowUI) +{ + char szCommand[MAX_COMMAND_BUFFER]; + Q_snprintf(szCommand,sizeof(szCommand), "entity_delete %s %g %g %g", pszEntity, x, y, z); + return(Editor_SendCommand(szCommand, bShowUI)); +} + + +// sets an arbitrary key/value pair in the entity +EditorSendResult_t Editor_SetKeyValue(const char *pszEntity, float x, float y, float z, const char *pKey, const char *pValue, bool bShowUI) +{ + char szCommand[MAX_COMMAND_BUFFER]; + Q_snprintf(szCommand,sizeof(szCommand), "entity_set_keyvalue %s %f %f %f \"%s\" \"%s\"", pszEntity, x, y, z, pKey, pValue); + return(Editor_SendCommand(szCommand, bShowUI)); +} + + +// applies an incremental rotation to an entity +EditorSendResult_t Editor_RotateEntity(const char *pszEntity, float x, float y, float z, const QAngle &incrementalRotation, bool bShowUI) +{ + char szCommand[MAX_COMMAND_BUFFER]; + Q_snprintf(szCommand,sizeof(szCommand), "entity_rotate_incremental %s %f %f %f %f %f %f", pszEntity, x, y, z, incrementalRotation.x, incrementalRotation.y, incrementalRotation.z ); + return(Editor_SendCommand(szCommand, bShowUI)); +} +//----------------------------------------------------------------------------- +// Purpose: Sends a command to the editor (if running) to delete an entity at +// a given (x, y, z) coordinate. +// Input : nID - unique ID of node to delete. +// Output : Returns Editor_OK on success, an error code on failure. +//----------------------------------------------------------------------------- +EditorSendResult_t Editor_DeleteNode(int nID, bool bShowUI) +{ + char szCommand[MAX_COMMAND_BUFFER]; + Q_snprintf(szCommand,sizeof(szCommand), "node_delete %d", nID); + return(Editor_SendCommand(szCommand, bShowUI)); +} + + +//----------------------------------------------------------------------------- +// Purpose: Sends a command to the editor (if running) to delete an entity at +// a given (x, y, z) coordinate. +// Input : nStartID - unique ID of one node that the link is connected to. +// nEndID - unique ID of the other node that the link is connected to. +// Output : Returns Editor_OK on success, an error code on failure. +//----------------------------------------------------------------------------- +EditorSendResult_t Editor_DeleteNodeLink(int nStartID, int nEndID, bool bShowUI) +{ + char szCommand[MAX_COMMAND_BUFFER]; + Q_snprintf(szCommand,sizeof(szCommand), "nodelink_delete %d %d", nStartID, nEndID); + return(Editor_SendCommand(szCommand, bShowUI)); +} + + +//----------------------------------------------------------------------------- +// Purpose: Sends a command to the editor (if running) to end the current remote +// editing session. +// Output : Returns Editor_OK on success, an error code if the session was rejected. +//----------------------------------------------------------------------------- +EditorSendResult_t Editor_EndSession(bool bShowUI) +{ + return(Editor_SendCommand("session_end", bShowUI)); +} + + +//----------------------------------------------------------------------------- +// Purpose: Attempts to sends a shell command to the editor. +// Input : pszCommand - Shell command to send. +// bShowUI - Whether to display mesage boxes on failure. +// Output : Returns one of the following values: +// Editor_OK - The command was executed successfully. +// Editor_NotRunning - Unable to establish a communications channel with the editor. +// Editor_BadCommand - The editor did not accept the command. +//----------------------------------------------------------------------------- +EditorSendResult_t Editor_SendCommand(const char *pszCommand, bool bShowUI) +{ +#ifdef _WIN32 + HWND hwnd = FindWindow("Worldcraft_ShellMessageWnd", "Worldcraft_ShellMessageWnd"); + if (hwnd != NULL) + { + // + // Fill out the data structure to send to the editor. + // + + COPYDATASTRUCT CopyData; + CopyData.cbData = strlen(pszCommand) + 1; + CopyData.dwData = 0; + CopyData.lpData = (void *)pszCommand; + + if (!SendMessage(hwnd, WM_COPYDATA, 0, (LPARAM)&CopyData)) + { + if (bShowUI) + { + char szError[1024]; + Q_snprintf(szError,sizeof(szError), "Worldcraft did not accept the command: \n\n\"%s\"\n\n Make sure the command is valid and that Worldcraft is still running properly.", pszCommand); + MessageBox(NULL, szError, "Editor_SendCommand Error", MB_OK); + } + + return(Editor_BadCommand); + } + } + else + { + if (bShowUI) + { + char szError[1024]; + Q_snprintf(szError,sizeof(szError), "Could not contact Worldcraft to send the command: \n\n\"%s\"\n\n Worldcraft does not appear to be running.", pszCommand); + MessageBox(NULL, szError, "Editor_SendCommand Error", MB_OK); + } + + return(Editor_NotRunning); + } +#endif + + return(Editor_OK); +} + +#endif // !_STATIC_LINKED || _SHARED_LIB diff --git a/sp/src/public/editor_sendcommand.h b/sp/src/public/editor_sendcommand.h new file mode 100644 index 00000000..3c944eb9 --- /dev/null +++ b/sp/src/public/editor_sendcommand.h @@ -0,0 +1,52 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Defines an interface to the map editor for the execution of +// editor shell commands from another application. Commands allow the +// creation and deletion of entities, AI nodes, and AI node connections. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef EDITOR_SENDCOMMAND_H +#define EDITOR_SENDCOMMAND_H +#pragma once + +class QAngle; + +// +// Result codes from Worldcraft_SendCommand. +// +enum EditorSendResult_t +{ + Editor_OK = 0, // Success. + Editor_NotRunning, // Unable to establish a communications channel with the editor. + Editor_BadCommand, // The editor did not accept the command. +}; + + +// +// Wrappers around specific commands for convenience. +// +EditorSendResult_t Editor_BeginSession(const char *pszMapName, int nMapVersion, bool bShowUI = false); +EditorSendResult_t Editor_EndSession(bool bShowUI); +EditorSendResult_t Editor_CheckVersion(const char *pszMapName, int nMapVersion, bool bShowUI = false); + +EditorSendResult_t Editor_CreateEntity(const char *pszEntity, float x, float y, float z, bool bShowUI = false); +EditorSendResult_t Editor_DeleteEntity(const char *pszEntity, float x, float y, float z, bool bShowUI = false); +EditorSendResult_t Editor_SetKeyValue(const char *pszEntity, float x, float y, float z, const char *pKey, const char *pValue, bool bShowUI = false); +EditorSendResult_t Editor_RotateEntity(const char *pszEntity, float x, float y, float z, const QAngle &incrementalRotation, bool bShowUI = false); + +EditorSendResult_t Editor_CreateNode(const char *pszNodeClass, int nID, float x, float y, float z, bool bShowUI = false); +EditorSendResult_t Editor_DeleteNode(int nID, bool bShowUI = false); + +EditorSendResult_t Editor_CreateNodeLink(int nStartID, int nEndID, bool bShowUI = false); +EditorSendResult_t Editor_DeleteNodeLink(int nStartID, int nEndID, bool bShowUI = false); + + +// +// Actually does the work. All the above commands route through this. +// +EditorSendResult_t Editor_SendCommand(const char *pszCommand, bool bShowUI); + + +#endif // EDITOR_SENDCOMMAND_H diff --git a/sp/src/public/eiface.h b/sp/src/public/eiface.h new file mode 100644 index 00000000..50e313bc --- /dev/null +++ b/sp/src/public/eiface.h @@ -0,0 +1,742 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef EIFACE_H +#define EIFACE_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "convar.h" +#include "icvar.h" +#include "edict.h" +#include "mathlib/vplane.h" +#include "iserverentity.h" +#include "engine/ivmodelinfo.h" +#include "soundflags.h" +#include "bitvec.h" +#include "engine/iserverplugin.h" +#include "tier1/bitbuf.h" + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- +class SendTable; +class ServerClass; +class IMoveHelper; +struct Ray_t; +class CGameTrace; +typedef CGameTrace trace_t; +struct typedescription_t; +class CSaveRestoreData; +struct datamap_t; +class SendTable; +class ServerClass; +class IMoveHelper; +struct Ray_t; +struct studiohdr_t; +class CBaseEntity; +class CRestore; +class CSave; +class variant_t; +struct vcollide_t; +class IRecipientFilter; +class CBaseEntity; +class ITraceFilter; +struct client_textmessage_t; +class INetChannelInfo; +class ISpatialPartition; +class IScratchPad3D; +class CStandardSendProxies; +class IAchievementMgr; +class CGamestatsData; +class CSteamID; +class IReplayFactory; +class IReplaySystem; + +typedef struct player_info_s player_info_t; + +//----------------------------------------------------------------------------- +// defines +//----------------------------------------------------------------------------- + +#ifdef _WIN32 +#define DLLEXPORT __stdcall +#else +#define DLLEXPORT /* */ +#endif + +#define INTERFACEVERSION_VENGINESERVER "VEngineServer021" + +struct bbox_t +{ + Vector mins; + Vector maxs; +}; + +//----------------------------------------------------------------------------- +// Purpose: Interface the engine exposes to the game DLL +//----------------------------------------------------------------------------- +abstract_class IVEngineServer +{ +public: + // Tell engine to change level ( "changelevel s1\n" or "changelevel2 s1 s2\n" ) + virtual void ChangeLevel( const char *s1, const char *s2 ) = 0; + + // Ask engine whether the specified map is a valid map file (exists and has valid version number). + virtual int IsMapValid( const char *filename ) = 0; + + // Is this a dedicated server? + virtual bool IsDedicatedServer( void ) = 0; + + // Is in Hammer editing mode? + virtual int IsInEditMode( void ) = 0; + + // Add to the server/client lookup/precache table, the specified string is given a unique index + // NOTE: The indices for PrecacheModel are 1 based + // a 0 returned from those methods indicates the model or sound was not correctly precached + // However, generic and decal are 0 based + // If preload is specified, the file is loaded into the server/client's cache memory before level startup, otherwise + // it'll only load when actually used (which can cause a disk i/o hitch if it occurs during play of a level). + virtual int PrecacheModel( const char *s, bool preload = false ) = 0; + virtual int PrecacheSentenceFile( const char *s, bool preload = false ) = 0; + virtual int PrecacheDecal( const char *name, bool preload = false ) = 0; + virtual int PrecacheGeneric( const char *s, bool preload = false ) = 0; + + // Check's if the name is precached, but doesn't actually precache the name if not... + virtual bool IsModelPrecached( char const *s ) const = 0; + virtual bool IsDecalPrecached( char const *s ) const = 0; + virtual bool IsGenericPrecached( char const *s ) const = 0; + + // Note that sounds are precached using the IEngineSound interface + + // Special purpose PVS checking + // Get the cluster # for the specified position + virtual int GetClusterForOrigin( const Vector &org ) = 0; + // Get the PVS bits for a specified cluster and copy the bits into outputpvs. Returns the number of bytes needed to pack the PVS + virtual int GetPVSForCluster( int cluster, int outputpvslength, unsigned char *outputpvs ) = 0; + // Check whether the specified origin is inside the specified PVS + virtual bool CheckOriginInPVS( const Vector &org, const unsigned char *checkpvs, int checkpvssize ) = 0; + // Check whether the specified worldspace bounding box is inside the specified PVS + virtual bool CheckBoxInPVS( const Vector &mins, const Vector &maxs, const unsigned char *checkpvs, int checkpvssize ) = 0; + + // Returns the server assigned userid for this player. Useful for logging frags, etc. + // returns -1 if the edict couldn't be found in the list of players. + virtual int GetPlayerUserId( const edict_t *e ) = 0; + virtual const char *GetPlayerNetworkIDString( const edict_t *e ) = 0; + + // Return the current number of used edict slots + virtual int GetEntityCount( void ) = 0; + // Given an edict, returns the entity index + virtual int IndexOfEdict( const edict_t *pEdict ) = 0; + // Given and entity index, returns the corresponding edict pointer + virtual edict_t *PEntityOfEntIndex( int iEntIndex ) = 0; + + // Get stats info interface for a client netchannel + virtual INetChannelInfo* GetPlayerNetInfo( int playerIndex ) = 0; + + // Allocate space for string and return index/offset of string in global string list + // If iForceEdictIndex is not -1, then it will return the edict with that index. If that edict index + // is already used, it'll return null. + virtual edict_t *CreateEdict( int iForceEdictIndex = -1 ) = 0; + // Remove the specified edict and place back into the free edict list + virtual void RemoveEdict( edict_t *e ) = 0; + + // Memory allocation for entity class data + virtual void *PvAllocEntPrivateData( long cb ) = 0; + virtual void FreeEntPrivateData( void *pEntity ) = 0; + + // Save/restore uses a special memory allocator (which zeroes newly allocated memory, etc.) + virtual void *SaveAllocMemory( size_t num, size_t size ) = 0; + virtual void SaveFreeMemory( void *pSaveMem ) = 0; + + // Emit an ambient sound associated with the specified entity + virtual void EmitAmbientSound( int entindex, const Vector &pos, const char *samp, float vol, soundlevel_t soundlevel, int fFlags, int pitch, float delay = 0.0f ) = 0; + + // Fade out the client's volume level toward silence (or fadePercent) + virtual void FadeClientVolume( const edict_t *pEdict, float fadePercent, float fadeOutSeconds, float holdTime, float fadeInSeconds ) = 0; + + // Sentences / sentence groups + virtual int SentenceGroupPick( int groupIndex, char *name, int nameBufLen ) = 0; + virtual int SentenceGroupPickSequential( int groupIndex, char *name, int nameBufLen, int sentenceIndex, int reset ) = 0; + virtual int SentenceIndexFromName( const char *pSentenceName ) = 0; + virtual const char *SentenceNameFromIndex( int sentenceIndex ) = 0; + virtual int SentenceGroupIndexFromName( const char *pGroupName ) = 0; + virtual const char *SentenceGroupNameFromIndex( int groupIndex ) = 0; + virtual float SentenceLength( int sentenceIndex ) = 0; + + // Issue a command to the command parser as if it was typed at the server console. + virtual void ServerCommand( const char *str ) = 0; + // Execute any commands currently in the command parser immediately (instead of once per frame) + virtual void ServerExecute( void ) = 0; + // Issue the specified command to the specified client (mimics that client typing the command at the console). + virtual void ClientCommand( edict_t *pEdict, PRINTF_FORMAT_STRING const char *szFmt, ... ) = 0; + + // Set the lightstyle to the specified value and network the change to any connected clients. Note that val must not + // change place in memory (use MAKE_STRING) for anything that's not compiled into your mod. + virtual void LightStyle( int style, const char *val ) = 0; + + // Project a static decal onto the specified entity / model (for level placed decals in the .bsp) + virtual void StaticDecal( const Vector &originInEntitySpace, int decalIndex, int entityIndex, int modelIndex, bool lowpriority ) = 0; + + // Given the current PVS(or PAS) and origin, determine which players should hear/receive the message + virtual void Message_DetermineMulticastRecipients( bool usepas, const Vector& origin, CBitVec< ABSOLUTE_PLAYER_LIMIT >& playerbits ) = 0; + + // Begin a message from a server side entity to its client side counterpart (func_breakable glass, e.g.) + virtual bf_write *EntityMessageBegin( int ent_index, ServerClass * ent_class, bool reliable ) = 0; + // Begin a usermessage from the server to the client .dll + virtual bf_write *UserMessageBegin( IRecipientFilter *filter, int msg_type ) = 0; + // Finish the Entity or UserMessage and dispatch to network layer + virtual void MessageEnd( void ) = 0; + + // Print szMsg to the client console. + virtual void ClientPrintf( edict_t *pEdict, const char *szMsg ) = 0; + + // SINGLE PLAYER/LISTEN SERVER ONLY (just matching the client .dll api for this) + // Prints the formatted string to the notification area of the screen ( down the right hand edge + // numbered lines starting at position 0 + virtual void Con_NPrintf( int pos, PRINTF_FORMAT_STRING const char *fmt, ... ) = 0; + // SINGLE PLAYER/LISTEN SERVER ONLY(just matching the client .dll api for this) + // Similar to Con_NPrintf, but allows specifying custom text color and duration information + virtual void Con_NXPrintf( const struct con_nprint_s *info, PRINTF_FORMAT_STRING const char *fmt, ... ) = 0; + + // Change a specified player's "view entity" (i.e., use the view entity position/orientation for rendering the client view) + virtual void SetView( const edict_t *pClient, const edict_t *pViewent ) = 0; + + // Get a high precision timer for doing profiling work + virtual float Time( void ) = 0; + + // Set the player's crosshair angle + virtual void CrosshairAngle( const edict_t *pClient, float pitch, float yaw ) = 0; + + // Get the current game directory (hl2, tf2, hl1, cstrike, etc.) + virtual void GetGameDir( char *szGetGameDir, int maxlength ) = 0; + + // Used by AI node graph code to determine if .bsp and .ain files are out of date + virtual int CompareFileTime( const char *filename1, const char *filename2, int *iCompare ) = 0; + + // Locks/unlocks the network string tables (.e.g, when adding bots to server, this needs to happen). + // Be sure to reset the lock after executing your code!!! + virtual bool LockNetworkStringTables( bool lock ) = 0; + + // Create a bot with the given name. Returns NULL if fake client can't be created + virtual edict_t *CreateFakeClient( const char *netname ) = 0; + + // Get a convar keyvalue for s specified client + virtual const char *GetClientConVarValue( int clientIndex, const char *name ) = 0; + + // Parse a token from a file + virtual const char *ParseFile( const char *data, char *token, int maxlen ) = 0; + // Copies a file + virtual bool CopyFile( const char *source, const char *destination ) = 0; + + // Reset the pvs, pvssize is the size in bytes of the buffer pointed to by pvs. + // This should be called right before any calls to AddOriginToPVS + virtual void ResetPVS( byte *pvs, int pvssize ) = 0; + // Merge the pvs bits into the current accumulated pvs based on the specified origin ( not that each pvs origin has an 8 world unit fudge factor ) + virtual void AddOriginToPVS( const Vector &origin ) = 0; + + // Mark a specified area portal as open/closed. + // Use SetAreaPortalStates if you want to set a bunch of them at a time. + virtual void SetAreaPortalState( int portalNumber, int isOpen ) = 0; + + // Queue a temp entity for transmission + virtual void PlaybackTempEntity( IRecipientFilter& filter, float delay, const void *pSender, const SendTable *pST, int classID ) = 0; + // Given a node number and the specified PVS, return with the node is in the PVS + virtual int CheckHeadnodeVisible( int nodenum, const byte *pvs, int vissize ) = 0; + // Using area bits, cheeck whether area1 flows into area2 and vice versa (depends on area portal state) + virtual int CheckAreasConnected( int area1, int area2 ) = 0; + // Given an origin, determine which area index the origin is within + virtual int GetArea( const Vector &origin ) = 0; + // Get area portal bit set + virtual void GetAreaBits( int area, unsigned char *bits, int buflen ) = 0; + // Given a view origin (which tells us the area to start looking in) and a portal key, + // fill in the plane that leads out of this area (it points into whatever area it leads to). + virtual bool GetAreaPortalPlane( Vector const &vViewOrigin, int portalKey, VPlane *pPlane ) = 0; + + // Apply a modification to the terrain. + //virtual void ApplyTerrainMod(TerrainModType type, CTerrainModParams const& params) = 0; + + // Save/restore wrapper - FIXME: At some point we should move this to it's own interface + virtual bool LoadGameState( char const *pMapName, bool createPlayers ) = 0; + virtual void LoadAdjacentEnts( const char *pOldLevel, const char *pLandmarkName ) = 0; + virtual void ClearSaveDir() = 0; + + // Get the pristine map entity lump string. (e.g., used by CS to reload the map entities when restarting a round.) + virtual const char* GetMapEntitiesString() = 0; + + // Text message system -- lookup the text message of the specified name + virtual client_textmessage_t *TextMessageGet( const char *pName ) = 0; + + // Print a message to the server log file + virtual void LogPrint( const char *msg ) = 0; + + // Builds PVS information for an entity + virtual void BuildEntityClusterList( edict_t *pEdict, PVSInfo_t *pPVSInfo ) = 0; + + // A solid entity moved, update spatial partition + virtual void SolidMoved( edict_t *pSolidEnt, ICollideable *pSolidCollide, const Vector* pPrevAbsOrigin, bool testSurroundingBoundsOnly ) = 0; + // A trigger entity moved, update spatial partition + virtual void TriggerMoved( edict_t *pTriggerEnt, bool testSurroundingBoundsOnly ) = 0; + + // Create/destroy a custom spatial partition + virtual ISpatialPartition *CreateSpatialPartition( const Vector& worldmin, const Vector& worldmax ) = 0; + virtual void DestroySpatialPartition( ISpatialPartition * ) = 0; + + // Draw the brush geometry in the map into the scratch pad. + // Flags is currently unused. + virtual void DrawMapToScratchPad( IScratchPad3D *pPad, unsigned long iFlags ) = 0; + + // This returns which entities, to the best of the server's knowledge, the client currently knows about. + // This is really which entities were in the snapshot that this client last acked. + // This returns a bit vector with one bit for each entity. + // + // USE WITH CARE. Whatever tick the client is really currently on is subject to timing and + // ordering differences, so you should account for about a quarter-second discrepancy in here. + // Also, this will return NULL if the client doesn't exist or if this client hasn't acked any frames yet. + // + // iClientIndex is the CLIENT index, so if you use pPlayer->entindex(), subtract 1. + virtual const CBitVec* GetEntityTransmitBitsForClient( int iClientIndex ) = 0; + + // Is the game paused? + virtual bool IsPaused() = 0; + + // Marks the filename for consistency checking. This should be called after precaching the file. + virtual void ForceExactFile( const char *s ) = 0; + virtual void ForceModelBounds( const char *s, const Vector &mins, const Vector &maxs ) = 0; + virtual void ClearSaveDirAfterClientLoad() = 0; + + // Sets a USERINFO client ConVar for a fakeclient + virtual void SetFakeClientConVarValue( edict_t *pEntity, const char *cvar, const char *value ) = 0; + + // Marks the material (vmt file) for consistency checking. If the client and server have different + // contents for the file, the client's vmt can only use the VertexLitGeneric shader, and can only + // contain $baseTexture and $bumpmap vars. + virtual void ForceSimpleMaterial( const char *s ) = 0; + + // Is the engine in Commentary mode? + virtual int IsInCommentaryMode( void ) = 0; + + + // Mark some area portals as open/closed. It's more efficient to use this + // than a bunch of individual SetAreaPortalState calls. + virtual void SetAreaPortalStates( const int *portalNumbers, const int *isOpen, int nPortals ) = 0; + + // Called when relevant edict state flags change. + virtual void NotifyEdictFlagsChange( int iEdict ) = 0; + + // Only valid during CheckTransmit. Also, only the PVS, networked areas, and + // m_pTransmitInfo are valid in the returned strucutre. + virtual const CCheckTransmitInfo* GetPrevCheckTransmitInfo( edict_t *pPlayerEdict ) = 0; + + virtual CSharedEdictChangeInfo* GetSharedEdictChangeInfo() = 0; + + // Tells the engine we can immdiately re-use all edict indices + // even though we may not have waited enough time + virtual void AllowImmediateEdictReuse( ) = 0; + + // Returns true if the engine is an internal build. i.e. is using the internal bugreporter. + virtual bool IsInternalBuild( void ) = 0; + + virtual IChangeInfoAccessor *GetChangeAccessor( const edict_t *pEdict ) = 0; + + // Name of most recently load .sav file + virtual char const *GetMostRecentlyLoadedFileName() = 0; + virtual char const *GetSaveFileName() = 0; + + // Matchmaking + virtual void MultiplayerEndGame() = 0; + virtual void ChangeTeam( const char *pTeamName ) = 0; + + // Cleans up the cluster list + virtual void CleanUpEntityClusterList( PVSInfo_t *pPVSInfo ) = 0; + + virtual void SetAchievementMgr( IAchievementMgr *pAchievementMgr ) =0; + virtual IAchievementMgr *GetAchievementMgr() = 0; + + virtual int GetAppID() = 0; + + virtual bool IsLowViolence() = 0; + + // Call this to find out the value of a cvar on the client. + // + // It is an asynchronous query, and it will call IServerGameDLL::OnQueryCvarValueFinished when + // the value comes in from the client. + // + // Store the return value if you want to match this specific query to the OnQueryCvarValueFinished call. + // Returns InvalidQueryCvarCookie if the entity is invalid. + virtual QueryCvarCookie_t StartQueryCvarValue( edict_t *pPlayerEntity, const char *pName ) = 0; + + virtual void InsertServerCommand( const char *str ) = 0; + + // Fill in the player info structure for the specified player index (name, model, etc.) + virtual bool GetPlayerInfo( int ent_num, player_info_t *pinfo ) = 0; + + // Returns true if this client has been fully authenticated by Steam + virtual bool IsClientFullyAuthenticated( edict_t *pEdict ) = 0; + + // This makes the host run 1 tick per frame instead of checking the system timer to see how many ticks to run in a certain frame. + // i.e. it does the same thing timedemo does. + virtual void SetDedicatedServerBenchmarkMode( bool bBenchmarkMode ) = 0; + + // Methods to set/get a gamestats data container so client & server running in same process can send combined data + virtual void SetGamestatsData( CGamestatsData *pGamestatsData ) = 0; + virtual CGamestatsData *GetGamestatsData() = 0; + + // Returns the SteamID of the specified player. It'll be NULL if the player hasn't authenticated yet. + virtual const CSteamID *GetClientSteamID( edict_t *pPlayerEdict ) = 0; + + // Returns the SteamID of the game server + virtual const CSteamID *GetGameServerSteamID() = 0; + + // Send a client command keyvalues + // keyvalues are deleted inside the function + virtual void ClientCommandKeyValues( edict_t *pEdict, KeyValues *pCommand ) = 0; + + // Returns the SteamID of the specified player. It'll be NULL if the player hasn't authenticated yet. + virtual const CSteamID *GetClientSteamIDByPlayerIndex( int entnum ) = 0; + // Gets a list of all clusters' bounds. Returns total number of clusters. + virtual int GetClusterCount() = 0; + virtual int GetAllClusterBounds( bbox_t *pBBoxList, int maxBBox ) = 0; + + // Create a bot with the given name. Returns NULL if fake client can't be created + virtual edict_t *CreateFakeClientEx( const char *netname, bool bReportFakeClient = true ) = 0; + + // Server version from the steam.inf, this will be compared to the GC version + virtual int GetServerVersion() const = 0; + + // Get sv.GetTime() + virtual float GetServerTime() const = 0; +}; + + +#define INTERFACEVERSION_SERVERGAMEDLL_VERSION_8 "ServerGameDLL008" +#define INTERFACEVERSION_SERVERGAMEDLL "ServerGameDLL009" +#define INTERFACEVERSION_SERVERGAMEDLL_INT 9 + +class IServerGCLobby; + +//----------------------------------------------------------------------------- +// Purpose: These are the interfaces that the game .dll exposes to the engine +//----------------------------------------------------------------------------- +abstract_class IServerGameDLL +{ +public: + // Initialize the game (one-time call when the DLL is first loaded ) + // Return false if there is an error during startup. + virtual bool DLLInit( CreateInterfaceFn engineFactory, + CreateInterfaceFn physicsFactory, + CreateInterfaceFn fileSystemFactory, + CGlobalVars *pGlobals) = 0; + + // Setup replay interfaces on the server + virtual bool ReplayInit( CreateInterfaceFn fnReplayFactory ) = 0; + + // This is called when a new game is started. (restart, map) + virtual bool GameInit( void ) = 0; + + // Called any time a new level is started (after GameInit() also on level transitions within a game) + virtual bool LevelInit( char const *pMapName, + char const *pMapEntities, char const *pOldLevel, + char const *pLandmarkName, bool loadGame, bool background ) = 0; + + // The server is about to activate + virtual void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ) = 0; + + // The server should run physics/think on all edicts + virtual void GameFrame( bool simulating ) = 0; + + // Called once per simulation frame on the final tick + virtual void PreClientUpdate( bool simulating ) = 0; + + // Called when a level is shutdown (including changing levels) + virtual void LevelShutdown( void ) = 0; + // This is called when a game ends (server disconnect, death, restart, load) + // NOT on level transitions within a game + virtual void GameShutdown( void ) = 0; + + // Called once during DLL shutdown + virtual void DLLShutdown( void ) = 0; + + // Get the simulation interval (must be compiled with identical values into both client and game .dll for MOD!!!) + // Right now this is only requested at server startup time so it can't be changed on the fly, etc. + virtual float GetTickInterval( void ) const = 0; + + // Give the list of datatable classes to the engine. The engine matches class names from here with + // edict_t::classname to figure out how to encode a class's data for networking + virtual ServerClass* GetAllServerClasses( void ) = 0; + + // Returns string describing current .dll. e.g., TeamFortress 2, Half-Life 2. + // Hey, it's more descriptive than just the name of the game directory + virtual const char *GetGameDescription( void ) = 0; + + // Let the game .dll allocate it's own network/shared string tables + virtual void CreateNetworkStringTables( void ) = 0; + + // Save/restore system hooks + virtual CSaveRestoreData *SaveInit( int size ) = 0; + virtual void SaveWriteFields( CSaveRestoreData *, const char *, void *, datamap_t *, typedescription_t *, int ) = 0; + virtual void SaveReadFields( CSaveRestoreData *, const char *, void *, datamap_t *, typedescription_t *, int ) = 0; + virtual void SaveGlobalState( CSaveRestoreData * ) = 0; + virtual void RestoreGlobalState( CSaveRestoreData * ) = 0; + virtual void PreSave( CSaveRestoreData * ) = 0; + virtual void Save( CSaveRestoreData * ) = 0; + virtual void GetSaveComment( char *comment, int maxlength, float flMinutes, float flSeconds, bool bNoTime = false ) = 0; + virtual void WriteSaveHeaders( CSaveRestoreData * ) = 0; + virtual void ReadRestoreHeaders( CSaveRestoreData * ) = 0; + virtual void Restore( CSaveRestoreData *, bool ) = 0; + virtual bool IsRestoring() = 0; + + // Returns the number of entities moved across the transition + virtual int CreateEntityTransitionList( CSaveRestoreData *, int ) = 0; + // Build the list of maps adjacent to the current map + virtual void BuildAdjacentMapList( void ) = 0; + + // Retrieve info needed for parsing the specified user message + virtual bool GetUserMessageInfo( int msg_type, char *name, int maxnamelength, int& size ) = 0; + + // Hand over the StandardSendProxies in the game DLL's module. + virtual CStandardSendProxies* GetStandardSendProxies() = 0; + + // Called once during startup, after the game .dll has been loaded and after the client .dll has also been loaded + virtual void PostInit() = 0; + // Called once per frame even when no level is loaded... + virtual void Think( bool finalTick ) = 0; + +#ifdef _XBOX + virtual void GetTitleName( const char *pMapName, char* pTitleBuff, int titleBuffSize ) = 0; +#endif + + virtual void PreSaveGameLoaded( char const *pSaveName, bool bCurrentlyInGame ) = 0; + + // Returns true if the game DLL wants the server not to be made public. + // Used by commentary system to hide multiplayer commentary servers from the master. + virtual bool ShouldHideServer( void ) = 0; + + virtual void InvalidateMdlCache() = 0; + + // * This function is new with version 6 of the interface. + // + // This is called when a query from IServerPluginHelpers::StartQueryCvarValue is finished. + // iCookie is the value returned by IServerPluginHelpers::StartQueryCvarValue. + // Added with version 2 of the interface. + virtual void OnQueryCvarValueFinished( QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue ) = 0; + + // Called after the steam API has been activated post-level startup + virtual void GameServerSteamAPIActivated( void ) = 0; + + // Called after the steam API has been shutdown post-level startup + virtual void GameServerSteamAPIShutdown( void ) = 0; + + virtual void SetServerHibernation( bool bHibernating ) = 0; + + // interface to the new GC based lobby system + virtual IServerGCLobby *GetServerGCLobby() = 0; + + // Return override string to show in the server browser + // "map" column, or NULL to just use the default value + // (the map name) + virtual const char *GetServerBrowserMapOverride() = 0; + + // Get gamedata string to send to the master serer updater. + virtual const char *GetServerBrowserGameData() = 0; +}; + +typedef IServerGameDLL IServerGameDLL008; + +//----------------------------------------------------------------------------- +// Just an interface version name for the random number interface +// See vstdlib/random.h for the interface definition +// NOTE: If you change this, also change VENGINE_CLIENT_RANDOM_INTERFACE_VERSION in cdll_int.h +//----------------------------------------------------------------------------- +#define VENGINE_SERVER_RANDOM_INTERFACE_VERSION "VEngineRandom001" + +#define INTERFACEVERSION_SERVERGAMEENTS "ServerGameEnts001" +//----------------------------------------------------------------------------- +// Purpose: Interface to get at server entities +//----------------------------------------------------------------------------- +abstract_class IServerGameEnts +{ +public: + virtual ~IServerGameEnts() {} + + // Only for debugging. Set the edict base so you can get an edict's index in the debugger while debugging the game .dll + virtual void SetDebugEdictBase(edict_t *base) = 0; + + // The engine wants to mark two entities as touching + virtual void MarkEntitiesAsTouching( edict_t *e1, edict_t *e2 ) = 0; + + // Frees the entity attached to this edict + virtual void FreeContainingEntity( edict_t * ) = 0; + + // This allows the engine to get at edicts in a CGameTrace. + virtual edict_t* BaseEntityToEdict( CBaseEntity *pEnt ) = 0; + virtual CBaseEntity* EdictToBaseEntity( edict_t *pEdict ) = 0; + + // This sets a bit in pInfo for each edict in the list that wants to be transmitted to the + // client specified in pInfo. + // + // This is also where an entity can force other entities to be transmitted if it refers to them + // with ehandles. + virtual void CheckTransmit( CCheckTransmitInfo *pInfo, const unsigned short *pEdictIndices, int nEdicts ) = 0; +}; + +#define INTERFACEVERSION_SERVERGAMECLIENTS_VERSION_3 "ServerGameClients003" +#define INTERFACEVERSION_SERVERGAMECLIENTS "ServerGameClients004" + +//----------------------------------------------------------------------------- +// Purpose: Player / Client related functions +//----------------------------------------------------------------------------- +abstract_class IServerGameClients +{ +public: + // Get server maxplayers and lower bound for same + virtual void GetPlayerLimits( int& minplayers, int& maxplayers, int &defaultMaxPlayers ) const = 0; + + // Client is connecting to server ( return false to reject the connection ) + // You can specify a rejection message by writing it into reject + virtual bool ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen ) = 0; + + // Client is going active + // If bLoadGame is true, don't spawn the player because its state is already setup. + virtual void ClientActive( edict_t *pEntity, bool bLoadGame ) = 0; + + // Client is disconnecting from server + virtual void ClientDisconnect( edict_t *pEntity ) = 0; + + // Client is connected and should be put in the game + virtual void ClientPutInServer( edict_t *pEntity, char const *playername ) = 0; + + // The client has typed a command at the console + virtual void ClientCommand( edict_t *pEntity, const CCommand &args ) = 0; + + // Sets the client index for the client who typed the command into his/her console + virtual void SetCommandClient( int index ) = 0; + + // A player changed one/several replicated cvars (name etc) + virtual void ClientSettingsChanged( edict_t *pEdict ) = 0; + + // Determine PVS origin and set PVS for the player/viewentity + virtual void ClientSetupVisibility( edict_t *pViewEntity, edict_t *pClient, unsigned char *pvs, int pvssize ) = 0; + + // A block of CUserCmds has arrived from the user, decode them and buffer for execution during player simulation + virtual float ProcessUsercmds( edict_t *player, bf_read *buf, int numcmds, int totalcmds, + int dropped_packets, bool ignore, bool paused ) = 0; + + // Let the game .dll do stuff after messages have been sent to all of the clients once the server frame is complete + virtual void PostClientMessagesSent_DEPRECIATED( void ) = 0; + + // For players, looks up the CPlayerState structure corresponding to the player + virtual CPlayerState *GetPlayerState( edict_t *player ) = 0; + + // Get the ear position for a specified client + virtual void ClientEarPosition( edict_t *pEntity, Vector *pEarOrigin ) = 0; + + // returns number of delay ticks if player is in Replay mode (0 = no delay) + virtual int GetReplayDelay( edict_t *player, int& entity ) = 0; + + // Anything this game .dll wants to add to the bug reporter text (e.g., the entity/model under the picker crosshair) + // can be added here + virtual void GetBugReportInfo( char *buf, int buflen ) = 0; + + // A user has had their network id setup and validated + virtual void NetworkIDValidated( const char *pszUserName, const char *pszNetworkID ) = 0; + + // The client has submitted a keyvalues command + virtual void ClientCommandKeyValues( edict_t *pEntity, KeyValues *pKeyValues ) = 0; + + // Hook for player spawning + virtual void ClientSpawned( edict_t *pPlayer ) = 0; +}; + +typedef IServerGameClients IServerGameClients003; + + +#define INTERFACEVERSION_UPLOADGAMESTATS "ServerUploadGameStats001" + +abstract_class IUploadGameStats +{ +public: + // Note that this call will block the server until the upload is completed, so use only at levelshutdown if at all. + virtual bool UploadGameStats( + char const *mapname, // Game map name + unsigned int blobversion, // Version of the binary blob data + unsigned int blobsize, // Size in bytes of blob data + const void *pvBlobData ) = 0; // Pointer to the blob data. + + // Call when created to init the CSER connection + virtual void InitConnection( void ) = 0; + + // Call periodically to poll steam for a CSER connection + virtual void UpdateConnection( void ) = 0; + + // If user has disabled stats tracking, do nothing + virtual bool IsGameStatsLoggingEnabled() = 0; + + // Gets a non-personally identifiable unique ID for this steam user, used for tracking total gameplay time across + // multiple stats sessions, but isn't trackable back to their Steam account or id. + // Buffer should be 16 bytes, ID will come back as a hexadecimal string version of a GUID + virtual void GetPseudoUniqueId( char *buf, size_t bufsize ) = 0; + + // For determining general % of users running using cyber cafe accounts... + virtual bool IsCyberCafeUser( void ) = 0; + + // Only works in single player + virtual bool IsHDREnabled( void ) = 0; +}; + +#define INTERFACEVERSION_PLUGINHELPERSCHECK "PluginHelpersCheck001" + +//----------------------------------------------------------------------------- +// Purpose: allows the game dll to control which plugin functions can be run +//----------------------------------------------------------------------------- +abstract_class IPluginHelpersCheck +{ +public: + virtual bool CreateMessage( const char *plugin, edict_t *pEntity, DIALOG_TYPE type, KeyValues *data ) = 0; +}; + +//----------------------------------------------------------------------------- +// Purpose: Interface exposed from the client .dll back to the engine for specifying shared .dll IAppSystems (e.g., ISoundEmitterSystem) +//----------------------------------------------------------------------------- +abstract_class IServerDLLSharedAppSystems +{ +public: + virtual int Count() = 0; + virtual char const *GetDllName( int idx ) = 0; + virtual char const *GetInterfaceName( int idx ) = 0; +}; + +#define SERVER_DLL_SHARED_APPSYSTEMS "VServerDllSharedAppSystems001" + +#define INTERFACEVERSION_SERVERGAMETAGS "ServerGameTags001" + +//----------------------------------------------------------------------------- +// Purpose: querying the game dll for Server cvar tags +//----------------------------------------------------------------------------- +abstract_class IServerGameTags +{ +public: + // Get the list of cvars that require tags to show differently in the server browser + virtual void GetTaggedConVarList( KeyValues *pCvarTagList ) = 0; +}; + +//----------------------------------------------------------------------------- +// Purpose: Provide hooks for the GC based lobby system +//----------------------------------------------------------------------------- +abstract_class IServerGCLobby +{ +public: + virtual bool HasLobby() const = 0; + virtual bool SteamIDAllowedToConnect( const CSteamID &steamId ) const = 0; + virtual void UpdateServerDetails(void) = 0; + virtual bool ShouldHibernate() = 0; +}; + +#endif // EIFACE_H diff --git a/sp/src/public/eifacev21.h b/sp/src/public/eifacev21.h new file mode 100644 index 00000000..289ffaaf --- /dev/null +++ b/sp/src/public/eifacev21.h @@ -0,0 +1,613 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Defines entity interface between engine and DLLs. +// This header file included by engine files and DLL files. +// +// Before including this header, DLLs must: +// include edict.h +// This is conveniently done for them in extdll.h +// +// $NoKeywords: $ +// +//============================================================================= + +#ifndef EIFACEV21_H +#define EIFACEV21_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "convar.h" +#include "icvar.h" +#include "edict.h" +#include "iserverentity.h" +#include "engine/ivmodelinfo.h" +#include "soundflags.h" +#include "bitvec.h" + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- +class SendTable; +class ServerClass; +class IMoveHelper; +struct Ray_t; +class CGameTrace; +typedef CGameTrace trace_t; +struct typedescription_t; +class CSaveRestoreData; +struct datamap_t; +class SendTable; +class ServerClass; +class IMoveHelper; +struct Ray_t; +struct studiohdr_t; +class CBaseEntity; +class CRestore; +class CSave; +class variant_t; +struct vcollide_t; +class bf_read; +class bf_write; +class IRecipientFilter; +class CBaseEntity; +class ITraceFilter; +struct client_textmessage_t; +class INetChannelInfo; +class ISpatialPartition; +class IScratchPad3D; +class CStandardSendProxiesV1; + + +// Terrain Modification Types +enum TerrainModType +{ + TMod_Sphere = 0, // sphere that pushes all vertices out along their normal. + TMod_Suck, + TMod_AABB +}; + +class CTerrainModParams +{ +public: + + // Flags for m_Flags. + enum + { + TMOD_SUCKTONORMAL = ( 1 << 0 ), // For TMod_Suck, suck into m_Normal rather than on +Z. + TMOD_STAYABOVEORIGINAL = ( 1 << 1 ) // For TMod_Suck, don't go below the original vert on Z. + }; + + CTerrainModParams() { m_Flags = 0; } // people always forget to init this + + Vector m_vCenter; + Vector m_vNormal; // If TMod_Suck and TMOD_SUCKTONORMAL is set. + int m_Flags; // Combination of TMOD_ flags. + float m_flRadius; + Vector m_vecMin; // Bounding box. + Vector m_vecMax; + float m_flStrength; // for TMod_Suck + float m_flMorphTime; // time over which the morph takes place +}; + +class CSpeculativeTerrainModVert +{ +public: + Vector m_vOriginal; // vertex position before any mods + Vector m_vCurrent; // current vertex position + Vector m_vNew; // vertex position if the mod were applied +}; + +//----------------------------------------------------------------------------- +// Terrain modification interface +//----------------------------------------------------------------------------- +class ITerrainMod +{ +public: + + //--------------------------------------------------------------------- + // Initialize the terrain modifier. + //--------------------------------------------------------------------- + virtual void Init( const CTerrainModParams ¶ms ) = 0; + + //--------------------------------------------------------------------- + // Apply the terrain modifier to the surface. The vertex should be + // moved from its original position to the target position. + // Return true if the position is modified. + //--------------------------------------------------------------------- + virtual bool ApplyMod( Vector &vecTargetPos, Vector const &vecOriginalPos ) = 0; + + //--------------------------------------------------------------------- + // Apply the terrain modifier to the surface. The vertex should from + // its original position toward the target position bassed on the + // morph time. + // Return true if the posistion is modified. + //--------------------------------------------------------------------- + virtual bool ApplyModAtMorphTime( Vector &vecTargetPos, const Vector&vecOriginalPos, + float flCurrentTime, float flMorphTime ) = 0; + + //--------------------------------------------------------------------- + // Get the bounding box for things that this mod can affect (note that + // it CAN move things outside of this bounding box). + //--------------------------------------------------------------------- + virtual void GetBBox( Vector &vecBBMin, Vector &vecBBMax ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Purpose: Interface the engine exposes to the game DLL +//----------------------------------------------------------------------------- +#define VENGINESERVER_INTERFACEVERSION_21 "VEngineServer021" + +namespace VEngineServerV21 +{ + +abstract_class IVEngineServerV21 +{ +public: + // Tell engine to change level ( "changelevel s1\n" or "changelevel2 s1 s2\n" ) + virtual void ChangeLevel( const char *s1, const char *s2 ) = 0; + + // Ask engine whether the specified map is a valid map file (exists and has valid version number). + virtual int IsMapValid( const char *filename ) = 0; + + // Is this a dedicated server? + virtual bool IsDedicatedServer( void ) = 0; + + // Is in Hammer editing mode? + virtual int IsInEditMode( void ) = 0; + + // Add to the server/client lookup/precache table, the specified string is given a unique index + // NOTE: The indices for PrecacheModel are 1 based + // a 0 returned from those methods indicates the model or sound was not correctly precached + // However, generic and decal are 0 based + // If preload is specified, the file is loaded into the server/client's cache memory before level startup, otherwise + // it'll only load when actually used (which can cause a disk i/o hitch if it occurs during play of a level). + virtual int PrecacheModel( const char *s, bool preload = false ) = 0; + virtual int PrecacheSentenceFile( const char *s, bool preload = false ) = 0; + virtual int PrecacheDecal( const char *name, bool preload = false ) = 0; + virtual int PrecacheGeneric( const char *s, bool preload = false ) = 0; + + // Check's if the name is precached, but doesn't actually precache the name if not... + virtual bool IsModelPrecached( char const *s ) const = 0; + virtual bool IsDecalPrecached( char const *s ) const = 0; + virtual bool IsGenericPrecached( char const *s ) const = 0; + + // Note that sounds are precached using the IEngineSound interface + + // Special purpose PVS checking + // Get the cluster # for the specified position + virtual int GetClusterForOrigin( const Vector &org ) = 0; + // Get the PVS bits for a specified cluster and copy the bits into outputpvs. Returns the number of bytes needed to pack the PVS + virtual int GetPVSForCluster( int cluster, int outputpvslength, unsigned char *outputpvs ) = 0; + // Check whether the specified origin is inside the specified PVS + virtual bool CheckOriginInPVS( const Vector &org, const unsigned char *checkpvs, int checkpvssize ) = 0; + // Check whether the specified worldspace bounding box is inside the specified PVS + virtual bool CheckBoxInPVS( const Vector &mins, const Vector &maxs, const unsigned char *checkpvs, int checkpvssize ) = 0; + + // Returns the server assigned userid for this player. Useful for logging frags, etc. + // returns -1 if the edict couldn't be found in the list of players. + virtual int GetPlayerUserId( const edict_t *e ) = 0; + virtual const char *GetPlayerNetworkIDString( const edict_t *e ) = 0; + + // Return the current number of used edict slots + virtual int GetEntityCount( void ) = 0; + // Given an edict, returns the entity index + virtual int IndexOfEdict( const edict_t *pEdict ) = 0; + // Given and entity index, returns the corresponding edict pointer + virtual edict_t *PEntityOfEntIndex( int iEntIndex ) = 0; + + // Get stats info interface for a client netchannel + virtual INetChannelInfo* GetPlayerNetInfo( int playerIndex ) = 0; + + // Allocate space for string and return index/offset of string in global string list + // If iForceEdictIndex is not -1, then it will return the edict with that index. If that edict index + // is already used, it'll return null. + virtual edict_t *CreateEdict( int iForceEdictIndex = -1 ) = 0; + // Remove the specified edict and place back into the free edict list + virtual void RemoveEdict( edict_t *e ) = 0; + + // Memory allocation for entity class data + virtual void *PvAllocEntPrivateData( long cb ) = 0; + virtual void FreeEntPrivateData( void *pEntity ) = 0; + + // Save/restore uses a special memory allocator (which zeroes newly allocated memory, etc.) + virtual void *SaveAllocMemory( size_t num, size_t size ) = 0; + virtual void SaveFreeMemory( void *pSaveMem ) = 0; + + // Emit an ambient sound associated with the specified entity + virtual void EmitAmbientSound( int entindex, const Vector &pos, const char *samp, float vol, soundlevel_t soundlevel, int fFlags, int pitch, float delay = 0.0f ) = 0; + + // Fade out the client's volume level toward silence (or fadePercent) + virtual void FadeClientVolume( const edict_t *pEdict, float fadePercent, float fadeOutSeconds, float holdTime, float fadeInSeconds ) = 0; + + // Sentences / sentence groups + virtual int SentenceGroupPick( int groupIndex, char *name, int nameBufLen ) = 0; + virtual int SentenceGroupPickSequential( int groupIndex, char *name, int nameBufLen, int sentenceIndex, int reset ) = 0; + virtual int SentenceIndexFromName( const char *pSentenceName ) = 0; + virtual const char *SentenceNameFromIndex( int sentenceIndex ) = 0; + virtual int SentenceGroupIndexFromName( const char *pGroupName ) = 0; + virtual const char *SentenceGroupNameFromIndex( int groupIndex ) = 0; + virtual float SentenceLength( int sentenceIndex ) = 0; + + // Issue a command to the command parser as if it was typed at the server console. + virtual void ServerCommand( const char *str ) = 0; + // Execute any commands currently in the command parser immediately (instead of once per frame) + virtual void ServerExecute( void ) = 0; + // Issue the specified command to the specified client (mimics that client typing the command at the console). + virtual void ClientCommand( edict_t *pEdict, PRINTF_FORMAT_STRING const char *szFmt, ... ) = 0; + + // Set the lightstyle to the specified value and network the change to any connected clients. Note that val must not + // change place in memory (use MAKE_STRING) for anything that's not compiled into your mod. + virtual void LightStyle( int style, const char *val ) = 0; + + // Project a static decal onto the specified entity / model (for level placed decals in the .bsp) + virtual void StaticDecal( const Vector &originInEntitySpace, int decalIndex, int entityIndex, int modelIndex, bool lowpriority ) = 0; + + // Given the current PVS(or PAS) and origin, determine which players should hear/receive the message + virtual void Message_DetermineMulticastRecipients( bool usepas, const Vector& origin, CBitVec< ABSOLUTE_PLAYER_LIMIT >& playerbits ) = 0; + + // Begin a message from a server side entity to its client side counterpart (func_breakable glass, e.g.) + virtual bf_write *EntityMessageBegin( int ent_index, ServerClass * ent_class, bool reliable ) = 0; + // Begin a usermessage from the server to the client .dll + virtual bf_write *UserMessageBegin( IRecipientFilter *filter, int msg_type ) = 0; + // Finish the Entity or UserMessage and dispatch to network layer + virtual void MessageEnd( void ) = 0; + + // Print szMsg to the client console. + virtual void ClientPrintf( edict_t *pEdict, const char *szMsg ) = 0; + + // SINGLE PLAYER/LISTEN SERVER ONLY (just matching the client .dll api for this) + // Prints the formatted string to the notification area of the screen ( down the right hand edge + // numbered lines starting at position 0 + virtual void Con_NPrintf( int pos, PRINTF_FORMAT_STRING const char *fmt, ... ) = 0; + // SINGLE PLAYER/LISTEN SERVER ONLY(just matching the client .dll api for this) + // Similar to Con_NPrintf, but allows specifying custom text color and duration information + virtual void Con_NXPrintf( const struct con_nprint_s *info, PRINTF_FORMAT_STRING const char *fmt, ... ) = 0; + + // For ConCommand parsing or parsing client commands issued by players typing at their console + // Retrieves the raw command string (untokenized) + virtual const char *Cmd_Args( void ) = 0; + // Returns the number of tokens in the command string + virtual int Cmd_Argc( void ) = 0; + // Retrieves a specified token + virtual char *Cmd_Argv( int argc ) = 0; + + // Change a specified player's "view entity" (i.e., use the view entity position/orientation for rendering the client view) + virtual void SetView( const edict_t *pClient, const edict_t *pViewent ) = 0; + + // Get a high precision timer for doing profiling work + virtual float Time( void ) = 0; + + // Set the player's crosshair angle + virtual void CrosshairAngle( const edict_t *pClient, float pitch, float yaw ) = 0; + + // Get the current game directory (hl2, tf2, hl1, cstrike, etc.) + virtual void GetGameDir( char *szGetGameDir, int maxlength ) = 0; + + // Used by AI node graph code to determine if .bsp and .ain files are out of date + virtual int CompareFileTime( const char *filename1, const char *filename2, int *iCompare ) = 0; + + // Locks/unlocks the network string tables (.e.g, when adding bots to server, this needs to happen). + // Be sure to reset the lock after executing your code!!! + virtual bool LockNetworkStringTables( bool lock ) = 0; + + // Create a bot with the given name. Returns NULL if fake client can't be created + virtual edict_t *CreateFakeClient( const char *netname ) = 0; + + // Get a convar keyvalue for s specified client + virtual const char *GetClientConVarValue( int clientIndex, const char *name ) = 0; + + // Parse a token from a file + virtual const char *ParseFile( const char *data, char *token, int maxlen ) = 0; + // Copies a file + virtual bool CopyFile( const char *source, const char *destination ) = 0; + + // Reset the pvs, pvssize is the size in bytes of the buffer pointed to by pvs. + // This should be called right before any calls to AddOriginToPVS + virtual void ResetPVS( byte *pvs, int pvssize ) = 0; + // Merge the pvs bits into the current accumulated pvs based on the specified origin ( not that each pvs origin has an 8 world unit fudge factor ) + virtual void AddOriginToPVS( const Vector &origin ) = 0; + // Mark a specified area portal as open/closes + virtual void SetAreaPortalState( int portalNumber, int isOpen ) = 0; + // Queue a temp entity for transmission + virtual void PlaybackTempEntity( IRecipientFilter& filter, float delay, const void *pSender, const SendTable *pST, int classID ) = 0; + // Given a node number and the specified PVS, return with the node is in the PVS + virtual int CheckHeadnodeVisible( int nodenum, const byte *pvs, int vissize ) = 0; + // Using area bits, cheeck whether area1 flows into area2 and vice versa (depends on area portal state) + virtual int CheckAreasConnected( int area1, int area2 ) = 0; + // Given an origin, determine which area index the origin is within + virtual int GetArea( const Vector &origin ) = 0; + // Get area portal bit set + virtual void GetAreaBits( int area, unsigned char *bits, int buflen ) = 0; + // Given a view origin (which tells us the area to start looking in) and a portal key, + // fill in the plane that leads out of this area (it points into whatever area it leads to). + virtual bool GetAreaPortalPlane( Vector const &vViewOrigin, int portalKey, VPlane *pPlane ) = 0; + + // Apply a modification to the terrain. + virtual void ApplyTerrainMod( TerrainModType type, CTerrainModParams const ¶ms ) = 0; + + // Save/restore wrapper - FIXME: At some point we should move this to it's own interface + virtual bool LoadGameState( char const *pMapName, bool createPlayers ) = 0; + virtual void LoadAdjacentEnts( const char *pOldLevel, const char *pLandmarkName ) = 0; + virtual void ClearSaveDir() = 0; + + // Get the pristine map entity lump string. (e.g., used by CS to reload the map entities when restarting a round.) + virtual const char* GetMapEntitiesString() = 0; + + // Text message system -- lookup the text message of the specified name + virtual client_textmessage_t *TextMessageGet( const char *pName ) = 0; + + // Print a message to the server log file + virtual void LogPrint( const char *msg ) = 0; + + // Builds PVS information for an entity + virtual void BuildEntityClusterList( edict_t *pEdict, PVSInfo_t *pPVSInfo ) = 0; + + // A solid entity moved, update spatial partition + virtual void SolidMoved( edict_t *pSolidEnt, ICollideable *pSolidCollide, const Vector* pPrevAbsOrigin ) = 0; + // A trigger entity moved, update spatial partition + virtual void TriggerMoved( edict_t *pTriggerEnt ) = 0; + + // Create/destroy a custom spatial partition + virtual ISpatialPartition *CreateSpatialPartition( const Vector& worldmin, const Vector& worldmax ) = 0; + virtual void DestroySpatialPartition( ISpatialPartition * ) = 0; + + // Draw the brush geometry in the map into the scratch pad. + // Flags is currently unused. + virtual void DrawMapToScratchPad( IScratchPad3D *pPad, unsigned long iFlags ) = 0; + + // This returns which entities, to the best of the server's knowledge, the client currently knows about. + // This is really which entities were in the snapshot that this client last acked. + // This returns a bit vector with one bit for each entity. + // + // USE WITH CARE. Whatever tick the client is really currently on is subject to timing and + // ordering differences, so you should account for about a quarter-second discrepancy in here. + // Also, this will return NULL if the client doesn't exist or if this client hasn't acked any frames yet. + // + // iClientIndex is the CLIENT index, so if you use pPlayer->entindex(), subtract 1. + virtual const CBitVec* GetEntityTransmitBitsForClient( int iClientIndex ) = 0; + + // Is the game paused? + virtual bool IsPaused() = 0; + + // Marks the filename for consistency checking. This should be called after precaching the file. + virtual void ForceExactFile( const char *s ) = 0; + virtual void ForceModelBounds( const char *s, const Vector &mins, const Vector &maxs ) = 0; + virtual void ClearSaveDirAfterClientLoad() = 0; + + // Sets a USERINFO client ConVar for a fakeclient + virtual void SetFakeClientConVarValue( edict_t *pEntity, const char *cvar, const char *value ) = 0; + + virtual void InsertServerCommand( const char *str ) = 0; + + // Marks the material (vmt file) for consistency checking. If the client and server have different + // contents for the file, the client's vmt can only use the VertexLitGeneric shader, and can only + // contain $baseTexture and $bumpmap vars. + virtual void ForceSimpleMaterial( const char *s ) = 0; + + + // Is the engine in Commentary mode? + virtual int IsInCommentaryMode( void ) = 0; +}; + +} // end namespace + + +//----------------------------------------------------------------------------- +// Purpose: These are the interfaces that the game .dll exposes to the engine +//----------------------------------------------------------------------------- +#define SERVERGAMEDLL_INTERFACEVERSION_3 "ServerGameDLL003" + +namespace ServerGameDLLV3 +{ + +abstract_class IServerGameDLLV3 +{ +public: + // Initialize the game (one-time call when the DLL is first loaded ) + // Return false if there is an error during startup. + virtual bool DLLInit( CreateInterfaceFn engineFactory, + CreateInterfaceFn physicsFactory, + CreateInterfaceFn fileSystemFactory, + CGlobalVars *pGlobals) = 0; + + // This is called when a new game is started. (restart, map) + virtual bool GameInit( void ) = 0; + + // Called any time a new level is started (after GameInit() also on level transitions within a game) + virtual bool LevelInit( char const *pMapName, + char const *pMapEntities, char const *pOldLevel, + char const *pLandmarkName, bool loadGame, bool background ) = 0; + + // The server is about to activate + virtual void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ) = 0; + + // The server should run physics/think on all edicts + virtual void GameFrame( bool simulating ) = 0; + + // Called once per simulation frame on the final tick + virtual void PreClientUpdate( bool simulating ) = 0; + + // Called when a level is shutdown (including changing levels) + virtual void LevelShutdown( void ) = 0; + // This is called when a game ends (server disconnect, death, restart, load) + // NOT on level transitions within a game + virtual void GameShutdown( void ) = 0; + + // Called once during DLL shutdown + virtual void DLLShutdown( void ) = 0; + + // Get the simulation interval (must be compiled with identical values into both client and game .dll for MOD!!!) + // Right now this is only requested at server startup time so it can't be changed on the fly, etc. + virtual float GetTickInterval( void ) const = 0; + + // Give the list of datatable classes to the engine. The engine matches class names from here with + // edict_t::classname to figure out how to encode a class's data for networking + virtual ServerClass* GetAllServerClasses( void ) = 0; + + // Returns string describing current .dll. e.g., TeamFortress 2, Half-Life 2. + // Hey, it's more descriptive than just the name of the game directory + virtual const char *GetGameDescription( void ) = 0; + + // Let the game .dll allocate it's own network/shared string tables + virtual void CreateNetworkStringTables( void ) = 0; + + // Save/restore system hooks + virtual CSaveRestoreData *SaveInit( int size ) = 0; + virtual void SaveWriteFields( CSaveRestoreData *, const char *, void *, datamap_t *, typedescription_t *, int ) = 0; + virtual void SaveReadFields( CSaveRestoreData *, const char *, void *, datamap_t *, typedescription_t *, int ) = 0; + virtual void SaveGlobalState( CSaveRestoreData * ) = 0; + virtual void RestoreGlobalState( CSaveRestoreData * ) = 0; + virtual void PreSave( CSaveRestoreData * ) = 0; + virtual void Save( CSaveRestoreData * ) = 0; + virtual void GetSaveComment( char *comment, int maxlength ) = 0; + virtual void WriteSaveHeaders( CSaveRestoreData * ) = 0; + virtual void ReadRestoreHeaders( CSaveRestoreData * ) = 0; + virtual void Restore( CSaveRestoreData *, bool ) = 0; + virtual bool IsRestoring() = 0; + + // Returns the number of entities moved across the transition + virtual int CreateEntityTransitionList( CSaveRestoreData *, int ) = 0; + // Build the list of maps adjacent to the current map + virtual void BuildAdjacentMapList( void ) = 0; + + // Retrieve info needed for parsing the specified user message + virtual bool GetUserMessageInfo( int msg_type, char *name, int maxnamelength, int& size ) = 0; + + // Hand over the StandardSendProxies in the game DLL's module. + virtual CStandardSendProxiesV1* GetStandardSendProxies() = 0; +}; + +} // end namespace + + +//----------------------------------------------------------------------------- +// Just an interface version name for the random number interface +// See vstdlib/random.h for the interface definition +// NOTE: If you change this, also change VENGINE_CLIENT_RANDOM_INTERFACE_VERSION in cdll_int.h +//----------------------------------------------------------------------------- +#define VENGINE_SERVER_RANDOM_INTERFACE_VERSION_1 "VEngineRandom001" + +//----------------------------------------------------------------------------- +// Purpose: Interface to get at server entities +//----------------------------------------------------------------------------- +#define SERVERGAMEENTS_INTERFACEVERSION_1 "ServerGameEnts001" + +namespace ServerGameEntsV1 +{ + +abstract_class IServerGameEntsV1 +{ +public: + virtual ~IServerGameEntsV1() {} + + // Only for debugging. Set the edict base so you can get an edict's index in the debugger while debugging the game .dll + virtual void SetDebugEdictBase(edict_t *base) = 0; + + // The engine wants to mark two entities as touching + virtual void MarkEntitiesAsTouching( edict_t *e1, edict_t *e2 ) = 0; + + // Frees the entity attached to this edict + virtual void FreeContainingEntity( edict_t * ) = 0; + + // This allows the engine to get at edicts in a CGameTrace. + virtual edict_t* BaseEntityToEdict( CBaseEntity *pEnt ) = 0; + virtual CBaseEntity* EdictToBaseEntity( edict_t *pEdict ) = 0; + + // This sets a bit in pInfo for each edict in the list that wants to be transmitted to the + // client specified in pInfo. + // + // This is also where an entity can force other entities to be transmitted if it refers to them + // with ehandles. + virtual void CheckTransmit( CCheckTransmitInfo *pInfo, const unsigned short *pEdictIndices, int nEdicts ) = 0; +}; + +} // end namespace ServerGameEntsV1 + + +//----------------------------------------------------------------------------- +// Purpose: Player / Client related functions +//----------------------------------------------------------------------------- +#define SERVERGAMECLIENTS_INTERFACEVERSION_3 "ServerGameClients003" + +namespace ServerGameClientsV3 +{ + +abstract_class IServerGameClientsV3 +{ +public: + // Get server maxplayers and lower bound for same + virtual void GetPlayerLimits( int& minplayers, int& maxplayers, int &defaultMaxPlayers ) const = 0; + + // Client is connecting to server ( return false to reject the connection ) + // You can specify a rejection message by writing it into reject + virtual bool ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen ) = 0; + + // Client is going active + // If bLoadGame is true, don't spawn the player because its state is already setup. + virtual void ClientActive( edict_t *pEntity, bool bLoadGame ) = 0; + + // Client is disconnecting from server + virtual void ClientDisconnect( edict_t *pEntity ) = 0; + + // Client is connected and should be put in the game + virtual void ClientPutInServer( edict_t *pEntity, char const *playername ) = 0; + + // The client has typed a command at the console + virtual void ClientCommand( edict_t *pEntity ) = 0; + + // Sets the client index for the client who typed the command into his/her console + virtual void SetCommandClient( int index ) = 0; + + // A player changed one/several replicated cvars (name etc) + virtual void ClientSettingsChanged( edict_t *pEdict ) = 0; + + // Determine PVS origin and set PVS for the player/viewentity + virtual void ClientSetupVisibility( edict_t *pViewEntity, edict_t *pClient, unsigned char *pvs, int pvssize ) = 0; + + // A block of CUserCmds has arrived from the user, decode them and buffer for execution during player simulation + virtual float ProcessUsercmds( edict_t *player, bf_read *buf, int numcmds, int totalcmds, + int dropped_packets, bool ignore, bool paused ) = 0; + + // Let the game .dll do stuff after messages have been sent to all of the clients once the server frame is complete + virtual void PostClientMessagesSent_DEPRECIATED( void ) = 0; + + // For players, looks up the CPlayerState structure corresponding to the player + virtual CPlayerState *GetPlayerState( edict_t *player ) = 0; + + // Get the ear position for a specified client + virtual void ClientEarPosition( edict_t *pEntity, Vector *pEarOrigin ) = 0; + + // returns number of delay ticks if player is in Replay mode (0 = no delay) + virtual int GetReplayDelay( edict_t *player ) = 0; + + // Anything this game .dll wants to add to the bug reporter text (e.g., the entity/model under the picker crosshair) + // can be added here + virtual void GetBugReportInfo( char *buf, int buflen ) = 0; +}; + +} // end namespace ServerGameClientsV3 + + +#define UPLOADGAMESTATS_INTERFACEVERSION_1 "ServerUploadGameStats001" + +namespace UploadGameStatsV1 +{ + +abstract_class IUploadGameStatsV1 +{ +public: + // Note that this call will block the server until the upload is completed, so use only at levelshutdown if at all. + virtual bool UploadGameStats( + char const *mapname, // Game map name + unsigned int blobversion, // Version of the binary blob data + unsigned int blobsize, // Size in bytes of blob data + const void *pvBlobData ) = 0; // Pointer to the blob data. +}; + +} // end namespace UploadGameStatsV1 + + +#endif // EIFACEV21_H diff --git a/sp/src/public/engine/IClientLeafSystem.h b/sp/src/public/engine/IClientLeafSystem.h new file mode 100644 index 00000000..6efab6a5 --- /dev/null +++ b/sp/src/public/engine/IClientLeafSystem.h @@ -0,0 +1,73 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Revision: $ +// $NoKeywords: $ +// +// This file contains code to allow us to associate client data with bsp leaves. +// +//=============================================================================// + +#if !defined( ICLIENTLEAFSYSTEM_H ) +#define ICLIENTLEAFSYSTEM_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "client_render_handle.h" + + +//----------------------------------------------------------------------------- +// Render groups +//----------------------------------------------------------------------------- +enum RenderGroup_Config_t +{ + // Number of buckets that are used to hold opaque entities + // and opaque static props by size. The bucketing should be used to reduce overdraw. + RENDER_GROUP_CFG_NUM_OPAQUE_ENT_BUCKETS = 4, +}; + +enum RenderGroup_t +{ + RENDER_GROUP_OPAQUE_STATIC_HUGE = 0, // Huge static prop + RENDER_GROUP_OPAQUE_ENTITY_HUGE = 1, // Huge opaque entity + RENDER_GROUP_OPAQUE_STATIC = RENDER_GROUP_OPAQUE_STATIC_HUGE + ( RENDER_GROUP_CFG_NUM_OPAQUE_ENT_BUCKETS - 1 ) * 2, + RENDER_GROUP_OPAQUE_ENTITY, // Opaque entity (smallest size, or default) + + RENDER_GROUP_TRANSLUCENT_ENTITY, + RENDER_GROUP_TWOPASS, // Implied opaque and translucent in two passes + RENDER_GROUP_VIEW_MODEL_OPAQUE, // Solid weapon view models + RENDER_GROUP_VIEW_MODEL_TRANSLUCENT, // Transparent overlays etc + + RENDER_GROUP_OPAQUE_BRUSH, // Brushes + + RENDER_GROUP_OTHER, // Unclassfied. Won't get drawn. + + // This one's always gotta be last + RENDER_GROUP_COUNT +}; + +#define CLIENTLEAFSYSTEM_INTERFACE_VERSION_1 "ClientLeafSystem001" +#define CLIENTLEAFSYSTEM_INTERFACE_VERSION "ClientLeafSystem002" + + +//----------------------------------------------------------------------------- +// The client leaf system +//----------------------------------------------------------------------------- +abstract_class IClientLeafSystemEngine +{ +public: + // Adds and removes renderables from the leaf lists + // CreateRenderableHandle stores the handle inside pRenderable. + virtual void CreateRenderableHandle( IClientRenderable* pRenderable, bool bIsStaticProp = false ) = 0; + virtual void RemoveRenderable( ClientRenderHandle_t handle ) = 0; + virtual void AddRenderableToLeaves( ClientRenderHandle_t renderable, int nLeafCount, unsigned short *pLeaves ) = 0; + virtual void ChangeRenderableRenderGroup( ClientRenderHandle_t handle, RenderGroup_t group ) = 0; +}; + + +#endif // ICLIENTLEAFSYSTEM_H + + diff --git a/sp/src/public/engine/ICollideable.h b/sp/src/public/engine/ICollideable.h new file mode 100644 index 00000000..8906e5a4 --- /dev/null +++ b/sp/src/public/engine/ICollideable.h @@ -0,0 +1,84 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef ENGINE_ICOLLIDEABLE_H +#define ENGINE_ICOLLIDEABLE_H +#ifdef _WIN32 +#pragma once +#endif + + +enum SolidType_t; +class IHandleEntity; +struct Ray_t; +struct model_t; +class Vector; +class QAngle; +class CGameTrace; +typedef CGameTrace trace_t; +class IClientUnknown; + + +abstract_class ICollideable +{ +public: + // Gets at the entity handle associated with the collideable + virtual IHandleEntity *GetEntityHandle() = 0; + + // These methods return the bounds of an OBB measured in "collision" space + // which can be retreived through the CollisionToWorldTransform or + // GetCollisionOrigin/GetCollisionAngles methods + virtual const Vector& OBBMinsPreScaled() const = 0; + virtual const Vector& OBBMaxsPreScaled() const = 0; + virtual const Vector& OBBMins() const = 0; + virtual const Vector& OBBMaxs() const = 0; + + // Returns the bounds of a world-space box used when the collideable is being traced + // against as a trigger. It's only valid to call these methods if the solid flags + // have the FSOLID_USE_TRIGGER_BOUNDS flag set. + virtual void WorldSpaceTriggerBounds( Vector *pVecWorldMins, Vector *pVecWorldMaxs ) const = 0; + + // custom collision test + virtual bool TestCollision( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr ) = 0; + + // Perform hitbox test, returns true *if hitboxes were tested at all*!! + virtual bool TestHitboxes( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr ) = 0; + + // Returns the BRUSH model index if this is a brush model. Otherwise, returns -1. + virtual int GetCollisionModelIndex() = 0; + + // Return the model, if it's a studio model. + virtual const model_t* GetCollisionModel() = 0; + + // Get angles and origin. + virtual const Vector& GetCollisionOrigin() const = 0; + virtual const QAngle& GetCollisionAngles() const = 0; + virtual const matrix3x4_t& CollisionToWorldTransform() const = 0; + + // Return a SOLID_ define. + virtual SolidType_t GetSolid() const = 0; + virtual int GetSolidFlags() const = 0; + + // Gets at the containing class... + virtual IClientUnknown* GetIClientUnknown() = 0; + + // We can filter out collisions based on collision group + virtual int GetCollisionGroup() const = 0; + + // Returns a world-aligned box guaranteed to surround *everything* in the collision representation + // Note that this will surround hitboxes, trigger bounds, physics. + // It may or may not be a tight-fitting box and its volume may suddenly change + virtual void WorldSpaceSurroundingBounds( Vector *pVecMins, Vector *pVecMaxs ) = 0; + + virtual bool ShouldTouchTrigger( int triggerSolidFlags ) const = 0; + + // returns NULL unless this collideable has specified FSOLID_ROOT_PARENT_ALIGNED + virtual const matrix3x4_t *GetRootParentToWorldTransform() const = 0; +}; + + +#endif // ENGINE_ICOLLIDEABLE_H diff --git a/sp/src/public/engine/IEngineSound.h b/sp/src/public/engine/IEngineSound.h new file mode 100644 index 00000000..f4f83a9c --- /dev/null +++ b/sp/src/public/engine/IEngineSound.h @@ -0,0 +1,123 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Client-server neutral sound interface +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef IENGINESOUND_H +#define IENGINESOUND_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "basetypes.h" +#include "interface.h" +#include "soundflags.h" +#include "irecipientfilter.h" +#include "utlvector.h" +#include "engine/SndInfo.h" + +//----------------------------------------------------------------------------- +// forward declaration +//----------------------------------------------------------------------------- +class Vector; + +// Handy defines for EmitSound +#define SOUND_FROM_UI_PANEL -2 // Sound being played inside a UI panel on the client +#define SOUND_FROM_LOCAL_PLAYER -1 +#define SOUND_FROM_WORLD 0 + + + +// These are used to feed a soundlevel to the sound system and have it use +// goldsrc-type attenuation. We should use this as little as possible and +// phase it out as soon as possible. + +// Take a regular sndlevel and convert it to compatibility mode. +#define SNDLEVEL_TO_COMPATIBILITY_MODE( x ) ((soundlevel_t)(int)( (x) + 256 )) + +// Take a compatibility-mode sndlevel and get the REAL sndlevel out of it. +#define SNDLEVEL_FROM_COMPATIBILITY_MODE( x ) ((soundlevel_t)(int)( (x) - 256 )) + +// Tells if the given sndlevel is marked as compatibility mode. +#define SNDLEVEL_IS_COMPATIBILITY_MODE( x ) ( (x) >= 256 ) + + + +//----------------------------------------------------------------------------- +// Client-server neutral effects interface +//----------------------------------------------------------------------------- +#define IENGINESOUND_CLIENT_INTERFACE_VERSION "IEngineSoundClient003" +#define IENGINESOUND_SERVER_INTERFACE_VERSION "IEngineSoundServer003" + +abstract_class IEngineSound +{ +public: + // Precache a particular sample + virtual bool PrecacheSound( const char *pSample, bool bPreload = false, bool bIsUISound = false ) = 0; + virtual bool IsSoundPrecached( const char *pSample ) = 0; + virtual void PrefetchSound( const char *pSample ) = 0; + + // Just loads the file header and checks for duration (not hooked up for .mp3's yet) + // Is accessible to server and client though + virtual float GetSoundDuration( const char *pSample ) = 0; + + // Pitch of 100 is no pitch shift. Pitch > 100 up to 255 is a higher pitch, pitch < 100 + // down to 1 is a lower pitch. 150 to 70 is the realistic range. + // EmitSound with pitch != 100 should be used sparingly, as it's not quite as + // fast (the pitchshift mixer is not native coded). + + // NOTE: setting iEntIndex to -1 will cause the sound to be emitted from the local + // player (client-side only) + virtual void EmitSound( IRecipientFilter& filter, int iEntIndex, int iChannel, const char *pSample, + float flVolume, float flAttenuation, int iFlags = 0, int iPitch = PITCH_NORM, int iSpecialDSP = 0, + const Vector *pOrigin = NULL, const Vector *pDirection = NULL, CUtlVector< Vector >* pUtlVecOrigins = NULL, bool bUpdatePositions = true, float soundtime = 0.0f, int speakerentity = -1 ) = 0; + + virtual void EmitSound( IRecipientFilter& filter, int iEntIndex, int iChannel, const char *pSample, + float flVolume, soundlevel_t iSoundlevel, int iFlags = 0, int iPitch = PITCH_NORM, int iSpecialDSP = 0, + const Vector *pOrigin = NULL, const Vector *pDirection = NULL, CUtlVector< Vector >* pUtlVecOrigins = NULL, bool bUpdatePositions = true, float soundtime = 0.0f, int speakerentity = -1 ) = 0; + + virtual void EmitSentenceByIndex( IRecipientFilter& filter, int iEntIndex, int iChannel, int iSentenceIndex, + float flVolume, soundlevel_t iSoundlevel, int iFlags = 0, int iPitch = PITCH_NORM,int iSpecialDSP = 0, + const Vector *pOrigin = NULL, const Vector *pDirection = NULL, CUtlVector< Vector >* pUtlVecOrigins = NULL, bool bUpdatePositions = true, float soundtime = 0.0f, int speakerentity = -1 ) = 0; + + virtual void StopSound( int iEntIndex, int iChannel, const char *pSample ) = 0; + + // stop all active sounds (client only) + virtual void StopAllSounds(bool bClearBuffers) = 0; + + // Set the room type for a player (client only) + virtual void SetRoomType( IRecipientFilter& filter, int roomType ) = 0; + + // Set the dsp preset for a player (client only) + virtual void SetPlayerDSP( IRecipientFilter& filter, int dspType, bool fastReset ) = 0; + + // emit an "ambient" sound that isn't spatialized + // only available on the client, assert on server + virtual void EmitAmbientSound( const char *pSample, float flVolume, int iPitch = PITCH_NORM, int flags = 0, float soundtime = 0.0f ) = 0; + + +// virtual EntChannel_t CreateEntChannel() = 0; + + virtual float GetDistGainFromSoundLevel( soundlevel_t soundlevel, float dist ) = 0; + + // Client .dll only functions + virtual int GetGuidForLastSoundEmitted() = 0; + virtual bool IsSoundStillPlaying( int guid ) = 0; + virtual void StopSoundByGuid( int guid ) = 0; + // Set's master volume (0.0->1.0) + virtual void SetVolumeByGuid( int guid, float fvol ) = 0; + + // Retrieves list of all active sounds + virtual void GetActiveSounds( CUtlVector< SndInfo_t >& sndlist ) = 0; + + virtual void PrecacheSentenceGroup( const char *pGroupName ) = 0; + virtual void NotifyBeginMoviePlayback() = 0; + virtual void NotifyEndMoviePlayback() = 0; +}; + + +#endif // IENGINESOUND_H diff --git a/sp/src/public/engine/IEngineTrace.h b/sp/src/public/engine/IEngineTrace.h new file mode 100644 index 00000000..6e497719 --- /dev/null +++ b/sp/src/public/engine/IEngineTrace.h @@ -0,0 +1,192 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#ifndef ENGINE_IENGINETRACE_H +#define ENGINE_IENGINETRACE_H +#ifdef _WIN32 +#pragma once +#endif + +#include "basehandle.h" +#include "utlvector.h" //need CUtlVector for IEngineTrace::GetBrushesIn*() +#include "mathlib/vector4d.h" + +class Vector; +class IHandleEntity; +struct Ray_t; +class CGameTrace; +typedef CGameTrace trace_t; +class ICollideable; +class QAngle; +class CTraceListData; +class CPhysCollide; +struct cplane_t; + +//----------------------------------------------------------------------------- +// The standard trace filter... NOTE: Most normal traces inherit from CTraceFilter!!! +//----------------------------------------------------------------------------- +enum TraceType_t +{ + TRACE_EVERYTHING = 0, + TRACE_WORLD_ONLY, // NOTE: This does *not* test static props!!! + TRACE_ENTITIES_ONLY, // NOTE: This version will *not* test static props + TRACE_EVERYTHING_FILTER_PROPS, // NOTE: This version will pass the IHandleEntity for props through the filter, unlike all other filters +}; + +abstract_class ITraceFilter +{ +public: + virtual bool ShouldHitEntity( IHandleEntity *pEntity, int contentsMask ) = 0; + virtual TraceType_t GetTraceType() const = 0; +}; + + +//----------------------------------------------------------------------------- +// Classes are expected to inherit these + implement the ShouldHitEntity method +//----------------------------------------------------------------------------- + +// This is the one most normal traces will inherit from +class CTraceFilter : public ITraceFilter +{ +public: + virtual TraceType_t GetTraceType() const + { + return TRACE_EVERYTHING; + } +}; + +class CTraceFilterEntitiesOnly : public ITraceFilter +{ +public: + virtual TraceType_t GetTraceType() const + { + return TRACE_ENTITIES_ONLY; + } +}; + + +//----------------------------------------------------------------------------- +// Classes need not inherit from these +//----------------------------------------------------------------------------- +class CTraceFilterWorldOnly : public ITraceFilter +{ +public: + bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask ) + { + return false; + } + virtual TraceType_t GetTraceType() const + { + return TRACE_WORLD_ONLY; + } +}; + +class CTraceFilterWorldAndPropsOnly : public ITraceFilter +{ +public: + bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask ) + { + return false; + } + virtual TraceType_t GetTraceType() const + { + return TRACE_EVERYTHING; + } +}; + +class CTraceFilterHitAll : public CTraceFilter +{ +public: + virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask ) + { + return true; + } +}; + + +//----------------------------------------------------------------------------- +// Enumeration interface for EnumerateLinkEntities +//----------------------------------------------------------------------------- +abstract_class IEntityEnumerator +{ +public: + // This gets called with each handle + virtual bool EnumEntity( IHandleEntity *pHandleEntity ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Interface the engine exposes to the game DLL +//----------------------------------------------------------------------------- +#define INTERFACEVERSION_ENGINETRACE_SERVER "EngineTraceServer003" +#define INTERFACEVERSION_ENGINETRACE_CLIENT "EngineTraceClient003" +abstract_class IEngineTrace +{ +public: + // Returns the contents mask + entity at a particular world-space position + virtual int GetPointContents( const Vector &vecAbsPosition, IHandleEntity** ppEntity = NULL ) = 0; + + // Get the point contents, but only test the specific entity. This works + // on static props and brush models. + // + // If the entity isn't a static prop or a brush model, it returns CONTENTS_EMPTY and sets + // bFailed to true if bFailed is non-null. + virtual int GetPointContents_Collideable( ICollideable *pCollide, const Vector &vecAbsPosition ) = 0; + + // Traces a ray against a particular entity + virtual void ClipRayToEntity( const Ray_t &ray, unsigned int fMask, IHandleEntity *pEnt, trace_t *pTrace ) = 0; + + // Traces a ray against a particular entity + virtual void ClipRayToCollideable( const Ray_t &ray, unsigned int fMask, ICollideable *pCollide, trace_t *pTrace ) = 0; + + // A version that simply accepts a ray (can work as a traceline or tracehull) + virtual void TraceRay( const Ray_t &ray, unsigned int fMask, ITraceFilter *pTraceFilter, trace_t *pTrace ) = 0; + + // A version that sets up the leaf and entity lists and allows you to pass those in for collision. + virtual void SetupLeafAndEntityListRay( const Ray_t &ray, CTraceListData &traceData ) = 0; + virtual void SetupLeafAndEntityListBox( const Vector &vecBoxMin, const Vector &vecBoxMax, CTraceListData &traceData ) = 0; + virtual void TraceRayAgainstLeafAndEntityList( const Ray_t &ray, CTraceListData &traceData, unsigned int fMask, ITraceFilter *pTraceFilter, trace_t *pTrace ) = 0; + + // A version that sweeps a collideable through the world + // abs start + abs end represents the collision origins you want to sweep the collideable through + // vecAngles represents the collision angles of the collideable during the sweep + virtual void SweepCollideable( ICollideable *pCollide, const Vector &vecAbsStart, const Vector &vecAbsEnd, + const QAngle &vecAngles, unsigned int fMask, ITraceFilter *pTraceFilter, trace_t *pTrace ) = 0; + + // Enumerates over all entities along a ray + // If triggers == true, it enumerates all triggers along a ray + virtual void EnumerateEntities( const Ray_t &ray, bool triggers, IEntityEnumerator *pEnumerator ) = 0; + + // Same thing, but enumerate entitys within a box + virtual void EnumerateEntities( const Vector &vecAbsMins, const Vector &vecAbsMaxs, IEntityEnumerator *pEnumerator ) = 0; + + // Convert a handle entity to a collideable. Useful inside enumer + virtual ICollideable *GetCollideable( IHandleEntity *pEntity ) = 0; + + // HACKHACK: Temp for performance measurments + virtual int GetStatByIndex( int index, bool bClear ) = 0; + + + //finds brushes in an AABB, prone to some false positives + virtual void GetBrushesInAABB( const Vector &vMins, const Vector &vMaxs, CUtlVector *pOutput, int iContentsMask = 0xFFFFFFFF ) = 0; + + //Creates a CPhysCollide out of all displacements wholly or partially contained in the specified AABB + virtual CPhysCollide* GetCollidableFromDisplacementsInAABB( const Vector& vMins, const Vector& vMaxs ) = 0; + + //retrieve brush planes and contents, returns true if data is being returned in the output pointers, false if the brush doesn't exist + virtual bool GetBrushInfo( int iBrush, CUtlVector *pPlanesOut, int *pContentsOut ) = 0; + + virtual bool PointOutsideWorld( const Vector &ptTest ) = 0; //Tests a point to see if it's outside any playable area + + // Walks bsp to find the leaf containing the specified point + virtual int GetLeafContainingPoint( const Vector &ptTest ) = 0; +}; + + + +#endif // ENGINE_IENGINETRACE_H diff --git a/sp/src/public/engine/IStaticPropMgr.h b/sp/src/public/engine/IStaticPropMgr.h new file mode 100644 index 00000000..ed6cc3cd --- /dev/null +++ b/sp/src/public/engine/IStaticPropMgr.h @@ -0,0 +1,100 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef IPROPS_H +#define IPROPS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "interface.h" +#include "mathlib/vector.h" +#include "utlvector.h" +#include "basehandle.h" + + +struct vcollide_t; +struct Ray_t; +class IClientRenderable; +class CGameTrace; +typedef CGameTrace trace_t; +class IVPhysicsKeyHandler; +class IPhysicsEnvironment; +class ICollideable; + + +//----------------------------------------------------------------------------- +// Interface versions for static props +//----------------------------------------------------------------------------- +#define INTERFACEVERSION_STATICPROPMGR_CLIENT "StaticPropMgrClient004" +#define INTERFACEVERSION_STATICPROPMGR_SERVER "StaticPropMgrServer002" + + +//----------------------------------------------------------------------------- +// Interface for static props +//----------------------------------------------------------------------------- +abstract_class IStaticPropMgr +{ +public: + // Create physics representations of props + virtual void CreateVPhysicsRepresentations( IPhysicsEnvironment *physenv, IVPhysicsKeyHandler *pDefaults, void *pGameData ) = 0; + + // Purpose: Trace a ray against the specified static Prop. Returns point of intersection in trace_t + virtual void TraceRayAgainstStaticProp( const Ray_t& ray, int staticPropIndex, trace_t& tr ) = 0; + + // Is a base handle a static prop? + virtual bool IsStaticProp( IHandleEntity *pHandleEntity ) const = 0; + virtual bool IsStaticProp( CBaseHandle handle ) const = 0; + + // returns a collideable interface to static props + virtual ICollideable *GetStaticPropByIndex( int propIndex ) = 0; +}; + +abstract_class IStaticPropMgrClient : public IStaticPropMgr +{ +public: + // Recomputes the static prop opacity given a view origin + virtual void ComputePropOpacity( const Vector &viewOrigin, float factor ) = 0; + + // Adds decals to static props, returns point of decal in trace_t + virtual void AddDecalToStaticProp( const Vector& rayStart, const Vector& rayEnd, + int staticPropIndex, int decalIndex, bool doTrace, trace_t& tr ) = 0; + // Adds/removes shadows from static props + virtual void AddShadowToStaticProp( unsigned short shadowHandle, IClientRenderable* pRenderable ) = 0; + virtual void RemoveAllShadowsFromStaticProp( IClientRenderable* pRenderable ) = 0; + + // Gets the lighting + material color of a static prop + virtual void GetStaticPropMaterialColorAndLighting( trace_t* pTrace, + int staticPropIndex, Vector& lighting, Vector& matColor ) = 0; + + //Changes made specifically to support the Portal mod (smack Dave Kircher if something breaks) (Added separately to both client and server to not mess with versioning) + //=================================================================== + virtual void GetAllStaticProps( CUtlVector *pOutput ) = 0; //testing function that will eventually be removed + virtual void GetAllStaticPropsInAABB( const Vector &vMins, const Vector &vMaxs, CUtlVector *pOutput ) = 0; //get all static props that exist wholly or partially in an AABB + virtual void GetAllStaticPropsInOBB( const Vector &ptOrigin, const Vector &vExtent1, const Vector &vExtent2, const Vector &vExtent3, CUtlVector *pOutput ) = 0; //get all static props that exist wholly or partially in an OBB + //=================================================================== + + virtual void DrawStaticProps( IClientRenderable **pProps, int count, bool bShadowDepth, bool drawVCollideWireframe ) = 0; + virtual void AddColorDecalToStaticProp( Vector const& rayStart, Vector const& rayEnd, + int staticPropIndex, int decalIndex, bool doTrace, trace_t& tr, bool bUseColor, Color cColor ) = 0; +}; + +class IStaticPropMgrServer : public IStaticPropMgr +{ +public: + + + //Changes made specifically to support the Portal mod (smack Dave Kircher if something breaks) (Added separately to both client and server to not mess with versioning) + //=================================================================== + virtual void GetAllStaticProps( CUtlVector *pOutput ) = 0; //testing function that will eventually be removed + virtual void GetAllStaticPropsInAABB( const Vector &vMins, const Vector &vMaxs, CUtlVector *pOutput ) = 0; //get all static props that exist wholly or partially in an AABB + virtual void GetAllStaticPropsInOBB( const Vector &ptOrigin, const Vector &vExtent1, const Vector &vExtent2, const Vector &vExtent3, CUtlVector *pOutput ) = 0; //get all static props that exist wholly or partially in an OBB + //=================================================================== +}; + + +#endif // IPROPS_H diff --git a/sp/src/public/engine/SndInfo.h b/sp/src/public/engine/SndInfo.h new file mode 100644 index 00000000..a3628f2f --- /dev/null +++ b/sp/src/public/engine/SndInfo.h @@ -0,0 +1,51 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef SNDINFO_H +#define SNDINFO_H +#ifdef _WIN32 +#pragma once +#endif + +class Vector; +#include "utlsymbol.h" + +//----------------------------------------------------------------------------- +// Purpose: Client side only +//----------------------------------------------------------------------------- +struct SndInfo_t +{ + // Sound Guid + int m_nGuid; + FileNameHandle_t m_filenameHandle; // filesystem filename handle - call IFilesystem to conver this to a string + int m_nSoundSource; + int m_nChannel; + // If a sound is being played through a speaker entity (e.g., on a monitor,), this is the + // entity upon which to show the lips moving, if the sound has sentence data + int m_nSpeakerEntity; + float m_flVolume; + float m_flLastSpatializedVolume; + // Radius of this sound effect (spatialization is different within the radius) + float m_flRadius; + int m_nPitch; + Vector *m_pOrigin; + Vector *m_pDirection; + + // if true, assume sound source can move and update according to entity + bool m_bUpdatePositions; + // true if playing linked sentence + bool m_bIsSentence; + // if true, bypass all dsp processing for this sound (ie: music) + bool m_bDryMix; + // true if sound is playing through in-game speaker entity. + bool m_bSpeaker; + // true if sound is playing with special DSP effect + bool m_bSpecialDSP; + // for snd_show, networked sounds get colored differently than local sounds + bool m_bFromServer; +}; + +#endif // SNDINFO_H diff --git a/sp/src/public/engine/http.h b/sp/src/public/engine/http.h new file mode 100644 index 00000000..79fd1dcd --- /dev/null +++ b/sp/src/public/engine/http.h @@ -0,0 +1,44 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +//=======================================================================================// + +#ifndef HTTP_H +#define HTTP_H + +#ifdef _WIN32 +#pragma once +#endif + +//-------------------------------------------------------------------------------------------------------------- +/** + * Status of the download thread, as set in RequestContext::status. + */ +enum HTTPStatus_t +{ + HTTP_INVALID = -1, + HTTP_CONNECTING = 0,///< This is set in the main thread before the download thread starts. + HTTP_FETCH, ///< The download thread sets this when it starts reading data. + HTTP_DONE, ///< The download thread sets this if it has read all the data successfully. + HTTP_ABORTED, ///< The download thread sets this if it aborts because it's RequestContext::shouldStop has been set. + HTTP_ERROR ///< The download thread sets this if there is an error connecting or downloading. Partial data may be present, so the main thread can check. +}; + +//-------------------------------------------------------------------------------------------------------------- +/** + * Error encountered in the download thread, as set in RequestContext::error. + */ +enum HTTPError_t +{ + HTTP_ERROR_NONE = 0, + HTTP_ERROR_ZERO_LENGTH_FILE, + HTTP_ERROR_CONNECTION_CLOSED, + HTTP_ERROR_INVALID_URL, ///< InternetCrackUrl failed + HTTP_ERROR_INVALID_PROTOCOL, ///< URL didn't start with http:// or https:// + HTTP_ERROR_CANT_BIND_SOCKET, + HTTP_ERROR_CANT_CONNECT, + HTTP_ERROR_NO_HEADERS, ///< Cannot read HTTP headers + HTTP_ERROR_FILE_NONEXISTENT, + HTTP_ERROR_MAX +}; + +#endif // HTTP_H diff --git a/sp/src/public/engine/ienginevoice.h b/sp/src/public/engine/ienginevoice.h new file mode 100644 index 00000000..aab5f99a --- /dev/null +++ b/sp/src/public/engine/ienginevoice.h @@ -0,0 +1,42 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Engine voice interface +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef IENGINEVOICE_H +#define IENGINEVOICE_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "basetypes.h" + +#define IENGINEVOICE_INTERFACE_VERSION "IEngineVoice001" + +abstract_class IEngineVoice +{ +public: + virtual bool IsHeadsetPresent( int iController ) = 0; + virtual bool IsLocalPlayerTalking( int iController ) = 0; + + virtual void AddPlayerToVoiceList( XUID xPlayer, int iController ) = 0; + virtual void RemovePlayerFromVoiceList( XUID xPlayer, int iController ) = 0; + + virtual void GetRemoteTalkers( int *pNumTalkers, XUID *pRemoteTalkers ) = 0; + + virtual bool VoiceUpdateData( int iController ) = 0; + virtual void GetVoiceData( int iController, const byte **ppvVoiceDataBuffer, unsigned int *pnumVoiceDataBytes ) = 0; + virtual void VoiceResetLocalData( int iController ) = 0; + + virtual void SetPlaybackPriority( XUID remoteTalker, int iController, int iAllowPlayback ) = 0; + virtual void PlayIncomingVoiceData( XUID xuid, const byte *pbData, unsigned int dwDataSize, const bool *bAudiblePlayers = NULL ) = 0; + + virtual void RemoveAllTalkers() = 0; +}; + + +#endif // IENGINEVOICE_H diff --git a/sp/src/public/engine/imatchmaking.h b/sp/src/public/engine/imatchmaking.h new file mode 100644 index 00000000..4c9aa81f --- /dev/null +++ b/sp/src/public/engine/imatchmaking.h @@ -0,0 +1,117 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#ifndef IMATCHMAKING_H +#define IMATCHMAKING_H +#ifdef _WIN32 +#pragma once +#endif + +#include "const.h" +#include "vgui/VGUI.h" + +#if !defined( _X360 ) +#include "xbox/xboxstubs.h" +#endif + +class KeyValues; + +enum SESSION_NOTIFY +{ + SESSION_NOTIFY_FAIL_SEARCH, + SESSION_NOTIFY_SEARCH_COMPLETED, + SESSION_NOFIFY_MODIFYING_SESSION, + SESSION_NOTIFY_MODIFYING_COMPLETED_HOST, + SESSION_NOTIFY_MODIFYING_COMPLETED_CLIENT, + SESSION_NOTIFY_MIGRATION_COMPLETED, + SESSION_NOTIFY_CONNECT_SESSIONFULL, + SESSION_NOTIFY_CONNECT_NOTAVAILABLE, + SESSION_NOTIFY_CONNECTED_TOSESSION, + SESSION_NOTIFY_CONNECTED_TOSERVER, + SESSION_NOTIFY_CONNECT_FAILED, + SESSION_NOTIFY_FAIL_CREATE, + SESSION_NOTIFY_FAIL_MIGRATE, + SESSION_NOTIFY_REGISTER_COMPLETED, + SESSION_NOTIFY_FAIL_REGISTER, + SESSION_NOTIFY_CLIENT_KICKED, + SESSION_NOTIFY_CREATED_HOST, + SESSION_NOTIFY_CREATED_CLIENT, + SESSION_NOTIFY_LOST_HOST, + SESSION_NOTIFY_LOST_SERVER, + SESSION_NOTIFY_COUNTDOWN, + SESSION_NOTIFY_ENDGAME_RANKED, // Ranked + SESSION_NOTIFY_ENDGAME_HOST, // Unranked + SESSION_NOTIFY_ENDGAME_CLIENT, // Unranked + SESSION_NOTIFY_DUMPSTATS, // debugging + SESSION_NOTIFY_WELCOME, // Close all dialogs and show the welcome main menu +}; + +enum SESSION_PROPS +{ + SESSION_CONTEXT, + SESSION_PROPERTY, + SESSION_FLAG, +}; + +struct hostData_s +{ + char hostName[MAX_PLAYER_NAME_LENGTH]; + char scenario[MAX_MAP_NAME]; + int gameState; + int gameTime; + XUID xuid; +}; + +struct MM_QOS_t +{ + int nPingMsMin; // Minimum round-trip time in ms + int nPingMsMed; // Median round-trip time in ms + float flBwUpKbs; // Bandwidth upstream in kilobytes/s + float flBwDnKbs; // Bandwidth downstream in kilobytes/s + float flLoss; // Average packet loss in percents +}; + +#define NO_TIME_LIMIT 65000 + +abstract_class IMatchmaking +{ +public: + virtual void SessionNotification( const SESSION_NOTIFY notification, const int param = 0 ) = 0; + virtual void AddSessionProperty( const uint nType, const char *pID, const char *pValue, const char *pValueType ) = 0; + virtual void SetSessionProperties( KeyValues *pPropertyKeys ) = 0; + virtual void SelectSession( uint idx ) = 0; + virtual void ModifySession() = 0; + virtual void UpdateMuteList() = 0; + virtual void StartHost( bool bSystemLink = false ) = 0; + virtual void StartClient( bool bSystemLink = false ) = 0; + virtual bool StartGame() = 0; + virtual bool CancelStartGame() = 0; + virtual void ChangeTeam( const char *pTeamName ) = 0; + virtual void TellClientsToConnect() = 0; + virtual void CancelCurrentOperation() = 0; + virtual void KickPlayerFromSession( uint64 id ) = 0; + virtual void JoinInviteSession( XSESSION_INFO *pHostInfo ) = 0; + virtual void JoinInviteSessionByID( XNKID nSessionID ) = 0; + virtual void EndStatsReporting() = 0; + + // For Gameui + virtual KeyValues *GetSessionProperties() = 0; + + // For voice chat + virtual uint64 PlayerIdToXuid( int playerId ) = 0; + virtual bool IsPlayerMuted( int iUserId, XUID id ) = 0; + + // To determine host Quality-of-Service + virtual MM_QOS_t GetQosWithLIVE() = 0; + + // Used by non-'host' local machines which are starting a map to "prime" the caches. Will sit at near completion indefinitely -- + // the client is waiting for a TellClientsToConnect message + virtual bool PreventFullServerStartup() = 0; +}; + +#define VENGINE_MATCHMAKING_VERSION "VENGINE_MATCHMAKING_VERSION001" + +#endif // IMATCHMAKING_H diff --git a/sp/src/public/engine/iserverplugin.h b/sp/src/public/engine/iserverplugin.h new file mode 100644 index 00000000..608583ba --- /dev/null +++ b/sp/src/public/engine/iserverplugin.h @@ -0,0 +1,163 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#ifndef ISERVERPLUGIN_H +#define ISERVERPLUGIN_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "edict.h" +#include "tier1/interface.h" +#include "tier1/KeyValues.h" + +class CCommand; + +// +// you will also want to listen for game events via IGameEventManager::AddListener() +// + +typedef enum +{ + PLUGIN_CONTINUE = 0, // keep going + PLUGIN_OVERRIDE, // run the game dll function but use our return value instead + PLUGIN_STOP, // don't run the game dll function at all +} PLUGIN_RESULT; + + +typedef enum +{ + eQueryCvarValueStatus_ValueIntact=0, // It got the value fine. + eQueryCvarValueStatus_CvarNotFound=1, + eQueryCvarValueStatus_NotACvar=2, // There's a ConCommand, but it's not a ConVar. + eQueryCvarValueStatus_CvarProtected=3 // The cvar was marked with FCVAR_SERVER_CAN_NOT_QUERY, so the server is not allowed to have its value. +} EQueryCvarValueStatus; + + +typedef int QueryCvarCookie_t; +#define InvalidQueryCvarCookie -1 + + +#define INTERFACEVERSION_ISERVERPLUGINCALLBACKS_VERSION_1 "ISERVERPLUGINCALLBACKS001" +#define INTERFACEVERSION_ISERVERPLUGINCALLBACKS_VERSION_2 "ISERVERPLUGINCALLBACKS002" +#define INTERFACEVERSION_ISERVERPLUGINCALLBACKS "ISERVERPLUGINCALLBACKS003" + +//----------------------------------------------------------------------------- +// Purpose: callbacks the engine exposes to the 3rd party plugins (ala MetaMod) +//----------------------------------------------------------------------------- +abstract_class IServerPluginCallbacks +{ +public: + // Initialize the plugin to run + // Return false if there is an error during startup. + virtual bool Load( CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory ) = 0; + + // Called when the plugin should be shutdown + virtual void Unload( void ) = 0; + + // called when a plugins execution is stopped but the plugin is not unloaded + virtual void Pause( void ) = 0; + + // called when a plugin should start executing again (sometime after a Pause() call) + virtual void UnPause( void ) = 0; + + // Returns string describing current plugin. e.g., Admin-Mod. + virtual const char *GetPluginDescription( void ) = 0; + + // Called any time a new level is started (after GameInit() also on level transitions within a game) + virtual void LevelInit( char const *pMapName ) = 0; + + // The server is about to activate + virtual void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ) = 0; + + // The server should run physics/think on all edicts + virtual void GameFrame( bool simulating ) = 0; + + // Called when a level is shutdown (including changing levels) + virtual void LevelShutdown( void ) = 0; + + // Client is going active + virtual void ClientActive( edict_t *pEntity ) = 0; + + // Client is disconnecting from server + virtual void ClientDisconnect( edict_t *pEntity ) = 0; + + // Client is connected and should be put in the game + virtual void ClientPutInServer( edict_t *pEntity, char const *playername ) = 0; + + // Sets the client index for the client who typed the command into their console + virtual void SetCommandClient( int index ) = 0; + + // A player changed one/several replicated cvars (name etc) + virtual void ClientSettingsChanged( edict_t *pEdict ) = 0; + + // Client is connecting to server ( set retVal to false to reject the connection ) + // You can specify a rejection message by writing it into reject + virtual PLUGIN_RESULT ClientConnect( bool *bAllowConnect, edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen ) = 0; + + // The client has typed a command at the console + virtual PLUGIN_RESULT ClientCommand( edict_t *pEntity, const CCommand &args ) = 0; + + // A user has had their network id setup and validated + virtual PLUGIN_RESULT NetworkIDValidated( const char *pszUserName, const char *pszNetworkID ) = 0; + + // This is called when a query from IServerPluginHelpers::StartQueryCvarValue is finished. + // iCookie is the value returned by IServerPluginHelpers::StartQueryCvarValue. + // Added with version 2 of the interface. + virtual void OnQueryCvarValueFinished( QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue ) = 0; + + // added with version 3 of the interface. + virtual void OnEdictAllocated( edict_t *edict ) = 0; + virtual void OnEdictFreed( const edict_t *edict ) = 0; +}; + +#define INTERFACEVERSION_ISERVERPLUGINHELPERS "ISERVERPLUGINHELPERS001" + + +typedef enum +{ + DIALOG_MSG = 0, // just an on screen message + DIALOG_MENU, // an options menu + DIALOG_TEXT, // a richtext dialog + DIALOG_ENTRY, // an entry box + DIALOG_ASKCONNECT // Ask the client to connect to a specified IP address. Only the "time" and "title" keys are used. +} DIALOG_TYPE; + +//----------------------------------------------------------------------------- +// Purpose: functions that only 3rd party plugins need +//----------------------------------------------------------------------------- +abstract_class IServerPluginHelpers +{ +public: + // creates an onscreen menu with various option buttons + // The keyvalues param can contain these fields: + // "title" - (string) the title to show in the hud and in the title bar + // "msg" - (string) a longer message shown in the GameUI + // "color" - (color) the color to display the message in the hud (white by default) + // "level" - (int) the priority of this message (closer to 0 is higher), only 1 message can be outstanding at a time + // "time" - (int) the time in seconds this message should stay active in the GameUI (min 10 sec, max 200 sec) + // + // For DIALOG_MENU add sub keys for each option with these fields: + // "command" - (string) client command to run if selected + // "msg" - (string) button text for this option + // + virtual void CreateMessage( edict_t *pEntity, DIALOG_TYPE type, KeyValues *data, IServerPluginCallbacks *plugin ) = 0; + virtual void ClientCommand( edict_t *pEntity, const char *cmd ) = 0; + + // Call this to find out the value of a cvar on the client. + // + // It is an asynchronous query, and it will call IServerPluginCallbacks::OnQueryCvarValueFinished when + // the value comes in from the client. + // + // Store the return value if you want to match this specific query to the OnQueryCvarValueFinished call. + // Returns InvalidQueryCvarCookie if the entity is invalid. + virtual QueryCvarCookie_t StartQueryCvarValue( edict_t *pEntity, const char *pName ) = 0; +}; + +#endif //ISERVERPLUGIN_H diff --git a/sp/src/public/engine/ishadowmgr.h b/sp/src/public/engine/ishadowmgr.h new file mode 100644 index 00000000..5165a8ab --- /dev/null +++ b/sp/src/public/engine/ishadowmgr.h @@ -0,0 +1,190 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#ifndef ISHADOWMGR_H +#define ISHADOWMGR_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "interface.h" +#include "mathlib/vmatrix.h" + + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- + +class IMaterial; +class Vector; +class Vector2D; +struct model_t; +typedef unsigned short ModelInstanceHandle_t; +class IClientRenderable; +class ITexture; + +// change this when the new version is incompatable with the old +#define ENGINE_SHADOWMGR_INTERFACE_VERSION "VEngineShadowMgr002" + + +//----------------------------------------------------------------------------- +// Flags for the creation method +//----------------------------------------------------------------------------- +enum ShadowFlags_t +{ + SHADOW_FLAGS_FLASHLIGHT = (1 << 0), + SHADOW_FLAGS_SHADOW = (1 << 1), + + // Update this if you add flags + SHADOW_FLAGS_LAST_FLAG = SHADOW_FLAGS_SHADOW +}; + +#define SHADOW_FLAGS_PROJECTED_TEXTURE_TYPE_MASK ( SHADOW_FLAGS_FLASHLIGHT | SHADOW_FLAGS_SHADOW ) + + +//----------------------------------------------------------------------------- +// +// Shadow-related functionality exported by the engine +// +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// This is a handle to shadows, clients can create as many as they want +//----------------------------------------------------------------------------- +typedef unsigned short ShadowHandle_t; + +enum +{ + SHADOW_HANDLE_INVALID = (ShadowHandle_t)~0 +}; + + +//----------------------------------------------------------------------------- +// Used for the creation Flags field of CreateShadow +//----------------------------------------------------------------------------- +enum ShadowCreateFlags_t +{ + SHADOW_CACHE_VERTS = ( 1 << 0 ), + SHADOW_FLASHLIGHT = ( 1 << 1 ), + + SHADOW_LAST_FLAG = SHADOW_FLASHLIGHT, +}; + + +//----------------------------------------------------------------------------- +// Information about a particular shadow +//----------------------------------------------------------------------------- +struct ShadowInfo_t +{ + // Transforms from world space into texture space of the shadow + VMatrix m_WorldToShadow; + + // The shadow should no longer be drawn once it's further than MaxDist + // along z in shadow texture coordinates. + float m_FalloffOffset; + float m_MaxDist; + float m_FalloffAmount; // how much to lighten the shadow maximally + Vector2D m_TexOrigin; + Vector2D m_TexSize; + unsigned char m_FalloffBias; +}; + +struct FlashlightState_t; + +//----------------------------------------------------------------------------- +// The engine's interface to the shadow manager +//----------------------------------------------------------------------------- +abstract_class IShadowMgr +{ +public: + // Create, destroy shadows (see ShadowCreateFlags_t for creationFlags) + virtual ShadowHandle_t CreateShadow( IMaterial* pMaterial, IMaterial* pModelMaterial, void* pBindProxy, int creationFlags ) = 0; + virtual void DestroyShadow( ShadowHandle_t handle ) = 0; + + // Resets the shadow material (useful for shadow LOD.. doing blobby at distance) + virtual void SetShadowMaterial( ShadowHandle_t handle, IMaterial* pMaterial, IMaterial* pModelMaterial, void* pBindProxy ) = 0; + + // Shadow opacity +// virtual void SetShadowOpacity( ShadowHandle_t handle, float alpha ) = 0; +// virtual float GetShadowOpacity( ShadowHandle_t handle ) const = 0; + + // Project a shadow into the world + // The two points specify the upper left coordinate and the lower-right + // coordinate of the shadow specified in a shadow "viewplane". The + // projection matrix is a shadow viewplane->world transformation, + // and can be orthographic orperspective. + + // I expect that the client DLL will call this method any time the shadow + // changes because the light changes, or because the entity casting the + // shadow moves + + // Note that we can't really control the shadows from the engine because + // the engine only knows about pevs, which don't exist on the client + + // The shadow matrix specifies a world-space transform for the shadow + // the shadow is projected down the z direction, and the origin of the + // shadow matrix is the origin of the projection ray. The size indicates + // the shadow size measured in the space of the shadow matrix; the + // shadow goes from +/- size.x/2 along the x axis of the shadow matrix + // and +/- size.y/2 along the y axis of the shadow matrix. + virtual void ProjectShadow( ShadowHandle_t handle, const Vector &origin, + const Vector& projectionDir, const VMatrix& worldToShadow, const Vector2D& size, + int nLeafCount, const int *pLeafList, + float maxHeight, float falloffOffset, float falloffAmount, const Vector &vecCasterOrigin ) = 0; + + virtual void ProjectFlashlight( ShadowHandle_t handle, const VMatrix &worldToShadow, int nLeafCount, const int *pLeafList ) = 0; + + // Gets at information about a particular shadow + virtual const ShadowInfo_t &GetInfo( ShadowHandle_t handle ) = 0; + + virtual const Frustum_t &GetFlashlightFrustum( ShadowHandle_t handle ) = 0; + + // Methods related to shadows on brush models + virtual void AddShadowToBrushModel( ShadowHandle_t handle, + model_t* pModel, const Vector& origin, const QAngle& angles ) = 0; + + // Removes all shadows from a brush model + virtual void RemoveAllShadowsFromBrushModel( model_t* pModel ) = 0; + + // Sets the texture coordinate range for a shadow... + virtual void SetShadowTexCoord( ShadowHandle_t handle, float x, float y, float w, float h ) = 0; + + // Methods related to shadows on studio models + virtual void AddShadowToModel( ShadowHandle_t shadow, ModelInstanceHandle_t instance ) = 0; + virtual void RemoveAllShadowsFromModel( ModelInstanceHandle_t instance ) = 0; + + // Set extra clip planes related to shadows... + // These are used to prevent pokethru and back-casting + virtual void ClearExtraClipPlanes( ShadowHandle_t shadow ) = 0; + virtual void AddExtraClipPlane( ShadowHandle_t shadow, const Vector& normal, float dist ) = 0; + + // Allows us to disable particular shadows + virtual void EnableShadow( ShadowHandle_t shadow, bool bEnable ) = 0; + + // Set the darkness falloff bias + virtual void SetFalloffBias( ShadowHandle_t shadow, unsigned char ucBias ) = 0; + + // Update the state for a flashlight. + virtual void UpdateFlashlightState( ShadowHandle_t shadowHandle, const FlashlightState_t &lightState ) = 0; + + virtual void DrawFlashlightDepthTexture( ) = 0; + + virtual void AddFlashlightRenderable( ShadowHandle_t shadow, IClientRenderable *pRenderable ) = 0; + virtual ShadowHandle_t CreateShadowEx( IMaterial* pMaterial, IMaterial* pModelMaterial, void* pBindProxy, int creationFlags ) = 0; + + virtual void SetFlashlightDepthTexture( ShadowHandle_t shadowHandle, ITexture *pFlashlightDepthTexture, unsigned char ucShadowStencilBit ) = 0; + + virtual const FlashlightState_t &GetFlashlightState( ShadowHandle_t handle ) = 0; + + virtual void SetFlashlightRenderState( ShadowHandle_t handle ) = 0; +}; + + +#endif diff --git a/sp/src/public/engine/ivdebugoverlay.h b/sp/src/public/engine/ivdebugoverlay.h new file mode 100644 index 00000000..c23e225d --- /dev/null +++ b/sp/src/public/engine/ivdebugoverlay.h @@ -0,0 +1,63 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// +// cdll_int.h +// +// 4-23-98 +// JOHN: client dll interface declarations +// + +#ifndef IVDEBUGOVERLAY_H +#define IVDEBUGOVERLAY_H + +#ifdef _WIN32 +#pragma once +#endif + +class Vector; + +#define VDEBUG_OVERLAY_INTERFACE_VERSION "VDebugOverlay003" + +// When used as a duration by a server-side NDebugOverlay:: call, +// causes the overlay to persist until the next server update. +#define NDEBUG_PERSIST_TILL_NEXT_SERVER (0.0f) + +class OverlayText_t; + +abstract_class IVDebugOverlay +{ +public: + virtual void AddEntityTextOverlay(int ent_index, int line_offset, float duration, int r, int g, int b, int a, PRINTF_FORMAT_STRING const char *format, ...) = 0; + virtual void AddBoxOverlay(const Vector& origin, const Vector& mins, const Vector& max, QAngle const& orientation, int r, int g, int b, int a, float duration) = 0; + virtual void AddTriangleOverlay(const Vector& p1, const Vector& p2, const Vector& p3, int r, int g, int b, int a, bool noDepthTest, float duration) = 0; + virtual void AddLineOverlay(const Vector& origin, const Vector& dest, int r, int g, int b,bool noDepthTest, float duration) = 0; + virtual void AddTextOverlay(const Vector& origin, float duration, PRINTF_FORMAT_STRING const char *format, ...) = 0; + virtual void AddTextOverlay(const Vector& origin, int line_offset, float duration, PRINTF_FORMAT_STRING const char *format, ...) = 0; + virtual void AddScreenTextOverlay(float flXPos, float flYPos,float flDuration, int r, int g, int b, int a, const char *text) = 0; + virtual void AddSweptBoxOverlay(const Vector& start, const Vector& end, const Vector& mins, const Vector& max, const QAngle & angles, int r, int g, int b, int a, float flDuration) = 0; + virtual void AddGridOverlay(const Vector& origin) = 0; + virtual int ScreenPosition(const Vector& point, Vector& screen) = 0; + virtual int ScreenPosition(float flXPos, float flYPos, Vector& screen) = 0; + + virtual OverlayText_t *GetFirst( void ) = 0; + virtual OverlayText_t *GetNext( OverlayText_t *current ) = 0; + virtual void ClearDeadOverlays( void ) = 0; + virtual void ClearAllOverlays() = 0; + + virtual void AddTextOverlayRGB(const Vector& origin, int line_offset, float duration, float r, float g, float b, float alpha, PRINTF_FORMAT_STRING const char *format, ...) = 0; + virtual void AddTextOverlayRGB(const Vector& origin, int line_offset, float duration, int r, int g, int b, int a, PRINTF_FORMAT_STRING const char *format, ...) = 0; + + virtual void AddLineOverlayAlpha(const Vector& origin, const Vector& dest, int r, int g, int b, int a, bool noDepthTest, float duration) = 0; + virtual void AddBoxOverlay2( const Vector& origin, const Vector& mins, const Vector& max, QAngle const& orientation, const Color& faceColor, const Color& edgeColor, float duration ) = 0; + +private: + inline void AddTextOverlay(const Vector& origin, int line_offset, float duration, int r, int g, int b, int a, PRINTF_FORMAT_STRING const char *format, ...) {} /* catch improper use of bad interface. Needed because '0' duration can be resolved by compiler to NULL format string (i.e., compiles but calls wrong function) */ +}; + + +#endif // IVDEBUGOVERLAY_H diff --git a/sp/src/public/engine/ivmodelinfo.h b/sp/src/public/engine/ivmodelinfo.h new file mode 100644 index 00000000..6d534604 --- /dev/null +++ b/sp/src/public/engine/ivmodelinfo.h @@ -0,0 +1,261 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#ifndef IVMODELINFO_H +#define IVMODELINFO_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "platform.h" +#include "dbg.h" + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class IMaterial; +class KeyValues; +struct vcollide_t; +struct model_t; +class Vector; +class QAngle; +class CGameTrace; +struct cplane_t; +typedef CGameTrace trace_t; +struct studiohdr_t; +struct virtualmodel_t; +typedef unsigned char byte; +struct virtualterrainparams_t; +class CPhysCollide; +typedef unsigned short MDLHandle_t; +class CUtlBuffer; +class IClientRenderable; + + +//----------------------------------------------------------------------------- +// Purpose: a callback class that is notified when a model has finished loading +//----------------------------------------------------------------------------- +abstract_class IModelLoadCallback +{ +public: + virtual void OnModelLoadComplete( const model_t* pModel ) = 0; + +protected: + // Protected destructor so that nobody tries to delete via this interface. + // Automatically unregisters if the callback is destroyed while still pending. + ~IModelLoadCallback(); +}; + + +//----------------------------------------------------------------------------- +// Purpose: Automate refcount tracking on a model index +//----------------------------------------------------------------------------- +class CRefCountedModelIndex +{ +private: + int m_nIndex; +public: + CRefCountedModelIndex() : m_nIndex( -1 ) { } + ~CRefCountedModelIndex() { Set( -1 ); } + + CRefCountedModelIndex( const CRefCountedModelIndex& src ) : m_nIndex( -1 ) { Set( src.m_nIndex ); } + CRefCountedModelIndex& operator=( const CRefCountedModelIndex& src ) { Set( src.m_nIndex ); return *this; } + + explicit CRefCountedModelIndex( int i ) : m_nIndex( -1 ) { Set( i ); } + CRefCountedModelIndex& operator=( int i ) { Set( i ); return *this; } + + int Get() const { return m_nIndex; } + void Set( int i ); + void Clear() { Set( -1 ); } + + operator int () const { return m_nIndex; } +}; + + +//----------------------------------------------------------------------------- +// Model info interface +//----------------------------------------------------------------------------- + +// change this when the new version is incompatable with the old +#define VMODELINFO_CLIENT_INTERFACE_VERSION "VModelInfoClient006" +#define VMODELINFO_SERVER_INTERFACE_VERSION_3 "VModelInfoServer003" +#define VMODELINFO_SERVER_INTERFACE_VERSION "VModelInfoServer004" + +// MODEL INDEX RULES +// If index >= 0, then index references the precached model string table +// If index == -1, then the model is invalid +// If index < -1, then the model is DYNAMIC and has a DYNAMIC INDEX of (-2 - index) +// - if the dynamic index is ODD, then the model is CLIENT ONLY +// and has a m_LocalDynamicModels lookup index of (dynamic index)>>1 +// - if the dynamic index is EVEN, then the model is NETWORKED +// and has a dynamic model string table index of (dynamic index)>>1 + +inline bool IsDynamicModelIndex( int modelindex ) { return modelindex < -1; } +inline bool IsClientOnlyModelIndex( int modelindex ) { return modelindex < -1 && (modelindex & 1); } + +abstract_class IVModelInfo +{ +public: + virtual ~IVModelInfo( void ) { } + + // Returns model_t* pointer for a model given a precached or dynamic model index. + virtual const model_t *GetModel( int modelindex ) = 0; + + // Returns index of model by name for precached or known dynamic models. + // Does not adjust reference count for dynamic models. + virtual int GetModelIndex( const char *name ) const = 0; + + // Returns name of model + virtual const char *GetModelName( const model_t *model ) const = 0; + virtual vcollide_t *GetVCollide( const model_t *model ) = 0; + virtual vcollide_t *GetVCollide( int modelindex ) = 0; + virtual void GetModelBounds( const model_t *model, Vector& mins, Vector& maxs ) const = 0; + virtual void GetModelRenderBounds( const model_t *model, Vector& mins, Vector& maxs ) const = 0; + virtual int GetModelFrameCount( const model_t *model ) const = 0; + virtual int GetModelType( const model_t *model ) const = 0; + virtual void *GetModelExtraData( const model_t *model ) = 0; + virtual bool ModelHasMaterialProxy( const model_t *model ) const = 0; + virtual bool IsTranslucent( model_t const* model ) const = 0; + virtual bool IsTranslucentTwoPass( const model_t *model ) const = 0; + virtual void RecomputeTranslucency( const model_t *model, int nSkin, int nBody, void /*IClientRenderable*/ *pClientRenderable, float fInstanceAlphaModulate=1.0f) = 0; + virtual int GetModelMaterialCount( const model_t* model ) const = 0; + virtual void GetModelMaterials( const model_t *model, int count, IMaterial** ppMaterial ) = 0; + virtual bool IsModelVertexLit( const model_t *model ) const = 0; + virtual const char *GetModelKeyValueText( const model_t *model ) = 0; + virtual bool GetModelKeyValue( const model_t *model, CUtlBuffer &buf ) = 0; // supports keyvalue blocks in submodels + virtual float GetModelRadius( const model_t *model ) = 0; + + virtual const studiohdr_t *FindModel( const studiohdr_t *pStudioHdr, void **cache, const char *modelname ) const = 0; + virtual const studiohdr_t *FindModel( void *cache ) const = 0; + virtual virtualmodel_t *GetVirtualModel( const studiohdr_t *pStudioHdr ) const = 0; + virtual byte *GetAnimBlock( const studiohdr_t *pStudioHdr, int iBlock ) const = 0; + + // Available on client only!!! + virtual void GetModelMaterialColorAndLighting( const model_t *model, Vector const& origin, + QAngle const& angles, trace_t* pTrace, + Vector& lighting, Vector& matColor ) = 0; + virtual void GetIlluminationPoint( const model_t *model, IClientRenderable *pRenderable, Vector const& origin, + QAngle const& angles, Vector* pLightingCenter ) = 0; + + virtual int GetModelContents( int modelIndex ) = 0; + virtual studiohdr_t *GetStudiomodel( const model_t *mod ) = 0; + virtual int GetModelSpriteWidth( const model_t *model ) const = 0; + virtual int GetModelSpriteHeight( const model_t *model ) const = 0; + + // Sets/gets a map-specified fade range (client only) + virtual void SetLevelScreenFadeRange( float flMinSize, float flMaxSize ) = 0; + virtual void GetLevelScreenFadeRange( float *pMinArea, float *pMaxArea ) const = 0; + + // Sets/gets a map-specified per-view fade range (client only) + virtual void SetViewScreenFadeRange( float flMinSize, float flMaxSize ) = 0; + + // Computes fade alpha based on distance fade + screen fade (client only) + virtual unsigned char ComputeLevelScreenFade( const Vector &vecAbsOrigin, float flRadius, float flFadeScale ) const = 0; + virtual unsigned char ComputeViewScreenFade( const Vector &vecAbsOrigin, float flRadius, float flFadeScale ) const = 0; + + // both client and server + virtual int GetAutoplayList( const studiohdr_t *pStudioHdr, unsigned short **pAutoplayList ) const = 0; + + // Gets a virtual terrain collision model (creates if necessary) + // NOTE: This may return NULL if the terrain model cannot be virtualized + virtual CPhysCollide *GetCollideForVirtualTerrain( int index ) = 0; + + virtual bool IsUsingFBTexture( const model_t *model, int nSkin, int nBody, void /*IClientRenderable*/ *pClientRenderable ) const = 0; + + // Obsolete methods. These are left in to maintain binary compatibility with clients using the IVModelInfo old version. + virtual const model_t *FindOrLoadModel( const char *name ) { Warning( "IVModelInfo::FindOrLoadModel is now obsolte.\n" ); return NULL; } + virtual void InitDynamicModels( ) { Warning( "IVModelInfo::InitDynamicModels is now obsolte.\n" ); } + virtual void ShutdownDynamicModels( ) { Warning( "IVModelInfo::ShutdownDynamicModels is now obsolte.\n" ); } + virtual void AddDynamicModel( const char *name, int nModelIndex = -1 ) { Warning( "IVModelInfo::AddDynamicModel is now obsolte.\n" ); } + virtual void ReferenceModel( int modelindex ) { Warning( "IVModelInfo::ReferenceModel is now obsolte.\n" ); } + virtual void UnreferenceModel( int modelindex ) { Warning( "IVModelInfo::UnreferenceModel is now obsolte.\n" ); } + virtual void CleanupDynamicModels( bool bForce = false ) { Warning( "IVModelInfo::CleanupDynamicModels is now obsolte.\n" ); } + + virtual MDLHandle_t GetCacheHandle( const model_t *model ) const = 0; + + // Returns planes of non-nodraw brush model surfaces + virtual int GetBrushModelPlaneCount( const model_t *model ) const = 0; + virtual void GetBrushModelPlane( const model_t *model, int nIndex, cplane_t &plane, Vector *pOrigin ) const = 0; + virtual int GetSurfacepropsForVirtualTerrain( int index ) = 0; + + // Poked by engine host system + virtual void OnLevelChange() = 0; + + virtual int GetModelClientSideIndex( const char *name ) const = 0; + + // Returns index of model by name, dynamically registered if not already known. + virtual int RegisterDynamicModel( const char *name, bool bClientSide ) = 0; + + virtual bool IsDynamicModelLoading( int modelIndex ) = 0; + + virtual void AddRefDynamicModel( int modelIndex ) = 0; + virtual void ReleaseDynamicModel( int modelIndex ) = 0; + + // Registers callback for when dynamic model has finished loading. + // Automatically adds reference, pair with ReleaseDynamicModel. + virtual bool RegisterModelLoadCallback( int modelindex, IModelLoadCallback* pCallback, bool bCallImmediatelyIfLoaded = true ) = 0; + virtual void UnregisterModelLoadCallback( int modelindex, IModelLoadCallback* pCallback ) = 0; +}; + +typedef IVModelInfo IVModelInfo003; + + +abstract_class IVModelInfoClient : public IVModelInfo +{ +public: + virtual void OnDynamicModelsStringTableChange( int nStringIndex, const char *pString, const void *pData ) = 0; + + // For tools only! + virtual const model_t *FindOrLoadModel( const char *name ) = 0; +}; + + +struct virtualterrainparams_t +{ + // UNDONE: Add grouping here, specified in BSP file? (test grouping to see if this is necessary) + int index; +}; + + +//----------------------------------------------------------------------------- +// Purpose: Force removal from callback list on destruction to avoid crashes. +//----------------------------------------------------------------------------- +inline IModelLoadCallback::~IModelLoadCallback() +{ +#ifdef CLIENT_DLL + extern IVModelInfoClient *modelinfo; +#else + extern IVModelInfo *modelinfo; +#endif + if ( modelinfo ) + { + modelinfo->UnregisterModelLoadCallback( -1, this ); + } +} + + + +//----------------------------------------------------------------------------- +// Purpose: Automate refcount tracking on a model index +//----------------------------------------------------------------------------- +inline void CRefCountedModelIndex::Set( int i ) +{ +#ifdef CLIENT_DLL + extern IVModelInfoClient *modelinfo; +#else + extern IVModelInfo *modelinfo; +#endif + if ( i == m_nIndex ) + return; + modelinfo->AddRefDynamicModel( i ); + modelinfo->ReleaseDynamicModel( m_nIndex ); + m_nIndex = i; +} + + +#endif // IVMODELINFO_H diff --git a/sp/src/public/engine/ivmodelrender.h b/sp/src/public/engine/ivmodelrender.h new file mode 100644 index 00000000..fabaa770 --- /dev/null +++ b/sp/src/public/engine/ivmodelrender.h @@ -0,0 +1,183 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef IVMODELRENDER_H +#define IVMODELRENDER_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "interface.h" +#include "mathlib/mathlib.h" +#include "istudiorender.h" + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- +struct mstudioanimdesc_t; +struct mstudioseqdesc_t; +struct model_t; +class IClientRenderable; +class Vector; +struct studiohdr_t; +class IMaterial; +class CStudioHdr; + +FORWARD_DECLARE_HANDLE( LightCacheHandle_t ); + + +//----------------------------------------------------------------------------- +// Model rendering state +//----------------------------------------------------------------------------- +struct DrawModelState_t +{ + studiohdr_t* m_pStudioHdr; + studiohwdata_t* m_pStudioHWData; + IClientRenderable* m_pRenderable; + const matrix3x4_t *m_pModelToWorld; + StudioDecalHandle_t m_decals; + int m_drawFlags; + int m_lod; +}; + + +//----------------------------------------------------------------------------- +// Model Rendering + instance data +//----------------------------------------------------------------------------- + +// change this when the new version is incompatable with the old +#define VENGINE_HUDMODEL_INTERFACE_VERSION "VEngineModel016" + +typedef unsigned short ModelInstanceHandle_t; + +enum +{ + MODEL_INSTANCE_INVALID = (ModelInstanceHandle_t)~0 +}; + +struct ModelRenderInfo_t +{ + Vector origin; + QAngle angles; + IClientRenderable *pRenderable; + const model_t *pModel; + const matrix3x4_t *pModelToWorld; + const matrix3x4_t *pLightingOffset; + const Vector *pLightingOrigin; + int flags; + int entity_index; + int skin; + int body; + int hitboxset; + ModelInstanceHandle_t instance; + + ModelRenderInfo_t() + { + pModelToWorld = NULL; + pLightingOffset = NULL; + pLightingOrigin = NULL; + } +}; + +struct StaticPropRenderInfo_t +{ + const matrix3x4_t *pModelToWorld; + const model_t *pModel; + IClientRenderable *pRenderable; + Vector *pLightingOrigin; + short skin; + ModelInstanceHandle_t instance; +}; + +// UNDONE: Move this to hud export code, subsume previous functions +abstract_class IVModelRender +{ +public: + virtual int DrawModel( int flags, + IClientRenderable *pRenderable, + ModelInstanceHandle_t instance, + int entity_index, + const model_t *model, + Vector const& origin, + QAngle const& angles, + int skin, + int body, + int hitboxset, + const matrix3x4_t *modelToWorld = NULL, + const matrix3x4_t *pLightingOffset = NULL ) = 0; + + // This causes a material to be used when rendering the model instead + // of the materials the model was compiled with + virtual void ForcedMaterialOverride( IMaterial *newMaterial, OverrideType_t nOverrideType = OVERRIDE_NORMAL ) = 0; + + virtual void SetViewTarget( const CStudioHdr *pStudioHdr, int nBodyIndex, const Vector& target ) = 0; + + // Creates, destroys instance data to be associated with the model + virtual ModelInstanceHandle_t CreateInstance( IClientRenderable *pRenderable, LightCacheHandle_t *pCache = NULL ) = 0; + virtual void DestroyInstance( ModelInstanceHandle_t handle ) = 0; + + // Associates a particular lighting condition with a model instance handle. + // FIXME: This feature currently only works for static props. To make it work for entities, etc., + // we must clean up the lightcache handles as the model instances are removed. + // At the moment, since only the static prop manager uses this, it cleans up all LightCacheHandles + // at level shutdown. + virtual void SetStaticLighting( ModelInstanceHandle_t handle, LightCacheHandle_t* pHandle ) = 0; + virtual LightCacheHandle_t GetStaticLighting( ModelInstanceHandle_t handle ) = 0; + + // moves an existing InstanceHandle to a nex Renderable to keep decals etc. Models must be the same + virtual bool ChangeInstance( ModelInstanceHandle_t handle, IClientRenderable *pRenderable ) = 0; + + // Creates a decal on a model instance by doing a planar projection + // along the ray. The material is the decal material, the radius is the + // radius of the decal to create. + virtual void AddDecal( ModelInstanceHandle_t handle, Ray_t const& ray, + Vector const& decalUp, int decalIndex, int body, bool noPokeThru = false, int maxLODToDecal = ADDDECAL_TO_ALL_LODS ) = 0; + + // Removes all the decals on a model instance + virtual void RemoveAllDecals( ModelInstanceHandle_t handle ) = 0; + + // Remove all decals from all models + virtual void RemoveAllDecalsFromAllModels() = 0; + + // Shadow rendering, DrawModelShadowSetup returns the address of the bone-to-world array, NULL in case of error + virtual matrix3x4_t* DrawModelShadowSetup( IClientRenderable *pRenderable, int body, int skin, DrawModelInfo_t *pInfo, matrix3x4_t *pCustomBoneToWorld = NULL ) = 0; + virtual void DrawModelShadow( IClientRenderable *pRenderable, const DrawModelInfo_t &info, matrix3x4_t *pCustomBoneToWorld = NULL ) = 0; + + // This gets called when overbright, etc gets changed to recompute static prop lighting. + virtual bool RecomputeStaticLighting( ModelInstanceHandle_t handle ) = 0; + + virtual void ReleaseAllStaticPropColorData( void ) = 0; + virtual void RestoreAllStaticPropColorData( void ) = 0; + + // Extended version of drawmodel + virtual int DrawModelEx( ModelRenderInfo_t &pInfo ) = 0; + + virtual int DrawModelExStaticProp( ModelRenderInfo_t &pInfo ) = 0; + + virtual bool DrawModelSetup( ModelRenderInfo_t &pInfo, DrawModelState_t *pState, matrix3x4_t *pCustomBoneToWorld, matrix3x4_t** ppBoneToWorldOut ) = 0; + virtual void DrawModelExecute( const DrawModelState_t &state, const ModelRenderInfo_t &pInfo, matrix3x4_t *pCustomBoneToWorld = NULL ) = 0; + + // Sets up lighting context for a point in space + virtual void SetupLighting( const Vector &vecCenter ) = 0; + + // doesn't support any debug visualization modes or other model options, but draws static props in the + // fastest way possible + virtual int DrawStaticPropArrayFast( StaticPropRenderInfo_t *pProps, int count, bool bShadowDepth ) = 0; + + // Allow client to override lighting state + virtual void SuppressEngineLighting( bool bSuppress ) = 0; + + virtual void SetupColorMeshes( int nTotalVerts ) = 0; + + virtual void AddColoredDecal( ModelInstanceHandle_t handle, Ray_t const& ray, + Vector const& decalUp, int decalIndex, int body, Color cColor, bool noPokeThru = false, int maxLODToDecal = ADDDECAL_TO_ALL_LODS ) = 0; +}; + + +#endif // IVMODELRENDER_H diff --git a/sp/src/public/engine/view_sharedv1.h b/sp/src/public/engine/view_sharedv1.h new file mode 100644 index 00000000..cd5fd48c --- /dev/null +++ b/sp/src/public/engine/view_sharedv1.h @@ -0,0 +1,94 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef VIEW_SHAREDV1_H +#define VIEW_SHAREDV1_H + +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +// Purpose: Renderer setup data. +//----------------------------------------------------------------------------- +class CViewSetupV1 +{ +public: + CViewSetupV1() + { + m_bForceAspectRatio1To1 = false; + m_bRenderToSubrectOfLargerScreen = false; + bForceClearWholeRenderTarget = false; + m_bUseRenderTargetAspectRatio = false; + } + +// shared by 2D & 3D views + + // User specified context + int context; + + // left side of view window + int x; + // top side of view window + int y; + // width of view window + int width; + // height of view window + int height; + + // clear the color buffer before rendering this view? + bool clearColor; + // clear the Depth buffer before rendering this view? + bool clearDepth; + // NOTE: This is for a workaround on ATI with building cubemaps. Clearing just the viewport doesn't seem to work properly. + bool bForceClearWholeRenderTarget; + +// the rest are only used by 3D views + + // Orthographic projection? + bool m_bOrtho; + // View-space rectangle for ortho projection. + float m_OrthoLeft; + float m_OrthoTop; + float m_OrthoRight; + float m_OrthoBottom; + + // horizontal FOV in degrees + float fov; + // horizontal FOV in degrees for in-view model + float fovViewmodel; + + // 3D origin of camera + Vector origin; + // Origin gets reflected on the water surface, but things like + // displacement LOD need to be calculated from the viewer's + // real position. + Vector m_vUnreflectedOrigin; + + // heading of camera (pitch, yaw, roll) + QAngle angles; + // local Z coordinate of near plane of camera + float zNear; + // local Z coordinate of far plane of camera + float zFar; + + // local Z coordinate of near plane of camera ( when rendering view model ) + float zNearViewmodel; + // local Z coordinate of far plane of camera ( when rendering view model ) + float zFarViewmodel; + + bool m_bForceAspectRatio1To1; + + // set to true if this is to draw into a subrect of the larger screen + // this really is a hack, but no more than the rest of the way this class is used + bool m_bRenderToSubrectOfLargerScreen; + + // Use this for situations like water where you want to render the aspect ratio of the + // back buffer into a square (or otherwise) render target. + bool m_bUseRenderTargetAspectRatio; +}; + +#endif // VIEW_SHAREDV1_H diff --git a/sp/src/public/engine_hlds_api.h b/sp/src/public/engine_hlds_api.h new file mode 100644 index 00000000..80535958 --- /dev/null +++ b/sp/src/public/engine_hlds_api.h @@ -0,0 +1,53 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef ENGINE_HLDS_API_H +#define ENGINE_HLDS_API_H +#ifdef _WIN32 +#pragma once +#endif + +#include "interface.h" +#include "appframework/IAppSystem.h" + + +#define VENGINE_HLDS_API_VERSION "VENGINE_HLDS_API_VERSION002" + + +struct ModInfo_t +{ + void *m_pInstance; + const char *m_pBaseDirectory; // Executable directory ("c:/program files/half-life 2", for example) + const char *m_pInitialMod; // Mod name ("cstrike", for example) + const char *m_pInitialGame; // Root game name ("hl2", for example, in the case of cstrike) + CAppSystemGroup *m_pParentAppSystemGroup; + bool m_bTextMode; +}; + + +//----------------------------------------------------------------------------- +// Purpose: This is the interface exported by the engine.dll to allow a dedicated server front end +// application to host it. +//----------------------------------------------------------------------------- +class IDedicatedServerAPI : public IAppSystem +{ +// Functions +public: + // Initialize the engine with the specified base directory and interface factories + virtual bool ModInit( ModInfo_t &info ) = 0; + // Shutdown the engine + virtual void ModShutdown( void ) = 0; + // Run a frame + virtual bool RunFrame( void ) = 0; + // Insert text into console + virtual void AddConsoleText( char *text ) = 0; + // Get current status to display in the hlds UI (console window title bar, e.g. ) + virtual void UpdateStatus(float *fps, int *nActive, int *nMaxPlayers, char *pszMap, int maxlen ) = 0; + // Get current Hostname to display in the hlds UI (console window title bar, e.g. ) + virtual void UpdateHostname(char *pszHostname, int maxlen) = 0; +}; + +#endif // ENGINE_HLDS_API_H diff --git a/sp/src/public/event_flags.h b/sp/src/public/event_flags.h new file mode 100644 index 00000000..868abb56 --- /dev/null +++ b/sp/src/public/event_flags.h @@ -0,0 +1,28 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef EVENT_FLAGS_H +#define EVENT_FLAGS_H + +#ifdef _WIN32 +#pragma once +#endif + + +// Skip local host for event send. +#define FEV_NOTHOST (1<<0) + +// Send the event reliably. You must specify the origin and angles and use +// PLAYBACK_EVENT_FULL for this to work correctly on the server for anything +// that depends on the event origin/angles. I.e., the origin/angles are not +// taken from the invoking edict for reliable events. +#define FEV_RELIABLE (1<<1) + +// Don't restrict to PAS/PVS, send this event to _everybody_ on the server ( useful for stopping CHAN_STATIC +// sounds started by client event when client is not in PVS anymore ( hwguy in TFC e.g. ). +#define FEV_GLOBAL (1<<2) + +#endif // EVENT_FLAGS_H diff --git a/sp/src/public/fgdlib/entitydefs.h b/sp/src/public/fgdlib/entitydefs.h new file mode 100644 index 00000000..f2fcd8d4 --- /dev/null +++ b/sp/src/public/fgdlib/entitydefs.h @@ -0,0 +1,20 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef ENTITYDEFS_H +#define ENTITYDEFS_H +#ifdef _WIN32 +#pragma once +#endif + + +#define MAX_ENTITY_NAME_LEN 256 + +#define MAX_IO_NAME_LEN 256 + + +#endif // ENTITYDEFS_H diff --git a/sp/src/public/fgdlib/fgdlib.h b/sp/src/public/fgdlib/fgdlib.h new file mode 100644 index 00000000..76051cfb --- /dev/null +++ b/sp/src/public/fgdlib/fgdlib.h @@ -0,0 +1,18 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef FGDLIB_H +#define FGDLIB_H +#ifdef _WIN32 +#pragma once +#endif + +#include "HelperInfo.h" +#include "GameData.h" +#include "GDClass.h" +#include "InputOutput.h" + +#endif // FGDLIB_H diff --git a/sp/src/public/fgdlib/gamedata.h b/sp/src/public/fgdlib/gamedata.h new file mode 100644 index 00000000..5d55db2f --- /dev/null +++ b/sp/src/public/fgdlib/gamedata.h @@ -0,0 +1,169 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef GAMEDATA_H +#define GAMEDATA_H +#ifdef _WIN32 +#pragma once +#endif + +#pragma warning(push, 1) +#pragma warning(disable:4701 4702 4530) +#include +#pragma warning(pop) +#include "TokenReader.h" +#include "GDClass.h" +#include "InputOutput.h" +#include "UtlString.h" +#include "utlvector.h" + + +class MDkeyvalue; +class GameData; +class KeyValues; + +enum TEXTUREFORMAT; + + +typedef void (*GameDataMessageFunc_t)(int level, PRINTF_FORMAT_STRING const char *fmt, ...); + +// FGD-based AutoMaterialExclusion data + +struct FGDMatExlcusions_s +{ + char szDirectory[MAX_PATH]; // Where we store the material exclusion directories + bool bUserGenerated; // If the user specified this ( default: false -- FGD defined ) +}; + +// FGD-based AutoVisGroup data + +struct FGDVisGroupsBaseClass_s +{ + char szClass[MAX_PATH]; // i.e. Scene Logic, Sounds, etc "Custom\Point Entities\Lights" + CUtlStringList szEntities; // i.e. func_viscluster +}; + +struct FGDAutoVisGroups_s +{ + char szParent[MAX_PATH]; // i.e. Custom, SFM, etc + CUtlVector< FGDVisGroupsBaseClass_s > m_Classes; // i.e. Scene Logic, Sounds, etc +}; + +#define MAX_DIRECTORY_SIZE 32 + + +//----------------------------------------------------------------------------- +// Purpose: Contains the set of data that is loaded from a single FGD file. +//----------------------------------------------------------------------------- +class GameData +{ + public: + typedef enum + { + NAME_FIXUP_PREFIX = 0, + NAME_FIXUP_POSTFIX, + NAME_FIXUP_NONE + } TNameFixup; + + GameData(); + ~GameData(); + + BOOL Load(const char *pszFilename); + + GDclass *ClassForName(const char *pszName, int *piIndex = NULL); + + void ClearData(); + + inline int GetMaxMapCoord(void); + inline int GetMinMapCoord(void); + + inline int GetClassCount(); + inline GDclass *GetClass(int nIndex); + + GDclass *BeginInstanceRemap( const char *pszClassName, const char *pszInstancePrefix, Vector &Origin, QAngle &Angle ); + bool RemapKeyValue( const char *pszKey, const char *pszInValue, char *pszOutValue, TNameFixup NameFixup ); + bool RemapNameField( const char *pszInValue, char *pszOutValue, TNameFixup NameFixup ); + bool LoadFGDMaterialExclusions( TokenReader &tr ); + bool LoadFGDAutoVisGroups( TokenReader &tr ); + +#ifdef MAPBASE + // Sets up for additional instance remap fixes from Mapbase + void SetupInstanceRemapParams( int iStartNodes, int iStartBrushSide, bool bRemapVecLines ); +#endif + + + CUtlVector< FGDMatExlcusions_s > m_FGDMaterialExclusions; + + CUtlVector< FGDAutoVisGroups_s > m_FGDAutoVisGroups; + + private: + + bool ParseMapSize(TokenReader &tr); + + CUtlVector m_Classes; + + int m_nMinMapCoord; // Min & max map bounds as defined by the FGD. + int m_nMaxMapCoord; + + // Instance Remapping + Vector m_InstanceOrigin; // the origin offset of the instance + QAngle m_InstanceAngle; // the rotation of the the instance + matrix3x4_t m_InstanceMat; // matrix of the origin and rotation of rendering + char m_InstancePrefix[ 128 ]; // the prefix used for the instance name remapping + GDclass *m_InstanceClass; // the entity class that is being remapped +#ifdef MAPBASE + int m_InstanceStartAINodes; // the number of AI nodes in the level (for AI node remapping) + int m_InstanceStartSide; // the number of brush sides in the level (for brush side remapping) + bool m_bRemapVecLines; // allows ivVecLine to be remapped +#endif +}; + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline int GameData::GetClassCount() +{ + return m_Classes.Count(); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline GDclass *GameData::GetClass(int nIndex) +{ + if (nIndex >= m_Classes.Count()) + return NULL; + + return m_Classes.Element(nIndex); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int GameData::GetMinMapCoord(void) +{ + return m_nMinMapCoord; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int GameData::GetMaxMapCoord(void) +{ + return m_nMaxMapCoord; +} + + +void GDSetMessageFunc(GameDataMessageFunc_t pFunc); +bool GDError(TokenReader &tr, PRINTF_FORMAT_STRING const char *error, ...); +bool GDSkipToken(TokenReader &tr, trtoken_t ttexpecting = TOKENNONE, const char *pszExpecting = NULL); +bool GDGetToken(TokenReader &tr, char *pszStore, int nSize, trtoken_t ttexpecting = TOKENNONE, const char *pszExpecting = NULL); +bool GDGetTokenDynamic(TokenReader &tr, char **pszStore, trtoken_t ttexpecting, const char *pszExpecting = NULL); + + +#endif // GAMEDATA_H diff --git a/sp/src/public/fgdlib/gdclass.h b/sp/src/public/fgdlib/gdclass.h new file mode 100644 index 00000000..fe81bb37 --- /dev/null +++ b/sp/src/public/fgdlib/gdclass.h @@ -0,0 +1,260 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Defines the interface to a game class as defined by the game data +// file (FGD). Each class is type of entity that can be placed in +// the editor and has attributes such as: keys that may be set, +// the default size and color of the entity, inputs and outputs, +// and any default models that are created when the entity is placed. +// +// The game classes support multiple inheritence through aggregation +// of properties. +// +//=============================================================================// + +#ifndef GDCLASS_H +#define GDCLASS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "HelperInfo.h" +#include "TokenReader.h" +#include "GDVar.h" +#include "InputOutput.h" +#include "mathlib/vector.h" + +class CHelperInfo; +class GameData; +class GDinputvariable; + +const int GD_MAX_VARIABLES = 128; + + +class GDclass +{ + public: + + GDclass(void); + ~GDclass(void); + + // + // Interface to class information: + // + inline const char *GetName(void) { return(m_szName); } + inline const char *GetDescription(void); + + // + // Reading a class from the game data file: + // + BOOL InitFromTokens(TokenReader& tr, GameData*); + + // + // Interface to variable information (keys): + // + inline int GetVariableCount(void) { return(m_nVariables); } + GDinputvariable *GetVariableAt(int iIndex); + void GetHelperForGDVar( GDinputvariable *pVar, CUtlVector *helperName ); + GDinputvariable *VarForName(const char *pszName, int *piIndex = NULL); + BOOL AddVariable(GDinputvariable *pVar, GDclass *pBase, int iBaseIndex, int iVarIndex); + void AddBase(GDclass *pBase); + + // + // Interface to input information: + // + inline void AddInput(CClassInput *pInput); + CClassInput *FindInput(const char *szName); + inline int GetInputCount(void) { return(m_Inputs.Count()); } + CClassInput *GetInput(int nIndex); + + // + // Interface to output information: + // + inline void AddOutput(CClassOutput *pOutput); + CClassOutput *FindOutput(const char *szName); + inline int GetOutputCount(void) { return(m_Outputs.Count()); } + CClassOutput *GetOutput(int nIndex); + + GameData *Parent; + + // + // Interface to class attributes: + // + inline bool IsClass(const char *pszClass); + inline bool IsSolidClass(void) { return(m_bSolid); } + inline bool IsBaseClass(void) { return(m_bBase); } + inline bool IsMoveClass(void) { return(m_bMove); } + inline bool IsKeyFrameClass(void) { return(m_bKeyFrame); } + inline bool IsPointClass(void) { return(m_bPoint); } + inline bool IsNPCClass(void) { return(m_bNPC); } + inline bool IsFilterClass(void) { return(m_bFilter); } + inline bool IsNodeClass(void); + static inline bool IsNodeClass(const char *pszClassName); + + inline bool ShouldSnapToHalfGrid() { return m_bHalfGridSnap; } + + inline void SetNPCClass(bool bNPC) { m_bNPC = bNPC; } + inline void SetFilterClass(bool bFilter) { m_bFilter = bFilter; } + inline void SetPointClass(bool bPoint) { m_bPoint = bPoint; } + inline void SetSolidClass(bool bSolid) { m_bSolid = bSolid; } + inline void SetBaseClass(bool bBase) { m_bBase = bBase; } + inline void SetMoveClass(bool bMove) { m_bMove = bMove; } + inline void SetKeyFrameClass(bool bKeyFrame) { m_bKeyFrame = bKeyFrame; } + + inline const Vector &GetMins(void) { return(m_bmins); } + inline const Vector &GetMaxs(void) { return(m_bmaxs); } + + BOOL GetBoundBox(Vector& pfMins, Vector& pfMaxs); + bool HasBoundBox() const { return m_bGotSize; } + + inline color32 GetColor(void); + + // + // Interface to helper information: + // + inline void AddHelper(CHelperInfo *pHelper); + inline int GetHelperCount(void) { return(m_Helpers.Count()); } + CHelperInfo *GetHelper(int nIndex); + + protected: + + // + // Parsing the game data file: + // + bool ParseInput(TokenReader &tr); + bool ParseInputOutput(TokenReader &tr, CClassInputOutputBase *pInputOutput); + bool ParseOutput(TokenReader &tr); + bool ParseVariable(TokenReader &tr); + + private: + + bool ParseBase(TokenReader &tr); + bool ParseColor(TokenReader &tr); + bool ParseHelper(TokenReader &tr, char *pszHelperName); + bool ParseSize(TokenReader &tr); + bool ParseSpecifiers(TokenReader &tr); + bool ParseVariables(TokenReader &tr); + + color32 m_rgbColor; // Color of entity. + + bool m_bBase; // Base only - not available to user. + bool m_bSolid; // Tied to solids only. + bool m_bModel; // Properties of a single model. + bool m_bMove; // Animatable + bool m_bKeyFrame; // Animation keyframe + bool m_bPoint; // Point class, not tied to solids. + bool m_bNPC; // NPC class - used for populating lists of NPC classes. + bool m_bFilter; // filter class - used for populating lists of filters. + bool m_bHalfGridSnap; // Snaps to a 1/2 grid so it can be centered on any geometry. Used for hinges, etc. + + bool m_bGotSize; // Just for loading. + bool m_bGotColor; + + char m_szName[MAX_IDENT]; // Name of this class. + char *m_pszDescription; // Description of this class, dynamically allocated. + + CUtlVector m_Variables; // Variables for this class. + int m_nVariables; // Count of base & local variables combined. + CUtlVector m_Bases; // List of base classes this class inherits from. + + CClassInputList m_Inputs; + CClassOutputList m_Outputs; + + CHelperInfoList m_Helpers; // Helpers for this class. + + // + // [0] = base number from Bases, or -1 if not in a base. + // [1] = index into base's variables + // + signed short m_VariableMap[GD_MAX_VARIABLES][2]; + + Vector m_bmins; // 3D minima of object (pointclass). + Vector m_bmaxs; // 3D maxima of object (pointclass). +}; + + +void GDclass::AddInput(CClassInput *pInput) +{ + Assert(pInput != NULL); + if (pInput != NULL) + { + m_Inputs.AddToTail(pInput); + } +} + + +inline void GDclass::AddOutput(CClassOutput *pOutput) +{ + Assert(pOutput != NULL); + if (pOutput != NULL) + { + m_Outputs.AddToTail(pOutput); + } +} + + +inline void GDclass::AddHelper(CHelperInfo *pHelper) +{ + Assert(pHelper != NULL); + if (pHelper != NULL) + { + m_Helpers.AddToTail(pHelper); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns the render color of this entity class. +//----------------------------------------------------------------------------- +color32 GDclass::GetColor(void) +{ + return m_rgbColor; +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns a description of this entity class, or the entity class name +// if no description exists. +//----------------------------------------------------------------------------- +const char *GDclass::GetDescription(void) +{ + if (m_pszDescription == NULL) + { + return(m_szName); + } + + return(m_pszDescription); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : pszClass - +//----------------------------------------------------------------------------- +bool GDclass::IsClass(const char *pszClass) +{ + Assert(pszClass != NULL); + return(!stricmp(pszClass, m_szName)); +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns true if the given classname represents an AI node class, false if not. +//----------------------------------------------------------------------------- +bool GDclass::IsNodeClass(const char *pszClassName) +{ + return((strnicmp(pszClassName, "info_node", 9) == 0) && (stricmp(pszClassName, "info_node_link") != 0)); +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns true if this is an AI node class, false if not. +// +// HACK: if this is necessary, we should have a new @NodeClass FGD specifier (or something) +//----------------------------------------------------------------------------- +bool GDclass::IsNodeClass(void) +{ + return(IsNodeClass(m_szName)); +} + + +#endif // GDCLASS_H diff --git a/sp/src/public/fgdlib/gdvar.h b/sp/src/public/fgdlib/gdvar.h new file mode 100644 index 00000000..e6eb37fe --- /dev/null +++ b/sp/src/public/fgdlib/gdvar.h @@ -0,0 +1,227 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef GDVAR_H +#define GDVAR_H +#pragma once + +#include +#include // dvs: for MAX_STRING. Fix. + + +class MDkeyvalue; + + +enum GDIV_TYPE +{ + ivBadType = -1, + ivAngle, + ivTargetDest, + ivTargetNameOrClass, + ivTargetSrc, + ivInteger, + ivString, + ivChoices, + ivFlags, + ivDecal, + ivColor255, // components are 0-255 + ivColor1, // components are 0-1 + ivStudioModel, + ivSprite, + ivSound, + ivVector, + ivNPCClass, + ivFilterClass, + ivFloat, + ivMaterial, + ivScene, + ivSide, // One brush face ID. + ivSideList, // One or more brush face IDs, space delimited. + ivOrigin, // The origin of an entity, in the form "x y z". + ivVecLine, // An origin that draws a line back to the parent entity. + ivAxis, // The axis of rotation for a rotating entity, in the form "x0 y0 z0, x1 y1 z1". + ivPointEntityClass, + ivNodeDest, + ivInstanceFile, // used for hammer to know this field should display a browse button to find map files + ivAngleNegativePitch, // used for instance rotating when just a pitch value is present + ivInstanceVariable, // used for instance variables for easy hammer editing + ivInstanceParm, // used for instance parameter declaration + + ivMax // count of types +}; + + +//----------------------------------------------------------------------------- +// Defines an element in a choices/flags list. Choices values are strings; +// flags values are integers, hence the iValue and szValue members. +//----------------------------------------------------------------------------- +typedef struct +{ + unsigned long iValue; // Bitflag value for ivFlags + char szValue[MAX_STRING]; // String value for ivChoices + char szCaption[MAX_STRING]; // Name of this choice + BOOL bDefault; // Flag set by default? +} GDIVITEM; + + +class GDinputvariable +{ + public: + + GDinputvariable(); + GDinputvariable( const char *szType, const char *szName ); + ~GDinputvariable(); + + BOOL InitFromTokens(TokenReader& tr); + + // functions: + inline const char *GetName() { return m_szName; } + inline const char *GetLongName(void) { return m_szLongName; } + inline const char *GetDescription(void); + + inline int GetFlagCount() { return m_Items.Count(); } + inline int GetFlagMask(int nFlag); + inline const char *GetFlagCaption(int nFlag); + + inline int GetChoiceCount() { return m_Items.Count(); } + inline const char *GetChoiceCaption(int nChoice); + + inline GDIV_TYPE GetType() { return m_eType; } + const char *GetTypeText(void); + +#ifdef MAPBASE + // The FGD library normally enforces that variable types should always stay the same. + // The new AI node remapping code needs to change the "nodeid" keyvalue on AI nodes so + // it's properly recognized as a node ID which needs to be remapped. + // That's what this hack is for. + inline void ForceSetType( GDIV_TYPE newType ) { m_eType = newType; } +#endif + + inline void GetDefault(int *pnStore) + { + pnStore[0] = m_nDefault; + } + + inline void GetDefault(char *pszStore) + { + strcpy(pszStore, m_szDefault); + } + + GDIV_TYPE GetTypeFromToken(const char *pszToken); + trtoken_t GetStoreAsFromType(GDIV_TYPE eType); + + const char *ItemStringForValue(const char *szValue); + const char *ItemValueForString(const char *szString); + + BOOL IsFlagSet(unsigned int); + void SetFlag(unsigned int, BOOL bSet); + + void ResetDefaults(); + + void ToKeyValue(MDkeyvalue* pkv); + void FromKeyValue(MDkeyvalue* pkv); + + inline bool IsReportable(void); + inline bool IsReadOnly(void); + + GDinputvariable &operator =(GDinputvariable &Other); + void Merge(GDinputvariable &Other); + + static const char *GetVarTypeName( GDIV_TYPE eType ); + + private: + + // for choices/flags: + CUtlVector m_Items; + + static char *m_pszEmpty; + + char m_szName[MAX_IDENT]; + char m_szLongName[MAX_STRING]; + char *m_pszDescription; + + GDIV_TYPE m_eType; + + int m_nDefault; + char m_szDefault[MAX_STRING]; + + int m_nValue; + char m_szValue[MAX_STRING]; + + bool m_bReportable; + bool m_bReadOnly; + + friend class GDclass; +}; + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +const char *GDinputvariable::GetDescription(void) +{ + if (m_pszDescription != NULL) + { + return(m_pszDescription); + } + + return(m_pszEmpty); +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns whether or not this variable is read only. Read only variables +// cannot be edited in the Entity Properties dialog. +//----------------------------------------------------------------------------- +bool GDinputvariable::IsReadOnly(void) +{ + return(m_bReadOnly); +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns whether or not this variable should be displayed in the Entity +// Report dialog. +//----------------------------------------------------------------------------- +bool GDinputvariable::IsReportable(void) +{ + return(m_bReportable); +} + + +//----------------------------------------------------------------------------- +// Returns the flag mask (eg 4096) for the flag at the given index. The +// array is packed, so it isn't just 1 >> nFlag. +//----------------------------------------------------------------------------- +int GDinputvariable::GetFlagMask(int nFlag) +{ + Assert(m_eType == ivFlags); + return m_Items.Element(nFlag).iValue; +} + + +//----------------------------------------------------------------------------- +// Returns the caption text (eg "Only break on trigger") for the flag at the given index. +//----------------------------------------------------------------------------- +const char *GDinputvariable::GetFlagCaption(int nFlag) +{ + Assert(m_eType == ivFlags); + return m_Items.Element(nFlag).szCaption; +} + + +//----------------------------------------------------------------------------- +// Returns the caption text (eg "Yes") for the choice at the given index. +//----------------------------------------------------------------------------- +const char *GDinputvariable::GetChoiceCaption(int nChoice) +{ + Assert(m_eType == ivChoices); + return m_Items.Element(nChoice).szCaption; +} + + +#endif // GDVAR_H diff --git a/sp/src/public/fgdlib/helperinfo.h b/sp/src/public/fgdlib/helperinfo.h new file mode 100644 index 00000000..affd5666 --- /dev/null +++ b/sp/src/public/fgdlib/helperinfo.h @@ -0,0 +1,128 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +//============================================================================= + +#ifndef HELPERINFO_H +#define HELPERINFO_H +#pragma once + +#include +#include + + +#define MAX_HELPER_NAME_LEN 256 + + +typedef CUtlVector CParameterList; + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CHelperInfo +{ + public: + + inline CHelperInfo(void); + inline ~CHelperInfo(void); + + inline const char *GetName(void) const { return(m_szName); } + inline void SetName(const char *pszName); + + inline bool AddParameter(const char *pszParameter); + + inline int GetParameterCount(void) const { return(m_Parameters.Count()); } + inline const char *GetParameter(int nIndex) const; + + protected: + + char m_szName[MAX_HELPER_NAME_LEN]; + CParameterList m_Parameters; +}; + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline CHelperInfo::CHelperInfo(void) +{ + m_szName[0] = '\0'; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +inline CHelperInfo::~CHelperInfo(void) +{ + int nCount = m_Parameters.Count(); + for (int i = 0; i < nCount; i++) + { + char *pszParam = m_Parameters.Element(i); + Assert(pszParam != NULL); + if (pszParam != NULL) + { + delete [] pszParam; + } + } + + m_Parameters.RemoveAll(); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : char *pszParameter - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +inline bool CHelperInfo::AddParameter(const char *pszParameter) +{ + if ((pszParameter != NULL) && (pszParameter[0] != '\0')) + { + int nLen = strlen(pszParameter); + + if (nLen > 0) + { + char *pszNew = new char [nLen + 1]; + if (pszNew != NULL) + { + strcpy(pszNew, pszParameter); + m_Parameters.AddToTail(pszNew); + return(true); + } + } + } + + return(false); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +inline const char *CHelperInfo::GetParameter(int nIndex) const +{ + if (nIndex >= m_Parameters.Count()) + return NULL; + + return m_Parameters.Element(nIndex); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : char *pszName - +//----------------------------------------------------------------------------- +inline void CHelperInfo::SetName(const char *pszName) +{ + if (pszName != NULL) + { + strcpy(m_szName, pszName); + } +} + + +typedef CUtlVector CHelperInfoList; + + +#endif // HELPERINFO_H diff --git a/sp/src/public/fgdlib/ieditortexture.h b/sp/src/public/fgdlib/ieditortexture.h new file mode 100644 index 00000000..076839ef --- /dev/null +++ b/sp/src/public/fgdlib/ieditortexture.h @@ -0,0 +1,165 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Defines the interface a given texture for the 3D renderer. Current +// implementations are for world textures (WADTexture.cpp) and sprite +// textures (Texture.cpp). +// +//============================================================================= + +#ifndef IEDITORTEXTURE_H +#define IEDITORTEXTURE_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include + + +class CDC; +class CPalette; +class IMaterial; + +// FGDLIB: +#define DEFAULT_TEXTURE_SCALE 0.25 +#define DEFAULT_LIGHTMAP_SCALE 16 + + +// +// Set your texture ID to this in your implementation's constructor. +// +#define TEXTURE_ID_NONE -1 + + +// +// Texture formats. hack: MUST correlate with radio buttons in IDD_OPTIONS_CONFIGS. +// +enum TEXTUREFORMAT +{ + tfNone = -1, + tfWAD = 0, + tfWAL = 1, + tfWAD3 = 2, + tfWAD4 = 3, + tfWAD5 = 4, + tfVMT = 5, + tfSprite = 6 // dvs: not sure if I want to do it this way +}; + + +// +// Flags for DrawTexData_t. +// +#define drawCaption 0x01 +#define drawResizeAlways 0x02 +#define drawIcons 0x04 +#define drawErrors 0x08 +#define drawUsageCount 0x10 + + +struct DrawTexData_t +{ + int nFlags; + int nUsageCount; +}; + + +class IEditorTexture +{ + public: + + virtual ~IEditorTexture(void) + { + } + + // + // dvs: remove one of these + // + virtual int GetImageWidth( void ) const = 0; + virtual int GetImageHeight( void ) const = 0; + + virtual int GetWidth( void ) const = 0; + virtual int GetHeight( void ) const = 0; + + virtual float GetDecalScale( void ) const = 0; + + // + // dvs: Try to remove as many of these as possible: + // + virtual const char *GetName( void ) const = 0; + virtual int GetShortName( char *szShortName ) const = 0; + virtual int GetKeywords( char *szKeywords ) const = 0; + // FGDLIB: + //virtual void Draw(CDC *pDC, RECT &rect, int iFontHeight, int iIconHeight, DrawTexData_t &DrawTexData) = 0; + virtual TEXTUREFORMAT GetTextureFormat( void ) const = 0; + virtual int GetSurfaceAttributes( void ) const = 0; + virtual int GetSurfaceContents(void ) const = 0; + virtual int GetSurfaceValue( void ) const = 0; + virtual CPalette *GetPalette( void ) const = 0; + virtual bool HasData( void ) const = 0; + virtual bool HasPalette( void ) const = 0; + virtual bool Load( void ) = 0; // ensure that texture is loaded. could this be done internally? + virtual void Reload( void ) = 0; // The texture changed + virtual bool IsLoaded( void ) const = 0; + virtual const char *GetFileName( void ) const = 0; + + virtual bool IsWater( void ) const = 0; + + //----------------------------------------------------------------------------- + // Purpose: + // Input : pData - + // Output : + //----------------------------------------------------------------------------- + virtual int GetImageDataRGB( void *pData = NULL ) = 0; + + //----------------------------------------------------------------------------- + // Purpose: + // Input : pData - + // Output : + //----------------------------------------------------------------------------- + virtual int GetImageDataRGBA( void *pData = NULL ) = 0; + + //----------------------------------------------------------------------------- + // Purpose: Returns true if this texture has an alpha component, false if not. + //----------------------------------------------------------------------------- + virtual bool HasAlpha( void ) const = 0; + + //----------------------------------------------------------------------------- + // Purpose: Returns whether this texture is a dummy texture or not. Dummy textures + // serve as placeholders for textures that were found in the map, but + // not in the WAD (or the materials tree). The dummy texture enables us + // to bind the texture, find it by name, etc. + //----------------------------------------------------------------------------- + virtual bool IsDummy( void ) const = 0; // dvs: perhaps not the best name? + + //----------------------------------------------------------------------------- + // Purpose: Returns the unique texture ID for this texture object. The texture ID + // identifies the texture object across all renderers, and is assigned + // by the first renderer that actually binds the texture thru BindTexture. + // + // Only the renderer ever needs to call SetTextureID. + //----------------------------------------------------------------------------- + virtual int GetTextureID( void ) const = 0; + + //----------------------------------------------------------------------------- + // Purpose: Sets the unique texture ID for this texture object. The texture ID + // identifies the texture object across all renderers, and is assigned + // by the first renderer that actually binds the texture thru BindTexture. + // + // Only the renderer should ever call SetTextureID! + //----------------------------------------------------------------------------- + virtual void SetTextureID( int nTextureID ) = 0; + + //----------------------------------------------------------------------------- + // Returns the material system material associated with a texture + //----------------------------------------------------------------------------- + + virtual IMaterial* GetMaterial() { return 0; } +}; + + +typedef CUtlVector EditorTextureList_t; + + +#endif // IEDITORTEXTURE_H diff --git a/sp/src/public/fgdlib/inputoutput.h b/sp/src/public/fgdlib/inputoutput.h new file mode 100644 index 00000000..7438f08f --- /dev/null +++ b/sp/src/public/fgdlib/inputoutput.h @@ -0,0 +1,105 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +//============================================================================= + +#ifndef INPUTOUTPUT_H +#define INPUTOUTPUT_H +#ifdef _WIN32 +#pragma once +#endif + + +#include +#include "fgdlib/EntityDefs.h" + + +enum InputOutputType_t +{ + iotInvalid = -1, + iotVoid, + iotInt, + iotBool, + iotString, + iotFloat, + iotVector, + iotEHandle, + iotColor, +}; + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CClassInputOutputBase +{ + public: + + CClassInputOutputBase(void); + CClassInputOutputBase(const char *pszName, InputOutputType_t eType); + virtual ~CClassInputOutputBase(void); + + inline const char *GetName(void) { return(m_szName); } + InputOutputType_t GetType(void) { return(m_eType); } + const char *GetTypeText(void); + inline const char *GetDescription(void); + + inline void SetName(const char *szName) { V_strcpy_safe(m_szName, szName); } + inline void SetType(InputOutputType_t eType) { m_eType = eType; } + InputOutputType_t SetType(const char *szType); + inline void SetDescription(char *pszDescription) { m_pszDescription = pszDescription; } + + CClassInputOutputBase &operator =(CClassInputOutputBase &); + + protected: + + static char *g_pszEmpty; + + char m_szName[MAX_IO_NAME_LEN]; + InputOutputType_t m_eType; + char *m_pszDescription; +}; + + +//----------------------------------------------------------------------------- +// Purpose: Returns this I/O's long description. +//----------------------------------------------------------------------------- +const char *CClassInputOutputBase::GetDescription(void) +{ + if (m_pszDescription != NULL) + { + return(m_pszDescription); + } + + return(g_pszEmpty); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CClassInput : public CClassInputOutputBase +{ + public: + + CClassInput(void); + CClassInput(const char *pszName, InputOutputType_t eType); +}; + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CClassOutput : public CClassInputOutputBase +{ + public: + + CClassOutput(void); + CClassOutput(const char *pszName, InputOutputType_t eType); +}; + + +typedef CUtlVector CClassInputList; +typedef CUtlVector CClassOutputList; + + +#endif // INPUTOUTPUT_H diff --git a/sp/src/public/fgdlib/wckeyvalues.h b/sp/src/public/fgdlib/wckeyvalues.h new file mode 100644 index 00000000..730d92d1 --- /dev/null +++ b/sp/src/public/fgdlib/wckeyvalues.h @@ -0,0 +1,233 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef WCKEYVALUES_H +#define WCKEYVALUES_H +#pragma once + + +#include +#include +#include +#pragma warning(push, 1) +#pragma warning(disable:4701 4702 4530) +#include +#pragma warning(pop) + + +#define KEYVALUE_MAX_KEY_LENGTH 80 +#define KEYVALUE_MAX_VALUE_LENGTH 512 + + +class MDkeyvalue +{ + public: + + // + // Constructors/Destructor. + // + inline MDkeyvalue(void); + inline MDkeyvalue(const char *pszKey, const char *pszValue); + ~MDkeyvalue(void); + + MDkeyvalue &operator =(const MDkeyvalue &other); + + inline void Set(const char *pszKey, const char *pszValue); + inline const char *Key(void) const; + inline const char *Value(void) const; + + // + // Serialization functions. + // + int SerializeRMF(std::fstream &f, BOOL bRMF); + int SerializeMAP(std::fstream &f, BOOL bRMF); + + char szKey[KEYVALUE_MAX_KEY_LENGTH]; // The name of this key. + char szValue[KEYVALUE_MAX_VALUE_LENGTH]; // The value of this key, stored as a string. +}; + + +//----------------------------------------------------------------------------- +// Purpose: Constructor. +//----------------------------------------------------------------------------- +MDkeyvalue::MDkeyvalue(void) +{ + szKey[0] = '\0'; + szValue[0] = '\0'; +} + + +//----------------------------------------------------------------------------- +// Purpose: Constructor with assignment. +//----------------------------------------------------------------------------- +MDkeyvalue::MDkeyvalue(const char *pszKey, const char *pszValue) +{ + szKey[0] = '\0'; + szValue[0] = '\0'; + + Set(pszKey, pszValue); +} + + +//----------------------------------------------------------------------------- +// Purpose: Assigns a key and value. +//----------------------------------------------------------------------------- +void MDkeyvalue::Set(const char *pszKey, const char *pszValue) +{ + Assert(pszKey); + Assert(pszValue); + + strcpy(szKey, pszKey); + strcpy(szValue, pszValue); +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns the string keyname. +//----------------------------------------------------------------------------- +const char *MDkeyvalue::Key(void) const +{ + return szKey; +} + + +//----------------------------------------------------------------------------- +// Purpose: Returns the string value of this keyvalue. +//----------------------------------------------------------------------------- +const char *MDkeyvalue::Value(void) const +{ + return szValue; +} + + +typedef CUtlVector KeyValueArray; + + +// Used in cases where there can be duplicate key names. +class WCKVBase_Vector +{ +public: + + // Iteration helpers. + inline int GetCount() const { return m_KeyValues.Count(); } + inline int GetFirst() const { return m_KeyValues.Count() - 1; } + inline int GetNext( int i ) const { return i - 1; } + static inline int GetInvalidIndex() { return -1; } + + void RemoveKeyAt(int nIndex); + int FindByKeyName( const char *pKeyName ) const; // Returns the same value as GetInvalidIndex if not found. + + // Special function used for non-unique keyvalue lists. + void AddKeyValue(const char *pszKey, const char *pszValue); + +protected: + + void InsertKeyValue( const MDkeyvalue &kv ); + +protected: + CUtlVector m_KeyValues; +}; + +// Used for most key/value sets because it's fast. Does not allow duplicate key names. +class WCKVBase_Dict +{ +public: + + // Iteration helpers. Note that there is no GetCount() because you can't iterate + // these by incrementing a counter. + inline int GetFirst() const { return m_KeyValues.First(); } + inline int GetNext( int i ) const { return m_KeyValues.Next( i ); } + static inline int GetInvalidIndex() { return CUtlDict::InvalidIndex(); } + + int FindByKeyName( const char *pKeyName ) const; // Returns the same value as GetInvalidIndex if not found. + void RemoveKeyAt(int nIndex); + +protected: + void InsertKeyValue( const MDkeyvalue &kv ); + +protected: + CUtlDict m_KeyValues; +}; + + +// See below for typedefs of this class you can use. +template +class WCKeyValuesT : public Base +{ +public: + + WCKeyValuesT(void); + ~WCKeyValuesT(void); + + void RemoveAll(void); + void RemoveKey(const char *pszKey); + + void SetValue(const char *pszKey, const char *pszValue); + void SetValue(const char *pszKey, int iValue); + + const char *GetKey(int nIndex) const; + MDkeyvalue &GetKeyValue(int nIndex); + const MDkeyvalue& GetKeyValue(int nIndex) const; + const char *GetValue(int nIndex) const; + const char *GetValue(const char *pszKey, int *piIndex = NULL) const; +}; + + +// These have explicit template instantiations so you can use them. +typedef WCKeyValuesT WCKeyValues; +typedef WCKeyValuesT WCKeyValuesVector; + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : nIndex - +//----------------------------------------------------------------------------- +template +inline const char *WCKeyValuesT::GetKey(int nIndex) const +{ + return(m_KeyValues.Element(nIndex).szKey); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : nIndex - +// Output : MDKeyValue +//----------------------------------------------------------------------------- +template +inline MDkeyvalue &WCKeyValuesT::GetKeyValue(int nIndex) +{ + return(m_KeyValues.Element(nIndex)); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : nIndex - +// Output : MDkeyvalue +//----------------------------------------------------------------------------- +template +inline const MDkeyvalue& WCKeyValuesT::GetKeyValue(int nIndex) const +{ + return(m_KeyValues.Element(nIndex)); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : nIndex - +//----------------------------------------------------------------------------- +template +inline const char *WCKeyValuesT::GetValue(int nIndex) const +{ + return(m_KeyValues.Element(nIndex).szValue); +} + + +void StripEdgeWhiteSpace(char *psz); + + +#endif // WCKEYVALUES_H diff --git a/sp/src/public/filesystem.h b/sp/src/public/filesystem.h new file mode 100644 index 00000000..9ae55bcb --- /dev/null +++ b/sp/src/public/filesystem.h @@ -0,0 +1,978 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include + +#include "tier0/threadtools.h" +#include "tier0/memalloc.h" +#include "tier1/interface.h" +#include "tier1/utlsymbol.h" +#include "tier1/utlstring.h" +#include "appframework/IAppSystem.h" +#include "tier1/checksum_crc.h" +#include "tier1/checksum_md5.h" +#include "tier1/refcount.h" + +#ifndef FILESYSTEM_H +#define FILESYSTEM_H + +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- + +class CUtlBuffer; +class KeyValues; +class IFileList; +class IThreadPool; +class CMemoryFileBacking; + +typedef void * FileHandle_t; +typedef void * FileCacheHandle_t; +typedef int FileFindHandle_t; +typedef void (*FileSystemLoggingFunc_t)( const char *fileName, const char *accessType ); +typedef int WaitForResourcesHandle_t; + +#ifdef _X360 +typedef void* HANDLE; +#endif + +#define USE_CRC_FILE_TRACKING 0 + +// Turn on some extra pure server debug spew in certain builds. +// WARNING: This spew can be used by hackers to locate places to hack +// the code to bypas sv_pure! Be careful! +#if defined( _DEBUG ) || defined( STAGING_ONLY ) + #define PURE_SERVER_DEBUG_SPEW +#endif + +/// How strict will the pure server be for a particular set of files +enum EPureServerFileClass +{ + ePureServerFileClass_Unknown = -1, // dummy debugging value + ePureServerFileClass_Any = 0, + ePureServerFileClass_AnyTrusted, + ePureServerFileClass_CheckHash, +}; + +class IPureServerWhitelist +{ +public: + + // Reference counting + virtual void AddRef() = 0; + virtual void Release() = 0; + + // What should we do with a particular file? + virtual EPureServerFileClass GetFileClass( const char *pszFilename ) = 0; + + // Access list of trusted keys which we will allow to set trusted content + virtual int GetTrustedKeyCount() const = 0; + virtual const byte *GetTrustedKey( int iKeyIndex, int *nKeySize ) const = 0; +}; + +//----------------------------------------------------------------------------- +// Enums used by the interface +//----------------------------------------------------------------------------- + +#define FILESYSTEM_MAX_SEARCH_PATHS 128 + +enum FileSystemSeek_t +{ + FILESYSTEM_SEEK_HEAD = SEEK_SET, + FILESYSTEM_SEEK_CURRENT = SEEK_CUR, + FILESYSTEM_SEEK_TAIL = SEEK_END, +}; + +enum +{ + FILESYSTEM_INVALID_FIND_HANDLE = -1 +}; + +enum FileWarningLevel_t +{ + // A problem! + FILESYSTEM_WARNING = -1, + + // Don't print anything + FILESYSTEM_WARNING_QUIET = 0, + + // On shutdown, report names of files left unclosed + FILESYSTEM_WARNING_REPORTUNCLOSED, + + // Report number of times a file was opened, closed + FILESYSTEM_WARNING_REPORTUSAGE, + + // Report all open/close events to console ( !slow! ) + FILESYSTEM_WARNING_REPORTALLACCESSES, + + // Report all open/close/read events to the console ( !slower! ) + FILESYSTEM_WARNING_REPORTALLACCESSES_READ, + + // Report all open/close/read/write events to the console ( !slower! ) + FILESYSTEM_WARNING_REPORTALLACCESSES_READWRITE, + + // Report all open/close/read/write events and all async I/O file events to the console ( !slower(est)! ) + FILESYSTEM_WARNING_REPORTALLACCESSES_ASYNC, + +}; + +// search path filtering +enum PathTypeFilter_t +{ + FILTER_NONE = 0, // no filtering, all search path types match + FILTER_CULLPACK = 1, // pack based search paths are culled (maps and zips) + FILTER_CULLNONPACK = 2, // non-pack based search paths are culled +}; + +// search path querying (bit flags) +enum +{ + PATH_IS_NORMAL = 0x00, // normal path, not pack based + PATH_IS_PACKFILE = 0x01, // path is a pack file + PATH_IS_MAPPACKFILE = 0x02, // path is a map pack file + PATH_IS_REMOTE = 0x04, // path is the remote filesystem +}; +typedef uint32 PathTypeQuery_t; + +#define IS_PACKFILE( n ) ( n & ( PATH_IS_PACKFILE | PATH_IS_MAPPACKFILE ) ) +#define IS_REMOTE( n ) ( n & PATH_IS_REMOTE ) + +enum DVDMode_t +{ + DVDMODE_OFF = 0, // not using dvd + DVDMODE_STRICT = 1, // dvd device only + DVDMODE_DEV = 2, // dev mode, mutiple devices ok +}; + +// In non-retail builds, enable the file blocking access tracking stuff... +#if defined( TRACK_BLOCKING_IO ) +enum FileBlockingWarning_t +{ + // Report how long synchronous i/o took to complete + FILESYSTEM_BLOCKING_SYNCHRONOUS = 0, + // Report how long async i/o took to complete if AsyncFileFinished caused it to load via "blocking" i/o + FILESYSTEM_BLOCKING_ASYNCHRONOUS_BLOCK, + // Report how long async i/o took to complete + FILESYSTEM_BLOCKING_ASYNCHRONOUS, + // Report how long the async "callback" took + FILESYSTEM_BLOCKING_CALLBACKTIMING, + + FILESYSTEM_BLOCKING_NUMBINS, +}; + +#pragma pack(1) +class FileBlockingItem +{ +public: + enum + { + FB_ACCESS_OPEN = 1, + FB_ACCESS_CLOSE = 2, + FB_ACCESS_READ = 3, + FB_ACCESS_WRITE = 4, + FB_ACCESS_APPEND = 5, + FB_ACCESS_SIZE = 6 + }; + + FileBlockingItem() : + m_ItemType( (FileBlockingWarning_t)0 ), + m_flElapsed( 0.0f ), + m_nAccessType( 0 ) + { + SetFileName( NULL ); + } + + FileBlockingItem( int type, char const *filename, float elapsed, int accessType ) : + m_ItemType( (FileBlockingWarning_t)type ), + m_flElapsed( elapsed ), + m_nAccessType( accessType ) + { + SetFileName( filename ); + } + + void SetFileName( char const *filename ) + { + if ( !filename ) + { + m_szFilename[ 0 ] = 0; + return; + } + + int len = Q_strlen( filename ); + if ( len >= sizeof( m_szFilename ) ) + { + Q_strncpy( m_szFilename, &filename[ len - sizeof( m_szFilename ) + 1 ], sizeof( m_szFilename ) ); + } + else + { + Q_strncpy( m_szFilename, filename, sizeof( m_szFilename ) ); + } + } + + char const *GetFileName() const + { + return m_szFilename; + } + + FileBlockingWarning_t m_ItemType; + float m_flElapsed; + byte m_nAccessType; +private: + + char m_szFilename[ 32 ]; +}; +#pragma pack() + +class IBlockingFileItemList +{ +public: + + // You can't call any of the below calls without locking first + virtual void LockMutex() = 0; + virtual void UnlockMutex() = 0; + + virtual int First() const = 0; + virtual int Next( int i ) const = 0; + virtual int InvalidIndex() const = 0; + + virtual const FileBlockingItem& Get( int index ) const = 0; + + virtual void Reset() = 0; +}; + +#endif // TRACK_BLOCKING_IO + +enum FilesystemMountRetval_t +{ + FILESYSTEM_MOUNT_OK = 0, + FILESYSTEM_MOUNT_FAILED, +}; + +enum SearchPathAdd_t +{ + PATH_ADD_TO_HEAD, // First path searched + PATH_ADD_TO_TAIL, // Last path searched +}; + +enum FilesystemOpenExFlags_t +{ + FSOPEN_UNBUFFERED = (1 << 0), + FSOPEN_FORCE_TRACK_CRC = (1 << 1), // This makes it calculate a CRC for the file (if the file came from disk) regardless + // of the IFileList passed to RegisterFileWhitelist. + FSOPEN_NEVERINPACK = (1 << 2), // 360 only, hint to FS that file is not allowed to be in pack file +}; + +#define FILESYSTEM_INVALID_HANDLE ( FileHandle_t )0 + +//----------------------------------------------------------------------------- +// Structures used by the interface +//----------------------------------------------------------------------------- + +struct FileSystemStatistics +{ + CInterlockedUInt nReads, + nWrites, + nBytesRead, + nBytesWritten, + nSeeks; +}; + +//----------------------------------------------------------------------------- +// File system allocation functions. Client must free on failure +//----------------------------------------------------------------------------- +typedef void *(*FSAllocFunc_t)( const char *pszFilename, unsigned nBytes ); + + +//----------------------------------------------------------------------------- +// Used to display dirty disk error functions +//----------------------------------------------------------------------------- +typedef void (*FSDirtyDiskReportFunc_t)(); + + +//----------------------------------------------------------------------------- +// Asynchronous support types +//----------------------------------------------------------------------------- +DECLARE_POINTER_HANDLE(FSAsyncControl_t); +DECLARE_POINTER_HANDLE(FSAsyncFile_t); +const FSAsyncFile_t FS_INVALID_ASYNC_FILE = (FSAsyncFile_t)(0x0000ffff); + + +//--------------------------------------------------------- +// Async file status +//--------------------------------------------------------- +enum FSAsyncStatus_t +{ + FSASYNC_ERR_NOT_MINE = -8, // Filename not part of the specified file system, try a different one. (Used internally to find the right filesystem) + FSASYNC_ERR_RETRY_LATER = -7, // Failure for a reason that might be temporary. You might retry, but not immediately. (E.g. Network problems) + FSASYNC_ERR_ALIGNMENT = -6, // read parameters invalid for unbuffered IO + FSASYNC_ERR_FAILURE = -5, // hard subsystem failure + FSASYNC_ERR_READING = -4, // read error on file + FSASYNC_ERR_NOMEMORY = -3, // out of memory for file read + FSASYNC_ERR_UNKNOWNID = -2, // caller's provided id is not recognized + FSASYNC_ERR_FILEOPEN = -1, // filename could not be opened (bad path, not exist, etc) + FSASYNC_OK = 0, // operation is successful + FSASYNC_STATUS_PENDING, // file is properly queued, waiting for service + FSASYNC_STATUS_INPROGRESS, // file is being accessed + FSASYNC_STATUS_ABORTED, // file was aborted by caller + FSASYNC_STATUS_UNSERVICED, // file is not yet queued +}; + +//--------------------------------------------------------- +// Async request flags +//--------------------------------------------------------- +enum FSAsyncFlags_t +{ + FSASYNC_FLAGS_ALLOCNOFREE = ( 1 << 0 ), // do the allocation for dataPtr, but don't free + FSASYNC_FLAGS_FREEDATAPTR = ( 1 << 1 ), // free the memory for the dataPtr post callback + FSASYNC_FLAGS_SYNC = ( 1 << 2 ), // Actually perform the operation synchronously. Used to simplify client code paths + FSASYNC_FLAGS_NULLTERMINATE = ( 1 << 3 ), // allocate an extra byte and null terminate the buffer read in +}; + +//--------------------------------------------------------- +// Return value for CheckFileCRC. +//--------------------------------------------------------- +enum EFileCRCStatus +{ + k_eFileCRCStatus_CantOpenFile, // We don't have this file. + k_eFileCRCStatus_GotCRC, + k_eFileCRCStatus_FileInVPK +}; + +// Used in CacheFileCRCs. +enum ECacheCRCType +{ + k_eCacheCRCType_SingleFile, + k_eCacheCRCType_Directory, + k_eCacheCRCType_Directory_Recursive +}; + +//--------------------------------------------------------- +// Optional completion callback for each async file serviced (or failed) +// call is not reentrant, async i/o guaranteed suspended until return +// Note: If you change the signature of the callback, you will have to account for it in FileSystemV12 (toml [4/18/2005] ) +//--------------------------------------------------------- +struct FileAsyncRequest_t; +typedef void (*FSAsyncCallbackFunc_t)(const FileAsyncRequest_t &request, int nBytesRead, FSAsyncStatus_t err); + +//--------------------------------------------------------- +// Description of an async request +//--------------------------------------------------------- +struct FileAsyncRequest_t +{ + FileAsyncRequest_t() { memset( this, 0, sizeof(*this) ); hSpecificAsyncFile = FS_INVALID_ASYNC_FILE; } + const char * pszFilename; // file system name + void * pData; // optional, system will alloc/free if NULL + int nOffset; // optional initial seek_set, 0=beginning + int nBytes; // optional read clamp, -1=exist test, 0=full read + FSAsyncCallbackFunc_t pfnCallback; // optional completion callback + void * pContext; // caller's unique file identifier + int priority; // inter list priority, 0=lowest + unsigned flags; // behavior modifier + const char * pszPathID; // path ID (NOTE: this field is here to remain binary compatible with release HL2 filesystem interface) + FSAsyncFile_t hSpecificAsyncFile; // Optional hint obtained using AsyncBeginRead() + FSAllocFunc_t pfnAlloc; // custom allocator. can be null. not compatible with FSASYNC_FLAGS_FREEDATAPTR +}; + + +struct FileHash_t +{ + enum EFileHashType_t + { + k_EFileHashTypeUnknown = 0, + k_EFileHashTypeEntireFile = 1, + k_EFileHashTypeIncompleteFile = 2, + }; + FileHash_t() + { + m_eFileHashType = FileHash_t::k_EFileHashTypeUnknown; + m_cbFileLen = 0; + m_PackFileID = 0; + m_nPackFileNumber = 0; + } + int m_eFileHashType; + CRC32_t m_crcIOSequence; + MD5Value_t m_md5contents; + int m_cbFileLen; + int m_PackFileID; + int m_nPackFileNumber; + + bool operator==( const FileHash_t &src ) const + { + return m_crcIOSequence == src.m_crcIOSequence && + m_md5contents == src.m_md5contents && + m_eFileHashType == src.m_eFileHashType; + } + bool operator!=( const FileHash_t &src ) const + { + return m_crcIOSequence != src.m_crcIOSequence || + m_md5contents != src.m_md5contents || + m_eFileHashType != src.m_eFileHashType; + } + +}; + +class CUnverifiedFileHash +{ +public: + char m_PathID[MAX_PATH]; + char m_Filename[MAX_PATH]; + int m_nFileFraction; + FileHash_t m_FileHash; +}; + +class CUnverifiedCRCFile +{ +public: + char m_PathID[MAX_PATH]; + char m_Filename[MAX_PATH]; + CRC32_t m_CRC; +}; + +class CUnverifiedMD5File +{ +public: + char m_PathID[MAX_PATH]; + char m_Filename[MAX_PATH]; + unsigned char bits[MD5_DIGEST_LENGTH]; +}; + +// Spew flags for SetWhitelistSpewFlags (set with the fs_whitelist_spew_flags cvar). +// Update the comment for the fs_whitelist_spew_flags cvar if you change these. +#define WHITELIST_SPEW_WHILE_LOADING 0x0001 // list files as they are added to the CRC tracker +#define WHITELIST_SPEW_RELOAD_FILES 0x0002 // show files the filesystem is telling the engine to reload +#define WHITELIST_SPEW_DONT_RELOAD_FILES 0x0004 // show files the filesystem is NOT telling the engine to reload + +//----------------------------------------------------------------------------- +// Interface to fetch a file asynchronously from any source. This is used +// as a hook +//----------------------------------------------------------------------------- + +abstract_class IAsyncFileFetch { +public: + typedef void *Handle; + + /// Initiate a request. Returns error status, or on success + /// returns an opaque handle used to terminate the job + /// + /// Should return FSASYNC_ERR_NOT_MINE if the filename isn't + /// handled by this interface + /// + /// The callback is required, and is the only mechanism to communicate + /// status. (No polling.) The request is automatically destroyed anytime + /// after the callback is executed. + virtual FSAsyncStatus_t Start( const FileAsyncRequest_t &request, Handle *pOutHandle, IThreadPool *pThreadPool ) = 0; + + /// Attempt to complete any active work, returning status. The callback WILL + /// be executed (this is necessary in case we allocated the buffer). + /// Afterwards, the request is automatically destroyed. + virtual FSAsyncStatus_t FinishSynchronous( Handle hControl ) = 0; + + /// Terminate any active work and destroy all resources and bookkeeping info. + /// The callback will NOT be executed. + virtual FSAsyncStatus_t Abort( Handle hControl ) = 0; +}; + +// This interface is for VPK files to communicate with FileTracker +abstract_class IThreadedFileMD5Processor +{ +public: + virtual int SubmitThreadedMD5Request( uint8 *pubBuffer, int cubBuffer, int PackFileID, int nPackFileNumber, int nPackFileFraction ) = 0; + virtual bool BlockUntilMD5RequestComplete( int iRequest, MD5Value_t *pMd5ValueOut ) = 0; + virtual bool IsMD5RequestComplete( int iRequest, MD5Value_t *pMd5ValueOut ) = 0; +}; + +//----------------------------------------------------------------------------- +// Base file system interface +//----------------------------------------------------------------------------- + +// This is the minimal interface that can be implemented to provide access to +// a named set of files. +#define BASEFILESYSTEM_INTERFACE_VERSION "VBaseFileSystem011" + +abstract_class IBaseFileSystem +{ +public: + virtual int Read( void* pOutput, int size, FileHandle_t file ) = 0; + virtual int Write( void const* pInput, int size, FileHandle_t file ) = 0; + + // if pathID is NULL, all paths will be searched for the file + virtual FileHandle_t Open( const char *pFileName, const char *pOptions, const char *pathID = 0 ) = 0; + virtual void Close( FileHandle_t file ) = 0; + + + virtual void Seek( FileHandle_t file, int pos, FileSystemSeek_t seekType ) = 0; + virtual unsigned int Tell( FileHandle_t file ) = 0; + virtual unsigned int Size( FileHandle_t file ) = 0; + virtual unsigned int Size( const char *pFileName, const char *pPathID = 0 ) = 0; + + virtual void Flush( FileHandle_t file ) = 0; + virtual bool Precache( const char *pFileName, const char *pPathID = 0 ) = 0; + + virtual bool FileExists( const char *pFileName, const char *pPathID = 0 ) = 0; + virtual bool IsFileWritable( char const *pFileName, const char *pPathID = 0 ) = 0; + virtual bool SetFileWritable( char const *pFileName, bool writable, const char *pPathID = 0 ) = 0; + + virtual long GetFileTime( const char *pFileName, const char *pPathID = 0 ) = 0; + + //-------------------------------------------------------- + // Reads/writes files to utlbuffers. Use this for optimal read performance when doing open/read/close + //-------------------------------------------------------- + virtual bool ReadFile( const char *pFileName, const char *pPath, CUtlBuffer &buf, int nMaxBytes = 0, int nStartingByte = 0, FSAllocFunc_t pfnAlloc = NULL ) = 0; + virtual bool WriteFile( const char *pFileName, const char *pPath, CUtlBuffer &buf ) = 0; + virtual bool UnzipFile( const char *pFileName, const char *pPath, const char *pDestination ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Main file system interface +//----------------------------------------------------------------------------- + +#define FILESYSTEM_INTERFACE_VERSION "VFileSystem022" + +abstract_class IFileSystem : public IAppSystem, public IBaseFileSystem +{ +public: + //-------------------------------------------------------- + // Steam operations + //-------------------------------------------------------- + + virtual bool IsSteam() const = 0; + + // Supplying an extra app id will mount this app in addition + // to the one specified in the environment variable "steamappid" + // + // If nExtraAppId is < -1, then it will mount that app ID only. + // (Was needed by the dedicated server b/c the "SteamAppId" env var only gets passed to steam.dll + // at load time, so the dedicated couldn't pass it in that way). + virtual FilesystemMountRetval_t MountSteamContent( int nExtraAppId = -1 ) = 0; + + //-------------------------------------------------------- + // Search path manipulation + //-------------------------------------------------------- + + // Add paths in priority order (mod dir, game dir, ....) + // If one or more .pak files are in the specified directory, then they are + // added after the file system path + // If the path is the relative path to a .bsp file, then any previous .bsp file + // override is cleared and the current .bsp is searched for an embedded PAK file + // and this file becomes the highest priority search path ( i.e., it's looked at first + // even before the mod's file system path ). + virtual void AddSearchPath( const char *pPath, const char *pathID, SearchPathAdd_t addType = PATH_ADD_TO_TAIL ) = 0; + virtual bool RemoveSearchPath( const char *pPath, const char *pathID = 0 ) = 0; + + // Remove all search paths (including write path?) + virtual void RemoveAllSearchPaths( void ) = 0; + + // Remove search paths associated with a given pathID + virtual void RemoveSearchPaths( const char *szPathID ) = 0; + + // This is for optimization. If you mark a path ID as "by request only", then files inside it + // will only be accessed if the path ID is specifically requested. Otherwise, it will be ignored. + // If there are currently no search paths with the specified path ID, then it will still + // remember it in case you add search paths with this path ID. + virtual void MarkPathIDByRequestOnly( const char *pPathID, bool bRequestOnly ) = 0; + + // converts a partial path into a full path + virtual const char *RelativePathToFullPath( const char *pFileName, const char *pPathID, char *pLocalPath, int localPathBufferSize, PathTypeFilter_t pathFilter = FILTER_NONE, PathTypeQuery_t *pPathType = NULL ) = 0; + + // Returns the search path, each path is separated by ;s. Returns the length of the string returned + virtual int GetSearchPath( const char *pathID, bool bGetPackFiles, char *pPath, int nMaxLen ) = 0; + + // interface for custom pack files > 4Gb + virtual bool AddPackFile( const char *fullpath, const char *pathID ) = 0; + + //-------------------------------------------------------- + // File manipulation operations + //-------------------------------------------------------- + + // Deletes a file (on the WritePath) + virtual void RemoveFile( char const* pRelativePath, const char *pathID = 0 ) = 0; + + // Renames a file (on the WritePath) + virtual bool RenameFile( char const *pOldPath, char const *pNewPath, const char *pathID = 0 ) = 0; + + // create a local directory structure + virtual void CreateDirHierarchy( const char *path, const char *pathID = 0 ) = 0; + + // File I/O and info + virtual bool IsDirectory( const char *pFileName, const char *pathID = 0 ) = 0; + + virtual void FileTimeToString( char* pStrip, int maxCharsIncludingTerminator, long fileTime ) = 0; + + //-------------------------------------------------------- + // Open file operations + //-------------------------------------------------------- + + virtual void SetBufferSize( FileHandle_t file, unsigned nBytes ) = 0; + + virtual bool IsOk( FileHandle_t file ) = 0; + + virtual bool EndOfFile( FileHandle_t file ) = 0; + + virtual char *ReadLine( char *pOutput, int maxChars, FileHandle_t file ) = 0; + virtual int FPrintf( FileHandle_t file, PRINTF_FORMAT_STRING const char *pFormat, ... ) = 0; + + //-------------------------------------------------------- + // Dynamic library operations + //-------------------------------------------------------- + + // load/unload modules + virtual CSysModule *LoadModule( const char *pFileName, const char *pPathID = 0, bool bValidatedDllOnly = true ) = 0; + virtual void UnloadModule( CSysModule *pModule ) = 0; + + //-------------------------------------------------------- + // File searching operations + //-------------------------------------------------------- + + // FindFirst/FindNext. Also see FindFirstEx. + virtual const char *FindFirst( const char *pWildCard, FileFindHandle_t *pHandle ) = 0; + virtual const char *FindNext( FileFindHandle_t handle ) = 0; + virtual bool FindIsDirectory( FileFindHandle_t handle ) = 0; + virtual void FindClose( FileFindHandle_t handle ) = 0; + + // Same as FindFirst, but you can filter by path ID, which can make it faster. + virtual const char *FindFirstEx( + const char *pWildCard, + const char *pPathID, + FileFindHandle_t *pHandle + ) = 0; + + //-------------------------------------------------------- + // File name and directory operations + //-------------------------------------------------------- + + // FIXME: This method is obsolete! Use RelativePathToFullPath instead! + // converts a partial path into a full path + virtual const char *GetLocalPath( const char *pFileName, char *pLocalPath, int localPathBufferSize ) = 0; + + // Returns true on success ( based on current list of search paths, otherwise false if + // it can't be resolved ) + virtual bool FullPathToRelativePath( const char *pFullpath, char *pRelative, int maxlen ) = 0; + + // Gets the current working directory + virtual bool GetCurrentDirectory( char* pDirectory, int maxlen ) = 0; + + //-------------------------------------------------------- + // Filename dictionary operations + //-------------------------------------------------------- + + virtual FileNameHandle_t FindOrAddFileName( char const *pFileName ) = 0; + virtual bool String( const FileNameHandle_t& handle, char *buf, int buflen ) = 0; + + //-------------------------------------------------------- + // Asynchronous file operations + //-------------------------------------------------------- + + //------------------------------------ + // Global operations + //------------------------------------ + FSAsyncStatus_t AsyncRead( const FileAsyncRequest_t &request, FSAsyncControl_t *phControl = NULL ) { return AsyncReadMultiple( &request, 1, phControl ); } + virtual FSAsyncStatus_t AsyncReadMultiple( const FileAsyncRequest_t *pRequests, int nRequests, FSAsyncControl_t *phControls = NULL ) = 0; + virtual FSAsyncStatus_t AsyncAppend(const char *pFileName, const void *pSrc, int nSrcBytes, bool bFreeMemory, FSAsyncControl_t *pControl = NULL ) = 0; + virtual FSAsyncStatus_t AsyncAppendFile(const char *pAppendToFileName, const char *pAppendFromFileName, FSAsyncControl_t *pControl = NULL ) = 0; + virtual void AsyncFinishAll( int iToPriority = 0 ) = 0; + virtual void AsyncFinishAllWrites() = 0; + virtual FSAsyncStatus_t AsyncFlush() = 0; + virtual bool AsyncSuspend() = 0; + virtual bool AsyncResume() = 0; + + /// Add async fetcher interface. This gives apps a hook to intercept async requests and + /// pull the data from a source of their choosing. The immediate use case is to load + /// assets from the CDN via HTTP. + virtual void AsyncAddFetcher( IAsyncFileFetch *pFetcher ) = 0; + virtual void AsyncRemoveFetcher( IAsyncFileFetch *pFetcher ) = 0; + + //------------------------------------ + // Functions to hold a file open if planning on doing mutiple reads. Use is optional, + // and is taken only as a hint + //------------------------------------ + virtual FSAsyncStatus_t AsyncBeginRead( const char *pszFile, FSAsyncFile_t *phFile ) = 0; + virtual FSAsyncStatus_t AsyncEndRead( FSAsyncFile_t hFile ) = 0; + + //------------------------------------ + // Request management + //------------------------------------ + virtual FSAsyncStatus_t AsyncFinish( FSAsyncControl_t hControl, bool wait = true ) = 0; + virtual FSAsyncStatus_t AsyncGetResult( FSAsyncControl_t hControl, void **ppData, int *pSize ) = 0; + virtual FSAsyncStatus_t AsyncAbort( FSAsyncControl_t hControl ) = 0; + virtual FSAsyncStatus_t AsyncStatus( FSAsyncControl_t hControl ) = 0; + // set a new priority for a file already in the queue + virtual FSAsyncStatus_t AsyncSetPriority(FSAsyncControl_t hControl, int newPriority) = 0; + virtual void AsyncAddRef( FSAsyncControl_t hControl ) = 0; + virtual void AsyncRelease( FSAsyncControl_t hControl ) = 0; + + //-------------------------------------------------------- + // Remote resource management + //-------------------------------------------------------- + + // starts waiting for resources to be available + // returns FILESYSTEM_INVALID_HANDLE if there is nothing to wait on + virtual WaitForResourcesHandle_t WaitForResources( const char *resourcelist ) = 0; + // get progress on waiting for resources; progress is a float [0, 1], complete is true on the waiting being done + // returns false if no progress is available + // any calls after complete is true or on an invalid handle will return false, 0.0f, true + virtual bool GetWaitForResourcesProgress( WaitForResourcesHandle_t handle, float *progress /* out */ , bool *complete /* out */ ) = 0; + // cancels a progress call + virtual void CancelWaitForResources( WaitForResourcesHandle_t handle ) = 0; + + // hints that a set of files will be loaded in near future + // HintResourceNeed() is not to be confused with resource precaching. + virtual int HintResourceNeed( const char *hintlist, int forgetEverything ) = 0; + // returns true if a file is on disk + virtual bool IsFileImmediatelyAvailable(const char *pFileName) = 0; + + // copies file out of pak/bsp/steam cache onto disk (to be accessible by third-party code) + virtual void GetLocalCopy( const char *pFileName ) = 0; + + //-------------------------------------------------------- + // Debugging operations + //-------------------------------------------------------- + + // Dump to printf/OutputDebugString the list of files that have not been closed + virtual void PrintOpenedFiles( void ) = 0; + virtual void PrintSearchPaths( void ) = 0; + + // output + virtual void SetWarningFunc( void (*pfnWarning)( PRINTF_FORMAT_STRING const char *fmt, ... ) ) = 0; + virtual void SetWarningLevel( FileWarningLevel_t level ) = 0; + virtual void AddLoggingFunc( void (*pfnLogFunc)( const char *fileName, const char *accessType ) ) = 0; + virtual void RemoveLoggingFunc( FileSystemLoggingFunc_t logFunc ) = 0; + + // Returns the file system statistics retreived by the implementation. Returns NULL if not supported. + virtual const FileSystemStatistics *GetFilesystemStatistics() = 0; + + //-------------------------------------------------------- + // Start of new functions after Lost Coast release (7/05) + //-------------------------------------------------------- + + virtual FileHandle_t OpenEx( const char *pFileName, const char *pOptions, unsigned flags = 0, const char *pathID = 0, char **ppszResolvedFilename = NULL ) = 0; + + // Extended version of read provides more context to allow for more optimal reading + virtual int ReadEx( void* pOutput, int sizeDest, int size, FileHandle_t file ) = 0; + virtual int ReadFileEx( const char *pFileName, const char *pPath, void **ppBuf, bool bNullTerminate = false, bool bOptimalAlloc = false, int nMaxBytes = 0, int nStartingByte = 0, FSAllocFunc_t pfnAlloc = NULL ) = 0; + + virtual FileNameHandle_t FindFileName( char const *pFileName ) = 0; + +#if defined( TRACK_BLOCKING_IO ) + virtual void EnableBlockingFileAccessTracking( bool state ) = 0; + virtual bool IsBlockingFileAccessEnabled() const = 0; + + virtual IBlockingFileItemList *RetrieveBlockingFileAccessInfo() = 0; +#endif + + virtual void SetupPreloadData() = 0; + virtual void DiscardPreloadData() = 0; + + // Fixme, we could do these via a string embedded into the compiled data, etc... + enum KeyValuesPreloadType_t + { + TYPE_VMT, + TYPE_SOUNDEMITTER, + TYPE_SOUNDSCAPE, + NUM_PRELOAD_TYPES + }; + + virtual void LoadCompiledKeyValues( KeyValuesPreloadType_t type, char const *archiveFile ) = 0; + + // If the "PreloadedData" hasn't been purged, then this'll try and instance the KeyValues using the fast path of compiled keyvalues loaded during startup. + // Otherwise, it'll just fall through to the regular KeyValues loading routines + virtual KeyValues *LoadKeyValues( KeyValuesPreloadType_t type, char const *filename, char const *pPathID = 0 ) = 0; + virtual bool LoadKeyValues( KeyValues& head, KeyValuesPreloadType_t type, char const *filename, char const *pPathID = 0 ) = 0; + virtual bool ExtractRootKeyName( KeyValuesPreloadType_t type, char *outbuf, size_t bufsize, char const *filename, char const *pPathID = 0 ) = 0; + + virtual FSAsyncStatus_t AsyncWrite(const char *pFileName, const void *pSrc, int nSrcBytes, bool bFreeMemory, bool bAppend = false, FSAsyncControl_t *pControl = NULL ) = 0; + virtual FSAsyncStatus_t AsyncWriteFile(const char *pFileName, const CUtlBuffer *pSrc, int nSrcBytes, bool bFreeMemory, bool bAppend = false, FSAsyncControl_t *pControl = NULL ) = 0; + // Async read functions with memory blame + FSAsyncStatus_t AsyncReadCreditAlloc( const FileAsyncRequest_t &request, const char *pszFile, int line, FSAsyncControl_t *phControl = NULL ) { return AsyncReadMultipleCreditAlloc( &request, 1, pszFile, line, phControl ); } + virtual FSAsyncStatus_t AsyncReadMultipleCreditAlloc( const FileAsyncRequest_t *pRequests, int nRequests, const char *pszFile, int line, FSAsyncControl_t *phControls = NULL ) = 0; + + virtual bool GetFileTypeForFullPath( char const *pFullPath, OUT_Z_BYTECAP(bufSizeInBytes) wchar_t *buf, size_t bufSizeInBytes ) = 0; + + //-------------------------------------------------------- + //-------------------------------------------------------- + virtual bool ReadToBuffer( FileHandle_t hFile, CUtlBuffer &buf, int nMaxBytes = 0, FSAllocFunc_t pfnAlloc = NULL ) = 0; + + //-------------------------------------------------------- + // Optimal IO operations + //-------------------------------------------------------- + virtual bool GetOptimalIOConstraints( FileHandle_t hFile, unsigned *pOffsetAlign, unsigned *pSizeAlign, unsigned *pBufferAlign ) = 0; + inline unsigned GetOptimalReadSize( FileHandle_t hFile, unsigned nLogicalSize ); + virtual void *AllocOptimalReadBuffer( FileHandle_t hFile, unsigned nSize = 0, unsigned nOffset = 0 ) = 0; + virtual void FreeOptimalReadBuffer( void * ) = 0; + + //-------------------------------------------------------- + // + //-------------------------------------------------------- + virtual void BeginMapAccess() = 0; + virtual void EndMapAccess() = 0; + + // Returns true on success, otherwise false if it can't be resolved + virtual bool FullPathToRelativePathEx( const char *pFullpath, const char *pPathId, char *pRelative, int maxlen ) = 0; + + virtual int GetPathIndex( const FileNameHandle_t &handle ) = 0; + virtual long GetPathTime( const char *pPath, const char *pPathID ) = 0; + + virtual DVDMode_t GetDVDMode() = 0; + + //-------------------------------------------------------- + // Whitelisting for pure servers. + //-------------------------------------------------------- + + // This should be called ONCE at startup. Multiplayer games (gameinfo.txt does not contain singleplayer_only) + // want to enable this so sv_pure works. + virtual void EnableWhitelistFileTracking( bool bEnable, bool bCacheAllVPKHashes, bool bRecalculateAndCheckHashes ) = 0; + + // This is called when the client connects to a server using a pure_server_whitelist.txt file. + virtual void RegisterFileWhitelist( IPureServerWhitelist *pWhiteList, IFileList **pFilesToReload ) = 0; + + // Called when the client logs onto a server. Any files that came off disk should be marked as + // unverified because this server may have a different set of files it wants to guarantee. + virtual void MarkAllCRCsUnverified() = 0; + + // As the server loads whitelists when it transitions maps, it calls this to calculate CRCs for any files marked + // with check_crc. Then it calls CheckCachedFileCRC later when it gets client requests to verify CRCs. + virtual void CacheFileCRCs( const char *pPathname, ECacheCRCType eType, IFileList *pFilter ) = 0; + virtual EFileCRCStatus CheckCachedFileHash( const char *pPathID, const char *pRelativeFilename, int nFileFraction, FileHash_t *pFileHash ) = 0; + + // Fills in the list of files that have been loaded off disk and have not been verified. + // Returns the number of files filled in (between 0 and nMaxFiles). + // + // This also removes any files it's returning from the unverified CRC list, so they won't be + // returned from here again. + // The client sends batches of these to the server to verify. + virtual int GetUnverifiedFileHashes( CUnverifiedFileHash *pFiles, int nMaxFiles ) = 0; + + // Control debug message output. + // Pass a combination of WHITELIST_SPEW_ flags. + virtual int GetWhitelistSpewFlags() = 0; + virtual void SetWhitelistSpewFlags( int flags ) = 0; + + // Installs a callback used to display a dirty disk dialog + virtual void InstallDirtyDiskReportFunc( FSDirtyDiskReportFunc_t func ) = 0; + + //-------------------------------------------------------- + // Low-level file caching. Cached files are loaded into memory and used + // to satisfy read requests (sync and async) until the cache is destroyed. + // NOTE: this could defeat file whitelisting, if a file were loaded in + // a non-whitelisted environment and then reused. Clients should not cache + // files across moves between pure/non-pure environments. + //-------------------------------------------------------- + virtual FileCacheHandle_t CreateFileCache() = 0; + virtual void AddFilesToFileCache( FileCacheHandle_t cacheId, const char **ppFileNames, int nFileNames, const char *pPathID ) = 0; + virtual bool IsFileCacheFileLoaded( FileCacheHandle_t cacheId, const char* pFileName ) = 0; + virtual bool IsFileCacheLoaded( FileCacheHandle_t cacheId ) = 0; + virtual void DestroyFileCache( FileCacheHandle_t cacheId ) = 0; + + // XXX For now, we assume that all path IDs are "GAME", never cache files + // outside of the game search path, and preferentially return those files + // whenever anyone searches for a match even if an on-disk file in another + // folder would have been found first in a traditional search. extending + // the memory cache to cover non-game files isn't necessary right now, but + // should just be a matter of defining a more complex key type. (henryg) + + // Register a CMemoryFileBacking; must balance with UnregisterMemoryFile. + // Returns false and outputs an ref-bumped pointer to the existing entry + // if the same file has already been registered by someone else; this must + // be Unregistered to maintain the balance. + virtual bool RegisterMemoryFile( CMemoryFileBacking *pFile, CMemoryFileBacking **ppExistingFileWithRef ) = 0; + + // Unregister a CMemoryFileBacking; must balance with RegisterMemoryFile. + virtual void UnregisterMemoryFile( CMemoryFileBacking *pFile ) = 0; + + virtual void CacheAllVPKFileHashes( bool bCacheAllVPKHashes, bool bRecalculateAndCheckHashes ) = 0; + virtual bool CheckVPKFileHash( int PackFileID, int nPackFileNumber, int nFileFraction, MD5Value_t &md5Value ) = 0; + + // Called when we unload a file, to remove that file's info for pure server purposes. + virtual void NotifyFileUnloaded( const char *pszFilename, const char *pPathId ) = 0; +}; + +//----------------------------------------------------------------------------- +// Memory file backing, which you can use to fake out the filesystem, caching data +// in memory and have it associated with a file +//----------------------------------------------------------------------------- +class CMemoryFileBacking : public CRefCounted +{ +public: + CMemoryFileBacking( IFileSystem* pFS ) : m_pFS( pFS ), m_nRegistered( 0 ), m_pFileName( NULL ), m_pData( NULL ), m_nLength( 0 ) { } + ~CMemoryFileBacking() { free( (char*) m_pFileName ); if ( m_pData ) m_pFS->FreeOptimalReadBuffer( (char*) m_pData ); } + + IFileSystem* m_pFS; + int m_nRegistered; + const char* m_pFileName; + const char* m_pData; + int m_nLength; + +private: + CMemoryFileBacking( const CMemoryFileBacking& ); // not defined + CMemoryFileBacking& operator=( const CMemoryFileBacking& ); // not defined +}; + +//----------------------------------------------------------------------------- + +#if defined( _X360 ) && !defined( _RETAIL ) +extern char g_szXboxProfileLastFileOpened[MAX_PATH]; +#define SetLastProfileFileRead( s ) Q_strncpy( g_szXboxProfileLastFileOpened, sizeof( g_szXboxProfileLastFileOpened), pFileName ) +#define GetLastProfileFileRead() (&g_szXboxProfileLastFileOpened[0]) +#else +#define SetLastProfileFileRead( s ) ((void)0) +#define GetLastProfileFileRead() NULL +#endif + +#if defined( _X360 ) && defined( _BASETSD_H_ ) +class CXboxDiskCacheSetter +{ +public: + CXboxDiskCacheSetter( SIZE_T newSize ) + { + m_oldSize = XGetFileCacheSize(); + XSetFileCacheSize( newSize ); + } + + ~CXboxDiskCacheSetter() + { + XSetFileCacheSize( m_oldSize ); + } +private: + SIZE_T m_oldSize; +}; +#define DISK_INTENSIVE() CXboxDiskCacheSetter cacheSetter( 1024*1024 ) +#else +#define DISK_INTENSIVE() ((void)0) +#endif + +//----------------------------------------------------------------------------- + +inline unsigned IFileSystem::GetOptimalReadSize( FileHandle_t hFile, unsigned nLogicalSize ) +{ + unsigned align; + if ( GetOptimalIOConstraints( hFile, &align, NULL, NULL ) ) + return AlignValue( nLogicalSize, align ); + else + return nLogicalSize; +} + +//----------------------------------------------------------------------------- + +// We include this here so it'll catch compile errors in VMPI early. +#include "filesystem_passthru.h" + +//----------------------------------------------------------------------------- +// Async memory tracking +//----------------------------------------------------------------------------- + +#if (defined(_DEBUG) || defined(USE_MEM_DEBUG)) +#define AsyncRead( a, b ) AsyncReadCreditAlloc( a, __FILE__, __LINE__, b ) +#define AsyncReadMutiple( a, b, c ) AsyncReadMultipleCreditAlloc( a, b, __FILE__, __LINE__, c ) +#endif + +extern IFileSystem *g_pFullFileSystem; + +#endif // FILESYSTEM_H diff --git a/sp/src/public/filesystem/IQueuedLoader.h b/sp/src/public/filesystem/IQueuedLoader.h new file mode 100644 index 00000000..2d5580a5 --- /dev/null +++ b/sp/src/public/filesystem/IQueuedLoader.h @@ -0,0 +1,156 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#ifndef QUEUEDLOADER_H +#define QUEUEDLOADER_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier0/platform.h" +#include "appframework/IAppSystem.h" + +class CFunctor; + +enum LoaderError_t +{ + LOADERERROR_NONE = 0, + LOADERERROR_FILEOPEN = -1, + LOADERERROR_READING = -2, +}; + +enum LoaderPriority_t +{ + LOADERPRIORITY_ANYTIME = 0, // low priority, job can finish during gameplay + LOADERPRIORITY_BEFOREPLAY = 1, // job must complete before load ends + LOADERPRIORITY_DURINGPRELOAD = 2, // job must be complete during preload phase +}; + +typedef void ( *QueuedLoaderCallback_t )( void *pContext, void *pContext2, const void *pData, int nSize, LoaderError_t loaderError ); + +typedef void ( *DynamicResourceCallback_t )( const char *pFilename, void *pContext, void *pContext2 ); + +struct LoaderJob_t +{ + LoaderJob_t() + { + memset( this, 0, sizeof( *this ) ); + } + + const char *m_pFilename; // path to resource + const char *m_pPathID; // optional, can be NULL + QueuedLoaderCallback_t m_pCallback; // called at i/o delivery + void *m_pContext; // caller provided data + void *m_pContext2; // caller provided data + void *m_pTargetData; // optional, caller provided target buffer + int m_nBytesToRead; // optional read clamp, otherwise 0 + unsigned int m_nStartOffset; // optional start offset, otherwise 0 + LoaderPriority_t m_Priority; // data must arrive by specified interval + bool m_bPersistTargetData; // caller wants ownership of i/o buffer +}; + +enum ResourcePreload_t +{ + RESOURCEPRELOAD_UNKNOWN, + RESOURCEPRELOAD_SOUND, + RESOURCEPRELOAD_MATERIAL, + RESOURCEPRELOAD_MODEL, + RESOURCEPRELOAD_CUBEMAP, + RESOURCEPRELOAD_STATICPROPLIGHTING, + RESOURCEPRELOAD_ANONYMOUS, + RESOURCEPRELOAD_COUNT +}; + +abstract_class IResourcePreload +{ +public: + // Called during preload phase for ALL the resources expected by the level. + // Caller should not do i/o but generate AddJob() requests. Resources that already exist + // and are not referenced by this function would be candidates for purge. + virtual bool CreateResource( const char *pName ) = 0; + + // Sent as an event hint during preload, that creation has completed, AddJob() i/o is about to commence. + // Caller should purge any unreferenced resources before the AddJobs are performed. + // "Must Complete" data will be guaranteed finished, at preload conclusion, before the normal load phase commences. + virtual void PurgeUnreferencedResources() = 0; + + // Sent as an event hint that gameplay rendering is imminent. + // Low priority jobs may still be in async flight. + virtual void OnEndMapLoading( bool bAbort ) = 0; + + virtual void PurgeAll() = 0; +}; + +// Default implementation +class CResourcePreload : public IResourcePreload +{ + void PurgeUnreferencedResources() {} + void OnEndMapLoading( bool bAbort ) {} + void PurgeAll() {} +}; + +// UI can install progress notification +abstract_class ILoaderProgress +{ +public: + // implementation must ignore UpdateProgress() if not scoped by Begin/End + virtual void BeginProgress() = 0; + virtual void EndProgress() = 0; + virtual void UpdateProgress( float progress ) = 0; +}; + +// spew detail +#define LOADER_DETAIL_NONE 0 +#define LOADER_DETAIL_TIMING (1<<0) +#define LOADER_DETAIL_COMPLETIONS (1<<1) +#define LOADER_DETAIL_LATECOMPLETIONS (1<<2) +#define LOADER_DETAIL_PURGES (1<<3) + +#define QUEUEDLOADER_INTERFACE_VERSION "QueuedLoaderVersion004" +abstract_class IQueuedLoader : public IAppSystem +{ +public: + virtual void InstallLoader( ResourcePreload_t type, IResourcePreload *pLoader ) = 0; + virtual void InstallProgress( ILoaderProgress *pProgress ) = 0; + + // Set bOptimizeReload if you want appropriate data (such as static prop lighting) + // to persist - rather than being purged and reloaded - when going from map A to map A. + virtual bool BeginMapLoading( const char *pMapName, bool bLoadForHDR, bool bOptimizeMapReload ) = 0; + virtual void EndMapLoading( bool bAbort ) = 0; + virtual bool AddJob( const LoaderJob_t *pLoaderJob ) = 0; + + // injects a resource into the map's reslist, rejected if not understood + virtual void AddMapResource( const char *pFilename ) = 0; + + // dynamically load a map resource + virtual void DynamicLoadMapResource( const char *pFilename, DynamicResourceCallback_t pCallback, void *pContext, void *pContext2 ) = 0; + virtual void QueueDynamicLoadFunctor( CFunctor* pFunctor ) = 0; + virtual bool CompleteDynamicLoad() = 0; + + // callback is asynchronous + virtual bool ClaimAnonymousJob( const char *pFilename, QueuedLoaderCallback_t pCallback, void *pContext, void *pContext2 = NULL ) = 0; + // provides data if loaded, caller owns data + virtual bool ClaimAnonymousJob( const char *pFilename, void **pData, int *pDataSize, LoaderError_t *pError = NULL ) = 0; + + virtual bool IsMapLoading() const = 0; + virtual bool IsSameMapLoading() const = 0; + virtual bool IsFinished() const = 0; + + // callers can expect that jobs are not immediately started when batching + virtual bool IsBatching() const = 0; + + virtual bool IsDynamic() const = 0; + + // callers can conditionalize operational spew + virtual int GetSpewDetail() const = 0; + + virtual void PurgeAll() = 0; +}; + +extern IQueuedLoader *g_pQueuedLoader; + +#endif // QUEUEDLOADER_H diff --git a/sp/src/public/filesystem_helpers.cpp b/sp/src/public/filesystem_helpers.cpp new file mode 100644 index 00000000..5e4ac997 --- /dev/null +++ b/sp/src/public/filesystem_helpers.cpp @@ -0,0 +1,129 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=====================================================================================// + +#include "filesystem.h" +#include "filesystem_helpers.h" +#include "characterset.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// wordbreak parsing set +static characterset_t g_BreakSet, g_BreakSetIncludingColons; + +static void InitializeCharacterSets() +{ + static bool s_CharacterSetInitialized = false; + if (!s_CharacterSetInitialized) + { + CharacterSetBuild( &g_BreakSet, "{}()'" ); + CharacterSetBuild( &g_BreakSetIncludingColons, "{}()':" ); + s_CharacterSetInitialized = true; + } +} + + +const char* ParseFileInternal( const char* pFileBytes, char* pTokenOut, bool* pWasQuoted, characterset_t *pCharSet, size_t nMaxTokenLen ) +{ + pTokenOut[0] = 0; + + if (pWasQuoted) + *pWasQuoted = false; + + if (!pFileBytes) + return 0; + + InitializeCharacterSets(); + + // YWB: Ignore colons as token separators in COM_Parse + static bool com_ignorecolons = false; + characterset_t& breaks = pCharSet ? *pCharSet : (com_ignorecolons ? g_BreakSet : g_BreakSetIncludingColons); + + int c; + unsigned int len = 0; + +// skip whitespace +skipwhite: + + while ( (c = *pFileBytes) <= ' ') + { + if (c == 0) + return 0; // end of file; + pFileBytes++; + } + +// skip // comments + if (c=='/' && pFileBytes[1] == '/') + { + while (*pFileBytes && *pFileBytes != '\n') + pFileBytes++; + goto skipwhite; + } + +// skip c-style comments + if (c=='/' && pFileBytes[1] == '*' ) + { + // Skip "/*" + pFileBytes += 2; + + while ( *pFileBytes ) + { + if ( *pFileBytes == '*' && + pFileBytes[1] == '/' ) + { + pFileBytes += 2; + break; + } + + pFileBytes++; + } + + goto skipwhite; + } + +// handle quoted strings specially + if (c == '\"') + { + if (pWasQuoted) + *pWasQuoted = true; + + pFileBytes++; + while (1) + { + c = *pFileBytes++; + if (c=='\"' || !c) + { + pTokenOut[len] = 0; + return pFileBytes; + } + pTokenOut[len] = c; + len += ( len < nMaxTokenLen-1 ) ? 1 : 0; + } + } + +// parse single characters + if ( IN_CHARACTERSET( breaks, c ) ) + { + pTokenOut[len] = c; + len += ( len < nMaxTokenLen-1 ) ? 1 : 0; + pTokenOut[len] = 0; + return pFileBytes+1; + } + +// parse a regular word + do + { + pTokenOut[len] = c; + pFileBytes++; + len += ( len < nMaxTokenLen-1 ) ? 1 : 0; + c = *pFileBytes; + if ( IN_CHARACTERSET( breaks, c ) ) + break; + } while (c>32); + + pTokenOut[len] = 0; + return pFileBytes; +} diff --git a/sp/src/public/filesystem_helpers.h b/sp/src/public/filesystem_helpers.h new file mode 100644 index 00000000..070e779a --- /dev/null +++ b/sp/src/public/filesystem_helpers.h @@ -0,0 +1,36 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#ifndef FILESYSTEM_HELPERS_H +#define FILESYSTEM_HELPERS_H + +#ifdef _WIN32 +#pragma once +#endif + +struct characterset_t; + +// Don't call this directly. You should (as long as your destination is an array) be +// able to call ParseFile, which is safer as it infers your array size for you. +const char* ParseFileInternal( const char* pFileBytes, OUT_Z_CAP(nMaxTokenLen) char* pTokenOut, bool* pWasQuoted, characterset_t *pCharSet, size_t nMaxTokenLen ); + +// Call until it returns NULL. Each time you call it, it will parse out a token. + +template +const char* ParseFile( const char* pFileBytes, OUT_Z_ARRAY char (&pTokenOut)[count], bool* pWasQuoted, characterset_t *pCharSet = NULL, unsigned int nMaxTokenLen = (unsigned int)-1 ) +{ + (void*)nMaxTokenLen; // Avoid unreferenced variable warnings. + return ParseFileInternal( pFileBytes, pTokenOut, pWasQuoted, pCharSet, count ); +} + +template +char* ParseFile( char* pFileBytes, OUT_Z_ARRAY char (&pTokenOut)[count], bool* pWasQuoted ) // (same exact thing as the const version) +{ + return const_cast( ParseFileInternal( pFileBytes, pTokenOut, pWasQuoted, NULL, count ) ); +} + +#endif // FILESYSTEM_HELPERS_H diff --git a/sp/src/public/filesystem_init.cpp b/sp/src/public/filesystem_init.cpp new file mode 100644 index 00000000..36b484f5 --- /dev/null +++ b/sp/src/public/filesystem_init.cpp @@ -0,0 +1,1383 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#undef PROTECTED_THINGS_ENABLE +#undef PROTECT_FILEIO_FUNCTIONS +#ifndef POSIX +#undef fopen +#endif + +#if defined( _WIN32 ) && !defined( _X360 ) +#include +#include +#include +#include +#elif defined( POSIX ) +#include +#define _chdir chdir +#define _access access +#endif +#include +#include +#include "tier1/strtools.h" +#include "tier1/utlbuffer.h" +#include "filesystem_init.h" +#include "tier0/icommandline.h" +#include "KeyValues.h" +#include "appframework/IAppSystemGroup.h" +#include "tier1/smartptr.h" +#if defined( _X360 ) +#include "xbox\xbox_win32stubs.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include + +#if !defined( _X360 ) +#define GAMEINFO_FILENAME "gameinfo.txt" +#else +// The .xtx file is a TCR requirement, as .txt files cannot live on the DVD. +// The .xtx file only exists outside the zips (same as .txt and is made during the image build) and is read to setup the search paths. +// So all other code should be able to safely expect gameinfo.txt after the zip is mounted as the .txt file exists inside the zips. +// The .xtx concept is private and should only have to occurr here. As a safety measure, if the .xtx file is not found +// a retry is made with the original .txt name +#define GAMEINFO_FILENAME "gameinfo.xtx" +#endif +#define GAMEINFO_FILENAME_ALTERNATE "gameinfo.txt" + +static char g_FileSystemError[256]; +static bool s_bUseVProjectBinDir = false; +static FSErrorMode_t g_FileSystemErrorMode = FS_ERRORMODE_VCONFIG; + +// Call this to use a bin directory relative to VPROJECT +void FileSystem_UseVProjectBinDir( bool bEnable ) +{ + s_bUseVProjectBinDir = bEnable; +} + +// This class lets you modify environment variables, and it restores the original value +// when it goes out of scope. +class CTempEnvVar +{ +public: + CTempEnvVar( const char *pVarName ) + { + m_bRestoreOriginalValue = true; + m_pVarName = pVarName; + + const char *pValue = NULL; + +#ifdef _WIN32 + // Use GetEnvironmentVariable instead of getenv because getenv doesn't pick up changes + // to the process environment after the DLL was loaded. + char szBuf[ 4096 ]; + if ( GetEnvironmentVariable( m_pVarName, szBuf, sizeof( szBuf ) ) != 0) + { + pValue = szBuf; + } +#else + // LINUX BUG: see above + pValue = getenv( pVarName ); +#endif + + if ( pValue ) + { + m_bExisted = true; + m_OriginalValue.SetSize( strlen( pValue ) + 1 ); + memcpy( m_OriginalValue.Base(), pValue, m_OriginalValue.Count() ); + } + else + { + m_bExisted = false; + } + } + + ~CTempEnvVar() + { + if ( m_bRestoreOriginalValue ) + { + // Restore the original value. + if ( m_bExisted ) + { + SetValue( "%s", m_OriginalValue.Base() ); + } + else + { + ClearValue(); + } + } + } + + void SetRestoreOriginalValue( bool bRestore ) + { + m_bRestoreOriginalValue = bRestore; + } + + int GetValue(char *pszBuf, int nBufSize ) + { + if ( !pszBuf || ( nBufSize <= 0 ) ) + return 0; + +#ifdef _WIN32 + // Use GetEnvironmentVariable instead of getenv because getenv doesn't pick up changes + // to the process environment after the DLL was loaded. + return GetEnvironmentVariable( m_pVarName, pszBuf, nBufSize ); +#else + // LINUX BUG: see above + const char *pszOut = getenv( m_pVarName ); + if ( !pszOut ) + { + *pszBuf = '\0'; + return 0; + } + + Q_strncpy( pszBuf, pszOut, nBufSize ); + return Q_strlen( pszBuf ); +#endif + } + + void SetValue( const char *pValue, ... ) + { + char valueString[4096]; + va_list marker; + va_start( marker, pValue ); + Q_vsnprintf( valueString, sizeof( valueString ), pValue, marker ); + va_end( marker ); + +#ifdef WIN32 + char str[4096]; + Q_snprintf( str, sizeof( str ), "%s=%s", m_pVarName, valueString ); + _putenv( str ); +#else + setenv( m_pVarName, valueString, 1 ); +#endif + } + + void ClearValue() + { +#ifdef WIN32 + char str[512]; + Q_snprintf( str, sizeof( str ), "%s=", m_pVarName ); + _putenv( str ); +#else + setenv( m_pVarName, "", 1 ); +#endif + } + +private: + bool m_bRestoreOriginalValue; + const char *m_pVarName; + bool m_bExisted; + CUtlVector m_OriginalValue; +}; + + +class CSteamEnvVars +{ +public: + CSteamEnvVars() : + m_SteamAppId( "SteamAppId" ), + m_SteamUserPassphrase( "SteamUserPassphrase" ), + m_SteamAppUser( "SteamAppUser" ), + m_Path( "path" ) + { + } + + void SetRestoreOriginalValue_ALL( bool bRestore ) + { + m_SteamAppId.SetRestoreOriginalValue( bRestore ); + m_SteamUserPassphrase.SetRestoreOriginalValue( bRestore ); + m_SteamAppUser.SetRestoreOriginalValue( bRestore ); + m_Path.SetRestoreOriginalValue( bRestore ); + } + + CTempEnvVar m_SteamAppId; + CTempEnvVar m_SteamUserPassphrase; + CTempEnvVar m_SteamAppUser; + CTempEnvVar m_Path; +}; + +// ---------------------------------------------------------------------------------------------------- // +// Helpers. +// ---------------------------------------------------------------------------------------------------- // +void Q_getwd( char *out, int outSize ) +{ +#if defined( _WIN32 ) || defined( WIN32 ) + _getcwd( out, outSize ); + Q_strncat( out, "\\", outSize, COPY_ALL_CHARACTERS ); +#else + getcwd( out, outSize ); + strcat( out, "/" ); +#endif + Q_FixSlashes( out ); +} + +// ---------------------------------------------------------------------------------------------------- // +// Module interface. +// ---------------------------------------------------------------------------------------------------- // + +CFSSearchPathsInit::CFSSearchPathsInit() +{ + m_pDirectoryName = NULL; + m_pLanguage = NULL; + m_ModPath[0] = 0; + m_bMountHDContent = m_bLowViolence = false; +} + + +CFSSteamSetupInfo::CFSSteamSetupInfo() +{ + m_pDirectoryName = NULL; + m_bOnlyUseDirectoryName = false; + m_bSteam = false; + m_bToolsMode = true; + m_bNoGameInfo = false; +} + + +CFSLoadModuleInfo::CFSLoadModuleInfo() +{ + m_pFileSystemDLLName = NULL; + m_pFileSystem = NULL; + m_pModule = NULL; +} + + +CFSMountContentInfo::CFSMountContentInfo() +{ + m_bToolsMode = true; + m_pDirectoryName = NULL; + m_pFileSystem = NULL; +} + + +const char *FileSystem_GetLastErrorString() +{ + return g_FileSystemError; +} + + +KeyValues* ReadKeyValuesFile( const char *pFilename ) +{ + // Read in the gameinfo.txt file and null-terminate it. + FILE *fp = fopen( pFilename, "rb" ); + if ( !fp ) + return NULL; + CUtlVector buf; + fseek( fp, 0, SEEK_END ); + buf.SetSize( ftell( fp ) + 1 ); + fseek( fp, 0, SEEK_SET ); + fread( buf.Base(), 1, buf.Count()-1, fp ); + fclose( fp ); + buf[buf.Count()-1] = 0; + + KeyValues *kv = new KeyValues( "" ); + if ( !kv->LoadFromBuffer( pFilename, buf.Base() ) ) + { + kv->deleteThis(); + return NULL; + } + + return kv; +} + +static bool Sys_GetExecutableName( char *out, int len ) +{ +#if defined( _WIN32 ) + if ( !::GetModuleFileName( ( HINSTANCE )GetModuleHandle( NULL ), out, len ) ) + { + return false; + } +#else + if ( CommandLine()->GetParm(0) ) + { + Q_MakeAbsolutePath( out, len, CommandLine()->GetParm(0) ); + } + else + { + return false; + } +#endif + + return true; +} + +bool FileSystem_GetExecutableDir( char *exedir, int exeDirLen ) +{ + exedir[0] = 0; + + if ( s_bUseVProjectBinDir ) + { + const char *pProject = GetVProjectCmdLineValue(); + if ( !pProject ) + { + // Check their registry. + pProject = getenv( GAMEDIR_TOKEN ); + } + if ( pProject ) + { + Q_snprintf( exedir, exeDirLen, "%s%c..%cbin", pProject, CORRECT_PATH_SEPARATOR, CORRECT_PATH_SEPARATOR ); + return true; + } + return false; + } + + if ( !Sys_GetExecutableName( exedir, exeDirLen ) ) + return false; + Q_StripFilename( exedir ); + + if ( IsX360() ) + { + // The 360 can have its exe and dlls reside on different volumes + // use the optional basedir as the exe dir + if ( CommandLine()->FindParm( "-basedir" ) ) + { + strcpy( exedir, CommandLine()->ParmValue( "-basedir", "" ) ); + } + } + + Q_FixSlashes( exedir ); + + // Return the bin directory as the executable dir if it's not in there + // because that's really where we're running from... + char ext[MAX_PATH]; + Q_StrRight( exedir, 4, ext, sizeof( ext ) ); + if ( ext[0] != CORRECT_PATH_SEPARATOR || Q_stricmp( ext+1, "bin" ) != 0 ) + { + Q_strncat( exedir, CORRECT_PATH_SEPARATOR_S, exeDirLen, COPY_ALL_CHARACTERS ); + Q_strncat( exedir, "bin", exeDirLen, COPY_ALL_CHARACTERS ); + Q_FixSlashes( exedir ); + } + + return true; +} + +static bool FileSystem_GetBaseDir( char *baseDir, int baseDirLen ) +{ + if ( FileSystem_GetExecutableDir( baseDir, baseDirLen ) ) + { + Q_StripFilename( baseDir ); + return true; + } + + return false; +} + +void LaunchVConfig() +{ +#if defined( _WIN32 ) && !defined( _X360 ) + char vconfigExe[MAX_PATH]; + FileSystem_GetExecutableDir( vconfigExe, sizeof( vconfigExe ) ); + Q_AppendSlash( vconfigExe, sizeof( vconfigExe ) ); + Q_strncat( vconfigExe, "vconfig.exe", sizeof( vconfigExe ), COPY_ALL_CHARACTERS ); + + char *argv[] = + { + vconfigExe, + "-allowdebug", + NULL + }; + + _spawnv( _P_NOWAIT, vconfigExe, argv ); +#elif defined( _X360 ) + Msg( "Launching vconfig.exe not supported\n" ); +#endif +} + +const char* GetVProjectCmdLineValue() +{ + return CommandLine()->ParmValue( "-vproject", CommandLine()->ParmValue( "-game" ) ); +} + +FSReturnCode_t SetupFileSystemError( bool bRunVConfig, FSReturnCode_t retVal, const char *pMsg, ... ) +{ + va_list marker; + va_start( marker, pMsg ); + Q_vsnprintf( g_FileSystemError, sizeof( g_FileSystemError ), pMsg, marker ); + va_end( marker ); + + Warning( "%s\n", g_FileSystemError ); + + // Run vconfig? + // Don't do it if they specifically asked for it not to, or if they manually specified a vconfig with -game or -vproject. + if ( bRunVConfig && g_FileSystemErrorMode == FS_ERRORMODE_VCONFIG && !CommandLine()->FindParm( CMDLINEOPTION_NOVCONFIG ) && !GetVProjectCmdLineValue() ) + { + LaunchVConfig(); + } + + if ( g_FileSystemErrorMode == FS_ERRORMODE_AUTO || g_FileSystemErrorMode == FS_ERRORMODE_VCONFIG ) + { + Error( "%s\n", g_FileSystemError ); + } + + return retVal; +} + +FSReturnCode_t LoadGameInfoFile( + const char *pDirectoryName, + KeyValues *&pMainFile, + KeyValues *&pFileSystemInfo, + KeyValues *&pSearchPaths ) +{ + // If GameInfo.txt exists under pBaseDir, then this is their game directory. + // All the filesystem mappings will be in this file. + char gameinfoFilename[MAX_PATH]; + Q_strncpy( gameinfoFilename, pDirectoryName, sizeof( gameinfoFilename ) ); + Q_AppendSlash( gameinfoFilename, sizeof( gameinfoFilename ) ); + Q_strncat( gameinfoFilename, GAMEINFO_FILENAME, sizeof( gameinfoFilename ), COPY_ALL_CHARACTERS ); + Q_FixSlashes( gameinfoFilename ); + pMainFile = ReadKeyValuesFile( gameinfoFilename ); + if ( IsX360() && !pMainFile ) + { + // try again + Q_strncpy( gameinfoFilename, pDirectoryName, sizeof( gameinfoFilename ) ); + Q_AppendSlash( gameinfoFilename, sizeof( gameinfoFilename ) ); + Q_strncat( gameinfoFilename, GAMEINFO_FILENAME_ALTERNATE, sizeof( gameinfoFilename ), COPY_ALL_CHARACTERS ); + Q_FixSlashes( gameinfoFilename ); + pMainFile = ReadKeyValuesFile( gameinfoFilename ); + } + if ( !pMainFile ) + { + return SetupFileSystemError( true, FS_MISSING_GAMEINFO_FILE, "%s is missing.", gameinfoFilename ); + } + + pFileSystemInfo = pMainFile->FindKey( "FileSystem" ); + if ( !pFileSystemInfo ) + { + pMainFile->deleteThis(); + return SetupFileSystemError( true, FS_INVALID_GAMEINFO_FILE, "%s is not a valid format.", gameinfoFilename ); + } + + // Now read in all the search paths. + pSearchPaths = pFileSystemInfo->FindKey( "SearchPaths" ); + if ( !pSearchPaths ) + { + pMainFile->deleteThis(); + return SetupFileSystemError( true, FS_INVALID_GAMEINFO_FILE, "%s is not a valid format.", gameinfoFilename ); + } + return FS_OK; +} + + +static void FileSystem_AddLoadedSearchPath( + CFSSearchPathsInit &initInfo, + const char *pPathID, + const char *fullLocationPath, + bool bLowViolence ) +{ + + // Check for mounting LV game content in LV builds only + if ( V_stricmp( pPathID, "game_lv" ) == 0 ) + { + + // Not in LV build, don't mount + if ( !initInfo.m_bLowViolence ) + return; + + // Mount, as a game path + pPathID = "game"; + } + + // Check for mounting HD game content if enabled + if ( V_stricmp( pPathID, "game_hd" ) == 0 ) + { + + // Not in LV build, don't mount + if ( !initInfo.m_bMountHDContent ) + return; + + // Mount, as a game path + pPathID = "game"; + } + + + // Special processing for ordinary game folders + if ( V_stristr( fullLocationPath, ".vpk" ) == NULL && Q_stricmp( pPathID, "game" ) == 0 ) + { + if ( CommandLine()->FindParm( "-tempcontent" ) != 0 ) + { + char szPath[MAX_PATH]; + Q_snprintf( szPath, sizeof(szPath), "%s_tempcontent", fullLocationPath ); + initInfo.m_pFileSystem->AddSearchPath( szPath, pPathID, PATH_ADD_TO_TAIL ); + } + } + + + if ( initInfo.m_pLanguage && + Q_stricmp( initInfo.m_pLanguage, "english" ) && + V_strstr( fullLocationPath, "_english" ) != NULL ) + { + char szPath[MAX_PATH]; + char szLangString[MAX_PATH]; + + // Need to add a language version of this path first + + Q_snprintf( szLangString, sizeof(szLangString), "_%s", initInfo.m_pLanguage); + V_StrSubst( fullLocationPath, "_english", szLangString, szPath, sizeof( szPath ), true ); + initInfo.m_pFileSystem->AddSearchPath( szPath, pPathID, PATH_ADD_TO_TAIL ); + } + + initInfo.m_pFileSystem->AddSearchPath( fullLocationPath, pPathID, PATH_ADD_TO_TAIL ); +} + +static int SortStricmp( char * const * sz1, char * const * sz2 ) +{ + return V_stricmp( *sz1, *sz2 ); +} + +FSReturnCode_t FileSystem_LoadSearchPaths( CFSSearchPathsInit &initInfo ) +{ + if ( !initInfo.m_pFileSystem || !initInfo.m_pDirectoryName ) + return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_LoadSearchPaths: Invalid parameters specified." ); + + KeyValues *pMainFile, *pFileSystemInfo, *pSearchPaths; + FSReturnCode_t retVal = LoadGameInfoFile( initInfo.m_pDirectoryName, pMainFile, pFileSystemInfo, pSearchPaths ); + if ( retVal != FS_OK ) + return retVal; + + // All paths except those marked with |gameinfo_path| are relative to the base dir. + char baseDir[MAX_PATH]; + if ( !FileSystem_GetBaseDir( baseDir, sizeof( baseDir ) ) ) + return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_GetBaseDir failed." ); + + // The MOD directory is always the one that contains gameinfo.txt + Q_strncpy( initInfo.m_ModPath, initInfo.m_pDirectoryName, sizeof( initInfo.m_ModPath ) ); + + #define GAMEINFOPATH_TOKEN "|gameinfo_path|" + #define BASESOURCEPATHS_TOKEN "|all_source_engine_paths|" + + const char *pszExtraSearchPath = CommandLine()->ParmValue( "-insert_search_path" ); + if ( pszExtraSearchPath ) + { + CUtlStringList vecPaths; + V_SplitString( pszExtraSearchPath, ",", vecPaths ); + FOR_EACH_VEC( vecPaths, idxExtraPath ) + { + char szAbsSearchPath[MAX_PATH]; + Q_StripPrecedingAndTrailingWhitespace( vecPaths[ idxExtraPath ] ); + V_MakeAbsolutePath( szAbsSearchPath, sizeof( szAbsSearchPath ), vecPaths[ idxExtraPath ], baseDir ); + V_FixSlashes( szAbsSearchPath ); + if ( !V_RemoveDotSlashes( szAbsSearchPath ) ) + Error( "Bad -insert_search_path - Can't resolve pathname for '%s'", szAbsSearchPath ); + V_StripTrailingSlash( szAbsSearchPath ); + FileSystem_AddLoadedSearchPath( initInfo, "GAME", szAbsSearchPath, false ); + FileSystem_AddLoadedSearchPath( initInfo, "MOD", szAbsSearchPath, false ); + } + } + + bool bLowViolence = initInfo.m_bLowViolence; + for ( KeyValues *pCur=pSearchPaths->GetFirstValue(); pCur; pCur=pCur->GetNextValue() ) + { + const char *pLocation = pCur->GetString(); + const char *pszBaseDir = baseDir; + + if ( Q_stristr( pLocation, GAMEINFOPATH_TOKEN ) == pLocation ) + { + pLocation += strlen( GAMEINFOPATH_TOKEN ); + pszBaseDir = initInfo.m_pDirectoryName; + } + else if ( Q_stristr( pLocation, BASESOURCEPATHS_TOKEN ) == pLocation ) + { + // This is a special identifier that tells it to add the specified path for all source engine versions equal to or prior to this version. + // So in Orange Box, if they specified: + // |all_source_engine_paths|hl2 + // it would add the ep2\hl2 folder and the base (ep1-era) hl2 folder. + // + // We need a special identifier in the gameinfo.txt here because the base hl2 folder exists in different places. + // In the case of a game or a Steam-launched dedicated server, all the necessary prior engine content is mapped in with the Steam depots, + // so we can just use the path as-is. + pLocation += strlen( BASESOURCEPATHS_TOKEN ); + } + + CUtlStringList vecFullLocationPaths; + char szAbsSearchPath[MAX_PATH]; + V_MakeAbsolutePath( szAbsSearchPath, sizeof( szAbsSearchPath ), pLocation, pszBaseDir ); + + // Now resolve any ./'s. + V_FixSlashes( szAbsSearchPath ); + if ( !V_RemoveDotSlashes( szAbsSearchPath ) ) + Error( "FileSystem_AddLoadedSearchPath - Can't resolve pathname for '%s'", szAbsSearchPath ); + V_StripTrailingSlash( szAbsSearchPath ); + + // Don't bother doing any wildcard expansion unless it has wildcards. This avoids the weird + // thing with xxx_dir.vpk files being referred to simply as xxx.vpk. + if ( V_stristr( pLocation, "?") == NULL && V_stristr( pLocation, "*") == NULL ) + { + vecFullLocationPaths.CopyAndAddToTail( szAbsSearchPath ); + } + else + { + FileFindHandle_t findHandle = NULL; + const char *pszFoundShortName = initInfo.m_pFileSystem->FindFirst( szAbsSearchPath, &findHandle ); + if ( pszFoundShortName ) + { + do + { + + // We only know how to mount VPK's and directories + if ( pszFoundShortName[0] != '.' && ( initInfo.m_pFileSystem->FindIsDirectory( findHandle ) || V_stristr( pszFoundShortName, ".vpk" ) ) ) + { + char szAbsName[MAX_PATH]; + V_ExtractFilePath( szAbsSearchPath, szAbsName, sizeof( szAbsName ) ); + V_AppendSlash( szAbsName, sizeof(szAbsName) ); + V_strcat_safe( szAbsName, pszFoundShortName ); + + vecFullLocationPaths.CopyAndAddToTail( szAbsName ); + + // Check for a common mistake + if ( + !V_stricmp( pszFoundShortName, "materials" ) + || !V_stricmp( pszFoundShortName, "maps" ) + || !V_stricmp( pszFoundShortName, "resource" ) + || !V_stricmp( pszFoundShortName, "scripts" ) + || !V_stricmp( pszFoundShortName, "sound" ) + || !V_stricmp( pszFoundShortName, "models" ) ) + { + + char szReadme[MAX_PATH]; + V_ExtractFilePath( szAbsSearchPath, szReadme, sizeof( szReadme ) ); + V_AppendSlash( szReadme, sizeof(szReadme) ); + V_strcat_safe( szReadme, "readme.txt" ); + + Error( + "Tried to add %s as a search path.\n" + "\nThis is probably not what you intended.\n" + "\nCheck %s for more info\n", + szAbsName, szReadme ); + } + + } + pszFoundShortName = initInfo.m_pFileSystem->FindNext( findHandle ); + } while ( pszFoundShortName ); + initInfo.m_pFileSystem->FindClose( findHandle ); + } + + // Sort alphabetically. Also note that this will put + // all the xxx_000.vpk packs just before the corresponding + // xxx_dir.vpk + vecFullLocationPaths.Sort( SortStricmp ); + + // Now for any _dir.vpk files, remove the _nnn.vpk ones. + int idx = vecFullLocationPaths.Count()-1; + while ( idx > 0 ) + { + char szTemp[ MAX_PATH ]; + V_strcpy_safe( szTemp, vecFullLocationPaths[ idx ] ); + --idx; + + char *szDirVpk = V_stristr( szTemp, "_dir.vpk" ); + if ( szDirVpk != NULL ) + { + *szDirVpk = '\0'; + while ( idx >= 0 ) + { + char *pszPath = vecFullLocationPaths[ idx ]; + if ( V_stristr( pszPath, szTemp ) != pszPath ) + break; + delete pszPath; + vecFullLocationPaths.Remove( idx ); + --idx; + } + } + } + } + + // Parse Path ID list + CUtlStringList vecPathIDs; + V_SplitString( pCur->GetName(), "+", vecPathIDs ); + FOR_EACH_VEC( vecPathIDs, idxPathID ) + { + Q_StripPrecedingAndTrailingWhitespace( vecPathIDs[ idxPathID ] ); + } + + // Mount them. + FOR_EACH_VEC( vecFullLocationPaths, idxLocation ) + { + FOR_EACH_VEC( vecPathIDs, idxPathID ) + { + FileSystem_AddLoadedSearchPath( initInfo, vecPathIDs[ idxPathID ], vecFullLocationPaths[ idxLocation ], bLowViolence ); + } + } + } + + pMainFile->deleteThis(); + + // Also, mark specific path IDs as "by request only". That way, we won't waste time searching in them + // when people forget to specify a search path. + initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "executable_path", true ); + initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "gamebin", true ); + initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "download", true ); + initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "mod", true ); + initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "game_write", true ); + initInfo.m_pFileSystem->MarkPathIDByRequestOnly( "mod_write", true ); + +#ifdef _DEBUG + // initInfo.m_pFileSystem->PrintSearchPaths(); +#endif + + return FS_OK; +} + +bool DoesFileExistIn( const char *pDirectoryName, const char *pFilename ) +{ + char filename[MAX_PATH]; + + Q_strncpy( filename, pDirectoryName, sizeof( filename ) ); + Q_AppendSlash( filename, sizeof( filename ) ); + Q_strncat( filename, pFilename, sizeof( filename ), COPY_ALL_CHARACTERS ); + Q_FixSlashes( filename ); + bool bExist = ( _access( filename, 0 ) == 0 ); + + return ( bExist ); +} + +namespace +{ + SuggestGameInfoDirFn_t & GetSuggestGameInfoDirFn( void ) + { + static SuggestGameInfoDirFn_t s_pfnSuggestGameInfoDir = NULL; + return s_pfnSuggestGameInfoDir; + } +}; // `anonymous` namespace + +SuggestGameInfoDirFn_t SetSuggestGameInfoDirFn( SuggestGameInfoDirFn_t pfnNewFn ) +{ + SuggestGameInfoDirFn_t &rfn = GetSuggestGameInfoDirFn(); + SuggestGameInfoDirFn_t pfnOldFn = rfn; + rfn = pfnNewFn; + return pfnOldFn; +} + +static FSReturnCode_t TryLocateGameInfoFile( char *pOutDir, int outDirLen, bool bBubbleDir ) +{ + // Retain a copy of suggested path for further attempts + CArrayAutoPtr < char > spchCopyNameBuffer( new char [ outDirLen ] ); + Q_strncpy( spchCopyNameBuffer.Get(), pOutDir, outDirLen ); + spchCopyNameBuffer[ outDirLen - 1 ] = 0; + + // Make appropriate slashes ('/' - Linux style) + for ( char *pchFix = spchCopyNameBuffer.Get(), + *pchEnd = pchFix + outDirLen; + pchFix < pchEnd; ++ pchFix ) + { + if ( '\\' == *pchFix ) + { + *pchFix = '/'; + } + } + + // Have a look in supplied path + do + { + if ( DoesFileExistIn( pOutDir, GAMEINFO_FILENAME ) ) + { + return FS_OK; + } + if ( IsX360() && DoesFileExistIn( pOutDir, GAMEINFO_FILENAME_ALTERNATE ) ) + { + return FS_OK; + } + } + while ( bBubbleDir && Q_StripLastDir( pOutDir, outDirLen ) ); + + // Make an attempt to resolve from "content -> game" directory + Q_strncpy( pOutDir, spchCopyNameBuffer.Get(), outDirLen ); + pOutDir[ outDirLen - 1 ] = 0; + if ( char *pchContentFix = Q_stristr( pOutDir, "/content/" ) ) + { + sprintf( pchContentFix, "/game/" ); + memmove( pchContentFix + 6, pchContentFix + 9, pOutDir + outDirLen - (pchContentFix + 9) ); + + // Try in the mapped "game" directory + do + { + if ( DoesFileExistIn( pOutDir, GAMEINFO_FILENAME ) ) + { + return FS_OK; + } + if ( IsX360() && DoesFileExistIn( pOutDir, GAMEINFO_FILENAME_ALTERNATE ) ) + { + return FS_OK; + } + } + while ( bBubbleDir && Q_StripLastDir( pOutDir, outDirLen ) ); + } + + // Could not find it here + return FS_MISSING_GAMEINFO_FILE; +} + +FSReturnCode_t LocateGameInfoFile( const CFSSteamSetupInfo &fsInfo, char *pOutDir, int outDirLen ) +{ + // Engine and Hammer don't want to search around for it. + if ( fsInfo.m_bOnlyUseDirectoryName ) + { + if ( !fsInfo.m_pDirectoryName ) + return SetupFileSystemError( false, FS_MISSING_GAMEINFO_FILE, "bOnlyUseDirectoryName=1 and pDirectoryName=NULL." ); + + bool bExists = DoesFileExistIn( fsInfo.m_pDirectoryName, GAMEINFO_FILENAME ); + if ( IsX360() && !bExists ) + { + bExists = DoesFileExistIn( fsInfo.m_pDirectoryName, GAMEINFO_FILENAME_ALTERNATE ); + } + if ( !bExists ) + { + if ( IsX360() && CommandLine()->FindParm( "-basedir" ) ) + { + char basePath[MAX_PATH]; + strcpy( basePath, CommandLine()->ParmValue( "-basedir", "" ) ); + Q_AppendSlash( basePath, sizeof( basePath ) ); + Q_strncat( basePath, fsInfo.m_pDirectoryName, sizeof( basePath ), COPY_ALL_CHARACTERS ); + if ( DoesFileExistIn( basePath, GAMEINFO_FILENAME ) ) + { + Q_strncpy( pOutDir, basePath, outDirLen ); + return FS_OK; + } + if ( IsX360() && DoesFileExistIn( basePath, GAMEINFO_FILENAME_ALTERNATE ) ) + { + Q_strncpy( pOutDir, basePath, outDirLen ); + return FS_OK; + } + } + + return SetupFileSystemError( true, FS_MISSING_GAMEINFO_FILE, "Setup file '%s' doesn't exist in subdirectory '%s'.\nCheck your -game parameter or VCONFIG setting.", GAMEINFO_FILENAME, fsInfo.m_pDirectoryName ); + } + + Q_strncpy( pOutDir, fsInfo.m_pDirectoryName, outDirLen ); + return FS_OK; + } + + // First, check for overrides on the command line or environment variables. + const char *pProject = GetVProjectCmdLineValue(); + + if ( pProject ) + { + if ( DoesFileExistIn( pProject, GAMEINFO_FILENAME ) ) + { + Q_MakeAbsolutePath( pOutDir, outDirLen, pProject ); + return FS_OK; + } + if ( IsX360() && DoesFileExistIn( pProject, GAMEINFO_FILENAME_ALTERNATE ) ) + { + Q_MakeAbsolutePath( pOutDir, outDirLen, pProject ); + return FS_OK; + } + + if ( IsX360() && CommandLine()->FindParm( "-basedir" ) ) + { + char basePath[MAX_PATH]; + strcpy( basePath, CommandLine()->ParmValue( "-basedir", "" ) ); + Q_AppendSlash( basePath, sizeof( basePath ) ); + Q_strncat( basePath, pProject, sizeof( basePath ), COPY_ALL_CHARACTERS ); + if ( DoesFileExistIn( basePath, GAMEINFO_FILENAME ) ) + { + Q_strncpy( pOutDir, basePath, outDirLen ); + return FS_OK; + } + if ( DoesFileExistIn( basePath, GAMEINFO_FILENAME_ALTERNATE ) ) + { + Q_strncpy( pOutDir, basePath, outDirLen ); + return FS_OK; + } + } + + if ( fsInfo.m_bNoGameInfo ) + { + // fsInfo.m_bNoGameInfo is set by the Steam dedicated server, before it knows which mod to use. + // Steam dedicated server doesn't need a gameinfo.txt, because we'll ask which mod to use, even if + // -game is supplied on the command line. + Q_strncpy( pOutDir, "", outDirLen ); + return FS_OK; + } + else + { + // They either specified vproject on the command line or it's in their registry. Either way, + // we don't want to continue if they've specified it but it's not valid. + goto ShowError; + } + } + + if ( fsInfo.m_bNoGameInfo ) + { + Q_strncpy( pOutDir, "", outDirLen ); + return FS_OK; + } + + // Ask the application if it can provide us with a game info directory + { + bool bBubbleDir = true; + SuggestGameInfoDirFn_t pfnSuggestGameInfoDirFn = GetSuggestGameInfoDirFn(); + if ( pfnSuggestGameInfoDirFn && + ( * pfnSuggestGameInfoDirFn )( &fsInfo, pOutDir, outDirLen, &bBubbleDir ) && + FS_OK == TryLocateGameInfoFile( pOutDir, outDirLen, bBubbleDir ) ) + return FS_OK; + } + + // Try to use the environment variable / registry + if ( ( pProject = getenv( GAMEDIR_TOKEN ) ) != NULL && + ( Q_MakeAbsolutePath( pOutDir, outDirLen, pProject ), 1 ) && + FS_OK == TryLocateGameInfoFile( pOutDir, outDirLen, false ) ) + return FS_OK; + + if ( IsPC() ) + { + Warning( "Warning: falling back to auto detection of vproject directory.\n" ); + + // Now look for it in the directory they passed in. + if ( fsInfo.m_pDirectoryName ) + Q_MakeAbsolutePath( pOutDir, outDirLen, fsInfo.m_pDirectoryName ); + else + Q_MakeAbsolutePath( pOutDir, outDirLen, "." ); + + if ( FS_OK == TryLocateGameInfoFile( pOutDir, outDirLen, true ) ) + return FS_OK; + + // Use the CWD + Q_getwd( pOutDir, outDirLen ); + if ( FS_OK == TryLocateGameInfoFile( pOutDir, outDirLen, true ) ) + return FS_OK; + } + +ShowError: + return SetupFileSystemError( true, FS_MISSING_GAMEINFO_FILE, + "Unable to find %s. Solutions:\n\n" + "1. Read http://www.valve-erc.com/srcsdk/faq.html#NoGameDir\n" + "2. Run vconfig to specify which game you're working on.\n" + "3. Add -game on the command line where is the directory that %s is in.\n", + GAMEINFO_FILENAME, GAMEINFO_FILENAME ); +} + +bool DoesPathExistAlready( const char *pPathEnvVar, const char *pTestPath ) +{ + // Fix the slashes in the input arguments. + char correctedPathEnvVar[8192], correctedTestPath[MAX_PATH]; + Q_strncpy( correctedPathEnvVar, pPathEnvVar, sizeof( correctedPathEnvVar ) ); + Q_FixSlashes( correctedPathEnvVar ); + pPathEnvVar = correctedPathEnvVar; + + Q_strncpy( correctedTestPath, pTestPath, sizeof( correctedTestPath ) ); + Q_FixSlashes( correctedTestPath ); + if ( strlen( correctedTestPath ) > 0 && PATHSEPARATOR( correctedTestPath[strlen(correctedTestPath)-1] ) ) + correctedTestPath[ strlen(correctedTestPath) - 1 ] = 0; + + pTestPath = correctedTestPath; + + const char *pCurPos = pPathEnvVar; + while ( 1 ) + { + const char *pTestPos = Q_stristr( pCurPos, pTestPath ); + if ( !pTestPos ) + return false; + + // Ok, we found pTestPath in the path, but it's only valid if it's followed by an optional slash and a semicolon. + pTestPos += strlen( pTestPath ); + if ( pTestPos[0] == 0 || pTestPos[0] == ';' || (PATHSEPARATOR( pTestPos[0] ) && pTestPos[1] == ';') ) + return true; + + // Advance our marker.. + pCurPos = pTestPos; + } +} + +FSReturnCode_t SetSteamInstallPath( char *steamInstallPath, int steamInstallPathLen, CSteamEnvVars &steamEnvVars, bool bErrorsAsWarnings ) +{ + if ( IsConsole() ) + { + // consoles don't use steam + return FS_MISSING_STEAM_DLL; + } + + if ( IsPosix() ) + return FS_OK; // under posix the content does not live with steam.dll up the path, rely on the environment already being set by steam + + // Start at our bin directory and move up until we find a directory with steam.dll in it. + char executablePath[MAX_PATH]; + if ( !FileSystem_GetExecutableDir( executablePath, sizeof( executablePath ) ) ) + { + if ( bErrorsAsWarnings ) + { + Warning( "SetSteamInstallPath: FileSystem_GetExecutableDir failed.\n" ); + return FS_INVALID_PARAMETERS; + } + else + { + return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_GetExecutableDir failed." ); + } + } + + Q_strncpy( steamInstallPath, executablePath, steamInstallPathLen ); +#ifdef WIN32 + const char *pchSteamDLL = "steam" DLL_EXT_STRING; +#elif defined(POSIX) + // under osx the bin lives in the bin/ folder, so step back one + Q_StripLastDir( steamInstallPath, steamInstallPathLen ); + const char *pchSteamDLL = "libsteam" DLL_EXT_STRING; +#else + #error +#endif + while ( 1 ) + { + // Ignore steamapp.cfg here in case they're debugging. We still need to know the real steam path so we can find their username. + // find + if ( DoesFileExistIn( steamInstallPath, pchSteamDLL ) && !DoesFileExistIn( steamInstallPath, "steamapp.cfg" ) ) + break; + + if ( !Q_StripLastDir( steamInstallPath, steamInstallPathLen ) ) + { + if ( bErrorsAsWarnings ) + { + Warning( "Can't find %s relative to executable path: %s.\n", pchSteamDLL, executablePath ); + return FS_MISSING_STEAM_DLL; + } + else + { + return SetupFileSystemError( false, FS_MISSING_STEAM_DLL, "Can't find %s relative to executable path: %s.", pchSteamDLL, executablePath ); + } + } + } + + // Also, add the install path to their PATH environment variable, so filesystem_steam.dll can get to steam.dll. + char szPath[ 8192 ]; + steamEnvVars.m_Path.GetValue( szPath, sizeof( szPath ) ); + if ( !DoesPathExistAlready( szPath, steamInstallPath ) ) + { +#ifdef WIN32 +#define PATH_SEP ";" +#else +#define PATH_SEP ":" +#endif + steamEnvVars.m_Path.SetValue( "%s%s%s", szPath, PATH_SEP, steamInstallPath ); + } + return FS_OK; +} + +FSReturnCode_t GetSteamCfgPath( char *steamCfgPath, int steamCfgPathLen ) +{ + steamCfgPath[0] = 0; + char executablePath[MAX_PATH]; + if ( !FileSystem_GetExecutableDir( executablePath, sizeof( executablePath ) ) ) + { + return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_GetExecutableDir failed." ); + } + Q_strncpy( steamCfgPath, executablePath, steamCfgPathLen ); + while ( 1 ) + { + if ( DoesFileExistIn( steamCfgPath, "steam.cfg" ) ) + break; + + if ( !Q_StripLastDir( steamCfgPath, steamCfgPathLen) ) + { + // the file isnt found, thats ok, its not mandatory + return FS_OK; + } + } + Q_AppendSlash( steamCfgPath, steamCfgPathLen ); + Q_strncat( steamCfgPath, "steam.cfg", steamCfgPathLen, COPY_ALL_CHARACTERS ); + + return FS_OK; +} + +void SetSteamAppUser( KeyValues *pSteamInfo, const char *steamInstallPath, CSteamEnvVars &steamEnvVars ) +{ + // Always inherit the Steam user if it's already set, since it probably means we (or the + // the app that launched us) were launched from Steam. + char appUser[MAX_PATH]; + if ( steamEnvVars.m_SteamAppUser.GetValue( appUser, sizeof( appUser ) ) ) + return; + + const char *pTempAppUser = NULL; + if ( pSteamInfo && (pTempAppUser = pSteamInfo->GetString( "SteamAppUser", NULL )) != NULL ) + { + Q_strncpy( appUser, pTempAppUser, sizeof( appUser ) ); + } + else + { + // They don't have SteamInfo.txt, or it's missing SteamAppUser. Try to figure out the user + // by looking in \config\SteamAppData.vdf. + char fullFilename[MAX_PATH]; + Q_strncpy( fullFilename, steamInstallPath, sizeof( fullFilename ) ); + Q_AppendSlash( fullFilename, sizeof( fullFilename ) ); + Q_strncat( fullFilename, "config\\SteamAppData.vdf", sizeof( fullFilename ), COPY_ALL_CHARACTERS ); + + KeyValues *pSteamAppData = ReadKeyValuesFile( fullFilename ); + if ( !pSteamAppData || (pTempAppUser = pSteamAppData->GetString( "AutoLoginUser", NULL )) == NULL ) + { + Error( "Can't find steam app user info." ); + } + Q_strncpy( appUser, pTempAppUser, sizeof( appUser ) ); + + pSteamAppData->deleteThis(); + } + + Q_strlower( appUser ); + steamEnvVars.m_SteamAppUser.SetValue( "%s", appUser ); +} + +void SetSteamUserPassphrase( KeyValues *pSteamInfo, CSteamEnvVars &steamEnvVars ) +{ + // Always inherit the passphrase if it's already set, since it probably means we (or the + // the app that launched us) were launched from Steam. + char szPassPhrase[ MAX_PATH ]; + if ( steamEnvVars.m_SteamUserPassphrase.GetValue( szPassPhrase, sizeof( szPassPhrase ) ) ) + return; + + // SteamUserPassphrase. + const char *pStr; + if ( pSteamInfo && (pStr = pSteamInfo->GetString( "SteamUserPassphrase", NULL )) != NULL ) + { + steamEnvVars.m_SteamUserPassphrase.SetValue( "%s", pStr ); + } +} + +FSReturnCode_t SetupSteamStartupEnvironment( KeyValues *pFileSystemInfo, const char *pGameInfoDirectory, CSteamEnvVars &steamEnvVars ) +{ + // Ok, we're going to run Steam. See if they have SteamInfo.txt. If not, we'll try to deduce what we can. + char steamInfoFile[MAX_PATH]; + Q_strncpy( steamInfoFile, pGameInfoDirectory, sizeof( steamInfoFile ) ); + Q_AppendSlash( steamInfoFile, sizeof( steamInfoFile ) ); + Q_strncat( steamInfoFile, "steaminfo.txt", sizeof( steamInfoFile ), COPY_ALL_CHARACTERS ); + KeyValues *pSteamInfo = ReadKeyValuesFile( steamInfoFile ); + + char steamInstallPath[MAX_PATH]; + FSReturnCode_t ret = SetSteamInstallPath( steamInstallPath, sizeof( steamInstallPath ), steamEnvVars, false ); + if ( ret != FS_OK ) + return ret; + + SetSteamAppUser( pSteamInfo, steamInstallPath, steamEnvVars ); + SetSteamUserPassphrase( pSteamInfo, steamEnvVars ); + + if ( pSteamInfo ) + pSteamInfo->deleteThis(); + + return FS_OK; +} + +FSReturnCode_t FileSystem_SetBasePaths( IFileSystem *pFileSystem ) +{ + pFileSystem->RemoveSearchPaths( "EXECUTABLE_PATH" ); + + char executablePath[MAX_PATH]; + if ( !FileSystem_GetExecutableDir( executablePath, sizeof( executablePath ) ) ) + return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_GetExecutableDir failed." ); + + pFileSystem->AddSearchPath( executablePath, "EXECUTABLE_PATH" ); + + if ( !FileSystem_GetBaseDir( executablePath, sizeof( executablePath ) ) ) + return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_GetBaseDir failed." ); + + pFileSystem->AddSearchPath( executablePath, "BASE_PATH" ); + + return FS_OK; +} + +//----------------------------------------------------------------------------- +// Returns the name of the file system DLL to use +//----------------------------------------------------------------------------- +FSReturnCode_t FileSystem_GetFileSystemDLLName( char *pFileSystemDLL, int nMaxLen, bool &bSteam ) +{ + bSteam = false; + + // Inside of here, we don't have a filesystem yet, so we have to assume that the filesystem_stdio or filesystem_steam + // is in this same directory with us. + char executablePath[MAX_PATH]; + if ( !FileSystem_GetExecutableDir( executablePath, sizeof( executablePath ) ) ) + return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_GetExecutableDir failed." ); + + // Assume we'll use local files + Q_snprintf( pFileSystemDLL, nMaxLen, "%s%cfilesystem_stdio" DLL_EXT_STRING, executablePath, CORRECT_PATH_SEPARATOR ); + + #if !defined( _X360 ) + + // Use filsystem_steam if it exists? + #if defined( OSX ) || defined( LINUX ) + struct stat statBuf; + #endif + if ( + #if defined( OSX ) || defined( LINUX ) + stat( pFileSystemDLL, &statBuf ) != 0 + #else + _access( pFileSystemDLL, 0 ) != 0 + #endif + ) { + Q_snprintf( pFileSystemDLL, nMaxLen, "%s%cfilesystem_steam" DLL_EXT_STRING, executablePath, CORRECT_PATH_SEPARATOR ); + bSteam = true; + } + #endif + + return FS_OK; +} + +//----------------------------------------------------------------------------- +// Sets up the steam.dll install path in our PATH env var (so you can then just +// LoadLibrary() on filesystem_steam.dll without having to copy steam.dll anywhere special ) +//----------------------------------------------------------------------------- +FSReturnCode_t FileSystem_SetupSteamInstallPath() +{ + CSteamEnvVars steamEnvVars; + char steamInstallPath[MAX_PATH]; + FSReturnCode_t ret = SetSteamInstallPath( steamInstallPath, sizeof( steamInstallPath ), steamEnvVars, true ); + steamEnvVars.m_Path.SetRestoreOriginalValue( false ); // We want to keep the change to the path going forward. + return ret; +} + +//----------------------------------------------------------------------------- +// Sets up the steam environment + gets back the gameinfo.txt path +//----------------------------------------------------------------------------- +FSReturnCode_t FileSystem_SetupSteamEnvironment( CFSSteamSetupInfo &fsInfo ) +{ + // First, locate the directory with gameinfo.txt. + FSReturnCode_t ret = LocateGameInfoFile( fsInfo, fsInfo.m_GameInfoPath, sizeof( fsInfo.m_GameInfoPath ) ); + if ( ret != FS_OK ) + return ret; + + // This is so that processes spawned by this application will have the same VPROJECT +#ifdef WIN32 + char pEnvBuf[MAX_PATH+32]; + Q_snprintf( pEnvBuf, sizeof(pEnvBuf), "%s=%s", GAMEDIR_TOKEN, fsInfo.m_GameInfoPath ); + _putenv( pEnvBuf ); +#else + setenv( GAMEDIR_TOKEN, fsInfo.m_GameInfoPath, 1 ); +#endif + + CSteamEnvVars steamEnvVars; + if ( fsInfo.m_bSteam ) + { + if ( fsInfo.m_bToolsMode ) + { + // Now, load gameinfo.txt (to make sure it's there) + KeyValues *pMainFile, *pFileSystemInfo, *pSearchPaths; + ret = LoadGameInfoFile( fsInfo.m_GameInfoPath, pMainFile, pFileSystemInfo, pSearchPaths ); + if ( ret != FS_OK ) + return ret; + + // If filesystem_stdio.dll is missing or -steam is specified, then load filesystem_steam.dll. + // There are two command line parameters for Steam: + // 1) -steam (runs Steam in remote filesystem mode; requires Steam backend) + // 2) -steamlocal (runs Steam in local filesystem mode (all content off HDD) + + // Setup all the environment variables related to Steam so filesystem_steam.dll knows how to initialize Steam. + ret = SetupSteamStartupEnvironment( pFileSystemInfo, fsInfo.m_GameInfoPath, steamEnvVars ); + if ( ret != FS_OK ) + return ret; + + steamEnvVars.m_SteamAppId.SetRestoreOriginalValue( false ); // We want to keep the change to the path going forward. + + // We're done with main file + pMainFile->deleteThis(); + } + else if ( fsInfo.m_bSetSteamDLLPath ) + { + // This is used by the engine to automatically set the path to their steam.dll when running the engine, + // so they can debug it without having to copy steam.dll up into their hl2.exe folder. + char steamInstallPath[MAX_PATH]; + ret = SetSteamInstallPath( steamInstallPath, sizeof( steamInstallPath ), steamEnvVars, true ); + steamEnvVars.m_Path.SetRestoreOriginalValue( false ); // We want to keep the change to the path going forward. + } + } + + return FS_OK; +} + + +//----------------------------------------------------------------------------- +// Loads the file system module +//----------------------------------------------------------------------------- +FSReturnCode_t FileSystem_LoadFileSystemModule( CFSLoadModuleInfo &fsInfo ) +{ + // First, locate the directory with gameinfo.txt. + FSReturnCode_t ret = FileSystem_SetupSteamEnvironment( fsInfo ); + if ( ret != FS_OK ) + return ret; + + // Now that the environment is setup, load the filesystem module. + if ( !Sys_LoadInterface( + fsInfo.m_pFileSystemDLLName, + FILESYSTEM_INTERFACE_VERSION, + &fsInfo.m_pModule, + (void**)&fsInfo.m_pFileSystem ) ) + { + return SetupFileSystemError( false, FS_UNABLE_TO_INIT, "Can't load %s.", fsInfo.m_pFileSystemDLLName ); + } + + if ( !fsInfo.m_pFileSystem->Connect( fsInfo.m_ConnectFactory ) ) + return SetupFileSystemError( false, FS_UNABLE_TO_INIT, "%s IFileSystem::Connect failed.", fsInfo.m_pFileSystemDLLName ); + + if ( fsInfo.m_pFileSystem->Init() != INIT_OK ) + return SetupFileSystemError( false, FS_UNABLE_TO_INIT, "%s IFileSystem::Init failed.", fsInfo.m_pFileSystemDLLName ); + + return FS_OK; +} + + +//----------------------------------------------------------------------------- +// Mounds a particular steam cache +//----------------------------------------------------------------------------- +FSReturnCode_t FileSystem_MountContent( CFSMountContentInfo &mountContentInfo ) +{ + // This part is Steam-only. + if ( mountContentInfo.m_pFileSystem->IsSteam() ) + { + return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "Should not be using filesystem_steam anymore!" ); + +// // Find out the "extra app id". This is for tools, which want to mount a base app's filesystem +// // like HL2, then mount the SDK content (tools materials and models, etc) in addition. +// int nExtraAppId = -1; +// if ( mountContentInfo.m_bToolsMode ) +// { +// // !FIXME! Here we need to mount the tools content (VPK's) in some way...? +// } +// +// // Set our working directory temporarily so Steam can remember it. +// // This is what Steam strips off absolute filenames like c:\program files\valve\steam\steamapps\username\sourcesdk +// // to get to the relative part of the path. +// char baseDir[MAX_PATH], oldWorkingDir[MAX_PATH]; +// if ( !FileSystem_GetBaseDir( baseDir, sizeof( baseDir ) ) ) +// return SetupFileSystemError( false, FS_INVALID_PARAMETERS, "FileSystem_GetBaseDir failed." ); +// +// Q_getwd( oldWorkingDir, sizeof( oldWorkingDir ) ); +// _chdir( baseDir ); +// +// // Filesystem_tools needs to add dependencies in here beforehand. +// FilesystemMountRetval_t retVal = mountContentInfo.m_pFileSystem->MountSteamContent( nExtraAppId ); +// +// _chdir( oldWorkingDir ); +// +// if ( retVal != FILESYSTEM_MOUNT_OK ) +// return SetupFileSystemError( true, FS_UNABLE_TO_INIT, "Unable to mount Steam content in the file system" ); + } + + return FileSystem_SetBasePaths( mountContentInfo.m_pFileSystem ); +} + +void FileSystem_SetErrorMode( FSErrorMode_t errorMode ) +{ + g_FileSystemErrorMode = errorMode; +} + +void FileSystem_ClearSteamEnvVars() +{ + CSteamEnvVars envVars; + + // Change the values and don't restore the originals. + envVars.m_SteamAppId.SetValue( "" ); + envVars.m_SteamUserPassphrase.SetValue( "" ); + envVars.m_SteamAppUser.SetValue( "" ); + + envVars.SetRestoreOriginalValue_ALL( false ); +} + +//----------------------------------------------------------------------------- +// Adds the platform folder to the search path. +//----------------------------------------------------------------------------- +void FileSystem_AddSearchPath_Platform( IFileSystem *pFileSystem, const char *szGameInfoPath ) +{ + char platform[MAX_PATH]; + Q_strncpy( platform, szGameInfoPath, MAX_PATH ); + Q_StripTrailingSlash( platform ); + Q_strncat( platform, "/../platform", MAX_PATH, MAX_PATH ); + + pFileSystem->AddSearchPath( platform, "PLATFORM" ); +} diff --git a/sp/src/public/filesystem_init.h b/sp/src/public/filesystem_init.h new file mode 100644 index 00000000..d95e7c3a --- /dev/null +++ b/sp/src/public/filesystem_init.h @@ -0,0 +1,222 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef FILESYSTEM_INIT_H +#define FILESYSTEM_INIT_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "filesystem.h" + + +// If this option is on the command line, then filesystem_init won't bring up the vconfig +// dialog even if FS_ERRORMODE_VCONFIG is used. +#define CMDLINEOPTION_NOVCONFIG "-NoVConfig" + +#define GAMEDIR_TOKEN "VProject" + + +#if defined( _WIN32 ) || defined( WIN32 ) +#define PATHSEPARATOR(c) ((c) == '\\' || (c) == '/') +#else //_WIN32 +#define PATHSEPARATOR(c) ((c) == '/') +#endif //_WIN32 + + +enum FSReturnCode_t +{ + FS_OK, + FS_MISSING_GAMEINFO_FILE, + FS_INVALID_GAMEINFO_FILE, + FS_INVALID_PARAMETERS, + FS_UNABLE_TO_INIT, + FS_MISSING_STEAM_DLL +}; + + +enum FSErrorMode_t +{ + FS_ERRORMODE_AUTO, // Call Error() in case of an error. + FS_ERRORMODE_VCONFIG, // Call Error() for errors and run vconfig when appropriate. + FS_ERRORMODE_NONE, // Just return FSReturnCode values and setup the string for FileSystem_GetLastErrorString. +}; + + +class CFSSteamSetupInfo +{ +public: + CFSSteamSetupInfo(); + +// Inputs. +public: + // If this is set, then the init code will look in this directory up to the root for gameinfo.txt. + // It must be set for FileSystem_LoadSearchPaths to work. + // + // (default: null) + const char *m_pDirectoryName; + + // If this is true, then it won't look at -vproject, -game, or the vproject environment variable + // to find gameinfo.txt. If this is true, then m_pDirectoryName must be set. + // + // (default: false) + bool m_bOnlyUseDirectoryName; + + // If this is true, then: + // 1. It will set the environment variables that steam.dll looks at for startup info. + // 2. It will look for ToolsAppId in the gameinfo.txt file and load the + // steam caches associated with that cache if it's there. This is so apps like Hammer and hlmv + // can load the main steam caches (like for Counter-Strike or Half-Life 2), and also load the + // caches that include tools-specific materials (materials\editor, materials\debug, etc). + // + // (default: true - should be FALSE for the engine) + bool m_bToolsMode; + + // If this is true, and m_bToolsMode is false, then it will append the path to steam.dll to the + // PATH environment variable. This makes it so you can run the engine under Steam without + // having to copy steam.dll up into your hl2.exe folder. + // (default: false) + bool m_bSetSteamDLLPath; + + // Are we loading the Steam filesystem? This should be the same value that + // FileSystem_GetFileSystemDLLName gave you. + bool m_bSteam; + + // If this is true, then it won't look for a gameinfo.txt. + // + // (default: false) + bool m_bNoGameInfo; + +// Outputs (if it returns FS_OK). +public: + char m_GameInfoPath[512]; // The directory that gameinfo.txt lives in. +}; + + +class CFSLoadModuleInfo : public CFSSteamSetupInfo +{ +public: + CFSLoadModuleInfo(); + +// Inputs. +public: + // Full path to the file system DLL (gotten from FileSystem_GetFileSystemDLLName). + const char *m_pFileSystemDLLName; + + // Passed to IFileSystem::Connect. + CreateInterfaceFn m_ConnectFactory; + +// Outputs (if it returns FS_OK). +public: + // The filesystem you got from FileSystem_LoadFileSystemModule. + IFileSystem *m_pFileSystem; + CSysModule *m_pModule; +}; + + +class CFSMountContentInfo +{ +public: + CFSMountContentInfo(); + +// Inputs. +public: + + // See CFSLoadModuleInfo::m_bToolsMode (this valid should always be the same as you passed to CFSLoadModuleInfo::m_bToolsMode). + bool m_bToolsMode; + + // This specifies the directory where gameinfo.txt is. This must be set. + // It can come from CFSLoadModuleInfo::m_GameInfoPath. + const char *m_pDirectoryName; + + // Gotten from CFSLoadModuleInfo::m_pFileSystem. + IFileSystem *m_pFileSystem; +}; + + +class CFSSearchPathsInit +{ +public: + CFSSearchPathsInit(); + +// Inputs. +public: + // This specifies the directory where gameinfo.txt is. This must be set. + const char *m_pDirectoryName; + + // If this is set, then any search paths with a _english will be replaced with _m_pLanguage and added before the + // _english path + // (default: null) + const char *m_pLanguage; + + // This is the filesystem FileSystem_LoadSearchPaths is talking to. + IFileSystem *m_pFileSystem; + + bool m_bMountHDContent; + bool m_bLowViolence; + +// Outputs. +public: + // This is the location of the first search path called "game", which also becomes your "mod" search path. + char m_ModPath[512]; +}; + + +const char *GetVProjectCmdLineValue(); + + +// Call this to use a bin directory relative to VPROJECT +void FileSystem_UseVProjectBinDir( bool bEnable ); + +// This is used by all things that use the application framework: +// Note that the application framework automatically takes care of step 1 if you use CSteamApplication. +// Step 1: Ask filesystem_init for the name of the filesystem DLL to load +FSReturnCode_t FileSystem_GetFileSystemDLLName( char *pFileSystemDLL, int nMaxLen, bool &bSteam ); + +// Step 2: Use filesystem framework to load/connect/init that filesystem DLL +// -or- just set up the steam environment and get back the gameinfo.txt path +// The second method is used by the application framework, which wants to connect/init the filesystem itself +FSReturnCode_t FileSystem_LoadFileSystemModule( CFSLoadModuleInfo &info ); +FSReturnCode_t FileSystem_SetupSteamEnvironment( CFSSteamSetupInfo &info ); + +// Step 3: Ask filesystem_init to set up the executable search path, and mount the steam content based on the mod gameinfo.txt file +FSReturnCode_t FileSystem_MountContent( CFSMountContentInfo &fsInfo ); + +// Step 4: Load the search paths out of pGameDirectory\gameinfo.txt. +FSReturnCode_t FileSystem_LoadSearchPaths( CFSSearchPathsInit &initInfo ); + +// This is automatically done during step 3, but if you want to redo all the search +// paths (like Hammer does), you can call this to reset executable_path. +FSReturnCode_t FileSystem_SetBasePaths( IFileSystem *pFileSystem ); + +// Utility function to add the PLATFORM search path. +void FileSystem_AddSearchPath_Platform( IFileSystem *pFileSystem, const char *szGameInfoPath ); + +// See FSErrorMode_t. If you don't specify one here, then the default is FS_ERRORMODE_VCONFIG. +void FileSystem_SetErrorMode( FSErrorMode_t errorMode = FS_ERRORMODE_VCONFIG ); + +bool FileSystem_GetExecutableDir( char *exedir, int exeDirLen ); + +// Clear SteamAppUser, SteamUserPassphrase, and SteamAppId from this process's environment. +// TODO: always do this after LoadFileSysteModule.. there's no reason it should be +// in the environment. +void FileSystem_ClearSteamEnvVars(); + +// Find the steam.cfg above you for optional stuff +FSReturnCode_t GetSteamCfgPath( char *steamCfgPath, int steamCfgPathLen ); + +// Setup the Steam.dll path without needing all the extra gameinfo stuff first +// used by the CSteamApplication::Create() code to LoadModule() on the filesystem +// before the underlying apps know specific details about the environment to load +FSReturnCode_t FileSystem_SetupSteamInstallPath(); + +// Returns the last error. +const char *FileSystem_GetLastErrorString(); + +void Q_getwd( char *out, int outSize ); + +#endif // FILESYSTEM_INIT_H diff --git a/sp/src/public/filesystem_passthru.h b/sp/src/public/filesystem_passthru.h new file mode 100644 index 00000000..b6f1d2c7 --- /dev/null +++ b/sp/src/public/filesystem_passthru.h @@ -0,0 +1,263 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef FILESYSTEM_PASSTHRU_H +#define FILESYSTEM_PASSTHRU_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "filesystem.h" +#include +#include + +#ifdef AsyncRead +#undef AsyncRead +#undef AsyncReadMutiple +#endif + +// +// These classes pass all filesystem interface calls through to another filesystem +// interface. They can be used anytime you want to override a couple things in +// a filesystem. VMPI uses this to override the base filesystem calls while +// allowing the rest of the filesystem functionality to work on the master. +// + +template +class CInternalFileSystemPassThru : public Base +{ +public: + CInternalFileSystemPassThru() + { + m_pBaseFileSystemPassThru = NULL; + } + virtual void InitPassThru( IBaseFileSystem *pBaseFileSystemPassThru ) + { + m_pBaseFileSystemPassThru = pBaseFileSystemPassThru; + } + virtual int Read( void* pOutput, int size, FileHandle_t file ) { return m_pBaseFileSystemPassThru->Read( pOutput, size, file ); } + virtual int Write( void const* pInput, int size, FileHandle_t file ) { return m_pBaseFileSystemPassThru->Write( pInput, size, file ); } + virtual FileHandle_t Open( const char *pFileName, const char *pOptions, const char *pathID ) { return m_pBaseFileSystemPassThru->Open( pFileName, pOptions, pathID ); } + virtual void Close( FileHandle_t file ) { m_pBaseFileSystemPassThru->Close( file ); } + virtual void Seek( FileHandle_t file, int pos, FileSystemSeek_t seekType ) { m_pBaseFileSystemPassThru->Seek( file, pos, seekType ); } + virtual unsigned int Tell( FileHandle_t file ) { return m_pBaseFileSystemPassThru->Tell( file ); } + virtual unsigned int Size( FileHandle_t file ) { return m_pBaseFileSystemPassThru->Size( file ); } + virtual unsigned int Size( const char *pFileName, const char *pPathID ) { return m_pBaseFileSystemPassThru->Size( pFileName, pPathID ); } + virtual void Flush( FileHandle_t file ) { m_pBaseFileSystemPassThru->Flush( file ); } + virtual bool Precache( const char *pFileName, const char *pPathID ) { return m_pBaseFileSystemPassThru->Precache( pFileName, pPathID ); } + virtual bool FileExists( const char *pFileName, const char *pPathID ) { return m_pBaseFileSystemPassThru->FileExists( pFileName, pPathID ); } + virtual bool IsFileWritable( char const *pFileName, const char *pPathID ) { return m_pBaseFileSystemPassThru->IsFileWritable( pFileName, pPathID ); } + virtual bool SetFileWritable( char const *pFileName, bool writable, const char *pPathID ) { return m_pBaseFileSystemPassThru->SetFileWritable( pFileName, writable, pPathID ); } + virtual long GetFileTime( const char *pFileName, const char *pPathID ) { return m_pBaseFileSystemPassThru->GetFileTime( pFileName, pPathID ); } + virtual bool ReadFile( const char *pFileName, const char *pPath, CUtlBuffer &buf, int nMaxBytes = 0, int nStartingByte = 0, FSAllocFunc_t pfnAlloc = NULL ) { return m_pBaseFileSystemPassThru->ReadFile( pFileName, pPath, buf, nMaxBytes, nStartingByte, pfnAlloc ); } + virtual bool WriteFile( const char *pFileName, const char *pPath, CUtlBuffer &buf ) { return m_pBaseFileSystemPassThru->WriteFile( pFileName, pPath, buf ); } + virtual bool UnzipFile( const char *pFileName, const char *pPath, const char *pDestination ) { return m_pBaseFileSystemPassThru->UnzipFile( pFileName, pPath, pDestination ); } + +protected: + IBaseFileSystem *m_pBaseFileSystemPassThru; +}; + + +class CBaseFileSystemPassThru : public CInternalFileSystemPassThru +{ +public: +}; + + +class CFileSystemPassThru : public CInternalFileSystemPassThru +{ +public: + typedef CInternalFileSystemPassThru BaseClass; + + CFileSystemPassThru() + { + m_pFileSystemPassThru = NULL; + } + virtual void InitPassThru( IFileSystem *pFileSystemPassThru, bool bBaseOnly ) + { + if ( !bBaseOnly ) + m_pFileSystemPassThru = pFileSystemPassThru; + + BaseClass::InitPassThru( pFileSystemPassThru ); + } + + // IAppSystem stuff. + // Here's where the app systems get to learn about each other + virtual bool Connect( CreateInterfaceFn factory ) { return m_pFileSystemPassThru->Connect( factory ); } + virtual void Disconnect() { m_pFileSystemPassThru->Disconnect(); } + virtual void *QueryInterface( const char *pInterfaceName ) { return m_pFileSystemPassThru->QueryInterface( pInterfaceName ); } + virtual InitReturnVal_t Init() { return m_pFileSystemPassThru->Init(); } + virtual void Shutdown() { m_pFileSystemPassThru->Shutdown(); } + + virtual void RemoveAllSearchPaths( void ) { m_pFileSystemPassThru->RemoveAllSearchPaths(); } + virtual void AddSearchPath( const char *pPath, const char *pathID, SearchPathAdd_t addType ) { m_pFileSystemPassThru->AddSearchPath( pPath, pathID, addType ); } + virtual bool RemoveSearchPath( const char *pPath, const char *pathID ) { return m_pFileSystemPassThru->RemoveSearchPath( pPath, pathID ); } + virtual void RemoveFile( char const* pRelativePath, const char *pathID ) { m_pFileSystemPassThru->RemoveFile( pRelativePath, pathID ); } + virtual bool RenameFile( char const *pOldPath, char const *pNewPath, const char *pathID ) { return m_pFileSystemPassThru->RenameFile( pOldPath, pNewPath, pathID ); } + virtual void CreateDirHierarchy( const char *path, const char *pathID ) { m_pFileSystemPassThru->CreateDirHierarchy( path, pathID ); } + virtual bool IsDirectory( const char *pFileName, const char *pathID ) { return m_pFileSystemPassThru->IsDirectory( pFileName, pathID ); } + virtual void FileTimeToString( char* pStrip, int maxCharsIncludingTerminator, long fileTime ) { m_pFileSystemPassThru->FileTimeToString( pStrip, maxCharsIncludingTerminator, fileTime ); } + virtual void SetBufferSize( FileHandle_t file, unsigned nBytes ) { m_pFileSystemPassThru->SetBufferSize( file, nBytes ); } + virtual bool IsOk( FileHandle_t file ) { return m_pFileSystemPassThru->IsOk( file ); } + virtual bool EndOfFile( FileHandle_t file ) { return m_pFileSystemPassThru->EndOfFile( file ); } + virtual char *ReadLine( char *pOutput, int maxChars, FileHandle_t file ) { return m_pFileSystemPassThru->ReadLine( pOutput, maxChars, file ); } + virtual int FPrintf( FileHandle_t file, PRINTF_FORMAT_STRING const char *pFormat, ... ) + { + char str[8192]; + va_list marker; + va_start( marker, pFormat ); + _vsnprintf( str, sizeof( str ), pFormat, marker ); + va_end( marker ); + return m_pFileSystemPassThru->FPrintf( file, "%s", str ); + } + virtual CSysModule *LoadModule( const char *pFileName, const char *pPathID, bool bValidatedDllOnly ) { return m_pFileSystemPassThru->LoadModule( pFileName, pPathID, bValidatedDllOnly ); } + virtual void UnloadModule( CSysModule *pModule ) { m_pFileSystemPassThru->UnloadModule( pModule ); } + virtual const char *FindFirst( const char *pWildCard, FileFindHandle_t *pHandle ) { return m_pFileSystemPassThru->FindFirst( pWildCard, pHandle ); } + virtual const char *FindNext( FileFindHandle_t handle ) { return m_pFileSystemPassThru->FindNext( handle ); } + virtual bool FindIsDirectory( FileFindHandle_t handle ) { return m_pFileSystemPassThru->FindIsDirectory( handle ); } + virtual void FindClose( FileFindHandle_t handle ) { m_pFileSystemPassThru->FindClose( handle ); } + virtual const char *GetLocalPath( const char *pFileName, char *pLocalPath, int localPathBufferSize ) { return m_pFileSystemPassThru->GetLocalPath( pFileName, pLocalPath, localPathBufferSize ); } + virtual bool FullPathToRelativePath( const char *pFullpath, char *pRelative, int maxlen ) { return m_pFileSystemPassThru->FullPathToRelativePath( pFullpath, pRelative, maxlen ); } + virtual bool GetCurrentDirectory( char* pDirectory, int maxlen ) { return m_pFileSystemPassThru->GetCurrentDirectory( pDirectory, maxlen ); } + virtual void PrintOpenedFiles( void ) { m_pFileSystemPassThru->PrintOpenedFiles(); } + virtual void PrintSearchPaths( void ) { m_pFileSystemPassThru->PrintSearchPaths(); } + virtual void SetWarningFunc( void (*pfnWarning)( PRINTF_FORMAT_STRING const char *fmt, ... ) ) { m_pFileSystemPassThru->SetWarningFunc( pfnWarning ); } + virtual void SetWarningLevel( FileWarningLevel_t level ) { m_pFileSystemPassThru->SetWarningLevel( level ); } + virtual void AddLoggingFunc( void (*pfnLogFunc)( const char *fileName, const char *accessType ) ){ m_pFileSystemPassThru->AddLoggingFunc( pfnLogFunc ); } + virtual void RemoveLoggingFunc( FileSystemLoggingFunc_t logFunc ) { m_pFileSystemPassThru->RemoveLoggingFunc( logFunc ); } + virtual FSAsyncStatus_t AsyncReadMultiple( const FileAsyncRequest_t *pRequests, int nRequests, FSAsyncControl_t *pControls ) { return m_pFileSystemPassThru->AsyncReadMultiple( pRequests, nRequests, pControls ); } + virtual FSAsyncStatus_t AsyncReadMultipleCreditAlloc( const FileAsyncRequest_t *pRequests, int nRequests, const char *pszFile, int line, FSAsyncControl_t *pControls ) { return m_pFileSystemPassThru->AsyncReadMultipleCreditAlloc( pRequests, nRequests, pszFile, line, pControls ); } + virtual FSAsyncStatus_t AsyncFinish(FSAsyncControl_t hControl, bool wait) { return m_pFileSystemPassThru->AsyncFinish( hControl, wait ); } + virtual FSAsyncStatus_t AsyncGetResult( FSAsyncControl_t hControl, void **ppData, int *pSize ) { return m_pFileSystemPassThru->AsyncGetResult( hControl, ppData, pSize ); } + virtual FSAsyncStatus_t AsyncAbort(FSAsyncControl_t hControl) { return m_pFileSystemPassThru->AsyncAbort( hControl ); } + virtual FSAsyncStatus_t AsyncStatus(FSAsyncControl_t hControl) { return m_pFileSystemPassThru->AsyncStatus( hControl ); } + virtual FSAsyncStatus_t AsyncFlush() { return m_pFileSystemPassThru->AsyncFlush(); } + virtual void AsyncAddRef( FSAsyncControl_t hControl ) { m_pFileSystemPassThru->AsyncAddRef( hControl ); } + virtual void AsyncRelease( FSAsyncControl_t hControl ) { m_pFileSystemPassThru->AsyncRelease( hControl ); } + virtual FSAsyncStatus_t AsyncBeginRead( const char *pszFile, FSAsyncFile_t *phFile ) { return m_pFileSystemPassThru->AsyncBeginRead( pszFile, phFile ); } + virtual FSAsyncStatus_t AsyncEndRead( FSAsyncFile_t hFile ) { return m_pFileSystemPassThru->AsyncEndRead( hFile ); } + virtual void AsyncAddFetcher( IAsyncFileFetch *pFetcher ) { m_pFileSystemPassThru->AsyncAddFetcher( pFetcher ); } + virtual void AsyncRemoveFetcher( IAsyncFileFetch *pFetcher ) { m_pFileSystemPassThru->AsyncRemoveFetcher( pFetcher ); } + virtual const FileSystemStatistics *GetFilesystemStatistics() { return m_pFileSystemPassThru->GetFilesystemStatistics(); } + virtual WaitForResourcesHandle_t WaitForResources( const char *resourcelist ) { return m_pFileSystemPassThru->WaitForResources( resourcelist ); } + virtual bool GetWaitForResourcesProgress( WaitForResourcesHandle_t handle, + float *progress, bool *complete ) { return m_pFileSystemPassThru->GetWaitForResourcesProgress( handle, progress, complete ); } + virtual void CancelWaitForResources( WaitForResourcesHandle_t handle ) { m_pFileSystemPassThru->CancelWaitForResources( handle ); } + virtual int HintResourceNeed( const char *hintlist, int forgetEverything ) { return m_pFileSystemPassThru->HintResourceNeed( hintlist, forgetEverything ); } + virtual bool IsFileImmediatelyAvailable(const char *pFileName) { return m_pFileSystemPassThru->IsFileImmediatelyAvailable( pFileName ); } + virtual void GetLocalCopy( const char *pFileName ) { m_pFileSystemPassThru->GetLocalCopy( pFileName ); } + virtual FileNameHandle_t FindOrAddFileName( char const *pFileName ) { return m_pFileSystemPassThru->FindOrAddFileName( pFileName ); } + virtual FileNameHandle_t FindFileName( char const *pFileName ) { return m_pFileSystemPassThru->FindFileName( pFileName ); } + virtual bool String( const FileNameHandle_t& handle, char *buf, int buflen ) { return m_pFileSystemPassThru->String( handle, buf, buflen ); } + virtual bool IsOk2( FileHandle_t file ) { return IsOk(file); } + virtual void RemoveSearchPaths( const char *szPathID ) { m_pFileSystemPassThru->RemoveSearchPaths( szPathID ); } + virtual bool IsSteam() const { return m_pFileSystemPassThru->IsSteam(); } + virtual FilesystemMountRetval_t MountSteamContent( int nExtraAppId = -1 ) { return m_pFileSystemPassThru->MountSteamContent( nExtraAppId ); } + + virtual const char *FindFirstEx( + const char *pWildCard, + const char *pPathID, + FileFindHandle_t *pHandle + ) { return m_pFileSystemPassThru->FindFirstEx( pWildCard, pPathID, pHandle ); } + virtual void MarkPathIDByRequestOnly( const char *pPathID, bool bRequestOnly ) { m_pFileSystemPassThru->MarkPathIDByRequestOnly( pPathID, bRequestOnly ); } + virtual bool AddPackFile( const char *fullpath, const char *pathID ) { return m_pFileSystemPassThru->AddPackFile( fullpath, pathID ); } + virtual FSAsyncStatus_t AsyncAppend(const char *pFileName, const void *pSrc, int nSrcBytes, bool bFreeMemory, FSAsyncControl_t *pControl ) { return m_pFileSystemPassThru->AsyncAppend( pFileName, pSrc, nSrcBytes, bFreeMemory, pControl); } + virtual FSAsyncStatus_t AsyncWrite(const char *pFileName, const void *pSrc, int nSrcBytes, bool bFreeMemory, bool bAppend, FSAsyncControl_t *pControl ) { return m_pFileSystemPassThru->AsyncWrite( pFileName, pSrc, nSrcBytes, bFreeMemory, bAppend, pControl); } + virtual FSAsyncStatus_t AsyncWriteFile(const char *pFileName, const CUtlBuffer *pSrc, int nSrcBytes, bool bFreeMemory, bool bAppend, FSAsyncControl_t *pControl ) { return m_pFileSystemPassThru->AsyncWriteFile( pFileName, pSrc, nSrcBytes, bFreeMemory, bAppend, pControl); } + virtual FSAsyncStatus_t AsyncAppendFile(const char *pDestFileName, const char *pSrcFileName, FSAsyncControl_t *pControl ) { return m_pFileSystemPassThru->AsyncAppendFile(pDestFileName, pSrcFileName, pControl); } + virtual void AsyncFinishAll( int iToPriority ) { m_pFileSystemPassThru->AsyncFinishAll(iToPriority); } + virtual void AsyncFinishAllWrites() { m_pFileSystemPassThru->AsyncFinishAllWrites(); } + virtual FSAsyncStatus_t AsyncSetPriority(FSAsyncControl_t hControl, int newPriority) { return m_pFileSystemPassThru->AsyncSetPriority(hControl, newPriority); } + virtual bool AsyncSuspend() { return m_pFileSystemPassThru->AsyncSuspend(); } + virtual bool AsyncResume() { return m_pFileSystemPassThru->AsyncResume(); } + virtual const char *RelativePathToFullPath( const char *pFileName, const char *pPathID, char *pLocalPath, int localPathBufferSize, PathTypeFilter_t pathFilter = FILTER_NONE, PathTypeQuery_t *pPathType = NULL ) { return m_pFileSystemPassThru->RelativePathToFullPath( pFileName, pPathID, pLocalPath, localPathBufferSize, pathFilter, pPathType ); } + virtual int GetSearchPath( const char *pathID, bool bGetPackFiles, char *pPath, int nMaxLen ) { return m_pFileSystemPassThru->GetSearchPath( pathID, bGetPackFiles, pPath, nMaxLen ); } + + virtual FileHandle_t OpenEx( const char *pFileName, const char *pOptions, unsigned flags = 0, const char *pathID = 0, char **ppszResolvedFilename = NULL ) { return m_pFileSystemPassThru->OpenEx( pFileName, pOptions, flags, pathID, ppszResolvedFilename );} + virtual int ReadEx( void* pOutput, int destSize, int size, FileHandle_t file ) { return m_pFileSystemPassThru->ReadEx( pOutput, destSize, size, file ); } + virtual int ReadFileEx( const char *pFileName, const char *pPath, void **ppBuf, bool bNullTerminate, bool bOptimalAlloc, int nMaxBytes = 0, int nStartingByte = 0, FSAllocFunc_t pfnAlloc = NULL ) { return m_pFileSystemPassThru->ReadFileEx( pFileName, pPath, ppBuf, bNullTerminate, bOptimalAlloc, nMaxBytes, nStartingByte, pfnAlloc ); } + +#if defined( TRACK_BLOCKING_IO ) + virtual void EnableBlockingFileAccessTracking( bool state ) { m_pFileSystemPassThru->EnableBlockingFileAccessTracking( state ); } + virtual bool IsBlockingFileAccessEnabled() const { return m_pFileSystemPassThru->IsBlockingFileAccessEnabled(); } + + virtual IBlockingFileItemList *RetrieveBlockingFileAccessInfo() { return m_pFileSystemPassThru->RetrieveBlockingFileAccessInfo(); } +#endif + virtual void SetupPreloadData() {} + virtual void DiscardPreloadData() {} + + virtual void LoadCompiledKeyValues( KeyValuesPreloadType_t type, char const *archiveFile ) { m_pFileSystemPassThru->LoadCompiledKeyValues( type, archiveFile ); } + + // If the "PreloadedData" hasn't been purged, then this'll try and instance the KeyValues using the fast path of compiled keyvalues loaded during startup. + // Otherwise, it'll just fall through to the regular KeyValues loading routines + virtual KeyValues *LoadKeyValues( KeyValuesPreloadType_t type, char const *filename, char const *pPathID = 0 ) { return m_pFileSystemPassThru->LoadKeyValues( type, filename, pPathID ); } + virtual bool LoadKeyValues( KeyValues& head, KeyValuesPreloadType_t type, char const *filename, char const *pPathID = 0 ) { return m_pFileSystemPassThru->LoadKeyValues( head, type, filename, pPathID ); } + virtual bool ExtractRootKeyName( KeyValuesPreloadType_t type, char *outbuf, size_t bufsize, char const *filename, char const *pPathID = 0 ) { return m_pFileSystemPassThru->ExtractRootKeyName( type, outbuf, bufsize, filename, pPathID ); } + + virtual bool GetFileTypeForFullPath( char const *pFullPath, wchar_t *buf, size_t bufSizeInBytes ) { return m_pFileSystemPassThru->GetFileTypeForFullPath( pFullPath, buf, bufSizeInBytes ); } + + virtual bool GetOptimalIOConstraints( FileHandle_t hFile, unsigned *pOffsetAlign, unsigned *pSizeAlign, unsigned *pBufferAlign ) { return m_pFileSystemPassThru->GetOptimalIOConstraints( hFile, pOffsetAlign, pSizeAlign, pBufferAlign ); } + virtual void *AllocOptimalReadBuffer( FileHandle_t hFile, unsigned nSize, unsigned nOffset ) { return m_pFileSystemPassThru->AllocOptimalReadBuffer( hFile, nOffset, nSize ); } + virtual void FreeOptimalReadBuffer( void *p ) { m_pFileSystemPassThru->FreeOptimalReadBuffer( p ); } + + virtual void BeginMapAccess() { m_pFileSystemPassThru->BeginMapAccess(); } + virtual void EndMapAccess() { m_pFileSystemPassThru->EndMapAccess(); } + + virtual bool ReadToBuffer( FileHandle_t hFile, CUtlBuffer &buf, int nMaxBytes = 0, FSAllocFunc_t pfnAlloc = NULL ) { return m_pFileSystemPassThru->ReadToBuffer( hFile, buf, nMaxBytes, pfnAlloc ); } + virtual bool FullPathToRelativePathEx( const char *pFullPath, const char *pPathId, char *pRelative, int nMaxLen ) { return m_pFileSystemPassThru->FullPathToRelativePathEx( pFullPath, pPathId, pRelative, nMaxLen ); } + virtual int GetPathIndex( const FileNameHandle_t &handle ) { return m_pFileSystemPassThru->GetPathIndex( handle ); } + virtual long GetPathTime( const char *pPath, const char *pPathID ) { return m_pFileSystemPassThru->GetPathTime( pPath, pPathID ); } + + virtual DVDMode_t GetDVDMode() { return m_pFileSystemPassThru->GetDVDMode(); } + + virtual void EnableWhitelistFileTracking( bool bEnable, bool bCacheAllVPKHashes, bool bRecalculateAndCheckHashes ) + { m_pFileSystemPassThru->EnableWhitelistFileTracking( bEnable, bCacheAllVPKHashes, bRecalculateAndCheckHashes ); } + virtual void RegisterFileWhitelist( IPureServerWhitelist *pWhiteList, IFileList **ppFilesToReload ) OVERRIDE + { m_pFileSystemPassThru->RegisterFileWhitelist( pWhiteList, ppFilesToReload ); } + virtual void MarkAllCRCsUnverified() + { m_pFileSystemPassThru->MarkAllCRCsUnverified(); } + virtual void CacheFileCRCs( const char *pPathname, ECacheCRCType eType, IFileList *pFilter ) + { return m_pFileSystemPassThru->CacheFileCRCs( pPathname, eType, pFilter ); } + virtual EFileCRCStatus CheckCachedFileHash( const char *pPathID, const char *pRelativeFilename, int nFileFraction, FileHash_t *pFileHash ) + { return m_pFileSystemPassThru->CheckCachedFileHash( pPathID, pRelativeFilename, nFileFraction, pFileHash ); } + virtual int GetUnverifiedFileHashes( CUnverifiedFileHash *pFiles, int nMaxFiles ) + { return m_pFileSystemPassThru->GetUnverifiedFileHashes( pFiles, nMaxFiles ); } + virtual int GetWhitelistSpewFlags() + { return m_pFileSystemPassThru->GetWhitelistSpewFlags(); } + virtual void SetWhitelistSpewFlags( int spewFlags ) + { m_pFileSystemPassThru->SetWhitelistSpewFlags( spewFlags ); } + virtual void InstallDirtyDiskReportFunc( FSDirtyDiskReportFunc_t func ) { m_pFileSystemPassThru->InstallDirtyDiskReportFunc( func ); } + + virtual FileCacheHandle_t CreateFileCache() { return m_pFileSystemPassThru->CreateFileCache(); } + virtual void AddFilesToFileCache( FileCacheHandle_t cacheId, const char **ppFileNames, int nFileNames, const char *pPathID ) { m_pFileSystemPassThru->AddFilesToFileCache( cacheId, ppFileNames, nFileNames, pPathID ); } + virtual bool IsFileCacheFileLoaded( FileCacheHandle_t cacheId, const char *pFileName ) { return m_pFileSystemPassThru->IsFileCacheFileLoaded( cacheId, pFileName ); } + virtual bool IsFileCacheLoaded( FileCacheHandle_t cacheId ) { return m_pFileSystemPassThru->IsFileCacheLoaded( cacheId ); } + virtual void DestroyFileCache( FileCacheHandle_t cacheId ) { m_pFileSystemPassThru->DestroyFileCache( cacheId ); } + + virtual bool RegisterMemoryFile( CMemoryFileBacking *pFile, CMemoryFileBacking **ppExistingFileWithRef ) { return m_pFileSystemPassThru->RegisterMemoryFile( pFile, ppExistingFileWithRef ); } + virtual void UnregisterMemoryFile( CMemoryFileBacking *pFile ) { m_pFileSystemPassThru->UnregisterMemoryFile( pFile ); } + virtual void CacheAllVPKFileHashes( bool bCacheAllVPKHashes, bool bRecalculateAndCheckHashes ) + { return m_pFileSystemPassThru->CacheAllVPKFileHashes( bCacheAllVPKHashes, bRecalculateAndCheckHashes ); } + virtual bool CheckVPKFileHash( int PackFileID, int nPackFileNumber, int nFileFraction, MD5Value_t &md5Value ) + { return m_pFileSystemPassThru->CheckVPKFileHash( PackFileID, nPackFileNumber, nFileFraction, md5Value ); } + virtual void NotifyFileUnloaded( const char *pszFilename, const char *pPathId ) OVERRIDE + { m_pFileSystemPassThru->NotifyFileUnloaded( pszFilename, pPathId ); } + +protected: + IFileSystem *m_pFileSystemPassThru; +}; + + +// This is so people who change the filesystem interface are forced to add the passthru wrapper into CFileSystemPassThru, +// so they don't break VMPI. +inline void GiveMeACompileError() +{ + CFileSystemPassThru asdf; +} + + +#endif // FILESYSTEM_PASSTHRU_H diff --git a/sp/src/public/g15/ig15.h b/sp/src/public/g15/ig15.h new file mode 100644 index 00000000..51b77b70 --- /dev/null +++ b/sp/src/public/g15/ig15.h @@ -0,0 +1,60 @@ +//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======= +// +// Purpose: +// +//============================================================================= + +#ifndef IG15_H +#define IG15_H +#ifdef _WIN32 +#pragma once +#endif + +typedef void * G15_HANDLE; + +typedef enum +{ + G15_BUTTON_1, G15_BUTTON_2, G15_BUTTON_3, G15_BUTTON_4 +} G15SoftButton; + +typedef enum +{ + G15_SMALL, G15_MEDIUM, G15_BIG +} G15TextSize; + +typedef enum +{ + G15_SCROLLING_TEXT, G15_STATIC_TEXT, G15_ICON, G15_PROGRESS_BAR, G15_UNKNOWN +} G15ObjectType; + +class IG15 +{ +public: + virtual void GetLCDSize( int &w, int &h ) = 0; + + // w, h should match the return value from GetLCDSize!!! + + // Creates the underlying object + virtual bool Init( char const *name ) = 0; + // Destroys the underlying object + virtual void Shutdown() = 0; + + virtual bool IsConnected() = 0; + + // Add/remove + virtual G15_HANDLE AddText(G15ObjectType type, G15TextSize size, int alignment, int maxLengthPixels) = 0; + virtual G15_HANDLE AddIcon( void *icon, int sizeX, int sizeY) = 0; + virtual void RemoveAndDestroyObject( G15_HANDLE hObject ) = 0; + + // Change + virtual int SetText(G15_HANDLE handle, char const * text) = 0; + virtual int SetOrigin(G15_HANDLE handle, int x, int y) = 0; + virtual int SetVisible(G15_HANDLE handle, bool visible) = 0; + + virtual bool ButtonTriggered(int button) = 0; + virtual void UpdateLCD( unsigned int dwTimestamp) = 0; +}; + +#define G15_INTERFACE_VERSION "G15_INTERFACE_VERSION001" + +#endif // IG15_H diff --git a/sp/src/public/game/client/IGameClientExports.h b/sp/src/public/game/client/IGameClientExports.h new file mode 100644 index 00000000..2679b6ef --- /dev/null +++ b/sp/src/public/game/client/IGameClientExports.h @@ -0,0 +1,53 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef IGAMECLIENTEXPORTS_H +#define IGAMECLIENTEXPORTS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "interface.h" + +//----------------------------------------------------------------------------- +// Purpose: Exports a set of functions for the GameUI interface to interact with the game client +//----------------------------------------------------------------------------- +abstract_class IGameClientExports : public IBaseInterface +{ +public: +#ifndef _XBOX + // ingame voice manipulation + virtual bool IsPlayerGameVoiceMuted(int playerIndex) = 0; + virtual void MutePlayerGameVoice(int playerIndex) = 0; + virtual void UnmutePlayerGameVoice(int playerIndex) = 0; + + // notification of gameui state changes + virtual void OnGameUIActivated() = 0; + virtual void OnGameUIHidden() = 0; +#endif + + //============================================================================= + // HPE_BEGIN + // [dwenger] Necessary for stats display + //============================================================================= + + virtual void CreateAchievementsPanel( vgui::Panel* pParent ) = 0; + virtual void DisplayAchievementPanel( ) = 0; + virtual void ShutdownAchievementPanel( ) = 0; + virtual int GetAchievementsPanelMinWidth( void ) const = 0; + + //============================================================================= + // HPE_END + //============================================================================= + + virtual const char *GetHolidayString() = 0; +}; + +#define GAMECLIENTEXPORTS_INTERFACE_VERSION "GameClientExports001" + + +#endif // IGAMECLIENTEXPORTS_H diff --git a/sp/src/public/game/client/iclientrendertargets.h b/sp/src/public/game/client/iclientrendertargets.h new file mode 100644 index 00000000..60a14474 --- /dev/null +++ b/sp/src/public/game/client/iclientrendertargets.h @@ -0,0 +1,41 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Exposes interfaces to the engine which allow the client to setup their own render targets +// during the proper period of material system's init. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef ICLIENTRENDERTARGETS_H +#define ICLIENTRENDERTARGETS_H +#ifdef _WIN32 + #pragma once +#endif + +#include "interface.h" // For base interface + +class IMaterialSystem; +class IMaterialSystemHardwareConfig; + +//--------------------------------------------------------------------------------------------------- +// Purpose: Exposes interfaces to the engine which allow the client to setup their own render targets +// during the proper period of material system's init. +//--------------------------------------------------------------------------------------------------- +abstract_class IClientRenderTargets +{ +public: + // Pass the material system interface to the client-- Their Material System singleton has not been created + // at the time they receive this call. + virtual void InitClientRenderTargets( IMaterialSystem* pMaterialSystem, IMaterialSystemHardwareConfig* pHardwareConfig ) = 0; + + // Call shutdown on every created refrence-- Clients keep track of this themselves + // and should add shutdown code to this function whenever they add a new render target. + virtual void ShutdownClientRenderTargets( void ) = 0; + +}; + +#define CLIENTRENDERTARGETS_INTERFACE_VERSION "ClientRenderTargets001" + +extern IClientRenderTargets * g_pClientRenderTargets; + +#endif // ICLIENTRENDERTARGETS_H diff --git a/sp/src/public/game/client/iviewport.h b/sp/src/public/game/client/iviewport.h new file mode 100644 index 00000000..5e26f3a5 --- /dev/null +++ b/sp/src/public/game/client/iviewport.h @@ -0,0 +1,61 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// +#if !defined( IVIEWPORT_H ) +#define IVIEWPORT_H +#ifdef _WIN32 +#pragma once +#endif + +#include + +#include "viewport_panel_names.h" + +class KeyValues; + +abstract_class IViewPortPanel +{ + +public: + virtual ~IViewPortPanel() {}; + + virtual const char *GetName( void ) = 0;// return identifer name + virtual void SetData(KeyValues *data) = 0; // set ViewPortPanel data + virtual void Reset( void ) = 0; // clears internal state, deactivates it + virtual void Update( void ) = 0; // updates all (size, position, content, etc) + virtual bool NeedsUpdate( void ) = 0; // query panel if content needs to be updated + virtual bool HasInputElements( void ) = 0; // true if panel contains elments which accepts input + + virtual void ShowPanel( bool state ) = 0; // activate VGUI Frame + + // VGUI functions: + virtual vgui::VPANEL GetVPanel( void ) = 0; // returns VGUI panel handle + virtual bool IsVisible() = 0; // true if panel is visible + virtual void SetParent( vgui::VPANEL parent ) = 0; +}; + +abstract_class IViewPort +{ +public: + virtual void UpdateAllPanels( void ) = 0; + virtual void ShowPanel( const char *pName, bool state ) = 0; + virtual void ShowPanel( IViewPortPanel* pPanel, bool state ) = 0; + virtual void ShowBackGround(bool bShow) = 0; + virtual IViewPortPanel* FindPanelByName(const char *szPanelName) = 0; + virtual IViewPortPanel* GetActivePanel( void ) = 0; + virtual void PostMessageToPanel( const char *pName, KeyValues *pKeyValues ) = 0; +}; + +extern IViewPort *gViewPortInterface; + + +#endif // IVIEWPORT_H \ No newline at end of file diff --git a/sp/src/public/game/server/ientityinfo.h b/sp/src/public/game/server/ientityinfo.h new file mode 100644 index 00000000..04ab6b39 --- /dev/null +++ b/sp/src/public/game/server/ientityinfo.h @@ -0,0 +1,150 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: provides an interface for plugins to query information about entities from the game dll +// +//===============================================================================================// +#ifndef IENTITYINFO_H +#define IENTITYINFO_H +#ifdef _WIN32 +#pragma once +#endif + +#include "mathlib/vector.h" +#include "pluginvariant.h" + +abstract_class IEntityInfo +{ +public: + // returns true if entity is a player + virtual const int EntityIndex() = 0; + virtual const char *GetEntityName() = 0; + virtual const char *GetClassname() = 0; + virtual const char *GetModelName() = 0; +//TODO + virtual const char *GetTargetName() = 0; + virtual void SetModel(const char *modelName) = 0; + virtual bool IsPlayer() = 0; + virtual bool IsNPC() = 0; + virtual bool IsDead() = 0; + virtual bool IsAlive() = 0; + virtual bool IsInWorld() = 0; + virtual bool IsTemplate() = 0; + virtual int GetEFlags() = 0; + virtual void SetEFlags( int iEFlags ) = 0; + virtual void AddEFlags( int nEFlagMask ) = 0; + virtual bool IsEFlagSet( int EFlagMask ) = 0; + + virtual const int GetEffects( void ) = 0; + virtual void AddEffects( int nEffects ) = 0; + virtual void RemoveEffects( int nEffects ) = 0; + virtual void ClearEffects( void ) = 0; + virtual void SetEffects( int nEffects ) = 0; + virtual bool IsEffectActive( int nEffects ) = 0; + virtual int GetRenderMode() = 0; + virtual void SetRenderMode( int nRenderMode ) = 0; + + virtual void SetBlocksLOS( bool bBlocksLOS ) = 0; + virtual bool BlocksLOS( void ) = 0; + + virtual const int GetHealth() = 0; + virtual const int GetMaxHealth() = 0; + virtual void SetHealth( int iHealth ) = 0; + virtual void SetMaxHealth( int iMaxHealth ) = 0; + + // returns the team the entity is on + virtual int GetTeamIndex() = 0; + // changes the entity to a new team (if the game dll logic allows it) + virtual void ChangeTeam( int iTeamNum ) = 0; + + // positioning and sizes + virtual const Vector GetAbsOrigin() = 0; + virtual void SetAbsOrigin( Vector & vec ) = 0; + virtual const QAngle GetAbsAngles() = 0; + virtual void SetAbsAngles( QAngle & ang ) = 0; + virtual const Vector GetLocalOrigin() = 0; + virtual void SetLocalOrigin( const Vector& origin ) = 0; + virtual const QAngle GetLocalAngles() = 0; + virtual void SetLocalAngles( const QAngle& angles ) = 0; + virtual const Vector GetAbsVelocity() = 0; + virtual const Vector GetLocalVelocity() = 0; + virtual const QAngle GetLocalAngularVelocity() = 0; + virtual void EntityToWorldSpace( const Vector &in, Vector *pOut ) = 0; + virtual void WorldToEntitySpace( const Vector &in, Vector *pOut ) = 0; + virtual Vector EyePosition() = 0; + virtual QAngle EyeAngles() = 0; + virtual QAngle LocalEyeAngles() = 0; + virtual Vector EarPosition() = 0; + + // returns world aligned mins/maxs of this entity + virtual const Vector GetWorldMins() = 0; + virtual const Vector GetWorldMaxs() = 0; + virtual const Vector WorldSpaceCenter() = 0; + + virtual int GetWaterLevel() = 0; + + // if this entity has an owner, it returns their edict_t. + virtual edict_t *GetOwner() = 0; + virtual edict_t *GetParent() = 0; + virtual edict_t *GetMoveParent() = 0; + virtual edict_t *GetRootMoveParent() = 0; + + // if this entity is following another, returns that entities edict_t. + virtual edict_t *GetFollowedEntity() = 0; + virtual edict_t *GetGroundEntity() = 0; //returns the entity that this one is standing on - if set. + + // accessor to hook mod specific information about the entity. + virtual bool GetCustomInfo(int valueType, pluginvariant &outValue, pluginvariant options) = 0; + + // entity debugging stuff. + virtual const char *GetDebugName() = 0; + virtual void EntityText( int text_offset, const char *text, float flDuration, int r = 255, int g = 255, int b = 255, int a = 255 ) = 0; + + //Keyvalues + virtual bool GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen ) = 0; + + +}; + + +#define INTERFACEVERSION_ENTITYINFOMANAGER "EntityInfoManager001" +abstract_class IEntityInfoManager +{ +public: + virtual IEntityInfo *GetEntityInfo( edict_t *pEdict ) = 0; + virtual IEntityInfo *GetEntityInfo( int index ) = 0; //Retrieves the info + + //Experiment.. + virtual IServerUnknown *GetServerEntity( edict_t *pEdict ) = 0; + + //----------------------------------------------------------------------------- + // Purpose: Iterates the entities with a given classname. + // Input : pStartEntity - Last entity found, NULL to start a new iteration. + // szName - Classname to search for. + //----------------------------------------------------------------------------- + virtual edict_t *FindEntityByClassname( edict_t *pStartEntity, const char *szName ) = 0; + + //----------------------------------------------------------------------------- + // Purpose: Iterates the entities with a given name. + // Input : pStartEntity - Last entity found, NULL to start a new iteration. + // szName - Name to search for. + //----------------------------------------------------------------------------- + virtual edict_t *FindEntityByName( edict_t *pStartEntity, const char *szName ) = 0; + + //----------------------------------------------------------------------------- + // Purpose: Iterates the entities with a given model name. + // Input : pStartEntity - Last entity found, NULL to start a new iteration. + // szModelName - Model Name to search for. + //----------------------------------------------------------------------------- + virtual edict_t *FindEntityByModel( edict_t *pStartEntity, const char *szModelName ) = 0; + + //----------------------------------------------------------------------------- + // Purpose: Used to iterate all the entities within a sphere. + // Input : pStartEntity - + // vecCenter - + // flRadius - + //----------------------------------------------------------------------------- + virtual edict_t *FindEntityInSphere( edict_t *pStartEntity, const Vector &vecCenter, float flRadius ) = 0; + + virtual void GetWorldBounds( Vector &mins, Vector &maxs ) = 0; +}; +#endif // IENTITYINFO_H diff --git a/sp/src/public/game/server/igameinfo.h b/sp/src/public/game/server/igameinfo.h new file mode 100644 index 00000000..8218a1f9 --- /dev/null +++ b/sp/src/public/game/server/igameinfo.h @@ -0,0 +1,45 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: provides an interface for plugins to query information about the gamerules in a simple +// and organized mannor. +// +//===============================================================================================// +#ifndef IGAMEINFO_H +#define IGAMEINFO_H +#ifdef _WIN32 +#pragma once +#endif + +#include "mathlib/vector.h" +#include "pluginvariant.h" + +//Tony; prefixing everything in this so that i can make IGameInfo an extension of CGameRules and not stomp on anything, since gamerules isn't an entity. +abstract_class IGameInfo +{ +public: + // returns an enumerated id for the current game type + virtual const int GetInfo_GameType() = 0; + // returns a name associated with the gametype, if defined. + virtual const char *GetInfo_GameTypeName() = 0; + // returns the team name associated with the number + virtual const char *GetInfo_GetTeamName(int teamNumber) = 0; + // returns how many teams the game has (typically always 4; 0 = unassigned, 1 = spectator, 2 = team1, 3 = team2) + virtual const int GetInfo_GetTeamCount() = 0; + // returns how many players are on a given team + virtual const int GetInfo_NumPlayersOnTeam(int teamNumber) = 0; + + // accessor to hook mod specific information about the rules. for TF2, fields such as + virtual bool GetInfo_Custom(int valueType, pluginvariant &outValue, pluginvariant options) = 0; + +}; + + +//Interface is very simple, there's not much really needed for the manager, this stuff is just in it's own interface so it's not mixed up with the entity +//or player managers. +#define INTERFACEVERSION_GAMEINFOMANAGER "GameInfoManager001" +abstract_class IGameInfoManager +{ +public: + virtual IGameInfo *GetGameInfo() = 0; +}; +#endif // IGAMEINFO_H diff --git a/sp/src/public/game/server/iplayerinfo.h b/sp/src/public/game/server/iplayerinfo.h new file mode 100644 index 00000000..630abe9e --- /dev/null +++ b/sp/src/public/game/server/iplayerinfo.h @@ -0,0 +1,195 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: provides an interface for dlls to query information about players from the game dll +// +//=============================================================================// +#ifndef IPLAYERINFO_H +#define IPLAYERINFO_H +#ifdef _WIN32 +#pragma once +#endif + +#include "mathlib/vector.h" + +// helper class for user commands +class CBotCmd +{ +public: + CBotCmd() + { + Reset(); + } + + virtual ~CBotCmd() { }; + + void Reset() + { + command_number = 0; + tick_count = 0; + viewangles.Init(); + forwardmove = 0.0f; + sidemove = 0.0f; + upmove = 0.0f; + buttons = 0; + impulse = 0; + weaponselect = 0; + weaponsubtype = 0; + random_seed = 0; + mousedx = 0; + mousedy = 0; + + hasbeenpredicted = false; + } + + CBotCmd& operator =( const CBotCmd& src ) + { + if ( this == &src ) + return *this; + + command_number = src.command_number; + tick_count = src.tick_count; + viewangles = src.viewangles; + forwardmove = src.forwardmove; + sidemove = src.sidemove; + upmove = src.upmove; + buttons = src.buttons; + impulse = src.impulse; + weaponselect = src.weaponselect; + weaponsubtype = src.weaponsubtype; + random_seed = src.random_seed; + mousedx = src.mousedx; + mousedy = src.mousedy; + hasbeenpredicted = src.hasbeenpredicted; + return *this; + } + + // For matching server and client commands for debugging + int command_number; + + // the tick the client created this command + int tick_count; + + // Player instantaneous view angles. + QAngle viewangles; + // Intended velocities + // forward velocity. + float forwardmove; + // sideways velocity. + float sidemove; + // upward velocity. + float upmove; + // Attack button states + int buttons; + // Impulse command issued. + byte impulse; + // Current weapon id + int weaponselect; + int weaponsubtype; + + int random_seed; // For shared random functions + + short mousedx; // mouse accum in x from create move + short mousedy; // mouse accum in y from create move + + // Client only, tracks whether we've predicted this command at least once + bool hasbeenpredicted; +}; + + + + +abstract_class IPlayerInfo +{ +public: + // returns the players name (UTF-8 encoded) + virtual const char *GetName() = 0; + // returns the userid (slot number) + virtual int GetUserID() = 0; + // returns the string of their network (i.e Steam) ID + virtual const char *GetNetworkIDString() = 0; + // returns the team the player is on + virtual int GetTeamIndex() = 0; + // changes the player to a new team (if the game dll logic allows it) + virtual void ChangeTeam( int iTeamNum ) = 0; + // returns the number of kills this player has (exact meaning is mod dependent) + virtual int GetFragCount() = 0; + // returns the number of deaths this player has (exact meaning is mod dependent) + virtual int GetDeathCount() = 0; + // returns if this player slot is actually valid + virtual bool IsConnected() = 0; + // returns the armor/health of the player (exact meaning is mod dependent) + virtual int GetArmorValue() = 0; + + // extensions added to V2 + + // various player flags + virtual bool IsHLTV() = 0; + virtual bool IsPlayer() = 0; + virtual bool IsFakeClient() = 0; + virtual bool IsDead() = 0; + virtual bool IsInAVehicle() = 0; + virtual bool IsObserver() = 0; + + // player position and size + virtual const Vector GetAbsOrigin() = 0; + virtual const QAngle GetAbsAngles() = 0; + virtual const Vector GetPlayerMins() = 0; + virtual const Vector GetPlayerMaxs() = 0; + // the name of the weapon currently being carried + virtual const char *GetWeaponName() = 0; + // the name of the player model in use + virtual const char *GetModelName() = 0; + // current player health + virtual const int GetHealth() = 0; + // max health value + virtual const int GetMaxHealth() = 0; + // the last user input from this player + virtual CBotCmd GetLastUserCommand() = 0; + + virtual bool IsReplay() = 0; +}; + + +#define INTERFACEVERSION_PLAYERINFOMANAGER "PlayerInfoManager002" +abstract_class IPlayerInfoManager +{ +public: + virtual IPlayerInfo *GetPlayerInfo( edict_t *pEdict ) = 0; + virtual CGlobalVars *GetGlobalVars() = 0; +}; + + + + +abstract_class IBotController +{ +public: + // change the bots position + virtual void SetAbsOrigin( Vector & vec ) = 0; + virtual void SetAbsAngles( QAngle & ang ) = 0; + virtual void SetLocalOrigin( const Vector& origin ) = 0; + virtual const Vector GetLocalOrigin( void ) = 0; + virtual void SetLocalAngles( const QAngle& angles ) = 0; + virtual const QAngle GetLocalAngles( void ) = 0; + + // strip them of weapons, etc + virtual void RemoveAllItems( bool removeSuit ) = 0; + // give them a weapon + virtual void SetActiveWeapon( const char *WeaponName ) = 0; + // check various effect flags + virtual bool IsEFlagSet( int nEFlagMask ) = 0; + // fire a virtual move command to the bot + virtual void RunPlayerMove( CBotCmd *ucmd ) = 0; +}; + + +#define INTERFACEVERSION_PLAYERBOTMANAGER "BotManager001" +abstract_class IBotManager +{ +public: + virtual IBotController *GetBotController( edict_t *pEdict ) = 0; + // create a new bot and spawn it into the server + virtual edict_t *CreateBot( const char *botname ) = 0; +}; + +#endif // IPLAYERINFO_H diff --git a/sp/src/public/game/server/pluginvariant.h b/sp/src/public/game/server/pluginvariant.h new file mode 100644 index 00000000..b4a798c7 --- /dev/null +++ b/sp/src/public/game/server/pluginvariant.h @@ -0,0 +1,165 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef PLUGINVARIANT_H +#define PLUGINVARIANT_H +#ifdef _WIN32 +#pragma once +#endif + +#include "stdstring.h" +#include "mathlib/vmatrix.h" + +/* +//Tony; including stdstring at this point (which I need) messes up the offsetof override in linux, so I need to reset it here. +#if defined( POSIX ) +#undef offsetof +#define offsetof(s,m) (size_t)&(((s *)0)->m) +#endif + */ +// +// A modified variant class for that functions almost identically to variant_t, for plugins to pass data back and forth. +// +class pluginvariant +{ + union + { + bool bVal; + int iVal; + float flVal; + float vecVal[3]; + color32 rgbaVal; + }; + //Tony; neither of these can be in the union because of constructors. + edict_t *eVal; + char iszVal[1024]; + + fieldtype_t fieldType; + +public: + + // constructor + pluginvariant() : fieldType(FIELD_VOID), iVal(0) {} + + inline bool Bool( void ) const { return( fieldType == FIELD_BOOLEAN ) ? bVal : false; } + inline const char *String( void ) const { return( ToString() ); } + inline int Int( void ) const { return( fieldType == FIELD_INTEGER ) ? iVal : 0; } + inline float Float( void ) const { return( fieldType == FIELD_FLOAT ) ? flVal : 0; } + inline const edict_t *Edict(void) const; + inline color32 Color32(void) const { return rgbaVal; } + inline void Vector3D(Vector &vec) const; + + fieldtype_t FieldType( void ) { return fieldType; } + + void SetBool( bool b ) { bVal = b; fieldType = FIELD_BOOLEAN; } + void SetString( char *str ) { Q_snprintf(iszVal, 1024, "%s", str); fieldType = FIELD_STRING; } + void SetInt( int val ) { iVal = val, fieldType = FIELD_INTEGER; } + void SetFloat( float val ) { flVal = val, fieldType = FIELD_FLOAT; } + void SetEdict( edict_t *val ) { eVal = val; fieldType = FIELD_EHANDLE; } + void SetVector3D( const Vector &val ) { vecVal[0] = val[0]; vecVal[1] = val[1]; vecVal[2] = val[2]; fieldType = FIELD_VECTOR; } + void SetPositionVector3D( const Vector &val ) { vecVal[0] = val[0]; vecVal[1] = val[1]; vecVal[2] = val[2]; fieldType = FIELD_POSITION_VECTOR; } + void SetColor32( color32 val ) { rgbaVal = val; fieldType = FIELD_COLOR32; } + void SetColor32( int r, int g, int b, int a ) { rgbaVal.r = r; rgbaVal.g = g; rgbaVal.b = b; rgbaVal.a = a; fieldType = FIELD_COLOR32; } + +protected: + + // + // Returns a string representation of the value without modifying the variant. + // + const char *ToString( void ) const + { + static char szBuf[512]; + + switch (fieldType) + { + case FIELD_STRING: + { + return (const char *)iszVal; + } + + case FIELD_BOOLEAN: + { + if (bVal == 0) + { + Q_strncpy(szBuf, "false",sizeof(szBuf)); + } + else + { + Q_strncpy(szBuf, "true",sizeof(szBuf)); + } + return(szBuf); + } + + case FIELD_INTEGER: + { + Q_snprintf( szBuf, sizeof( szBuf ), "%i", iVal ); + return(szBuf); + } + + case FIELD_FLOAT: + { + Q_snprintf(szBuf,sizeof(szBuf), "%g", flVal); + return(szBuf); + } + + case FIELD_COLOR32: + { + Q_snprintf(szBuf,sizeof(szBuf), "%d %d %d %d", (int)rgbaVal.r, (int)rgbaVal.g, (int)rgbaVal.b, (int)rgbaVal.a); + return(szBuf); + } + + case FIELD_VECTOR: + { + Q_snprintf(szBuf,sizeof(szBuf), "[%g %g %g]", (double)vecVal[0], (double)vecVal[1], (double)vecVal[2]); + return(szBuf); + } + + case FIELD_VOID: + { + szBuf[0] = '\0'; + return(szBuf); + } + } + + return("No conversion to string"); + } +}; + + +////////////////////////// pluginvariant implementation ////////////////////////// + + +//----------------------------------------------------------------------------- +// Purpose: Returns this variant as a vector. +//----------------------------------------------------------------------------- +inline void pluginvariant::Vector3D(Vector &vec) const +{ + if (( fieldType == FIELD_VECTOR ) || ( fieldType == FIELD_POSITION_VECTOR )) + { + vec[0] = vecVal[0]; + vec[1] = vecVal[1]; + vec[2] = vecVal[2]; + } + else + { + vec = vec3_origin; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Returns this variant as an edict_t +//----------------------------------------------------------------------------- +inline const edict_t *pluginvariant::Edict(void) const +{ + if ( fieldType == FIELD_EHANDLE ) + return eVal; + + return NULL; +} + + +#endif // pluginvariant_H diff --git a/sp/src/public/gamebspfile.h b/sp/src/public/gamebspfile.h new file mode 100644 index 00000000..f8029bae --- /dev/null +++ b/sp/src/public/gamebspfile.h @@ -0,0 +1,220 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Defines game-specific data +// +// $Revision: $ +// $NoKeywords: $ +//=============================================================================// + +#ifndef GAMEBSPFILE_H +#define GAMEBSPFILE_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "mathlib/vector.h" +#include "basetypes.h" + + +//----------------------------------------------------------------------------- +// This enumerations defines all the four-CC codes for the client lump names +//----------------------------------------------------------------------------- +// TODO: We may have some endian considerations here! +#define GAMELUMP_MAKE_CODE(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d) << 0) +enum +{ + GAMELUMP_DETAIL_PROPS = GAMELUMP_MAKE_CODE('d', 'p', 'r', 'p'), + GAMELUMP_DETAIL_PROP_LIGHTING = GAMELUMP_MAKE_CODE('d', 'p', 'l', 't'), + GAMELUMP_STATIC_PROPS = GAMELUMP_MAKE_CODE('s', 'p', 'r', 'p'), + GAMELUMP_DETAIL_PROP_LIGHTING_HDR = GAMELUMP_MAKE_CODE('d', 'p', 'l', 'h'), +}; + +// Versions... +enum +{ + GAMELUMP_DETAIL_PROPS_VERSION = 4, + GAMELUMP_DETAIL_PROP_LIGHTING_VERSION = 0, + GAMELUMP_STATIC_PROPS_VERSION = 6, + GAMELUMP_STATIC_PROP_LIGHTING_VERSION = 0, + GAMELUMP_DETAIL_PROP_LIGHTING_HDR_VERSION = 0, +}; + + +//----------------------------------------------------------------------------- +// This is the data associated with the GAMELUMP_DETAIL_PROPS lump +//----------------------------------------------------------------------------- +#define DETAIL_NAME_LENGTH 128 + +enum DetailPropOrientation_t +{ + DETAIL_PROP_ORIENT_NORMAL = 0, + DETAIL_PROP_ORIENT_SCREEN_ALIGNED, + DETAIL_PROP_ORIENT_SCREEN_ALIGNED_VERTICAL, +}; + +// NOTE: If DetailPropType_t enum changes, change CDetailModel::QuadsToDraw +// in detailobjectsystem.cpp +enum DetailPropType_t +{ + DETAIL_PROP_TYPE_MODEL = 0, + DETAIL_PROP_TYPE_SPRITE, + DETAIL_PROP_TYPE_SHAPE_CROSS, + DETAIL_PROP_TYPE_SHAPE_TRI, +}; + +//----------------------------------------------------------------------------- +// Model index when using studiomdls for detail props +//----------------------------------------------------------------------------- +struct DetailObjectDictLump_t +{ + DECLARE_BYTESWAP_DATADESC(); + char m_Name[DETAIL_NAME_LENGTH]; // model name +}; + +//----------------------------------------------------------------------------- +// Information about the sprite to render +//----------------------------------------------------------------------------- +struct DetailSpriteDictLump_t +{ + DECLARE_BYTESWAP_DATADESC(); + // NOTE: All detail prop sprites must lie in the material detail/detailsprites + Vector2D m_UL; // Coordinate of upper left + Vector2D m_LR; // Coordinate of lower right + Vector2D m_TexUL; // Texcoords of upper left + Vector2D m_TexLR; // Texcoords of lower left +}; + +struct DetailObjectLump_t +{ + DECLARE_BYTESWAP_DATADESC(); + Vector m_Origin; + QAngle m_Angles; + unsigned short m_DetailModel; // either index into DetailObjectDictLump_t or DetailPropSpriteLump_t + unsigned short m_Leaf; + ColorRGBExp32 m_Lighting; + unsigned int m_LightStyles; + unsigned char m_LightStyleCount; + unsigned char m_SwayAmount; // how much do the details sway + unsigned char m_ShapeAngle; // angle param for shaped sprites + unsigned char m_ShapeSize; // size param for shaped sprites + unsigned char m_Orientation; // See DetailPropOrientation_t + unsigned char m_Padding2[3]; // FIXME: Remove when we rev the detail lump again.. + unsigned char m_Type; // See DetailPropType_t + unsigned char m_Padding3[3]; // FIXME: Remove when we rev the detail lump again.. + float m_flScale; // For sprites only currently +}; + +//----------------------------------------------------------------------------- +// This is the data associated with the GAMELUMP_DETAIL_PROP_LIGHTING lump +//----------------------------------------------------------------------------- +struct DetailPropLightstylesLump_t +{ + DECLARE_BYTESWAP_DATADESC(); + ColorRGBExp32 m_Lighting; + unsigned char m_Style; +}; + +//----------------------------------------------------------------------------- +// This is the data associated with the GAMELUMP_STATIC_PROPS lump +//----------------------------------------------------------------------------- +enum +{ + STATIC_PROP_NAME_LENGTH = 128, + + // Flags field + // These are automatically computed + STATIC_PROP_FLAG_FADES = 0x1, + STATIC_PROP_USE_LIGHTING_ORIGIN = 0x2, + STATIC_PROP_NO_DRAW = 0x4, // computed at run time based on dx level + + // These are set in WC + STATIC_PROP_IGNORE_NORMALS = 0x8, + STATIC_PROP_NO_SHADOW = 0x10, + STATIC_PROP_SCREEN_SPACE_FADE = 0x20, + + STATIC_PROP_NO_PER_VERTEX_LIGHTING = 0x40, // in vrad, compute lighting at + // lighting origin, not for each vertex + + STATIC_PROP_NO_SELF_SHADOWING = 0x80, // disable self shadowing in vrad + + STATIC_PROP_WC_MASK = 0xd8, // all flags settable in hammer (?) +}; + +struct StaticPropDictLump_t +{ + DECLARE_BYTESWAP_DATADESC(); + char m_Name[STATIC_PROP_NAME_LENGTH]; // model name +}; + +struct StaticPropLumpV4_t +{ + DECLARE_BYTESWAP_DATADESC(); + Vector m_Origin; + QAngle m_Angles; + unsigned short m_PropType; + unsigned short m_FirstLeaf; + unsigned short m_LeafCount; + unsigned char m_Solid; + unsigned char m_Flags; + int m_Skin; + float m_FadeMinDist; + float m_FadeMaxDist; + Vector m_LightingOrigin; +// int m_Lighting; // index into the GAMELUMP_STATIC_PROP_LIGHTING lump +}; + +struct StaticPropLumpV5_t +{ + DECLARE_BYTESWAP_DATADESC(); + Vector m_Origin; + QAngle m_Angles; + unsigned short m_PropType; + unsigned short m_FirstLeaf; + unsigned short m_LeafCount; + unsigned char m_Solid; + unsigned char m_Flags; + int m_Skin; + float m_FadeMinDist; + float m_FadeMaxDist; + Vector m_LightingOrigin; + float m_flForcedFadeScale; +// int m_Lighting; // index into the GAMELUMP_STATIC_PROP_LIGHTING lump +}; + +struct StaticPropLump_t +{ + DECLARE_BYTESWAP_DATADESC(); + Vector m_Origin; + QAngle m_Angles; + unsigned short m_PropType; + unsigned short m_FirstLeaf; + unsigned short m_LeafCount; + unsigned char m_Solid; + unsigned char m_Flags; + int m_Skin; + float m_FadeMinDist; + float m_FadeMaxDist; + Vector m_LightingOrigin; + float m_flForcedFadeScale; + unsigned short m_nMinDXLevel; + unsigned short m_nMaxDXLevel; + // int m_Lighting; // index into the GAMELUMP_STATIC_PROP_LIGHTING lump +}; + +struct StaticPropLeafLump_t +{ + DECLARE_BYTESWAP_DATADESC(); + unsigned short m_Leaf; +}; + +//----------------------------------------------------------------------------- +// This is the data associated with the GAMELUMP_STATIC_PROP_LIGHTING lump +//----------------------------------------------------------------------------- +struct StaticPropLightstylesLump_t +{ + ColorRGBExp32 m_Lighting; +}; + +#endif // GAMEBSPFILE_H diff --git a/sp/src/public/gametrace.h b/sp/src/public/gametrace.h new file mode 100644 index 00000000..7fe40005 --- /dev/null +++ b/sp/src/public/gametrace.h @@ -0,0 +1,176 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef GAMETRACE_H +#define GAMETRACE_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "cmodel.h" +#include "utlvector.h" +#include "ihandleentity.h" +#include "ispatialpartition.h" + +#if defined( CLIENT_DLL ) + class C_BaseEntity; +#else + class CBaseEntity; +#endif + + +//----------------------------------------------------------------------------- +// Purpose: A trace is returned when a box is swept through the world +// NOTE: eventually more of this class should be moved up into the base class!! +//----------------------------------------------------------------------------- +class CGameTrace : public CBaseTrace +{ +public: + + // Returns true if hEnt points at the world entity. + // If this returns true, then you can't use GetHitBoxIndex(). + bool DidHitWorld() const; + + // Returns true if we hit something and it wasn't the world. + bool DidHitNonWorldEntity() const; + + // Gets the entity's network index if the trace has hit an entity. + // If not, returns -1. + int GetEntityIndex() const; + + // Returns true if there was any kind of impact at all + bool DidHit() const; + + // The engine doesn't know what a CBaseEntity is, so it has a backdoor to + // let it get at the edict. +#if defined( ENGINE_DLL ) + void SetEdict( edict_t *pEdict ); + edict_t* GetEdict() const; +#endif + + +public: + + float fractionleftsolid; // time we left a solid, only valid if we started in solid + csurface_t surface; // surface hit (impact surface) + + int hitgroup; // 0 == generic, non-zero is specific body part + short physicsbone; // physics bone hit by trace in studio + +#if defined( CLIENT_DLL ) + C_BaseEntity *m_pEnt; +#else + CBaseEntity *m_pEnt; +#endif + + // NOTE: this member is overloaded. + // If hEnt points at the world entity, then this is the static prop index. + // Otherwise, this is the hitbox index. + int hitbox; // box hit by trace in studio + + CGameTrace() {} + +private: + // No copy constructors allowed + CGameTrace(const CGameTrace& vOther); +}; + + +//----------------------------------------------------------------------------- +// Returns true if there was any kind of impact at all +//----------------------------------------------------------------------------- +inline bool CGameTrace::DidHit() const +{ + return fraction < 1 || allsolid || startsolid; +} + + +typedef CGameTrace trace_t; + +//============================================================================= + +#define TLD_DEF_LEAF_MAX 256 +#define TLD_DEF_ENTITY_MAX 1024 + +class CTraceListData : public IPartitionEnumerator +{ +public: + + CTraceListData( int nLeafMax = TLD_DEF_LEAF_MAX, int nEntityMax = TLD_DEF_ENTITY_MAX ) + { + MEM_ALLOC_CREDIT(); + m_nLeafCount = 0; + m_aLeafList.SetSize( nLeafMax ); + + m_nEntityCount = 0; + m_aEntityList.SetSize( nEntityMax ); + } + + ~CTraceListData() + { + m_nLeafCount = 0; + m_aLeafList.RemoveAll(); + + m_nEntityCount = 0; + m_aEntityList.RemoveAll(); + } + + void Reset( void ) + { + m_nLeafCount = 0; + m_nEntityCount = 0; + } + + bool IsEmpty( void ) const { return ( m_nLeafCount == 0 && m_nEntityCount == 0 ); } + + int LeafCount( void ) const { return m_nLeafCount; } + int LeafCountMax( void ) const { return m_aLeafList.Count(); } + void LeafCountReset( void ) { m_nLeafCount = 0; } + + int EntityCount( void ) const { return m_nEntityCount; } + int EntityCountMax( void ) const { return m_aEntityList.Count(); } + void EntityCountReset( void ) { m_nEntityCount = 0; } + + // For leaves... + void AddLeaf( int iLeaf ) + { + if ( m_nLeafCount >= m_aLeafList.Count() ) + { + DevMsg( "CTraceListData: Max leaf count along ray exceeded!\n" ); + m_aLeafList.AddMultipleToTail( m_aLeafList.Count() ); + } + + m_aLeafList[m_nLeafCount] = iLeaf; + m_nLeafCount++; + } + + // For entities... + IterationRetval_t EnumElement( IHandleEntity *pHandleEntity ) + { + if ( m_nEntityCount >= m_aEntityList.Count() ) + { + DevMsg( "CTraceListData: Max entity count along ray exceeded!\n" ); + m_aEntityList.AddMultipleToTail( m_aEntityList.Count() ); + } + + m_aEntityList[m_nEntityCount] = pHandleEntity; + m_nEntityCount++; + + return ITERATION_CONTINUE; + } + +public: + + int m_nLeafCount; + CUtlVector m_aLeafList; + + int m_nEntityCount; + CUtlVector m_aEntityList; +}; + +#endif // GAMETRACE_H + diff --git a/sp/src/public/globalvars_base.h b/sp/src/public/globalvars_base.h new file mode 100644 index 00000000..7ba96cb2 --- /dev/null +++ b/sp/src/public/globalvars_base.h @@ -0,0 +1,109 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef GLOBALVARS_BASE_H +#define GLOBALVARS_BASE_H + +#ifdef _WIN32 +#pragma once +#endif + +class CSaveRestoreData; + +//----------------------------------------------------------------------------- +// Purpose: Global variables used by shared code +//----------------------------------------------------------------------------- +class CGlobalVarsBase +{ +public: + + CGlobalVarsBase( bool bIsClient ); + + // This can be used to filter debug output or to catch the client or server in the act. + bool IsClient() const; + + // for encoding m_flSimulationTime, m_flAnimTime + int GetNetworkBase( int nTick, int nEntity ); + +public: + + // Absolute time (per frame still - Use Plat_FloatTime() for a high precision real time + // perf clock, but not that it doesn't obey host_timescale/host_framerate) + float realtime; + // Absolute frame counter + int framecount; + // Non-paused frametime + float absoluteframetime; + + // Current time + // + // On the client, this (along with tickcount) takes a different meaning based on what + // piece of code you're in: + // + // - While receiving network packets (like in PreDataUpdate/PostDataUpdate and proxies), + // this is set to the SERVER TICKCOUNT for that packet. There is no interval between + // the server ticks. + // [server_current_Tick * tick_interval] + // + // - While rendering, this is the exact client clock + // [client_current_tick * tick_interval + interpolation_amount] + // + // - During prediction, this is based on the client's current tick: + // [client_current_tick * tick_interval] + float curtime; + + // Time spent on last server or client frame (has nothing to do with think intervals) + float frametime; + // current maxplayers setting + int maxClients; + + // Simulation ticks + int tickcount; + + // Simulation tick interval + float interval_per_tick; + + // interpolation amount ( client-only ) based on fraction of next tick which has elapsed + float interpolation_amount; + int simTicksThisFrame; + + int network_protocol; + + // current saverestore data + CSaveRestoreData *pSaveData; + +private: + // Set to true in client code. + bool m_bClient; + + // 100 (i.e., tickcount is rounded down to this base and then the "delta" from this base is networked + int nTimestampNetworkingBase; + // 32 (entindex() % nTimestampRandomizeWindow ) is subtracted from gpGlobals->tickcount to set the networking basis, prevents + // all of the entities from forcing a new PackedEntity on the same tick (i.e., prevents them from getting lockstepped on this) + int nTimestampRandomizeWindow; + +}; + +inline int CGlobalVarsBase::GetNetworkBase( int nTick, int nEntity ) +{ + int nEntityMod = nEntity % nTimestampRandomizeWindow; + int nBaseTick = nTimestampNetworkingBase * (int)( ( nTick - nEntityMod ) / nTimestampNetworkingBase ); + return nBaseTick; +} + +inline CGlobalVarsBase::CGlobalVarsBase( bool bIsClient ) : + m_bClient( bIsClient ), + nTimestampNetworkingBase( 100 ), + nTimestampRandomizeWindow( 32 ) +{ +} + +inline bool CGlobalVarsBase::IsClient() const +{ + return m_bClient; +} + +#endif // GLOBALVARS_BASE_H diff --git a/sp/src/public/haptics/haptic_msgs.cpp b/sp/src/public/haptics/haptic_msgs.cpp new file mode 100644 index 00000000..57b4bed2 --- /dev/null +++ b/sp/src/public/haptics/haptic_msgs.cpp @@ -0,0 +1,192 @@ +#include "cbase.h" + +#ifdef CLIENT_DLL + #include "tier3/tier3.h" + #include "iviewrender.h" + #include "inputsystem/iinputsystem.h" + #include "vgui/IInputInternal.h" + #include "c_basecombatweapon.h" + #include "c_baseplayer.h" + #include "hud_macros.h" + #include "iclientvehicle.h" + #include "c_prop_vehicle.h" + #include "prediction.h" + #include "activitylist.h" +#ifdef TERROR + #include "ClientTerrorPlayer.h" +#endif +extern vgui::IInputInternal *g_InputInternal; +#else + #include "usermessages.h" +#endif + +#include "haptics/haptic_msgs.h" + +void RegisterHapticMessages(void) +{ + usermessages->Register( "SPHapWeapEvent", 4 ); + usermessages->Register( "HapDmg", -1 ); + usermessages->Register( "HapPunch", -1 ); + usermessages->Register( "HapSetDrag", -1 ); + usermessages->Register( "HapSetConst", -1 ); + usermessages->Register( "HapMeleeContact", 0); +} + +//----------------------------------------------------------------------------- +// Server +//----------------------------------------------------------------------------- +#ifndef CLIENT_DLL + +void HapticMsg_SendWeaponAnim( CBasePlayer *pPlayer, int iActivity ) +{ + //Send the haptics message + CSingleUserRecipientFilter user( pPlayer ); + user.MakeReliable(); + UserMessageBegin( user, "SPHapWeapEvent" ); + WRITE_LONG(iActivity); + MessageEnd(); +} + +void HapticMsg_SetDrag(CBasePlayer* pPlayer, float drag) +{ + CSingleUserRecipientFilter user( pPlayer ); + user.MakeReliable(); + UserMessageBegin( user, "HapSetDrag" ); + WRITE_FLOAT(drag); + MessageEnd(); +} + +void HapticMsg_SetConstantForce(CBasePlayer* pPlayer, Vector force) +{ + // portal does not network this. + CSingleUserRecipientFilter user( pPlayer ); + user.MakeReliable(); + UserMessageBegin( user, "HapSetConst" ); + WRITE_SHORT(force.x); + WRITE_SHORT(force.y); + WRITE_SHORT(force.z); + MessageEnd(); +} + +void HapticMsg_HapDmg(CBasePlayer* pPlayer, float pitch, float yaw, float dmg, float dmgType ) +{ + CSingleUserRecipientFilter user(pPlayer); + user.MakeReliable(); + UserMessageBegin(user,"HapDmg"); + + WRITE_FLOAT(pitch); + WRITE_FLOAT(yaw); + WRITE_FLOAT(dmg); + WRITE_LONG(dmgType); + MessageEnd(); +} + +void HapticMsg_Punch(CBasePlayer* pPlayer, float x, float y, float z) +{ + CSingleUserRecipientFilter user(pPlayer); + user.MakeReliable(); + UserMessageBegin(user,"HapPunch"); + + WRITE_FLOAT(x); + WRITE_FLOAT(y); + WRITE_FLOAT(z); + MessageEnd(); +} + +void HapticMsg_MeleeContact(CBasePlayer* pPlayer) +{ + CSingleUserRecipientFilter user(pPlayer); + user.MakeReliable(); + UserMessageBegin(user,"HapMeleeContact"); + MessageEnd(); +} + +#endif //!CLIENT_DLL + +//----------------------------------------------------------------------------- +// Client +//----------------------------------------------------------------------------- +#ifdef CLIENT_DLL +void HookHapticMessages(void) +{ + HOOK_MESSAGE(SPHapWeapEvent); + HOOK_MESSAGE(HapDmg); + HOOK_MESSAGE(HapPunch); + HOOK_MESSAGE(HapSetDrag); + HOOK_MESSAGE(HapSetConst); + HOOK_MESSAGE(HapMeleeContact); + +} + +// Defined in haptics_utils +#ifdef WIN32 +void HapticsHandleMsg_HapSetDrag( float drag ); +void HapticsHandleMsg_HapSetConst( Vector const &constant ); +void HapticsHandleMsg_SPHapWeapEvent( int iActivity ); +void HapticsHandleMsg_HapPunch( QAngle const &angle ); +void HapticsHandleMsg_HapDmg( float pitch, float yaw, float damage, int damageType ); +void HapticsHandleMsg_HapMeleeContact(); +#endif // WIN32 + +void __MsgFunc_HapSetDrag( bf_read &msg ) +{ +#ifdef WIN32 + float drag = msg.ReadFloat(); + HapticsHandleMsg_HapSetDrag( drag ); +#endif // WIN32 +} + +//Might be able to handle this better... +void __MsgFunc_HapSetConst( bf_read &msg ) +{ +#ifdef WIN32 + Vector constant; + constant.x = msg.ReadShort(); + constant.y = msg.ReadShort(); + constant.z = msg.ReadShort(); + + HapticsHandleMsg_HapSetConst( constant ); +#endif // WIN32 +} + +void __MsgFunc_SPHapWeapEvent( bf_read &msg ) +{ +#ifdef WIN32 + int iActivity = msg.ReadLong(); + + HapticsHandleMsg_SPHapWeapEvent( iActivity ); +#endif // WIN32 +} + +void __MsgFunc_HapPunch( bf_read &msg ) +{ +#ifdef WIN32 + float x = msg.ReadFloat(); + float y = msg.ReadFloat(); + float z = msg.ReadFloat(); + + HapticsHandleMsg_HapPunch( QAngle(x,y,z) ); +#endif // WIN32 +} + +void __MsgFunc_HapDmg( bf_read &msg ) +{ +#ifdef WIN32 + float pitch = msg.ReadFloat(); + float yaw = msg.ReadFloat(); + float damage = msg.ReadFloat(); + int damageType = msg.ReadLong(); + + HapticsHandleMsg_HapDmg( pitch, yaw, damage, damageType ); +#endif // WIN32 +} + +void __MsgFunc_HapMeleeContact( bf_read &msg ) +{ +#ifdef WIN32 + HapticsHandleMsg_HapMeleeContact(); +#endif // WIN32 +} +#endif // CLIENT_DLL + + diff --git a/sp/src/public/haptics/haptic_msgs.h b/sp/src/public/haptics/haptic_msgs.h new file mode 100644 index 00000000..a7e4df17 --- /dev/null +++ b/sp/src/public/haptics/haptic_msgs.h @@ -0,0 +1,34 @@ +#ifndef HAPTIC_MSGS_H +#define HAPTIC_MSGS_H + +void RegisterHapticMessages(void); + +//----------------------------------------------------------------------------- +// Server +//----------------------------------------------------------------------------- +#ifndef CLIENT_DLL + void HapticMsg_SendWeaponAnim( CBasePlayer *pPlayer, int iActivity ); + void HapticMsg_SetDrag(CBasePlayer* pPlayer, float drag); + void HapticMsg_SetConstantForce(CBasePlayer* pPlayer, Vector force); + void HapticMsg_HapDmg(CBasePlayer* pPlayer, float pitch, float yaw, float dmg, float dmgType ); + void HapticMsg_Punch(CBasePlayer* pPlayer, float x, float y, float z); + void HapticMsg_MeleeContact(CBasePlayer* pPlayer); +#endif // !CLIENT_DLL + +//----------------------------------------------------------------------------- +// Client +//----------------------------------------------------------------------------- +#ifdef CLIENT_DLL + void HookHapticMessages(void); + + void __MsgFunc_SPHapWeapEvent( bf_read &HapticMsg ); + void __MsgFunc_HapDmg( bf_read &HapticMsg ); + void __MsgFunc_HapSetConst( bf_read &HapticMsg ); + void __MsgFunc_HapPunch( bf_read &HapticMsg ); + void __MsgFunc_HapGeneric( bf_read &HapticMsg ); + void __MsgFunc_HapSetDrag( bf_read &HapticMsg ); + void __MsgFunc_HapSetDrag( bf_read &HapticMsg ); + void __MsgFunc_HapMeleeContact( bf_read &HapticMsg ); +#endif // CLIENT_DLL + +#endif // HAPTIC_MSGS_H diff --git a/sp/src/public/haptics/haptic_utils.cpp b/sp/src/public/haptics/haptic_utils.cpp new file mode 100644 index 00000000..b9c72b2f --- /dev/null +++ b/sp/src/public/haptics/haptic_utils.cpp @@ -0,0 +1,443 @@ +#include "cbase.h" + +#ifdef CLIENT_DLL + #include "tier3/tier3.h" + #include "iviewrender.h" + #include "inputsystem/iinputsystem.h" + #include "vgui/IInputInternal.h" + #include "c_basecombatweapon.h" + #include "c_baseplayer.h" + #include "haptics/ihaptics.h" + #include "hud_macros.h" + #include "iclientvehicle.h" + #include "c_prop_vehicle.h" + #include "prediction.h" + #include "activitylist.h" +#ifdef TERROR + #include "ClientTerrorPlayer.h" +#endif +extern vgui::IInputInternal *g_InputInternal; +#else + #include "usermessages.h" +#endif + +#include "haptics/haptic_utils.h" +#include "haptics/haptic_msgs.h" + +#ifndef TERROR +#ifndef FCVAR_RELEASE +#define FCVAR_RELEASE 0 +#endif +#endif + +#ifdef CLIENT_DLL +ConVar hap_HasDevice ( "hap_HasDevice", "0", FCVAR_USERINFO/*|FCVAR_HIDDEN*/, "falcon is connected" ); +// damage scale on a title basis. Convar referenced in the haptic dll. +#ifdef PORTAL +#define HAP_DEFAULT_DAMAGE_SCALE_GAME "0.75" +#elif TF_CLIENT_DLL +#define HAP_DEFAULT_DAMAGE_SCALE_GAME "0.3" +#else +#define HAP_DEFAULT_DAMAGE_SCALE_GAME "1.0" +#endif +ConVar hap_damagescale_game("hap_damagescale_game", HAP_DEFAULT_DAMAGE_SCALE_GAME); +#undef HAP_DEFAULT_DAMAGE_SCALE_GAME + +#endif + +void HapticSendWeaponAnim(CBaseCombatWeapon* weapon, int iActivity) +{ + //ignore idle + if(iActivity == ACT_VM_IDLE) + return; + + #if defined( CLIENT_DLL ) + //if(hap_PrintEvents.GetBool()) + // Msg("Client Activity :%s %s %s\n",weapon->GetName(),"Activities",VarArgs("%i",iActivity)); + if ( weapon->IsPredicted() ) + haptics->ProcessHapticWeaponActivity(weapon->GetName(),iActivity); + #else + if( !weapon->IsPredicted() && weapon->GetOwner() && weapon->GetOwner()->IsPlayer()) + { + HapticMsg_SendWeaponAnim( ToBasePlayer(weapon->GetOwner()), iActivity ); + } + #endif +} + + +void HapticSetDrag(CBasePlayer* pPlayer, float drag) +{ +#ifdef CLIENT_DLL + haptics->SetDrag(drag); +#else + HapticMsg_SetDrag( pPlayer, drag ); +#endif +} + +#ifdef CLIENT_DLL +void HapticsHandleMsg_HapSetDrag( float drag ) +{ + haptics->SetDrag(drag); +} +#endif + +void HapticSetConstantForce(CBasePlayer* pPlayer, Vector force) +{ +#ifdef CLIENT_DLL + haptics->SetConstantForce(force); +#else + HapticMsg_SetConstantForce( pPlayer, force ); +#endif +} + +#ifdef CLIENT_DLL + +#ifndef HAPTICS_TEST_PREFIX +#define HAPTICS_TEST_PREFIX +#endif +static CSysModule *pFalconModule =0; +void ConnectHaptics(CreateInterfaceFn appFactory) +{ + bool success = false; + // NVNT load haptics module + pFalconModule = Sys_LoadModule( HAPTICS_TEST_PREFIX HAPTICS_DLL_NAME ); + if(pFalconModule) + { + CreateInterfaceFn factory = Sys_GetFactory( pFalconModule ); + if(factory) + { + haptics = reinterpret_cast< IHaptics* >( factory( HAPTICS_INTERFACE_VERSION, NULL ) ); + if(haptics && + haptics->Initialize(engine, + view, + g_InputInternal, + gpGlobals, + appFactory, + g_pVGuiInput->GetIMEWindow(), + filesystem, + enginevgui, + ActivityList_IndexForName, + ActivityList_NameForIndex)) + { + success = true; + hap_HasDevice.SetValue(1); + } + } + } + if(!success) + { + Sys_UnloadModule(pFalconModule); + pFalconModule = 0; + haptics = new CHapticsStubbed; + } + + if(haptics->HasDevice()) + { + Assert( (void*)haptics == inputsystem->GetHapticsInterfaceAddress() ); + } + HookHapticMessages(); +} + +void DisconnectHaptics() +{ + haptics->ShutdownHaptics(); + if(pFalconModule) + { + Sys_UnloadModule(pFalconModule); + pFalconModule = 0; + }else{ + // delete the stub. + delete haptics; + } + haptics = NULL; +} +//Might be able to handle this better... +void HapticsHandleMsg_HapSetConst( Vector const &constant ) +{ + //Msg("__MsgFunc_HapSetConst: %f %f %f\n",constant.x,constant.y,constant.z); + haptics->SetConstantForce(constant); + //C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); +} + + +//Might be able to handle this better... +void HapticsHandleMsg_SPHapWeapEvent( int iActivity ) +{ + C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); + C_BaseCombatWeapon* weap = NULL; + if(pPlayer) + weap = pPlayer->GetActiveWeapon(); + if(weap) + haptics->ProcessHapticEvent(4,"Weapons",weap->GetName(),"Activities",VarArgs("%i",iActivity)); +} + +void HapticsHandleMsg_HapPunch( QAngle const &angle ) +{ + haptics->HapticsPunch(1,angle); + +} +#ifdef TERROR +ConVar hap_zombie_damage_scale("hap_zombie_damage_scale", "0.25", FCVAR_RELEASE|FCVAR_NEVER_AS_STRING); +#endif +void HapticsHandleMsg_HapDmg( float pitch, float yaw, float damage, int damageType ) +{ + if(!haptics->HasDevice()) + return; + +#ifdef TERROR + C_TerrorPlayer *pPlayer = C_TerrorPlayer::GetLocalTerrorPlayer(); +#else + C_BasePlayer *pPlayer = CBasePlayer::GetLocalPlayer(); +#endif + + if(pPlayer) + { + Vector damageDirection; + + damageDirection.x = cos(pitch*M_PI/180.0)*sin(yaw*M_PI/180.0); + damageDirection.y = -sin(pitch*M_PI/180.0); + damageDirection.z = -(cos(pitch*M_PI/180.0)*cos(yaw*M_PI/180.0)); +#ifdef TERROR + if(pPlayer->GetTeamNumber()==TEAM_ZOMBIE) + { + damageDirection *= hap_zombie_damage_scale.GetFloat(); + } +#endif + + haptics->ApplyDamageEffect(damage, damageType, damageDirection); + } +} + +ConVar hap_melee_scale("hap_melee_scale", "0.8", FCVAR_RELEASE|FCVAR_NEVER_AS_STRING); +void HapticsHandleMsg_HapMeleeContact() +{ + haptics->HapticsPunch(hap_melee_scale.GetFloat(), QAngle(0,0,0)); +} +ConVar hap_noclip_avatar_scale("hap_noclip_avatar_scale", "0.10f", FCVAR_RELEASE|FCVAR_NEVER_AS_STRING); +void UpdateAvatarEffect(void) +{ + if(!haptics->HasDevice()) + return; + + Vector vel; + Vector vvel; + Vector evel; + QAngle eye; + C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); + if(!pPlayer) + return; + + eye = pPlayer->GetAbsAngles(); + + if(pPlayer->IsInAVehicle() && pPlayer->GetVehicle()) + { + pPlayer->GetVehicle()->GetVehicleEnt()->EstimateAbsVelocity(vvel); + eye = pPlayer->GetVehicle()->GetVehicleEnt()->EyeAngles(); + + if(!Q_stristr(pPlayer->GetVehicle()->GetVehicleEnt()->GetClassname(),"choreo")) + { + eye[YAW] += 90; + } + + + + } + else + { + vel = pPlayer->GetAbsVelocity(); + } + + Vector PlayerVel = pPlayer->GetAbsVelocity(); + + //Choreo vehicles use player avatar and don't produce their own velocity + if(!pPlayer->GetVehicle() || abs(vvel.Length()) == 0 ) + { + vel = PlayerVel; + } + else + vel = vvel; + + + + VectorYawRotate(vel, -90 -eye[YAW], vel ); + + vel.y = -vel.y; + vel.z = -vel.z; + + switch(pPlayer->GetMoveType()) { + case MOVETYPE_NOCLIP: + vel *= hap_noclip_avatar_scale.GetFloat(); + break; + default: + break; + } + + haptics->UpdateAvatarVelocity(vel); +} + +#endif + + +#ifndef CLIENT_DLL +void HapticsDamage(CBasePlayer* pPlayer, const CTakeDamageInfo &info) +{ +#if !defined(TF_DLL) && !defined(CSTRIKE_DLL) + if(!pPlayer->HasHaptics()) + return;// do not send to non haptic users. + + Vector DamageDirection(0,0,0); + CBaseEntity *eInflictor = info.GetInflictor(); + // Pat: nuero toxix crash fix + if(!eInflictor) { + return; + } + // Player Data + Vector playerPosition = pPlayer->GetLocalOrigin(); + Vector inflictorPosition = eInflictor->GetLocalOrigin(); + + Vector posWithDir = playerPosition + (playerPosition - inflictorPosition); + pPlayer->WorldToEntitySpace(posWithDir, &DamageDirection); + QAngle dir(0,0,0); + VectorAngles(DamageDirection, dir); + float yawAngle = dir[YAW]; + float pitchAngle = dir[PITCH]; + + int bitDamageType = info.GetDamageType(); + + if(bitDamageType & DMG_FALL) + { + pitchAngle = ((float)-90.0); // coming from beneath + } + else if(bitDamageType & DMG_BURN && (bitDamageType & ~DMG_BURN)==0) + { + // just burn, use the z axis here. + pitchAngle = 0.0; + } +#ifdef TERROR + else if( + (bitDamageType & ( DMG_PARALYZE | DMG_NERVEGAS | DMG_POISON | DMG_RADIATION | DMG_DROWNRECOVER | DMG_ACID | DMG_SLOWBURN ) ) && + (bitDamageType & ~( DMG_PARALYZE | DMG_NERVEGAS | DMG_POISON | DMG_RADIATION | DMG_DROWNRECOVER | DMG_ACID | DMG_SLOWBURN ) )==0 ) + { + // it is time based. and should not really do a punch. + return; + } +#endif + + float sendDamage = info.GetDamage(); + + if(sendDamage>0.0f) + { + HapticMsg_HapDmg( pPlayer, pitchAngle, -yawAngle, sendDamage, bitDamageType ); + } +#endif +} + +void HapticPunch(CBasePlayer* pPlayer, float x, float y, float z) +{ + HapticMsg_Punch( pPlayer, x, y, z ); +} + +void HapticMeleeContact(CBasePlayer* pPlayer) +{ + HapticMsg_MeleeContact( pPlayer ); +} + + + +#endif // NOT CLIENT_DLL + +void HapticProcessSound(const char* soundname, int entIndex) +{ +#ifdef CLIENT_DLL + if (prediction->InPrediction() && prediction->IsFirstTimePredicted()) + { + bool local = false; + C_BaseEntity *ent = C_BaseEntity::Instance( entIndex ); + if(ent) + local = (entIndex == -1 || ent == C_BasePlayer::GetLocalPlayer() || ent == C_BasePlayer::GetLocalPlayer()->GetActiveWeapon()); + + haptics->ProcessHapticEvent(2,"Sounds",soundname); + } +#endif +} + +#ifdef CLIENT_DLL + +// NVNT add || defined(OTHER_DEFINITION) if your game uses vehicles. +#if defined( HL2_CLIENT_DLL ) +#define HAPTIC_VEHICLE_DEFAULT "1" +#else +#define HAPTIC_VEHICLE_DEFAULT "0" +#endif + +// determines weather the vehicles control box option is faded +ConVar hap_ui_vehicles( "hap_ui_vehicles", + HAPTIC_VEHICLE_DEFAULT, + 0 + ); + +#undef HAPTIC_VEHICLE_DEFAULT + +void HapticsEnteredVehicle(C_BaseEntity* vehicle, C_BaseCombatCharacter *pPassenger ) +{ + if(!vehicle) + return; + + // NVNT notify haptics system of navigation change. + + C_PropVehicleDriveable* drivable = dynamic_cast(vehicle); + bool hasgun = false; + if(drivable) + hasgun = drivable->HasGun(); + + + + + + if(Q_stristr(vehicle->GetClassname(),"airboat")) + { + haptics->ProcessHapticEvent(2,"Movement","airboat"); + if(hasgun) + haptics->SetNavigationClass("vehicle_gun"); + else + haptics->SetNavigationClass("vehicle_airboat"); + } + else if(Q_stristr(vehicle->GetClassname(),"jeepepisodic")) + { + haptics->ProcessHapticEvent(2,"Movement","BaseVehicle"); + haptics->SetNavigationClass("vehicle_nogun"); + } + else if(Q_stristr(vehicle->GetClassname(),"jeep")) + { + haptics->ProcessHapticEvent(2,"Movement","BaseVehicle"); + haptics->SetNavigationClass("vehicle_gun"); + } + else if(Q_stristr(vehicle->GetClassname(),"choreo")) + { + haptics->ProcessHapticEvent(2,"Movement","ChoreoVehicle"); + haptics->SetNavigationClass("vehicle_gun_nofix");//Give this a bit of aiming + } + else + { + haptics->ProcessHapticEvent(2,"Movement","BaseVehicle"); + haptics->SetNavigationClass("vehicle_nogun"); + } + + Msg("VehicleType:%s:\n",vehicle->GetClassname()); +} + +void HapticsExitedVehicle(C_BaseEntity* vehicle, C_BaseCombatCharacter *pPassenger ) +{ + // NVNT notify haptics system of navigation change. + haptics->SetNavigationClass("on_foot"); + haptics->ProcessHapticEvent(2,"Movement","BasePlayer"); +} +#endif + + + + + + + + diff --git a/sp/src/public/haptics/haptic_utils.h b/sp/src/public/haptics/haptic_utils.h new file mode 100644 index 00000000..18a05ab2 --- /dev/null +++ b/sp/src/public/haptics/haptic_utils.h @@ -0,0 +1,104 @@ +#ifndef HAPTIC_UTILS_H +#define HAPTIC_UTILS_H + + +#ifdef CLIENT_DLL + +#include "haptics/ihaptics.h" + +// forward decl. +class C_BaseEntity; +class C_BaseCombatCharacter; +class C_BasePlayer; +class bf_read; + +// use client side versions. +#ifndef CBasePlayer +#define CBasePlayer C_BasePlayer; +#endif +#ifndef CBaseCombatWeapon +#define CBaseCombatWeapon C_BaseCombatWeapon +#endif + +// stubbed version of haptics interface. Used when haptics is not available. +class CHapticsStubbed : public IHaptics +{ +public: +public: // Initialization. + virtual bool Initialize(IVEngineClient* newengine, + IViewRender *newview, + vgui::IInputInternal* newinput, + CGlobalVarsBase* newgpGlobals, + CreateInterfaceFn newengineFactory, + void *IMEWindow, + IFileSystem* filesystem, + IEngineVGui* newvgui, + ActivityList_IndexForName_t actIndexForName, + ActivityList_NameForIndex_t actNameForIndex) + {return false;}; + +public: // Device methods + virtual bool HasDevice(){return false;}; + virtual void ShutdownHaptics(){}; + +public: // Game input handling + virtual void CalculateMove(float &forward_move, float &side_move, float delta){}; + virtual void OnPlayerChanged(){} + virtual void SetNavigationClass(const char *defaultNavigationName){}; + virtual const char *GetNavigationClass(){ return 0; }; + virtual void GameProcess(){} + virtual void MenuProcess(){} + +public: // Effect methods + virtual void ProcessHapticEvent(int numArgs, ...){} + virtual void ProcessHapticWeaponActivity(const char *weapon, int activity){} + virtual void HapticsPunch(float strength, const QAngle &angle){} + virtual void ApplyDamageEffect(float damage, int damagetype, const Vector &angle){} + virtual void UpdateAvatarVelocity(const Vector &vel){} + virtual void RemoveAvatarEffect(){} + virtual void SetConstantForce(const Vector &force){} + virtual Vector GetConstantForce(){return Vector(0,0,0);} + virtual void SetDrag(float amount){} + virtual void SetShake(float scalar, float currentamount){} + virtual void SetHeld(float amount){} + virtual void SetMoveSurface(HapticSurfaceType_t surface){} + virtual HapticSurfaceType_t GetMoveSurface(){ return HST_NONE; } + virtual void SetDangling(float amount){}; + +public: // Notify methods + virtual void LocalPlayerReset(){}; + virtual void UpdatePlayerFOV(float fov){}; + virtual void WorldPrecache() {}; +}; +#else +// forward decl. +class CBasePlayer; +class CBaseCombatWeapon; +class CTakeDamageInfo; + +#endif // CLIENT_DLL + +void HapticSendWeaponAnim(class CBaseCombatWeapon* weapon, int iActivity); +void HapticSetConstantForce(class CBasePlayer* pPlayer,Vector force); +void HapticSetDrag(class CBasePlayer* pPlayer, float drag); + +// note: does nothing on server. +void HapticProcessSound(const char* soundname, int entIndex); + +#ifdef CLIENT_DLL + void ConnectHaptics(CreateInterfaceFn appFactory); + void DisconnectHaptics(); + + void UpdateAvatarEffect(void); + void HapticsExitedVehicle(C_BaseEntity* vehicle, C_BaseCombatCharacter *pPassenger ); + void HapticsEnteredVehicle(C_BaseEntity* vehicle, C_BaseCombatCharacter *pPassenger ); + + //bool value true if user is using a haptic device. + extern ConVar hap_HasDevice; +#else + void HapticsDamage(CBasePlayer* pPlayer, const CTakeDamageInfo &info); + void HapticPunch(CBasePlayer* pPlayer, float amount, float x, float y); + void HapticMeleeContact(CBasePlayer* pPlayer); +#endif + +#endif \ No newline at end of file diff --git a/sp/src/public/haptics/ihaptics.h b/sp/src/public/haptics/ihaptics.h new file mode 100644 index 00000000..d99017bc --- /dev/null +++ b/sp/src/public/haptics/ihaptics.h @@ -0,0 +1,144 @@ +#ifndef HAPTICS_INTERFACE_H +#define HAPTICS_INTERFACE_H + +#ifdef GAME_DLL +#pragma warning("IHaptics.h is only for client ussage"); +#endif + +#include "tier0/platform.h" +#include "appframework/IAppSystem.h" + +#define HAPTICS_INTERFACE_VERSION "HapticsInterface001" +#define HAPTICS_DLL_NAME "haptics" + +// systems forward decl. +class IVEngineClient; +class IViewRender; +class IInputInternal; +class CGlobalVarsBase; +class IFileSystem; +class IEngineVGui; + +// vgui forward decl +namespace vgui{ + class IInputInternal; +} + +// math types forward decl +class QAngle; +class Vector; + +typedef enum { + HST_NONE = 0, + HST_ROPE, +} HapticSurfaceType_t; + +typedef int (*ActivityList_IndexForName_t)( const char *pszActivityName ); +typedef const char *(*ActivityList_NameForIndex_t)( int iActivityIndex ); +// NVNT haptic system interface declaration +abstract_class IHaptics +{ +public: // Initialization. + virtual bool Initialize(IVEngineClient* newengine, + IViewRender *newview, + vgui::IInputInternal* newinput, + CGlobalVarsBase* newgpGlobals, + CreateInterfaceFn newengineFactory, + void *IMEWindow, + IFileSystem* filesystem, + IEngineVGui* newvgui, + ActivityList_IndexForName_t actIndexForName, + ActivityList_NameForIndex_t actNameForIndex) = 0; + +public: // Device methods + + // returns true if there is at least one device connected. + virtual bool HasDevice() = 0; + + // closes all haptic devices and effect processing + virtual void ShutdownHaptics() = 0; + +public: // Game input handling + + // computes view angles and adjusts forward_move and side_move + virtual void CalculateMove(float &forward_move, float &side_move, float delta) = 0; + + virtual void OnPlayerChanged()=0; + + // Sets the internal navigation class. + virtual void SetNavigationClass(const char *defaultNavigationName) = 0; + + // Turns the internal navigation off. ( clears navigation class ) + inline void ClearNavigationClass(); + + // Returns the active navigation class ( if none returns NULL ) + virtual const char *GetNavigationClass() = 0; + + // Should be called by the game input class after CalculateMove (when not in menu) + virtual void GameProcess() = 0; + + // Should be called by the game input class when in a menu + virtual void MenuProcess() = 0; + + +public: // Effect methods + + // process a haptic event. + virtual void ProcessHapticEvent(int numArgs, ...) = 0; + virtual void ProcessHapticWeaponActivity(const char *weapon, int activity) = 0; + + // send a haptic punch effect + virtual void HapticsPunch(float strength, const QAngle &angle) = 0; + + // trigger a damage effect + virtual void ApplyDamageEffect(float damage, int damagetype, const Vector &angle) = 0; + + // update the avatar ( acceleration ) effect by a velocity sample + virtual void UpdateAvatarVelocity(const Vector &velocity) = 0; + + // stop processing any running avatar effects + virtual void RemoveAvatarEffect() = 0; + + // sets the device's constant force effect to force vector + virtual void SetConstantForce(const Vector &force) = 0; + + // returns the last sent constant force + virtual Vector GetConstantForce() = 0; + + // set the amount of drag (viscosity) on the haptic devices + virtual void SetDrag(float amount) = 0; + + // set the values to the screen shake effect + virtual void SetShake(float scalar, float currentamount) = 0; + + // enable/disable device position lock. + virtual void SetHeld(float amount) = 0; + + // set anchor weight mass scaler. + virtual void SetMoveSurface(HapticSurfaceType_t surface) = 0; + + virtual HapticSurfaceType_t GetMoveSurface() = 0; + + // set dangling ( being hung, holding onto ledges ) + virtual void SetDangling(float amount) = 0; + +public: // Notify methods + + // notify the haptics system that we have been respawned. + virtual void LocalPlayerReset()=0; + + // notify the haptics system of the player's field of view angle + virtual void UpdatePlayerFOV(float fov)=0; + + virtual void WorldPrecache() = 0; + +}; + +inline void IHaptics::ClearNavigationClass( void ) +{ + SetNavigationClass(0); +} + +extern IHaptics* haptics; + +#endif// HAPTICS_INTERFACE_H \ No newline at end of file diff --git a/sp/src/public/html/htmlmessages.h b/sp/src/public/html/htmlmessages.h new file mode 100644 index 00000000..bfdc3475 --- /dev/null +++ b/sp/src/public/html/htmlmessages.h @@ -0,0 +1,116 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +//=============================================================================// + +#ifndef HTMLMESSAGES_H +#define HTMLMESSAGES_H + +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +// Purpose: Commands we IPC across to the html thread and get responses for +//----------------------------------------------------------------------------- +enum EHTMLCommands +{ + // input events + eHTMLCommands_KeyUp, + eHTMLCommands_KeyDown, + eHTMLCommands_KeyChar, + eHTMLCommands_MouseDown, + eHTMLCommands_MouseUp, + eHTMLCommands_MouseDblClick, + eHTMLCommands_MouseWheel, + eHTMLCommands_MouseMove, + eHTMLCommands_MouseLeave, + + // command events + eHTMLCommands_BrowserCreate, + eHTMLCommands_BrowserRemove, + eHTMLCommands_BrowserErrorStrings, + eHTMLCommands_BrowserSize, + eHTMLCommands_BrowserPosition, + eHTMLCommands_PostURL, + eHTMLCommands_StopLoad, + eHTMLCommands_Reload, + eHTMLCommands_GoForward, + eHTMLCommands_GoBack, + eHTMLCommands_Copy, + eHTMLCommands_Paste, + eHTMLCommands_ExecuteJavaScript, + eHTMLCommands_SetFocus, + eHTMLCommands_HorizontalScrollBarSize, + eHTMLCommands_VerticalScrollBarSize, + eHTMLCommands_Find, + eHTMLCommands_StopFind, + eHTMLCommands_SetHorizontalScroll, + eHTMLCommands_SetVerticalScroll, + eHTMLCommands_SetZoomLevel, + eHTMLCommands_ViewSource, + eHTMLCommands_NeedsPaintResponse, + eHTMLCommands_AddHeader, + eHTMLCommands_GetZoom, + eHTMLCommands_FileLoadDialogResponse, + eHTMLCommands_LinkAtPosition, + eHTMLCommands_ZoomToElementAtPosition, + eHTMLCommands_SavePageToJPEG, + eHTMLCommands_JSAlert, + eHTMLCommands_JSConfirm, + eHTMLCommands_CanGoBackandForward, + eHTMLCommands_OpenSteamURL, + eHTMLCommands_SizePopup, + eHTMLCommands_SetCookie, + eHTMLCommands_SetTargetFrameRate, + eHTMLCommands_FullRepaint, + eHTMLCommands_SetPageScale, + eHTMLCommands_RequestFullScreen, + eHTMLCommands_ExitFullScreen, + eHTMLCommands_GetCookiesForURL, + eHTMLCommands_ZoomToCurrentlyFocusedNode, + eHTMLCommands_CloseFullScreenFlashIfOpen, + eHTMLCommands_PauseFullScreenFlashMovieIfOpen, + eHTMLCommands_GetFocusedNodeValue, + + // output back to the main thread + eHTMLCommands_BrowserCreateResponse, + eHTMLCommands_BrowserReady, + eHTMLCommands_URLChanged, + eHTMLCommands_FinishedRequest, + eHTMLCommands_StartRequest, + eHTMLCommands_ShowPopup, + eHTMLCommands_HidePopup, + eHTMLCommands_OpenNewTab, + eHTMLCommands_PopupHTMLWindow, + eHTMLCommands_PopupHTMLWindowResponse, + eHTMLCommands_SetHTMLTitle, + eHTMLCommands_LoadingResource, + eHTMLCommands_StatusText, + eHTMLCommands_SetCursor, + eHTMLCommands_FileLoadDialog, + eHTMLCommands_ShowToolTip, + eHTMLCommands_UpdateToolTip, + eHTMLCommands_HideToolTip, + eHTMLCommands_SearchResults, + eHTMLCommands_Close, + eHTMLCommands_VerticalScrollBarSizeResponse, + eHTMLCommands_HorizontalScrollBarSizeResponse, + eHTMLCommands_GetZoomResponse, + eHTMLCommands_StartRequestResponse, + eHTMLCommands_NeedsPaint, + eHTMLCommands_LinkAtPositionResponse, + eHTMLCommands_ZoomToElementAtPositionResponse, + eHTMLCommands_JSDialogResponse, + eHTMLCommands_ScaleToValueResponse, + eHTMLCommands_RequestFullScreenResponse, + eHTMLCommands_GetCookiesForURLResponse, + eHTMLCommands_NodeGotFocus, + eHTMLCommands_SavePageToJPEGResponse, + eHTMLCommands_GetFocusedNodeValueResponse, + + eHTMLCommands_None, + +}; + +#endif // HTMLMESSAGES_H \ No newline at end of file diff --git a/sp/src/public/html/htmlprotobuf.cpp b/sp/src/public/html/htmlprotobuf.cpp new file mode 100644 index 00000000..19822273 --- /dev/null +++ b/sp/src/public/html/htmlprotobuf.cpp @@ -0,0 +1,70 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +//=============================================================================// + + +#include "html/htmlprotobuf.h" +#include "tier0/vprof.h" +#include "tier0/valve_minmax_off.h" + + +#ifdef _WIN64 +// disable 64-bit warnings for the google headers +#pragma warning(push) +#pragma warning(disable:4244) // warning C4244: 'return' : conversion from '__int64' to 'int', possible loss of data +#pragma warning(disable:4267) // warning C4267: 'argument' : conversion from 'size_t' to 'int', possible loss of data +#endif + +#include "tier0/memdbgoff.h" +#include "protobuf-2.3.0/src/google/protobuf/message_lite.h" +#include "tier0/memdbgon.h" + +#ifdef _WIN64 +#pragma warning(pop) +#endif + +//----------------------------------------------------------------------------- +// Purpose: serialize a protobuf into a utlbuffer +//----------------------------------------------------------------------------- +void CHTMLBaseProtoBufMsg::SerializeCrossProc( CUtlBuffer *pBuffer ) const +{ + VPROF_BUDGET( "CUIProtoBufMsg::SerializeCrossProc", VPROF_BUDGETGROUP_OTHER_VGUI ); + uint32 unSize = ((google::protobuf::MessageLite *)m_pMsg)->ByteSize(); + + // Ensure enough for type, size, and serialized data + pBuffer->EnsureCapacity( pBuffer->TellPut() + sizeof(uint32) * 3 + unSize ); // bugbug cboyd - drop to * 2 whenpassthrough is removed below + + pBuffer->PutUnsignedInt( unSize ); + + if ( unSize == 0 ) + return; + + uint8 *pBody = (uint8*)pBuffer->Base()+pBuffer->TellPut(); + ((google::protobuf::MessageLite *)m_pMsg)->SerializeWithCachedSizesToArray( pBody ); + pBuffer->SeekPut( CUtlBuffer::SEEK_CURRENT, unSize ); +} + + +//----------------------------------------------------------------------------- +// Purpose: grab a previously serialized protobuf +//----------------------------------------------------------------------------- +bool CHTMLBaseProtoBufMsg::BDeserializeCrossProc( CUtlBuffer *pBuffer ) +{ + VPROF_BUDGET( "CUIProtoBufMsg::BDeserialize", VPROF_BUDGETGROUP_OTHER_VGUI ); + if ( pBuffer->GetBytesRemaining() < (int)sizeof(uint32) ) + return false; + uint32 unSize = pBuffer->GetUnsignedInt(); + + if ( unSize == 0 ) + return true; + + if ( pBuffer->GetBytesRemaining() < (int)unSize ) + return false; + + bool bSucccess = ((google::protobuf::MessageLite *)m_pMsg)->ParseFromArray( (uint8*)pBuffer->Base()+pBuffer->TellGet(), unSize ); + pBuffer->SeekGet( CUtlBuffer::SEEK_CURRENT, unSize ); + + return bSucccess; +} + diff --git a/sp/src/public/html/htmlprotobuf.h b/sp/src/public/html/htmlprotobuf.h new file mode 100644 index 00000000..35d1d1d9 --- /dev/null +++ b/sp/src/public/html/htmlprotobuf.h @@ -0,0 +1,71 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +//=============================================================================// + +#ifndef HTML_PROTOBUF +#define HTML_PROTOBUF + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/utlbuffer.h" +#include "html/htmlmessages.h" + +namespace google +{ + namespace protobuf + { + class MessageLite; + } +} + +class CHTMLBaseProtoBufMsg +{ +public: + void SerializeCrossProc( CUtlBuffer *pBuffer ) const; + bool BDeserializeCrossProc( CUtlBuffer *pBuffer ); + +protected: + void *m_pMsg; + bool m_bIsValid; +}; + + +//----------------------------------------------------------------------------- +// Purpose: Base class for protobuf objects +//----------------------------------------------------------------------------- +template< typename PB_OBJECT_TYPE > +class CHTMLProtoBufMsg : public CHTMLBaseProtoBufMsg +{ +public: + CHTMLProtoBufMsg( EHTMLCommands eMsg ) + { + m_pMsg = new PB_OBJECT_TYPE; + m_bIsValid = true; + } + + // Construct and deserialize in one + CHTMLProtoBufMsg( CUtlBuffer *pBuffer ) + { + m_pMsg = NULL; + m_bIsValid = BDeserializeCrossProc( pBuffer ); + } + + // Destructor + virtual ~CHTMLProtoBufMsg() + { + delete (PB_OBJECT_TYPE *)m_pMsg; + } + + bool BIsValid() { return m_bIsValid; } + + // Accessors + PB_OBJECT_TYPE &Body() { return *((PB_OBJECT_TYPE*)( (google::protobuf::MessageLite *)m_pMsg )); } + const PB_OBJECT_TYPE &BodyConst() const { return *((const PB_OBJECT_TYPE*)( (google::protobuf::MessageLite *)m_pMsg )); } + +}; + + +#endif // HTML_PROTOBUF diff --git a/sp/src/public/html/ichromehtmlwrapper.h b/sp/src/public/html/ichromehtmlwrapper.h new file mode 100644 index 00000000..d606ba05 --- /dev/null +++ b/sp/src/public/html/ichromehtmlwrapper.h @@ -0,0 +1,63 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef ICHROMEHTMLWRAPPER_H +#define ICHROMEHTMLWRAPPER_H + +#ifdef _WIN32 +#pragma once +#endif + +#include + +class CUtlString; +class IHTMLResponses; +struct HTMLCommandBuffer_t; + + +//------------------------------------------------------------- ---------------- +// Purpose: wrapper for HTML functionality +//----------------------------------------------------------------------------- +class IHTMLChromeController +{ +public: + virtual ~IHTMLChromeController() {} + + virtual bool Init( const char *pchHTMLCacheDir, const char *pchCookiePath ) = 0; + virtual void Shutdown() = 0; + virtual bool RunFrame() = 0; + + + // set a cookie in the CEF instance. pchPath is typically "/". If nExpires is 0 then it is a session only cookie, other wise it is saved. + virtual void SetWebCookie( const char *pchHostname, const char *pchKey, const char *pchValue, const char *pchPath, RTime32 nExpires = 0 ) = 0; + virtual void GetWebCookiesForURL( CUtlString *pstrValue, const char *pchURL, const char *pchName ) = 0; + + virtual void SetClientBuildID( uint64 ulBuildID ) = 0; + + virtual bool BHasPendingMessages() = 0; + + virtual void CreateBrowser( IHTMLResponses *pBrowser, bool bPopupWindow, const char *pchUserAgentIdentifier ) = 0; + virtual void RemoveBrowser( IHTMLResponses *pBrowser ) = 0; + + virtual void WakeThread() = 0; + virtual HTMLCommandBuffer_t *GetFreeCommandBuffer( EHTMLCommands eCmd, int iBrowser ) = 0; + virtual void PushCommand( HTMLCommandBuffer_t * ) = 0; + +#ifdef DBGFLAG_VALIDATE + virtual void Validate( CValidator &validator, const char *pchName ) = 0; + + virtual bool ChromePrepareForValidate() = 0; + virtual bool ChromeResumeFromValidate() = 0; +#endif + + virtual void SetCefThreadTargetFrameRate( uint32 nFPS ) = 0; +}; + +#define CHROMEHTML_CONTROLLER_INTERFACE_VERSION "ChromeHTML_Controller_001" + + +#endif // ICHROMEHTMLWRAPPER_H \ No newline at end of file diff --git a/sp/src/public/html/ihtmlchrome.h b/sp/src/public/html/ihtmlchrome.h new file mode 100644 index 00000000..b4b74355 --- /dev/null +++ b/sp/src/public/html/ihtmlchrome.h @@ -0,0 +1,120 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +//=============================================================================// + +#ifndef IHTMLCHROME_H +#define IHTMLCHROME_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "htmlmessages.h" +#include "tier1/utlbuffer.h" + +// prototypes for all the protobuf messages, so we don't need to include all of protobuf +class CMsgBrowserReady; +class CMsgNeedsPaint; +class CMsgStartRequest; +class CMsgURLChanged; +class CMsgFinishedRequest; +class CMsgShowPopup; +class CMsgHidePopup; +class CMsgOpenNewTab; +class CMsgPopupHTMLWindow; +class CMsgSetHTMLTitle; +class CMsgLoadingResource; +class CMsgStatusText; +class CMsgSetCursor; +class CMsgFileLoadDialog; +class CMsgShowToolTip; +class CMsgUpdateToolTip; +class CMsgHideToolTip; +class CMsgSearchResults; +class CMsgClose; +class CMsgHorizontalScrollBarSizeResponse; +class CMsgVerticalScrollBarSizeResponse; +class CMsgGetZoomResponse; +class CMsgLinkAtPositionResponse; +class CMsgZoomToElementAtPositionResponse; +class CMsgJSAlert; +class CMsgJSConfirm; +class CMsgCanGoBackAndForward; +class CMsgOpenSteamURL; +class CMsgSizePopup; +class CMsgScalePageToValueResponse; +class CMsgRequestFullScreen; +class CMsgExitFullScreen; +class CMsgGetCookiesForURLResponse; +class CMsgNodeHasFocus; +class CMsgSavePageToJPEGResponse; +class CMsgFocusedNodeTextResponse; + +//----------------------------------------------------------------------------- +// Purpose: a single IPC packet for the html thread (in and out) +//----------------------------------------------------------------------------- +struct HTMLCommandBuffer_t +{ + EHTMLCommands m_eCmd; + int m_iBrowser; + CUtlBuffer m_Buffer; +#ifdef DBGFLAG_VALIDATE + virtual void Validate( CValidator &validator, const tchar *pchName ) + { + VALIDATE_SCOPE(); + ValidateObj( m_Buffer ); + } +#endif +}; + + +//----------------------------------------------------------------------------- +// Purpose: callback interfaces for messages from the html thread +//----------------------------------------------------------------------------- +class IHTMLResponses +{ +public: + virtual ~IHTMLResponses() {} + + virtual void BrowserSetIndex( int idx ) = 0; + virtual int BrowserGetIndex() = 0; + virtual void BrowserReady( const CMsgBrowserReady *pCmd ) = 0; + virtual void BrowserNeedsPaint( const CMsgNeedsPaint *pCmd ) = 0; + virtual void BrowserStartRequest( const CMsgStartRequest *pCmd ) = 0; + virtual void BrowserURLChanged( const CMsgURLChanged *pCmd ) = 0; + virtual void BrowserFinishedRequest( const CMsgFinishedRequest *pCmd ) = 0; + virtual void BrowserShowPopup( const CMsgShowPopup *pCmd ) = 0; + virtual void BrowserHidePopup( const CMsgHidePopup *pCmd ) = 0; + virtual void BrowserOpenNewTab( const CMsgOpenNewTab *pCmd ) = 0; + virtual void BrowserPopupHTMLWindow( const CMsgPopupHTMLWindow *pCmd ) = 0; + virtual void BrowserSetHTMLTitle( const CMsgSetHTMLTitle *pCmd ) = 0; + virtual void BrowserLoadingResource( const CMsgLoadingResource *pCmd ) = 0; + virtual void BrowserStatusText( const CMsgStatusText *pCmd ) = 0; + virtual void BrowserSetCursor( const CMsgSetCursor *pCmd ) = 0; + virtual void BrowserFileLoadDialog( const CMsgFileLoadDialog *pCmd ) = 0; + virtual void BrowserShowToolTip( const CMsgShowToolTip *pCmd ) = 0; + virtual void BrowserUpdateToolTip( const CMsgUpdateToolTip *pCmd ) = 0; + virtual void BrowserHideToolTip( const CMsgHideToolTip *pCmd ) = 0; + virtual void BrowserSearchResults( const CMsgSearchResults *pCmd ) = 0; + virtual void BrowserClose( const CMsgClose *pCmd ) = 0; + virtual void BrowserHorizontalScrollBarSizeResponse( const CMsgHorizontalScrollBarSizeResponse *pCmd ) = 0; + virtual void BrowserVerticalScrollBarSizeResponse( const CMsgVerticalScrollBarSizeResponse *pCmd ) = 0; + virtual void BrowserGetZoomResponse( const CMsgGetZoomResponse *pCmd ) = 0; + virtual void BrowserLinkAtPositionResponse( const CMsgLinkAtPositionResponse *pCmd ) = 0; + virtual void BrowserZoomToElementAtPositionResponse( const CMsgZoomToElementAtPositionResponse *pCmd ) = 0; + virtual void BrowserJSAlert( const CMsgJSAlert *pCmd ) = 0; + virtual void BrowserJSConfirm( const CMsgJSConfirm *pCmd ) = 0; + virtual void BrowserCanGoBackandForward( const CMsgCanGoBackAndForward *pCmd ) = 0; + virtual void BrowserOpenSteamURL( const CMsgOpenSteamURL *pCmd ) = 0; + virtual void BrowserSizePopup( const CMsgSizePopup *pCmd ) = 0; + virtual void BrowserScalePageToValueResponse( const CMsgScalePageToValueResponse *pCmd ) = 0; + virtual void BrowserRequestFullScreen( const CMsgRequestFullScreen *pCmd ) = 0; + virtual void BrowserExitFullScreen( const CMsgExitFullScreen *pCmd ) = 0; + virtual void BrowserGetCookiesForURLResponse( const CMsgGetCookiesForURLResponse *pCmd ) = 0; + virtual void BrowserNodeGotFocus( const CMsgNodeHasFocus *pCmd ) = 0; + virtual void BrowserSavePageToJPEGResponse( const CMsgSavePageToJPEGResponse *pCmd ) = 0; + virtual void BrowserFocusedNodeValueResponse( const CMsgFocusedNodeTextResponse *pCmd ) = 0; +}; + +#endif // IHTMLCHROME_H diff --git a/sp/src/public/html/ipainthtml.h b/sp/src/public/html/ipainthtml.h new file mode 100644 index 00000000..9e47e23f --- /dev/null +++ b/sp/src/public/html/ipainthtml.h @@ -0,0 +1,54 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#ifndef IPAINTHTML_H +#define IPAINTHTML_H + +class IPaintHTML +{ +public: + enum EPaintTarget + { + ePaintBrowser, + ePaintPopup, + ePaintMAX + }; + // returns the texture id used, pass in -1 to create a new texture + virtual int DrawSubTextureRGBA( EPaintTarget eTarget, int textureID, int x, int y, const unsigned char *pRGBA, int updateWide, int updateTall, int fullTextureWide, int fullTextureTall ) = 0; + virtual void DeleteTexture( EPaintTarget eTarget, int textureID ) = 0; +}; + +class IInputEventHTML +{ +public: + enum EMouseButton + { + eButtonLeft, + eButtonMiddle, + eButtonRight + }; + + virtual bool ChromeHandleMouseClick( EMouseButton eButton, bool bUp, int nClickCount ) = 0; + virtual bool ChromeHandleMouseMove( int x, int y ) = 0; + virtual bool ChromeHandleMouseWheel( int delta ) = 0; + + enum EKeyType + { + KeyDown, + KeyUp, + Char + }; + enum EKeyModifier + { + AltDown = 1, + CrtlDown = 2, + ShiftDown = 4, + }; + + virtual bool ChromeHandleKeyEvent( EKeyType type, int key, int modifiers, bool bKeyUp ) = 0; +}; + +#endif // IPAINTHTML_H \ No newline at end of file diff --git a/sp/src/public/iachievementmgr.h b/sp/src/public/iachievementmgr.h new file mode 100644 index 00000000..303eea44 --- /dev/null +++ b/sp/src/public/iachievementmgr.h @@ -0,0 +1,81 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#ifndef IACHIEVEMENTMGR_H +#define IACHIEVEMENTMGR_H +#ifdef _WIN32 +#pragma once +#endif + +#include "utlmap.h" +#include "vgui_controls/Panel.h" + +class CBaseAchievement; + +abstract_class IAchievement +{ +public: + virtual int GetAchievementID() = 0; + virtual const char *GetName() = 0; + virtual int GetFlags() = 0; + virtual int GetGoal() = 0; + virtual int GetCount() = 0; + virtual bool IsAchieved() = 0; + virtual int GetPointValue() = 0; + virtual bool ShouldSaveWithGame() = 0; + virtual bool ShouldHideUntilAchieved() = 0; + virtual bool ShouldShowOnHUD() = 0; + virtual void SetShowOnHUD( bool bShow ) = 0; +}; + + +abstract_class IAchievementMgr +{ +public: + virtual IAchievement* GetAchievementByIndex( int index ) = 0; + virtual CBaseAchievement* GetAchievementByID ( int id ) = 0; + virtual int GetAchievementCount() = 0; + virtual void InitializeAchievements() = 0; + virtual void AwardAchievement( int iAchievementID ) = 0; + virtual void OnMapEvent( const char *pchEventName ) = 0; + virtual void DownloadUserData() = 0; + virtual void EnsureGlobalStateLoaded() = 0; + virtual void SaveGlobalStateIfDirty( bool bAsync ) = 0; + virtual bool HasAchieved( const char *pchName ) = 0; + virtual bool WereCheatsEverOn() = 0; +}; + +// flags for IAchievement::GetFlags + +#define ACH_LISTEN_KILL_EVENTS 0x0001 +#define ACH_LISTEN_MAP_EVENTS 0x0002 +#define ACH_LISTEN_COMPONENT_EVENTS 0x0004 +#define ACH_HAS_COMPONENTS 0x0020 +#define ACH_SAVE_WITH_GAME 0x0040 +#define ACH_SAVE_GLOBAL 0x0080 +#define ACH_FILTER_ATTACKER_IS_PLAYER 0x0100 +#define ACH_FILTER_VICTIM_IS_PLAYER_ENEMY 0x0200 +#define ACH_FILTER_FULL_ROUND_ONLY 0x0400 + +#define ACH_LISTEN_PLAYER_KILL_ENEMY_EVENTS ACH_LISTEN_KILL_EVENTS | ACH_FILTER_ATTACKER_IS_PLAYER | ACH_FILTER_VICTIM_IS_PLAYER_ENEMY +#define ACH_LISTEN_KILL_ENEMY_EVENTS ACH_LISTEN_KILL_EVENTS | ACH_FILTER_VICTIM_IS_PLAYER_ENEMY + +// Update this for changes in either abstract class in this file +#define ACHIEVEMENTMGR_INTERFACE_VERSION "ACHIEVEMENTMGR_INTERFACE_VERSION001" + +#define ACHIEVEMENT_LOCALIZED_NAME_FROM_STR( name ) \ + ( g_pVGuiLocalize->Find( CFmtStr( "#%s_NAME", name ) ) ) + +#define ACHIEVEMENT_LOCALIZED_NAME( pAchievement ) \ + ( ACHIEVEMENT_LOCALIZED_NAME_FROM_STR( pAchievement->GetName() ) ) + +#define ACHIEVEMENT_LOCALIZED_DESC_FROM_STR( name ) \ + ( g_pVGuiLocalize->Find( CFmtStr( "#%s_DESC", name ) ) ) + +#define ACHIEVEMENT_LOCALIZED_DESC( pAchievement ) \ + ( ACHIEVEMENT_LOCALIZED_DESC_FROM_STR( pAchievement->GetName() ) ) + +#endif // IACHIEVEMENTMGR_H diff --git a/sp/src/public/ibsppack.h b/sp/src/public/ibsppack.h new file mode 100644 index 00000000..7ecaa780 --- /dev/null +++ b/sp/src/public/ibsppack.h @@ -0,0 +1,41 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef IBSPPACK_H +#define IBSPPACK_H +#ifdef _WIN32 +#pragma once +#endif + +#include "interface.h" +#include "utlvector.h" +#include "utlstring.h" + +class IFileSystem; + +abstract_class IBSPPack +{ +public: + virtual void LoadBSPFile( IFileSystem *pFileSystem, char *filename ) = 0; + virtual void WriteBSPFile( char *filename ) = 0; + virtual void ClearPackFile( void ) = 0; + virtual void AddFileToPack( const char *relativename, const char *fullpath ) = 0; + virtual void AddBufferToPack( const char *relativename, void *data, int length, bool bTextMode ) = 0; + virtual void SetHDRMode( bool bHDR ) = 0; + virtual bool SwapBSPFile( IFileSystem *pFileSystem, const char *filename, const char *swapFilename, bool bSwapOnLoad, VTFConvertFunc_t pVTFConvertFunc, VHVFixupFunc_t pVHVFixupFunc, CompressFunc_t pCompressFunc ) = 0; + + // used to get/set the pak file from a BSP + virtual bool GetPakFileLump( IFileSystem *pFileSystem, const char *pBSPFilename, void **pPakData, int *pPakSize ) = 0; + virtual bool SetPakFileLump( IFileSystem *pFileSystem, const char *pBSPFilename, const char *pNewFilename, void *pPakData, int pakSize ) = 0; + + // populates list of files that bsp owns, i.e. world/cubmap materials, statis props, etc + virtual bool GetBSPDependants( IFileSystem *pFileSystem, const char *pBSPFilename, CUtlVector< CUtlString > *pList ) = 0; +}; + +#define IBSPPACK_VERSION_STRING "IBSPPACK003" + +#endif // IBSPPACK_H diff --git a/sp/src/public/iclient.h b/sp/src/public/iclient.h new file mode 100644 index 00000000..2ba39e2a --- /dev/null +++ b/sp/src/public/iclient.h @@ -0,0 +1,92 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef ICLIENT_H +#define ICLIENT_H +#ifdef _WIN32 +#pragma once +#endif + +#include +#include "tier0/platform.h" +#include "userid.h" + +class IServer; +class INetMessage; + +abstract_class IClient : public INetChannelHandler +{ +public: + virtual ~IClient() {} + + // connect client + virtual void Connect(const char * szName, int nUserID, INetChannel *pNetChannel, bool bFakePlayer, int clientChallenge ) = 0; + + // set the client in a pending state waiting for a new game + virtual void Inactivate( void ) = 0; + + // Reconnect without dropiing the netchannel + virtual void Reconnect( void ) = 0; // froce reconnect + + // disconnects a client with a given reason + virtual void Disconnect( PRINTF_FORMAT_STRING const char *reason, ... ) = 0; + + virtual int GetPlayerSlot() const = 0; // returns client slot (usually entity number-1) + virtual int GetUserID() const = 0; // unique ID on this server + virtual const USERID_t GetNetworkID() const = 0; // network wide ID + virtual const char *GetClientName() const = 0; // returns client name + virtual INetChannel *GetNetChannel() = 0; // returns client netchannel + virtual IServer *GetServer() = 0; // returns the object server the client belongs to + virtual const char *GetUserSetting(const char *cvar) const = 0; // returns a clients FCVAR_USERINFO setting + virtual const char *GetNetworkIDString() const = 0; // returns a human readable representation of the network id + + // set/get client data rate in bytes/second + virtual void SetRate( int nRate, bool bForce ) = 0; + virtual int GetRate( void ) const = 0; + + // set/get updates/second rate + virtual void SetUpdateRate( int nUpdateRate, bool bForce ) = 0; + virtual int GetUpdateRate( void ) const = 0; + + // clear complete object & free all memory + virtual void Clear( void ) = 0; + + // returns the highest world tick number acknowledge by client + virtual int GetMaxAckTickCount() const = 0; + + // execute a client command + virtual bool ExecuteStringCommand( const char *s ) = 0; + // send client a network message + virtual bool SendNetMsg(INetMessage &msg, bool bForceReliable = false) = 0; + // send client a text message + virtual void ClientPrintf (PRINTF_FORMAT_STRING const char *fmt, ...) = 0; + + // client has established network channels, nothing else + virtual bool IsConnected( void ) const = 0; + // client is downloading signon data + virtual bool IsSpawned( void ) const = 0; + // client active is ingame, receiving snapshots + virtual bool IsActive( void ) const = 0; + // returns true, if client is not a real player + virtual bool IsFakeClient( void ) const = 0; + // returns true, if client is a HLTV proxy + virtual bool IsHLTV( void ) const = 0; +#if defined( REPLAY_ENABLED ) + // returns true, if client is a Replay proxy + virtual bool IsReplay( void ) const = 0; +#else + // !KLUDGE! Reduce number of #ifdefs required + inline bool IsReplay( void ) const { return false; } +#endif + // returns true, if client hears this player + virtual bool IsHearingClient(int index) const = 0; + // returns true, if client hears this player by proximity + virtual bool IsProximityHearingClient(int index) const = 0; + + virtual void SetMaxRoutablePayloadSize( int nMaxRoutablePayloadSize ) = 0; +}; + +#endif // ICLIENT_H diff --git a/sp/src/public/icliententity.h b/sp/src/public/icliententity.h new file mode 100644 index 00000000..213381f0 --- /dev/null +++ b/sp/src/public/icliententity.h @@ -0,0 +1,48 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef ICLIENTENTITY_H +#define ICLIENTENTITY_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "iclientrenderable.h" +#include "iclientnetworkable.h" +#include "iclientthinkable.h" + +struct Ray_t; +class CGameTrace; +typedef CGameTrace trace_t; +class CMouthInfo; +class IClientEntityInternal; +struct SpatializationInfo_t; + + +//----------------------------------------------------------------------------- +// Purpose: All client entities must implement this interface. +//----------------------------------------------------------------------------- +abstract_class IClientEntity : public IClientUnknown, public IClientRenderable, public IClientNetworkable, public IClientThinkable +{ +public: + // Delete yourself. + virtual void Release( void ) = 0; + + // Network origin + angles + virtual const Vector& GetAbsOrigin( void ) const = 0; + virtual const QAngle& GetAbsAngles( void ) const = 0; + + virtual CMouthInfo *GetMouth( void ) = 0; + + // Retrieve sound spatialization info for the specified sound on this entity + // Return false to indicate sound is not audible + virtual bool GetSoundSpatialization( SpatializationInfo_t& info ) = 0; +}; + + +#endif // ICLIENTENTITY_H diff --git a/sp/src/public/icliententitylist.h b/sp/src/public/icliententitylist.h new file mode 100644 index 00000000..1e0e2586 --- /dev/null +++ b/sp/src/public/icliententitylist.h @@ -0,0 +1,56 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//=============================================================================// +#if !defined( ICLIENTENTITYLIST_H ) +#define ICLIENTENTITYLIST_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "interface.h" + +class IClientEntity; +class ClientClass; +class IClientNetworkable; +class CBaseHandle; +class IClientUnknown; + + +//----------------------------------------------------------------------------- +// Purpose: Exposes IClientEntity's to engine +//----------------------------------------------------------------------------- +abstract_class IClientEntityList +{ +public: + // Get IClientNetworkable interface for specified entity + virtual IClientNetworkable* GetClientNetworkable( int entnum ) = 0; + virtual IClientNetworkable* GetClientNetworkableFromHandle( CBaseHandle hEnt ) = 0; + virtual IClientUnknown* GetClientUnknownFromHandle( CBaseHandle hEnt ) = 0; + + // NOTE: This function is only a convenience wrapper. + // It returns GetClientNetworkable( entnum )->GetIClientEntity(). + virtual IClientEntity* GetClientEntity( int entnum ) = 0; + virtual IClientEntity* GetClientEntityFromHandle( CBaseHandle hEnt ) = 0; + + // Returns number of entities currently in use + virtual int NumberOfEntities( bool bIncludeNonNetworkable ) = 0; + + // Returns highest index actually used + virtual int GetHighestEntityIndex( void ) = 0; + + // Sizes entity list to specified size + virtual void SetMaxEntities( int maxents ) = 0; + virtual int GetMaxEntities( ) = 0; +}; + +extern IClientEntityList *entitylist; + +#define VCLIENTENTITYLIST_INTERFACE_VERSION "VClientEntityList003" + +#endif // ICLIENTENTITYLIST_H diff --git a/sp/src/public/iclientnetworkable.h b/sp/src/public/iclientnetworkable.h new file mode 100644 index 00000000..434a276b --- /dev/null +++ b/sp/src/public/iclientnetworkable.h @@ -0,0 +1,105 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef ICLIENTNETWORKABLE_H +#define ICLIENTNETWORKABLE_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "iclientunknown.h" +#include "tier1/bitbuf.h" + + +class IClientEntity; +class ClientClass; + + +enum ShouldTransmitState_t +{ + SHOULDTRANSMIT_START=0, // The entity is starting to be transmitted (maybe it entered the PVS). + + SHOULDTRANSMIT_END // Called when the entity isn't being transmitted by the server. + // This signals a good time to hide the entity until next time + // the server wants to transmit its state. +}; + +// NOTE: All of these are commented out; NotifyShouldTransmit actually +// has all these in them. Left it as an enum in case we want to go back though +enum DataUpdateType_t +{ + DATA_UPDATE_CREATED = 0, // indicates it was created +and+ entered the pvs +// DATA_UPDATE_ENTERED_PVS, + DATA_UPDATE_DATATABLE_CHANGED, +// DATA_UPDATE_LEFT_PVS, +// DATA_UPDATE_DESTROYED, // FIXME: Could enable this, but it's a little worrying + // since it changes a bunch of existing code +}; + +abstract_class IClientNetworkable +{ +public: + // Gets at the containing class... + virtual IClientUnknown* GetIClientUnknown() = 0; + + // Called by the engine when the server deletes the entity. + virtual void Release() = 0; + + // Supplied automatically by the IMPLEMENT_CLIENTCLASS macros. + virtual ClientClass* GetClientClass() = 0; + + // This tells the entity what the server says for ShouldTransmit on this entity. + // Note: This used to be EntityEnteredPVS/EntityRemainedInPVS/EntityLeftPVS. + virtual void NotifyShouldTransmit( ShouldTransmitState_t state ) = 0; + + + + // + // NOTE FOR ENTITY WRITERS: + // + // In 90% of the cases, you should hook OnPreDataChanged/OnDataChanged instead of + // PreDataUpdate/PostDataUpdate. + // + // The DataChanged events are only called once per frame whereas Pre/PostDataUpdate + // are called once per packet (and sometimes multiple times per frame). + // + // OnDataChanged is called during simulation where entity origins are correct and + // attachments can be used. whereas PostDataUpdate is called while parsing packets + // so attachments and other entity origins may not be valid yet. + // + + virtual void OnPreDataChanged( DataUpdateType_t updateType ) = 0; + virtual void OnDataChanged( DataUpdateType_t updateType ) = 0; + + // Called when data is being updated across the network. + // Only low-level entities should need to know about these. + virtual void PreDataUpdate( DataUpdateType_t updateType ) = 0; + virtual void PostDataUpdate( DataUpdateType_t updateType ) = 0; + + + // Objects become dormant on the client if they leave the PVS on the server. + virtual bool IsDormant( void ) = 0; + + // Ent Index is the server handle used to reference this entity. + // If the index is < 0, that indicates the entity is not known to the server + virtual int entindex( void ) const = 0; + + // Server to client entity message received + virtual void ReceiveMessage( int classID, bf_read &msg ) = 0; + + // Get the base pointer to the networked data that GetClientClass->m_pRecvTable starts at. + // (This is usually just the "this" pointer). + virtual void* GetDataTableBasePtr() = 0; + + // Tells the entity that it's about to be destroyed due to the client receiving + // an uncompressed update that's caused it to destroy all entities & recreate them. + virtual void SetDestroyedOnRecreateEntities( void ) = 0; +}; + + +#endif // ICLIENTNETWORKABLE_H diff --git a/sp/src/public/iclientrenderable.h b/sp/src/public/iclientrenderable.h new file mode 100644 index 00000000..77ce8f22 --- /dev/null +++ b/sp/src/public/iclientrenderable.h @@ -0,0 +1,282 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#ifndef ICLIENTRENDERABLE_H +#define ICLIENTRENDERABLE_H +#ifdef _WIN32 +#pragma once +#endif + +#include "mathlib/mathlib.h" +#include "interface.h" +#include "iclientunknown.h" +#include "client_render_handle.h" +#include "engine/ivmodelrender.h" + +struct model_t; +struct matrix3x4_t; + +extern void DefaultRenderBoundsWorldspace( IClientRenderable *pRenderable, Vector &absMins, Vector &absMaxs ); + +//----------------------------------------------------------------------------- +// Handles to a client shadow +//----------------------------------------------------------------------------- +typedef unsigned short ClientShadowHandle_t; + +enum +{ + CLIENTSHADOW_INVALID_HANDLE = (ClientShadowHandle_t)~0 +}; + +//----------------------------------------------------------------------------- +// What kind of shadows to render? +//----------------------------------------------------------------------------- +enum ShadowType_t +{ + SHADOWS_NONE = 0, + SHADOWS_SIMPLE, + SHADOWS_RENDER_TO_TEXTURE, + SHADOWS_RENDER_TO_TEXTURE_DYNAMIC, // the shadow is always changing state + SHADOWS_RENDER_TO_DEPTH_TEXTURE, +}; + + +// This provides a way for entities to know when they've entered or left the PVS. +// Normally, server entities can use NotifyShouldTransmit to get this info, but client-only +// entities can use this. Store a CPVSNotifyInfo in your +// +// When bInPVS=true, it's being called DURING rendering. It might be after rendering any +// number of views. +// +// If no views had the entity, then it is called with bInPVS=false after rendering. +abstract_class IPVSNotify +{ +public: + virtual void OnPVSStatusChanged( bool bInPVS ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Purpose: All client entities must implement this interface. +//----------------------------------------------------------------------------- +abstract_class IClientRenderable +{ +public: + // Gets at the containing class... + virtual IClientUnknown* GetIClientUnknown() = 0; + + // Data accessors + virtual Vector const& GetRenderOrigin( void ) = 0; + virtual QAngle const& GetRenderAngles( void ) = 0; + virtual bool ShouldDraw( void ) = 0; + virtual bool IsTransparent( void ) = 0; + virtual bool UsesPowerOfTwoFrameBufferTexture() = 0; + virtual bool UsesFullFrameBufferTexture() = 0; + + virtual ClientShadowHandle_t GetShadowHandle() const = 0; + + // Used by the leaf system to store its render handle. + virtual ClientRenderHandle_t& RenderHandle() = 0; + + // Render baby! + virtual const model_t* GetModel( ) const = 0; + virtual int DrawModel( int flags ) = 0; + + // Get the body parameter + virtual int GetBody() = 0; + + // Determine alpha and blend amount for transparent objects based on render state info + virtual void ComputeFxBlend( ) = 0; + virtual int GetFxBlend( void ) = 0; + + // Determine the color modulation amount + virtual void GetColorModulation( float* color ) = 0; + + // Returns false if the entity shouldn't be drawn due to LOD. + // (NOTE: This is no longer used/supported, but kept in the vtable for backwards compat) + virtual bool LODTest() = 0; + + // Call this to get the current bone transforms for the model. + // currentTime parameter will affect interpolation + // nMaxBones specifies how many matrices pBoneToWorldOut can hold. (Should be greater than or + // equal to studiohdr_t::numbones. Use MAXSTUDIOBONES to be safe.) + virtual bool SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime ) = 0; + + virtual void SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights ) = 0; + virtual void DoAnimationEvents( void ) = 0; + + // Return this if you want PVS notifications. See IPVSNotify for more info. + // Note: you must always return the same value from this function. If you don't, + // undefined things will occur, and they won't be good. + virtual IPVSNotify* GetPVSNotifyInterface() = 0; + + // Returns the bounds relative to the origin (render bounds) + virtual void GetRenderBounds( Vector& mins, Vector& maxs ) = 0; + + // returns the bounds as an AABB in worldspace + virtual void GetRenderBoundsWorldspace( Vector& mins, Vector& maxs ) = 0; + + // These normally call through to GetRenderAngles/GetRenderBounds, but some entities custom implement them. + virtual void GetShadowRenderBounds( Vector &mins, Vector &maxs, ShadowType_t shadowType ) = 0; + + // Should this object be able to have shadows cast onto it? + virtual bool ShouldReceiveProjectedTextures( int flags ) = 0; + + // These methods return true if we want a per-renderable shadow cast direction + distance + virtual bool GetShadowCastDistance( float *pDist, ShadowType_t shadowType ) const = 0; + virtual bool GetShadowCastDirection( Vector *pDirection, ShadowType_t shadowType ) const = 0; + + // Other methods related to shadow rendering + virtual bool IsShadowDirty( ) = 0; + virtual void MarkShadowDirty( bool bDirty ) = 0; + + // Iteration over shadow hierarchy + virtual IClientRenderable *GetShadowParent() = 0; + virtual IClientRenderable *FirstShadowChild() = 0; + virtual IClientRenderable *NextShadowPeer() = 0; + + // Returns the shadow cast type + virtual ShadowType_t ShadowCastType() = 0; + + // Create/get/destroy model instance + virtual void CreateModelInstance() = 0; + virtual ModelInstanceHandle_t GetModelInstance() = 0; + + // Returns the transform from RenderOrigin/RenderAngles to world + virtual const matrix3x4_t &RenderableToWorldTransform() = 0; + + // Attachments + virtual int LookupAttachment( const char *pAttachmentName ) = 0; + virtual bool GetAttachment( int number, Vector &origin, QAngle &angles ) = 0; + virtual bool GetAttachment( int number, matrix3x4_t &matrix ) = 0; + + // Rendering clip plane, should be 4 floats, return value of NULL indicates a disabled render clip plane + virtual float *GetRenderClipPlane( void ) = 0; + + // Get the skin parameter + virtual int GetSkin() = 0; + + // Is this a two-pass renderable? + virtual bool IsTwoPass( void ) = 0; + + virtual void OnThreadedDrawSetup() = 0; + + virtual bool UsesFlexDelayedWeights() = 0; + + virtual void RecordToolMessage() = 0; + + virtual bool IgnoresZBuffer( void ) const = 0; +}; + + +// This class can be used to implement default versions of some of the +// functions of IClientRenderable. +abstract_class CDefaultClientRenderable : public IClientUnknown, public IClientRenderable +{ +public: + CDefaultClientRenderable() + { + m_hRenderHandle = INVALID_CLIENT_RENDER_HANDLE; + } + + virtual const Vector & GetRenderOrigin( void ) = 0; + virtual const QAngle & GetRenderAngles( void ) = 0; + virtual const matrix3x4_t & RenderableToWorldTransform() = 0; + virtual bool ShouldDraw( void ) = 0; + virtual bool IsTransparent( void ) = 0; + virtual bool IsTwoPass( void ) { return false; } + virtual void OnThreadedDrawSetup() {} + virtual bool UsesPowerOfTwoFrameBufferTexture( void ) { return false; } + virtual bool UsesFullFrameBufferTexture( void ) { return false; } + + virtual ClientShadowHandle_t GetShadowHandle() const + { + return CLIENTSHADOW_INVALID_HANDLE; + } + + virtual ClientRenderHandle_t& RenderHandle() + { + return m_hRenderHandle; + } + + virtual int GetBody() { return 0; } + virtual int GetSkin() { return 0; } + virtual bool UsesFlexDelayedWeights() { return false; } + + virtual const model_t* GetModel( ) const { return NULL; } + virtual int DrawModel( int flags ) { return 0; } + virtual void ComputeFxBlend( ) { return; } + virtual int GetFxBlend( ) { return 255; } + virtual bool LODTest() { return true; } + virtual bool SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime ) { return true; } + virtual void SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights ) {} + virtual void DoAnimationEvents( void ) {} + virtual IPVSNotify* GetPVSNotifyInterface() { return NULL; } + virtual void GetRenderBoundsWorldspace( Vector& absMins, Vector& absMaxs ) { DefaultRenderBoundsWorldspace( this, absMins, absMaxs ); } + + // Determine the color modulation amount + virtual void GetColorModulation( float* color ) + { + Assert(color); + color[0] = color[1] = color[2] = 1.0f; + } + + // Should this object be able to have shadows cast onto it? + virtual bool ShouldReceiveProjectedTextures( int flags ) + { + return false; + } + + // These methods return true if we want a per-renderable shadow cast direction + distance + virtual bool GetShadowCastDistance( float *pDist, ShadowType_t shadowType ) const { return false; } + virtual bool GetShadowCastDirection( Vector *pDirection, ShadowType_t shadowType ) const { return false; } + + virtual void GetShadowRenderBounds( Vector &mins, Vector &maxs, ShadowType_t shadowType ) + { + GetRenderBounds( mins, maxs ); + } + + virtual bool IsShadowDirty( ) { return false; } + virtual void MarkShadowDirty( bool bDirty ) {} + virtual IClientRenderable *GetShadowParent() { return NULL; } + virtual IClientRenderable *FirstShadowChild(){ return NULL; } + virtual IClientRenderable *NextShadowPeer() { return NULL; } + virtual ShadowType_t ShadowCastType() { return SHADOWS_NONE; } + virtual void CreateModelInstance() {} + virtual ModelInstanceHandle_t GetModelInstance() { return MODEL_INSTANCE_INVALID; } + + // Attachments + virtual int LookupAttachment( const char *pAttachmentName ) { return -1; } + virtual bool GetAttachment( int number, Vector &origin, QAngle &angles ) { return false; } + virtual bool GetAttachment( int number, matrix3x4_t &matrix ) { return false; } + + // Rendering clip plane, should be 4 floats, return value of NULL indicates a disabled render clip plane + virtual float *GetRenderClipPlane() { return NULL; } + + virtual void RecordToolMessage() {} + virtual bool IgnoresZBuffer( void ) const { return false; } + +// IClientUnknown implementation. +public: + virtual void SetRefEHandle( const CBaseHandle &handle ) { Assert( false ); } + virtual const CBaseHandle& GetRefEHandle() const { Assert( false ); return *((CBaseHandle*)0); } + + virtual IClientUnknown* GetIClientUnknown() { return this; } + virtual ICollideable* GetCollideable() { return 0; } + virtual IClientRenderable* GetClientRenderable() { return this; } + virtual IClientNetworkable* GetClientNetworkable() { return 0; } + virtual IClientEntity* GetIClientEntity() { return 0; } + virtual C_BaseEntity* GetBaseEntity() { return 0; } + virtual IClientThinkable* GetClientThinkable() { return 0; } + + +public: + ClientRenderHandle_t m_hRenderHandle; +}; + + +#endif // ICLIENTRENDERABLE_H diff --git a/sp/src/public/iclientthinkable.h b/sp/src/public/iclientthinkable.h new file mode 100644 index 00000000..4adc8bb5 --- /dev/null +++ b/sp/src/public/iclientthinkable.h @@ -0,0 +1,41 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef ICLIENTTHINKABLE_H +#define ICLIENTTHINKABLE_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "iclientunknown.h" + + +class CClientThinkHandlePtr; +typedef CClientThinkHandlePtr* ClientThinkHandle_t; + + +// Entities that implement this interface can be put into the client think list. +abstract_class IClientThinkable +{ +public: + // Gets at the containing class... + virtual IClientUnknown* GetIClientUnknown() = 0; + + virtual void ClientThink() = 0; + + // Called when you're added to the think list. + // GetThinkHandle's return value must be initialized to INVALID_THINK_HANDLE. + virtual ClientThinkHandle_t GetThinkHandle() = 0; + virtual void SetThinkHandle( ClientThinkHandle_t hThink ) = 0; + + // Called by the client when it deletes the entity. + virtual void Release() = 0; +}; + + +#endif // ICLIENTTHINKABLE_H diff --git a/sp/src/public/iclientunknown.h b/sp/src/public/iclientunknown.h new file mode 100644 index 00000000..ac7e1e8f --- /dev/null +++ b/sp/src/public/iclientunknown.h @@ -0,0 +1,41 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#ifndef ICLIENTUNKNOWN_H +#define ICLIENTUNKNOWN_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "tier0/platform.h" +#include "ihandleentity.h" + +class IClientNetworkable; +class C_BaseEntity; +class IClientRenderable; +class ICollideable; +class IClientEntity; +class IClientThinkable; + + + +// This is the client's version of IUnknown. We may want to use a QueryInterface-like +// mechanism if this gets big. +abstract_class IClientUnknown : public IHandleEntity +{ +public: + virtual ICollideable* GetCollideable() = 0; + virtual IClientNetworkable* GetClientNetworkable() = 0; + virtual IClientRenderable* GetClientRenderable() = 0; + virtual IClientEntity* GetIClientEntity() = 0; + virtual C_BaseEntity* GetBaseEntity() = 0; + virtual IClientThinkable* GetClientThinkable() = 0; +}; + + +#endif // ICLIENTUNKNOWN_H diff --git a/sp/src/public/iclientvirtualreality.h b/sp/src/public/iclientvirtualreality.h new file mode 100644 index 00000000..b24cd26d --- /dev/null +++ b/sp/src/public/iclientvirtualreality.h @@ -0,0 +1,64 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Contains the IClientVirtualReality interface, which is implemented in +// client.dll and called by engine.dll +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef ICLIENTVIRTUALREALITY_H +#define ICLIENTVIRTUALREALITY_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/interface.h" +#include "tier1/refcount.h" +#include "appframework/IAppSystem.h" + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// important enumeration +//----------------------------------------------------------------------------- + +// NOTE NOTE NOTE!!!! If you up this, grep for "NEW_INTERFACE" to see if there is anything +// waiting to be enabled during an interface revision. +#define CLIENTVIRTUALREALITY_INTERFACE_VERSION "ClientVirtualReality001" + +//----------------------------------------------------------------------------- +// The ISourceVirtualReality interface +//----------------------------------------------------------------------------- + + + +abstract_class IClientVirtualReality : public IAppSystem +{ +public: + virtual ~IClientVirtualReality() {} + + // Placeholder for API revision + virtual bool Connect( CreateInterfaceFn factory ) = 0; + virtual void Disconnect() = 0; + virtual void *QueryInterface( const char *pInterfaceName ) = 0; + virtual InitReturnVal_t Init() = 0; + virtual void Shutdown() = 0; + + // the interface + + // Draw the main menu in VR mode + virtual void DrawMainMenu() = 0; +}; + + + +//----------------------------------------------------------------------------- + +extern IClientVirtualReality *g_pClientVR; + + +#endif // ICLIENTVIRTUALREALITY_H diff --git a/sp/src/public/icvar.h b/sp/src/public/icvar.h new file mode 100644 index 00000000..369adc58 --- /dev/null +++ b/sp/src/public/icvar.h @@ -0,0 +1,203 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#ifndef ICVAR_H +#define ICVAR_H +#ifdef _WIN32 +#pragma once +#endif + +#include "appframework/IAppSystem.h" +#include "tier1/iconvar.h" + +class ConCommandBase; +class ConCommand; +class ConVar; +class Color; + + +//----------------------------------------------------------------------------- +// ConVars/ComCommands are marked as having a particular DLL identifier +//----------------------------------------------------------------------------- +typedef int CVarDLLIdentifier_t; + + +//----------------------------------------------------------------------------- +// Used to display console messages +//----------------------------------------------------------------------------- +abstract_class IConsoleDisplayFunc +{ +public: + virtual void ColorPrint( const Color& clr, const char *pMessage ) = 0; + virtual void Print( const char *pMessage ) = 0; + virtual void DPrint( const char *pMessage ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Purpose: Applications can implement this to modify behavior in ICvar +//----------------------------------------------------------------------------- +#define CVAR_QUERY_INTERFACE_VERSION "VCvarQuery001" +abstract_class ICvarQuery : public IAppSystem +{ +public: + // Can these two convars be aliased? + virtual bool AreConVarsLinkable( const ConVar *child, const ConVar *parent ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Purpose: DLL interface to ConVars/ConCommands +//----------------------------------------------------------------------------- +abstract_class ICvar : public IAppSystem +{ +public: + // Allocate a unique DLL identifier + virtual CVarDLLIdentifier_t AllocateDLLIdentifier() = 0; + + // Register, unregister commands + virtual void RegisterConCommand( ConCommandBase *pCommandBase ) = 0; + virtual void UnregisterConCommand( ConCommandBase *pCommandBase ) = 0; + virtual void UnregisterConCommands( CVarDLLIdentifier_t id ) = 0; + + // If there is a + on the command line, this returns the value. + // Otherwise, it returns NULL. + virtual const char* GetCommandLineValue( const char *pVariableName ) = 0; + + // Try to find the cvar pointer by name + virtual ConCommandBase *FindCommandBase( const char *name ) = 0; + virtual const ConCommandBase *FindCommandBase( const char *name ) const = 0; + virtual ConVar *FindVar ( const char *var_name ) = 0; + virtual const ConVar *FindVar ( const char *var_name ) const = 0; + virtual ConCommand *FindCommand( const char *name ) = 0; + virtual const ConCommand *FindCommand( const char *name ) const = 0; + + // Get first ConCommandBase to allow iteration + virtual ConCommandBase *GetCommands( void ) = 0; + virtual const ConCommandBase *GetCommands( void ) const = 0; + + // Install a global change callback (to be called when any convar changes) + virtual void InstallGlobalChangeCallback( FnChangeCallback_t callback ) = 0; + virtual void RemoveGlobalChangeCallback( FnChangeCallback_t callback ) = 0; + virtual void CallGlobalChangeCallbacks( ConVar *var, const char *pOldString, float flOldValue ) = 0; + + // Install a console printer + virtual void InstallConsoleDisplayFunc( IConsoleDisplayFunc* pDisplayFunc ) = 0; + virtual void RemoveConsoleDisplayFunc( IConsoleDisplayFunc* pDisplayFunc ) = 0; + virtual void ConsoleColorPrintf( const Color& clr, PRINTF_FORMAT_STRING const char *pFormat, ... ) const = 0; + virtual void ConsolePrintf( PRINTF_FORMAT_STRING const char *pFormat, ... ) const = 0; + virtual void ConsoleDPrintf( PRINTF_FORMAT_STRING const char *pFormat, ... ) const = 0; + + // Reverts cvars which contain a specific flag + virtual void RevertFlaggedConVars( int nFlag ) = 0; + + // Method allowing the engine ICvarQuery interface to take over + // A little hacky, owing to the fact the engine is loaded + // well after ICVar, so we can't use the standard connect pattern + virtual void InstallCVarQuery( ICvarQuery *pQuery ) = 0; + +#if defined( _X360 ) + virtual void PublishToVXConsole( ) = 0; +#endif + virtual bool IsMaterialThreadSetAllowed( ) const = 0; + virtual void QueueMaterialThreadSetValue( ConVar *pConVar, const char *pValue ) = 0; + virtual void QueueMaterialThreadSetValue( ConVar *pConVar, int nValue ) = 0; + virtual void QueueMaterialThreadSetValue( ConVar *pConVar, float flValue ) = 0; + virtual bool HasQueuedMaterialThreadConVarSets() const = 0; + virtual int ProcessQueuedMaterialThreadConVarSets() = 0; + +protected: class ICVarIteratorInternal; +public: + /// Iteration over all cvars. + /// (THIS IS A SLOW OPERATION AND YOU SHOULD AVOID IT.) + /// usage: + /// { ICVar::Iterator iter(g_pCVar); + /// for ( iter.SetFirst() ; iter.IsValid() ; iter.Next() ) + /// { + /// ConCommandBase *cmd = iter.Get(); + /// } + /// } + /// The Iterator class actually wraps the internal factory methods + /// so you don't need to worry about new/delete -- scope takes care + // of it. + /// We need an iterator like this because we can't simply return a + /// pointer to the internal data type that contains the cvars -- + /// it's a custom, protected class with unusual semantics and is + /// prone to change. + class Iterator + { + public: + inline Iterator(ICvar *icvar); + inline ~Iterator(void); + inline void SetFirst( void ); + inline void Next( void ); + inline bool IsValid( void ); + inline ConCommandBase *Get( void ); + private: + ICVarIteratorInternal *m_pIter; + }; + +protected: + // internals for ICVarIterator + class ICVarIteratorInternal + { + public: + // warning: delete called on 'ICvar::ICVarIteratorInternal' that is abstract but has non-virtual destructor [-Wdelete-non-virtual-dtor] + virtual ~ICVarIteratorInternal() {} + virtual void SetFirst( void ) = 0; + virtual void Next( void ) = 0; + virtual bool IsValid( void ) = 0; + virtual ConCommandBase *Get( void ) = 0; + }; + + virtual ICVarIteratorInternal *FactoryInternalIterator( void ) = 0; + friend class Iterator; +}; + +inline ICvar::Iterator::Iterator(ICvar *icvar) +{ + m_pIter = icvar->FactoryInternalIterator(); +} + +inline ICvar::Iterator::~Iterator( void ) +{ + delete m_pIter; +} + +inline void ICvar::Iterator::SetFirst( void ) +{ + m_pIter->SetFirst(); +} + +inline void ICvar::Iterator::Next( void ) +{ + m_pIter->Next(); +} + +inline bool ICvar::Iterator::IsValid( void ) +{ + return m_pIter->IsValid(); +} + +inline ConCommandBase * ICvar::Iterator::Get( void ) +{ + return m_pIter->Get(); +} + +#define CVAR_INTERFACE_VERSION "VEngineCvar004" + + +//----------------------------------------------------------------------------- +// These global names are defined by tier1.h, duplicated here so you +// don't have to include tier1.h +//----------------------------------------------------------------------------- + +// These are marked DLL_EXPORT for Linux. +DLL_EXPORT ICvar *cvar; +extern ICvar *g_pCVar; + + +#endif // ICVAR_H diff --git a/sp/src/public/idedicatedexports.h b/sp/src/public/idedicatedexports.h new file mode 100644 index 00000000..817401f7 --- /dev/null +++ b/sp/src/public/idedicatedexports.h @@ -0,0 +1,28 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef IDEDICATEDEXPORTS_H +#define IDEDICATEDEXPORTS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "interface.h" +#include "appframework/IAppSystem.h" + + +abstract_class IDedicatedExports : public IAppSystem +{ +public: + virtual void Sys_Printf( char *text ) = 0; + virtual void RunServer() = 0; +}; + +#define VENGINE_DEDICATEDEXPORTS_API_VERSION "VENGINE_DEDICATEDEXPORTS_API_VERSION003" + + +#endif // IDEDICATEDEXPORTS_H diff --git a/sp/src/public/iefx.h b/sp/src/public/iefx.h new file mode 100644 index 00000000..83835389 --- /dev/null +++ b/sp/src/public/iefx.h @@ -0,0 +1,67 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#if !defined( IEFX_H ) +#define IEFX_H +#ifdef _WIN32 +#pragma once +#endif + +#include "interface.h" +#include "mathlib/vector.h" + +struct model_t; +struct dlight_t; +class IMaterial; + +#define MAX_DLIGHTS 32 + +//----------------------------------------------------------------------------- +// Purpose: Exposes effects api to client .dll +//----------------------------------------------------------------------------- +abstract_class IVEfx +{ +public: + // Retrieve decal texture index from decal by name + virtual int Draw_DecalIndexFromName ( char *name ) = 0; + + // Apply decal + virtual void DecalShoot ( int textureIndex, int entity, + const model_t *model, const Vector& model_origin, const QAngle& model_angles, + const Vector& position, const Vector *saxis, int flags ) = 0; + + // Apply colored decal + virtual void DecalColorShoot ( int textureIndex, int entity, + const model_t *model, const Vector& model_origin, const QAngle& model_angles, + const Vector& position, const Vector *saxis, int flags, const color32 &rgbaColor ) = 0; + + virtual void PlayerDecalShoot( IMaterial *material, void *userdata, int entity, const model_t *model, + const Vector& model_origin, const QAngle& model_angles, + const Vector& position, const Vector *saxis, int flags, const color32 &rgbaColor ) = 0; + + // Allocate a dynamic world light ( key is the entity to whom it is associated ) + virtual dlight_t *CL_AllocDlight ( int key ) = 0; + + // Allocate a dynamic entity light ( key is the entity to whom it is associated ) + virtual dlight_t *CL_AllocElight ( int key ) = 0; + + // Get a list of the currently-active dynamic lights. + virtual int CL_GetActiveDLights( dlight_t *pList[MAX_DLIGHTS] ) = 0; + + // Retrieve decal texture name from decal by index + virtual const char *Draw_DecalNameFromIndex( int nIndex ) = 0; + + // Given an elight key, find it. Does not search ordinary dlights. May return NULL. + virtual dlight_t *GetElightByKey( int key ) = 0; +}; + +#define VENGINE_EFFECTS_INTERFACE_VERSION "VEngineEffects001" + +extern IVEfx *effects; + +#endif // IEFX_H diff --git a/sp/src/public/ienginevgui.h b/sp/src/public/ienginevgui.h new file mode 100644 index 00000000..601ba27c --- /dev/null +++ b/sp/src/public/ienginevgui.h @@ -0,0 +1,65 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//=============================================================================// +#if !defined( IENGINEVGUI_H ) +#define IENGINEVGUI_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "interface.h" +#include "vgui/VGUI.h" + +// Forward declarations. +namespace vgui +{ + class Panel; +}; + +enum VGuiPanel_t +{ + PANEL_ROOT = 0, + PANEL_GAMEUIDLL, + PANEL_CLIENTDLL, + PANEL_TOOLS, + PANEL_INGAMESCREENS, + PANEL_GAMEDLL, + PANEL_CLIENTDLL_TOOLS +}; + +// In-game panels are cropped to the current engine viewport size +enum PaintMode_t +{ + PAINT_UIPANELS = (1<<0), + PAINT_INGAMEPANELS = (1<<1), + PAINT_CURSOR = (1<<2), // software cursor, if appropriate +}; + +abstract_class IEngineVGui +{ +public: + virtual ~IEngineVGui( void ) { } + + virtual vgui::VPANEL GetPanel( VGuiPanel_t type ) = 0; + + virtual bool IsGameUIVisible() = 0; +}; + +#define VENGINE_VGUI_VERSION "VEngineVGui001" + +#if defined(_STATIC_LINKED) && defined(CLIENT_DLL) +namespace Client +{ +extern IEngineVGui *enginevgui; +} +#else +extern IEngineVGui *enginevgui; +#endif + +#endif // IENGINEVGUI_H diff --git a/sp/src/public/iexternaltest.h b/sp/src/public/iexternaltest.h new file mode 100644 index 00000000..74174056 --- /dev/null +++ b/sp/src/public/iexternaltest.h @@ -0,0 +1,279 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: interface to external test DLLs +// +//============================================================================= + +#ifndef IEXTERNALTEST +#define IEXTERNALTEST +#ifdef _WIN32 +#pragma once +#endif + +#include "steam/isteamfriends.h" +#include "clientenums.h" + +// An equivalent to EConnectionPriority that can be used in +// external tests without needing to depend on Steam's version of the enum +enum EExternalTestConnectionPriority +{ + k_EExternalTestConnectionPriorityLow = 0, + k_EExternalTestConnectionPriorityMedium = 1, + k_EExternalTestConnectionPriorityHigh = 2, +}; + +// used to pass arbitrary buffers full of data back to the external test +typedef uint32 ExternalTestBuffer_t; +static const ExternalTestBuffer_t k_unExternalTestBufferInvalid = 0; + + +//----------------------------------------------------------------------------- +// Purpose: Represents a single test client (game client or game server) inside +// of a test. +//----------------------------------------------------------------------------- +class IExternalTestClient +{ +public: + virtual ~IExternalTestClient() {} + virtual void *GetISteamGenericInterface( const char *pchInterfaceVersion ) = 0; + virtual ISteamUserStats *GetISteamUserStats( const char *pchVersion ) = 0; + virtual ISteamGameServerStats *GetISteamGameServerStats( const char *pchVersion ) = 0; + virtual CSteamID GetSteamID() = 0; + virtual bool GetAccountName( char *pchBuf, int cchBuf ) = 0; + + virtual bool BLoggedOn() = 0; + virtual void YieldingLogOff() = 0; + virtual bool BYieldingLogOn() = 0; + virtual void RequestAppInfoUpdate() = 0; + virtual bool BGetAppInfoUpdateResult( EResult *peResult, uint32 *punAppsUpdated ) = 0; + virtual void GetServerDetails( AppId_t *pnAppIdServed, uint32 *punIPGameServer, uint16 *pusPortGameServer, bool *pbSecure ) = 0; + virtual bool BYieldingPrepareForApp( AppId_t unAppID ) = 0; + virtual void SetConnectionPriority( EExternalTestConnectionPriority eConnectionPriority ) = 0; + + // methods to manipulate friend/social stuff that isn't in ISteamFriends + virtual void SetPersonaState( EPersonaState ePersonaState ) = 0; + virtual void AddFriend( const CSteamID & steamIDFriend ) = 0; + virtual void RemoveFriend( const CSteamID & steamIDFriend ) = 0; + + // Removes every queued callback for this client + virtual void ClearCallbacks() = 0; + + // Sets this user as an admin in this universe + virtual void YieldingSetAsAdmin() = 0; + + // bans this user for the specified app ID + virtual void YieldingBan( AppId_t unAppID, int nDeltaSeconds, bool bOneYearBan ) = 0; + + virtual bool BYieldingAwaitNewCallback( void *pCallback, uint32 unCallbackSize, int nCallbackType ) = 0; + virtual bool BYieldingAwaitQueuedCallback( void * pCallback, uint32 unCallbackSize, int nCallbackType ) = 0; + virtual bool BGetQueuedCallbackOfType( void * pCallback, uint32 unCallbackSize, int nCallbackType ) = 0; + + // Retrieves the current status of the API call. Returns false if the call is still in progress + virtual bool BYieldingGetAPICallResult( SteamAPICall_t hSteamAPICall, void *pCallback, uint32 unCallbackSize, int nCallback, bool *pbAPICallFailed ) = 0; + + template< typename TCallback > + inline bool BYieldingAwaitQueuedCallback( TCallback & callback ) { return BYieldingAwaitQueuedCallback( &callback, sizeof(TCallback), TCallback::k_iCallback ); } + template< typename TCallback > + inline bool BYieldingAwaitNewCallback( TCallback & callback ) { return BYieldingAwaitNewCallback( &callback, sizeof(TCallback), TCallback::k_iCallback ); } + template< typename TCallback > + inline bool BGetQueuedCallbackOfType( TCallback & callback ) { return BGetQueuedCallbackOfType( &callback, sizeof(TCallback), TCallback::k_iCallback ); } + + // more friends stuff that isnt in ISteamFriends + virtual void SetIgnoreFriend( const CSteamID & steamIDFriend ) = 0; +}; + +//----------------------------------------------------------------------------- +// Purpose: Helper functions for interacting with the steam client during tests +//----------------------------------------------------------------------------- +class IExternalTestUtils +{ +public: + virtual ~IExternalTestUtils() {} + + // creates a single user client that is logged into an optional gameserver + virtual IExternalTestClient *YieldingCreateUserClient( IExternalTestClient *pGameserver ) = 0; + + // creates a single gameserver client at the specified (fake) IP addr and port + virtual IExternalTestClient *YieldingCreateGameserverClient( uint32 unAddr, uint16 usPort ) = 0; + + // returns the ISteamClient object so the test can fetch other ISteam interfaces. + virtual ISteamClient *SteamClient() = 0; + + // deploys the gctest dll at the current AppID. This is probably not useful outside of the + // gctest tests. + virtual void YieldingDeployGC( ) = 0; + + // takes down the gctest dll at the current app DI + virtual void YieldingDownGC( ) = 0; + + // returns the app ID this test is running as + virtual AppId_t GetAppId() = 0; + + // draws a dot in the output + virtual void DrawProgressDot() = 0; + + // spews some text in the output + virtual void EmitTestOutput( const char *pchMessage ) = 0; + + // used by the external test framework to clean up some things between + // test cases. Test cases should not call this. + virtual void YieldingResetBetweenTests() = 0; + + // Checks a bool condition and spews if it fails. If this fails the test + // will be recorded as having failed. + virtual bool BCheck( bool bCondition ) = 0; + + // Yields until the stress test is finished. If this test is running as a + // regression test, this will return immediately. + virtual void YieldingWaitForTestToFinish() = 0; + + // used by the external test framework to record test success/failure in + // a file that buildbot can use to build reports. Tests should not call this directly. + virtual void UpdateProgressFile( const char *pchTestName, const char *pchStatus ) = 0; + + // Returns true if the test that ran most recently (and might still be running) passed. + virtual bool BLastTestPassed() = 0; + + // Called by a test to report that the test has reached the "running" state. This is only + // useful in stress tests. + virtual void MarkTestRunning() = 0; + + // Logs on a bunch of clients all at once and returns when they are all logged on. + virtual bool BYieldingCreateUserClientBatch( IExternalTestClient **prClients, int cClients, EExternalTestConnectionPriority eConnectionPriority ) = 0; + + // Logs on a bunch of gameservers all at once and returns when they are all logged on. + virtual bool BYieldingCreateGameserverClientBatch( IExternalTestClient **prClients, int cClients, EExternalTestConnectionPriority eConnectionPriority ) = 0; + + // returns true if the test is finished + virtual bool BIsStressTestFinished() = 0; + + // waits a single frame before resuming the test + virtual void YieldingWaitOneFrame() = 0; + + // reports a stress test action success/failure + virtual void ReportStressActionResult( uint32 unActionIndex, bool bResult, const char *pchFailureLocation ) = 0; + + // waits for the specified number of seconds to pass + virtual void YieldingWaitForRealTime( uint32 unSeconds ) = 0; + + // deploys the specified zip file as the GC for the specified app ID + virtual bool BYieldingGCDeploy( AppId_t appID, const char *pchGCZipFile ) = 0; + + // Downs the specified GC + virtual bool BYieldingGCDown( AppId_t appID ) = 0; + + // Revives the specified GC + virtual bool BYieldingGCRevive( AppId_t appID ) = 0; + + // Bounces the specified GC + virtual bool BYieldingGCBounce( AppId_t appID ) = 0; + + // returns the universe the tests are running in + virtual EUniverse GetUniverse() = 0; + + // returns the memory for a buffer + virtual void *GetPvBuffer( ExternalTestBuffer_t unBuffer ) = 0; + + // returns the memory for a buffer + virtual uint32 GetCubBuffer( ExternalTestBuffer_t unBuffer ) = 0; + + // makes a simulated WG request and returns the result + virtual ExternalTestBuffer_t YieldingSimulateWGRequest( const CSteamID & actorID, const void *pvRequestKV, uint32 cubRequestKV ) = 0; + + // Verifies that there is no support ticket for the specified steam ID + virtual void YieldingVerifyNoSupportTicket( const CSteamID & steamID ) = 0; + + // Verifies that there is a support event for the specified steam ID + virtual void YieldingVerifySupportEventRecord( const CSteamID & victimID, const CSteamID & actorID, ESupportEvent eAction, GID_t gidTxn, const char *pchNote ) = 0; + + // forces an appinfo update for the specified app. (Pass invalid to use the default app ID + virtual void YieldingForceAppInfoUpdate( AppId_t appId ) = 0; + + // returns the stats KV section serialized as a buffer + virtual ExternalTestBuffer_t YieldingGetAppInfoStats( AppId_t appId ) = 0; + + // makes a web request and returns the result + virtual bool BYieldingHTTPRequest( int nWebMethod, bool bUseSSL, const char *pchURL, const KeyValues *pkvPostParams, const char *pchAPIKey, const CSteamID & steamID, ExternalTestBuffer_t *punBuffer, int *pnResultCode ) = 0; + + // returns the full path to the DLL that these tests are running from + virtual const char *GetPchDllPath() = 0; + + // returns true if these tests are running in dev mode (i.e. the server was started with -etdev) + virtual bool BIsDevMode() = 0; + + // Sets the persona name for this user via the wg call so we can actually tell when + // it's been set. + virtual bool BYieldingSetPersonaName( const CSteamID & steamID, const char *pchPersonaName ) = 0; + + // waits for the writeback queue to clear + virtual bool BYieldingWaitForCacheWriteback() = 0; +}; + + +//----------------------------------------------------------------------------- +// Purpose: Functions for sending and receiving messages from the Game Coordinator +// for this application +//----------------------------------------------------------------------------- +class IExternalTest +{ +public: + + // returns the number of tests present in this DLL + virtual uint32 GetTestCount() = 0; + + // returns the name of the specified test + virtual const char *GetTestName( uint32 unTest ) = 0; + + // returns the short name (no suite prefix) of the specified test + virtual const char *GetTestShortName( uint32 unTest ) = 0; + + // returns the suite of the specified test + virtual const char *GetTestSuite( uint32 unTest ) = 0; + + // returns the flags for the specified test + virtual uint32 GetTestFlags( uint32 unTest ) = 0; + + // runs the specified tests. The tests should run to completion + // (yielding on a regular basis) and call pETestUtils->BCheck(false) + // on failure + virtual void BRunTests( uint32 *punTests, uint32 unTestCount, IExternalTestUtils * pETestUtils ) = 0; + + // Returns the name of a stress test action + virtual const char *GetStressActionName( uint32 unAction ) = 0; + +}; +#define EXTERNALTEST_INTERFACE_VERSION "IExternalTest001" + +// flags set by individual tests +static const uint32 k_unETFlag_ValidForStress = 1<<0; +static const uint32 k_unETFlag_ValidForRegression = 1<<1; + + +//----------------------------------------------------------------------------- +// Purpose: For one time init of an externaltests dll +//----------------------------------------------------------------------------- +class IExternalTestInitialize +{ +public: + virtual bool BDoBundleInit() = 0; // called once *PER ATS* at DLL Load time + virtual bool BDoOneTimeInit( IExternalTestUtils *pExternalTestUtils ) = 0; // called once PER TEST RUN by ATS0 + virtual bool BDoPerATSInit( IExternalTestUtils *pExternalTestUtils ) = 0; // called once PER TEST RUN PER ATS + virtual void Cleanup() = 0; +}; +#define EXTERNALTEST_INITIALIZE_INTERFACE_VERSION "IExternalTestInitialize001" + + +//----------------------------------------------------------------------------- +// Purpose: Allows an external test DLL to export its ability to validate its +// own allocations +//----------------------------------------------------------------------------- +class IExternalTestValidation +{ +public: + + virtual void Validate( CValidator &validator, const char *pchName ) = 0; +}; +#define EXTERNALTEST_VALIDATION_INTERFACE_VERSION "IExternalTestValidation001" + + +#endif // IEXTERNALTEST diff --git a/sp/src/public/ifilelist.h b/sp/src/public/ifilelist.h new file mode 100644 index 00000000..00dd20f9 --- /dev/null +++ b/sp/src/public/ifilelist.h @@ -0,0 +1,28 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef IFILELIST_H +#define IFILELIST_H +#ifdef _WIN32 +#pragma once +#endif + + +// This class represents a group of files. Internally, it can represent whole folders of files +// that are in or out of the group. So you can't iterate the list, but you can ask the +// class if a particular filename is in the list. +class IFileList +{ +public: + virtual bool IsFileInList( const char *pFilename ) = 0; + virtual void Release() = 0; +}; + + +#endif // IFILELIST_H + + diff --git a/sp/src/public/igameevents.h b/sp/src/public/igameevents.h new file mode 100644 index 00000000..4746361e --- /dev/null +++ b/sp/src/public/igameevents.h @@ -0,0 +1,193 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// +#if !defined( IGAMEEVENTS_H ) +#define IGAMEEVENTS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/interface.h" + +#define INTERFACEVERSION_GAMEEVENTSMANAGER "GAMEEVENTSMANAGER001" // old game event manager, don't use it! +#define INTERFACEVERSION_GAMEEVENTSMANAGER2 "GAMEEVENTSMANAGER002" // new game event manager, + +#include "tier1/bitbuf.h" +//----------------------------------------------------------------------------- +// Purpose: Engine interface into global game event management +//----------------------------------------------------------------------------- + +/* + +The GameEventManager keeps track and fires of all global game events. Game events +are fired by game.dll for events like player death or team wins. Each event has a +unique name and comes with a KeyValue structure providing informations about this +event. Some events are generated also by the engine. + +Events are networked to connected clients and invoked there to. Therefore you +have to specify all data fields and there data types in an public resource +file which is parsed by server and broadcasted to it's clients. A typical game +event is defined like this: + + "game_start" // a new game starts + { + "roundslimit" "long" // max round + "timelimit" "long" // time limit + "fraglimit" "long" // frag limit + "objective" "string" // round objective + } + +All events must have unique names (case sensitive) and may have a list +of data fields. each data field must specify a data type, so the engine +knows how to serialize/unserialize that event for network transmission. +Valid data types are string, float, long, short, byte & bool. If a +data field should not be broadcasted to clients, use the type "local". +*/ + + +#define MAX_EVENT_NAME_LENGTH 32 // max game event name length +#define MAX_EVENT_BITS 9 // max bits needed for an event index +#define MAX_EVENT_NUMBER (1< (fn) + +class INetMessage +{ +public: + virtual ~INetMessage() {}; + + // Use these to setup who can hear whose voice. + // Pass in client indices (which are their ent indices - 1). + + virtual void SetNetChannel(INetChannel * netchan) = 0; // netchannel this message is from/for + virtual void SetReliable( bool state ) = 0; // set to true if it's a reliable message + + virtual bool Process( void ) = 0; // calles the recently set handler to process this message + + virtual bool ReadFromBuffer( bf_read &buffer ) = 0; // returns true if parsing was OK + virtual bool WriteToBuffer( bf_write &buffer ) = 0; // returns true if writing was OK + + virtual bool IsReliable( void ) const = 0; // true, if message needs reliable handling + + virtual int GetType( void ) const = 0; // returns module specific header tag eg svc_serverinfo + virtual int GetGroup( void ) const = 0; // returns net message group of this message + virtual const char *GetName( void ) const = 0; // returns network message name, eg "svc_serverinfo" + virtual INetChannel *GetNetChannel( void ) const = 0; + virtual const char *ToString( void ) const = 0; // returns a human readable string about message content +}; + + +#endif + diff --git a/sp/src/public/inetmsghandler.h b/sp/src/public/inetmsghandler.h new file mode 100644 index 00000000..80181cc4 --- /dev/null +++ b/sp/src/public/inetmsghandler.h @@ -0,0 +1,216 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// +#if !defined( INETMSGHANDLER_H ) +#define INETMSGHANDLER_H +#ifdef _WIN32 +#pragma once +#endif + +class INetChannel; +typedef struct netpacket_s netpacket_t; + +class INetChannelHandler +{ +public: + virtual ~INetChannelHandler( void ) {}; + + virtual void ConnectionStart(INetChannel *chan) = 0; // called first time network channel is established + + virtual void ConnectionClosing(const char *reason) = 0; // network channel is being closed by remote site + + virtual void ConnectionCrashed(const char *reason) = 0; // network error occured + + virtual void PacketStart(int incoming_sequence, int outgoing_acknowledged) = 0; // called each time a new packet arrived + + virtual void PacketEnd( void ) = 0; // all messages has been parsed + + virtual void FileRequested(const char *fileName, unsigned int transferID ) = 0; // other side request a file for download + + virtual void FileReceived(const char *fileName, unsigned int transferID ) = 0; // we received a file + + virtual void FileDenied(const char *fileName, unsigned int transferID ) = 0; // a file request was denied by other side + + virtual void FileSent(const char *fileName, unsigned int transferID ) = 0; // we sent a file +}; + +#define PROCESS_NET_MESSAGE( name ) \ + virtual bool Process##name( NET_##name *msg ) + +#define PROCESS_SVC_MESSAGE( name ) \ + virtual bool Process##name( SVC_##name *msg ) + +#define PROCESS_CLC_MESSAGE( name ) \ + virtual bool Process##name( CLC_##name *msg ) + +#define PROCESS_MM_MESSAGE( name ) \ + virtual bool Process##name( MM_##name *msg ) + + +#define REGISTER_NET_MSG( name ) \ + NET_##name * p##name = new NET_##name(); \ + p##name->m_pMessageHandler = this; \ + chan->RegisterMessage( p##name ); \ + +#define REGISTER_SVC_MSG( name ) \ + SVC_##name * p##name = new SVC_##name(); \ + p##name->m_pMessageHandler = this; \ + chan->RegisterMessage( p##name ); \ + +#define REGISTER_CLC_MSG( name ) \ + CLC_##name * p##name = new CLC_##name(); \ + p##name->m_pMessageHandler = this; \ + chan->RegisterMessage( p##name ); \ + +#define REGISTER_MM_MSG( name ) \ + MM_##name * p##name = new MM_##name(); \ + p##name->m_pMessageHandler = this; \ + chan->RegisterMessage( p##name ); \ + +class NET_Tick; +class NET_StringCmd; +class NET_SetConVar; +class NET_SignonState; + + +class INetMessageHandler +{ +public: + virtual ~INetMessageHandler( void ) {}; + + PROCESS_NET_MESSAGE( Tick ) = 0; + PROCESS_NET_MESSAGE( StringCmd ) = 0; + PROCESS_NET_MESSAGE( SetConVar ) = 0; + PROCESS_NET_MESSAGE( SignonState ) = 0; +}; + +class CLC_ClientInfo; +class CLC_Move; +class CLC_VoiceData; +class CLC_BaselineAck; +class CLC_ListenEvents; +class CLC_RespondCvarValue; +class CLC_FileCRCCheck; +class CLC_FileMD5Check; +class CLC_SaveReplay; +class CLC_CmdKeyValues; + +class IClientMessageHandler : public INetMessageHandler +{ +public: + virtual ~IClientMessageHandler( void ) {}; + + PROCESS_CLC_MESSAGE( ClientInfo ) = 0; + PROCESS_CLC_MESSAGE( Move ) = 0; + PROCESS_CLC_MESSAGE( VoiceData ) = 0; + PROCESS_CLC_MESSAGE( BaselineAck ) = 0; + PROCESS_CLC_MESSAGE( ListenEvents ) = 0; + PROCESS_CLC_MESSAGE( RespondCvarValue ) = 0; + PROCESS_CLC_MESSAGE( FileCRCCheck ) = 0; + PROCESS_CLC_MESSAGE( FileMD5Check ) = 0; +#if defined( REPLAY_ENABLED ) + PROCESS_CLC_MESSAGE( SaveReplay ) = 0; +#endif + PROCESS_CLC_MESSAGE( CmdKeyValues ) = 0; +}; + +class SVC_Print; +class SVC_ServerInfo; +class SVC_SendTable; +class SVC_ClassInfo; +class SVC_SetPause; +class SVC_CreateStringTable; +class SVC_UpdateStringTable; +class SVC_VoiceInit; +class SVC_VoiceData; +class SVC_Sounds; +class SVC_SetView; +class SVC_FixAngle; +class SVC_CrosshairAngle; +class SVC_BSPDecal; +class SVC_GameEvent; +class SVC_UserMessage; +class SVC_EntityMessage; +class SVC_PacketEntities; +class SVC_TempEntities; +class SVC_Prefetch; +class SVC_Menu; +class SVC_GameEventList; +class SVC_GetCvarValue; +class SVC_CmdKeyValues; + +class IServerMessageHandler : public INetMessageHandler +{ +public: + virtual ~IServerMessageHandler( void ) {}; + + // Returns dem file protocol version, or, if not playing a demo, just returns PROTOCOL_VERSION + virtual int GetDemoProtocolVersion() const = 0; + + PROCESS_SVC_MESSAGE( Print ) = 0; + PROCESS_SVC_MESSAGE( ServerInfo ) = 0; + PROCESS_SVC_MESSAGE( SendTable ) = 0; + PROCESS_SVC_MESSAGE( ClassInfo ) = 0; + PROCESS_SVC_MESSAGE( SetPause ) = 0; + PROCESS_SVC_MESSAGE( CreateStringTable ) = 0; + PROCESS_SVC_MESSAGE( UpdateStringTable ) = 0; + PROCESS_SVC_MESSAGE( VoiceInit ) = 0; + PROCESS_SVC_MESSAGE( VoiceData ) = 0; + PROCESS_SVC_MESSAGE( Sounds ) = 0; + PROCESS_SVC_MESSAGE( SetView ) = 0; + PROCESS_SVC_MESSAGE( FixAngle ) = 0; + PROCESS_SVC_MESSAGE( CrosshairAngle ) = 0; + PROCESS_SVC_MESSAGE( BSPDecal ) = 0; + PROCESS_SVC_MESSAGE( GameEvent ) = 0; + PROCESS_SVC_MESSAGE( UserMessage ) = 0; + PROCESS_SVC_MESSAGE( EntityMessage ) = 0; + PROCESS_SVC_MESSAGE( PacketEntities ) = 0; + PROCESS_SVC_MESSAGE( TempEntities ) = 0; + PROCESS_SVC_MESSAGE( Prefetch ) = 0; + PROCESS_SVC_MESSAGE( Menu ) = 0; + PROCESS_SVC_MESSAGE( GameEventList ) = 0; + PROCESS_SVC_MESSAGE( GetCvarValue ) = 0; + PROCESS_SVC_MESSAGE( CmdKeyValues ) = 0; +}; + +class MM_Heartbeat; +class MM_ClientInfo; +class MM_JoinResponse; +class MM_RegisterResponse; +class MM_Migrate; +class MM_Mutelist; +class MM_Checkpoint; + +class IMatchmakingMessageHandler : public INetMessageHandler +{ +public: + virtual ~IMatchmakingMessageHandler( void ) {}; + + PROCESS_MM_MESSAGE( Heartbeat ) = 0; + PROCESS_MM_MESSAGE( ClientInfo ) = 0; + PROCESS_MM_MESSAGE( JoinResponse ) = 0; + PROCESS_MM_MESSAGE( RegisterResponse ) = 0; + PROCESS_MM_MESSAGE( Migrate ) = 0; + PROCESS_MM_MESSAGE( Mutelist ) = 0; + PROCESS_MM_MESSAGE( Checkpoint) = 0; +}; + +class IConnectionlessPacketHandler +{ +public: + virtual ~IConnectionlessPacketHandler( void ) {}; + + virtual bool ProcessConnectionlessPacket( netpacket_t *packet ) = 0; // process a connectionless packet +}; + + +#endif // INETMSGHANDLER_H diff --git a/sp/src/public/inetwork.h b/sp/src/public/inetwork.h new file mode 100644 index 00000000..5014e15f --- /dev/null +++ b/sp/src/public/inetwork.h @@ -0,0 +1,52 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef INETWORK_H +#define INETWORK_H +#ifdef _WIN32 +#pragma once +#endif + +class IConnectionlessPacketHandler; + +abstract_class INetwork +{ +public: + virtual ~INetwork( void ) {}; + + virtual void Init( void ) = 0; + virtual void Config (bool multiplayer); + virtual void IsMultiplayer( void ) = 0; // true = full MP mode, false = loopback SP mode + virtual void IsEnabled( void ) = 0; + + // shuts down Network, closes all UPD/TCP channels + virtual void Shutdown( void ) = 0; + + // must be called each system frame to do any asynchronouse TCP stuff + virtual void RunFrame( double time ) = 0; + + virtual void ProcessSocket( netsrc_t sock, IConnectionlessPacketHandler * handler ) = 0; + + virtual void OutOfBandPrintf(netsrc_t sock, netadr_t &adr, PRINTF_FORMAT_STRING const char *format, ...) = 0; + virtual void SendConnectionless(netsrc_t sock, netadr_t &adr, unsigned char * data, int length ) = 0; + + virtual void LogBadPacket(netpacket_t * packet) = 0; + + // Address conversion + virtual bool StringToAdr ( const char *s, netadr_t *a) = 0; + + // Convert from host to network byte ordering + virtual unsigned short HostToNetShort( unsigned short us_in ); + + // and vice versa + virtual unsigned short NetToHostShort( unsigned short us_in ); + + + +}; + + +#endif // INETWORK_H diff --git a/sp/src/public/inputsystem/AnalogCode.h b/sp/src/public/inputsystem/AnalogCode.h new file mode 100644 index 00000000..51a8441d --- /dev/null +++ b/sp/src/public/inputsystem/AnalogCode.h @@ -0,0 +1,44 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#ifndef ANALOGCODE_H +#define ANALOGCODE_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "inputsystem/InputEnums.h" + + +//----------------------------------------------------------------------------- +// Macro to get at joystick codes +//----------------------------------------------------------------------------- +#define JOYSTICK_AXIS_INTERNAL( _joystick, _axis ) ( JOYSTICK_FIRST_AXIS + ((_joystick) * MAX_JOYSTICK_AXES) + (_axis) ) +#define JOYSTICK_AXIS( _joystick, _axis ) ( (AnalogCode_t)JOYSTICK_AXIS_INTERNAL( _joystick, _axis ) ) + + +//----------------------------------------------------------------------------- +// Enumeration for analog input devices. Includes joysticks, mousewheel, mouse +//----------------------------------------------------------------------------- +enum AnalogCode_t +{ + ANALOG_CODE_INVALID = -1, + MOUSE_X = 0, + MOUSE_Y, + MOUSE_XY, // Invoked when either x or y changes + MOUSE_WHEEL, + + JOYSTICK_FIRST_AXIS, + JOYSTICK_LAST_AXIS = JOYSTICK_AXIS_INTERNAL( MAX_JOYSTICKS-1, MAX_JOYSTICK_AXES-1 ), + + ANALOG_CODE_LAST, +}; + + +#endif // ANALOGCODE_H diff --git a/sp/src/public/inputsystem/ButtonCode.h b/sp/src/public/inputsystem/ButtonCode.h new file mode 100644 index 00000000..39dc7e0a --- /dev/null +++ b/sp/src/public/inputsystem/ButtonCode.h @@ -0,0 +1,378 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#ifndef BUTTONCODE_H +#define BUTTONCODE_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "inputsystem/InputEnums.h" +#include "mathlib/mathlib.h" + +//----------------------------------------------------------------------------- +// Button enum. "Buttons" are binary-state input devices (mouse buttons, keyboard keys) +//----------------------------------------------------------------------------- +enum +{ + JOYSTICK_MAX_BUTTON_COUNT = 32, + JOYSTICK_POV_BUTTON_COUNT = 4, + JOYSTICK_AXIS_BUTTON_COUNT = MAX_JOYSTICK_AXES * 2, +}; + +#define JOYSTICK_BUTTON_INTERNAL( _joystick, _button ) ( JOYSTICK_FIRST_BUTTON + ((_joystick) * JOYSTICK_MAX_BUTTON_COUNT) + (_button) ) +#define JOYSTICK_POV_BUTTON_INTERNAL( _joystick, _button ) ( JOYSTICK_FIRST_POV_BUTTON + ((_joystick) * JOYSTICK_POV_BUTTON_COUNT) + (_button) ) +#define JOYSTICK_AXIS_BUTTON_INTERNAL( _joystick, _button ) ( JOYSTICK_FIRST_AXIS_BUTTON + ((_joystick) * JOYSTICK_AXIS_BUTTON_COUNT) + (_button) ) + +#define JOYSTICK_BUTTON( _joystick, _button ) ( (ButtonCode_t)JOYSTICK_BUTTON_INTERNAL( _joystick, _button ) ) +#define JOYSTICK_POV_BUTTON( _joystick, _button ) ( (ButtonCode_t)JOYSTICK_POV_BUTTON_INTERNAL( _joystick, _button ) ) +#define JOYSTICK_AXIS_BUTTON( _joystick, _button ) ( (ButtonCode_t)JOYSTICK_AXIS_BUTTON_INTERNAL( _joystick, _button ) ) + +enum ButtonCode_t +{ + BUTTON_CODE_INVALID = -1, + BUTTON_CODE_NONE = 0, + + KEY_FIRST = 0, + + KEY_NONE = KEY_FIRST, + KEY_0, + KEY_1, + KEY_2, + KEY_3, + KEY_4, + KEY_5, + KEY_6, + KEY_7, + KEY_8, + KEY_9, + KEY_A, + KEY_B, + KEY_C, + KEY_D, + KEY_E, + KEY_F, + KEY_G, + KEY_H, + KEY_I, + KEY_J, + KEY_K, + KEY_L, + KEY_M, + KEY_N, + KEY_O, + KEY_P, + KEY_Q, + KEY_R, + KEY_S, + KEY_T, + KEY_U, + KEY_V, + KEY_W, + KEY_X, + KEY_Y, + KEY_Z, + KEY_PAD_0, + KEY_PAD_1, + KEY_PAD_2, + KEY_PAD_3, + KEY_PAD_4, + KEY_PAD_5, + KEY_PAD_6, + KEY_PAD_7, + KEY_PAD_8, + KEY_PAD_9, + KEY_PAD_DIVIDE, + KEY_PAD_MULTIPLY, + KEY_PAD_MINUS, + KEY_PAD_PLUS, + KEY_PAD_ENTER, + KEY_PAD_DECIMAL, + KEY_LBRACKET, + KEY_RBRACKET, + KEY_SEMICOLON, + KEY_APOSTROPHE, + KEY_BACKQUOTE, + KEY_COMMA, + KEY_PERIOD, + KEY_SLASH, + KEY_BACKSLASH, + KEY_MINUS, + KEY_EQUAL, + KEY_ENTER, + KEY_SPACE, + KEY_BACKSPACE, + KEY_TAB, + KEY_CAPSLOCK, + KEY_NUMLOCK, + KEY_ESCAPE, + KEY_SCROLLLOCK, + KEY_INSERT, + KEY_DELETE, + KEY_HOME, + KEY_END, + KEY_PAGEUP, + KEY_PAGEDOWN, + KEY_BREAK, + KEY_LSHIFT, + KEY_RSHIFT, + KEY_LALT, + KEY_RALT, + KEY_LCONTROL, + KEY_RCONTROL, + KEY_LWIN, + KEY_RWIN, + KEY_APP, + KEY_UP, + KEY_LEFT, + KEY_DOWN, + KEY_RIGHT, + KEY_F1, + KEY_F2, + KEY_F3, + KEY_F4, + KEY_F5, + KEY_F6, + KEY_F7, + KEY_F8, + KEY_F9, + KEY_F10, + KEY_F11, + KEY_F12, + KEY_CAPSLOCKTOGGLE, + KEY_NUMLOCKTOGGLE, + KEY_SCROLLLOCKTOGGLE, + + KEY_LAST = KEY_SCROLLLOCKTOGGLE, + KEY_COUNT = KEY_LAST - KEY_FIRST + 1, + + // Mouse + MOUSE_FIRST = KEY_LAST + 1, + + MOUSE_LEFT = MOUSE_FIRST, + MOUSE_RIGHT, + MOUSE_MIDDLE, + MOUSE_4, + MOUSE_5, + MOUSE_WHEEL_UP, // A fake button which is 'pressed' and 'released' when the wheel is moved up + MOUSE_WHEEL_DOWN, // A fake button which is 'pressed' and 'released' when the wheel is moved down + + MOUSE_LAST = MOUSE_WHEEL_DOWN, + MOUSE_COUNT = MOUSE_LAST - MOUSE_FIRST + 1, + + // Joystick + JOYSTICK_FIRST = MOUSE_LAST + 1, + + JOYSTICK_FIRST_BUTTON = JOYSTICK_FIRST, + JOYSTICK_LAST_BUTTON = JOYSTICK_BUTTON_INTERNAL( MAX_JOYSTICKS-1, JOYSTICK_MAX_BUTTON_COUNT-1 ), + JOYSTICK_FIRST_POV_BUTTON, + JOYSTICK_LAST_POV_BUTTON = JOYSTICK_POV_BUTTON_INTERNAL( MAX_JOYSTICKS-1, JOYSTICK_POV_BUTTON_COUNT-1 ), + JOYSTICK_FIRST_AXIS_BUTTON, + JOYSTICK_LAST_AXIS_BUTTON = JOYSTICK_AXIS_BUTTON_INTERNAL( MAX_JOYSTICKS-1, JOYSTICK_AXIS_BUTTON_COUNT-1 ), + + JOYSTICK_LAST = JOYSTICK_LAST_AXIS_BUTTON, + +#if !defined ( _X360 ) + NOVINT_FIRST = JOYSTICK_LAST + 2, // plus 1 missing key. +1 seems to cause issues on the first button. + + NOVINT_LOGO_0 = NOVINT_FIRST, + NOVINT_TRIANGLE_0, + NOVINT_BOLT_0, + NOVINT_PLUS_0, + NOVINT_LOGO_1, + NOVINT_TRIANGLE_1, + NOVINT_BOLT_1, + NOVINT_PLUS_1, + + NOVINT_LAST = NOVINT_PLUS_1, +#endif + + BUTTON_CODE_LAST, + BUTTON_CODE_COUNT = BUTTON_CODE_LAST - KEY_FIRST + 1, + + // Helpers for XBox 360 + KEY_XBUTTON_UP = JOYSTICK_FIRST_POV_BUTTON, // POV buttons + KEY_XBUTTON_RIGHT, + KEY_XBUTTON_DOWN, + KEY_XBUTTON_LEFT, + + KEY_XBUTTON_A = JOYSTICK_FIRST_BUTTON, // Buttons + KEY_XBUTTON_B, + KEY_XBUTTON_X, + KEY_XBUTTON_Y, + KEY_XBUTTON_LEFT_SHOULDER, + KEY_XBUTTON_RIGHT_SHOULDER, + KEY_XBUTTON_BACK, + KEY_XBUTTON_START, + KEY_XBUTTON_STICK1, + KEY_XBUTTON_STICK2, + + KEY_XSTICK1_RIGHT = JOYSTICK_FIRST_AXIS_BUTTON, // XAXIS POSITIVE + KEY_XSTICK1_LEFT, // XAXIS NEGATIVE + KEY_XSTICK1_DOWN, // YAXIS POSITIVE + KEY_XSTICK1_UP, // YAXIS NEGATIVE + KEY_XBUTTON_LTRIGGER, // ZAXIS POSITIVE + KEY_XBUTTON_RTRIGGER, // ZAXIS NEGATIVE + KEY_XSTICK2_RIGHT, // UAXIS POSITIVE + KEY_XSTICK2_LEFT, // UAXIS NEGATIVE + KEY_XSTICK2_DOWN, // VAXIS POSITIVE + KEY_XSTICK2_UP, // VAXIS NEGATIVE +}; + +inline bool IsAlpha( ButtonCode_t code ) +{ + return ( code >= KEY_A ) && ( code <= KEY_Z ); +} + +inline bool IsAlphaNumeric( ButtonCode_t code ) +{ + return ( code >= KEY_0 ) && ( code <= KEY_Z ); +} + +inline bool IsSpace( ButtonCode_t code ) +{ + return ( code == KEY_ENTER ) || ( code == KEY_TAB ) || ( code == KEY_SPACE ); +} + +inline bool IsKeypad( ButtonCode_t code ) +{ + return ( code >= MOUSE_FIRST ) && ( code <= KEY_PAD_DECIMAL ); +} + +inline bool IsPunctuation( ButtonCode_t code ) +{ + return ( code >= KEY_0 ) && ( code <= KEY_SPACE ) && !IsAlphaNumeric( code ) && !IsSpace( code ) && !IsKeypad( code ); +} + +inline bool IsKeyCode( ButtonCode_t code ) +{ + return ( code >= KEY_FIRST ) && ( code <= KEY_LAST ); +} + +inline bool IsMouseCode( ButtonCode_t code ) +{ + return ( code >= MOUSE_FIRST ) && ( code <= MOUSE_LAST ); +} + +inline bool IsNovintCode( ButtonCode_t code ) +{ +#if !defined ( _X360 ) + return ( ( code >= NOVINT_FIRST ) && ( code <= NOVINT_LAST ) ); +#else + return false; +#endif +} + +inline bool IsNovintButtonCode( ButtonCode_t code ) +{ +#if !defined ( _X360 ) + return IsNovintCode( code ); +#else + return false; +#endif +} + +inline bool IsJoystickCode( ButtonCode_t code ) +{ + return ( ( ( code >= JOYSTICK_FIRST ) && ( code <= JOYSTICK_LAST ) ) || IsNovintCode( code ) ); +} + +inline bool IsJoystickButtonCode( ButtonCode_t code ) +{ + return ( ( ( code >= JOYSTICK_FIRST_BUTTON ) && ( code <= JOYSTICK_LAST_BUTTON ) ) || IsNovintButtonCode( code ) ); +} + +inline bool IsJoystickPOVCode( ButtonCode_t code ) +{ + return ( code >= JOYSTICK_FIRST_POV_BUTTON ) && ( code <= JOYSTICK_LAST_POV_BUTTON ); +} + +inline bool IsJoystickAxisCode( ButtonCode_t code ) +{ + return ( code >= JOYSTICK_FIRST_AXIS_BUTTON ) && ( code <= JOYSTICK_LAST_AXIS_BUTTON ); +} + +inline ButtonCode_t GetBaseButtonCode( ButtonCode_t code ) +{ + if ( IsJoystickButtonCode( code ) ) + { + int offset = ( code - JOYSTICK_FIRST_BUTTON ) % JOYSTICK_MAX_BUTTON_COUNT; + return (ButtonCode_t)( JOYSTICK_FIRST_BUTTON + offset ); + } + + if ( IsJoystickPOVCode( code ) ) + { + int offset = ( code - JOYSTICK_FIRST_POV_BUTTON ) % JOYSTICK_POV_BUTTON_COUNT; + return (ButtonCode_t)( JOYSTICK_FIRST_POV_BUTTON + offset ); + } + + if ( IsJoystickAxisCode( code ) ) + { + int offset = ( code - JOYSTICK_FIRST_AXIS_BUTTON ) % JOYSTICK_AXIS_BUTTON_COUNT; + return (ButtonCode_t)( JOYSTICK_FIRST_AXIS_BUTTON + offset ); + } + + return code; +} + +inline int GetJoystickForCode( ButtonCode_t code ) +{ + if ( !IsJoystickCode( code ) ) + return 0; + + if ( IsJoystickButtonCode( code ) ) + { + int offset = ( code - JOYSTICK_FIRST_BUTTON ) / JOYSTICK_MAX_BUTTON_COUNT; + return offset; + } + if ( IsJoystickPOVCode( code ) ) + { + int offset = ( code - JOYSTICK_FIRST_POV_BUTTON ) / JOYSTICK_POV_BUTTON_COUNT; + return offset; + } + if ( IsJoystickAxisCode( code ) ) + { + int offset = ( code - JOYSTICK_FIRST_AXIS_BUTTON ) / JOYSTICK_AXIS_BUTTON_COUNT; + return offset; + } + + return 0; +} + +inline ButtonCode_t ButtonCodeToJoystickButtonCode( ButtonCode_t code, int nDesiredJoystick ) +{ + if ( !IsJoystickCode( code ) || nDesiredJoystick == 0 ) + return code; + + nDesiredJoystick = ::clamp( nDesiredJoystick, 0, MAX_JOYSTICKS - 1 ); + + code = GetBaseButtonCode( code ); + + // Now upsample it + if ( IsJoystickButtonCode( code ) ) + { + int nOffset = code - JOYSTICK_FIRST_BUTTON; + return JOYSTICK_BUTTON( nDesiredJoystick, nOffset ); + } + + if ( IsJoystickPOVCode( code ) ) + { + int nOffset = code - JOYSTICK_FIRST_POV_BUTTON; + return JOYSTICK_POV_BUTTON( nDesiredJoystick, nOffset ); + } + + if ( IsJoystickAxisCode( code ) ) + { + int nOffset = code - JOYSTICK_FIRST_AXIS_BUTTON; + return JOYSTICK_AXIS_BUTTON( nDesiredJoystick, nOffset ); + } + + return code; +} + +#endif // BUTTONCODE_H diff --git a/sp/src/public/inputsystem/InputEnums.h b/sp/src/public/inputsystem/InputEnums.h new file mode 100644 index 00000000..4da6866b --- /dev/null +++ b/sp/src/public/inputsystem/InputEnums.h @@ -0,0 +1,100 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#ifndef INPUTENUMS_H +#define INPUTENUMS_H +#ifdef _WIN32 +#pragma once +#endif + +// Standard maximum +/- value of a joystick axis +#define MAX_BUTTONSAMPLE 32768 + +#if !defined( _X360 ) +#define INVALID_USER_ID -1 +#else +#define INVALID_USER_ID XBX_INVALID_USER_ID +#endif + +//----------------------------------------------------------------------------- +// Forward declarations: +//----------------------------------------------------------------------------- + +enum +{ + MAX_JOYSTICKS = 1, + MOUSE_BUTTON_COUNT = 5, + MAX_NOVINT_DEVICES = 2, +}; + +#if defined( LINUX ) +// Linux has a slightly different mapping order on the joystick axes +enum JoystickAxis_t +{ + JOY_AXIS_X = 0, + JOY_AXIS_Y, + JOY_AXIS_Z, + JOY_AXIS_U, + JOY_AXIS_R, + JOY_AXIS_V, + MAX_JOYSTICK_AXES, +}; +#else +enum JoystickAxis_t +{ + JOY_AXIS_X = 0, + JOY_AXIS_Y, + JOY_AXIS_Z, + JOY_AXIS_R, + JOY_AXIS_U, + JOY_AXIS_V, + MAX_JOYSTICK_AXES, +}; +#endif + + + +//----------------------------------------------------------------------------- +// Extra mouse codes +//----------------------------------------------------------------------------- +enum +{ + MS_WM_XBUTTONDOWN = 0x020B, + MS_WM_XBUTTONUP = 0x020C, + MS_WM_XBUTTONDBLCLK = 0x020D, + MS_MK_BUTTON4 = 0x0020, + MS_MK_BUTTON5 = 0x0040, +}; + +//----------------------------------------------------------------------------- +// Events +//----------------------------------------------------------------------------- +enum InputEventType_t +{ + IE_ButtonPressed = 0, // m_nData contains a ButtonCode_t + IE_ButtonReleased, // m_nData contains a ButtonCode_t + IE_ButtonDoubleClicked, // m_nData contains a ButtonCode_t + IE_AnalogValueChanged, // m_nData contains an AnalogCode_t, m_nData2 contains the value + + IE_FirstSystemEvent = 100, + IE_Quit = IE_FirstSystemEvent, + IE_ControllerInserted, // m_nData contains the controller ID + IE_ControllerUnplugged, // m_nData contains the controller ID + + IE_FirstVguiEvent = 1000, // Assign ranges for other systems that post user events here + IE_FirstAppEvent = 2000, +}; + +struct InputEvent_t +{ + int m_nType; // Type of the event (see InputEventType_t) + int m_nTick; // Tick on which the event occurred + int m_nData; // Generic 32-bit data, what it contains depends on the event + int m_nData2; // Generic 32-bit data, what it contains depends on the event + int m_nData3; // Generic 32-bit data, what it contains depends on the event +}; + +#endif // INPUTENUMS_H diff --git a/sp/src/public/inputsystem/iinputsystem.h b/sp/src/public/inputsystem/iinputsystem.h new file mode 100644 index 00000000..ab408e09 --- /dev/null +++ b/sp/src/public/inputsystem/iinputsystem.h @@ -0,0 +1,130 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#ifndef IINPUTSYSTEM_H +#define IINPUTSYSTEM_H +#ifdef _WIN32 +#pragma once +#endif + +#include "tier0/platform.h" +#include "appframework/IAppSystem.h" + +#include "inputsystem/InputEnums.h" +#include "inputsystem/ButtonCode.h" +#include "inputsystem/AnalogCode.h" + +//----------------------------------------------------------------------------- +// Main interface for input. This is a low-level interface +//----------------------------------------------------------------------------- +#define INPUTSYSTEM_INTERFACE_VERSION "InputSystemVersion001" +abstract_class IInputSystem : public IAppSystem +{ +public: + // Attach, detach input system from a particular window + // This window should be the root window for the application + // Only 1 window should be attached at any given time. + virtual void AttachToWindow( void* hWnd ) = 0; + virtual void DetachFromWindow( ) = 0; + + // Enables/disables input. PollInputState will not update current + // button/analog states when it is called if the system is disabled. + virtual void EnableInput( bool bEnable ) = 0; + + // Enables/disables the windows message pump. PollInputState will not + // Peek/Dispatch messages if this is disabled + virtual void EnableMessagePump( bool bEnable ) = 0; + + // Polls the current input state + virtual void PollInputState() = 0; + + // Gets the time of the last polling in ms + virtual int GetPollTick() const = 0; + + // Is a button down? "Buttons" are binary-state input devices (mouse buttons, keyboard keys) + virtual bool IsButtonDown( ButtonCode_t code ) const = 0; + + // Returns the tick at which the button was pressed and released + virtual int GetButtonPressedTick( ButtonCode_t code ) const = 0; + virtual int GetButtonReleasedTick( ButtonCode_t code ) const = 0; + + // Gets the value of an analog input device this frame + // Includes joysticks, mousewheel, mouse + virtual int GetAnalogValue( AnalogCode_t code ) const = 0; + + // Gets the change in a particular analog input device this frame + // Includes joysticks, mousewheel, mouse + virtual int GetAnalogDelta( AnalogCode_t code ) const = 0; + + // Returns the input events since the last poll + virtual int GetEventCount() const = 0; + virtual const InputEvent_t* GetEventData( ) const = 0; + + // Posts a user-defined event into the event queue; this is expected + // to be called in overridden wndprocs connected to the root panel. + virtual void PostUserEvent( const InputEvent_t &event ) = 0; + + // Returns the number of joysticks + virtual int GetJoystickCount() const = 0; + + // Enable/disable joystick, it has perf costs + virtual void EnableJoystickInput( int nJoystick, bool bEnable ) = 0; + + // Enable/disable diagonal joystick POV (simultaneous POV buttons down) + virtual void EnableJoystickDiagonalPOV( int nJoystick, bool bEnable ) = 0; + + // Sample the joystick and append events to the input queue + virtual void SampleDevices( void ) = 0; + + // FIXME: Currently force-feedback is only supported on the Xbox 360 + virtual void SetRumble( float fLeftMotor, float fRightMotor, int userId = INVALID_USER_ID ) = 0; + virtual void StopRumble( void ) = 0; + + // Resets the input state + virtual void ResetInputState() = 0; + + // Sets a player as the primary user - all other controllers will be ignored. + virtual void SetPrimaryUserId( int userId ) = 0; + + // Convert back + forth between ButtonCode/AnalogCode + strings + virtual const char *ButtonCodeToString( ButtonCode_t code ) const = 0; + virtual const char *AnalogCodeToString( AnalogCode_t code ) const = 0; + virtual ButtonCode_t StringToButtonCode( const char *pString ) const = 0; + virtual AnalogCode_t StringToAnalogCode( const char *pString ) const = 0; + + // Sleeps until input happens. Pass a negative number to sleep infinitely + virtual void SleepUntilInput( int nMaxSleepTimeMS = -1 ) = 0; + + // Convert back + forth between virtual codes + button codes + // FIXME: This is a temporary piece of code + virtual ButtonCode_t VirtualKeyToButtonCode( int nVirtualKey ) const = 0; + virtual int ButtonCodeToVirtualKey( ButtonCode_t code ) const = 0; + virtual ButtonCode_t ScanCodeToButtonCode( int lParam ) const = 0; + + // How many times have we called PollInputState? + virtual int GetPollCount() const = 0; + + // Sets the cursor position + virtual void SetCursorPosition( int x, int y ) = 0; + + // NVNT get address to haptics interface + virtual void *GetHapticsInterfaceAddress() const = 0; + + virtual void SetNovintPure( bool bPure ) = 0; + + // read and clear accumulated raw input values + virtual bool GetRawMouseAccumulators( int& accumX, int& accumY ) = 0; + + // tell the input system that we're not a game, we're console text mode. + // this is used for dedicated servers to not initialize joystick system. + // this needs to be called before CInputSystem::Init (e.g. in PreInit of + // some system) if you want ot prevent the joystick system from ever + // being initialized. + virtual void SetConsoleTextMode( bool bConsoleTextMode ) = 0; +}; + + +#endif // IINPUTSYSTEM_H diff --git a/sp/src/public/interpolatortypes.cpp b/sp/src/public/interpolatortypes.cpp new file mode 100644 index 00000000..e8227ed1 --- /dev/null +++ b/sp/src/public/interpolatortypes.cpp @@ -0,0 +1,506 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= +#include "basetypes.h" +#include "tier1/strtools.h" +#include "interpolatortypes.h" +#include "tier0/dbg.h" +#include "mathlib/mathlib.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +struct InterpolatorNameMap_t +{ + int type; + char const *name; + char const *printname; +}; + +static InterpolatorNameMap_t g_InterpolatorNameMap[] = +{ + { INTERPOLATE_DEFAULT, "default", "Default" }, + { INTERPOLATE_CATMULL_ROM_NORMALIZEX, "catmullrom_normalize_x", "Catmull-Rom (Norm X)" }, + { INTERPOLATE_EASE_IN, "easein", "Ease In" }, + { INTERPOLATE_EASE_OUT, "easeout", "Ease Out" }, + { INTERPOLATE_EASE_INOUT, "easeinout", "Ease In/Out" }, + { INTERPOLATE_BSPLINE, "bspline", "B-Spline" }, + { INTERPOLATE_LINEAR_INTERP, "linear_interp", "Linear Interp." }, + { INTERPOLATE_KOCHANEK_BARTELS, "kochanek", "Kochanek-Bartels" }, + { INTERPOLATE_KOCHANEK_BARTELS_EARLY, "kochanek_early", "Kochanek-Bartels Early" }, + { INTERPOLATE_KOCHANEK_BARTELS_LATE, "kochanek_late", "Kochanek-Bartels Late" }, + { INTERPOLATE_SIMPLE_CUBIC, "simple_cubic", "Simple Cubic" }, + { INTERPOLATE_CATMULL_ROM, "catmullrom", "Catmull-Rom" }, + { INTERPOLATE_CATMULL_ROM_NORMALIZE, "catmullrom_normalize", "Catmull-Rom (Norm)" }, + { INTERPOLATE_CATMULL_ROM_TANGENT, "catmullrom_tangent", "Catmull-Rom (Tangent)" }, + { INTERPOLATE_EXPONENTIAL_DECAY, "exponential_decay", "Exponential Decay" }, + { INTERPOLATE_HOLD, "hold", "Hold" }, +}; + +int Interpolator_InterpolatorForName( char const *name ) +{ + for ( int i = 0; i < NUM_INTERPOLATE_TYPES; ++i ) + { + InterpolatorNameMap_t *slot = &g_InterpolatorNameMap[ i ]; + if ( !Q_stricmp( name, slot->name ) ) + return slot->type; + } + + Assert( !"Interpolator_InterpolatorForName failed!!!" ); + return INTERPOLATE_DEFAULT; +} + +char const *Interpolator_NameForInterpolator( int type, bool printname ) +{ + int i = (int)type; + int c = ARRAYSIZE( g_InterpolatorNameMap ); + if ( i < 0 || i >= c ) + { + Assert( "!Interpolator_NameForInterpolator: bogus type!" ); + // returns "unspecified!!!"; + return printname ? g_InterpolatorNameMap[ 0 ].printname : g_InterpolatorNameMap[ 0 ].name; + } + + return printname ? g_InterpolatorNameMap[ i ].printname : g_InterpolatorNameMap[ i ].name; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +struct CurveNameMap_t +{ + int type; + int hotkey; +}; + +static CurveNameMap_t g_CurveNameMap[] = +{ + { CURVE_CATMULL_ROM_TO_CATMULL_ROM, '1' }, + { CURVE_EASE_IN_TO_EASE_OUT, '2' }, + { CURVE_EASE_IN_TO_EASE_IN, '3' }, + { CURVE_EASE_OUT_TO_EASE_OUT, '4' }, + { CURVE_BSPLINE_TO_BSPLINE, '5' }, + { CURVE_LINEAR_INTERP_TO_LINEAR_INTERP, '6' }, + { CURVE_KOCHANEK_BARTELS_TO_KOCHANEK_BARTELS, '7' }, + { CURVE_KOCHANEK_BARTELS_EARLY_TO_KOCHANEK_BARTELS_EARLY, '8' }, + { CURVE_KOCHANEK_BARTELS_LATE_TO_KOCHANEK_BARTELS_LATE, '9' }, + { CURVE_SIMPLE_CUBIC_TO_SIMPLE_CUBIC, '0' }, +}; + +// Turn enum into string and vice versa +int Interpolator_CurveTypeForName( const char *name ) +{ + char sz[ 128 ]; + Q_strncpy( sz, name, sizeof( sz ) ); + + int leftcurve = 0; + int rightcurve = 0; + + int skip = Q_strlen( "curve_" ); + + if ( !Q_strnicmp( sz, "curve_", skip ) ) + { + char *p = sz + skip; + char *second = Q_stristr( p, "_to_curve_" ); + + char save = *second; + *second = 0; + + leftcurve = Interpolator_InterpolatorForName( p ); + + *second = save; + + p = second + Q_strlen( "_to_curve_" ); + + rightcurve = Interpolator_InterpolatorForName( p ); + } + + return MAKE_CURVE_TYPE( leftcurve, rightcurve ); +} + +const char *Interpolator_NameForCurveType( int type, bool printname ) +{ + static char outname[ 256 ]; + + int leftside = GET_LEFT_CURVE( type ); + int rightside = GET_RIGHT_CURVE( type ); + + if ( !printname ) + { + Q_snprintf( outname, sizeof( outname ), "curve_%s_to_curve_%s", + Interpolator_NameForInterpolator( leftside, printname ), + Interpolator_NameForInterpolator( rightside, printname ) ); + } + else + { + Q_snprintf( outname, sizeof( outname ), "%s <-> %s", + Interpolator_NameForInterpolator( leftside, printname ), + Interpolator_NameForInterpolator( rightside, printname ) ); + } + + return outname; +} + +void Interpolator_CurveInterpolatorsForType( int type, int& inbound, int& outbound ) +{ + inbound = GET_LEFT_CURVE( type ); + outbound = GET_RIGHT_CURVE( type ); +} + +int Interpolator_CurveTypeForHotkey( int key ) +{ + int c = ARRAYSIZE( g_CurveNameMap ); + for ( int i = 0; i < c; ++i ) + { + CurveNameMap_t *slot = &g_CurveNameMap[ i ]; + if ( slot->hotkey == key ) + return slot->type; + } + + return -1; +} + +void Interpolator_GetKochanekBartelsParams( int interpolationType, float& tension, float& bias, float& continuity ) +{ + switch ( interpolationType ) + { + default: + tension = 0.0f; + bias = 0.0f; + continuity = 0.0f; + Assert( 0 ); + break; + case INTERPOLATE_KOCHANEK_BARTELS: + tension = 0.77f; + bias = 0.0f; + continuity = 0.77f; + break; + case INTERPOLATE_KOCHANEK_BARTELS_EARLY: + tension = 0.77f; + bias = -1.0f; + continuity = 0.77f; + break; + case INTERPOLATE_KOCHANEK_BARTELS_LATE: + tension = 0.77f; + bias = 1.0f; + continuity = 0.77f; + break; + } +} + +void Interpolator_CurveInterpolate( int interpolationType, + const Vector &vPre, + const Vector &vStart, + const Vector &vEnd, + const Vector &vNext, + float f, + Vector &vOut ) +{ + vOut.Init(); + + switch ( interpolationType ) + { + default: + Warning( "Unknown interpolation type %d\n", + (int)interpolationType ); + // break; // Fall through and use catmull_rom as default + case INTERPOLATE_DEFAULT: + case INTERPOLATE_CATMULL_ROM_NORMALIZEX: + Catmull_Rom_Spline_NormalizeX( + vPre, + vStart, + vEnd, + vNext, + f, + vOut ); + break; + case INTERPOLATE_CATMULL_ROM: + Catmull_Rom_Spline( + vPre, + vStart, + vEnd, + vNext, + f, + vOut ); + break; + case INTERPOLATE_CATMULL_ROM_NORMALIZE: + Catmull_Rom_Spline_Normalize( + vPre, + vStart, + vEnd, + vNext, + f, + vOut ); + break; + case INTERPOLATE_CATMULL_ROM_TANGENT: + Catmull_Rom_Spline_Tangent( + vPre, + vStart, + vEnd, + vNext, + f, + vOut ); + break; + case INTERPOLATE_EASE_IN: + { + f = sin( M_PI * f * 0.5f ); + // Fixme, since this ignores vPre and vNext we could omit computing them aove + VectorLerp( vStart, vEnd, f, vOut ); + } + break; + case INTERPOLATE_EASE_OUT: + { + f = 1.0f - sin( M_PI * f * 0.5f + 0.5f * M_PI ); + // Fixme, since this ignores vPre and vNext we could omit computing them aove + VectorLerp( vStart, vEnd, f, vOut ); + } + break; + case INTERPOLATE_EASE_INOUT: + { + f = SimpleSpline( f ); + // Fixme, since this ignores vPre and vNext we could omit computing them aove + VectorLerp( vStart, vEnd, f, vOut ); + } + break; + case INTERPOLATE_LINEAR_INTERP: + // Fixme, since this ignores vPre and vNext we could omit computing them aove + VectorLerp( vStart, vEnd, f, vOut ); + break; + case INTERPOLATE_KOCHANEK_BARTELS: + case INTERPOLATE_KOCHANEK_BARTELS_EARLY: + case INTERPOLATE_KOCHANEK_BARTELS_LATE: + { + float t, b, c; + Interpolator_GetKochanekBartelsParams( interpolationType, t, b, c ); + Kochanek_Bartels_Spline_NormalizeX + ( + t, b, c, + vPre, + vStart, + vEnd, + vNext, + f, + vOut + ); + } + break; + case INTERPOLATE_SIMPLE_CUBIC: + Cubic_Spline_NormalizeX( + vPre, + vStart, + vEnd, + vNext, + f, + vOut ); + break; + case INTERPOLATE_BSPLINE: + BSpline( + vPre, + vStart, + vEnd, + vNext, + f, + vOut ); + break; + case INTERPOLATE_EXPONENTIAL_DECAY: + { + float dt = vEnd.x - vStart.x; + if ( dt > 0.0f ) + { + float val = 1.0f - ExponentialDecay( 0.001, dt, f * dt ); + vOut.y = vStart.y + val * ( vEnd.y - vStart.y ); + } + else + { + vOut.y = vStart.y; + } + } + break; + case INTERPOLATE_HOLD: + { + vOut.y = vStart.y; + } + break; + } +} + +void Interpolator_CurveInterpolate_NonNormalized( int interpolationType, + const Vector &vPre, + const Vector &vStart, + const Vector &vEnd, + const Vector &vNext, + float f, + Vector &vOut ) +{ + vOut.Init(); + + switch ( interpolationType ) + { + default: + Warning( "Unknown interpolation type %d\n", + (int)interpolationType ); + // break; // Fall through and use catmull_rom as default + case INTERPOLATE_CATMULL_ROM_NORMALIZEX: + case INTERPOLATE_DEFAULT: + case INTERPOLATE_CATMULL_ROM: + case INTERPOLATE_CATMULL_ROM_NORMALIZE: + case INTERPOLATE_CATMULL_ROM_TANGENT: + Catmull_Rom_Spline( + vPre, + vStart, + vEnd, + vNext, + f, + vOut ); + break; + case INTERPOLATE_EASE_IN: + { + f = sin( M_PI * f * 0.5f ); + // Fixme, since this ignores vPre and vNext we could omit computing them aove + VectorLerp( vStart, vEnd, f, vOut ); + } + break; + case INTERPOLATE_EASE_OUT: + { + f = 1.0f - sin( M_PI * f * 0.5f + 0.5f * M_PI ); + // Fixme, since this ignores vPre and vNext we could omit computing them aove + VectorLerp( vStart, vEnd, f, vOut ); + } + break; + case INTERPOLATE_EASE_INOUT: + { + f = SimpleSpline( f ); + // Fixme, since this ignores vPre and vNext we could omit computing them aove + VectorLerp( vStart, vEnd, f, vOut ); + } + break; + case INTERPOLATE_LINEAR_INTERP: + // Fixme, since this ignores vPre and vNext we could omit computing them aove + VectorLerp( vStart, vEnd, f, vOut ); + break; + case INTERPOLATE_KOCHANEK_BARTELS: + case INTERPOLATE_KOCHANEK_BARTELS_EARLY: + case INTERPOLATE_KOCHANEK_BARTELS_LATE: + { + float t, b, c; + Interpolator_GetKochanekBartelsParams( interpolationType, t, b, c ); + Kochanek_Bartels_Spline + ( + t, b, c, + vPre, + vStart, + vEnd, + vNext, + f, + vOut + ); + } + break; + case INTERPOLATE_SIMPLE_CUBIC: + Cubic_Spline( + vPre, + vStart, + vEnd, + vNext, + f, + vOut ); + break; + case INTERPOLATE_BSPLINE: + BSpline( + vPre, + vStart, + vEnd, + vNext, + f, + vOut ); + break; + case INTERPOLATE_EXPONENTIAL_DECAY: + { + float dt = vEnd.x - vStart.x; + if ( dt > 0.0f ) + { + float val = 1.0f - ExponentialDecay( 0.001, dt, f * dt ); + vOut.y = vStart.y + val * ( vEnd.y - vStart.y ); + } + else + { + vOut.y = vStart.y; + } + } + break; + case INTERPOLATE_HOLD: + { + vOut.y = vStart.y; + } + break; + } +} + + +void Interpolator_CurveInterpolate_NonNormalized( int interpolationType, + const Quaternion &vPre, + const Quaternion &vStart, + const Quaternion &vEnd, + const Quaternion &vNext, + float f, + Quaternion &vOut ) +{ + vOut.Init(); + + switch ( interpolationType ) + { + default: + Warning( "Unknown interpolation type %d\n", + (int)interpolationType ); + // break; // Fall through and use catmull_rom as default + case INTERPOLATE_CATMULL_ROM_NORMALIZEX: + case INTERPOLATE_DEFAULT: + case INTERPOLATE_CATMULL_ROM: + case INTERPOLATE_CATMULL_ROM_NORMALIZE: + case INTERPOLATE_CATMULL_ROM_TANGENT: + case INTERPOLATE_KOCHANEK_BARTELS: + case INTERPOLATE_KOCHANEK_BARTELS_EARLY: + case INTERPOLATE_KOCHANEK_BARTELS_LATE: + case INTERPOLATE_SIMPLE_CUBIC: + case INTERPOLATE_BSPLINE: + // FIXME, since this ignores vPre and vNext we could omit computing them aove + QuaternionSlerp( vStart, vEnd, f, vOut ); + break; + case INTERPOLATE_EASE_IN: + { + f = sin( M_PI * f * 0.5f ); + // Fixme, since this ignores vPre and vNext we could omit computing them aove + QuaternionSlerp( vStart, vEnd, f, vOut ); + } + break; + case INTERPOLATE_EASE_OUT: + { + f = 1.0f - sin( M_PI * f * 0.5f + 0.5f * M_PI ); + // Fixme, since this ignores vPre and vNext we could omit computing them aove + QuaternionSlerp( vStart, vEnd, f, vOut ); + } + break; + case INTERPOLATE_EASE_INOUT: + { + f = SimpleSpline( f ); + // Fixme, since this ignores vPre and vNext we could omit computing them aove + QuaternionSlerp( vStart, vEnd, f, vOut ); + } + break; + case INTERPOLATE_LINEAR_INTERP: + // Fixme, since this ignores vPre and vNext we could omit computing them aove + QuaternionSlerp( vStart, vEnd, f, vOut ); + break; + case INTERPOLATE_EXPONENTIAL_DECAY: + vOut.Init(); + break; + case INTERPOLATE_HOLD: + { + vOut = vStart; + } + break; + } +} \ No newline at end of file diff --git a/sp/src/public/interpolatortypes.h b/sp/src/public/interpolatortypes.h new file mode 100644 index 00000000..74c667a1 --- /dev/null +++ b/sp/src/public/interpolatortypes.h @@ -0,0 +1,102 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef INTERPOLATORTYPES_H +#define INTERPOLATORTYPES_H +#ifdef _WIN32 +#pragma once +#endif + +class Quaternion; + +enum +{ + INTERPOLATE_DEFAULT = 0, + INTERPOLATE_CATMULL_ROM_NORMALIZEX, + INTERPOLATE_EASE_IN, + INTERPOLATE_EASE_OUT, + INTERPOLATE_EASE_INOUT, + INTERPOLATE_BSPLINE, + INTERPOLATE_LINEAR_INTERP, + INTERPOLATE_KOCHANEK_BARTELS, + INTERPOLATE_KOCHANEK_BARTELS_EARLY, + INTERPOLATE_KOCHANEK_BARTELS_LATE, + INTERPOLATE_SIMPLE_CUBIC, + + INTERPOLATE_CATMULL_ROM, + INTERPOLATE_CATMULL_ROM_NORMALIZE, + INTERPOLATE_CATMULL_ROM_TANGENT, + + INTERPOLATE_EXPONENTIAL_DECAY, + + INTERPOLATE_HOLD, + + NUM_INTERPOLATE_TYPES, +}; + +#define MAKE_CURVE_TYPE( left, right ) ( ( right ) & 0xff ) | ( ( ( left ) & 0xff ) << 8 ) + +#define GET_RIGHT_CURVE(w) ( ( w ) & 0xff ) +#define GET_LEFT_CURVE(w) ( ( ( w ) >> 8) & 0xff ) + +// Presets used by faceposer +enum +{ + CURVE_DEFAULT = MAKE_CURVE_TYPE( INTERPOLATE_DEFAULT, INTERPOLATE_DEFAULT ), + CURVE_CATMULL_ROM_TO_CATMULL_ROM = MAKE_CURVE_TYPE( INTERPOLATE_CATMULL_ROM_NORMALIZEX , INTERPOLATE_CATMULL_ROM_NORMALIZEX ), // hotkey 1 + CURVE_EASE_IN_TO_EASE_OUT = MAKE_CURVE_TYPE( INTERPOLATE_EASE_IN, INTERPOLATE_EASE_OUT ), // hotkey 2 + CURVE_EASE_IN_TO_EASE_IN = MAKE_CURVE_TYPE( INTERPOLATE_EASE_IN, INTERPOLATE_EASE_IN ), + CURVE_EASE_OUT_TO_EASE_OUT = MAKE_CURVE_TYPE( INTERPOLATE_EASE_OUT, INTERPOLATE_EASE_OUT ), + CURVE_BSPLINE_TO_BSPLINE = MAKE_CURVE_TYPE( INTERPOLATE_BSPLINE, INTERPOLATE_BSPLINE ), + CURVE_LINEAR_INTERP_TO_LINEAR_INTERP = MAKE_CURVE_TYPE( INTERPOLATE_LINEAR_INTERP, INTERPOLATE_LINEAR_INTERP ), + CURVE_KOCHANEK_BARTELS_TO_KOCHANEK_BARTELS = MAKE_CURVE_TYPE( INTERPOLATE_KOCHANEK_BARTELS, INTERPOLATE_KOCHANEK_BARTELS ), + CURVE_KOCHANEK_BARTELS_EARLY_TO_KOCHANEK_BARTELS_EARLY = MAKE_CURVE_TYPE( INTERPOLATE_KOCHANEK_BARTELS_EARLY, INTERPOLATE_KOCHANEK_BARTELS_EARLY ), + CURVE_KOCHANEK_BARTELS_LATE_TO_KOCHANEK_BARTELS_LATE = MAKE_CURVE_TYPE( INTERPOLATE_KOCHANEK_BARTELS_LATE, INTERPOLATE_KOCHANEK_BARTELS_LATE ), + CURVE_SIMPLE_CUBIC_TO_SIMPLE_CUBIC = MAKE_CURVE_TYPE( INTERPOLATE_SIMPLE_CUBIC, INTERPOLATE_SIMPLE_CUBIC ), + CURVE_LINEAR_TO_HOLD = MAKE_CURVE_TYPE( INTERPOLATE_LINEAR_INTERP, INTERPOLATE_HOLD ), + CURVE_HOLD_TO_LINEAR = MAKE_CURVE_TYPE( INTERPOLATE_HOLD, INTERPOLATE_LINEAR_INTERP ), +}; + +// Turn enum into string and vice versa +int Interpolator_CurveTypeForName( const char *name ); +const char *Interpolator_NameForCurveType( int type, bool printname ); +void Interpolator_CurveInterpolatorsForType( int type, int& inbound, int& outbound ); +int Interpolator_CurveTypeForHotkey( int key ); + +int Interpolator_InterpolatorForName( char const *name ); +char const *Interpolator_NameForInterpolator( int type, bool printname ); + +void Interpolator_GetKochanekBartelsParams( int interpolatorType, float& tension, float& bias, float& continuity ); + +class Vector; +// Main spline interpolation function, assumes .x holds time and .y holds one dimensional value +void Interpolator_CurveInterpolate( int interpolationType, + const Vector &vPre, + const Vector &vStart, + const Vector &vEnd, + const Vector &vNext, + float f, + Vector &vOut ); + +// Main spline interpolation function for Vectors, doesn't assume time is in .x and doesn't do normalization +void Interpolator_CurveInterpolate_NonNormalized( int interpolationType, + const Vector &vPre, + const Vector &vStart, + const Vector &vEnd, + const Vector &vNext, + float f, + Vector &vOut ); + +// Main spline interpolation function for Vectors, doesn't assume time is in .x and doesn't do normalization +void Interpolator_CurveInterpolate_NonNormalized( int interpolationType, + const Quaternion &vPre, + const Quaternion &vStart, + const Quaternion &vEnd, + const Quaternion &vNext, + float f, + Quaternion &vOut ); + +#endif // INTERPOLATORTYPES_H diff --git a/sp/src/public/iprediction.h b/sp/src/public/iprediction.h new file mode 100644 index 00000000..858bff3b --- /dev/null +++ b/sp/src/public/iprediction.h @@ -0,0 +1,67 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// +#if !defined( IPREDICTION_H ) +#define IPREDICTION_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "interface.h" +#include "mathlib/vector.h" // Solely to get at define for QAngle + + +class IMoveHelper; + +//----------------------------------------------------------------------------- +// Purpose: Engine interface into client side prediction system +//----------------------------------------------------------------------------- +abstract_class IPrediction +{ +public: + virtual ~IPrediction( void ) {}; + + virtual void Init( void ) = 0; + virtual void Shutdown( void ) = 0; + + // Run prediction + virtual void Update + ( + int startframe, // World update ( un-modded ) most recently received + bool validframe, // Is frame data valid + int incoming_acknowledged, // Last command acknowledged to have been run by server (un-modded) + int outgoing_command // Last command (most recent) sent to server (un-modded) + ) = 0; + + // We are about to get a network update from the server. We know the update #, so we can pull any + // data purely predicted on the client side and transfer it to the new from data state. + virtual void PreEntityPacketReceived( int commands_acknowledged, int current_world_update_packet ) = 0; + virtual void PostEntityPacketReceived( void ) = 0; + virtual void PostNetworkDataReceived( int commands_acknowledged ) = 0; + + virtual void OnReceivedUncompressedPacket( void ) = 0; + + // The engine needs to be able to access a few predicted values + virtual void GetViewOrigin( Vector& org ) = 0; + virtual void SetViewOrigin( Vector& org ) = 0; + virtual void GetViewAngles( QAngle& ang ) = 0; + virtual void SetViewAngles( QAngle& ang ) = 0; + virtual void GetLocalViewAngles( QAngle& ang ) = 0; + virtual void SetLocalViewAngles( QAngle& ang ) = 0; +}; + +extern IPrediction *g_pClientSidePrediction; + +#define VCLIENT_PREDICTION_INTERFACE_VERSION "VClientPrediction001" + +#endif // IPREDICTION_H diff --git a/sp/src/public/irecipientfilter.h b/sp/src/public/irecipientfilter.h new file mode 100644 index 00000000..001e0ce5 --- /dev/null +++ b/sp/src/public/irecipientfilter.h @@ -0,0 +1,29 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef IRECIPIENTFILTER_H +#define IRECIPIENTFILTER_H +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +// Purpose: Generic interface for routing messages to users +//----------------------------------------------------------------------------- +class IRecipientFilter +{ +public: + virtual ~IRecipientFilter() {} + + virtual bool IsReliable( void ) const = 0; + virtual bool IsInitMessage( void ) const = 0; + + virtual int GetRecipientCount( void ) const = 0; + virtual int GetRecipientIndex( int slot ) const = 0; +}; + +#endif // IRECIPIENTFILTER_H diff --git a/sp/src/public/iregistry.h b/sp/src/public/iregistry.h new file mode 100644 index 00000000..9280680a --- /dev/null +++ b/sp/src/public/iregistry.h @@ -0,0 +1,52 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// +#if !defined( UTIL_REGISTRY_H ) +#define UTIL_REGISTRY_H +#ifdef _WIN32 +#pragma once +#endif + +#include "tier0/platform.h" + + +//----------------------------------------------------------------------------- +// Purpose: Interface to registry +//----------------------------------------------------------------------------- +abstract_class IRegistry +{ +public: + // We have to have a virtual destructor since otherwise the derived class destructors + // will not be called. + virtual ~IRegistry() {} + + // Init/shutdown + virtual bool Init( const char *platformName ) = 0; + virtual void Shutdown( void ) = 0; + + // Read/write integers + virtual int ReadInt( const char *key, int defaultValue = 0 ) = 0; + virtual void WriteInt( const char *key, int value ) = 0; + + // Read/write strings + virtual const char *ReadString( const char *key, const char *defaultValue = 0 ) = 0; + virtual void WriteString( const char *key, const char *value ) = 0; + + // Read/write helper methods + virtual int ReadInt( const char *pKeyBase, const char *pKey, int defaultValue = 0 ) = 0; + virtual void WriteInt( const char *pKeyBase, const char *key, int value ) = 0; + virtual const char *ReadString( const char *pKeyBase, const char *key, const char *defaultValue ) = 0; + virtual void WriteString( const char *pKeyBase, const char *key, const char *value ) = 0; +}; + +extern IRegistry *registry; + +// Creates it and calls Init +IRegistry *InstanceRegistry( char const *subDirectoryUnderValve ); +// Calls Shutdown and deletes it +void ReleaseInstancedRegistry( IRegistry *reg ); + +#endif // UTIL_REGISTRY_H diff --git a/sp/src/public/isaverestore.h b/sp/src/public/isaverestore.h new file mode 100644 index 00000000..bfb40a17 --- /dev/null +++ b/sp/src/public/isaverestore.h @@ -0,0 +1,387 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef ISAVERESTORE_H +#define ISAVERESTORE_H + +#include "string_t.h" +#include "datamap.h" +#include "mathlib/vmatrix.h" + +#if defined( _WIN32 ) +#pragma once +#endif + +#ifndef CLIENT_DLL +class SINGLE_INHERITANCE CBaseEntity; +#endif + +class Vector; +class VMatrix; +struct edict_t; +template< class T > class CHandle; +typedef CHandle EHANDLE; +struct matrix3x4_t; + +class CSaveRestoreData; +class CGameSaveRestoreInfo; + +class ISave; +class IRestore; + +//----------------------------------------------------------------------------- + +#pragma pack(push,1) + +struct SaveRestoreRecordHeader_t +{ + unsigned short size; + unsigned short symbol; +}; + + +#pragma pack(pop) + +//----------------------------------------------------------------------------- +// +// ISaveRestoreBlockHandler +// +//----------------------------------------------------------------------------- + +const int MAX_BLOCK_NAME_LEN = 31; +const int SIZE_BLOCK_NAME_BUF = 31 + 1; + +//------------------------------------- + +abstract_class ISaveRestoreBlockHandler +{ +public: + virtual const char *GetBlockName() = 0; + + virtual void PreSave( CSaveRestoreData * ) = 0; // Called immediately prior to save, generally used to set up any necessary tables + virtual void Save( ISave * ) = 0; + virtual void WriteSaveHeaders( ISave * ) = 0; // Called after save to allow the writing out of any dictionaries/tables/indexes generated during save + virtual void PostSave() = 0; + + virtual void PreRestore() = 0; + virtual void ReadRestoreHeaders( IRestore * ) = 0; // Called prior to Restore() + virtual void Restore( IRestore *, bool fCreatePlayers ) = 0; + virtual void PostRestore() = 0; +}; + +//------------------------------------- + +abstract_class ISaveRestoreBlockSet : public ISaveRestoreBlockHandler +{ +public: + virtual void AddBlockHandler( ISaveRestoreBlockHandler *pHandler ) = 0; + virtual void RemoveBlockHandler( ISaveRestoreBlockHandler *pHandler ) = 0; + virtual void CallBlockHandlerRestore( ISaveRestoreBlockHandler *pHandler, int baseFilePos, IRestore *pRestore, bool fCreatePlayers ) = 0; +}; + +extern ISaveRestoreBlockSet *g_pGameSaveRestoreBlockSet; + +//------------------------------------- + +abstract_class CDefSaveRestoreBlockHandler : public ISaveRestoreBlockHandler +{ + virtual const char *GetBlockName() = 0; + + virtual void PreSave( CSaveRestoreData * ) {} + virtual void Save( ISave * ) {} + virtual void WriteSaveHeaders( ISave * ) {} + virtual void PostSave() {} + + virtual void PreRestore() {} + virtual void ReadRestoreHeaders( IRestore * ) {} + virtual void Restore( IRestore *, bool fCreatePlayers ) {} + virtual void PostRestore() {} +}; + +//----------------------------------------------------------------------------- +// +// ISave +// +//----------------------------------------------------------------------------- + +abstract_class ISave +{ +public: + + //--------------------------------- + // Logging + virtual void StartLogging( const char *pszLogName ) = 0; + virtual void EndLogging( void ) = 0; + + //--------------------------------- + virtual bool IsAsync() = 0; + + //--------------------------------- + + virtual int GetWritePos() const = 0; + virtual void SetWritePos(int pos) = 0; + + //--------------------------------- + // Datamap based writing + // + + virtual int WriteAll( const void *pLeafObject, datamap_t *pLeafMap ) = 0; + virtual int WriteFields( const char *pname, const void *pBaseData, datamap_t *pMap, typedescription_t *pFields, int fieldCount ) = 0; + + template + int WriteAll( const T *pLeafObject ) + { + return WriteAll( pLeafObject, &pLeafObject->m_DataMap ); + } + + //--------------------------------- + // Block support + // + // Using these, one doesn't have to worry about queuing up the read pointer on restore if only + // a subset of the data is read + // + + virtual void StartBlock( const char *pszBlockName ) = 0; + virtual void StartBlock() = 0; + virtual void EndBlock() = 0; + + //--------------------------------- + // Primitive types + // + + virtual void WriteShort( const short *value, int count = 1 ) = 0; + virtual void WriteInt( const int *value, int count = 1 ) = 0; // Save an int + inline void WriteInt( const unsigned *value, int count = 1 ) { WriteInt( (int *)value, count ); } + virtual void WriteBool( const bool *value, int count = 1 ) = 0; // Save a bool + virtual void WriteFloat( const float *value, int count = 1 ) = 0; // Save a float + virtual void WriteData( const char *pdata, int size ) = 0; // Save a binary data block + virtual void WriteString( const char *pstring ) = 0; // Save a null-terminated string + virtual void WriteString( const string_t *stringId, int count = 1 ) = 0; // Save a null-terminated string (engine string) + virtual void WriteVector( const Vector &value ) = 0; // Save a vector + virtual void WriteVector( const Vector *value, int count = 1 ) = 0; // Save a vector array + virtual void WriteQuaternion( const Quaternion &value ) = 0; // Save a Quaternion + virtual void WriteQuaternion( const Quaternion *value, int count = 1 ) = 0; // Save a Quaternion array + + // Note: All of the following will write out both a header and the data. On restore, + // this needs to be cracked + virtual void WriteShort( const char *pname, const short *value, int count = 1 ) = 0; + virtual void WriteInt( const char *pname, const int *value, int count = 1 ) = 0; // Save an int + virtual void WriteBool( const char *pname, const bool *value, int count = 1 ) = 0; // Save a bool + virtual void WriteFloat( const char *pname, const float *value, int count = 1 ) = 0; // Save a float + virtual void WriteData( const char *pname, int size, const char *pdata ) = 0; // Save a binary data block + virtual void WriteString( const char *pname, const char *pstring ) = 0; // Save a null-terminated string + virtual void WriteString( const char *pname, const string_t *stringId, int count = 1 ) = 0; // Save a null-terminated string (engine string) + virtual void WriteVector( const char *pname, const Vector &value ) = 0; // Save a vector + virtual void WriteVector( const char *pname, const Vector *value, int count = 1 ) = 0; // Save a vector array + virtual void WriteQuaternion( const char *pname, const Quaternion &value ) = 0; // Save a Quaternion + virtual void WriteQuaternion( const char *pname, const Quaternion *value, int count = 1 ) = 0; // Save a Quaternion array + + //--------------------------------- + // Game types + // + + virtual void WriteTime( const char *pname, const float *value, int count = 1 ) = 0; // Save a float (timevalue) + virtual void WriteTick( const char *pname, const int *value, int count = 1 ) = 0; // Save a tick (timevalue) + virtual void WritePositionVector( const char *pname, const Vector &value ) = 0; // Offset for landmark if necessary + virtual void WritePositionVector( const char *pname, const Vector *value, int count = 1 ) = 0; // array of pos vectors + virtual void WriteFunction( datamap_t *pMap, const char *pname, inputfunc_t **value, int count = 1 ) = 0; // Save a function pointer + + virtual void WriteTime( const float *value, int count = 1 ) = 0; // Save a float (timevalue) + virtual void WriteTick( const int *value, int count = 1 ) = 0; // Save a tick (timevalue) + virtual void WritePositionVector( const Vector &value ) = 0; // Offset for landmark if necessary + virtual void WritePositionVector( const Vector *value, int count = 1 ) = 0; // array of pos vectors + + virtual void WriteEntityPtr( const char *pname, CBaseEntity **ppEntity, int count = 1 ) = 0; + virtual void WriteEdictPtr( const char *pname, edict_t **ppEdict, int count = 1 ) = 0; + virtual void WriteEHandle( const char *pname, const EHANDLE *pEHandle, int count = 1 ) = 0; + + virtual void WriteEntityPtr( CBaseEntity **ppEntity, int count = 1 ) = 0; + virtual void WriteEdictPtr( edict_t **ppEdict, int count = 1 ) = 0; + virtual void WriteEHandle( const EHANDLE *pEHandle, int count = 1 ) = 0; + + //--------------------------------- + // Back door to support somewhat awkward ownership of game save/restore data + virtual CGameSaveRestoreInfo *GetGameSaveRestoreInfo() = 0; + +protected: + virtual ~ISave() {}; +}; + +//----------------------------------------------------------------------------- +// +// IRestore +// +//----------------------------------------------------------------------------- + +abstract_class IRestore +{ +public: + + //--------------------------------- + + virtual int GetReadPos() const = 0; + virtual void SetReadPos( int pos ) = 0; + + //--------------------------------- + // Datamap based reading + // + + virtual int ReadAll( void *pLeafObject, datamap_t *pLeafMap ) = 0; + + virtual int ReadFields( const char *pname, void *pBaseData, datamap_t *pMap, typedescription_t *pFields, int fieldcount = 1 ) = 0; + virtual void EmptyFields( void *pBaseData, typedescription_t *pFields, int fieldcount = 1 ) = 0; + + template + int ReadAll( T *pLeafObject ) + { + return ReadAll( pLeafObject, &pLeafObject->m_DataMap ); + } + + //--------------------------------- + // Block support + // + + virtual void StartBlock( SaveRestoreRecordHeader_t *pHeader ) = 0; + virtual void StartBlock( char szBlockName[SIZE_BLOCK_NAME_BUF] ) = 0; + virtual void StartBlock() = 0; + virtual void EndBlock() = 0; + + //--------------------------------- + // Field header cracking + // + + virtual void ReadHeader( SaveRestoreRecordHeader_t *pheader ) = 0; + virtual int SkipHeader() = 0; // skips the header, but returns the size of the field + virtual const char *StringFromHeaderSymbol( int symbol ) = 0; + + //--------------------------------- + // Primitive types + // + + virtual short ReadShort( void ) = 0; + virtual int ReadShort( short *pValue, int count = 1, int nBytesAvailable = 0 ) = 0; + virtual int ReadInt( int *pValue, int count = 1, int nBytesAvailable = 0 ) = 0; + inline int ReadInt( unsigned *pValue, int count = 1, int nBytesAvailable = 0 ) { return ReadInt( (int *)pValue, count, nBytesAvailable ); } + virtual int ReadInt( void ) = 0; + virtual int ReadBool( bool *pValue, int count = 1, int nBytesAvailable = 0 ) = 0; + virtual int ReadFloat( float *pValue, int count = 1, int nBytesAvailable = 0 ) = 0; + virtual int ReadData( char *pData, int size, int nBytesAvailable ) = 0; + virtual void ReadString( char *pDest, int nSizeDest, int nBytesAvailable ) = 0; // A null-terminated string + virtual int ReadString( string_t *pString, int count = 1, int nBytesAvailable = 0 ) = 0; + virtual int ReadVector( Vector *pValue ) = 0; + virtual int ReadVector( Vector *pValue, int count = 1, int nBytesAvailable = 0 ) = 0; + virtual int ReadQuaternion( Quaternion *pValue ) = 0; + virtual int ReadQuaternion( Quaternion *pValue, int count = 1, int nBytesAvailable = 0 ) = 0; + + //--------------------------------- + // Game types + // + + virtual int ReadTime( float *pValue, int count = 1, int nBytesAvailable = 0 ) = 0; + virtual int ReadTick( int *pValue, int count = 1, int nBytesAvailable = 0 ) = 0; + virtual int ReadPositionVector( Vector *pValue ) = 0; + virtual int ReadPositionVector( Vector *pValue, int count = 1, int nBytesAvailable = 0 ) = 0; + virtual int ReadFunction( datamap_t *pMap, inputfunc_t **pValue, int count = 1, int nBytesAvailable = 0) = 0; + + virtual int ReadEntityPtr( CBaseEntity **ppEntity, int count = 1, int nBytesAvailable = 0 ) = 0; + virtual int ReadEdictPtr( edict_t **ppEdict, int count = 1, int nBytesAvailable = 0 ) = 0; + virtual int ReadEHandle( EHANDLE *pEHandle, int count = 1, int nBytesAvailable = 0 ) = 0; + virtual int ReadVMatrix( VMatrix *pValue, int count = 1, int nBytesAvailable = 0) = 0; + virtual int ReadVMatrixWorldspace( VMatrix *pValue, int count = 1, int nBytesAvailable = 0) = 0; + virtual int ReadMatrix3x4Worldspace( matrix3x4_t *pValue, int nElems = 1, int nBytesAvailable = 0 ) = 0; + + //--------------------------------- + + virtual bool GetPrecacheMode( void ) = 0; + + //--------------------------------- + // Back door to support somewhat awkward ownership of game save/restore data + virtual CGameSaveRestoreInfo *GetGameSaveRestoreInfo() = 0; + +protected: + virtual ~IRestore() {}; +}; + +//----------------------------------------------------------------------------- +// Purpose: The operations necessary to save and restore custom types (FIELD_CUSTOM) +// +// + +struct SaveRestoreFieldInfo_t +{ + void * pField; + + // Note that it is legal for the following two fields to be NULL, + // though it may be disallowed by implementors of ISaveRestoreOps + void * pOwner; + typedescription_t *pTypeDesc; +}; + +abstract_class ISaveRestoreOps +{ +public: + // save data type interface + virtual void Save( const SaveRestoreFieldInfo_t &fieldInfo, ISave *pSave ) = 0; + virtual void Restore( const SaveRestoreFieldInfo_t &fieldInfo, IRestore *pRestore ) = 0; + + virtual bool IsEmpty( const SaveRestoreFieldInfo_t &fieldInfo ) = 0; + virtual void MakeEmpty( const SaveRestoreFieldInfo_t &fieldInfo ) = 0; + virtual bool Parse( const SaveRestoreFieldInfo_t &fieldInfo, char const* szValue ) = 0; + + //--------------------------------- + + void Save( void *pField, ISave *pSave ) { SaveRestoreFieldInfo_t fieldInfo = { pField, NULL, NULL }; Save( fieldInfo, pSave ); } + void Restore( void *pField, IRestore *pRestore ) { SaveRestoreFieldInfo_t fieldInfo = { pField, NULL, NULL }; Restore( fieldInfo, pRestore ); } + + bool IsEmpty( void *pField) { SaveRestoreFieldInfo_t fieldInfo = { pField, NULL, NULL }; return IsEmpty( fieldInfo ); } + void MakeEmpty( void *pField) { SaveRestoreFieldInfo_t fieldInfo = { pField, NULL, NULL }; MakeEmpty( fieldInfo ); } + bool Parse( void *pField, char const *pszValue ) { SaveRestoreFieldInfo_t fieldInfo = { pField, NULL, NULL }; return Parse( fieldInfo, pszValue ); } +}; + +//------------------------------------- + +class CDefSaveRestoreOps : public ISaveRestoreOps +{ +public: + // save data type interface + virtual void Save( const SaveRestoreFieldInfo_t &fieldInfo, ISave *pSave ) {} + virtual void Restore( const SaveRestoreFieldInfo_t &fieldInfo, IRestore *pRestore ) {} + + virtual bool IsEmpty( const SaveRestoreFieldInfo_t &fieldInfo ) { return false; } + virtual void MakeEmpty( const SaveRestoreFieldInfo_t &fieldInfo ) {} + virtual bool Parse( const SaveRestoreFieldInfo_t &fieldInfo, char const* szValue ) { return false; } +}; + + +//----------------------------------------------------------------------------- +// Used by ops that deal with pointers +//----------------------------------------------------------------------------- +class CClassPtrSaveRestoreOps : public CDefSaveRestoreOps +{ +public: + virtual bool IsEmpty( const SaveRestoreFieldInfo_t &fieldInfo ) + { + void **ppClassPtr = (void **)fieldInfo.pField; + int nObjects = fieldInfo.pTypeDesc->fieldSize; + for ( int i = 0; i < nObjects; i++ ) + { + if ( ppClassPtr[i] != NULL ) + return false; + } + return true; + } + + virtual void MakeEmpty( const SaveRestoreFieldInfo_t &fieldInfo ) + { + memset( fieldInfo.pField, 0, fieldInfo.pTypeDesc->fieldSize * sizeof( void * ) ); + } +}; + + +//============================================================================= + +#endif // ISAVERESTORE_H diff --git a/sp/src/public/iscratchpad3d.h b/sp/src/public/iscratchpad3d.h new file mode 100644 index 00000000..82e43654 --- /dev/null +++ b/sp/src/public/iscratchpad3d.h @@ -0,0 +1,326 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef ISCRATCHPAD3D_H +#define ISCRATCHPAD3D_H +#ifdef _WIN32 +#pragma once +#endif + + +// IScratchPad3D will store drawing commands in a file to be viewed by ScratchPad3DViewer. +// It can be used while stepping through geometry code to visualize what is going on as +// drawing commands will be immediately visible in ScratchPad3DViewer even while you're stuck +// in the debugger + +// ScratchPad3DViewer initially orbits 100 inches from the origin, so it can be useful +// to call SetMapping to map what you're drawing input into this cube. + + +#include "mathlib/vector.h" +#include "mathlib/vector2d.h" +#include "utlvector.h" + +class IFileSystem; + + +class CSPColor +{ +public: + CSPColor() + { + m_flAlpha = 1; + } + CSPColor( const Vector &vColor, float flAlpha=1 ) + { + m_vColor = vColor; + m_flAlpha = flAlpha; + } + CSPColor( float r, float g, float b, float a=1 ) + { + m_vColor.Init( r, g, b ); + m_flAlpha = a; + } + + Vector m_vColor; + float m_flAlpha; +}; + + +class CSPVert +{ +public: + CSPVert(); + CSPVert( Vector const &vPos, const CSPColor &vColor=CSPColor( Vector(1, 1, 1), 1 ) ); + + void Init( Vector const &vPos, const CSPColor &vColor=CSPColor( Vector(1, 1, 1), 1 ) ); + +public: + Vector m_vPos; + CSPColor m_vColor; +}; + + +class CSPVertList +{ +public: + CSPVertList( int nVerts = 0 ); + CSPVertList(CSPVert const *pVerts, int nVerts); + CSPVertList(Vector const *pVerts, int nVerts, CSPColor vColor=CSPColor(1,1,1) ); + + CSPVertList(Vector const *pVerts, Vector const *pColors, int nVerts); + CSPVertList(Vector const *pVerts, CSPColor const *pColors, int nVerts); + + CSPVertList(Vector const &vert1, CSPColor const &color1, + Vector const &vert2, CSPColor const &color2, + Vector const &vert3, CSPColor const &color3); + + CUtlVector m_Verts; +}; + +class SPRGBA +{ +public: + unsigned char r,g,b,a; +}; + + +class CTextParams +{ +public: + CTextParams(); + + + Vector m_vColor; // Color of the string (starting color.. at some point, + // we can embed commands in the text itself to change the color). + float m_flAlpha; // Alpha of the whole thing. + + bool m_bSolidBackground; // Should the background be solid or alpha'd? + + // Draw an outline around the text? + bool m_bOutline; + + Vector m_vPos; // Where to render the text. + bool m_bCentered; // Centered on m_vPos, or is m_vPos the upper-left corner? + + QAngle m_vAngles; // Orientation of the text. + bool m_bTwoSided; // Render the text from both sides? + + float m_flLetterWidth; // Letter width in world space. +}; + + +abstract_class IScratchPad3D +{ +protected: + + virtual ~IScratchPad3D() {} + + +// Types. +public: + + enum RenderState + { + RS_FillMode=0, // val = one of the FillMode enums + RS_ZRead, + RS_ZBias // val = 0 - 16 to push Z towards viewer + }; + + enum FillMode + { + FillMode_Wireframe=0, + FillMode_Solid + }; + + +public: + + virtual void Release() = 0; + + // This sets up a mapping between input coordinates and output coordinates. + // This can be used to zoom into an area of interest where you'll be drawing things. + // An alternative is to press Z while in VisLibViewer to have it center and zoom on + // everything that has been drawn. + virtual void SetMapping( + Vector const &vInputMin, + Vector const &vInputMax, + Vector const &vOutputMin, + Vector const &vOutputMax ) = 0; + + // Enable/disable auto flush. When set to true (the default), all drawing commands + // are immediately written to the file and will show up in VisLibViewer right away. + // If you want to draw a lot of things, you can set this to false and call Flush() + // manually when you want the file written out. + // When you set auto flush to true, it calls Flush(). + virtual bool GetAutoFlush() = 0; + virtual void SetAutoFlush( bool bAutoFlush ) = 0; + + // Draw a point. Point size is (roughly) in world coordinates, so points + // get smaller as the viewer moves away. + virtual void DrawPoint( CSPVert const &v, float flPointSize ) = 0; + + // Draw a line. + virtual void DrawLine( CSPVert const &v1, CSPVert const &v2 ) = 0; + + // Draw a polygon. + virtual void DrawPolygon( CSPVertList const &verts ) = 0; + + // Draw 2D rectangles. + virtual void DrawRectYZ( float xPos, Vector2D const &vMin, Vector2D const &vMax, const CSPColor &vColor ) = 0; + virtual void DrawRectXZ( float yPos, Vector2D const &vMin, Vector2D const &vMax, const CSPColor &vColor ) = 0; + virtual void DrawRectXY( float zPos, Vector2D const &vMin, Vector2D const &vMax, const CSPColor &vColor ) = 0; + + // Draw a wireframe box. + virtual void DrawWireframeBox( Vector const &vMin, Vector const &vMax, Vector const &vColor ) = 0; + + // Draw some text. + virtual void DrawText( const char *pStr, const CTextParams ¶ms ) = 0; + + // Wireframe on/off. + virtual void SetRenderState( RenderState state, unsigned long val ) = 0; + + // Clear all the drawing commands. + virtual void Clear() = 0; + + // Calling this writes all the commands to the file. If AutoFlush is true, this is called + // automatically in all the drawing commands. + virtual void Flush() = 0; + + +// Primitives that build on the atomic primitives. +public: + + // Draw a black and white image. + // Corners are in this order: bottom-left, top-left, top-right, bottom-right. + // If the corners are NULL, then the image is drawn in the XY plane from (-100,-100) to (100,100). + virtual void DrawImageBW( + unsigned char const *pData, + int width, + int height, + int pitchInBytes, + bool bOutlinePixels=true, + bool bOutlineImage=false, + Vector *vCorners=NULL ) = 0; + + // Draw an RGBA image. + // Corners are in this order: bottom-left, top-left, top-right, bottom-right. + virtual void DrawImageRGBA( + SPRGBA *pData, + int width, + int height, + int pitchInBytes, + bool bOutlinePixels=true, + bool bOutlineImage=false, + Vector *vCorners=NULL ) = 0; +}; + + +// Just a helper for functions where you want to have a CScratchPad3D around +// and release it automatically when the function exits. +class CScratchPadAutoRelease +{ +public: + CScratchPadAutoRelease( IScratchPad3D *pPad ) { m_pPad = pPad; } + ~CScratchPadAutoRelease() { if( m_pPad ) m_pPad->Release(); } + + IScratchPad3D *m_pPad; +}; + + + +IScratchPad3D* ScratchPad3D_Create( char const *pFilename = "scratch.pad" ); + + + +// ------------------------------------------------------------------------------------ // +// Inlines. +// ------------------------------------------------------------------------------------ // + +inline CTextParams::CTextParams() +{ + m_vColor.Init( 1, 1, 1 ); + m_flAlpha = 1; + m_bSolidBackground = true; + m_bOutline = true; + m_vPos.Init(); + m_bCentered = true; + m_vAngles.Init(); + m_bTwoSided = true; + m_flLetterWidth = 3; +} + +inline CSPVert::CSPVert() +{ +} + +inline CSPVert::CSPVert( Vector const &vPos, const CSPColor &vColor ) +{ + Init( vPos, vColor ); +} + +inline void CSPVert::Init( Vector const &vPos, const CSPColor &vColor ) +{ + m_vPos = vPos; + m_vColor = vColor; +} + + +inline CSPVertList::CSPVertList( int nVerts ) +{ + if( nVerts ) + m_Verts.AddMultipleToTail( nVerts ); +} + +inline CSPVertList::CSPVertList(CSPVert const *pVerts, int nVerts ) +{ + m_Verts.CopyArray( pVerts, nVerts ); +} + +inline CSPVertList::CSPVertList(Vector const *pVerts, int nVerts, CSPColor vColor ) +{ + m_Verts.AddMultipleToTail( nVerts ); + for( int i=0; i < nVerts; i++ ) + { + m_Verts[i].m_vPos = pVerts[i]; + m_Verts[i].m_vColor = vColor; + } +} + +inline CSPVertList::CSPVertList( Vector const *pVerts, Vector const *pColors, int nVerts ) +{ + m_Verts.AddMultipleToTail( nVerts ); + for( int i=0; i < nVerts; i++ ) + { + m_Verts[i].m_vPos = pVerts[i]; + m_Verts[i].m_vColor = pColors[i]; + } +} + +inline CSPVertList::CSPVertList( Vector const *pVerts, CSPColor const *pColors, int nVerts ) +{ + m_Verts.AddMultipleToTail( nVerts ); + for( int i=0; i < nVerts; i++ ) + { + m_Verts[i].m_vPos = pVerts[i]; + m_Verts[i].m_vColor = pColors[i]; + } +} + +inline CSPVertList::CSPVertList( + Vector const &vert1, CSPColor const &color1, + Vector const &vert2, CSPColor const &color2, + Vector const &vert3, CSPColor const &color3 ) +{ + m_Verts.AddMultipleToTail( 3 ); + m_Verts[0].Init( vert1, color1 ); + m_Verts[1].Init( vert2, color2 ); + m_Verts[2].Init( vert3, color3 ); +} + + +#endif // ISCRATCHPAD3D_H diff --git a/sp/src/public/iserver.h b/sp/src/public/iserver.h new file mode 100644 index 00000000..9e59355a --- /dev/null +++ b/sp/src/public/iserver.h @@ -0,0 +1,68 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef ISERVER_H +#define ISERVER_H +#ifdef _WIN32 +#pragma once +#endif + +#include +#include +#include + +class INetMessage; +class IRecipientFilter; +class IClient; + +typedef struct player_info_s player_info_t; + +abstract_class IServer : public IConnectionlessPacketHandler +{ +public: + virtual ~IServer() {} + + virtual int GetNumClients( void ) const = 0; // returns current number of clients + virtual int GetNumProxies( void ) const = 0; // returns number of attached HLTV proxies + virtual int GetNumFakeClients() const = 0; // returns number of fake clients/bots + virtual int GetMaxClients( void ) const = 0; // returns current client limit + virtual IClient *GetClient( int index ) = 0; // returns interface to client + virtual int GetClientCount() const = 0; // returns number of clients slots (used & unused) + virtual int GetUDPPort( void ) const = 0; // returns current used UDP port + virtual float GetTime( void ) const = 0; // returns game world time + virtual int GetTick( void ) const = 0; // returns game world tick + virtual float GetTickInterval( void ) const = 0; // tick interval in seconds + virtual const char *GetName( void ) const = 0; // public server name + virtual const char *GetMapName( void ) const = 0; // current map name (BSP) + virtual int GetSpawnCount( void ) const = 0; + virtual int GetNumClasses( void ) const = 0; + virtual int GetClassBits( void ) const = 0; + virtual void GetNetStats( float &avgIn, float &avgOut ) = 0; // total net in/out in bytes/sec + virtual int GetNumPlayers() = 0; + virtual bool GetPlayerInfo( int nClientIndex, player_info_t *pinfo ) = 0; + + virtual bool IsActive( void ) const = 0; + virtual bool IsLoading( void ) const = 0; + virtual bool IsDedicated( void ) const = 0; + virtual bool IsPaused( void ) const = 0; + virtual bool IsMultiplayer( void ) const = 0; + virtual bool IsPausable() const = 0; + virtual bool IsHLTV() const = 0; + virtual bool IsReplay() const = 0; + + virtual const char * GetPassword() const = 0; // returns the password or NULL if none set + + virtual void SetPaused(bool paused) = 0; + virtual void SetPassword(const char *password) = 0; // set password (NULL to disable) + + virtual void BroadcastMessage( INetMessage &msg, bool onlyActive = false, bool reliable = false) = 0; + virtual void BroadcastMessage( INetMessage &msg, IRecipientFilter &filter ) = 0; + + virtual void DisconnectClient( IClient *client, const char *reason ) = 0; +}; + + +#endif // ISERVER_H diff --git a/sp/src/public/iserverentity.h b/sp/src/public/iserverentity.h new file mode 100644 index 00000000..a53e9c34 --- /dev/null +++ b/sp/src/public/iserverentity.h @@ -0,0 +1,42 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef ISERVERENTITY_H +#define ISERVERENTITY_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "iserverunknown.h" +#include "string_t.h" + + + +struct Ray_t; +class ServerClass; +class ICollideable; +class IServerNetworkable; +class Vector; +class QAngle; + +// This class is how the engine talks to entities in the game DLL. +// CBaseEntity implements this interface. +class IServerEntity : public IServerUnknown +{ +public: + virtual ~IServerEntity() {} + +// Previously in pev + virtual int GetModelIndex( void ) const = 0; + virtual string_t GetModelName( void ) const = 0; + + virtual void SetModelIndex( int index ) = 0; +}; + + +#endif // ISERVERENTITY_H diff --git a/sp/src/public/iservernetworkable.h b/sp/src/public/iservernetworkable.h new file mode 100644 index 00000000..cefa7534 --- /dev/null +++ b/sp/src/public/iservernetworkable.h @@ -0,0 +1,114 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef ISERVERNETWORKABLE_H +#define ISERVERNETWORKABLE_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "ihandleentity.h" +#include "basetypes.h" +#include "bitvec.h" +#include "const.h" +#include "bspfile.h" + + + +// Entities can span this many clusters before we revert to a slower area checking algorithm +#define MAX_FAST_ENT_CLUSTERS 4 +#define MAX_ENT_CLUSTERS 64 +#define MAX_WORLD_AREAS 8 + + +class ServerClass; +class SendTable; +struct edict_t; +class CBaseEntity; +class CSerialEntity; +class CBaseNetworkable; + + +class CCheckTransmitInfo +{ +public: + edict_t *m_pClientEnt; // pointer to receiver edict + byte m_PVS[PAD_NUMBER( MAX_MAP_CLUSTERS,8 ) / 8]; + int m_nPVSSize; // PVS size in bytes + + CBitVec *m_pTransmitEdict; // entity n is already marked for transmission + CBitVec *m_pTransmitAlways; // entity n is always sent even if not in PVS (HLTV and Replay only) + + int m_AreasNetworked; // number of networked areas + int m_Areas[MAX_WORLD_AREAS]; // the areas + + // This is used to determine visibility, so if the previous state + // is the same as the current state (along with pvs and areas networked), + // then the parts of the map that the player can see haven't changed. + byte m_AreaFloodNums[MAX_MAP_AREAS]; + int m_nMapAreas; +}; + +//----------------------------------------------------------------------------- +// Stores information necessary to perform PVS testing. +//----------------------------------------------------------------------------- +struct PVSInfo_t +{ + // headnode for the entity's bounding box + short m_nHeadNode; + + // number of clusters or -1 if too many + short m_nClusterCount; + + // cluster indices + unsigned short *m_pClusters; + + // For dynamic "area portals" + short m_nAreaNum; + short m_nAreaNum2; + + // current position + float m_vCenter[3]; + +private: + unsigned short m_pClustersInline[MAX_FAST_ENT_CLUSTERS]; + + friend class CVEngineServer; +}; + + +// IServerNetworkable is the interface the engine uses for all networkable data. +class IServerNetworkable +{ +// These functions are handled automatically by the server_class macros and CBaseNetworkable. +public: + // Gets at the entity handle associated with the collideable + virtual IHandleEntity *GetEntityHandle() = 0; + + // Tell the engine which class this object is. + virtual ServerClass* GetServerClass() = 0; + + virtual edict_t *GetEdict() const = 0; + + virtual const char* GetClassName() const = 0; + virtual void Release() = 0; + + virtual int AreaNum() const = 0; + + // In place of a generic QueryInterface. + virtual CBaseNetworkable* GetBaseNetworkable() = 0; + virtual CBaseEntity* GetBaseEntity() = 0; // Only used by game code. + virtual PVSInfo_t* GetPVSInfo() = 0; // get current visibilty data + +protected: + // Should never call delete on this! + virtual ~IServerNetworkable() {} +}; + + +#endif // ISERVERNETWORKABLE_H diff --git a/sp/src/public/iserverunknown.h b/sp/src/public/iserverunknown.h new file mode 100644 index 00000000..97f3c998 --- /dev/null +++ b/sp/src/public/iserverunknown.h @@ -0,0 +1,35 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef ISERVERUNKNOWN_H +#define ISERVERUNKNOWN_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "ihandleentity.h" + +class ICollideable; +class IServerNetworkable; +class CBaseEntity; + + +// This is the server's version of IUnknown. We may want to use a QueryInterface-like +// mechanism if this gets big. +class IServerUnknown : public IHandleEntity +{ +public: + // Gets the interface to the collideable + networkable representation of the entity + virtual ICollideable* GetCollideable() = 0; + virtual IServerNetworkable* GetNetworkable() = 0; + virtual CBaseEntity* GetBaseEntity() = 0; +}; + + +#endif // ISERVERUNKNOWN_H diff --git a/sp/src/public/ishadercompiledll.h b/sp/src/public/ishadercompiledll.h new file mode 100644 index 00000000..03a1d1c9 --- /dev/null +++ b/sp/src/public/ishadercompiledll.h @@ -0,0 +1,26 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef ISHADERCOMPILEDLL_H +#define ISHADERCOMPILEDLL_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "interface.h" + +#define SHADER_COMPILE_INTERFACE_VERSION "shadercompiledll_0" + +// This is the DLL interface to ShaderCompile +abstract_class IShaderCompileDLL +{ +public: + // All vrad.exe does is load the VRAD DLL and run this. + virtual int main( int argc, char **argv ) = 0; +}; + +#endif // ISHADERCOMPILEDLL_H diff --git a/sp/src/public/isoundcombiner.h b/sp/src/public/isoundcombiner.h new file mode 100644 index 00000000..8c90a29e --- /dev/null +++ b/sp/src/public/isoundcombiner.h @@ -0,0 +1,40 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef ISOUNDCOMBINER_H +#define ISOUNDCOMBINER_H +#ifdef _WIN32 +#pragma once +#endif + +#include "utlvector.h" + +class IFileSystem; + +struct CombinerEntry +{ + CombinerEntry() + { + wavefile[ 0 ] = 0; + startoffset = 0.0f; + } + + char wavefile[ MAX_PATH ]; + float startoffset; +}; + +abstract_class ISoundCombiner +{ +public: + virtual ~ISoundCombiner() {} + + virtual bool CombineSoundFiles( IFileSystem *filesystem, char const *outfile, CUtlVector< CombinerEntry >& info ) = 0; + virtual bool IsCombinedFileChecksumValid( IFileSystem *filesystem, char const *outfile, CUtlVector< CombinerEntry >& info ) = 0; +}; + +extern ISoundCombiner *soundcombiner; + +#endif // ISOUNDCOMBINER_H diff --git a/sp/src/public/ispatialpartition.h b/sp/src/public/ispatialpartition.h new file mode 100644 index 00000000..6b6678f7 --- /dev/null +++ b/sp/src/public/ispatialpartition.h @@ -0,0 +1,216 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Revision: $ +// $NoKeywords: $ +//=============================================================================// + +#ifndef ISPATIALPARTITION_H +#define ISPATIALPARTITION_H + +#include "interface.h" + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- + +class Vector; +struct Ray_t; +class IHandleEntity; + + +#define INTERFACEVERSION_SPATIALPARTITION "SpatialPartition001" + +//----------------------------------------------------------------------------- +// These are the various partition lists. Note some are server only, some +// are client only +//----------------------------------------------------------------------------- + +enum +{ + PARTITION_ENGINE_SOLID_EDICTS = (1 << 0), // every edict_t that isn't SOLID_TRIGGER or SOLID_NOT (and static props) + PARTITION_ENGINE_TRIGGER_EDICTS = (1 << 1), // every edict_t that IS SOLID_TRIGGER + PARTITION_CLIENT_SOLID_EDICTS = (1 << 2), + PARTITION_CLIENT_RESPONSIVE_EDICTS = (1 << 3), // these are client-side only objects that respond to being forces, etc. + PARTITION_ENGINE_NON_STATIC_EDICTS = (1 << 4), // everything in solid & trigger except the static props, includes SOLID_NOTs + PARTITION_CLIENT_STATIC_PROPS = (1 << 5), + PARTITION_ENGINE_STATIC_PROPS = (1 << 6), + PARTITION_CLIENT_NON_STATIC_EDICTS = (1 << 7), // everything except the static props +}; + +// Use this to look for all client edicts. +#define PARTITION_ALL_CLIENT_EDICTS ( \ + PARTITION_CLIENT_NON_STATIC_EDICTS | \ + PARTITION_CLIENT_STATIC_PROPS | \ + PARTITION_CLIENT_RESPONSIVE_EDICTS | \ + PARTITION_CLIENT_SOLID_EDICTS \ + ) + + +// These are the only handles in the spatial partition that the game is controlling (everything but static props) +// These masks are used to handle updating the dirty spatial partition list in each game DLL +#define PARTITION_CLIENT_GAME_EDICTS (PARTITION_ALL_CLIENT_EDICTS & ~PARTITION_CLIENT_STATIC_PROPS) +#define PARTITION_SERVER_GAME_EDICTS (PARTITION_ENGINE_SOLID_EDICTS|PARTITION_ENGINE_TRIGGER_EDICTS|PARTITION_ENGINE_NON_STATIC_EDICTS) + +//----------------------------------------------------------------------------- +// Clients that want to know about all elements within a particular +// volume must inherit from this +//----------------------------------------------------------------------------- + +enum IterationRetval_t +{ + ITERATION_CONTINUE = 0, + ITERATION_STOP, +}; + + +typedef unsigned short SpatialPartitionHandle_t; + +// A combination of the PARTITION_ flags above. +typedef int SpatialPartitionListMask_t; + +typedef int SpatialTempHandle_t; + + +//----------------------------------------------------------------------------- +// Any search in the CSpatialPartition must use this to filter out entities it doesn't want. +// You're forced to use listMasks because it can filter by listMasks really fast. Any other +// filtering can be done by EnumElement. +//----------------------------------------------------------------------------- + +class IPartitionEnumerator +{ +public: + virtual IterationRetval_t EnumElement( IHandleEntity *pHandleEntity ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Installs a callback to call right before a spatial partition query occurs +//----------------------------------------------------------------------------- +class IPartitionQueryCallback +{ +public: + virtual void OnPreQuery_V1() = 0; + virtual void OnPreQuery( SpatialPartitionListMask_t listMask ) = 0; + virtual void OnPostQuery( SpatialPartitionListMask_t listMask ) = 0; +}; + + +//----------------------------------------------------------------------------- +// This is the spatial partition manager, groups objects into buckets +//----------------------------------------------------------------------------- +enum +{ + PARTITION_INVALID_HANDLE = (SpatialPartitionHandle_t)~0 +}; + + +abstract_class ISpatialPartition +{ +public: + // Add a virtual destructor to silence the clang warning. + // This is harmless but not important since the only derived class + // doesn't have a destructor. + virtual ~ISpatialPartition() {} + + // Create/destroy a handle for this dude in our system. Destroy + // will also remove it from all lists it happens to be in + virtual SpatialPartitionHandle_t CreateHandle( IHandleEntity *pHandleEntity ) = 0; + + // A fast method of creating a handle + inserting into the tree in the right place + virtual SpatialPartitionHandle_t CreateHandle( IHandleEntity *pHandleEntity, + SpatialPartitionListMask_t listMask, const Vector& mins, const Vector& maxs ) = 0; + + virtual void DestroyHandle( SpatialPartitionHandle_t handle ) = 0; + + // Adds, removes an handle from a particular spatial partition list + // There can be multiple partition lists; each has a unique id + virtual void Insert( SpatialPartitionListMask_t listMask, + SpatialPartitionHandle_t handle ) = 0; + virtual void Remove( SpatialPartitionListMask_t listMask, + SpatialPartitionHandle_t handle ) = 0; + + // Same as calling Remove() then Insert(). For performance-sensitive areas where you want to save a call. + virtual void RemoveAndInsert( SpatialPartitionListMask_t removeMask, SpatialPartitionListMask_t insertMask, + SpatialPartitionHandle_t handle ) = 0; + + // This will remove a particular handle from all lists + virtual void Remove( SpatialPartitionHandle_t handle ) = 0; + + // Call this when an entity moves... + virtual void ElementMoved( SpatialPartitionHandle_t handle, + const Vector& mins, const Vector& maxs ) = 0; + + // A fast method to insert + remove a handle from the tree... + // This is used to suppress collision of a single model.. + virtual SpatialTempHandle_t HideElement( SpatialPartitionHandle_t handle ) = 0; + virtual void UnhideElement( SpatialPartitionHandle_t handle, SpatialTempHandle_t tempHandle ) = 0; + + // Installs callbacks to get called right before a query occurs + virtual void InstallQueryCallback_V1( IPartitionQueryCallback *pCallback ) = 0; + virtual void RemoveQueryCallback( IPartitionQueryCallback *pCallback ) = 0; + + // Gets all entities in a particular volume... + // if coarseTest == true, it'll return all elements that are in + // spatial partitions that intersect the box + // if coarseTest == false, it'll return only elements that truly intersect + virtual void EnumerateElementsInBox( + SpatialPartitionListMask_t listMask, + const Vector& mins, + const Vector& maxs, + bool coarseTest, + IPartitionEnumerator* pIterator + ) = 0; + + virtual void EnumerateElementsInSphere( + SpatialPartitionListMask_t listMask, + const Vector& origin, + float radius, + bool coarseTest, + IPartitionEnumerator* pIterator + ) = 0; + + virtual void EnumerateElementsAlongRay( + SpatialPartitionListMask_t listMask, + const Ray_t& ray, + bool coarseTest, + IPartitionEnumerator* pIterator + ) = 0; + + virtual void EnumerateElementsAtPoint( + SpatialPartitionListMask_t listMask, + const Vector& pt, + bool coarseTest, + IPartitionEnumerator* pIterator + ) = 0; + + // For debugging.... suppress queries on particular lists + virtual void SuppressLists( SpatialPartitionListMask_t nListMask, bool bSuppress ) = 0; + virtual SpatialPartitionListMask_t GetSuppressedLists() = 0; + + virtual void RenderAllObjectsInTree( float flTime ) = 0; + virtual void RenderObjectsInPlayerLeafs( const Vector &vecPlayerMin, const Vector &vecPlayerMax, float flTime ) = 0; + virtual void RenderLeafsForRayTraceStart( float flTime ) = 0; + virtual void RenderLeafsForRayTraceEnd( void ) = 0; + virtual void RenderLeafsForHullTraceStart( float flTime ) = 0; + virtual void RenderLeafsForHullTraceEnd( void ) = 0; + virtual void RenderLeafsForBoxStart( float flTime ) = 0; + virtual void RenderLeafsForBoxEnd( void ) = 0; + virtual void RenderLeafsForSphereStart( float flTime ) = 0; + virtual void RenderLeafsForSphereEnd( void ) = 0; + + virtual void RenderObjectsInBox( const Vector &vecMin, const Vector &vecMax, float flTime ) = 0; + virtual void RenderObjectsInSphere( const Vector &vecCenter, float flRadius, float flTime ) = 0; + virtual void RenderObjectsAlongRay( const Ray_t& ray, float flTime ) = 0; + + virtual void ReportStats( const char *pFileName ) = 0; + + virtual void InstallQueryCallback( IPartitionQueryCallback *pCallback ) = 0; +}; + +#endif + + + diff --git a/sp/src/public/isqlwrapper.h b/sp/src/public/isqlwrapper.h new file mode 100644 index 00000000..5e6603b5 --- /dev/null +++ b/sp/src/public/isqlwrapper.h @@ -0,0 +1,116 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Sql wrapper, encapsulates basic SQL functionality +// +// $NoKeywords: $ +//============================================================================= +#ifndef ISQLWRAPPER_H +#define ISQLWRAPPER_H + +#include "tier0/platform.h" + +#ifdef _WIN32 +#pragma once +#endif + +// SQL column types +enum EColumnType +{ + SQL_NONE = 0, + SQL_INT, + SQL_STRING, + SQL_FLOAT, + SQL_TIME, + SQL_UINT64 +}; + + +//----------------------------------------------------------------------------- +// encapsulates a table's description +//----------------------------------------------------------------------------- +class ISQLTable +{ +public: + virtual int GetCSQLColumn() const = 0; + virtual const char *PchColumnName( int iSQLColumn ) const = 0; + virtual EColumnType GetEColumnType( int iSQLColumn ) const = 0; + virtual const char *PchName() const = 0; +}; + + +//----------------------------------------------------------------------------- +// encapsulates a database worth of tables +//----------------------------------------------------------------------------- +class ISQLTableSet +{ +public: + virtual int GetCSQLTable() const = 0; + virtual const ISQLTable *PSQLTable( int iSQLTable ) const = 0; +}; + + +//----------------------------------------------------------------------------- +// encapsulates a single returned row from a valid SQL query +//----------------------------------------------------------------------------- +class ISQLRow +{ +public: + virtual int GetCSQLRowData() const = 0; + virtual const char *PchData( int iSQLColumn ) const = 0; + virtual int NData( int iSQLColumn ) const = 0; + virtual uint64 UlData( int iSQLColumn ) const = 0; + virtual float FlData( int iSQLColumn ) const = 0; + virtual uint64 UlTime( int iSQLColumn ) const = 0; + virtual bool BData( int iSQLColumn ) const = 0; + virtual EColumnType GetEColumnType( int iSQLColumn ) const = 0; +}; + + +//----------------------------------------------------------------------------- +// encapsulates a result set, which is made up of a series of rows +// You need to call PNextResult() NRow() times to get all the results +// (there is no random access to the result set). +//----------------------------------------------------------------------------- +class IResultSet +{ +public: + virtual int GetCSQLRow() const = 0; + virtual const ISQLRow *PSQLRowNextResult() = 0; // note, not const on the class because it makes a new row object +}; + + +//----------------------------------------------------------------------------- +// This interface encapsulates a database connection and lets you operate on it. +// Use the ISQLWrapperFactory factory to get access to the interface. +// NOTE - you can only have one outstanding query at a time. When you are done with a query call FreeResult() +//----------------------------------------------------------------------------- +class ISQLWrapper +{ +public: + // run a SQL statement against the DB, typically an insert statement as no data is returned + virtual bool BInsert( const char *pchQueryString ) = 0; + // get a description of the tables associated with the db you connected to + virtual const ISQLTableSet *PSQLTableSetDescription() = 0; + // run a query against the db and then iterate the result set (you can only have 1 outstanding query at a time, and call FreeResults() when you are done) + virtual IResultSet *PResultSetQuery( const char *pchQueryString ) = 0; + // you MUST call then after you finish with the IResultSet from the above query + virtual void FreeResult() = 0; +}; + + +//----------------------------------------------------------------------------- +// This is a factory to create objects that let you interact with a MySQL database. +// Make sure you Free() any interfaces you create. +//----------------------------------------------------------------------------- +class ISQLWrapperFactory +{ +public: + // setup details about this db connection + virtual ISQLWrapper *Create( const char *pchDB, const char *pchHost, const char *pchUsername, const char *pchPassword ) = 0; + virtual void Free( ISQLWrapper *pSQLWrapper ) = 0; +}; + +#define INTERFACEVERSION_ISQLWRAPPER "ISQLWRAPPER001" + +#endif // ISQLWRAPPER_H + diff --git a/sp/src/public/istudiorender.h b/sp/src/public/istudiorender.h new file mode 100644 index 00000000..f0af6115 --- /dev/null +++ b/sp/src/public/istudiorender.h @@ -0,0 +1,371 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#ifndef ISTUDIORENDER_H +#define ISTUDIORENDER_H +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/interface.h" +#include "mathlib/vector.h" +#include "mathlib/vector4d.h" +#include "tier1/utlbuffer.h" +#include "tier1/utlvector.h" +#include "materialsystem/imaterial.h" +#include "materialsystem/imaterialsystem.h" +#include "appframework/IAppSystem.h" +#include "datacache/imdlcache.h" +#include "studio.h" + + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- +struct studiohdr_t; +struct studiomeshdata_t; +class Vector; +struct LightDesc_t; +class IMaterial; +struct studiohwdata_t; +struct Ray_t; +class Vector4D; +class IMaterialSystem; +struct matrix3x4_t; +class IMesh; +struct vertexFileHeader_t; +struct FlashlightState_t; +class VMatrix; +namespace OptimizedModel { struct FileHeader_t; } +class IPooledVBAllocator; + +// undone: what's the standard for function type naming? +typedef void (*StudioRender_Printf_t)( PRINTF_FORMAT_STRING const char *fmt, ... ); + +struct StudioRenderConfig_t +{ + float fEyeShiftX; // eye X position + float fEyeShiftY; // eye Y position + float fEyeShiftZ; // eye Z position + float fEyeSize; // adjustment to iris textures + float fEyeGlintPixelWidthLODThreshold; + + int maxDecalsPerModel; + int drawEntities; + int skin; + int fullbright; + + bool bEyeMove : 1; // look around + bool bSoftwareSkin : 1; + bool bNoHardware : 1; + bool bNoSoftware : 1; + bool bTeeth : 1; + bool bEyes : 1; + bool bFlex : 1; + bool bWireframe : 1; + bool bDrawNormals : 1; + bool bDrawTangentFrame : 1; + bool bDrawZBufferedWireframe : 1; + bool bSoftwareLighting : 1; + bool bShowEnvCubemapOnly : 1; + bool bWireframeDecals : 1; + + // Reserved for future use + int m_nReserved[4]; +}; + + + +//----------------------------------------------------------------------------- +// Studio render interface +//----------------------------------------------------------------------------- +DECLARE_POINTER_HANDLE( StudioDecalHandle_t ); +#define STUDIORENDER_DECAL_INVALID ( (StudioDecalHandle_t)0 ) + +enum +{ + ADDDECAL_TO_ALL_LODS = -1 +}; + + +//----------------------------------------------------------------------------- +// DrawModel flags +//----------------------------------------------------------------------------- +enum +{ + STUDIORENDER_DRAW_ENTIRE_MODEL = 0, + STUDIORENDER_DRAW_OPAQUE_ONLY = 0x01, + STUDIORENDER_DRAW_TRANSLUCENT_ONLY = 0x02, + STUDIORENDER_DRAW_GROUP_MASK = 0x03, + + STUDIORENDER_DRAW_NO_FLEXES = 0x04, + STUDIORENDER_DRAW_STATIC_LIGHTING = 0x08, + + STUDIORENDER_DRAW_ACCURATETIME = 0x10, // Use accurate timing when drawing the model. + STUDIORENDER_DRAW_NO_SHADOWS = 0x20, + STUDIORENDER_DRAW_GET_PERF_STATS = 0x40, + + STUDIORENDER_DRAW_WIREFRAME = 0x80, + + STUDIORENDER_DRAW_ITEM_BLINK = 0x100, + + STUDIORENDER_SHADOWDEPTHTEXTURE = 0x200, + + STUDIORENDER_SSAODEPTHTEXTURE = 0x1000, + + STUDIORENDER_GENERATE_STATS = 0x8000, +}; + + +//----------------------------------------------------------------------------- +// Standard model vertex formats +//----------------------------------------------------------------------------- +// FIXME: remove these (materials/shaders should drive vertex format). Need to +// list required forcedmaterialoverrides in models/bsps (rather than +// all models supporting all possible overrides, as they do currently). +#define VERTEX_TEXCOORD0_2D ( ( (uint64) 2 ) << ( TEX_COORD_SIZE_BIT + ( 3*0 ) ) ) +enum MaterialVertexFormat_t +{ + MATERIAL_VERTEX_FORMAT_MODEL_SKINNED = (VertexFormat_t) VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D | VERTEX_BONEWEIGHT(2) | VERTEX_BONE_INDEX | VERTEX_USERDATA_SIZE(4), + MATERIAL_VERTEX_FORMAT_MODEL_SKINNED_DX7 = (VertexFormat_t) VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D | VERTEX_BONEWEIGHT(2) | VERTEX_BONE_INDEX, + MATERIAL_VERTEX_FORMAT_MODEL = (VertexFormat_t) VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D | VERTEX_USERDATA_SIZE(4), + MATERIAL_VERTEX_FORMAT_MODEL_DX7 = (VertexFormat_t) VERTEX_POSITION | VERTEX_COLOR | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D, + MATERIAL_VERTEX_FORMAT_COLOR = (VertexFormat_t) VERTEX_SPECULAR +}; + + +//----------------------------------------------------------------------------- +// What kind of material override is it? +//----------------------------------------------------------------------------- +enum OverrideType_t +{ + OVERRIDE_NORMAL = 0, + OVERRIDE_BUILD_SHADOWS, + OVERRIDE_DEPTH_WRITE, + OVERRIDE_SSAO_DEPTH_WRITE, +}; + + +//----------------------------------------------------------------------------- +// DrawModel info +//----------------------------------------------------------------------------- + +// Special flag for studio models that have a compiled in shadow lod version +// It's negative 2 since positive numbers == use a regular slot and -1 means +// have studiorender compute a value instead +enum +{ + USESHADOWLOD = -2, +}; + +// beyond this number of materials, you won't get info back from DrawModel +#define MAX_DRAW_MODEL_INFO_MATERIALS 8 + +struct DrawModelResults_t +{ + int m_ActualTriCount; + int m_TextureMemoryBytes; + int m_NumHardwareBones; + int m_NumBatches; + int m_NumMaterials; + int m_nLODUsed; + int m_flLODMetric; + CFastTimer m_RenderTime; + CUtlVectorFixed m_Materials; +}; + +struct ColorMeshInfo_t +{ + // A given color mesh can own a unique Mesh, or it can use a shared Mesh + // (in which case it uses a sub-range defined by m_nVertOffset and m_nNumVerts) + IMesh * m_pMesh; + IPooledVBAllocator * m_pPooledVBAllocator; + int m_nVertOffsetInBytes; + int m_nNumVerts; +}; + +struct DrawModelInfo_t +{ + studiohdr_t *m_pStudioHdr; + studiohwdata_t *m_pHardwareData; + StudioDecalHandle_t m_Decals; + int m_Skin; + int m_Body; + int m_HitboxSet; + void *m_pClientEntity; + int m_Lod; + ColorMeshInfo_t *m_pColorMeshes; + bool m_bStaticLighting; + Vector m_vecAmbientCube[6]; // ambient, and lights that aren't in locallight[] + int m_nLocalLightCount; + LightDesc_t m_LocalLightDescs[4]; +}; + +struct GetTriangles_Vertex_t +{ + Vector m_Position; + Vector m_Normal; + Vector4D m_TangentS; + Vector2D m_TexCoord; + Vector4D m_BoneWeight; + int m_BoneIndex[4]; + int m_NumBones; +}; + +struct GetTriangles_MaterialBatch_t +{ + IMaterial *m_pMaterial; + CUtlVector m_Verts; + CUtlVector m_TriListIndices; +}; + +struct GetTriangles_Output_t +{ + CUtlVector m_MaterialBatches; + matrix3x4_t m_PoseToWorld[MAXSTUDIOBONES]; +}; + + +struct model_array_instance_t +{ + matrix3x4_t modelToWorld; + + // UNDONE: Per instance lighting values? +}; + +//----------------------------------------------------------------------------- +// Cache Callback Function +// implementation can either statically persist data (tools) or lru cache (engine) it. +// caller returns base pointer to resident data. +// code expectes data to be dynamic and invokes cache callback prior to iterative access. +// virtualModel is member passed in via studiohdr_t and passed back for model identification. +//----------------------------------------------------------------------------- +#define STUDIO_DATA_CACHE_INTERFACE_VERSION "VStudioDataCache005" + +abstract_class IStudioDataCache : public IAppSystem +{ +public: + virtual bool VerifyHeaders( studiohdr_t *pStudioHdr ) = 0; + virtual vertexFileHeader_t *CacheVertexData( studiohdr_t *pStudioHdr ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Studio render interface +//----------------------------------------------------------------------------- +#define STUDIO_RENDER_INTERFACE_VERSION "VStudioRender025" + +abstract_class IStudioRender : public IAppSystem +{ +public: + virtual void BeginFrame( void ) = 0; + virtual void EndFrame( void ) = 0; + + // Used for the mat_stub console command. + virtual void Mat_Stub( IMaterialSystem *pMatSys ) = 0; + + // Updates the rendering configuration + virtual void UpdateConfig( const StudioRenderConfig_t& config ) = 0; + virtual void GetCurrentConfig( StudioRenderConfig_t& config ) = 0; + + // Load, unload model data + virtual bool LoadModel( studiohdr_t *pStudioHdr, void *pVtxData, studiohwdata_t *pHardwareData ) = 0; + virtual void UnloadModel( studiohwdata_t *pHardwareData ) = 0; + + // Refresh the studiohdr since it was lost... + virtual void RefreshStudioHdr( studiohdr_t* pStudioHdr, studiohwdata_t* pHardwareData ) = 0; + + // This is needed to do eyeglint and calculate the correct texcoords for the eyes. + virtual void SetEyeViewTarget( const studiohdr_t *pStudioHdr, int nBodyIndex, const Vector& worldPosition ) = 0; + + // Methods related to lighting state + // NOTE: SetAmbientLightColors assumes that the arraysize is the same as + // returned from GetNumAmbientLightSamples + virtual int GetNumAmbientLightSamples() = 0; + virtual const Vector *GetAmbientLightDirections() = 0; + virtual void SetAmbientLightColors( const Vector4D *pAmbientOnlyColors ) = 0; + virtual void SetAmbientLightColors( const Vector *pAmbientOnlyColors ) = 0; + virtual void SetLocalLights( int numLights, const LightDesc_t *pLights ) = 0; + + // Sets information about the camera location + orientation + virtual void SetViewState( const Vector& viewOrigin, const Vector& viewRight, + const Vector& viewUp, const Vector& viewPlaneNormal ) = 0; + + // Allocates flex weights for use in rendering + // NOTE: Pass in a non-null second parameter to lock delayed flex weights + virtual void LockFlexWeights( int nWeightCount, float **ppFlexWeights, float **ppFlexDelayedWeights = NULL ) = 0; + virtual void UnlockFlexWeights() = 0; + + // Used to allocate bone matrices to be used to pass into DrawModel + virtual matrix3x4_t* LockBoneMatrices( int nBoneCount ) = 0; + virtual void UnlockBoneMatrices() = 0; + + // LOD stuff + virtual int GetNumLODs( const studiohwdata_t &hardwareData ) const = 0; + virtual float GetLODSwitchValue( const studiohwdata_t &hardwareData, int lod ) const = 0; + virtual void SetLODSwitchValue( studiohwdata_t &hardwareData, int lod, float switchValue ) = 0; + + // Sets the color/alpha modulation + virtual void SetColorModulation( float const* pColor ) = 0; + virtual void SetAlphaModulation( float flAlpha ) = 0; + + // Draws the model + virtual void DrawModel( DrawModelResults_t *pResults, const DrawModelInfo_t& info, + matrix3x4_t *pBoneToWorld, float *pFlexWeights, float *pFlexDelayedWeights, const Vector &modelOrigin, int flags = STUDIORENDER_DRAW_ENTIRE_MODEL ) = 0; + + // Methods related to static prop rendering + virtual void DrawModelStaticProp( const DrawModelInfo_t& drawInfo, const matrix3x4_t &modelToWorld, int flags = STUDIORENDER_DRAW_ENTIRE_MODEL ) = 0; + virtual void DrawStaticPropDecals( const DrawModelInfo_t &drawInfo, const matrix3x4_t &modelToWorld ) = 0; + virtual void DrawStaticPropShadows( const DrawModelInfo_t &drawInfo, const matrix3x4_t &modelToWorld, int flags ) = 0; + + // Causes a material to be used instead of the materials the model was compiled with + virtual void ForcedMaterialOverride( IMaterial *newMaterial, OverrideType_t nOverrideType = OVERRIDE_NORMAL ) = 0; + + // Create, destroy list of decals for a particular model + virtual StudioDecalHandle_t CreateDecalList( studiohwdata_t *pHardwareData ) = 0; + virtual void DestroyDecalList( StudioDecalHandle_t handle ) = 0; + + // Add decals to a decal list by doing a planar projection along the ray + // The BoneToWorld matrices must be set before this is called + virtual void AddDecal( StudioDecalHandle_t handle, studiohdr_t *pStudioHdr, matrix3x4_t *pBoneToWorld, + const Ray_t & ray, const Vector& decalUp, IMaterial* pDecalMaterial, float radius, int body, bool noPokethru = false, int maxLODToDecal = ADDDECAL_TO_ALL_LODS ) = 0; + + // Compute the lighting at a point and normal + virtual void ComputeLighting( const Vector* pAmbient, int lightCount, + LightDesc_t* pLights, const Vector& pt, const Vector& normal, Vector& lighting ) = 0; + + // Compute the lighting at a point, constant directional component is passed + // as flDirectionalAmount + virtual void ComputeLightingConstDirectional( const Vector* pAmbient, int lightCount, + LightDesc_t* pLights, const Vector& pt, const Vector& normal, Vector& lighting, float flDirectionalAmount ) = 0; + + // Shadow state (affects the models as they are rendered) + virtual void AddShadow( IMaterial* pMaterial, void* pProxyData, FlashlightState_t *m_pFlashlightState = NULL, VMatrix *pWorldToTexture = NULL, ITexture *pFlashlightDepthTexture = NULL ) = 0; + virtual void ClearAllShadows() = 0; + + // Gets the model LOD; pass in the screen size in pixels of a sphere + // of radius 1 that has the same origin as the model to get the LOD out... + virtual int ComputeModelLod( studiohwdata_t* pHardwareData, float unitSphereSize, float *pMetric = NULL ) = 0; + + // Return a number that is usable for budgets, etc. + // Things that we care about: + // 1) effective triangle count (factors in batch sizes, state changes, etc) + // 2) texture memory usage + // Get Triangles returns the LOD used + virtual void GetPerfStats( DrawModelResults_t *pResults, const DrawModelInfo_t &info, CUtlBuffer *pSpewBuf = NULL ) const = 0; + virtual void GetTriangles( const DrawModelInfo_t& info, matrix3x4_t *pBoneToWorld, GetTriangles_Output_t &out ) = 0; + + // Returns materials used by a particular model + virtual int GetMaterialList( studiohdr_t *pStudioHdr, int count, IMaterial** ppMaterials ) = 0; + virtual int GetMaterialListFromBodyAndSkin( MDLHandle_t studio, int nSkin, int nBody, int nCountOutputMaterials, IMaterial** ppOutputMaterials ) = 0; + // draw an array of models with the same state + virtual void DrawModelArray( const DrawModelInfo_t &drawInfo, int arrayCount, model_array_instance_t *pInstanceData, int instanceStride, int flags = STUDIORENDER_DRAW_ENTIRE_MODEL ) = 0; +}; + +extern IStudioRender *g_pStudioRender; + +#endif // ISTUDIORENDER_H diff --git a/sp/src/public/ivguicenterprint.h b/sp/src/public/ivguicenterprint.h new file mode 100644 index 00000000..f1d97465 --- /dev/null +++ b/sp/src/public/ivguicenterprint.h @@ -0,0 +1,39 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// +#if !defined( IVGUICENTERPRINT_H ) +#define IVGUICENTERPRINT_H +#ifdef _WIN32 +#pragma once +#endif + +#include "interface.h" + +//----------------------------------------------------------------------------- +// Purpose: Engine Center Print Interface +//----------------------------------------------------------------------------- +abstract_class ICenterPrint +{ +public: + virtual void SetTextColor( int r, int g, int b, int a ) = 0; + virtual void Print( char *text ) = 0; + virtual void Print( wchar_t *text ) = 0; + virtual void ColorPrint( int r, int g, int b, int a, char *text ) = 0; + virtual void ColorPrint( int r, int g, int b, int a, wchar_t *text ) = 0; + virtual void Clear( void ) = 0; +}; + +extern ICenterPrint *centerprint; + +#define VCENTERPRINT_INTERFACE_VERSION "VCENTERPRINT002" + +#endif // IVGUICENTERPRINT_H \ No newline at end of file diff --git a/sp/src/public/ivoiceserver.h b/sp/src/public/ivoiceserver.h new file mode 100644 index 00000000..c0a48f70 --- /dev/null +++ b/sp/src/public/ivoiceserver.h @@ -0,0 +1,34 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: This module defines the IVoiceServer interface, which is used by +// game code to control which clients are listening to which other +// clients' voice streams. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef IVOICESERVER_H +#define IVOICESERVER_H + + +#include "interface.h" + + +#define INTERFACEVERSION_VOICESERVER "VoiceServer002" + + +abstract_class IVoiceServer +{ +public: + virtual ~IVoiceServer() {} + + // Use these to setup who can hear whose voice. + // Pass in client indices (which are their ent indices - 1). + virtual bool GetClientListening(int iReceiver, int iSender) = 0; + virtual bool SetClientListening(int iReceiver, int iSender, bool bListen) = 0; + virtual bool SetClientProximity(int iReceiver, int iSender, bool bUseProximity) = 0; +}; + + +#endif + diff --git a/sp/src/public/ivoicetweak.h b/sp/src/public/ivoicetweak.h new file mode 100644 index 00000000..4a4d0eaf --- /dev/null +++ b/sp/src/public/ivoicetweak.h @@ -0,0 +1,40 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef IVOICETWEAK_H +#define IVOICETWEAK_H +#ifdef _WIN32 +#pragma once +#endif + +// These provide access to the voice controls. +typedef enum +{ + MicrophoneVolume=0, // values 0-1. + OtherSpeakerScale, // values 0-1. Scales how loud other players are. + MicBoost, + SpeakingVolume, // values 0-1. Current voice volume received through Voice Tweak mode + +} VoiceTweakControl; + + +typedef struct IVoiceTweak_s +{ + // These turn voice tweak mode on and off. While in voice tweak mode, the user's voice is echoed back + // without sending to the server. + int (*StartVoiceTweakMode)(); // Returns 0 on error. + void (*EndVoiceTweakMode)(); + + // Get/set control values. + void (*SetControlFloat)(VoiceTweakControl iControl, float value); + float (*GetControlFloat)(VoiceTweakControl iControl); + + bool (*IsStillTweaking)(); // This can return false if the user restarts the sound system during voice tweak mode +} IVoiceTweak; + + +#endif // IVOICETWEAK_H diff --git a/sp/src/public/ivraddll.h b/sp/src/public/ivraddll.h new file mode 100644 index 00000000..4b917591 --- /dev/null +++ b/sp/src/public/ivraddll.h @@ -0,0 +1,99 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef IVRADDLL_H +#define IVRADDLL_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "interface.h" +#include "bspfile.h" + + +#define VRAD_INTERFACE_VERSION "vraddll_1" + + +class CBSPInfo +{ +public: + byte *dlightdata; + int lightdatasize; + + dface_t *dfaces; + unsigned char *m_pFacesTouched; // If non-null, then this has 1 byte for each face and + // tells which faces had their lightmaps updated. + int numfaces; + + dvertex_t *dvertexes; + int numvertexes; + + dedge_t *dedges; + int numedges; + + int *dsurfedges; + int numsurfedges; + + texinfo_t *texinfo; + int numtexinfo; + + dtexdata_t *dtexdata; + int numtexdata; + + ddispinfo_t *g_dispinfo; + int g_numdispinfo; + + char *texDataStringData; + int nTexDataStringData; + + int *texDataStringTable; + int nTexDataStringTable; +}; + + +// This is the DLL interface to VRAD. +class IVRadDLL +{ +public: + // All vrad.exe does is load the VRAD DLL and run this. + virtual int main( int argc, char **argv ) = 0; + + + // Load the BSP file into memory. + virtual bool Init( char const *pFilename ) = 0; + + // You must call this if you call Init(), to free resources. + virtual void Release() = 0; + + // Get some data from the BSP file that's in memory. + virtual void GetBSPInfo( CBSPInfo *pInfo ) = 0; + + // Incrementally relight the BSP file in memory given the new entity + // descriptions in pVMFFile. pVMFFile should only contain light entities. + // + // Returns true only if the lightmaps are updated. If the process is + // interrupted or there is an error, false is returned. + virtual bool DoIncrementalLight( char const *pVMFFile ) = 0; + + // Calling DoIncrementalLight doesn't actually write anything to disk. + // Calling this will write the incremental light file out and will write the + // current in-memory light data into the BSP. + // NOTE: if DoIncrementalLight never finished, this will do nothing and return false. + virtual bool Serialize() = 0; + + // Returns a 0-1 value telling how close it is to completing the task. + // This can be called from a separate thread than DoIncrementLight. + virtual float GetPercentComplete() = 0; + + // This can be called from a separate thread than the DoIncrementalLight thread. + // It asynchronously tells DoIncrementalLight to stop as soon as possible and exit. + virtual void Interrupt() = 0; +}; + + +#endif // IVRADDLL_H diff --git a/sp/src/public/ivrenderview.h b/sp/src/public/ivrenderview.h new file mode 100644 index 00000000..79dadc6f --- /dev/null +++ b/sp/src/public/ivrenderview.h @@ -0,0 +1,330 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $NoKeywords: $ +//===========================================================================// +#if !defined( IVRENDERVIEW_H ) +#define IVRENDERVIEW_H +#ifdef _WIN32 +#pragma once +#endif + +#include "basetypes.h" +#include "mathlib/vplane.h" +#include "interface.h" +#include "materialsystem/imaterialsystem.h" +#include "const.h" +#include "tier1/refcount.h" + + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class CViewSetup; +class CEngineSprite; +class IClientEntity; +class IMaterial; +struct model_t; +class IClientRenderable; + + +//----------------------------------------------------------------------------- +// Flags used by DrawWorldLists +//----------------------------------------------------------------------------- +enum +{ + DRAWWORLDLISTS_DRAW_STRICTLYABOVEWATER = 0x001, + DRAWWORLDLISTS_DRAW_STRICTLYUNDERWATER = 0x002, + DRAWWORLDLISTS_DRAW_INTERSECTSWATER = 0x004, + DRAWWORLDLISTS_DRAW_WATERSURFACE = 0x008, + DRAWWORLDLISTS_DRAW_SKYBOX = 0x010, + DRAWWORLDLISTS_DRAW_CLIPSKYBOX = 0x020, + DRAWWORLDLISTS_DRAW_SHADOWDEPTH = 0x040, + DRAWWORLDLISTS_DRAW_REFRACTION = 0x080, + DRAWWORLDLISTS_DRAW_REFLECTION = 0x100, + DRAWWORLDLISTS_DRAW_SSAO = 0x800, +}; + +enum +{ + MAT_SORT_GROUP_STRICTLY_ABOVEWATER = 0, + MAT_SORT_GROUP_STRICTLY_UNDERWATER, + MAT_SORT_GROUP_INTERSECTS_WATER_SURFACE, + MAT_SORT_GROUP_WATERSURFACE, + + MAX_MAT_SORT_GROUPS +}; + +enum ERenderDepthMode +{ + DEPTH_MODE_NORMAL = 0, + DEPTH_MODE_SHADOW = 1, + DEPTH_MODE_SSA0 = 2, + DEPTH_MODE_OVERRIDE = 3, + + DEPTH_MODE_MAX +}; + +typedef VPlane Frustum[FRUSTUM_NUMPLANES]; + + +//----------------------------------------------------------------------------- +// Leaf index +//----------------------------------------------------------------------------- +typedef unsigned short LeafIndex_t; +typedef short LeafFogVolume_t; +enum +{ + INVALID_LEAF_INDEX = (LeafIndex_t)~0 +}; + + +//----------------------------------------------------------------------------- +// Describes the leaves to be rendered this view, set by BuildWorldLists +//----------------------------------------------------------------------------- +struct WorldListInfo_t +{ + int m_ViewFogVolume; + int m_LeafCount; + LeafIndex_t* m_pLeafList; + LeafFogVolume_t* m_pLeafFogVolume; +}; + +class IWorldRenderList : public IRefCounted +{ +}; + +//----------------------------------------------------------------------------- +// Describes the fog volume for a particular point +//----------------------------------------------------------------------------- +struct VisibleFogVolumeInfo_t +{ + int m_nVisibleFogVolume; + int m_nVisibleFogVolumeLeaf; + bool m_bEyeInFogVolume; + float m_flDistanceToWater; + float m_flWaterHeight; + IMaterial *m_pFogVolumeMaterial; +}; + + +//----------------------------------------------------------------------------- +// Vertex format for brush models +//----------------------------------------------------------------------------- +struct BrushVertex_t +{ + Vector m_Pos; + Vector m_Normal; + Vector m_TangentS; + Vector m_TangentT; + Vector2D m_TexCoord; + Vector2D m_LightmapCoord; + +private: + BrushVertex_t( const BrushVertex_t& src ); +}; + +//----------------------------------------------------------------------------- +// Visibility data for area portal culling +//----------------------------------------------------------------------------- +struct VisOverrideData_t +{ + Vector m_vecVisOrigin; // The point to to use as the viewpoint for area portal backface cull checks. + float m_fDistToAreaPortalTolerance; // The distance from an area portal before using the full screen as the viewable portion. +}; + + +//----------------------------------------------------------------------------- +// interface for asking about the Brush surfaces from the client DLL +//----------------------------------------------------------------------------- + +class IBrushSurface +{ +public: + // Computes texture coordinates + lightmap coordinates given a world position + virtual void ComputeTextureCoordinate( Vector const& worldPos, Vector2D& texCoord ) = 0; + virtual void ComputeLightmapCoordinate( Vector const& worldPos, Vector2D& lightmapCoord ) = 0; + + // Gets the vertex data for this surface + virtual int GetVertexCount() const = 0; + virtual void GetVertexData( BrushVertex_t* pVerts ) = 0; + + // Gets at the material properties for this surface + virtual IMaterial* GetMaterial() = 0; +}; + + +//----------------------------------------------------------------------------- +// interface for installing a new renderer for brush surfaces +//----------------------------------------------------------------------------- + +class IBrushRenderer +{ +public: + // Draws the surface; returns true if decals should be rendered on this surface + virtual bool RenderBrushModelSurface( IClientEntity* pBaseEntity, IBrushSurface* pBrushSurface ) = 0; +}; + + +#define MAX_VIS_LEAVES 32 +//----------------------------------------------------------------------------- +// Purpose: Interface to client .dll to set up a rendering pass over world +// The client .dll can call Render multiple times to overlay one or more world +// views on top of one another +//----------------------------------------------------------------------------- +enum DrawBrushModelMode_t +{ + DBM_DRAW_ALL = 0, + DBM_DRAW_OPAQUE_ONLY, + DBM_DRAW_TRANSLUCENT_ONLY, +}; + +class IVRenderView +{ +public: + + // Draw normal brush model. + // If pMaterialOverride is non-null, then all the faces of the bmodel will + // set this material rather than their regular material. + virtual void DrawBrushModel( + IClientEntity *baseentity, + model_t *model, + const Vector& origin, + const QAngle& angles, + bool bUnused ) = 0; + + // Draw brush model that has no origin/angles change ( uses identity transform ) + // FIXME, Material proxy IClientEntity *baseentity is unused right now, use DrawBrushModel for brushes with + // proxies for now. + virtual void DrawIdentityBrushModel( IWorldRenderList *pList, model_t *model ) = 0; + + // Mark this dynamic light as having changed this frame ( so light maps affected will be recomputed ) + virtual void TouchLight( struct dlight_t *light ) = 0; + // Draw 3D Overlays + virtual void Draw3DDebugOverlays( void ) = 0; + // Sets global blending fraction + virtual void SetBlend( float blend ) = 0; + virtual float GetBlend( void ) = 0; + + // Sets global color modulation + virtual void SetColorModulation( float const* blend ) = 0; + virtual void GetColorModulation( float* blend ) = 0; + + // Wrap entire scene drawing + virtual void SceneBegin( void ) = 0; + virtual void SceneEnd( void ) = 0; + + // Gets the fog volume for a particular point + virtual void GetVisibleFogVolume( const Vector& eyePoint, VisibleFogVolumeInfo_t *pInfo ) = 0; + + // Wraps world drawing + // If iForceViewLeaf is not -1, then it uses the specified leaf as your starting area for setting up area portal culling. + // This is used by water since your reflected view origin is often in solid space, but we still want to treat it as though + // the first portal we're looking out of is a water portal, so our view effectively originates under the water. + virtual IWorldRenderList * CreateWorldList() = 0; + + virtual void BuildWorldLists( IWorldRenderList *pList, WorldListInfo_t* pInfo, int iForceFViewLeaf, const VisOverrideData_t* pVisData = NULL, bool bShadowDepth = false, float *pReflectionWaterHeight = NULL ) = 0; + virtual void DrawWorldLists( IWorldRenderList *pList, unsigned long flags, float waterZAdjust ) = 0; + + // Optimization for top view + virtual void DrawTopView( bool enable ) = 0; + virtual void TopViewBounds( Vector2D const& mins, Vector2D const& maxs ) = 0; + + // Draw lights + virtual void DrawLights( void ) = 0; + // FIXME: This function is a stub, doesn't do anything in the engine right now + virtual void DrawMaskEntities( void ) = 0; + + // Draw surfaces with alpha + virtual void DrawTranslucentSurfaces( IWorldRenderList *pList, int sortIndex, unsigned long flags, bool bShadowDepth ) = 0; + + // Draw Particles ( just draws the linefine for debugging map leaks ) + virtual void DrawLineFile( void ) = 0; + // Draw lightmaps + virtual void DrawLightmaps( IWorldRenderList *pList, int pageId ) = 0; + // Wraps view render sequence, sets up a view + virtual void ViewSetupVis( bool novis, int numorigins, const Vector origin[] ) = 0; + + // Return true if any of these leaves are visible in the current PVS. + virtual bool AreAnyLeavesVisible( int *leafList, int nLeaves ) = 0; + + virtual void VguiPaint( void ) = 0; + // Sets up view fade parameters + virtual void ViewDrawFade( byte *color, IMaterial *pMaterial ) = 0; + // Sets up the projection matrix for the specified field of view + virtual void OLD_SetProjectionMatrix( float fov, float zNear, float zFar ) = 0; + // Determine lighting at specified position + virtual colorVec GetLightAtPoint( Vector& pos ) = 0; + // Whose eyes are we looking through? + virtual int GetViewEntity( void ) = 0; + // Get engine field of view setting + virtual float GetFieldOfView( void ) = 0; + // 1 == ducking, 0 == not + virtual unsigned char **GetAreaBits( void ) = 0; + + // Set up fog for a particular leaf + virtual void SetFogVolumeState( int nVisibleFogVolume, bool bUseHeightFog ) = 0; + + // Installs a brush surface draw override method, null means use normal renderer + virtual void InstallBrushSurfaceRenderer( IBrushRenderer* pBrushRenderer ) = 0; + + // Draw brush model shadow + virtual void DrawBrushModelShadow( IClientRenderable *pRenderable ) = 0; + + // Does the leaf contain translucent surfaces? + virtual bool LeafContainsTranslucentSurfaces( IWorldRenderList *pList, int sortIndex, unsigned long flags ) = 0; + + virtual bool DoesBoxIntersectWaterVolume( const Vector &mins, const Vector &maxs, int leafWaterDataID ) = 0; + + virtual void SetAreaState( + unsigned char chAreaBits[MAX_AREA_STATE_BYTES], + unsigned char chAreaPortalBits[MAX_AREA_PORTAL_STATE_BYTES] ) = 0; + + // See i + virtual void VGui_Paint( int mode ) = 0; + + // Push, pop views (see PushViewFlags_t above for flags) + virtual void Push3DView( const CViewSetup &view, int nFlags, ITexture* pRenderTarget, Frustum frustumPlanes ) = 0; + virtual void Push2DView( const CViewSetup &view, int nFlags, ITexture* pRenderTarget, Frustum frustumPlanes ) = 0; + virtual void PopView( Frustum frustumPlanes ) = 0; + + // Sets the main view + virtual void SetMainView( const Vector &vecOrigin, const QAngle &angles ) = 0; + + enum + { + VIEW_SETUP_VIS_EX_RETURN_FLAGS_USES_RADIAL_VIS = 0x00000001 + }; + + // Wraps view render sequence, sets up a view + virtual void ViewSetupVisEx( bool novis, int numorigins, const Vector origin[], unsigned int &returnFlags ) = 0; + + //replaces the current view frustum with a rhyming replacement of your choice + virtual void OverrideViewFrustum( Frustum custom ) = 0; + + virtual void DrawBrushModelShadowDepth( IClientEntity *baseentity, model_t *model, const Vector& origin, const QAngle& angles, ERenderDepthMode DepthMode ) = 0; + virtual void UpdateBrushModelLightmap( model_t *model, IClientRenderable *pRenderable ) = 0; + virtual void BeginUpdateLightmaps( void ) = 0; + virtual void EndUpdateLightmaps( void ) = 0; + virtual void OLD_SetOffCenterProjectionMatrix( float fov, float zNear, float zFar, float flAspectRatio, float flBottom, float flTop, float flLeft, float flRight ) = 0; + virtual void OLD_SetProjectionMatrixOrtho( float left, float top, float right, float bottom, float zNear, float zFar ) = 0; + virtual void Push3DView( const CViewSetup &view, int nFlags, ITexture* pRenderTarget, Frustum frustumPlanes, ITexture* pDepthTexture ) = 0; + virtual void GetMatricesForView( const CViewSetup &view, VMatrix *pWorldToView, VMatrix *pViewToProjection, VMatrix *pWorldToProjection, VMatrix *pWorldToPixels ) = 0; + virtual void DrawBrushModelEx( IClientEntity *baseentity, model_t *model, const Vector& origin, const QAngle& angles, DrawBrushModelMode_t mode ) = 0; +}; + +// change this when the new version is incompatable with the old +#define VENGINE_RENDERVIEW_INTERFACE_VERSION "VEngineRenderView014" + +#if defined(_STATIC_LINKED) && defined(CLIENT_DLL) +namespace Client +{ +extern IVRenderView *render; +} +#else +extern IVRenderView *render; +#endif + +#endif // IVRENDERVIEW_H diff --git a/sp/src/public/ivtex.h b/sp/src/public/ivtex.h new file mode 100644 index 00000000..b85b6213 --- /dev/null +++ b/sp/src/public/ivtex.h @@ -0,0 +1,32 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#ifndef IVTEX_H +#define IVTEX_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/interface.h" +#include "appframework/IAppSystem.h" + + +class IVTex : public IAppSystem +{ +public: + // For use by command-line tools + virtual int VTex( int argc, char **argv ) = 0; + + // For use by engine + virtual int VTex( CreateInterfaceFn filesystemFactory, const char *pGameDir, int argc, char **argv ) = 0; +}; + +#define IVTEX_VERSION_STRING "VTEX_003" + + +#endif // IVTEX_H diff --git a/sp/src/public/ixboxsystem.h b/sp/src/public/ixboxsystem.h new file mode 100644 index 00000000..009da96e --- /dev/null +++ b/sp/src/public/ixboxsystem.h @@ -0,0 +1,82 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Interface to Xbox 360 system functions. Helps deal with the async system and Live +// functions by either providing a handle for the caller to check results or handling +// automatic cleanup of the async data when the caller doesn't care about the results. +// +//===========================================================================// + +#ifndef IXBOXSYSTEM_H +#define IXBOXSYSTEM_H +#ifdef _WIN32 +#pragma once +#endif + +#if !defined( _X360 ) +#include "xbox/xboxstubs.h" +#endif + +typedef void* AsyncHandle_t; +typedef void* XboxHandle_t; + +#ifdef POSIX +#define ERROR_SUCCESS 0 +#define ERROR_IO_PENDING 1 +#define ERROR_IO_INCOMPLETE 2 +#define ERROR_INSUFFICIENT_BUFFER 3 +#endif + +//----------------------------------------------------------------------------- +// Xbox system interface +//----------------------------------------------------------------------------- +abstract_class IXboxSystem +{ +public: + virtual AsyncHandle_t CreateAsyncHandle( void ) = 0; + virtual void ReleaseAsyncHandle( AsyncHandle_t handle ) = 0; + virtual int GetOverlappedResult( AsyncHandle_t handle, uint *pResultCode, bool bWait ) = 0; + virtual void CancelOverlappedOperation( AsyncHandle_t handle ) = 0; + + // Save/Load + virtual void GetModSaveContainerNames( const char *pchModName, const wchar_t **ppchDisplayName, const char **ppchName ) = 0; + virtual uint GetContainerRemainingSpace( void ) = 0; + virtual bool DeviceCapacityAdequate( DWORD nStorageID, const char *pModName ) = 0; + virtual DWORD DiscoverUserData( DWORD nUserID, const char *pModName ) = 0; + + // XUI + virtual bool ShowDeviceSelector( bool bForce, uint *pStorageID, AsyncHandle_t *pHandle ) = 0; + virtual void ShowSigninUI( uint nPanes, uint nFlags ) = 0; + + // Rich Presence and Matchmaking + virtual int UserSetContext( uint nUserIdx, uint nContextID, uint nContextValue, bool bAsync = true, AsyncHandle_t *pHandle = NULL ) = 0; + virtual int UserSetProperty( uint nUserIndex, uint nPropertyId, uint nBytes, const void *pvValue, bool bAsync = true, AsyncHandle_t *pHandle = NULL ) = 0; + + // Matchmaking + virtual int CreateSession( uint nFlags, uint nUserIdx, uint nMaxPublicSlots, uint nMaxPrivateSlots, uint64 *pNonce, void *pSessionInfo, XboxHandle_t *pSessionHandle, bool bAsync, AsyncHandle_t *pAsyncHandle = NULL ) = 0; + virtual uint DeleteSession( XboxHandle_t hSession, bool bAsync, AsyncHandle_t *pAsyncHandle = NULL ) = 0; + virtual uint SessionSearch( uint nProcedureIndex, uint nUserIndex, uint nNumResults, uint nNumUsers, uint nNumProperties, uint nNumContexts, XUSER_PROPERTY *pSearchProperties, XUSER_CONTEXT *pSearchContexts, uint *pcbResultsBuffer, XSESSION_SEARCHRESULT_HEADER *pSearchResults, bool bAsync, AsyncHandle_t *pAsyncHandle = NULL ) = 0; + virtual uint SessionStart( XboxHandle_t hSession, uint nFlags, bool bAsync, AsyncHandle_t *pAsyncHandle = NULL ) = 0; + virtual uint SessionEnd( XboxHandle_t hSession, bool bAsync, AsyncHandle_t *pAsyncHandle = NULL ) = 0; + virtual int SessionJoinLocal( XboxHandle_t hSession, uint nUserCount, const uint *pUserIndexes, const bool *pPrivateSlots, bool bAsync, AsyncHandle_t *pAsyncHandle = NULL ) = 0; + virtual int SessionJoinRemote( XboxHandle_t hSession, uint nUserCount, const XUID *pXuids, const bool *pPrivateSlots, bool bAsync, AsyncHandle_t *pAsyncHandle = NULL ) = 0; + virtual int SessionLeaveLocal( XboxHandle_t hSession, uint nUserCount, const uint *pUserIndexes, bool bAsync, AsyncHandle_t *pAsyncHandle = NULL ) = 0; + virtual int SessionLeaveRemote( XboxHandle_t hSession, uint nUserCount, const XUID *pXuids, bool bAsync, AsyncHandle_t *pAsyncHandle = NULL ) = 0; + virtual int SessionMigrate( XboxHandle_t hSession, uint nUserIndex, void *pSessionInfo, bool bAsync, AsyncHandle_t *pAsyncHandle = NULL ) = 0; + virtual int SessionArbitrationRegister( XboxHandle_t hSession, uint nFlags, uint64 nonce, uint *pBytes, void *pBuffer, bool bAsync, AsyncHandle_t *pAsyncHandle = NULL ) = 0; + + // Stats + virtual int WriteStats( XboxHandle_t hSession, XUID xuid, uint nViews, void* pViews, bool bAsync, AsyncHandle_t *pAsyncHandle = NULL ) = 0; + + // Achievements + virtual int EnumerateAchievements( uint nUserIdx, uint64 xuid, uint nStartingIdx, uint nCount, void *pBuffer, uint nBufferBytes, bool bAsync = true, AsyncHandle_t *pAsyncHandle = NULL ) = 0; + virtual void AwardAchievement( uint nUserIdx, uint nAchievementId ) = 0; + + virtual void FinishContainerWrites( void ) = 0; + virtual uint GetContainerOpenResult( void ) = 0; + virtual uint OpenContainers( void ) = 0; + virtual void CloseContainers( void ) = 0; +}; + +#define XBOXSYSTEM_INTERFACE_VERSION "XboxSystemInterface001" + +#endif // IXBOXSYSTEM_H diff --git a/sp/src/public/jigglebones.cpp b/sp/src/public/jigglebones.cpp new file mode 100644 index 00000000..10038e58 --- /dev/null +++ b/sp/src/public/jigglebones.cpp @@ -0,0 +1,775 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#include "tier1/convar.h" +#include "jigglebones.h" + +#ifdef CLIENT_DLL +#include "engine/ivdebugoverlay.h" +#include "cdll_client_int.h" +#endif // CLIENT_DLL + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#ifdef CLIENT_DLL +//----------------------------------------------------------------------------- +ConVar cl_jiggle_bone_debug( "cl_jiggle_bone_debug", "0", FCVAR_CHEAT, "Display physics-based 'jiggle bone' debugging information" ); +ConVar cl_jiggle_bone_debug_yaw_constraints( "cl_jiggle_bone_debug_yaw_constraints", "0", FCVAR_CHEAT, "Display physics-based 'jiggle bone' debugging information" ); +ConVar cl_jiggle_bone_debug_pitch_constraints( "cl_jiggle_bone_debug_pitch_constraints", "0", FCVAR_CHEAT, "Display physics-based 'jiggle bone' debugging information" ); +#endif // CLIENT_DLL + +ConVar cl_jiggle_bone_framerate_cutoff( "cl_jiggle_bone_framerate_cutoff", "45", 0, "Skip jiggle bone simulation if framerate drops below this value (frames/second)" ); + + +//----------------------------------------------------------------------------- +JiggleData * CJiggleBones::GetJiggleData( int bone, float currenttime, const Vector &initBasePos, const Vector &initTipPos ) +{ + FOR_EACH_LL( m_jiggleBoneState, it ) + { + if ( m_jiggleBoneState[it].bone == bone ) + { + return &m_jiggleBoneState[it]; + } + } + + JiggleData data; + data.Init( bone, currenttime, initBasePos, initTipPos ); + + int idx = m_jiggleBoneState.AddToHead( data ); + if ( idx == m_jiggleBoneState.InvalidIndex() ) + return NULL; + + return &m_jiggleBoneState[idx]; +} + + +//----------------------------------------------------------------------------- +/** + * Do spring physics calculations and update "jiggle bone" matrix + * (Michael Booth, Turtle Rock Studios) + */ +void CJiggleBones::BuildJiggleTransformations( int boneIndex, float currenttime, const mstudiojigglebone_t *jiggleInfo, const matrix3x4_t &goalMX, matrix3x4_t &boneMX ) +{ + Vector goalBasePosition; + MatrixPosition( goalMX, goalBasePosition ); + + Vector goalForward, goalUp, goalLeft; + MatrixGetColumn( goalMX, 0, goalLeft ); + MatrixGetColumn( goalMX, 1, goalUp ); + MatrixGetColumn( goalMX, 2, goalForward ); + + // compute goal tip position + Vector goalTip = goalBasePosition + jiggleInfo->length * goalForward; + + JiggleData *data = GetJiggleData( boneIndex, currenttime, goalBasePosition, goalTip ); + if ( !data ) + { + return; + } + + // if frames have been skipped since our last update, we were likely + // disabled and re-enabled, so re-init +#if defined(CLIENT_DLL) || defined(GAME_DLL) + float timeTolerance = 1.2f * gpGlobals->frametime; +#else + float timeTolerance = 0.5f; +#endif + + if ( currenttime - data->lastUpdate > timeTolerance ) + { + data->Init( boneIndex, currenttime, goalBasePosition, goalTip ); + } + + if ( data->lastLeft.IsZero() ) + { + data->lastLeft = goalLeft; + } + + // limit maximum deltaT to avoid simulation blowups + // if framerate is too low, skip jigglebones altogether, since movement will be too + // large between frames to simulate with a simple Euler integration + float deltaT = currenttime - data->lastUpdate; + + const float thousandHZ = 0.001f; + if ( deltaT < thousandHZ ) + { + deltaT = thousandHZ; + } + else if ( cl_jiggle_bone_framerate_cutoff.GetFloat() <= 0.0f || deltaT > ( 1.0f / cl_jiggle_bone_framerate_cutoff.GetFloat() ) ) + { + // disable jigglebone - just use goal matrix + boneMX = goalMX; + return; + } + + // we want lastUpdate here, so if jigglebones were skipped they get reinitialized if they turn back on + data->lastUpdate = currenttime; + + // + // Bone tip flex + // + if ( jiggleInfo->flags & ( JIGGLE_IS_FLEXIBLE | JIGGLE_IS_RIGID ) ) + { + // apply gravity in global space + data->tipAccel.z -= jiggleInfo->tipMass; + + if ( jiggleInfo->flags & JIGGLE_IS_FLEXIBLE ) + { + // decompose into local coordinates + Vector error = goalTip - data->tipPos; + + Vector localError; + localError.x = DotProduct( goalLeft, error ); + localError.y = DotProduct( goalUp, error ); + localError.z = DotProduct( goalForward, error ); + + Vector localVel; + localVel.x = DotProduct( goalLeft, data->tipVel ); + localVel.y = DotProduct( goalUp, data->tipVel ); + + // yaw spring + float yawAccel = jiggleInfo->yawStiffness * localError.x - jiggleInfo->yawDamping * localVel.x; + + // pitch spring + float pitchAccel = jiggleInfo->pitchStiffness * localError.y - jiggleInfo->pitchDamping * localVel.y; + + if ( jiggleInfo->flags & JIGGLE_HAS_LENGTH_CONSTRAINT ) + { + // drive tip towards goal tip position + data->tipAccel += yawAccel * goalLeft + pitchAccel * goalUp; + } + else + { + // allow flex along length of spring + localVel.z = DotProduct( goalForward, data->tipVel ); + + // along spring + float alongAccel = jiggleInfo->alongStiffness * localError.z - jiggleInfo->alongDamping * localVel.z; + + // drive tip towards goal tip position + data->tipAccel += yawAccel * goalLeft + pitchAccel * goalUp + alongAccel * goalForward; + } + } + + + // simple euler integration + data->tipVel += data->tipAccel * deltaT; + data->tipPos += data->tipVel * deltaT; + + // clear this timestep's accumulated accelerations + data->tipAccel = vec3_origin; + + // + // Apply optional constraints + // + if ( jiggleInfo->flags & ( JIGGLE_HAS_YAW_CONSTRAINT | JIGGLE_HAS_PITCH_CONSTRAINT ) ) + { + // find components of spring vector in local coordinate system + Vector along = data->tipPos - goalBasePosition; + Vector localAlong; + localAlong.x = DotProduct( goalLeft, along ); + localAlong.y = DotProduct( goalUp, along ); + localAlong.z = DotProduct( goalForward, along ); + + Vector localVel; + localVel.x = DotProduct( goalLeft, data->tipVel ); + localVel.y = DotProduct( goalUp, data->tipVel ); + localVel.z = DotProduct( goalForward, data->tipVel ); + + if ( jiggleInfo->flags & JIGGLE_HAS_YAW_CONSTRAINT ) + { + // enforce yaw constraints in local XZ plane + float yawError = atan2( localAlong.x, localAlong.z ); + + bool isAtLimit = false; + float yaw = 0.0f; + + if ( yawError < jiggleInfo->minYaw ) + { + // at angular limit + isAtLimit = true; + yaw = jiggleInfo->minYaw; + } + else if ( yawError > jiggleInfo->maxYaw ) + { + // at angular limit + isAtLimit = true; + yaw = jiggleInfo->maxYaw; + } + + if ( isAtLimit ) + { + float sy, cy; + SinCos( yaw, &sy, &cy ); + + // yaw matrix + matrix3x4_t yawMatrix; + + yawMatrix[0][0] = cy; + yawMatrix[1][0] = 0; + yawMatrix[2][0] = -sy; + + yawMatrix[0][1] = 0; + yawMatrix[1][1] = 1.0f; + yawMatrix[2][1] = 0; + + yawMatrix[0][2] = sy; + yawMatrix[1][2] = 0; + yawMatrix[2][2] = cy; + + yawMatrix[0][3] = 0; + yawMatrix[1][3] = 0; + yawMatrix[2][3] = 0; + + // global coordinates of limit + matrix3x4_t limitMatrix; + ConcatTransforms( goalMX, yawMatrix, limitMatrix ); + + Vector limitLeft( limitMatrix.m_flMatVal[0][0], + limitMatrix.m_flMatVal[1][0], + limitMatrix.m_flMatVal[2][0] ); + + Vector limitUp( limitMatrix.m_flMatVal[0][1], + limitMatrix.m_flMatVal[1][1], + limitMatrix.m_flMatVal[2][1] ); + + Vector limitForward( limitMatrix.m_flMatVal[0][2], + limitMatrix.m_flMatVal[1][2], + limitMatrix.m_flMatVal[2][2] ); + +#ifdef CLIENT_DLL + if ( cl_jiggle_bone_debug_yaw_constraints.GetBool() ) + { + float dT = 0.01f; + const float axisSize = 10.0f; + debugoverlay->AddLineOverlay( goalBasePosition, goalBasePosition + axisSize * limitLeft, 0, 255, 255, true, dT ); + debugoverlay->AddLineOverlay( goalBasePosition, goalBasePosition + axisSize * limitUp, 255, 255, 0, true, dT ); + debugoverlay->AddLineOverlay( goalBasePosition, goalBasePosition + axisSize * limitForward, 255, 0, 255, true, dT ); + } +#endif // CLIENT_DLL + + Vector limitAlong( DotProduct( limitLeft, along ), + DotProduct( limitUp, along ), + DotProduct( limitForward, along ) ); + + // clip to limit plane + data->tipPos = goalBasePosition + limitAlong.y * limitUp + limitAlong.z * limitForward; + + // removed friction and velocity clipping against constraint - was causing simulation blowups (MSB 12/9/2010) + data->tipVel.Zero(); + + // update along vectors for use by pitch constraint + along = data->tipPos - goalBasePosition; + localAlong.x = DotProduct( goalLeft, along ); + localAlong.y = DotProduct( goalUp, along ); + localAlong.z = DotProduct( goalForward, along ); + + localVel.x = DotProduct( goalLeft, data->tipVel ); + localVel.y = DotProduct( goalUp, data->tipVel ); + localVel.z = DotProduct( goalForward, data->tipVel ); + } + } + + + if ( jiggleInfo->flags & JIGGLE_HAS_PITCH_CONSTRAINT ) + { + // enforce pitch constraints in local YZ plane + float pitchError = atan2( localAlong.y, localAlong.z ); + + bool isAtLimit = false; + float pitch = 0.0f; + + if ( pitchError < jiggleInfo->minPitch ) + { + // at angular limit + isAtLimit = true; + pitch = jiggleInfo->minPitch; + } + else if ( pitchError > jiggleInfo->maxPitch ) + { + // at angular limit + isAtLimit = true; + pitch = jiggleInfo->maxPitch; + } + + if ( isAtLimit ) + { + float sp, cp; + SinCos( pitch, &sp, &cp ); + + // pitch matrix + matrix3x4_t pitchMatrix; + + pitchMatrix[0][0] = 1.0f; + pitchMatrix[1][0] = 0; + pitchMatrix[2][0] = 0; + + pitchMatrix[0][1] = 0; + pitchMatrix[1][1] = cp; + pitchMatrix[2][1] = -sp; + + pitchMatrix[0][2] = 0; + pitchMatrix[1][2] = sp; + pitchMatrix[2][2] = cp; + + pitchMatrix[0][3] = 0; + pitchMatrix[1][3] = 0; + pitchMatrix[2][3] = 0; + + // global coordinates of limit + matrix3x4_t limitMatrix; + ConcatTransforms( goalMX, pitchMatrix, limitMatrix ); + + Vector limitLeft( limitMatrix.m_flMatVal[0][0], + limitMatrix.m_flMatVal[1][0], + limitMatrix.m_flMatVal[2][0] ); + + Vector limitUp( limitMatrix.m_flMatVal[0][1], + limitMatrix.m_flMatVal[1][1], + limitMatrix.m_flMatVal[2][1] ); + + Vector limitForward( limitMatrix.m_flMatVal[0][2], + limitMatrix.m_flMatVal[1][2], + limitMatrix.m_flMatVal[2][2] ); + +#ifdef CLIENT_DLL + if (cl_jiggle_bone_debug_pitch_constraints.GetBool()) + { + float dT = 0.01f; + const float axisSize = 10.0f; + debugoverlay->AddLineOverlay( goalBasePosition, goalBasePosition + axisSize * limitLeft, 0, 255, 255, true, dT ); + debugoverlay->AddLineOverlay( goalBasePosition, goalBasePosition + axisSize * limitUp, 255, 255, 0, true, dT ); + debugoverlay->AddLineOverlay( goalBasePosition, goalBasePosition + axisSize * limitForward, 255, 0, 255, true, dT ); + } +#endif // CLIENT_DLL + + Vector limitAlong( DotProduct( limitLeft, along ), + DotProduct( limitUp, along ), + DotProduct( limitForward, along ) ); + + // clip to limit plane + data->tipPos = goalBasePosition + limitAlong.x * limitLeft + limitAlong.z * limitForward; + + // removed friction and velocity clipping against constraint - was causing simulation blowups (MSB 12/9/2010) + data->tipVel.Zero(); + } + } + } + + // needed for matrix assembly below + Vector forward = data->tipPos - goalBasePosition; + forward.NormalizeInPlace(); + + if ( jiggleInfo->flags & JIGGLE_HAS_ANGLE_CONSTRAINT ) + { + // enforce max angular error + Vector error = goalTip - data->tipPos; + float dot = DotProduct( forward, goalForward ); + float angleBetween = acos( dot ); + if ( dot < 0.0f ) + { + angleBetween = 2.0f * M_PI - angleBetween; + } + + if ( angleBetween > jiggleInfo->angleLimit ) + { + // at angular limit + float maxBetween = jiggleInfo->length * sin( jiggleInfo->angleLimit ); + + Vector delta = goalTip - data->tipPos; + delta.NormalizeInPlace(); + + data->tipPos = goalTip - maxBetween * delta; + + forward = data->tipPos - goalBasePosition; + forward.NormalizeInPlace(); + } + } + + if ( jiggleInfo->flags & JIGGLE_HAS_LENGTH_CONSTRAINT ) + { + // enforce spring length + data->tipPos = goalBasePosition + jiggleInfo->length * forward; + + // zero velocity along forward bone axis + data->tipVel -= DotProduct( data->tipVel, forward ) * forward; + } + + // + // Build bone matrix to align along current tip direction + // + Vector left = CrossProduct( goalUp, forward ); + left.NormalizeInPlace(); + + if ( DotProduct( left, data->lastLeft ) < 0.0f ) + { + // The bone has rotated so far its on the other side of the up vector + // resulting in the cross product result flipping 180 degrees around the up + // vector. Flip it back. + left = -left; + } + data->lastLeft = left; + +#ifdef CLIENT_DLL + if ( cl_jiggle_bone_debug.GetBool() ) + { + debugoverlay->AddLineOverlay( goalBasePosition, goalBasePosition + 10.0f * data->lastLeft, 255, 0, 255, true, 0.01f ); + } +#endif + + Vector up = CrossProduct( forward, left ); + + boneMX[0][0] = left.x; + boneMX[1][0] = left.y; + boneMX[2][0] = left.z; + boneMX[0][1] = up.x; + boneMX[1][1] = up.y; + boneMX[2][1] = up.z; + boneMX[0][2] = forward.x; + boneMX[1][2] = forward.y; + boneMX[2][2] = forward.z; + + boneMX[0][3] = goalBasePosition.x; + boneMX[1][3] = goalBasePosition.y; + boneMX[2][3] = goalBasePosition.z; + } + + + // + // Bone base flex + // + if ( jiggleInfo->flags & JIGGLE_HAS_BASE_SPRING ) + { + // gravity + data->baseAccel.z -= jiggleInfo->baseMass; + + // simple spring + Vector error = goalBasePosition - data->basePos; + data->baseAccel += jiggleInfo->baseStiffness * error - jiggleInfo->baseDamping * data->baseVel; + + data->baseVel += data->baseAccel * deltaT; + data->basePos += data->baseVel * deltaT; + + // clear this timestep's accumulated accelerations + data->baseAccel = vec3_origin; + + // constrain to limits + error = data->basePos - goalBasePosition; + Vector localError; + localError.x = DotProduct( goalLeft, error ); + localError.y = DotProduct( goalUp, error ); + localError.z = DotProduct( goalForward, error ); + + Vector localVel; + localVel.x = DotProduct( goalLeft, data->baseVel ); + localVel.y = DotProduct( goalUp, data->baseVel ); + localVel.z = DotProduct( goalForward, data->baseVel ); + + // horizontal constraint + if ( localError.x < jiggleInfo->baseMinLeft ) + { + localError.x = jiggleInfo->baseMinLeft; + + // friction + data->baseAccel -= jiggleInfo->baseLeftFriction * (localVel.y * goalUp + localVel.z * goalForward); + } + else if ( localError.x > jiggleInfo->baseMaxLeft ) + { + localError.x = jiggleInfo->baseMaxLeft; + + // friction + data->baseAccel -= jiggleInfo->baseLeftFriction * (localVel.y * goalUp + localVel.z * goalForward); + } + + if ( localError.y < jiggleInfo->baseMinUp ) + { + localError.y = jiggleInfo->baseMinUp; + + // friction + data->baseAccel -= jiggleInfo->baseUpFriction * (localVel.x * goalLeft + localVel.z * goalForward); + } + else if ( localError.y > jiggleInfo->baseMaxUp ) + { + localError.y = jiggleInfo->baseMaxUp; + + // friction + data->baseAccel -= jiggleInfo->baseUpFriction * (localVel.x * goalLeft + localVel.z * goalForward); + } + + if ( localError.z < jiggleInfo->baseMinForward ) + { + localError.z = jiggleInfo->baseMinForward; + + // friction + data->baseAccel -= jiggleInfo->baseForwardFriction * (localVel.x * goalLeft + localVel.y * goalUp); + } + else if ( localError.z > jiggleInfo->baseMaxForward ) + { + localError.z = jiggleInfo->baseMaxForward; + + // friction + data->baseAccel -= jiggleInfo->baseForwardFriction * (localVel.x * goalLeft + localVel.y * goalUp); + } + + data->basePos = goalBasePosition + localError.x * goalLeft + localError.y * goalUp + localError.z * goalForward; + + + // fix up velocity + data->baseVel = (data->basePos - data->baseLastPos) / deltaT; + data->baseLastPos = data->basePos; + + + if ( !( jiggleInfo->flags & ( JIGGLE_IS_FLEXIBLE | JIGGLE_IS_RIGID ) ) ) + { + // no tip flex - use bone's goal orientation + boneMX = goalMX; + } + + // update bone position + MatrixSetColumn( data->basePos, 3, boneMX ); + } + else if ( jiggleInfo->flags & JIGGLE_IS_BOING ) + { + // estimate velocity + Vector vel = goalBasePosition - data->lastBoingPos; + +#ifdef CLIENT_DLL + if ( cl_jiggle_bone_debug.GetBool() ) + { + debugoverlay->AddLineOverlay( data->lastBoingPos, goalBasePosition, 0, 128, ( gpGlobals->framecount & 0x1 ) ? 0 : 200, true, 999.9f ); + } +#endif + + data->lastBoingPos = goalBasePosition; + + float speed = vel.NormalizeInPlace(); + if ( speed < 0.00001f ) + { + vel = Vector( 0, 0, 1.0f ); + speed = 0.0f; + } + else + { + speed /= deltaT; + } + + data->boingTime += deltaT; + + // if velocity changed a lot, we impacted and should *boing* + const float minSpeed = 5.0f; // 15.0f; + const float minReBoingTime = 0.5f; + if ( ( speed > minSpeed || data->boingSpeed > minSpeed ) && data->boingTime > minReBoingTime ) + { + if ( fabs( data->boingSpeed - speed ) > jiggleInfo->boingImpactSpeed || DotProduct( vel, data->boingVelDir ) < jiggleInfo->boingImpactAngle ) + { + data->boingTime = 0.0f; + data->boingDir = -vel; + +#ifdef CLIENT_DLL + if ( cl_jiggle_bone_debug.GetBool() ) + { + debugoverlay->AddLineOverlay( goalBasePosition, goalBasePosition + 5.0f * data->boingDir, 255, 255, 0, true, 999.9f ); + debugoverlay->AddLineOverlay( goalBasePosition, goalBasePosition + Vector( 0.1, 0, 0 ), 128, 128, 0, true, 999.9f ); + debugoverlay->AddLineOverlay( goalBasePosition, goalBasePosition + Vector( 0, 0.1, 0 ), 128, 128, 0, true, 999.9f ); + debugoverlay->AddLineOverlay( goalBasePosition, goalBasePosition + Vector( 0, 0, 0.1 ), 128, 128, 0, true, 999.9f ); + } +#endif + } + } + + data->boingVelDir = vel; + data->boingSpeed = speed; + + float damping = 1.0f - ( jiggleInfo->boingDampingRate * data->boingTime ); + if ( damping < 0.01f ) + { + // boing has entirely damped out + boneMX = goalMX; + } + else + { + damping *= damping; + damping *= damping; + + float flex = jiggleInfo->boingAmplitude * cos( jiggleInfo->boingFrequency * data->boingTime ) * damping; + + float squash = 1.0f + flex; + float stretch = 1.0f - flex; + + + boneMX[0][0] = goalLeft.x; + boneMX[1][0] = goalLeft.y; + boneMX[2][0] = goalLeft.z; + + boneMX[0][1] = goalUp.x; + boneMX[1][1] = goalUp.y; + boneMX[2][1] = goalUp.z; + + boneMX[0][2] = goalForward.x; + boneMX[1][2] = goalForward.y; + boneMX[2][2] = goalForward.z; + + boneMX[0][3] = 0.0f; + boneMX[1][3] = 0.0f; + boneMX[2][3] = 0.0f; + + + // build transform into "boing space", where Z is along primary boing axis + Vector boingSide; + if ( fabs( data->boingDir.x ) < 0.9f ) + { + boingSide = CrossProduct( data->boingDir, Vector( 1.0f, 0, 0 ) ); + } + else + { + boingSide = CrossProduct( data->boingDir, Vector( 0, 0, 1.0f ) ); + } + boingSide.NormalizeInPlace(); + + Vector boingOtherSide = CrossProduct( data->boingDir, boingSide ); + + matrix3x4_t xfrmToBoingCoordsMX; + + xfrmToBoingCoordsMX[0][0] = boingSide.x; + xfrmToBoingCoordsMX[0][1] = boingSide.y; + xfrmToBoingCoordsMX[0][2] = boingSide.z; + + xfrmToBoingCoordsMX[1][0] = boingOtherSide.x; + xfrmToBoingCoordsMX[1][1] = boingOtherSide.y; + xfrmToBoingCoordsMX[1][2] = boingOtherSide.z; + + xfrmToBoingCoordsMX[2][0] = data->boingDir.x; + xfrmToBoingCoordsMX[2][1] = data->boingDir.y; + xfrmToBoingCoordsMX[2][2] = data->boingDir.z; + + xfrmToBoingCoordsMX[0][3] = 0.0f; + xfrmToBoingCoordsMX[1][3] = 0.0f; + xfrmToBoingCoordsMX[2][3] = 0.0f; + + // build squash and stretch transform in "boing space" + matrix3x4_t boingMX; + + boingMX[0][0] = squash; + boingMX[1][0] = 0.0f; + boingMX[2][0] = 0.0f; + + boingMX[0][1] = 0.0f; + boingMX[1][1] = squash; + boingMX[2][1] = 0.0f; + + boingMX[0][2] = 0.0f; + boingMX[1][2] = 0.0f; + boingMX[2][2] = stretch; + + boingMX[0][3] = 0.0f; + boingMX[1][3] = 0.0f; + boingMX[2][3] = 0.0f; + + // transform back from boing space (inverse is transpose since orthogonal) + matrix3x4_t xfrmFromBoingCoordsMX; + xfrmFromBoingCoordsMX[0][0] = xfrmToBoingCoordsMX[0][0]; + xfrmFromBoingCoordsMX[1][0] = xfrmToBoingCoordsMX[0][1]; + xfrmFromBoingCoordsMX[2][0] = xfrmToBoingCoordsMX[0][2]; + + xfrmFromBoingCoordsMX[0][1] = xfrmToBoingCoordsMX[1][0]; + xfrmFromBoingCoordsMX[1][1] = xfrmToBoingCoordsMX[1][1]; + xfrmFromBoingCoordsMX[2][1] = xfrmToBoingCoordsMX[1][2]; + + xfrmFromBoingCoordsMX[0][2] = xfrmToBoingCoordsMX[2][0]; + xfrmFromBoingCoordsMX[1][2] = xfrmToBoingCoordsMX[2][1]; + xfrmFromBoingCoordsMX[2][2] = xfrmToBoingCoordsMX[2][2]; + + xfrmFromBoingCoordsMX[0][3] = 0.0f; + xfrmFromBoingCoordsMX[1][3] = 0.0f; + xfrmFromBoingCoordsMX[2][3] = 0.0f; + + // put it all together + matrix3x4_t xfrmMX; + MatrixMultiply( xfrmToBoingCoordsMX, boingMX, xfrmMX ); + MatrixMultiply( xfrmMX, xfrmFromBoingCoordsMX, xfrmMX ); + MatrixMultiply( boneMX, xfrmMX, boneMX ); + +#ifdef CLIENT_DLL + if ( cl_jiggle_bone_debug.GetBool() ) + { + float dT = 0.01f; + debugoverlay->AddLineOverlay( goalBasePosition, goalBasePosition + 50.0f * data->boingDir, 255, 255, 0, true, dT ); + debugoverlay->AddLineOverlay( goalBasePosition, goalBasePosition + 50.0f * boingSide, 255, 0, 255, true, dT ); + debugoverlay->AddLineOverlay( goalBasePosition, goalBasePosition + 50.0f * boingOtherSide, 0, 255, 255, true, dT ); + } +#endif + + boneMX[0][3] = goalBasePosition.x; + boneMX[1][3] = goalBasePosition.y; + boneMX[2][3] = goalBasePosition.z; + } + } + else if ( !( jiggleInfo->flags & ( JIGGLE_IS_FLEXIBLE | JIGGLE_IS_RIGID ) ) ) + { + // no flex at all - just use goal matrix + boneMX = goalMX; + } + +#ifdef CLIENT_DLL + // debug display for client only so server doesn't try to also draw it + if ( cl_jiggle_bone_debug.GetBool() ) + { + float dT = 0.01f; + const float axisSize = 5.0f; + debugoverlay->AddLineOverlay( goalBasePosition, goalBasePosition + axisSize * goalLeft, 255, 0, 0, true, dT ); + debugoverlay->AddLineOverlay( goalBasePosition, goalBasePosition + axisSize * goalUp, 0, 255, 0, true, dT ); + debugoverlay->AddLineOverlay( goalBasePosition, goalBasePosition + axisSize * goalForward, 0, 0, 255, true, dT ); + + if ( cl_jiggle_bone_debug.GetInt() > 1 ) + { + DevMsg( "Jiggle bone #%d, basePos( %3.2f, %3.2f, %3.2f ), tipPos( %3.2f, %3.2f, %3.2f ), left( %3.2f, %3.2f, %3.2f ), up( %3.2f, %3.2f, %3.2f ), forward( %3.2f, %3.2f, %3.2f )\n", + data->bone, + goalBasePosition.x, goalBasePosition.y, goalBasePosition.z, + data->tipPos.x, data->tipPos.y, data->tipPos.z, + goalLeft.x, goalLeft.y, goalLeft.z, + goalUp.x, goalUp.y, goalUp.z, + goalForward.x, goalForward.y, goalForward.z ); + } + + const float sz = 1.0f; + + if ( jiggleInfo->flags & ( JIGGLE_IS_FLEXIBLE | JIGGLE_IS_RIGID ) ) + { + debugoverlay->AddLineOverlay( goalBasePosition, + data->tipPos, 255, 255, 0, true, dT ); + + debugoverlay->AddLineOverlay( data->tipPos + Vector( -sz, 0, 0 ), + data->tipPos + Vector( sz, 0, 0 ), 0, 255, 255, true, dT ); + debugoverlay->AddLineOverlay( data->tipPos + Vector( 0, -sz, 0 ), + data->tipPos + Vector( 0, sz, 0 ), 0, 255, 255, true, dT ); + debugoverlay->AddLineOverlay( data->tipPos + Vector( 0, 0, -sz ), + data->tipPos + Vector( 0, 0, sz ), 0, 255, 255, true, dT ); + } + + if ( jiggleInfo->flags & JIGGLE_HAS_BASE_SPRING ) + { + debugoverlay->AddLineOverlay( data->basePos + Vector( -sz, 0, 0 ), + data->basePos + Vector( sz, 0, 0 ), 255, 0, 255, true, dT ); + debugoverlay->AddLineOverlay( data->basePos + Vector( 0, -sz, 0 ), + data->basePos + Vector( 0, sz, 0 ), 255, 0, 255, true, dT ); + debugoverlay->AddLineOverlay( data->basePos + Vector( 0, 0, -sz ), + data->basePos + Vector( 0, 0, sz ), 255, 0, 255, true, dT ); + } + + + if ( jiggleInfo->flags & JIGGLE_IS_BOING ) + { + if ( cl_jiggle_bone_debug.GetInt() > 2 ) + { + DevMsg( " boingSpeed = %3.2f, boingVelDir( %3.2f, %3.2f, %3.2f )\n", data->boingVelDir.Length() / deltaT, data->boingVelDir.x, data->boingVelDir.y, data->boingVelDir.z ); + } + } + } +#endif // CLIENT_DLL +} + diff --git a/sp/src/public/jigglebones.h b/sp/src/public/jigglebones.h new file mode 100644 index 00000000..57afdaa7 --- /dev/null +++ b/sp/src/public/jigglebones.h @@ -0,0 +1,82 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $NoKeywords: $ +//=============================================================================// +#ifndef C_JIGGLEBONES_H +#define C_JIGGLEBONES_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "studio.h" +#include "utlvector.h" +#include "utllinkedlist.h" + +//----------------------------------------------------------------------------- +/** + * JiggleData is the instance-specific data for a jiggle bone + */ +struct JiggleData +{ + void Init( int initBone, float currenttime, const Vector &initBasePos, const Vector &initTipPos ) + { + bone = initBone; + + lastUpdate = currenttime; + + basePos = initBasePos; + baseLastPos = basePos; + baseVel.Init(); + baseAccel.Init(); + + tipPos = initTipPos; + tipVel.Init(); + tipAccel.Init(); + + lastLeft = Vector( 0, 0, 0 ); + + lastBoingPos = initBasePos; + boingDir = Vector( 0.0f, 0.0f, 1.0f ); + boingVelDir.Init(); + boingSpeed = 0.0f; + boingTime = 0.0f; + } + + int bone; + + float lastUpdate; // based on gpGlobals->realtime + + Vector basePos; // position of the base of the jiggle bone + Vector baseLastPos; + Vector baseVel; + Vector baseAccel; + + Vector tipPos; // position of the tip of the jiggle bone + Vector tipVel; + Vector tipAccel; + Vector lastLeft; // previous up vector + + Vector lastBoingPos; // position of base of jiggle bone last update for tracking velocity + Vector boingDir; // current direction along which the boing effect is occurring + Vector boingVelDir; // current estimation of jiggle bone unit velocity vector for boing effect + float boingSpeed; // current estimation of jiggle bone speed for boing effect + float boingTime; +}; + +class CJiggleBones +{ +public: + JiggleData * GetJiggleData( int bone, float currenttime, const Vector &initBasePos, const Vector &initTipPos ); + void BuildJiggleTransformations( int boneIndex, float currentime, const mstudiojigglebone_t *jiggleParams, const matrix3x4_t &goalMX, matrix3x4_t &boneMX ); + + CUtlLinkedList< JiggleData > m_jiggleBoneState; +}; + + +extern void DevMsgRT( PRINTF_FORMAT_STRING char const* pMsg, ... ); + +#endif // C_BASEANIMATING_H diff --git a/sp/src/public/jpeglib/jconfig.h b/sp/src/public/jpeglib/jconfig.h new file mode 100644 index 00000000..23ebaa60 --- /dev/null +++ b/sp/src/public/jpeglib/jconfig.h @@ -0,0 +1,56 @@ +/* jconfig.h. Generated from jconfig.cfg by configure. */ +/* jconfig.cfg --- source file edited by configure script */ +/* see jconfig.txt for explanations */ + +#define HAVE_PROTOTYPES 1 +#define HAVE_UNSIGNED_CHAR 1 +#define HAVE_UNSIGNED_SHORT 1 +/* #undef void */ +/* #undef const */ +/* #undef CHAR_IS_UNSIGNED */ +#define HAVE_STDDEF_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_LOCALE_H 1 +/* #undef NEED_BSD_STRINGS */ +/* #undef NEED_SYS_TYPES_H */ +/* #undef NEED_FAR_POINTERS */ +/* #undef NEED_SHORT_EXTERNAL_NAMES */ +/* Define this if you get warnings about undefined structures. */ +/* #undef INCOMPLETE_TYPES_BROKEN */ + +/* Define "boolean" as unsigned char, not int, on Windows systems. */ +#ifdef _WIN32 +#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ +typedef unsigned char boolean; +#endif +#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ +#endif + +#ifdef JPEG_INTERNALS + +/* #undef RIGHT_SHIFT_IS_UNSIGNED */ +#ifdef __cplusplus +#define INLINE __inline__ +#endif +/* These are for configuring the JPEG memory manager. */ +/* #undef DEFAULT_MAX_MEM */ +/* #undef NO_MKTEMP */ + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +/* #undef RLE_SUPPORTED */ +#define TARGA_SUPPORTED /* Targa image file format */ + +/* #undef TWO_FILE_COMMANDLINE */ +/* #undef NEED_SIGNAL_CATCHER */ +/* #undef DONT_USE_B_MODE */ + +/* Define this if you want percent-done progress reports from cjpeg/djpeg. */ +/* #undef PROGRESS_REPORT */ + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/sp/src/public/jpeglib/jmorecfg.h b/sp/src/public/jpeglib/jmorecfg.h new file mode 100644 index 00000000..928d052c --- /dev/null +++ b/sp/src/public/jpeglib/jmorecfg.h @@ -0,0 +1,371 @@ +/* + * jmorecfg.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * Modified 1997-2009 by Guido Vollbeding. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains additional configuration options that customize the + * JPEG software for special applications or support machine-dependent + * optimizations. Most users will not need to touch this file. + */ + + +/* + * Define BITS_IN_JSAMPLE as either + * 8 for 8-bit sample values (the usual setting) + * 12 for 12-bit sample values + * Only 8 and 12 are legal data precisions for lossy JPEG according to the + * JPEG standard, and the IJG code does not support anything else! + * We do not support run-time selection of data precision, sorry. + */ + +#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ + + +/* + * Maximum number of components (color channels) allowed in JPEG image. + * To meet the letter of the JPEG spec, set this to 255. However, darn + * few applications need more than 4 channels (maybe 5 for CMYK + alpha + * mask). We recommend 10 as a reasonable compromise; use 4 if you are + * really short on memory. (Each allowed component costs a hundred or so + * bytes of storage, whether actually used in an image or not.) + */ + +#define MAX_COMPONENTS 10 /* maximum number of image components */ + + +/* + * Basic data types. + * You may need to change these if you have a machine with unusual data + * type sizes; for example, "char" not 8 bits, "short" not 16 bits, + * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, + * but it had better be at least 16. + */ + +/* Representation of a single sample (pixel element value). + * We frequently allocate large arrays of these, so it's important to keep + * them small. But if you have memory to burn and access to char or short + * arrays is very slow on your hardware, you might want to change these. + */ + +#if BITS_IN_JSAMPLE == 8 +/* JSAMPLE should be the smallest type that will hold the values 0..255. + * You can use a signed char by having GETJSAMPLE mask it with 0xFF. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JSAMPLE; +#ifdef CHAR_IS_UNSIGNED +#define GETJSAMPLE(value) ((int) (value)) +#else +#define GETJSAMPLE(value) ((int) (value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + +#define MAXJSAMPLE 255 +#define CENTERJSAMPLE 128 + +#endif /* BITS_IN_JSAMPLE == 8 */ + + +#if BITS_IN_JSAMPLE == 12 +/* JSAMPLE should be the smallest type that will hold the values 0..4095. + * On nearly all machines "short" will do nicely. + */ + +typedef short JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#define MAXJSAMPLE 4095 +#define CENTERJSAMPLE 2048 + +#endif /* BITS_IN_JSAMPLE == 12 */ + + +/* Representation of a DCT frequency coefficient. + * This should be a signed value of at least 16 bits; "short" is usually OK. + * Again, we allocate large arrays of these, but you can change to int + * if you have memory to burn and "short" is really slow. + */ + +typedef short JCOEF; + + +/* Compressed datastreams are represented as arrays of JOCTET. + * These must be EXACTLY 8 bits wide, at least once they are written to + * external storage. Note that when using the stdio data source/destination + * managers, this is also the data type passed to fread/fwrite. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JOCTET; +#define GETJOCTET(value) (value) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JOCTET; +#ifdef CHAR_IS_UNSIGNED +#define GETJOCTET(value) (value) +#else +#define GETJOCTET(value) ((value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + + +/* These typedefs are used for various table entries and so forth. + * They must be at least as wide as specified; but making them too big + * won't cost a huge amount of memory, so we don't provide special + * extraction code like we did for JSAMPLE. (In other words, these + * typedefs live at a different point on the speed/space tradeoff curve.) + */ + +/* UINT8 must hold at least the values 0..255. */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char UINT8; +#else /* not HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char UINT8; +#else /* not CHAR_IS_UNSIGNED */ +typedef short UINT8; +#endif /* CHAR_IS_UNSIGNED */ +#endif /* HAVE_UNSIGNED_CHAR */ + +/* UINT16 must hold at least the values 0..65535. */ + +#ifdef HAVE_UNSIGNED_SHORT +typedef unsigned short UINT16; +#else /* not HAVE_UNSIGNED_SHORT */ +typedef unsigned int UINT16; +#endif /* HAVE_UNSIGNED_SHORT */ + +/* INT16 must hold at least the values -32768..32767. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ +typedef short INT16; +#endif + +/* INT32 must hold at least signed 32-bit values. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ +#ifndef _BASETSD_H_ /* Microsoft defines it in basetsd.h */ +#ifndef _BASETSD_H /* MinGW is slightly different */ +#ifndef QGLOBAL_H /* Qt defines it in qglobal.h */ +typedef long INT32; +#endif +#endif +#endif +#endif + +/* Datatype used for image dimensions. The JPEG standard only supports + * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore + * "unsigned int" is sufficient on all machines. However, if you need to + * handle larger images and you don't mind deviating from the spec, you + * can change this datatype. + */ + +typedef unsigned int JDIMENSION; + +#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ + + +/* These macros are used in all function definitions and extern declarations. + * You could modify them if you need to change function linkage conventions; + * in particular, you'll need to do that to make the library a Windows DLL. + * Another application is to make all functions global for use with debuggers + * or code profilers that require it. + */ + +/* a function called through method pointers: */ +#define METHODDEF(type) static type +/* a function used only in its module: */ +#define LOCAL(type) static type +/* a function referenced thru EXTERNs: */ +#define GLOBAL(type) type +/* a reference to a GLOBAL function: */ +#define EXTERN(type) extern type + + +/* This macro is used to declare a "method", that is, a function pointer. + * We want to supply prototype parameters if the compiler can cope. + * Note that the arglist parameter must be parenthesized! + * Again, you can customize this if you need special linkage keywords. + */ + +#ifdef HAVE_PROTOTYPES +#define JMETHOD(type,methodname,arglist) type (*methodname) arglist +#else +#define JMETHOD(type,methodname,arglist) type (*methodname) () +#endif + + +/* Here is the pseudo-keyword for declaring pointers that must be "far" + * on 80x86 machines. Most of the specialized coding for 80x86 is handled + * by just saying "FAR *" where such a pointer is needed. In a few places + * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol. + */ + +#ifndef FAR +#ifdef NEED_FAR_POINTERS +#define FAR far +#else +#define FAR +#endif +#endif + + +/* + * On a few systems, type boolean and/or its values FALSE, TRUE may appear + * in standard header files. Or you may have conflicts with application- + * specific header files that you want to include together with these files. + * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. + */ + +#ifndef HAVE_BOOLEAN +typedef int boolean; +#endif +#ifndef FALSE /* in case these macros already exist */ +#define FALSE 0 /* values of boolean */ +#endif +#ifndef TRUE +#define TRUE 1 +#endif + + +/* + * The remaining options affect code selection within the JPEG library, + * but they don't need to be visible to most applications using the library. + * To minimize application namespace pollution, the symbols won't be + * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined. + */ + +#ifdef JPEG_INTERNALS +#define JPEG_INTERNAL_OPTIONS +#endif + +#ifdef JPEG_INTERNAL_OPTIONS + + +/* + * These defines indicate whether to include various optional functions. + * Undefining some of these symbols will produce a smaller but less capable + * library. Note that you can leave certain source files out of the + * compilation/linking process if you've #undef'd the corresponding symbols. + * (You may HAVE to do that if your compiler doesn't like null source files.) + */ + +/* Capability options common to encoder and decoder: */ + +#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ +#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ +#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */ + +/* Encoder capability options: */ + +#define C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define DCT_SCALING_SUPPORTED /* Input rescaling via DCT? (Requires DCT_ISLOW)*/ +#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ +/* Note: if you selected 12-bit data precision, it is dangerous to turn off + * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit + * precision, so jchuff.c normally uses entropy optimization to compute + * usable tables for higher precision. If you don't want to do optimization, + * you'll have to supply different default Huffman tables. + * The exact same statements apply for progressive JPEG: the default tables + * don't work for progressive mode. (This may get fixed, however.) + */ +#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */ + +/* Decoder capability options: */ + +#define D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ +#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ +#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ +#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ +#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ +#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ +#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ + +/* more capability options later, no doubt */ + + +/* + * Ordering of RGB data in scanlines passed to or from the application. + * If your application wants to deal with data in the order B,G,R, just + * change these macros. You can also deal with formats such as R,G,B,X + * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing + * the offsets will also change the order in which colormap data is organized. + * RESTRICTIONS: + * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. + * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not + * useful if you are using JPEG color spaces other than YCbCr or grayscale. + * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE + * is not 3 (they don't understand about dummy color components!). So you + * can't use color quantization if you change that value. + */ + +#define RGB_RED 0 /* Offset of Red in an RGB scanline element */ +#define RGB_GREEN 1 /* Offset of Green */ +#define RGB_BLUE 2 /* Offset of Blue */ +#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ + + +/* Definitions for speed-related optimizations. */ + + +/* If your compiler supports inline functions, define INLINE + * as the inline keyword; otherwise define it as empty. + */ + +#ifndef INLINE +#ifdef __GNUC__ /* for instance, GNU C knows about inline */ +#define INLINE __inline__ +#endif +#ifndef INLINE +#define INLINE /* default is to define it as empty */ +#endif +#endif + + +/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying + * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER + * as short on such a machine. MULTIPLIER must be at least 16 bits wide. + */ + +#ifndef MULTIPLIER +#define MULTIPLIER int /* type for fastest integer multiply */ +#endif + + +/* FAST_FLOAT should be either float or double, whichever is done faster + * by your compiler. (Note that this type is only used in the floating point + * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) + * Typically, float is faster in ANSI C compilers, while double is faster in + * pre-ANSI compilers (because they insist on converting to double anyway). + * The code below therefore chooses float if we have ANSI-style prototypes. + */ + +#ifndef FAST_FLOAT +#ifdef HAVE_PROTOTYPES +#define FAST_FLOAT float +#else +#define FAST_FLOAT double +#endif +#endif + +#endif /* JPEG_INTERNAL_OPTIONS */ diff --git a/sp/src/public/jpeglib/jpeglib.h b/sp/src/public/jpeglib/jpeglib.h new file mode 100644 index 00000000..5039d4bf --- /dev/null +++ b/sp/src/public/jpeglib/jpeglib.h @@ -0,0 +1,1158 @@ +/* + * jpeglib.h + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * Modified 2002-2009 by Guido Vollbeding. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the application interface for the JPEG library. + * Most applications using the library need only include this file, + * and perhaps jerror.h if they want to know the exact error codes. + */ + +#ifndef JPEGLIB_H +#define JPEGLIB_H + +/* + * First we include the configuration files that record how this + * installation of the JPEG library is set up. jconfig.h can be + * generated automatically for many systems. jmorecfg.h contains + * manual configuration options that most people need not worry about. + */ + +#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ +#include "jconfig.h" /* widely used configuration options */ +#endif +#include "jmorecfg.h" /* seldom changed options */ + + +#ifdef __cplusplus +#ifndef DONT_USE_EXTERN_C +extern "C" { +#endif +#endif + +/* Version ID for the JPEG library. + * Might be useful for tests like "#if JPEG_LIB_VERSION >= 80". + */ + +#define JPEG_LIB_VERSION 80 /* Version 8.0 */ + + +/* Various constants determining the sizes of things. + * All of these are specified by the JPEG standard, so don't change them + * if you want to be compatible. + */ + +#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */ +#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ +#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ +#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ +#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ +#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ +#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ +/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; + * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. + * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU + * to handle it. We even let you do this from the jconfig.h file. However, + * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe + * sometimes emits noncompliant files doesn't mean you should too. + */ +#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ +#ifndef D_MAX_BLOCKS_IN_MCU +#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ +#endif + + +/* Data structures for images (arrays of samples and of DCT coefficients). + * On 80x86 machines, the image arrays are too big for near pointers, + * but the pointer arrays can fit in near memory. + */ + +typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */ +typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ +typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ + +typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ +typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */ +typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ +typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ + +typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ + + +/* Types for JPEG compression parameters and working tables. */ + + +/* DCT coefficient quantization tables. */ + +typedef struct { + /* This array gives the coefficient quantizers in natural array order + * (not the zigzag order in which they are stored in a JPEG DQT marker). + * CAUTION: IJG versions prior to v6a kept this array in zigzag order. + */ + UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JQUANT_TBL; + + +/* Huffman coding tables. */ + +typedef struct { + /* These two fields directly represent the contents of a JPEG DHT marker */ + UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ + /* length k bits; bits[0] is unused */ + UINT8 huffval[256]; /* The symbols, in order of incr code length */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JHUFF_TBL; + + +/* Basic info about one component (color channel). */ + +typedef struct { + /* These values are fixed over the whole image. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOF marker. */ + int component_id; /* identifier for this component (0..255) */ + int component_index; /* its index in SOF or cinfo->comp_info[] */ + int h_samp_factor; /* horizontal sampling factor (1..4) */ + int v_samp_factor; /* vertical sampling factor (1..4) */ + int quant_tbl_no; /* quantization table selector (0..3) */ + /* These values may vary between scans. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOS marker. */ + /* The decompressor output side may not use these variables. */ + int dc_tbl_no; /* DC entropy table selector (0..3) */ + int ac_tbl_no; /* AC entropy table selector (0..3) */ + + /* Remaining fields should be treated as private by applications. */ + + /* These values are computed during compression or decompression startup: */ + /* Component's size in DCT blocks. + * Any dummy blocks added to complete an MCU are not counted; therefore + * these values do not depend on whether a scan is interleaved or not. + */ + JDIMENSION width_in_blocks; + JDIMENSION height_in_blocks; + /* Size of a DCT block in samples, + * reflecting any scaling we choose to apply during the DCT step. + * Values from 1 to 16 are supported. + * Note that different components may receive different DCT scalings. + */ + int DCT_h_scaled_size; + int DCT_v_scaled_size; + /* The downsampled dimensions are the component's actual, unpadded number + * of samples at the main buffer (preprocessing/compression interface); + * DCT scaling is included, so + * downsampled_width = ceil(image_width * Hi/Hmax * DCT_h_scaled_size/DCTSIZE) + * and similarly for height. + */ + JDIMENSION downsampled_width; /* actual width in samples */ + JDIMENSION downsampled_height; /* actual height in samples */ + /* This flag is used only for decompression. In cases where some of the + * components will be ignored (eg grayscale output from YCbCr image), + * we can skip most computations for the unused components. + */ + boolean component_needed; /* do we need the value of this component? */ + + /* These values are computed before starting a scan of the component. */ + /* The decompressor output side may not use these variables. */ + int MCU_width; /* number of blocks per MCU, horizontally */ + int MCU_height; /* number of blocks per MCU, vertically */ + int MCU_blocks; /* MCU_width * MCU_height */ + int MCU_sample_width; /* MCU width in samples: MCU_width * DCT_h_scaled_size */ + int last_col_width; /* # of non-dummy blocks across in last MCU */ + int last_row_height; /* # of non-dummy blocks down in last MCU */ + + /* Saved quantization table for component; NULL if none yet saved. + * See jdinput.c comments about the need for this information. + * This field is currently used only for decompression. + */ + JQUANT_TBL * quant_table; + + /* Private per-component storage for DCT or IDCT subsystem. */ + void * dct_table; +} jpeg_component_info; + + +/* The script for encoding a multiple-scan file is an array of these: */ + +typedef struct { + int comps_in_scan; /* number of components encoded in this scan */ + int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ + int Ss, Se; /* progressive JPEG spectral selection parms */ + int Ah, Al; /* progressive JPEG successive approx. parms */ +} jpeg_scan_info; + +/* The decompressor can save APPn and COM markers in a list of these: */ + +typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr; + +struct jpeg_marker_struct { + jpeg_saved_marker_ptr next; /* next in list, or NULL */ + UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ + unsigned int original_length; /* # bytes of data in the file */ + unsigned int data_length; /* # bytes of data saved at data[] */ + JOCTET FAR * data; /* the data contained in the marker */ + /* the marker length word is not counted in data_length or original_length */ +}; + +/* Known color spaces. */ + +typedef enum { + JCS_UNKNOWN, /* error/unspecified */ + JCS_GRAYSCALE, /* monochrome */ + JCS_RGB, /* red/green/blue */ + JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ + JCS_CMYK, /* C/M/Y/K */ + JCS_YCCK /* Y/Cb/Cr/K */ +} J_COLOR_SPACE; + +/* DCT/IDCT algorithm options. */ + +typedef enum { + JDCT_ISLOW, /* slow but accurate integer algorithm */ + JDCT_IFAST, /* faster, less accurate integer method */ + JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ +} J_DCT_METHOD; + +#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ +#define JDCT_DEFAULT JDCT_ISLOW +#endif +#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ +#define JDCT_FASTEST JDCT_IFAST +#endif + +/* Dithering options for decompression. */ + +typedef enum { + JDITHER_NONE, /* no dithering */ + JDITHER_ORDERED, /* simple ordered dither */ + JDITHER_FS /* Floyd-Steinberg error diffusion dither */ +} J_DITHER_MODE; + + +/* Common fields between JPEG compression and decompression master structs. */ + +#define jpeg_common_fields \ + struct jpeg_error_mgr * err; /* Error handler module */\ + struct jpeg_memory_mgr * mem; /* Memory manager module */\ + struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ + void * client_data; /* Available for use by application */\ + boolean is_decompressor; /* So common code can tell which is which */\ + int global_state /* For checking call sequence validity */ + +/* Routines that are to be used by both halves of the library are declared + * to receive a pointer to this structure. There are no actual instances of + * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. + */ +struct jpeg_common_struct { + jpeg_common_fields; /* Fields common to both master struct types */ + /* Additional fields follow in an actual jpeg_compress_struct or + * jpeg_decompress_struct. All three structs must agree on these + * initial fields! (This would be a lot cleaner in C++.) + */ +}; + +typedef struct jpeg_common_struct * j_common_ptr; +typedef struct jpeg_compress_struct * j_compress_ptr; +typedef struct jpeg_decompress_struct * j_decompress_ptr; + + +/* Master record for a compression instance */ + +struct jpeg_compress_struct { + jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ + + /* Destination for compressed data */ + struct jpeg_destination_mgr * dest; + + /* Description of source image --- these fields must be filled in by + * outer application before starting compression. in_color_space must + * be correct before you can even call jpeg_set_defaults(). + */ + + JDIMENSION image_width; /* input image width */ + JDIMENSION image_height; /* input image height */ + int input_components; /* # of color components in input image */ + J_COLOR_SPACE in_color_space; /* colorspace of input image */ + + double input_gamma; /* image gamma of input image */ + + /* Compression parameters --- these fields must be set before calling + * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + * initialize everything to reasonable defaults, then changing anything + * the application specifically wants to change. That way you won't get + * burnt when new parameters are added. Also note that there are several + * helper routines to simplify changing parameters. + */ + + unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + + JDIMENSION jpeg_width; /* scaled JPEG image width */ + JDIMENSION jpeg_height; /* scaled JPEG image height */ + /* Dimensions of actual JPEG image that will be written to file, + * derived from input dimensions by scaling factors above. + * These fields are computed by jpeg_start_compress(). + * You can also use jpeg_calc_jpeg_dimensions() to determine these values + * in advance of calling jpeg_start_compress(). + */ + + int data_precision; /* bits of precision in image data */ + + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + int q_scale_factor[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined, + * and corresponding scale factors (percentage, initialized 100). + */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + int num_scans; /* # of entries in scan_info array */ + const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ + /* The default value of scan_info is NULL, which causes a single-scan + * sequential JPEG file to be emitted. To create a multi-scan file, + * set num_scans and scan_info to point to an array of scan definitions. + */ + + boolean raw_data_in; /* TRUE=caller supplies downsampled data */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + boolean optimize_coding; /* TRUE=optimize entropy encoding parms */ + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + boolean do_fancy_downsampling; /* TRUE=apply fancy downsampling */ + int smoothing_factor; /* 1..100, or 0 for no input smoothing */ + J_DCT_METHOD dct_method; /* DCT algorithm selector */ + + /* The restart interval can be specified in absolute MCUs by setting + * restart_interval, or in MCU rows by setting restart_in_rows + * (in which case the correct restart_interval will be figured + * for each scan). + */ + unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ + int restart_in_rows; /* if > 0, MCU rows per restart interval */ + + /* Parameters controlling emission of special markers. */ + + boolean write_JFIF_header; /* should a JFIF marker be written? */ + UINT8 JFIF_major_version; /* What to write for the JFIF version number */ + UINT8 JFIF_minor_version; + /* These three values are not used by the JPEG code, merely copied */ + /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ + /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ + /* ratio is defined by X_density/Y_density even when density_unit=0. */ + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean write_Adobe_marker; /* should an Adobe marker be written? */ + + /* State variable: index of next scanline to be written to + * jpeg_write_scanlines(). Application may use this to control its + * processing loop, e.g., "while (next_scanline < image_height)". + */ + + JDIMENSION next_scanline; /* 0 .. image_height-1 */ + + /* Remaining fields are known throughout compressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during compression startup + */ + boolean progressive_mode; /* TRUE if scan script uses progressive mode */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */ + int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ + /* The coefficient controller receives data in units of MCU rows as defined + * for fully interleaved scans (whether the JPEG file is interleaved or not). + * There are v_samp_factor * DCTSIZE sample rows of each component in an + * "iMCU" (interleaved MCU) row. + */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[C_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + int block_size; /* the basic DCT block size: 1..16 */ + const int * natural_order; /* natural-order position array */ + int lim_Se; /* min( Se, DCTSIZE2-1 ) */ + + /* + * Links to compression subobjects (methods and private variables of modules) + */ + struct jpeg_comp_master * master; + struct jpeg_c_main_controller * main; + struct jpeg_c_prep_controller * prep; + struct jpeg_c_coef_controller * coef; + struct jpeg_marker_writer * marker; + struct jpeg_color_converter * cconvert; + struct jpeg_downsampler * downsample; + struct jpeg_forward_dct * fdct; + struct jpeg_entropy_encoder * entropy; + jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */ + int script_space_size; +}; + + +/* Master record for a decompression instance */ + +struct jpeg_decompress_struct { + jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ + + /* Source of compressed data */ + struct jpeg_source_mgr * src; + + /* Basic description of image --- filled in by jpeg_read_header(). */ + /* Application may inspect these values to decide how to process image. */ + + JDIMENSION image_width; /* nominal image width (from SOF marker) */ + JDIMENSION image_height; /* nominal image height */ + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + /* Decompression processing parameters --- these fields must be set before + * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes + * them to default values. + */ + + J_COLOR_SPACE out_color_space; /* colorspace for output */ + + unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + + double output_gamma; /* image gamma wanted in output */ + + boolean buffered_image; /* TRUE=multiple output passes */ + boolean raw_data_out; /* TRUE=downsampled data wanted */ + + J_DCT_METHOD dct_method; /* IDCT algorithm selector */ + boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */ + boolean do_block_smoothing; /* TRUE=apply interblock smoothing */ + + boolean quantize_colors; /* TRUE=colormapped output wanted */ + /* the following are ignored if not quantize_colors: */ + J_DITHER_MODE dither_mode; /* type of color dithering to use */ + boolean two_pass_quantize; /* TRUE=use two-pass color quantization */ + int desired_number_of_colors; /* max # colors to use in created colormap */ + /* these are significant only in buffered-image mode: */ + boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */ + boolean enable_external_quant;/* enable future use of external colormap */ + boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */ + + /* Description of actual output image that will be returned to application. + * These fields are computed by jpeg_start_decompress(). + * You can also use jpeg_calc_output_dimensions() to determine these values + * in advance of calling jpeg_start_decompress(). + */ + + JDIMENSION output_width; /* scaled image width */ + JDIMENSION output_height; /* scaled image height */ + int out_color_components; /* # of color components in out_color_space */ + int output_components; /* # of color components returned */ + /* output_components is 1 (a colormap index) when quantizing colors; + * otherwise it equals out_color_components. + */ + int rec_outbuf_height; /* min recommended height of scanline buffer */ + /* If the buffer passed to jpeg_read_scanlines() is less than this many rows + * high, space and time will be wasted due to unnecessary data copying. + * Usually rec_outbuf_height will be 1 or 2, at most 4. + */ + + /* When quantizing colors, the output colormap is described by these fields. + * The application can supply a colormap by setting colormap non-NULL before + * calling jpeg_start_decompress; otherwise a colormap is created during + * jpeg_start_decompress or jpeg_start_output. + * The map has out_color_components rows and actual_number_of_colors columns. + */ + int actual_number_of_colors; /* number of entries in use */ + JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ + + /* State variables: these variables indicate the progress of decompression. + * The application may examine these but must not modify them. + */ + + /* Row index of next scanline to be read from jpeg_read_scanlines(). + * Application may use this to control its processing loop, e.g., + * "while (output_scanline < output_height)". + */ + JDIMENSION output_scanline; /* 0 .. output_height-1 */ + + /* Current input scan number and number of iMCU rows completed in scan. + * These indicate the progress of the decompressor input side. + */ + int input_scan_number; /* Number of SOS markers seen so far */ + JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ + + /* The "output scan number" is the notional scan being displayed by the + * output side. The decompressor will not allow output scan/row number + * to get ahead of input scan/row, but it can fall arbitrarily far behind. + */ + int output_scan_number; /* Nominal scan number being displayed */ + JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ + + /* Current progression status. coef_bits[c][i] indicates the precision + * with which component c's DCT coefficient i (in zigzag order) is known. + * It is -1 when no data has yet been received, otherwise it is the point + * transform (shift) value for the most recent scan of the coefficient + * (thus, 0 at completion of the progression). + * This pointer is NULL when reading a non-progressive file. + */ + int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ + + /* Internal JPEG parameters --- the application usually need not look at + * these fields. Note that the decompressor output side may not use + * any parameters that can change between scans. + */ + + /* Quantization and Huffman tables are carried forward across input + * datastreams when processing abbreviated JPEG datastreams. + */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + /* These parameters are never carried across datastreams, since they + * are given in SOF/SOS markers or defined to be reset by SOI. + */ + + int data_precision; /* bits of precision in image data */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + boolean is_baseline; /* TRUE if Baseline SOF0 encountered */ + boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ + + /* These fields record data obtained from optional markers recognized by + * the JPEG library. + */ + boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ + /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ + UINT8 JFIF_major_version; /* JFIF version number */ + UINT8 JFIF_minor_version; + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ + UINT8 Adobe_transform; /* Color transform code from Adobe marker */ + + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + + /* Aside from the specific data retained from APPn markers known to the + * library, the uninterpreted contents of any or all APPn and COM markers + * can be saved in a list for examination by the application. + */ + jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ + + /* Remaining fields are known throughout decompressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during decompression startup + */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */ + int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ + /* The coefficient controller's input and output progress is measured in + * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows + * in fully interleaved JPEG scans, but are used whether the scan is + * interleaved or not. We define an iMCU row as v_samp_factor DCT block + * rows of each component. Therefore, the IDCT output contains + * v_samp_factor*DCT_v_scaled_size sample rows of a component per iMCU row. + */ + + JSAMPLE * sample_range_limit; /* table for fast range-limiting */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + * Note that the decompressor output side must not use these fields. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[D_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* These fields are derived from Se of first SOS marker. + */ + int block_size; /* the basic DCT block size: 1..16 */ + const int * natural_order; /* natural-order position array for entropy decode */ + int lim_Se; /* min( Se, DCTSIZE2-1 ) for entropy decode */ + + /* This field is shared between entropy decoder and marker parser. + * It is either zero or the code of a JPEG marker that has been + * read from the data source, but has not yet been processed. + */ + int unread_marker; + + /* + * Links to decompression subobjects (methods, private variables of modules) + */ + struct jpeg_decomp_master * master; + struct jpeg_d_main_controller * main; + struct jpeg_d_coef_controller * coef; + struct jpeg_d_post_controller * post; + struct jpeg_input_controller * inputctl; + struct jpeg_marker_reader * marker; + struct jpeg_entropy_decoder * entropy; + struct jpeg_inverse_dct * idct; + struct jpeg_upsampler * upsample; + struct jpeg_color_deconverter * cconvert; + struct jpeg_color_quantizer * cquantize; +}; + + +/* "Object" declarations for JPEG modules that may be supplied or called + * directly by the surrounding application. + * As with all objects in the JPEG library, these structs only define the + * publicly visible methods and state variables of a module. Additional + * private fields may exist after the public ones. + */ + + +/* Error handler object */ + +struct jpeg_error_mgr { + /* Error exit handler: does not return to caller */ + JMETHOD(void, error_exit, (j_common_ptr cinfo)); + /* Conditionally emit a trace or warning message */ + JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); + /* Routine that actually outputs a trace or error message */ + JMETHOD(void, output_message, (j_common_ptr cinfo)); + /* Format a message string for the most recent JPEG error or message */ + JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer)); +#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ + /* Reset error state variables at start of a new image */ + JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); + + /* The message ID code and any parameters are saved here. + * A message can have one string parameter or up to 8 int parameters. + */ + int msg_code; +#define JMSG_STR_PARM_MAX 80 + union { + int i[8]; + char s[JMSG_STR_PARM_MAX]; + } msg_parm; + + /* Standard state variables for error facility */ + + int trace_level; /* max msg_level that will be displayed */ + + /* For recoverable corrupt-data errors, we emit a warning message, + * but keep going unless emit_message chooses to abort. emit_message + * should count warnings in num_warnings. The surrounding application + * can check for bad data by seeing if num_warnings is nonzero at the + * end of processing. + */ + long num_warnings; /* number of corrupt-data warnings */ + + /* These fields point to the table(s) of error message strings. + * An application can change the table pointer to switch to a different + * message list (typically, to change the language in which errors are + * reported). Some applications may wish to add additional error codes + * that will be handled by the JPEG library error mechanism; the second + * table pointer is used for this purpose. + * + * First table includes all errors generated by JPEG library itself. + * Error code 0 is reserved for a "no such error string" message. + */ + const char * const * jpeg_message_table; /* Library errors */ + int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ + /* Second table can be added by application (see cjpeg/djpeg for example). + * It contains strings numbered first_addon_message..last_addon_message. + */ + const char * const * addon_message_table; /* Non-library errors */ + int first_addon_message; /* code for first string in addon table */ + int last_addon_message; /* code for last string in addon table */ +}; + + +/* Progress monitor object */ + +struct jpeg_progress_mgr { + JMETHOD(void, progress_monitor, (j_common_ptr cinfo)); + + long pass_counter; /* work units completed in this pass */ + long pass_limit; /* total number of work units in this pass */ + int completed_passes; /* passes completed so far */ + int total_passes; /* total number of passes expected */ +}; + + +/* Data destination object for compression */ + +struct jpeg_destination_mgr { + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + + JMETHOD(void, init_destination, (j_compress_ptr cinfo)); + JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo)); + JMETHOD(void, term_destination, (j_compress_ptr cinfo)); +}; + + +/* Data source object for decompression */ + +struct jpeg_source_mgr { + const JOCTET * next_input_byte; /* => next byte to read from buffer */ + size_t bytes_in_buffer; /* # of bytes remaining in buffer */ + + JMETHOD(void, init_source, (j_decompress_ptr cinfo)); + JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo)); + JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes)); + JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired)); + JMETHOD(void, term_source, (j_decompress_ptr cinfo)); +}; + + +/* Memory manager object. + * Allocates "small" objects (a few K total), "large" objects (tens of K), + * and "really big" objects (virtual arrays with backing store if needed). + * The memory manager does not allow individual objects to be freed; rather, + * each created object is assigned to a pool, and whole pools can be freed + * at once. This is faster and more convenient than remembering exactly what + * to free, especially where malloc()/free() are not too speedy. + * NB: alloc routines never return NULL. They exit to error_exit if not + * successful. + */ + +#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ +#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ +#define JPOOL_NUMPOOLS 2 + +typedef struct jvirt_sarray_control * jvirt_sarray_ptr; +typedef struct jvirt_barray_control * jvirt_barray_ptr; + + +struct jpeg_memory_mgr { + /* Method pointers */ + JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, + JDIMENSION samplesperrow, + JDIMENSION numrows)); + JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, + JDIMENSION blocksperrow, + JDIMENSION numrows)); + JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION samplesperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION blocksperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); + JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, + jvirt_sarray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, + jvirt_barray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); + JMETHOD(void, self_destruct, (j_common_ptr cinfo)); + + /* Limit on memory allocation for this JPEG object. (Note that this is + * merely advisory, not a guaranteed maximum; it only affects the space + * used for virtual-array buffers.) May be changed by outer application + * after creating the JPEG object. + */ + long max_memory_to_use; + + /* Maximum allocation request accepted by alloc_large. */ + long max_alloc_chunk; +}; + + +/* Routine signature for application-supplied marker processing methods. + * Need not pass marker code since it is stored in cinfo->unread_marker. + */ +typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); + + +/* Declarations for routines called by application. + * The JPP macro hides prototype parameters from compilers that can't cope. + * Note JPP requires double parentheses. + */ + +#ifdef HAVE_PROTOTYPES +#define JPP(arglist) arglist +#else +#define JPP(arglist) () +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. + * We shorten external names to be unique in the first six letters, which + * is good enough for all known systems. + * (If your compiler itself needs names to be unique in less than 15 + * characters, you are out of luck. Get a better compiler.) + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_error jStdError +#define jpeg_CreateCompress jCreaCompress +#define jpeg_CreateDecompress jCreaDecompress +#define jpeg_destroy_compress jDestCompress +#define jpeg_destroy_decompress jDestDecompress +#define jpeg_stdio_dest jStdDest +#define jpeg_stdio_src jStdSrc +#define jpeg_mem_dest jMemDest +#define jpeg_mem_src jMemSrc +#define jpeg_set_defaults jSetDefaults +#define jpeg_set_colorspace jSetColorspace +#define jpeg_default_colorspace jDefColorspace +#define jpeg_set_quality jSetQuality +#define jpeg_set_linear_quality jSetLQuality +#define jpeg_default_qtables jDefQTables +#define jpeg_add_quant_table jAddQuantTable +#define jpeg_quality_scaling jQualityScaling +#define jpeg_simple_progression jSimProgress +#define jpeg_suppress_tables jSuppressTables +#define jpeg_alloc_quant_table jAlcQTable +#define jpeg_alloc_huff_table jAlcHTable +#define jpeg_start_compress jStrtCompress +#define jpeg_write_scanlines jWrtScanlines +#define jpeg_finish_compress jFinCompress +#define jpeg_calc_jpeg_dimensions jCjpegDimensions +#define jpeg_write_raw_data jWrtRawData +#define jpeg_write_marker jWrtMarker +#define jpeg_write_m_header jWrtMHeader +#define jpeg_write_m_byte jWrtMByte +#define jpeg_write_tables jWrtTables +#define jpeg_read_header jReadHeader +#define jpeg_start_decompress jStrtDecompress +#define jpeg_read_scanlines jReadScanlines +#define jpeg_finish_decompress jFinDecompress +#define jpeg_read_raw_data jReadRawData +#define jpeg_has_multiple_scans jHasMultScn +#define jpeg_start_output jStrtOutput +#define jpeg_finish_output jFinOutput +#define jpeg_input_complete jInComplete +#define jpeg_new_colormap jNewCMap +#define jpeg_consume_input jConsumeInput +#define jpeg_core_output_dimensions jCoreDimensions +#define jpeg_calc_output_dimensions jCalcDimensions +#define jpeg_save_markers jSaveMarkers +#define jpeg_set_marker_processor jSetMarker +#define jpeg_read_coefficients jReadCoefs +#define jpeg_write_coefficients jWrtCoefs +#define jpeg_copy_critical_parameters jCopyCrit +#define jpeg_abort_compress jAbrtCompress +#define jpeg_abort_decompress jAbrtDecompress +#define jpeg_abort jAbort +#define jpeg_destroy jDestroy +#define jpeg_resync_to_restart jResyncRestart +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Default error-management setup */ +EXTERN(struct jpeg_error_mgr *) jpeg_std_error + JPP((struct jpeg_error_mgr * err)); + +/* Initialization of JPEG compression objects. + * jpeg_create_compress() and jpeg_create_decompress() are the exported + * names that applications should call. These expand to calls on + * jpeg_CreateCompress and jpeg_CreateDecompress with additional information + * passed for version mismatch checking. + * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. + */ +#define jpeg_create_compress(cinfo) \ + jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_compress_struct)) +#define jpeg_create_decompress(cinfo) \ + jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_decompress_struct)) +EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo, + int version, size_t structsize)); +EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo, + int version, size_t structsize)); +/* Destruction of JPEG compression objects */ +EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); + +/* Standard data source and destination managers: stdio streams. */ +/* Caller is responsible for opening the file before and closing after. */ +EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); +EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); + +/* Data source and destination managers: memory buffers. */ +EXTERN(void) jpeg_mem_dest JPP((j_compress_ptr cinfo, + unsigned char ** outbuffer, + unsigned long * outsize)); +EXTERN(void) jpeg_mem_src JPP((j_decompress_ptr cinfo, + unsigned char * inbuffer, + unsigned long insize)); + +/* Default parameter setup for compression */ +EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); +/* Compression parameter setup aids */ +EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo, + J_COLOR_SPACE colorspace)); +EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, + boolean force_baseline)); +EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo, + int scale_factor, + boolean force_baseline)); +EXTERN(void) jpeg_default_qtables JPP((j_compress_ptr cinfo, + boolean force_baseline)); +EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, + boolean force_baseline)); +EXTERN(int) jpeg_quality_scaling JPP((int quality)); +EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo, + boolean suppress)); +EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); +EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); + +/* Main entry points for compression */ +EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo, + boolean write_all_tables)); +EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION num_lines)); +EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo)); + +/* Precalculate JPEG dimensions for current compression parameters. */ +EXTERN(void) jpeg_calc_jpeg_dimensions JPP((j_compress_ptr cinfo)); + +/* Replaces jpeg_write_scanlines when writing raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION num_lines)); + +/* Write a special marker. See libjpeg.txt concerning safe usage. */ +EXTERN(void) jpeg_write_marker + JPP((j_compress_ptr cinfo, int marker, + const JOCTET * dataptr, unsigned int datalen)); +/* Same, but piecemeal. */ +EXTERN(void) jpeg_write_m_header + JPP((j_compress_ptr cinfo, int marker, unsigned int datalen)); +EXTERN(void) jpeg_write_m_byte + JPP((j_compress_ptr cinfo, int val)); + +/* Alternate compression function: just write an abbreviated table file */ +EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo)); + +/* Decompression startup: read start of JPEG datastream to see what's there */ +EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo, + boolean require_image)); +/* Return value is one of: */ +#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ +#define JPEG_HEADER_OK 1 /* Found valid image datastream */ +#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ +/* If you pass require_image = TRUE (normal case), you need not check for + * a TABLES_ONLY return code; an abbreviated file will cause an error exit. + * JPEG_SUSPENDED is only possible if you use a data source module that can + * give a suspension return (the stdio source module doesn't). + */ + +/* Main entry points for decompression */ +EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION max_lines)); +EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); + +/* Replaces jpeg_read_scanlines when reading raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION max_lines)); + +/* Additional entry points for buffered-image mode. */ +EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo, + int scan_number)); +EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo)); +EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo)); +/* Return value is one of: */ +/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ +#define JPEG_REACHED_SOS 1 /* Reached start of new scan */ +#define JPEG_REACHED_EOI 2 /* Reached end of image */ +#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ +#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ + +/* Precalculate output dimensions for current decompression parameters. */ +EXTERN(void) jpeg_core_output_dimensions JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); + +/* Control saving of COM and APPn markers into marker_list. */ +EXTERN(void) jpeg_save_markers + JPP((j_decompress_ptr cinfo, int marker_code, + unsigned int length_limit)); + +/* Install a special processing method for COM or APPn markers. */ +EXTERN(void) jpeg_set_marker_processor + JPP((j_decompress_ptr cinfo, int marker_code, + jpeg_marker_parser_method routine)); + +/* Read or write raw DCT coefficients --- useful for lossless transcoding. */ +EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays)); +EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, + j_compress_ptr dstinfo)); + +/* If you choose to abort compression or decompression before completing + * jpeg_finish_(de)compress, then you need to clean up to release memory, + * temporary files, etc. You can just call jpeg_destroy_(de)compress + * if you're done with the JPEG object, but if you want to clean it up and + * reuse it, call this: + */ +EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); + +/* Generic versions of jpeg_abort and jpeg_destroy that work on either + * flavor of JPEG object. These may be more convenient in some places. + */ +EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo)); + +/* Default restart-marker-resync procedure for use by data source modules */ +EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, + int desired)); + + +/* These marker codes are exported since applications and data source modules + * are likely to want to use them. + */ + +#define JPEG_RST0 0xD0 /* RST0 marker code */ +#define JPEG_EOI 0xD9 /* EOI marker code */ +#define JPEG_APP0 0xE0 /* APP0 marker code */ +#define JPEG_COM 0xFE /* COM marker code */ + + +/* If we have a brain-damaged compiler that emits warnings (or worse, errors) + * for structure definitions that are never filled in, keep it quiet by + * supplying dummy definitions for the various substructures. + */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +struct jpeg_comp_master { long dummy; }; +struct jpeg_c_main_controller { long dummy; }; +struct jpeg_c_prep_controller { long dummy; }; +struct jpeg_c_coef_controller { long dummy; }; +struct jpeg_marker_writer { long dummy; }; +struct jpeg_color_converter { long dummy; }; +struct jpeg_downsampler { long dummy; }; +struct jpeg_forward_dct { long dummy; }; +struct jpeg_entropy_encoder { long dummy; }; +struct jpeg_decomp_master { long dummy; }; +struct jpeg_d_main_controller { long dummy; }; +struct jpeg_d_coef_controller { long dummy; }; +struct jpeg_d_post_controller { long dummy; }; +struct jpeg_input_controller { long dummy; }; +struct jpeg_marker_reader { long dummy; }; +struct jpeg_entropy_decoder { long dummy; }; +struct jpeg_inverse_dct { long dummy; }; +struct jpeg_upsampler { long dummy; }; +struct jpeg_color_deconverter { long dummy; }; +struct jpeg_color_quantizer { long dummy; }; +#endif /* JPEG_INTERNALS */ +#endif /* INCOMPLETE_TYPES_BROKEN */ + + +/* + * The JPEG library modules define JPEG_INTERNALS before including this file. + * The internal structure declarations are read only when that is true. + * Applications using the library should not include jpegint.h, but may wish + * to include jerror.h. + */ + +#ifdef JPEG_INTERNALS +#include "jpegint.h" /* fetch private declarations */ +#include "jerror.h" /* fetch error codes too */ +#endif + +#ifdef __cplusplus +#ifndef DONT_USE_EXTERN_C +} +#endif +#endif + +#endif /* JPEGLIB_H */ diff --git a/sp/src/public/kevvaluescompiler.cpp b/sp/src/public/kevvaluescompiler.cpp new file mode 100644 index 00000000..56459062 --- /dev/null +++ b/sp/src/public/kevvaluescompiler.cpp @@ -0,0 +1,436 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= +#include "keyvaluescompiler.h" +#include "filesystem.h" +#include "tier1/KeyValues.h" + +extern IFileSystem *g_pFullFileSystem; + +bool CRunTimeKeyValuesStringTable::ReadStringTable( int numStrings, CUtlBuffer& buf ) +{ + Assert( m_Strings.Count() == 0 ); + + CUtlVector< int > offsets; + offsets.EnsureCapacity( numStrings ); + + offsets.CopyArray( (int *)( buf.PeekGet() ), numStrings ); + + // Skip over data + buf.SeekGet( CUtlBuffer::SEEK_HEAD, buf.TellGet() + numStrings * sizeof( int ) ); + + int stringSize = buf.GetInt(); + + // Read in the string table + m_Strings.EnsureCapacity( numStrings ); + int i; + for ( i = 0 ; i < numStrings; ++i ) + { + m_Strings.AddToTail( (const char *)buf.PeekGet( offsets[ i ] ) ); + } + + buf.SeekGet( CUtlBuffer::SEEK_HEAD, buf.TellGet() + stringSize ); + + return true; +} + +void CCompiledKeyValuesWriter::BuildKVData_R( KeyValues *kv, int parent ) +{ + // Add self + KVInfo_t info; + info.key = m_StringTable.AddString( kv->GetName() ); + info.value = m_StringTable.AddString( kv->GetString() ); + + info.SetSubTree( kv->GetFirstSubKey() != NULL ? true : false ); + info.SetParent( parent ); + + int newParent = m_Data.AddToTail( info ); + + // Then add children + for ( KeyValues *sub = kv->GetFirstSubKey(); sub; sub = sub->GetNextKey() ) + { + BuildKVData_R( sub, newParent ); + } + + // Then add peers + if ( parent == -1 ) + { + if ( kv->GetNextKey() ) + { + BuildKVData_R( kv->GetNextKey(), parent ); + } + } +} + +void CCompiledKeyValuesWriter::Describe( const KVFile_t& file ) +{ + Msg( "file( %s )\n", m_StringTable.String( file.filename ) ); + + int c = file.numElements; + for ( int i = 0; i < c; ++i ) + { + KVInfo_t &info = m_Data[ file.firstElement + i ]; + if ( info.IsSubTree() ) + { + Msg( "%d: %s -> subtree at parent %i\n", + file.firstElement + i, + m_StringTable.String( info.key ), + info.GetParent() ); + } + else + { + Msg( "%d: %s -> %s at parent %i\n", + file.firstElement + i, + m_StringTable.String( info.key ), + m_StringTable.String( info.value ), + info.GetParent() ); + } + } +} + +void CCompiledKeyValuesWriter::AppendKeyValuesFile( char const *filename ) +{ + KVFile_t kvf; + kvf.filename = m_StringTable.AddString( filename ); + kvf.firstElement = m_Data.Count(); + + KeyValues *kv = new KeyValues( filename ); + if ( kv->LoadFromFile( g_pFullFileSystem, filename ) ) + { + // Add to dictionary + // do a depth first traversal of the keyvalues + BuildKVData_R( kv, -1 ); + } + kv->deleteThis(); + + kvf.numElements = m_Data.Count() - kvf.firstElement; + +// Describe( kvf ); + + m_Files.AddToTail( kvf ); +} + +void CCompiledKeyValuesWriter::WriteData( CUtlBuffer& buf ) +{ + int c = m_Data.Count(); + buf.PutInt( c ); + for ( int i = 0; i < c; ++i ) + { + KVInfo_t &info = m_Data[ i ]; + buf.PutShort( info.key ); + buf.PutShort( info.value ); + buf.PutShort( info.GetParent() ); + buf.PutChar( info.IsSubTree() ? 1 : 0 ); + } +} + +void CCompiledKeyValuesWriter::WriteFiles( CUtlBuffer &buf ) +{ + int c = m_Files.Count(); + buf.PutInt( c ); + for ( int i = 0; i < c; ++i ) + { + KVFile_t &file = m_Files[ i ]; + buf.PutShort( file.filename ); + buf.PutShort( file.firstElement ); + buf.PutShort( file.numElements ); + } +} + +void CCompiledKeyValuesWriter::WriteStringTable( CUtlBuffer& buf ) +{ + int i; + CUtlVector< int > offsets; + + CUtlBuffer stringBuffer; + + offsets.AddToTail( stringBuffer.TellPut() ); + + stringBuffer.PutString( "" ); + // save all the rest + int c = m_StringTable.GetNumStrings(); + for ( i = 1; i < c; i++) + { + offsets.AddToTail( stringBuffer.TellPut() ); + stringBuffer.PutString( m_StringTable.String( i ) ); + } + + buf.Put( offsets.Base(), offsets.Count() * sizeof( int ) ); + + buf.PutInt( stringBuffer.TellPut() ); + buf.Put( stringBuffer.Base(), stringBuffer.TellPut() ); +} + +void CCompiledKeyValuesWriter::WriteFile( char const *outfile ) +{ + CUtlBuffer buf; + + // Write the data file out + KVHeader_t header; + header.fileid = COMPILED_KEYVALUES_ID; + header.version = COMPILED_KEYVALUES_VERSION; + header.numStrings = m_StringTable.GetNumStrings(); + + buf.Put( &header, sizeof( header ) ); + + WriteStringTable( buf ); + WriteData( buf ); + WriteFiles( buf ); + + g_pFullFileSystem->WriteFile( outfile, NULL, buf ); +} + +CCompiledKeyValuesReader::CCompiledKeyValuesReader() + : m_Dict( 0, 0, FileInfo_t::Less ) +{ +} + +int CCompiledKeyValuesReader::First() const +{ + return m_Dict.FirstInorder(); +} + +int CCompiledKeyValuesReader::Next( int i ) const +{ + return m_Dict.NextInorder( i ); +} + +int CCompiledKeyValuesReader::InvalidIndex() const +{ + return m_Dict.InvalidIndex(); +} + +void CCompiledKeyValuesReader::GetFileName( int index, char *buf, size_t bufsize ) +{ + Assert( buf ); + buf[ 0 ] = 0; + FileNameHandle_t& handle = m_Dict[ index ].hFile; + g_pFullFileSystem->String( handle, buf, bufsize ); +} + +bool CCompiledKeyValuesReader::LoadFile( char const *filename ) +{ + int i; + m_LoadBuffer.Purge(); + + g_pFullFileSystem->ReadFile( filename, NULL, m_LoadBuffer ); + + KVHeader_t header; + m_LoadBuffer.Get( &header, sizeof( header ) ); + + if ( header.fileid != COMPILED_KEYVALUES_ID ) + { + return false; + } + + if ( header.version != COMPILED_KEYVALUES_VERSION ) + { + return false; + } + + if ( !m_StringTable.ReadStringTable( header.numStrings, m_LoadBuffer ) ) + { + return false; + } + + // Now parse the data + int dataCount = m_LoadBuffer.GetInt(); + m_Data.EnsureCapacity( dataCount ); + for ( i = 0; i < dataCount; ++i ) + { + KVInfo_t info; + info.key = m_LoadBuffer.GetShort(); + info.value = m_LoadBuffer.GetShort(); + info.SetParent( m_LoadBuffer.GetShort() ); + info.SetSubTree( m_LoadBuffer.GetChar() == 1 ? true : false ); + m_Data.AddToTail( info ); + } + + int fileCount = m_LoadBuffer.GetInt(); + for ( i = 0; i < fileCount; ++i ) + { + FileInfo_t kvf; + short fileNameString = m_LoadBuffer.GetShort(); + + kvf.hFile = g_pFullFileSystem->FindOrAddFileName( m_StringTable.Lookup( fileNameString ) ); + kvf.nFirstIndex = m_LoadBuffer.GetShort(); + kvf.nCount = m_LoadBuffer.GetShort(); + + m_Dict.Insert( kvf ); + } + + return true; +} + +struct CreateHelper_t +{ + int index; + KeyValues *kv; + KeyValues *tail; + + static bool Less( const CreateHelper_t& lhs, const CreateHelper_t& rhs ) + { + return lhs.index < rhs.index; + } +}; + +KeyValues *CCompiledKeyValuesReader::CreateFromData( const FileInfo_t& info ) +{ + KeyValues *head = new KeyValues( "" ); + if ( CreateInPlaceFromData( *head, info ) ) + { + return head; + } + else + { + head->deleteThis(); + return NULL; + } +} + +bool CCompiledKeyValuesReader::CreateInPlaceFromData( KeyValues& head, const FileInfo_t& info ) +{ + int first = info.nFirstIndex; + int num = info.nCount; + + KeyValues *root = NULL; + KeyValues *tail = NULL; + + CUtlRBTree< CreateHelper_t, int > helper( 0, 0, CreateHelper_t::Less ); + + for ( int i = 0; i < num; ++i ) + { + int offset = first + i; + KVInfo_t& info = m_Data[ offset ]; + + if ( info.GetParent() != -1 ) + { + CreateHelper_t search; + search.index = info.GetParent(); + int idx = helper.Find( search ); + if ( idx == helper.InvalidIndex() ) + { + return NULL; + } + + KeyValues *parent = helper[ idx ].kv; + Assert( parent ); + + KeyValues *sub = new KeyValues( m_StringTable.Lookup( info.key ) ); + + if ( !info.IsSubTree() ) + { + sub->SetStringValue(m_StringTable.Lookup( info.value ) ); + } + + if ( !parent->GetFirstSubKey() ) + { + parent->AddSubKey( sub ); + } + else + { + KeyValues *last = helper[ idx ].tail; + last->SetNextKey( sub ); + } + + helper[ idx ].tail = sub; + + CreateHelper_t insert; + insert.index = offset; + insert.kv = sub; + insert.tail = NULL; + helper.Insert( insert ); + } + else + { + if ( !root ) + { + root = &head; + root->SetName( m_StringTable.Lookup( info.key ) ); + tail = root; + + CreateHelper_t insert; + insert.index = offset; + insert.kv = root; + insert.tail = NULL; + helper.Insert( insert ); + } + else + { + CreateHelper_t insert; + insert.index = offset; + insert.kv = new KeyValues( m_StringTable.Lookup( info.key ) ); + insert.tail = NULL; + helper.Insert( insert ); + + tail->SetNextKey( insert.kv ); + tail = insert.kv; + } + } + } + return true; +} + + +bool CCompiledKeyValuesReader::InstanceInPlace( KeyValues& head, char const *kvfilename ) +{ + char sz[ 512 ]; + Q_strncpy( sz, kvfilename, sizeof( sz ) ); + Q_FixSlashes( sz ); + + FileInfo_t search; + search.hFile = g_pFullFileSystem->FindOrAddFileName( sz ); + + int idx = m_Dict.Find( search ); + if ( idx == m_Dict.InvalidIndex() ) + { + return false; + } + + const FileInfo_t& info = m_Dict[ idx ]; + + return CreateInPlaceFromData( head, info ); +} + +KeyValues *CCompiledKeyValuesReader::Instance( char const *kvfilename ) +{ + char sz[ 512 ]; + Q_strncpy( sz, kvfilename, sizeof( sz ) ); + Q_FixSlashes( sz ); + + FileInfo_t search; + search.hFile = g_pFullFileSystem->FindOrAddFileName( sz ); + + int idx = m_Dict.Find( search ); + if ( idx == m_Dict.InvalidIndex() ) + { + return NULL; + } + + const FileInfo_t& info = m_Dict[ idx ]; + + return CreateFromData( info ); +} + +bool CCompiledKeyValuesReader::LookupKeyValuesRootKeyName( char const *kvfilename, char *outbuf, size_t bufsize ) +{ + char sz[ 512 ]; + Q_strncpy( sz, kvfilename, sizeof( sz ) ); + Q_FixSlashes( sz ); + + FileInfo_t search; + search.hFile = g_pFullFileSystem->FindOrAddFileName( sz ); + + int idx = m_Dict.Find( search ); + if ( idx == m_Dict.InvalidIndex() ) + { + return false; + } + + const FileInfo_t& info = m_Dict[ idx ]; + + Q_strncpy( outbuf, m_StringTable.Lookup( m_Data[ info.nFirstIndex ].key ), bufsize ); + return true; +} diff --git a/sp/src/public/keyframe/keyframe.cpp b/sp/src/public/keyframe/keyframe.cpp new file mode 100644 index 00000000..1e08b0a3 --- /dev/null +++ b/sp/src/public/keyframe/keyframe.cpp @@ -0,0 +1,501 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//=============================================================================// + +#include +#include +#include +#include + +typedef unsigned char byte; +#pragma warning(disable:4244) + +#include "tier0/dbg.h" +#include "mathlib/vector.h" +#include "keyframe.h" +#include "mathlib/mathlib.h" +#include "rope_shared.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// +// Implementation of keyframe.h interface +// +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// Key Frames +//----------------------------------------------------------------------------- +#define HIGHEST_KEYFRAME 3 +#define LOWEST_KEYFRAME -3 + +#define TOTAL_KEYFRAMES (HIGHEST_KEYFRAME - LOWEST_KEYFRAME + 1) + +// + +struct KeyFrame_t +{ + Vector vPos; + Quaternion qRot; +}; + + +KeyFrame_t g_KeyFrames[ TOTAL_KEYFRAMES ]; +KeyFrame_t *g_KeyFramePtr = &g_KeyFrames[ -LOWEST_KEYFRAME ]; // points to the middle keyframe, keyframe 0 + +bool Motion_SetKeyAngles( int keyNum, Quaternion &quatAngles ) +{ + if ( keyNum > HIGHEST_KEYFRAME || keyNum < LOWEST_KEYFRAME ) + return false; + + g_KeyFramePtr[keyNum].qRot = quatAngles; + return true; +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// Time Modifier function enumeration & implementation +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +typedef float (*TimeModifierFunc_t)(float); + +typedef struct +{ + const char *szName; + TimeModifierFunc_t pFunc; + +} TimeModifier_t; + +float TimeModifierFunc_Linear( float time ) +{ + return time; +} + +float TimeModifierFunc_Cosine( float time ) +{ + return ( cos((time+1) * M_PI) * 0.5 ) + 0.5; +} + +float TimeModifierFunc_TimeSquared( float time ) +{ + return (time * time); +} + +TimeModifier_t g_TimeModifiers[] = +{ + { "Linear", TimeModifierFunc_Linear }, + { "Accel/Deaccel (cosine)", TimeModifierFunc_Cosine }, + { "Accel (time*time)", TimeModifierFunc_TimeSquared }, +}; + +int Motion_GetNumberOfTimeModifiers( void ) +{ + return ARRAYSIZE(g_TimeModifiers); +} + +bool Motion_GetTimeModifierDetails( int timeInterpNum, const char **outName ) +{ + if ( timeInterpNum < 0 || timeInterpNum >= Motion_GetNumberOfTimeModifiers() ) + { + return false; + } + + if ( !g_TimeModifiers[0].szName || !g_TimeModifiers[0].pFunc ) + { + return false; + } + + if ( outName ) + *outName = g_TimeModifiers[0].szName; + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : time - +// timeModifierFuncNum - +// *outNewTime - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool Motion_CalculateModifiedTime( float time, int timeModifierFuncNum, float *outNewTime ) +{ + *outNewTime = g_TimeModifiers[timeModifierFuncNum].pFunc( time ); + return true; +} + + + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// Position interpolator function enumeration & implementation +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +// ------------------------------------------------------------------------------------ // +// Linear position interpolator. +// ------------------------------------------------------------------------------------ // + +class CPositionInterpolator_Linear : public IPositionInterpolator +{ +public: + virtual void Release(); + virtual void GetDetails( char **outName, int *outMinKeyReq, int *outMaxKeyReq ); + virtual void SetKeyPosition( int keyNum, Vector const &vPos ); + virtual void InterpolatePosition( float time, Vector &vOut ); + virtual bool ProcessKey( char const *pName, char const *pValue ) { return false; } +}; + +CPositionInterpolator_Linear g_LinearInterpolator; + +IPositionInterpolator* GetLinearInterpolator() +{ + return &g_LinearInterpolator; +} + +void CPositionInterpolator_Linear::Release() +{ +} + +void CPositionInterpolator_Linear::GetDetails( char **outName, int *outMinKeyReq, int *outMaxKeyReq ) +{ + *outName = "Linear"; + *outMinKeyReq = 0; + *outMaxKeyReq = 1; +} + +void CPositionInterpolator_Linear::SetKeyPosition( int keyNum, Vector const &vPos ) +{ + Assert ( keyNum <= HIGHEST_KEYFRAME && keyNum >= LOWEST_KEYFRAME ); + VectorCopy( vPos, g_KeyFramePtr[keyNum].vPos ); +} + +void CPositionInterpolator_Linear::InterpolatePosition( float time, Vector &vOut ) +{ + VectorLerp( g_KeyFramePtr[0].vPos, g_KeyFramePtr[1].vPos, time, vOut ); +} + + + + + +// ------------------------------------------------------------------------------------ // +// Catmull-Rom position interpolator. +// ------------------------------------------------------------------------------------ // + +class CPositionInterpolator_CatmullRom : public IPositionInterpolator +{ +public: + virtual void Release(); + virtual void GetDetails( char **outName, int *outMinKeyReq, int *outMaxKeyReq ); + virtual void SetKeyPosition( int keyNum, Vector const &vPos ); + virtual void InterpolatePosition( float time, Vector &vOut ); + virtual bool ProcessKey( char const *pName, char const *pValue ) { return false; } +}; + +CPositionInterpolator_CatmullRom g_CatmullRomInterpolator; + +IPositionInterpolator* GetCatmullRomInterpolator() +{ + return &g_CatmullRomInterpolator; +} + +void CPositionInterpolator_CatmullRom::Release() +{ +} + +void CPositionInterpolator_CatmullRom::GetDetails( char **outName, int *outMinKeyReq, int *outMaxKeyReq ) +{ + *outName = "Catmull-Rom Spline"; + *outMinKeyReq = -1; + *outMaxKeyReq = 2; +} + +void CPositionInterpolator_CatmullRom::SetKeyPosition( int keyNum, Vector const &vPos ) +{ + Assert ( keyNum <= HIGHEST_KEYFRAME && keyNum >= LOWEST_KEYFRAME ); + VectorCopy( vPos, g_KeyFramePtr[keyNum].vPos ); +} + +void CPositionInterpolator_CatmullRom::InterpolatePosition( float time, Vector &vOut ) +{ + Catmull_Rom_Spline( + g_KeyFramePtr[-1].vPos, + g_KeyFramePtr[0].vPos, + g_KeyFramePtr[1].vPos, + g_KeyFramePtr[2].vPos, + time, + vOut ); +} + + + +// ------------------------------------------------------------------------------------ // +// Rope interpolator. +// ------------------------------------------------------------------------------------ // +#include "rope_physics.h" + +class CRopeDelegate : public CSimplePhysics::IHelper +{ +public: + virtual void GetNodeForces( CSimplePhysics::CNode *pNodes, int iNode, Vector *pAccel ); + virtual void ApplyConstraints( CSimplePhysics::CNode *pNodes, int nNodes ); + + +public: + Vector m_CurEndPoints[2]; +}; + +void CRopeDelegate::GetNodeForces( CSimplePhysics::CNode *pNodes, int iNode, Vector *pAccel ) +{ + // Gravity. + pAccel->Init( 0, 0, -1500 ); +} + +void CRopeDelegate::ApplyConstraints( CSimplePhysics::CNode *pNodes, int nNodes ) +{ + if( nNodes >= 2 ) + { + pNodes[0].m_vPos = m_CurEndPoints[0]; + pNodes[nNodes-1].m_vPos = m_CurEndPoints[1]; + } +} + + +class CPositionInterpolator_Rope : public IPositionInterpolator +{ +public: + CPositionInterpolator_Rope(); + + virtual void Release(); + virtual void GetDetails( char **outName, int *outMinKeyReq, int *outMaxKeyReq ); + virtual void SetKeyPosition( int keyNum, Vector const &vPos ); + virtual void InterpolatePosition( float time, Vector &vOut ); + virtual bool ProcessKey( char const *pName, char const *pValue ); + + +private: + CRopePhysics<10> m_RopePhysics; + CRopeDelegate m_Delegate; + + float m_flSlack; // Extra length of rope. + + bool m_bChange; + int m_nSegments; +}; + +IPositionInterpolator* GetRopeInterpolator() +{ + return new CPositionInterpolator_Rope; +} + + +CPositionInterpolator_Rope::CPositionInterpolator_Rope() +{ + m_flSlack = 0; + m_bChange = false; + m_nSegments = 5; + + for( int i=0; i < 2; i++ ) + m_Delegate.m_CurEndPoints[i] = Vector( 1e24, 1e24, 1e24 ); +} + +void CPositionInterpolator_Rope::Release() +{ + delete this; +} + +void CPositionInterpolator_Rope::GetDetails( char **outName, int *outMinKeyReq, int *outMaxKeyReq ) +{ + *outName = "Rope"; + *outMinKeyReq = 0; + *outMinKeyReq = 1; +} + +void CPositionInterpolator_Rope::SetKeyPosition( int keyNum, Vector const &vPos ) +{ + if( keyNum == 0 || keyNum == 1 ) + { + if( vPos != m_Delegate.m_CurEndPoints[keyNum] ) + m_bChange = true; + + m_Delegate.m_CurEndPoints[keyNum] = vPos; + } +} + +void CPositionInterpolator_Rope::InterpolatePosition( float time, Vector &vOut ) +{ + // Check if we need to resimulate.. + if( m_bChange ) + { + m_RopePhysics.SetNumNodes( m_nSegments ); + + // Init all the nodes. + for( int i=0; i < m_RopePhysics.NumNodes(); i++ ) + m_RopePhysics.GetNode(i)->m_vPos = m_RopePhysics.GetNode(i)->m_vPrevPos = m_Delegate.m_CurEndPoints[0]; + + float flDist = (m_Delegate.m_CurEndPoints[0] - m_Delegate.m_CurEndPoints[1]).Length(); + flDist += m_flSlack; + + m_RopePhysics.Restart(); + m_RopePhysics.SetupSimulation( flDist / (m_RopePhysics.NumNodes() - 1), &m_Delegate ); + + // Run the simulation for a while to let the rope settle down.. + m_RopePhysics.Simulate( 5 ); + + m_bChange = false; + } + + // Ok, now we have all the nodes setup.. + float flNode = time * (m_RopePhysics.NumNodes()-1); + int iNode = (int)( flNode ); + VectorLerp( + m_RopePhysics.GetNode(iNode)->m_vPredicted, + m_RopePhysics.GetNode(iNode+1)->m_vPredicted, + flNode - iNode, + vOut ); +} + +bool CPositionInterpolator_Rope::ProcessKey( char const *pName, char const *pValue ) +{ + if( stricmp( pName, "Slack" ) == 0 ) + { + m_flSlack = atof( pValue ) + ROPESLACK_FUDGEFACTOR; + m_bChange = true; + return true; + } + else if( stricmp( pName, "Type" ) == 0 ) + { + int iType = atoi( pValue ); + if( iType == 0 ) + m_nSegments = ROPE_MAX_SEGMENTS; + else if( iType == 1 ) + m_nSegments = ROPE_TYPE1_NUMSEGMENTS; + else + m_nSegments = ROPE_TYPE2_NUMSEGMENTS; + + m_bChange = true; + return true; + } + + return false; +} + + + +// ------------------------------------------------------------------------------------ // +// The global table of all the position interpolators. +// ------------------------------------------------------------------------------------ // + +typedef IPositionInterpolator* (*PositionInterpolatorCreateFn)(); +PositionInterpolatorCreateFn g_PositionInterpolatorCreateFns[] = +{ + GetLinearInterpolator, + GetCatmullRomInterpolator, + GetRopeInterpolator +}; + +int Motion_GetNumberOfPositionInterpolators( void ) +{ + return ARRAYSIZE(g_PositionInterpolatorCreateFns); +} + + +IPositionInterpolator* Motion_GetPositionInterpolator( int interpNum ) +{ + Assert( interpNum >= 0 && interpNum < Motion_GetNumberOfPositionInterpolators() ); + return g_PositionInterpolatorCreateFns[clamp( interpNum, 0, Motion_GetNumberOfPositionInterpolators() - 1 )](); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// Rotation interpolator function enumeration & implementation +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +typedef void (*RotationInterpolatorFunc_t)(float time, Quaternion &outRot); + +typedef struct +{ + char *szName; + RotationInterpolatorFunc_t pFunc; + + // defines the range of keys this interpolator needs to function + int iMinReqKeyFrame; + int iMaxReqKeyFrame; + +} RotationInterpolator_t; + +void RotationInterpolatorFunc_Linear( float time, Quaternion &outRot ) +{ + // basic 4D spherical linear interpolation + QuaternionSlerp( g_KeyFramePtr[0].qRot, g_KeyFramePtr[1].qRot, time, outRot ); +} + +RotationInterpolator_t g_RotationInterpolators[] = +{ + { "Linear", RotationInterpolatorFunc_Linear, 0, 1 }, +}; + +int Motion_GetNumberOfRotationInterpolators( void ) +{ + return ARRAYSIZE(g_RotationInterpolators); +} + +bool Motion_GetRotationInterpolatorDetails( int rotInterpNum, char **outName, int *outMinKeyReq, int *outMaxKeyReq ) +{ + if ( rotInterpNum < 0 || rotInterpNum >= Motion_GetNumberOfRotationInterpolators() ) + { + return false; + } + + if ( !g_RotationInterpolators[rotInterpNum].szName || !g_RotationInterpolators[rotInterpNum].pFunc ) + { + return false; + } + + if ( outName ) + *outName = g_RotationInterpolators[rotInterpNum].szName; + + if ( outMinKeyReq ) + *outMinKeyReq = g_RotationInterpolators[rotInterpNum].iMinReqKeyFrame; + + if ( outMaxKeyReq ) + *outMaxKeyReq = g_RotationInterpolators[rotInterpNum].iMaxReqKeyFrame; + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Interpolates a rotation +// Time is assumed to have already been modified by the TimeModifyFunc (above) +// Requires the keyframes be already set +// Input : time - value from 0..1 +// interpFuncNum - +// *outQuatRotation - result in quaternion form +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool Motion_InterpolateRotation( float time, int interpFuncNum, Quaternion &outQuatRotation ) +{ + if ( time < 0.0f || time > 1.0f ) + return false; + + g_RotationInterpolators[interpFuncNum].pFunc( time, outQuatRotation ); + return true; +} diff --git a/sp/src/public/keyframe/keyframe.h b/sp/src/public/keyframe/keyframe.h new file mode 100644 index 00000000..b2cfd27c --- /dev/null +++ b/sp/src/public/keyframe/keyframe.h @@ -0,0 +1,42 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Keyframed animation header +// shared between game and tools +//=============================================================================// + +#ifndef KEYFRAME_H +#define KEYFRAME_H +#pragma once + + +class IPositionInterpolator +{ +public: + virtual void Release() = 0; + + virtual void GetDetails( char **outName, int *outMinKeyReq, int *outMaxKeyReq ) = 0; + virtual void SetKeyPosition( int keyNum, Vector const &vPos ) = 0; + virtual void InterpolatePosition( float time, Vector &vOut ) = 0; + + // Returns true if the key causes a change that changes the interpolated positions. + virtual bool ProcessKey( char const *pName, char const *pValue ) = 0; +}; + + +// Time modifiers. +int Motion_GetNumberOfTimeModifiers( void ); +bool Motion_GetTimeModifierDetails( int timeInterpNum, const char **outName ); +bool Motion_CalculateModifiedTime( float time, int timeModifierFuncNum, float *outNewTime ); + +// Position interpolators. +int Motion_GetNumberOfPositionInterpolators( void ); +IPositionInterpolator* Motion_GetPositionInterpolator( int interpNum ); + +// Rotation interpolators. +int Motion_GetNumberOfRotationInterpolators( void ); +bool Motion_GetRotationInterpolatorDetails( int rotInterpNum, char **outName, int *outMinKeyReq, int *outMaxKeyReq ); +bool Motion_InterpolateRotation( float time, int interpFuncNum, Quaternion &outQuatRotation ); +bool Motion_SetKeyAngles( int keyNum, Quaternion &quatAngles ); + + +#endif // KEYFRAME_H diff --git a/sp/src/public/keyvaluescompiler.h b/sp/src/public/keyvaluescompiler.h new file mode 100644 index 00000000..ff6cc40d --- /dev/null +++ b/sp/src/public/keyvaluescompiler.h @@ -0,0 +1,188 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef KEYVALUESCOMPILER_H +#define KEYVALUESCOMPILER_H +#ifdef _WIN32 +#pragma once +#endif + +#include "tier0/platform.h" +#include "tier1/utlbuffer.h" +#include "tier1/utlsymbol.h" +#include "tier1/utldict.h" + +class KeyValues; + +#define COMPILED_KEYVALUES_ID MAKEID( 'V', 'K', 'V', 'F' ) + +#define COMPILED_KEYVALUES_VERSION 1 + +struct KVHeader_t +{ + int fileid; + int version; + int numStrings; +}; + +#pragma pack(1) +struct KVFile_t +{ + KVFile_t() : + filename( 0 ), + firstElement( 0 ), + numElements( 0 ) + { + } + short filename; + short firstElement; + short numElements; +}; + +struct KVInfo_t +{ + KVInfo_t() : + key( 0 ), + value( 0 ), + parentIndex( -1 ), + issubtree( false ) + { + } + + inline void SetParent( int index ) + { + Assert( index <= 32768 ); + parentIndex = index; + } + + inline short GetParent() const + { + return parentIndex; + } + + inline void SetSubTree( bool state ) + { + issubtree = state; + } + + inline bool IsSubTree() const + { + return issubtree; + } + + short key; + short value; + +private: + + short parentIndex; + bool issubtree; +}; +#pragma pack() + +//----------------------------------------------------------------------------- +// Purpose: stringtable is a session global string table. +//----------------------------------------------------------------------------- +class CCompiledKeyValuesWriter +{ +public: + + CCompiledKeyValuesWriter() + { + m_StringTable.AddString( "" ); + } + + void AppendKeyValuesFile( char const *filename ); + void WriteFile( char const *outfile ); + +private: + + void Describe( const KVFile_t& file ); + + void BuildKVData_R( KeyValues *kv, int parent ); + + void WriteStringTable( CUtlBuffer& buf ); + void WriteData( CUtlBuffer& buf ); + void WriteFiles( CUtlBuffer &buf ); + + CUtlVector< KVFile_t > m_Files; + CUtlVector< KVInfo_t > m_Data; + + CUtlSymbolTable m_StringTable; +}; + + +class CRunTimeKeyValuesStringTable +{ +public: + + bool ReadStringTable( int numStrings, CUtlBuffer& buf ); + + inline int Count() const + { + return m_Strings.Count(); + } + + inline char const *Lookup( short index ) + { + return m_Strings[ index ]; + } + +private: + CUtlVector< const char * > m_Strings; +}; + +class CCompiledKeyValuesReader +{ +public: + + CCompiledKeyValuesReader(); + + bool LoadFile( char const *filename ); + + KeyValues *Instance( char const *kvfilename ); + bool InstanceInPlace( KeyValues& head, char const *kvfilename ); + bool LookupKeyValuesRootKeyName( char const *kvfilename, char *outbuf, size_t bufsize ); + + int First() const; + int Next( int i ) const; + int InvalidIndex() const; + + void GetFileName( int index, char *buf, size_t bufsize ); + +private: + + struct FileInfo_t + { + FileInfo_t() : + hFile( 0 ), + nFirstIndex( 0 ), + nCount( 0 ) + { + } + FileNameHandle_t hFile; + short nFirstIndex; + short nCount; + + static bool Less( const FileInfo_t& lhs, const FileInfo_t& rhs ) + { + return lhs.hFile < rhs.hFile; + } + }; + + KeyValues *CreateFromData( const FileInfo_t& info ); + bool CreateInPlaceFromData( KeyValues& head, const FileInfo_t& info ); + + // Now get the actual files + CUtlRBTree< FileInfo_t, unsigned short > m_Dict; + CUtlVector< KVInfo_t > m_Data; + + CRunTimeKeyValuesStringTable m_StringTable; + + CUtlBuffer m_LoadBuffer; +}; + +#endif // KEYVALUESCOMPILER_H diff --git a/sp/src/public/list.h b/sp/src/public/list.h new file mode 100644 index 00000000..af25411f --- /dev/null +++ b/sp/src/public/list.h @@ -0,0 +1,352 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef __LIST_H__ +#define __LIST_H__ + +// TODO: +// GetPositionAtIndex needs to keep a cache of the previous call so +// that it doesn't do a linear search every time. + +#include + +// FIXME: change the name of this to something more specific. +typedef struct +{ +} _Position; +typedef _Position *Position; + +template class GList; +template class GListIterator; + +// GListNode: Class decleration and definition +template class GListNode +{ +private: + T data; + GListNode *next; + GListNode *prev; + GListNode(); + GListNode( T item ); + friend class GList; + friend class GListIterator; +}; + +template +GListNode::GListNode() +{ + next = NULL; + prev = NULL; +} + +template +GListNode::GListNode( T item ) +{ + data = item; + next = NULL; + prev = NULL; +} + +// GList: Class decleration and definition +template class GList +{ +public: + // Contructors/destructors + GList(); + + // + Position InsertAtHead( T ); + Position InsertAtTail( T ); + T Remove( Position position ); + void RemoveAll( void (*DeleteItem)( T ) ); + void RemoveSelectedItems( bool (*NeedsRemovalFunc)( T ), void (*DeleteItemFunc)( T ) ); + Position InsertAfter( T item, Position position ); + Position InsertBefore( T item, Position position ); + bool IsEmpty(); + int GetNumItems(); + T GetItemAtPosition( Position position ); + Position GetPositionAtIndex( int index ); + T GetItemAtIndex( int index ); + +protected: + GListNode *head; + GListNode *tail; + int numItems; + friend class GListIterator; +}; + +template +GList::GList() +{ + // Set up a dummy head node and a dummy tail node. + head = new GListNode; + tail = new GListNode; + head->next = tail; + head->prev = head; + tail->next = tail; + tail->prev = head; + numItems = 0; +} + +template +Position GList::InsertAtHead( T item ) +{ + GListNode *newNode = new GListNode( item ); + head->next->prev = newNode; + newNode->next = head->next; + newNode->prev = head; + head->next = newNode; + numItems++; + return ( Position )( void * )newNode; +} + +template +Position GList::InsertAtTail( T item ) +{ + GListNode *newNode = new GListNode( item ); + tail->prev->next = newNode; + newNode->prev = tail->prev; + tail->prev = newNode; + newNode->next = tail; + numItems++; + return ( Position )( void * )newNode; +} + +template +T GList::Remove( Position position ) +{ + GListNode *node = ( GListNode * )( void * )position; + node->prev->next = node->next; + node->next->prev = node->prev; + T data = node->data; + numItems--; + delete node; + return data; +} + +template +void GList::RemoveAll( void (*DeleteItemFunc)( T ) ) +{ + GListNode *tmpNode; + GListNode *node = head->next; + while( node != tail ) + { + if( DeleteItemFunc ) + { + DeleteItemFunc( node->data ); + } + tmpNode = node->next; + delete node; + node = tmpNode; + } + head->next = tail; + head->prev = head; + tail->next = tail; + tail->prev = head; + numItems = 0; +} + +template +void GList::RemoveSelectedItems( bool (*NeedsRemovalFunc)( T ), void (*DeleteItemFunc)( T ) ) +{ + GListNode *tmpNode; + GListNode *node = head->next; + while( node != tail ) + { + if( NeedsRemovalFunc( node->data ) ) + { + DeleteItemFunc( node->data ); + node->prev->next = node->next; + node->next->prev = node->prev; + tmpNode = node; + node = node->next; + delete tmpNode; + numItems--; + } + else + { + node = node->next; + } + } +} + +template +Position GList::InsertAfter( T item, Position position ) +{ + GListNode *node = ( GListNode * )( void * )position; + GListNode *newNode = new GListNode( item ); + newNode->prev = node; + newNode->next = node->next; + node->next->prev = newNode; + node->next = newNode; + numItems++; + return ( Position )( void * )newNode; +} + +template +Position GList::InsertBefore( T item, Position position ) +{ + GListNode *node = ( GListNode * )( void * )position; + GListNode *newNode = new GListNode( item ); + newNode->prev = node->prev; + newNode->next = node; + node->prev->next = newNode; + node->prev = newNode; + numItems++; + return ( Position )( void * )newNode; +} + +template +bool GList::IsEmpty() +{ + return ( numItems == 0 ); +} + +template +int GList::GetNumItems() +{ + return numItems; +} + +template +T GList::GetItemAtPosition( Position position ) +{ + return ( ( GListNode * )( void * )position )->data; +} + +template +Position GList::GetPositionAtIndex( int index ) +{ + int i; + GListNode *node = head->next; + for( i = 0; i < index; i++ ) + { + node = node->next; + } + return ( Position )( void * )node; +} + +template +T GList::GetItemAtIndex( int index ) +{ + return GetItemAtPosition( GetPositionAtIndex( index ) ); +} + +// GListIterator: Class decleration and definition +template class GListIterator +{ +public: + GListIterator( GList *GList ); + void GotoHead( void ); + void GotoTail( void ); + void Goto( int index ); + void Increment(); + void Decrement(); + T GetCurrentAndIncrement(); + T GetCurrentAndDecrement(); + T IncrementAndGetCurrent(); + T DecrementAndGetCurrent(); + // postfix + T operator++( int ) { return GetCurrentAndIncrement(); } + T operator--( int ) { return GetCurrentAndDecrement(); } + // prefix + T operator++() { return IncrementAndGetCurrent(); } + T operator--() { return DecrementAndGetCurrent(); } + T GetCurrent(); + bool AtEnd( void ); + bool AtBeginning( void ); +protected: + GList *list; + GListNode *currentNode; +}; + +template +GListIterator::GListIterator( GList *list ) +{ + this->list = list; + GotoHead(); +} + +template +void GListIterator::GotoHead() +{ + this->currentNode = list->head->next; +} + +template +void GListIterator::GotoTail() +{ + this->currentNode = list->tail->prev; +} + +template +void GListIterator::Goto( int index ) +{ + currentNode = ( GListNode * )( void * )list->GetPositionAtIndex( index ); +} + +template +void GListIterator::Increment() +{ + currentNode = currentNode->next; +} + +template +void GListIterator::Decrement() +{ + currentNode = currentNode->prev; +} + +template +T GListIterator::GetCurrentAndIncrement() +{ + T retval = currentNode->data; + Increment(); + return retval; +} + +template +T GListIterator::GetCurrentAndDecrement() +{ + T retval = currentNode->data; + Decrement(); + return retval; +} + +template +T GListIterator::IncrementAndGetCurrent() +{ + Increment(); + return GetCurrent(); +} + +template +T GListIterator::DecrementAndGetCurrent() +{ + Decrement(); + return GetCurrent(); +} + +template +T GListIterator::GetCurrent() +{ + return currentNode->data; +} + +template +bool GListIterator::AtEnd( void ) +{ + return currentNode->next == currentNode; +} + +template +bool GListIterator::AtBeginning( void ) +{ + return currentNode->prev == currentNode; +} + +#endif /* __LIST_H__ */ diff --git a/sp/src/public/loadcmdline.cpp b/sp/src/public/loadcmdline.cpp new file mode 100644 index 00000000..1df30efb --- /dev/null +++ b/sp/src/public/loadcmdline.cpp @@ -0,0 +1,123 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: loads additional command line options from a config file +// +// $NoKeywords: $ +//=============================================================================// + +#include "KeyValues.h" +#include "tier1/strtools.h" +#include "FileSystem_Tools.h" +#include "tier1/utlstring.h" + +// So we know whether or not we own argv's memory +static bool sFoundConfigArgs = false; + +//----------------------------------------------------------------------------- +// Purpose: Parses arguments and adds them to argv and argc +//----------------------------------------------------------------------------- +static void AddArguments( int &argc, char **&argv, const char *str ) +{ + char **args = 0; + char *argList = 0; + int argCt = argc; + + argList = new char[ Q_strlen( str ) + 1 ]; + Q_strcpy( argList, str ); + + // Parse the arguments out of the string + char *token = strtok( argList, " " ); + while( token ) + { + ++argCt; + token = strtok( NULL, " " ); + } + + // Make sure someting was actually found in the file + if( argCt > argc ) + { + sFoundConfigArgs = true; + + // Allocate a new array for argv + args = new char*[ argCt ]; + + // Copy original arguments, up to the last one + int i; + for( i = 0; i < argc - 1; ++i ) + { + args[ i ] = new char[ Q_strlen( argv[ i ] ) + 1 ]; + Q_strcpy( args[ i ], argv[ i ] ); + } + + // copy new arguments + Q_strcpy( argList, str ); + token = strtok( argList, " " ); + for( ; i < argCt - 1; ++i ) + { + args[ i ] = new char[ Q_strlen( token ) + 1 ]; + Q_strcpy( args[ i ], token ); + token = strtok( NULL, " " ); + } + + // Copy the last original argument + args[ i ] = new char[ Q_strlen( argv[ argc - 1 ] ) + 1 ]; + Q_strcpy( args[ i ], argv[ argc - 1 ] ); + + argc = argCt; + argv = args; + } + + delete [] argList; +} + +//----------------------------------------------------------------------------- +// Purpose: Loads additional commandline arguments from a config file for an app. +// Filesystem must be initialized before calling this function. +// keyname: Name of the block containing the key/args pairs (ie map or model name) +// appname: Keyname for the commandline arguments to be loaded - typically the exe name. +//----------------------------------------------------------------------------- +void LoadCmdLineFromFile( int &argc, char **&argv, const char *keyname, const char *appname ) +{ + sFoundConfigArgs = false; + + assert( g_pFileSystem ); + if( !g_pFileSystem ) + return; + + // Load the cfg file, and find the keyname + KeyValues *kv = new KeyValues( "CommandLine" ); + + char filename[512]; + Q_snprintf( filename, sizeof( filename ), "%s/cfg/commandline.cfg", gamedir ); + + if ( kv->LoadFromFile( g_pFileSystem, filename ) ) + { + // Load the commandline arguments for this app + KeyValues *appKey = kv->FindKey( keyname ); + if( appKey ) + { + const char *str = appKey->GetString( appname ); + Msg( "Command Line found: %s\n", str ); + + AddArguments( argc, argv, str ); + } + } + + kv->deleteThis(); +} + +//----------------------------------------------------------------------------- +// Purpose: Cleans up any memory allocated for the new argv. Pass in the app's +// argc and argv - this is safe even if no extra arguments were loaded. +//----------------------------------------------------------------------------- +void DeleteCmdLine( int argc, char **argv ) +{ + if( !sFoundConfigArgs ) + return; + + for( int i = 0; i < argc; ++i ) + { + delete [] argv[i]; + } + delete [] argv; +} \ No newline at end of file diff --git a/sp/src/public/loadcmdline.h b/sp/src/public/loadcmdline.h new file mode 100644 index 00000000..084e090d --- /dev/null +++ b/sp/src/public/loadcmdline.h @@ -0,0 +1,27 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: loads additional command line options from a config file +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef LOADCMDLINE_H +#define LOADCMDLINE_H +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +// Purpose: Loads additional commandline arguments from a config file for an app. +// keyname: Name of the block containing the key/args pairs (ie map or model name) +// appname: Keyname for the commandline arguments to be loaded - typically the exe name. +//----------------------------------------------------------------------------- +void LoadCmdLineFromFile( int &argc, char **&argv, const char *keyname, const char *appname ); + +//----------------------------------------------------------------------------- +// Purpose: Cleans up any memory allocated for the new argv. Pass in the app's +// argc and argv - this is safe even if no extra arguments were loaded. +//----------------------------------------------------------------------------- +void DeleteCmdLine( int argc, char **argv ); + +#endif // LOADCMDLINE_H \ No newline at end of file diff --git a/sp/src/public/localflexcontroller.h b/sp/src/public/localflexcontroller.h new file mode 100644 index 00000000..7afb1c9d --- /dev/null +++ b/sp/src/public/localflexcontroller.h @@ -0,0 +1,30 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef LOCALFLEXCONTROLLER_H +#define LOCALFLEXCONTROLLER_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier0/platform.h" + +enum LocalFlexController_t +{ + // this isn't really an enum - its just a typed int. gcc will not accept it as a fwd decl, so we'll define one value + DUMMY_FLEX_CONTROLLER=0x7fffffff // make take 32 bits +}; + +inline LocalFlexController_t &operator++( LocalFlexController_t &a ) { return a = LocalFlexController_t( int( a ) + 1 ); } +inline LocalFlexController_t &operator--( LocalFlexController_t &a ) { return a = LocalFlexController_t( int( a ) - 1 ); } +inline LocalFlexController_t operator++( LocalFlexController_t &a, int ) { LocalFlexController_t t = a; a = LocalFlexController_t( int( a ) + 1 ); return t; } +inline LocalFlexController_t operator--( LocalFlexController_t &a, int ) { LocalFlexController_t t = a; a = LocalFlexController_t( int( a ) - 1 ); return t; } + + +#endif // LOCALFLEXCONTROLLER_H diff --git a/sp/src/public/lumpfiles.cpp b/sp/src/public/lumpfiles.cpp new file mode 100644 index 00000000..eb11e788 --- /dev/null +++ b/sp/src/public/lumpfiles.cpp @@ -0,0 +1,27 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "bspfile.h" +#include "strtools.h" +#include "filesystem.h" +#include "lumpfiles.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// Purpose: Generate a lump file name for a given bsp & index +// Input : *bspfilename - +// *lumpfilename - +// iIndex - +//----------------------------------------------------------------------------- +void GenerateLumpFileName( const char *bspfilename, char *lumpfilename, int iBufferSize, int iIndex ) +{ + char lumppre[MAX_PATH]; + V_StripExtension( bspfilename, lumppre, MAX_PATH ); + Q_snprintf( lumpfilename, iBufferSize, "%s_l_%d.lmp", lumppre, iIndex ); +} + diff --git a/sp/src/public/lumpfiles.h b/sp/src/public/lumpfiles.h new file mode 100644 index 00000000..a2512163 --- /dev/null +++ b/sp/src/public/lumpfiles.h @@ -0,0 +1,20 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef LUMPFILES_H +#define LUMPFILES_H +#ifdef _WIN32 +#pragma once +#endif + +#define MAX_LUMPFILES 128 + +//----------------------------------------------------------------------------- +// Lump files +//----------------------------------------------------------------------------- +void GenerateLumpFileName( const char *bspfilename, char *lumpfilename, int iBufferSize, int iIndex ); + +#endif // LUMPFILES_H diff --git a/sp/src/public/map_utils.cpp b/sp/src/public/map_utils.cpp new file mode 100644 index 00000000..a0022b5d --- /dev/null +++ b/sp/src/public/map_utils.cpp @@ -0,0 +1,48 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "mathlib/vector.h" +#include "bspfile.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +void SetupLightNormalFromProps( const QAngle &angles, float angle, float pitch, Vector &output ) +{ + if (angle == ANGLE_UP) + { + output[0] = output[1] = 0; + output[2] = 1; + } + else if (angle == ANGLE_DOWN) + { + output[0] = output[1] = 0; + output[2] = -1; + } + else + { + // if we don't have a specific "angle" use the "angles" YAW + if ( !angle ) + { + angle = angles[YAW]; + } + + output[2] = 0; + output[0] = (float)cos (angle/180*M_PI); + output[1] = (float)sin (angle/180*M_PI); + } + + if ( !pitch ) + { + // if we don't have a specific "pitch" use the "angles" PITCH + pitch = angles[PITCH]; + } + + output[2] = (float)sin(pitch/180*M_PI); + output[0] *= (float)cos(pitch/180*M_PI); + output[1] *= (float)cos(pitch/180*M_PI); +} + diff --git a/sp/src/public/map_utils.h b/sp/src/public/map_utils.h new file mode 100644 index 00000000..555ca235 --- /dev/null +++ b/sp/src/public/map_utils.h @@ -0,0 +1,25 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef MAP_UTILS_H +#define MAP_UTILS_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "mathlib/vector.h" + + +// angles comes from the "angles" property +// +// yaw and pitch will override the values in angles if they are nonzero +// yaw comes from the (obsolete) "angle" property +// pitch comes from the "pitch" property +void SetupLightNormalFromProps( const QAngle &angles, float yaw, float pitch, Vector &output ); + + +#endif // MAP_UTILS_H diff --git a/sp/src/public/materialsystem/IColorCorrection.h b/sp/src/public/materialsystem/IColorCorrection.h new file mode 100644 index 00000000..1aa0c246 --- /dev/null +++ b/sp/src/public/materialsystem/IColorCorrection.h @@ -0,0 +1,73 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#ifndef ICOLORCORRECTION_H +#define ICOLORCORRECTION_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/interface.h" +#include "bitmap/imageformat.h" + +typedef unsigned int ColorCorrectionHandle_t; +struct ShaderColorCorrectionInfo_t; + +#define COLORCORRECTION_INTERFACE_VERSION "COLORCORRECTION_VERSION_1" + +abstract_class IColorCorrectionSystem +{ +public: + virtual void Init() = 0; + virtual void Shutdown() = 0; + + virtual ColorCorrectionHandle_t AddLookup( const char *pName ) = 0; + virtual bool RemoveLookup( ColorCorrectionHandle_t handle ) = 0; + + virtual void SetLookupWeight( ColorCorrectionHandle_t handle, float flWeight ) = 0; + virtual float GetLookupWeight( ColorCorrectionHandle_t handle ) = 0; + virtual float GetLookupWeight( int i ) = 0; + + virtual void LockLookup() = 0; + virtual void LockLookup( ColorCorrectionHandle_t handle ) = 0; + + virtual void UnlockLookup() = 0; + virtual void UnlockLookup( ColorCorrectionHandle_t handle ) = 0; + + virtual void SetLookup( RGBX5551_t inColor, color24 outColor ) = 0; + virtual void SetLookup( ColorCorrectionHandle_t handle, RGBX5551_t inColor, color24 outColor ) = 0; + + virtual color24 GetLookup( RGBX5551_t inColor ) = 0; + virtual color24 GetLookup( ColorCorrectionHandle_t handle, RGBX5551_t inColor ) = 0; + + virtual void LoadLookup( const char *pLookupName ) = 0; + virtual void LoadLookup( ColorCorrectionHandle_t handle, const char *pLookupName ) = 0; + + virtual void CopyLookup( const color24 *pSrcColorCorrection ) = 0; + virtual void CopyLookup( ColorCorrectionHandle_t handle, const color24 *pSrcColorCorrection ) = 0; + + virtual void ResetLookup( ColorCorrectionHandle_t handle ) = 0; + virtual void ResetLookup( ) = 0; + + virtual void ReleaseTextures( ) = 0; + virtual void RestoreTextures( ) = 0; + + virtual void ResetLookupWeights( ) = 0; + + virtual int GetNumLookups( ) = 0; + + virtual color24 ConvertToColor24( RGBX5551_t inColor ) = 0; + + virtual void SetResetable( ColorCorrectionHandle_t handle, bool bResetable ) = 0; + + virtual void EnableColorCorrection( bool bEnable ) = 0; + + // FIXME: Move this to a private interface only the material system can see? + virtual void GetCurrentColorCorrection( ShaderColorCorrectionInfo_t* pInfo ) = 0; +}; + +#endif diff --git a/sp/src/public/materialsystem/IShader.h b/sp/src/public/materialsystem/IShader.h new file mode 100644 index 00000000..27bf91e3 --- /dev/null +++ b/sp/src/public/materialsystem/IShader.h @@ -0,0 +1,205 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#ifndef ISHADER_H +#define ISHADER_H + +#ifdef _WIN32 +#pragma once +#endif + +//================================================================================================== +// **this goes into both platforms which run the translator, either the real Mac client or +// the Windows client running with r_emulategl mode ** +// +// size of the VS register bank in ARB / GLSL we expose +// it's not 256, because you can't use all 256 slots in 10.5.x. +// use this constant everywhere you might normally use "256" in reference to a parameter array size. +// The highest shader constant is c218, plus we allocate c219 and c220 for two clip planes +#define DXABSTRACT_VS_PARAM_SLOTS 219 +#define DXABSTRACT_VS_FIRST_BONE_SLOT VERTEX_SHADER_MODEL + +// user clip plane 0 goes in DXABSTRACT_VS_CLIP_PLANE_BASE... plane 1 goes in the slot after that +// dxabstract uses these constants to check plane index limit and to deliver planes to shader for DP4 -> oCLP[n] +#define DXABSTRACT_VS_CLIP_PLANE_BASE (DXABSTRACT_VS_PARAM_SLOTS-2) + +//================================================================================================== + + +#include "materialsystem/imaterialsystem.h" +#include "materialsystem/ishaderapi.h" + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- +class IMaterialVar; +class IShaderShadow; +class IShaderDynamicAPI; +class IShaderInit; +class CBasePerMaterialContextData; + +//----------------------------------------------------------------------------- +// Shader flags +//----------------------------------------------------------------------------- +enum ShaderFlags_t +{ + SHADER_NOT_EDITABLE = 0x1 +}; + + +//----------------------------------------------------------------------------- +// Shader parameter flags +//----------------------------------------------------------------------------- +enum ShaderParamFlags_t +{ + SHADER_PARAM_NOT_EDITABLE = 0x1 +}; + + +//----------------------------------------------------------------------------- +// Information about each shader parameter +//----------------------------------------------------------------------------- +struct ShaderParamInfo_t +{ + const char *m_pName; + const char *m_pHelp; + ShaderParamType_t m_Type; + const char *m_pDefaultValue; + int m_nFlags; +}; + + +//----------------------------------------------------------------------------- +// Standard vertex shader constants +//----------------------------------------------------------------------------- +enum +{ + // Standard vertex shader constants + VERTEX_SHADER_MATH_CONSTANTS0 = 0, + VERTEX_SHADER_MATH_CONSTANTS1 = 1, + VERTEX_SHADER_CAMERA_POS = 2, + VERTEX_SHADER_FLEXSCALE = 3, // used by DX9 only! + VERTEX_SHADER_LIGHT_INDEX = 3, // used by DX8 only! + VERTEX_SHADER_MODELVIEWPROJ = 4, + VERTEX_SHADER_VIEWPROJ = 8, + VERTEX_SHADER_MODELVIEWPROJ_THIRD_ROW = 12, + VERTEX_SHADER_VIEWPROJ_THIRD_ROW = 13, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_10 = 14, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_11 = 15, + VERTEX_SHADER_FOG_PARAMS = 16, + VERTEX_SHADER_VIEWMODEL = 17, + VERTEX_SHADER_AMBIENT_LIGHT = 21, + VERTEX_SHADER_LIGHTS = 27, + VERTEX_SHADER_LIGHT0_POSITION = 29, + VERTEX_SHADER_MODULATION_COLOR = 47, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_0 = 48, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_1 = 49, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_2 = 50, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_3 = 51, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_4 = 52, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_5 = 53, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_6 = 54, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_7 = 55, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_8 = 56, + VERTEX_SHADER_SHADER_SPECIFIC_CONST_9 = 57, + VERTEX_SHADER_MODEL = 58, + + // + // We reserve up through 216 for the 53 bones + // + + // 219 ClipPlane0 |------ OpenGL will jam clip planes into these two + // 220 ClipPlane1 | + + VERTEX_SHADER_FLEX_WEIGHTS = 1024, + VERTEX_SHADER_MAX_FLEX_WEIGHT_COUNT = 512, +}; + +#define VERTEX_SHADER_BONE_TRANSFORM( k ) ( VERTEX_SHADER_MODEL + 3 * (k) ) + +//----------------------------------------------------------------------------- +// Standard vertex shader constants +//----------------------------------------------------------------------------- +enum +{ + // Standard vertex shader constants + VERTEX_SHADER_LIGHT_ENABLE_BOOL_CONST = 0, + VERTEX_SHADER_LIGHT_ENABLE_BOOL_CONST_COUNT = 4, + + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_0 = 4, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_1 = 5, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_2 = 6, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_3 = 7, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_4 = 8, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_5 = 9, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_6 = 10, + VERTEX_SHADER_SHADER_SPECIFIC_BOOL_CONST_7 = 11, +}; +// The public methods exposed by each shader +//----------------------------------------------------------------------------- +abstract_class IShader +{ +public: + // Returns the shader name + virtual char const* GetName( ) const = 0; + + // returns the shader fallbacks + virtual char const* GetFallbackShader( IMaterialVar** params ) const = 0; + + // Shader parameters + virtual int GetNumParams( ) const = 0; + + // These functions must be implemented by the shader + virtual void InitShaderParams( IMaterialVar** ppParams, const char *pMaterialName ) = 0; + virtual void InitShaderInstance( IMaterialVar** ppParams, IShaderInit *pShaderInit, const char *pMaterialName, const char *pTextureGroupName ) = 0; + virtual void DrawElements( IMaterialVar **params, int nModulationFlags, + IShaderShadow* pShaderShadow, IShaderDynamicAPI* pShaderAPI, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr ) = 0; + + virtual char const* GetParamName( int paramIndex ) const = 0; + virtual char const* GetParamHelp( int paramIndex ) const = 0; + virtual ShaderParamType_t GetParamType( int paramIndex ) const = 0; + virtual char const* GetParamDefault( int paramIndex ) const = 0; + + // FIXME: Figure out a better way to do this? + virtual int ComputeModulationFlags( IMaterialVar** params, IShaderDynamicAPI* pShaderAPI ) = 0; + virtual bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame = true ) const = 0; + virtual bool NeedsFullFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const = 0; + virtual bool IsTranslucent( IMaterialVar **params ) const = 0; + + virtual int GetParamFlags( int paramIndex ) const = 0; + + virtual int GetFlags() const = 0; + + // FIXME: Remove GetParamName, etc. above +// virtual const ShaderParamInfo_t& GetParamInfo( int paramIndex ) const = 0; +}; + + +//----------------------------------------------------------------------------- +// Shader dictionaries defined in DLLs +//----------------------------------------------------------------------------- +enum PrecompiledShaderType_t +{ + PRECOMPILED_VERTEX_SHADER = 0, + PRECOMPILED_PIXEL_SHADER, + + PRECOMPILED_SHADER_TYPE_COUNT, +}; + + +//----------------------------------------------------------------------------- +// Flags field of PrecompiledShader_t +//----------------------------------------------------------------------------- +enum +{ + // runtime flags + SHADER_DYNAMIC_COMPILE_IS_HLSL = 0x1, + SHADER_FAILED_LOAD = 0x2, +}; + +#endif // ISHADER_H diff --git a/sp/src/public/materialsystem/MaterialSystemUtil.cpp b/sp/src/public/materialsystem/MaterialSystemUtil.cpp new file mode 100644 index 00000000..ba63f007 --- /dev/null +++ b/sp/src/public/materialsystem/MaterialSystemUtil.cpp @@ -0,0 +1,255 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $NoKeywords: $ +//===========================================================================// + +#include "materialsystem/MaterialSystemUtil.h" +#include "materialsystem/imaterial.h" +#include "materialsystem/itexture.h" +#include "materialsystem/imaterialsystem.h" +#include "tier1/KeyValues.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// Little utility class to deal with material references +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// constructor, destructor +//----------------------------------------------------------------------------- +CMaterialReference::CMaterialReference( char const* pMaterialName, const char *pTextureGroupName, bool bComplain ) : m_pMaterial( 0 ) +{ + if ( pMaterialName ) + { + Assert( pTextureGroupName ); + Init( pMaterialName, pTextureGroupName, bComplain ); + } +} + +CMaterialReference::~CMaterialReference() +{ + Shutdown(); +} + +//----------------------------------------------------------------------------- +// Attach to a material +//----------------------------------------------------------------------------- +void CMaterialReference::Init( char const* pMaterialName, const char *pTextureGroupName, bool bComplain ) +{ + IMaterial *pMaterial = materials->FindMaterial( pMaterialName, pTextureGroupName, bComplain); + if( IsErrorMaterial( pMaterial ) ) + { + if (IsOSX()) + { + printf("\n ##### CMaterialReference::Init got error material for %s in tex group %s", pMaterialName, pTextureGroupName ); + } + } + + Assert( pMaterial ); + Init( pMaterial ); +} + +void CMaterialReference::Init( const char *pMaterialName, KeyValues *pVMTKeyValues ) +{ + // CreateMaterial has a refcount of 1 + Shutdown(); + m_pMaterial = materials->CreateMaterial( pMaterialName, pVMTKeyValues ); +} + +void CMaterialReference::Init( const char *pMaterialName, const char *pTextureGroupName, KeyValues *pVMTKeyValues ) +{ + IMaterial *pMaterial = materials->FindProceduralMaterial( pMaterialName, pTextureGroupName, pVMTKeyValues ); + Assert( pMaterial ); + Init( pMaterial ); +} + +void CMaterialReference::Init( IMaterial* pMaterial ) +{ + if ( m_pMaterial != pMaterial ) + { + Shutdown(); + m_pMaterial = pMaterial; + if ( m_pMaterial ) + { + m_pMaterial->IncrementReferenceCount(); + } + } +} + +void CMaterialReference::Init( CMaterialReference& ref ) +{ + if ( m_pMaterial != ref.m_pMaterial ) + { + Shutdown(); + m_pMaterial = ref.m_pMaterial; + if (m_pMaterial) + { + m_pMaterial->IncrementReferenceCount(); + } + } +} + +//----------------------------------------------------------------------------- +// Detach from a material +//----------------------------------------------------------------------------- +void CMaterialReference::Shutdown( ) +{ + if ( m_pMaterial && materials ) + { + m_pMaterial->DecrementReferenceCount(); + m_pMaterial = NULL; + } +} + + +//----------------------------------------------------------------------------- +// Little utility class to deal with texture references +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// constructor, destructor +//----------------------------------------------------------------------------- +CTextureReference::CTextureReference( ) : m_pTexture(NULL) +{ +} + +CTextureReference::CTextureReference( const CTextureReference &ref ) +{ + m_pTexture = ref.m_pTexture; + if ( m_pTexture ) + { + m_pTexture->IncrementReferenceCount(); + } +} + +void CTextureReference::operator=( CTextureReference &ref ) +{ + m_pTexture = ref.m_pTexture; + if ( m_pTexture ) + { + m_pTexture->IncrementReferenceCount(); + } +} + +CTextureReference::~CTextureReference( ) +{ + Shutdown(); +} + +//----------------------------------------------------------------------------- +// Attach to a texture +//----------------------------------------------------------------------------- +void CTextureReference::Init( char const* pTextureName, const char *pTextureGroupName, bool bComplain ) +{ + Shutdown(); + m_pTexture = materials->FindTexture( pTextureName, pTextureGroupName, bComplain ); + if ( m_pTexture ) + { + m_pTexture->IncrementReferenceCount(); + } +} + +void CTextureReference::Init( ITexture* pTexture ) +{ + Shutdown(); + + m_pTexture = pTexture; + if (m_pTexture) + { + m_pTexture->IncrementReferenceCount(); + } +} + +void CTextureReference::InitProceduralTexture( const char *pTextureName, const char *pTextureGroupName, int w, int h, ImageFormat fmt, int nFlags ) +{ + Shutdown(); + + m_pTexture = materials->CreateProceduralTexture( pTextureName, pTextureGroupName, w, h, fmt, nFlags ); + + // NOTE: The texture reference is already incremented internally above! + /* + if ( m_pTexture ) + { + m_pTexture->IncrementReferenceCount(); + } + */ +} + +void CTextureReference::InitRenderTarget( int w, int h, RenderTargetSizeMode_t sizeMode, ImageFormat fmt, MaterialRenderTargetDepth_t depth, bool bHDR, char *pStrOptionalName /* = NULL */ ) +{ + Shutdown(); + + int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT; + if ( depth == MATERIAL_RT_DEPTH_ONLY ) + textureFlags |= TEXTUREFLAGS_POINTSAMPLE; + + int renderTargetFlags = bHDR ? CREATERENDERTARGETFLAGS_HDR : 0; + + // NOTE: Refcount returned by CreateRenderTargetTexture is 1 + m_pTexture = materials->CreateNamedRenderTargetTextureEx( pStrOptionalName, w, h, sizeMode, fmt, + depth, textureFlags, renderTargetFlags ); + + Assert( m_pTexture ); +} + +//----------------------------------------------------------------------------- +// Detach from a texture +//----------------------------------------------------------------------------- +void CTextureReference::Shutdown( bool bDeleteIfUnReferenced ) +{ + if ( m_pTexture && materials ) + { + m_pTexture->DecrementReferenceCount(); + if ( bDeleteIfUnReferenced ) + { + m_pTexture->DeleteIfUnreferenced(); + } + m_pTexture = NULL; + } +} + +//----------------------------------------------------------------------------- +// Builds ONLY the system ram render target. Used when caller is explicitly managing. +// The paired EDRAM surface can be built in an alternate format. +//----------------------------------------------------------------------------- +#if defined( _X360 ) +void CTextureReference::InitRenderTargetTexture( int w, int h, RenderTargetSizeMode_t sizeMode, ImageFormat fmt, MaterialRenderTargetDepth_t depth, bool bHDR, char *pStrOptionalName ) +{ + // other variants not implemented yet + Assert( depth == MATERIAL_RT_DEPTH_NONE || depth == MATERIAL_RT_DEPTH_SHARED ); + Assert( !bHDR ); + + int renderTargetFlags = CREATERENDERTARGETFLAGS_NOEDRAM; + + m_pTexture = materials->CreateNamedRenderTargetTextureEx( + pStrOptionalName, + w, + h, + sizeMode, + fmt, + depth, + TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, + renderTargetFlags ); + Assert( m_pTexture ); +} +#endif + +//----------------------------------------------------------------------------- +// Builds ONLY the EDRAM render target surface. Used when caller is explicitly managing. +// The paired system memory texture can be built in an alternate format. +//----------------------------------------------------------------------------- +#if defined( _X360 ) +void CTextureReference::InitRenderTargetSurface( int width, int height, ImageFormat fmt, bool bSameAsTexture ) +{ + // texture has to be created first + Assert( m_pTexture && m_pTexture->IsRenderTarget() ); + + m_pTexture->CreateRenderTargetSurface( width, height, fmt, bSameAsTexture ); +} +#endif + diff --git a/sp/src/public/materialsystem/deformations.h b/sp/src/public/materialsystem/deformations.h new file mode 100644 index 00000000..083ceeb5 --- /dev/null +++ b/sp/src/public/materialsystem/deformations.h @@ -0,0 +1,58 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#ifndef DEFORMATIONS_H +#define DEFORMATIONS_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier0/platform.h" + +// nonlinear transformations which may be applied to model vertices when rendering. must be powers of two +enum DeformationType_t +{ + DEFORMATION_CLAMP_TO_BOX_IN_WORLDSPACE = 1, // minxyz.minsoftness / maxxyz.maxsoftness +}; + + +struct DeformationBase_t // base class. don't use this +{ + DeformationType_t m_eType; +}; + + +struct BoxDeformation_t : DeformationBase_t +{ + // don't change the layout without changing code in shaderapidx8!!!! + Vector m_SourceMins; // cube to clamp within + float m_flPad0; + Vector m_SourceMaxes; + float m_flPad1; + + Vector m_ClampMins; + float m_flPad2; + Vector m_ClampMaxes; + float m_flPad3; + + FORCEINLINE BoxDeformation_t( void ) + { + m_eType = DEFORMATION_CLAMP_TO_BOX_IN_WORLDSPACE; + // invalid cube + m_SourceMins.Init( 0,0,0 ); + m_SourceMaxes.Init( -1, -1, -1 ); + + // no clamp + m_ClampMins.Init( -FLT_MAX, -FLT_MAX, -FLT_MAX ); + m_ClampMaxes.Init( FLT_MAX, FLT_MAX, FLT_MAX ); + } + +}; + + + +#endif diff --git a/sp/src/public/materialsystem/hardwareverts.h b/sp/src/public/materialsystem/hardwareverts.h new file mode 100644 index 00000000..c7a08fe9 --- /dev/null +++ b/sp/src/public/materialsystem/hardwareverts.h @@ -0,0 +1,86 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Hardware Verts +// +// Contains data purposely formatted for a dma copy into a D3D Vertex Buffer. +// The file is divided into two partitions, the foremost contains the static +// portion (header), the latter contains the streamable compliant portion. +// The streamable component starts and ends on a sector (512) aligned boundary. +// The header identifies the vertex format of the data and the atomic sizes of each component. +// The hierarchial mesh is flattened for dma but the vertex counts are available +// per mesh to transfer each mesh individually. +//=============================================================================// + +#ifndef HARDWAREVERTS_H +#define HARDWAREVERTS_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "datamap.h" + +// valve hardware vertexes +#define VHV_VERSION 2 + +namespace HardwareVerts +{ + +#pragma pack(1) + +struct MeshHeader_t +{ + DECLARE_BYTESWAP_DATADESC(); + + // this mesh is part of this lod + unsigned int m_nLod; + + // this mesh has this many vertexes + unsigned int m_nVertexes; + + // starting at this offset + unsigned int m_nOffset; + + unsigned int m_nUnused[4]; +}; + +struct FileHeader_t +{ + DECLARE_BYTESWAP_DATADESC(); + + // file version as defined by VHV_VERSION + int m_nVersion; + + // must match checkSum in the .mdl header + unsigned int m_nChecksum; + + // a vertex consists of these components + uint32 m_nVertexFlags; + + // the byte size of a single vertex + // this won't be adequate, need some concept of byte format i.e. rgbexp32 vs rgba8888 + unsigned int m_nVertexSize; + + // total number of vertexes + unsigned int m_nVertexes; + + int m_nMeshes; + inline MeshHeader_t *pMesh( int nMesh ) const + { + return (MeshHeader_t *)(((byte *)this) + sizeof(FileHeader_t)) + nMesh; + }; + + inline void *pVertexBase( int nMesh ) const + { + return (void *)((byte *)this + pMesh( nMesh )->m_nOffset); + }; + + unsigned int m_nUnused[4]; +}; + +#pragma pack() + +}; // end namespace + +#endif // HARDWAREVERTS_H + diff --git a/sp/src/public/materialsystem/idebugtextureinfo.h b/sp/src/public/materialsystem/idebugtextureinfo.h new file mode 100644 index 00000000..426486da --- /dev/null +++ b/sp/src/public/materialsystem/idebugtextureinfo.h @@ -0,0 +1,69 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef IDEBUGTEXTUREINFO_H +#define IDEBUGTEXTUREINFO_H +#ifdef _WIN32 +#pragma once +#endif + + +class KeyValues; + + +// This interface is actually exported by the shader API DLL. +#define DEBUG_TEXTURE_INFO_VERSION "DebugTextureInfo001" + + +abstract_class IDebugTextureInfo +{ +public: + + // Use this to turn on the mode where it builds the debug texture list. + // At the end of the next frame, GetDebugTextureList() will return a valid list of the textures. + virtual void EnableDebugTextureList( bool bEnable ) = 0; + + // If this is on, then it will return all textures that exist, not just the ones that were bound in the last frame. + // It is required to enable debug texture list to get this. + virtual void EnableGetAllTextures( bool bEnable ) = 0; + + // Use this to get the results of the texture list. + // Do NOT release the KeyValues after using them. + // There will be a bunch of subkeys, each with these values: + // Name - the texture's filename + // Binds - how many times the texture was bound + // Format - ImageFormat of the texture + // Width - Width of the texture + // Height - Height of the texture + // It is required to enable debug texture list to get this. + virtual KeyValues* GetDebugTextureList() = 0; + + // Texture memory usage + enum TextureMemoryType + { + MEMORY_RESERVED_MIN = 0, + MEMORY_BOUND_LAST_FRAME, // sums up textures bound last frame + MEMORY_TOTAL_LOADED, // total texture memory used + MEMORY_ESTIMATE_PICMIP_1, // estimate of running with "picmip 1" + MEMORY_ESTIMATE_PICMIP_2, // estimate of running with "picmip 2" + MEMORY_RESERVED_MAX + }; + + // This returns how much memory was used. + virtual int GetTextureMemoryUsed( TextureMemoryType eTextureMemory ) = 0; + + // Use this to determine if texture debug info was computed within last numFramesAllowed frames. + virtual bool IsDebugTextureListFresh( int numFramesAllowed = 1 ) = 0; + + // Enable debug texture rendering when texture binds should not count towards textures + // used during a frame. Returns the old state of debug texture rendering flag to use + // it for restoring the mode. + virtual bool SetDebugTextureRendering( bool bEnable ) = 0; + +}; + + +#endif // IDEBUGTEXTUREINFO_H diff --git a/sp/src/public/materialsystem/imaterial.h b/sp/src/public/materialsystem/imaterial.h new file mode 100644 index 00000000..7af7aa15 --- /dev/null +++ b/sp/src/public/materialsystem/imaterial.h @@ -0,0 +1,612 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef IMATERIAL_H +#define IMATERIAL_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "bitmap/imageformat.h" +#include "materialsystem/imaterialsystem.h" + +//----------------------------------------------------------------------------- +// forward declaraions +//----------------------------------------------------------------------------- + +class IMaterialVar; +class ITexture; +class IMaterialProxy; +class Vector; + +//----------------------------------------------------------------------------- +// Flags for GetVertexFormat +//----------------------------------------------------------------------------- +#define VERTEX_POSITION 0x0001 +#define VERTEX_NORMAL 0x0002 +#define VERTEX_COLOR 0x0004 +#define VERTEX_SPECULAR 0x0008 + +#define VERTEX_TANGENT_S 0x0010 +#define VERTEX_TANGENT_T 0x0020 +#define VERTEX_TANGENT_SPACE ( VERTEX_TANGENT_S | VERTEX_TANGENT_T ) + +// Indicates we're using wrinkle +#define VERTEX_WRINKLE 0x0040 + +// Indicates we're using bone indices +#define VERTEX_BONE_INDEX 0x0080 + +// Indicates this is a vertex shader +#define VERTEX_FORMAT_VERTEX_SHADER 0x0100 + +// Indicates this format shouldn't be bloated to cache align it +// (only used for VertexUsage) +#define VERTEX_FORMAT_USE_EXACT_FORMAT 0x0200 + +// Indicates that compressed vertex elements are to be used (see also VertexCompressionType_t) +#define VERTEX_FORMAT_COMPRESSED 0x400 + +// Update this if you add or remove bits... +#define VERTEX_LAST_BIT 10 + +#define VERTEX_BONE_WEIGHT_BIT (VERTEX_LAST_BIT + 1) +#define USER_DATA_SIZE_BIT (VERTEX_LAST_BIT + 4) +#define TEX_COORD_SIZE_BIT (VERTEX_LAST_BIT + 7) + +#define VERTEX_BONE_WEIGHT_MASK ( 0x7 << VERTEX_BONE_WEIGHT_BIT ) +#define USER_DATA_SIZE_MASK ( 0x7 << USER_DATA_SIZE_BIT ) + +#define VERTEX_FORMAT_FIELD_MASK 0x0FF + +// If everything is off, it's an unknown vertex format +#define VERTEX_FORMAT_UNKNOWN 0 + + + +//----------------------------------------------------------------------------- +// Macros for construction.. +//----------------------------------------------------------------------------- +#define VERTEX_BONEWEIGHT( _n ) ((_n) << VERTEX_BONE_WEIGHT_BIT) +#define VERTEX_USERDATA_SIZE( _n ) ((_n) << USER_DATA_SIZE_BIT) +#define VERTEX_TEXCOORD_MASK( _coord ) (( 0x7ULL ) << ( TEX_COORD_SIZE_BIT + 3 * (_coord) )) + +inline VertexFormat_t VERTEX_TEXCOORD_SIZE( int nIndex, int nNumCoords ) +{ + uint64 n64=nNumCoords; + uint64 nShift=TEX_COORD_SIZE_BIT + (3*nIndex); + return n64 << nShift; +} + + + +//----------------------------------------------------------------------------- +// Gets at various vertex format info... +//----------------------------------------------------------------------------- +inline int VertexFlags( VertexFormat_t vertexFormat ) +{ + return static_cast ( vertexFormat & ( (1 << (VERTEX_LAST_BIT+1)) - 1 ) ); +} + +inline int NumBoneWeights( VertexFormat_t vertexFormat ) +{ + return static_cast ( (vertexFormat >> VERTEX_BONE_WEIGHT_BIT) & 0x7 ); +} + +inline int UserDataSize( VertexFormat_t vertexFormat ) +{ + return static_cast ( (vertexFormat >> USER_DATA_SIZE_BIT) & 0x7 ); +} + +inline int TexCoordSize( int nTexCoordIndex, VertexFormat_t vertexFormat ) +{ + return static_cast ( (vertexFormat >> (TEX_COORD_SIZE_BIT + 3*nTexCoordIndex) ) & 0x7 ); +} + +inline bool UsesVertexShader( VertexFormat_t vertexFormat ) +{ + return (vertexFormat & VERTEX_FORMAT_VERTEX_SHADER) != 0; +} + +inline VertexCompressionType_t CompressionType( VertexFormat_t vertexFormat ) +{ + // This is trivial now, but we may add multiple flavours of compressed vertex later on + if ( vertexFormat & VERTEX_FORMAT_COMPRESSED ) + return VERTEX_COMPRESSION_ON; + else + return VERTEX_COMPRESSION_NONE; +} + + +//----------------------------------------------------------------------------- +// VertexElement_t (enumerates all usable vertex elements) +//----------------------------------------------------------------------------- +// FIXME: unify this with VertexFormat_t (i.e. construct the lower bits of VertexFormat_t with "1 << (VertexElement_t)element") +enum VertexElement_t +{ + VERTEX_ELEMENT_NONE = -1, + + // Deliberately explicitly numbered so it's a pain in the ass to change, so you read this: + // #!#!#NOTE#!#!# update GetVertexElementSize, VertexElementToDeclType and + // CVBAllocTracker (elementTable) when you update this! + VERTEX_ELEMENT_POSITION = 0, + VERTEX_ELEMENT_NORMAL = 1, + VERTEX_ELEMENT_COLOR = 2, + VERTEX_ELEMENT_SPECULAR = 3, + VERTEX_ELEMENT_TANGENT_S = 4, + VERTEX_ELEMENT_TANGENT_T = 5, + VERTEX_ELEMENT_WRINKLE = 6, + VERTEX_ELEMENT_BONEINDEX = 7, + VERTEX_ELEMENT_BONEWEIGHTS1 = 8, + VERTEX_ELEMENT_BONEWEIGHTS2 = 9, + VERTEX_ELEMENT_BONEWEIGHTS3 = 10, + VERTEX_ELEMENT_BONEWEIGHTS4 = 11, + VERTEX_ELEMENT_USERDATA1 = 12, + VERTEX_ELEMENT_USERDATA2 = 13, + VERTEX_ELEMENT_USERDATA3 = 14, + VERTEX_ELEMENT_USERDATA4 = 15, + VERTEX_ELEMENT_TEXCOORD1D_0 = 16, + VERTEX_ELEMENT_TEXCOORD1D_1 = 17, + VERTEX_ELEMENT_TEXCOORD1D_2 = 18, + VERTEX_ELEMENT_TEXCOORD1D_3 = 19, + VERTEX_ELEMENT_TEXCOORD1D_4 = 20, + VERTEX_ELEMENT_TEXCOORD1D_5 = 21, + VERTEX_ELEMENT_TEXCOORD1D_6 = 22, + VERTEX_ELEMENT_TEXCOORD1D_7 = 23, + VERTEX_ELEMENT_TEXCOORD2D_0 = 24, + VERTEX_ELEMENT_TEXCOORD2D_1 = 25, + VERTEX_ELEMENT_TEXCOORD2D_2 = 26, + VERTEX_ELEMENT_TEXCOORD2D_3 = 27, + VERTEX_ELEMENT_TEXCOORD2D_4 = 28, + VERTEX_ELEMENT_TEXCOORD2D_5 = 29, + VERTEX_ELEMENT_TEXCOORD2D_6 = 30, + VERTEX_ELEMENT_TEXCOORD2D_7 = 31, + VERTEX_ELEMENT_TEXCOORD3D_0 = 32, + VERTEX_ELEMENT_TEXCOORD3D_1 = 33, + VERTEX_ELEMENT_TEXCOORD3D_2 = 34, + VERTEX_ELEMENT_TEXCOORD3D_3 = 35, + VERTEX_ELEMENT_TEXCOORD3D_4 = 36, + VERTEX_ELEMENT_TEXCOORD3D_5 = 37, + VERTEX_ELEMENT_TEXCOORD3D_6 = 38, + VERTEX_ELEMENT_TEXCOORD3D_7 = 39, + VERTEX_ELEMENT_TEXCOORD4D_0 = 40, + VERTEX_ELEMENT_TEXCOORD4D_1 = 41, + VERTEX_ELEMENT_TEXCOORD4D_2 = 42, + VERTEX_ELEMENT_TEXCOORD4D_3 = 43, + VERTEX_ELEMENT_TEXCOORD4D_4 = 44, + VERTEX_ELEMENT_TEXCOORD4D_5 = 45, + VERTEX_ELEMENT_TEXCOORD4D_6 = 46, + VERTEX_ELEMENT_TEXCOORD4D_7 = 47, + + VERTEX_ELEMENT_NUMELEMENTS = 48 +}; + +inline void Detect_VertexElement_t_Changes( VertexElement_t element ) // GREPs for VertexElement_t will hit this +{ + // Make it harder for someone to change VertexElement_t without noticing that dependent code + // (GetVertexElementSize, VertexElementToDeclType, CVBAllocTracker) needs updating + Assert( VERTEX_ELEMENT_NUMELEMENTS == 48 ); + switch ( element ) + { + case VERTEX_ELEMENT_POSITION: Assert( VERTEX_ELEMENT_POSITION == 0 ); break; + case VERTEX_ELEMENT_NORMAL: Assert( VERTEX_ELEMENT_NORMAL == 1 ); break; + case VERTEX_ELEMENT_COLOR: Assert( VERTEX_ELEMENT_COLOR == 2 ); break; + case VERTEX_ELEMENT_SPECULAR: Assert( VERTEX_ELEMENT_SPECULAR == 3 ); break; + case VERTEX_ELEMENT_TANGENT_S: Assert( VERTEX_ELEMENT_TANGENT_S == 4 ); break; + case VERTEX_ELEMENT_TANGENT_T: Assert( VERTEX_ELEMENT_TANGENT_T == 5 ); break; + case VERTEX_ELEMENT_WRINKLE: Assert( VERTEX_ELEMENT_WRINKLE == 6 ); break; + case VERTEX_ELEMENT_BONEINDEX: Assert( VERTEX_ELEMENT_BONEINDEX == 7 ); break; + case VERTEX_ELEMENT_BONEWEIGHTS1: Assert( VERTEX_ELEMENT_BONEWEIGHTS1 == 8 ); break; + case VERTEX_ELEMENT_BONEWEIGHTS2: Assert( VERTEX_ELEMENT_BONEWEIGHTS2 == 9 ); break; + case VERTEX_ELEMENT_BONEWEIGHTS3: Assert( VERTEX_ELEMENT_BONEWEIGHTS3 == 10 ); break; + case VERTEX_ELEMENT_BONEWEIGHTS4: Assert( VERTEX_ELEMENT_BONEWEIGHTS4 == 11 ); break; + case VERTEX_ELEMENT_USERDATA1: Assert( VERTEX_ELEMENT_USERDATA1 == 12 ); break; + case VERTEX_ELEMENT_USERDATA2: Assert( VERTEX_ELEMENT_USERDATA2 == 13 ); break; + case VERTEX_ELEMENT_USERDATA3: Assert( VERTEX_ELEMENT_USERDATA3 == 14 ); break; + case VERTEX_ELEMENT_USERDATA4: Assert( VERTEX_ELEMENT_USERDATA4 == 15 ); break; + case VERTEX_ELEMENT_TEXCOORD1D_0: Assert( VERTEX_ELEMENT_TEXCOORD1D_0 == 16 ); break; + case VERTEX_ELEMENT_TEXCOORD1D_1: Assert( VERTEX_ELEMENT_TEXCOORD1D_1 == 17 ); break; + case VERTEX_ELEMENT_TEXCOORD1D_2: Assert( VERTEX_ELEMENT_TEXCOORD1D_2 == 18 ); break; + case VERTEX_ELEMENT_TEXCOORD1D_3: Assert( VERTEX_ELEMENT_TEXCOORD1D_3 == 19 ); break; + case VERTEX_ELEMENT_TEXCOORD1D_4: Assert( VERTEX_ELEMENT_TEXCOORD1D_4 == 20 ); break; + case VERTEX_ELEMENT_TEXCOORD1D_5: Assert( VERTEX_ELEMENT_TEXCOORD1D_5 == 21 ); break; + case VERTEX_ELEMENT_TEXCOORD1D_6: Assert( VERTEX_ELEMENT_TEXCOORD1D_6 == 22 ); break; + case VERTEX_ELEMENT_TEXCOORD1D_7: Assert( VERTEX_ELEMENT_TEXCOORD1D_7 == 23 ); break; + case VERTEX_ELEMENT_TEXCOORD2D_0: Assert( VERTEX_ELEMENT_TEXCOORD2D_0 == 24 ); break; + case VERTEX_ELEMENT_TEXCOORD2D_1: Assert( VERTEX_ELEMENT_TEXCOORD2D_1 == 25 ); break; + case VERTEX_ELEMENT_TEXCOORD2D_2: Assert( VERTEX_ELEMENT_TEXCOORD2D_2 == 26 ); break; + case VERTEX_ELEMENT_TEXCOORD2D_3: Assert( VERTEX_ELEMENT_TEXCOORD2D_3 == 27 ); break; + case VERTEX_ELEMENT_TEXCOORD2D_4: Assert( VERTEX_ELEMENT_TEXCOORD2D_4 == 28 ); break; + case VERTEX_ELEMENT_TEXCOORD2D_5: Assert( VERTEX_ELEMENT_TEXCOORD2D_5 == 29 ); break; + case VERTEX_ELEMENT_TEXCOORD2D_6: Assert( VERTEX_ELEMENT_TEXCOORD2D_6 == 30 ); break; + case VERTEX_ELEMENT_TEXCOORD2D_7: Assert( VERTEX_ELEMENT_TEXCOORD2D_7 == 31 ); break; + case VERTEX_ELEMENT_TEXCOORD3D_0: Assert( VERTEX_ELEMENT_TEXCOORD3D_0 == 32 ); break; + case VERTEX_ELEMENT_TEXCOORD3D_1: Assert( VERTEX_ELEMENT_TEXCOORD3D_1 == 33 ); break; + case VERTEX_ELEMENT_TEXCOORD3D_2: Assert( VERTEX_ELEMENT_TEXCOORD3D_2 == 34 ); break; + case VERTEX_ELEMENT_TEXCOORD3D_3: Assert( VERTEX_ELEMENT_TEXCOORD3D_3 == 35 ); break; + case VERTEX_ELEMENT_TEXCOORD3D_4: Assert( VERTEX_ELEMENT_TEXCOORD3D_4 == 36 ); break; + case VERTEX_ELEMENT_TEXCOORD3D_5: Assert( VERTEX_ELEMENT_TEXCOORD3D_5 == 37 ); break; + case VERTEX_ELEMENT_TEXCOORD3D_6: Assert( VERTEX_ELEMENT_TEXCOORD3D_6 == 38 ); break; + case VERTEX_ELEMENT_TEXCOORD3D_7: Assert( VERTEX_ELEMENT_TEXCOORD3D_7 == 39 ); break; + case VERTEX_ELEMENT_TEXCOORD4D_0: Assert( VERTEX_ELEMENT_TEXCOORD4D_0 == 40 ); break; + case VERTEX_ELEMENT_TEXCOORD4D_1: Assert( VERTEX_ELEMENT_TEXCOORD4D_1 == 41 ); break; + case VERTEX_ELEMENT_TEXCOORD4D_2: Assert( VERTEX_ELEMENT_TEXCOORD4D_2 == 42 ); break; + case VERTEX_ELEMENT_TEXCOORD4D_3: Assert( VERTEX_ELEMENT_TEXCOORD4D_3 == 43 ); break; + case VERTEX_ELEMENT_TEXCOORD4D_4: Assert( VERTEX_ELEMENT_TEXCOORD4D_4 == 44 ); break; + case VERTEX_ELEMENT_TEXCOORD4D_5: Assert( VERTEX_ELEMENT_TEXCOORD4D_5 == 45 ); break; + case VERTEX_ELEMENT_TEXCOORD4D_6: Assert( VERTEX_ELEMENT_TEXCOORD4D_6 == 46 ); break; + case VERTEX_ELEMENT_TEXCOORD4D_7: Assert( VERTEX_ELEMENT_TEXCOORD4D_7 == 47 ); break; + default: + Assert( 0 ); // Invalid input or VertexElement_t has definitely changed + break; + } +} + +// We're testing 2 normal compression methods +// One compressed normals+tangents into a SHORT2 each (8 bytes total) +// The other compresses them together, into a single UBYTE4 (4 bytes total) +// FIXME: pick one or the other, compare lighting quality in important cases +#define COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 0 +#define COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 1 +//#define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 +#define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 + +inline int GetVertexElementSize( VertexElement_t element, VertexCompressionType_t compressionType ) +{ + Detect_VertexElement_t_Changes( element ); + + if ( compressionType == VERTEX_COMPRESSION_ON ) + { + // Compressed-vertex element sizes + switch ( element ) + { +#if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 ) + case VERTEX_ELEMENT_NORMAL: + return ( 2 * sizeof( short ) ); + case VERTEX_ELEMENT_USERDATA4: + return ( 2 * sizeof( short ) ); +#else //( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) + // Normals and tangents (userdata4) are combined into a single UBYTE4 vertex element + case VERTEX_ELEMENT_NORMAL: + return ( 4 * sizeof( unsigned char ) ); + case VERTEX_ELEMENT_USERDATA4: + return ( 0 ); +#endif + // Compressed bone weights use a SHORT2 vertex element: + case VERTEX_ELEMENT_BONEWEIGHTS1: + case VERTEX_ELEMENT_BONEWEIGHTS2: + return ( 2 * sizeof( short ) ); + default: + break; + } + } + + // Uncompressed-vertex element sizes + switch ( element ) + { + case VERTEX_ELEMENT_POSITION: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_NORMAL: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_COLOR: return ( 4 * sizeof( unsigned char ) ); + case VERTEX_ELEMENT_SPECULAR: return ( 4 * sizeof( unsigned char ) ); + case VERTEX_ELEMENT_TANGENT_S: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TANGENT_T: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_WRINKLE: return ( 1 * sizeof( float ) ); // Packed into Position.W + case VERTEX_ELEMENT_BONEINDEX: return ( 4 * sizeof( unsigned char ) ); + case VERTEX_ELEMENT_BONEWEIGHTS1: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_BONEWEIGHTS2: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_BONEWEIGHTS3: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_BONEWEIGHTS4: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_USERDATA1: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_USERDATA2: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_USERDATA3: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_USERDATA4: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD1D_0: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD1D_1: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD1D_2: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD1D_3: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD1D_4: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD1D_5: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD1D_6: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD1D_7: return ( 1 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD2D_0: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD2D_1: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD2D_2: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD2D_3: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD2D_4: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD2D_5: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD2D_6: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD2D_7: return ( 2 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD3D_0: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD3D_1: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD3D_2: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD3D_3: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD3D_4: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD3D_5: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD3D_6: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD3D_7: return ( 3 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD4D_0: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD4D_1: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD4D_2: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD4D_3: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD4D_4: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD4D_5: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD4D_6: return ( 4 * sizeof( float ) ); + case VERTEX_ELEMENT_TEXCOORD4D_7: return ( 4 * sizeof( float ) ); + default: + Assert(0); + return 0; + }; +} + + +//----------------------------------------------------------------------------- +// Shader state flags can be read from the FLAGS materialvar +// Also can be read or written to with the Set/GetMaterialVarFlags() call +// Also make sure you add/remove a string associated with each flag below to CShaderSystem::ShaderStateString in ShaderSystem.cpp +//----------------------------------------------------------------------------- +enum MaterialVarFlags_t +{ + MATERIAL_VAR_DEBUG = (1 << 0), + MATERIAL_VAR_NO_DEBUG_OVERRIDE = (1 << 1), + MATERIAL_VAR_NO_DRAW = (1 << 2), + MATERIAL_VAR_USE_IN_FILLRATE_MODE = (1 << 3), + + MATERIAL_VAR_VERTEXCOLOR = (1 << 4), + MATERIAL_VAR_VERTEXALPHA = (1 << 5), + MATERIAL_VAR_SELFILLUM = (1 << 6), + MATERIAL_VAR_ADDITIVE = (1 << 7), + MATERIAL_VAR_ALPHATEST = (1 << 8), + MATERIAL_VAR_MULTIPASS = (1 << 9), + MATERIAL_VAR_ZNEARER = (1 << 10), + MATERIAL_VAR_MODEL = (1 << 11), + MATERIAL_VAR_FLAT = (1 << 12), + MATERIAL_VAR_NOCULL = (1 << 13), + MATERIAL_VAR_NOFOG = (1 << 14), + MATERIAL_VAR_IGNOREZ = (1 << 15), + MATERIAL_VAR_DECAL = (1 << 16), + MATERIAL_VAR_ENVMAPSPHERE = (1 << 17), + MATERIAL_VAR_NOALPHAMOD = (1 << 18), + MATERIAL_VAR_ENVMAPCAMERASPACE = (1 << 19), + MATERIAL_VAR_BASEALPHAENVMAPMASK = (1 << 20), + MATERIAL_VAR_TRANSLUCENT = (1 << 21), + MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK = (1 << 22), + MATERIAL_VAR_NEEDS_SOFTWARE_SKINNING = (1 << 23), + MATERIAL_VAR_OPAQUETEXTURE = (1 << 24), + MATERIAL_VAR_ENVMAPMODE = (1 << 25), + MATERIAL_VAR_SUPPRESS_DECALS = (1 << 26), + MATERIAL_VAR_HALFLAMBERT = (1 << 27), + MATERIAL_VAR_WIREFRAME = (1 << 28), + MATERIAL_VAR_ALLOWALPHATOCOVERAGE = (1 << 29), + MATERIAL_VAR_IGNORE_ALPHA_MODULATION = (1 << 30), + + // NOTE: Only add flags here that either should be read from + // .vmts or can be set directly from client code. Other, internal + // flags should to into the flag enum in imaterialinternal.h +}; + + +//----------------------------------------------------------------------------- +// Internal flags not accessible from outside the material system. Stored in Flags2 +//----------------------------------------------------------------------------- +enum MaterialVarFlags2_t +{ + // NOTE: These are for $flags2!!!!! +// UNUSED = (1 << 0), + + MATERIAL_VAR2_LIGHTING_UNLIT = 0, + MATERIAL_VAR2_LIGHTING_VERTEX_LIT = (1 << 1), + MATERIAL_VAR2_LIGHTING_LIGHTMAP = (1 << 2), + MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP = (1 << 3), + MATERIAL_VAR2_LIGHTING_MASK = + ( MATERIAL_VAR2_LIGHTING_VERTEX_LIT | + MATERIAL_VAR2_LIGHTING_LIGHTMAP | + MATERIAL_VAR2_LIGHTING_BUMPED_LIGHTMAP ), + + // FIXME: Should this be a part of the above lighting enums? + MATERIAL_VAR2_DIFFUSE_BUMPMAPPED_MODEL = (1 << 4), + MATERIAL_VAR2_USES_ENV_CUBEMAP = (1 << 5), + MATERIAL_VAR2_NEEDS_TANGENT_SPACES = (1 << 6), + MATERIAL_VAR2_NEEDS_SOFTWARE_LIGHTING = (1 << 7), + // GR - HDR path puts lightmap alpha in separate texture... + MATERIAL_VAR2_BLEND_WITH_LIGHTMAP_ALPHA = (1 << 8), + MATERIAL_VAR2_NEEDS_BAKED_LIGHTING_SNAPSHOTS = (1 << 9), + MATERIAL_VAR2_USE_FLASHLIGHT = (1 << 10), + MATERIAL_VAR2_USE_FIXED_FUNCTION_BAKED_LIGHTING = (1 << 11), + MATERIAL_VAR2_NEEDS_FIXED_FUNCTION_FLASHLIGHT = (1 << 12), + MATERIAL_VAR2_USE_EDITOR = (1 << 13), + MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE = (1 << 14), + MATERIAL_VAR2_NEEDS_FULL_FRAME_BUFFER_TEXTURE = (1 << 15), + MATERIAL_VAR2_IS_SPRITECARD = (1 << 16), + MATERIAL_VAR2_USES_VERTEXID = (1 << 17), + MATERIAL_VAR2_SUPPORTS_HW_SKINNING = (1 << 18), + MATERIAL_VAR2_SUPPORTS_FLASHLIGHT = (1 << 19), +}; + + +//----------------------------------------------------------------------------- +// Preview image return values +//----------------------------------------------------------------------------- +enum PreviewImageRetVal_t +{ + MATERIAL_PREVIEW_IMAGE_BAD = 0, + MATERIAL_PREVIEW_IMAGE_OK, + MATERIAL_NO_PREVIEW_IMAGE, +}; + + +//----------------------------------------------------------------------------- +// material interface +//----------------------------------------------------------------------------- +abstract_class IMaterial +{ +public: + // Get the name of the material. This is a full path to + // the vmt file starting from "hl2/materials" (or equivalent) without + // a file extension. + virtual const char * GetName() const = 0; + virtual const char * GetTextureGroupName() const = 0; + + // Get the preferred size/bitDepth of a preview image of a material. + // This is the sort of image that you would use for a thumbnail view + // of a material, or in WorldCraft until it uses materials to render. + // separate this for the tools maybe + virtual PreviewImageRetVal_t GetPreviewImageProperties( int *width, int *height, + ImageFormat *imageFormat, bool* isTranslucent ) const = 0; + + // Get a preview image at the specified width/height and bitDepth. + // Will do resampling if necessary.(not yet!!! :) ) + // Will do color format conversion. (works now.) + virtual PreviewImageRetVal_t GetPreviewImage( unsigned char *data, + int width, int height, + ImageFormat imageFormat ) const = 0; + // + virtual int GetMappingWidth( ) = 0; + virtual int GetMappingHeight( ) = 0; + + virtual int GetNumAnimationFrames( ) = 0; + + // For material subrects (material pages). Offset(u,v) and scale(u,v) are normalized to texture. + virtual bool InMaterialPage( void ) = 0; + virtual void GetMaterialOffset( float *pOffset ) = 0; + virtual void GetMaterialScale( float *pScale ) = 0; + virtual IMaterial *GetMaterialPage( void ) = 0; + + // find a vmt variable. + // This is how game code affects how a material is rendered. + // The game code must know about the params that are used by + // the shader for the material that it is trying to affect. + virtual IMaterialVar * FindVar( const char *varName, bool *found, bool complain = true ) = 0; + + // The user never allocates or deallocates materials. Reference counting is + // used instead. Garbage collection is done upon a call to + // IMaterialSystem::UncacheUnusedMaterials. + virtual void IncrementReferenceCount( void ) = 0; + virtual void DecrementReferenceCount( void ) = 0; + + inline void AddRef() { IncrementReferenceCount(); } + inline void Release() { DecrementReferenceCount(); } + + // Each material is assigned a number that groups it with like materials + // for sorting in the application. + virtual int GetEnumerationID( void ) const = 0; + + virtual void GetLowResColorSample( float s, float t, float *color ) const = 0; + + // This computes the state snapshots for this material + virtual void RecomputeStateSnapshots() = 0; + + // Are we translucent? + virtual bool IsTranslucent() = 0; + + // Are we alphatested? + virtual bool IsAlphaTested() = 0; + + // Are we vertex lit? + virtual bool IsVertexLit() = 0; + + // Gets the vertex format + virtual VertexFormat_t GetVertexFormat() const = 0; + + // returns true if this material uses a material proxy + virtual bool HasProxy( void ) const = 0; + + virtual bool UsesEnvCubemap( void ) = 0; + + virtual bool NeedsTangentSpace( void ) = 0; + + virtual bool NeedsPowerOfTwoFrameBufferTexture( bool bCheckSpecificToThisFrame = true ) = 0; + virtual bool NeedsFullFrameBufferTexture( bool bCheckSpecificToThisFrame = true ) = 0; + + // returns true if the shader doesn't do skinning itself and requires + // the data that is sent to it to be preskinned. + virtual bool NeedsSoftwareSkinning( void ) = 0; + + // Apply constant color or alpha modulation + virtual void AlphaModulate( float alpha ) = 0; + virtual void ColorModulate( float r, float g, float b ) = 0; + + // Material Var flags... + virtual void SetMaterialVarFlag( MaterialVarFlags_t flag, bool on ) = 0; + virtual bool GetMaterialVarFlag( MaterialVarFlags_t flag ) const = 0; + + // Gets material reflectivity + virtual void GetReflectivity( Vector& reflect ) = 0; + + // Gets material property flags + virtual bool GetPropertyFlag( MaterialPropertyTypes_t type ) = 0; + + // Is the material visible from both sides? + virtual bool IsTwoSided() = 0; + + // Sets the shader associated with the material + virtual void SetShader( const char *pShaderName ) = 0; + + // Can't be const because the material might have to precache itself. + virtual int GetNumPasses( void ) = 0; + + // Can't be const because the material might have to precache itself. + virtual int GetTextureMemoryBytes( void ) = 0; + + // Meant to be used with materials created using CreateMaterial + // It updates the materials to reflect the current values stored in the material vars + virtual void Refresh() = 0; + + // GR - returns true is material uses lightmap alpha for blending + virtual bool NeedsLightmapBlendAlpha( void ) = 0; + + // returns true if the shader doesn't do lighting itself and requires + // the data that is sent to it to be prelighted + virtual bool NeedsSoftwareLighting( void ) = 0; + + // Gets at the shader parameters + virtual int ShaderParamCount() const = 0; + virtual IMaterialVar **GetShaderParams( void ) = 0; + + // Returns true if this is the error material you get back from IMaterialSystem::FindMaterial if + // the material can't be found. + virtual bool IsErrorMaterial() const = 0; + + virtual void SetUseFixedFunctionBakedLighting( bool bEnable ) = 0; + + // Gets the current alpha modulation + virtual float GetAlphaModulation() = 0; + virtual void GetColorModulation( float *r, float *g, float *b ) = 0; + + // Gets the morph format + virtual MorphFormat_t GetMorphFormat() const = 0; + + // fast find that stores the index of the found var in the string table in local cache + virtual IMaterialVar * FindVarFast( char const *pVarName, unsigned int *pToken ) = 0; + + // Sets new VMT shader parameters for the material + virtual void SetShaderAndParams( KeyValues *pKeyValues ) = 0; + virtual const char * GetShaderName() const = 0; + + virtual void DeleteIfUnreferenced() = 0; + + virtual bool IsSpriteCard() = 0; + + virtual void CallBindProxy( void *proxyData ) = 0; + + virtual IMaterial *CheckProxyReplacement( void *proxyData ) = 0; + + virtual void RefreshPreservingMaterialVars() = 0; + + virtual bool WasReloadedFromWhitelist() = 0; + + virtual bool IsPrecached() const = 0; +}; + + +inline bool IsErrorMaterial( IMaterial *pMat ) +{ + return !pMat || pMat->IsErrorMaterial(); +} + +#endif // IMATERIAL_H diff --git a/sp/src/public/materialsystem/imaterialproxy.h b/sp/src/public/materialsystem/imaterialproxy.h new file mode 100644 index 00000000..52c49bef --- /dev/null +++ b/sp/src/public/materialsystem/imaterialproxy.h @@ -0,0 +1,32 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef IMATERIALPROXY_H +#define IMATERIALPROXY_H +#pragma once + +#include "interface.h" + +#define IMATERIAL_PROXY_INTERFACE_VERSION "_IMaterialProxy003" + +class IMaterial; +class KeyValues; + +abstract_class IMaterialProxy +{ +public: + virtual bool Init( IMaterial* pMaterial, KeyValues *pKeyValues ) = 0; + virtual void OnBind( void * ) = 0; + virtual void Release() = 0; + virtual IMaterial * GetMaterial() = 0; + +protected: + // no one should call this directly + virtual ~IMaterialProxy() {} +}; + +#endif // IMATERIALPROXY_H diff --git a/sp/src/public/materialsystem/imaterialproxyfactory.h b/sp/src/public/materialsystem/imaterialproxyfactory.h new file mode 100644 index 00000000..4045cb00 --- /dev/null +++ b/sp/src/public/materialsystem/imaterialproxyfactory.h @@ -0,0 +1,25 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef IMATERIALPROXYFACTORY_H +#define IMATERIALPROXYFACTORY_H +#pragma once + +#include "interface.h" + +#define IMATERIAL_PROXY_FACTOR_INTERFACE_VERSION "IMaterialProxyFactory001" + +class IMaterialProxy; + +abstract_class IMaterialProxyFactory +{ +public: + virtual IMaterialProxy *CreateProxy( const char *proxyName ) = 0; + virtual void DeleteProxy( IMaterialProxy *pProxy ) = 0; +}; + +#endif // IMATERIALPROXYFACTORY_H diff --git a/sp/src/public/materialsystem/imaterialsystem.h b/sp/src/public/materialsystem/imaterialsystem.h new file mode 100644 index 00000000..0aab3790 --- /dev/null +++ b/sp/src/public/materialsystem/imaterialsystem.h @@ -0,0 +1,1807 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef IMATERIALSYSTEM_H +#define IMATERIALSYSTEM_H + +#ifdef _WIN32 +#pragma once +#endif + +#define OVERBRIGHT 2.0f +#define OO_OVERBRIGHT ( 1.0f / 2.0f ) +#define GAMMA 2.2f +#define TEXGAMMA 2.2f + +#include "tier1/interface.h" +#include "tier1/refcount.h" +#include "mathlib/vector.h" +#include "mathlib/vector4d.h" +#include "mathlib/vmatrix.h" +#include "appframework/IAppSystem.h" +#include "bitmap/imageformat.h" +#include "texture_group_names.h" +#include "vtf/vtf.h" +#include "materialsystem/deformations.h" +#include "materialsystem/imaterialsystemhardwareconfig.h" +#include "materialsystem/IColorCorrection.h" +#include "tier0/icommandline.h" + + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- +class IMaterial; +class IMesh; +class IVertexBuffer; +class IIndexBuffer; +struct MaterialSystem_Config_t; +class VMatrix; +struct matrix3x4_t; +class ITexture; +struct MaterialSystemHardwareIdentifier_t; +class KeyValues; +class IShader; +class IVertexTexture; +class IMorph; +class IMatRenderContext; +class ICallQueue; +struct MorphWeight_t; +class IFileList; + + +//----------------------------------------------------------------------------- +// The vertex format type +//----------------------------------------------------------------------------- +typedef uint64 VertexFormat_t; + +//----------------------------------------------------------------------------- +// important enumeration +//----------------------------------------------------------------------------- + +// NOTE NOTE NOTE!!!! If you up this, grep for "NEW_INTERFACE" to see if there is anything +// waiting to be enabled during an interface revision. +#define MATERIAL_SYSTEM_INTERFACE_VERSION "VMaterialSystem080" + +#ifdef POSIX +#define ABSOLUTE_MINIMUM_DXLEVEL 90 +#else +#define ABSOLUTE_MINIMUM_DXLEVEL 80 +#endif + +enum ShaderParamType_t +{ + SHADER_PARAM_TYPE_TEXTURE, + SHADER_PARAM_TYPE_INTEGER, + SHADER_PARAM_TYPE_COLOR, + SHADER_PARAM_TYPE_VEC2, + SHADER_PARAM_TYPE_VEC3, + SHADER_PARAM_TYPE_VEC4, + SHADER_PARAM_TYPE_ENVMAP, // obsolete + SHADER_PARAM_TYPE_FLOAT, + SHADER_PARAM_TYPE_BOOL, + SHADER_PARAM_TYPE_FOURCC, + SHADER_PARAM_TYPE_MATRIX, + SHADER_PARAM_TYPE_MATERIAL, + SHADER_PARAM_TYPE_STRING, +}; + +enum MaterialMatrixMode_t +{ + MATERIAL_VIEW = 0, + MATERIAL_PROJECTION, + + // Texture matrices + MATERIAL_TEXTURE0, + MATERIAL_TEXTURE1, + MATERIAL_TEXTURE2, + MATERIAL_TEXTURE3, + MATERIAL_TEXTURE4, + MATERIAL_TEXTURE5, + MATERIAL_TEXTURE6, + MATERIAL_TEXTURE7, + + MATERIAL_MODEL, + + // Total number of matrices + NUM_MATRIX_MODES = MATERIAL_MODEL+1, + + // Number of texture transforms + NUM_TEXTURE_TRANSFORMS = MATERIAL_TEXTURE7 - MATERIAL_TEXTURE0 + 1 +}; + +// FIXME: How do I specify the actual number of matrix modes? +const int NUM_MODEL_TRANSFORMS = 53; +const int MATERIAL_MODEL_MAX = MATERIAL_MODEL + NUM_MODEL_TRANSFORMS; + +enum MaterialPrimitiveType_t +{ + MATERIAL_POINTS = 0x0, + MATERIAL_LINES, + MATERIAL_TRIANGLES, + MATERIAL_TRIANGLE_STRIP, + MATERIAL_LINE_STRIP, + MATERIAL_LINE_LOOP, // a single line loop + MATERIAL_POLYGON, // this is a *single* polygon + MATERIAL_QUADS, + MATERIAL_INSTANCED_QUADS, // (X360) like MATERIAL_QUADS, but uses vertex instancing + + // This is used for static meshes that contain multiple types of + // primitive types. When calling draw, you'll need to specify + // a primitive type. + MATERIAL_HETEROGENOUS +}; + +enum MaterialPropertyTypes_t +{ + MATERIAL_PROPERTY_NEEDS_LIGHTMAP = 0, // bool + MATERIAL_PROPERTY_OPACITY, // int (enum MaterialPropertyOpacityTypes_t) + MATERIAL_PROPERTY_REFLECTIVITY, // vec3_t + MATERIAL_PROPERTY_NEEDS_BUMPED_LIGHTMAPS // bool +}; + +// acceptable property values for MATERIAL_PROPERTY_OPACITY +enum MaterialPropertyOpacityTypes_t +{ + MATERIAL_ALPHATEST = 0, + MATERIAL_OPAQUE, + MATERIAL_TRANSLUCENT +}; + +enum MaterialBufferTypes_t +{ + MATERIAL_FRONT = 0, + MATERIAL_BACK +}; + +enum MaterialCullMode_t +{ + MATERIAL_CULLMODE_CCW, // this culls polygons with counterclockwise winding + MATERIAL_CULLMODE_CW // this culls polygons with clockwise winding +}; + +enum MaterialIndexFormat_t +{ + MATERIAL_INDEX_FORMAT_UNKNOWN = -1, + MATERIAL_INDEX_FORMAT_16BIT = 0, + MATERIAL_INDEX_FORMAT_32BIT, +}; + +enum MaterialFogMode_t +{ + MATERIAL_FOG_NONE, + MATERIAL_FOG_LINEAR, + MATERIAL_FOG_LINEAR_BELOW_FOG_Z, +}; + +enum MaterialHeightClipMode_t +{ + MATERIAL_HEIGHTCLIPMODE_DISABLE, + MATERIAL_HEIGHTCLIPMODE_RENDER_ABOVE_HEIGHT, + MATERIAL_HEIGHTCLIPMODE_RENDER_BELOW_HEIGHT +}; + +enum MaterialNonInteractiveMode_t +{ + MATERIAL_NON_INTERACTIVE_MODE_NONE = -1, + MATERIAL_NON_INTERACTIVE_MODE_STARTUP = 0, + MATERIAL_NON_INTERACTIVE_MODE_LEVEL_LOAD, + + MATERIAL_NON_INTERACTIVE_MODE_COUNT, +}; + + +//----------------------------------------------------------------------------- +// Special morph used in decalling pass +//----------------------------------------------------------------------------- +#define MATERIAL_MORPH_DECAL ( (IMorph*)1 ) + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +enum MaterialThreadMode_t +{ + MATERIAL_SINGLE_THREADED, + MATERIAL_QUEUED_SINGLE_THREADED, + MATERIAL_QUEUED_THREADED +}; + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +enum MaterialContextType_t +{ + MATERIAL_HARDWARE_CONTEXT, + MATERIAL_QUEUED_CONTEXT, + MATERIAL_NULL_CONTEXT +}; + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +enum MaterialFindContext_t +{ + MATERIAL_FINDCONTEXT_NONE, + MATERIAL_FINDCONTEXT_ISONAMODEL, +}; + +//----------------------------------------------------------------------------- +// Light structure +//----------------------------------------------------------------------------- +#include "mathlib/lightdesc.h" + +#if 0 +enum LightType_t +{ + MATERIAL_LIGHT_DISABLE = 0, + MATERIAL_LIGHT_POINT, + MATERIAL_LIGHT_DIRECTIONAL, + MATERIAL_LIGHT_SPOT, +}; + +enum LightType_OptimizationFlags_t +{ + LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION0 = 1, + LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION1 = 2, + LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION2 = 4, +}; + + +struct LightDesc_t +{ + LightType_t m_Type; + Vector m_Color; + Vector m_Position; + Vector m_Direction; + float m_Range; + float m_Falloff; + float m_Attenuation0; + float m_Attenuation1; + float m_Attenuation2; + float m_Theta; + float m_Phi; + // These aren't used by DX8. . used for software lighting. + float m_ThetaDot; + float m_PhiDot; + unsigned int m_Flags; + + + LightDesc_t() {} + +private: + // No copy constructors allowed + LightDesc_t(const LightDesc_t& vOther); +}; +#endif + +#define CREATERENDERTARGETFLAGS_HDR 0x00000001 +#define CREATERENDERTARGETFLAGS_AUTOMIPMAP 0x00000002 +#define CREATERENDERTARGETFLAGS_UNFILTERABLE_OK 0x00000004 +// XBOX ONLY: +#define CREATERENDERTARGETFLAGS_NOEDRAM 0x00000008 // inhibit allocation in 360 EDRAM +#define CREATERENDERTARGETFLAGS_TEMP 0x00000010 // only allocates memory upon first resolve, destroyed at level end + + +//----------------------------------------------------------------------------- +// allowed stencil operations. These match the d3d operations +//----------------------------------------------------------------------------- +enum StencilOperation_t +{ +#if !defined( _X360 ) + STENCILOPERATION_KEEP = 1, + STENCILOPERATION_ZERO = 2, + STENCILOPERATION_REPLACE = 3, + STENCILOPERATION_INCRSAT = 4, + STENCILOPERATION_DECRSAT = 5, + STENCILOPERATION_INVERT = 6, + STENCILOPERATION_INCR = 7, + STENCILOPERATION_DECR = 8, +#else + STENCILOPERATION_KEEP = D3DSTENCILOP_KEEP, + STENCILOPERATION_ZERO = D3DSTENCILOP_ZERO, + STENCILOPERATION_REPLACE = D3DSTENCILOP_REPLACE, + STENCILOPERATION_INCRSAT = D3DSTENCILOP_INCRSAT, + STENCILOPERATION_DECRSAT = D3DSTENCILOP_DECRSAT, + STENCILOPERATION_INVERT = D3DSTENCILOP_INVERT, + STENCILOPERATION_INCR = D3DSTENCILOP_INCR, + STENCILOPERATION_DECR = D3DSTENCILOP_DECR, +#endif + STENCILOPERATION_FORCE_DWORD = 0x7fffffff +}; + +enum StencilComparisonFunction_t +{ +#if !defined( _X360 ) + STENCILCOMPARISONFUNCTION_NEVER = 1, + STENCILCOMPARISONFUNCTION_LESS = 2, + STENCILCOMPARISONFUNCTION_EQUAL = 3, + STENCILCOMPARISONFUNCTION_LESSEQUAL = 4, + STENCILCOMPARISONFUNCTION_GREATER = 5, + STENCILCOMPARISONFUNCTION_NOTEQUAL = 6, + STENCILCOMPARISONFUNCTION_GREATEREQUAL = 7, + STENCILCOMPARISONFUNCTION_ALWAYS = 8, +#else + STENCILCOMPARISONFUNCTION_NEVER = D3DCMP_NEVER, + STENCILCOMPARISONFUNCTION_LESS = D3DCMP_LESS, + STENCILCOMPARISONFUNCTION_EQUAL = D3DCMP_EQUAL, + STENCILCOMPARISONFUNCTION_LESSEQUAL = D3DCMP_LESSEQUAL, + STENCILCOMPARISONFUNCTION_GREATER = D3DCMP_GREATER, + STENCILCOMPARISONFUNCTION_NOTEQUAL = D3DCMP_NOTEQUAL, + STENCILCOMPARISONFUNCTION_GREATEREQUAL = D3DCMP_GREATEREQUAL, + STENCILCOMPARISONFUNCTION_ALWAYS = D3DCMP_ALWAYS, +#endif + + STENCILCOMPARISONFUNCTION_FORCE_DWORD = 0x7fffffff +}; + + +//----------------------------------------------------------------------------- +// Enumeration for the various fields capable of being morphed +//----------------------------------------------------------------------------- +enum MorphFormatFlags_t +{ + MORPH_POSITION = 0x0001, // 3D + MORPH_NORMAL = 0x0002, // 3D + MORPH_WRINKLE = 0x0004, // 1D + MORPH_SPEED = 0x0008, // 1D + MORPH_SIDE = 0x0010, // 1D +}; + + +//----------------------------------------------------------------------------- +// The morph format type +//----------------------------------------------------------------------------- +typedef unsigned int MorphFormat_t; + + +//----------------------------------------------------------------------------- +// Standard lightmaps +//----------------------------------------------------------------------------- +enum StandardLightmap_t +{ + MATERIAL_SYSTEM_LIGHTMAP_PAGE_WHITE = -1, + MATERIAL_SYSTEM_LIGHTMAP_PAGE_WHITE_BUMP = -2, + MATERIAL_SYSTEM_LIGHTMAP_PAGE_USER_DEFINED = -3 +}; + + +struct MaterialSystem_SortInfo_t +{ + IMaterial *material; + int lightmapPageID; +}; + + +#define MAX_FB_TEXTURES 4 + +//----------------------------------------------------------------------------- +// Information about each adapter +//----------------------------------------------------------------------------- +enum +{ + MATERIAL_ADAPTER_NAME_LENGTH = 512 +}; + +struct MaterialAdapterInfo_t +{ + char m_pDriverName[MATERIAL_ADAPTER_NAME_LENGTH]; + unsigned int m_VendorID; + unsigned int m_DeviceID; + unsigned int m_SubSysID; + unsigned int m_Revision; + int m_nDXSupportLevel; // This is the *preferred* dx support level + int m_nMaxDXSupportLevel; + unsigned int m_nDriverVersionHigh; + unsigned int m_nDriverVersionLow; +}; + + +//----------------------------------------------------------------------------- +// Video mode info.. +//----------------------------------------------------------------------------- +struct MaterialVideoMode_t +{ + int m_Width; // if width and height are 0 and you select + int m_Height; // windowed mode, it'll use the window size + ImageFormat m_Format; // use ImageFormats (ignored for windowed mode) + int m_RefreshRate; // 0 == default (ignored for windowed mode) +}; +// fixme: should move this into something else. +struct FlashlightState_t +{ + FlashlightState_t() + { + m_bEnableShadows = false; // Provide reasonable defaults for shadow depth mapping parameters + m_bDrawShadowFrustum = false; +#ifdef ASW_PROJECTED_TEXTURES + m_flShadowMapResolution = 2048.0f; + m_flShadowFilterSize = 0.5f; + m_flShadowSlopeScaleDepthBias = 16.0f; + m_flShadowDepthBias = 0.0005f; +#elif defined(MAPBASE) + m_flShadowMapResolution = 2048; + m_flShadowFilterSize = 1.0f; + m_flShadowSlopeScaleDepthBias = 4.0f; + m_flShadowDepthBias = 0.00001f; +#else + m_flShadowMapResolution = 1024.0f; + m_flShadowFilterSize = 3.0f; + m_flShadowSlopeScaleDepthBias = 16.0f; + m_flShadowDepthBias = 0.0005f; +#endif + m_flShadowJitterSeed = 0.0f; + m_flShadowAtten = 0.0f; + m_bScissor = false; + m_nLeft = -1; + m_nTop = -1; + m_nRight = -1; + m_nBottom = -1; + m_nShadowQuality = 0; +#ifdef ASW_PROJECTED_TEXTURES + m_bOrtho = false; + m_fOrthoLeft = -1.0f; + m_fOrthoRight = 1.0f; + m_fOrthoTop = -1.0f; + m_fOrthoBottom = 1.0f; + + m_fBrightnessScale = 1.0f; + m_pSpotlightTexture = NULL; +#endif + } + + Vector m_vecLightOrigin; + Quaternion m_quatOrientation; + float m_NearZ; + float m_FarZ; + float m_fHorizontalFOVDegrees; + float m_fVerticalFOVDegrees; + float m_fQuadraticAtten; + float m_fLinearAtten; + float m_fConstantAtten; + float m_Color[4]; + ITexture *m_pSpotlightTexture; + int m_nSpotlightTextureFrame; + + // Shadow depth mapping parameters + bool m_bEnableShadows; + bool m_bDrawShadowFrustum; + float m_flShadowMapResolution; + float m_flShadowFilterSize; + float m_flShadowSlopeScaleDepthBias; + float m_flShadowDepthBias; + float m_flShadowJitterSeed; + float m_flShadowAtten; + int m_nShadowQuality; + +#ifdef ASW_PROJECTED_TEXTURES + bool m_bOrtho; + float m_fOrthoLeft; + float m_fOrthoRight; + float m_fOrthoTop; + float m_fOrthoBottom; + + float m_FarZAtten; + float m_fBrightnessScale; + bool m_bGlobalLight; +#endif + +#ifdef MAPBASE + bool m_bAlwaysDraw; +#endif + + // Getters for scissor members + bool DoScissor() { return m_bScissor; } + int GetLeft() { return m_nLeft; } + int GetTop() { return m_nTop; } + int GetRight() { return m_nRight; } + int GetBottom() { return m_nBottom; } + +private: + + friend class CShadowMgr; + + bool m_bScissor; + int m_nLeft; + int m_nTop; + int m_nRight; + int m_nBottom; +}; + +//----------------------------------------------------------------------------- +// Flags to be used with the Init call +//----------------------------------------------------------------------------- +enum MaterialInitFlags_t +{ + MATERIAL_INIT_ALLOCATE_FULLSCREEN_TEXTURE = 0x2, + MATERIAL_INIT_REFERENCE_RASTERIZER = 0x4, +}; + +//----------------------------------------------------------------------------- +// Flags to specify type of depth buffer used with RT +//----------------------------------------------------------------------------- + +// GR - this is to add RT with no depth buffer bound + +enum MaterialRenderTargetDepth_t +{ + MATERIAL_RT_DEPTH_SHARED = 0x0, + MATERIAL_RT_DEPTH_SEPARATE = 0x1, + MATERIAL_RT_DEPTH_NONE = 0x2, + MATERIAL_RT_DEPTH_ONLY = 0x3, +}; + +//----------------------------------------------------------------------------- +// A function to be called when we need to release all vertex buffers +// NOTE: The restore function will tell the caller if all the vertex formats +// changed so that it can flush caches, etc. if it needs to (for dxlevel support) +//----------------------------------------------------------------------------- +enum RestoreChangeFlags_t +{ + MATERIAL_RESTORE_VERTEX_FORMAT_CHANGED = 0x1, +}; + + +// NOTE: All size modes will force the render target to be smaller than or equal to +// the size of the framebuffer. +enum RenderTargetSizeMode_t +{ + RT_SIZE_NO_CHANGE=0, // Only allowed for render targets that don't want a depth buffer + // (because if they have a depth buffer, the render target must be less than or equal to the size of the framebuffer). + RT_SIZE_DEFAULT=1, // Don't play with the specified width and height other than making sure it fits in the framebuffer. + RT_SIZE_PICMIP=2, // Apply picmip to the render target's width and height. + RT_SIZE_HDR=3, // frame_buffer_width / 4 + RT_SIZE_FULL_FRAME_BUFFER=4, // Same size as frame buffer, or next lower power of 2 if we can't do that. + RT_SIZE_OFFSCREEN=5, // Target of specified size, don't mess with dimensions + RT_SIZE_FULL_FRAME_BUFFER_ROUNDED_UP=6, // Same size as the frame buffer, rounded up if necessary for systems that can't do non-power of two textures. + RT_SIZE_REPLAY_SCREENSHOT = 7, // Rounded down to power of 2, essentially... + RT_SIZE_LITERAL = 8 // Use the size passed in. Don't clamp it to the frame buffer size. Really. +}; + +typedef void (*MaterialBufferReleaseFunc_t)( ); +typedef void (*MaterialBufferRestoreFunc_t)( int nChangeFlags ); // see RestoreChangeFlags_t +typedef void (*ModeChangeCallbackFunc_t)( void ); + +typedef int VertexBufferHandle_t; +typedef unsigned short MaterialHandle_t; + +DECLARE_POINTER_HANDLE( OcclusionQueryObjectHandle_t ); +#define INVALID_OCCLUSION_QUERY_OBJECT_HANDLE ( (OcclusionQueryObjectHandle_t)0 ) + +class IMaterialProxyFactory; +class ITexture; +class IMaterialSystemHardwareConfig; +class CShadowMgr; + +DECLARE_POINTER_HANDLE( MaterialLock_t ); + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- + +abstract_class IMaterialSystem : public IAppSystem +{ +public: + + // Placeholder for API revision + virtual bool Connect( CreateInterfaceFn factory ) = 0; + virtual void Disconnect() = 0; + virtual void *QueryInterface( const char *pInterfaceName ) = 0; + virtual InitReturnVal_t Init() = 0; + virtual void Shutdown() = 0; + + //--------------------------------------------------------- + // Initialization and shutdown + //--------------------------------------------------------- + + // Call this to initialize the material system + // returns a method to create interfaces in the shader dll + virtual CreateInterfaceFn Init( char const* pShaderAPIDLL, + IMaterialProxyFactory *pMaterialProxyFactory, + CreateInterfaceFn fileSystemFactory, + CreateInterfaceFn cvarFactory=NULL ) = 0; + + // Call this to set an explicit shader version to use + // Must be called before Init(). + virtual void SetShaderAPI( char const *pShaderAPIDLL ) = 0; + + // Must be called before Init(), if you're going to call it at all... + virtual void SetAdapter( int nAdapter, int nFlags ) = 0; + + // Call this when the mod has been set up, which may occur after init + // At this point, the game + gamebin paths have been set up + virtual void ModInit() = 0; + virtual void ModShutdown() = 0; + + //--------------------------------------------------------- + // + //--------------------------------------------------------- + virtual void SetThreadMode( MaterialThreadMode_t mode, int nServiceThread = -1 ) = 0; + virtual MaterialThreadMode_t GetThreadMode( ) = 0; + virtual bool IsRenderThreadSafe( ) = 0; + virtual void ExecuteQueued() = 0; + + //--------------------------------------------------------- + // Config management + //--------------------------------------------------------- + + virtual IMaterialSystemHardwareConfig *GetHardwareConfig( const char *pVersion, int *returnCode ) = 0; + + + // Call this before rendering each frame with the current config + // for the material system. + // Will do whatever is necessary to get the material system into the correct state + // upon configuration change. .doesn't much else otherwise. + virtual bool UpdateConfig( bool bForceUpdate ) = 0; + + // Force this to be the config; update all material system convars to match the state + // return true if lightmaps need to be redownloaded + virtual bool OverrideConfig( const MaterialSystem_Config_t &config, bool bForceUpdate ) = 0; + + // Get the current config for this video card (as last set by UpdateConfig) + virtual const MaterialSystem_Config_t &GetCurrentConfigForVideoCard() const = 0; + + // Gets *recommended* configuration information associated with the display card, + // given a particular dx level to run under. + // Use dxlevel 0 to use the recommended dx level. + // The function returns false if an invalid dxlevel was specified + + // UNDONE: To find out all convars affected by configuration, we'll need to change + // the dxsupport.pl program to output all column headers into a single keyvalue block + // and then we would read that in, and send it back to the client + virtual bool GetRecommendedConfigurationInfo( int nDXLevel, KeyValues * pKeyValues ) = 0; + + + // ----------------------------------------------------------- + // Device methods + // ----------------------------------------------------------- + + // Gets the number of adapters... + virtual int GetDisplayAdapterCount() const = 0; + + // Returns the current adapter in use + virtual int GetCurrentAdapter() const = 0; + + // Returns info about each adapter + virtual void GetDisplayAdapterInfo( int adapter, MaterialAdapterInfo_t& info ) const = 0; + + // Returns the number of modes + virtual int GetModeCount( int adapter ) const = 0; + + // Returns mode information.. + virtual void GetModeInfo( int adapter, int mode, MaterialVideoMode_t& info ) const = 0; + + virtual void AddModeChangeCallBack( ModeChangeCallbackFunc_t func ) = 0; + + // Returns the mode info for the current display device + virtual void GetDisplayMode( MaterialVideoMode_t& mode ) const = 0; + + // Sets the mode... + virtual bool SetMode( void* hwnd, const MaterialSystem_Config_t &config ) = 0; + + virtual bool SupportsMSAAMode( int nMSAAMode ) = 0; + + // FIXME: REMOVE! Get video card identitier + virtual const MaterialSystemHardwareIdentifier_t &GetVideoCardIdentifier( void ) const = 0; + + // Use this to spew information about the 3D layer + virtual void SpewDriverInfo() const = 0; + + virtual void GetDXLevelDefaults(uint &max_dxlevel,uint &recommended_dxlevel) = 0; + + // Get the image format of the back buffer. . useful when creating render targets, etc. + virtual void GetBackBufferDimensions( int &width, int &height) const = 0; + virtual ImageFormat GetBackBufferFormat() const = 0; + + virtual bool SupportsHDRMode( HDRType_t nHDRModede ) = 0; + + + // ----------------------------------------------------------- + // Window methods + // ----------------------------------------------------------- + + // Creates/ destroys a child window + virtual bool AddView( void* hwnd ) = 0; + virtual void RemoveView( void* hwnd ) = 0; + + // Sets the view + virtual void SetView( void* hwnd ) = 0; + + + // ----------------------------------------------------------- + // Control flow + // ----------------------------------------------------------- + + virtual void BeginFrame( float frameTime ) = 0; + virtual void EndFrame( ) = 0; + virtual void Flush( bool flushHardware = false ) = 0; + + /// FIXME: This stuff needs to be cleaned up and abstracted. + // Stuff that gets exported to the launcher through the engine + virtual void SwapBuffers( ) = 0; + + // Flushes managed textures from the texture cacher + virtual void EvictManagedResources() = 0; + + virtual void ReleaseResources(void) = 0; + virtual void ReacquireResources(void ) = 0; + + + // ----------------------------------------------------------- + // Device loss/restore + // ----------------------------------------------------------- + + // Installs a function to be called when we need to release vertex buffers + textures + virtual void AddReleaseFunc( MaterialBufferReleaseFunc_t func ) = 0; + virtual void RemoveReleaseFunc( MaterialBufferReleaseFunc_t func ) = 0; + + // Installs a function to be called when we need to restore vertex buffers + virtual void AddRestoreFunc( MaterialBufferRestoreFunc_t func ) = 0; + virtual void RemoveRestoreFunc( MaterialBufferRestoreFunc_t func ) = 0; + + // Release temporary HW memory... + virtual void ResetTempHWMemory( bool bExitingLevel = false ) = 0; + + // For dealing with device lost in cases where SwapBuffers isn't called all the time (Hammer) + virtual void HandleDeviceLost() = 0; + + + // ----------------------------------------------------------- + // Shaders + // ----------------------------------------------------------- + + // Used to iterate over all shaders for editing purposes + // GetShaders returns the number of shaders it actually found + virtual int ShaderCount() const = 0; + virtual int GetShaders( int nFirstShader, int nMaxCount, IShader **ppShaderList ) const = 0; + + // FIXME: Is there a better way of doing this? + // Returns shader flag names for editors to be able to edit them + virtual int ShaderFlagCount() const = 0; + virtual const char * ShaderFlagName( int nIndex ) const = 0; + + // Gets the actual shader fallback for a particular shader + virtual void GetShaderFallback( const char *pShaderName, char *pFallbackShader, int nFallbackLength ) = 0; + + + // ----------------------------------------------------------- + // Material proxies + // ----------------------------------------------------------- + + virtual IMaterialProxyFactory *GetMaterialProxyFactory() = 0; + + // Sets the material proxy factory. Calling this causes all materials to be uncached. + virtual void SetMaterialProxyFactory( IMaterialProxyFactory* pFactory ) = 0; + + + // ----------------------------------------------------------- + // Editor mode + // ----------------------------------------------------------- + + // Used to enable editor materials. Must be called before Init. + virtual void EnableEditorMaterials() = 0; + + + // ----------------------------------------------------------- + // Stub mode mode + // ----------------------------------------------------------- + + // Force it to ignore Draw calls. + virtual void SetInStubMode( bool bInStubMode ) = 0; + + + //--------------------------------------------------------- + // Debug support + //--------------------------------------------------------- + + virtual void DebugPrintUsedMaterials( const char *pSearchSubString, bool bVerbose ) = 0; + virtual void DebugPrintUsedTextures( void ) = 0; + + virtual void ToggleSuppressMaterial( char const* pMaterialName ) = 0; + virtual void ToggleDebugMaterial( char const* pMaterialName ) = 0; + + + //--------------------------------------------------------- + // Misc features + //--------------------------------------------------------- + //returns whether fast clipping is being used or not - needed to be exposed for better per-object clip behavior + virtual bool UsingFastClipping( void ) = 0; + + virtual int StencilBufferBits( void ) = 0; //number of bits per pixel in the stencil buffer + + + //--------------------------------------------------------- + // Material and texture management + //--------------------------------------------------------- + + // uncache all materials. . good for forcing reload of materials. + virtual void UncacheAllMaterials( ) = 0; + + // Remove any materials from memory that aren't in use as determined + // by the IMaterial's reference count. + virtual void UncacheUnusedMaterials( bool bRecomputeStateSnapshots = false ) = 0; + + // Load any materials into memory that are to be used as determined + // by the IMaterial's reference count. + virtual void CacheUsedMaterials( ) = 0; + + // Force all textures to be reloaded from disk. + virtual void ReloadTextures( ) = 0; + + // Reloads materials + virtual void ReloadMaterials( const char *pSubString = NULL ) = 0; + + // Create a procedural material. The keyvalues looks like a VMT file + virtual IMaterial * CreateMaterial( const char *pMaterialName, KeyValues *pVMTKeyValues ) = 0; + + // Find a material by name. + // The name of a material is a full path to + // the vmt file starting from "hl2/materials" (or equivalent) without + // a file extension. + // eg. "dev/dev_bumptest" refers to somethign similar to: + // "d:/hl2/hl2/materials/dev/dev_bumptest.vmt" + // + // Most of the texture groups for pTextureGroupName are listed in texture_group_names.h. + // + // Note: if the material can't be found, this returns a checkerboard material. You can + // find out if you have that material by calling IMaterial::IsErrorMaterial(). + // (Or use the global IsErrorMaterial function, which checks if it's null too). + virtual IMaterial * FindMaterial( char const* pMaterialName, const char *pTextureGroupName, bool complain = true, const char *pComplainPrefix = NULL ) = 0; + + // Query whether a material is loaded (eg, whether FindMaterial will be nonblocking) + virtual bool IsMaterialLoaded( char const* pMaterialName ) = 0; + + //--------------------------------- + // This is the interface for knowing what materials are available + // is to use the following functions to get a list of materials. The + // material names will have the full path to the material, and that is the + // only way that the directory structure of the materials will be seen through this + // interface. + // NOTE: This is mostly for worldcraft to get a list of materials to put + // in the "texture" browser.in Worldcraft + virtual MaterialHandle_t FirstMaterial() const = 0; + + // returns InvalidMaterial if there isn't another material. + // WARNING: you must call GetNextMaterial until it returns NULL, + // otherwise there will be a memory leak. + virtual MaterialHandle_t NextMaterial( MaterialHandle_t h ) const = 0; + + // This is the invalid material + virtual MaterialHandle_t InvalidMaterial() const = 0; + + // Returns a particular material + virtual IMaterial* GetMaterial( MaterialHandle_t h ) const = 0; + + // Get the total number of materials in the system. These aren't just the used + // materials, but the complete collection. + virtual int GetNumMaterials( ) const = 0; + + //--------------------------------- + + virtual void SetAsyncTextureLoadCache( void* hFileCache ) = 0; + + virtual ITexture * FindTexture( char const* pTextureName, const char *pTextureGroupName, bool complain = true, int nAdditionalCreationFlags = 0 ) = 0; + + // Checks to see if a particular texture is loaded + virtual bool IsTextureLoaded( char const* pTextureName ) const = 0; + + // Creates a procedural texture + virtual ITexture * CreateProceduralTexture( const char *pTextureName, + const char *pTextureGroupName, + int w, + int h, + ImageFormat fmt, + int nFlags ) = 0; + + // + // Render targets + // + virtual void BeginRenderTargetAllocation() = 0; + virtual void EndRenderTargetAllocation() = 0; // Simulate an Alt-Tab in here, which causes a release/restore of all resources + + // Creates a render target + // If depth == true, a depth buffer is also allocated. If not, then + // the screen's depth buffer is used. + // Creates a texture for use as a render target + virtual ITexture * CreateRenderTargetTexture( int w, + int h, + RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). + ImageFormat format, + MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED ) = 0; + + virtual ITexture * CreateNamedRenderTargetTextureEx( const char *pRTName, // Pass in NULL here for an unnamed render target. + int w, + int h, + RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). + ImageFormat format, + MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, + unsigned int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, + unsigned int renderTargetFlags = 0 ) = 0; + + virtual ITexture * CreateNamedRenderTargetTexture( const char *pRTName, + int w, + int h, + RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). + ImageFormat format, + MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, + bool bClampTexCoords = true, + bool bAutoMipMap = false ) = 0; + + // Must be called between the above Begin-End calls! + virtual ITexture * CreateNamedRenderTargetTextureEx2( const char *pRTName, // Pass in NULL here for an unnamed render target. + int w, + int h, + RenderTargetSizeMode_t sizeMode, // Controls how size is generated (and regenerated on video mode change). + ImageFormat format, + MaterialRenderTargetDepth_t depth = MATERIAL_RT_DEPTH_SHARED, + unsigned int textureFlags = TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT, + unsigned int renderTargetFlags = 0 ) = 0; + + // ----------------------------------------------------------- + // Lightmaps + // ----------------------------------------------------------- + + // To allocate lightmaps, sort the whole world by material twice. + // The first time through, call AllocateLightmap for every surface. + // that has a lightmap. + // The second time through, call AllocateWhiteLightmap for every + // surface that expects to use shaders that expect lightmaps. + virtual void BeginLightmapAllocation( ) = 0; + virtual void EndLightmapAllocation( ) = 0; + + // returns the sorting id for this surface + virtual int AllocateLightmap( int width, int height, + int offsetIntoLightmapPage[2], + IMaterial *pMaterial ) = 0; + // returns the sorting id for this surface + virtual int AllocateWhiteLightmap( IMaterial *pMaterial ) = 0; + + // lightmaps are in linear color space + // lightmapPageID is returned by GetLightmapPageIDForSortID + // lightmapSize and offsetIntoLightmapPage are returned by AllocateLightmap. + // You should never call UpdateLightmap for a lightmap allocated through + // AllocateWhiteLightmap. + virtual void UpdateLightmap( int lightmapPageID, int lightmapSize[2], + int offsetIntoLightmapPage[2], + float *pFloatImage, float *pFloatImageBump1, + float *pFloatImageBump2, float *pFloatImageBump3 ) = 0; + + // fixme: could just be an array of ints for lightmapPageIDs since the material + // for a surface is already known. + virtual int GetNumSortIDs( ) = 0; + virtual void GetSortInfo( MaterialSystem_SortInfo_t *sortInfoArray ) = 0; + + // Read the page size of an existing lightmap by sort id (returned from AllocateLightmap()) + virtual void GetLightmapPageSize( int lightmap, int *width, int *height ) const = 0; + + virtual void ResetMaterialLightmapPageInfo() = 0; + + + + virtual void ClearBuffers( bool bClearColor, bool bClearDepth, bool bClearStencil = false ) = 0; + + // ----------------------------------------------------------- + // X360 specifics + // ----------------------------------------------------------- + +#if defined( _X360 ) + virtual void ListUsedMaterials( void ) = 0; + virtual HXUIFONT OpenTrueTypeFont( const char *pFontname, int tall, int style ) = 0; + virtual void CloseTrueTypeFont( HXUIFONT hFont ) = 0; + virtual bool GetTrueTypeFontMetrics( HXUIFONT hFont, XUIFontMetrics *pFontMetrics, XUICharMetrics charMetrics[256] ) = 0; + // Render a sequence of characters and extract the data into a buffer + // For each character, provide the width+height of the font texture subrect, + // an offset to apply when rendering the glyph, and an offset into a buffer to receive the RGBA data + virtual bool GetTrueTypeGlyphs( HXUIFONT hFont, int numChars, wchar_t *pWch, int *pOffsetX, int *pOffsetY, int *pWidth, int *pHeight, unsigned char *pRGBA, int *pRGBAOffset ) = 0; + virtual void PersistDisplay() = 0; + virtual void *GetD3DDevice() = 0; + virtual bool OwnGPUResources( bool bEnable ) = 0; +#endif + + // ----------------------------------------------------------- + // Access the render contexts + // ----------------------------------------------------------- + virtual IMatRenderContext * GetRenderContext() = 0; + + virtual bool SupportsShadowDepthTextures( void ) = 0; + virtual void BeginUpdateLightmaps( void ) = 0; + virtual void EndUpdateLightmaps( void ) = 0; + + // ----------------------------------------------------------- + // Methods to force the material system into non-threaded, non-queued mode + // ----------------------------------------------------------- + virtual MaterialLock_t Lock() = 0; + virtual void Unlock( MaterialLock_t ) = 0; + + // Vendor-dependent shadow depth texture format + virtual ImageFormat GetShadowDepthTextureFormat() = 0; + + virtual bool SupportsFetch4( void ) = 0; + + // Create a custom render context. Cannot be used to create MATERIAL_HARDWARE_CONTEXT + virtual IMatRenderContext *CreateRenderContext( MaterialContextType_t type ) = 0; + + // Set a specified render context to be the global context for the thread. Returns the prior context. + virtual IMatRenderContext *SetRenderContext( IMatRenderContext * ) = 0; + + virtual bool SupportsCSAAMode( int nNumSamples, int nQualityLevel ) = 0; + + virtual void RemoveModeChangeCallBack( ModeChangeCallbackFunc_t func ) = 0; + + // Finds or create a procedural material. + virtual IMaterial * FindProceduralMaterial( const char *pMaterialName, const char *pTextureGroupName, KeyValues *pVMTKeyValues ) = 0; + + virtual ImageFormat GetNullTextureFormat() = 0; + + virtual void AddTextureAlias( const char *pAlias, const char *pRealName ) = 0; + virtual void RemoveTextureAlias( const char *pAlias ) = 0; + + // returns a lightmap page ID for this allocation, -1 if none available + // frameID is a number that should be changed every frame to prevent locking any textures that are + // being used to draw in the previous frame + virtual int AllocateDynamicLightmap( int lightmapSize[2], int *pOutOffsetIntoPage, int frameID ) = 0; + + virtual void SetExcludedTextures( const char *pScriptName ) = 0; + virtual void UpdateExcludedTextures( void ) = 0; + + virtual bool IsInFrame( ) const = 0; + + virtual void CompactMemory() = 0; + + // For sv_pure mode. The filesystem figures out which files the client needs to reload to be "pure" ala the server's preferences. + virtual void ReloadFilesInList( IFileList *pFilesToReload ) = 0; + virtual bool AllowThreading( bool bAllow, int nServiceThread ) = 0; + + // Extended version of FindMaterial(). + // Contains context in so it can make decisions (i.e. if it's a model, ignore certain cheat parameters) + virtual IMaterial * FindMaterialEx( char const* pMaterialName, const char *pTextureGroupName, int nContext, bool complain = true, const char *pComplainPrefix = NULL ) = 0; + +#ifdef DX_TO_GL_ABSTRACTION + virtual void DoStartupShaderPreloading( void ) = 0; +#endif + + // Sets the override sizes for all render target size tests. These replace the frame buffer size. + // Set them when you are rendering primarily to something larger than the frame buffer (as in VR mode). + virtual void SetRenderTargetFrameBufferSizeOverrides( int nWidth, int nHeight ) = 0; + + // Returns the (possibly overridden) framebuffer size for render target sizing. + virtual void GetRenderTargetFrameBufferDimensions( int & nWidth, int & nHeight ) = 0; + + // returns the display device name that matches the adapter index we were started with + virtual char *GetDisplayDeviceName() const = 0; +}; + + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +abstract_class IMatRenderContext : public IRefCounted +{ +public: + virtual void BeginRender() = 0; + virtual void EndRender() = 0; + + virtual void Flush( bool flushHardware = false ) = 0; + + virtual void BindLocalCubemap( ITexture *pTexture ) = 0; + + // pass in an ITexture (that is build with "rendertarget" "1") or + // pass in NULL for the regular backbuffer. + virtual void SetRenderTarget( ITexture *pTexture ) = 0; + virtual ITexture * GetRenderTarget( void ) = 0; + + virtual void GetRenderTargetDimensions( int &width, int &height) const = 0; + + // Bind a material is current for rendering. + virtual void Bind( IMaterial *material, void *proxyData = 0 ) = 0; + // Bind a lightmap page current for rendering. You only have to + // do this for materials that require lightmaps. + virtual void BindLightmapPage( int lightmapPageID ) = 0; + + // inputs are between 0 and 1 + virtual void DepthRange( float zNear, float zFar ) = 0; + + virtual void ClearBuffers( bool bClearColor, bool bClearDepth, bool bClearStencil = false ) = 0; + + // read to a unsigned char rgb image. + virtual void ReadPixels( int x, int y, int width, int height, unsigned char *data, ImageFormat dstFormat ) = 0; + + // Sets lighting + virtual void SetAmbientLight( float r, float g, float b ) = 0; + virtual void SetLight( int lightNum, const LightDesc_t& desc ) = 0; + + // The faces of the cube are specified in the same order as cubemap textures + virtual void SetAmbientLightCube( Vector4D cube[6] ) = 0; + + // Blit the backbuffer to the framebuffer texture + virtual void CopyRenderTargetToTexture( ITexture *pTexture ) = 0; + + // Set the current texture that is a copy of the framebuffer. + virtual void SetFrameBufferCopyTexture( ITexture *pTexture, int textureIndex = 0 ) = 0; + virtual ITexture *GetFrameBufferCopyTexture( int textureIndex ) = 0; + + // + // end vertex array api + // + + // matrix api + virtual void MatrixMode( MaterialMatrixMode_t matrixMode ) = 0; + virtual void PushMatrix( void ) = 0; + virtual void PopMatrix( void ) = 0; + virtual void LoadMatrix( VMatrix const& matrix ) = 0; + virtual void LoadMatrix( matrix3x4_t const& matrix ) = 0; + virtual void MultMatrix( VMatrix const& matrix ) = 0; + virtual void MultMatrix( matrix3x4_t const& matrix ) = 0; + virtual void MultMatrixLocal( VMatrix const& matrix ) = 0; + virtual void MultMatrixLocal( matrix3x4_t const& matrix ) = 0; + virtual void GetMatrix( MaterialMatrixMode_t matrixMode, VMatrix *matrix ) = 0; + virtual void GetMatrix( MaterialMatrixMode_t matrixMode, matrix3x4_t *matrix ) = 0; + virtual void LoadIdentity( void ) = 0; + virtual void Ortho( double left, double top, double right, double bottom, double zNear, double zFar ) = 0; + virtual void PerspectiveX( double fovx, double aspect, double zNear, double zFar ) = 0; + virtual void PickMatrix( int x, int y, int width, int height ) = 0; + virtual void Rotate( float angle, float x, float y, float z ) = 0; + virtual void Translate( float x, float y, float z ) = 0; + virtual void Scale( float x, float y, float z ) = 0; + // end matrix api + + // Sets/gets the viewport + virtual void Viewport( int x, int y, int width, int height ) = 0; + virtual void GetViewport( int& x, int& y, int& width, int& height ) const = 0; + + // The cull mode + virtual void CullMode( MaterialCullMode_t cullMode ) = 0; + + // end matrix api + + // This could easily be extended to a general user clip plane + virtual void SetHeightClipMode( MaterialHeightClipMode_t nHeightClipMode ) = 0; + // garymcthack : fog z is always used for heightclipz for now. + virtual void SetHeightClipZ( float z ) = 0; + + // Fog methods... + virtual void FogMode( MaterialFogMode_t fogMode ) = 0; + virtual void FogStart( float fStart ) = 0; + virtual void FogEnd( float fEnd ) = 0; + virtual void SetFogZ( float fogZ ) = 0; + virtual MaterialFogMode_t GetFogMode( void ) = 0; + + virtual void FogColor3f( float r, float g, float b ) = 0; + virtual void FogColor3fv( float const* rgb ) = 0; + virtual void FogColor3ub( unsigned char r, unsigned char g, unsigned char b ) = 0; + virtual void FogColor3ubv( unsigned char const* rgb ) = 0; + + virtual void GetFogColor( unsigned char *rgb ) = 0; + + // Sets the number of bones for skinning + virtual void SetNumBoneWeights( int numBones ) = 0; + + // Creates/destroys Mesh + virtual IMesh* CreateStaticMesh( VertexFormat_t fmt, const char *pTextureBudgetGroup, IMaterial * pMaterial = NULL ) = 0; + virtual void DestroyStaticMesh( IMesh* mesh ) = 0; + + // Gets the dynamic mesh associated with the currently bound material + // note that you've got to render the mesh before calling this function + // a second time. Clients should *not* call DestroyStaticMesh on the mesh + // returned by this call. + // Use buffered = false if you want to not have the mesh be buffered, + // but use it instead in the following pattern: + // meshBuilder.Begin + // meshBuilder.End + // Draw partial + // Draw partial + // Draw partial + // meshBuilder.Begin + // meshBuilder.End + // etc + // Use Vertex or Index Override to supply a static vertex or index buffer + // to use in place of the dynamic buffers. + // + // If you pass in a material in pAutoBind, it will automatically bind the + // material. This can be helpful since you must bind the material you're + // going to use BEFORE calling GetDynamicMesh. + virtual IMesh* GetDynamicMesh( + bool buffered = true, + IMesh* pVertexOverride = 0, + IMesh* pIndexOverride = 0, + IMaterial *pAutoBind = 0 ) = 0; + + // ------------ New Vertex/Index Buffer interface ---------------------------- + // Do we need support for bForceTempMesh and bSoftwareVertexShader? + // I don't think we use bSoftwareVertexShader anymore. .need to look into bForceTempMesh. + virtual IVertexBuffer *CreateStaticVertexBuffer( VertexFormat_t fmt, int nVertexCount, const char *pTextureBudgetGroup ) = 0; + virtual IIndexBuffer *CreateStaticIndexBuffer( MaterialIndexFormat_t fmt, int nIndexCount, const char *pTextureBudgetGroup ) = 0; + virtual void DestroyVertexBuffer( IVertexBuffer * ) = 0; + virtual void DestroyIndexBuffer( IIndexBuffer * ) = 0; + // Do we need to specify the stream here in the case of locking multiple dynamic VBs on different streams? + virtual IVertexBuffer *GetDynamicVertexBuffer( int streamID, VertexFormat_t vertexFormat, bool bBuffered = true ) = 0; + virtual IIndexBuffer *GetDynamicIndexBuffer( MaterialIndexFormat_t fmt, bool bBuffered = true ) = 0; + virtual void BindVertexBuffer( int streamID, IVertexBuffer *pVertexBuffer, int nOffsetInBytes, int nFirstVertex, int nVertexCount, VertexFormat_t fmt, int nRepetitions = 1 ) = 0; + virtual void BindIndexBuffer( IIndexBuffer *pIndexBuffer, int nOffsetInBytes ) = 0; + virtual void Draw( MaterialPrimitiveType_t primitiveType, int firstIndex, int numIndices ) = 0; + // ------------ End ---------------------------- + + // Selection mode methods + virtual int SelectionMode( bool selectionMode ) = 0; + virtual void SelectionBuffer( unsigned int* pBuffer, int size ) = 0; + virtual void ClearSelectionNames( ) = 0; + virtual void LoadSelectionName( int name ) = 0; + virtual void PushSelectionName( int name ) = 0; + virtual void PopSelectionName() = 0; + + // Sets the Clear Color for ClearBuffer.... + virtual void ClearColor3ub( unsigned char r, unsigned char g, unsigned char b ) = 0; + virtual void ClearColor4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) = 0; + + // Allows us to override the depth buffer setting of a material + virtual void OverrideDepthEnable( bool bEnable, bool bDepthEnable ) = 0; + + // FIXME: This is a hack required for NVidia/XBox, can they fix in drivers? + virtual void DrawScreenSpaceQuad( IMaterial* pMaterial ) = 0; + + // For debugging and building recording files. This will stuff a token into the recording file, + // then someone doing a playback can watch for the token. + virtual void SyncToken( const char *pToken ) = 0; + + // FIXME: REMOVE THIS FUNCTION! + // The only reason why it's not gone is because we're a week from ship when I found the bug in it + // and everything's tuned to use it. + // It's returning values which are 2x too big (it's returning sphere diameter x2) + // Use ComputePixelDiameterOfSphere below in all new code instead. + virtual float ComputePixelWidthOfSphere( const Vector& origin, float flRadius ) = 0; + + // + // Occlusion query support + // + + // Allocate and delete query objects. + virtual OcclusionQueryObjectHandle_t CreateOcclusionQueryObject( void ) = 0; + virtual void DestroyOcclusionQueryObject( OcclusionQueryObjectHandle_t ) = 0; + + // Bracket drawing with begin and end so that we can get counts next frame. + virtual void BeginOcclusionQueryDrawing( OcclusionQueryObjectHandle_t ) = 0; + virtual void EndOcclusionQueryDrawing( OcclusionQueryObjectHandle_t ) = 0; + + // Get the number of pixels rendered between begin and end on an earlier frame. + // Calling this in the same frame is a huge perf hit! + virtual int OcclusionQuery_GetNumPixelsRendered( OcclusionQueryObjectHandle_t ) = 0; + + virtual void SetFlashlightMode( bool bEnable ) = 0; + + virtual void SetFlashlightState( const FlashlightState_t &state, const VMatrix &worldToTexture ) = 0; + + // Gets the current height clip mode + virtual MaterialHeightClipMode_t GetHeightClipMode( ) = 0; + + // This returns the diameter of the sphere in pixels based on + // the current model, view, + projection matrices and viewport. + virtual float ComputePixelDiameterOfSphere( const Vector& vecAbsOrigin, float flRadius ) = 0; + + // By default, the material system applies the VIEW and PROJECTION matrices to the user clip + // planes (which are specified in world space) to generate projection-space user clip planes + // Occasionally (for the particle system in hl2, for example), we want to override that + // behavior and explictly specify a ViewProj transform for user clip planes + virtual void EnableUserClipTransformOverride( bool bEnable ) = 0; + virtual void UserClipTransform( const VMatrix &worldToView ) = 0; + + virtual bool GetFlashlightMode() const = 0; + + // Used to make the handle think it's never had a successful query before + virtual void ResetOcclusionQueryObject( OcclusionQueryObjectHandle_t ) = 0; + + // FIXME: Remove + virtual void Unused3() {} + + // Creates/destroys morph data associated w/ a particular material + virtual IMorph *CreateMorph( MorphFormat_t format, const char *pDebugName ) = 0; + virtual void DestroyMorph( IMorph *pMorph ) = 0; + + // Binds the morph data for use in rendering + virtual void BindMorph( IMorph *pMorph ) = 0; + + // Sets flexweights for rendering + virtual void SetFlexWeights( int nFirstWeight, int nCount, const MorphWeight_t* pWeights ) = 0; + + // FIXME: Remove + virtual void Unused4() {}; + virtual void Unused5() {}; + virtual void Unused6() {}; + virtual void Unused7() {}; + virtual void Unused8() {}; + + // Read w/ stretch to a host-memory buffer + virtual void ReadPixelsAndStretch( Rect_t *pSrcRect, Rect_t *pDstRect, unsigned char *pBuffer, ImageFormat dstFormat, int nDstStride ) = 0; + + // Gets the window size + virtual void GetWindowSize( int &width, int &height ) const = 0; + + // This function performs a texture map from one texture map to the render destination, doing + // all the necessary pixel/texel coordinate fix ups. fractional values can be used for the + // src_texture coordinates to get linear sampling - integer values should produce 1:1 mappings + // for non-scaled operations. + virtual void DrawScreenSpaceRectangle( + IMaterial *pMaterial, + int destx, int desty, + int width, int height, + float src_texture_x0, float src_texture_y0, // which texel you want to appear at + // destx/y + float src_texture_x1, float src_texture_y1, // which texel you want to appear at + // destx+width-1, desty+height-1 + int src_texture_width, int src_texture_height, // needed for fixup + void *pClientRenderable = NULL, + int nXDice = 1, + int nYDice = 1 )=0; + + virtual void LoadBoneMatrix( int boneIndex, const matrix3x4_t& matrix ) = 0; + + // This version will push the current rendertarget + current viewport onto the stack + virtual void PushRenderTargetAndViewport( ) = 0; + + // This version will push a new rendertarget + a maximal viewport for that rendertarget onto the stack + virtual void PushRenderTargetAndViewport( ITexture *pTexture ) = 0; + + // This version will push a new rendertarget + a specified viewport onto the stack + virtual void PushRenderTargetAndViewport( ITexture *pTexture, int nViewX, int nViewY, int nViewW, int nViewH ) = 0; + + // This version will push a new rendertarget + a specified viewport onto the stack + virtual void PushRenderTargetAndViewport( ITexture *pTexture, ITexture *pDepthTexture, int nViewX, int nViewY, int nViewW, int nViewH ) = 0; + + // This will pop a rendertarget + viewport + virtual void PopRenderTargetAndViewport( void ) = 0; + + // Binds a particular texture as the current lightmap + virtual void BindLightmapTexture( ITexture *pLightmapTexture ) = 0; + + // Blit a subrect of the current render target to another texture + virtual void CopyRenderTargetToTextureEx( ITexture *pTexture, int nRenderTargetID, Rect_t *pSrcRect, Rect_t *pDstRect = NULL ) = 0; + virtual void CopyTextureToRenderTargetEx( int nRenderTargetID, ITexture *pTexture, Rect_t *pSrcRect, Rect_t *pDstRect = NULL ) = 0; + + // Special off-center perspective matrix for DoF, MSAA jitter and poster rendering + virtual void PerspectiveOffCenterX( double fovx, double aspect, double zNear, double zFar, double bottom, double top, double left, double right ) = 0; + + // Rendering parameters control special drawing modes withing the material system, shader + // system, shaders, and engine. renderparm.h has their definitions. + virtual void SetFloatRenderingParameter(int parm_number, float value) = 0; + virtual void SetIntRenderingParameter(int parm_number, int value) = 0; + virtual void SetVectorRenderingParameter(int parm_number, Vector const &value) = 0; + + // stencil buffer operations. + virtual void SetStencilEnable(bool onoff) = 0; + virtual void SetStencilFailOperation(StencilOperation_t op) = 0; + virtual void SetStencilZFailOperation(StencilOperation_t op) = 0; + virtual void SetStencilPassOperation(StencilOperation_t op) = 0; + virtual void SetStencilCompareFunction(StencilComparisonFunction_t cmpfn) = 0; + virtual void SetStencilReferenceValue(int ref) = 0; + virtual void SetStencilTestMask(uint32 msk) = 0; + virtual void SetStencilWriteMask(uint32 msk) = 0; + virtual void ClearStencilBufferRectangle(int xmin, int ymin, int xmax, int ymax,int value) =0; + + virtual void SetRenderTargetEx( int nRenderTargetID, ITexture *pTexture ) = 0; + + // rendering clip planes, beware that only the most recently pushed plane will actually be used in a sizeable chunk of hardware configurations + // and that changes to the clip planes mid-frame while UsingFastClipping() is true will result unresolvable depth inconsistencies + virtual void PushCustomClipPlane( const float *pPlane ) = 0; + virtual void PopCustomClipPlane( void ) = 0; + + // Returns the number of vertices + indices we can render using the dynamic mesh + // Passing true in the second parameter will return the max # of vertices + indices + // we can use before a flush is provoked and may return different values + // if called multiple times in succession. + // Passing false into the second parameter will return + // the maximum possible vertices + indices that can be rendered in a single batch + virtual void GetMaxToRender( IMesh *pMesh, bool bMaxUntilFlush, int *pMaxVerts, int *pMaxIndices ) = 0; + + // Returns the max possible vertices + indices to render in a single draw call + virtual int GetMaxVerticesToRender( IMaterial *pMaterial ) = 0; + virtual int GetMaxIndicesToRender( ) = 0; + virtual void DisableAllLocalLights() = 0; + virtual int CompareMaterialCombos( IMaterial *pMaterial1, IMaterial *pMaterial2, int lightMapID1, int lightMapID2 ) = 0; + + virtual IMesh *GetFlexMesh() = 0; + + virtual void SetFlashlightStateEx( const FlashlightState_t &state, const VMatrix &worldToTexture, ITexture *pFlashlightDepthTexture ) = 0; + + // Returns the currently bound local cubemap + virtual ITexture *GetLocalCubemap( ) = 0; + + // This is a version of clear buffers which will only clear the buffer at pixels which pass the stencil test + virtual void ClearBuffersObeyStencil( bool bClearColor, bool bClearDepth ) = 0; + + //enables/disables all entered clipping planes, returns the input from the last time it was called. + virtual bool EnableClipping( bool bEnable ) = 0; + + //get fog distances entered with FogStart(), FogEnd(), and SetFogZ() + virtual void GetFogDistances( float *fStart, float *fEnd, float *fFogZ ) = 0; + + // Hooks for firing PIX events from outside the Material System... + virtual void BeginPIXEvent( unsigned long color, const char *szName ) = 0; + virtual void EndPIXEvent() = 0; + virtual void SetPIXMarker( unsigned long color, const char *szName ) = 0; + + // Batch API + // from changelist 166623: + // - replaced obtuse material system batch usage with an explicit and easier to thread API + virtual void BeginBatch( IMesh* pIndices ) = 0; + virtual void BindBatch( IMesh* pVertices, IMaterial *pAutoBind = NULL ) = 0; + virtual void DrawBatch(int firstIndex, int numIndices ) = 0; + virtual void EndBatch() = 0; + + // Raw access to the call queue, which can be NULL if not in a queued mode + virtual ICallQueue *GetCallQueue() = 0; + + // Returns the world-space camera position + virtual void GetWorldSpaceCameraPosition( Vector *pCameraPos ) = 0; + virtual void GetWorldSpaceCameraVectors( Vector *pVecForward, Vector *pVecRight, Vector *pVecUp ) = 0; + + // Tone mapping + virtual void ResetToneMappingScale( float monoscale) = 0; // set scale to monoscale instantly with no chasing + virtual void SetGoalToneMappingScale( float monoscale) = 0; // set scale to monoscale instantly with no chasing + + // call TurnOnToneMapping before drawing the 3d scene to get the proper interpolated brightness + // value set. + virtual void TurnOnToneMapping() = 0; + + // Set a linear vector color scale for all 3D rendering. + // A value of [1.0f, 1.0f, 1.0f] should match non-tone-mapped rendering. + virtual void SetToneMappingScaleLinear( const Vector &scale ) = 0; + + virtual Vector GetToneMappingScaleLinear( void ) = 0; + virtual void SetShadowDepthBiasFactors( float fSlopeScaleDepthBias, float fDepthBias ) = 0; + + // Apply stencil operations to every pixel on the screen without disturbing depth or color buffers + virtual void PerformFullScreenStencilOperation( void ) = 0; + + // Sets lighting origin for the current model (needed to convert directional lights to points) + virtual void SetLightingOrigin( Vector vLightingOrigin ) = 0; + + // Set scissor rect for rendering + virtual void SetScissorRect( const int nLeft, const int nTop, const int nRight, const int nBottom, const bool bEnableScissor ) = 0; + + // Methods used to build the morph accumulator that is read from when HW morph E* LockRenderDataTyped( int nCount, const E* pSrcData = NULL ); + + // Temp render data gets immediately freed after it's all unlocked in single core. + // This prevents it from being freed + virtual void AddRefRenderData() = 0; + virtual void ReleaseRenderData() = 0; + + // Returns whether a pointer is render data. NOTE: passing NULL returns true + virtual bool IsRenderData( const void *pData ) const = 0; + virtual void PrintfVA( char *fmt, va_list vargs ) = 0; + virtual void Printf( PRINTF_FORMAT_STRING const char *fmt, ... ) = 0; + virtual float Knob( char *knobname, float *setvalue = NULL ) = 0; + // Allows us to override the alpha write setting of a material + virtual void OverrideAlphaWriteEnable( bool bEnable, bool bAlphaWriteEnable ) = 0; + virtual void OverrideColorWriteEnable( bool bOverrideEnable, bool bColorWriteEnable ) = 0; + + virtual void ClearBuffersObeyStencilEx( bool bClearColor, bool bClearAlpha, bool bClearDepth ) = 0; +}; + +template< class E > inline E* IMatRenderContext::LockRenderDataTyped( int nCount, const E* pSrcData ) +{ + int nSizeInBytes = nCount * sizeof(E); + E *pDstData = (E*)LockRenderData( nSizeInBytes ); + if ( pSrcData && pDstData ) + { + memcpy( pDstData, pSrcData, nSizeInBytes ); + } + return pDstData; +} + + +//----------------------------------------------------------------------------- +// Utility class for addreffing/releasing render data (prevents freeing on single core) +//----------------------------------------------------------------------------- +class CMatRenderDataReference +{ +public: + CMatRenderDataReference(); + CMatRenderDataReference( IMatRenderContext* pRenderContext ); + ~CMatRenderDataReference(); + void Lock( IMatRenderContext *pRenderContext ); + void Release(); + +private: + IMatRenderContext *m_pRenderContext; +}; + + +inline CMatRenderDataReference::CMatRenderDataReference() +{ + m_pRenderContext = NULL; +} + +inline CMatRenderDataReference::CMatRenderDataReference( IMatRenderContext* pRenderContext ) +{ + m_pRenderContext = NULL; + Lock( pRenderContext ); +} + +inline CMatRenderDataReference::~CMatRenderDataReference() +{ + Release(); +} + +inline void CMatRenderDataReference::Lock( IMatRenderContext* pRenderContext ) +{ + if ( !m_pRenderContext ) + { + m_pRenderContext = pRenderContext; + m_pRenderContext->AddRefRenderData( ); + } +} + +inline void CMatRenderDataReference::Release() +{ + if ( m_pRenderContext ) + { + m_pRenderContext->ReleaseRenderData( ); + m_pRenderContext = NULL; + } +} + + +//----------------------------------------------------------------------------- +// Utility class for locking/unlocking render data +//----------------------------------------------------------------------------- +template< typename E > +class CMatRenderData +{ +public: + CMatRenderData( IMatRenderContext* pRenderContext ); + CMatRenderData( IMatRenderContext* pRenderContext, int nCount, const E *pSrcData = NULL ); + ~CMatRenderData(); + E* Lock( int nCount, const E* pSrcData = NULL ); + void Release(); + bool IsValid() const; + const E* Base() const; + E* Base(); + const E& operator[]( int i ) const; + E& operator[]( int i ); + +private: + IMatRenderContext* m_pRenderContext; + E *m_pRenderData; + int m_nCount; + bool m_bNeedsUnlock; +}; + +template< typename E > +inline CMatRenderData::CMatRenderData( IMatRenderContext* pRenderContext ) +{ + m_pRenderContext = pRenderContext; + m_nCount = 0; + m_pRenderData = 0; + m_bNeedsUnlock = false; +} + +template< typename E > +inline CMatRenderData::CMatRenderData( IMatRenderContext* pRenderContext, int nCount, const E* pSrcData ) +{ + m_pRenderContext = pRenderContext; + m_nCount = 0; + m_pRenderData = 0; + m_bNeedsUnlock = false; + Lock( nCount, pSrcData ); +} + +template< typename E > +inline CMatRenderData::~CMatRenderData() +{ + Release(); +} + +template< typename E > +inline bool CMatRenderData::IsValid() const +{ + return m_pRenderData != NULL; +} + +template< typename E > +inline E* CMatRenderData::Lock( int nCount, const E* pSrcData ) +{ + m_nCount = nCount; + if ( pSrcData && m_pRenderContext->IsRenderData( pSrcData ) ) + { + // Yes, we're const-casting away, but that should be ok since + // the src data is render data + m_pRenderData = const_cast( pSrcData ); + m_pRenderContext->AddRefRenderData(); + m_bNeedsUnlock = false; + return m_pRenderData; + } + m_pRenderData = m_pRenderContext->LockRenderDataTyped( nCount, pSrcData ); + m_bNeedsUnlock = true; + return m_pRenderData; +} + +template< typename E > +inline void CMatRenderData::Release() +{ + if ( m_pRenderContext && m_pRenderData ) + { + if ( m_bNeedsUnlock ) + { + m_pRenderContext->UnlockRenderData( m_pRenderData ); + } + else + { + m_pRenderContext->ReleaseRenderData(); + } + } + m_pRenderData = NULL; + m_nCount = 0; + m_bNeedsUnlock = false; +} + +template< typename E > +inline E* CMatRenderData::Base() +{ + return m_pRenderData; +} + +template< typename E > +inline const E* CMatRenderData::Base() const +{ + return m_pRenderData; +} + +template< typename E > +inline E& CMatRenderData::operator[]( int i ) +{ + Assert( ( i >= 0 ) && ( i < m_nCount ) ); + return m_pRenderData[i]; +} + +template< typename E > +inline const E& CMatRenderData::operator[]( int i ) const +{ + Assert( ( i >= 0 ) && ( i < m_nCount ) ); + return m_pRenderData[i]; +} + + +//----------------------------------------------------------------------------- + +class CMatRenderContextPtr : public CRefPtr +{ + typedef CRefPtr BaseClass; +public: + CMatRenderContextPtr() {} + CMatRenderContextPtr( IMatRenderContext *pInit ) : BaseClass( pInit ) { if ( BaseClass::m_pObject ) BaseClass::m_pObject->BeginRender(); } + CMatRenderContextPtr( IMaterialSystem *pFrom ) : BaseClass( pFrom->GetRenderContext() ) { if ( BaseClass::m_pObject ) BaseClass::m_pObject->BeginRender(); } + ~CMatRenderContextPtr() { if ( BaseClass::m_pObject ) BaseClass::m_pObject->EndRender(); } + + IMatRenderContext *operator=( IMatRenderContext *p ) { if ( p ) p->BeginRender(); return BaseClass::operator=( p ); } + + void SafeRelease() { if ( BaseClass::m_pObject ) BaseClass::m_pObject->EndRender(); BaseClass::SafeRelease(); } + void AssignAddRef( IMatRenderContext *pFrom ) { if ( BaseClass::m_pObject ) BaseClass::m_pObject->EndRender(); BaseClass::AssignAddRef( pFrom ); BaseClass::m_pObject->BeginRender(); } + + void GetFrom( IMaterialSystem *pFrom ) { AssignAddRef( pFrom->GetRenderContext() ); } + + +private: + CMatRenderContextPtr( const CMatRenderContextPtr &from ); + void operator=( const CMatRenderContextPtr &from ); + +}; + +//----------------------------------------------------------------------------- +// Helper class for begin/end of pix event via constructor/destructor +//----------------------------------------------------------------------------- +#define PIX_VALVE_ORANGE 0xFFF5940F + +class PIXEvent +{ +public: + PIXEvent( IMatRenderContext *pRenderContext, const char *szName, unsigned long color = PIX_VALVE_ORANGE ) + { + m_pRenderContext = pRenderContext; + Assert( m_pRenderContext ); + Assert( szName ); + m_pRenderContext->BeginPIXEvent( color, szName ); + } + ~PIXEvent() + { + m_pRenderContext->EndPIXEvent(); + } +private: + IMatRenderContext *m_pRenderContext; +}; + + +// Also be sure to enable PIX_INSTRUMENTATION in shaderdevicedx8.h +//#define PIX_ENABLE 1 // set this to 1 and build engine/studiorender to enable pix events in the engine + +#if PIX_ENABLE +# define PIXEVENT PIXEvent _pixEvent +#else +# define PIXEVENT +#endif + +//----------------------------------------------------------------------------- + +#ifdef MATERIAL_SYSTEM_DEBUG_CALL_QUEUE +#include "tier1/callqueue.h" +#include "tier1/fmtstr.h" +static void DoMatSysQueueMark( IMaterialSystem *pMaterialSystem, const char *psz ) +{ + CMatRenderContextPtr pRenderContext( pMaterialSystem ); + if ( pRenderContext->GetCallQueue() ) + pRenderContext->GetCallQueue()->QueueCall( Plat_DebugString, CUtlEnvelope( psz ) ); +} + +#define MatSysQueueMark( pMaterialSystem, ...) DoMatSysQueueMark( pMaterialSystem, CFmtStr( __VA_ARGS__ ) ) +#else +#define MatSysQueueMark( msg, ...) ((void)0) +#endif + +//----------------------------------------------------------------------------- + +extern IMaterialSystem *materials; +extern IMaterialSystem *g_pMaterialSystem; + +#endif // IMATERIALSYSTEM_H diff --git a/sp/src/public/materialsystem/imaterialsystemhardwareconfig.h b/sp/src/public/materialsystem/imaterialsystemhardwareconfig.h new file mode 100644 index 00000000..699b9bdf --- /dev/null +++ b/sp/src/public/materialsystem/imaterialsystemhardwareconfig.h @@ -0,0 +1,212 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Header: $ +// $NoKeywords: $ +//===========================================================================// + +#ifndef IMATERIALSYSTEMHARDWARECONFIG_H +#define IMATERIALSYSTEMHARDWARECONFIG_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "tier1/interface.h" + +//----------------------------------------------------------------------------- +// GL helpers +//----------------------------------------------------------------------------- +FORCEINLINE bool IsEmulatingGL() +{ + static bool bIsEmulatingGL = ( Plat_GetCommandLineA() ) ? ( strstr( Plat_GetCommandLineA(), "-r_emulate_gl" ) != NULL ) : false; + return bIsEmulatingGL; +} + +FORCEINLINE bool IsOpenGL( void ) +{ + return IsPlatformOpenGL() || IsEmulatingGL(); +} + +//----------------------------------------------------------------------------- +// Material system interface version +//----------------------------------------------------------------------------- +#define MATERIALSYSTEM_HARDWARECONFIG_INTERFACE_VERSION "MaterialSystemHardwareConfig012" + +// HDRFIXME NOTE: must match common_ps_fxc.h +enum HDRType_t +{ + HDR_TYPE_NONE, + HDR_TYPE_INTEGER, + HDR_TYPE_FLOAT, +}; + +// For now, vertex compression is simply "on or off" (for the sake of simplicity +// and MeshBuilder perf.), but later we may support multiple flavours. +enum VertexCompressionType_t +{ + // This indicates an uninitialized VertexCompressionType_t value + VERTEX_COMPRESSION_INVALID = 0xFFFFFFFF, + + // 'VERTEX_COMPRESSION_NONE' means that no elements of a vertex are compressed + VERTEX_COMPRESSION_NONE = 0, + + // Currently (more stuff may be added as needed), 'VERTEX_COMPRESSION_ON' means: + // - if a vertex contains VERTEX_ELEMENT_NORMAL, this is compressed + // (see CVertexBuilder::CompressedNormal3f) + // - if a vertex contains VERTEX_ELEMENT_USERDATA4 (and a normal - together defining a tangent + // frame, with the binormal reconstructed in the vertex shader), this is compressed + // (see CVertexBuilder::CompressedUserData) + // - if a vertex contains VERTEX_ELEMENT_BONEWEIGHTSx, this is compressed + // (see CVertexBuilder::CompressedBoneWeight3fv) + VERTEX_COMPRESSION_ON = 1 +}; + + +// use DEFCONFIGMETHOD to define time-critical methods that we want to make just return constants +// on the 360, so that the checks will happen at compile time. Not all methods are defined this way +// - just the ones that I perceive as being called often in the frame interval. +#ifdef _X360 +#define DEFCONFIGMETHOD( ret_type, method, xbox_return_value ) \ +FORCEINLINE ret_type method const \ +{ \ + return xbox_return_value; \ +} + + +#else +#define DEFCONFIGMETHOD( ret_type, method, xbox_return_value ) \ +virtual ret_type method const = 0; +#endif + + + +//----------------------------------------------------------------------------- +// Material system configuration +//----------------------------------------------------------------------------- +class IMaterialSystemHardwareConfig +{ +public: + // on xbox, some methods are inlined to return constants + + DEFCONFIGMETHOD( bool, HasDestAlphaBuffer(), true ); + DEFCONFIGMETHOD( bool, HasStencilBuffer(), true ); + virtual int GetFrameBufferColorDepth() const = 0; + virtual int GetSamplerCount() const = 0; + virtual bool HasSetDeviceGammaRamp() const = 0; + DEFCONFIGMETHOD( bool, SupportsCompressedTextures(), true ); + virtual VertexCompressionType_t SupportsCompressedVertices() const = 0; + DEFCONFIGMETHOD( bool, SupportsNormalMapCompression(), true ); + DEFCONFIGMETHOD( bool, SupportsVertexAndPixelShaders(), true ); + DEFCONFIGMETHOD( bool, SupportsPixelShaders_1_4(), true ); + DEFCONFIGMETHOD( bool, SupportsStaticControlFlow(), true ); + DEFCONFIGMETHOD( bool, SupportsPixelShaders_2_0(), true ); + DEFCONFIGMETHOD( bool, SupportsVertexShaders_2_0(), true ); + virtual int MaximumAnisotropicLevel() const = 0; // 0 means no anisotropic filtering + virtual int MaxTextureWidth() const = 0; + virtual int MaxTextureHeight() const = 0; + virtual int TextureMemorySize() const = 0; + virtual bool SupportsOverbright() const = 0; + virtual bool SupportsCubeMaps() const = 0; + virtual bool SupportsMipmappedCubemaps() const = 0; + virtual bool SupportsNonPow2Textures() const = 0; + + // The number of texture stages represents the number of computations + // we can do in the fixed-function pipeline, it is *not* related to the + // simultaneous number of textures we can use + virtual int GetTextureStageCount() const = 0; + virtual int NumVertexShaderConstants() const = 0; + virtual int NumPixelShaderConstants() const = 0; + virtual int MaxNumLights() const = 0; + virtual bool SupportsHardwareLighting() const = 0; + virtual int MaxBlendMatrices() const = 0; + virtual int MaxBlendMatrixIndices() const = 0; + virtual int MaxTextureAspectRatio() const = 0; + virtual int MaxVertexShaderBlendMatrices() const = 0; + virtual int MaxUserClipPlanes() const = 0; + virtual bool UseFastClipping() const = 0; + + // This here should be the major item looked at when checking for compat + // from anywhere other than the material system shaders + DEFCONFIGMETHOD( int, GetDXSupportLevel(), 98 ); + virtual const char *GetShaderDLLName() const = 0; + + virtual bool ReadPixelsFromFrontBuffer() const = 0; + + // Are dx dynamic textures preferred? + virtual bool PreferDynamicTextures() const = 0; + + DEFCONFIGMETHOD( bool, SupportsHDR(), true ); + + virtual bool HasProjectedBumpEnv() const = 0; + virtual bool SupportsSpheremapping() const = 0; + virtual bool NeedsAAClamp() const = 0; + virtual bool NeedsATICentroidHack() const = 0; + + virtual bool SupportsColorOnSecondStream() const = 0; + virtual bool SupportsStaticPlusDynamicLighting() const = 0; + + // Does our card have a hard time with fillrate + // relative to other cards w/ the same dx level? + virtual bool PreferReducedFillrate() const = 0; + + // This is the max dx support level supported by the card + virtual int GetMaxDXSupportLevel() const = 0; + + // Does the card specify fog color in linear space when sRGBWrites are enabled? + virtual bool SpecifiesFogColorInLinearSpace() const = 0; + + // Does the card support sRGB reads/writes? + DEFCONFIGMETHOD( bool, SupportsSRGB(), true ); + DEFCONFIGMETHOD( bool, FakeSRGBWrite(), false ); + DEFCONFIGMETHOD( bool, CanDoSRGBReadFromRTs(), true ); + + virtual bool SupportsGLMixedSizeTargets() const = 0; + + virtual bool IsAAEnabled() const = 0; // Is antialiasing being used? + + // NOTE: Anything after this was added after shipping HL2. + virtual int GetVertexTextureCount() const = 0; + virtual int GetMaxVertexTextureDimension() const = 0; + + virtual int MaxTextureDepth() const = 0; + + virtual HDRType_t GetHDRType() const = 0; + virtual HDRType_t GetHardwareHDRType() const = 0; + + DEFCONFIGMETHOD( bool, SupportsPixelShaders_2_b(), true ); + virtual bool SupportsStreamOffset() const = 0; + + virtual int StencilBufferBits() const = 0; + virtual int MaxViewports() const = 0; + + virtual void OverrideStreamOffsetSupport( bool bOverrideEnabled, bool bEnableSupport ) = 0; + + virtual int GetShadowFilterMode() const = 0; + + virtual int NeedsShaderSRGBConversion() const = 0; + + DEFCONFIGMETHOD( bool, UsesSRGBCorrectBlending(), true ); + + virtual bool SupportsShaderModel_3_0() const = 0; + virtual bool HasFastVertexTextures() const = 0; + virtual int MaxHWMorphBatchCount() const = 0; + + // Does the board actually support this? + DEFCONFIGMETHOD( bool, ActuallySupportsPixelShaders_2_b(), true ); + + virtual bool SupportsHDRMode( HDRType_t nHDRMode ) const = 0; + + virtual bool GetHDREnabled( void ) const = 0; + virtual void SetHDREnabled( bool bEnable ) = 0; + + virtual bool SupportsBorderColor( void ) const = 0; + virtual bool SupportsFetch4( void ) const = 0; + + inline bool ShouldAlwaysUseShaderModel2bShaders() const { return IsOpenGL(); } + inline bool PlatformRequiresNonNullPixelShaders() const { return IsOpenGL(); } +}; + +#endif // IMATERIALSYSTEMHARDWARECONFIG_H diff --git a/sp/src/public/materialsystem/imaterialsystemstub.h b/sp/src/public/materialsystem/imaterialsystemstub.h new file mode 100644 index 00000000..b289e1b9 --- /dev/null +++ b/sp/src/public/materialsystem/imaterialsystemstub.h @@ -0,0 +1,31 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef IMATERIALSYSTEMSTUB_H +#define IMATERIALSYSTEMSTUB_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "materialsystem/imaterialsystem.h" + + +// If you get this interface out of the material system, it'll return an IMaterialSystem +// with everything stubbed. This is used for running the client in text mode. +#define MATERIAL_SYSTEM_STUB_INTERFACE_VERSION "VMaterialSystemStub001" + + +class IMaterialSystemStub : public IMaterialSystem +{ +public: + // If this is called, then the stub will call through to the real material + // system in some functions. + virtual void SetRealMaterialSystem( IMaterialSystem *pSys ) = 0; +}; + + +#endif // IMATERIALSYSTEMSTUB_H diff --git a/sp/src/public/materialsystem/imaterialvar.h b/sp/src/public/materialsystem/imaterialvar.h new file mode 100644 index 00000000..4918d246 --- /dev/null +++ b/sp/src/public/materialsystem/imaterialvar.h @@ -0,0 +1,245 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef IMATERIALVAR_H +#define IMATERIALVAR_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier0/platform.h" +#include "tier1/utlsymbol.h" +#include "mathlib/vector4d.h" +class IMaterial; +class VMatrix; +class ITexture; + +#define MAKE_MATERIALVAR_FOURCC(ch0, ch1, ch2, ch3) \ + ((unsigned long)(ch0) | ((unsigned long)(ch1) << 8) | \ + ((unsigned long)(ch2) << 16) | ((unsigned long)(ch3) << 24 )) + +// This fourcc is reserved. +#define FOURCC_UNKNOWN MAKE_MATERIALVAR_FOURCC('U','N','K','N') + + +//----------------------------------------------------------------------------- +// Various material var types +//----------------------------------------------------------------------------- +enum MaterialVarType_t +{ + MATERIAL_VAR_TYPE_FLOAT = 0, + MATERIAL_VAR_TYPE_STRING, + MATERIAL_VAR_TYPE_VECTOR, + MATERIAL_VAR_TYPE_TEXTURE, + MATERIAL_VAR_TYPE_INT, + MATERIAL_VAR_TYPE_FOURCC, + MATERIAL_VAR_TYPE_UNDEFINED, + MATERIAL_VAR_TYPE_MATRIX, + MATERIAL_VAR_TYPE_MATERIAL, +}; + +typedef unsigned short MaterialVarSym_t; + +class IMaterialVar +{ +public: + typedef unsigned long FourCC; + +protected: + // base data and accessors + char* m_pStringVal; + int m_intVal; + Vector4D m_VecVal; + + // member data. total = 4 bytes + uint8 m_Type : 4; + uint8 m_nNumVectorComps : 3; + uint8 m_bFakeMaterialVar : 1; + uint8 m_nTempIndex; + CUtlSymbol m_Name; + +public: + // class factory methods + static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey, VMatrix const& matrix ); + static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey, char const* pVal ); + static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey, float* pVal, int numcomps ); + static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey, float val ); + static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey, int val ); + static IMaterialVar* Create( IMaterial* pMaterial, char const* pKey ); + static void Destroy( IMaterialVar* pVar ); + static MaterialVarSym_t GetSymbol( char const* pName ); + static MaterialVarSym_t FindSymbol( char const* pName ); + static bool SymbolMatches( char const* pName, MaterialVarSym_t symbol ); + static void DeleteUnreferencedTextures( bool enable ); + + virtual ITexture *GetTextureValue( void ) = 0; + + virtual char const * GetName( void ) const = 0; + virtual MaterialVarSym_t GetNameAsSymbol() const = 0; + + virtual void SetFloatValue( float val ) = 0; + + virtual void SetIntValue( int val ) = 0; + + virtual void SetStringValue( char const *val ) = 0; + virtual char const * GetStringValue( void ) const = 0; + + // Use FourCC values to pass app-defined data structures between + // the proxy and the shader. The shader should ignore the data if + // its FourCC type not correct. + virtual void SetFourCCValue( FourCC type, void *pData ) = 0; + virtual void GetFourCCValue( FourCC *type, void **ppData ) = 0; + + // Vec (dim 2-4) + virtual void SetVecValue( float const* val, int numcomps ) = 0; + virtual void SetVecValue( float x, float y ) = 0; + virtual void SetVecValue( float x, float y, float z ) = 0; + virtual void SetVecValue( float x, float y, float z, float w ) = 0; + virtual void GetLinearVecValue( float *val, int numcomps ) const = 0; + + // revisit: is this a good interface for textures? + virtual void SetTextureValue( ITexture * ) = 0; + + virtual IMaterial * GetMaterialValue( void ) = 0; + virtual void SetMaterialValue( IMaterial * ) = 0; + + virtual bool IsDefined() const = 0; + virtual void SetUndefined() = 0; + + // Matrix + virtual void SetMatrixValue( VMatrix const& matrix ) = 0; + virtual const VMatrix &GetMatrixValue( ) = 0; + virtual bool MatrixIsIdentity() const = 0; + + // Copy.... + virtual void CopyFrom( IMaterialVar *pMaterialVar ) = 0; + + virtual void SetValueAutodetectType( char const *val ) = 0; + + virtual IMaterial * GetOwningMaterial() = 0; + + //set just 1 component + virtual void SetVecComponentValue( float fVal, int nComponent ) = 0; + +protected: + virtual int GetIntValueInternal( void ) const = 0; + virtual float GetFloatValueInternal( void ) const = 0; + virtual float const* GetVecValueInternal( ) const = 0; + virtual void GetVecValueInternal( float *val, int numcomps ) const = 0; + virtual int VectorSizeInternal() const = 0; + +public: + FORCEINLINE MaterialVarType_t GetType( void ) const + { + return ( MaterialVarType_t )m_Type; + } + + FORCEINLINE bool IsTexture() const + { + return m_Type == MATERIAL_VAR_TYPE_TEXTURE; + } + + FORCEINLINE operator ITexture*() + { + return GetTextureValue(); + } + + // NOTE: Fast methods should only be called in thread-safe situations + FORCEINLINE int GetIntValueFast( void ) const + { + // Set methods for float and vector update this + return m_intVal; + } + + FORCEINLINE float GetFloatValueFast( void ) const + { + return m_VecVal[0]; + } + + FORCEINLINE float const* GetVecValueFast( ) const + { + return m_VecVal.Base(); + } + + FORCEINLINE void GetVecValueFast( float *val, int numcomps ) const + { + Assert( ( numcomps >0 ) && ( numcomps <= 4 ) ); + for( int i=0 ; i < numcomps; i++ ) + { + val[i] = m_VecVal[ i ]; + } + } + + FORCEINLINE int VectorSizeFast() const + { + return m_nNumVectorComps; + } + +#ifdef FAST_MATERIALVAR_ACCESS + FORCEINLINE int GetIntValue( void ) const + { + return GetIntValueFast(); + } + + FORCEINLINE float GetFloatValue( void ) const + { + return GetFloatValueFast(); + } + + FORCEINLINE float const* GetVecValue( ) const + { + return GetVecValueFast(); + } + + FORCEINLINE void GetVecValue( float *val, int numcomps ) const + { + GetVecValueFast( val, numcomps ); + } + + FORCEINLINE int VectorSize() const + { + return VectorSizeFast(); + } +#else // !FAST_MATERIALVAR_ACCESS + FORCEINLINE int GetIntValue( void ) const + { + return GetIntValueInternal(); + } + + FORCEINLINE float GetFloatValue( void ) const + { + return GetFloatValueInternal(); + } + + FORCEINLINE float const* GetVecValue( ) const + { + return GetVecValueInternal(); + } + + FORCEINLINE void GetVecValue( float *val, int numcomps ) const + { + return GetVecValueInternal( val, numcomps ); + } + + FORCEINLINE int VectorSize() const + { + return VectorSizeInternal(); + } +#endif + +private: + FORCEINLINE void SetTempIndex( int nIndex ) + { + m_nTempIndex = nIndex; + } + + friend void EnableThreadedMaterialVarAccess( bool bEnable, IMaterialVar **ppParams, int nVarCount ); +}; + +#endif // IMATERIALVAR_H diff --git a/sp/src/public/materialsystem/imesh.h b/sp/src/public/materialsystem/imesh.h new file mode 100644 index 00000000..b71be4d9 --- /dev/null +++ b/sp/src/public/materialsystem/imesh.h @@ -0,0 +1,4047 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#ifndef IMESH_H +#define IMESH_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier1/interface.h" +#include "materialsystem/imaterial.h" +#include +#include +#include "tier0/dbg.h" +#include "tier2/meshutils.h" +#include "mathlib/mathlib.h" + +#if defined( DX_TO_GL_ABSTRACTION ) +// Swap these so that we do color swapping on 10.6.2, which doesn't have EXT_vertex_array_bgra +#define OPENGL_SWAP_COLORS +#endif + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- +class IMaterial; +class CMeshBuilder; +class IMaterialVar; +typedef uint64 VertexFormat_t; + + +//----------------------------------------------------------------------------- +// Define this to find write-combine problems +//----------------------------------------------------------------------------- +#ifdef _DEBUG +//#ifndef DEBUG_WRITE_COMBINE +//#define DEBUG_WRITE_COMBINE 1 +//#endif +#endif + + +//----------------------------------------------------------------------------- +// The Vertex Buffer interface +//----------------------------------------------------------------------------- +enum +{ + VERTEX_MAX_TEXTURE_COORDINATES = 8, + BONE_MATRIX_INDEX_INVALID = 255 +}; + +// Internal maximums for sizes. Don't use directly, use IMaterialSystem::GetMaxToRender() +enum +{ + INDEX_BUFFER_SIZE = 32768, + DYNAMIC_VERTEX_BUFFER_MEMORY = ( 1024 + 512 ) * 1024, + DYNAMIC_VERTEX_BUFFER_MEMORY_SMALL = 384 * 1024, // Only allocate this much during map transitions +}; + +// Vertex fields must be written in well-defined order to achieve write combining, +// which is a perf booster +enum WriteCombineOrdering_t +{ + MB_FIELD_NONE = -1, + MB_FIELD_POSITION = 0, + MB_FIELD_BONE_WEIGHTS, + MB_FIELD_BONE_INDEX, + MB_FIELD_NORMAL, + MB_FIELD_COLOR, + MB_FIELD_SPECULAR, + MB_FIELD_TEXCOORD_FIRST, + MB_FIELD_TEXCOORD_LAST = MB_FIELD_TEXCOORD_FIRST + VERTEX_MAX_TEXTURE_COORDINATES - 1, + MB_FIELD_TANGENT_S, + MB_FIELD_TANGENT_T, + MB_FIELD_USERDATA, +}; + +#define MB_FIELD_TEXCOORD( nStage ) ( MB_FIELD_TEXCOORD_FIRST + ( nStage ) ) + +struct VertexDesc_t +{ + // These can be set to zero if there are pointers to dummy buffers, when the + // actual buffer format doesn't contain the data but it needs to be safe to + // use all the CMeshBuilder functions. + int m_VertexSize_Position; + int m_VertexSize_BoneWeight; + int m_VertexSize_BoneMatrixIndex; + int m_VertexSize_Normal; + int m_VertexSize_Color; + int m_VertexSize_Specular; + int m_VertexSize_TexCoord[VERTEX_MAX_TEXTURE_COORDINATES]; + int m_VertexSize_TangentS; + int m_VertexSize_TangentT; + int m_VertexSize_Wrinkle; + + int m_VertexSize_UserData; + + int m_ActualVertexSize; // Size of the vertices.. Some of the m_VertexSize_ elements above + // are set to this value and some are set to zero depending on which + // fields exist in a buffer's vertex format. + + // The type of compression applied to this vertex data + VertexCompressionType_t m_CompressionType; + + // Number of bone weights per vertex... + int m_NumBoneWeights; + + // Pointers to our current vertex data + float *m_pPosition; + + float *m_pBoneWeight; + +#ifndef NEW_SKINNING + unsigned char *m_pBoneMatrixIndex; +#else + float *m_pBoneMatrixIndex; +#endif + + float *m_pNormal; + + unsigned char *m_pColor; + unsigned char *m_pSpecular; + float *m_pTexCoord[VERTEX_MAX_TEXTURE_COORDINATES]; + + // Tangent space *associated with one particular set of texcoords* + float *m_pTangentS; + float *m_pTangentT; + + float *m_pWrinkle; + + // user data + float *m_pUserData; + + // The first vertex index (used for buffered vertex buffers, or cards that don't support stream offset) + int m_nFirstVertex; + + // The offset in bytes of the memory we're writing into + // from the start of the D3D buffer (will be 0 for static meshes) + unsigned int m_nOffset; + +#ifdef DEBUG_WRITE_COMBINE + int m_nLastWrittenField; + unsigned char* m_pLastWrittenAddress; +#endif +}; + +struct IndexDesc_t +{ + // Pointers to the index data + unsigned short *m_pIndices; + + // The offset in bytes of the memory we're writing into + // from the start of the D3D buffer (will be 0 for static meshes) + unsigned int m_nOffset; + + // The first index (used for buffered index buffers, or cards that don't support stream offset) + unsigned int m_nFirstIndex; + + // 1 if the device is active, 0 if the device isn't active. + // Faster than doing if checks for null m_pIndices if someone is + // trying to write the m_pIndices while the device is inactive. + unsigned char m_nIndexSize; +}; + + +//----------------------------------------------------------------------------- +// The Mesh memory descriptor +//----------------------------------------------------------------------------- +struct MeshDesc_t : public VertexDesc_t, public IndexDesc_t +{ +}; + + +//----------------------------------------------------------------------------- +// Standard vertex formats for models +//----------------------------------------------------------------------------- +struct ModelVertexDX7_t +{ + Vector m_vecPosition; + Vector2D m_flBoneWeights; + unsigned int m_nBoneIndices; + Vector m_vecNormal; + unsigned int m_nColor; // ARGB + Vector2D m_vecTexCoord; +}; + +struct ModelVertexDX8_t : public ModelVertexDX7_t +{ + Vector4D m_vecUserData; +}; + + +//----------------------------------------------------------------------------- +// Utility methods for buffer builders +//----------------------------------------------------------------------------- +inline float *OffsetFloatPointer( float *pBufferPointer, int nVertexCount, int vertexSize ) +{ + return reinterpret_cast( + reinterpret_cast(pBufferPointer) + + nVertexCount * vertexSize); +} + +inline const float *OffsetFloatPointer( const float *pBufferPointer, int nVertexCount, int vertexSize ) +{ + return reinterpret_cast( + reinterpret_cast(pBufferPointer) + + nVertexCount * vertexSize); +} + +inline void IncrementFloatPointer( float* &pBufferPointer, int vertexSize ) +{ + pBufferPointer = reinterpret_cast( reinterpret_cast( pBufferPointer ) + vertexSize ); +} + + +//----------------------------------------------------------------------------- +// Used in lists of indexed primitives. +//----------------------------------------------------------------------------- +class CPrimList +{ +public: + CPrimList(); + CPrimList( int nFirstIndex, int nIndexCount ); + + int m_FirstIndex; + int m_NumIndices; +}; + +inline CPrimList::CPrimList() +{ +} + +inline CPrimList::CPrimList( int nFirstIndex, int nIndexCount ) +{ + m_FirstIndex = nFirstIndex; + m_NumIndices = nIndexCount; +} + +abstract_class IVertexBuffer +{ +public: + // Add a virtual destructor to silence the clang warning. + // This is harmless but not important since the only derived class + // doesn't have a destructor. + virtual ~IVertexBuffer() {} + + // NOTE: The following two methods are only valid for static vertex buffers + // Returns the number of vertices and the format of the vertex buffer + virtual int VertexCount() const = 0; + virtual VertexFormat_t GetVertexFormat() const = 0; + + // Is this vertex buffer dynamic? + virtual bool IsDynamic() const = 0; + + // NOTE: For dynamic vertex buffers only! + // Casts the memory of the dynamic vertex buffer to the appropriate type + virtual void BeginCastBuffer( VertexFormat_t format ) = 0; + virtual void EndCastBuffer() = 0; + + // Returns the number of vertices that can still be written into the buffer + virtual int GetRoomRemaining() const = 0; + + virtual bool Lock( int nVertexCount, bool bAppend, VertexDesc_t &desc ) = 0; + virtual void Unlock( int nVertexCount, VertexDesc_t &desc ) = 0; + + // Spews the mesh data + virtual void Spew( int nVertexCount, const VertexDesc_t &desc ) = 0; + + // Call this in debug mode to make sure our data is good. + virtual void ValidateData( int nVertexCount, const VertexDesc_t & desc ) = 0; +}; + +abstract_class IIndexBuffer +{ +public: + // Add a virtual destructor to silence the clang warning. + // This is harmless but not important since the only derived class + // doesn't have a destructor. + virtual ~IIndexBuffer() {} + + // NOTE: The following two methods are only valid for static index buffers + // Returns the number of indices and the format of the index buffer + virtual int IndexCount() const = 0; + virtual MaterialIndexFormat_t IndexFormat() const = 0; + + // Is this index buffer dynamic? + virtual bool IsDynamic() const = 0; + + // NOTE: For dynamic index buffers only! + // Casts the memory of the dynamic index buffer to the appropriate type + virtual void BeginCastBuffer( MaterialIndexFormat_t format ) = 0; + virtual void EndCastBuffer() = 0; + + // Returns the number of indices that can still be written into the buffer + virtual int GetRoomRemaining() const = 0; + + // Locks, unlocks the index buffer + virtual bool Lock( int nMaxIndexCount, bool bAppend, IndexDesc_t &desc ) = 0; + virtual void Unlock( int nWrittenIndexCount, IndexDesc_t &desc ) = 0; + + // FIXME: Remove this!! + // Locks, unlocks the index buffer for modify + virtual void ModifyBegin( bool bReadOnly, int nFirstIndex, int nIndexCount, IndexDesc_t& desc ) = 0; + virtual void ModifyEnd( IndexDesc_t& desc ) = 0; + + // Spews the mesh data + virtual void Spew( int nIndexCount, const IndexDesc_t &desc ) = 0; + + // Ensures the data in the index buffer is valid + virtual void ValidateData( int nIndexCount, const IndexDesc_t &desc ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Interface to the mesh - needs to contain an IVertexBuffer and an IIndexBuffer to emulate old mesh behavior +//----------------------------------------------------------------------------- +abstract_class IMesh : public IVertexBuffer, public IIndexBuffer +{ +public: + // ----------------------------------- + + // Sets/gets the primitive type + virtual void SetPrimitiveType( MaterialPrimitiveType_t type ) = 0; + + // Draws the mesh + virtual void Draw( int nFirstIndex = -1, int nIndexCount = 0 ) = 0; + + virtual void SetColorMesh( IMesh *pColorMesh, int nVertexOffset ) = 0; + + // Draw a list of (lists of) primitives. Batching your lists together that use + // the same lightmap, material, vertex and index buffers with multipass shaders + // can drastically reduce state-switching overhead. + // NOTE: this only works with STATIC meshes. + virtual void Draw( CPrimList *pLists, int nLists ) = 0; + + // Copy verts and/or indices to a mesh builder. This only works for temp meshes! + virtual void CopyToMeshBuilder( + int iStartVert, // Which vertices to copy. + int nVerts, + int iStartIndex, // Which indices to copy. + int nIndices, + int indexOffset, // This is added to each index. + CMeshBuilder &builder ) = 0; + + // Spews the mesh data + virtual void Spew( int nVertexCount, int nIndexCount, const MeshDesc_t &desc ) = 0; + + // Call this in debug mode to make sure our data is good. + virtual void ValidateData( int nVertexCount, int nIndexCount, const MeshDesc_t &desc ) = 0; + + // New version + // Locks/unlocks the mesh, providing space for nVertexCount and nIndexCount. + // nIndexCount of -1 means don't lock the index buffer... + virtual void LockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ) = 0; + virtual void ModifyBegin( int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t& desc ) = 0; + virtual void ModifyEnd( MeshDesc_t& desc ) = 0; + virtual void UnlockMesh( int nVertexCount, int nIndexCount, MeshDesc_t &desc ) = 0; + + virtual void ModifyBeginEx( bool bReadOnly, int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount, MeshDesc_t &desc ) = 0; + + virtual void SetFlexMesh( IMesh *pMesh, int nVertexOffset ) = 0; + + virtual void DisableFlexMesh() = 0; + + virtual void MarkAsDrawn() = 0; + + virtual unsigned ComputeMemoryUsed() = 0; +}; + + +#include "meshreader.h" + +#define INVALID_BUFFER_OFFSET 0xFFFFFFFFUL + +// flags for advancevertex optimization +#define VTX_HAVEPOS 1 +#define VTX_HAVENORMAL 2 +#define VTX_HAVECOLOR 4 +#define VTX_HAVEALL ( VTX_HAVEPOS | VTX_HAVENORMAL | VTX_HAVECOLOR ) + + +//----------------------------------------------------------------------------- +// +// Helper class used to define vertex buffers +// +//----------------------------------------------------------------------------- +class CVertexBuilder : private VertexDesc_t +{ +public: + CVertexBuilder(); + CVertexBuilder( IVertexBuffer *pVertexBuffer, VertexFormat_t fmt = 0 ); + ~CVertexBuilder(); + + // Begins, ends modification of the index buffer (returns true if the lock succeeded) + // A lock may not succeed if append is set to true and there isn't enough room + // NOTE: Append is only used with dynamic index buffers; it's ignored for static buffers + bool Lock( int nMaxIndexCount, bool bAppend = false ); + void Unlock(); + + // Spews the current data + // NOTE: Can only be called during a lock/unlock block + void SpewData(); + + // Returns the number of indices we can fit into the buffer without needing to discard + int GetRoomRemaining() const; + + // Binds this vertex buffer + void Bind( IMatRenderContext *pContext, int nStreamID, VertexFormat_t usage = 0 ); + + // Returns the byte offset + int Offset() const; + + // This must be called before Begin, if a vertex buffer with a compressed format is to be used + void SetCompressionType( VertexCompressionType_t compressionType ); + void ValidateCompressionType(); + + void Begin( IVertexBuffer *pVertexBuffer, int nVertexCount, int *nFirstVertex ); + void Begin( IVertexBuffer *pVertexBuffer, int nVertexCount ); + + // Use this when you're done writing + // Set bDraw to true to call m_pMesh->Draw automatically. + void End( bool bSpewData = false ); + + // Locks the vertex buffer to modify existing data + // Passing nVertexCount == -1 says to lock all the vertices for modification. + void BeginModify( IVertexBuffer *pVertexBuffer, int nFirstVertex = 0, int nVertexCount = -1 ); + void EndModify( bool bSpewData = false ); + + // returns the number of vertices + int VertexCount() const; + + // Returns the total number of vertices across all Locks() + int TotalVertexCount() const; + + // Resets the mesh builder so it points to the start of everything again + void Reset(); + + // Returns the size of the vertex + int VertexSize() { return m_ActualVertexSize; } + + // returns the data size of a given texture coordinate + int TextureCoordinateSize( int nTexCoordNumber ) { return m_VertexSize_TexCoord[ nTexCoordNumber ]; } + + // Returns the base vertex memory pointer + void* BaseVertexData(); + + // Selects the nth Vertex and Index + void SelectVertex( int idx ); + + // Advances the current vertex and index by one + void AdvanceVertex( void ); + template void AdvanceVertexF( void ); + void AdvanceVertices( int nVerts ); + + int GetCurrentVertex() const; + int GetFirstVertex() const; + + // Data retrieval... + const float *Position() const; + + const float *Normal() const; + + unsigned int Color() const; + + unsigned char *Specular() const; + + const float *TexCoord( int stage ) const; + + const float *TangentS() const; + const float *TangentT() const; + + const float *BoneWeight() const; + float Wrinkle() const; + + int NumBoneWeights() const; +#ifndef NEW_SKINNING + unsigned char *BoneMatrix() const; +#else + float *BoneMatrix() const; +#endif + + // position setting + void Position3f( float x, float y, float z ); + void Position3fv( const float *v ); + + // normal setting + void Normal3f( float nx, float ny, float nz ); + void Normal3fv( const float *n ); + void NormalDelta3fv( const float *n ); + void NormalDelta3f( float nx, float ny, float nz ); + // normal setting (templatized for code which needs to support compressed vertices) + template void CompressedNormal3f( float nx, float ny, float nz ); + template void CompressedNormal3fv( const float *n ); + + // color setting + void Color3f( float r, float g, float b ); + void Color3fv( const float *rgb ); + void Color4f( float r, float g, float b, float a ); + void Color4fv( const float *rgba ); + + // Faster versions of color + void Color3ub( unsigned char r, unsigned char g, unsigned char b ); + void Color3ubv( unsigned char const* rgb ); + void Color4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ); + void Color4ubv( unsigned char const* rgba ); + + // specular color setting + void Specular3f( float r, float g, float b ); + void Specular3fv( const float *rgb ); + void Specular4f( float r, float g, float b, float a ); + void Specular4fv( const float *rgba ); + + // Faster version of specular + void Specular3ub( unsigned char r, unsigned char g, unsigned char b ); + void Specular3ubv( unsigned char const *c ); + void Specular4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ); + void Specular4ubv( unsigned char const *c ); + + // texture coordinate setting + void TexCoord1f( int stage, float s ); + void TexCoord2f( int stage, float s, float t ); + void TexCoord2fv( int stage, const float *st ); + void TexCoord3f( int stage, float s, float t, float u ); + void TexCoord3fv( int stage, const float *stu ); + void TexCoord4f( int stage, float s, float t, float u, float w ); + void TexCoord4fv( int stage, const float *stuv ); + + void TexCoordSubRect2f( int stage, float s, float t, float offsetS, float offsetT, float scaleS, float scaleT ); + void TexCoordSubRect2fv( int stage, const float *st, const float *offset, const float *scale ); + + // tangent space + void TangentS3f( float sx, float sy, float sz ); + void TangentS3fv( const float* s ); + + void TangentT3f( float tx, float ty, float tz ); + void TangentT3fv( const float* t ); + + // Wrinkle + void Wrinkle1f( float flWrinkle ); + + // bone weights + void BoneWeight( int idx, float weight ); + // bone weights (templatized for code which needs to support compressed vertices) + template void CompressedBoneWeight3fv( const float * pWeights ); + + // bone matrix index + void BoneMatrix( int idx, int matrixIndex ); + + // Generic per-vertex data + void UserData( const float* pData ); + // Generic per-vertex data (templatized for code which needs to support compressed vertices) + template void CompressedUserData( const float* pData ); + + // Fast Vertex! No need to call advance vertex, and no random access allowed. + // WARNING - these are low level functions that are intended only for use + // in the software vertex skinner. + void FastVertex( const ModelVertexDX7_t &vertex ); + void FastVertexSSE( const ModelVertexDX7_t &vertex ); + + // store 4 dx7 vertices fast. for special sse dx7 pipeline + void Fast4VerticesSSE( + ModelVertexDX7_t const *vtx_a, + ModelVertexDX7_t const *vtx_b, + ModelVertexDX7_t const *vtx_c, + ModelVertexDX7_t const *vtx_d); + + void FastVertex( const ModelVertexDX8_t &vertex ); + void FastVertexSSE( const ModelVertexDX8_t &vertex ); + + // Add number of verts and current vert since FastVertex routines do not update. + void FastAdvanceNVertices( int n ); + +#if defined( _X360 ) + void VertexDX8ToX360( const ModelVertexDX8_t &vertex ); +#endif + + // FIXME: Remove! Backward compat so we can use this from a CMeshBuilder. + void AttachBegin( IMesh* pMesh, int nMaxVertexCount, const MeshDesc_t &desc ); + void AttachEnd(); + void AttachBeginModify( IMesh* pMesh, int nFirstVertex, int nVertexCount, const MeshDesc_t &desc ); + void AttachEndModify(); + +private: + // The vertex buffer we're modifying + IVertexBuffer *m_pVertexBuffer; + + // Used to make sure Begin/End calls and BeginModify/EndModify calls match. + bool m_bModify; + + // Max number of indices and vertices + int m_nMaxVertexCount; + + // Number of indices and vertices + int m_nVertexCount; + + // The current vertex and index + mutable int m_nCurrentVertex; + + // Optimization: Pointer to the current pos, norm, texcoord, and color + mutable float *m_pCurrPosition; + mutable float *m_pCurrNormal; + mutable float *m_pCurrTexCoord[VERTEX_MAX_TEXTURE_COORDINATES]; + mutable unsigned char *m_pCurrColor; + + // Total number of vertices appended + int m_nTotalVertexCount; + + // First vertex buffer offset + index + unsigned int m_nBufferOffset; + unsigned int m_nBufferFirstVertex; + +#if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) + // Debug checks to make sure we write userdata4/tangents AFTER normals + bool m_bWrittenNormal : 1; + bool m_bWrittenUserData : 1; +#endif + + friend class CMeshBuilder; +}; + + +//----------------------------------------------------------------------------- +// +// Inline methods of CVertexBuilder +// +//----------------------------------------------------------------------------- +inline CVertexBuilder::CVertexBuilder() +{ + m_pVertexBuffer = NULL; + m_nBufferOffset = INVALID_BUFFER_OFFSET; + m_nBufferFirstVertex = 0; + m_nVertexCount = 0; + m_nCurrentVertex = 0; + m_nMaxVertexCount = 0; + m_nTotalVertexCount = 0; + m_CompressionType = VERTEX_COMPRESSION_INVALID; + +#ifdef _DEBUG + m_pCurrPosition = NULL; + m_pCurrNormal = NULL; + m_pCurrColor = NULL; + memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) ); + m_bModify = false; +#endif +} + +inline CVertexBuilder::CVertexBuilder( IVertexBuffer *pVertexBuffer, VertexFormat_t fmt ) +{ + m_pVertexBuffer = pVertexBuffer; + m_nBufferOffset = INVALID_BUFFER_OFFSET; + m_nBufferFirstVertex = 0; + m_nVertexCount = 0; + m_nCurrentVertex = 0; + m_nMaxVertexCount = 0; + m_nTotalVertexCount = 0; + m_CompressionType = VERTEX_COMPRESSION_INVALID; + + if ( m_pVertexBuffer->IsDynamic() ) + { + m_pVertexBuffer->BeginCastBuffer( fmt ); + } + else + { + Assert( m_pVertexBuffer->GetVertexFormat() == fmt ); + } + +#ifdef _DEBUG + m_pCurrPosition = NULL; + m_pCurrNormal = NULL; + m_pCurrColor = NULL; + memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) ); + m_bModify = false; +#endif +} + +inline CVertexBuilder::~CVertexBuilder() +{ + if ( m_pVertexBuffer && m_pVertexBuffer->IsDynamic() ) + { + m_pVertexBuffer->EndCastBuffer(); + } +} + +//----------------------------------------------------------------------------- +// Begins, ends modification of the index buffer +//----------------------------------------------------------------------------- +inline bool CVertexBuilder::Lock( int nMaxVertexCount, bool bAppend ) +{ + Assert( m_pVertexBuffer ); + m_bModify = false; + m_nMaxVertexCount = nMaxVertexCount; + bool bFirstLock = ( m_nBufferOffset == INVALID_BUFFER_OFFSET ); + if ( bFirstLock ) + { + bAppend = false; + } + if ( !bAppend ) + { + m_nTotalVertexCount = 0; + } + + // Lock the vertex buffer + if ( !m_pVertexBuffer->Lock( m_nMaxVertexCount, bAppend, *this ) ) + { + m_nMaxVertexCount = 0; + return false; + } + + Reset(); + + if ( bFirstLock ) + { + m_nBufferOffset = m_nOffset; + m_nBufferFirstVertex = m_nFirstVertex; + } + + return true; +} + +inline void CVertexBuilder::Unlock() +{ + Assert( !m_bModify && m_pVertexBuffer ); + +#ifdef _DEBUG + m_pVertexBuffer->ValidateData( m_nVertexCount, *this ); +#endif + + m_pVertexBuffer->Unlock( m_nVertexCount, *this ); + m_nTotalVertexCount += m_nVertexCount; + + m_nMaxVertexCount = 0; + +#ifdef _DEBUG + // Null out our data... + m_pCurrPosition = NULL; + m_pCurrNormal = NULL; + m_pCurrColor = NULL; + memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) ); + memset( static_cast( this ), 0, sizeof(VertexDesc_t) ); +#endif +} + +inline void CVertexBuilder::SpewData() +{ + m_pVertexBuffer->Spew( m_nVertexCount, *this ); +} + + +//----------------------------------------------------------------------------- +// Binds this vertex buffer +//----------------------------------------------------------------------------- +inline void CVertexBuilder::Bind( IMatRenderContext *pContext, int nStreamID, VertexFormat_t usage ) +{ + if ( m_pVertexBuffer && ( m_nBufferOffset != INVALID_BUFFER_OFFSET ) ) + { + pContext->BindVertexBuffer( nStreamID, m_pVertexBuffer, m_nBufferOffset, + m_nFirstVertex, m_nTotalVertexCount, usage ? usage : m_pVertexBuffer->GetVertexFormat() ); + } + else + { + pContext->BindVertexBuffer( nStreamID, NULL, 0, 0, 0, 0 ); + } +} + + +//----------------------------------------------------------------------------- +// Returns the byte offset +//----------------------------------------------------------------------------- +inline int CVertexBuilder::Offset() const +{ + return m_nBufferOffset; +} + +inline int CVertexBuilder::GetFirstVertex() const +{ + return m_nBufferFirstVertex; +} + +//----------------------------------------------------------------------------- +// Specify the type of vertex compression that this CMeshBuilder will perform +//----------------------------------------------------------------------------- +inline void CVertexBuilder::SetCompressionType( VertexCompressionType_t compressionType ) +{ + // The real purpose of this method is to allow us to emit a Warning in Begin() + m_CompressionType = compressionType; +} + +inline void CVertexBuilder::ValidateCompressionType() +{ +#ifdef _DEBUG + VertexCompressionType_t vbCompressionType = CompressionType( m_pVertexBuffer->GetVertexFormat() ); + if ( vbCompressionType != VERTEX_COMPRESSION_NONE ) + { + Assert( m_CompressionType == vbCompressionType ); + if ( m_CompressionType != vbCompressionType ) + { + Warning( "ERROR: CVertexBuilder::SetCompressionType() must be called to specify the same vertex compression type (%s) as the vertex buffer being modified." + "Junk vertices will be rendered, or there will be a crash in CVertexBuilder!\n", + vbCompressionType == VERTEX_COMPRESSION_ON ? "VERTEX_COMPRESSION_ON" : "VERTEX_COMPRESSION_NONE" ); + } + // Never use vertex compression for dynamic VBs (the conversions can really hurt perf) + Assert( !m_pVertexBuffer->IsDynamic() ); + } +#endif +} + +inline void CVertexBuilder::Begin( IVertexBuffer *pVertexBuffer, int nVertexCount ) +{ + Assert( pVertexBuffer && (!m_pVertexBuffer) ); + + m_pVertexBuffer = pVertexBuffer; + m_bModify = false; + + m_nMaxVertexCount = nVertexCount; + m_nVertexCount = 0; + + // Make sure SetCompressionType was called correctly, if this VB is compressed + ValidateCompressionType(); + + // Lock the vertex and index buffer + m_pVertexBuffer->Lock( m_nMaxVertexCount, false, *this ); + + // Point to the start of the buffers.. + Reset(); +} + + +//----------------------------------------------------------------------------- +// Use this when you're done modifying the mesh +//----------------------------------------------------------------------------- +inline void CVertexBuilder::End( bool bSpewData ) +{ + // Make sure they called Begin() + Assert( !m_bModify ); + + if ( bSpewData ) + { + m_pVertexBuffer->Spew( m_nVertexCount, *this ); + } + +#ifdef _DEBUG + m_pVertexBuffer->ValidateData( m_nVertexCount, *this ); +#endif + + // Unlock our buffers + m_pVertexBuffer->Unlock( m_nVertexCount, *this ); + + m_pVertexBuffer = 0; + m_nMaxVertexCount = 0; + + m_CompressionType = VERTEX_COMPRESSION_INVALID; + +#ifdef _DEBUG + // Null out our pointers... + m_pCurrPosition = NULL; + m_pCurrNormal = NULL; + m_pCurrColor = NULL; + memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) ); + memset( static_cast< VertexDesc_t* >( this ), 0, sizeof(VertexDesc_t) ); +#endif +} + + +//----------------------------------------------------------------------------- +// FIXME: Remove! Backward compat so we can use this from a CMeshBuilder. +//----------------------------------------------------------------------------- +inline void CVertexBuilder::AttachBegin( IMesh* pMesh, int nMaxVertexCount, const MeshDesc_t &desc ) +{ + VertexCompressionType_t compressionType = m_CompressionType; + + m_pVertexBuffer = pMesh; + memcpy( static_cast( this ), static_cast( &desc ), sizeof(VertexDesc_t) ); + m_nMaxVertexCount = nMaxVertexCount; + m_NumBoneWeights = m_NumBoneWeights == 0 ? 0 : 2; // Two weights if any + m_nVertexCount = 0; + m_bModify = false; + + if ( compressionType != VERTEX_COMPRESSION_INVALID ) + m_CompressionType = compressionType; + + // Make sure SetCompressionType was called correctly, if this VB is compressed + ValidateCompressionType(); + + if ( m_nBufferOffset == INVALID_BUFFER_OFFSET ) + { + m_nTotalVertexCount = 0; + m_nBufferOffset = static_cast< const VertexDesc_t* >( &desc )->m_nOffset; + m_nBufferFirstVertex = desc.m_nFirstVertex; + } +} + +inline void CVertexBuilder::AttachEnd() +{ + // Make sure they called Begin() + Assert( !m_bModify ); + + m_nMaxVertexCount = 0; + m_pVertexBuffer = NULL; + + m_CompressionType = VERTEX_COMPRESSION_INVALID; + +#ifdef _DEBUG + // Null out our pointers... + m_pCurrPosition = NULL; + m_pCurrNormal = NULL; + m_pCurrColor = NULL; + memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) ); + memset( static_cast( this ), 0, sizeof(VertexDesc_t) ); +#endif +} + +inline void CVertexBuilder::AttachBeginModify( IMesh* pMesh, int nFirstVertex, int nVertexCount, const MeshDesc_t &desc ) +{ + Assert( pMesh && (!m_pVertexBuffer) ); + + m_pVertexBuffer = pMesh; + memcpy( static_cast( this ), static_cast( &desc ), sizeof(VertexDesc_t) ); + m_nMaxVertexCount = m_nVertexCount = nVertexCount; + m_NumBoneWeights = m_NumBoneWeights == 0 ? 0 : 2; // Two weights if any + m_bModify = true; + + // Make sure SetCompressionType was called correctly, if this VB is compressed + ValidateCompressionType(); +} + +inline void CVertexBuilder::AttachEndModify() +{ + Assert( m_pVertexBuffer ); + Assert( m_bModify ); // Make sure they called BeginModify. + + m_pVertexBuffer = 0; + m_nMaxVertexCount = 0; + + m_CompressionType = VERTEX_COMPRESSION_INVALID; + +#ifdef _DEBUG + // Null out our pointers... + m_pCurrPosition = NULL; + m_pCurrNormal = NULL; + m_pCurrColor = NULL; + memset( m_pCurrTexCoord, 0, sizeof( m_pCurrTexCoord ) ); + memset( static_cast( this ), 0, sizeof(VertexDesc_t) ); +#endif +} + + +//----------------------------------------------------------------------------- +// Computes the first min non-null address +//----------------------------------------------------------------------------- +inline unsigned char* FindMinAddress( void *pAddress1, void *pAddress2, int nAddress2Size ) +{ + if ( nAddress2Size == 0 ) + return (unsigned char*)pAddress1; + if ( !pAddress1 ) + return (unsigned char*)pAddress2; + return ( pAddress1 < pAddress2 ) ? (unsigned char*)pAddress1 : (unsigned char*)pAddress2; +} + +//----------------------------------------------------------------------------- +// Resets the vertex buffer builder so it points to the start of everything again +//----------------------------------------------------------------------------- +inline void CVertexBuilder::Reset() +{ + m_nCurrentVertex = 0; + + m_pCurrPosition = m_pPosition; + m_pCurrNormal = m_pNormal; + for ( int i = 0; i < NELEMS( m_pCurrTexCoord ); i++ ) + { + m_pCurrTexCoord[i] = m_pTexCoord[i]; + } + m_pCurrColor = m_pColor; + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif + +#ifdef DEBUG_WRITE_COMBINE + // Logic for m_pLastWrittenAddress is tricky. It really wants the min of the + // non-null address pointers. + m_nLastWrittenField = MB_FIELD_NONE; + m_pLastWrittenAddress = NULL; + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pPosition, m_VertexSize_Position ); + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pBoneWeight, m_VertexSize_BoneWeight ); + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pBoneMatrixIndex, m_VertexSize_BoneMatrixIndex ); + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pNormal, m_VertexSize_Normal ); + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pColor, m_VertexSize_Color ); + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pSpecular, m_VertexSize_Specular ); + for ( int i = 0; i < VERTEX_MAX_TEXTURE_COORDINATES; ++i ) + { + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pTexCoord[i], m_VertexSize_TexCoord[i] ); + } + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pTangentS, m_VertexSize_TangentS ); + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pTangentT, m_VertexSize_TangentT ); + m_pLastWrittenAddress = FindMinAddress( m_pLastWrittenAddress, m_pUserData, m_VertexSize_UserData ); +#endif +} + + +//----------------------------------------------------------------------------- +// returns the number of vertices +//----------------------------------------------------------------------------- +inline int CVertexBuilder::VertexCount() const +{ + return m_nVertexCount; +} + + +//----------------------------------------------------------------------------- +// Returns the total number of vertices across all Locks() +//----------------------------------------------------------------------------- +inline int CVertexBuilder::TotalVertexCount() const +{ + return m_nTotalVertexCount; +} + + +//----------------------------------------------------------------------------- +// Returns the base vertex memory pointer +//----------------------------------------------------------------------------- +inline void* CVertexBuilder::BaseVertexData() +{ + // FIXME: If there's no position specified, we need to find + // the base address + Assert( m_pPosition ); + return m_pPosition; +} + + +//----------------------------------------------------------------------------- +// Selects the current vertex +//----------------------------------------------------------------------------- +inline void CVertexBuilder::SelectVertex( int nIndex ) +{ + // NOTE: This index is expected to be relative + Assert( (nIndex >= 0) && (nIndex < m_nMaxVertexCount) ); + m_nCurrentVertex = nIndex; + + m_pCurrPosition = OffsetFloatPointer( m_pPosition, m_nCurrentVertex, m_VertexSize_Position ); + m_pCurrNormal = OffsetFloatPointer( m_pNormal, m_nCurrentVertex, m_VertexSize_Normal ); + + COMPILE_TIME_ASSERT( VERTEX_MAX_TEXTURE_COORDINATES == 8 ); + m_pCurrTexCoord[0] = OffsetFloatPointer( m_pTexCoord[0], m_nCurrentVertex, m_VertexSize_TexCoord[0] ); + m_pCurrTexCoord[1] = OffsetFloatPointer( m_pTexCoord[1], m_nCurrentVertex, m_VertexSize_TexCoord[1] ); + m_pCurrTexCoord[2] = OffsetFloatPointer( m_pTexCoord[2], m_nCurrentVertex, m_VertexSize_TexCoord[2] ); + m_pCurrTexCoord[3] = OffsetFloatPointer( m_pTexCoord[3], m_nCurrentVertex, m_VertexSize_TexCoord[3] ); + m_pCurrTexCoord[4] = OffsetFloatPointer( m_pTexCoord[4], m_nCurrentVertex, m_VertexSize_TexCoord[4] ); + m_pCurrTexCoord[5] = OffsetFloatPointer( m_pTexCoord[5], m_nCurrentVertex, m_VertexSize_TexCoord[5] ); + m_pCurrTexCoord[6] = OffsetFloatPointer( m_pTexCoord[6], m_nCurrentVertex, m_VertexSize_TexCoord[6] ); + m_pCurrTexCoord[7] = OffsetFloatPointer( m_pTexCoord[7], m_nCurrentVertex, m_VertexSize_TexCoord[7] ); + m_pCurrColor = m_pColor + m_nCurrentVertex * m_VertexSize_Color; + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} + + +//----------------------------------------------------------------------------- +// Advances vertex after you're done writing to it. +//----------------------------------------------------------------------------- + +template FORCEINLINE void CVertexBuilder::AdvanceVertexF() +{ + if ( ++m_nCurrentVertex > m_nVertexCount ) + { + m_nVertexCount = m_nCurrentVertex; + } + + if ( nFlags & VTX_HAVEPOS ) + IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position ); + if ( nFlags & VTX_HAVENORMAL ) + IncrementFloatPointer( m_pCurrNormal, m_VertexSize_Normal ); + if ( nFlags & VTX_HAVECOLOR ) + m_pCurrColor += m_VertexSize_Color; + + COMPILE_TIME_ASSERT( VERTEX_MAX_TEXTURE_COORDINATES == 8 ); + if ( nNumTexCoords > 0 ) + IncrementFloatPointer( m_pCurrTexCoord[0], m_VertexSize_TexCoord[0] ); + if ( nNumTexCoords > 1 ) + IncrementFloatPointer( m_pCurrTexCoord[1], m_VertexSize_TexCoord[1] ); + if ( nNumTexCoords > 2 ) + IncrementFloatPointer( m_pCurrTexCoord[2], m_VertexSize_TexCoord[2] ); + if ( nNumTexCoords > 3 ) + IncrementFloatPointer( m_pCurrTexCoord[3], m_VertexSize_TexCoord[3] ); + if ( nNumTexCoords > 4 ) + IncrementFloatPointer( m_pCurrTexCoord[4], m_VertexSize_TexCoord[4] ); + if ( nNumTexCoords > 5 ) + IncrementFloatPointer( m_pCurrTexCoord[5], m_VertexSize_TexCoord[5] ); + if ( nNumTexCoords > 6 ) + IncrementFloatPointer( m_pCurrTexCoord[6], m_VertexSize_TexCoord[6] ); + if ( nNumTexCoords > 7 ) + IncrementFloatPointer( m_pCurrTexCoord[7], m_VertexSize_TexCoord[7] ); + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} + +inline void CVertexBuilder::AdvanceVertex() +{ + AdvanceVertexF(); +} + + +inline void CVertexBuilder::AdvanceVertices( int nVerts ) +{ + m_nCurrentVertex += nVerts; + if ( m_nCurrentVertex > m_nVertexCount ) + { + m_nVertexCount = m_nCurrentVertex; + } + + IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position*nVerts ); + IncrementFloatPointer( m_pCurrNormal, m_VertexSize_Normal*nVerts ); + + COMPILE_TIME_ASSERT( VERTEX_MAX_TEXTURE_COORDINATES == 8 ); + IncrementFloatPointer( m_pCurrTexCoord[0], m_VertexSize_TexCoord[0]*nVerts ); + IncrementFloatPointer( m_pCurrTexCoord[1], m_VertexSize_TexCoord[1]*nVerts ); + IncrementFloatPointer( m_pCurrTexCoord[2], m_VertexSize_TexCoord[2]*nVerts ); + IncrementFloatPointer( m_pCurrTexCoord[3], m_VertexSize_TexCoord[3]*nVerts ); + IncrementFloatPointer( m_pCurrTexCoord[4], m_VertexSize_TexCoord[4]*nVerts ); + IncrementFloatPointer( m_pCurrTexCoord[5], m_VertexSize_TexCoord[5]*nVerts ); + IncrementFloatPointer( m_pCurrTexCoord[6], m_VertexSize_TexCoord[6]*nVerts ); + IncrementFloatPointer( m_pCurrTexCoord[7], m_VertexSize_TexCoord[7]*nVerts ); + m_pCurrColor += m_VertexSize_Color*nVerts; + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} + + +//----------------------------------------------------------------------------- +// For use with the FastVertex methods, advances the current vertex by N +//----------------------------------------------------------------------------- +inline void CVertexBuilder::FastAdvanceNVertices( int n ) +{ + m_nCurrentVertex += n; + m_nVertexCount = m_nCurrentVertex; +} + + + +#ifndef COMPILER_MSVC64 +// Implement for 64-bit Windows if needed. +//----------------------------------------------------------------------------- +// Fast Vertex! No need to call advance vertex, and no random access allowed +//----------------------------------------------------------------------------- +inline void CVertexBuilder::FastVertex( const ModelVertexDX7_t &vertex ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + +#if defined( _WIN32 ) && !defined( _X360 ) + const void *pRead = &vertex; + void *pCurrPos = m_pCurrPosition; + + __asm + { + mov esi, pRead + mov edi, pCurrPos + + movq mm0, [esi + 0] + movq mm1, [esi + 8] + movq mm2, [esi + 16] + movq mm3, [esi + 24] + movq mm4, [esi + 32] + movq mm5, [esi + 40] + + movntq [edi + 0], mm0 + movntq [edi + 8], mm1 + movntq [edi + 16], mm2 + movntq [edi + 24], mm3 + movntq [edi + 32], mm4 + movntq [edi + 40], mm5 + + emms + } +#elif defined(GNUC) + const void *pRead = &vertex; + void *pCurrPos = m_pCurrPosition; + __asm__ __volatile__ ( + "movq (%0), %%mm0\n" + "movq 8(%0), %%mm1\n" + "movq 16(%0), %%mm2\n" + "movq 24(%0), %%mm3\n" + "movq 32(%0), %%mm4\n" + "movq 40(%0), %%mm5\n" + "movntq %%mm0, (%1)\n" + "movntq %%mm1, 8(%1)\n" + "movntq %%mm2, 16(%1)\n" + "movntq %%mm3, 24(%1)\n" + "movntq %%mm4, 32(%1)\n" + "movntq %%mm5, 40(%1)\n" + "emms\n" + :: "r" (pRead), "r" (pCurrPos) : "memory"); +#else + Error( "Implement CMeshBuilder::FastVertex(dx7) "); +#endif + + IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position ); + //m_nVertexCount = ++m_nCurrentVertex; + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} + +inline void CVertexBuilder::FastVertexSSE( const ModelVertexDX7_t &vertex ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + +#if defined( _WIN32 ) && !defined( _X360 ) + const void *pRead = &vertex; + void *pCurrPos = m_pCurrPosition; + __asm + { + mov esi, pRead + mov edi, pCurrPos + + movaps xmm0, [esi + 0] + movaps xmm1, [esi + 16] + movaps xmm2, [esi + 32] + + movntps [edi + 0], xmm0 + movntps [edi + 16], xmm1 + movntps [edi + 32], xmm2 + } +#elif defined(GNUC) + const char *pRead = (char *)&vertex; + char *pCurrPos = (char *)m_pCurrPosition; + __m128 m1 = _mm_load_ps( (float *)pRead ); + __m128 m2 = _mm_load_ps( (float *)(pRead + 16) ); + __m128 m3 = _mm_load_ps( (float *)(pRead + 32) ); + _mm_stream_ps( (float *)pCurrPos, m1 ); + _mm_stream_ps( (float *)(pCurrPos + 16), m2 ); + _mm_stream_ps( (float *)(pCurrPos + 32), m3 ); +#else + Error( "Implement CMeshBuilder::FastVertexSSE(dx7)" ); +#endif + + IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position ); + //m_nVertexCount = ++m_nCurrentVertex; + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} + +inline void CVertexBuilder::Fast4VerticesSSE( + ModelVertexDX7_t const *vtx_a, + ModelVertexDX7_t const *vtx_b, + ModelVertexDX7_t const *vtx_c, + ModelVertexDX7_t const *vtx_d) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed + Assert( m_nCurrentVertex < m_nMaxVertexCount-3 ); + +#if defined( _WIN32 ) && !defined( _X360 ) + void *pCurrPos = m_pCurrPosition; + __asm + { + mov esi, vtx_a + mov ecx, vtx_b + + mov edi, pCurrPos + nop + + movaps xmm0, [esi + 0] + movaps xmm1, [esi + 16] + movaps xmm2, [esi + 32] + movaps xmm3, [ecx + 0] + movaps xmm4, [ecx + 16] + movaps xmm5, [ecx + 32] + + mov esi, vtx_c + mov ecx, vtx_d + + movntps [edi + 0], xmm0 + movntps [edi + 16], xmm1 + movntps [edi + 32], xmm2 + movntps [edi + 48], xmm3 + movntps [edi + 64], xmm4 + movntps [edi + 80], xmm5 + + movaps xmm0, [esi + 0] + movaps xmm1, [esi + 16] + movaps xmm2, [esi + 32] + movaps xmm3, [ecx + 0] + movaps xmm4, [ecx + 16] + movaps xmm5, [ecx + 32] + + movntps [edi + 0+96], xmm0 + movntps [edi + 16+96], xmm1 + movntps [edi + 32+96], xmm2 + movntps [edi + 48+96], xmm3 + movntps [edi + 64+96], xmm4 + movntps [edi + 80+96], xmm5 + + } +#else + Error( "Implement CMeshBuilder::Fast4VerticesSSE\n"); +#endif + IncrementFloatPointer( m_pCurrPosition, 4*m_VertexSize_Position ); + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} + +inline void CVertexBuilder::FastVertex( const ModelVertexDX8_t &vertex ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + +#if defined( _WIN32 ) && !defined( _X360 ) + const void *pRead = &vertex; + void *pCurrPos = m_pCurrPosition; + __asm + { + mov esi, pRead + mov edi, pCurrPos + + movq mm0, [esi + 0] + movq mm1, [esi + 8] + movq mm2, [esi + 16] + movq mm3, [esi + 24] + movq mm4, [esi + 32] + movq mm5, [esi + 40] + movq mm6, [esi + 48] + movq mm7, [esi + 56] + + movntq [edi + 0], mm0 + movntq [edi + 8], mm1 + movntq [edi + 16], mm2 + movntq [edi + 24], mm3 + movntq [edi + 32], mm4 + movntq [edi + 40], mm5 + movntq [edi + 48], mm6 + movntq [edi + 56], mm7 + + emms + } +#elif defined(GNUC) + const void *pRead = &vertex; + void *pCurrPos = m_pCurrPosition; + __asm__ __volatile__ ( + "movq (%0), %%mm0\n" + "movq 8(%0), %%mm1\n" + "movq 16(%0), %%mm2\n" + "movq 24(%0), %%mm3\n" + "movq 32(%0), %%mm4\n" + "movq 40(%0), %%mm5\n" + "movq 48(%0), %%mm6\n" + "movq 56(%0), %%mm7\n" + "movntq %%mm0, (%1)\n" + "movntq %%mm1, 8(%1)\n" + "movntq %%mm2, 16(%1)\n" + "movntq %%mm3, 24(%1)\n" + "movntq %%mm4, 32(%1)\n" + "movntq %%mm5, 40(%1)\n" + "movntq %%mm6, 48(%1)\n" + "movntq %%mm7, 56(%1)\n" + "emms\n" + :: "r" (pRead), "r" (pCurrPos) : "memory"); +#else + Error( "Implement CMeshBuilder::FastVertex(dx8)" ); +#endif + + IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position ); + // m_nVertexCount = ++m_nCurrentVertex; + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} + +inline void CVertexBuilder::FastVertexSSE( const ModelVertexDX8_t &vertex ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + +#if defined( _WIN32 ) && !defined( _X360 ) + const void *pRead = &vertex; + void *pCurrPos = m_pCurrPosition; + __asm + { + mov esi, pRead + mov edi, pCurrPos + + movaps xmm0, [esi + 0] + movaps xmm1, [esi + 16] + movaps xmm2, [esi + 32] + movaps xmm3, [esi + 48] + + movntps [edi + 0], xmm0 + movntps [edi + 16], xmm1 + movntps [edi + 32], xmm2 + movntps [edi + 48], xmm3 + } +#elif defined(GNUC) + const void *pRead = &vertex; + void *pCurrPos = m_pCurrPosition; + __asm__ __volatile__ ( + "movaps (%0), %%xmm0\n" + "movaps 16(%0), %%xmm1\n" + "movaps 32(%0), %%xmm2\n" + "movaps 48(%0), %%xmm3\n" + "movntps %%xmm0, (%1)\n" + "movntps %%xmm1, 16(%1)\n" + "movntps %%xmm2, 32(%1)\n" + "movntps %%xmm3, 48(%1)\n" + :: "r" (pRead), "r" (pCurrPos) : "memory"); +#else + Error( "Implement CMeshBuilder::FastVertexSSE((dx8)" ); +#endif + + IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position ); + // m_nVertexCount = ++m_nCurrentVertex; + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} +#endif // COMPILER_MSVC64 + + +//----------------------------------------------------------------------------- +// Returns the current vertex +//----------------------------------------------------------------------------- +inline int CVertexBuilder::GetCurrentVertex() const +{ + return m_nCurrentVertex; +} + + +//----------------------------------------------------------------------------- +// Copies a vertex into the x360 format +//----------------------------------------------------------------------------- +#if defined( _X360 ) +inline void CVertexBuilder::VertexDX8ToX360( const ModelVertexDX8_t &vertex ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // FIXME: support compressed verts if needed + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + + // get the start of the data + unsigned char *pDst = (unsigned char*)m_pCurrPosition; + + Assert( m_VertexSize_Position > 0 ); // Assume position is always present + Assert( GetVertexElementSize( VERTEX_ELEMENT_POSITION, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_vecPosition ) ); + memcpy( pDst, vertex.m_vecPosition.Base(), sizeof( vertex.m_vecPosition ) ); + pDst += sizeof( vertex.m_vecPosition ); + + if ( m_VertexSize_BoneWeight ) + { + Assert( vertex.m_flBoneWeights[0] >= 0 && vertex.m_flBoneWeights[0] <= 1.0f ); + Assert( vertex.m_flBoneWeights[1] >= 0 && vertex.m_flBoneWeights[1] <= 1.0f ); + Assert( GetVertexElementSize( VERTEX_ELEMENT_BONEWEIGHTS2, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_flBoneWeights ) ); + memcpy( pDst, vertex.m_flBoneWeights.Base(), sizeof( vertex.m_flBoneWeights ) ); + pDst += sizeof( vertex.m_flBoneWeights ); + + if ( m_VertexSize_BoneMatrixIndex ) + { + Assert( GetVertexElementSize( VERTEX_ELEMENT_BONEINDEX, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_nBoneIndices ) ); + *(unsigned int*)pDst = vertex.m_nBoneIndices; + pDst += sizeof( vertex.m_nBoneIndices ); + } + } + + if ( m_VertexSize_Normal ) + { + Assert( GetVertexElementSize( VERTEX_ELEMENT_NORMAL, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_vecNormal ) ); + memcpy( pDst, vertex.m_vecNormal.Base(), sizeof( vertex.m_vecNormal ) ); + pDst += sizeof( vertex.m_vecNormal ); + } + + if ( m_VertexSize_Color ) + { + Assert( GetVertexElementSize( VERTEX_ELEMENT_COLOR, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_nColor ) ); + *(unsigned int*)pDst = vertex.m_nColor; + pDst += sizeof( vertex.m_nColor ); + } + + if ( m_VertexSize_TexCoord[0] ) + { + Assert( GetVertexElementSize( VERTEX_ELEMENT_TEXCOORD2D_0, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_vecTexCoord ) ); + memcpy( pDst, vertex.m_vecTexCoord.Base(), sizeof( vertex.m_vecTexCoord ) ); + pDst += sizeof( vertex.m_vecTexCoord ); + } + + if ( m_VertexSize_UserData ) + { + Assert( GetVertexElementSize( VERTEX_ELEMENT_USERDATA4, VERTEX_COMPRESSION_NONE ) == sizeof( vertex.m_vecUserData ) ); + memcpy( pDst, vertex.m_vecUserData.Base(), sizeof( vertex.m_vecUserData ) ); + pDst += sizeof( vertex.m_vecUserData ); + } + + // ensure code is synced with the mesh builder that established the offsets + Assert( pDst - (unsigned char*)m_pCurrPosition == m_VertexSize_Position ); + + IncrementFloatPointer( m_pCurrPosition, m_VertexSize_Position ); + +#if ( defined( _DEBUG ) && ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) ) + m_bWrittenNormal = false; + m_bWrittenUserData = false; +#endif +} +#endif + + +//----------------------------------------------------------------------------- +// Data retrieval... +//----------------------------------------------------------------------------- +inline const float* CVertexBuilder::Position() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return m_pCurrPosition; +} + +inline const float* CVertexBuilder::Normal() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return m_pCurrNormal; +} + +inline unsigned int CVertexBuilder::Color() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + // Swizzle it so it returns the same format as accepted by Color4ubv - rgba + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + unsigned int color; + if ( IsPC() || !IsX360() ) + { + color = (m_pCurrColor[3] << 24) | (m_pCurrColor[0] << 16) | (m_pCurrColor[1] << 8) | (m_pCurrColor[2]); + } + else + { + // in memory as argb, back to rgba + color = (m_pCurrColor[1] << 24) | (m_pCurrColor[2] << 16) | (m_pCurrColor[3] << 8) | (m_pCurrColor[0]); + } + return color; +} + +inline unsigned char *CVertexBuilder::Specular() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return m_pSpecular + m_nCurrentVertex * m_VertexSize_Specular; +} + +inline const float* CVertexBuilder::TexCoord( int stage ) const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return m_pCurrTexCoord[stage]; +} + +inline const float* CVertexBuilder::TangentS() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return OffsetFloatPointer( m_pTangentS, m_nCurrentVertex, m_VertexSize_TangentS ); +} + +inline const float* CVertexBuilder::TangentT() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return OffsetFloatPointer( m_pTangentT, m_nCurrentVertex, m_VertexSize_TangentT ); +} + +inline float CVertexBuilder::Wrinkle() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return *OffsetFloatPointer( m_pWrinkle, m_nCurrentVertex, m_VertexSize_Wrinkle ); +} + +inline const float* CVertexBuilder::BoneWeight() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return OffsetFloatPointer( m_pBoneWeight, m_nCurrentVertex, m_VertexSize_BoneWeight ); +} + +inline int CVertexBuilder::NumBoneWeights() const +{ + return m_NumBoneWeights; +} + +#ifndef NEW_SKINNING +inline unsigned char* CVertexBuilder::BoneMatrix() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return m_pBoneMatrixIndex + m_nCurrentVertex * m_VertexSize_BoneMatrixIndex; +} +#else +inline float* CVertexBuilder::BoneMatrix() const +{ + // FIXME: add a templatized accessor (return type varies to ensure calling code is updated appropriately) + // for code that needs to access compressed data (and/or a return-by-value templatized accessor) + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); + Assert( m_nCurrentVertex < m_nMaxVertexCount ); + return m_pBoneMatrixIndex + m_nCurrentVertex * m_VertexSize_BoneMatrixIndex; +} +#endif + + +//----------------------------------------------------------------------------- +// Position setting methods +//----------------------------------------------------------------------------- +inline void CVertexBuilder::Position3f( float x, float y, float z ) +{ + Assert( m_pPosition && m_pCurrPosition ); + Assert( IsFinite(x) && IsFinite(y) && IsFinite(z) ); + float *pDst = m_pCurrPosition; + *pDst++ = x; + *pDst++ = y; + *pDst = z; +} + +inline void CVertexBuilder::Position3fv( const float *v ) +{ + Assert(v); + Assert( m_pPosition && m_pCurrPosition ); + + float *pDst = m_pCurrPosition; + *pDst++ = *v++; + *pDst++ = *v++; + *pDst = *v; +} + + +//----------------------------------------------------------------------------- +// Normal setting methods +//----------------------------------------------------------------------------- +inline void CVertexBuilder::Normal3f( float nx, float ny, float nz ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // Use the templatized version if you want to support compression + Assert( m_pNormal ); + Assert( IsFinite(nx) && IsFinite(ny) && IsFinite(nz) ); + Assert( nx >= -1.05f && nx <= 1.05f ); + Assert( ny >= -1.05f && ny <= 1.05f ); + Assert( nz >= -1.05f && nz <= 1.05f ); + + float *pDst = m_pCurrNormal; + *pDst++ = nx; + *pDst++ = ny; + *pDst = nz; +} + +inline void CVertexBuilder::Normal3fv( const float *n ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // Use the templatized version if you want to support compression + Assert( n ); + Assert( m_pNormal && m_pCurrNormal ); + Assert( IsFinite(n[0]) && IsFinite(n[1]) && IsFinite(n[2]) ); + Assert( n[0] >= -1.05f && n[0] <= 1.05f ); + Assert( n[1] >= -1.05f && n[1] <= 1.05f ); + Assert( n[2] >= -1.05f && n[2] <= 1.05f ); + + float *pDst = m_pCurrNormal; + *pDst++ = *n++; + *pDst++ = *n++; + *pDst = *n; +} + +inline void CVertexBuilder::NormalDelta3f( float nx, float ny, float nz ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // Use the templatized version if you want to support compression + Assert( m_pNormal ); + Assert( IsFinite(nx) && IsFinite(ny) && IsFinite(nz) ); + + float *pDst = m_pCurrNormal; + *pDst++ = nx; + *pDst++ = ny; + *pDst = nz; +} + +inline void CVertexBuilder::NormalDelta3fv( const float *n ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // Use the templatized version if you want to support compression + Assert( n ); + Assert( m_pNormal && m_pCurrNormal ); + Assert( IsFinite(n[0]) && IsFinite(n[1]) && IsFinite(n[2]) ); + + float *pDst = m_pCurrNormal; + *pDst++ = *n++; + *pDst++ = *n++; + *pDst = *n; +} + +//----------------------------------------------------------------------------- +// Templatized normal setting methods which support compressed vertices +//----------------------------------------------------------------------------- +template inline void CVertexBuilder::CompressedNormal3f( float nx, float ny, float nz ) +{ + Assert( T == m_CompressionType ); + Assert( m_pNormal && m_pCurrNormal ); + Assert( IsFinite(nx) && IsFinite(ny) && IsFinite(nz) ); + Assert( nx >= -1.05f && nx <= 1.05f ); + Assert( ny >= -1.05f && ny <= 1.05f ); + Assert( nz >= -1.05f && nz <= 1.05f ); + // FIXME: studiorender is passing in non-unit normals + //float lengthSqd = nx*nx + ny*ny + nz*nz; + //Assert( lengthSqd >= 0.95f && lengthSqd <= 1.05f ); + + if ( T == VERTEX_COMPRESSION_ON ) + { +#if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 ) + PackNormal_SHORT2( nx, ny, nz, (unsigned int *)m_pCurrNormal ); + +#else //( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) + // NOTE: write the normal into the lower 16 bits of a word, clearing the top 16 bits - a userdata4 + // tangent must be written into the upper 16 bits by CompressedUserData() *AFTER* this. +#ifdef _DEBUG + Assert( m_bWrittenUserData == false ); + m_bWrittenNormal = true; +#endif + PackNormal_UBYTE4( nx, ny, nz, (unsigned int *)m_pCurrNormal ); +#endif + } + else + { + float *pDst = m_pCurrNormal; + *pDst++ = nx; + *pDst++ = ny; + *pDst = nz; + } +} + +template inline void CVertexBuilder::CompressedNormal3fv( const float *n ) +{ + Assert( n ); + CompressedNormal3f( n[0], n[1], n[2] ); +} + + +//----------------------------------------------------------------------------- +// Color setting methods +//----------------------------------------------------------------------------- +inline void CVertexBuilder::Color3f( float r, float g, float b ) +{ + Assert( m_pColor && m_pCurrColor ); + Assert( IsFinite(r) && IsFinite(g) && IsFinite(b) ); + Assert( (r >= 0.0) && (g >= 0.0) && (b >= 0.0) ); + Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) ); + +#ifdef OPENGL_SWAP_COLORS + int col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | 0xFF000000; +#else + int col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | 0xFF000000; +#endif + *(int*)m_pCurrColor = col; +} + +inline void CVertexBuilder::Color3fv( const float *rgb ) +{ + Assert(rgb); + Assert( m_pColor && m_pCurrColor ); + Assert( IsFinite(rgb[0]) && IsFinite(rgb[1]) && IsFinite(rgb[2]) ); + Assert( (rgb[0] >= 0.0) && (rgb[1] >= 0.0) && (rgb[2] >= 0.0) ); + Assert( (rgb[0] <= 1.0) && (rgb[1] <= 1.0) && (rgb[2] <= 1.0) ); + +#ifdef OPENGL_SWAP_COLORS + int col = (FastFToC(rgb[0])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[2]) << 16) | 0xFF000000; +#else + int col = (FastFToC(rgb[2])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[0]) << 16) | 0xFF000000; +#endif + *(int*)m_pCurrColor = col; +} + +inline void CVertexBuilder::Color4f( float r, float g, float b, float a ) +{ + Assert( m_pColor && m_pCurrColor ); + Assert( IsFinite(r) && IsFinite(g) && IsFinite(b) && IsFinite(a) ); + Assert( (r >= 0.0) && (g >= 0.0) && (b >= 0.0) && (a >= 0.0) ); + Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) && (a <= 1.0) ); + +#ifdef OPENGL_SWAP_COLORS + int col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | (FastFToC(a) << 24); +#else + int col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | (FastFToC(a) << 24); +#endif + *(int*)m_pCurrColor = col; +} + +inline void CVertexBuilder::Color4fv( const float *rgba ) +{ + Assert(rgba); + Assert( m_pColor && m_pCurrColor ); + Assert( IsFinite(rgba[0]) && IsFinite(rgba[1]) && IsFinite(rgba[2]) && IsFinite(rgba[3]) ); + Assert( (rgba[0] >= 0.0) && (rgba[1] >= 0.0) && (rgba[2] >= 0.0) && (rgba[3] >= 0.0) ); + Assert( (rgba[0] <= 1.0) && (rgba[1] <= 1.0) && (rgba[2] <= 1.0) && (rgba[3] <= 1.0) ); + +#ifdef OPENGL_SWAP_COLORS + int col = (FastFToC(rgba[0])) | (FastFToC(rgba[1]) << 8) | (FastFToC(rgba[2]) << 16) | (FastFToC(rgba[3]) << 24); +#else + int col = (FastFToC(rgba[2])) | (FastFToC(rgba[1]) << 8) | (FastFToC(rgba[0]) << 16) | (FastFToC(rgba[3]) << 24); +#endif + *(int*)m_pCurrColor = col; +} + + +//----------------------------------------------------------------------------- +// Faster versions of color +//----------------------------------------------------------------------------- + +// note that on the OSX target (OpenGL) whenever there is vertex data being written as bytes - they need to be written in R,G,B,A memory order + +inline void CVertexBuilder::Color3ub( unsigned char r, unsigned char g, unsigned char b ) +{ + Assert( m_pColor && m_pCurrColor ); + #ifdef OPENGL_SWAP_COLORS + int col = r | (g << 8) | (b << 16) | 0xFF000000; // r, g, b, a in memory + #else + int col = b | (g << 8) | (r << 16) | 0xFF000000; + #endif + + *(int*)m_pCurrColor = col; +} + +inline void CVertexBuilder::Color3ubv( unsigned char const* rgb ) +{ + Assert(rgb); + Assert( m_pColor && m_pCurrColor ); + #ifdef OPENGL_SWAP_COLORS + int col = rgb[0] | (rgb[1] << 8) | (rgb[2] << 16) | 0xFF000000; // r, g, b, a in memory + #else + int col = rgb[2] | (rgb[1] << 8) | (rgb[0] << 16) | 0xFF000000; + #endif + + *(int*)m_pCurrColor = col; +} + +inline void CVertexBuilder::Color4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) +{ + Assert( m_pColor && m_pCurrColor ); + #ifdef OPENGL_SWAP_COLORS + int col = r | (g << 8) | (b << 16) | (a << 24); // r, g, b, a in memory + #else + int col = b | (g << 8) | (r << 16) | (a << 24); + #endif + + *(int*)m_pCurrColor = col; +} + +inline void CVertexBuilder::Color4ubv( unsigned char const* rgba ) +{ + Assert( rgba ); + Assert( m_pColor && m_pCurrColor ); + #ifdef OPENGL_SWAP_COLORS + int col = rgba[0] | (rgba[1] << 8) | (rgba[2] << 16) | (rgba[3] << 24); // r, g, b, a in memory + #else + int col = rgba[2] | (rgba[1] << 8) | (rgba[0] << 16) | (rgba[3] << 24); + #endif + *(int*)m_pCurrColor = col; +} + +inline void CVertexBuilder::Specular3f( float r, float g, float b ) +{ + Assert( m_pSpecular ); + Assert( IsFinite(r) && IsFinite(g) && IsFinite(b) ); + Assert( (r >= 0.0) && (g >= 0.0) && (b >= 0.0) ); + Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) ); + + unsigned char* pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; +#ifdef OPENGL_SWAP_COLORS + int col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | 0xFF000000; +#else + int col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | 0xFF000000; +#endif + *(int*)pSpecular = col; +} + +inline void CVertexBuilder::Specular3fv( const float *rgb ) +{ + Assert(rgb); + Assert( m_pSpecular ); + Assert( IsFinite(rgb[0]) && IsFinite(rgb[1]) && IsFinite(rgb[2]) ); + Assert( (rgb[0] >= 0.0) && (rgb[1] >= 0.0) && (rgb[2] >= 0.0) ); + Assert( (rgb[0] <= 1.0) && (rgb[1] <= 1.0) && (rgb[2] <= 1.0) ); + + unsigned char* pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; +#ifdef OPENGL_SWAP_COLORS + int col = (FastFToC(rgb[0])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[2]) << 16) | 0xFF000000; +#else + int col = (FastFToC(rgb[2])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[0]) << 16) | 0xFF000000; +#endif + *(int*)pSpecular = col; +} + +inline void CVertexBuilder::Specular4f( float r, float g, float b, float a ) +{ + Assert( m_pSpecular ); + Assert( IsFinite(r) && IsFinite(g) && IsFinite(b) && IsFinite(a) ); + Assert( (r >= 0.0) && (g >= 0.0) && (b >= 0.0) && (a >= 0.0) ); + Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) && (a <= 1.0f) ); + + unsigned char* pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; +#ifdef OPENGL_SWAP_COLORS + int col = (FastFToC(r)) | (FastFToC(g) << 8) | (FastFToC(b) << 16) | (FastFToC(a) << 24); +#else + int col = (FastFToC(b)) | (FastFToC(g) << 8) | (FastFToC(r) << 16) | (FastFToC(a) << 24); +#endif + *(int*)pSpecular = col; +} + +inline void CVertexBuilder::Specular4fv( const float *rgb ) +{ + Assert(rgb); + Assert( m_pSpecular ); + Assert( IsFinite(rgb[0]) && IsFinite(rgb[1]) && IsFinite(rgb[2]) && IsFinite(rgb[3]) ); + Assert( (rgb[0] >= 0.0) && (rgb[1] >= 0.0) && (rgb[2] >= 0.0) && (rgb[3] >= 0.0) ); + Assert( (rgb[0] <= 1.0) && (rgb[1] <= 1.0) && (rgb[2] <= 1.0) && (rgb[3] <= 1.0) ); + + unsigned char* pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; +#ifdef OPENGL_SWAP_COLORS + int col = (FastFToC(rgb[0])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[2]) << 16) | (FastFToC(rgb[3]) << 24); +#else + int col = (FastFToC(rgb[2])) | (FastFToC(rgb[1]) << 8) | (FastFToC(rgb[0]) << 16) | (FastFToC(rgb[3]) << 24); +#endif + *(int*)pSpecular = col; +} + +inline void CVertexBuilder::Specular3ub( unsigned char r, unsigned char g, unsigned char b ) +{ + Assert( m_pSpecular ); + unsigned char *pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; + + #ifdef OPENGL_SWAP_COLORS + int col = r | (g << 8) | (b << 16) | 0xFF000000; // r, g, b, a in memory + #else + int col = b | (g << 8) | (r << 16) | 0xFF000000; + #endif + + *(int*)pSpecular = col; +} + +inline void CVertexBuilder::Specular3ubv( unsigned char const *c ) +{ + Assert( m_pSpecular ); + unsigned char *pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; + + #ifdef OPENGL_SWAP_COLORS + int col = c[0] | (c[1] << 8) | (c[2] << 16) | 0xFF000000; // r, g, b, a in memory + #else + int col = c[2] | (c[1] << 8) | (c[0] << 16) | 0xFF000000; + #endif + + *(int*)pSpecular = col; +} + +inline void CVertexBuilder::Specular4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) +{ + Assert( m_pSpecular ); + unsigned char *pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; + + #ifdef OPENGL_SWAP_COLORS + int col = r | (g << 8) | (b << 16) | (a << 24); // r, g, b, a in memory + #else + int col = b | (g << 8) | (r << 16) | (a << 24); + #endif + + *(int*)pSpecular = col; +} + +inline void CVertexBuilder::Specular4ubv( unsigned char const *c ) +{ + Assert( m_pSpecular ); + unsigned char *pSpecular = &m_pSpecular[m_nCurrentVertex * m_VertexSize_Specular]; + + #ifdef OPENGL_SWAP_COLORS + int col = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24); + #else + int col = c[2] | (c[1] << 8) | (c[0] << 16) | (c[3] << 24); + #endif + + *(int*)pSpecular = col; +} + + +//----------------------------------------------------------------------------- +// Texture coordinate setting methods +//----------------------------------------------------------------------------- +inline void CVertexBuilder::TexCoord1f( int nStage, float s ) +{ + Assert( m_pTexCoord[nStage] && m_pCurrTexCoord[nStage] ); + Assert( IsFinite(s) ); + + float *pDst = m_pCurrTexCoord[nStage]; + *pDst = s; +} + +inline void CVertexBuilder::TexCoord2f( int nStage, float s, float t ) +{ + Assert( m_pTexCoord[nStage] && m_pCurrTexCoord[nStage] ); + Assert( IsFinite(s) && IsFinite(t) ); + + float *pDst = m_pCurrTexCoord[nStage]; + *pDst++ = s; + *pDst = t; +} + +inline void CVertexBuilder::TexCoord2fv( int nStage, const float *st ) +{ + Assert(st); + Assert( m_pTexCoord[nStage] && m_pCurrTexCoord[nStage] ); + Assert( IsFinite(st[0]) && IsFinite(st[1]) ); + + float *pDst = m_pCurrTexCoord[nStage]; + *pDst++ = *st++; + *pDst = *st; +} + +inline void CVertexBuilder::TexCoord3f( int stage, float s, float t, float u ) +{ + // Tried to add too much! + Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] ); + Assert( IsFinite(s) && IsFinite(t) && IsFinite(u) ); + float *pDst = m_pCurrTexCoord[stage]; + *pDst++ = s; + *pDst++ = t; + *pDst = u; +} + +inline void CVertexBuilder::TexCoord3fv( int stage, const float *stu ) +{ + Assert(stu); + Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] ); + Assert( IsFinite(stu[0]) && IsFinite(stu[1]) && IsFinite(stu[2]) ); + + float *pDst = m_pCurrTexCoord[stage]; + *pDst++ = *stu++; + *pDst++ = *stu++; + *pDst = *stu; +} + +inline void CVertexBuilder::TexCoord4f( int stage, float s, float t, float u, float v ) +{ + // Tried to add too much! + Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] ); + Assert( IsFinite(s) && IsFinite(t) && IsFinite(u) ); + float *pDst = m_pCurrTexCoord[stage]; + *pDst++ = s; + *pDst++ = t; + *pDst++ = u; + *pDst = v; +} + +inline void CVertexBuilder::TexCoord4fv( int stage, const float *stuv ) +{ + Assert(stuv); + Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] ); + Assert( IsFinite(stuv[0]) && IsFinite(stuv[1]) && IsFinite(stuv[2]) ); + + float *pDst = m_pCurrTexCoord[stage]; + *pDst++ = *stuv++; + *pDst++ = *stuv++; + *pDst++ = *stuv++; + *pDst = *stuv; +} + + +inline void CVertexBuilder::TexCoordSubRect2f( int stage, float s, float t, float offsetS, float offsetT, float scaleS, float scaleT ) +{ + Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] ); + Assert( IsFinite(s) && IsFinite(t) ); + + float *pDst = m_pCurrTexCoord[stage]; + *pDst++ = ( s * scaleS ) + offsetS; + *pDst = ( t * scaleT ) + offsetT; +} + +inline void CVertexBuilder::TexCoordSubRect2fv( int stage, const float *st, const float *offset, const float *scale ) +{ + Assert(st); + Assert( m_pTexCoord[stage] && m_pCurrTexCoord[stage] ); + Assert( IsFinite(st[0]) && IsFinite(st[1]) ); + + float *pDst = m_pCurrTexCoord[stage]; + *pDst++ = ( *st++ * *scale++ ) + *offset++; + *pDst = ( *st * *scale ) + *offset; +} + + +//----------------------------------------------------------------------------- +// Tangent space setting methods +//----------------------------------------------------------------------------- +inline void CVertexBuilder::TangentS3f( float sx, float sy, float sz ) +{ + Assert( m_pTangentS ); + Assert( IsFinite(sx) && IsFinite(sy) && IsFinite(sz) ); + + float* pTangentS = OffsetFloatPointer( m_pTangentS, m_nCurrentVertex, m_VertexSize_TangentS ); + *pTangentS++ = sx; + *pTangentS++ = sy; + *pTangentS = sz; +} + +inline void CVertexBuilder::TangentS3fv( const float* s ) +{ + Assert( s ); + Assert( m_pTangentS ); + Assert( IsFinite(s[0]) && IsFinite(s[1]) && IsFinite(s[2]) ); + + float* pTangentS = OffsetFloatPointer( m_pTangentS, m_nCurrentVertex, m_VertexSize_TangentS ); + *pTangentS++ = *s++; + *pTangentS++ = *s++; + *pTangentS = *s; +} + +inline void CVertexBuilder::TangentT3f( float tx, float ty, float tz ) +{ + Assert( m_pTangentT ); + Assert( IsFinite(tx) && IsFinite(ty) && IsFinite(tz) ); + + float* pTangentT = OffsetFloatPointer( m_pTangentT, m_nCurrentVertex, m_VertexSize_TangentT ); + *pTangentT++ = tx; + *pTangentT++ = ty; + *pTangentT = tz; +} + +inline void CVertexBuilder::TangentT3fv( const float* t ) +{ + Assert( t ); + Assert( m_pTangentT ); + Assert( IsFinite(t[0]) && IsFinite(t[1]) && IsFinite(t[2]) ); + + float* pTangentT = OffsetFloatPointer( m_pTangentT, m_nCurrentVertex, m_VertexSize_TangentT ); + *pTangentT++ = *t++; + *pTangentT++ = *t++; + *pTangentT = *t; +} + + +//----------------------------------------------------------------------------- +// Wrinkle setting methods +//----------------------------------------------------------------------------- +inline void CVertexBuilder::Wrinkle1f( float flWrinkle ) +{ + Assert( m_pWrinkle ); + Assert( IsFinite(flWrinkle) ); + + float *pWrinkle = OffsetFloatPointer( m_pWrinkle, m_nCurrentVertex, m_VertexSize_Wrinkle ); + *pWrinkle = flWrinkle; +} + + +//----------------------------------------------------------------------------- +// Bone weight setting methods +//----------------------------------------------------------------------------- +inline void CVertexBuilder::BoneWeight( int idx, float weight ) +{ + Assert( m_pBoneWeight ); + Assert( IsFinite( weight ) ); + Assert( idx >= 0 ); + AssertOnce( m_NumBoneWeights == 2 ); + + // This test is here because we store N-1 bone weights (the Nth is computed in + // the vertex shader as "1 - C", where C is the sum of the (N-1) other weights) + if ( idx < m_NumBoneWeights ) + { + float* pBoneWeight = OffsetFloatPointer( m_pBoneWeight, m_nCurrentVertex, m_VertexSize_BoneWeight ); + pBoneWeight[idx] = weight; + } +} + +static int sg_IndexSwap[4] = { 2, 1, 0, 3 }; + +inline void CVertexBuilder::BoneMatrix( int idx, int matrixIdx ) +{ + Assert( m_pBoneMatrixIndex ); + Assert( idx >= 0 ); + Assert( idx < 4 ); + + // garymcthack + if ( matrixIdx == BONE_MATRIX_INDEX_INVALID ) + { + matrixIdx = 0; + } + Assert( (matrixIdx >= 0) && (matrixIdx < 53) ); + +#ifdef OPENGL_SWAP_COLORS + idx = sg_IndexSwap[idx]; +#endif + +#ifndef NEW_SKINNING + unsigned char* pBoneMatrix = &m_pBoneMatrixIndex[m_nCurrentVertex * m_VertexSize_BoneMatrixIndex]; + if ( IsX360() ) + { + // store sequentially as wzyx order, gpu delivers as xyzw + idx = 3-idx; + } + pBoneMatrix[idx] = (unsigned char)matrixIdx; +#else + float* pBoneMatrix = &m_pBoneMatrixIndex[m_nCurrentVertex * m_VertexSize_BoneMatrixIndex]; + pBoneMatrix[idx] = matrixIdx; +#endif +} + +//----------------------------------------------------------------------------- +// Templatized bone weight setting methods which support compressed vertices +//----------------------------------------------------------------------------- +template inline void CVertexBuilder::CompressedBoneWeight3fv( const float * pWeights ) +{ + Assert( T == m_CompressionType ); + Assert( m_pBoneWeight ); + Assert( pWeights ); + + float *pDestWeights = OffsetFloatPointer( m_pBoneWeight, m_nCurrentVertex, m_VertexSize_BoneWeight ); + + if ( T == VERTEX_COMPRESSION_ON ) + { + // Quantize to 15 bits per weight (we use D3DDECLTYPE_SHORT2) + // NOTE: we perform careful normalization (weights sum to 1.0f in the vertex shader), so + // as to avoid cracking at boundaries between meshes with different numbers of weights + // per vertex. For example, (1) needs to yield the same normalized weights as (1,0), + // and (0.5,0.49) needs to normalize the same normalized weights as (0.5,0.49,0). + // The key is that values which are *computed* in the shader (e.g. the second weight + // in a 2-weight mesh) must exactly equal values which are *read* from the vertex + // stream (e.g. the second weight in a 3-weight mesh). + + // Only 1 or 2 weights (SHORT2N) supported for compressed verts so far + Assert( m_NumBoneWeights <= 2 ); + + const int WEIGHT0_SHIFT = IsX360() ? 16 : 0; + const int WEIGHT1_SHIFT = IsX360() ? 0 : 16; + unsigned int *weights = (unsigned int *)pDestWeights; + + // We scale our weights so that they sum to 32768, then subtract 1 (which gets added + // back in the shader), because dividing by 32767 introduces nasty rounding issues. + Assert( IsFinite( pWeights[0] ) && ( pWeights[0] >= 0.0f ) && ( pWeights[0] <= 1.0f ) ); + unsigned int weight0 = Float2Int( pWeights[0] * 32768.0f ); + *weights = ( 0x0000FFFF & (weight0 - 1) ) << WEIGHT0_SHIFT; + +#ifdef DEBUG + if ( m_NumBoneWeights == 1 ) + { + // Double-check the validity of the values that were passed in + Assert( IsFinite( pWeights[1] ) && ( pWeights[1] >= 0.0f ) && ( pWeights[1] <= 1.0f ) ); + unsigned int weight1 = Float2Int( pWeights[1] * 32768.0f ); + Assert( ( weight0 + weight1 ) <= 32768 ); + } +#endif + + if ( m_NumBoneWeights > 1 ) + { + // This path for 3 weights per vert (2 are stored and the 3rd is computed + // in the shader - we do post-quantization normalization here in such a + // way as to avoid mesh-boundary cracking) + Assert( m_NumBoneWeights == 2 ); + Assert( IsFinite( pWeights[1] ) && ( pWeights[1] >= 0.0f ) && ( pWeights[1] <= 1.0f ) ); + Assert( IsFinite( pWeights[2] ) && ( pWeights[2] >= 0.0f ) && ( pWeights[2] <= 1.0f ) ); + unsigned int weight1 = Float2Int( pWeights[1] * 32768.0f ); + unsigned int weight2 = Float2Int( pWeights[2] * 32768.0f ); + Assert( ( weight0 + weight1 + weight2 ) <= 32768 ); + unsigned int residual = 32768 - ( weight0 + weight1 + weight2 ); + weight1 += residual; // Normalize + *weights |= ( 0x0000FFFF & ( weight1 - 1 ) ) << WEIGHT1_SHIFT; + } + } + else // Uncompressed path + { + pDestWeights[0] = pWeights[0]; + pDestWeights[1] = pWeights[1]; + } +} + +//----------------------------------------------------------------------------- +// Generic per-vertex data setting method +//----------------------------------------------------------------------------- +inline void CVertexBuilder::UserData( const float* pData ) +{ + Assert( m_CompressionType == VERTEX_COMPRESSION_NONE ); // Use the templatized version if you want to support compression + Assert( pData ); + + int userDataSize = 4; // garymcthack + float *pUserData = OffsetFloatPointer( m_pUserData, m_nCurrentVertex, m_VertexSize_UserData ); + memcpy( pUserData, pData, sizeof( float ) * userDataSize ); +} + +//----------------------------------------------------------------------------- +// Templatized generic per-vertex data setting method which supports compressed vertices +//----------------------------------------------------------------------------- +template inline void CVertexBuilder::CompressedUserData( const float* pData ) +{ + Assert( T == m_CompressionType ); + Assert( pData ); + // This is always in fact a tangent vector, not generic 'userdata' + Assert( IsFinite(pData[0]) && IsFinite(pData[1]) && IsFinite(pData[2]) ); + Assert( pData[0] >= -1.05f && pData[0] <= 1.05f ); + Assert( pData[1] >= -1.05f && pData[1] <= 1.05f ); + Assert( pData[2] >= -1.05f && pData[2] <= 1.05f ); + Assert( pData[3] == +1.0f || pData[3] == -1.0f ); + // FIXME: studiorender is passing in non-unit normals + //float lengthSqd = pData[0]*pData[0] + pData[1]*pData[1] + pData[2]*pData[2]; + //Assert( lengthSqd >= 0.95f && lengthSqd <= 1.05f ); + + if ( T == VERTEX_COMPRESSION_ON ) + { + float binormalSign = pData[3]; + +#if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 ) + float *pUserData = OffsetFloatPointer( m_pUserData, m_nCurrentVertex, m_VertexSize_UserData ); + PackNormal_SHORT2( pData, (unsigned int *)pUserData, binormalSign ); +#else //( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 ) + // FIXME: add a combined CompressedNormalAndTangent() accessor, to avoid reading back from write-combined memory here + // The normal should have already been written into the lower 16 + // bits - here, we OR in the tangent into the upper 16 bits + unsigned int existingNormalData = *(unsigned int *)m_pCurrNormal; + Assert( ( existingNormalData & 0xFFFF0000 ) == 0 ); +#ifdef _DEBUG + Assert( m_bWrittenNormal == true ); + m_bWrittenUserData = true; +#endif + bool bIsTangent = true; + unsigned int tangentData = 0; + PackNormal_UBYTE4( pData, &tangentData, bIsTangent, binormalSign ); + *(unsigned int *)m_pCurrNormal = existingNormalData | tangentData; +#endif + } + else + { + int userDataSize = 4; // garymcthack + float *pUserData = OffsetFloatPointer( m_pUserData, m_nCurrentVertex, m_VertexSize_UserData ); + memcpy( pUserData, pData, sizeof( float ) * userDataSize ); + } +} + + +//----------------------------------------------------------------------------- +// +// Helper class used to define index buffers +// +//----------------------------------------------------------------------------- +class CIndexBuilder : private IndexDesc_t +{ +public: + CIndexBuilder(); + CIndexBuilder( IIndexBuffer *pIndexBuffer, MaterialIndexFormat_t fmt = MATERIAL_INDEX_FORMAT_UNKNOWN ); + ~CIndexBuilder(); + + // Begins, ends modification of the index buffer (returns true if the lock succeeded) + // A lock may not succeed if append is set to true and there isn't enough room + // NOTE: Append is only used with dynamic index buffers; it's ignored for static buffers + bool Lock( int nMaxIndexCount, int nIndexOffset, bool bAppend = false ); + void Unlock(); + + // Spews the current data + // NOTE: Can only be called during a lock/unlock block + void SpewData(); + + // Returns the number of indices we can fit into the buffer without needing to discard + int GetRoomRemaining() const; + + // Binds this index buffer + void Bind( IMatRenderContext *pContext ); + + // Returns the byte offset + int Offset() const; + + // Begins, ends modification of the index buffer + // NOTE: IndexOffset is the number to add to all indices written into the buffer; + // useful when using dynamic vertex buffers. + void Begin( IIndexBuffer *pIndexBuffer, int nMaxIndexCount, int nIndexOffset = 0 ); + void End( bool bSpewData = false ); + + // Locks the index buffer to modify existing data + // Passing nVertexCount == -1 says to lock all the vertices for modification. + // Pass 0 for nIndexCount to not lock the index buffer. + void BeginModify( IIndexBuffer *pIndexBuffer, int nFirstIndex = 0, int nIndexCount = 0, int nIndexOffset = 0 ); + void EndModify( bool bSpewData = false ); + + // returns the number of indices + int IndexCount() const; + + // Returns the total number of indices across all Locks() + int TotalIndexCount() const; + + // Resets the mesh builder so it points to the start of everything again + void Reset(); + + // Selects the nth Index + void SelectIndex( int nBufferIndex ); + + // Advances the current index by one + void AdvanceIndex(); + void AdvanceIndices( int nIndexCount ); + + int GetCurrentIndex(); + int GetFirstIndex() const; + + unsigned short const* Index() const; + + // Used to define the indices (only used if you aren't using primitives) + void Index( unsigned short nIndex ); + + // Fast Index! No need to call advance index, and no random access allowed + void FastIndex( unsigned short nIndex ); + + // NOTE: This version is the one you really want to achieve write-combining; + // Write combining only works if you write in 4 bytes chunks. + void FastIndex2( unsigned short nIndex1, unsigned short nIndex2 ); + + // Generates indices for a particular primitive type + void GenerateIndices( MaterialPrimitiveType_t primitiveType, int nIndexCount ); + + // FIXME: Remove! Backward compat so we can use this from a CMeshBuilder. + void AttachBegin( IMesh* pMesh, int nMaxIndexCount, const MeshDesc_t &desc ); + void AttachEnd(); + void AttachBeginModify( IMesh* pMesh, int nFirstIndex, int nIndexCount, const MeshDesc_t &desc ); + void AttachEndModify(); + + void FastTriangle( int startVert ); + void FastQuad( int startVert ); + void FastPolygon( int startVert, int numTriangles ); + void FastPolygonList( int startVert, int *pVertexCount, int polygonCount ); + void FastIndexList( const unsigned short *pIndexList, int startVert, int indexCount ); + +private: + // The mesh we're modifying + IIndexBuffer *m_pIndexBuffer; + + // Max number of indices + int m_nMaxIndexCount; + + // Number of indices + int m_nIndexCount; + + // Offset to add to each index as it's written into the buffer + int m_nIndexOffset; + + // The current index + mutable int m_nCurrentIndex; + + // Total number of indices appended + int m_nTotalIndexCount; + + // First index buffer offset + first index + unsigned int m_nBufferOffset; + unsigned int m_nBufferFirstIndex; + + // Used to make sure Begin/End calls and BeginModify/EndModify calls match. + bool m_bModify; +}; + + +//----------------------------------------------------------------------------- +// +// Inline methods related to CIndexBuilder +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +inline CIndexBuilder::CIndexBuilder() : m_pIndexBuffer(0), m_nIndexCount(0), + m_nCurrentIndex(0), m_nMaxIndexCount(0) +{ + m_nTotalIndexCount = 0; + m_nBufferOffset = INVALID_BUFFER_OFFSET; + m_nBufferFirstIndex = 0; +#ifdef _DEBUG + m_bModify = false; +#endif +} + +inline CIndexBuilder::CIndexBuilder( IIndexBuffer *pIndexBuffer, MaterialIndexFormat_t fmt ) +{ + m_pIndexBuffer = pIndexBuffer; + m_nBufferOffset = INVALID_BUFFER_OFFSET; + m_nBufferFirstIndex = 0; + m_nIndexCount = 0; + m_nCurrentIndex = 0; + m_nMaxIndexCount = 0; + m_nTotalIndexCount = 0; + if ( m_pIndexBuffer->IsDynamic() ) + { + m_pIndexBuffer->BeginCastBuffer( fmt ); + } + else + { + Assert( m_pIndexBuffer->IndexFormat() == fmt ); + } +#ifdef _DEBUG + m_bModify = false; +#endif +} + +inline CIndexBuilder::~CIndexBuilder() +{ + if ( m_pIndexBuffer && m_pIndexBuffer->IsDynamic() ) + { + m_pIndexBuffer->EndCastBuffer(); + } +} + + +//----------------------------------------------------------------------------- +// Begins, ends modification of the index buffer +//----------------------------------------------------------------------------- +inline bool CIndexBuilder::Lock( int nMaxIndexCount, int nIndexOffset, bool bAppend ) +{ + Assert( m_pIndexBuffer ); + m_bModify = false; + m_nIndexOffset = nIndexOffset; + m_nMaxIndexCount = nMaxIndexCount; + bool bFirstLock = ( m_nBufferOffset == INVALID_BUFFER_OFFSET ); + if ( bFirstLock ) + { + bAppend = false; + } + if ( !bAppend ) + { + m_nTotalIndexCount = 0; + } + Reset(); + + // Lock the index buffer + if ( !m_pIndexBuffer->Lock( m_nMaxIndexCount, bAppend, *this ) ) + { + m_nMaxIndexCount = 0; + return false; + } + + if ( bFirstLock ) + { + m_nBufferOffset = m_nOffset; + m_nBufferFirstIndex = m_nFirstIndex; + } + + return true; +} + +inline void CIndexBuilder::Unlock() +{ + Assert( !m_bModify && m_pIndexBuffer ); + + m_pIndexBuffer->Unlock( m_nIndexCount, *this ); + m_nTotalIndexCount += m_nIndexCount; + + m_nMaxIndexCount = 0; + +#ifdef _DEBUG + // Null out our data... + memset( (IndexDesc_t*)this, 0, sizeof(IndexDesc_t) ); +#endif +} + +inline void CIndexBuilder::SpewData() +{ + m_pIndexBuffer->Spew( m_nIndexCount, *this ); +} + + +//----------------------------------------------------------------------------- +// Binds this index buffer +//----------------------------------------------------------------------------- +inline void CIndexBuilder::Bind( IMatRenderContext *pContext ) +{ + if ( m_pIndexBuffer && ( m_nBufferOffset != INVALID_BUFFER_OFFSET ) ) + { + pContext->BindIndexBuffer( m_pIndexBuffer, m_nBufferOffset ); + } + else + { + pContext->BindIndexBuffer( NULL, 0 ); + } +} + + +//----------------------------------------------------------------------------- +// Returns the byte offset +//----------------------------------------------------------------------------- +inline int CIndexBuilder::Offset() const +{ + return m_nBufferOffset; +} + +inline int CIndexBuilder::GetFirstIndex() const +{ + return m_nBufferFirstIndex; +} + + +//----------------------------------------------------------------------------- +// Begins, ends modification of the index buffer +//----------------------------------------------------------------------------- +inline void CIndexBuilder::Begin( IIndexBuffer *pIndexBuffer, int nMaxIndexCount, int nIndexOffset ) +{ + Assert( pIndexBuffer && (!m_pIndexBuffer) ); + + m_pIndexBuffer = pIndexBuffer; + m_nIndexCount = 0; + m_nMaxIndexCount = nMaxIndexCount; + m_nIndexOffset = nIndexOffset; + + m_bModify = false; + + // Lock the index buffer + m_pIndexBuffer->Lock( m_nMaxIndexCount, false, *this ); + + // Point to the start of the buffers.. + Reset(); +} + +inline void CIndexBuilder::End( bool bSpewData ) +{ + // Make sure they called Begin() + Assert( !m_bModify ); + + if ( bSpewData ) + { + m_pIndexBuffer->Spew( m_nIndexCount, *this ); + } + + // Unlock our buffers + m_pIndexBuffer->Unlock( m_nIndexCount, *this ); + + m_pIndexBuffer = 0; + m_nMaxIndexCount = 0; + +#ifdef _DEBUG + // Null out our data... + memset( (IndexDesc_t*)this, 0, sizeof(IndexDesc_t) ); +#endif +} + + +//----------------------------------------------------------------------------- +// Begins, ends modification of an existing index buffer which has already been filled out +//----------------------------------------------------------------------------- +inline void CIndexBuilder::BeginModify( IIndexBuffer* pIndexBuffer, int nFirstIndex, int nIndexCount, int nIndexOffset ) +{ + m_pIndexBuffer = pIndexBuffer; + m_nIndexCount = nIndexCount; + m_nMaxIndexCount = nIndexCount; + m_nIndexOffset = nIndexOffset; + m_bModify = true; + + // Lock the vertex and index buffer + m_pIndexBuffer->ModifyBegin( false, nFirstIndex, nIndexCount, *this ); + + // Point to the start of the buffers.. + Reset(); +} + +inline void CIndexBuilder::EndModify( bool bSpewData ) +{ + Assert( m_pIndexBuffer ); + Assert( m_bModify ); // Make sure they called BeginModify. + + if ( bSpewData ) + { + m_pIndexBuffer->Spew( m_nIndexCount, *this ); + } + + // Unlock our buffers + m_pIndexBuffer->ModifyEnd( *this ); + + m_pIndexBuffer = 0; + m_nMaxIndexCount = 0; + +#ifdef _DEBUG + // Null out our data... + memset( (IndexDesc_t*)this, 0, sizeof(IndexDesc_t) ); +#endif +} + + +//----------------------------------------------------------------------------- +// FIXME: Remove! Backward compat so we can use this from a CMeshBuilder. +//----------------------------------------------------------------------------- +inline void CIndexBuilder::AttachBegin( IMesh* pMesh, int nMaxIndexCount, const MeshDesc_t &desc ) +{ + m_pIndexBuffer = pMesh; + m_nIndexCount = 0; + m_nMaxIndexCount = nMaxIndexCount; + + m_bModify = false; + + // Copy relevant data from the mesh desc + m_nIndexOffset = desc.m_nFirstVertex; + m_pIndices = desc.m_pIndices; + m_nIndexSize = desc.m_nIndexSize; + + // Point to the start of the buffers.. + Reset(); +} + +inline void CIndexBuilder::AttachEnd() +{ + Assert( m_pIndexBuffer ); + Assert( !m_bModify ); // Make sure they called AttachBegin. + + m_pIndexBuffer = 0; + m_nMaxIndexCount = 0; + +#ifdef _DEBUG + // Null out our data... + memset( (IndexDesc_t*)this, 0, sizeof(IndexDesc_t) ); +#endif +} + +inline void CIndexBuilder::AttachBeginModify( IMesh* pMesh, int nFirstIndex, int nIndexCount, const MeshDesc_t &desc ) +{ + m_pIndexBuffer = pMesh; + m_nIndexCount = nIndexCount; + m_nMaxIndexCount = nIndexCount; + m_bModify = true; + + // Copy relevant data from the mesh desc + m_nIndexOffset = desc.m_nFirstVertex; + m_pIndices = desc.m_pIndices; + m_nIndexSize = desc.m_nIndexSize; + + // Point to the start of the buffers.. + Reset(); +} + +inline void CIndexBuilder::AttachEndModify() +{ + Assert( m_pIndexBuffer ); + Assert( m_bModify ); // Make sure they called AttachBeginModify. + + m_pIndexBuffer = 0; + m_nMaxIndexCount = 0; + +#ifdef _DEBUG + // Null out our data... + memset( (IndexDesc_t*)this, 0, sizeof(IndexDesc_t) ); +#endif +} + + +//----------------------------------------------------------------------------- +// Resets the index buffer builder so it points to the start of everything again +//----------------------------------------------------------------------------- +inline void CIndexBuilder::Reset() +{ + m_nCurrentIndex = 0; +} + + +//----------------------------------------------------------------------------- +// returns the number of indices +//----------------------------------------------------------------------------- +inline int CIndexBuilder::IndexCount() const +{ + return m_nIndexCount; +} + + +//----------------------------------------------------------------------------- +// Returns the total number of indices across all Locks() +//----------------------------------------------------------------------------- +inline int CIndexBuilder::TotalIndexCount() const +{ + return m_nTotalIndexCount; +} + + +//----------------------------------------------------------------------------- +// Advances the current index +//----------------------------------------------------------------------------- +inline void CIndexBuilder::AdvanceIndex() +{ + m_nCurrentIndex += m_nIndexSize; + if ( m_nCurrentIndex > m_nIndexCount ) + { + m_nIndexCount = m_nCurrentIndex; + } +} + +inline void CIndexBuilder::AdvanceIndices( int nIndices ) +{ + m_nCurrentIndex += nIndices * m_nIndexSize; + if ( m_nCurrentIndex > m_nIndexCount ) + { + m_nIndexCount = m_nCurrentIndex; + } +} + + +//----------------------------------------------------------------------------- +// Returns the current index +//----------------------------------------------------------------------------- +inline int CIndexBuilder::GetCurrentIndex() +{ + return m_nCurrentIndex; +} + +inline unsigned short const* CIndexBuilder::Index() const +{ + Assert( m_nCurrentIndex < m_nMaxIndexCount ); + return &m_pIndices[m_nCurrentIndex]; +} + +inline void CIndexBuilder::SelectIndex( int nIndex ) +{ + Assert( ( nIndex >= 0 ) && ( nIndex < m_nIndexCount ) ); + m_nCurrentIndex = nIndex * m_nIndexSize; +} + + +//----------------------------------------------------------------------------- +// Used to write data into the index buffer +//----------------------------------------------------------------------------- +inline void CIndexBuilder::Index( unsigned short nIndex ) +{ + Assert( m_pIndices ); + Assert( m_nCurrentIndex < m_nMaxIndexCount ); + m_pIndices[ m_nCurrentIndex ] = (unsigned short)( m_nIndexOffset + nIndex ); +} + +// Fast Index! No need to call advance index +inline void CIndexBuilder::FastIndex( unsigned short nIndex ) +{ + Assert( m_pIndices ); + Assert( m_nCurrentIndex < m_nMaxIndexCount ); + m_pIndices[m_nCurrentIndex] = (unsigned short)( m_nIndexOffset + nIndex ); + m_nCurrentIndex += m_nIndexSize; + m_nIndexCount = m_nCurrentIndex; +} + +inline void CIndexBuilder::FastTriangle( int startVert ) +{ + startVert += m_nIndexOffset; + m_pIndices[m_nCurrentIndex+0] = startVert; + m_pIndices[m_nCurrentIndex+1] = startVert + 1; + m_pIndices[m_nCurrentIndex+2] = startVert + 2; + + AdvanceIndices(3); +} + +inline void CIndexBuilder::FastQuad( int startVert ) +{ + startVert += m_nIndexOffset; + m_pIndices[m_nCurrentIndex+0] = startVert; + m_pIndices[m_nCurrentIndex+1] = startVert + 1; + m_pIndices[m_nCurrentIndex+2] = startVert + 2; + m_pIndices[m_nCurrentIndex+3] = startVert; + m_pIndices[m_nCurrentIndex+4] = startVert + 2; + m_pIndices[m_nCurrentIndex+5] = startVert + 3; + AdvanceIndices(6); +} + +inline void CIndexBuilder::FastPolygon( int startVert, int triangleCount ) +{ + unsigned short *pIndex = &m_pIndices[m_nCurrentIndex]; + startVert += m_nIndexOffset; + if ( !IsX360() ) + { + // NOTE: IndexSize is 1 or 0 (0 for alt-tab) + // This prevents us from writing into bogus memory + Assert( m_nIndexSize == 0 || m_nIndexSize == 1 ); + triangleCount *= m_nIndexSize; + } + for ( int v = 0; v < triangleCount; ++v ) + { + *pIndex++ = startVert; + *pIndex++ = startVert + v + 1; + *pIndex++ = startVert + v + 2; + } + AdvanceIndices(triangleCount*3); +} + +inline void CIndexBuilder::FastPolygonList( int startVert, int *pVertexCount, int polygonCount ) +{ + unsigned short *pIndex = &m_pIndices[m_nCurrentIndex]; + startVert += m_nIndexOffset; + int indexOut = 0; + + if ( !IsX360() ) + { + // NOTE: IndexSize is 1 or 0 (0 for alt-tab) + // This prevents us from writing into bogus memory + Assert( m_nIndexSize == 0 || m_nIndexSize == 1 ); + polygonCount *= m_nIndexSize; + } + + for ( int i = 0; i < polygonCount; i++ ) + { + int vertexCount = pVertexCount[i]; + int triangleCount = vertexCount-2; + for ( int v = 0; v < triangleCount; ++v ) + { + *pIndex++ = startVert; + *pIndex++ = startVert + v + 1; + *pIndex++ = startVert + v + 2; + } + startVert += vertexCount; + indexOut += triangleCount * 3; + } + AdvanceIndices(indexOut); +} + +inline void CIndexBuilder::FastIndexList( const unsigned short *pIndexList, int startVert, int indexCount ) +{ + unsigned short *pIndexOut = &m_pIndices[m_nCurrentIndex]; + startVert += m_nIndexOffset; + if ( !IsX360() ) + { + // NOTE: IndexSize is 1 or 0 (0 for alt-tab) + // This prevents us from writing into bogus memory + Assert( m_nIndexSize == 0 || m_nIndexSize == 1 ); + indexCount *= m_nIndexSize; + } + for ( int i = 0; i < indexCount; ++i ) + { + pIndexOut[i] = startVert + pIndexList[i]; + } + AdvanceIndices(indexCount); +} + + +//----------------------------------------------------------------------------- +// NOTE: This version is the one you really want to achieve write-combining; +// Write combining only works if you write in 4 bytes chunks. +//----------------------------------------------------------------------------- +inline void CIndexBuilder::FastIndex2( unsigned short nIndex1, unsigned short nIndex2 ) +{ + Assert( m_pIndices ); + Assert( m_nCurrentIndex < m_nMaxIndexCount - 1 ); +// Assert( ( (int)( &m_pIndices[m_nCurrentIndex] ) & 0x3 ) == 0 ); + +#ifndef _X360 + unsigned int nIndices = ( (unsigned int)nIndex1 + m_nIndexOffset ) | ( ( (unsigned int)nIndex2 + m_nIndexOffset ) << 16 ); +#else + unsigned int nIndices = ( (unsigned int)nIndex2 + m_nIndexOffset ) | ( ( (unsigned int)nIndex1 + m_nIndexOffset ) << 16 ); +#endif + + *(int*)( &m_pIndices[m_nCurrentIndex] ) = nIndices; + m_nCurrentIndex += m_nIndexSize + m_nIndexSize; + m_nIndexCount = m_nCurrentIndex; +} + + +//----------------------------------------------------------------------------- +// Generates indices for a particular primitive type +//----------------------------------------------------------------------------- +inline void CIndexBuilder::GenerateIndices( MaterialPrimitiveType_t primitiveType, int nIndexCount ) +{ + // FIXME: How to make this work with short vs int sized indices? + // Don't generate indices if we've got an empty buffer + if ( m_nIndexSize == 0 ) + return; + + int nMaxIndices = m_nMaxIndexCount - m_nCurrentIndex; + nIndexCount = Min( nMaxIndices, nIndexCount ); + if ( nIndexCount == 0 ) + return; + + unsigned short *pIndices = &m_pIndices[m_nCurrentIndex]; + + switch( primitiveType ) + { + case MATERIAL_INSTANCED_QUADS: + Assert(0); // Shouldn't get here (this primtype is unindexed) + break; + case MATERIAL_QUADS: + GenerateQuadIndexBuffer( pIndices, nIndexCount, m_nIndexOffset ); + break; + case MATERIAL_POLYGON: + GeneratePolygonIndexBuffer( pIndices, nIndexCount, m_nIndexOffset ); + break; + case MATERIAL_LINE_STRIP: + GenerateLineStripIndexBuffer( pIndices, nIndexCount, m_nIndexOffset ); + break; + case MATERIAL_LINE_LOOP: + GenerateLineLoopIndexBuffer( pIndices, nIndexCount, m_nIndexOffset ); + break; + case MATERIAL_POINTS: + Assert(0); // Shouldn't get here (this primtype is unindexed) + break; + default: + GenerateSequentialIndexBuffer( pIndices, nIndexCount, m_nIndexOffset ); + break; + } + + AdvanceIndices( nIndexCount ); +} + + +//----------------------------------------------------------------------------- +// +// Helper class used to define meshes +// +//----------------------------------------------------------------------------- +//class CMeshBuilder : private MeshDesc_t +// hack fixme +class CMeshBuilder : public MeshDesc_t +{ +public: + CMeshBuilder(); + ~CMeshBuilder() { Assert(!m_pMesh); } // if this fires you did a Begin() without an End() + + operator CIndexBuilder&() { return m_IndexBuilder; } + + // This must be called before Begin, if a vertex buffer with a compressed format is to be used + void SetCompressionType( VertexCompressionType_t compressionType ); + + // Locks the vertex buffer + // (*cannot* use the Index() call below) + void Begin( IMesh *pMesh, MaterialPrimitiveType_t type, int numPrimitives ); + + // Locks the vertex buffer, can specify arbitrary index lists + // (must use the Index() call below) + void Begin( IMesh *pMesh, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount, int *nFirstVertex ); + void Begin( IMesh *pMesh, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount ); + + // forward compat + void Begin( IVertexBuffer *pVertexBuffer, MaterialPrimitiveType_t type, int numPrimitives ); + void Begin( IVertexBuffer *pVertexBuffer, IIndexBuffer *pIndexBuffer, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount, int *nFirstVertex ); + void Begin( IVertexBuffer *pVertexBuffer, IIndexBuffer *pIndexBuffer, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount ); + + // Use this when you're done writing + // Set bDraw to true to call m_pMesh->Draw automatically. + void End( bool bSpewData = false, bool bDraw = false ); + + // Locks the vertex buffer to modify existing data + // Passing nVertexCount == -1 says to lock all the vertices for modification. + // Pass 0 for nIndexCount to not lock the index buffer. + void BeginModify( IMesh *pMesh, int nFirstVertex = 0, int nVertexCount = -1, int nFirstIndex = 0, int nIndexCount = 0 ); + void EndModify( bool bSpewData = false ); + + // A helper method since this seems to be done a whole bunch. + void DrawQuad( IMesh* pMesh, const float *v1, const float *v2, + const float *v3, const float *v4, unsigned char const *pColor, bool wireframe = false ); + + // returns the number of indices and vertices + int VertexCount() const; + int IndexCount() const; + + // Resets the mesh builder so it points to the start of everything again + void Reset(); + + // Returns the size of the vertex + int VertexSize() { return m_ActualVertexSize; } + + // returns the data size of a given texture coordinate + int TextureCoordinateSize( int nTexCoordNumber ) { return m_VertexSize_TexCoord[ nTexCoordNumber ]; } + + // Returns the base vertex memory pointer + void* BaseVertexData(); + + // Selects the nth Vertex and Index + void SelectVertex( int idx ); + void SelectIndex( int idx ); + + // Given an index, point to the associated vertex + void SelectVertexFromIndex( int idx ); + + // Advances the current vertex and index by one + void AdvanceVertex(); + template void AdvanceVertexF(); + void AdvanceVertices( int nVerts ); + void AdvanceIndex(); + void AdvanceIndices( int nIndices ); + + int GetCurrentVertex(); + int GetCurrentIndex(); + + // Data retrieval... + const float *Position() const; + + const float *Normal() const; + + unsigned int Color() const; + + unsigned char *Specular() const; + + const float *TexCoord( int stage ) const; + + const float *TangentS() const; + const float *TangentT() const; + + const float *BoneWeight() const; + float Wrinkle() const; + + int NumBoneWeights() const; +#ifndef NEW_SKINNING + unsigned char *BoneMatrix() const; +#else + float *BoneMatrix() const; +#endif + unsigned short const *Index() const; + + // position setting + void Position3f( float x, float y, float z ); + void Position3fv( const float *v ); + + // normal setting + void Normal3f( float nx, float ny, float nz ); + void Normal3fv( const float *n ); + void NormalDelta3fv( const float *n ); + void NormalDelta3f( float nx, float ny, float nz ); + + // normal setting (templatized for code which needs to support compressed vertices) + template void CompressedNormal3f( float nx, float ny, float nz ); + template void CompressedNormal3fv( const float *n ); + + // color setting + void Color3f( float r, float g, float b ); + void Color3fv( const float *rgb ); + void Color4f( float r, float g, float b, float a ); + void Color4fv( const float *rgba ); + + // Faster versions of color + void Color3ub( unsigned char r, unsigned char g, unsigned char b ); + void Color3ubv( unsigned char const* rgb ); + void Color4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ); + void Color4ubv( unsigned char const* rgba ); + + // specular color setting + void Specular3f( float r, float g, float b ); + void Specular3fv( const float *rgb ); + void Specular4f( float r, float g, float b, float a ); + void Specular4fv( const float *rgba ); + + // Faster version of specular + void Specular3ub( unsigned char r, unsigned char g, unsigned char b ); + void Specular3ubv( unsigned char const *c ); + void Specular4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ); + void Specular4ubv( unsigned char const *c ); + + // texture coordinate setting + void TexCoord1f( int stage, float s ); + void TexCoord2f( int stage, float s, float t ); + void TexCoord2fv( int stage, const float *st ); + void TexCoord3f( int stage, float s, float t, float u ); + void TexCoord3fv( int stage, const float *stu ); + void TexCoord4f( int stage, float s, float t, float u, float w ); + void TexCoord4fv( int stage, const float *stuv ); + + void TexCoordSubRect2f( int stage, float s, float t, float offsetS, float offsetT, float scaleS, float scaleT ); + void TexCoordSubRect2fv( int stage, const float *st, const float *offset, const float *scale ); + + // tangent space + void TangentS3f( float sx, float sy, float sz ); + void TangentS3fv( const float *s ); + + void TangentT3f( float tx, float ty, float tz ); + void TangentT3fv( const float *t ); + + // Wrinkle + void Wrinkle1f( float flWrinkle ); + + // bone weights + void BoneWeight( int idx, float weight ); + // bone weights (templatized for code which needs to support compressed vertices) + template void CompressedBoneWeight3fv( const float * pWeights ); + + // bone matrix index + void BoneMatrix( int idx, int matrixIndex ); + + // Generic per-vertex data + void UserData( const float *pData ); + // Generic per-vertex data (templatized for code which needs to support compressed vertices) + template void CompressedUserData( const float* pData ); + + // Used to define the indices (only used if you aren't using primitives) + void Index( unsigned short index ); + + // NOTE: Use this one to get write combining! Much faster than the other version of FastIndex + // Fast Index! No need to call advance index, and no random access allowed + void FastIndex2( unsigned short nIndex1, unsigned short nIndex2 ); + + // Fast Index! No need to call advance index, and no random access allowed + void FastIndex( unsigned short index ); + + // Fast Vertex! No need to call advance vertex, and no random access allowed. + // WARNING - these are low level functions that are intended only for use + // in the software vertex skinner. + void FastVertex( const ModelVertexDX7_t &vertex ); + void FastVertexSSE( const ModelVertexDX7_t &vertex ); + + // store 4 dx7 vertices fast. for special sse dx7 pipeline + void Fast4VerticesSSE( + ModelVertexDX7_t const *vtx_a, + ModelVertexDX7_t const *vtx_b, + ModelVertexDX7_t const *vtx_c, + ModelVertexDX7_t const *vtx_d); + + void FastVertex( const ModelVertexDX8_t &vertex ); + void FastVertexSSE( const ModelVertexDX8_t &vertex ); + + // Add number of verts and current vert since FastVertexxx routines do not update. + void FastAdvanceNVertices(int n); + +#if defined( _X360 ) + void VertexDX8ToX360( const ModelVertexDX8_t &vertex ); +#endif + +private: + // Computes number of verts and indices + void ComputeNumVertsAndIndices( int *pMaxVertices, int *pMaxIndices, + MaterialPrimitiveType_t type, int nPrimitiveCount ); + int IndicesFromVertices( MaterialPrimitiveType_t type, int nVertexCount ); + + // The mesh we're modifying + IMesh *m_pMesh; + + MaterialPrimitiveType_t m_Type; + + // Generate indices? + bool m_bGenerateIndices; + + CIndexBuilder m_IndexBuilder; + CVertexBuilder m_VertexBuilder; +}; + + +//----------------------------------------------------------------------------- +// Forward compat +//----------------------------------------------------------------------------- +inline void CMeshBuilder::Begin( IVertexBuffer* pVertexBuffer, MaterialPrimitiveType_t type, int numPrimitives ) +{ + Assert( 0 ); + // Begin( pVertexBuffer->GetMesh(), type, numPrimitives ); +} + +inline void CMeshBuilder::Begin( IVertexBuffer* pVertexBuffer, IIndexBuffer *pIndexBuffer, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount, int *nFirstVertex ) +{ + Assert( 0 ); + // Begin( pVertexBuffer->GetMesh(), type, nVertexCount, nIndexCount, nFirstVertex ); +} + +inline void CMeshBuilder::Begin( IVertexBuffer* pVertexBuffer, IIndexBuffer *pIndexBuffer, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount ) +{ + Assert( 0 ); + // Begin( pVertexBuffer->GetMesh(), type, nVertexCount, nIndexCount ); +} + + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +inline CMeshBuilder::CMeshBuilder() : m_pMesh(0), m_bGenerateIndices(false) +{ +} + + +//----------------------------------------------------------------------------- +// Computes the number of verts and indices based on primitive type and count +//----------------------------------------------------------------------------- +inline void CMeshBuilder::ComputeNumVertsAndIndices( int *pMaxVertices, int *pMaxIndices, + MaterialPrimitiveType_t type, int nPrimitiveCount ) +{ + switch(type) + { + case MATERIAL_POINTS: + *pMaxVertices = *pMaxIndices = nPrimitiveCount; + break; + + case MATERIAL_LINES: + *pMaxVertices = *pMaxIndices = nPrimitiveCount * 2; + break; + + case MATERIAL_LINE_STRIP: + *pMaxVertices = nPrimitiveCount + 1; + *pMaxIndices = nPrimitiveCount * 2; + break; + + case MATERIAL_LINE_LOOP: + *pMaxVertices = nPrimitiveCount; + *pMaxIndices = nPrimitiveCount * 2; + break; + + case MATERIAL_TRIANGLES: + *pMaxVertices = *pMaxIndices = nPrimitiveCount * 3; + break; + + case MATERIAL_TRIANGLE_STRIP: + *pMaxVertices = *pMaxIndices = nPrimitiveCount + 2; + break; + + case MATERIAL_QUADS: + *pMaxVertices = nPrimitiveCount * 4; + *pMaxIndices = nPrimitiveCount * 6; + break; + + case MATERIAL_INSTANCED_QUADS: + *pMaxVertices = nPrimitiveCount; + *pMaxIndices = 0; // This primtype is unindexed + break; + + case MATERIAL_POLYGON: + *pMaxVertices = nPrimitiveCount; + *pMaxIndices = (nPrimitiveCount - 2) * 3; + break; + + default: + Assert(0); + } + + // FIXME: need to get this from meshdx8.cpp, or move it to somewhere common + Assert( *pMaxVertices <= 32768 ); + Assert( *pMaxIndices <= 32768 ); +} + + +inline int CMeshBuilder::IndicesFromVertices( MaterialPrimitiveType_t type, int nVertexCount ) +{ + switch( type ) + { + case MATERIAL_QUADS: + Assert( (nVertexCount & 0x3) == 0 ); + return (nVertexCount * 6) / 4; + + case MATERIAL_INSTANCED_QUADS: + // This primtype is unindexed + return 0; + + case MATERIAL_POLYGON: + Assert( nVertexCount >= 3 ); + return (nVertexCount - 2) * 3; + + case MATERIAL_LINE_STRIP: + Assert( nVertexCount >= 2 ); + return (nVertexCount - 1) * 2; + + case MATERIAL_LINE_LOOP: + Assert( nVertexCount >= 3 ); + return nVertexCount * 2; + + default: + return nVertexCount; + } +} + +//----------------------------------------------------------------------------- +// Specify the type of vertex compression that this CMeshBuilder will perform +//----------------------------------------------------------------------------- +inline void CMeshBuilder::SetCompressionType( VertexCompressionType_t vertexCompressionType ) +{ + m_VertexBuilder.SetCompressionType( vertexCompressionType ); +} + +//----------------------------------------------------------------------------- +// Begins modifying the mesh +//----------------------------------------------------------------------------- +inline void CMeshBuilder::Begin( IMesh *pMesh, MaterialPrimitiveType_t type, int numPrimitives ) +{ + Assert( pMesh && (!m_pMesh) ); + Assert( type != MATERIAL_HETEROGENOUS ); + + m_pMesh = pMesh; + m_bGenerateIndices = true; + m_Type = type; + + int nMaxVertexCount, nMaxIndexCount; + ComputeNumVertsAndIndices( &nMaxVertexCount, &nMaxIndexCount, type, numPrimitives ); + + switch( type ) + { + case MATERIAL_INSTANCED_QUADS: + m_pMesh->SetPrimitiveType( MATERIAL_INSTANCED_QUADS ); + break; + + case MATERIAL_QUADS: + case MATERIAL_POLYGON: + m_pMesh->SetPrimitiveType( MATERIAL_TRIANGLES ); + break; + + case MATERIAL_LINE_STRIP: + case MATERIAL_LINE_LOOP: + m_pMesh->SetPrimitiveType( MATERIAL_LINES ); + break; + + default: + m_pMesh->SetPrimitiveType( type ); + } + + // Lock the mesh + m_pMesh->LockMesh( nMaxVertexCount, nMaxIndexCount, *this ); + + m_IndexBuilder.AttachBegin( pMesh, nMaxIndexCount, *this ); + m_VertexBuilder.AttachBegin( pMesh, nMaxVertexCount, *this ); + + // Point to the start of the index and vertex buffers + Reset(); +} + +inline void CMeshBuilder::Begin( IMesh *pMesh, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount, int *nFirstVertex ) +{ + Begin( pMesh, type, nVertexCount, nIndexCount ); + + *nFirstVertex = m_VertexBuilder.m_nFirstVertex * m_VertexBuilder.VertexSize(); +} + +inline void CMeshBuilder::Begin( IMesh* pMesh, MaterialPrimitiveType_t type, int nVertexCount, int nIndexCount ) +{ + Assert( pMesh && (!m_pMesh) ); + + // NOTE: We can't specify the indices when we use quads, polygons, or + // linestrips; they aren't actually directly supported by + // the material system + Assert( (type != MATERIAL_QUADS) && (type != MATERIAL_INSTANCED_QUADS) && (type != MATERIAL_POLYGON) && + (type != MATERIAL_LINE_STRIP) && (type != MATERIAL_LINE_LOOP)); + + // Dx8 doesn't support indexed points... + Assert( type != MATERIAL_POINTS ); + + m_pMesh = pMesh; + m_bGenerateIndices = false; + m_Type = type; + + // Set the primitive type + m_pMesh->SetPrimitiveType( type ); + + // Lock the vertex and index buffer + m_pMesh->LockMesh( nVertexCount, nIndexCount, *this ); + + m_IndexBuilder.AttachBegin( pMesh, nIndexCount, *this ); + m_VertexBuilder.AttachBegin( pMesh, nVertexCount, *this ); + + // Point to the start of the buffers.. + Reset(); +} + + +//----------------------------------------------------------------------------- +// Use this when you're done modifying the mesh +//----------------------------------------------------------------------------- +inline void CMeshBuilder::End( bool bSpewData, bool bDraw ) +{ + if ( m_bGenerateIndices ) + { + int nIndexCount = IndicesFromVertices( m_Type, m_VertexBuilder.VertexCount() ); + m_IndexBuilder.GenerateIndices( m_Type, nIndexCount ); + } + + if ( bSpewData ) + { + m_pMesh->Spew( m_VertexBuilder.VertexCount(), m_IndexBuilder.IndexCount(), *this ); + } + +#ifdef _DEBUG + m_pMesh->ValidateData( m_VertexBuilder.VertexCount(), m_IndexBuilder.IndexCount(), *this ); +#endif + + // Unlock our buffers + m_pMesh->UnlockMesh( m_VertexBuilder.VertexCount(), m_IndexBuilder.IndexCount(), *this ); + + m_IndexBuilder.AttachEnd(); + m_VertexBuilder.AttachEnd(); + + if ( bDraw ) + { + m_pMesh->Draw(); + } + + m_pMesh = 0; + +#ifdef _DEBUG + memset( (MeshDesc_t*)this, 0, sizeof(MeshDesc_t) ); +#endif +} + + +//----------------------------------------------------------------------------- +// Locks the vertex buffer to modify existing data +//----------------------------------------------------------------------------- +inline void CMeshBuilder::BeginModify( IMesh* pMesh, int nFirstVertex, int nVertexCount, int nFirstIndex, int nIndexCount ) +{ + Assert( pMesh && (!m_pMesh) ); + + if (nVertexCount < 0) + { + nVertexCount = pMesh->VertexCount(); + } + + m_pMesh = pMesh; + m_bGenerateIndices = false; + + // Locks mesh for modifying + pMesh->ModifyBeginEx( false, nFirstVertex, nVertexCount, nFirstIndex, nIndexCount, *this ); + + m_IndexBuilder.AttachBeginModify( pMesh, nFirstIndex, nIndexCount, *this ); + m_VertexBuilder.AttachBeginModify( pMesh, nFirstVertex, nVertexCount, *this ); + + // Point to the start of the buffers.. + Reset(); +} + +inline void CMeshBuilder::EndModify( bool bSpewData ) +{ + Assert( m_pMesh ); + + if (bSpewData) + { + m_pMesh->Spew( m_VertexBuilder.VertexCount(), m_IndexBuilder.IndexCount(), *this ); + } +#ifdef _DEBUG + m_pMesh->ValidateData( m_VertexBuilder.VertexCount(), m_IndexBuilder.IndexCount(), *this ); +#endif + + // Unlocks mesh + m_pMesh->ModifyEnd( *this ); + m_pMesh = 0; + + m_IndexBuilder.AttachEndModify(); + m_VertexBuilder.AttachEndModify(); + +#ifdef _DEBUG + // Null out our pointers... + memset( (MeshDesc_t*)this, 0, sizeof(MeshDesc_t) ); +#endif +} + + +//----------------------------------------------------------------------------- +// Resets the mesh builder so it points to the start of everything again +//----------------------------------------------------------------------------- +inline void CMeshBuilder::Reset() +{ + m_IndexBuilder.Reset(); + m_VertexBuilder.Reset(); +} + + +//----------------------------------------------------------------------------- +// Selects the current Vertex and Index +//----------------------------------------------------------------------------- +FORCEINLINE void CMeshBuilder::SelectVertex( int nIndex ) +{ + m_VertexBuilder.SelectVertex( nIndex ); +} + +inline void CMeshBuilder::SelectVertexFromIndex( int idx ) +{ + // NOTE: This index is expected to be relative + int vertIdx = idx - m_nFirstVertex; + SelectVertex( vertIdx ); +} + +FORCEINLINE void CMeshBuilder::SelectIndex( int idx ) +{ + m_IndexBuilder.SelectIndex( idx ); +} + + +//----------------------------------------------------------------------------- +// Advances the current vertex and index by one +//----------------------------------------------------------------------------- +template FORCEINLINE void CMeshBuilder::AdvanceVertexF() +{ + m_VertexBuilder.AdvanceVertexF(); +} +FORCEINLINE void CMeshBuilder::AdvanceVertex() +{ + m_VertexBuilder.AdvanceVertex(); +} + +FORCEINLINE void CMeshBuilder::AdvanceVertices( int nVertexCount ) +{ + m_VertexBuilder.AdvanceVertices( nVertexCount ); +} + +FORCEINLINE void CMeshBuilder::AdvanceIndex() +{ + m_IndexBuilder.AdvanceIndex(); +} + +FORCEINLINE void CMeshBuilder::AdvanceIndices( int nIndices ) +{ + m_IndexBuilder.AdvanceIndices( nIndices ); +} + +FORCEINLINE int CMeshBuilder::GetCurrentVertex() +{ + return m_VertexBuilder.GetCurrentVertex(); +} + +FORCEINLINE int CMeshBuilder::GetCurrentIndex() +{ + return m_IndexBuilder.GetCurrentIndex(); +} + + +//----------------------------------------------------------------------------- +// A helper method since this seems to be done a whole bunch. +//----------------------------------------------------------------------------- +inline void CMeshBuilder::DrawQuad( IMesh* pMesh, const float* v1, const float* v2, + const float* v3, const float* v4, unsigned char const* pColor, bool wireframe ) +{ + if (!wireframe) + { + Begin( pMesh, MATERIAL_TRIANGLE_STRIP, 2 ); + + Position3fv (v1); + Color4ubv( pColor ); + AdvanceVertexF(); + + Position3fv (v2); + Color4ubv( pColor ); + AdvanceVertexF(); + + Position3fv (v4); + Color4ubv( pColor ); + AdvanceVertexF(); + + Position3fv (v3); + Color4ubv( pColor ); + AdvanceVertexF(); + } + else + { + Begin( pMesh, MATERIAL_LINE_LOOP, 4 ); + Position3fv (v1); + Color4ubv( pColor ); + AdvanceVertexF(); + + Position3fv (v2); + Color4ubv( pColor ); + AdvanceVertexF(); + + Position3fv (v3); + Color4ubv( pColor ); + AdvanceVertexF(); + + Position3fv (v4); + Color4ubv( pColor ); + AdvanceVertexF(); + } + + End(); + pMesh->Draw(); +} + + +//----------------------------------------------------------------------------- +// returns the number of indices and vertices +//----------------------------------------------------------------------------- +FORCEINLINE int CMeshBuilder::VertexCount() const +{ + return m_VertexBuilder.VertexCount(); +} + +FORCEINLINE int CMeshBuilder::IndexCount() const +{ + return m_IndexBuilder.IndexCount(); +} + + +//----------------------------------------------------------------------------- +// Returns the base vertex memory pointer +//----------------------------------------------------------------------------- +FORCEINLINE void* CMeshBuilder::BaseVertexData() +{ + return m_VertexBuilder.BaseVertexData(); +} + +//----------------------------------------------------------------------------- +// Data retrieval... +//----------------------------------------------------------------------------- +FORCEINLINE const float* CMeshBuilder::Position() const +{ + return m_VertexBuilder.Position(); +} + +FORCEINLINE const float* CMeshBuilder::Normal() const +{ + return m_VertexBuilder.Normal(); +} + +FORCEINLINE unsigned int CMeshBuilder::Color() const +{ + return m_VertexBuilder.Color(); +} + +FORCEINLINE unsigned char *CMeshBuilder::Specular() const +{ + return m_VertexBuilder.Specular(); +} + +FORCEINLINE const float* CMeshBuilder::TexCoord( int nStage ) const +{ + return m_VertexBuilder.TexCoord( nStage ); +} + +FORCEINLINE const float* CMeshBuilder::TangentS() const +{ + return m_VertexBuilder.TangentS(); +} + +FORCEINLINE const float* CMeshBuilder::TangentT() const +{ + return m_VertexBuilder.TangentT(); +} + +FORCEINLINE float CMeshBuilder::Wrinkle() const +{ + return m_VertexBuilder.Wrinkle(); +} + +FORCEINLINE const float* CMeshBuilder::BoneWeight() const +{ + return m_VertexBuilder.BoneWeight(); +} + +FORCEINLINE int CMeshBuilder::NumBoneWeights() const +{ + return m_VertexBuilder.NumBoneWeights(); +} + +FORCEINLINE unsigned short const* CMeshBuilder::Index() const +{ + return m_IndexBuilder.Index(); +} + + +//----------------------------------------------------------------------------- +// Index +//----------------------------------------------------------------------------- +FORCEINLINE void CMeshBuilder::Index( unsigned short idx ) +{ + m_IndexBuilder.Index( idx ); +} + + +//----------------------------------------------------------------------------- +// Fast Index! No need to call advance index +//----------------------------------------------------------------------------- +FORCEINLINE void CMeshBuilder::FastIndex( unsigned short idx ) +{ + m_IndexBuilder.FastIndex( idx ); +} + +// NOTE: Use this one to get write combining! Much faster than the other version of FastIndex +// Fast Index! No need to call advance index, and no random access allowed +FORCEINLINE void CMeshBuilder::FastIndex2( unsigned short nIndex1, unsigned short nIndex2 ) +{ + m_IndexBuilder.FastIndex2( nIndex1, nIndex2 ); +} + +//----------------------------------------------------------------------------- +// For use with the FastVertex methods, advances the current vertex by N +//----------------------------------------------------------------------------- +FORCEINLINE void CMeshBuilder::FastAdvanceNVertices( int nVertexCount ) +{ + m_VertexBuilder.FastAdvanceNVertices( nVertexCount ); +} + + +//----------------------------------------------------------------------------- +// Fast Vertex! No need to call advance vertex, and no random access allowed +//----------------------------------------------------------------------------- +FORCEINLINE void CMeshBuilder::FastVertex( const ModelVertexDX7_t &vertex ) +{ + m_VertexBuilder.FastVertex( vertex ); +} + +FORCEINLINE void CMeshBuilder::FastVertexSSE( const ModelVertexDX7_t &vertex ) +{ + m_VertexBuilder.FastVertexSSE( vertex ); +} + +FORCEINLINE void CMeshBuilder::Fast4VerticesSSE( + const ModelVertexDX7_t *vtx_a, const ModelVertexDX7_t *vtx_b, + const ModelVertexDX7_t *vtx_c, const ModelVertexDX7_t *vtx_d ) +{ + m_VertexBuilder.Fast4VerticesSSE( vtx_a, vtx_b, vtx_c, vtx_d ); +} + +FORCEINLINE void CMeshBuilder::FastVertex( const ModelVertexDX8_t &vertex ) +{ + m_VertexBuilder.FastVertex( vertex ); +} + +FORCEINLINE void CMeshBuilder::FastVertexSSE( const ModelVertexDX8_t &vertex ) +{ + m_VertexBuilder.FastVertexSSE( vertex ); +} + +//----------------------------------------------------------------------------- +// Copies a vertex into the x360 format +//----------------------------------------------------------------------------- +#if defined( _X360 ) +inline void CMeshBuilder::VertexDX8ToX360( const ModelVertexDX8_t &vertex ) +{ + m_VertexBuilder.VertexDX8ToX360( vertex ); +} +#endif + +//----------------------------------------------------------------------------- +// Vertex field setting methods +//----------------------------------------------------------------------------- +FORCEINLINE void CMeshBuilder::Position3f( float x, float y, float z ) +{ + m_VertexBuilder.Position3f( x, y, z ); +} + +FORCEINLINE void CMeshBuilder::Position3fv( const float *v ) +{ + m_VertexBuilder.Position3fv( v ); +} + +FORCEINLINE void CMeshBuilder::Normal3f( float nx, float ny, float nz ) +{ + m_VertexBuilder.Normal3f( nx, ny, nz ); +} + +FORCEINLINE void CMeshBuilder::Normal3fv( const float *n ) +{ + m_VertexBuilder.Normal3fv( n ); +} + +FORCEINLINE void CMeshBuilder::NormalDelta3f( float nx, float ny, float nz ) +{ + m_VertexBuilder.NormalDelta3f( nx, ny, nz ); +} + +FORCEINLINE void CMeshBuilder::NormalDelta3fv( const float *n ) +{ + m_VertexBuilder.NormalDelta3fv( n ); +} + +FORCEINLINE void CMeshBuilder::Color3f( float r, float g, float b ) +{ + m_VertexBuilder.Color3f( r, g, b ); +} + +FORCEINLINE void CMeshBuilder::Color3fv( const float *rgb ) +{ + m_VertexBuilder.Color3fv( rgb ); +} + +FORCEINLINE void CMeshBuilder::Color4f( float r, float g, float b, float a ) +{ + m_VertexBuilder.Color4f( r, g ,b, a ); +} + +FORCEINLINE void CMeshBuilder::Color4fv( const float *rgba ) +{ + m_VertexBuilder.Color4fv( rgba ); +} + +FORCEINLINE void CMeshBuilder::Color3ub( unsigned char r, unsigned char g, unsigned char b ) +{ + m_VertexBuilder.Color3ub( r, g, b ); +} + +FORCEINLINE void CMeshBuilder::Color3ubv( unsigned char const* rgb ) +{ + m_VertexBuilder.Color3ubv( rgb ); +} + +FORCEINLINE void CMeshBuilder::Color4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) +{ + m_VertexBuilder.Color4ub( r, g, b, a ); +} + +FORCEINLINE void CMeshBuilder::Color4ubv( unsigned char const* rgba ) +{ + m_VertexBuilder.Color4ubv( rgba ); +} + +FORCEINLINE void CMeshBuilder::Specular3f( float r, float g, float b ) +{ + m_VertexBuilder.Specular3f( r, g, b ); +} + +FORCEINLINE void CMeshBuilder::Specular3fv( const float *rgb ) +{ + m_VertexBuilder.Specular3fv( rgb ); +} + +FORCEINLINE void CMeshBuilder::Specular4f( float r, float g, float b, float a ) +{ + m_VertexBuilder.Specular4f( r, g, b, a ); +} + +FORCEINLINE void CMeshBuilder::Specular4fv( const float *rgba ) +{ + m_VertexBuilder.Specular4fv( rgba ); +} + +FORCEINLINE void CMeshBuilder::Specular3ub( unsigned char r, unsigned char g, unsigned char b ) +{ + m_VertexBuilder.Specular3ub( r, g, b ); +} + +FORCEINLINE void CMeshBuilder::Specular3ubv( unsigned char const *c ) +{ + m_VertexBuilder.Specular3ubv( c ); +} + +FORCEINLINE void CMeshBuilder::Specular4ub( unsigned char r, unsigned char g, unsigned char b, unsigned char a ) +{ + m_VertexBuilder.Specular4ub( r, g, b, a ); +} + +FORCEINLINE void CMeshBuilder::Specular4ubv( unsigned char const *c ) +{ + m_VertexBuilder.Specular4ubv( c ); +} + +FORCEINLINE void CMeshBuilder::TexCoord1f( int nStage, float s ) +{ + m_VertexBuilder.TexCoord1f( nStage, s ); +} + +FORCEINLINE void CMeshBuilder::TexCoord2f( int nStage, float s, float t ) +{ + m_VertexBuilder.TexCoord2f( nStage, s, t ); +} + +FORCEINLINE void CMeshBuilder::TexCoord2fv( int nStage, const float *st ) +{ + m_VertexBuilder.TexCoord2fv( nStage, st ); +} + +FORCEINLINE void CMeshBuilder::TexCoord3f( int nStage, float s, float t, float u ) +{ + m_VertexBuilder.TexCoord3f( nStage, s, t, u ); +} + +FORCEINLINE void CMeshBuilder::TexCoord3fv( int nStage, const float *stu ) +{ + m_VertexBuilder.TexCoord3fv( nStage, stu ); +} + +FORCEINLINE void CMeshBuilder::TexCoord4f( int nStage, float s, float t, float u, float v ) +{ + m_VertexBuilder.TexCoord4f( nStage, s, t, u, v ); +} + +FORCEINLINE void CMeshBuilder::TexCoord4fv( int nStage, const float *stuv ) +{ + m_VertexBuilder.TexCoord4fv( nStage, stuv ); +} + +FORCEINLINE void CMeshBuilder::TexCoordSubRect2f( int nStage, float s, float t, float offsetS, float offsetT, float scaleS, float scaleT ) +{ + m_VertexBuilder.TexCoordSubRect2f( nStage, s, t, offsetS, offsetT, scaleS, scaleT ); +} + +FORCEINLINE void CMeshBuilder::TexCoordSubRect2fv( int nStage, const float *st, const float *offset, const float *scale ) +{ + m_VertexBuilder.TexCoordSubRect2fv( nStage, st, offset, scale ); +} + +FORCEINLINE void CMeshBuilder::TangentS3f( float sx, float sy, float sz ) +{ + m_VertexBuilder.TangentS3f( sx, sy, sz ); +} + +FORCEINLINE void CMeshBuilder::TangentS3fv( const float* s ) +{ + m_VertexBuilder.TangentS3fv( s ); +} + +FORCEINLINE void CMeshBuilder::TangentT3f( float tx, float ty, float tz ) +{ + m_VertexBuilder.TangentT3f( tx, ty, tz ); +} + +FORCEINLINE void CMeshBuilder::TangentT3fv( const float* t ) +{ + m_VertexBuilder.TangentT3fv( t ); +} + +FORCEINLINE void CMeshBuilder::Wrinkle1f( float flWrinkle ) +{ + m_VertexBuilder.Wrinkle1f( flWrinkle ); +} + +FORCEINLINE void CMeshBuilder::BoneWeight( int nIndex, float flWeight ) +{ + m_VertexBuilder.BoneWeight( nIndex, flWeight ); +} + +template FORCEINLINE void CMeshBuilder::CompressedBoneWeight3fv( const float * pWeights ) +{ + m_VertexBuilder.CompressedBoneWeight3fv( pWeights ); +} + +FORCEINLINE void CMeshBuilder::BoneMatrix( int nIndex, int nMatrixIdx ) +{ + m_VertexBuilder.BoneMatrix( nIndex, nMatrixIdx ); +} + +FORCEINLINE void CMeshBuilder::UserData( const float* pData ) +{ + m_VertexBuilder.UserData( pData ); +} + +template FORCEINLINE void CMeshBuilder::CompressedUserData( const float* pData ) +{ + m_VertexBuilder.CompressedUserData( pData ); +} + +//----------------------------------------------------------------------------- +// Templatized vertex field setting methods which support compression +//----------------------------------------------------------------------------- + +template FORCEINLINE void CMeshBuilder::CompressedNormal3f( float nx, float ny, float nz ) +{ + m_VertexBuilder.CompressedNormal3f( nx, ny, nz ); +} + +template FORCEINLINE void CMeshBuilder::CompressedNormal3fv( const float *n ) +{ + m_VertexBuilder.CompressedNormal3fv( n ); +} + +#endif // IMESH_H diff --git a/sp/src/public/materialsystem/imorph.h b/sp/src/public/materialsystem/imorph.h new file mode 100644 index 00000000..c3bff78b --- /dev/null +++ b/sp/src/public/materialsystem/imorph.h @@ -0,0 +1,251 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// The copyright to the contents herein is the property of Valve, L.L.C. +// The contents may be used and/or copied only with the written permission of +// Valve, L.L.C., or in accordance with the terms and conditions stipulated in +// the agreement/contract under which the contents have been supplied. +// +// $Header: $ +// $NoKeywords: $ +// +// Interface used to construct morph buffers +//============================================================================= + +#ifndef IMORPH_H +#define IMORPH_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "mathlib/vector.h" +#include +#include "tier0/dbg.h" +#include "materialsystem/imaterial.h" + + +//----------------------------------------------------------------------------- +// Single morph data +//----------------------------------------------------------------------------- +struct MorphVertexInfo_t +{ + int m_nVertexId; // What vertex is this going to affect? + int m_nMorphTargetId; // What morph did it come from? + Vector m_PositionDelta; // Positional morph delta + Vector m_NormalDelta; // Normal morph delta + float m_flWrinkleDelta; // Wrinkle morph delta + float m_flSpeed; + float m_flSide; +}; + + +//----------------------------------------------------------------------------- +// Morph weight data +//----------------------------------------------------------------------------- +enum MorphWeightType_t +{ + MORPH_WEIGHT = 0, + MORPH_WEIGHT_LAGGED, + MORPH_WEIGHT_STEREO, + MORPH_WEIGHT_STEREO_LAGGED, + + MORPH_WEIGHT_COUNT, +}; + +struct MorphWeight_t +{ + float m_pWeight[MORPH_WEIGHT_COUNT]; +}; + + +//----------------------------------------------------------------------------- +// Interface to the morph +//----------------------------------------------------------------------------- +abstract_class IMorph +{ +public: + // Locks the morph, destroys any existing contents + virtual void Lock( float flFloatToFixedScale = 1.0f ) = 0; + + // Adds a morph + virtual void AddMorph( const MorphVertexInfo_t &info ) = 0; + + // Unlocks the morph + virtual void Unlock( ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Morph builders +//----------------------------------------------------------------------------- +class CMorphBuilder +{ +public: + CMorphBuilder(); + ~CMorphBuilder(); + + // Start building the morph + void Begin( IMorph *pMorph, float flFloatToFixedScale = 1.0f ); + + // End building the morph + void End(); + + void PositionDelta3fv( const float *pDelta ); + void PositionDelta3f( float dx, float dy, float dz ); + void PositionDelta3( const Vector &vec ); + + void NormalDelta3fv( const float *pDelta ); + void NormalDelta3f( float dx, float dy, float dz ); + void NormalDelta3( const Vector &vec ); + + void WrinkleDelta1f( float flWrinkle ); + + // Both are 0-1 values indicating which morph target to use (for stereo morph targets) + // and how much to blend between using lagged weights vs actual weights + // Speed: 0 - use lagged, 1 - use actual + void Speed1f( float flSpeed ); + void Side1f( float flSide ); + + void AdvanceMorph( int nSourceVertex, int nMorphTargetId ); + +private: + MorphVertexInfo_t m_Info; + IMorph *m_pMorph; +}; + + +//----------------------------------------------------------------------------- +// Constructor, destructor +//----------------------------------------------------------------------------- +inline CMorphBuilder::CMorphBuilder() +{ + m_pMorph = NULL; +} + +inline CMorphBuilder::~CMorphBuilder() +{ + // You forgot to call End()! + Assert( !m_pMorph ); +} + + +//----------------------------------------------------------------------------- +// Start building the morph +//----------------------------------------------------------------------------- +inline void CMorphBuilder::Begin( IMorph *pMorph, float flFloatToFixedScale ) +{ + Assert( pMorph && !m_pMorph ); + m_pMorph = pMorph; + m_pMorph->Lock( flFloatToFixedScale ); + +#ifdef _DEBUG + m_Info.m_PositionDelta.Init( VEC_T_NAN, VEC_T_NAN, VEC_T_NAN ); + m_Info.m_NormalDelta.Init( VEC_T_NAN, VEC_T_NAN, VEC_T_NAN ); + m_Info.m_flWrinkleDelta = VEC_T_NAN; + m_Info.m_flSpeed = VEC_T_NAN; + m_Info.m_flSide = VEC_T_NAN; +#endif +} + +// End building the morph +inline void CMorphBuilder::End() +{ + Assert( m_pMorph ); + m_pMorph->Unlock(); + m_pMorph = NULL; +} + + +//----------------------------------------------------------------------------- +// Set position delta +//----------------------------------------------------------------------------- +inline void CMorphBuilder::PositionDelta3fv( const float *pDelta ) +{ + Assert( m_pMorph ); + m_Info.m_PositionDelta.Init( pDelta[0], pDelta[1], pDelta[2] ); +} + +inline void CMorphBuilder::PositionDelta3f( float dx, float dy, float dz ) +{ + Assert( m_pMorph ); + m_Info.m_PositionDelta.Init( dx, dy, dz ); +} + +inline void CMorphBuilder::PositionDelta3( const Vector &vec ) +{ + Assert( m_pMorph ); + m_Info.m_PositionDelta = vec; +} + + +//----------------------------------------------------------------------------- +// Set normal delta +//----------------------------------------------------------------------------- +inline void CMorphBuilder::NormalDelta3fv( const float *pDelta ) +{ + Assert( m_pMorph ); + m_Info.m_NormalDelta.Init( pDelta[0], pDelta[1], pDelta[2] ); +} + +inline void CMorphBuilder::NormalDelta3f( float dx, float dy, float dz ) +{ + Assert( m_pMorph ); + m_Info.m_NormalDelta.Init( dx, dy, dz ); +} + +inline void CMorphBuilder::NormalDelta3( const Vector &vec ) +{ + Assert( m_pMorph ); + m_Info.m_NormalDelta = vec; +} + + +//----------------------------------------------------------------------------- +// Set wrinkle delta +//----------------------------------------------------------------------------- +inline void CMorphBuilder::WrinkleDelta1f( float flWrinkle ) +{ + Assert( m_pMorph ); + m_Info.m_flWrinkleDelta = flWrinkle; +} + + +//----------------------------------------------------------------------------- +// Set speed,side data +//----------------------------------------------------------------------------- +inline void CMorphBuilder::Speed1f( float flSpeed ) +{ + Assert( m_pMorph ); + m_Info.m_flSpeed = flSpeed; +} + +inline void CMorphBuilder::Side1f( float flSide ) +{ + Assert( m_pMorph ); + m_Info.m_flSide = flSide; +} + + +//----------------------------------------------------------------------------- +// Advance morph +//----------------------------------------------------------------------------- +inline void CMorphBuilder::AdvanceMorph( int nSourceVertex, int nMorphTargetId ) +{ + Assert( m_pMorph ); + + m_Info.m_nVertexId = nSourceVertex; + m_Info.m_nMorphTargetId = nMorphTargetId; + + m_pMorph->AddMorph( m_Info ); + +#ifdef _DEBUG + m_Info.m_PositionDelta.Init( VEC_T_NAN, VEC_T_NAN, VEC_T_NAN ); + m_Info.m_NormalDelta.Init( VEC_T_NAN, VEC_T_NAN, VEC_T_NAN ); + m_Info.m_flWrinkleDelta = VEC_T_NAN; + m_Info.m_flSpeed = VEC_T_NAN; + m_Info.m_flSide = VEC_T_NAN; +#endif +} + + +#endif // IMORPH_H diff --git a/sp/src/public/materialsystem/ishaderapi.h b/sp/src/public/materialsystem/ishaderapi.h new file mode 100644 index 00000000..e16ad8c7 --- /dev/null +++ b/sp/src/public/materialsystem/ishaderapi.h @@ -0,0 +1,43 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: NOTE: This file is for backward compat! +// We'll get rid of it soon. Most of the contents of this file were moved +// into shaderpi/ishadershadow.h, shaderapi/ishaderdynamic.h, or +// shaderapi/shareddefs.h +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef ISHADERAPI_MS_H +#define ISHADERAPI_MS_H + +#ifdef _WIN32 +#pragma once +#endif + +#include +#include +#include + + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- +class IMaterialVar; + + +//----------------------------------------------------------------------------- +// Methods that can be called from the SHADER_INIT blocks of shaders +//----------------------------------------------------------------------------- +abstract_class IShaderInit +{ +public: + // Loads up a texture + virtual void LoadTexture( IMaterialVar *pTextureVar, const char *pTextureGroupName, int nAdditionalCreationFlags = 0 ) = 0; + virtual void LoadBumpMap( IMaterialVar *pTextureVar, const char *pTextureGroupName ) = 0; + virtual void LoadCubeMap( IMaterialVar **ppParams, IMaterialVar *pTextureVar, int nAdditionalCreationFlags = 0 ) = 0; +}; + + +#endif // ISHADERAPI_MS_H diff --git a/sp/src/public/materialsystem/itexture.h b/sp/src/public/materialsystem/itexture.h new file mode 100644 index 00000000..a5aa20fd --- /dev/null +++ b/sp/src/public/materialsystem/itexture.h @@ -0,0 +1,132 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef ITEXTURE_H +#define ITEXTURE_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier0/platform.h" +#include "bitmap/imageformat.h" // ImageFormat defn. + +class IVTFTexture; +class ITexture; +struct Rect_t; + +//----------------------------------------------------------------------------- +// This will get called on procedural textures to re-fill the textures +// with the appropriate bit pattern. Calling Download() will also +// cause this interface to be called. It will also be called upon +// mode switch, or on other occasions where the bits are discarded. +//----------------------------------------------------------------------------- +abstract_class ITextureRegenerator +{ +public: + // This will be called when the texture bits need to be regenerated. + // Use the VTFTexture interface, which has been set up with the + // appropriate texture size + format + // The rect specifies which part of the texture needs to be updated + // You can choose to update all of the bits if you prefer + virtual void RegenerateTextureBits( ITexture *pTexture, IVTFTexture *pVTFTexture, Rect_t *pRect ) = 0; + + // This will be called when the regenerator needs to be deleted + // which will happen when the texture is destroyed + virtual void Release() = 0; +}; + +abstract_class ITexture +{ +public: + // Various texture polling methods + virtual const char *GetName( void ) const = 0; + virtual int GetMappingWidth() const = 0; + virtual int GetMappingHeight() const = 0; + virtual int GetActualWidth() const = 0; + virtual int GetActualHeight() const = 0; + virtual int GetNumAnimationFrames() const = 0; + virtual bool IsTranslucent() const = 0; + virtual bool IsMipmapped() const = 0; + + virtual void GetLowResColorSample( float s, float t, float *color ) const = 0; + + // Gets texture resource data of the specified type. + // Params: + // eDataType type of resource to retrieve. + // pnumBytes on return is the number of bytes available in the read-only data buffer or is undefined + // Returns: + // pointer to the resource data, or NULL + virtual void *GetResourceData( uint32 eDataType, size_t *pNumBytes ) const = 0; + + // Methods associated with reference count + virtual void IncrementReferenceCount( void ) = 0; + virtual void DecrementReferenceCount( void ) = 0; + + inline void AddRef() { IncrementReferenceCount(); } + inline void Release() { DecrementReferenceCount(); } + + // Used to modify the texture bits (procedural textures only) + virtual void SetTextureRegenerator( ITextureRegenerator *pTextureRegen ) = 0; + + // Reconstruct the texture bits in HW memory + + // If rect is not specified, reconstruct all bits, otherwise just + // reconstruct a subrect. + virtual void Download( Rect_t *pRect = 0, int nAdditionalCreationFlags = 0 ) = 0; + + // Uses for stats. . .get the approximate size of the texture in it's current format. + virtual int GetApproximateVidMemBytes( void ) const = 0; + + // Returns true if the texture data couldn't be loaded. + virtual bool IsError() const = 0; + + // NOTE: Stuff after this is added after shipping HL2. + + // For volume textures + virtual bool IsVolumeTexture() const = 0; + virtual int GetMappingDepth() const = 0; + virtual int GetActualDepth() const = 0; + + virtual ImageFormat GetImageFormat() const = 0; + virtual NormalDecodeMode_t GetNormalDecodeMode() const = 0; + + // Various information about the texture + virtual bool IsRenderTarget() const = 0; + virtual bool IsCubeMap() const = 0; + virtual bool IsNormalMap() const = 0; + virtual bool IsProcedural() const = 0; + + virtual void DeleteIfUnreferenced() = 0; + +#if defined( _X360 ) + virtual bool ClearTexture( int r, int g, int b, int a ) = 0; + virtual bool CreateRenderTargetSurface( int width, int height, ImageFormat format, bool bSameAsTexture ) = 0; +#endif + + // swap everything except the name with another texture + virtual void SwapContents( ITexture *pOther ) = 0; + + // Retrieve the vtf flags mask + virtual unsigned int GetFlags( void ) const = 0; + + // Force LOD override (automatically downloads the texture) + virtual void ForceLODOverride( int iNumLodsOverrideUpOrDown ) = 0; + + // Save texture to a file. + virtual bool SaveToFile( const char *fileName ) = 0; +}; + + +inline bool IsErrorTexture( ITexture *pTex ) +{ + return !pTex || pTex->IsError(); +} + + +#endif // ITEXTURE_H diff --git a/sp/src/public/materialsystem/ivballoctracker.h b/sp/src/public/materialsystem/ivballoctracker.h new file mode 100644 index 00000000..7d07e25d --- /dev/null +++ b/sp/src/public/materialsystem/ivballoctracker.h @@ -0,0 +1,35 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: tracks VB allocations (and compressed/uncompressed vertex memory usage) +// +//===========================================================================// + +#ifndef IVBALLOCTRACKER_H +#define IVBALLOCTRACKER_H + +#include "materialsystem/imaterialsystem.h" + +// By default, only enable this alloc tracking for a debug shaderapidx*.dll +// (it uses about 0.25MB to track ~7000 allocations) +#if defined(_DEBUG) +#define ENABLE_VB_ALLOC_TRACKER 1 +#else +#define ENABLE_VB_ALLOC_TRACKER 0 +#endif + +// This interface is actually exported by the shader API DLL. +#define VB_ALLOC_TRACKER_INTERFACE_VERSION "VBAllocTracker001" + +// Interface to the VB mem alloc tracker +abstract_class IVBAllocTracker +{ +public: + // This should be called wherever VertexBuffers are allocated + virtual void CountVB( void * buffer, bool isDynamic, int bufferSize, int vertexSize, VertexFormat_t fmt ) = 0; + // This should be called wherever VertexBuffers are freed + virtual void UnCountVB( void * buffer ) = 0; + // Track mesh allocations (set this before an allocation, clear it after) + virtual bool TrackMeshAllocations( const char * allocatorName ) = 0; +}; + +#endif // IVBALLOCTRACKER_H diff --git a/sp/src/public/measure_section.cpp b/sp/src/public/measure_section.cpp new file mode 100644 index 00000000..e43a16ac --- /dev/null +++ b/sp/src/public/measure_section.cpp @@ -0,0 +1,271 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// +#include +#include +#include "basetypes.h" +#include "measure_section.h" +#include "convar.h" + + +// Static members +CMeasureSection *CMeasureSection::s_pSections = 0; +int CMeasureSection::s_nCount = 0; +double CMeasureSection::m_dNextResort = 0.0; + +ConVar measure_resort( "measure_resort", "1.0", 0, "How often to re-sort profiling sections\n" ); +ConVar game_speeds( "game_speeds","0" ); +extern ConVar host_speeds; + +//----------------------------------------------------------------------------- +// Purpose: Creates a profiling section +// Input : *name - name of the section ( allocated on stack hopefully ) +//----------------------------------------------------------------------------- +CMeasureSection::CMeasureSection( const char *name ) +{ + // Just point at name since it's static + m_pszName = name; + + // Clear accumulators + Reset(); + SortReset(); + m_dMaxTime.Init(); + + // Link into master list + m_pNext = s_pSections; + s_pSections = this; + // Update count + s_nCount++; +} + +//----------------------------------------------------------------------------- +// Purpose: Destroys the object +//----------------------------------------------------------------------------- +CMeasureSection::~CMeasureSection( void ) +{ + m_pNext = NULL; + s_nCount--; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CMeasureSection::UpdateMax( void ) +{ + if (m_dMaxTime.IsLessThan(m_dAccumulatedTime)) + { + m_dMaxTime.Init(); + CCycleCount::Add(m_dMaxTime,m_dAccumulatedTime,m_dMaxTime); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CMeasureSection::Reset( void ) +{ + m_dAccumulatedTime.Init(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CMeasureSection::SortReset( void ) +{ + m_dTotalTime.Init(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : const char +//----------------------------------------------------------------------------- +const char *CMeasureSection::GetName( void ) +{ + return m_pszName; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : +//----------------------------------------------------------------------------- +CCycleCount const& CMeasureSection::GetTotalTime( void ) +{ + return m_dTotalTime; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : +//----------------------------------------------------------------------------- +CCycleCount const& CMeasureSection::GetTime( void ) +{ + return m_dAccumulatedTime; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : +//----------------------------------------------------------------------------- +CCycleCount const& CMeasureSection::GetMaxTime( void ) +{ + return m_dMaxTime; +} + +//----------------------------------------------------------------------------- +// Purpose: Accumulates a timeslice +// Input : time - +//----------------------------------------------------------------------------- +void CMeasureSection::AddTime( CCycleCount const &rCount ) +{ + CCycleCount::Add(m_dAccumulatedTime, rCount, m_dAccumulatedTime); + CCycleCount::Add(m_dTotalTime, rCount, m_dTotalTime); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : CMeasureSection +//----------------------------------------------------------------------------- +CMeasureSection *CMeasureSection::GetNext( void ) +{ + return m_pNext; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : CMeasureSection +//----------------------------------------------------------------------------- +CMeasureSection *CMeasureSection::GetList( void ) +{ + return s_pSections; +} + +//----------------------------------------------------------------------------- +// Purpose: Compares accumulated time for two sections +// Input : ppms1 - +// ppms2 - +// Output : static int +//----------------------------------------------------------------------------- +static int SectionCompare( const void* ppms1,const void* ppms2 ) +{ + CMeasureSection* pms1 = *(CMeasureSection**)ppms1; + CMeasureSection* pms2 = *(CMeasureSection**)ppms2; + + if ( pms1->GetTotalTime().IsLessThan(pms2->GetTotalTime()) ) + return 1; + else + return -1; +} + +//----------------------------------------------------------------------------- +// Purpose: Sorts sections by time usage +//----------------------------------------------------------------------------- +void CMeasureSection::SortSections( void ) +{ + // Not enough to be sortable + if ( s_nCount <= 1 ) + return; + + CMeasureSection *sortarray[ 128 ]; + CMeasureSection *ms; + + memset(sortarray,sizeof(CMeasureSection*)*128,0); + + ms = GetList(); + int i; + int c = 0; + while ( ms ) + { + sortarray[ c++ ] = ms; + ms = ms->GetNext(); + } + + // Sort the array alphabetically + qsort( sortarray, c , sizeof( CMeasureSection * ), SectionCompare ); + + // Fix next pointers + for ( i = 0; i < c-1; i++ ) + { + sortarray[ i ]->m_pNext = sortarray[ i + 1 ]; + } + sortarray[i]->m_pNext = NULL; + + // Point head of list at it + s_pSections = sortarray[ 0 ]; +} + +//----------------------------------------------------------------------------- +// Purpose: Creates an instance for timing a section +// Input : *ms - +//----------------------------------------------------------------------------- +CMeasureSectionInstance::CMeasureSectionInstance( CMeasureSection *ms ) +{ + // Remember where to put accumulated time + m_pMS = ms; + + if ( host_speeds.GetInt() < 3 && !game_speeds.GetInt()) + return; + + // Get initial timestamp + m_Timer.Start(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CMeasureSectionInstance::~CMeasureSectionInstance( void ) +{ + if ( host_speeds.GetInt() < 3 && !game_speeds.GetInt()) + return; + + // Get final timestamp + m_Timer.End(); + + // Add time to section + m_pMS->AddTime( m_Timer.GetDuration() ); +} + +//----------------------------------------------------------------------------- +// Purpose: Re-sort all data and determine whether sort keys should be reset too ( after +// re-doing sort if needed ). +//----------------------------------------------------------------------------- +void ResetTimeMeasurements( void ) +{ +#if defined( _DEBUG ) || defined( FORCE_MEASURE ) + bool sort_reset = false; + + // Time to redo sort? + if ( measure_resort.GetFloat() > 0.0 && + GetRealTime() >= CMeasureSection::m_dNextResort ) + { + // Redo it + CMeasureSection::SortSections(); + // Set next time + CMeasureSection::m_dNextResort = GetRealTime() + measure_resort.GetFloat(); + // Flag to reset sort accumulator, too + sort_reset = true; + } + + // Iterate through the sections now + CMeasureSection *p = CMeasureSection::GetList(); + while ( p ) + { + // Reset regular accum. + p->Reset(); + // Reset sort accum less often + if ( sort_reset ) + { + p->SortReset(); + } + p = p->GetNext(); + } +#endif +} \ No newline at end of file diff --git a/sp/src/public/measure_section.h b/sp/src/public/measure_section.h new file mode 100644 index 00000000..4fb2362e --- /dev/null +++ b/sp/src/public/measure_section.h @@ -0,0 +1,127 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//=============================================================================// +#if !defined( MEASURE_SECTION_H ) +#define MEASURE_SECTION_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "tier0/fasttimer.h" +#include "convar.h" + + +// This is the macro to use in your code to measure until the code goes +// out of scope +#if defined( _DEBUG ) || defined( FORCE_MEASURE ) +#define MEASURECODE( description ) \ + static CMeasureSection _xxx_ms( description ); \ + CMeasureSectionInstance _xxx_ms_inst( &_xxx_ms ); +#else +#define MEASURECODE( description ) +#endif + + +// ------------------------------------------------------------------------------------ // +// These things must exist in the executable for the CMeasureSection code to work. +// ------------------------------------------------------------------------------------ // +float GetRealTime(); // Get the clock's time. + +extern ConVar game_speeds; +extern ConVar measure_resort; +// ------------------------------------------------------------------------------------ // + + + +// Called once per frame to allow any necessary measurements to latch +void ResetTimeMeasurements( void ); + +//----------------------------------------------------------------------------- +// Purpose: Accumulates time for the named section +//----------------------------------------------------------------------------- +class CMeasureSection +{ +public: + // Allows for measuring named section + CMeasureSection( const char *name ); + virtual ~CMeasureSection( void ); + + + // Update max value hit + void UpdateMax( void ); + // Reset totals + void Reset( void ); + // Reset sortable totals + void SortReset( void ); + // Get static name of section + const char *GetName( void ); + + // Get accumulated time + CCycleCount const& GetTotalTime( void ); + + CCycleCount const& GetTime(); + + CCycleCount const& GetMaxTime(); + + // Add in some time + void AddTime( CCycleCount const &rCount ); + + // Get next section in chain + CMeasureSection *GetNext( void ); + + // Get head of list of all sections + static CMeasureSection *GetList( void ); + // Sort all sections by most time consuming + static void SortSections( void ); + +public: + // Time when list should be sorted again + static double m_dNextResort; + +private: + // Accumulated time for section + CCycleCount m_dAccumulatedTime; + + // Max time for section + CCycleCount m_dMaxTime; + + // Elapsed time for section + CCycleCount m_dTotalTime; + + // Name of section + const char *m_pszName; + // Next section in chain + CMeasureSection *m_pNext; + // Head of section list + static CMeasureSection *s_pSections; + // Quick total for doing sorts faster + static int s_nCount; +}; + +//----------------------------------------------------------------------------- +// Purpose: On construction marks time and on destruction adds time to +// parent CMeasureSection object +//----------------------------------------------------------------------------- +class CMeasureSectionInstance +{ +public: + // Constructor: Points to object to accumulate time into + CMeasureSectionInstance( CMeasureSection *ms ); + // Destructor: Latches accumulated time + virtual ~CMeasureSectionInstance( void ); + +private: + // Time of construction + CFastTimer m_Timer; + + // Where to place elapsed time + CMeasureSection *m_pMS; +}; + +#endif // MEASURE_SECTION_H \ No newline at end of file diff --git a/sp/src/public/minmax.h b/sp/src/public/minmax.h new file mode 100644 index 00000000..7597957c --- /dev/null +++ b/sp/src/public/minmax.h @@ -0,0 +1,18 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef MINMAX_H +#define MINMAX_H + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#endif // MINMAX_H diff --git a/sp/src/public/model_types.h b/sp/src/public/model_types.h new file mode 100644 index 00000000..54f3891c --- /dev/null +++ b/sp/src/public/model_types.h @@ -0,0 +1,47 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//=============================================================================// +#if !defined( MODEL_TYPES_H ) +#define MODEL_TYPES_H +#ifdef _WIN32 +#pragma once +#endif + +#define STUDIO_NONE 0x00000000 +#define STUDIO_RENDER 0x00000001 +#define STUDIO_VIEWXFORMATTACHMENTS 0x00000002 +#define STUDIO_DRAWTRANSLUCENTSUBMODELS 0x00000004 +#define STUDIO_TWOPASS 0x00000008 +#define STUDIO_STATIC_LIGHTING 0x00000010 +#define STUDIO_WIREFRAME 0x00000020 +#define STUDIO_ITEM_BLINK 0x00000040 +#define STUDIO_NOSHADOWS 0x00000080 +#define STUDIO_WIREFRAME_VCOLLIDE 0x00000100 + +// Not a studio flag, but used to flag when we want studio stats +#define STUDIO_GENERATE_STATS 0x01000000 + +// Not a studio flag, but used to flag model as using shadow depth material override +#define STUDIO_SSAODEPTHTEXTURE 0x08000000 + +// Not a studio flag, but used to flag model as using shadow depth material override +#define STUDIO_SHADOWDEPTHTEXTURE 0x40000000 + +// Not a studio flag, but used to flag model as a non-sorting brush model +#define STUDIO_TRANSPARENCY 0x80000000 + + +enum modtype_t +{ + mod_bad = 0, + mod_brush, + mod_sprite, + mod_studio +}; + +#endif // MODEL_TYPES_H diff --git a/sp/src/public/modes.h b/sp/src/public/modes.h new file mode 100644 index 00000000..ba092007 --- /dev/null +++ b/sp/src/public/modes.h @@ -0,0 +1,21 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#if !defined( MODES_H ) +#define MODES_H +#ifdef _WIN32 +#pragma once +#endif + +typedef struct vmode_s +{ + int width; + int height; + int bpp; + int refreshRate; +} vmode_t; + +#endif // MODES_H diff --git a/sp/src/public/mouthinfo.h b/sp/src/public/mouthinfo.h new file mode 100644 index 00000000..e474db74 --- /dev/null +++ b/sp/src/public/mouthinfo.h @@ -0,0 +1,197 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// +#if !defined( MOUTHINFO_H ) +#define MOUTHINFO_H +#ifdef _WIN32 +#pragma once +#endif + +class CAudioSource; + +#pragma pack(push,4) +class CVoiceData +{ +public: + CVoiceData( void ) + { + m_flElapsed = 0.0f; + m_pAudioSource = NULL; + m_bIgnorePhonemes = false; + } + + void SetElapsedTime( float t ) + { + m_flElapsed = t; + } + + float GetElapsedTime() const + { + return m_flElapsed; + } + + void SetSource( CAudioSource *source, bool bIgnorePhonemes ) + { + m_pAudioSource = source; + m_bIgnorePhonemes = bIgnorePhonemes; + } + + bool ShouldIgnorePhonemes() const + { + return m_bIgnorePhonemes; + } + + CAudioSource *GetSource() + { + return m_pAudioSource; + } + +private: + float m_flElapsed; + CAudioSource *m_pAudioSource; + bool m_bIgnorePhonemes; +}; + +#define UNKNOWN_VOICE_SOURCE -1 + +//----------------------------------------------------------------------------- +// Purpose: Describes position of mouth for lip syncing +//----------------------------------------------------------------------------- +class CMouthInfo +{ +public: + // 0 = mouth closed, 255 = mouth agape + byte mouthopen; + // counter for running average + byte sndcount; + // running average + int sndavg; + +public: + CMouthInfo( void ) { m_nVoiceSources = 0; m_needsEnvelope = false; } + virtual ~CMouthInfo( void ) { ClearVoiceSources(); } + + int GetNumVoiceSources( void ); + CVoiceData *GetVoiceSource( int number ); + + void ClearVoiceSources( void ); + int GetIndexForSource( CAudioSource *source ); + bool IsSourceReferenced( CAudioSource *source ); + + CVoiceData *AddSource( CAudioSource *source, bool bIgnorePhonemes ); + + void RemoveSource( CAudioSource *source ); + void RemoveSourceByIndex( int index ); + + bool IsActive( void ); + bool NeedsEnvelope() { return m_needsEnvelope != 0; } + void ActivateEnvelope() { m_needsEnvelope = true; } + +private: + enum + { + MAX_VOICE_DATA = 4 + }; + + short m_nVoiceSources; + short m_needsEnvelope; + CVoiceData m_VoiceSources[ MAX_VOICE_DATA ]; +}; +#pragma pack(pop) + + +inline bool CMouthInfo::IsActive( void ) +{ + return ( GetNumVoiceSources() > 0 ) ? true : false; +} + +inline int CMouthInfo::GetNumVoiceSources( void ) +{ + return m_nVoiceSources; +} + +inline CVoiceData *CMouthInfo::GetVoiceSource( int number ) +{ + if ( number < 0 || number >= m_nVoiceSources ) + return NULL; + + return &m_VoiceSources[ number ]; +} + +inline void CMouthInfo::ClearVoiceSources( void ) +{ + m_nVoiceSources = 0; +} + +inline int CMouthInfo::GetIndexForSource( CAudioSource *source ) +{ + for ( int i = 0; i < m_nVoiceSources; i++ ) + { + CVoiceData *v = &m_VoiceSources[ i ]; + if ( !v ) + continue; + + if ( v->GetSource() == source ) + return i; + } + + return UNKNOWN_VOICE_SOURCE; +} + +inline bool CMouthInfo::IsSourceReferenced( CAudioSource *source ) +{ + if ( GetIndexForSource( source ) != UNKNOWN_VOICE_SOURCE ) + return true; + + return false; +} + +inline void CMouthInfo::RemoveSource( CAudioSource *source ) +{ + int idx = GetIndexForSource( source ); + if ( idx == UNKNOWN_VOICE_SOURCE ) + return; + + RemoveSourceByIndex( idx ); +} + +inline void CMouthInfo::RemoveSourceByIndex( int index ) +{ + if ( index < 0 || index >= m_nVoiceSources ) + return; + + m_VoiceSources[ index ] = m_VoiceSources[ --m_nVoiceSources ]; +} + +inline CVoiceData *CMouthInfo::AddSource( CAudioSource *source, bool bIgnorePhonemes ) +{ + int idx = GetIndexForSource( source ); + if ( idx == UNKNOWN_VOICE_SOURCE ) + { + if ( m_nVoiceSources < MAX_VOICE_DATA ) + { + idx = m_nVoiceSources++; + } + else + { + // No room! + return NULL; + } + } + + CVoiceData *data = &m_VoiceSources[ idx ]; + data->SetSource( source, bIgnorePhonemes ); + data->SetElapsedTime( 0.0f ); + return data; +} + +#endif // MOUTHINFO_H \ No newline at end of file diff --git a/sp/src/public/networkstringtabledefs.h b/sp/src/public/networkstringtabledefs.h new file mode 100644 index 00000000..d82df2ef --- /dev/null +++ b/sp/src/public/networkstringtabledefs.h @@ -0,0 +1,80 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef NETWORKSTRINGTABLEDEFS_H +#define NETWORKSTRINGTABLEDEFS_H +#ifdef _WIN32 +#pragma once +#endif + +typedef int TABLEID; + +#define INVALID_STRING_TABLE -1 +const unsigned short INVALID_STRING_INDEX = (unsigned short )-1; + +// table index is sent in log2(MAX_TABLES) bits +#define MAX_TABLES 32 // Table id is 4 bits + +#define INTERFACENAME_NETWORKSTRINGTABLESERVER "VEngineServerStringTable001" +#define INTERFACENAME_NETWORKSTRINGTABLECLIENT "VEngineClientStringTable001" + +class INetworkStringTable; + +typedef void (*pfnStringChanged)( void *object, INetworkStringTable *stringTable, int stringNumber, char const *newString, void const *newData ); + +//----------------------------------------------------------------------------- +// Purpose: Game .dll shared string table interfaces +//----------------------------------------------------------------------------- +class INetworkStringTable +{ +public: + + virtual ~INetworkStringTable( void ) {}; + + // Table Info + virtual const char *GetTableName( void ) const = 0; + virtual TABLEID GetTableId( void ) const = 0; + virtual int GetNumStrings( void ) const = 0; + virtual int GetMaxStrings( void ) const = 0; + virtual int GetEntryBits( void ) const = 0; + + // Networking + virtual void SetTick( int tick ) = 0; + virtual bool ChangedSinceTick( int tick ) const = 0; + + // Accessors (length -1 means don't change user data if string already exits) + virtual int AddString( bool bIsServer, const char *value, int length = -1, const void *userdata = 0 ) = 0; + + virtual const char *GetString( int stringNumber ) = 0; + virtual void SetStringUserData( int stringNumber, int length, const void *userdata ) = 0; + virtual const void *GetStringUserData( int stringNumber, int *length ) = 0; + virtual int FindStringIndex( char const *string ) = 0; // returns INVALID_STRING_INDEX if not found + + // Callbacks + virtual void SetStringChangedCallback( void *object, pfnStringChanged changeFunc ) = 0; +}; + +class INetworkStringTableContainer +{ +public: + + virtual ~INetworkStringTableContainer( void ) {}; + + // table creation/destruction + virtual INetworkStringTable *CreateStringTable( const char *tableName, int maxentries, int userdatafixedsize = 0, int userdatanetworkbits = 0 ) = 0; + virtual void RemoveAllTables( void ) = 0; + + // table infos + virtual INetworkStringTable *FindTable( const char *tableName ) const = 0; + virtual INetworkStringTable *GetTable( TABLEID stringTable ) const = 0; + virtual int GetNumTables( void ) const = 0; + + virtual INetworkStringTable *CreateStringTableEx( const char *tableName, int maxentries, int userdatafixedsize = 0, int userdatanetworkbits = 0, bool bIsFilenames = false ) = 0; + virtual void SetAllowClientSideAddString( INetworkStringTable *table, bool bAllowClientSideAddString ) = 0; +}; + +#endif // NETWORKSTRINGTABLEDEFS_H diff --git a/sp/src/public/networkvar.cpp b/sp/src/public/networkvar.cpp new file mode 100644 index 00000000..65cb1d6a --- /dev/null +++ b/sp/src/public/networkvar.cpp @@ -0,0 +1,15 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#if !defined(_STATIC_LINKED) || defined(_SHARED_LIB) + + +bool g_bUseNetworkVars = true; + +#endif + + + diff --git a/sp/src/public/networkvar.h b/sp/src/public/networkvar.h new file mode 100644 index 00000000..142b35e9 --- /dev/null +++ b/sp/src/public/networkvar.h @@ -0,0 +1,781 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef NETWORKVAR_H +#define NETWORKVAR_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "tier0/dbg.h" +#include "convar.h" + +#if defined( CLIENT_DLL ) || defined( GAME_DLL ) + #include "basehandle.h" +#endif + + +#pragma warning( disable : 4284 ) // warning C4284: return type for 'CNetworkVarT::operator ->' is 'int *' (ie; not a UDT or reference to a UDT. Will produce errors if applied using infix notation) + +#define MyOffsetOf( type, var ) ( (int)&((type*)0)->var ) + +#ifdef _DEBUG + extern bool g_bUseNetworkVars; + #define CHECK_USENETWORKVARS if(g_bUseNetworkVars) +#else + #define CHECK_USENETWORKVARS // don't check for g_bUseNetworkVars +#endif + + + +inline int InternalCheckDeclareClass( const char *pClassName, const char *pClassNameMatch, void *pTestPtr, void *pBasePtr ) +{ + // This makes sure that casting from ThisClass to BaseClass works right. You'll get a compiler error if it doesn't + // work at all, and you'll get a runtime error if you use multiple inheritance. + Assert( pTestPtr == pBasePtr ); + + // This is triggered by IMPLEMENT_SERVER_CLASS. It does DLLClassName::CheckDeclareClass( #DLLClassName ). + // If they didn't do a DECLARE_CLASS in DLLClassName, then it'll be calling its base class's version + // and the class names won't match. + Assert( (void*)pClassName == (void*)pClassNameMatch ); + return 0; +} + + +template +inline int CheckDeclareClass_Access( T *, const char *pShouldBe ) +{ + return T::CheckDeclareClass( pShouldBe ); +} + +#ifndef _STATIC_LINKED +#ifdef _MSC_VER +#if defined(_DEBUG) && (_MSC_VER > 1200 ) + #define VALIDATE_DECLARE_CLASS 1 +#endif +#endif +#endif + +#ifdef VALIDATE_DECLARE_CLASS + + #define DECLARE_CLASS( className, baseClassName ) \ + typedef baseClassName BaseClass; \ + typedef className ThisClass; \ + template friend int CheckDeclareClass_Access(T *, const char *pShouldBe); \ + static int CheckDeclareClass( const char *pShouldBe ) \ + { \ + InternalCheckDeclareClass( pShouldBe, #className, (ThisClass*)0xFFFFF, (BaseClass*)(ThisClass*)0xFFFFF ); \ + return CheckDeclareClass_Access( (BaseClass *)NULL, #baseClassName ); \ + } + + // Use this macro when you have a base class, but it's part of a library that doesn't use network vars + // or any of the things that use ThisClass or BaseClass. + #define DECLARE_CLASS_GAMEROOT( className, baseClassName ) \ + typedef baseClassName BaseClass; \ + typedef className ThisClass; \ + template friend int CheckDeclareClass_Access(T *, const char *pShouldBe); \ + static int CheckDeclareClass( const char *pShouldBe ) \ + { \ + return InternalCheckDeclareClass( pShouldBe, #className, (ThisClass*)0xFFFFF, (BaseClass*)(ThisClass*)0xFFFFF ); \ + } + + // Deprecated macro formerly used to work around VC++98 bug + #define DECLARE_CLASS_NOFRIEND( className, baseClassName ) \ + DECLARE_CLASS( className, baseClassName ) + + #define DECLARE_CLASS_NOBASE( className ) \ + typedef className ThisClass; \ + template friend int CheckDeclareClass_Access(T *, const char *pShouldBe); \ + static int CheckDeclareClass( const char *pShouldBe ) \ + { \ + return InternalCheckDeclareClass( pShouldBe, #className, 0, 0 ); \ + } + +#else + #define DECLARE_CLASS( className, baseClassName ) \ + typedef baseClassName BaseClass; \ + typedef className ThisClass; + + #define DECLARE_CLASS_GAMEROOT( className, baseClassName ) DECLARE_CLASS( className, baseClassName ) + #define DECLARE_CLASS_NOFRIEND( className, baseClassName ) DECLARE_CLASS( className, baseClassName ) + + #define DECLARE_CLASS_NOBASE( className ) typedef className ThisClass; +#endif + + + + +// All classes that contain CNetworkVars need a NetworkStateChanged() function. If the class is not an entity, +// it needs to forward the call to the entity it's in. These macros can help. + + // These macros setup an entity pointer in your class. Use IMPLEMENT_NETWORKVAR_CHAIN before you do + // anything inside the class itself. + class CBaseEntity; + class CAutoInitEntPtr + { + public: + CAutoInitEntPtr() + { + m_pEnt = NULL; + } + CBaseEntity *m_pEnt; + }; + + //TODO: Currently, these don't get the benefit of tracking changes to individual vars. + // Would be nice if they did. + #define DECLARE_NETWORKVAR_CHAIN() \ + CAutoInitEntPtr __m_pChainEntity; \ + void NetworkStateChanged() { CHECK_USENETWORKVARS __m_pChainEntity.m_pEnt->NetworkStateChanged(); } \ + void NetworkStateChanged( void *pVar ) { CHECK_USENETWORKVARS __m_pChainEntity.m_pEnt->NetworkStateChanged(); } + + #define IMPLEMENT_NETWORKVAR_CHAIN( varName ) \ + (varName)->__m_pChainEntity.m_pEnt = this; + + + +// Use this macro when you want to embed a structure inside your entity and have CNetworkVars in it. +template< class T > +static inline void DispatchNetworkStateChanged( T *pObj ) +{ + CHECK_USENETWORKVARS pObj->NetworkStateChanged(); +} +template< class T > +static inline void DispatchNetworkStateChanged( T *pObj, void *pVar ) +{ + CHECK_USENETWORKVARS pObj->NetworkStateChanged( pVar ); +} + + +#define DECLARE_EMBEDDED_NETWORKVAR() \ + template friend int ServerClassInit(T *); \ + template friend int ClientClassInit(T *); \ + virtual void NetworkStateChanged() {} virtual void NetworkStateChanged( void *pProp ) {} + +// NOTE: Assignment operator is disabled because it doesn't call copy constructors of scalar types within the aggregate, so they are not marked changed +#define CNetworkVarEmbedded( type, name ) \ + class NetworkVar_##name; \ + friend class NetworkVar_##name; \ + static inline int GetOffset_##name() { return MyOffsetOf(ThisClass,name); } \ + typedef ThisClass ThisClass_##name; \ + class NetworkVar_##name : public type \ + { \ + template< class T > NetworkVar_##name& operator=( const T &val ) { *((type*)this) = val; return *this; } \ + public: \ + void CopyFrom( const type &src ) { *((type *)this) = src; NetworkStateChanged(); } \ + virtual void NetworkStateChanged() \ + { \ + DispatchNetworkStateChanged( (ThisClass_##name*)( ((char*)this) - GetOffset_##name() ) ); \ + } \ + virtual void NetworkStateChanged( void *pVar ) \ + { \ + DispatchNetworkStateChanged( (ThisClass_##name*)( ((char*)this) - GetOffset_##name() ), pVar ); \ + } \ + }; \ + NetworkVar_##name name; + +template +FORCEINLINE void NetworkVarConstruct( T &x ) { x = T(0); } +FORCEINLINE void NetworkVarConstruct( color32_s &x ) { x.r = x.g = x.b = x.a = 0; } + +template< class Type, class Changer > +class CNetworkVarBase +{ +public: + inline CNetworkVarBase() + { + NetworkVarConstruct( m_Value ); + } + + template< class C > + const Type& operator=( const C &val ) + { + return Set( ( const Type )val ); + } + + template< class C > + const Type& operator=( const CNetworkVarBase< C, Changer > &val ) + { + return Set( ( const Type )val.m_Value ); + } + + const Type& Set( const Type &val ) + { + if ( memcmp( &m_Value, &val, sizeof(Type) ) ) + { + NetworkStateChanged(); + m_Value = val; + } + return m_Value; + } + + Type& GetForModify() + { + NetworkStateChanged(); + return m_Value; + } + + template< class C > + const Type& operator+=( const C &val ) + { + return Set( m_Value + ( const Type )val ); + } + + template< class C > + const Type& operator-=( const C &val ) + { + return Set( m_Value - ( const Type )val ); + } + + template< class C > + const Type& operator/=( const C &val ) + { + return Set( m_Value / ( const Type )val ); + } + + template< class C > + const Type& operator*=( const C &val ) + { + return Set( m_Value * ( const Type )val ); + } + + template< class C > + const Type& operator^=( const C &val ) + { + return Set( m_Value ^ ( const Type )val ); + } + + template< class C > + const Type& operator|=( const C &val ) + { + return Set( m_Value | ( const Type )val ); + } + + const Type& operator++() + { + return (*this += 1); + } + + Type operator--() + { + return (*this -= 1); + } + + Type operator++( int ) // postfix version.. + { + Type val = m_Value; + (*this += 1); + return val; + } + + Type operator--( int ) // postfix version.. + { + Type val = m_Value; + (*this -= 1); + return val; + } + + // For some reason the compiler only generates type conversion warnings for this operator when used like + // CNetworkVarBase = 0x1 + // (it warns about converting from an int to an unsigned char). + template< class C > + const Type& operator&=( const C &val ) + { + return Set( m_Value & ( const Type )val ); + } + + operator const Type&() const + { + return m_Value; + } + + const Type& Get() const + { + return m_Value; + } + + const Type* operator->() const + { + return &m_Value; + } + + Type m_Value; + +protected: + inline void NetworkStateChanged() + { + Changer::NetworkStateChanged( this ); + } +}; + + +template< class Type, class Changer > +class CNetworkColor32Base : public CNetworkVarBase< Type, Changer > +{ +public: + inline void Init( byte rVal, byte gVal, byte bVal ) + { + SetR( rVal ); + SetG( gVal ); + SetB( bVal ); + } + inline void Init( byte rVal, byte gVal, byte bVal, byte aVal ) + { + SetR( rVal ); + SetG( gVal ); + SetB( bVal ); + SetA( aVal ); + } + + const Type& operator=( const Type &val ) + { + return this->Set( val ); + } + + const Type& operator=( const CNetworkColor32Base &val ) + { + return CNetworkVarBase::Set( val.m_Value ); + } + + inline byte GetR() const { return CNetworkColor32Base::m_Value.r; } + inline byte GetG() const { return CNetworkColor32Base::m_Value.g; } + inline byte GetB() const { return CNetworkColor32Base::m_Value.b; } + inline byte GetA() const { return CNetworkColor32Base::m_Value.a; } + inline void SetR( byte val ) { SetVal( CNetworkColor32Base::m_Value.r, val ); } + inline void SetG( byte val ) { SetVal( CNetworkColor32Base::m_Value.g, val ); } + inline void SetB( byte val ) { SetVal( CNetworkColor32Base::m_Value.b, val ); } + inline void SetA( byte val ) { SetVal( CNetworkColor32Base::m_Value.a, val ); } + +protected: + inline void SetVal( byte &out, const byte &in ) + { + if ( out != in ) + { + CNetworkVarBase< Type, Changer >::NetworkStateChanged(); + out = in; + } + } +}; + + +// Network vector wrapper. +template< class Type, class Changer > +class CNetworkVectorBase : public CNetworkVarBase< Type, Changer > +{ +public: + inline void Init( float ix=0, float iy=0, float iz=0 ) + { + SetX( ix ); + SetY( iy ); + SetZ( iz ); + } + + const Type& operator=( const Type &val ) + { + return CNetworkVarBase< Type, Changer >::Set( val ); + } + + const Type& operator=( const CNetworkVectorBase &val ) + { + return CNetworkVarBase::Set( val.m_Value ); + } + + inline float GetX() const { return CNetworkVectorBase::m_Value.x; } + inline float GetY() const { return CNetworkVectorBase::m_Value.y; } + inline float GetZ() const { return CNetworkVectorBase::m_Value.z; } + inline float operator[]( int i ) const { return CNetworkVectorBase::m_Value[i]; } + + inline void SetX( float val ) { DetectChange( CNetworkVectorBase::m_Value.x, val ); } + inline void SetY( float val ) { DetectChange( CNetworkVectorBase::m_Value.y, val ); } + inline void SetZ( float val ) { DetectChange( CNetworkVectorBase::m_Value.z, val ); } + inline void Set( int i, float val ) { DetectChange( CNetworkVectorBase::m_Value[i], val ); } + + bool operator==( const Type &val ) const + { + return CNetworkVectorBase::m_Value == (Type)val; + } + + bool operator!=( const Type &val ) const + { + return CNetworkVectorBase::m_Value != (Type)val; + } + + const Type operator+( const Type &val ) const + { + return CNetworkVectorBase::m_Value + val; + } + + const Type operator-( const Type &val ) const + { + return CNetworkVectorBase::m_Value - val; + } + + const Type operator*( const Type &val ) const + { + return CNetworkVectorBase::m_Value * val; + } + + const Type& operator*=( float val ) + { + return CNetworkVarBase< Type, Changer >::Set( CNetworkVectorBase::m_Value * val ); + } + + const Type operator*( float val ) const + { + return CNetworkVectorBase::m_Value * val; + } + + const Type operator/( const Type &val ) const + { + return CNetworkVectorBase::m_Value / val; + } + +private: + inline void DetectChange( float &out, float in ) + { + if ( out != in ) + { + CNetworkVectorBase::NetworkStateChanged(); + out = in; + } + } +}; + + +// Network vector wrapper. +template< class Type, class Changer > +class CNetworkQuaternionBase : public CNetworkVarBase< Type, Changer > +{ +public: + inline void Init( float ix=0, float iy=0, float iz=0, float iw = 0 ) + { + SetX( ix ); + SetY( iy ); + SetZ( iz ); + SetW( iw ); + } + + const Type& operator=( const Type &val ) + { + return CNetworkVarBase< Type, Changer >::Set( val ); + } + + const Type& operator=( const CNetworkQuaternionBase &val ) + { + return CNetworkVarBase::Set( val.m_Value ); + } + + inline float GetX() const { return CNetworkQuaternionBase::m_Value.x; } + inline float GetY() const { return CNetworkQuaternionBase::m_Value.y; } + inline float GetZ() const { return CNetworkQuaternionBase::m_Value.z; } + inline float GetW() const { return CNetworkQuaternionBase::m_Value.w; } + inline float operator[]( int i ) const { return CNetworkQuaternionBase::m_Value[i]; } + + inline void SetX( float val ) { DetectChange( CNetworkQuaternionBase::m_Value.x, val ); } + inline void SetY( float val ) { DetectChange( CNetworkQuaternionBase::m_Value.y, val ); } + inline void SetZ( float val ) { DetectChange( CNetworkQuaternionBase::m_Value.z, val ); } + inline void SetW( float val ) { DetectChange( CNetworkQuaternionBase::m_Value.w, val ); } + inline void Set( int i, float val ) { DetectChange( CNetworkQuaternionBase::m_Value[i], val ); } + + bool operator==( const Type &val ) const + { + return CNetworkQuaternionBase::m_Value == (Type)val; + } + + bool operator!=( const Type &val ) const + { + return CNetworkQuaternionBase::m_Value != (Type)val; + } + + const Type operator+( const Type &val ) const + { + return CNetworkQuaternionBase::m_Value + val; + } + + const Type operator-( const Type &val ) const + { + return CNetworkQuaternionBase::m_Value - val; + } + + const Type operator*( const Type &val ) const + { + return CNetworkQuaternionBase::m_Value * val; + } + + const Type& operator*=( float val ) + { + return CNetworkQuaternionBase< Type, Changer >::Set( CNetworkQuaternionBase::m_Value * val ); + } + + const Type operator*( float val ) const + { + return CNetworkQuaternionBase::m_Value * val; + } + + const Type operator/( const Type &val ) const + { + return CNetworkQuaternionBase::m_Value / val; + } + +private: + inline void DetectChange( float &out, float in ) + { + if ( out != in ) + { + CNetworkQuaternionBase::NetworkStateChanged(); + out = in; + } + } +}; + + +// Network ehandle wrapper. +#if defined( CLIENT_DLL ) || defined( GAME_DLL ) + inline void NetworkVarConstruct( CBaseHandle &x ) {} + + template< class Type, class Changer > + class CNetworkHandleBase : public CNetworkVarBase< CBaseHandle, Changer > + { + public: + const Type* operator=( const Type *val ) + { + return Set( val ); + } + + const Type& operator=( const CNetworkHandleBase &val ) + { + const CBaseHandle &handle = CNetworkVarBase::Set( val.m_Value ); + return *(const Type*)handle.Get(); + } + + bool operator !() const + { + return !CNetworkHandleBase::m_Value.Get(); + } + + operator Type*() const + { + return static_cast< Type* >( CNetworkHandleBase::m_Value.Get() ); + } + + const Type* Set( const Type *val ) + { + if ( CNetworkHandleBase::m_Value != val ) + { + this->NetworkStateChanged(); + CNetworkHandleBase::m_Value = val; + } + return val; + } + + Type* Get() const + { + return static_cast< Type* >( CNetworkHandleBase::m_Value.Get() ); + } + + Type* operator->() const + { + return static_cast< Type* >( CNetworkHandleBase::m_Value.Get() ); + } + + bool operator==( const Type *val ) const + { + return CNetworkHandleBase::m_Value == val; + } + + bool operator!=( const Type *val ) const + { + return CNetworkHandleBase::m_Value != val; + } + }; + + + + #define CNetworkHandle( type, name ) CNetworkHandleInternal( type, name, NetworkStateChanged ) + + #define CNetworkHandleInternal( type, name, stateChangedFn ) \ + NETWORK_VAR_START( type, name ) \ + NETWORK_VAR_END( type, name, CNetworkHandleBase, stateChangedFn ) +#endif + + +// Use this macro to define a network variable. +#define CNetworkVar( type, name ) \ + NETWORK_VAR_START( type, name ) \ + NETWORK_VAR_END( type, name, CNetworkVarBase, NetworkStateChanged ) + + +// Use this macro when you have a base class with a variable, and it doesn't have that variable in a SendTable, +// but a derived class does. Then, the entity is only flagged as changed when the variable is changed in +// an entity that wants to transmit the variable. + #define CNetworkVarForDerived( type, name ) \ + virtual void NetworkStateChanged_##name() {} \ + virtual void NetworkStateChanged_##name( void *pVar ) {} \ + NETWORK_VAR_START( type, name ) \ + NETWORK_VAR_END( type, name, CNetworkVarBase, NetworkStateChanged_##name ) + + #define CNetworkVectorForDerived( name ) \ + virtual void NetworkStateChanged_##name() {} \ + virtual void NetworkStateChanged_##name( void *pVar ) {} \ + CNetworkVectorInternal( Vector, name, NetworkStateChanged_##name ) + + #define CNetworkHandleForDerived( type, name ) \ + virtual void NetworkStateChanged_##name() {} \ + virtual void NetworkStateChanged_##name( void *pVar ) {} \ + CNetworkHandleInternal( type, name, NetworkStateChanged_##name ) + + #define CNetworkArrayForDerived( type, name, count ) \ + virtual void NetworkStateChanged_##name() {} \ + virtual void NetworkStateChanged_##name( void *pVar ) {} \ + CNetworkArrayInternal( type, name, count, NetworkStateChanged_##name ) + + #define IMPLEMENT_NETWORK_VAR_FOR_DERIVED( name ) \ + virtual void NetworkStateChanged_##name() { CHECK_USENETWORKVARS NetworkStateChanged(); } \ + virtual void NetworkStateChanged_##name( void *pVar ) { CHECK_USENETWORKVARS NetworkStateChanged( pVar ); } + + +// This virtualizes the change detection on the variable, but it is ON by default. +// Use this when you have a base class in which MOST of its derived classes use this variable +// in their SendTables, but there are a couple that don't (and they +// can use DISABLE_NETWORK_VAR_FOR_DERIVED). + #define CNetworkVarForDerived_OnByDefault( type, name ) \ + virtual void NetworkStateChanged_##name() { CHECK_USENETWORKVARS NetworkStateChanged(); } \ + virtual void NetworkStateChanged_##name( void *pVar ) { CHECK_USENETWORKVARS NetworkStateChanged( pVar ); } \ + NETWORK_VAR_START( type, name ) \ + NETWORK_VAR_END( type, name, CNetworkVarBase, NetworkStateChanged_##name ) + + #define DISABLE_NETWORK_VAR_FOR_DERIVED( name ) \ + virtual void NetworkStateChanged_##name() {} \ + virtual void NetworkStateChanged_##name( void *pVar ) {} + + + +// Vectors + some convenient helper functions. +#define CNetworkVector( name ) CNetworkVectorInternal( Vector, name, NetworkStateChanged ) +#define CNetworkQAngle( name ) CNetworkVectorInternal( QAngle, name, NetworkStateChanged ) + +#define CNetworkVectorInternal( type, name, stateChangedFn ) \ + NETWORK_VAR_START( type, name ) \ + NETWORK_VAR_END( type, name, CNetworkVectorBase, stateChangedFn ) + +#define CNetworkQuaternion( name ) \ + NETWORK_VAR_START( Quaternion, name ) \ + NETWORK_VAR_END( Quaternion, name, CNetworkQuaternionBase, NetworkStateChanged ) + +// Helper for color32's. Contains GetR(), SetR(), etc.. functions. +#define CNetworkColor32( name ) \ + NETWORK_VAR_START( color32, name ) \ + NETWORK_VAR_END( color32, name, CNetworkColor32Base, NetworkStateChanged ) + + +#define CNetworkString( name, length ) \ + class NetworkVar_##name; \ + friend class NetworkVar_##name; \ + typedef ThisClass MakeANetworkVar_##name; \ + class NetworkVar_##name \ + { \ + public: \ + NetworkVar_##name() { m_Value[0] = '\0'; } \ + operator const char*() const { return m_Value; } \ + const char* Get() const { return m_Value; } \ + char* GetForModify() \ + { \ + NetworkStateChanged(); \ + return m_Value; \ + } \ + protected: \ + inline void NetworkStateChanged() \ + { \ + CHECK_USENETWORKVARS ((ThisClass*)(((char*)this) - MyOffsetOf(ThisClass,name)))->NetworkStateChanged(); \ + } \ + private: \ + char m_Value[length]; \ + }; \ + NetworkVar_##name name; + + + + +// Use this to define networked arrays. +// You can access elements for reading with operator[], and you can set elements with the Set() function. +#define CNetworkArrayInternal( type, name, count, stateChangedFn ) \ + class NetworkVar_##name; \ + friend class NetworkVar_##name; \ + typedef ThisClass MakeANetworkVar_##name; \ + class NetworkVar_##name \ + { \ + public: \ + inline NetworkVar_##name() \ + { \ + for ( int i = 0 ; i < count ; ++i ) \ + NetworkVarConstruct( m_Value[i] ); \ + } \ + template friend int ServerClassInit(T *); \ + const type& operator[]( int i ) const \ + { \ + return Get( i ); \ + } \ + \ + const type& Get( int i ) const \ + { \ + Assert( i >= 0 && i < count ); \ + return m_Value[i]; \ + } \ + \ + type& GetForModify( int i ) \ + { \ + Assert( i >= 0 && i < count ); \ + NetworkStateChanged( i ); \ + return m_Value[i]; \ + } \ + \ + void Set( int i, const type &val ) \ + { \ + Assert( i >= 0 && i < count ); \ + if( memcmp( &m_Value[i], &val, sizeof(type) ) ) \ + { \ + NetworkStateChanged( i ); \ + m_Value[i] = val; \ + } \ + } \ + const type* Base() const { return m_Value; } \ + int Count() const { return count; } \ + protected: \ + inline void NetworkStateChanged( int index ) \ + { \ + CHECK_USENETWORKVARS ((ThisClass*)(((char*)this) - MyOffsetOf(ThisClass,name)))->stateChangedFn( &m_Value[index] ); \ + } \ + type m_Value[count]; \ + }; \ + NetworkVar_##name name; + + +#define CNetworkArray( type, name, count ) CNetworkArrayInternal( type, name, count, NetworkStateChanged ) + + +// Internal macros used in definitions of network vars. +#define NETWORK_VAR_START( type, name ) \ + class NetworkVar_##name; \ + friend class NetworkVar_##name; \ + typedef ThisClass MakeANetworkVar_##name; \ + class NetworkVar_##name \ + { \ + public: \ + template friend int ServerClassInit(T *); + + +#define NETWORK_VAR_END( type, name, base, stateChangedFn ) \ + public: \ + static inline void NetworkStateChanged( void *ptr ) \ + { \ + CHECK_USENETWORKVARS ((ThisClass*)(((char*)ptr) - MyOffsetOf(ThisClass,name)))->stateChangedFn( ptr ); \ + } \ + }; \ + base< type, NetworkVar_##name > name; + + + +#endif // NETWORKVAR_H diff --git a/sp/src/public/nmatrix.h b/sp/src/public/nmatrix.h new file mode 100644 index 00000000..2b8d206e --- /dev/null +++ b/sp/src/public/nmatrix.h @@ -0,0 +1,332 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef NMATRIX_H +#define NMATRIX_H +#ifdef _WIN32 +#pragma once +#endif + + +#include +#include "nvector.h" + + +#define NMatrixMN NMatrix + + +template +class NMatrix +{ +public: + + NMatrixMN() {} + + static NMatrixMN SetupNMatrixNull(); // Return a matrix of all zeros. + static NMatrixMN SetupNMatrixIdentity(); // Return an identity matrix. + + NMatrixMN const& operator=( NMatrixMN const &other ); + + NMatrixMN operator+( NMatrixMN const &v ) const; + NMatrixMN const& operator+=( NMatrixMN const &v ); + + NMatrixMN operator-() const; + NMatrixMN operator-( NMatrixMN const &v ) const; + + // Multiplies the column vector on the right-hand side. + NVector operator*( NVector const &v ) const; + + // Can't get the compiler to work with a real MxN * NxR matrix multiply... + NMatrix operator*( NMatrix const &b ) const; + + NMatrixMN operator*( float val ) const; + + bool InverseGeneral( NMatrixMN &mInverse ) const; + NMatrix Transpose() const; + + +public: + + float m[M][N]; +}; + + + +// Return the matrix generated by multiplying a column vector 'a' by row vector 'b'. +template +inline NMatrix OuterProduct( NVectorN const &a, NVectorN const &b ) +{ + NMatrix ret; + + for( int i=0; i < N; i++ ) + for( int j=0; j < N; j++ ) + ret.m[i][j] = a.v[i] * b.v[j]; + + return ret; +} + + +// -------------------------------------------------------------------------------- // +// NMatrix inlines. +// -------------------------------------------------------------------------------- // + +template +inline NMatrixMN NMatrixMN::SetupNMatrixNull() +{ + NMatrix ret; + memset( ret.m, 0, sizeof(float)*M*N ); + return ret; +} + + +template +inline NMatrixMN NMatrixMN::SetupNMatrixIdentity() +{ + assert( M == N ); // Identity matrices must be square. + + NMatrix ret; + memset( ret.m, 0, sizeof(float)*M*N ); + for( int i=0; i < N; i++ ) + ret.m[i][i] = 1; + return ret; +} + + +template +inline NMatrixMN const &NMatrixMN::operator=( NMatrixMN const &v ) +{ + memcpy( m, v.m, sizeof(float)*M*N ); + return *this; +} + + +template +inline NMatrixMN NMatrixMN::operator+( NMatrixMN const &v ) const +{ + NMatrixMN ret; + for( int i=0; i < M; i++ ) + for( int j=0; j < N; j++ ) + ret.m[i][j] = m[i][j] + v.m[i][j]; + + return ret; +} + + +template +inline NMatrixMN const &NMatrixMN::operator+=( NMatrixMN const &v ) +{ + for( int i=0; i < M; i++ ) + for( int j=0; j < N; j++ ) + m[i][j] += v.m[i][j]; + + return *this; +} + + +template +inline NMatrixMN NMatrixMN::operator-() const +{ + NMatrixMN ret; + + for( int i=0; i < M*N; i++ ) + ((float*)ret.m)[i] = -((float*)m)[i]; + + return ret; +} + + +template +inline NMatrixMN NMatrixMN::operator-( NMatrixMN const &v ) const +{ + NMatrixMN ret; + for( int i=0; i < M; i++ ) + for( int j=0; j < N; j++ ) + ret.m[i][j] = m[i][j] - v.m[i][j]; + return ret; +} + + +template +inline NVector NMatrixMN::operator*( NVectorN const &v ) const +{ + NVectorN ret; + + for( int i=0; i < M; i++ ) + { + ret.v[i] = 0; + + for( int j=0; j < N; j++ ) + ret.v[i] += m[i][j] * v.v[j]; + } + + return ret; +} + + +template +inline NMatrix NMatrixMN::operator*( NMatrix const &b ) const +{ + NMatrix ret; + + for( int myRow=0; myRow < M; myRow++ ) + { + for( int otherCol=0; otherCol < M; otherCol++ ) + { + ret[myRow][otherCol] = 0; + for( int i=0; i < N; i++ ) + ret[myRow][otherCol] += a.m[myRow][i] * b.m[i][otherCol]; + } + } + + return ret; +} + + +template +inline NMatrixMN NMatrixMN::operator*( float val ) const +{ + NMatrixMN ret; + + for( int i=0; i < N*M; i++ ) + ((float*)ret.m)[i] = ((float*)m)[i] * val; + + return ret; +} + + +template +bool NMatrixMN::InverseGeneral( NMatrixMN &mInverse ) const +{ + int iRow, i, j, iTemp, iTest; + float mul, fTest, fLargest; + float mat[N][2*N]; + int rowMap[N], iLargest; + float *pOut, *pRow, *pScaleRow; + + + // Can only invert square matrices. + if( M != N ) + { + assert( !"Tried to invert a non-square matrix" ); + return false; + } + + + // How it's done. + // AX = I + // A = this + // X = the matrix we're looking for + // I = identity + + // Setup AI + for(i=0; i < N; i++) + { + const float *pIn = m[i]; + pOut = mat[i]; + + for(j=0; j < N; j++) + { + pOut[j] = pIn[j]; + } + + for(j=N; j < 2*N; j++) + pOut[j] = 0; + + pOut[i+N] = 1.0f; + + rowMap[i] = i; + } + + // Use row operations to get to reduced row-echelon form using these rules: + // 1. Multiply or divide a row by a nonzero number. + // 2. Add a multiple of one row to another. + // 3. Interchange two rows. + + for(iRow=0; iRow < N; iRow++) + { + // Find the row with the largest element in this column. + fLargest = 0.001f; + iLargest = -1; + for(iTest=iRow; iTest < N; iTest++) + { + fTest = (float)fabs(mat[rowMap[iTest]][iRow]); + if(fTest > fLargest) + { + iLargest = iTest; + fLargest = fTest; + } + } + + // They're all too small.. sorry. + if(iLargest == -1) + { + return false; + } + + // Swap the rows. + iTemp = rowMap[iLargest]; + rowMap[iLargest] = rowMap[iRow]; + rowMap[iRow] = iTemp; + + pRow = mat[rowMap[iRow]]; + + // Divide this row by the element. + mul = 1.0f / pRow[iRow]; + for(j=0; j < 2*N; j++) + pRow[j] *= mul; + + pRow[iRow] = 1.0f; // Preserve accuracy... + + // Eliminate this element from the other rows using operation 2. + for(i=0; i < N; i++) + { + if(i == iRow) + continue; + + pScaleRow = mat[rowMap[i]]; + + // Multiply this row by -(iRow*the element). + mul = -pScaleRow[iRow]; + for(j=0; j < 2*N; j++) + { + pScaleRow[j] += pRow[j] * mul; + } + + pScaleRow[iRow] = 0.0f; // Preserve accuracy... + } + } + + // The inverse is on the right side of AX now (the identity is on the left). + for(i=0; i < N; i++) + { + const float *pIn = mat[rowMap[i]] + N; + pOut = mInverse.m[i]; + + for(j=0; j < N; j++) + { + pOut[j] = pIn[j]; + } + } + + return true; +} + + +template +inline NMatrix NMatrixMN::Transpose() const +{ + NMatrix ret; + + for( int i=0; i < M; i++ ) + for( int j=0; j < N; j++ ) + ret.m[j][i] = m[i][j]; + + return ret; +} + +#endif // NMATRIX_H + diff --git a/sp/src/public/ntree.h b/sp/src/public/ntree.h new file mode 100644 index 00000000..3fb448a4 --- /dev/null +++ b/sp/src/public/ntree.h @@ -0,0 +1,316 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef __TREE_H__ +#define __TREE_H__ + +#include "List.h" +#include "ArrayStack.h" + +// NTreeNode: Class decleration and definition +template class NTreeNode +{ +public: + // constructor + NTreeNode( T data ); + + NTreeNode *PrependChild( NTreeNode *node ); + NTreeNode *AppendChild( NTreeNode *node ); + NTreeNode *InsertChildAfterIndex( NTreeNode *node, int index ); + NTreeNode *InsertChildBeforeIndex( NTreeNode *node, int index ); + NTreeNode *RemoveChild( Position position ); + NTreeNode *RemoveChild( int index ); + Position InsertAfter( NTreeNode *node, Position position ); + Position InsertBefore( NTreeNode *node, Position position ); + int GetNumChildren(); + Position GetChildPosition( int childNum ); + NTreeNode *GetChild( int childNum ); + NTreeNode *GetChild( Position position ); + int GetIndexRelativeToParent(); + T GetItem(); + NTreeNode *GetParent(); + NTreeNode *GetRoot(); + NTreeNode *GetNextSibling(); + void Traverse( void (*VisitFunc)( T, int depth ), int maxTreeDepth ); + NTreeNode *ReentrantTraversalGetFirst( int maxTreeDepth ); + NTreeNode *ReentrantTraversalGetNext( void ); + +protected: + GList * > *list; + T data; + NTreeNode *parent; + ArrayStack *> *reentrantStack; +}; + +template +NTreeNode::NTreeNode( T data ) +{ + list = new GList * >; + this->data = data; + this->parent = NULL; + this->reentrantStack = NULL; +} + +template +NTreeNode *NTreeNode::PrependChild( NTreeNode *node ) +{ + node->parent = this; + return list->GetItemAtPosition( list->InsertAtHead( node ) ); +} + +template +NTreeNode *NTreeNode::AppendChild( NTreeNode *node ) +{ + node->parent = this; + return list->GetItemAtPosition( list->InsertAtTail( node ) ); +} + +template +NTreeNode *NTreeNode::InsertChildAfterIndex( NTreeNode *node, int index ) +{ + node->parent = this; + if( index < 0 ) + { + // if out of range in the negative direction, prepend + this->PrependChild( node ); + } + else if( index > list->GetNumItems() - 1 ) + { + // if out of range, just append. + this->AppendChild( node ); + } + else + { + Position pos; + pos = list->GetPositionAtIndex( index ); + list->InsertAfter( node, pos ); + } + return node; +} + +template +NTreeNode *NTreeNode::InsertChildBeforeIndex( NTreeNode *node, int index ) +{ + node->parent = this; + if( index < 0 ) + { + // if out of range in the negative direction, prepend + this->PrependChild( node ); + } + else if( index > list->GetNumItems() - 1 ) + { + // if out of range, just append. + this->AppendChild( node ); + } + else + { + Position pos; + pos = list->GetPositionAtIndex( index ); + list->InsertBefore( node, pos ); + } + return node; +} + +template +NTreeNode *NTreeNode::RemoveChild( Position position ) +{ + NTreeNode **node = ( NTreeNode ** )( void * )position; + ( *node )->parent = NULL; + return list->Remove( position ); +} + +template +NTreeNode *NTreeNode::RemoveChild( int index ) +{ + Position position = list->GetPositionAtIndex( index ); + NTreeNode **node = ( NTreeNode ** )( void * )position; + ( *node )->parent = NULL; + return list->Remove( position ); +} + +template +Position NTreeNode::InsertAfter( NTreeNode *node, Position position ) +{ + node->parent = this; + return list->InsertAfter( node, position ); +} + +template +Position NTreeNode::InsertBefore( NTreeNode *node, Position position ) +{ + node->parent = this; + return list->InsertBefore( node, position ); +} + +template +int NTreeNode::GetNumChildren() +{ + return list->GetNumItems(); +} + +template +Position NTreeNode::GetChildPosition( int childNum ) +{ + return list->GetPositionAtIndex( childNum ); +} + +template +NTreeNode *NTreeNode::GetChild( int childNum ) +{ + return list->GetItemAtIndex( childNum ); +} + +template +NTreeNode *NTreeNode::GetChild( Position position ) +{ + return list->GetItemAtIndex( position ); +} + +template +int NTreeNode::GetIndexRelativeToParent() +{ + if( !parent ) + { + assert( 0 ); // hack + return -1; + } + GListIterator *> iterator( parent->list ); + int i; + for( i = 0, iterator.GotoHead(); !iterator.AtEnd(); iterator++, i++ ) + { + if( iterator.GetCurrent() == this ) + { + return i; + } + } + assert( 0 ); // hack + return -1; +} + +template +T NTreeNode::GetItem() +{ + return data; +} + +template +NTreeNode *NTreeNode::GetParent() +{ + return parent; +} + +template +NTreeNode *NTreeNode::GetRoot() +{ + NTreeNode *node; + node = this; + while( node->GetParent() ) + { + node = node->GetParent(); + } + return node; +} + +template +NTreeNode *NTreeNode::GetNextSibling() +{ + int currentID, siblingID; + NTreeNode *parent; + parent = this->GetParent(); + if( !parent ) + { + return NULL; + } + currentID = this->GetIndexRelativeToParent(); + siblingID = currentID + 1; + if( siblingID < parent->GetNumChildren() ) + { + return parent->GetChild( siblingID ); + } + else + { + return NULL; + } +} + +template +void NTreeNode::Traverse( void (*VisitFunc)( T, int depth ), int maxTreeDepth ) +{ + ArrayStack *> stack( maxTreeDepth ); + NTreeNode *current, *nextSibling; + + stack.Push( this ); + Visit( this->GetItem(), 0 ); + while( !stack.IsEmpty() ) + { + current = stack.Pop(); + if( current->GetNumChildren() > 0 ) + { + stack.Push( current ); + stack.Push( current->GetChild( 0 ) ); + Visit( current->GetChild( 0 )->GetItem(), stack.GetDepth() - 1 ); + } + else + { + while( !stack.IsEmpty() && !( nextSibling = current->GetNextSibling() ) ) + { + current = stack.Pop(); + } + if( !stack.IsEmpty() ) + { + stack.Push( nextSibling ); + Visit( nextSibling->GetItem(), stack.GetDepth() - 1 ); + } + } + } +} + +template +NTreeNode *NTreeNode::ReentrantTraversalGetFirst( int maxTreeDepth ) +{ + if( reentrantStack ) + { + delete reentrantStack; + } + reentrantStack = new ArrayStack *>( maxTreeDepth ); + reentrantStack->Push( this ); + return this; +} + +template +NTreeNode *NTreeNode::ReentrantTraversalGetNext( void ) +{ + NTreeNode *current, *nextSibling; + + while( !reentrantStack->IsEmpty() ) + { + current = reentrantStack->Pop(); + if( current->GetNumChildren() > 0 ) + { + reentrantStack->Push( current ); + reentrantStack->Push( current->GetChild( 0 ) ); + return current->GetChild( 0 ); + } + else + { + while( !reentrantStack->IsEmpty() && !( nextSibling = current->GetNextSibling() ) ) + { + current = reentrantStack->Pop(); + } + if( !reentrantStack->IsEmpty() ) + { + reentrantStack->Push( nextSibling ); + return nextSibling; + } + } + } + delete reentrantStack; + reentrantStack = NULL; + return NULL; +} + +#endif /* __TREE_H__ */ diff --git a/sp/src/public/nvector.h b/sp/src/public/nvector.h new file mode 100644 index 00000000..e80b317f --- /dev/null +++ b/sp/src/public/nvector.h @@ -0,0 +1,203 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef NVECTOR_H +#define NVECTOR_H +#ifdef _WIN32 +#pragma once +#endif + + +#include + + +#define NVectorN NVector +#define NVector3 NVector<3> + + +// N-dimensional vector. +template +class NVector +{ +public: + + NVectorN() {} + + float& operator[]( int i ); + float const& operator[]( int i ) const; + + float Dot( NVectorN const &b ) const; + NVectorN Cross( NVectorN const &b ) const; + NVectorN Normalize() const; + float Length() const; + + NVectorN operator-() const; + NVectorN operator+( NVectorN const &b ) const; + NVectorN const &operator+=( NVectorN const &b ); + NVectorN operator-( NVectorN const &b ) const; + NVectorN operator*( float val ) const; + + +// Static helpers. +public: + + static NVectorN SetupNVectorNull(); // Returns a vector of all zeros. + + +public: + + float v[N]; +}; + + +template +inline float NDot( NVector const &a, NVector const &b ) +{ + float ret = 0; + for( int i=0; i < N; i++ ) + ret += a.v[i] * b.v[i]; + return ret; +} + +template +Vector& ToVec( NVector &vec ) {assert( N >= 3 ); return *((Vector*)&vec);} + +template +Vector const& ToVec( NVector const &vec ){assert( N >= 3 ); return *((Vector const*)&vec);} + +NVector<3>& ToNVec( Vector &vec ) {return *((NVector<3>*)&vec);} +NVector<3> const& ToNVec( Vector const &vec ) {return *((NVector<3> const*)&vec);} + + +// ------------------------------------------------------------------------------------ // +// NVector inlines. +// ------------------------------------------------------------------------------------ // + +template +NVectorN NVectorN::SetupNVectorNull() +{ + NVector ret; + memset( ret.v, 0, sizeof(float)*N ); + return ret; +} + + +template +float& NVectorN::operator[]( int i ) +{ + assert( i >= 0 && i < N ); + return v[i]; +} + + +template +float const& NVectorN::operator[]( int i ) const +{ + assert( i >= 0 && i < N ); + return v[i]; +} + + +template +float NVectorN::Dot( NVectorN const &b ) const +{ + float ret = 0; + + for( int i=0; i < N; i++ ) + ret += v[i]*b.v[i]; + + return ret; +} + + +template +NVectorN NVectorN::Cross( NVectorN const &b ) const +{ + NVector ret; + NMatrix mat; + + for( int i=0; i < N; i++ ) + { + for( y=0; y < N; y++ ) + for( x=0; x < N; x++ ) + mat.m[y][x] = + + ret.v[i] = v[i]*b.v[i]; + } + + return ret; +} + + +template +NVectorN NVectorN::Normalize() const +{ + return *this * (1.0f / Length()); +} + + +template +float NVectorN::Length() const +{ + return (float)sqrt( Dot(*this) ); +} + + +template +NVectorN NVectorN::operator-() const +{ + NVectorN ret; + for( int i=0; i < N; i++ ) + ret.v[i] = -v[i]; + return ret; +} + + +template +NVectorN NVectorN::operator+( NVectorN const &b ) const +{ + NVectorN ret; + + for( int i=0; i < N; i++ ) + ret.v[i] = v[i]+b.v[i]; + + return ret; +} + + +template +NVectorN const &NVectorN::operator+=( NVectorN const &b ) +{ + for( int i=0; i < N; i++ ) + v[i] += b.v[i]; + return *this; +} + + +template +NVectorN NVectorN::operator-( NVectorN const &b ) const +{ + NVectorN ret; + + for( int i=0; i < N; i++ ) + ret.v[i] = v[i]-b.v[i]; + + return ret; +} + +template +NVectorN NVectorN::operator*( float val ) const +{ + NVectorN ret; + for( int i=0; i < N; i++ ) + ret.v[i] = v[i] * val; + return ret; +} + + +#endif // NVECTOR_H + diff --git a/sp/src/public/nvtc.h b/sp/src/public/nvtc.h new file mode 100644 index 00000000..fd1c9806 --- /dev/null +++ b/sp/src/public/nvtc.h @@ -0,0 +1,87 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +/* + * Copyright (c) 1997-8 S3 Inc. All Rights Reserved. + * + * Module Name: s3_intrf.h + * + * Purpose: Constant, structure, and prototype definitions for S3TC + * interface to DX surface + * + * Author: Dan Hung, Martin Hoffesommer + * + * Revision History: + * version Beta 1.00.00-98-03-26 + */ + +// Highlevel interface + +#ifndef NVTC_H +#define NVTC_H + +#if defined( _WIN32 ) && !defined( _X360 ) +#include +#endif + +// RGB encoding types +#define S3TC_ENCODE_RGB_FULL 0x0 +#define S3TC_ENCODE_RGB_COLOR_KEY 0x1 +#define S3TC_ENCODE_RGB_ALPHA_COMPARE 0x2 +#define _S3TC_ENCODE_RGB_MASK 0xff + +// alpha encoding types +#define S3TC_ENCODE_ALPHA_NONE 0x000 +#define S3TC_ENCODE_ALPHA_EXPLICIT 0x100 +#define S3TC_ENCODE_ALPHA_INTERPOLATED 0x200 +#define _S3TC_ENCODE_ALPHA_MASK 0xff00 + + +#if defined( _WIN32 ) && !defined( _X360 ) +// common encoding types +//@@@TBD + +// error codes +#define ERROR_ABORTED -1 + +// Progress Callback for S3TCencode +typedef BOOL (* LP_S3TC_PROGRESS_CALLBACK)(float fProgress, LPVOID lpUser1, LPVOID lpUser2); + +// set alpha reference value for alpha compare encoding +void S3TCsetAlphaReference(int nRef); + +// determine number of bytes needed to compress given source image +unsigned int S3TCgetEncodeSize(DDSURFACEDESC *lpDesc, // [in] + unsigned int dwEncodeType // [in] + ); + +// encode (compress) given source image to given destination surface +void S3TCencode(DDSURFACEDESC *lpSrc, // [in] + PALETTEENTRY *lpPal, // [in], may be NULL + DDSURFACEDESC *lpDest, // [out] + void *lpDestBuf, // [in] + unsigned int dwEncodeType, // [in] + float *weight // [in] + ); + +int S3TCencodeEx(DDSURFACEDESC *lpSrc, // [in] + PALETTEENTRY *lpPal, // [in], may be NULL + DDSURFACEDESC *lpDest, // [out] + void *lpDestBuf, // [in] + unsigned int dwEncodeType, // [in] + float *weight, // [in] + LP_S3TC_PROGRESS_CALLBACK lpS3TCProgressProc, // [in], may be NULL + LPVOID lpArg1, // in + LPVOID lpArg2 // in + ); + +// determine number of bytes needed do decompress given compressed image +unsigned int S3TCgetDecodeSize(DDSURFACEDESC *lpDesc); + +// decode (decompress) to ARGB8888 +void S3TCdecode(DDSURFACEDESC *lpSrc, // [in] + DDSURFACEDESC *lpDest, // [out] + void *lpDestBuf // [in] + ); + +#endif // _WIN32 + +#endif // NVTC_H diff --git a/sp/src/public/optimize.h b/sp/src/public/optimize.h new file mode 100644 index 00000000..4a14bf31 --- /dev/null +++ b/sp/src/public/optimize.h @@ -0,0 +1,257 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef OPTIMIZE_H +#define OPTIMIZE_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "studio.h" + + +// NOTE: You can change this without affecting the vtx file format. +#define MAX_NUM_BONES_PER_TRI ( MAX_NUM_BONES_PER_VERT * 3 ) +#define MAX_NUM_BONES_PER_STRIP 512 + +#define OPTIMIZED_MODEL_FILE_VERSION 7 + +extern bool g_bDumpGLViewFiles; + +struct s_bodypart_t; + +namespace OptimizedModel +{ + +#pragma pack(1) + +struct BoneStateChangeHeader_t +{ + DECLARE_BYTESWAP_DATADESC(); + int hardwareID; + int newBoneID; +}; + +struct Vertex_t +{ + DECLARE_BYTESWAP_DATADESC(); + // these index into the mesh's vert[origMeshVertID]'s bones + unsigned char boneWeightIndex[MAX_NUM_BONES_PER_VERT]; + unsigned char numBones; + + unsigned short origMeshVertID; + + // for sw skinned verts, these are indices into the global list of bones + // for hw skinned verts, these are hardware bone indices + char boneID[MAX_NUM_BONES_PER_VERT]; +}; + +enum StripHeaderFlags_t { + STRIP_IS_TRILIST = 0x01, + STRIP_IS_TRISTRIP = 0x02 +}; + +// a strip is a piece of a stripgroup that is divided by bones +// (and potentially tristrips if we remove some degenerates.) +struct StripHeader_t +{ + DECLARE_BYTESWAP_DATADESC(); + // indexOffset offsets into the mesh's index array. + int numIndices; + int indexOffset; + + // vertexOffset offsets into the mesh's vert array. + int numVerts; + int vertOffset; + + // use this to enable/disable skinning. + // May decide (in optimize.cpp) to put all with 1 bone in a different strip + // than those that need skinning. + short numBones; + + unsigned char flags; + + int numBoneStateChanges; + int boneStateChangeOffset; + inline BoneStateChangeHeader_t *pBoneStateChange( int i ) const + { + return (BoneStateChangeHeader_t *)(((byte *)this) + boneStateChangeOffset) + i; + }; +}; + +enum StripGroupFlags_t +{ + STRIPGROUP_IS_FLEXED = 0x01, + STRIPGROUP_IS_HWSKINNED = 0x02, + STRIPGROUP_IS_DELTA_FLEXED = 0x04, + STRIPGROUP_SUPPRESS_HW_MORPH = 0x08, // NOTE: This is a temporary flag used at run time. +}; + +// a locking group +// a single vertex buffer +// a single index buffer +struct StripGroupHeader_t +{ + DECLARE_BYTESWAP_DATADESC(); + // These are the arrays of all verts and indices for this mesh. strips index into this. + int numVerts; + int vertOffset; + inline Vertex_t *pVertex( int i ) const + { + return (Vertex_t *)(((byte *)this) + vertOffset) + i; + }; + + int numIndices; + int indexOffset; + inline unsigned short *pIndex( int i ) const + { + return (unsigned short *)(((byte *)this) + indexOffset) + i; + }; + + int numStrips; + int stripOffset; + inline StripHeader_t *pStrip( int i ) const + { + return (StripHeader_t *)(((byte *)this) + stripOffset) + i; + }; + + unsigned char flags; +}; + +enum MeshFlags_t { + // these are both material properties, and a mesh has a single material. + MESH_IS_TEETH = 0x01, + MESH_IS_EYES = 0x02 +}; + +// a collection of locking groups: +// up to 4: +// non-flexed, hardware skinned +// flexed, hardware skinned +// non-flexed, software skinned +// flexed, software skinned +// +// A mesh has a material associated with it. +struct MeshHeader_t +{ + DECLARE_BYTESWAP_DATADESC(); + int numStripGroups; + int stripGroupHeaderOffset; + inline StripGroupHeader_t *pStripGroup( int i ) const + { + StripGroupHeader_t *pDebug = (StripGroupHeader_t *)(((byte *)this) + stripGroupHeaderOffset) + i; + return pDebug; + }; + unsigned char flags; +}; + +struct ModelLODHeader_t +{ + DECLARE_BYTESWAP_DATADESC(); + int numMeshes; + int meshOffset; + float switchPoint; + inline MeshHeader_t *pMesh( int i ) const + { + MeshHeader_t *pDebug = (MeshHeader_t *)(((byte *)this) + meshOffset) + i; + return pDebug; + }; +}; + +// This maps one to one with models in the mdl file. +// There are a bunch of model LODs stored inside potentially due to the qc $lod command +struct ModelHeader_t +{ + DECLARE_BYTESWAP_DATADESC(); + int numLODs; // garymcthack - this is also specified in FileHeader_t + int lodOffset; + inline ModelLODHeader_t *pLOD( int i ) const + { + ModelLODHeader_t *pDebug = ( ModelLODHeader_t *)(((byte *)this) + lodOffset) + i; + return pDebug; + }; +}; + +struct BodyPartHeader_t +{ + DECLARE_BYTESWAP_DATADESC(); + int numModels; + int modelOffset; + inline ModelHeader_t *pModel( int i ) const + { + ModelHeader_t *pDebug = (ModelHeader_t *)(((byte *)this) + modelOffset) + i; + return pDebug; + }; +}; + +struct MaterialReplacementHeader_t +{ + DECLARE_BYTESWAP_DATADESC(); + short materialID; + int replacementMaterialNameOffset; + inline const char *pMaterialReplacementName( void ) + { + const char *pDebug = (const char *)(((byte *)this) + replacementMaterialNameOffset); + return pDebug; + } +}; + +struct MaterialReplacementListHeader_t +{ + DECLARE_BYTESWAP_DATADESC(); + int numReplacements; + int replacementOffset; + inline MaterialReplacementHeader_t *pMaterialReplacement( int i ) const + { + MaterialReplacementHeader_t *pDebug = ( MaterialReplacementHeader_t *)(((byte *)this) + replacementOffset) + i; + return pDebug; + } +}; + +struct FileHeader_t +{ + DECLARE_BYTESWAP_DATADESC(); + // file version as defined by OPTIMIZED_MODEL_FILE_VERSION + int version; + + // hardware params that affect how the model is to be optimized. + int vertCacheSize; + unsigned short maxBonesPerStrip; + unsigned short maxBonesPerTri; + int maxBonesPerVert; + + // must match checkSum in the .mdl + int checkSum; + + int numLODs; // garymcthack - this is also specified in ModelHeader_t and should match + + // one of these for each LOD + int materialReplacementListOffset; + MaterialReplacementListHeader_t *pMaterialReplacementList( int lodID ) const + { + MaterialReplacementListHeader_t *pDebug = + (MaterialReplacementListHeader_t *)(((byte *)this) + materialReplacementListOffset) + lodID; + return pDebug; + } + + int numBodyParts; + int bodyPartOffset; + inline BodyPartHeader_t *pBodyPart( int i ) const + { + BodyPartHeader_t *pDebug = (BodyPartHeader_t *)(((byte *)this) + bodyPartOffset) + i; + return pDebug; + }; +}; + +#pragma pack() + +void WriteOptimizedFiles( studiohdr_t *phdr, s_bodypart_t *pSrcBodyParts ); + +}; // namespace OptimizedModel + +#endif // OPTIMIZE_H diff --git a/sp/src/public/overlaytext.h b/sp/src/public/overlaytext.h new file mode 100644 index 00000000..d720652d --- /dev/null +++ b/sp/src/public/overlaytext.h @@ -0,0 +1,58 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// +#if !defined( OVERLAYTEXT_H ) +#define OVERLAYTEXT_H +#ifdef _WIN32 +#pragma once +#endif + +#include "mathlib/vector.h" + +class OverlayText_t +{ +public: + OverlayText_t() + { + nextOverlayText = 0; + origin.Init(); + bUseOrigin = false; + lineOffset = 0; + flXPos = 0; + flYPos = 0; + text[ 0 ] = 0; + m_flEndTime = 0.0f; + m_nServerCount = -1; + m_nCreationTick = -1; + r = g = b = a = 255; + } + + bool IsDead(); + void SetEndTime( float duration ); + + Vector origin; + bool bUseOrigin; + int lineOffset; + float flXPos; + float flYPos; + char text[512]; + float m_flEndTime; // When does this text go away + int m_nCreationTick; // If > 0, show only one server frame + int m_nServerCount; // compare server spawn count to remove stale overlays + int r; + int g; + int b; + int a; + OverlayText_t *nextOverlayText; +}; + +#endif // OVERLAYTEXT_H \ No newline at end of file diff --git a/sp/src/public/phonemeconverter.cpp b/sp/src/public/phonemeconverter.cpp new file mode 100644 index 00000000..2253155c --- /dev/null +++ b/sp/src/public/phonemeconverter.cpp @@ -0,0 +1,202 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +#include +#include +#include "tier0/dbg.h" + +struct PhonemeMap_t +{ + const char *string; + int code; + float weight; + bool isStandard; + const char *desc; +}; + +static PhonemeMap_t g_Phonemes[] = +{ + { "b", 'b', 0.8f, true, "Big : voiced alveolar stop" }, + { "m", 'm', 1.0f, true, "Mat : voiced bilabial nasal" }, + { "p", 'p', 0.8f, true, "Put; voiceless alveolar stop" }, + { "w", 'w', 1.0f, true, "With : voiced labial-velar approximant" }, + { "f", 'f', 0.8f, true, "Fork : voiceless labiodental fricative" }, + { "v", 'v', 0.8f, true, "Val : voiced labialdental fricative" }, + { "r", 0x0279, 1.0f, true, "Red : voiced alveolar approximant" }, + { "r2", 'r', 1.0f, true, "Red : voiced alveolar trill" }, + { "r3", 0x027b, 1.0f, true, "Red : voiced retroflex approximant" }, + { "er", 0x025a, 1.2f, true, "URn : rhotacized schwa" }, + { "er2", 0x025d, 1.2f, true, "URn : rhotacized lower-mid central vowel" }, + { "dh", 0x00f0, 1.0f, true, "THen : voiced dental fricative" }, + { "th", 0x03b8, 1.0f, true, "THin : voiceless dental fricative" }, + { "sh", 0x0283, 1.0f, true, "SHe : voiceless postalveolar fricative" }, + { "jh", 0x02a4, 1.0f, true, "Joy : voiced postalveolar afficate" }, + { "ch", 0x02a7, 1.0f, true, "CHin : voiceless postalveolar affricate" }, + { "s", 's', 0.8f, true, "Sit : voiceless alveolar fricative" }, + { "z", 'z', 0.8f, true, "Zap : voiced alveolar fricative" }, + { "d", 'd', 0.8f, true, "Dig : voiced bilabial stop" }, + { "d2", 0x027e, 0.8f, true, "Dig : voiced alveolar flap or tap" }, + { "l", 'l', 0.8f, true, "Lid : voiced alveolar lateral approximant" }, + { "l2", 0x026b, 0.8f, true, "Lid : velarized voiced alveolar lateral approximant" }, + { "n", 'n', 0.8f, true, "No : voiced alveolar nasal" }, + { "t", 't', 0.8f, true, "Talk : voiceless bilabial stop" }, + { "ow", 'o', 1.2f, true, "gO : upper-mid back rounded vowel" }, + { "uw", 'u', 1.2f, true, "tOO : high back rounded vowel" }, + { "ey", 'e', 1.0f, true, "Ate : upper-mid front unrounded vowel" }, + { "ae", 0x00e6, 1.0f, true, "cAt : semi-low front unrounded vowel" }, + { "aa", 0x0251, 1.0f, true, "fAther : low back unrounded vowel" }, + { "aa2", 'a', 1.0f, true, "fAther : low front unrounded vowel" }, + { "iy", 'i', 1.0f, true, "fEEl : high front unrounded vowel" }, + { "y", 'j', 0.7f, true, "Yacht : voiced palatal approximant" }, + { "ah", 0x028c, 1.0f, true, "cUt : lower-mid back unrounded vowel" }, + { "ao", 0x0254, 1.2f, true, "dOg : lower-mid back rounded vowel" }, + { "ax", 0x0259, 1.0f, true, "Ago : mid-central unrounded vowel" }, + { "ax2", 0x025c, 1.0f, true, "Ago : lower-mid central unrounded vowel" }, + { "eh", 0x025b, 1.0f, true, "pEt : lower-mid front unrounded vowel"}, + { "ih", 0x026a, 1.0f, true, "fIll : semi-high front unrounded vowel" }, + { "ih2", 0x0268, 1.0f, true, "fIll : high central unrounded vowel" }, + { "uh", 0x028a, 1.0f, true, "bOOk : semi-high back rounded vowel" }, + { "g", 'g', 0.8f, true, "taG : voiced velar stop" }, + { "g2", 0x0261, 1.0f, true, "taG : voiced velar stop" }, + { "hh", 'h', 0.8f, true, "Help : voiceless glottal fricative" }, + { "hh2", 0x0266, 0.8f, true, "Help : breathy-voiced glottal fricative" }, + { "c", 'k', 0.6f, true, "Cut : voiceless velar stop" }, + { "nx", 0x014b, 1.0f, true, "siNG : voiced velar nasal" }, + { "zh", 0x0292, 1.0f, true, "aZure : voiced postalveolar fricative" }, + + // Added + { "h", 'h', 0.8f, false, "Help : voiceless glottal fricative" }, + { "k", 'k', 0.6f, false, "Cut : voiceless velar stop" }, + { "ay", 0x0251, 1.0f, false, "fAther : low back unrounded vowel" }, // or possibly +0x026a (ih) + { "ng", 0x014b, 1.0f, false, "siNG : voiced velar nasal" }, // nx + { "aw", 0x0251, 1.2f, false, "fAther : low back unrounded vowel" }, // // vOWel, // aa + uh??? + { "oy", 'u', 1.2f, false, "tOO : high back rounded vowel" }, + + // Silence + { "", '_', 1.0f, true, "silence" }, +}; + +//----------------------------------------------------------------------------- +// Purpose: +// Input : code - +// Output : const char +//----------------------------------------------------------------------------- +const char *ConvertPhoneme( int code ) +{ + for ( int i = 0; i < ARRAYSIZE( g_Phonemes ); ++i ) + { + PhonemeMap_t *test = &g_Phonemes[ i ]; + if ( test->code == code ) + return test->string; + } + + Warning( "Unrecognized phoneme code %i\n", code ); + return ""; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *text - +// Output : int +//----------------------------------------------------------------------------- +int TextToPhoneme( const char *text ) +{ + for ( int i = 0; i < ARRAYSIZE( g_Phonemes ); ++i ) + { + PhonemeMap_t *test = &g_Phonemes[ i ]; + if ( !stricmp( test->string, text ) ) + return test->code; + } + + Warning( "Unrecognized phoneme %s\n", text ); + return '_'; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : code - +// Output : float +//----------------------------------------------------------------------------- +float WeightForPhonemeCode( int code ) +{ + for ( int i = 0; i < ARRAYSIZE( g_Phonemes ); ++i ) + { + PhonemeMap_t *test = &g_Phonemes[ i ]; + if ( test->code == code ) + return test->weight; + } + + Warning( "Unrecognized phoneme code %i\n", code ); + return 1.0f; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *text - +// Output : float +//----------------------------------------------------------------------------- +float WeightForPhoneme( char *text ) +{ + for ( int i = 0; i < ARRAYSIZE( g_Phonemes ); ++i ) + { + PhonemeMap_t *test = &g_Phonemes[ i ]; + if ( !stricmp( test->string, text ) ) + return test->weight; + } + + Warning( "WeightForPhoneme:: Unrecognized phoneme %s\n", text ); + return 1.0f; +} + +int NumPhonemes() +{ + return ARRAYSIZE( g_Phonemes ); +} + +const char *NameForPhonemeByIndex( int index ) +{ + Assert( index >= 0 && index < NumPhonemes() ); + return g_Phonemes[ index ].string; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *text - +// Output : int +//----------------------------------------------------------------------------- +int TextToPhonemeIndex( const char *text ) +{ + for ( int i = 0; i < ARRAYSIZE( g_Phonemes ); ++i ) + { + PhonemeMap_t *test = &g_Phonemes[ i ]; + if ( !stricmp( test->string, text ) ) + return i; + } + + return -1; +} + +int CodeForPhonemeByIndex( int index ) +{ + if ( index < 0 || index >= NumPhonemes() ) + return '_'; + return g_Phonemes[ index ].code; +} + +bool IsStandardPhoneme( int index ) +{ + if ( index < 0 || index >= NumPhonemes() ) + return false; + return g_Phonemes[ index ].isStandard; +} + +const char *DescForPhonemeByIndex( int index ) +{ + if ( index < 0 || index >= NumPhonemes() ) + return NULL; + return g_Phonemes[ index ].desc; +} \ No newline at end of file diff --git a/sp/src/public/phonemeconverter.h b/sp/src/public/phonemeconverter.h new file mode 100644 index 00000000..5b710828 --- /dev/null +++ b/sp/src/public/phonemeconverter.h @@ -0,0 +1,26 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#ifndef PHONEMECONVERTER_H +#define PHONEMECONVERTER_H +#ifdef _WIN32 +#pragma once +#endif + +const char *ConvertPhoneme( int code ); +int TextToPhoneme( const char *text ); +float WeightForPhonemeCode( int code ); +float WeightForPhoneme( char *text ); + +int NumPhonemes(); +int TextToPhonemeIndex( const char *text ); +const char *NameForPhonemeByIndex( int index ); +int CodeForPhonemeByIndex( int index ); +const char *DescForPhonemeByIndex( int index ); +bool IsStandardPhoneme( int index ); + +#endif // PHONEMECONVERTER_H diff --git a/sp/src/public/phyfile.h b/sp/src/public/phyfile.h new file mode 100644 index 00000000..c6b37720 --- /dev/null +++ b/sp/src/public/phyfile.h @@ -0,0 +1,23 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef PHYFILE_H +#define PHYFILE_H +#pragma once + +#include "datamap.h" + +typedef struct phyheader_s +{ + DECLARE_BYTESWAP_DATADESC(); + int size; + int id; + int solidCount; + long checkSum; // checksum of source .mdl file +} phyheader_t; + +#endif // PHYFILE_H diff --git a/sp/src/public/pixelwriter.h b/sp/src/public/pixelwriter.h new file mode 100644 index 00000000..c2d31d67 --- /dev/null +++ b/sp/src/public/pixelwriter.h @@ -0,0 +1,875 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef PIXELWRITER_H +#define PIXELWRITER_H + +#ifdef _WIN32 +#pragma once +#endif + +#ifdef _WIN32 +#define FORCEINLINE_PIXEL FORCEINLINE +#elif POSIX +#define FORCEINLINE_PIXEL inline +#else +#error "implement me" +#endif + +#include "bitmap/imageformat.h" +#include "tier0/dbg.h" +#include "mathlib/compressed_vector.h" +#include "mathlib/ssemath.h" + +//----------------------------------------------------------------------------- +// Color writing class +//----------------------------------------------------------------------------- + +class CPixelWriter +{ +public: + FORCEINLINE void SetPixelMemory( ImageFormat format, void* pMemory, int stride ); + FORCEINLINE void *GetPixelMemory() { return m_pBase; } + + // this is no longer used: +#if 0 // defined( _X360 ) + // set after SetPixelMemory() + FORCEINLINE void ActivateByteSwapping( bool bSwap ); +#endif + + FORCEINLINE void Seek( int x, int y ); + FORCEINLINE void* SkipBytes( int n ); + FORCEINLINE void SkipPixels( int n ); + FORCEINLINE void WritePixel( int r, int g, int b, int a = 255 ); + FORCEINLINE void WritePixelNoAdvance( int r, int g, int b, int a = 255 ); + FORCEINLINE void WritePixelSigned( int r, int g, int b, int a = 255 ); + FORCEINLINE void WritePixelNoAdvanceSigned( int r, int g, int b, int a = 255 ); + FORCEINLINE void ReadPixelNoAdvance( int &r, int &g, int &b, int &a ); + + // Floating point formats + FORCEINLINE void WritePixelNoAdvanceF( float r, float g, float b, float a = 1.0f ); + FORCEINLINE void WritePixelF( float r, float g, float b, float a = 1.0f ); + + // SIMD formats + FORCEINLINE void WritePixel( FLTX4 rgba ); + FORCEINLINE void WritePixelNoAdvance( FLTX4 rgba ); +#ifdef _X360 + // here are some explicit formats so we can avoid the switch: + FORCEINLINE void WritePixelNoAdvance_RGBA8888( FLTX4 rgba ); + FORCEINLINE void WritePixelNoAdvance_BGRA8888( FLTX4 rgba ); + // as above, but with m_pBits passed in to avoid a LHS + FORCEINLINE void WritePixelNoAdvance_BGRA8888( FLTX4 rgba, void *pBits ); + // for writing entire SIMD registers at once when they have + // already been packed, and when m_pBits is vector-aligned + // (which is a requirement for write-combined memory) + // offset is added to m_pBits (saving you from the obligatory + // LHS of a SkipBytes) + FORCEINLINE void WriteFourPixelsExplicitLocation_BGRA8888( FLTX4 rgba, int offset ); +#endif + + + FORCEINLINE unsigned char GetPixelSize() { return m_Size; } + + FORCEINLINE bool IsUsingFloatFormat() const; + FORCEINLINE unsigned char *GetCurrentPixel() { return m_pBits; } + +private: + enum + { + PIXELWRITER_USING_FLOAT_FORMAT = 0x01, + PIXELWRITER_USING_16BIT_FLOAT_FORMAT = 0x02, + PIXELWRITER_SWAPBYTES = 0x04, + }; + + unsigned char* m_pBase; + unsigned char* m_pBits; + unsigned short m_BytesPerRow; + unsigned char m_Size; + unsigned char m_nFlags; + signed short m_RShift; + signed short m_GShift; + signed short m_BShift; + signed short m_AShift; + unsigned int m_RMask; + unsigned int m_GMask; + unsigned int m_BMask; + unsigned int m_AMask; + +#ifdef _X360 + ImageFormat m_Format; +public: + inline const ImageFormat &GetFormat() { return m_Format; } +private: +#endif +}; + +FORCEINLINE_PIXEL bool CPixelWriter::IsUsingFloatFormat() const +{ + return (m_nFlags & PIXELWRITER_USING_FLOAT_FORMAT) != 0; +} + +FORCEINLINE_PIXEL void CPixelWriter::SetPixelMemory( ImageFormat format, void* pMemory, int stride ) +{ + m_pBits = (unsigned char*)pMemory; + m_pBase = m_pBits; + m_BytesPerRow = (unsigned short)stride; + m_nFlags = 0; +#ifdef _X360 + m_Format = format; +#endif + + switch ( format ) + { + case IMAGE_FORMAT_R32F: // NOTE! : the low order bits are first in this naming convention. + m_Size = 4; + m_RShift = 0; + m_GShift = 0; + m_BShift = 0; + m_AShift = 0; + m_RMask = 0xFFFFFFFF; + m_GMask = 0x0; + m_BMask = 0x0; + m_AMask = 0x0; + m_nFlags |= PIXELWRITER_USING_FLOAT_FORMAT; + break; + + case IMAGE_FORMAT_RGBA32323232F: + m_Size = 16; + m_RShift = 0; + m_GShift = 32; + m_BShift = 64; + m_AShift = 96; + m_RMask = 0xFFFFFFFF; + m_GMask = 0xFFFFFFFF; + m_BMask = 0xFFFFFFFF; + m_AMask = 0xFFFFFFFF; + m_nFlags |= PIXELWRITER_USING_FLOAT_FORMAT; + break; + + case IMAGE_FORMAT_RGBA16161616F: + m_Size = 8; + m_RShift = 0; + m_GShift = 16; + m_BShift = 32; + m_AShift = 48; + m_RMask = 0xFFFF; + m_GMask = 0xFFFF; + m_BMask = 0xFFFF; + m_AMask = 0xFFFF; + m_nFlags |= PIXELWRITER_USING_FLOAT_FORMAT | PIXELWRITER_USING_16BIT_FLOAT_FORMAT; + break; + + case IMAGE_FORMAT_RGBA8888: +#if defined( _X360 ) + case IMAGE_FORMAT_LINEAR_RGBA8888: +#endif + m_Size = 4; + m_RShift = 0; + m_GShift = 8; + m_BShift = 16; + m_AShift = 24; + m_RMask = 0xFF; + m_GMask = 0xFF; + m_BMask = 0xFF; + m_AMask = 0xFF; + break; + + case IMAGE_FORMAT_BGRA8888: // NOTE! : the low order bits are first in this naming convention. +#if defined( _X360 ) + case IMAGE_FORMAT_LINEAR_BGRA8888: +#endif + m_Size = 4; + m_RShift = 16; + m_GShift = 8; + m_BShift = 0; + m_AShift = 24; + m_RMask = 0xFF; + m_GMask = 0xFF; + m_BMask = 0xFF; + m_AMask = 0xFF; + break; + + case IMAGE_FORMAT_BGRX8888: +#if defined( _X360 ) + case IMAGE_FORMAT_LINEAR_BGRX8888: +#endif + m_Size = 4; + m_RShift = 16; + m_GShift = 8; + m_BShift = 0; + m_AShift = 24; + m_RMask = 0xFF; + m_GMask = 0xFF; + m_BMask = 0xFF; + m_AMask = 0x00; + break; + + case IMAGE_FORMAT_BGRA4444: + m_Size = 2; + m_RShift = 4; + m_GShift = 0; + m_BShift = -4; + m_AShift = 8; + m_RMask = 0xF0; + m_GMask = 0xF0; + m_BMask = 0xF0; + m_AMask = 0xF0; + break; + + case IMAGE_FORMAT_BGR888: + m_Size = 3; + m_RShift = 16; + m_GShift = 8; + m_BShift = 0; + m_AShift = 0; + m_RMask = 0xFF; + m_GMask = 0xFF; + m_BMask = 0xFF; + m_AMask = 0x00; + break; + + case IMAGE_FORMAT_BGR565: + m_Size = 2; + m_RShift = 8; + m_GShift = 3; + m_BShift = -3; + m_AShift = 0; + m_RMask = 0xF8; + m_GMask = 0xFC; + m_BMask = 0xF8; + m_AMask = 0x00; + break; + + case IMAGE_FORMAT_BGRA5551: + case IMAGE_FORMAT_BGRX5551: + m_Size = 2; + m_RShift = 7; + m_GShift = 2; + m_BShift = -3; + m_AShift = 8; + m_RMask = 0xF8; + m_GMask = 0xF8; + m_BMask = 0xF8; + m_AMask = 0x80; + break; + + // GR - alpha format for HDR support + case IMAGE_FORMAT_A8: + m_Size = 1; + m_RShift = 0; + m_GShift = 0; + m_BShift = 0; + m_AShift = 0; + m_RMask = 0x00; + m_GMask = 0x00; + m_BMask = 0x00; + m_AMask = 0xFF; + break; + + case IMAGE_FORMAT_UVWQ8888: + m_Size = 4; + m_RShift = 0; + m_GShift = 8; + m_BShift = 16; + m_AShift = 24; + m_RMask = 0xFF; + m_GMask = 0xFF; + m_BMask = 0xFF; + m_AMask = 0xFF; + break; + + case IMAGE_FORMAT_RGBA16161616: +#if defined( _X360 ) + case IMAGE_FORMAT_LINEAR_RGBA16161616: +#endif + m_Size = 8; + if ( !IsX360() ) + { + m_RShift = 0; + m_GShift = 16; + m_BShift = 32; + m_AShift = 48; + } + else + { + m_RShift = 48; + m_GShift = 32; + m_BShift = 16; + m_AShift = 0; + } + m_RMask = 0xFFFF; + m_GMask = 0xFFFF; + m_BMask = 0xFFFF; + m_AMask = 0xFFFF; + break; + + case IMAGE_FORMAT_I8: + // whatever goes into R is considered the intensity. + m_Size = 1; + m_RShift = 0; + m_GShift = 0; + m_BShift = 0; + m_AShift = 0; + m_RMask = 0xFF; + m_GMask = 0x00; + m_BMask = 0x00; + m_AMask = 0x00; + break; + // FIXME: Add more color formats as need arises + default: + { + static bool format_error_printed[NUM_IMAGE_FORMATS]; + if ( !format_error_printed[format] ) + { + Assert( 0 ); + Msg( "CPixelWriter::SetPixelMemory: Unsupported image format %i\n", format ); + format_error_printed[format] = true; + } + m_Size = 0; // set to zero so that we don't stomp memory for formats that we don't understand. + } + break; + } +} + +#if 0 // defined( _X360 ) +FORCEINLINE void CPixelWriter::ActivateByteSwapping( bool bSwap ) +{ + // X360TBD: Who is trying to use this? + // Purposely not hooked up because PixelWriter has been ported to read/write native pixels only + Assert( 0 ); + + if ( bSwap && !(m_nFlags & PIXELWRITER_SWAPBYTES ) ) + { + m_nFlags |= PIXELWRITER_SWAPBYTES; + + // only tested with 4 byte formats + Assert( m_Size == 4 ); + } + else if ( !bSwap && (m_nFlags & PIXELWRITER_SWAPBYTES ) ) + { + m_nFlags &= ~PIXELWRITER_SWAPBYTES; + } + else + { + // same state + return; + } + + // swap the shifts + m_RShift = 24-m_RShift; + m_GShift = 24-m_GShift; + m_BShift = 24-m_BShift; + m_AShift = 24-m_AShift; +} +#endif + +//----------------------------------------------------------------------------- +// Sets where we're writing to +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::Seek( int x, int y ) +{ + m_pBits = m_pBase + y * m_BytesPerRow + x * m_Size; +} + + +//----------------------------------------------------------------------------- +// Skips n bytes: +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void* CPixelWriter::SkipBytes( int n ) RESTRICT +{ + m_pBits += n; + return m_pBits; +} + + +//----------------------------------------------------------------------------- +// Skips n pixels: +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::SkipPixels( int n ) +{ + SkipBytes( n * m_Size ); +} + + +//----------------------------------------------------------------------------- +// Writes a pixel without advancing the index PC ONLY +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::WritePixelNoAdvanceF( float r, float g, float b, float a ) +{ + Assert( IsUsingFloatFormat() ); + + // X360TBD: Not ported + Assert( IsPC() ); + + if (PIXELWRITER_USING_16BIT_FLOAT_FORMAT & m_nFlags) + { + float16 fp16[4]; + fp16[0].SetFloat( r ); + fp16[1].SetFloat( g ); + fp16[2].SetFloat( b ); + fp16[3].SetFloat( a ); + // fp16 + unsigned short pBuf[4] = { 0, 0, 0, 0 }; + pBuf[ m_RShift >> 4 ] |= (fp16[0].GetBits() & m_RMask) << ( m_RShift & 0xF ); + pBuf[ m_GShift >> 4 ] |= (fp16[1].GetBits() & m_GMask) << ( m_GShift & 0xF ); + pBuf[ m_BShift >> 4 ] |= (fp16[2].GetBits() & m_BMask) << ( m_BShift & 0xF ); + pBuf[ m_AShift >> 4 ] |= (fp16[3].GetBits() & m_AMask) << ( m_AShift & 0xF ); + memcpy( m_pBits, pBuf, m_Size ); + } + else + { + // fp32 + int pBuf[4] = { 0, 0, 0, 0 }; + pBuf[ m_RShift >> 5 ] |= (FloatBits(r) & m_RMask) << ( m_RShift & 0x1F ); + pBuf[ m_GShift >> 5 ] |= (FloatBits(g) & m_GMask) << ( m_GShift & 0x1F ); + pBuf[ m_BShift >> 5 ] |= (FloatBits(b) & m_BMask) << ( m_BShift & 0x1F ); + pBuf[ m_AShift >> 5 ] |= (FloatBits(a) & m_AMask) << ( m_AShift & 0x1F ); + memcpy( m_pBits, pBuf, m_Size ); + } +} + +//----------------------------------------------------------------------------- +// Writes a pixel, advances the write index +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::WritePixelF( float r, float g, float b, float a ) +{ + WritePixelNoAdvanceF(r, g, b, a); + m_pBits += m_Size; +} + + +//----------------------------------------------------------------------------- +// Writes a pixel, advances the write index +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::WritePixel( int r, int g, int b, int a ) +{ + WritePixelNoAdvance(r,g,b,a); + m_pBits += m_Size; +} + +//----------------------------------------------------------------------------- +// Writes a pixel, advances the write index +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::WritePixelSigned( int r, int g, int b, int a ) +{ + WritePixelNoAdvanceSigned(r,g,b,a); + m_pBits += m_Size; +} + + +//----------------------------------------------------------------------------- +// Writes a pixel without advancing the index +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::WritePixelNoAdvance( int r, int g, int b, int a ) +{ + Assert( !IsUsingFloatFormat() ); + + if ( m_Size <= 0 ) + { + return; + } + if ( m_Size < 5 ) + { + unsigned int val = (r & m_RMask) << m_RShift; + val |= (g & m_GMask) << m_GShift; + val |= (m_BShift > 0) ? ((b & m_BMask) << m_BShift) : ((b & m_BMask) >> -m_BShift); + val |= (a & m_AMask) << m_AShift; + + switch( m_Size ) + { + default: + Assert( 0 ); + return; + case 1: + { + m_pBits[0] = (unsigned char)((val & 0xff)); + return; + } + case 2: + { + ((unsigned short *)m_pBits)[0] = (unsigned short)((val & 0xffff)); + return; + } + case 3: + { + if ( IsPC() || !IsX360() ) + { + ((unsigned short *)m_pBits)[0] = (unsigned short)((val & 0xffff)); + m_pBits[2] = (unsigned char)((val >> 16) & 0xff); + } + else + { + m_pBits[0] = (unsigned char)(((val >> 16) & 0xff)); + m_pBits[1] = (unsigned char)(((val >> 8 ) & 0xff)); + m_pBits[2] = (unsigned char)(val & 0xff); + } + return; + } + case 4: + { + ((unsigned int *)m_pBits)[0] = val; + return; + } + } + } + else // RGBA32323232 or RGBA16161616 -- PC only. + { + AssertMsg(!IsX360(), "Unsupported lightmap format used in WritePixelNoAdvance(). This is a severe performance fault.\n"); + + int64 val = ( ( int64 )(r & m_RMask) ) << m_RShift; + val |= ( ( int64 )(g & m_GMask) ) << m_GShift; + val |= (m_BShift > 0) ? ((( int64 )( b & m_BMask)) << m_BShift) : (((int64)( b & m_BMask)) >> -m_BShift); + val |= ( ( int64 )(a & m_AMask) ) << m_AShift; + + switch( m_Size ) + { + case 6: + { + if ( IsPC() || !IsX360() ) + { + ((unsigned int *)m_pBits)[0] = val & 0xffffffff; + ((unsigned short *)m_pBits)[2] = (unsigned short)( ( val >> 32 ) & 0xffff ); + } + else + { + ((unsigned int *)m_pBits)[0] = (val >> 16) & 0xffffffff; + ((unsigned short *)m_pBits)[2] = (unsigned short)( val & 0xffff ); + } + return; + } + case 8: + { + if ( IsPC() || !IsX360() ) + { + ((unsigned int *)m_pBits)[0] = val & 0xffffffff; + ((unsigned int *)m_pBits)[1] = ( val >> 32 ) & 0xffffffff; + } + else + { + ((unsigned int *)m_pBits)[0] = ( val >> 32 ) & 0xffffffff; + ((unsigned int *)m_pBits)[1] = val & 0xffffffff; + } + return; + } + default: + Assert( 0 ); + return; + } + } +} + +#ifdef _X360 +// There isn't a PC port of these because of the many varied +// pixel formats the PC deals with. If you write SSE versions +// of all the various necessary packers, then this can be made +// to work on PC. + +//----------------------------------------------------------------------------- +// Writes a pixel, advances the write index +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::WritePixel( FLTX4 rgba ) RESTRICT +{ + WritePixelNoAdvance(rgba); + m_pBits += m_Size; +} + +//----------------------------------------------------------------------------- +// Writes a pixel without advancing the index +// rgba are four float values, each on the range 0..255 (though they may leak +// fractionally over 255 due to numerical errors earlier) +//----------------------------------------------------------------------------- +FORCEINLINE_PIXEL void CPixelWriter::WritePixelNoAdvance( FLTX4 rgba ) RESTRICT +{ + Assert( !IsUsingFloatFormat() ); + + switch (m_Size) + { + case 0: + return; + case 4: + { + AssertMsg((reinterpret_cast(m_pBits) & 0x03) == 0,"Unaligned m_pBits in WritePixelNoAdvance!"); + switch ( m_Format ) + { + // note: format names are low-order-byte first. + case IMAGE_FORMAT_RGBA8888: + case IMAGE_FORMAT_LINEAR_RGBA8888: + WritePixelNoAdvance_RGBA8888(rgba); + break; + + case IMAGE_FORMAT_BGRA8888: // NOTE! : the low order bits are first in this naming convention. + case IMAGE_FORMAT_LINEAR_BGRA8888: + WritePixelNoAdvance_BGRA8888(rgba); + break; + + + default: + AssertMsg1(false, "Unknown four-byte pixel format %d in lightmap write.\n", m_Format); + } + break; + } + + default: + AssertMsg1(false, "WritePixelNoAdvance on unsupported 360 %d-byte format\n", m_Size); + break; + } + +} + + +// here are some explicit formats so we can avoid the switch: +FORCEINLINE void CPixelWriter::WritePixelNoAdvance_RGBA8888( FLTX4 rgba ) +{ + // it's easier to do tiered convert-saturates here + // than the d3d color convertor op + + // first permute + const static fltx4 permReverse = XMVectorPermuteControl(3,2,1,0); + fltx4 N = XMVectorPermute(rgba, rgba, permReverse); + + N = __vctuxs(N, 0); // convert to unsigned fixed point 0 w/ saturate + N = __vpkuwus(N, N); // convert to halfword saturate + N = __vpkuhus(N, N); // convert to byte saturate + N = __vspltw(N, 0); // splat w-word to all four + + __stvewx(N, m_pBits, 0); // store whatever word happens to be aligned with m_pBits to that word +} + +FORCEINLINE void CPixelWriter::WritePixelNoAdvance_BGRA8888( FLTX4 rgba ) +{ + WritePixelNoAdvance_BGRA8888( rgba, m_pBits ); +} + +FORCEINLINE void CPixelWriter::WritePixelNoAdvance_BGRA8888( FLTX4 rgba, void * RESTRICT pBits ) RESTRICT +{ + // this happens to be in an order such that we can use the handy builtin packing op + // clamp to 0..255 (coz it might have leaked over) + static const fltx4 vTwoFiftyFive = {255.0f, 255.0f, 255.0f, 255.0f}; + fltx4 N = MinSIMD(vTwoFiftyFive, rgba); + + // the magic number such that when mul-accummulated against rbga, + // gets us a representation 3.0 + (r)*2^-22 -- puts the bits at + // the bottom of the float + static CONST XMVECTOR PackScale = { (1.0f / (FLOAT)(1 << 22)), (1.0f / (FLOAT)(1 << 22)), (1.0f / (FLOAT)(1 << 22)), (1.0f / (FLOAT)(1 << 22))}; // 255.0f / (FLOAT)(1 << 22) + static const XMVECTOR Three = {3.0f, 3.0f, 3.0f, 3.0f}; + + N = __vmaddfp(N, PackScale, Three); + N = __vpkd3d(N, N, VPACK_D3DCOLOR, VPACK_32, 3); // pack to X word + N = __vspltw(N, 0); // splat X + + // this is a nasty thing to work around the April XDK bug in __stvewx + { + void * RESTRICT copyOfPBits = pBits; + __stvewx(N, copyOfPBits, 0); + } + +} + +// for writing entire SIMD registers at once +FORCEINLINE void CPixelWriter::WriteFourPixelsExplicitLocation_BGRA8888 ( FLTX4 rgba, int offset ) +{ + Assert( (reinterpret_cast(m_pBits) & 15) == 0 ); // assert alignment + XMStoreVector4A( m_pBits + offset , rgba ); +} + + +#endif + +//----------------------------------------------------------------------------- +// Writes a signed pixel without advancing the index +//----------------------------------------------------------------------------- + +FORCEINLINE_PIXEL void CPixelWriter::WritePixelNoAdvanceSigned( int r, int g, int b, int a ) +{ + Assert( !IsUsingFloatFormat() ); + + if ( m_Size <= 0 ) + { + return; + } + + if ( m_Size < 5 ) + { + int val = (r & m_RMask) << m_RShift; + val |= (g & m_GMask) << m_GShift; + val |= (m_BShift > 0) ? ((b & m_BMask) << m_BShift) : ((b & m_BMask) >> -m_BShift); + val |= (a & m_AMask) << m_AShift; + signed char *pSignedBits = (signed char *)m_pBits; + + if ( IsPC() || !IsX360() ) + { + switch ( m_Size ) + { + case 4: + pSignedBits[3] = (signed char)((val >> 24) & 0xff); + // fall through intentionally. + case 3: + pSignedBits[2] = (signed char)((val >> 16) & 0xff); + // fall through intentionally. + case 2: + pSignedBits[1] = (signed char)((val >> 8) & 0xff); + // fall through intentionally. + case 1: + pSignedBits[0] = (signed char)((val & 0xff)); + // fall through intentionally. + return; + } + } + else + { + switch ( m_Size ) + { + case 4: + pSignedBits[0] = (signed char)((val >> 24) & 0xff); + pSignedBits[1] = (signed char)((val >> 16) & 0xff); + pSignedBits[2] = (signed char)((val >> 8) & 0xff); + pSignedBits[3] = (signed char)(val & 0xff); + break; + case 3: + pSignedBits[0] = (signed char)((val >> 16) & 0xff); + pSignedBits[1] = (signed char)((val >> 8) & 0xff); + pSignedBits[2] = (signed char)(val & 0xff); + break; + case 2: + pSignedBits[0] = (signed char)((val >> 8) & 0xff); + pSignedBits[1] = (signed char)(val & 0xff); + break; + case 1: + pSignedBits[0] = (signed char)(val & 0xff); + break; + } + } + } + else + { + int64 val = ( ( int64 )(r & m_RMask) ) << m_RShift; + val |= ( ( int64 )(g & m_GMask) ) << m_GShift; + val |= (m_BShift > 0) ? ((( int64 )( b & m_BMask)) << m_BShift) : (((int64)( b & m_BMask)) >> -m_BShift); + val |= ( ( int64 )(a & m_AMask) ) << m_AShift; + signed char *pSignedBits = ( signed char * )m_pBits; + + if ( IsPC() || !IsX360() ) + { + switch( m_Size ) + { + case 8: + pSignedBits[7] = (signed char)((val >> 56) & 0xff); + pSignedBits[6] = (signed char)((val >> 48) & 0xff); + // fall through intentionally. + case 6: + pSignedBits[5] = (signed char)((val >> 40) & 0xff); + pSignedBits[4] = (signed char)((val >> 32) & 0xff); + // fall through intentionally. + case 4: + pSignedBits[3] = (signed char)((val >> 24) & 0xff); + // fall through intentionally. + case 3: + pSignedBits[2] = (signed char)((val >> 16) & 0xff); + // fall through intentionally. + case 2: + pSignedBits[1] = (signed char)((val >> 8) & 0xff); + // fall through intentionally. + case 1: + pSignedBits[0] = (signed char)((val & 0xff)); + break; + default: + Assert( 0 ); + return; + } + } + else + { + switch( m_Size ) + { + case 8: + pSignedBits[0] = (signed char)((val >> 56) & 0xff); + pSignedBits[1] = (signed char)((val >> 48) & 0xff); + pSignedBits[2] = (signed char)((val >> 40) & 0xff); + pSignedBits[3] = (signed char)((val >> 32) & 0xff); + pSignedBits[4] = (signed char)((val >> 24) & 0xff); + pSignedBits[5] = (signed char)((val >> 16) & 0xff); + pSignedBits[6] = (signed char)((val >> 8) & 0xff); + pSignedBits[7] = (signed char)(val & 0xff); + break; + case 6: + pSignedBits[0] = (signed char)((val >> 40) & 0xff); + pSignedBits[1] = (signed char)((val >> 32) & 0xff); + pSignedBits[2] = (signed char)((val >> 24) & 0xff); + pSignedBits[3] = (signed char)((val >> 16) & 0xff); + pSignedBits[4] = (signed char)((val >> 8) & 0xff); + pSignedBits[5] = (signed char)(val & 0xff); + break; + case 4: + pSignedBits[0] = (signed char)((val >> 24) & 0xff); + pSignedBits[1] = (signed char)((val >> 16) & 0xff); + pSignedBits[2] = (signed char)((val >> 8) & 0xff); + pSignedBits[3] = (signed char)(val & 0xff); + break; + case 3: + pSignedBits[0] = (signed char)((val >> 16) & 0xff); + pSignedBits[1] = (signed char)((val >> 8) & 0xff); + pSignedBits[2] = (signed char)(val & 0xff); + break; + case 2: + pSignedBits[0] = (signed char)((val >> 8) & 0xff); + pSignedBits[1] = (signed char)(val & 0xff); + break; + case 1: + pSignedBits[0] = (signed char)(val & 0xff); + break; + default: + Assert( 0 ); + return; + } + } + } +} + +FORCEINLINE_PIXEL void CPixelWriter::ReadPixelNoAdvance( int &r, int &g, int &b, int &a ) +{ + Assert( !IsUsingFloatFormat() ); + + int val = m_pBits[0]; + if ( m_Size > 1 ) + { + if ( IsPC() || !IsX360() ) + { + val |= (int)m_pBits[1] << 8; + if ( m_Size > 2 ) + { + val |= (int)m_pBits[2] << 16; + if ( m_Size > 3 ) + { + val |= (int)m_pBits[3] << 24; + } + } + } + else + { + val <<= 8; + val |= (int)m_pBits[1]; + if ( m_Size > 2 ) + { + val <<= 8; + val |= (int)m_pBits[2]; + if ( m_Size > 3 ) + { + val <<= 8; + val |= (int)m_pBits[3]; + } + } + } + } + + r = (val>>m_RShift) & m_RMask; + g = (val>>m_GShift) & m_GMask; + b = (val>>m_BShift) & m_BMask; + a = (val>>m_AShift) & m_AMask; +} + +#endif // PIXELWRITER_H; diff --git a/sp/src/public/posedebugger.cpp b/sp/src/public/posedebugger.cpp new file mode 100644 index 00000000..b8a7d1ed --- /dev/null +++ b/sp/src/public/posedebugger.cpp @@ -0,0 +1,655 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "tier0/dbg.h" +#include "tier0/platform.h" +#include "mathlib/mathlib.h" +#include "tier0/tslist.h" +#include "tier1/utlmap.h" +#include "tier1/convar.h" + +#include "bone_setup.h" + +#include "con_nprint.h" +#include "cdll_int.h" +#include "globalvars_base.h" + +#include "posedebugger.h" + +#include "iclientnetworkable.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +extern IVEngineClient *engine; +extern CGlobalVarsBase *gpGlobals; + +static ConVar ui_posedebug_fade_in_time( "ui_posedebug_fade_in_time", "0.2", + FCVAR_CHEAT | FCVAR_DONTRECORD, + "Time during which a new pose activity layer is shown in green in +posedebug UI" ); +static ConVar ui_posedebug_fade_out_time( "ui_posedebug_fade_out_time", "0.8", + FCVAR_CHEAT | FCVAR_DONTRECORD, + "Time to keep a no longer active pose activity layer in red until removing it from +posedebug UI" ); + + +////////////////////////////////////////////////////////////////////////// +// +// CPoseDebuggerStub : IPoseDebugger +// empty interface implementation +// +////////////////////////////////////////////////////////////////////////// + +class CPoseDebuggerStub : public IPoseDebugger +{ +public: + virtual void StartBlending( IClientNetworkable *pEntity, const CStudioHdr *pStudioHdr ) { } + virtual void AccumulatePose( + const CStudioHdr *pStudioHdr, + CIKContext *pIKContext, + Vector pos[], + Quaternion q[], + int sequence, + float cycle, + const float poseParameter[], + int boneMask, + float flWeight, + float flTime + ) { } +}; + +static CPoseDebuggerStub s_PoseDebuggerStub; +IPoseDebugger *g_pPoseDebugger = &s_PoseDebuggerStub; + +////////////////////////////////////////////////////////////////////////// +// +// CPoseDebuggerImpl : IPoseDebugger +// Purpose: Main implementation of the pose debugger +// Declaration +// +////////////////////////////////////////////////////////////////////////// + +class ModelPoseDebugInfo +{ +public: + ModelPoseDebugInfo() : m_iEntNum( 0 ), m_iCurrentText( 0 ) { } + + +public: + // Entity number + int m_iEntNum; + + // Currently processed text + int m_iCurrentText; + + // Info Text Flags + enum InfoTextFlags + { + F_SEEN_THIS_FRAME = 1 << 0, + F_SEEN_LAST_FRAME = 1 << 1, + }; + + struct InfoText + { + InfoText() { memset( this, 0, sizeof( *this ) ); } + + // Flags + uint32 m_uiFlags; + + // Time seen + float m_flTimeToLive, m_flTimeAlive; + + // Activity/label + int m_iActivity; + char m_chActivity[100]; + char m_chLabel[100]; + + // Text + char m_chTextLines[4][256]; + enum + { + MAX_TEXT_LINES = 4 + }; + }; + + CCopyableUtlVector< InfoText > m_arrTxt; + + +public: + // Add an info text + void AddInfoText( InfoText *x, ModelPoseDebugInfo *pOld ); + + // Lookup an info text + InfoText *LookupInfoText( InfoText *x ); + + // Print pending info text + void PrintPendingInfoText( int &rnPosPrint ); +}; + +void ModelPoseDebugInfo::AddInfoText( InfoText *x, ModelPoseDebugInfo *pOld ) +{ + if ( x ) + { + // Try to set the proper flags on the info text + x->m_uiFlags &= ~F_SEEN_LAST_FRAME; + x->m_uiFlags |= F_SEEN_THIS_FRAME; + } + + // If we have smth to compare against + if ( pOld ) + { + // Search for the same activity/label in the other model pose debug info + ModelPoseDebugInfo &o = *pOld; + int k = o.m_iCurrentText; + if ( x ) + { + for ( ; k < o.m_arrTxt.Count(); ++ k ) + { + InfoText &txt = o.m_arrTxt[k]; + if ( ( txt.m_uiFlags & F_SEEN_THIS_FRAME ) && + !stricmp( x->m_chActivity, txt.m_chActivity ) && + !stricmp( x->m_chLabel, txt.m_chLabel ) && + ( x->m_iActivity == txt.m_iActivity ) ) + { + x->m_flTimeAlive = txt.m_flTimeAlive; + break; + } + } + } + else + { + k = o.m_arrTxt.Count(); + } + + // Range of finished activities + int iFinishedRange[2] = { o.m_iCurrentText, k }; + + // Check whether this is a new message + if ( k == o.m_arrTxt.Count() ) + { + if ( !x ) + { + o.m_iCurrentText = k; + } + else + { + // Don't update the current when insertion happens and don't have finished commands + iFinishedRange[1] = iFinishedRange[0]; + } + } + else + { + o.m_iCurrentText = k + 1; + if ( x ) + { + x->m_uiFlags |= F_SEEN_LAST_FRAME; + x->m_flTimeAlive += gpGlobals->frametime; + } + } + + // Everything before finished + for ( int iFinished = iFinishedRange[0]; iFinished < iFinishedRange[1]; ++ iFinished ) + { + InfoText &txtFinished = o.m_arrTxt[ iFinished ]; + + if ( txtFinished.m_uiFlags & F_SEEN_THIS_FRAME ) + txtFinished.m_uiFlags |= F_SEEN_LAST_FRAME; + + txtFinished.m_uiFlags &= ~F_SEEN_THIS_FRAME; + + txtFinished.m_flTimeToLive -= gpGlobals->frametime; + txtFinished.m_flTimeAlive += gpGlobals->frametime; + + if ( txtFinished.m_flTimeToLive >= 0.0f ) + m_arrTxt.AddToTail( txtFinished ); + } + } + + if ( x ) + { + // Now add it to the array + x->m_flTimeToLive = ui_posedebug_fade_out_time.GetFloat(); + m_arrTxt.AddToTail( *x ); + } +} + +ModelPoseDebugInfo::InfoText * ModelPoseDebugInfo::LookupInfoText( InfoText *x ) +{ + int k = m_iCurrentText; + if ( x ) + { + for ( ; k < m_arrTxt.Count(); ++ k ) + { + InfoText &txt = m_arrTxt[k]; + if ( ( txt.m_uiFlags & F_SEEN_THIS_FRAME ) && + !stricmp( x->m_chActivity, txt.m_chActivity ) && + !stricmp( x->m_chLabel, txt.m_chLabel ) && + ( x->m_iActivity == txt.m_iActivity ) ) + { + return &txt; + } + } + } + return NULL; +} + +void ModelPoseDebugInfo::PrintPendingInfoText( int &rnPosPrint ) +{ + con_nprint_s nxPrn = { 0 }; + nxPrn.time_to_live = -1; + nxPrn.color[0] = 1.0f, nxPrn.color[1] = 1.0f, nxPrn.color[2] = 1.0f; + nxPrn.fixed_width_font = true; + + float const flFadeInTime = ui_posedebug_fade_in_time.GetFloat(); + float const flFadeOutTime = ui_posedebug_fade_out_time.GetFloat(); + + // Now print all the accumulated spew + for ( int k = m_iCurrentText; k < m_arrTxt.Count(); ++ k ) + { + InfoText &prntxt = m_arrTxt[k]; + + switch( prntxt.m_uiFlags & ( F_SEEN_LAST_FRAME | F_SEEN_THIS_FRAME ) ) + { + case ( F_SEEN_LAST_FRAME | F_SEEN_THIS_FRAME ) : + nxPrn.color[0] = 1.f; + nxPrn.color[1] = 1.f; + nxPrn.color[2] = 1.f; + if ( prntxt.m_flTimeAlive > flFadeInTime ) + break; + else + NULL; // Fall-through to keep showing in green + case F_SEEN_THIS_FRAME : + if ( flFadeInTime > 0.f ) + { + nxPrn.color[0] = 1.f * prntxt.m_flTimeAlive / flFadeInTime; + nxPrn.color[1] = 1.f; + nxPrn.color[2] = 1.f * prntxt.m_flTimeAlive / flFadeInTime; + } + else + { + nxPrn.color[0] = ( prntxt.m_flTimeAlive > 0.0f ) ? 1.f : 0.f; + nxPrn.color[1] = 1.f; + nxPrn.color[2] = ( prntxt.m_flTimeAlive > 0.0f ) ? 1.f : 0.f; + } + break; + case F_SEEN_LAST_FRAME : + case 0: + if ( flFadeOutTime > 0.f ) + nxPrn.color[0] = 1.f * prntxt.m_flTimeToLive / flFadeOutTime; + else + nxPrn.color[0] = ( prntxt.m_flTimeToLive > 0.0f ) ? 1.f : 0.f; + nxPrn.color[1] = 0.f; + nxPrn.color[2] = 0.f; + break; + } + + nxPrn.index = ( rnPosPrint += 1 ); + engine->Con_NXPrintf( &nxPrn, "%s", prntxt.m_chTextLines[0] ); + + for ( int iLine = 1; iLine < ModelPoseDebugInfo::InfoText::MAX_TEXT_LINES; ++ iLine) + { + if ( !prntxt.m_chTextLines[iLine][0] ) + break; + + nxPrn.index = ( rnPosPrint += 1 ); + engine->Con_NXPrintf( &nxPrn, "%s", prntxt.m_chTextLines[iLine] ); + } + } + + m_iCurrentText = m_arrTxt.Count(); +} + + + +class CPoseDebuggerImpl : public IPoseDebugger +{ +public: + CPoseDebuggerImpl(); + ~CPoseDebuggerImpl(); + +public: + void ShowAllModels( bool bShow ); + void ShowModel( int iEntNum, bool bShow ); + bool IsModelShown( int iEntNum ) const; + +public: + virtual void StartBlending( IClientNetworkable *pEntity, const CStudioHdr *pStudioHdr ); + virtual void AccumulatePose( + const CStudioHdr *pStudioHdr, + CIKContext *pIKContext, + Vector pos[], + Quaternion q[], + int sequence, + float cycle, + const float poseParameter[], + int boneMask, + float flWeight, + float flTime + ); + +protected: + typedef CUtlMap< CStudioHdr const *, ModelPoseDebugInfo > MapModel; + MapModel m_mapModel, m_mapModelOld; + int m_nPosPrint; + + CBitVec< MAX_EDICTS > m_uiMaskShowModels; + + CStudioHdr const *m_pLastModel; +}; + +static CPoseDebuggerImpl s_PoseDebuggerImpl; + +////////////////////////////////////////////////////////////////////////// +// +// CPoseDebuggerImpl +// Implementation +// +////////////////////////////////////////////////////////////////////////// + +CPoseDebuggerImpl::CPoseDebuggerImpl() : + m_mapModel( DefLessFunc( CStudioHdr const * ) ), + m_mapModelOld( DefLessFunc( CStudioHdr const * ) ), + m_nPosPrint( 0 ), + m_pLastModel( NULL ) +{ + m_uiMaskShowModels.SetAll(); +} + +CPoseDebuggerImpl::~CPoseDebuggerImpl() +{ + // g_pPoseDebugger = &s_PoseDebuggerStub; +} + +void CPoseDebuggerImpl::ShowAllModels( bool bShow ) +{ + bShow ? m_uiMaskShowModels.SetAll() : m_uiMaskShowModels.ClearAll(); +} + +void CPoseDebuggerImpl::ShowModel( int iEntNum, bool bShow ) +{ + Assert( iEntNum < MAX_EDICTS ); + if ( iEntNum < MAX_EDICTS ) + m_uiMaskShowModels.Set( iEntNum, bShow ); +} + +bool CPoseDebuggerImpl::IsModelShown( int iEntNum ) const +{ + Assert( iEntNum < MAX_EDICTS ); + if ( iEntNum >= 0 && iEntNum < MAX_EDICTS ) + return m_uiMaskShowModels.IsBitSet( iEntNum ); + else + return false; +} + +void CPoseDebuggerImpl::StartBlending( IClientNetworkable *pEntity, const CStudioHdr *pStudioHdr ) +{ +// virtualmodel_t const *pVMdl = pStudioHdr->GetVirtualModel(); +// if ( !pVMdl ) +// return; + + // If we are starting a new model then finalize the previous one + if ( pStudioHdr != m_pLastModel && m_pLastModel ) + { + MapModel::IndexType_t idx = m_mapModel.Find( m_pLastModel ); + if ( idx != m_mapModel.InvalidIndex() ) + { + ModelPoseDebugInfo &mpi = m_mapModel.Element( idx ); + ModelPoseDebugInfo *pMpiOld = NULL; + MapModel::IndexType_t idxMapModelOld = m_mapModelOld.Find( m_pLastModel ); + if ( idxMapModelOld != m_mapModelOld.InvalidIndex() ) + { + pMpiOld = &m_mapModelOld.Element( idxMapModelOld ); + } + mpi.AddInfoText( NULL, pMpiOld ); + mpi.PrintPendingInfoText( m_nPosPrint ); + } + } + m_pLastModel = pStudioHdr; + + // Go ahead with the new model + studiohdr_t const *pRMdl = pStudioHdr->GetRenderHdr(); + if ( !pRMdl || + !pRMdl->numincludemodels ) + return; + + // Entity number + int iEntNum = pEntity->entindex(); + if ( !IsModelShown( iEntNum ) ) + return; + + // Check if we saw the model + if ( m_mapModel.Find( pStudioHdr ) != m_mapModel.InvalidIndex() ) + { + // Initialize the printing position + m_nPosPrint = 9; + + // Swap the maps + m_mapModelOld.RemoveAll(); + m_mapModelOld.Swap( m_mapModel ); + + // Zero out the text on the old map + for ( int k = m_mapModelOld.FirstInorder(); + k != m_mapModelOld.InvalidIndex(); + k = m_mapModelOld.NextInorder( k ) ) + { + ModelPoseDebugInfo &mpi = m_mapModelOld[k]; + mpi.m_iCurrentText = 0; + } + } + else + { + // Next model + m_nPosPrint += 3; + } + + ModelPoseDebugInfo mpi; + mpi.m_iEntNum = iEntNum; + m_mapModel.Insert( pStudioHdr, mpi ); + + con_nprint_s nxPrn = { 0 }; + nxPrn.index = m_nPosPrint; + nxPrn.time_to_live = -1; + nxPrn.color[0] = 0.9f, nxPrn.color[1] = 1.0f, nxPrn.color[2] = 0.9f; + nxPrn.fixed_width_font = false; + + engine->Con_NXPrintf( &nxPrn, "[ %2d ] Model: %s", iEntNum, pRMdl->pszName() ); + m_nPosPrint += 3; +} + +void CPoseDebuggerImpl::AccumulatePose( const CStudioHdr *pStudioHdr, CIKContext *pIKContext, + Vector pos[], Quaternion q[], int sequence, float cycle, + const float poseParameter[], int boneMask, + float flWeight, float flTime ) +{ +// virtualmodel_t const *pVMdl = pStudioHdr->GetVirtualModel(); +// if ( !pVMdl ) +// return; + + studiohdr_t const *pRMdl = pStudioHdr->GetRenderHdr(); + if ( !pRMdl || + !pRMdl->numincludemodels ) + return; + + MapModel::IndexType_t idxMapModel = m_mapModel.Find( pStudioHdr ); + if ( idxMapModel == m_mapModel.InvalidIndex() ) + return; + + ModelPoseDebugInfo &mpi = m_mapModel.Element( idxMapModel ); + if ( !IsModelShown( mpi.m_iEntNum ) ) + return; + + ModelPoseDebugInfo *pMpiOld = NULL; + MapModel::IndexType_t idxMapModelOld = m_mapModelOld.Find( pStudioHdr ); + if ( idxMapModelOld != m_mapModelOld.InvalidIndex() ) + { + pMpiOld = &m_mapModelOld.Element( idxMapModelOld ); + } + + + // + // Actual processing + // + + mstudioseqdesc_t &seqdesc = ((CStudioHdr *)pStudioHdr)->pSeqdesc( sequence ); + + if ( sequence >= pStudioHdr->GetNumSeq() ) + { + sequence = 0; + seqdesc = ((CStudioHdr *)pStudioHdr)->pSeqdesc( sequence ); + } + + enum + { + widthActivity = 35, + widthLayer = 35, + widthIks = 60, + widthPercent = 6, + }; + + // Prepare the text + char chBuffer[256]; + ModelPoseDebugInfo::InfoText txt; + int numLines = 0; + + txt.m_iActivity = seqdesc.activity; + sprintf( txt.m_chActivity, "%s", seqdesc.pszActivityName() ); + sprintf( txt.m_chLabel, "%s", seqdesc.pszLabel() ); + + if ( !txt.m_chActivity[0] ) + { + // Try to find the last seen activity and re-use it + for ( int iLast = mpi.m_arrTxt.Count(); iLast --> 0; ) + { + ModelPoseDebugInfo::InfoText &lastSeenTxt = mpi.m_arrTxt[iLast]; + if ( lastSeenTxt.m_uiFlags & ModelPoseDebugInfo::F_SEEN_THIS_FRAME && + lastSeenTxt.m_chActivity[0] ) + { + sprintf( txt.m_chActivity, "%s", lastSeenTxt.m_chActivity ); + break; + } + } + } + + // The layer information + ModelPoseDebugInfo::InfoText *pOldTxt = pMpiOld ? pMpiOld->LookupInfoText( &txt ) : NULL; + sprintf( txt.m_chTextLines[numLines], + "%-*s %-*s %*.2f %*.1f/%-*d %*.0f%% ", + widthActivity, + seqdesc.pszActivityName(), + widthLayer, + seqdesc.pszLabel(), + 7, + pOldTxt ? pOldTxt->m_flTimeAlive : 0.f, + 5, + cycle * ( ((CStudioHdr *)pStudioHdr)->pAnimdesc( seqdesc.anim( 0, 0 ) ).numframes - 1 ), + 3, + ((CStudioHdr *)pStudioHdr)->pAnimdesc( seqdesc.anim( 0, 0 ) ).numframes, + widthPercent, + flWeight * 100.0f + ); + ++ numLines; + + if ( seqdesc.numiklocks ) + { + sprintf( chBuffer, + "iklocks : %-2d : ", + seqdesc.numiklocks ); + + for ( int k = 0; k < seqdesc.numiklocks; ++ k ) + { + mstudioiklock_t *plock = seqdesc.pIKLock( k ); + mstudioikchain_t *pchain = pStudioHdr->pIKChain( plock->chain ); + + sprintf( chBuffer + strlen( chBuffer ), "%s ", pchain->pszName() ); + // plock->flPosWeight; + // plock->flLocalQWeight; + } + + sprintf( txt.m_chTextLines[numLines], + "%-*s", + widthIks, + chBuffer + ); + ++ numLines; + } + + if ( seqdesc.numikrules ) + { + sprintf( chBuffer, "ikrules : %-2d", + seqdesc.numikrules ); + + sprintf( txt.m_chTextLines[numLines], + "%-*s", + widthIks, + chBuffer + ); + ++ numLines; + } + + + // Now add the accumulated text into the container + mpi.AddInfoText( &txt, pMpiOld ); + mpi.PrintPendingInfoText( m_nPosPrint ); +} + + +////////////////////////////////////////////////////////////////////////// +// +// Con-commands +// +////////////////////////////////////////////////////////////////////////// + +static void IN_PoseDebuggerStart( const CCommand &args ) +{ + if ( args.ArgC() <= 1 ) + { + // No args, enable all + s_PoseDebuggerImpl.ShowAllModels( true ); + } + else + { + // If explicitly showing the pose debugger when it was disabled + if ( g_pPoseDebugger != &s_PoseDebuggerImpl ) + { + s_PoseDebuggerImpl.ShowAllModels( false ); + } + + // Show only specific models + for ( int k = 1; k < args.ArgC(); ++ k ) + { + int iEntNum = atoi( args.Arg( k ) ); + s_PoseDebuggerImpl.ShowModel( iEntNum, true ); + } + } + + g_pPoseDebugger = &s_PoseDebuggerImpl; +} + +static void IN_PoseDebuggerEnd( const CCommand &args ) +{ + if ( args.ArgC() <= 1 ) + { + // No args, disable all + s_PoseDebuggerImpl.ShowAllModels( false ); + + // Set the stub pointer + g_pPoseDebugger = &s_PoseDebuggerStub; + } + else + { + // Hide only specific models + for ( int k = 1; k < args.ArgC(); ++ k ) + { + int iEntNum = atoi( args.Arg( k ) ); + s_PoseDebuggerImpl.ShowModel( iEntNum, false ); + } + } +} + +static ConCommand posedebuggerstart( "+posedebug", IN_PoseDebuggerStart, "Turn on pose debugger or add ents to pose debugger UI", FCVAR_CHEAT ); +static ConCommand posedebuggerend ( "-posedebug", IN_PoseDebuggerEnd, "Turn off pose debugger or hide ents from pose debugger UI", FCVAR_CHEAT ); diff --git a/sp/src/public/posedebugger.h b/sp/src/public/posedebugger.h new file mode 100644 index 00000000..f8b81537 --- /dev/null +++ b/sp/src/public/posedebugger.h @@ -0,0 +1,38 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#ifndef POSEDEBUGGER_H +#define POSEDEBUGGER_H +#ifdef _WIN32 +#pragma once +#endif + +class IClientNetworkable; + +abstract_class IPoseDebugger +{ +public: + virtual void StartBlending( IClientNetworkable *pEntity, const CStudioHdr *pStudioHdr ) = 0; + + virtual void AccumulatePose( + const CStudioHdr *pStudioHdr, + CIKContext *pIKContext, + Vector pos[], + Quaternion q[], + int sequence, + float cycle, + const float poseParameter[], + int boneMask, + float flWeight, + float flTime + ) = 0; +}; + +extern IPoseDebugger *g_pPoseDebugger; + +#endif // #ifndef POSEDEBUGGER_H diff --git a/sp/src/public/r_efx.h b/sp/src/public/r_efx.h new file mode 100644 index 00000000..fea23845 --- /dev/null +++ b/sp/src/public/r_efx.h @@ -0,0 +1,38 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +#if !defined ( EFXH ) +#define EFXH +#ifdef _WIN32 +#pragma once +#endif + +#include "iefx.h" + +class IMaterial; +struct dlight_t; + +class CVEfx : public IVEfx +{ +public: + virtual ~CVEfx() {} + + virtual int Draw_DecalIndexFromName ( char *name ); + virtual void DecalShoot ( int textureIndex, int entity, const model_t *model, const Vector& model_origin, const QAngle& model_angles, const Vector& position, const Vector *saxis, int flags); + virtual void DecalColorShoot ( int textureIndex, int entity, const model_t *model, const Vector& model_origin, const QAngle& model_angles, const Vector& position, const Vector *saxis, int flags, const color32 &rgbaColor); + virtual void PlayerDecalShoot ( IMaterial *material, void *userdata, int entity, const model_t *model, const Vector& model_origin, const QAngle& model_angles, + const Vector& position, const Vector *saxis, int flags, const color32 &rgbaColor ); + virtual dlight_t *CL_AllocDlight ( int key ); + virtual dlight_t *CL_AllocElight ( int key ); + virtual int CL_GetActiveDLights ( dlight_t *pList[MAX_DLIGHTS] ); + virtual const char *Draw_DecalNameFromIndex ( int nIndex ); + virtual dlight_t *GetElightByKey ( int key ); +}; + +extern CVEfx *g_pEfx; + +#endif \ No newline at end of file diff --git a/sp/src/public/raytrace.h b/sp/src/public/raytrace.h new file mode 100644 index 00000000..9692b8d6 --- /dev/null +++ b/sp/src/public/raytrace.h @@ -0,0 +1,390 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// $Id:$ + +#ifndef RAYTRACE_H +#define RAYTRACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +// fast SSE-ONLY ray tracing module. Based upon various "real time ray tracing" research. +//#define DEBUG_RAYTRACE 1 + +class FourRays +{ +public: + FourVectors origin; + FourVectors direction; + + inline void Check(void) const + { + // in order to be valid to trace as a group, all four rays must have the same signs in all + // of their direction components +#ifndef NDEBUG + for(int c=1;c<4;c++) + { + Assert(direction.X(0)*direction.X(c)>=0); + Assert(direction.Y(0)*direction.Y(c)>=0); + Assert(direction.Z(0)*direction.Z(c)>=0); + } +#endif + } + // returns direction sign mask for 4 rays. returns -1 if the rays can not be traced as a + // bundle. + int CalculateDirectionSignMask(void) const; + +}; + +/// The format a triangle is stored in for intersections. size of this structure is important. +/// This structure can be in one of two forms. Before the ray tracing environment is set up, the +/// ProjectedEdgeEquations hold the coordinates of the 3 vertices, for facilitating bounding box +/// checks needed while building the tree. afterwards, they are changed into the projected ege +/// equations for intersection purposes. +enum triangleflags +{ + FCACHETRI_TRANSPARENT = 0x01, + FCACHETRI_NEGATIVE_NORMAL = 0x02, +}; + + +struct TriIntersectData_t +{ + // this structure is 16longs=64 bytes for cache line packing. + float m_flNx, m_flNy, m_flNz; // plane equation + float m_flD; + + int32 m_nTriangleID; // id of the triangle. + + float m_ProjectedEdgeEquations[6]; // A,B,C for each edge equation. a + // point is inside the triangle if + // a*c1+b*c2+c is negative for all 3 + // edges. + + uint8 m_nCoordSelect0,m_nCoordSelect1; // the triangle is projected onto a 2d + // plane for edge testing. These are + // the indices (0..2) of the + // coordinates preserved in the + // projection + + uint8 m_nFlags; // triangle flags + uint8 m_unused0; // no longer used +}; + + +struct TriGeometryData_t +{ + int32 m_nTriangleID; // id of the triangle. + + float m_VertexCoordData[9]; // can't use a vector in a union + + uint8 m_nFlags; // triangle flags + signed char m_nTmpData0; // used by kd-tree builder + signed char m_nTmpData1; // used by kd-tree builder + + + // accessors to get around union annoyance + FORCEINLINE Vector &Vertex(int idx) + { + return * ( reinterpret_cast ( m_VertexCoordData+3*idx ) ); + } + +}; + + +struct CacheOptimizedTriangle +{ + + union + { + TriIntersectData_t m_IntersectData; + TriGeometryData_t m_GeometryData; + } m_Data; + + // accessors to get around union annoyance + FORCEINLINE Vector &Vertex(int idx) + { + return * ( reinterpret_cast (m_Data.m_GeometryData.m_VertexCoordData+3*idx ) ); + } + + FORCEINLINE const Vector &Vertex(int idx) const + { + return * ( reinterpret_cast (m_Data.m_GeometryData.m_VertexCoordData+3*idx ) ); + } + + void ChangeIntoIntersectionFormat(void); // change information storage format for + // computing intersections. + + int ClassifyAgainstAxisSplit(int split_plane, float split_value); // PLANECHECK_xxx below + +}; + +#define PLANECHECK_POSITIVE 1 +#define PLANECHECK_NEGATIVE -1 +#define PLANECHECK_STRADDLING 0 + +#define KDNODE_STATE_XSPLIT 0 // this node is an x split +#define KDNODE_STATE_YSPLIT 1 // this node is a ysplit +#define KDNODE_STATE_ZSPLIT 2 // this node is a zsplit +#define KDNODE_STATE_LEAF 3 // this node is a leaf + +struct CacheOptimizedKDNode +{ + // this is the cache intensive data structure. "Tricks" are used to fit it into 8 bytes: + // + // A) the right child is always stored after the left child, which means we only need one + // pointer + // B) The type of node (KDNODE_xx) is stored in the lower 2 bits of the pointer. + // C) for leaf nodes, we store the number of triangles in the leaf in the same place as the floating + // point splitting parameter is stored in a non-leaf node + + int32 Children; // child idx, or'ed with flags above + float SplittingPlaneValue; // for non-leaf nodes, the nodes on the + // "high" side of the splitting plane + // are on the right + +#ifdef DEBUG_RAYTRACE + Vector vecMins; + Vector vecMaxs; +#endif + + inline int NodeType(void) const + + { + return Children & 3; + } + + inline int32 TriangleIndexStart(void) const + { + assert(NodeType()==KDNODE_STATE_LEAF); + return Children>>2; + } + + inline int LeftChild(void) const + { + assert(NodeType()!=KDNODE_STATE_LEAF); + return Children>>2; + } + + inline int RightChild(void) const + { + return LeftChild()+1; + } + + inline int NumberOfTrianglesInLeaf(void) const + { + assert(NodeType()==KDNODE_STATE_LEAF); + return *((int32 *) &SplittingPlaneValue); + } + + inline void SetNumberOfTrianglesInLeafNode(int n) + { + *((int32 *) &SplittingPlaneValue)=n; + } + +protected: + + +}; + + +struct RayTracingSingleResult +{ + Vector surface_normal; // surface normal at intersection + int32 HitID; // -1=no hit. otherwise, triangle index + float HitDistance; // distance to intersection + float ray_length; // leng of initial ray +}; + +struct RayTracingResult +{ + FourVectors surface_normal; // surface normal at intersection + ALIGN16 int32 HitIds[4] ALIGN16_POST; // -1=no hit. otherwise, triangle index + fltx4 HitDistance; // distance to intersection +}; + + +class RayTraceLight +{ +public: + FourVectors Position; + FourVectors Intensity; +}; + + +#define RTE_FLAGS_FAST_TREE_GENERATION 1 +#define RTE_FLAGS_DONT_STORE_TRIANGLE_COLORS 2 // saves memory if not needed +#define RTE_FLAGS_DONT_STORE_TRIANGLE_MATERIALS 4 + +enum RayTraceLightingMode_t { + DIRECT_LIGHTING, // just dot product lighting + DIRECT_LIGHTING_WITH_SHADOWS, // with shadows + GLOBAL_LIGHTING // global light w/ shadows +}; + + +class RayStream +{ + friend class RayTracingEnvironment; + + RayTracingSingleResult *PendingStreamOutputs[8][4]; + int n_in_stream[8]; + FourRays PendingRays[8]; + +public: + RayStream(void) + { + memset(n_in_stream,0,sizeof(n_in_stream)); + } +}; + +// When transparent triangles are in the list, the caller can provide a callback that will get called at each triangle +// allowing the callback to stop processing if desired. +// UNDONE: This is not currently SIMD - it really only supports single rays +// Also for efficiency FourRays really needs some kind of active mask for the cases where rays get unbundled +class ITransparentTriangleCallback +{ +public: + virtual bool VisitTriangle_ShouldContinue( const TriIntersectData_t &triangle, const FourRays &rays, fltx4 *hitMask, fltx4 *b0, fltx4 *b1, fltx4 *b2, int32 hitID ) = 0; +}; + +class RayTracingEnvironment +{ +public: + uint32 Flags; // RTE_FLAGS_xxx above + Vector m_MinBound; + Vector m_MaxBound; + + FourVectors BackgroundColor; //< color where no intersection + CUtlVector OptimizedKDTree; //< the packed kdtree. root is 0 + CUtlBlockVector OptimizedTriangleList; //< the packed triangles + CUtlVector TriangleIndexList; //< the list of triangle indices. + CUtlVector LightList; //< the list of lights + CUtlVector TriangleColors; //< color of tries + CUtlVector TriangleMaterials; //< material index of tries + +public: + RayTracingEnvironment() : OptimizedTriangleList( 1024 ) + { + BackgroundColor.DuplicateVector(Vector(1,0,0)); // red + Flags=0; + } + + + // call AddTriangle to set up the world + void AddTriangle(int32 id, const Vector &v1, const Vector &v2, const Vector &v3, + const Vector &color); + + // Adds a triangle with flags & material + void AddTriangle(int32 id, const Vector &v1, const Vector &v2, const Vector &v3, + const Vector &color, uint16 flags, int32 materialIndex); + + + void AddQuad(int32 id, const Vector &v1, const Vector &v2, const Vector &v3, + const Vector &v4, // specify vertices in cw or ccw order + const Vector &color); + + // for ease of testing. + void AddAxisAlignedRectangularSolid(int id,Vector mincoord, Vector Maxcoord, + const Vector &color); + + + // SetupAccelerationStructure to prepare for tracing + void SetupAccelerationStructure(void); + + + // lowest level intersection routine - fire 4 rays through the scene. all 4 rays must pass the + // Check() function, and t extents must be initialized. skipid can be set to exclude a + // particular id (such as the origin surface). This function finds the closest intersection. + void Trace4Rays(const FourRays &rays, fltx4 TMin, fltx4 TMax,int DirectionSignMask, + RayTracingResult *rslt_out, + int32 skip_id=-1, ITransparentTriangleCallback *pCallback = NULL); + + // higher level intersection routine that handles computing the mask and handling rays which do not match in direciton sign + void Trace4Rays(const FourRays &rays, fltx4 TMin, fltx4 TMax, + RayTracingResult *rslt_out, + int32 skip_id=-1, ITransparentTriangleCallback *pCallback = NULL); + + // compute virtual light sources to model inter-reflection + void ComputeVirtualLightSources(void); + + + // high level interface - pass viewing parameters, rendering flags, and a destination frame + // buffer, and get a ray traced scene in 32-bit rgba format + void RenderScene(int width, int height, // width and height of desired rendering + int stride, // actual width in pixels of target buffer + uint32 *output_buffer, // pointer to destination + Vector CameraOrigin, // eye position + Vector ULCorner, // word space coordinates of upper left + // monitor corner + Vector URCorner, // top right corner + Vector LLCorner, // lower left + Vector LRCorner, // lower right + RayTraceLightingMode_t lightmode=DIRECT_LIGHTING); + + + /// raytracing stream - lets you trace an array of rays by feeding them to this function. + /// results will not be returned until FinishStream is called. This function handles sorting + /// the rays by direction, tracing them 4 at a time, and de-interleaving the results. + + void AddToRayStream(RayStream &s, + Vector const &start,Vector const &end,RayTracingSingleResult *rslt_out); + + inline void FlushStreamEntry(RayStream &s,int msk); + + /// call this when you are done. handles all cleanup. After this is called, all rslt ptrs + /// previously passed to AddToRaySteam will have been filled in. + void FinishRayStream(RayStream &s); + + + int MakeLeafNode(int first_tri, int last_tri); + + + float CalculateCostsOfSplit( + int split_plane,int32 const *tri_list,int ntris, + Vector MinBound,Vector MaxBound, float &split_value, + int &nleft, int &nright, int &nboth); + + void RefineNode(int node_number,int32 const *tri_list,int ntris, + Vector MinBound,Vector MaxBound, int depth); + + void CalculateTriangleListBounds(int32 const *tris,int ntris, + Vector &minout, Vector &maxout); + + void AddInfinitePointLight(Vector position, // light center + Vector intensity); // rgb amount + + // use the global variables set by LoadBSPFile to populated the RayTracingEnvironment with + // faces. + void InitializeFromLoadedBSP(void); + + void AddBSPFace(int id,dface_t const &face); + + // MakeRoomForTriangles - a hint telling it how many triangles we are going to add so that + // the utl vectors used can be pre-allocated + void MakeRoomForTriangles( int ntriangles ); + + const CacheOptimizedTriangle &GetTriangle( int32 triID ) + { + return OptimizedTriangleList[triID]; + } + + int32 GetTriangleMaterial( int32 triID ) + { + return TriangleMaterials[triID]; + } + const Vector &GetTriangleColor( int triID ) + { + return TriangleColors[triID]; + } + +}; + + + +#endif diff --git a/sp/src/public/registry.cpp b/sp/src/public/registry.cpp new file mode 100644 index 00000000..be4286cb --- /dev/null +++ b/sp/src/public/registry.cpp @@ -0,0 +1,421 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// + +#if defined( WIN32 ) && !defined( _X360 ) +#include +#endif +#include "tier0/platform.h" +#include "tier0/vcrmode.h" +#include "iregistry.h" +#include "tier0/dbg.h" +#include "tier1/strtools.h" +#include +#if defined( _X360 ) +#include "xbox/xbox_win32stubs.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// Purpose: Exposes registry interface to rest of launcher +//----------------------------------------------------------------------------- +class CRegistry : public IRegistry +{ +public: + CRegistry( void ); + virtual ~CRegistry( void ); + + virtual bool Init( const char *platformName ); + virtual bool DirectInit( const char *subDirectoryUnderValve ); + virtual void Shutdown( void ); + + virtual int ReadInt( const char *key, int defaultValue = 0); + virtual void WriteInt( const char *key, int value ); + + virtual const char *ReadString( const char *key, const char *defaultValue = NULL ); + virtual void WriteString( const char *key, const char *value ); + + // Read/write helper methods + virtual int ReadInt( const char *pKeyBase, const char *pKey, int defaultValue = 0 ); + virtual void WriteInt( const char *pKeyBase, const char *key, int value ); + virtual const char *ReadString( const char *pKeyBase, const char *key, const char *defaultValue ); + virtual void WriteString( const char *pKeyBase, const char *key, const char *value ); + +private: + bool m_bValid; +#ifdef WIN32 + HKEY m_hKey; +#endif +}; + +// Creates it and calls Init +IRegistry *InstanceRegistry( char const *subDirectoryUnderValve ) +{ + CRegistry *instance = new CRegistry(); + instance->DirectInit( subDirectoryUnderValve ); + return instance; +} + +// Calls Shutdown and deletes it +void ReleaseInstancedRegistry( IRegistry *reg ) +{ + if ( !reg ) + { + Assert( !"ReleaseInstancedRegistry( reg == NULL )!" ); + return; + } + + reg->Shutdown(); + delete reg; +} + +// Expose to launcher +static CRegistry g_Registry; +IRegistry *registry = ( IRegistry * )&g_Registry; + +//----------------------------------------------------------------------------- +// Read/write helper methods +//----------------------------------------------------------------------------- +int CRegistry::ReadInt( const char *pKeyBase, const char *pKey, int defaultValue ) +{ + int nLen = strlen( pKeyBase ); + int nKeyLen = strlen( pKey ); + char *pFullKey = (char*)_alloca( nLen + nKeyLen + 2 ); + Q_snprintf( pFullKey, nLen + nKeyLen + 2, "%s\\%s", pKeyBase, pKey ); + return ReadInt( pFullKey, defaultValue ); +} + +void CRegistry::WriteInt( const char *pKeyBase, const char *pKey, int value ) +{ + int nLen = strlen( pKeyBase ); + int nKeyLen = strlen( pKey ); + char *pFullKey = (char*)_alloca( nLen + nKeyLen + 2 ); + Q_snprintf( pFullKey, nLen + nKeyLen + 2, "%s\\%s", pKeyBase, pKey ); + WriteInt( pFullKey, value ); +} + +const char *CRegistry::ReadString( const char *pKeyBase, const char *pKey, const char *defaultValue ) +{ + int nLen = strlen( pKeyBase ); + int nKeyLen = strlen( pKey ); + char *pFullKey = (char*)_alloca( nLen + nKeyLen + 2 ); + Q_snprintf( pFullKey, nLen + nKeyLen + 2, "%s\\%s", pKeyBase, pKey ); + return ReadString( pFullKey, defaultValue ); +} + +void CRegistry::WriteString( const char *pKeyBase, const char *pKey, const char *value ) +{ + int nLen = strlen( pKeyBase ); + int nKeyLen = strlen( pKey ); + char *pFullKey = (char*)_alloca( nLen + nKeyLen + 2 ); + Q_snprintf( pFullKey, nLen + nKeyLen + 2, "%s\\%s", pKeyBase, pKey ); + WriteString( pFullKey, value ); +} + +#ifndef POSIX + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CRegistry::CRegistry( void ) +{ + // Assume failure + m_bValid = false; + m_hKey = 0; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CRegistry::~CRegistry( void ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: Read integer from registry +// Input : *key - +// defaultValue - +// Output : int +//----------------------------------------------------------------------------- +int CRegistry::ReadInt( const char *key, int defaultValue /*= 0*/ ) +{ + LONG lResult; // Registry function result code + DWORD dwType; // Type of key + DWORD dwSize; // Size of element data + + int value; + + if ( !m_bValid ) + { + return defaultValue; + } + + dwSize = sizeof( DWORD ); + + lResult = VCRHook_RegQueryValueEx( + m_hKey, // handle to key + key, // value name + 0, // reserved + &dwType, // type buffer + (LPBYTE)&value, // data buffer + &dwSize ); // size of data buffer + + if (lResult != ERROR_SUCCESS) // Failure + return defaultValue; + + if (dwType != REG_DWORD) + return defaultValue; + + return value; +} + +//----------------------------------------------------------------------------- +// Purpose: Save integer to registry +// Input : *key - +// value - +//----------------------------------------------------------------------------- +void CRegistry::WriteInt( const char *key, int value ) +{ + // Size of element data + DWORD dwSize; + + if ( !m_bValid ) + { + return; + } + + dwSize = sizeof( DWORD ); + + VCRHook_RegSetValueEx( + m_hKey, // handle to key + key, // value name + 0, // reserved + REG_DWORD, // type buffer + (LPBYTE)&value, // data buffer + dwSize ); // size of data buffer +} + +//----------------------------------------------------------------------------- +// Purpose: Read string value from registry +// Input : *key - +// *defaultValue - +// Output : const char +//----------------------------------------------------------------------------- +const char *CRegistry::ReadString( const char *key, const char *defaultValue /* = NULL */ ) +{ + LONG lResult; + // Type of key + DWORD dwType; + // Size of element data + DWORD dwSize = 512; + + static char value[ 512 ]; + + value[0] = 0; + + if ( !m_bValid ) + { + return defaultValue; + } + + lResult = VCRHook_RegQueryValueEx( + m_hKey, // handle to key + key, // value name + 0, // reserved + &dwType, // type buffer + (unsigned char *)value, // data buffer + &dwSize ); // size of data buffer + + if ( lResult != ERROR_SUCCESS ) + { + return defaultValue; + } + + if ( dwType != REG_SZ ) + { + return defaultValue; + } + + return value; +} + +//----------------------------------------------------------------------------- +// Purpose: Save string to registry +// Input : *key - +// *value - +//----------------------------------------------------------------------------- +void CRegistry::WriteString( const char *key, const char *value ) +{ + DWORD dwSize; // Size of element data + + if ( !m_bValid ) + { + return; + } + + dwSize = (DWORD)( strlen( value ) + 1 ); + + VCRHook_RegSetValueEx( + m_hKey, // handle to key + key, // value name + 0, // reserved + REG_SZ, // type buffer + (LPBYTE)value, // data buffer + dwSize ); // size of data buffer +} + + + + +bool CRegistry::DirectInit( const char *subDirectoryUnderValve ) +{ + LONG lResult; // Registry function result code + ULONG dwDisposition; // Type of key opening event + + char szModelKey[ 1024 ]; + wsprintf( szModelKey, "Software\\Valve\\%s", subDirectoryUnderValve ); + + lResult = VCRHook_RegCreateKeyEx( + HKEY_CURRENT_USER, // handle of open key + szModelKey, // address of name of subkey to open + 0ul, // DWORD ulOptions, // reserved + NULL, // Type of value + REG_OPTION_NON_VOLATILE, // Store permanently in reg. + KEY_ALL_ACCESS, // REGSAM samDesired, // security access mask + NULL, + &m_hKey, // Key we are creating + &dwDisposition ); // Type of creation + + if ( lResult != ERROR_SUCCESS ) + { + m_bValid = false; + return false; + } + + // Success + m_bValid = true; + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Open default launcher key based on game directory +//----------------------------------------------------------------------------- +bool CRegistry::Init( const char *platformName ) +{ + char subDir[ 512 ]; + wsprintf( subDir, "%s\\Settings", platformName ); + return DirectInit( subDir ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CRegistry::Shutdown( void ) +{ + if ( !m_bValid ) + return; + + // Make invalid + m_bValid = false; + VCRHook_RegCloseKey( m_hKey ); +} + +#else + + + + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CRegistry::CRegistry( void ) +{ + // Assume failure + m_bValid = false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CRegistry::~CRegistry( void ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: Read integer from registry +// Input : *key - +// defaultValue - +// Output : int +//----------------------------------------------------------------------------- +int CRegistry::ReadInt( const char *key, int defaultValue /*= 0*/ ) +{ + return 0; +} + +//----------------------------------------------------------------------------- +// Purpose: Save integer to registry +// Input : *key - +// value - +//----------------------------------------------------------------------------- +void CRegistry::WriteInt( const char *key, int value ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: Read string value from registry +// Input : *key - +// *defaultValue - +// Output : const char +//----------------------------------------------------------------------------- +const char *CRegistry::ReadString( const char *key, const char *defaultValue /* = NULL */ ) +{ + return 0; +} + +//----------------------------------------------------------------------------- +// Purpose: Save string to registry +// Input : *key - +// *value - +//----------------------------------------------------------------------------- +void CRegistry::WriteString( const char *key, const char *value ) +{ +} + + + +bool CRegistry::DirectInit( const char *subDirectoryUnderValve ) +{ + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Open default launcher key based on game directory +//----------------------------------------------------------------------------- +bool CRegistry::Init( const char *platformName ) +{ + char subDir[ 512 ]; + snprintf( subDir, sizeof(subDir), "%s\\Settings", platformName ); + return DirectInit( subDir ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CRegistry::Shutdown( void ) +{ + if ( !m_bValid ) + return; + + // Make invalid + m_bValid = false; +} +#endif // POSIX + diff --git a/sp/src/public/renamed_recvtable_compat.cpp b/sp/src/public/renamed_recvtable_compat.cpp new file mode 100644 index 00000000..6e5e08db --- /dev/null +++ b/sp/src/public/renamed_recvtable_compat.cpp @@ -0,0 +1,12 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +//=======================================================================================// + +#include "renamed_recvtable_compat.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +CRenamedRecvTableInfo *g_pRenamedRecvTableInfoHead = 0; + + diff --git a/sp/src/public/renamed_recvtable_compat.h b/sp/src/public/renamed_recvtable_compat.h new file mode 100644 index 00000000..63d23749 --- /dev/null +++ b/sp/src/public/renamed_recvtable_compat.h @@ -0,0 +1,45 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +//=======================================================================================// +#if !defined( RENAMED_RECVTABLE_COMPAT_H ) +#define RENAMED_RECVTABLE_COMPAT_H +#ifdef _WIN32 +#pragma once +#endif + +class CRenamedRecvTableInfo; + +extern CRenamedRecvTableInfo *g_pRenamedRecvTableInfoHead; + +//----------------------------------------------------------------------------- +// Purpose: Used by NOTE_RENAMED_RECVTABLE() macro. +//----------------------------------------------------------------------------- +class CRenamedRecvTableInfo +{ +public: + CRenamedRecvTableInfo( const char *pOldName, const char *pNewName ) + : m_pOldName( pOldName ), + m_pNewName( pNewName ) + { + m_pNext = g_pRenamedRecvTableInfoHead; + g_pRenamedRecvTableInfoHead = this; + } + +public: + const char *m_pOldName; + const char *m_pNewName; + CRenamedRecvTableInfo *m_pNext; +}; + +//----------------------------------------------------------------------------- +// Purpose: To keep from breaking older demos, use this macro to allow the +// engine to find the new datatable from the old name. +//----------------------------------------------------------------------------- +#define NOTE_RENAMED_RECVTABLE( oldname_, newname_ ) \ + static CRenamedRecvTableInfo g_##oldname_##Register( \ + #oldname_, \ + #newname_ \ + ); + + +#endif // RENAMED_RECVTABLE_COMPAT_H diff --git a/sp/src/public/renderparm.h b/sp/src/public/renderparm.h new file mode 100644 index 00000000..d56e258b --- /dev/null +++ b/sp/src/public/renderparm.h @@ -0,0 +1,85 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: defines constants to use for the materialsystem and shaderapi +// SetxxxRenderingParameter functions +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef RENDERPARM_H +#define RENDERPARM_H + +#ifndef _WIN32 +#pragma once +#endif + + +enum RenderParamVector_t +{ + VECTOR_RENDERPARM_HMDWARP_LEFT_CENTRE = 0, + VECTOR_RENDERPARM_HMDWARP_LEFT_COEFF012, + VECTOR_RENDERPARM_HMDWARP_LEFT_COEFF34_RED_OFFSET, + VECTOR_RENDERPARM_HMDWARP_RIGHT_CENTRE, + VECTOR_RENDERPARM_HMDWARP_RIGHT_COEFF012, + VECTOR_RENDERPARM_HMDWARP_RIGHT_COEFF34_BLUE_OFFSET, + VECTOR_RENDERPARM_HMDWARP_GROW_OUTIN, + VECTOR_RENDERPARM_HMDWARP_GROW_ABOVEBELOW, + VECTOR_RENDERPARM_HMDWARP_ASPECT, + INT_RENDERPARM_DISTORTION_TYPE, + + VECTOR_RENDERPARM_WIND_DIRECTION, + + MAX_VECTOR_RENDER_PARMS = 20 +}; + + +#define MAX_FLOAT_RENDER_PARMS 20 + +enum RenderParamInt_t +{ + INT_RENDERPARM_ENABLE_FIXED_LIGHTING = 0, + INT_RENDERPARM_MORPH_ACCUMULATOR_X_OFFSET, + INT_RENDERPARM_MORPH_ACCUMULATOR_Y_OFFSET, + INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_WIDTH, + INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_HEIGHT, + INT_RENDERPARM_MORPH_ACCUMULATOR_4TUPLE_COUNT, + + INT_RENDERPARM_MORPH_WEIGHT_X_OFFSET, + INT_RENDERPARM_MORPH_WEIGHT_Y_OFFSET, + INT_RENDERPARM_MORPH_WEIGHT_SUBRECT_WIDTH, + INT_RENDERPARM_MORPH_WEIGHT_SUBRECT_HEIGHT, + + INT_RENDERPARM_WRITE_DEPTH_TO_DESTALPHA, + + INT_RENDERPARM_BACK_BUFFER_INDEX, + + INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST, + INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_LAST = INT_FLASHLIGHT_DEPTHTEXTURE_FALLBACK_FIRST + 4, + + MAX_INT_RENDER_PARMS = 20 +}; + +// for INT_RENDERPARM_BACK_BUFFER_INDEX +#define BACK_BUFFER_INDEX_DEFAULT 0 +#define BACK_BUFFER_INDEX_HDR 1 + +enum RenderParamTexture_t +{ + TEXTURE_RENDERPARM_AMBIENT_OCCLUSION = 0, + + MAX_TEXTURE_RENDER_PARMS = 2 +}; + +// ENABLE_FIXED_LIGHTING modes: +#define ENABLE_FIXED_LIGHTING_NONE 0 +#define ENABLE_FIXED_LIGHTING_BASICLIGHT 1 +#define ENABLE_FIXED_LIGHTING_OUTPUTMRTS_FOR_DEFERRED_LIGHTING 2 +#define ENABLE_FIXED_LIGHTING_OUTPUTNORMAL_AND_DEPTH 3 + +enum RenderParamFloat_t +{ + FLOAT_RENDERPARM_MINIMUMLIGHTING = 0, +}; + +#endif // RENDERPARM_H diff --git a/sp/src/public/rope_physics.cpp b/sp/src/public/rope_physics.cpp new file mode 100644 index 00000000..9fe3ff52 --- /dev/null +++ b/sp/src/public/rope_physics.cpp @@ -0,0 +1,152 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + + +#include "rope_physics.h" +#include "tier0/dbg.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +CBaseRopePhysics::CBaseRopePhysics( CSimplePhysics::CNode *pNodes, int nNodes, CRopeSpring *pSprings, float *flSpringDistsSqr ) +{ + m_pNodes = pNodes; + m_pSprings = pSprings; + m_flNodeSpringDistsSqr = flSpringDistsSqr; + m_flSpringDist = m_flSpringDistSqr = 1; + Restart(); + + // Initialize the nodes. + for ( int i=0; i < nNodes; i++ ) + { + pNodes[i].m_vPos.Init(); + pNodes[i].m_vPrevPos.Init(); + pNodes[i].m_vPredicted.Init(); + } + + SetNumNodes( nNodes ); + + m_pDelegate = NULL; +} + + +void CBaseRopePhysics::SetNumNodes( int nNodes ) +{ + m_nNodes = nNodes; + + // Setup the springs. + for( int i=0; i < NumSprings(); i++ ) + { + m_pSprings[i].m_pNode1 = &m_pNodes[i].m_vPos; + m_pSprings[i].m_pNode2 = &m_pNodes[i+1].m_vPos; + Assert( m_pSprings[i].m_pNode1->IsValid() ); + Assert( m_pSprings[i].m_pNode2->IsValid() ); + + m_flNodeSpringDistsSqr[i] = m_flSpringDistSqr / NumSprings(); + } +} + + +void CBaseRopePhysics::Restart() +{ + m_Physics.Init( 1.0 / 50 ); +} + + +void CBaseRopePhysics::ResetSpringLength( float flSpringDist ) +{ + m_flSpringDist = max( flSpringDist, 0 ); + m_flSpringDistSqr = m_flSpringDist * m_flSpringDist; + + for( int i=0; i < NumSprings(); i++ ) + { + m_flNodeSpringDistsSqr[i] = m_flSpringDistSqr / NumSprings(); + } +} + +float CBaseRopePhysics::GetSpringLength() const +{ + return m_flSpringDist; +} + +void CBaseRopePhysics::ResetNodeSpringLength( int iStartNode, float flSpringDist ) +{ + m_flNodeSpringDistsSqr[iStartNode] = flSpringDist * flSpringDist; +} + +void CBaseRopePhysics::SetupSimulation( float flSpringDist, CSimplePhysics::IHelper *pDelegate ) +{ + ResetSpringLength( flSpringDist ); + SetDelegate( pDelegate ); +} + + +void CBaseRopePhysics::SetDelegate( CSimplePhysics::IHelper *pDelegate ) +{ + m_pDelegate = pDelegate; +} + + +void CBaseRopePhysics::Simulate( float dt ) +{ + static float flEnergy = 0.98; + m_Physics.Simulate( m_pNodes, m_nNodes, this, dt, flEnergy ); +} + + +void CBaseRopePhysics::GetNodeForces( CSimplePhysics::CNode *pNodes, int iNode, Vector *pAccel ) +{ + if( m_pDelegate ) + m_pDelegate->GetNodeForces( pNodes, iNode, pAccel ); + else + pAccel->Init( 0, 0, 0 ); +} + + +void CBaseRopePhysics::ApplyConstraints( CSimplePhysics::CNode *pNodes, int nNodes ) +{ + // Handle springs.. + // + // Iterate multiple times here. If we don't, then gravity tends to + // win over the constraint solver and it's impossible to get straight ropes. + static int nIterations = 3; + for( int iIteration=0; iIteration < nIterations; iIteration++ ) + { + for( int i=0; i < NumSprings(); i++ ) + { + CRopeSpring *s = &m_pSprings[i]; + + Vector vTo = *s->m_pNode1 - *s->m_pNode2; + + float flDistSqr = vTo.LengthSqr(); + + // If we don't have an overall spring distance, see if we have a per-node one + float flSpringDist = m_flSpringDistSqr; + if ( !flSpringDist ) + { + // TODO: This still isn't enough. Ropes with different spring lengths + // per-node will oscillate forever. + flSpringDist = m_flNodeSpringDistsSqr[i]; + } + + if( flDistSqr > flSpringDist ) + { + float flDist = (float)sqrt( flDistSqr ); + vTo *= 1 - (m_flSpringDist / flDist); + + *s->m_pNode1 -= vTo * 0.5f; + *s->m_pNode2 += vTo * 0.5f; + } + } + + if( m_pDelegate ) + m_pDelegate->ApplyConstraints( pNodes, nNodes ); + } +} + + diff --git a/sp/src/public/rope_physics.h b/sp/src/public/rope_physics.h new file mode 100644 index 00000000..68f6a5d3 --- /dev/null +++ b/sp/src/public/rope_physics.h @@ -0,0 +1,117 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef ROPE_PHYSICS_H +#define ROPE_PHYSICS_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "simple_physics.h" +#include "networkvar.h" + + +class CRopeSpring +{ +public: + Vector *m_pNode1; + Vector *m_pNode2; +}; + + +class CBaseRopePhysics : public CSimplePhysics::IHelper +{ +public: + DECLARE_CLASS_NOBASE( CBaseRopePhysics ); + + CBaseRopePhysics( + CSimplePhysics::CNode *pNodes, + int nNodes, + CRopeSpring *pSprings, + float *flSpringDistsSqr ); + + // nNodes should be less than or equal to what you passed into the constructor. + void SetNumNodes( int nNodes ); + + // Restart timers and such. + void Restart(); + + void ResetSpringLength(float flSpringDist ); + float GetSpringLength() const; + void ResetNodeSpringLength( int iStartNode, float flSpringDist ); + + // Set simulation parameters. + // If you pass in a delegate, you can be called to apply constraints. + void SetupSimulation( float flSpringDist, CSimplePhysics::IHelper *pDelegate=0 ); + + // Set the physics delegate. + void SetDelegate( CSimplePhysics::IHelper *pDelegate ); + + void Simulate( float dt ); + + int NumNodes() { return m_nNodes; } + CSimplePhysics::CNode* GetNode( int iNode ) { return &m_pNodes[iNode]; } + CSimplePhysics::CNode* GetFirstNode() { return &m_pNodes[0]; } + CSimplePhysics::CNode* GetLastNode() { return &m_pNodes[ m_nNodes-1 ]; } + + + +public: + + virtual void GetNodeForces( CSimplePhysics::CNode *pNodes, int iNode, Vector *pAccel ); + virtual void ApplyConstraints( CSimplePhysics::CNode *pNodes, int nNodes ); + + +private: + + int NumSprings() {return m_nNodes - 1;} + + +protected: + + CSimplePhysics::IHelper *m_pDelegate; + + CSimplePhysics::CNode *m_pNodes; + int m_nNodes; + + CRopeSpring *m_pSprings; + + float m_flSpringDist; + float m_flSpringDistSqr; + + // Spring lengths per node + float *m_flNodeSpringDistsSqr; + + CSimplePhysics m_Physics; +}; + + + + + +template< int NUM_NODES > +class CRopePhysics : public CBaseRopePhysics +{ +public: + + CRopePhysics(); + + CSimplePhysics::CNode m_Nodes[NUM_NODES]; + CRopeSpring m_Springs[NUM_NODES - 1]; + float m_SpringDistsSqr[NUM_NODES - 1]; +}; + + +template< int NUM_NODES > +CRopePhysics::CRopePhysics() : + CBaseRopePhysics( m_Nodes, NUM_NODES, m_Springs, m_SpringDistsSqr ) +{ +} + + +#endif // ROPE_PHYSICS_H diff --git a/sp/src/public/rope_shared.h b/sp/src/public/rope_shared.h new file mode 100644 index 00000000..fe79b6e6 --- /dev/null +++ b/sp/src/public/rope_shared.h @@ -0,0 +1,73 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef ROPE_SHARED_H +#define ROPE_SHARED_H +#ifdef _WIN32 +#pragma once +#endif + + +// Shared definitions for rope. +#define ROPE_MAX_SEGMENTS 10 +#define ROPE_TYPE1_NUMSEGMENTS 4 +#define ROPE_TYPE2_NUMSEGMENTS 2 + +// Default rope gravity vector. +#define ROPE_GRAVITY 0, 0, -1500 + + +// Rope flags. +#define ROPE_RESIZE (1<<0) // Try to keep the rope dangling the same amount + // even as the rope length changes. +#define ROPE_BARBED (1<<1) // Hack option to draw like a barbed wire. +#define ROPE_COLLIDE (1<<2) // Collide with the world? +#define ROPE_SIMULATE (1<<3) // Is the rope valid? +#define ROPE_BREAKABLE (1<<4) // Can the endpoints detach? +#ifdef MAPBASE +#define ROPE_USE_WIND (1<<5) // Wind simulation on this rope. +#else +#define ROPE_NO_WIND (1<<5) // No wind simulation on this rope. +#endif +#define ROPE_INITIAL_HANG (1<<6) // By default, ropes will simulate for a bit internally when they + // are created so they sag, but dynamically created ropes for things + // like harpoons don't want this. +#define ROPE_PLAYER_WPN_ATTACH (1<<7) // If this flag is set, then the second attachment must be a player. + // The rope will attach to "buff_attach" on the player's active weapon. + // (This is a flag because it requires special code on the client to + // find the weapon). +#define ROPE_NO_GRAVITY (1<<8) // Disable gravity on this rope. +#define ROPE_NUMFLAGS 9 + + +// This is added to all rope slacks so when a level designer enters a +// slack of zero in the entity, it doesn't dangle so low. +#define ROPESLACK_FUDGEFACTOR -100 + + +// Rope shader IDs. +#define ROPESHADER_BLACKCABLE 0 +#define ROPESHADER_ROPE 1 +#define ROPESHADER_CHAIN 2 + + +// Rope locked points +enum +{ + ROPE_LOCK_START_POINT = 0x1, + ROPE_LOCK_END_POINT = 0x2, + ROPE_LOCK_START_DIRECTION = 0x4, + ROPE_LOCK_END_DIRECTION = 0x8, +}; + + +// Rope attachment points. +#define ROPE_ATTACHMENT_START_POINT 1 +#define ROPE_ATTACHMENT_END_POINT 2 + + +#endif // ROPE_SHARED_H diff --git a/sp/src/public/savegame_version.h b/sp/src/public/savegame_version.h new file mode 100644 index 00000000..44253dc2 --- /dev/null +++ b/sp/src/public/savegame_version.h @@ -0,0 +1,15 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#if !defined( SAVEGAME_VERSION_H ) +#define SAVEGAME_VERSION_H +#ifdef _WIN32 +#pragma once +#endif + +#define SAVEGAME_VERSION 0x0073 // Version 0.73 + +#endif // SAVEGAME_VERSION_H diff --git a/sp/src/public/saverestoretypes.h b/sp/src/public/saverestoretypes.h new file mode 100644 index 00000000..b92a77c7 --- /dev/null +++ b/sp/src/public/saverestoretypes.h @@ -0,0 +1,547 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +// @Note (toml 12-02-02): For now, all of the methods in the types defined here +// are inline to permit simple cross-DLL usage +//=============================================================================// + +#ifndef SAVERESTORETYPES_H +#define SAVERESTORETYPES_H + +#if defined( _WIN32 ) +#pragma once +#endif + +#include "tier1/utlhash.h" + +#include // NULL_STRING define +struct edict_t; + + +#ifdef EHANDLE_H // not available to engine +#define SR_ENTS_VISIBLE 1 +#endif + + +//----------------------------------------------------------------------------- +// +// class CSaveRestoreSegment +// + +class CSaveRestoreSegment +{ +public: + CSaveRestoreSegment(); + + //--------------------------------- + // Buffer operations + // + void Init( void *pNewBase, int nBytes ); + void Rebase(); + void Rewind( int nBytes ); + char *GetBuffer(); + int BytesAvailable() const; + int SizeBuffer() const; + bool Write( const void *pData, int nBytes ); + bool Read( void *pOutput, int nBytes ); + int GetCurPos(); + char *AccessCurPos(); + bool Seek( int absPosition ); + void MoveCurPos( int nBytes ); + + //--------------------------------- + // Symbol table operations + // + void InitSymbolTable( char **pNewTokens, int sizeTable); + char **DetachSymbolTable(); + int SizeSymbolTable(); + bool DefineSymbol( const char *pszToken, int token ); + unsigned short FindCreateSymbol( const char *pszToken ); + const char *StringFromSymbol( int token ); + +private: +#ifndef _WIN32 + unsigned _rotr ( unsigned val, int shift); +#endif + unsigned int HashString( const char *pszToken ); + + //--------------------------------- + // Buffer data + // + char *pBaseData; // Start of all entity save data + char *pCurrentData; // Current buffer pointer for sequential access + int size; // Current data size, aka, pCurrentData - pBaseData + int bufferSize; // Total space for data + + //--------------------------------- + // Symbol table + // + int tokenCount; // Number of elements in the pTokens table + char **pTokens; // Hash table of entity strings (sparse) +}; + + +//----------------------------------------------------------------------------- +// +// class CGameSaveRestoreInfo +// + +struct levellist_t +{ + DECLARE_SIMPLE_DATADESC(); + + char mapName[ MAX_MAP_NAME ]; + char landmarkName[ 32 ]; + edict_t *pentLandmark; + Vector vecLandmarkOrigin; +}; + +#define MAX_LEVEL_CONNECTIONS 16 // These are encoded in the lower 16bits of entitytable_t->flags + +//------------------------------------- + +struct EHandlePlaceholder_t // Engine does some of the game writing (alas, probably shouldn't), but can't see ehandle.h +{ + unsigned long i; +}; + +//------------------------------------- + +struct entitytable_t +{ + void Clear() + { + id = -1; + edictindex = -1; + saveentityindex = -1; + restoreentityindex = -1; + location = 0; + size = 0; + flags = 0; + classname = NULL_STRING; + globalname = NULL_STRING; + landmarkModelSpace.Init(); + modelname = NULL_STRING; + } + + int id; // Ordinal ID of this entity (used for entity <--> pointer conversions) + int edictindex; // saved for if the entity requires a certain edict number when restored (players, world) + + int saveentityindex; // the entity index the entity had at save time ( for fixing up client side entities ) + int restoreentityindex; // the entity index given to this entity at restore time + +#ifdef SR_ENTS_VISIBLE + EHANDLE hEnt; // Pointer to the in-game entity +#else + EHandlePlaceholder_t hEnt; +#endif + + int location; // Offset from the base data of this entity + int size; // Byte size of this entity's data + int flags; // This could be a short -- bit mask of transitions that this entity is in the PVS of + string_t classname; // entity class name + string_t globalname; // entity global name + Vector landmarkModelSpace; // a fixed position in model space for comparison + // NOTE: Brush models can be built in different coordiante systems + // in different levels, so this fixes up local quantities to match + // those differences. + string_t modelname; + + DECLARE_SIMPLE_DATADESC(); +}; + +#define FENTTABLE_PLAYER 0x80000000 +#define FENTTABLE_REMOVED 0x40000000 +#define FENTTABLE_MOVEABLE 0x20000000 +#define FENTTABLE_GLOBAL 0x10000000 +#define FENTTABLE_PLAYERCHILD 0x08000000 // this entity is connected to a player, so it must be spawned with it +#define FENTTABLE_LEVELMASK 0x0000FFFF // reserve bits for 16 level connections +//------------------------------------- + +struct saverestorelevelinfo_t +{ + int connectionCount;// Number of elements in the levelList[] + levellist_t levelList[ MAX_LEVEL_CONNECTIONS ]; // List of connections from this level + + // smooth transition + int fUseLandmark; + char szLandmarkName[20]; // landmark we'll spawn near in next level + Vector vecLandmarkOffset; // for landmark transitions + float time; + char szCurrentMapName[MAX_MAP_NAME]; // To check global entities + int mapVersion; +}; + +//------------------------------------- + +class CGameSaveRestoreInfo +{ +public: + CGameSaveRestoreInfo() + : tableCount( 0 ), pTable( 0 ), m_pCurrentEntity( 0 ), m_EntityToIndex( 1024 ) + { + memset( &levelInfo, 0, sizeof( levelInfo ) ); + modelSpaceOffset.Init( 0, 0, 0 ); + } + + void InitEntityTable( entitytable_t *pNewTable = NULL, int size = 0 ) + { + pTable = pNewTable; + tableCount = size; + + for ( int i = 0; i < NumEntities(); i++ ) + { + GetEntityInfo( i )->Clear(); + } + } + + entitytable_t *DetachEntityTable() + { + entitytable_t *pReturn = pTable; + pTable = NULL; + tableCount = 0; + return pReturn; + } + + CBaseEntity *GetCurrentEntityContext() { return m_pCurrentEntity; } + void SetCurrentEntityContext(CBaseEntity *pEntity) { m_pCurrentEntity = pEntity; } + + int NumEntities() { return tableCount; } + entitytable_t *GetEntityInfo( int i ) { return (pTable + i); } + float GetBaseTime() const { return levelInfo.time; } + Vector GetLandmark() const { return ( levelInfo.fUseLandmark ) ? levelInfo.vecLandmarkOffset : vec3_origin; } + + void BuildEntityHash() + { +#ifdef GAME_DLL + int i; + entitytable_t *pTable; + int nEntities = NumEntities(); + + for ( i = 0; i < nEntities; i++ ) + { + pTable = GetEntityInfo( i ); + m_EntityToIndex.Insert( CHashElement( pTable->hEnt.Get(), i ) ); + } +#endif + } + + void PurgeEntityHash() + { + m_EntityToIndex.Purge(); + } + + int GetEntityIndex( const CBaseEntity *pEntity ) + { +#ifdef SR_ENTS_VISIBLE + if ( pEntity ) + { + if ( m_EntityToIndex.Count() ) + { + UtlHashHandle_t hElement = m_EntityToIndex.Find( CHashElement( pEntity ) ); + if ( hElement != m_EntityToIndex.InvalidHandle() ) + { + return m_EntityToIndex.Element( hElement ).index; + } + } + else + { + int i; + entitytable_t *pTable; + + int nEntities = NumEntities(); + for ( i = 0; i < nEntities; i++ ) + { + pTable = GetEntityInfo( i ); + if ( pTable->hEnt == pEntity ) + return pTable->id; + } + } + } +#endif + return -1; + } + + saverestorelevelinfo_t levelInfo; + Vector modelSpaceOffset; // used only for globaly entity brushes modelled in different coordinate systems. + +private: + int tableCount; // Number of elements in the entity table + entitytable_t *pTable; // Array of entitytable_t elements (1 for each entity) + CBaseEntity *m_pCurrentEntity; // only valid during the save functions of this entity, NULL otherwise + + + struct CHashElement + { + const CBaseEntity *pEntity; + int index; + + CHashElement( const CBaseEntity *pEntity, int index) : pEntity(pEntity), index(index) {} + CHashElement( const CBaseEntity *pEntity ) : pEntity(pEntity) {} + CHashElement() {} + }; + + class CHashFuncs + { + public: + CHashFuncs( int ) {} + + // COMPARE + bool operator()( const CHashElement &lhs, const CHashElement &rhs ) const + { + return lhs.pEntity == rhs.pEntity; + } + + // HASH + unsigned int operator()( const CHashElement &item ) const + { + return HashItem( item.pEntity ); + } + }; + + typedef CUtlHash CEntityToIndexHash; + + CEntityToIndexHash m_EntityToIndex; +}; + +//----------------------------------------------------------------------------- + + +class CSaveRestoreData : public CSaveRestoreSegment, + public CGameSaveRestoreInfo +{ +public: + CSaveRestoreData() : bAsync( false ) {} + + + bool bAsync; +}; + +inline CSaveRestoreData *MakeSaveRestoreData( void *pMemory ) +{ + return new (pMemory) CSaveRestoreData; +} + +//----------------------------------------------------------------------------- +// +// class CSaveRestoreSegment, inline functions +// + +inline CSaveRestoreSegment::CSaveRestoreSegment() +{ + memset( this, 0, sizeof(*this) ); +} + +inline void CSaveRestoreSegment::Init( void *pNewBase, int nBytes ) +{ + pCurrentData = pBaseData = (char *)pNewBase; + size = 0; + bufferSize = nBytes; +} + +inline void CSaveRestoreSegment::MoveCurPos( int nBytes ) +{ + pCurrentData += nBytes; + size += nBytes; +} + +inline void CSaveRestoreSegment::Rebase() +{ + pBaseData = pCurrentData; + bufferSize -= size; + size = 0; +} + +inline void CSaveRestoreSegment::Rewind( int nBytes ) +{ + if ( size < nBytes ) + nBytes = size; + + MoveCurPos( -nBytes ); +} + +inline char *CSaveRestoreSegment::GetBuffer() +{ + return pBaseData; +} + +inline int CSaveRestoreSegment::BytesAvailable() const +{ + return (bufferSize - size); +} + +inline int CSaveRestoreSegment::SizeBuffer() const +{ + return bufferSize; +} + +inline bool CSaveRestoreSegment::Write( const void *pData, int nBytes ) +{ + if ( nBytes > BytesAvailable() ) + { + size = bufferSize; + return false; + } + + memcpy( pCurrentData, pData, nBytes ); + MoveCurPos( nBytes ); + + return true; +} + +inline bool CSaveRestoreSegment::Read( void *pOutput, int nBytes ) +{ + if ( !BytesAvailable() ) + return false; + + if ( nBytes > BytesAvailable() ) + { + size = bufferSize; + return false; + } + + if ( pOutput ) + memcpy( pOutput, pCurrentData, nBytes ); + MoveCurPos( nBytes ); + return true; +} + +inline int CSaveRestoreSegment::GetCurPos() +{ + return size; +} + +inline char *CSaveRestoreSegment::AccessCurPos() +{ + return pCurrentData; +} + +inline bool CSaveRestoreSegment::Seek( int absPosition ) +{ + if ( absPosition < 0 || absPosition >= bufferSize ) + return false; + + size = absPosition; + pCurrentData = pBaseData + size; + return true; +} + +inline void CSaveRestoreSegment::InitSymbolTable( char **pNewTokens, int sizeTable) +{ + Assert( !pTokens ); + tokenCount = sizeTable; + pTokens = pNewTokens; + memset( pTokens, 0, sizeTable * sizeof( pTokens[0]) ); +} + +inline char **CSaveRestoreSegment::DetachSymbolTable() +{ + char **pResult = pTokens; + tokenCount = 0; + pTokens = NULL; + return pResult; +} + +inline int CSaveRestoreSegment::SizeSymbolTable() +{ + return tokenCount; +} + +inline bool CSaveRestoreSegment::DefineSymbol( const char *pszToken, int token ) +{ + if ( pTokens[token] == NULL ) + { + pTokens[token] = (char *)pszToken; + return true; + } + Assert( 0 ); + return false; +} + +inline unsigned short CSaveRestoreSegment::FindCreateSymbol( const char *pszToken ) +{ + unsigned short hash = (unsigned short)(HashString( pszToken ) % (unsigned)tokenCount ); + +#if _DEBUG + static int tokensparsed = 0; + tokensparsed++; + if ( !tokenCount || !pTokens ) + { + AssertMsg( 0, ("No token table array in TokenHash()!") ); + } +#endif + + for ( int i=0; i 50 && !beentheredonethat ) + { + beentheredonethat = true; + AssertMsg( 0, ("CSaveRestoreBuffer::TokenHash() is getting too full!" ) ); + } +#endif + + int index = hash + i; + if ( index >= tokenCount ) + index -= tokenCount; + + if ( !pTokens[index] || strcmp( pszToken, pTokens[index] ) == 0 ) + { + pTokens[index] = (char *)pszToken; + return index; + } + } + + // Token hash table full!!! + // [Consider doing overflow table(s) after the main table & limiting linear hash table search] + Warning( "CSaveRestoreBuffer::TokenHash() is COMPLETELY FULL!" ); + Assert( 0 ); + return 0; +} + +inline const char *CSaveRestoreSegment::StringFromSymbol( int token ) +{ + if ( token >= 0 && token < tokenCount ) + return pTokens[token]; + Assert( 0 ); + return "<>"; +} + +#ifndef _WIN32 +inline unsigned CSaveRestoreSegment::_rotr ( unsigned val, int shift) +{ + register unsigned lobit; /* non-zero means lo bit set */ + register unsigned num = val; /* number to rotate */ + + shift &= 0x1f; /* modulo 32 -- this will also make + negative shifts work */ + + while (shift--) + { + lobit = num & 1; /* get high bit */ + num >>= 1; /* shift right one bit */ + if (lobit) + num |= 0x80000000; /* set hi bit if lo bit was set */ + } + + return num; +} +#endif + +inline unsigned int CSaveRestoreSegment::HashString( const char *pszToken ) +{ + unsigned int hash = 0; + + while ( *pszToken ) + hash = _rotr( hash, 4 ) ^ *pszToken++; + + return hash; +} + +//============================================================================= + +#endif // SAVERESTORETYPES_H diff --git a/sp/src/public/scratchpad3d.cpp b/sp/src/public/scratchpad3d.cpp new file mode 100644 index 00000000..96db2174 --- /dev/null +++ b/sp/src/public/scratchpad3d.cpp @@ -0,0 +1,635 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include +#include "scratchpad3d.h" +#include "tier0/dbg.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#ifndef POSIX +// NOTE - linux doesn't need any of this code! + +extern "C" +{ + extern void __stdcall Sleep( unsigned long ms ); +}; + + +class CFileRead +{ +public: + CFileRead( IFileSystem* pFileSystem, FileHandle_t fp ) + { + m_pFileSystem = pFileSystem; + m_fp = fp; + m_Pos = 0; + } + + bool Read( void *pDest, int len ) + { + int count = m_pFileSystem->Read( pDest, len, m_fp ); + m_Pos += count; + return count == len; + } + + IFileSystem* m_pFileSystem; + FileHandle_t m_fp; + int m_Pos; +}; + + +// ------------------------------------------------------------------------ // +// CCommand_Point. +// ------------------------------------------------------------------------ // + +void CScratchPad3D::CCommand_Point::Read( CFileRead *pFile ) +{ + pFile->Read( &m_flPointSize, sizeof(m_flPointSize) ); + pFile->Read( &m_Vert, sizeof(m_Vert) ); +} + +void CScratchPad3D::CCommand_Point::Write( IFileSystem* pFileSystem, FileHandle_t fp ) +{ + pFileSystem->Write( &m_flPointSize, sizeof(m_flPointSize), fp ); + pFileSystem->Write( &m_Vert, sizeof(m_Vert), fp ); +} + + +// ------------------------------------------------------------------------ // +// CCommand_Line. +// ------------------------------------------------------------------------ // + +void CScratchPad3D::CCommand_Line::Read( CFileRead *pFile ) +{ + pFile->Read( m_Verts, sizeof(m_Verts) ); +} + +void CScratchPad3D::CCommand_Line::Write( IFileSystem* pFileSystem, FileHandle_t fp ) +{ + pFileSystem->Write( m_Verts, sizeof(m_Verts), fp ); +} + + +// ------------------------------------------------------------------------ // +// CCommand_Polygon. +// ------------------------------------------------------------------------ // + +void CScratchPad3D::CCommand_Polygon::Read( CFileRead *pFile ) +{ + int count; + pFile->Read( &count, sizeof(count) ); + m_Verts.RemoveAll(); + m_Verts.AddMultipleToTail( count ); + + if( count ) + pFile->Read( &m_Verts[0], sizeof(CSPVert)*count ); +} + +void CScratchPad3D::CCommand_Polygon::Write( IFileSystem* pFileSystem, FileHandle_t fp ) +{ + int count = m_Verts.Size(); + pFileSystem->Write( &count, sizeof(count), fp ); + + if( count ) + pFileSystem->Write( &m_Verts[0], sizeof(CSPVert)*count, fp ); +} + + +// ------------------------------------------------------------------------ // +// CCommand_Matrix. +// ------------------------------------------------------------------------ // + +void CScratchPad3D::CCommand_Matrix::Read( CFileRead *pFile ) +{ + pFile->Read( &m_mMatrix, sizeof(m_mMatrix) ); +} + +void CScratchPad3D::CCommand_Matrix::Write( IFileSystem* pFileSystem, FileHandle_t fp ) +{ + pFileSystem->Write( &m_mMatrix, sizeof(m_mMatrix), fp ); +} + + +// ------------------------------------------------------------------------ // +// CCommand_RenderState. +// ------------------------------------------------------------------------ // + +void CScratchPad3D::CCommand_RenderState::Read( CFileRead *pFile ) +{ + pFile->Read( &m_State, sizeof(m_State) ); + pFile->Read( &m_Val, sizeof(m_Val) ); +} + +void CScratchPad3D::CCommand_RenderState::Write( IFileSystem* pFileSystem, FileHandle_t fp ) +{ + pFileSystem->Write( &m_State, sizeof(m_State), fp ); + pFileSystem->Write( &m_Val, sizeof(m_Val), fp ); +} + + +// ------------------------------------------------------------------------ // +// CCommand_Text. +// ------------------------------------------------------------------------ // + +void CScratchPad3D::CCommand_Text::Read( CFileRead *pFile ) +{ + int strLen; + pFile->Read( &strLen, sizeof( strLen ) ); + m_String.SetSize( strLen ); + pFile->Read( m_String.Base(), strLen ); + + pFile->Read( &m_TextParams, sizeof( m_TextParams ) ); +} + + +void CScratchPad3D::CCommand_Text::Write( IFileSystem* pFileSystem, FileHandle_t fp ) +{ + int strLen = m_String.Count(); + pFileSystem->Write( &strLen, sizeof( strLen ), fp ); + pFileSystem->Write( m_String.Base(), strLen, fp ); + + pFileSystem->Write( &m_TextParams, sizeof( m_TextParams ), fp ); +} + + +// ------------------------------------------------------------------------ // +// CScratchPad3D internals. +// ------------------------------------------------------------------------ // + +CScratchPad3D::CScratchPad3D( char const *pFilename, IFileSystem* pFileSystem, bool bAutoClear ) +{ + m_pFileSystem = pFileSystem; + m_pFilename = pFilename; + m_bAutoFlush = true; + + if( bAutoClear ) + Clear(); // Clear whatever is in the file.. +} + +void CScratchPad3D::AutoFlush() +{ + if( m_bAutoFlush ) + Flush(); +} + +void CScratchPad3D::DrawRectGeneric( int iPlane, int otherDim1, int otherDim2, float planeDist, const Vector2D &vMin, const Vector2D &vMax, const CSPColor &vColor ) +{ + Vector verts[4]; + + verts[0][iPlane] = verts[1][iPlane] = verts[2][iPlane] = verts[3][iPlane] = planeDist; + + verts[0][otherDim1] = vMin.x; + verts[0][otherDim2] = vMin.y; + + verts[1][otherDim1] = vMin.x; + verts[1][otherDim2] = vMax.y; + + verts[2][otherDim1] = vMax.x; + verts[2][otherDim2] = vMax.y; + + verts[3][otherDim1] = vMax.x; + verts[3][otherDim2] = vMin.y; + + DrawPolygon( CSPVertList(verts, 4, vColor) ); +} + +void CScratchPad3D::DeleteCommands() +{ + for( int i=0; i < m_Commands.Size(); i++ ) + delete m_Commands[i]; + + m_Commands.RemoveAll(); +} + +bool CScratchPad3D::LoadCommandsFromFile( ) +{ + DeleteCommands(); + + FileHandle_t fp = m_pFileSystem->Open( m_pFilename, "rb" ); + if( !fp ) + return false; + + long fileEndPos = m_pFileSystem->Size( fp ); + + CFileRead fileRead( m_pFileSystem, fp ); + while( fileRead.m_Pos != fileEndPos ) + { + unsigned char iCommand; + fileRead.Read( &iCommand, sizeof(iCommand) ); + + CBaseCommand *pCmd = NULL; + if( iCommand == COMMAND_POINT ) + pCmd = new CCommand_Point; + else if( iCommand == COMMAND_LINE ) + pCmd = new CCommand_Line; + else if( iCommand == COMMAND_POLYGON ) + pCmd = new CCommand_Polygon; + else if( iCommand == COMMAND_MATRIX ) + pCmd = new CCommand_Matrix; + else if( iCommand == COMMAND_RENDERSTATE ) + pCmd = new CCommand_RenderState; + else if ( iCommand == COMMAND_TEXT ) + pCmd = new CCommand_Text; + + if( !pCmd ) + { + Assert( !"LoadCommandsFromFile: invalid file" ); + m_pFileSystem->Close( fp ); + return false; + } + + pCmd->Read( &fileRead ); + m_Commands.AddToTail( pCmd ); + } + + m_pFileSystem->Close( fp ); + return true; +} + + +// ------------------------------------------------------------------------ // +// CScratchPad3D's IScratchPad3D implementation. +// ------------------------------------------------------------------------ // + +void CScratchPad3D::Release() +{ + Flush(); + delete this; +} + +void CScratchPad3D::SetMapping( + const Vector &vInputMin, + const Vector &vInputMax, + const Vector &vOutputMin, + const Vector &vOutputMax ) +{ + CCommand_Matrix *cmd = new CCommand_Matrix; + m_Commands.AddToTail( cmd ); + + Vector vDivisor(1,1,1); + for( int i=0; i < 3; i++ ) + vDivisor[i] = fabs(vInputMax[i] - vInputMin[i]) < 0.0001f ? 0.001f : (vInputMax[i] - vInputMin[i]); + + Vector vScale = (vOutputMax - vOutputMin) / vDivisor; + Vector vShift = -vInputMin * vScale + vOutputMin; + + cmd->m_mMatrix.Init( + vScale.x, 0, 0, vShift.x, + 0, vScale.y, 0, vShift.y, + 0, 0, vScale.z, vShift.z, + 0, 0, 0, 1 ); + + + AutoFlush(); +} + +bool CScratchPad3D::GetAutoFlush() +{ + return m_bAutoFlush; +} + +void CScratchPad3D::SetAutoFlush( bool bAutoFlush ) +{ + m_bAutoFlush = bAutoFlush; + if( m_bAutoFlush ) + Flush(); +} + +void CScratchPad3D::DrawPoint( CSPVert const &v, float flPointSize ) +{ + CCommand_Point *cmd = new CCommand_Point; + m_Commands.AddToTail( cmd ); + + cmd->m_Vert = v; + cmd->m_flPointSize = flPointSize; + + AutoFlush(); +} + +void CScratchPad3D::DrawLine( CSPVert const &v1, CSPVert const &v2 ) +{ + CCommand_Line *cmd = new CCommand_Line; + m_Commands.AddToTail( cmd ); + + cmd->m_Verts[0] = v1; + cmd->m_Verts[1] = v2; + + AutoFlush(); +} + +void CScratchPad3D::DrawPolygon( CSPVertList const &verts ) +{ + CCommand_Polygon *cmd = new CCommand_Polygon; + m_Commands.AddToTail( cmd ); + + cmd->m_Verts.AddVectorToTail( verts.m_Verts ); + + AutoFlush(); +} + +void CScratchPad3D::DrawRectYZ( float xPos, const Vector2D &vMin, const Vector2D &vMax, const CSPColor &vColor ) +{ + DrawRectGeneric( 0, 1, 2, xPos, vMin, vMax, vColor ); +} + +void CScratchPad3D::DrawRectXZ( float yPos, const Vector2D &vMin, const Vector2D &vMax, const CSPColor &vColor ) +{ + DrawRectGeneric( 1, 0, 2, yPos, vMin, vMax, vColor ); +} + +void CScratchPad3D::DrawRectXY( float zPos, const Vector2D &vMin, const Vector2D &vMax, const CSPColor &vColor ) +{ + DrawRectGeneric( 2, 0, 1, zPos, vMin, vMax, vColor ); +} + +void CScratchPad3D::SetRenderState( RenderState state, unsigned long val ) +{ + CCommand_RenderState *cmd = new CCommand_RenderState; + m_Commands.AddToTail( cmd ); + + cmd->m_State = (unsigned long)state; + cmd->m_Val = val; +} + +void CScratchPad3D::DrawWireframeBox( const Vector &vMin, const Vector &vMax, const Vector &vColor ) +{ + // Bottom 4. + DrawLine( + CSPVert(Vector(vMin.x, vMin.y, vMin.z), vColor), + CSPVert(Vector(vMax.x, vMin.y, vMin.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMin.x, vMin.y, vMin.z), vColor), + CSPVert(Vector(vMin.x, vMax.y, vMin.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMax.x, vMin.y, vMin.z), vColor), + CSPVert(Vector(vMax.x, vMax.y, vMin.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMax.x, vMax.y, vMin.z), vColor), + CSPVert(Vector(vMin.x, vMax.y, vMin.z), vColor) ); + + // Top 4. + DrawLine( + CSPVert(Vector(vMin.x, vMin.y, vMax.z), vColor), + CSPVert(Vector(vMax.x, vMin.y, vMax.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMin.x, vMin.y, vMax.z), vColor), + CSPVert(Vector(vMin.x, vMax.y, vMax.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMax.x, vMin.y, vMax.z), vColor), + CSPVert(Vector(vMax.x, vMax.y, vMax.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMax.x, vMax.y, vMax.z), vColor), + CSPVert(Vector(vMin.x, vMax.y, vMax.z), vColor) ); + + // Connecting 4. + DrawLine( + CSPVert(Vector(vMin.x, vMin.y, vMin.z), vColor), + CSPVert(Vector(vMin.x, vMin.y, vMax.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMin.x, vMax.y, vMin.z), vColor), + CSPVert(Vector(vMin.x, vMax.y, vMax.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMax.x, vMax.y, vMin.z), vColor), + CSPVert(Vector(vMax.x, vMax.y, vMax.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMax.x, vMin.y, vMin.z), vColor), + CSPVert(Vector(vMax.x, vMin.y, vMax.z), vColor) ); +} + + +void CScratchPad3D::DrawText( const char *pStr, const CTextParams ¶ms ) +{ + CCommand_Text *cmd = new CCommand_Text; + m_Commands.AddToTail( cmd ); + + cmd->m_String.CopyArray( pStr, strlen( pStr ) + 1 ); + cmd->m_TextParams = params; + + AutoFlush(); +} + + +void CScratchPad3D::Clear() +{ + FileHandle_t fp; + + while( ( fp = m_pFileSystem->Open(m_pFilename, "wb") ) == NULL ) + { +#ifdef _WIN32 + Sleep( 5 ); +#elif POSIX + usleep( 5 ); +#endif + } + + m_pFileSystem->Close( fp ); + + DeleteCommands(); +} + + +void CScratchPad3D::Flush() +{ + FileHandle_t fp; + + while( ( fp = m_pFileSystem->Open(m_pFilename, "ab+") ) == NULL ) + { +#ifdef _WIN32 + Sleep( 5 ); +#elif POSIX + usleep( 5 ); +#endif + } + + // Append the new commands to the file. + for( int i=0; i < m_Commands.Size(); i++ ) + { + m_pFileSystem->Write( &m_Commands[i]->m_iCommand, sizeof(m_Commands[i]->m_iCommand), fp ); + m_Commands[i]->Write( m_pFileSystem, fp ); + } + + m_pFileSystem->Close( fp ); + + DeleteCommands(); +} + +void CScratchPad3D::DrawImageBW( + unsigned char const *pData, + int width, + int height, + int pitchInBytes, + bool bOutlinePixels, + bool bOutlineImage, + Vector *vCorners ) +{ + SPRGBA *pRGBA = new SPRGBA[width*height]; + for( int y=0; y < height; y++ ) + { + SPRGBA *pDest = &pRGBA[ y * width ]; + unsigned char const *pSrc = &pData[ y * pitchInBytes ]; + for( int x=0; x < width; x++ ) + { + pDest->r = pDest->g = pDest->b = *pSrc; + ++pSrc; + ++pDest; + } + } + + DrawImageRGBA( pRGBA, width, height, width*sizeof(SPRGBA), bOutlinePixels, bOutlineImage, vCorners ); + delete [] pRGBA; +} + + +void CScratchPad3D::DrawPolygonsForPixels( + SPRGBA *pData, + int width, + int height, + int pitchInBytes, + Vector *vCorners ) +{ + // Scan top-down. + Vector vCurLeft = vCorners[1]; + Vector vCurRight = vCorners[2]; + + Vector vLeftInc = (vCorners[0] - vCorners[1]) / height; + Vector vRightInc = (vCorners[3] - vCorners[2]) / height; + + Vector vNextLeft = vCurLeft + vLeftInc; + Vector vNextRight = vCurRight + vRightInc; + + Vector vPolyBox[4]; + Vector &vTopLeft = vPolyBox[0]; + Vector &vTopRight = vPolyBox[1]; + Vector &vBottomRight = vPolyBox[2]; + Vector &vBottomLeft = vPolyBox[3]; + + for( int y=0; y < height; y++ ) + { + vTopLeft = vCurLeft; + vBottomLeft = vNextLeft; + + Vector vTopXInc = (vCurRight - vCurLeft) / width; + Vector vBottomXInc = (vNextRight - vNextLeft) / width; + + vTopRight = vTopLeft + vTopXInc; + vBottomRight = vBottomLeft + vBottomXInc; + + SPRGBA *pSrc = &pData[ y * (pitchInBytes/sizeof(SPRGBA)) ]; + for( int x=0; x < width; x++ ) + { + if ( pData ) + DrawPolygon( CSPVertList( vPolyBox, 4, Vector(pSrc->r/255.1f, pSrc->g/255.1f, pSrc->b/255.1f) ) ); + else + DrawPolygon( CSPVertList( vPolyBox, 4, Vector(1,1,1) ) ); + + ++pSrc; + vTopLeft += vTopXInc; + vTopRight += vTopXInc; + vBottomLeft += vBottomXInc; + vBottomRight += vBottomXInc; + } + + vCurLeft += vLeftInc; + vNextLeft += vLeftInc; + vCurRight += vRightInc; + vNextRight += vRightInc; + } +} + + +void CScratchPad3D::DrawImageRGBA( + SPRGBA *pData, + int width, + int height, + int pitchInBytes, + bool bOutlinePixels, + bool bOutlineImage, + Vector *vCorners ) +{ + Assert( pitchInBytes % sizeof(SPRGBA) == 0 ); + + Vector vDefaultCorners[4]; + if ( !vCorners ) + { + vCorners = vDefaultCorners; + vDefaultCorners[0].Init( -100, -100 ); + vDefaultCorners[1].Init( -100, 100 ); + vDefaultCorners[2].Init( 100, 100 ); + vDefaultCorners[3].Init( 100, -100 ); + } + + // Don't auto-flush while drawing all these primitives. + bool bOldAutoFlush = m_bAutoFlush; + m_bAutoFlush = false; + + // Draw solids. + SetRenderState( IScratchPad3D::RS_FillMode, IScratchPad3D::FillMode_Solid ); + DrawPolygonsForPixels( pData, width, height, pitchInBytes, vCorners ); + + // Draw wireframe. + if ( bOutlinePixels ) + { + SetRenderState( IScratchPad3D::RS_FillMode, IScratchPad3D::FillMode_Wireframe ); + DrawPolygonsForPixels( NULL, width, height, pitchInBytes, vCorners ); + } + + // Draw an outline around the whole image. + if ( bOutlineImage ) + { + SetRenderState( IScratchPad3D::RS_FillMode, IScratchPad3D::FillMode_Wireframe ); + DrawPolygon( CSPVertList( vCorners, 4 ) ); + } + + // Restore the old auto-flush state. + m_bAutoFlush = bOldAutoFlush; + AutoFlush(); +} + + +// ------------------------------------------------------------------------ // +// Global functions. +// ------------------------------------------------------------------------ // +IFileSystem* ScratchPad3D_SetupFileSystem() +{ + // Get a filesystem interface. + CSysModule *pModule = Sys_LoadModule( "filesystem_stdio" ); + if( !pModule ) + return NULL; + + CreateInterfaceFn fn = Sys_GetFactory( pModule ); + IFileSystem *pFileSystem; + if( !fn || (pFileSystem = (IFileSystem *)fn( FILESYSTEM_INTERFACE_VERSION, NULL )) == NULL ) + { + Sys_UnloadModule( pModule ); + return NULL; + } + + return pFileSystem; +} + +IScratchPad3D* ScratchPad3D_Create( char const *pFilename ) +{ + IFileSystem *pFileSystem = ScratchPad3D_SetupFileSystem(); + if( !pFileSystem ) + return NULL; + + CScratchPad3D *pRet = new CScratchPad3D( pFilename, pFileSystem, true ); + return pRet; +} +#endif // POSIX + diff --git a/sp/src/public/scratchpad3d.h b/sp/src/public/scratchpad3d.h new file mode 100644 index 00000000..7e9aad66 --- /dev/null +++ b/sp/src/public/scratchpad3d.h @@ -0,0 +1,224 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef SCRATCHPAD3D_H +#define SCRATCHPAD3D_H +#ifdef _WIN32 +#pragma once +#endif + + +#include +#include "iscratchpad3d.h" +#include "mathlib/vmatrix.h" +#include "filesystem.h" + +class CFileRead; + + +class CScratchPad3D : public IScratchPad3D +{ +// Commands that can go in the file. +public: + + enum + { + COMMAND_POINT=0, + COMMAND_LINE, + COMMAND_POLYGON, + COMMAND_MATRIX, + COMMAND_RENDERSTATE, + COMMAND_TEXT, + COMMAND_NUMCOMMANDS + }; + + class ICachedRenderData + { + public: + virtual void Release() = 0; + }; + + class CBaseCommand + { + public: + CBaseCommand( unsigned char iCommand ) + { + m_iCommand = (unsigned char)iCommand; + m_pCachedRenderData = NULL; + } + + ~CBaseCommand() + { + ReleaseCachedRenderData(); + } + + virtual void Read( CFileRead *pFile ) = 0; + virtual void Write( IFileSystem* pFileSystem, FileHandle_t fp ) = 0; + + // Release cached render data. Usually used for releasing things like textures when + // the app is resizing.. + void ReleaseCachedRenderData() + { + if ( m_pCachedRenderData ) + { + m_pCachedRenderData->Release(); + m_pCachedRenderData = NULL; + } + } + + public: + + unsigned char m_iCommand; // One of the COMMAND_ defines. + + // The renderer can cache data with the commands to speedup the rendering after + // the first time (text uses this big time). + ICachedRenderData *m_pCachedRenderData; + }; + + class CCommand_Point : public CBaseCommand + { + public: + CCommand_Point() : CBaseCommand( COMMAND_POINT ) {} + + virtual void Read( CFileRead *pFile ); + virtual void Write( IFileSystem* pFileSystem, FileHandle_t fp ); + + float m_flPointSize; + CSPVert m_Vert; + }; + + class CCommand_Line : public CBaseCommand + { + public: + CCommand_Line() : CBaseCommand( COMMAND_LINE ) {} + + virtual void Read( CFileRead *pFile ); + virtual void Write( IFileSystem* pFileSystem, FileHandle_t fp ); + + CSPVert m_Verts[2]; + }; + + class CCommand_Polygon : public CBaseCommand + { + public: + CCommand_Polygon() : CBaseCommand( COMMAND_POLYGON ) {} + + virtual void Read( CFileRead *pFile ); + virtual void Write( IFileSystem* pFileSystem, FileHandle_t fp ); + + CUtlVector m_Verts; + }; + + class CCommand_Matrix : public CBaseCommand + { + public: + CCommand_Matrix() : CBaseCommand( COMMAND_MATRIX ) {} + + virtual void Read( CFileRead *pFile ); + virtual void Write( IFileSystem* pFileSystem, FileHandle_t fp ); + + VMatrix m_mMatrix; + }; + + class CCommand_RenderState : public CBaseCommand + { + public: + CCommand_RenderState() : CBaseCommand( COMMAND_RENDERSTATE ) {} + + virtual void Read( CFileRead *pFile ); + virtual void Write( IFileSystem* pFileSystem, FileHandle_t fp ); + + unsigned long m_State; // One of the RS_ enums. + unsigned long m_Val; + }; + + class CCommand_Text : public CBaseCommand + { + public: + CCommand_Text() : CBaseCommand( COMMAND_TEXT ) {} + + virtual void Read( CFileRead *pFile ); + virtual void Write( IFileSystem* pFileSystem, FileHandle_t fp ); + + CUtlVector m_String; // The string to render. + CTextParams m_TextParams; + }; + + +public: + + CScratchPad3D( char const *pFilename, IFileSystem *pFileSystem, bool bAutoClear ); + + void AutoFlush(); + void DrawRectGeneric( int iPlane, int otherDim1, int otherDim2, float planeDist, Vector2D const &vMin, Vector2D const &vMax, CSPColor const &vColor ); + void DeleteCommands(); + + // Load a file... + bool LoadCommandsFromFile( ); + + +public: + + virtual void Release(); + + virtual void SetMapping( + Vector const &vInputMin, + Vector const &vInputMax, + Vector const &vOutputMin, + Vector const &vOutputMax ); + virtual bool GetAutoFlush(); + virtual void SetAutoFlush( bool bAutoFlush ); + virtual void DrawPoint( CSPVert const &v, float flPointSize ); + virtual void DrawLine( CSPVert const &v1, CSPVert const &v2 ); + virtual void DrawPolygon( CSPVertList const &verts ); + virtual void DrawRectYZ( float xPos, Vector2D const &vMin, Vector2D const &vMax, CSPColor const &vColor ); + virtual void DrawRectXZ( float yPos, Vector2D const &vMin, Vector2D const &vMax, CSPColor const &vColor ); + virtual void DrawRectXY( float zPos, Vector2D const &vMin, Vector2D const &vMax, CSPColor const &vColor ); + virtual void DrawWireframeBox( Vector const &vMin, Vector const &vMax, Vector const &vColor ); + virtual void DrawText( const char *pStr, const CTextParams ¶ms ); + virtual void SetRenderState( RenderState state, unsigned long val ); + virtual void Clear(); + virtual void Flush(); + virtual void DrawImageBW( + unsigned char const *pData, + int width, + int height, + int pitchInBytes, + bool bOutlinePixels=true, + bool bOutlineImage=false, + Vector *vCorners=NULL ); + + // Draw an RGBA image. + // Corners are in this order: bottom-left, top-left, top-right, bottom-right. + virtual void DrawImageRGBA( + SPRGBA *pData, + int width, + int height, + int pitchInBytes, + bool bOutlinePixels=true, + bool bOutlineImage=false, + Vector *vCorners=NULL ); + + void DrawPolygonsForPixels( + SPRGBA *pData, + int width, + int height, + int pitchInBytes, + Vector *vCorners ); + +public: + IFileSystem* m_pFileSystem; + char const *m_pFilename; + CUtlVector m_Commands; + bool m_bAutoFlush; +}; + + +IFileSystem* ScratchPad3D_SetupFileSystem(); + + +#endif // SCRATCHPAD3D_H diff --git a/sp/src/public/sentence.cpp b/sp/src/public/sentence.cpp new file mode 100644 index 00000000..49c24c3c --- /dev/null +++ b/sp/src/public/sentence.cpp @@ -0,0 +1,1764 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#if !defined(_STATIC_LINKED) || defined(_SHARED_LIB) + +#include +#include "commonmacros.h" +#include "basetypes.h" +#include "sentence.h" +#include "utlbuffer.h" +#include +#include "mathlib/vector.h" +#include "mathlib/mathlib.h" +#include +#include "checksum_crc.h" +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// Purpose: converts an english string to unicode +//----------------------------------------------------------------------------- +int ConvertANSIToUnicode(const char *ansi, wchar_t *unicode, int unicodeBufferSize); + +#if PHONEME_EDITOR +void CEmphasisSample::SetSelected( bool isSelected ) +{ + selected = isSelected; +} +void CPhonemeTag::SetSelected( bool isSelected ) +{ + m_bSelected = isSelected; +} +bool CPhonemeTag::GetSelected() const +{ + return m_bSelected; +} +void CPhonemeTag::SetStartAndEndBytes( unsigned int start, unsigned int end ) +{ + m_uiStartByte = start; + m_uiEndByte = end; +} +unsigned int CPhonemeTag::GetStartByte() const +{ + return m_uiStartByte; +} +unsigned int CPhonemeTag::GetEndByte() const +{ + return m_uiEndByte; +} +void CWordTag::SetSelected( bool isSelected ) +{ + m_bSelected = isSelected; +} +bool CWordTag::GetSelected() const +{ + return m_bSelected; +} +void CWordTag::SetStartAndEndBytes( unsigned int start, unsigned int end ) +{ + m_uiStartByte = start; + m_uiEndByte = end; +} +unsigned int CWordTag::GetStartByte() const +{ + return m_uiStartByte; +} +unsigned int CWordTag::GetEndByte() const +{ + return m_uiEndByte; +} +#else +// xbox doesn't store this data +void CEmphasisSample::SetSelected( bool isSelected ) {} +void CPhonemeTag::SetSelected( bool isSelected ) {} +bool CPhonemeTag::GetSelected() const { return false; } +void CPhonemeTag::SetStartAndEndBytes( unsigned int start, unsigned int end ) {} +unsigned int CPhonemeTag::GetStartByte() const { return 0; } +unsigned int CPhonemeTag::GetEndByte() const { return 0; } +void CWordTag::SetSelected( bool isSelected ) {} +bool CWordTag::GetSelected() const { return false; } +void CWordTag::SetStartAndEndBytes( unsigned int start, unsigned int end ) {} +unsigned int CWordTag::GetStartByte() const { return 0; } +unsigned int CWordTag::GetEndByte() const { return 0; } +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CWordTag::CWordTag( void ) +{ + m_pszWord = NULL; + + SetStartAndEndBytes( 0, 0 ); + + m_flStartTime = 0.0f; + m_flEndTime = 0.0f; + + SetSelected( false ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : from - +//----------------------------------------------------------------------------- +CWordTag::CWordTag( const CWordTag& from ) +{ + m_pszWord = NULL; + SetWord( from.m_pszWord ); + + SetStartAndEndBytes( from.GetStartByte(), from.GetEndByte() ); + + m_flStartTime = from.m_flStartTime; + m_flEndTime = from.m_flEndTime; + + SetSelected( from.GetSelected() ); + + for ( int p = 0; p < from.m_Phonemes.Size(); p++ ) + { + CPhonemeTag *newPhoneme = new CPhonemeTag( *from.m_Phonemes[ p ] ); + m_Phonemes.AddToTail( newPhoneme ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *word - +//----------------------------------------------------------------------------- +CWordTag::CWordTag( const char *word ) +{ + SetStartAndEndBytes( 0, 0 ); + + m_flStartTime = 0.0f; + m_flEndTime = 0.0f; + + m_pszWord = NULL; + + SetSelected( false ); + + SetWord( word ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CWordTag::~CWordTag( void ) +{ + delete[] m_pszWord; + + while ( m_Phonemes.Size() > 0 ) + { + delete m_Phonemes[ 0 ]; + m_Phonemes.Remove( 0 ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *tag - +// Output : int +//----------------------------------------------------------------------------- +int CWordTag::IndexOfPhoneme( CPhonemeTag *tag ) +{ + for ( int i = 0 ; i < m_Phonemes.Size(); i++ ) + { + CPhonemeTag *p = m_Phonemes[ i ]; + if ( p == tag ) + return i; + } + return -1; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *word - +//----------------------------------------------------------------------------- +void CWordTag::SetWord( const char *word ) +{ + delete[] m_pszWord; + m_pszWord = NULL; + if ( !word || !word[ 0 ] ) + return; + + int len = strlen( word ) + 1; + m_pszWord = new char[ len ]; + Assert( m_pszWord ); + Q_strncpy( m_pszWord, word, len ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : const char +//----------------------------------------------------------------------------- +const char *CWordTag::GetWord() const +{ + return m_pszWord ? m_pszWord : ""; +} + + +unsigned int CWordTag::ComputeDataCheckSum() +{ + int i; + int c; + CRC32_t crc; + CRC32_Init( &crc ); + + // Checksum the text + if ( m_pszWord != NULL ) + { + CRC32_ProcessBuffer( &crc, m_pszWord, Q_strlen( m_pszWord ) ); + } + // Checksum phonemes + c = m_Phonemes.Count(); + for ( i = 0; i < c; ++i ) + { + CPhonemeTag *phoneme = m_Phonemes[ i ]; + unsigned int phonemeCheckSum = phoneme->ComputeDataCheckSum(); + CRC32_ProcessBuffer( &crc, &phonemeCheckSum, sizeof( unsigned int ) ); + } + // Checksum timestamps + CRC32_ProcessBuffer( &crc, &m_flStartTime, sizeof( float ) ); + CRC32_ProcessBuffer( &crc, &m_flEndTime, sizeof( float ) ); + + CRC32_Final( &crc ); + + return ( unsigned int )crc; +} + +CBasePhonemeTag::CBasePhonemeTag() +{ + m_flStartTime = 0; + m_flEndTime = 0; + + m_nPhonemeCode = 0; +} + +CBasePhonemeTag::CBasePhonemeTag( const CBasePhonemeTag& from ) +{ + memcpy( this, &from, sizeof(*this) ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CPhonemeTag::CPhonemeTag( void ) +{ + m_szPhoneme = NULL; + + SetStartAndEndBytes( 0, 0 ); + + SetSelected( false ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : from - +//----------------------------------------------------------------------------- +CPhonemeTag::CPhonemeTag( const CPhonemeTag& from ) : + BaseClass( from ) +{ + SetStartAndEndBytes( from.GetStartByte(), from.GetEndByte() ); + + SetSelected( from.GetSelected() ); + + m_szPhoneme = NULL; + SetTag( from.GetTag() ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *phoneme - +//----------------------------------------------------------------------------- +CPhonemeTag::CPhonemeTag( const char *phoneme ) +{ + SetStartAndEndBytes( 0, 0 ); + + SetStartTime( 0.0f ); + SetEndTime( 0.0f ); + + SetSelected( false ); + + SetPhonemeCode( 0 ); + + m_szPhoneme = NULL; + SetTag( phoneme ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CPhonemeTag::~CPhonemeTag( void ) +{ + delete[] m_szPhoneme; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *phoneme - +//----------------------------------------------------------------------------- +void CPhonemeTag::SetTag( const char *phoneme ) +{ + delete m_szPhoneme; + m_szPhoneme = NULL; + if ( !phoneme || !phoneme [ 0 ] ) + return; + + int len = Q_strlen( phoneme ) + 1; + m_szPhoneme = new char[ len ]; + Assert( m_szPhoneme ); + Q_strncpy( m_szPhoneme, phoneme, len ); +} + +char const *CPhonemeTag::GetTag() const +{ + return m_szPhoneme ? m_szPhoneme : ""; +} + + +unsigned int CPhonemeTag::ComputeDataCheckSum() +{ + CRC32_t crc; + CRC32_Init( &crc ); + + // Checksum the text + CRC32_ProcessBuffer( &crc, m_szPhoneme, Q_strlen( m_szPhoneme ) ); + int phonemeCode = GetPhonemeCode(); + CRC32_ProcessBuffer( &crc, &phonemeCode, sizeof( int ) ); + + // Checksum timestamps + float startTime = GetStartTime(); + float endTime = GetEndTime(); + CRC32_ProcessBuffer( &crc, &startTime, sizeof( float ) ); + CRC32_ProcessBuffer( &crc, &endTime, sizeof( float ) ); + + CRC32_Final( &crc ); + + return ( unsigned int )crc; +} + +//----------------------------------------------------------------------------- +// Purpose: Simple language to string and string to language lookup dictionary +//----------------------------------------------------------------------------- +#pragma pack(1) + +struct CCLanguage +{ + int type; + char const *name; + unsigned char r, g, b; // For faceposer, indicator color for this language +}; + +static CCLanguage g_CCLanguageLookup[] = +{ + { CC_ENGLISH, "english", 0, 0, 0 }, + { CC_FRENCH, "french", 150, 0, 0 }, + { CC_GERMAN, "german", 0, 150, 0 }, + { CC_ITALIAN, "italian", 0, 150, 150 }, + { CC_KOREAN, "koreana", 150, 0, 150 }, + { CC_SCHINESE, "schinese", 150, 0, 150 }, + { CC_SPANISH, "spanish", 0, 0, 150 }, + { CC_TCHINESE, "tchinese", 150, 0, 150 }, + { CC_JAPANESE, "japanese", 250, 150, 0 }, + { CC_RUSSIAN, "russian", 0, 250, 150 }, + { CC_THAI, "thai", 0 , 150, 250 }, + { CC_PORTUGUESE,"portuguese", 0 , 0, 150 }, +}; + +#pragma pack() + +void CSentence::ColorForLanguage( int language, unsigned char& r, unsigned char& g, unsigned char& b ) +{ + r = g = b = 0; + + if ( language < 0 || language >= CC_NUM_LANGUAGES ) + { + return; + } + + r = g_CCLanguageLookup[ language ].r; + g = g_CCLanguageLookup[ language ].g; + b = g_CCLanguageLookup[ language ].b; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : language - +// Output : char const +//----------------------------------------------------------------------------- +char const *CSentence::NameForLanguage( int language ) +{ + if ( language < 0 || language >= CC_NUM_LANGUAGES ) + return "unknown_language"; + + CCLanguage *entry = &g_CCLanguageLookup[ language ]; + Assert( entry->type == language ); + return entry->name; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *name - +// Output : int +//----------------------------------------------------------------------------- +int CSentence::LanguageForName( char const *name ) +{ + int l; + for ( l = 0; l < CC_NUM_LANGUAGES; l++ ) + { + CCLanguage *entry = &g_CCLanguageLookup[ l ]; + Assert( entry->type == l ); + if ( !stricmp( entry->name, name ) ) + return l; + } + return -1; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CSentence::CSentence( void ) +{ +#if PHONEME_EDITOR + m_nResetWordBase = 0; + m_szText = 0; + m_uCheckSum = 0; +#endif + m_bShouldVoiceDuck = false; + m_bStoreCheckSum = false; + m_bIsValid = false; + m_bIsCached = false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CSentence::~CSentence( void ) +{ + Reset(); +#if PHONEME_EDITOR + delete[] m_szText; +#endif +} + + +void CSentence::ParsePlaintext( CUtlBuffer& buf ) +{ + char token[ 4096 ]; + char text[ 4096 ]; + text[ 0 ] = 0; + while ( 1 ) + { + buf.GetString( token ); + if ( !stricmp( token, "}" ) ) + break; + + Q_strncat( text, token, sizeof( text ), COPY_ALL_CHARACTERS ); + Q_strncat( text, " ", sizeof( text ), COPY_ALL_CHARACTERS ); + } + + SetText( text ); +} + +void CSentence::ParseWords( CUtlBuffer& buf ) +{ + char token[ 4096 ]; + char word[ 256 ]; + float start, end; + + while ( 1 ) + { + buf.GetString( token ); + if ( !stricmp( token, "}" ) ) + break; + + if ( stricmp( token, "WORD" ) ) + break; + + buf.GetString( token ); + Q_strncpy( word, token, sizeof( word ) ); + + buf.GetString( token ); + start = atof( token ); + buf.GetString( token ); + end = atof( token ); + + CWordTag *wt = new CWordTag( word ); + assert( wt ); + wt->m_flStartTime = start; + wt->m_flEndTime = end; + + AddWordTag( wt ); + + buf.GetString( token ); + if ( stricmp( token, "{" ) ) + break; + + while ( 1 ) + { + buf.GetString( token ); + if ( !stricmp( token, "}" ) ) + break; + + // Parse phoneme + int code; + char phonemename[ 256 ]; + float start, end; + float volume; + + code = atoi( token ); + + buf.GetString( token ); + Q_strncpy( phonemename, token, sizeof( phonemename ) ); + buf.GetString( token ); + start = atof( token ); + buf.GetString( token ); + end = atof( token ); + buf.GetString( token ); + volume = atof( token ); + + CPhonemeTag *pt = new CPhonemeTag(); + assert( pt ); + pt->SetPhonemeCode( code ); + pt->SetTag( phonemename ); + pt->SetStartTime( start ); + pt->SetEndTime( end ); + + AddPhonemeTag( wt, pt ); + } + } +} + +void CSentence::ParseEmphasis( CUtlBuffer& buf ) +{ + char token[ 4096 ]; + while ( 1 ) + { + buf.GetString( token ); + if ( !stricmp( token, "}" ) ) + break; + + char t[ 256 ]; + Q_strncpy( t, token, sizeof( t ) ); + buf.GetString( token ); + + char value[ 256 ]; + Q_strncpy( value, token, sizeof( value ) ); + + CEmphasisSample sample; + sample.SetSelected( false ); + sample.time = atof( t ); + sample.value = atof( value ); + + + m_EmphasisSamples.AddToTail( sample ); + + } +} + +// This is obsolete, so it doesn't do anything with the data which is parsed. +void CSentence::ParseCloseCaption( CUtlBuffer& buf ) +{ + char token[ 4096 ]; + while ( 1 ) + { + // Format is + // language_name + // { + // PHRASE char streamlength "streambytes" starttime endtime + // PHRASE unicode streamlength "streambytes" starttime endtime + // } + buf.GetString( token ); + if ( !stricmp( token, "}" ) ) + break; + + buf.GetString( token ); + if ( stricmp( token, "{" ) ) + break; + + buf.GetString( token ); + while ( 1 ) + { + if ( !stricmp( token, "}" ) ) + break; + + if ( stricmp( token, "PHRASE" ) ) + break; + + char cc_type[32]; + char cc_stream[ 4096 ]; + int cc_length; + + memset( cc_stream, 0, sizeof( cc_stream ) ); + + buf.GetString( token ); + Q_strncpy( cc_type, token, sizeof( cc_type ) ); + + bool unicode = false; + if ( !stricmp( cc_type, "unicode" ) ) + { + unicode = true; + } + else if ( stricmp( cc_type, "char" ) ) + { + Assert( 0 ); + } + + buf.GetString( token ); + cc_length = atoi( token ); + Assert( cc_length >= 0 && cc_length < sizeof( cc_stream ) ); + // Skip space + buf.GetChar(); + buf.Get( cc_stream, cc_length ); + cc_stream[ cc_length ] = 0; + + // Skip space + buf.GetChar(); + buf.GetString( token ); + buf.GetString( token ); + + buf.GetString( token ); + } + } +} + +void CSentence::ParseOptions( CUtlBuffer& buf ) +{ + char token[ 4096 ]; + while ( 1 ) + { + buf.GetString( token ); + if ( !stricmp( token, "}" ) ) + break; + + if ( Q_strlen( token ) == 0 ) + break; + + char key[ 256 ]; + Q_strncpy( key, token, sizeof( key ) ); + char value[ 256 ]; + buf.GetString( token ); + Q_strncpy( value, token, sizeof( value ) ); + + if ( !strcmpi( key, "voice_duck" ) ) + { + SetVoiceDuck( atoi(value) ? true : false ); + } + else if ( !strcmpi( key, "checksum" ) ) + { + SetDataCheckSum( (unsigned int)atoi( value ) ); + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: VERSION 1.0 parser, need to implement new ones if +// file format changes!!! +// Input : buf - +//----------------------------------------------------------------------------- +void CSentence::ParseDataVersionOnePointZero( CUtlBuffer& buf ) +{ + char token[ 4096 ]; + + while ( 1 ) + { + buf.GetString( token ); + if ( strlen( token ) <= 0 ) + break; + + char section[ 256 ]; + Q_strncpy( section, token, sizeof( section ) ); + + buf.GetString( token ); + if ( stricmp( token, "{" ) ) + break; + + if ( !stricmp( section, "PLAINTEXT" ) ) + { + ParsePlaintext( buf ); + } + else if ( !stricmp( section, "WORDS" ) ) + { + ParseWords( buf ); + } + else if ( !stricmp( section, "EMPHASIS" ) ) + { + ParseEmphasis( buf ); + } + else if ( !stricmp( section, "CLOSECAPTION" ) ) + { + // NOTE: CLOSECAPTION IS NO LONGER VALID + // This just skips the section of data. + ParseCloseCaption( buf ); + } + else if ( !stricmp( section, "OPTIONS" ) ) + { + ParseOptions( buf ); + } + } +} + +// This is a compressed save of just the data needed to drive phonemes in the engine (no word / sentence text, etc ) +//----------------------------------------------------------------------------- +// Purpose: +// Input : buf - +//----------------------------------------------------------------------------- +void CSentence::CacheSaveToBuffer( CUtlBuffer& buf, int version ) +{ + Assert( !buf.IsText() ); + Assert( m_bIsCached ); + + int i; + unsigned short pcount = GetRuntimePhonemeCount(); + + // header + if ( version == CACHED_SENTENCE_VERSION_ALIGNED ) + { + buf.PutChar( version ); + buf.PutChar( 0 ); + buf.PutChar( 0 ); + buf.PutChar( 0 ); + buf.PutInt( pcount ); + } + else + { + buf.PutChar( version ); + buf.PutShort( pcount ); + } + + // phoneme + if ( version == CACHED_SENTENCE_VERSION_ALIGNED ) + { + for ( i = 0; i < pcount; ++i ) + { + const CBasePhonemeTag *phoneme = GetRuntimePhoneme( i ); + Assert( phoneme ); + buf.PutInt( phoneme->GetPhonemeCode() ); + buf.PutFloat( phoneme->GetStartTime() ); + buf.PutFloat( phoneme->GetEndTime() ); + } + } + else + { + for ( i = 0; i < pcount; ++i ) + { + const CBasePhonemeTag *phoneme = GetRuntimePhoneme( i ); + Assert( phoneme ); + buf.PutShort( phoneme->GetPhonemeCode() ); + buf.PutFloat( phoneme->GetStartTime() ); + buf.PutFloat( phoneme->GetEndTime() ); + } + } + + // emphasis samples and voice duck + int c = m_EmphasisSamples.Count(); + Assert( c <= 32767 ); + + if ( version == CACHED_SENTENCE_VERSION_ALIGNED ) + { + buf.PutInt( c ); + for ( i = 0; i < c; i++ ) + { + CEmphasisSample *sample = &m_EmphasisSamples[i]; + Assert( sample ); + buf.PutFloat( sample->time ); + buf.PutFloat( sample->value ); + } + buf.PutInt( GetVoiceDuck() ? 1 : 0 ); + } + else + { + buf.PutShort( c ); + for ( i = 0; i < c; i++ ) + { + CEmphasisSample *sample = &m_EmphasisSamples[i]; + Assert( sample ); + buf.PutFloat( sample->time ); + short scaledValue = clamp( (short)( sample->value * 32767 ), (short)0, (short)32767 ); + buf.PutShort( scaledValue ); + } + buf.PutChar( GetVoiceDuck() ? 1 : 0 ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : buf - +//----------------------------------------------------------------------------- +void CSentence::CacheRestoreFromBuffer( CUtlBuffer& buf ) +{ + Assert( !buf.IsText() ); + + Reset(); + + m_bIsCached = true; + + // determine format + int version = buf.GetChar(); + if ( version != CACHED_SENTENCE_VERSION && version != CACHED_SENTENCE_VERSION_ALIGNED ) + { + // Uh oh, version changed... + m_bIsValid = false; + return; + } + + unsigned short pcount; + if ( version == CACHED_SENTENCE_VERSION_ALIGNED ) + { + buf.GetChar(); + buf.GetChar(); + buf.GetChar(); + pcount = buf.GetInt(); + } + else + { + pcount = (unsigned short)buf.GetShort(); + } + + // phonemes + CPhonemeTag pt; + int i; + if ( version == CACHED_SENTENCE_VERSION_ALIGNED ) + { + for ( i = 0; i < pcount; ++i ) + { + int code = buf.GetInt(); + float st = buf.GetFloat(); + float et = buf.GetFloat(); + + pt.SetPhonemeCode( code ); + pt.SetStartTime( st ); + pt.SetEndTime( et ); + AddRuntimePhoneme( &pt ); + } + } + else + { + for ( i = 0; i < pcount; ++i ) + { + unsigned short code = buf.GetShort(); + float st = buf.GetFloat(); + float et = buf.GetFloat(); + + pt.SetPhonemeCode( code ); + pt.SetStartTime( st ); + pt.SetEndTime( et ); + AddRuntimePhoneme( &pt ); + } + } + + // emphasis samples and voice duck + int c; + if ( version == CACHED_SENTENCE_VERSION_ALIGNED ) + { + c = buf.GetInt(); + for ( i = 0; i < c; i++ ) + { + CEmphasisSample sample; + sample.SetSelected( false ); + sample.time = buf.GetFloat(); + sample.value = buf.GetFloat(); + m_EmphasisSamples.AddToTail( sample ); + } + SetVoiceDuck( buf.GetInt() == 0 ? false : true ); + } + else + { + c = buf.GetShort(); + for ( i = 0; i < c; i++ ) + { + CEmphasisSample sample; + sample.SetSelected( false ); + sample.time = buf.GetFloat(); + sample.value = (float)buf.GetShort() / 32767.0f; + m_EmphasisSamples.AddToTail( sample ); + } + SetVoiceDuck( buf.GetChar() == 0 ? false : true ); + } + + m_bIsValid = true; +} + +int CSentence::GetRuntimePhonemeCount() const +{ + return m_RunTimePhonemes.Count(); +} + +const CBasePhonemeTag *CSentence::GetRuntimePhoneme( int i ) const +{ + Assert( m_bIsCached ); + return m_RunTimePhonemes[ i ]; +} + +void CSentence::ClearRuntimePhonemes() +{ + while ( m_RunTimePhonemes.Count() > 0 ) + { + CBasePhonemeTag *tag = m_RunTimePhonemes[ 0 ]; + delete tag; + m_RunTimePhonemes.Remove( 0 ); + } +} + +void CSentence::AddRuntimePhoneme( const CPhonemeTag *src ) +{ + Assert( m_bIsCached ); + + CBasePhonemeTag *tag = new CBasePhonemeTag(); + *tag = *src; + + m_RunTimePhonemes.AddToTail( tag ); +} + +void CSentence::MakeRuntimeOnly() +{ + m_bIsCached = true; +#if PHONEME_EDITOR + delete m_szText; + m_szText = NULL; + + int c = m_Words.Count(); + for ( int i = 0; i < c; ++i ) + { + CWordTag *word = m_Words[ i ]; + Assert( word ); + int pcount = word->m_Phonemes.Count(); + for ( int j = 0; j < pcount; ++j ) + { + CPhonemeTag *phoneme = word->m_Phonemes[ j ]; + assert( phoneme ); + + AddRuntimePhoneme( phoneme ); + } + } + + // Remove all existing words + while ( m_Words.Count() > 0 ) + { + CWordTag *word = m_Words[ 0 ]; + delete word; + m_Words.Remove( 0 ); + } +#endif + m_bIsValid = true; +} + + +void CSentence::SaveToBuffer( CUtlBuffer& buf ) +{ +#if PHONEME_EDITOR + Assert( !m_bIsCached ); + + int i, j; + + buf.Printf( "VERSION 1.0\n" ); + + buf.Printf( "PLAINTEXT\n" ); + buf.Printf( "{\n" ); + buf.Printf( "%s\n", GetText() ); + buf.Printf( "}\n" ); + buf.Printf( "WORDS\n" ); + buf.Printf( "{\n" ); + for ( i = 0; i < m_Words.Size(); i++ ) + { + CWordTag *word = m_Words[ i ]; + Assert( word ); + + buf.Printf( "WORD %s %.3f %.3f\n", + word->GetWord(), + word->m_flStartTime, + word->m_flEndTime ); + + buf.Printf( "{\n" ); + for ( j = 0; j < word->m_Phonemes.Size(); j++ ) + { + CPhonemeTag *phoneme = word->m_Phonemes[ j ]; + Assert( phoneme ); + + buf.Printf( "%i %s %.3f %.3f 1\n", + phoneme->GetPhonemeCode(), + phoneme->GetTag(), + phoneme->GetStartTime(), + phoneme->GetEndTime() ); + } + + buf.Printf( "}\n" ); + } + buf.Printf( "}\n" ); + buf.Printf( "EMPHASIS\n" ); + buf.Printf( "{\n" ); + int c = m_EmphasisSamples.Count(); + for ( i = 0; i < c; i++ ) + { + CEmphasisSample *sample = &m_EmphasisSamples[ i ]; + Assert( sample ); + + buf.Printf( "%f %f\n", sample->time, sample->value ); + } + + buf.Printf( "}\n" ); + buf.Printf( "OPTIONS\n" ); + buf.Printf( "{\n" ); + buf.Printf( "voice_duck %d\n", GetVoiceDuck() ? 1 : 0 ); + if ( m_bStoreCheckSum ) + { + buf.Printf( "checksum %d\n", m_uCheckSum ); + } + buf.Printf( "}\n" ); +#else + Assert( 0 ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *data - +// size - +//----------------------------------------------------------------------------- +void CSentence::InitFromDataChunk( void *data, int size ) +{ + CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); + buf.EnsureCapacity( size ); + buf.Put( data, size ); + buf.SeekPut( CUtlBuffer::SEEK_HEAD, size ); + + InitFromBuffer( buf ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : buf - +//----------------------------------------------------------------------------- +void CSentence::InitFromBuffer( CUtlBuffer& buf ) +{ + Assert( buf.IsText() ); + + Reset(); + + char token[ 4096 ]; + buf.GetString( token ); + + if ( stricmp( token, "VERSION" ) ) + return; + + buf.GetString( token ); + if ( atof( token ) == 1.0f ) + { + ParseDataVersionOnePointZero( buf ); + m_bIsValid = true; + } + else + { + assert( 0 ); + return; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : int +//----------------------------------------------------------------------------- +int CSentence::GetWordBase( void ) +{ +#if PHONEME_EDITOR + return m_nResetWordBase; +#else + Assert( 0 ); + return 0; +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSentence::ResetToBase( void ) +{ +#if PHONEME_EDITOR + // Delete everything after m_nResetWordBase + while ( m_Words.Size() > m_nResetWordBase ) + { + delete m_Words[ m_Words.Size() - 1 ]; + m_Words.Remove( m_Words.Size() - 1 ); + } +#endif + ClearRuntimePhonemes(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSentence::MarkNewPhraseBase( void ) +{ +#if PHONEME_EDITOR + m_nResetWordBase = max( m_Words.Size(), 0 ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSentence::Reset( void ) +{ +#if PHONEME_EDITOR + m_nResetWordBase = 0; + + while ( m_Words.Size() > 0 ) + { + delete m_Words[ 0 ]; + m_Words.Remove( 0 ); + } +#endif + m_EmphasisSamples.RemoveAll(); + + ClearRuntimePhonemes(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *tag - +//----------------------------------------------------------------------------- +void CSentence::AddPhonemeTag( CWordTag *word, CPhonemeTag *tag ) +{ + word->m_Phonemes.AddToTail( tag ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *tag - +//----------------------------------------------------------------------------- +void CSentence::AddWordTag( CWordTag *tag ) +{ +#if PHONEME_EDITOR + m_Words.AddToTail( tag ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : int +//----------------------------------------------------------------------------- +int CSentence::CountPhonemes( void ) +{ + int c = 0; +#if PHONEME_EDITOR + for( int i = 0; i < m_Words.Size(); i++ ) + { + CWordTag *word = m_Words[ i ]; + c += word->m_Phonemes.Size(); + } +#endif + return c; +} + +//----------------------------------------------------------------------------- +// Purpose: // For legacy loading, try to find a word that contains the time +// Input : time - +// Output : CWordTag +//----------------------------------------------------------------------------- +CWordTag *CSentence::EstimateBestWord( float time ) +{ +#if PHONEME_EDITOR + CWordTag *bestWord = NULL; + + for( int i = 0; i < m_Words.Size(); i++ ) + { + CWordTag *word = m_Words[ i ]; + if ( !word ) + continue; + + if ( word->m_flStartTime <= time && word->m_flEndTime >= time ) + return word; + + if ( time < word->m_flStartTime ) + { + bestWord = word; + } + + if ( time > word->m_flEndTime && bestWord ) + return bestWord; + } + + // return best word if we found one + if ( bestWord ) + { + return bestWord; + } + + // Return last word + if ( m_Words.Size() >= 1 ) + { + return m_Words[ m_Words.Size() - 1 ]; + } +#endif + // Oh well + return NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *phoneme - +// Output : CWordTag +//----------------------------------------------------------------------------- +CWordTag *CSentence::GetWordForPhoneme( CPhonemeTag *phoneme ) +{ +#if PHONEME_EDITOR + for( int i = 0; i < m_Words.Size(); i++ ) + { + CWordTag *word = m_Words[ i ]; + if ( !word ) + continue; + + for ( int j = 0 ; j < word->m_Phonemes.Size() ; j++ ) + { + CPhonemeTag *p = word->m_Phonemes[ j ]; + if ( p == phoneme ) + { + return word; + } + } + + } +#endif + return NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: Assignment operator +// Input : src - +// Output : CSentence& +//----------------------------------------------------------------------------- +CSentence& CSentence::operator=( const CSentence& src ) +{ + int i; + + // Clear current stuff + Reset(); + + int c; + +#if PHONEME_EDITOR + // Copy everything + for ( i = 0 ; i < src.m_Words.Size(); i++ ) + { + CWordTag *word = src.m_Words[ i ]; + + CWordTag *newWord = new CWordTag( *word ); + + AddWordTag( newWord ); + } + + SetText( src.GetText() ); + m_nResetWordBase = src.m_nResetWordBase; + + c = src.m_EmphasisSamples.Size(); + for ( i = 0; i < c; i++ ) + { + CEmphasisSample s = src.m_EmphasisSamples[ i ]; + m_EmphasisSamples.AddToTail( s ); + } +#endif + + m_bIsCached = src.m_bIsCached; + + c = src.GetRuntimePhonemeCount(); + for ( i = 0; i < c; i++ ) + { + Assert( m_bIsCached ); + + const CBasePhonemeTag *tag = src.GetRuntimePhoneme( i ); + CPhonemeTag full; + ((CBasePhonemeTag &)(full)) = *tag; + + AddRuntimePhoneme( &full ); + } + + m_bShouldVoiceDuck = src.m_bShouldVoiceDuck; +#if PHONEME_EDITOR + m_bStoreCheckSum = src.m_bStoreCheckSum; + m_uCheckSum = src.m_uCheckSum; +#endif + m_bIsValid = src.m_bIsValid; + + return (*this); +} + +void CSentence::Append( float starttime, const CSentence& src ) +{ +#if PHONEME_EDITOR + int i; + // Combine + for ( i = 0 ; i < src.m_Words.Size(); i++ ) + { + CWordTag *word = src.m_Words[ i ]; + + CWordTag *newWord = new CWordTag( *word ); + + newWord->m_flStartTime += starttime; + newWord->m_flEndTime += starttime; + + // Offset times + int c = newWord->m_Phonemes.Count(); + for ( int i = 0; i < c; ++i ) + { + CPhonemeTag *tag = newWord->m_Phonemes[ i ]; + tag->AddStartTime( starttime ); + tag->AddEndTime( starttime ); + } + + AddWordTag( newWord ); + } + + if ( src.GetText()[ 0 ] ) + { + char fulltext[ 4096 ]; + if ( GetText()[ 0 ] ) + { + Q_snprintf( fulltext, sizeof( fulltext ), "%s %s", GetText(), src.GetText() ); + } + else + { + Q_strncpy( fulltext, src.GetText(), sizeof( fulltext ) ); + } + SetText( fulltext ); + } + + int c = src.m_EmphasisSamples.Size(); + for ( i = 0; i < c; i++ ) + { + CEmphasisSample s = src.m_EmphasisSamples[ i ]; + + s.time += starttime; + + m_EmphasisSamples.AddToTail( s ); + } + + // Or in voice duck settings + m_bShouldVoiceDuck |= src.m_bShouldVoiceDuck; +#else + Assert( 0 ); +#endif +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *text - +//----------------------------------------------------------------------------- +void CSentence::SetText( const char *text ) +{ +#if PHONEME_EDITOR + delete[] m_szText; + m_szText = NULL; + + if ( !text || !text[ 0 ] ) + { + return; + } + + int len = Q_strlen( text ) + 1; + + m_szText = new char[ len ]; + Assert( m_szText ); + Q_strncpy( m_szText, text, len ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : const char +//----------------------------------------------------------------------------- +const char *CSentence::GetText( void ) const +{ +#if PHONEME_EDITOR + return m_szText ? m_szText : ""; +#else + return ""; +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSentence::SetTextFromWords( void ) +{ +#if PHONEME_EDITOR + char fulltext[ 1024 ]; + fulltext[ 0 ] = 0; + for ( int i = 0 ; i < m_Words.Size(); i++ ) + { + CWordTag *word = m_Words[ i ]; + + Q_strncat( fulltext, word->GetWord(), sizeof( fulltext ), COPY_ALL_CHARACTERS ); + + if ( i != m_Words.Size() ) + { + Q_strncat( fulltext, " ", sizeof( fulltext ), COPY_ALL_CHARACTERS ); + } + } + + SetText( fulltext ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSentence::Resort( void ) +{ + int c = m_EmphasisSamples.Size(); + for ( int i = 0; i < c; i++ ) + { + for ( int j = i + 1; j < c; j++ ) + { + CEmphasisSample src = m_EmphasisSamples[ i ]; + CEmphasisSample dest = m_EmphasisSamples[ j ]; + + if ( src.time > dest.time ) + { + m_EmphasisSamples[ i ] = dest; + m_EmphasisSamples[ j ] = src; + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : number - +// Output : CEmphasisSample +//----------------------------------------------------------------------------- +CEmphasisSample *CSentence::GetBoundedSample( int number, float endtime ) +{ + // Search for two samples which span time f + static CEmphasisSample nullstart; + nullstart.time = 0.0f; + nullstart.value = 0.5f; + static CEmphasisSample nullend; + nullend.time = endtime; + nullend.value = 0.5f; + + if ( number < 0 ) + { + return &nullstart; + } + else if ( number >= GetNumSamples() ) + { + return &nullend; + } + + return GetSample( number ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : time - +// type - +// Output : float +//----------------------------------------------------------------------------- +float CSentence::GetIntensity( float time, float endtime ) +{ + float zeroValue = 0.5f; + + int c = GetNumSamples(); + + if ( c <= 0 ) + { + return zeroValue; + } + + int i; + for ( i = -1 ; i < c; i++ ) + { + CEmphasisSample *s = GetBoundedSample( i, endtime ); + CEmphasisSample *n = GetBoundedSample( i + 1, endtime ); + if ( !s || !n ) + continue; + + if ( time >= s->time && time <= n->time ) + { + break; + } + } + + int prev = i - 1; + int start = i; + int end = i + 1; + int next = i + 2; + + prev = max( -1, prev ); + start = max( -1, start ); + end = min( end, GetNumSamples() ); + next = min( next, GetNumSamples() ); + + CEmphasisSample *esPre = GetBoundedSample( prev, endtime ); + CEmphasisSample *esStart = GetBoundedSample( start, endtime ); + CEmphasisSample *esEnd = GetBoundedSample( end, endtime ); + CEmphasisSample *esNext = GetBoundedSample( next, endtime ); + + float dt = esEnd->time - esStart->time; + dt = clamp( dt, 0.01f, 1.0f ); + + Vector vPre( esPre->time, esPre->value, 0 ); + Vector vStart( esStart->time, esStart->value, 0 ); + Vector vEnd( esEnd->time, esEnd->value, 0 ); + Vector vNext( esNext->time, esNext->value, 0 ); + + float f2 = ( time - esStart->time ) / ( dt ); + f2 = clamp( f2, 0.0f, 1.0f ); + + Vector vOut; + Catmull_Rom_Spline( + vPre, + vStart, + vEnd, + vNext, + f2, + vOut ); + + float retval = clamp( vOut.y, 0.0f, 1.0f ); + return retval; +} + +int CSentence::GetNumSamples( void ) +{ + return m_EmphasisSamples.Count(); +} + +CEmphasisSample *CSentence::GetSample( int index ) +{ + if ( index < 0 || index >= GetNumSamples() ) + return NULL; + + return &m_EmphasisSamples[ index ]; +} + +void CSentence::GetEstimatedTimes( float& start, float &end ) +{ +#if PHONEME_EDITOR + float beststart = 100000.0f; + float bestend = -100000.0f; + + int c = m_Words.Count(); + if ( !c ) + { + start = end = 0.0f; + return; + } + + for ( int i = 0; i< c; i++ ) + { + CWordTag *w = m_Words[ i ]; + Assert( w ); + if ( w->m_flStartTime < beststart ) + { + beststart = w->m_flStartTime; + } + if ( w->m_flEndTime > bestend ) + { + bestend = w->m_flEndTime; + } + } + + if ( beststart == 100000.0f ) + { + Assert( 0 ); + beststart = 0.0f; + } + if ( bestend == -100000.0f ) + { + Assert( 0 ); + bestend = 1.0f; + } + start = beststart; + end = bestend; +#endif +} + +void CSentence::SetDataCheckSum( unsigned int chk ) +{ +#if PHONEME_EDITOR + m_bStoreCheckSum = true; + m_uCheckSum = chk; +#endif +} + +unsigned int CSentence::ComputeDataCheckSum() +{ +#if PHONEME_EDITOR + int i; + int c; + CRC32_t crc; + CRC32_Init( &crc ); + + // Checksum the text + CRC32_ProcessBuffer( &crc, GetText(), Q_strlen( GetText() ) ); + // Checsum words and phonemes + c = m_Words.Count(); + for ( i = 0; i < c; ++i ) + { + CWordTag *word = m_Words[ i ]; + unsigned int wordCheckSum = word->ComputeDataCheckSum(); + CRC32_ProcessBuffer( &crc, &wordCheckSum, sizeof( unsigned int ) ); + } + + // Checksum emphasis data + c = m_EmphasisSamples.Count(); + for ( i = 0; i < c; ++i ) + { + CRC32_ProcessBuffer( &crc, &m_EmphasisSamples[ i ].time, sizeof( float ) ); + CRC32_ProcessBuffer( &crc, &m_EmphasisSamples[ i ].value, sizeof( float ) ); + } + + CRC32_Final( &crc ); + + return ( unsigned int )crc; +#else + Assert( 0 ); + return 0; +#endif +} + +unsigned int CSentence::GetDataCheckSum() const +{ +#if PHONEME_EDITOR + Assert( m_bStoreCheckSum ); + Assert( m_uCheckSum != 0 ); + return m_uCheckSum; +#else + Assert( 0 ); + return 0; +#endif +} + +#define STARTEND_TIMEGAP 0.1 + +int CSentence::CountWords( char const *str ) +{ + if ( !str || !str[ 0 ] ) + return 0; + + int c = 1; + + unsigned char *p = (unsigned char *)str; + while ( *p ) + { + if ( *p <= 32 ) + { + c++; + + while ( *p && *p <= 32 ) + { + p++; + } + } + + if ( !(*p) ) + break; + + p++; + } + + return c; +} + + +//----------------------------------------------------------------------------- +// Purpose: Static method +// Input : in - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CSentence::ShouldSplitWord( char in ) +{ + if ( in <= 32 ) + return true; + + if ( in >= 128 ) + return true; + + if ( ispunct( in ) ) + { + // don't split on apostrophe + if ( in == '\'' ) + return false; + return true; + } + + return false; +} + +void CSentence::CreateEventWordDistribution( char const *pszText, float flSentenceDuration ) +{ + Assert( pszText ); + if ( !pszText ) + return; + + int wordCount = CountWords( pszText ); + if ( wordCount <= 0 ) + return; + + float wordLength = ( flSentenceDuration - 2 * STARTEND_TIMEGAP) / (float)wordCount; + float wordStart = STARTEND_TIMEGAP; + + Reset(); + + char word[ 256 ]; + unsigned char const *in = (unsigned char *)pszText; + char *out = word; + + while ( *in ) + { + if ( !ShouldSplitWord( *in ) ) + { + *out++ = *in++; + } + else + { + *out = 0; + + // Skip over splitters + while ( *in && ( ShouldSplitWord( *in ) ) ) + { + in++; + } + + if ( strlen( word ) > 0 ) + { + CWordTag *w = new CWordTag(); + Assert( w ); + w->SetWord( word ); + w->m_flStartTime = wordStart; + w->m_flEndTime = wordStart + wordLength; + + AddWordTag( w ); + + wordStart += wordLength; + } + + out = word; + } + } + + *out = 0; + + if ( strlen( word ) > 0 ) + { + CWordTag *w = new CWordTag(); + Assert( w ); + w->SetWord( word ); + w->m_flStartTime = wordStart; + w->m_flEndTime = wordStart + wordLength; + + AddWordTag( w ); + + wordStart += wordLength; + } +} + + +#endif // !_STATIC_LINKED || _SHARED_LIB \ No newline at end of file diff --git a/sp/src/public/sentence.h b/sp/src/public/sentence.h new file mode 100644 index 00000000..de0f8d9a --- /dev/null +++ b/sp/src/public/sentence.h @@ -0,0 +1,302 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef SENTENCE_H +#define SENTENCE_H +#ifdef _WIN32 +#pragma once +#endif + +// X360 optimizes out the extra memory needed by the editors in these types +#ifndef _X360 +#define PHONEME_EDITOR 1 +#endif + +#include "utlvector.h" + +class CUtlBuffer; + +#define CACHED_SENTENCE_VERSION 1 +#define CACHED_SENTENCE_VERSION_ALIGNED 4 + +//----------------------------------------------------------------------------- +// Purpose: A sample point +//----------------------------------------------------------------------------- +// Can't do this due to backward compat issues +//#ifdef _WIN32 +//#pragma pack (1) +//#endif + +struct CEmphasisSample +{ + float time; + float value; + + void SetSelected( bool isSelected ); +#if PHONEME_EDITOR + // Used by editors only + bool selected; +#endif +}; + +class CBasePhonemeTag +{ +public: + CBasePhonemeTag(); + CBasePhonemeTag( const CBasePhonemeTag& from ); + + CBasePhonemeTag &operator=( const CBasePhonemeTag &from ) { memcpy( this, &from, sizeof(*this) ); return *this; } + + float GetStartTime() const { return m_flStartTime; } + void SetStartTime( float startTime ) { m_flStartTime = startTime; } + void AddStartTime( float startTime ) { m_flStartTime += startTime; } + + float GetEndTime() const { return m_flEndTime; } + void SetEndTime( float endTime ) { m_flEndTime = endTime; } + void AddEndTime( float startTime ) { m_flEndTime += startTime; } + + int GetPhonemeCode() const { return m_nPhonemeCode; } + void SetPhonemeCode( int phonemeCode ) { m_nPhonemeCode = phonemeCode; } + +private: + float m_flStartTime; + float m_flEndTime; + unsigned short m_nPhonemeCode; +}; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CPhonemeTag : public CBasePhonemeTag +{ + typedef CBasePhonemeTag BaseClass; +public: + + CPhonemeTag( void ); + CPhonemeTag( const char *phoneme ); + CPhonemeTag( const CPhonemeTag& from ); + ~CPhonemeTag( void ); + + void SetTag( const char *phoneme ); + char const *GetTag() const; + + unsigned int ComputeDataCheckSum(); +#if PHONEME_EDITOR + bool m_bSelected; + unsigned int m_uiStartByte; + unsigned int m_uiEndByte; +#endif + void SetSelected( bool isSelected ); + bool GetSelected() const; + void SetStartAndEndBytes( unsigned int start, unsigned int end ); + unsigned int GetStartByte() const; + unsigned int GetEndByte() const; + +private: + char *m_szPhoneme; + +}; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CWordTag +{ +public: + CWordTag( void ); + CWordTag( const char *word ); + CWordTag( const CWordTag& from ); + ~CWordTag( void ); + + void SetWord( const char *word ); + const char *GetWord() const; + + int IndexOfPhoneme( CPhonemeTag *tag ); + + unsigned int ComputeDataCheckSum(); + + float m_flStartTime; + float m_flEndTime; + + CUtlVector < CPhonemeTag *> m_Phonemes; +#if PHONEME_EDITOR + bool m_bSelected; + unsigned int m_uiStartByte; + unsigned int m_uiEndByte; +#endif + void SetSelected( bool isSelected ); + bool GetSelected() const; + void SetStartAndEndBytes( unsigned int start, unsigned int end ); + unsigned int GetStartByte() const; + unsigned int GetEndByte() const; + +private: + char *m_pszWord; +}; + +// A sentence can be closed captioned +// The default case is the entire sentence shown at start time +// +// "The default case" +// "is the entire sentence shown at start time" + +// Commands that aren't closed at end of phrase are automatically terminated +// +// Commands +// The line should persist for 2.0 seconds beyond m_flEndTime +// Don't go to new line for next phrase on stack +// Push current color onto stack and start drawing with new +// color until we reach the next marker or a with no commands which +// means restore the previous color +// Underline text (start/end) +// Italics text (start/end) +// Bold text (start/end) +// Draw caption at special location ??? needed +// Go to new line + +// Close Captioning Support +// The phonemes drive the mouth in english, but the CC text can +// be one of several languages +enum +{ + CC_ENGLISH = 0, + CC_FRENCH, + CC_GERMAN, + CC_ITALIAN, + CC_KOREAN, + CC_SCHINESE, // Simplified Chinese + CC_SPANISH, + CC_TCHINESE, // Traditional Chinese + CC_JAPANESE, + CC_RUSSIAN, + CC_THAI, + CC_PORTUGUESE, + // etc etc + + CC_NUM_LANGUAGES +}; + +//----------------------------------------------------------------------------- +// Purpose: A sentence is a box of words, and words contain phonemes +//----------------------------------------------------------------------------- +class CSentence +{ +public: + static char const *NameForLanguage( int language ); + static int LanguageForName( char const *name ); + static void ColorForLanguage( int language, unsigned char& r, unsigned char& g, unsigned char& b ); + + // Construction + CSentence( void ); + ~CSentence( void ); + + // Assignment operator + CSentence& operator =(const CSentence& src ); + + void Append( float starttime, const CSentence& src ); + + void SetText( const char *text ); + const char *GetText( void ) const; + + void InitFromDataChunk( void *data, int size ); + void InitFromBuffer( CUtlBuffer& buf ); + void SaveToBuffer( CUtlBuffer& buf ); + + // This strips out all of the stuff used by the editor, leaving just one blank work, no sentence text, and just + // the phonemes without the phoneme text...(same as the cacherestore version below) + void MakeRuntimeOnly(); + + // This is a compressed save of just the data needed to drive phonemes in the engine (no word / sentence text, etc ) + void CacheSaveToBuffer( CUtlBuffer& buf, int version ); + void CacheRestoreFromBuffer( CUtlBuffer& buf ); + + // Add word/phoneme to sentence + void AddPhonemeTag( CWordTag *word, CPhonemeTag *tag ); + void AddWordTag( CWordTag *tag ); + + void Reset( void ); + + void ResetToBase( void ); + + void MarkNewPhraseBase( void ); + + int GetWordBase( void ); + + int CountPhonemes( void ); + + // For legacy loading, try to find a word that contains the time + CWordTag *EstimateBestWord( float time ); + + CWordTag *GetWordForPhoneme( CPhonemeTag *phoneme ); + + void SetTextFromWords( void ); + + float GetIntensity( float time, float endtime ); + void Resort( void ); + CEmphasisSample *GetBoundedSample( int number, float endtime ); + int GetNumSamples( void ); + CEmphasisSample *GetSample( int index ); + + // Compute start and endtime based on all words + void GetEstimatedTimes( float& start, float &end ); + + void SetVoiceDuck( bool shouldDuck ) { m_bShouldVoiceDuck = shouldDuck; } + bool GetVoiceDuck() const { return m_bShouldVoiceDuck; } + + unsigned int ComputeDataCheckSum(); + + void SetDataCheckSum( unsigned int chk ); + unsigned int GetDataCheckSum() const; + + int GetRuntimePhonemeCount() const; + const CBasePhonemeTag *GetRuntimePhoneme( int i ) const; + void ClearRuntimePhonemes(); + void AddRuntimePhoneme( const CPhonemeTag *src ); + + void CreateEventWordDistribution( char const *pszText, float flSentenceDuration ); + static int CountWords( char const *pszText ); + static bool ShouldSplitWord( char in ); + +public: +#if PHONEME_EDITOR + char *m_szText; + + CUtlVector< CWordTag * > m_Words; +#endif + CUtlVector < CBasePhonemeTag *> m_RunTimePhonemes; + +#if PHONEME_EDITOR + int m_nResetWordBase; +#endif + // Phoneme emphasis data + CUtlVector< CEmphasisSample > m_EmphasisSamples; + +#if PHONEME_EDITOR + unsigned int m_uCheckSum; +#endif + bool m_bIsValid : 8; + bool m_bStoreCheckSum : 8; + bool m_bShouldVoiceDuck : 8; + bool m_bIsCached : 8; + +private: + void ParseDataVersionOnePointZero( CUtlBuffer& buf ); + void ParsePlaintext( CUtlBuffer& buf ); + void ParseWords( CUtlBuffer& buf ); + void ParseEmphasis( CUtlBuffer& buf ); + void ParseOptions( CUtlBuffer& buf ); + void ParseCloseCaption( CUtlBuffer& buf ); + + void ResetCloseCaptionAll( void ); + + friend class PhonemeEditor; +}; + +//#ifdef _WIN32 +//#pragma pack () +//#endif + +#endif // SENTENCE_H diff --git a/sp/src/public/server_class.cpp b/sp/src/public/server_class.cpp new file mode 100644 index 00000000..5932f5b9 --- /dev/null +++ b/sp/src/public/server_class.cpp @@ -0,0 +1,16 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "server_class.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +ServerClass *g_pServerClassHead=0; + + diff --git a/sp/src/public/server_class.h b/sp/src/public/server_class.h new file mode 100644 index 00000000..ac961361 --- /dev/null +++ b/sp/src/public/server_class.h @@ -0,0 +1,146 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#ifndef SERVER_CLASS_H +#define SERVER_CLASS_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "tier0/dbg.h" +#include "dt_send.h" +#include "networkstringtabledefs.h" + + +class ServerClass; +class SendTable; + +extern ServerClass *g_pServerClassHead; + + +class ServerClass +{ +public: + ServerClass( const char *pNetworkName, SendTable *pTable ) + { + m_pNetworkName = pNetworkName; + m_pTable = pTable; + m_InstanceBaselineIndex = INVALID_STRING_INDEX; + // g_pServerClassHead is sorted alphabetically, so find the correct place to insert + if ( !g_pServerClassHead ) + { + g_pServerClassHead = this; + m_pNext = NULL; + } + else + { + ServerClass *p1 = g_pServerClassHead; + ServerClass *p2 = p1->m_pNext; + + // use _stricmp because Q_stricmp isn't hooked up properly yet + if ( _stricmp( p1->GetName(), pNetworkName ) > 0) + { + m_pNext = g_pServerClassHead; + g_pServerClassHead = this; + p1 = NULL; + } + + while( p1 ) + { + if ( p2 == NULL || _stricmp( p2->GetName(), pNetworkName ) > 0) + { + m_pNext = p2; + p1->m_pNext = this; + break; + } + p1 = p2; + p2 = p2->m_pNext; + } + } + } + + const char* GetName() { return m_pNetworkName; } + + +public: + const char *m_pNetworkName; + SendTable *m_pTable; + ServerClass *m_pNext; + int m_ClassID; // Managed by the engine. + + // This is an index into the network string table (sv.GetInstanceBaselineTable()). + int m_InstanceBaselineIndex; // INVALID_STRING_INDEX if not initialized yet. +}; + + +class CBaseNetworkable; + +// If you do a DECLARE_SERVERCLASS, you need to do this inside the class definition. +#define DECLARE_SERVERCLASS() \ + public: \ + virtual ServerClass* GetServerClass(); \ + static SendTable *m_pClassSendTable; \ + template friend int ServerClassInit(T *); \ + virtual int YouForgotToImplementOrDeclareServerClass(); \ + +#define DECLARE_SERVERCLASS_NOBASE() \ + public: \ + template friend int ServerClassInit(T *); \ + +// Use this macro to expose your class's data across the network. +#define IMPLEMENT_SERVERCLASS( DLLClassName, sendTable ) \ + IMPLEMENT_SERVERCLASS_INTERNAL( DLLClassName, sendTable ) + +// You can use this instead of BEGIN_SEND_TABLE and it will do a DECLARE_SERVERCLASS automatically. +#define IMPLEMENT_SERVERCLASS_ST(DLLClassName, sendTable) \ + IMPLEMENT_SERVERCLASS_INTERNAL( DLLClassName, sendTable )\ + BEGIN_SEND_TABLE(DLLClassName, sendTable) + +#define IMPLEMENT_SERVERCLASS_ST_NOBASE(DLLClassName, sendTable) \ + IMPLEMENT_SERVERCLASS_INTERNAL( DLLClassName, sendTable )\ + BEGIN_SEND_TABLE_NOBASE( DLLClassName, sendTable ) + + +#ifdef VALIDATE_DECLARE_CLASS + #define CHECK_DECLARE_CLASS( DLLClassName, sendTable ) \ + template int CheckDeclareClass_Access(T *); \ + template <> int CheckDeclareClass_Access(sendTable::ignored *, const char *pIgnored) \ + { \ + return DLLClassName::CheckDeclareClass( #DLLClassName ); \ + } \ + namespace sendTable \ + { \ + int verifyDeclareClass = CheckDeclareClass_Access( (sendTable::ignored*)0 ); \ + } +#else + #define CHECK_DECLARE_CLASS( DLLClassName, sendTable ) +#endif + + +#define IMPLEMENT_SERVERCLASS_INTERNAL( DLLClassName, sendTable ) \ + namespace sendTable \ + { \ + struct ignored; \ + extern SendTable g_SendTable; \ + } \ + CHECK_DECLARE_CLASS( DLLClassName, sendTable ) \ + static ServerClass g_##DLLClassName##_ClassReg(\ + #DLLClassName, \ + &sendTable::g_SendTable\ + ); \ + \ + ServerClass* DLLClassName::GetServerClass() {return &g_##DLLClassName##_ClassReg;} \ + SendTable *DLLClassName::m_pClassSendTable = &sendTable::g_SendTable;\ + int DLLClassName::YouForgotToImplementOrDeclareServerClass() {return 0;} + + +#endif + + + diff --git a/sp/src/public/shake.h b/sp/src/public/shake.h new file mode 100644 index 00000000..8283d8d1 --- /dev/null +++ b/sp/src/public/shake.h @@ -0,0 +1,63 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Network data for screen shake and screen fade. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef SHAKE_H +#define SHAKE_H +#ifdef _WIN32 +#pragma once +#endif + + +// +// Commands for the screen shake effect. +// + +struct ScreenShake_t +{ + int command; + float amplitude; + float frequency; + float duration; +}; + +enum ShakeCommand_t +{ + SHAKE_START = 0, // Starts the screen shake for all players within the radius. + SHAKE_STOP, // Stops the screen shake for all players within the radius. + SHAKE_AMPLITUDE, // Modifies the amplitude of an active screen shake for all players within the radius. + SHAKE_FREQUENCY, // Modifies the frequency of an active screen shake for all players within the radius. + SHAKE_START_RUMBLEONLY, // Starts a shake effect that only rumbles the controller, no screen effect. + SHAKE_START_NORUMBLE, // Starts a shake that does NOT rumble the controller. +}; + + +// +// Screen shake message. +// +extern int gmsgShake; + +// Fade in/out +extern int gmsgFade; + +#define FFADE_IN 0x0001 // Just here so we don't pass 0 into the function +#define FFADE_OUT 0x0002 // Fade out (not in) +#define FFADE_MODULATE 0x0004 // Modulate (don't blend) +#define FFADE_STAYOUT 0x0008 // ignores the duration, stays faded out until new ScreenFade message received +#define FFADE_PURGE 0x0010 // Purges all other fades, replacing them with this one + +#define SCREENFADE_FRACBITS 9 // which leaves 16-this for the integer part +// This structure is sent over the net to describe a screen fade event +struct ScreenFade_t +{ + unsigned short duration; // FIXED 16 bit, with SCREENFADE_FRACBITS fractional, seconds duration + unsigned short holdTime; // FIXED 16 bit, with SCREENFADE_FRACBITS fractional, seconds duration until reset (fade & hold) + short fadeFlags; // flags + byte r, g, b, a; // fade to color ( max alpha ) +}; + + +#endif // SHAKE_H diff --git a/sp/src/public/shattersurfacetypes.h b/sp/src/public/shattersurfacetypes.h new file mode 100644 index 00000000..eb5c55b3 --- /dev/null +++ b/sp/src/public/shattersurfacetypes.h @@ -0,0 +1,21 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#if !defined ( SHATTERSURFACETYPES_H ) +#define SHATTERSURFACETYPES_H +#ifdef _WIN32 +#pragma once +#endif + +enum ShatterSurface_t +{ + // Note: This much match with the client entity + SHATTERSURFACE_GLASS = 0, + SHATTERSURFACE_TILE = 1, +}; + +#endif diff --git a/sp/src/public/simple_physics.cpp b/sp/src/public/simple_physics.cpp new file mode 100644 index 00000000..0d1eed39 --- /dev/null +++ b/sp/src/public/simple_physics.cpp @@ -0,0 +1,72 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "simple_physics.h" +#include "tier0/dbg.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +CSimplePhysics::CSimplePhysics() +{ + Init( 1.0f / 30.0f ); // default is 30 steps per second +} + + +void CSimplePhysics::Init( float flTimeStep ) +{ + m_flPredictedTime = 0; + m_iCurTimeStep = 0; + m_flTimeStep = flTimeStep; + m_flTimeStepMul = m_flTimeStep*m_flTimeStep*0.5f; +} + + +void CSimplePhysics::Simulate( + CSimplePhysics::CNode *pNodes, + int nNodes, + CSimplePhysics::IHelper *pHelper, + float dt, + float flDamp ) +{ + // Figure out how many time steps to run. + m_flPredictedTime += dt; + int newTimeStep = (int)ceil( m_flPredictedTime / m_flTimeStep ); + int nTimeSteps = newTimeStep - m_iCurTimeStep; + for( int iTimeStep=0; iTimeStep < nTimeSteps; iTimeStep++ ) + { + // Simulate everything.. + for( int iNode=0; iNode < nNodes; iNode++ ) + { + CSimplePhysics::CNode *pNode = &pNodes[iNode]; + + // Apply forces. + Vector vAccel; + pHelper->GetNodeForces( pNodes, iNode, &vAccel ); + Assert( vAccel.IsValid() ); + + Vector vPrevPos = pNode->m_vPos; + pNode->m_vPos = pNode->m_vPos + (pNode->m_vPos - pNode->m_vPrevPos) * flDamp + vAccel * m_flTimeStepMul; + pNode->m_vPrevPos = vPrevPos; + } + + // Apply constraints. + pHelper->ApplyConstraints( pNodes, nNodes ); + } + m_iCurTimeStep = newTimeStep; + + // Setup predicted positions. + float flInterpolant = (m_flPredictedTime - (GetCurTime() - m_flTimeStep)) / m_flTimeStep; + for( int iNode=0; iNode < nNodes; iNode++ ) + { + CSimplePhysics::CNode *pNode = &pNodes[iNode]; + VectorLerp( pNode->m_vPrevPos, pNode->m_vPos, flInterpolant, pNode->m_vPredicted ); + } +} + + diff --git a/sp/src/public/simple_physics.h b/sp/src/public/simple_physics.h new file mode 100644 index 00000000..fd40b18f --- /dev/null +++ b/sp/src/public/simple_physics.h @@ -0,0 +1,81 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef SIMPLE_PHYSICS_H +#define SIMPLE_PHYSICS_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "mathlib/vector.h" + + +// CSimplePhysics is a framework for simplified physics simulation. +// It simulates at a fixed timestep and uses the Verlet integrator. +// +// To use it, create your nodes and implement your constraints and +// forces in an IHelper, then call Simulate each frame. +// CSimplePhysics will figure out how many timesteps to run and will +// provide predicted positions of things for you. +class CSimplePhysics +{ +public: + + class CNode + { + public: + + // Call this when initializing the nodes with their starting positions. + void Init( const Vector &vPos ) + { + m_vPos = m_vPrevPos = m_vPredicted = vPos; + } + + Vector m_vPos; // At time t + Vector m_vPrevPos; // At time t - m_flTimeStep + Vector m_vPredicted; // Predicted position + }; + + class IHelper + { + public: + virtual void GetNodeForces( CNode *pNodes, int iNode, Vector *pAccel ) = 0; + virtual void ApplyConstraints( CNode *pNodes, int nNodes ) = 0; + }; + + +public: + + CSimplePhysics(); + + void Init( float flTimeStep ); + + void Simulate( + CNode *pNodes, + int nNodes, + IHelper *pHelper, + float dt, + float flDamp ); + + +private: + + double GetCurTime() { return m_flTimeStep * m_iCurTimeStep; } + + +private: + + double m_flPredictedTime; // (GetCurTime()-m_flTimeStep) <= m_flPredictedTime <= GetCurTime() + int m_iCurTimeStep; + + float m_flTimeStep; + float m_flTimeStepMul; // dt*dt*0.5 +}; + + +#endif // SIMPLE_PHYSICS_H diff --git a/sp/src/public/smooth_average.h b/sp/src/public/smooth_average.h new file mode 100644 index 00000000..25f694b9 --- /dev/null +++ b/sp/src/public/smooth_average.h @@ -0,0 +1,222 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef SMOOTH_AVERAGE_H +#define SMOOTH_AVERAGE_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "utldict.h" + + + +// Use this macro around any value, and it'll queue up the results given to it nTimes and +// provide a running average. +#define SMOOTH_AVERAGE( value, nCount ) CalcSmoothAverage( value, nCount, __FILE__, __LINE__ ) + + +// Same as their counterpart functions but they return more info in a CTimingInfo structure. +#define SMOOTH_AVERAGE_STRUCT( value, nCount ) CalcSmoothAverage_Struct( value, nCount, __FILE__, __LINE__ ) +#define SUM_OVER_TIME_INTERVAL_STRUCT( value, nSeconds ) SumOverTimeInterval_Struct( value, nSeconds, __FILE__, __LINE__ ) + + +template< class T > +class CTimingInfo +{ +public: + T m_AverageValue; // Note: this will be the SUM of the values if using SUM_OVER_TIME_INTERVAL. + + // The high and low points for m_AverageValue over the time interval. + T m_HighAverage; + T m_LowAverage; + + // The high and low points for the value itself over the time interval. + T m_HighValue; + T m_LowValue; +}; + + +template< class T > +class CAveragesInfo +{ +public: + class CEntry + { + public: + T m_Average; + T m_Value; + }; + +public: + CUtlVector< CEntry > m_Values; + int m_iCurValue; +}; + + +template< class T > +class CAveragesInfo_TimeBased +{ +public: + class CEntry + { + public: + CCycleCount m_Time; // When this sample was taken. + T m_Value; + T m_Average; + }; + + CUtlVector m_Values; +}; + + +#if 0 +template< class T > +inline CTimingInfo< T > CalcSmoothAverage_Struct( const T &value, int nTimes, const char *pFilename, int iLine ) +{ + // Find an entry at this file and line. + char fullStr[1024]; + Q_snprintf( fullStr, sizeof( fullStr ), "%s_%i", pFilename, iLine ); + + int index = s_SmoothAverages.Find( fullStr ); + CAveragesInfo *pInfo; + if ( index == s_SmoothAverages.InvalidIndex() ) + { + pInfo = new CAveragesInfo; + index = s_SmoothAverages.Insert( fullStr, pInfo ); + } + else + { + pInfo = (CAveragesInfo*)s_SmoothAverages[index]; + } + + // Add the new value. + int newValueIndex; + CAveragesInfo< T >::CEntry entry; + entry.m_Value = value; + if ( pInfo->m_Values.Count() < nTimes ) + { + newValueIndex = pInfo->m_Values.AddToTail( entry ); + pInfo->m_iCurValue = 0; + } + else + { + newValueIndex = pInfo->m_iCurValue; + pInfo->m_Values[pInfo->m_iCurValue] = entry; + pInfo->m_iCurValue = (pInfo->m_iCurValue+1) % pInfo->m_Values.Count(); + } + + CTimingInfo< T > info; + info.m_AverageValue = pInfo->m_Values[0].m_Value; + + info.m_HighAverage = pInfo->m_Values[0].m_Average; + info.m_LowAverage = pInfo->m_Values[0].m_Average; + + info.m_HighValue = pInfo->m_Values[0].m_Value; + info.m_LowValue = pInfo->m_Values[0].m_Value; + + for ( int i=1; i < pInfo->m_Values.Count(); i++ ) + { + if ( i != newValueIndex ) + { + info.m_HighAverage = max( pInfo->m_Values[i].m_Average, info.m_HighAverage ); + info.m_LowAverage = min( pInfo->m_Values[i].m_Average, info.m_LowAverage ); + } + + info.m_HighValue = max( pInfo->m_Values[i].m_Value, info.m_HighValue ); + info.m_LowValue = min( pInfo->m_Values[i].m_Value, info.m_LowValue ); + + info.m_AverageValue += pInfo->m_Values[i].m_Value; + } + + info.m_AverageValue /= pInfo->m_Values.Count(); + pInfo->m_Values[newValueIndex].m_Average = info.m_AverageValue; + return info; +} +#endif + +template< class T > +inline T CalcSmoothAverage( const T &value, int nTimes, const char *pFilename, int iLine ) +{ + CTimingInfo< T > info = CalcSmoothAverage_Struct( value, nTimes, pFilename, iLine ); + return info.m_AverageValue; +}; + + +template< class T > +inline CTimingInfo< T > SumOverTimeInterval_Struct( const T &value, float nSeconds, const char *pFilename, int iLine ) +{ + static CUtlDict< CAveragesInfo_TimeBased< T >*, int > s_SmoothAverages; + + char fullStr[1024]; + Q_snprintf( fullStr, sizeof( fullStr ), "%s_%i", pFilename, iLine ); + + int index = s_SmoothAverages.Find( fullStr ); + CAveragesInfo_TimeBased *pInfo; + if ( index == s_SmoothAverages.InvalidIndex() ) + { + pInfo = new CAveragesInfo_TimeBased; + index = s_SmoothAverages.Insert( fullStr, pInfo ); + } + else + { + pInfo = s_SmoothAverages[index]; + } + + // Get the current time now. + CCycleCount curTime; + curTime.Sample(); + + // Get rid of old samples. + while ( pInfo->m_Values.Count() > 0 && (curTime.GetSeconds() - pInfo->m_Values[0].m_Time.GetSeconds()) > nSeconds ) + pInfo->m_Values.Remove( 0 ); + + // Add on the new sample. + typename CAveragesInfo_TimeBased< T >::CEntry newEntry; + newEntry.m_Time = curTime; + newEntry.m_Value = value; + int newValueIndex = pInfo->m_Values.AddToTail( newEntry ); + + CTimingInfo< T > info; + info.m_AverageValue = pInfo->m_Values[0].m_Value; + + info.m_HighAverage = pInfo->m_Values[0].m_Average; + info.m_LowAverage = pInfo->m_Values[0].m_Average; + + info.m_HighValue = pInfo->m_Values[0].m_Value; + info.m_LowValue = pInfo->m_Values[0].m_Value; + + for ( int i=1; i < pInfo->m_Values.Count(); i++ ) + { + if ( i != newValueIndex ) + { + info.m_HighAverage = max( pInfo->m_Values[i].m_Average, info.m_HighAverage ); + info.m_LowAverage = min( pInfo->m_Values[i].m_Average, info.m_LowAverage ); + } + + info.m_HighValue = max( pInfo->m_Values[i].m_Value, info.m_HighValue ); + info.m_LowValue = min( pInfo->m_Values[i].m_Value, info.m_LowValue ); + + info.m_AverageValue += pInfo->m_Values[i].m_Value; + } + + info.m_AverageValue /= pInfo->m_Values.Count(); + pInfo->m_Values[newValueIndex].m_Average = info.m_AverageValue; + return info; +} + + +template< class T > +inline CTimingInfo< T > SumOverTimeInterval( const T &value, float nSeconds, const char *pFilename, int iLine ) +{ + CTimingInfo< T > info = SumOverTimeInterval_Struct( value, nSeconds, pFilename, iLine ); + return info.m_AverageValue; +} + + +#endif // SMOOTH_AVERAGE_H + diff --git a/sp/src/public/soundchars.h b/sp/src/public/soundchars.h new file mode 100644 index 00000000..cca7779e --- /dev/null +++ b/sp/src/public/soundchars.h @@ -0,0 +1,68 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef SOUNDCHARS_H +#define SOUNDCHARS_H +#ifdef _WIN32 +#pragma once +#endif + +#define CHAR_STREAM '*' // as one of 1st 2 chars in name, indicates streaming wav data +#define CHAR_USERVOX '?' // as one of 1st 2 chars in name, indicates user realtime voice data +#define CHAR_SENTENCE '!' // as one of 1st 2 chars in name, indicates sentence wav +#define CHAR_DRYMIX '#' // as one of 1st 2 chars in name, indicates wav bypasses dsp fx +#define CHAR_DOPPLER '>' // as one of 1st 2 chars in name, indicates doppler encoded stereo wav: left wav (incomming) and right wav (outgoing). +#define CHAR_DIRECTIONAL '<' // as one of 1st 2 chars in name, indicates stereo wav has direction cone: mix left wav (front facing) with right wav (rear facing) based on soundfacing direction +#define CHAR_DISTVARIANT '^' // as one of 1st 2 chars in name, indicates distance variant encoded stereo wav (left is close, right is far) +#define CHAR_OMNI '@' // as one of 1st 2 chars in name, indicates non-directional wav (default mono or stereo) +#define CHAR_SPATIALSTEREO ')' // as one of 1st 2 chars in name, indicates spatialized stereo wav +#define CHAR_FAST_PITCH '}' // as one of 1st 2 chars in name, forces low quality, non-interpolated pitch shift + +inline bool IsSoundChar(char c) +{ + bool b; + + b = (c == CHAR_STREAM || c == CHAR_USERVOX || c == CHAR_SENTENCE || c == CHAR_DRYMIX || c == CHAR_OMNI ); + b = b || (c == CHAR_DOPPLER || c == CHAR_DIRECTIONAL || c == CHAR_DISTVARIANT || c == CHAR_SPATIALSTEREO || c == CHAR_FAST_PITCH ); + + return b; +} + +// return pointer to first valid character in file name +// by skipping over CHAR_STREAM...CHAR_DRYMIX + +inline char *PSkipSoundChars(const char *pch) +{ + char *pcht = (char *)pch; + + while ( 1 ) + { + if (!IsSoundChar(*pcht)) + break; + pcht++; + } + + return pcht; +} + + +inline bool TestSoundChar(const char *pch, char c) +{ + char *pcht = (char *)pch; + + while ( 1 ) + { + if (!IsSoundChar(*pcht)) + break; + if (*pcht == c) + return true; + pcht++; + } + + return false; +} + +#endif // SOUNDCHARS_H diff --git a/sp/src/public/soundcombiner.cpp b/sp/src/public/soundcombiner.cpp new file mode 100644 index 00000000..3445b46a --- /dev/null +++ b/sp/src/public/soundcombiner.cpp @@ -0,0 +1,823 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#include "cbase.h" +#include "isoundcombiner.h" +#include "sentence.h" +#include "filesystem.h" +#include "tier2/riff.h" +#include "tier1/utlbuffer.h" +#include "snd_audio_source.h" +#include "snd_wave_source.h" +#include "AudioWaveOutput.h" +#include "ifaceposersound.h" +#include "vstdlib/random.h" +#include "checksum_crc.h" + +#define WAVEOUTPUT_BITSPERCHANNEL 16 +#define WAVEOUTPUT_FREQUENCY 44100 + +class CSoundCombiner : public ISoundCombiner +{ +public: + CSoundCombiner() : + m_pWaveOutput( NULL ), + m_pOutRIFF( NULL ), + m_pOutIterator( NULL ) + { + m_szOutFile[ 0 ] = 0; + } + + virtual bool CombineSoundFiles( IFileSystem *filesystem, char const *outfile, CUtlVector< CombinerEntry >& info ); + virtual bool IsCombinedFileChecksumValid( IFileSystem *filesystem, char const *outfile, CUtlVector< CombinerEntry >& info ); + +private: + + struct CombinerWork + { + CombinerWork() : + sentence(), + duration( 0.0 ), + wave( 0 ), + mixer( 0 ), + entry( 0 ) + { + } + CSentence sentence; + float duration; + CAudioSource *wave; + CAudioMixer *mixer; + CombinerEntry *entry; + }; + + bool InternalCombineSoundFiles( IFileSystem *filesystem, char const *outfile, CUtlVector< CombinerEntry >& info ); + bool VerifyFilesExist( IFileSystem *filesystem, CUtlVector< CombinerEntry >& info ); + bool CreateWorkList( IFileSystem *filesystem, CUtlVector< CombinerEntry >& info ); + + bool PerformSplicingOnWorkItems( IFileSystem *filesystem ); + void CleanupWork(); + + // .wav file utils + int ComputeBestNumChannels(); + void ParseSentence( CSentence& sentence, IterateRIFF &walk ); + bool LoadSentenceFromWavFileUsingIO( char const *wavfile, CSentence& sentence, IFileReadBinary& io ); + bool LoadSentenceFromWavFile( char const *wavfile, CSentence& sentence ); + void StoreValveDataChunk( CSentence& sentence ); +// bool SaveSentenceToWavFile( char const *wavfile, CSentence& sentence ); + + bool InitSplicer( IFileSystem *filesystem, int samplerate, int numchannels, int bitspersample ); + bool LoadSpliceAudioSources(); + bool AppendSilence( int ¤tsample, float duration ); + bool AppendStereo16Data( short samples[ 2 ] ); + bool AppendWaveData( int& currentsample, CAudioSource *wave, CAudioMixer *mixer ); + void AddSentenceToCombined( float offset, CSentence& sentence ); + + unsigned int CheckSumWork( IFileSystem *filesystem, CUtlVector< CombinerEntry >& info ); + unsigned int ComputeChecksum(); + + CUtlVector< CombinerWork * > m_Work; + CSentence m_Combined; + + CAudioWaveOutput *m_pWaveOutput; + + OutFileRIFF *m_pOutRIFF; + IterateOutputRIFF *m_pOutIterator; + + int m_nSampleRate; + int m_nNumChannels; + int m_nBitsPerSample; + int m_nBytesPerSample; + char m_szOutFile[ MAX_PATH ]; +}; + +static CSoundCombiner g_SoundCombiner; +ISoundCombiner *soundcombiner = &g_SoundCombiner; + +bool CSoundCombiner::CreateWorkList( IFileSystem *filesystem, CUtlVector< CombinerEntry >& info ) +{ + m_Work.RemoveAll(); + + int c = info.Count(); + for ( int i = 0; i < c; ++i ) + { + CombinerWork *workitem = new CombinerWork(); + + char fullpath[ MAX_PATH ]; + Q_strncpy( fullpath, info[ i ].wavefile, sizeof( fullpath ) ); + filesystem->GetLocalPath( info[ i ].wavefile, fullpath, sizeof( fullpath ) ); + + if ( !LoadSentenceFromWavFile( fullpath, workitem->sentence ) ) + { + Warning( "CSoundCombiner::CreateWorkList couldn't load %s for work item (%d)\n", + fullpath, i ); + return false; + } + + workitem->entry = &info[ i ]; + + m_Work.AddToTail( workitem ); + } + + return true; +} + +void CSoundCombiner::CleanupWork() +{ + int c = m_Work.Count(); + for ( int i = 0; i < c; ++i ) + { + CombinerWork *workitem = m_Work[ i ]; + delete workitem->mixer; + delete workitem->wave; + + delete m_Work[ i ]; + } + m_Work.RemoveAll(); + + delete m_pOutIterator; + m_pOutIterator = NULL; + + delete m_pOutRIFF; + m_pOutRIFF = NULL; +} + +bool CSoundCombiner::InternalCombineSoundFiles( IFileSystem *filesystem, char const *outfile, CUtlVector< CombinerEntry >& info ) +{ + Q_strncpy( m_szOutFile, outfile, sizeof( m_szOutFile ) ); + if ( info.Count() <= 0 ) + { + Warning( "CSoundCombiner::InternalCombineSoundFiles: work item count is zero\n" ); + return false; + } + + if ( !VerifyFilesExist( filesystem, info ) ) + { + return false; + } + + if ( !CreateWorkList( filesystem, info ) ) + { + return false; + } + + PerformSplicingOnWorkItems( filesystem ); + + return true; +} + +bool CSoundCombiner::CombineSoundFiles( IFileSystem *filesystem, char const *outfile, CUtlVector< CombinerEntry >& info ) +{ + bool bret = InternalCombineSoundFiles( filesystem, outfile, info ); + CleanupWork(); + return bret; +} + +unsigned int CSoundCombiner::ComputeChecksum() +{ + CRC32_t crc; + CRC32_Init( &crc ); + + int c = m_Work.Count(); + for ( int i = 0; i < c; ++i ) + { + CombinerWork *curitem = m_Work[ i ]; + unsigned int chk = curitem->sentence.ComputeDataCheckSum(); + + // Msg( " %i -> sentence %u, startoffset %f fn %s\n", + // i, chk, curitem->entry->startoffset, curitem->entry->wavefile ); + + CRC32_ProcessBuffer( &crc, &chk, sizeof( unsigned long ) ); + CRC32_ProcessBuffer( &crc, &curitem->entry->startoffset, sizeof( float ) ); + CRC32_ProcessBuffer( &crc, curitem->entry->wavefile, Q_strlen( curitem->entry->wavefile ) ); + } + + CRC32_Final( &crc ); + return ( unsigned int )crc; +} + +unsigned int CSoundCombiner::CheckSumWork( IFileSystem *filesystem, CUtlVector< CombinerEntry >& info ) +{ + if ( info.Count() <= 0 ) + { + Warning( "CSoundCombiner::CheckSumWork: work item count is zero\n" ); + return 0; + } + + if ( !VerifyFilesExist( filesystem, info ) ) + { + return 0; + } + + if ( !CreateWorkList( filesystem, info ) ) + { + return 0; + } + + // Checkum work items + unsigned int checksum = ComputeChecksum(); + + return checksum; +} + +bool CSoundCombiner::IsCombinedFileChecksumValid( IFileSystem *filesystem, char const *outfile, CUtlVector< CombinerEntry >& info ) +{ + unsigned int computedChecksum = CheckSumWork( filesystem, info ); + + char fullpath[ MAX_PATH ]; + Q_strncpy( fullpath, outfile, sizeof( fullpath ) ); + filesystem->GetLocalPath( outfile, fullpath, sizeof( fullpath ) ); + + CSentence sentence; + + bool valid = false; + + if ( LoadSentenceFromWavFile( fullpath, sentence ) ) + { + unsigned int diskFileEmbeddedChecksum = sentence.GetDataCheckSum(); + + valid = computedChecksum == diskFileEmbeddedChecksum; + + if ( !valid ) + { + Warning( " checksum computed %u, disk %u\n", + computedChecksum, diskFileEmbeddedChecksum ); + } + } + else + { + Warning( "CSoundCombiner::IsCombinedFileChecksumValid: Unabled to load %s\n", fullpath ); + } + + CleanupWork(); + return valid; +} + +bool CSoundCombiner::VerifyFilesExist( IFileSystem *filesystem, CUtlVector< CombinerEntry >& info ) +{ + int c = info.Count(); + for ( int i = 0 ; i < c; ++i ) + { + CombinerEntry& entry = info[ i ]; + if ( !filesystem->FileExists( entry.wavefile ) ) + { + Warning( "CSoundCombiner::VerifyFilesExist: missing file %s\n", entry.wavefile ); + return false; + } + } + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Implements the RIFF i/o interface on stdio +//----------------------------------------------------------------------------- +class StdIOReadBinary : public IFileReadBinary +{ +public: + int open( const char *pFileName ) + { + return (int)filesystem->Open( pFileName, "rb" ); + } + + int read( void *pOutput, int size, int file ) + { + if ( !file ) + return 0; + + return filesystem->Read( pOutput, size, (FileHandle_t)file ); + } + + void seek( int file, int pos ) + { + if ( !file ) + return; + + filesystem->Seek( (FileHandle_t)file, pos, FILESYSTEM_SEEK_HEAD ); + } + + unsigned int tell( int file ) + { + if ( !file ) + return 0; + + return filesystem->Tell( (FileHandle_t)file ); + } + + unsigned int size( int file ) + { + if ( !file ) + return 0; + + return filesystem->Size( (FileHandle_t)file ); + } + + void close( int file ) + { + if ( !file ) + return; + + filesystem->Close( (FileHandle_t)file ); + } +}; + +class StdIOWriteBinary : public IFileWriteBinary +{ +public: + int create( const char *pFileName ) + { + return (int)filesystem->Open( pFileName, "wb" ); + } + + int write( void *pData, int size, int file ) + { + return filesystem->Write( pData, size, (FileHandle_t)file ); + } + + void close( int file ) + { + filesystem->Close( (FileHandle_t)file ); + } + + void seek( int file, int pos ) + { + filesystem->Seek( (FileHandle_t)file, pos, FILESYSTEM_SEEK_HEAD ); + } + + unsigned int tell( int file ) + { + return filesystem->Tell( (FileHandle_t)file ); + } +}; + +static StdIOReadBinary io_in; +static StdIOWriteBinary io_out; + +#define RIFF_WAVE MAKEID('W','A','V','E') +#define WAVE_FMT MAKEID('f','m','t',' ') +#define WAVE_DATA MAKEID('d','a','t','a') +#define WAVE_FACT MAKEID('f','a','c','t') +#define WAVE_CUE MAKEID('c','u','e',' ') + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &walk - +//----------------------------------------------------------------------------- +void CSoundCombiner::ParseSentence( CSentence& sentence, IterateRIFF &walk ) +{ + CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); + + buf.EnsureCapacity( walk.ChunkSize() ); + walk.ChunkRead( buf.Base() ); + buf.SeekPut( CUtlBuffer::SEEK_HEAD, walk.ChunkSize() ); + + sentence.InitFromDataChunk( buf.Base(), buf.TellPut() ); +} + +bool CSoundCombiner::LoadSentenceFromWavFileUsingIO( char const *wavfile, CSentence& sentence, IFileReadBinary& io ) +{ + sentence.Reset(); + + InFileRIFF riff( wavfile, io ); + + // UNDONE: Don't use printf to handle errors + if ( riff.RIFFName() != RIFF_WAVE ) + { + return false; + } + + // set up the iterator for the whole file (root RIFF is a chunk) + IterateRIFF walk( riff, riff.RIFFSize() ); + + // This chunk must be first as it contains the wave's format + // break out when we've parsed it + bool found = false; + while ( walk.ChunkAvailable() && !found ) + { + switch( walk.ChunkName() ) + { + case WAVE_VALVEDATA: + { + found = true; + CSoundCombiner::ParseSentence( sentence, walk ); + } + break; + } + walk.ChunkNext(); + } + + return true; +} + +bool CSoundCombiner::LoadSentenceFromWavFile( char const *wavfile, CSentence& sentence ) +{ + return CSoundCombiner::LoadSentenceFromWavFileUsingIO( wavfile, sentence, io_in ); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : store - +//----------------------------------------------------------------------------- +void CSoundCombiner::StoreValveDataChunk( CSentence& sentence ) +{ + // Buffer and dump data + CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); + + sentence.SaveToBuffer( buf ); + + // Copy into store + m_pOutIterator->ChunkWriteData( buf.Base(), buf.TellPut() ); +} + +/* +bool CSoundCombiner::SaveSentenceToWavFile( char const *wavfile, CSentence& sentence ) +{ + char tempfile[ 512 ]; + + Q_StripExtension( wavfile, tempfile, sizeof( tempfile ) ); + Q_DefaultExtension( tempfile, ".tmp", sizeof( tempfile ) ); + + if ( filesystem->FileExists( tempfile, NULL ) ) + { + filesystem->RemoveFile( tempfile, NULL ); + } + + if ( !filesystem->IsFileWritable( wavfile ) ) + { + Msg( "%s is not writable, can't save sentence data to file\n", wavfile ); + return false; + } + + // Rename original wavfile to temp + filesystem->RenameFile( wavfile, tempfile, NULL ); + + // NOTE: Put this in it's own scope so that the destructor for outfileRFF actually closes the file!!!! + { + // Read from Temp + InFileRIFF riff( tempfile, io_in ); + Assert( riff.RIFFName() == RIFF_WAVE ); + + // set up the iterator for the whole file (root RIFF is a chunk) + IterateRIFF walk( riff, riff.RIFFSize() ); + + // And put data back into original wavfile by name + OutFileRIFF riffout( wavfile, io_out ); + + IterateOutputRIFF store( riffout ); + + bool wordtrackwritten = false; + + // Walk input chunks and copy to output + while ( walk.ChunkAvailable() ) + { + m_pOutIterator->ChunkStart( walk.ChunkName() ); + + switch ( walk.ChunkName() ) + { + case WAVE_VALVEDATA: + { + // Overwrite data + CSoundCombiner::StoreValveDataChunk( sentence ); + wordtrackwritten = true; + } + break; + default: + m_pOutIterator->CopyChunkData( walk ); + break; + } + + m_pOutIterator->ChunkFinish(); + + walk.ChunkNext(); + } + + // If we didn't write it above, write it now + if ( !wordtrackwritten ) + { + m_pOutIterator->ChunkStart( WAVE_VALVEDATA ); + CSoundCombiner::StoreValveDataChunk( sentence ); + m_pOutIterator->ChunkFinish(); + } + } + + // Remove temp file + filesystem->RemoveFile( tempfile, NULL ); + + return true; +} +*/ + +typedef struct channel_s +{ + int leftvol; + int rightvol; + int rleftvol; + int rrightvol; + float pitch; +} channel_t; + +bool CSoundCombiner::InitSplicer( IFileSystem *filesystem, int samplerate, int numchannels, int bitspersample ) +{ + m_nSampleRate = samplerate; + m_nNumChannels = numchannels; + m_nBitsPerSample = bitspersample; + m_nBytesPerSample = bitspersample >> 3; + + m_pWaveOutput = ( CAudioWaveOutput * )sound->GetAudioOutput(); + if ( !m_pWaveOutput ) + { + Warning( "CSoundCombiner::InitSplicer m_pWaveOutput == NULL\n" ); + return false; + } + + // Make sure the directory exists + char basepath[ 512 ]; + Q_ExtractFilePath( m_szOutFile, basepath, sizeof( basepath ) ); + filesystem->CreateDirHierarchy( basepath, "GAME" ); + + // Create out put file + m_pOutRIFF = new OutFileRIFF( m_szOutFile, io_out ); + if ( !m_pOutRIFF ) + { + Warning( "CSoundCombiner::InitSplicer m_pOutRIFF == NULL\n" ); + return false; + } + + // Create output iterator + m_pOutIterator = new IterateOutputRIFF( *m_pOutRIFF ); + if ( !m_pOutIterator ) + { + Warning( "CSoundCombiner::InitSplicer m_pOutIterator == NULL\n" ); + return false; + } + + WAVEFORMATEX format; + format.cbSize = sizeof( format ); + + format.wFormatTag = WAVE_FORMAT_PCM; + format.nAvgBytesPerSec = m_nSampleRate * m_nNumChannels * m_nBytesPerSample; + format.nChannels = m_nNumChannels; + format.wBitsPerSample = m_nBitsPerSample; + format.nSamplesPerSec = m_nSampleRate; + format.nBlockAlign = 1; + + // Always store the format chunk first + m_pOutIterator->ChunkWrite( WAVE_FMT, &format, sizeof( format ) ); + + return true; +} + +bool CSoundCombiner::LoadSpliceAudioSources() +{ + int c = m_Work.Count(); + for ( int i = 0; i < c; ++i ) + { + CombinerWork *item = m_Work[ i ]; + + CAudioSource *wave = sound->LoadSound( item->entry->wavefile ); + if ( !wave ) + { + Warning( "CSoundCombiner::LoadSpliceAudioSources LoadSound failed '%s'\n", item->entry->wavefile ); + return false; + } + + CAudioMixer *pMixer = wave->CreateMixer(); + if ( !pMixer ) + { + Warning( "CSoundCombiner::LoadSpliceAudioSources CreateMixer failed '%s'\n", item->entry->wavefile ); + return false; + } + + item->wave = wave; + item->mixer = pMixer; + item->duration = wave->GetRunningLength(); + } + + return true; +} + +bool CSoundCombiner::AppendSilence( int ¤tsample, float duration ) +{ + int numSamples = duration * m_nSampleRate; + +#define MOTION_RANGE 150 +#define MOTION_MAXSTEP 20 + int currentValue = 32767; + int maxValue = currentValue + ( MOTION_RANGE / 2 ); + int minValue = currentValue - ( MOTION_RANGE / 2 ); + + short samples[ 2 ]; + + while ( --numSamples >= 0 ) + { + currentValue += random->RandomInt( -MOTION_MAXSTEP, MOTION_MAXSTEP ); + currentValue = min( maxValue, currentValue ); + currentValue = max( minValue, currentValue ); + + // Downsample to 0 65556 range + short s = (float)currentValue / 32768.0f; + + samples[ 0 ] = s; + samples[ 1 ] = s; + + AppendStereo16Data( samples ); + } + + return true; +} + +bool CSoundCombiner::AppendStereo16Data( short samples[ 2 ] ) +{ +// Convert from 16 bit, 2 channels to output size + if ( m_nNumChannels == 1 ) + { + if ( m_nBytesPerSample == 1 ) + { + // Convert to 8 bit mono + // left + right (2 channels ) * 16 bits + float s1 = (float)( samples[ 0 ] >> 8 ); + float s2 = (float)( samples[ 1 ] >> 8 ); + + float avg = ( s1 + s2 ) * 0.5f; + avg = clamp( avg, -127.0f, 127.0f ); + byte chopped = (byte)( avg+ 127 ); + + m_pOutIterator->ChunkWriteData( &chopped, sizeof( byte ) ); + } + else if ( m_nBytesPerSample == 2 ) + { + // Conver to 16 bit mono + float s1 = (float)( samples[ 0 ] ); + float s2 = (float)( samples[ 1 ] ); + + float avg = ( s1 + s2 ) * 0.5f; + unsigned short chopped = (unsigned short)( avg ); + + m_pOutIterator->ChunkWriteData( &chopped, sizeof( unsigned short ) ); + } + else + { + Assert( 0 ); + return false; + } + } + else if ( m_nNumChannels == 2 ) + { + if ( m_nBytesPerSample == 1 ) + { + // Convert to 8 bit stereo + // left + right (2 channels ) * 16 bits + float s1 = (float)( samples[ 0 ] >> 8 ); + float s2 = (float)( samples[ 1 ] >> 8 ); + + s1 = clamp( s1, -127.0f, 127.0f ); + s2 = clamp( s2, -127.0f, 127.0f ); + + byte chopped1 = (byte)( s1 + 127.0f ); + byte chopped2 = (byte)( s2 + 127.0f ); + + m_pOutIterator->ChunkWriteData( &chopped1, sizeof( byte ) ); + m_pOutIterator->ChunkWriteData( &chopped2, sizeof( byte ) ); + } + else if ( m_nBytesPerSample == 2 ) + { + // Leave as 16 bit stereo + // Directly store values + m_pOutIterator->ChunkWriteData( &samples[ 0 ], sizeof( unsigned short ) ); + m_pOutIterator->ChunkWriteData( &samples[ 1 ], sizeof( unsigned short ) ); + } + else + { + Assert( 0 ); + return false; + } + } + else + { + Assert( 0 ); + return false; + } + + return true; +} + +bool CSoundCombiner::AppendWaveData( int& currentsample, CAudioSource *wave, CAudioMixer *mixer ) +{ + // need a bit of space + short samples[ 2 ]; + channel_t channel; + memset( &channel, 0, sizeof( channel ) ); + channel.leftvol = 255; + channel.rightvol = 255; + channel.pitch = 1.0; + + while ( 1 ) + { + m_pWaveOutput->m_audioDevice.MixBegin(); + + if ( !mixer->MixDataToDevice( &m_pWaveOutput->m_audioDevice, &channel, currentsample, 1, wave->SampleRate(), true ) ) + break; + + m_pWaveOutput->m_audioDevice.TransferBufferStereo16( samples, 1 ); + + currentsample = mixer->GetSamplePosition(); + + AppendStereo16Data( samples ); + } + + return true; +} + +int CSoundCombiner::ComputeBestNumChannels() +{ + // We prefer mono output unless one of the source wav files is stereo, then we'll do stereo output + int c = m_Work.Count(); + for ( int i = 0; i < c; ++i ) + { + CombinerWork *curitem = m_Work[ i ]; + + if ( curitem->wave->GetNumChannels() == 2 ) + { + return 2; + } + } + return 1; +} + +bool CSoundCombiner::PerformSplicingOnWorkItems( IFileSystem *filesystem ) +{ + if ( !LoadSpliceAudioSources() ) + { + return false; + } + + int bestNumChannels = ComputeBestNumChannels(); + int bitsPerChannel = WAVEOUTPUT_BITSPERCHANNEL; + + // Pull in data and write it out + if ( !InitSplicer( filesystem, WAVEOUTPUT_FREQUENCY, bestNumChannels, bitsPerChannel ) ) + { + return false; + } + + m_pOutIterator->ChunkStart( WAVE_DATA ); + + float timeoffset = 0.0f; + + m_Combined.Reset(); + m_Combined.SetText( "" ); + + int c = m_Work.Count(); + for ( int i = 0; i < c; ++i ) + { + int currentsample = 0; + + CombinerWork *curitem = m_Work[ i ]; + CombinerWork *nextitem = NULL; + if ( i != c - 1 ) + { + nextitem = m_Work[ i + 1 ]; + } + + float duration = curitem->duration; + + AppendWaveData( currentsample, curitem->wave, curitem->mixer ); + + AddSentenceToCombined( timeoffset, curitem->sentence ); + + timeoffset += duration; + + if ( nextitem != NULL ) + { + float nextstart = nextitem->entry->startoffset; + float silence_time = nextstart - timeoffset; + + AppendSilence( currentsample, silence_time ); + + timeoffset += silence_time; + } + } + + m_pOutIterator->ChunkFinish(); + + // Checksum the work items + unsigned int checksum = ComputeChecksum(); + + // Make sure the checksum is embedded in the data file + m_Combined.SetDataCheckSum( checksum ); + + // Msg( " checksum computed %u\n", checksum ); + + m_pOutIterator->ChunkStart( WAVE_VALVEDATA ); + StoreValveDataChunk( m_Combined ); + m_pOutIterator->ChunkFinish(); + + + return true; +} + +void CSoundCombiner::AddSentenceToCombined( float offset, CSentence& sentence ) +{ + m_Combined.Append( offset, sentence ); +} diff --git a/sp/src/public/soundflags.h b/sp/src/public/soundflags.h new file mode 100644 index 00000000..71ae1192 --- /dev/null +++ b/sp/src/public/soundflags.h @@ -0,0 +1,161 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef SOUNDFLAGS_H +#define SOUNDFLAGS_H + +#if defined( _WIN32 ) +#pragma once +#endif + + +//----------------------------------------------------------------------------- +// channels +//----------------------------------------------------------------------------- +enum +{ + CHAN_REPLACE = -1, + CHAN_AUTO = 0, + CHAN_WEAPON = 1, + CHAN_VOICE = 2, + CHAN_ITEM = 3, + CHAN_BODY = 4, + CHAN_STREAM = 5, // allocate stream channel from the static or dynamic area + CHAN_STATIC = 6, // allocate channel from the static area + CHAN_VOICE2 = 7, + CHAN_VOICE_BASE = 8, // allocate channel for network voice data + CHAN_USER_BASE = (CHAN_VOICE_BASE+128) // Anything >= this number is allocated to game code. +}; + +//----------------------------------------------------------------------------- +// common volume values +//----------------------------------------------------------------------------- +#define VOL_NORM 1.0f + + +//----------------------------------------------------------------------------- +// common attenuation values +//----------------------------------------------------------------------------- +#define ATTN_NONE 0.0f +#define ATTN_NORM 0.8f +#define ATTN_IDLE 2.0f +#define ATTN_STATIC 1.25f +#define ATTN_RICOCHET 1.5f + +// HL2 world is 8x bigger now! We want to hear gunfire from farther. +// Don't change this without consulting Kelly or Wedge (sjb). +#define ATTN_GUNFIRE 0.27f + +enum soundlevel_t +{ + SNDLVL_NONE = 0, + + SNDLVL_20dB = 20, // rustling leaves + SNDLVL_25dB = 25, // whispering + SNDLVL_30dB = 30, // library + SNDLVL_35dB = 35, + SNDLVL_40dB = 40, + SNDLVL_45dB = 45, // refrigerator + + SNDLVL_50dB = 50, // 3.9 // average home + SNDLVL_55dB = 55, // 3.0 + + SNDLVL_IDLE = 60, // 2.0 + SNDLVL_60dB = 60, // 2.0 // normal conversation, clothes dryer + + SNDLVL_65dB = 65, // 1.5 // washing machine, dishwasher + SNDLVL_STATIC = 66, // 1.25 + + SNDLVL_70dB = 70, // 1.0 // car, vacuum cleaner, mixer, electric sewing machine + + SNDLVL_NORM = 75, + SNDLVL_75dB = 75, // 0.8 // busy traffic + + SNDLVL_80dB = 80, // 0.7 // mini-bike, alarm clock, noisy restaurant, office tabulator, outboard motor, passing snowmobile + SNDLVL_TALKING = 80, // 0.7 + SNDLVL_85dB = 85, // 0.6 // average factory, electric shaver + SNDLVL_90dB = 90, // 0.5 // screaming child, passing motorcycle, convertible ride on frw + SNDLVL_95dB = 95, + SNDLVL_100dB = 100, // 0.4 // subway train, diesel truck, woodworking shop, pneumatic drill, boiler shop, jackhammer + SNDLVL_105dB = 105, // helicopter, power mower + SNDLVL_110dB = 110, // snowmobile drvrs seat, inboard motorboat, sandblasting + SNDLVL_120dB = 120, // auto horn, propeller aircraft + SNDLVL_130dB = 130, // air raid siren + + SNDLVL_GUNFIRE = 140, // 0.27 // THRESHOLD OF PAIN, gunshot, jet engine + SNDLVL_140dB = 140, // 0.2 + + SNDLVL_150dB = 150, // 0.2 + + SNDLVL_180dB = 180, // rocket launching + + // NOTE: Valid soundlevel_t values are 0-255. + // 256-511 are reserved for sounds using goldsrc compatibility attenuation. +}; + +#define MAX_SNDLVL_BITS 9 // Used to encode 0-255 for regular soundlevel_t's and 256-511 for goldsrc-compatible ones. +#define MIN_SNDLVL_VALUE 0 +#define MAX_SNDLVL_VALUE ((1< 50) ? (20.0f / (float)(a - 50)) : 4.0 ) + +// This is a limit due to network encoding. +// It encodes attenuation * 64 in 8 bits, so the maximum is (255 / 64) +#define MAX_ATTENUATION 3.98f + +//----------------------------------------------------------------------------- +// Flags to be or-ed together for the iFlags field +//----------------------------------------------------------------------------- +enum SoundFlags_t +{ + SND_NOFLAGS = 0, // to keep the compiler happy + SND_CHANGE_VOL = (1<<0), // change sound vol + SND_CHANGE_PITCH = (1<<1), // change sound pitch + SND_STOP = (1<<2), // stop the sound + SND_SPAWNING = (1<<3), // we're spawning, used in some cases for ambients + // not sent over net, only a param between dll and server. + SND_DELAY = (1<<4), // sound has an initial delay + SND_STOP_LOOPING = (1<<5), // stop all looping sounds on the entity. + SND_SPEAKER = (1<<6), // being played again by a microphone through a speaker + + SND_SHOULDPAUSE = (1<<7), // this sound should be paused if the game is paused + SND_IGNORE_PHONEMES = (1<<8), + SND_IGNORE_NAME = (1<<9), // used to change all sounds emitted by an entity, regardless of scriptname + + SND_DO_NOT_OVERWRITE_EXISTING_ON_CHANNEL = (1<<10), +}; + +#define SND_FLAG_BITS_ENCODE 11 + +#define MAX_SOUND_INDEX_BITS 14 +#define MAX_SOUNDS (1<name ) \ + buffer.WriteOneBit(0); \ + else \ + { \ + buffer.WriteOneBit(1); \ + buffer.WriteUBitLong( name, length ); \ + } + +#define READ_DELTA_UINT( name, length ) \ + if ( buffer.ReadOneBit() != 0 ) \ + { name = buffer.ReadUBitLong( length ); }\ + else { name = delta->name; } + +#define WRITE_DELTA_SINT( name, length ) \ + if ( name == delta->name ) \ + buffer.WriteOneBit(0); \ + else \ + { \ + buffer.WriteOneBit(1); \ + buffer.WriteSBitLong( name, length ); \ + } + +#define WRITE_DELTA_SINT_SCALE( name, scale, length ) \ + if ( name == delta->name ) \ + buffer.WriteOneBit(0); \ + else \ + { \ + buffer.WriteOneBit(1); \ + buffer.WriteSBitLong( name / scale, length ); \ + } + +#define READ_DELTA_SINT( name, length ) \ + if ( buffer.ReadOneBit() != 0 ) \ + { name = buffer.ReadSBitLong( length ); } \ + else { name = delta->name; } + +#define READ_DELTA_SINT_SCALE( name, scale, length ) \ + if ( buffer.ReadOneBit() != 0 ) \ + { name = scale * buffer.ReadSBitLong( length ); } \ + else { name = delta->name; } + +#define SOUND_SEQNUMBER_BITS 10 +#define SOUND_SEQNUMBER_MASK ( (1<nEntityIndex ) + { + buffer.WriteOneBit( 0 ); + } + else + { + buffer.WriteOneBit( 1 ); + + if ( nEntityIndex <= 31) + { + buffer.WriteOneBit( 1 ); + buffer.WriteUBitLong( nEntityIndex, 5 ); + } + else + { + buffer.WriteOneBit( 0 ); + buffer.WriteUBitLong( nEntityIndex, MAX_EDICT_BITS ); + } + } + + WRITE_DELTA_UINT( nSoundNum, MAX_SOUND_INDEX_BITS ); + + WRITE_DELTA_UINT( nFlags, SND_FLAG_BITS_ENCODE ); + + WRITE_DELTA_UINT( nChannel, 3 ); + + buffer.WriteOneBit( bIsAmbient?1:0 ); + buffer.WriteOneBit( bIsSentence?1:0 ); // NOTE: SND_STOP behavior is different depending on this flag + + if ( nFlags != SND_STOP ) + { + if ( nSequenceNumber == delta->nSequenceNumber ) + { + // didn't change, most often case + buffer.WriteOneBit( 1 ); + } + else if ( nSequenceNumber == (delta->nSequenceNumber+1) ) + { + // increased by one + buffer.WriteOneBit( 0 ); + buffer.WriteOneBit( 1 ); + } + else + { + // send full seqnr + buffer.WriteUBitLong( 0, 2 ); // 2 zero bits + buffer.WriteUBitLong( nSequenceNumber, SOUND_SEQNUMBER_BITS ); + } + + if ( fVolume == delta->fVolume ) + { + buffer.WriteOneBit( 0 ); + } + else + { + buffer.WriteOneBit( 1 ); + buffer.WriteUBitLong( (unsigned int)(fVolume*127.0f), 7 ); + } + + WRITE_DELTA_UINT( Soundlevel, MAX_SNDLVL_BITS ); + + WRITE_DELTA_UINT( nPitch, 8 ); + + WRITE_DELTA_UINT( nSpecialDSP, 8 ); + + if ( fDelay == delta->fDelay ) + { + buffer.WriteOneBit( 0 ); + } + else + { + buffer.WriteOneBit( 1 ); + + // skipahead works in 10 ms increments + // bias results so that we only incur the precision loss on relatively large skipaheads + fDelay += SOUND_DELAY_OFFSET; + + // Convert to msecs + int iDelay = fDelay * 1000.0f; + + iDelay = clamp( iDelay, (int)(-10 * MAX_SOUND_DELAY_MSEC), (int)(MAX_SOUND_DELAY_MSEC) ); + + if ( iDelay < 0 ) + { + iDelay /=10; + } + + buffer.WriteSBitLong( iDelay , MAX_SOUND_DELAY_MSEC_ENCODE_BITS ); + } + + // don't transmit sounds with high precision + WRITE_DELTA_SINT_SCALE( vOrigin.x, 8.0f, COORD_INTEGER_BITS - 2 ); + WRITE_DELTA_SINT_SCALE( vOrigin.y, 8.0f, COORD_INTEGER_BITS - 2 ); + WRITE_DELTA_SINT_SCALE( vOrigin.z, 8.0f, COORD_INTEGER_BITS - 2 ); + + WRITE_DELTA_SINT( nSpeakerEntity, MAX_EDICT_BITS + 1 ); + } + else + { + ClearStopFields(); + } + }; + + void ReadDelta( SoundInfo_t *delta, bf_read &buffer, int nProtoVersion ) + { + if ( !buffer.ReadOneBit() ) + { + nEntityIndex = delta->nEntityIndex; + } + else + { + if ( buffer.ReadOneBit() ) + { + nEntityIndex = buffer.ReadUBitLong( 5 ); + } + else + { + nEntityIndex = buffer.ReadUBitLong( MAX_EDICT_BITS ); + } + } + + if ( nProtoVersion > 22 ) + { + READ_DELTA_UINT( nSoundNum, MAX_SOUND_INDEX_BITS ); + } + else + { + READ_DELTA_UINT( nSoundNum, 13 ); + } + + if ( nProtoVersion > 18 ) + { + READ_DELTA_UINT( nFlags, SND_FLAG_BITS_ENCODE ); + } + else + { + // There was 9 flag bits for version 18 and below (prior to Halloween 2011) + READ_DELTA_UINT( nFlags, 9 ); + } + + READ_DELTA_UINT( nChannel, 3 ); + + bIsAmbient = buffer.ReadOneBit() != 0; + bIsSentence = buffer.ReadOneBit() != 0; // NOTE: SND_STOP behavior is different depending on this flag + + if ( nFlags != SND_STOP ) + { + if ( buffer.ReadOneBit() != 0 ) + { + nSequenceNumber = delta->nSequenceNumber; + } + else if ( buffer.ReadOneBit() != 0 ) + { + nSequenceNumber = delta->nSequenceNumber + 1; + } + else + { + nSequenceNumber = buffer.ReadUBitLong( SOUND_SEQNUMBER_BITS ); + } + + if ( buffer.ReadOneBit() != 0 ) + { + fVolume = (float)buffer.ReadUBitLong( 7 )/127.0f; + } + else + { + fVolume = delta->fVolume; + } + + if ( buffer.ReadOneBit() != 0 ) + { + Soundlevel = (soundlevel_t)buffer.ReadUBitLong( MAX_SNDLVL_BITS ); + } + else + { + Soundlevel = delta->Soundlevel; + } + + READ_DELTA_UINT( nPitch, 8 ); + + if ( nProtoVersion > 21 ) + { + // These bit weren't written in version 19 and below + READ_DELTA_UINT( nSpecialDSP, 8 ); + } + + if ( buffer.ReadOneBit() != 0 ) + { + // Up to 4096 msec delay + fDelay = (float)buffer.ReadSBitLong( MAX_SOUND_DELAY_MSEC_ENCODE_BITS ) / 1000.0f; ; + + if ( fDelay < 0 ) + { + fDelay *= 10.0f; + } + // bias results so that we only incur the precision loss on relatively large skipaheads + fDelay -= SOUND_DELAY_OFFSET; + } + else + { + fDelay = delta->fDelay; + } + + READ_DELTA_SINT_SCALE( vOrigin.x, 8.0f, COORD_INTEGER_BITS - 2 ); + READ_DELTA_SINT_SCALE( vOrigin.y, 8.0f, COORD_INTEGER_BITS - 2 ); + READ_DELTA_SINT_SCALE( vOrigin.z, 8.0f, COORD_INTEGER_BITS - 2 ); + + READ_DELTA_SINT( nSpeakerEntity, MAX_EDICT_BITS + 1 ); + } + else + { + ClearStopFields(); + } + } +}; + +struct SpatializationInfo_t +{ + typedef enum + { + SI_INCREATION = 0, + SI_INSPATIALIZATION + } SPATIALIZATIONTYPE; + + // Inputs + SPATIALIZATIONTYPE type; + // Info about the sound, channel, origin, direction, etc. + SoundInfo_t info; + + // Requested Outputs ( NULL == not requested ) + Vector *pOrigin; + QAngle *pAngles; + float *pflRadius; +}; +#pragma pack() + +#endif // SOUNDINFO_H diff --git a/sp/src/public/stdstring.h b/sp/src/public/stdstring.h new file mode 100644 index 00000000..50ed1c29 --- /dev/null +++ b/sp/src/public/stdstring.h @@ -0,0 +1,102 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "isaverestore.h" + +#ifndef STDSTRING_H +#define STDSTRING_H + +#if defined( _WIN32 ) +#pragma once +#endif + +#ifdef _WIN32 +#pragma warning(push) +#include // warnings get enabled in yvals.h +#pragma warning(disable:4663) +#pragma warning(disable:4530) +#pragma warning(disable:4245) +#pragma warning(disable:4018) +#pragma warning(disable:4511) +#endif + +#include "tier0/valve_minmax_off.h" // GCC 4.2.2 headers screw up our min/max defs. +#include +#include "tier0/valve_minmax_on.h" // GCC 4.2.2 headers screw up our min/max defs. + +#ifdef _WIN32 +#pragma warning(pop) +#endif + +class CStdStringSaveRestoreOps : public CDefSaveRestoreOps +{ +public: + enum + { + MAX_SAVE_LEN = 4096, + }; + + // save data type interface + virtual void Save( const SaveRestoreFieldInfo_t &fieldInfo, ISave *pSave ) + { + std::string *pString = (std::string *)fieldInfo.pField; + Assert( pString->length() < MAX_SAVE_LEN - 1 ); + if ( pString->length() < MAX_SAVE_LEN - 1 ) + pSave->WriteString( pString->c_str() ); + else + pSave->WriteString( "<>" ); + } + + virtual void Restore( const SaveRestoreFieldInfo_t &fieldInfo, IRestore *pRestore ) + { + std::string *pString = (std::string *)fieldInfo.pField; + char szString[MAX_SAVE_LEN]; + pRestore->ReadString( szString, sizeof(szString), 0 ); + szString[MAX_SAVE_LEN - 1] = 0; + pString->assign( szString ); + } + + virtual void MakeEmpty( const SaveRestoreFieldInfo_t &fieldInfo ) + { + std::string *pString = (std::string *)fieldInfo.pField; + pString->erase(); + } + + virtual bool IsEmpty( const SaveRestoreFieldInfo_t &fieldInfo ) + { + std::string *pString = (std::string *)fieldInfo.pField; + return pString->empty(); + } + +#ifdef MAPBASE + virtual bool Parse( const SaveRestoreFieldInfo_t &fieldInfo, char const* szValue ) + { + std::string *pString = (std::string *)fieldInfo.pField; + pString->assign(szValue); + return true; + } +#endif +}; + +//------------------------------------- + +inline ISaveRestoreOps *GetStdStringDataOps() +{ + static CStdStringSaveRestoreOps ops; + return &ops; +} + +//------------------------------------- + +#define DEFINE_STDSTRING(name) \ + { FIELD_CUSTOM, #name, { offsetof(classNameTypedef,name), 0 }, 1, FTYPEDESC_SAVE, NULL, GetStdStringDataOps(), NULL } + +#ifdef MAPBASE +#define DEFINE_KEYSTDSTRING(name,mapname) \ + { FIELD_CUSTOM, #name, { offsetof(classNameTypedef, name), 0 }, 1, FTYPEDESC_SAVE | FTYPEDESC_KEY, mapname, GetStdStringDataOps(), NULL } +#endif + +#endif // STDSTRING_H diff --git a/sp/src/public/string_t.h b/sp/src/public/string_t.h new file mode 100644 index 00000000..9fa1de64 --- /dev/null +++ b/sp/src/public/string_t.h @@ -0,0 +1,115 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Defines the more complete set of operations on the string_t defined +// These should be used instead of direct manipulation to allow more +// flexibility in future ports or optimization. +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef STRING_T_H +#define STRING_T_H + +#if defined( _WIN32 ) +#pragma once +#endif + +#ifndef NO_STRING_T + +#ifdef WEAK_STRING_T + +typedef int string_t; + +//----------------------------------------------------------------------------- +// Purpose: The correct way to specify the NULL string as a constant. +//----------------------------------------------------------------------------- + +#define NULL_STRING 0 + +//----------------------------------------------------------------------------- +// Purpose: Given a string_t, make a C string. By convention the result string +// pointer should be considered transient and should not be stored. +//----------------------------------------------------------------------------- + +#define STRING( offset ) ( ( offset ) ? reinterpret_cast( offset ) : "" ) + +//----------------------------------------------------------------------------- +// Purpose: Given a C string, obtain a string_t +//----------------------------------------------------------------------------- + +#define MAKE_STRING( str ) ( ( *str != 0 ) ? reinterpret_cast( str ) : 0 ) + +//----------------------------------------------------------------------------- + +#define IDENT_STRINGS( s1, s2 ) *((void **)&(s1)) == *((void **)&(s2)) + +//----------------------------------------------------------------------------- + +#else // Strong string_t + +//----------------------------------------------------------------------------- + +struct string_t +{ +public: + bool operator!() const { return ( pszValue == NULL ); } + bool operator==( const string_t &rhs ) const { return ( pszValue == rhs.pszValue ); } + bool operator!=( const string_t &rhs ) const { return ( pszValue != rhs.pszValue ); } + bool operator<( const string_t &rhs ) const { return ((void *)pszValue < (void *)rhs.pszValue ); } + + const char *ToCStr() const { return ( pszValue ) ? pszValue : ""; } + +protected: + const char *pszValue; +}; + +//----------------------------------------------------------------------------- + +struct castable_string_t : public string_t // string_t is used in unions, hence, no constructor allowed +{ + castable_string_t() { pszValue = NULL; } + castable_string_t( const char *pszFrom ) { pszValue = (pszFrom && *pszFrom) ? pszFrom : 0; } +}; + +//----------------------------------------------------------------------------- +// Purpose: The correct way to specify the NULL string as a constant. +//----------------------------------------------------------------------------- + +#define NULL_STRING castable_string_t() + +//----------------------------------------------------------------------------- +// Purpose: Given a string_t, make a C string. By convention the result string +// pointer should be considered transient and should not be stored. +//----------------------------------------------------------------------------- + +#define STRING( string_t_obj ) (string_t_obj).ToCStr() + +//----------------------------------------------------------------------------- +// Purpose: Given a C string, obtain a string_t +//----------------------------------------------------------------------------- + +#define MAKE_STRING( c_str ) castable_string_t( c_str ) + +//----------------------------------------------------------------------------- + +#define IDENT_STRINGS( s1, s2 ) *((void **)&(s1)) == *((void **)&(s2)) + +//----------------------------------------------------------------------------- + +inline void NetworkVarConstruct( string_t &x ) { x = NULL_STRING; } + +#endif + +#else // NO_STRING_T + +typedef const char *string_t; +#define NULL_STRING 0 +#define STRING( c_str ) ( c_str ) +#define MAKE_STRING( c_str ) ( c_str ) +#define IDENT_STRINGS( s1, s2 ) *((void **)&(s1)) == *((void **)&(s2)) + +#endif // NO_STRING_T + +//============================================================================= + +#endif // STRING_T_H diff --git a/sp/src/public/stringregistry.cpp b/sp/src/public/stringregistry.cpp new file mode 100644 index 00000000..896430bf --- /dev/null +++ b/sp/src/public/stringregistry.cpp @@ -0,0 +1,145 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: A registry of strings and associated ints +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// + + +#include +#include +#include "stringregistry.h" +#include "utldict.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#if !defined(_STATIC_LINKED) || defined(CLIENT_DLL) + +//----------------------------------------------------------------------------- +// Purpose: This class wraps the containers that do the actual work +//----------------------------------------------------------------------------- +struct StringTable_t : public CUtlDict +{ +}; + + + +//----------------------------------------------------------------------------- +// Purpose: Add null terminated string to the string registry +// Input : +// Output : +//----------------------------------------------------------------------------- +unsigned short CStringRegistry::AddString(const char *stringText, int stringID) +{ + return m_pStringList->Insert( stringText, stringID ); +} + +//----------------------------------------------------------------------------- +// Purpose: Given string text get the string ID +// Input : Text of string to find +// Output : Return string id or -1 if no such string exists +//----------------------------------------------------------------------------- +int CStringRegistry::GetStringID( const char *stringText ) +{ + unsigned short index = m_pStringList->Find( stringText ); + if ( m_pStringList->IsValidIndex( index ) ) + { + return (*m_pStringList)[index]; + } + + return -1; +} + +//----------------------------------------------------------------------------- +// Purpose: Given a string ID return the string text +// Input : ID of string to find +// Output : Return string text of NULL of no such ID exists +//----------------------------------------------------------------------------- +char const *CStringRegistry::GetStringText( int stringID ) +{ + for( unsigned short index = m_pStringList->First() ; index != m_pStringList->InvalidIndex(); index = m_pStringList->Next( index ) ) + { + if ( (*m_pStringList)[index] == stringID ) + { + return m_pStringList->GetElementName( index ); + } + } + + return NULL; +} + + +//----------------------------------------------------------------------------- +// Purpose: Given a key return the string text +//----------------------------------------------------------------------------- +char const *CStringRegistry::GetStringForKey( unsigned short key ) +{ + if ( !m_pStringList->IsValidIndex( key ) ) + return NULL; + + return m_pStringList->GetElementName( key ); +} + +//----------------------------------------------------------------------------- +// Purpose: Given a key return the string text +//----------------------------------------------------------------------------- +int CStringRegistry::GetIDForKey( unsigned short key ) +{ + if ( !m_pStringList->IsValidIndex( key ) ) + return 0; + + return (*m_pStringList)[key]; +} + +//----------------------------------------------------------------------------- +// Purpose: Clear all strings from the string registry +//----------------------------------------------------------------------------- +void CStringRegistry::ClearStrings(void) +{ + m_pStringList->RemoveAll(); +} + +//----------------------------------------------------------------------------- +// Purpose: Destructor - delete the list of strings and maps +// Input : +// Output : +//----------------------------------------------------------------------------- +CStringRegistry::~CStringRegistry(void) +{ + delete m_pStringList; +} + +//----------------------------------------------------------------------------- +// Purpose: Constructor +// Input : +// Output : +//----------------------------------------------------------------------------- +CStringRegistry::CStringRegistry(void) +{ + m_pStringList = new StringTable_t; +} + + +unsigned short CStringRegistry::First() const +{ + return m_pStringList->First(); +} + +unsigned short CStringRegistry::Next( unsigned short key ) const +{ + return m_pStringList->Next( key ); +} + +unsigned short CStringRegistry::InvalidIndex() const +{ + return m_pStringList->InvalidIndex(); +} + +#endif // _STATIC_LINKED && CLIENT_DLL diff --git a/sp/src/public/stringregistry.h b/sp/src/public/stringregistry.h new file mode 100644 index 00000000..9e4ff82c --- /dev/null +++ b/sp/src/public/stringregistry.h @@ -0,0 +1,57 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: A registry of strings and associated ints +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef STRINGREGISTRY_H +#define STRINGREGISTRY_H +#pragma once + +struct StringTable_t; + +//----------------------------------------------------------------------------- +// Purpose: Just a convenience/legacy wrapper for CUtlDict<> . +//----------------------------------------------------------------------------- +class CStringRegistry +{ +private: + StringTable_t *m_pStringList; + +public: + // returns a key for a given string + unsigned short AddString(const char *stringText, int stringID); + + // This is optimized. It will do 2 O(logN) searches + // Only one of the searches needs to compare strings, the other compares symbols (ints) + // returns -1 if the string is not present in the registry. + int GetStringID(const char *stringText); + + // This is unoptimized. It will linearly search (but only compares ints, not strings) + const char *GetStringText(int stringID); + + // This is O(1). It will not search. key MUST be a value that was returned by AddString + const char *GetStringForKey(unsigned short key); + // This is O(1). It will not search. key MUST be a value that was returned by AddString + int GetIDForKey(unsigned short key); + + void ClearStrings(void); + + + // Iterate all the keys. + unsigned short First() const; + unsigned short Next( unsigned short key ) const; + unsigned short InvalidIndex() const; + + ~CStringRegistry(void); // Need to free allocated memory + CStringRegistry(void); +}; + +#endif // STRINGREGISTRY_H diff --git a/sp/src/public/studio.cpp b/sp/src/public/studio.cpp new file mode 100644 index 00000000..9bf97018 --- /dev/null +++ b/sp/src/public/studio.cpp @@ -0,0 +1,1830 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "studio.h" +#include "datacache/idatacache.h" +#include "datacache/imdlcache.h" +#include "convar.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +mstudioanimdesc_t &studiohdr_t::pAnimdesc( int i ) const +{ + if (numincludemodels == 0) + { + return *pLocalAnimdesc( i ); + } + + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + virtualgroup_t *pGroup = &pVModel->m_group[ pVModel->m_anim[i].group ]; + const studiohdr_t *pStudioHdr = pGroup->GetStudioHdr(); + Assert( pStudioHdr ); + + return *pStudioHdr->pLocalAnimdesc( pVModel->m_anim[i].index ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +mstudioanim_t *mstudioanimdesc_t::pAnimBlock( int block, int index ) const +{ + if (block == -1) + { + return (mstudioanim_t *)NULL; + } + if (block == 0) + { + return (mstudioanim_t *)(((byte *)this) + index); + } + + byte *pAnimBlock = pStudiohdr()->GetAnimBlock( block ); + if ( pAnimBlock ) + { + return (mstudioanim_t *)(pAnimBlock + index); + } + + return (mstudioanim_t *)NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +static ConVar mod_load_showstall( "mod_load_showstall", "0", 0, "1 - show hitches , 2 - show stalls" ); +mstudioanim_t *mstudioanimdesc_t::pAnim( int *piFrame ) const +{ + float flStall; + return pAnim( piFrame, flStall ); +} + +mstudioanim_t *mstudioanimdesc_t::pAnim( int *piFrame, float &flStall ) const +{ + mstudioanim_t *panim = NULL; + + int block = animblock; + int index = animindex; + int section = 0; + + if (sectionframes != 0) + { + if (numframes > sectionframes && *piFrame == numframes - 1) + { + // last frame on long anims is stored separately + *piFrame = 0; + section = (numframes / sectionframes) + 1; + } + else + { + section = *piFrame / sectionframes; + *piFrame -= section * sectionframes; + } + + block = pSection( section )->animblock; + index = pSection( section )->animindex; + } + + if (block == -1) + { + // model needs to be recompiled + return NULL; + } + + panim = pAnimBlock( block, index ); + + // force a preload on the next block + if ( sectionframes != 0 ) + { + int count = ( numframes / sectionframes) + 2; + for ( int i = section + 1; i < count; i++ ) + { + if ( pSection( i )->animblock != block ) + { + pAnimBlock( pSection( i )->animblock, pSection( i )->animindex ); + break; + } + } + } + + if (panim == NULL) + { + if (section > 0 && mod_load_showstall.GetInt() > 0) + { + Msg("[%8.3f] hitch on %s:%s:%d:%d\n", Plat_FloatTime(), pStudiohdr()->pszName(), pszName(), section, block ); + } + // back up until a previously loaded block is found + while (--section >= 0) + { + block = pSection( section )->animblock; + index = pSection( section )->animindex; + panim = pAnimBlock( block, index ); + if (panim) + { + // set it to the last frame in the last valid section + *piFrame = sectionframes - 1; + break; + } + } + } + + // try to guess a valid stall time interval (tuned for the X360) + flStall = 0.0f; + if (panim == NULL && section <= 0) + { + zeroframestalltime = Plat_FloatTime(); + flStall = 1.0f; + } + else if (panim != NULL && zeroframestalltime != 0.0f) + { + float dt = Plat_FloatTime() - zeroframestalltime; + if (dt >= 0.0) + { + flStall = SimpleSpline( clamp( (0.200f - dt) * 5.0f, 0.0f, 1.0f ) ); + } + + if (flStall == 0.0f) + { + // disable stalltime + zeroframestalltime = 0.0f; + } + else if (mod_load_showstall.GetInt() > 1) + { + Msg("[%8.3f] stall blend %.2f on %s:%s:%d:%d\n", Plat_FloatTime(), flStall, pStudiohdr()->pszName(), pszName(), section, block ); + } + } + + if (panim == NULL && mod_load_showstall.GetInt() > 1) + { + Msg("[%8.3f] stall on %s:%s:%d:%d\n", Plat_FloatTime(), pStudiohdr()->pszName(), pszName(), section, block ); + } + + return panim; +} + +mstudioikrule_t *mstudioanimdesc_t::pIKRule( int i ) const +{ + if (ikruleindex) + { + return (mstudioikrule_t *)(((byte *)this) + ikruleindex) + i; + } + else if (animblockikruleindex) + { + if (animblock == 0) + { + return (mstudioikrule_t *)(((byte *)this) + animblockikruleindex) + i; + } + else + { + byte *pAnimBlocks = pStudiohdr()->GetAnimBlock( animblock ); + + if ( pAnimBlocks ) + { + return (mstudioikrule_t *)(pAnimBlocks + animblockikruleindex) + i; + } + } + } + + return NULL; +} + + +mstudiolocalhierarchy_t *mstudioanimdesc_t::pHierarchy( int i ) const +{ + if (localhierarchyindex) + { + if (animblock == 0) + { + return (mstudiolocalhierarchy_t *)(((byte *)this) + localhierarchyindex) + i; + } + else + { + byte *pAnimBlocks = pStudiohdr()->GetAnimBlock( animblock ); + + if ( pAnimBlocks ) + { + return (mstudiolocalhierarchy_t *)(pAnimBlocks + localhierarchyindex) + i; + } + } + } + + return NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +bool studiohdr_t::SequencesAvailable() const +{ + if (numincludemodels == 0) + { + return true; + } + + return ( GetVirtualModel() != NULL ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int studiohdr_t::GetNumSeq( void ) const +{ + if (numincludemodels == 0) + { + return numlocalseq; + } + + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + return pVModel->m_seq.Count(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +mstudioseqdesc_t &studiohdr_t::pSeqdesc( int i ) const +{ + if (numincludemodels == 0) + { + return *pLocalSeqdesc( i ); + } + + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + if ( !pVModel ) + { + return *pLocalSeqdesc( i ); + } + + virtualgroup_t *pGroup = &pVModel->m_group[ pVModel->m_seq[i].group ]; + const studiohdr_t *pStudioHdr = pGroup->GetStudioHdr(); + Assert( pStudioHdr ); + + return *pStudioHdr->pLocalSeqdesc( pVModel->m_seq[i].index ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int studiohdr_t::iRelativeAnim( int baseseq, int relanim ) const +{ + if (numincludemodels == 0) + { + return relanim; + } + + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + virtualgroup_t *pGroup = &pVModel->m_group[ pVModel->m_seq[baseseq].group ]; + + return pGroup->masterAnim[ relanim ]; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int studiohdr_t::iRelativeSeq( int baseseq, int relseq ) const +{ + if (numincludemodels == 0) + { + return relseq; + } + + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + virtualgroup_t *pGroup = &pVModel->m_group[ pVModel->m_seq[baseseq].group ]; + + return pGroup->masterSeq[ relseq ]; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int studiohdr_t::GetNumPoseParameters( void ) const +{ + if (numincludemodels == 0) + { + return numlocalposeparameters; + } + + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + return pVModel->m_pose.Count(); +} + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +const mstudioposeparamdesc_t &studiohdr_t::pPoseParameter( int i ) +{ + if (numincludemodels == 0) + { + return *pLocalPoseParameter( i ); + } + + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + if ( pVModel->m_pose[i].group == 0) + return *pLocalPoseParameter( pVModel->m_pose[i].index ); + + virtualgroup_t *pGroup = &pVModel->m_group[ pVModel->m_pose[i].group ]; + + const studiohdr_t *pStudioHdr = pGroup->GetStudioHdr(); + Assert( pStudioHdr ); + + return *pStudioHdr->pLocalPoseParameter( pVModel->m_pose[i].index ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int studiohdr_t::GetSharedPoseParameter( int iSequence, int iLocalPose ) const +{ + if (numincludemodels == 0) + { + return iLocalPose; + } + + if (iLocalPose == -1) + return iLocalPose; + + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + virtualgroup_t *pGroup = &pVModel->m_group[ pVModel->m_seq[iSequence].group ]; + + return pGroup->masterPose[iLocalPose]; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int studiohdr_t::EntryNode( int iSequence ) +{ + mstudioseqdesc_t &seqdesc = pSeqdesc( iSequence ); + + if (numincludemodels == 0 || seqdesc.localentrynode == 0) + { + return seqdesc.localentrynode; + } + + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + virtualgroup_t *pGroup = &pVModel->m_group[ pVModel->m_seq[iSequence].group ]; + + return pGroup->masterNode[seqdesc.localentrynode-1]+1; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + + +int studiohdr_t::ExitNode( int iSequence ) +{ + mstudioseqdesc_t &seqdesc = pSeqdesc( iSequence ); + + if (numincludemodels == 0 || seqdesc.localexitnode == 0) + { + return seqdesc.localexitnode; + } + + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + virtualgroup_t *pGroup = &pVModel->m_group[ pVModel->m_seq[iSequence].group ]; + + return pGroup->masterNode[seqdesc.localexitnode-1]+1; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int studiohdr_t::GetNumAttachments( void ) const +{ + if (numincludemodels == 0) + { + return numlocalattachments; + } + + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + return pVModel->m_attachment.Count(); +} + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +const mstudioattachment_t &studiohdr_t::pAttachment( int i ) const +{ + if (numincludemodels == 0) + { + return *pLocalAttachment( i ); + } + + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + virtualgroup_t *pGroup = &pVModel->m_group[ pVModel->m_attachment[i].group ]; + const studiohdr_t *pStudioHdr = pGroup->GetStudioHdr(); + Assert( pStudioHdr ); + + return *pStudioHdr->pLocalAttachment( pVModel->m_attachment[i].index ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int studiohdr_t::GetAttachmentBone( int i ) +{ + const mstudioattachment_t &attachment = pAttachment( i ); + + // remap bone + virtualmodel_t *pVModel = GetVirtualModel(); + if (pVModel) + { + virtualgroup_t *pGroup = &pVModel->m_group[ pVModel->m_attachment[i].group ]; + int iBone = pGroup->masterBone[attachment.localbone]; + if (iBone == -1) + return 0; + return iBone; + } + return attachment.localbone; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void studiohdr_t::SetAttachmentBone( int iAttachment, int iBone ) +{ + mstudioattachment_t &attachment = (mstudioattachment_t &)pAttachment( iAttachment ); + + // remap bone + virtualmodel_t *pVModel = GetVirtualModel(); + if (pVModel) + { + virtualgroup_t *pGroup = &pVModel->m_group[ pVModel->m_attachment[iAttachment].group ]; + iBone = pGroup->boneMap[iBone]; + } + attachment.localbone = iBone; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +char *studiohdr_t::pszNodeName( int iNode ) +{ + if (numincludemodels == 0) + { + return pszLocalNodeName( iNode ); + } + + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + if ( pVModel->m_node.Count() <= iNode-1 ) + return "Invalid node"; + + return pVModel->m_group[ pVModel->m_node[iNode-1].group ].GetStudioHdr()->pszLocalNodeName( pVModel->m_node[iNode-1].index ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int studiohdr_t::GetTransition( int iFrom, int iTo ) const +{ + if (numincludemodels == 0) + { + return *pLocalTransition( (iFrom-1)*numlocalnodes + (iTo - 1) ); + } + + return iTo; + /* + FIXME: not connected + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + return pVModel->m_transition.Element( iFrom ).Element( iTo ); + */ +} + + +int studiohdr_t::GetActivityListVersion( void ) +{ + if (numincludemodels == 0) + { + return activitylistversion; + } + + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + int version = activitylistversion; + + int i; + for (i = 1; i < pVModel->m_group.Count(); i++) + { + virtualgroup_t *pGroup = &pVModel->m_group[ i ]; + const studiohdr_t *pStudioHdr = pGroup->GetStudioHdr(); + + Assert( pStudioHdr ); + + version = min( version, pStudioHdr->activitylistversion ); + } + + return version; +} + +void studiohdr_t::SetActivityListVersion( int version ) const +{ + activitylistversion = version; + + if (numincludemodels == 0) + { + return; + } + + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + int i; + for (i = 1; i < pVModel->m_group.Count(); i++) + { + virtualgroup_t *pGroup = &pVModel->m_group[ i ]; + const studiohdr_t *pStudioHdr = pGroup->GetStudioHdr(); + + Assert( pStudioHdr ); + + pStudioHdr->SetActivityListVersion( version ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + + +int studiohdr_t::GetNumIKAutoplayLocks( void ) const +{ + if (numincludemodels == 0) + { + return numlocalikautoplaylocks; + } + + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + return pVModel->m_iklock.Count(); +} + +const mstudioiklock_t &studiohdr_t::pIKAutoplayLock( int i ) +{ + if (numincludemodels == 0) + { + return *pLocalIKAutoplayLock( i ); + } + + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + virtualgroup_t *pGroup = &pVModel->m_group[ pVModel->m_iklock[i].group ]; + const studiohdr_t *pStudioHdr = pGroup->GetStudioHdr(); + Assert( pStudioHdr ); + + return *pStudioHdr->pLocalIKAutoplayLock( pVModel->m_iklock[i].index ); +} + +int studiohdr_t::CountAutoplaySequences() const +{ + int count = 0; + for (int i = 0; i < GetNumSeq(); i++) + { + mstudioseqdesc_t &seqdesc = pSeqdesc( i ); + if (seqdesc.flags & STUDIO_AUTOPLAY) + { + count++; + } + } + return count; +} + +int studiohdr_t::CopyAutoplaySequences( unsigned short *pOut, int outCount ) const +{ + int outIndex = 0; + for (int i = 0; i < GetNumSeq() && outIndex < outCount; i++) + { + mstudioseqdesc_t &seqdesc = pSeqdesc( i ); + if (seqdesc.flags & STUDIO_AUTOPLAY) + { + pOut[outIndex] = i; + outIndex++; + } + } + return outIndex; +} + +//----------------------------------------------------------------------------- +// Purpose: maps local sequence bone to global bone +//----------------------------------------------------------------------------- + +int studiohdr_t::RemapSeqBone( int iSequence, int iLocalBone ) const +{ + // remap bone + virtualmodel_t *pVModel = GetVirtualModel(); + if (pVModel) + { + const virtualgroup_t *pSeqGroup = pVModel->pSeqGroup( iSequence ); + return pSeqGroup->masterBone[iLocalBone]; + } + return iLocalBone; +} + +int studiohdr_t::RemapAnimBone( int iAnim, int iLocalBone ) const +{ + // remap bone + virtualmodel_t *pVModel = GetVirtualModel(); + if (pVModel) + { + const virtualgroup_t *pAnimGroup = pVModel->pAnimGroup( iAnim ); + return pAnimGroup->masterBone[iLocalBone]; + } + return iLocalBone; +} + + + + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +CStudioHdr::CStudioHdr( void ) +{ + // set pointer to bogus value + m_nFrameUnlockCounter = 0; + m_pFrameUnlockCounter = &m_nFrameUnlockCounter; + Init( NULL ); +} + +CStudioHdr::CStudioHdr( const studiohdr_t *pStudioHdr, IMDLCache *mdlcache ) +{ + // preset pointer to bogus value (it may be overwritten with legitimate data later) + m_nFrameUnlockCounter = 0; + m_pFrameUnlockCounter = &m_nFrameUnlockCounter; + Init( pStudioHdr, mdlcache ); +} + + +// extern IDataCache *g_pDataCache; + +void CStudioHdr::Init( const studiohdr_t *pStudioHdr, IMDLCache *mdlcache ) +{ + m_pStudioHdr = pStudioHdr; + + m_pVModel = NULL; + m_pStudioHdrCache.RemoveAll(); + + if (m_pStudioHdr == NULL) + { + return; + } + + if ( mdlcache ) + { + m_pFrameUnlockCounter = mdlcache->GetFrameUnlockCounterPtr( MDLCACHE_STUDIOHDR ); + m_nFrameUnlockCounter = *m_pFrameUnlockCounter - 1; + } + + if (m_pStudioHdr->numincludemodels == 0) + { +#if STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE +#else + m_ActivityToSequence.Initialize(this); +#endif + } + else + { + ResetVModel( m_pStudioHdr->GetVirtualModel() ); +#if STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE +#else + m_ActivityToSequence.Initialize(this); +#endif + } + + m_boneFlags.EnsureCount( numbones() ); + m_boneParent.EnsureCount( numbones() ); + for (int i = 0; i < numbones(); i++) + { + m_boneFlags[i] = pBone( i )->flags; + m_boneParent[i] = pBone( i )->parent; + } +} + +void CStudioHdr::Term() +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +bool CStudioHdr::SequencesAvailable() const +{ + if (m_pStudioHdr->numincludemodels == 0) + { + return true; + } + + if (m_pVModel == NULL) + { + // repoll m_pVModel + return (ResetVModel( m_pStudioHdr->GetVirtualModel() ) != NULL); + } + else + return true; +} + + +const virtualmodel_t * CStudioHdr::ResetVModel( const virtualmodel_t *pVModel ) const +{ + if (pVModel != NULL) + { + m_pVModel = (virtualmodel_t *)pVModel; + Assert( !pVModel->m_Lock.GetOwnerId() ); + m_pStudioHdrCache.SetCount( m_pVModel->m_group.Count() ); + + int i; + for (i = 0; i < m_pStudioHdrCache.Count(); i++) + { + m_pStudioHdrCache[ i ] = NULL; + } + + return const_cast(pVModel); + } + else + { + m_pVModel = NULL; + return NULL; + } +} + +const studiohdr_t *CStudioHdr::GroupStudioHdr( int i ) +{ + if ( !this ) + { + ExecuteNTimes( 5, Warning( "Call to NULL CStudioHdr::GroupStudioHdr()\n" ) ); + } + + if ( m_nFrameUnlockCounter != *m_pFrameUnlockCounter ) + { + m_FrameUnlockCounterMutex.Lock(); + if ( *m_pFrameUnlockCounter != m_nFrameUnlockCounter ) // i.e., this thread got the mutex + { + memset( m_pStudioHdrCache.Base(), 0, m_pStudioHdrCache.Count() * sizeof(studiohdr_t *) ); + m_nFrameUnlockCounter = *m_pFrameUnlockCounter; + } + m_FrameUnlockCounterMutex.Unlock(); + } + + if ( !m_pStudioHdrCache.IsValidIndex( i ) ) + { + const char *pszName = ( m_pStudioHdr ) ? m_pStudioHdr->pszName() : "<>"; + ExecuteNTimes( 5, Warning( "Invalid index passed to CStudioHdr(%s)::GroupStudioHdr(): %d, but max is %d\n", pszName, i, m_pStudioHdrCache.Count() ) ); + DebuggerBreakIfDebugging(); + return m_pStudioHdr; // return something known to probably exist, certainly things will be messed up, but hopefully not crash before the warning is noticed + } + + const studiohdr_t *pStudioHdr = m_pStudioHdrCache[ i ]; + + if (pStudioHdr == NULL) + { + Assert( !m_pVModel->m_Lock.GetOwnerId() ); + virtualgroup_t *pGroup = &m_pVModel->m_group[ i ]; + pStudioHdr = pGroup->GetStudioHdr(); + m_pStudioHdrCache[ i ] = pStudioHdr; + } + + Assert( pStudioHdr ); + return pStudioHdr; +} + + +const studiohdr_t *CStudioHdr::pSeqStudioHdr( int sequence ) +{ + if (m_pVModel == NULL) + { + return m_pStudioHdr; + } + + const studiohdr_t *pStudioHdr = GroupStudioHdr( m_pVModel->m_seq[sequence].group ); + + return pStudioHdr; +} + + +const studiohdr_t *CStudioHdr::pAnimStudioHdr( int animation ) +{ + if (m_pVModel == NULL) + { + return m_pStudioHdr; + } + + const studiohdr_t *pStudioHdr = GroupStudioHdr( m_pVModel->m_anim[animation].group ); + + return pStudioHdr; +} + + + +mstudioanimdesc_t &CStudioHdr::pAnimdesc( int i ) +{ + if (m_pVModel == NULL) + { + return *m_pStudioHdr->pLocalAnimdesc( i ); + } + + const studiohdr_t *pStudioHdr = GroupStudioHdr( m_pVModel->m_anim[i].group ); + + return *pStudioHdr->pLocalAnimdesc( m_pVModel->m_anim[i].index ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int CStudioHdr::GetNumSeq( void ) const +{ + if (m_pVModel == NULL) + { + return m_pStudioHdr->numlocalseq; + } + + return m_pVModel->m_seq.Count(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +mstudioseqdesc_t &CStudioHdr::pSeqdesc( int i ) +{ + Assert( ( i >= 0 && i < GetNumSeq() ) || ( i == 1 && GetNumSeq() <= 1 ) ); + if ( i < 0 || i >= GetNumSeq() ) + { + // Avoid reading random memory. + i = 0; + } + + if (m_pVModel == NULL) + { + return *m_pStudioHdr->pLocalSeqdesc( i ); + } + + const studiohdr_t *pStudioHdr = GroupStudioHdr( m_pVModel->m_seq[i].group ); + + return *pStudioHdr->pLocalSeqdesc( m_pVModel->m_seq[i].index ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int CStudioHdr::iRelativeAnim( int baseseq, int relanim ) const +{ + if (m_pVModel == NULL) + { + return relanim; + } + + virtualgroup_t *pGroup = &m_pVModel->m_group[ m_pVModel->m_seq[baseseq].group ]; + + return pGroup->masterAnim[ relanim ]; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int CStudioHdr::iRelativeSeq( int baseseq, int relseq ) const +{ + if (m_pVModel == NULL) + { + return relseq; + } + + Assert( m_pVModel ); + + virtualgroup_t *pGroup = &m_pVModel->m_group[ m_pVModel->m_seq[baseseq].group ]; + + return pGroup->masterSeq[ relseq ]; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int CStudioHdr::GetNumPoseParameters( void ) const +{ + if (m_pVModel == NULL) + { + if ( m_pStudioHdr ) + return m_pStudioHdr->numlocalposeparameters; + else + return 0; + } + + Assert( m_pVModel ); + + return m_pVModel->m_pose.Count(); +} + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +const mstudioposeparamdesc_t &CStudioHdr::pPoseParameter( int i ) +{ + if (m_pVModel == NULL) + { + return *m_pStudioHdr->pLocalPoseParameter( i ); + } + + if ( m_pVModel->m_pose[i].group == 0) + return *m_pStudioHdr->pLocalPoseParameter( m_pVModel->m_pose[i].index ); + + const studiohdr_t *pStudioHdr = GroupStudioHdr( m_pVModel->m_pose[i].group ); + + return *pStudioHdr->pLocalPoseParameter( m_pVModel->m_pose[i].index ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int CStudioHdr::GetSharedPoseParameter( int iSequence, int iLocalPose ) const +{ + if (m_pVModel == NULL) + { + return iLocalPose; + } + + if (iLocalPose == -1) + return iLocalPose; + + Assert( m_pVModel ); + + virtualgroup_t *pGroup = &m_pVModel->m_group[ m_pVModel->m_seq[iSequence].group ]; + + return pGroup->masterPose[iLocalPose]; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int CStudioHdr::EntryNode( int iSequence ) +{ + mstudioseqdesc_t &seqdesc = pSeqdesc( iSequence ); + + if (m_pVModel == NULL || seqdesc.localentrynode == 0) + { + return seqdesc.localentrynode; + } + + Assert( m_pVModel ); + + virtualgroup_t *pGroup = &m_pVModel->m_group[ m_pVModel->m_seq[iSequence].group ]; + + return pGroup->masterNode[seqdesc.localentrynode-1]+1; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + + +int CStudioHdr::ExitNode( int iSequence ) +{ + mstudioseqdesc_t &seqdesc = pSeqdesc( iSequence ); + + if (m_pVModel == NULL || seqdesc.localexitnode == 0) + { + return seqdesc.localexitnode; + } + + Assert( m_pVModel ); + + virtualgroup_t *pGroup = &m_pVModel->m_group[ m_pVModel->m_seq[iSequence].group ]; + + return pGroup->masterNode[seqdesc.localexitnode-1]+1; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int CStudioHdr::GetNumAttachments( void ) const +{ + if (m_pVModel == NULL) + { + return m_pStudioHdr->numlocalattachments; + } + + Assert( m_pVModel ); + + return m_pVModel->m_attachment.Count(); +} + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +const mstudioattachment_t &CStudioHdr::pAttachment( int i ) +{ + if (m_pVModel == NULL) + { + return *m_pStudioHdr->pLocalAttachment( i ); + } + + Assert( m_pVModel ); + + const studiohdr_t *pStudioHdr = GroupStudioHdr( m_pVModel->m_attachment[i].group ); + + return *pStudioHdr->pLocalAttachment( m_pVModel->m_attachment[i].index ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int CStudioHdr::GetAttachmentBone( int i ) +{ + if (m_pVModel == 0) + { + return m_pStudioHdr->pLocalAttachment( i )->localbone; + } + + virtualgroup_t *pGroup = &m_pVModel->m_group[ m_pVModel->m_attachment[i].group ]; + const mstudioattachment_t &attachment = pAttachment( i ); + int iBone = pGroup->masterBone[attachment.localbone]; + if (iBone == -1) + return 0; + return iBone; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void CStudioHdr::SetAttachmentBone( int iAttachment, int iBone ) +{ + mstudioattachment_t &attachment = (mstudioattachment_t &)m_pStudioHdr->pAttachment( iAttachment ); + + // remap bone + if (m_pVModel) + { + virtualgroup_t *pGroup = &m_pVModel->m_group[ m_pVModel->m_attachment[iAttachment].group ]; + iBone = pGroup->boneMap[iBone]; + } + attachment.localbone = iBone; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +char *CStudioHdr::pszNodeName( int iNode ) +{ + if (m_pVModel == NULL) + { + return m_pStudioHdr->pszLocalNodeName( iNode ); + } + + if ( m_pVModel->m_node.Count() <= iNode-1 ) + return "Invalid node"; + + const studiohdr_t *pStudioHdr = GroupStudioHdr( m_pVModel->m_node[iNode-1].group ); + + return pStudioHdr->pszLocalNodeName( m_pVModel->m_node[iNode-1].index ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int CStudioHdr::GetTransition( int iFrom, int iTo ) const +{ + if (m_pVModel == NULL) + { + return *m_pStudioHdr->pLocalTransition( (iFrom-1)*m_pStudioHdr->numlocalnodes + (iTo - 1) ); + } + + return iTo; + /* + FIXME: not connected + virtualmodel_t *pVModel = (virtualmodel_t *)GetVirtualModel(); + Assert( pVModel ); + + return pVModel->m_transition.Element( iFrom ).Element( iTo ); + */ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int CStudioHdr::GetActivityListVersion( void ) +{ + if (m_pVModel == NULL) + { + return m_pStudioHdr->activitylistversion; + } + + int version = m_pStudioHdr->activitylistversion; + + int i; + for (i = 1; i < m_pVModel->m_group.Count(); i++) + { + const studiohdr_t *pStudioHdr = GroupStudioHdr( i ); + Assert( pStudioHdr ); + version = min( version, pStudioHdr->activitylistversion ); + } + + return version; +} + +void CStudioHdr::SetActivityListVersion( int version ) +{ + m_pStudioHdr->activitylistversion = version; + + if (m_pVModel == NULL) + { + return; + } + + int i; + for (i = 1; i < m_pVModel->m_group.Count(); i++) + { + const studiohdr_t *pStudioHdr = GroupStudioHdr( i ); + Assert( pStudioHdr ); + pStudioHdr->SetActivityListVersion( version ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +int CStudioHdr::GetEventListVersion( void ) +{ + if (m_pVModel == NULL) + { + return m_pStudioHdr->eventsindexed; + } + + int version = m_pStudioHdr->eventsindexed; + + int i; + for (i = 1; i < m_pVModel->m_group.Count(); i++) + { + const studiohdr_t *pStudioHdr = GroupStudioHdr( i ); + Assert( pStudioHdr ); + version = min( version, pStudioHdr->eventsindexed ); + } + + return version; +} + +void CStudioHdr::SetEventListVersion( int version ) +{ + m_pStudioHdr->eventsindexed = version; + + if (m_pVModel == NULL) + { + return; + } + + int i; + for (i = 1; i < m_pVModel->m_group.Count(); i++) + { + const studiohdr_t *pStudioHdr = GroupStudioHdr( i ); + Assert( pStudioHdr ); + pStudioHdr->eventsindexed = version; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + + +int CStudioHdr::GetNumIKAutoplayLocks( void ) const +{ + if (m_pVModel == NULL) + { + return m_pStudioHdr->numlocalikautoplaylocks; + } + + return m_pVModel->m_iklock.Count(); +} + +const mstudioiklock_t &CStudioHdr::pIKAutoplayLock( int i ) +{ + if (m_pVModel == NULL) + { + return *m_pStudioHdr->pLocalIKAutoplayLock( i ); + } + + const studiohdr_t *pStudioHdr = GroupStudioHdr( m_pVModel->m_iklock[i].group ); + Assert( pStudioHdr ); + return *pStudioHdr->pLocalIKAutoplayLock( m_pVModel->m_iklock[i].index ); +} + +#if 0 +int CStudioHdr::CountAutoplaySequences() const +{ + int count = 0; + for (int i = 0; i < GetNumSeq(); i++) + { + mstudioseqdesc_t &seqdesc = pSeqdesc( i ); + if (seqdesc.flags & STUDIO_AUTOPLAY) + { + count++; + } + } + return count; +} + +int CStudioHdr::CopyAutoplaySequences( unsigned short *pOut, int outCount ) const +{ + int outIndex = 0; + for (int i = 0; i < GetNumSeq() && outIndex < outCount; i++) + { + mstudioseqdesc_t &seqdesc = pSeqdesc( i ); + if (seqdesc.flags & STUDIO_AUTOPLAY) + { + pOut[outIndex] = i; + outIndex++; + } + } + return outIndex; +} + +#endif + +//----------------------------------------------------------------------------- +// Purpose: maps local sequence bone to global bone +//----------------------------------------------------------------------------- + +int CStudioHdr::RemapSeqBone( int iSequence, int iLocalBone ) const +{ + // remap bone + if (m_pVModel) + { + const virtualgroup_t *pSeqGroup = m_pVModel->pSeqGroup( iSequence ); + return pSeqGroup->masterBone[iLocalBone]; + } + return iLocalBone; +} + +int CStudioHdr::RemapAnimBone( int iAnim, int iLocalBone ) const +{ + // remap bone + if (m_pVModel) + { + const virtualgroup_t *pAnimGroup = m_pVModel->pAnimGroup( iAnim ); + return pAnimGroup->masterBone[iLocalBone]; + } + return iLocalBone; +} + +// JasonM hack +//ConVar flex_maxrule( "flex_maxrule", "0" ); + + +//----------------------------------------------------------------------------- +// Purpose: run the interpreted FAC's expressions, converting flex_controller +// values into FAC weights +//----------------------------------------------------------------------------- +void CStudioHdr::RunFlexRules( const float *src, float *dest ) +{ + int i, j; + + // FIXME: this shouldn't be needed, flex without rules should be stripped in studiomdl + for (i = 0; i < numflexdesc(); i++) + { + dest[i] = 0; + } + + for (i = 0; i < numflexrules(); i++) + { + float stack[32] = {}; + int k = 0; + mstudioflexrule_t *prule = pFlexRule( i ); + + mstudioflexop_t *pops = prule->iFlexOp( 0 ); +/* + // JasonM hack for flex perf testing... + int nFlexRulesToRun = 0; // 0 means run them all + const char *pszExpression = flex_maxrule.GetString(); + if ( pszExpression ) + { + nFlexRulesToRun = atoi(pszExpression); // 0 will be returned if not a numeric string + } + // end JasonM hack +//*/ + // debugoverlay->AddTextOverlay( GetAbsOrigin() + Vector( 0, 0, 64 ), i + 1, 0, "%2d:%d\n", i, prule->flex ); + + for (j = 0; j < prule->numops; j++) + { + switch (pops->op) + { + case STUDIO_ADD: stack[k-2] = stack[k-2] + stack[k-1]; k--; break; + case STUDIO_SUB: stack[k-2] = stack[k-2] - stack[k-1]; k--; break; + case STUDIO_MUL: stack[k-2] = stack[k-2] * stack[k-1]; k--; break; + case STUDIO_DIV: + if (stack[k-1] > 0.0001) + { + stack[k-2] = stack[k-2] / stack[k-1]; + } + else + { + stack[k-2] = 0; + } + k--; + break; + case STUDIO_NEG: stack[k-1] = -stack[k-1]; break; + case STUDIO_MAX: stack[k-2] = max( stack[k-2], stack[k-1] ); k--; break; + case STUDIO_MIN: stack[k-2] = min( stack[k-2], stack[k-1] ); k--; break; + case STUDIO_CONST: stack[k] = pops->d.value; k++; break; + case STUDIO_FETCH1: + { + int m = pFlexcontroller( (LocalFlexController_t)pops->d.index)->localToGlobal; + stack[k] = src[m]; + k++; + break; + } + case STUDIO_FETCH2: + { + stack[k] = dest[pops->d.index]; k++; break; + } + case STUDIO_COMBO: + { + int m = pops->d.index; + int km = k - m; + for ( int i = km + 1; i < k; ++i ) + { + stack[ km ] *= stack[ i ]; + } + k = k - m + 1; + } + break; + case STUDIO_DOMINATE: + { + int m = pops->d.index; + int km = k - m; + float dv = stack[ km ]; + for ( int i = km + 1; i < k; ++i ) + { + dv *= stack[ i ]; + } + stack[ km - 1 ] *= 1.0f - dv; + k -= m; + } + break; + case STUDIO_2WAY_0: + { + int m = pFlexcontroller( (LocalFlexController_t)pops->d.index )->localToGlobal; + stack[ k ] = RemapValClamped( src[m], -1.0f, 0.0f, 1.0f, 0.0f ); + k++; + } + break; + case STUDIO_2WAY_1: + { + int m = pFlexcontroller( (LocalFlexController_t)pops->d.index )->localToGlobal; + stack[ k ] = RemapValClamped( src[m], 0.0f, 1.0f, 0.0f, 1.0f ); + k++; + } + break; + case STUDIO_NWAY: + { + LocalFlexController_t valueControllerIndex = static_cast< LocalFlexController_t >( (int)stack[ k - 1 ] ); + int m = pFlexcontroller( valueControllerIndex )->localToGlobal; + float flValue = src[ m ]; + int v = pFlexcontroller( (LocalFlexController_t)pops->d.index )->localToGlobal; + + const Vector4D filterRamp( stack[ k - 5 ], stack[ k - 4 ], stack[ k - 3 ], stack[ k - 2 ] ); + + // Apply multicontrol remapping + if ( flValue <= filterRamp.x || flValue >= filterRamp.w ) + { + flValue = 0.0f; + } + else if ( flValue < filterRamp.y ) + { + flValue = RemapValClamped( flValue, filterRamp.x, filterRamp.y, 0.0f, 1.0f ); + } + else if ( flValue > filterRamp.z ) + { + flValue = RemapValClamped( flValue, filterRamp.z, filterRamp.w, 1.0f, 0.0f ); + } + else + { + flValue = 1.0f; + } + + stack[ k - 5 ] = flValue * src[ v ]; + + k -= 4; + } + break; + case STUDIO_DME_LOWER_EYELID: + { + const mstudioflexcontroller_t *const pCloseLidV = pFlexcontroller( (LocalFlexController_t)pops->d.index ); + const float flCloseLidV = RemapValClamped( src[ pCloseLidV->localToGlobal ], pCloseLidV->min, pCloseLidV->max, 0.0f, 1.0f ); + + const mstudioflexcontroller_t *const pCloseLid = pFlexcontroller( static_cast< LocalFlexController_t >( (int)stack[ k - 1 ] ) ); + const float flCloseLid = RemapValClamped( src[ pCloseLid->localToGlobal ], pCloseLid->min, pCloseLid->max, 0.0f, 1.0f ); + + int nBlinkIndex = static_cast< int >( stack[ k - 2 ] ); + float flBlink = 0.0f; + if ( nBlinkIndex >= 0 ) + { + const mstudioflexcontroller_t *const pBlink = pFlexcontroller( static_cast< LocalFlexController_t >( (int)stack[ k - 2 ] ) ); + flBlink = RemapValClamped( src[ pBlink->localToGlobal ], pBlink->min, pBlink->max, 0.0f, 1.0f ); + } + + int nEyeUpDownIndex = static_cast< int >( stack[ k - 3 ] ); + float flEyeUpDown = 0.0f; + if ( nEyeUpDownIndex >= 0 ) + { + const mstudioflexcontroller_t *const pEyeUpDown = pFlexcontroller( static_cast< LocalFlexController_t >( (int)stack[ k - 3 ] ) ); + flEyeUpDown = RemapValClamped( src[ pEyeUpDown->localToGlobal ], pEyeUpDown->min, pEyeUpDown->max, -1.0f, 1.0f ); + } + + if ( flEyeUpDown > 0.0 ) + { + stack [ k - 3 ] = ( 1.0f - flEyeUpDown ) * ( 1.0f - flCloseLidV ) * flCloseLid; + } + else + { + stack [ k - 3 ] = ( 1.0f - flCloseLidV ) * flCloseLid; + } + k -= 2; + } + break; + case STUDIO_DME_UPPER_EYELID: + { + const mstudioflexcontroller_t *const pCloseLidV = pFlexcontroller( (LocalFlexController_t)pops->d.index ); + const float flCloseLidV = RemapValClamped( src[ pCloseLidV->localToGlobal ], pCloseLidV->min, pCloseLidV->max, 0.0f, 1.0f ); + + const mstudioflexcontroller_t *const pCloseLid = pFlexcontroller( static_cast< LocalFlexController_t >( (int)stack[ k - 1 ] ) ); + const float flCloseLid = RemapValClamped( src[ pCloseLid->localToGlobal ], pCloseLid->min, pCloseLid->max, 0.0f, 1.0f ); + + int nBlinkIndex = static_cast< int >( stack[ k - 2 ] ); + float flBlink = 0.0f; + if ( nBlinkIndex >= 0 ) + { + const mstudioflexcontroller_t *const pBlink = pFlexcontroller( static_cast< LocalFlexController_t >( (int)stack[ k - 2 ] ) ); + flBlink = RemapValClamped( src[ pBlink->localToGlobal ], pBlink->min, pBlink->max, 0.0f, 1.0f ); + } + + int nEyeUpDownIndex = static_cast< int >( stack[ k - 3 ] ); + float flEyeUpDown = 0.0f; + if ( nEyeUpDownIndex >= 0 ) + { + const mstudioflexcontroller_t *const pEyeUpDown = pFlexcontroller( static_cast< LocalFlexController_t >( (int)stack[ k - 3 ] ) ); + flEyeUpDown = RemapValClamped( src[ pEyeUpDown->localToGlobal ], pEyeUpDown->min, pEyeUpDown->max, -1.0f, 1.0f ); + } + + if ( flEyeUpDown < 0.0f ) + { + stack [ k - 3 ] = ( 1.0f + flEyeUpDown ) * flCloseLidV * flCloseLid; + } + else + { + stack [ k - 3 ] = flCloseLidV * flCloseLid; + } + k -= 2; + } + break; + } + + pops++; + } + + dest[prule->flex] = stack[0]; +/* + // JasonM hack + if ( nFlexRulesToRun == 0) // 0 means run all rules correctly + { + dest[prule->flex] = stack[0]; + } + else // run only up to nFlexRulesToRun correctly...zero out the rest + { + if ( j < nFlexRulesToRun ) + dest[prule->flex] = stack[0]; + else + dest[prule->flex] = 0.0f; + } + + dest[prule->flex] = 1.0f; +//*/ + // end JasonM hack + + } +} + + + +//----------------------------------------------------------------------------- +// CODE PERTAINING TO ACTIVITY->SEQUENCE MAPPING SUBCLASS +//----------------------------------------------------------------------------- +#define iabs(i) (( (i) >= 0 ) ? (i) : -(i) ) + + +extern void SetActivityForSequence( CStudioHdr *pstudiohdr, int i ); +void CStudioHdr::CActivityToSequenceMapping::Initialize( CStudioHdr * __restrict pstudiohdr ) +{ + // Algorithm: walk through every sequence in the model, determine to which activity + // it corresponds, and keep a count of sequences per activity. Once the total count + // is available, allocate an array large enough to contain them all, update the + // starting indices for every activity's section in the array, and go back through, + // populating the array with its data. + + AssertMsg1( m_pSequenceTuples == NULL, "Tried to double-initialize sequence mapping for %s", pstudiohdr->pszName() ); + if ( m_pSequenceTuples != NULL ) + return; // don't double initialize. + + SetValidationPair(pstudiohdr); + + if ( ! pstudiohdr->SequencesAvailable() ) + return; // nothing to do. + +#if STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE + m_bIsInitialized = true; +#endif + + // Some studio headers have no activities at all. In those + // cases we can avoid a lot of this effort. + bool bFoundOne = false; + + // for each sequence in the header... + const int NumSeq = pstudiohdr->GetNumSeq(); + for ( int i = 0 ; i < NumSeq ; ++i ) + { + const mstudioseqdesc_t &seqdesc = pstudiohdr->pSeqdesc( i ); +#if defined(SERVER_DLL) || defined(CLIENT_DLL) || defined(GAME_DLL) + if (!(seqdesc.flags & STUDIO_ACTIVITY)) + { + // AssertMsg2( false, "Sequence %d on studiohdr %s didn't have its activity initialized!", i, pstudiohdr->pszName() ); + SetActivityForSequence( pstudiohdr, i ); + } +#endif + + // is there an activity associated with this sequence? + if (seqdesc.activity >= 0) + { + bFoundOne = true; + + // look up if we already have an entry. First we need to make a speculative one -- + HashValueType entry(seqdesc.activity, 0, 1, iabs(seqdesc.actweight)); + UtlHashHandle_t handle = m_ActToSeqHash.Find(entry); + if ( m_ActToSeqHash.IsValidHandle(handle) ) + { + // we already have an entry and must update it by incrementing count + HashValueType * __restrict toUpdate = &m_ActToSeqHash.Element(handle); + toUpdate->count += 1; + toUpdate->totalWeight += iabs(seqdesc.actweight); + Assert( toUpdate->totalWeight > 0 ); + } + else + { + // we do not have an entry yet; create one. + m_ActToSeqHash.Insert(entry); + } + } + } + + // if we found nothing, don't bother with any other initialization! + if (!bFoundOne) + return; + + // Now, create starting indices for each activity. For an activity n, + // the starting index is of course the sum of counts [0..n-1]. + register int sequenceCount = 0; + int topActivity = 0; // this will store the highest seen activity number (used later to make an ad hoc map on the stack) + for ( UtlHashHandle_t handle = m_ActToSeqHash.GetFirstHandle() ; + m_ActToSeqHash.IsValidHandle(handle) ; + handle = m_ActToSeqHash.GetNextHandle(handle) ) + { + HashValueType &element = m_ActToSeqHash[handle]; + element.startingIdx = sequenceCount; + sequenceCount += element.count; + topActivity = max(topActivity, element.activityIdx); + } + + + // Allocate the actual array of sequence information. Note the use of restrict; + // this is an important optimization, but means that you must never refer to this + // array through m_pSequenceTuples in the scope of this function. + SequenceTuple * __restrict tupleList = new SequenceTuple[sequenceCount]; + m_pSequenceTuples = tupleList; // save it off -- NEVER USE m_pSequenceTuples in this function! + m_iSequenceTuplesCount = sequenceCount; + + + + // Now we're going to actually populate that list with the relevant data. + // First, create an array on the stack to store how many sequences we've written + // so far for each activity. (This is basically a very simple way of doing a map.) + // This stack may potentially grow very large; so if you have problems with it, + // go to a utlmap or similar structure. + unsigned int allocsize = (topActivity + 1) * sizeof(int); +#define ALIGN_VALUE( val, alignment ) ( ( val + alignment - 1 ) & ~( alignment - 1 ) ) // need macro for constant expression + allocsize = ALIGN_VALUE(allocsize,16); + int * __restrict seqsPerAct = static_cast(stackalloc(allocsize)); + memset(seqsPerAct, 0, allocsize); + + // okay, walk through all the sequences again, and write the relevant data into + // our little table. + for ( int i = 0 ; i < NumSeq ; ++i ) + { + const mstudioseqdesc_t &seqdesc = pstudiohdr->pSeqdesc( i ); + if (seqdesc.activity >= 0) + { + const HashValueType &element = m_ActToSeqHash[m_ActToSeqHash.Find(HashValueType(seqdesc.activity, 0, 0, 0))]; + + // If this assert trips, we've written more sequences per activity than we allocated + // (therefore there must have been a miscount in the first for loop above). + int tupleOffset = seqsPerAct[seqdesc.activity]; + Assert( tupleOffset < element.count ); + + // You might be tempted to collapse this pointer math into a single pointer -- + // don't! the tuple list is marked __restrict above. + (tupleList + element.startingIdx + tupleOffset)->seqnum = i; // store sequence number + (tupleList + element.startingIdx + tupleOffset)->weight = iabs(seqdesc.actweight); + + // We can't have weights of 0 + // Assert( (tupleList + element.startingIdx + tupleOffset)->weight > 0 ); + if ( (tupleList + element.startingIdx + tupleOffset)->weight == 0 ) + { + (tupleList + element.startingIdx + tupleOffset)->weight = 1; + } + + seqsPerAct[seqdesc.activity] += 1; + } + } + +#ifdef DBGFLAG_ASSERT + // double check that we wrote exactly the right number of sequences. + unsigned int chkSequenceCount = 0; + for (int j = 0 ; j <= topActivity ; ++j) + { + chkSequenceCount += seqsPerAct[j]; + } + Assert(chkSequenceCount == m_iSequenceTuplesCount); +#endif + +} + +/// Force Initialize() to occur again, even if it has already occured. +void CStudioHdr::CActivityToSequenceMapping::Reinitialize( CStudioHdr *pstudiohdr ) +{ + m_bIsInitialized = false; + if (m_pSequenceTuples) + { + delete m_pSequenceTuples; + m_pSequenceTuples = NULL; + } + m_ActToSeqHash.RemoveAll(); + + Initialize(pstudiohdr); +} + +// Look up relevant data for an activity's sequences. This isn't terribly efficient, due to the +// load-hit-store on the output parameters, so the most common case -- SelectWeightedSequence -- +// is specially implemented. +const CStudioHdr::CActivityToSequenceMapping::SequenceTuple *CStudioHdr::CActivityToSequenceMapping::GetSequences( int forActivity, int * __restrict outSequenceCount, int * __restrict outTotalWeight ) +{ + // Construct a dummy entry so we can do a hash lookup (the UtlHash does not divorce keys from values) + + HashValueType entry(forActivity, 0, 0, 0); + UtlHashHandle_t handle = m_ActToSeqHash.Find(entry); + + if (m_ActToSeqHash.IsValidHandle(handle)) + { + const HashValueType &element = m_ActToSeqHash[handle]; + const SequenceTuple *retval = m_pSequenceTuples + element.startingIdx; + *outSequenceCount = element.count; + *outTotalWeight = element.totalWeight; + + return retval; + } + else + { + // invalid handle; return NULL. + // this is actually a legit use case, so no need to assert. + return NULL; + } +} + +int CStudioHdr::CActivityToSequenceMapping::NumSequencesForActivity( int forActivity ) +{ + // If this trips, you've called this function on something that doesn't + // have activities. + //Assert(m_pSequenceTuples != NULL); + if ( m_pSequenceTuples == NULL ) + return 0; + + HashValueType entry(forActivity, 0, 0, 0); + UtlHashHandle_t handle = m_ActToSeqHash.Find(entry); + if (m_ActToSeqHash.IsValidHandle(handle)) + { + return m_ActToSeqHash[handle].count; + } + else + { + return 0; + } +} + +// double-check that the data I point to hasn't changed +bool CStudioHdr::CActivityToSequenceMapping::ValidateAgainst( const CStudioHdr * RESTRICT pstudiohdr ) RESTRICT +{ + if (m_bIsInitialized) + { + return m_expectedPStudioHdr == pstudiohdr->GetRenderHdr() && + m_expectedVModel == pstudiohdr->GetVirtualModel(); + } + else + { + return true; // Allow an ordinary initialization to take place without printing a panicky assert. + } +} + +void CStudioHdr::CActivityToSequenceMapping::SetValidationPair( const CStudioHdr *RESTRICT pstudiohdr ) RESTRICT +{ + m_expectedPStudioHdr = pstudiohdr->GetRenderHdr(); + m_expectedVModel = pstudiohdr->GetVirtualModel(); +} \ No newline at end of file diff --git a/sp/src/public/studio.h b/sp/src/public/studio.h new file mode 100644 index 00000000..bcc38d5d --- /dev/null +++ b/sp/src/public/studio.h @@ -0,0 +1,3194 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#ifndef STUDIO_H +#define STUDIO_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "basetypes.h" +#include "mathlib/vector2d.h" +#include "mathlib/vector.h" +#include "mathlib/vector4d.h" +#include "mathlib/compressed_vector.h" +#include "tier0/dbg.h" +#include "tier0/threadtools.h" +#include "mathlib/mathlib.h" +#include "utlvector.h" +#include "utlhash.h" +#include "datamap.h" +#include "generichash.h" +#include "localflexcontroller.h" + + +#define STUDIO_ENABLE_PERF_COUNTERS + +#define STUDIO_SEQUENCE_ACTIVITY_LOOKUPS_ARE_SLOW 0 +// If this is set to 1, then the activity->sequence mapping inside +// the CStudioHdr will not be initialized until the first call to +// SelectWeightedSequence() or HaveSequenceForActivity(). If set +// to zero, the mapping will be initialized from CStudioHdr::Init() +// (itself called from the constructor). +// As of June 4 2007, this was set to 1 because physics, among other +// systems, extemporaneously declares CStudioHdrs inside local function +// scopes without querying their activity/sequence mapping at all. +#define STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE 1 + +//----------------------------------------------------------------------------- +// forward declarations +//----------------------------------------------------------------------------- + +class IMaterial; +class IMesh; +class IMorph; +struct virtualmodel_t; +struct vertexFileHeader_t; +struct thinModelVertices_t; + +namespace OptimizedModel +{ + struct StripHeader_t; +} + + +/* +============================================================================== + +STUDIO MODELS + +Studio models are position independent, so the cache manager can move them. +============================================================================== +*/ + +#define STUDIO_VERSION 48 + +#ifndef _XBOX +#define MAXSTUDIOTRIANGLES 65536 // TODO: tune this +#define MAXSTUDIOVERTS 65536 // TODO: tune this +#define MAXSTUDIOFLEXVERTS 10000 // max number of verts that can be flexed per mesh. TODO: tune this +#else +#define MAXSTUDIOTRIANGLES 25000 +#define MAXSTUDIOVERTS 10000 +#define MAXSTUDIOFLEXVERTS 1000 +#endif +#define MAXSTUDIOSKINS 32 // total textures +#define MAXSTUDIOBONES 128 // total bones actually used +#define MAXSTUDIOFLEXDESC 1024 // maximum number of low level flexes (actual morph targets) +#define MAXSTUDIOFLEXCTRL 96 // maximum number of flexcontrollers (input sliders) +#define MAXSTUDIOPOSEPARAM 24 +#define MAXSTUDIOBONECTRLS 4 +#define MAXSTUDIOANIMBLOCKS 256 + +#define MAXSTUDIOBONEBITS 7 // NOTE: MUST MATCH MAXSTUDIOBONES + +// NOTE!!! : Changing this number also changes the vtx file format!!!!! +#define MAX_NUM_BONES_PER_VERT 3 + +//Adrian - Remove this when we completely phase out the old event system. +#define NEW_EVENT_STYLE ( 1 << 10 ) + +struct mstudiodata_t +{ + int count; + int offset; +}; + +#define STUDIO_PROC_AXISINTERP 1 +#define STUDIO_PROC_QUATINTERP 2 +#define STUDIO_PROC_AIMATBONE 3 +#define STUDIO_PROC_AIMATATTACH 4 +#define STUDIO_PROC_JIGGLE 5 + +struct mstudioaxisinterpbone_t +{ + DECLARE_BYTESWAP_DATADESC(); + int control;// local transformation of this bone used to calc 3 point blend + int axis; // axis to check + Vector pos[6]; // X+, X-, Y+, Y-, Z+, Z- + Quaternion quat[6];// X+, X-, Y+, Y-, Z+, Z- + + mstudioaxisinterpbone_t(){} +private: + // No copy constructors allowed + mstudioaxisinterpbone_t(const mstudioaxisinterpbone_t& vOther); +}; + + +struct mstudioquatinterpinfo_t +{ + DECLARE_BYTESWAP_DATADESC(); + float inv_tolerance; // 1 / radian angle of trigger influence + Quaternion trigger; // angle to match + Vector pos; // new position + Quaternion quat; // new angle + + mstudioquatinterpinfo_t(){} +private: + // No copy constructors allowed + mstudioquatinterpinfo_t(const mstudioquatinterpinfo_t& vOther); +}; + +struct mstudioquatinterpbone_t +{ + DECLARE_BYTESWAP_DATADESC(); + int control;// local transformation to check + int numtriggers; + int triggerindex; + inline mstudioquatinterpinfo_t *pTrigger( int i ) const { return (mstudioquatinterpinfo_t *)(((byte *)this) + triggerindex) + i; }; + + mstudioquatinterpbone_t(){} +private: + // No copy constructors allowed + mstudioquatinterpbone_t(const mstudioquatinterpbone_t& vOther); +}; + + +#define JIGGLE_IS_FLEXIBLE 0x01 +#define JIGGLE_IS_RIGID 0x02 +#define JIGGLE_HAS_YAW_CONSTRAINT 0x04 +#define JIGGLE_HAS_PITCH_CONSTRAINT 0x08 +#define JIGGLE_HAS_ANGLE_CONSTRAINT 0x10 +#define JIGGLE_HAS_LENGTH_CONSTRAINT 0x20 +#define JIGGLE_HAS_BASE_SPRING 0x40 +#define JIGGLE_IS_BOING 0x80 // simple squash and stretch sinusoid "boing" + +struct mstudiojigglebone_t +{ + DECLARE_BYTESWAP_DATADESC(); + + int flags; + + // general params + float length; // how from from bone base, along bone, is tip + float tipMass; + + // flexible params + float yawStiffness; + float yawDamping; + float pitchStiffness; + float pitchDamping; + float alongStiffness; + float alongDamping; + + // angle constraint + float angleLimit; // maximum deflection of tip in radians + + // yaw constraint + float minYaw; // in radians + float maxYaw; // in radians + float yawFriction; + float yawBounce; + + // pitch constraint + float minPitch; // in radians + float maxPitch; // in radians + float pitchFriction; + float pitchBounce; + + // base spring + float baseMass; + float baseStiffness; + float baseDamping; + float baseMinLeft; + float baseMaxLeft; + float baseLeftFriction; + float baseMinUp; + float baseMaxUp; + float baseUpFriction; + float baseMinForward; + float baseMaxForward; + float baseForwardFriction; + + // boing + float boingImpactSpeed; + float boingImpactAngle; + float boingDampingRate; + float boingFrequency; + float boingAmplitude; + +private: + // No copy constructors allowed + //mstudiojigglebone_t(const mstudiojigglebone_t& vOther); +}; + +struct mstudioaimatbone_t +{ + DECLARE_BYTESWAP_DATADESC(); + + int parent; + int aim; // Might be bone or attach + Vector aimvector; + Vector upvector; + Vector basepos; + + mstudioaimatbone_t() {} +private: + // No copy constructors allowed + mstudioaimatbone_t(const mstudioaimatbone_t& vOther); +}; + +// bones +struct mstudiobone_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char * const pszName( void ) const { return ((char *)this) + sznameindex; } + int parent; // parent bone + int bonecontroller[6]; // bone controller index, -1 == none + + // default values + Vector pos; + Quaternion quat; + RadianEuler rot; + // compression scale + Vector posscale; + Vector rotscale; + + matrix3x4_t poseToBone; + Quaternion qAlignment; + int flags; + int proctype; + int procindex; // procedural rule + mutable int physicsbone; // index into physically simulated bone + inline void *pProcedure( ) const { if (procindex == 0) return NULL; else return (void *)(((byte *)this) + procindex); }; + int surfacepropidx; // index into string tablefor property name + inline char * const pszSurfaceProp( void ) const { return ((char *)this) + surfacepropidx; } + int contents; // See BSPFlags.h for the contents flags + + int unused[8]; // remove as appropriate + + mstudiobone_t(){} +private: + // No copy constructors allowed + mstudiobone_t(const mstudiobone_t& vOther); +}; + +struct mstudiolinearbone_t +{ + DECLARE_BYTESWAP_DATADESC(); + + int numbones; + + int flagsindex; + inline int flags( int i ) const { Assert( i >= 0 && i < numbones); return *((int *)(((byte *)this) + flagsindex) + i); }; + inline int *pflags( int i ) { Assert( i >= 0 && i < numbones); return ((int *)(((byte *)this) + flagsindex) + i); }; + + int parentindex; + inline int parent( int i ) const { Assert( i >= 0 && i < numbones); return *((int *)(((byte *)this) + parentindex) + i); }; + + int posindex; + inline Vector pos( int i ) const { Assert( i >= 0 && i < numbones); return *((Vector *)(((byte *)this) + posindex) + i); }; + + int quatindex; + inline Quaternion quat( int i ) const { Assert( i >= 0 && i < numbones); return *((Quaternion *)(((byte *)this) + quatindex) + i); }; + + int rotindex; + inline RadianEuler rot( int i ) const { Assert( i >= 0 && i < numbones); return *((RadianEuler *)(((byte *)this) + rotindex) + i); }; + + int posetoboneindex; + inline matrix3x4_t poseToBone( int i ) const { Assert( i >= 0 && i < numbones); return *((matrix3x4_t *)(((byte *)this) + posetoboneindex) + i); }; + + int posscaleindex; + inline Vector posscale( int i ) const { Assert( i >= 0 && i < numbones); return *((Vector *)(((byte *)this) + posscaleindex) + i); }; + + int rotscaleindex; + inline Vector rotscale( int i ) const { Assert( i >= 0 && i < numbones); return *((Vector *)(((byte *)this) + rotscaleindex) + i); }; + + int qalignmentindex; + inline Quaternion qalignment( int i ) const { Assert( i >= 0 && i < numbones); return *((Quaternion *)(((byte *)this) + qalignmentindex) + i); }; + + int unused[6]; + + mstudiolinearbone_t(){} +private: + // No copy constructors allowed + mstudiolinearbone_t(const mstudiolinearbone_t& vOther); +}; + + +//----------------------------------------------------------------------------- +// The component of the bone used by mstudioboneflexdriver_t +//----------------------------------------------------------------------------- +enum StudioBoneFlexComponent_t +{ + STUDIO_BONE_FLEX_INVALID = -1, // Invalid + STUDIO_BONE_FLEX_TX = 0, // Translate X + STUDIO_BONE_FLEX_TY = 1, // Translate Y + STUDIO_BONE_FLEX_TZ = 2 // Translate Z +}; + + +//----------------------------------------------------------------------------- +// Component is one of Translate X, Y or Z [0,2] (StudioBoneFlexComponent_t) +//----------------------------------------------------------------------------- +struct mstudioboneflexdrivercontrol_t +{ + DECLARE_BYTESWAP_DATADESC(); + + int m_nBoneComponent; // Bone component that drives flex, StudioBoneFlexComponent_t + int m_nFlexControllerIndex; // Flex controller to drive + float m_flMin; // Min value of bone component mapped to 0 on flex controller + float m_flMax; // Max value of bone component mapped to 1 on flex controller + + mstudioboneflexdrivercontrol_t(){} +private: + // No copy constructors allowed + mstudioboneflexdrivercontrol_t( const mstudioboneflexdrivercontrol_t &vOther ); +}; + + +//----------------------------------------------------------------------------- +// Drive flex controllers from bone components +//----------------------------------------------------------------------------- +struct mstudioboneflexdriver_t +{ + DECLARE_BYTESWAP_DATADESC(); + + int m_nBoneIndex; // Bone to drive flex controller + int m_nControlCount; // Number of flex controllers being driven + int m_nControlIndex; // Index into data where controllers are (relative to this) + + inline mstudioboneflexdrivercontrol_t *pBoneFlexDriverControl( int i ) const + { + Assert( i >= 0 && i < m_nControlCount ); + return (mstudioboneflexdrivercontrol_t *)(((byte *)this) + m_nControlIndex) + i; + } + + int unused[3]; + + mstudioboneflexdriver_t(){} +private: + // No copy constructors allowed + mstudioboneflexdriver_t( const mstudioboneflexdriver_t &vOther ); +}; + + +#define BONE_CALCULATE_MASK 0x1F +#define BONE_PHYSICALLY_SIMULATED 0x01 // bone is physically simulated when physics are active +#define BONE_PHYSICS_PROCEDURAL 0x02 // procedural when physics is active +#define BONE_ALWAYS_PROCEDURAL 0x04 // bone is always procedurally animated +#define BONE_SCREEN_ALIGN_SPHERE 0x08 // bone aligns to the screen, not constrained in motion. +#define BONE_SCREEN_ALIGN_CYLINDER 0x10 // bone aligns to the screen, constrained by it's own axis. + +#define BONE_USED_MASK 0x0007FF00 +#define BONE_USED_BY_ANYTHING 0x0007FF00 +#define BONE_USED_BY_HITBOX 0x00000100 // bone (or child) is used by a hit box +#define BONE_USED_BY_ATTACHMENT 0x00000200 // bone (or child) is used by an attachment point +#define BONE_USED_BY_VERTEX_MASK 0x0003FC00 +#define BONE_USED_BY_VERTEX_LOD0 0x00000400 // bone (or child) is used by the toplevel model via skinned vertex +#define BONE_USED_BY_VERTEX_LOD1 0x00000800 +#define BONE_USED_BY_VERTEX_LOD2 0x00001000 +#define BONE_USED_BY_VERTEX_LOD3 0x00002000 +#define BONE_USED_BY_VERTEX_LOD4 0x00004000 +#define BONE_USED_BY_VERTEX_LOD5 0x00008000 +#define BONE_USED_BY_VERTEX_LOD6 0x00010000 +#define BONE_USED_BY_VERTEX_LOD7 0x00020000 +#define BONE_USED_BY_BONE_MERGE 0x00040000 // bone is available for bone merge to occur against it + +#define BONE_USED_BY_VERTEX_AT_LOD(lod) ( BONE_USED_BY_VERTEX_LOD0 << (lod) ) +#define BONE_USED_BY_ANYTHING_AT_LOD(lod) ( ( BONE_USED_BY_ANYTHING & ~BONE_USED_BY_VERTEX_MASK ) | BONE_USED_BY_VERTEX_AT_LOD(lod) ) + +#define MAX_NUM_LODS 8 + +#define BONE_TYPE_MASK 0x00F00000 +#define BONE_FIXED_ALIGNMENT 0x00100000 // bone can't spin 360 degrees, all interpolation is normalized around a fixed orientation + +#define BONE_HAS_SAVEFRAME_POS 0x00200000 // Vector48 +#define BONE_HAS_SAVEFRAME_ROT 0x00400000 // Quaternion64 + +// bone controllers +struct mstudiobonecontroller_t +{ + DECLARE_BYTESWAP_DATADESC(); + int bone; // -1 == 0 + int type; // X, Y, Z, XR, YR, ZR, M + float start; + float end; + int rest; // byte index value at rest + int inputfield; // 0-3 user set controller, 4 mouth + int unused[8]; +}; + +// intersection boxes +struct mstudiobbox_t +{ + DECLARE_BYTESWAP_DATADESC(); + int bone; + int group; // intersection group + Vector bbmin; // bounding box + Vector bbmax; + int szhitboxnameindex; // offset to the name of the hitbox. + int unused[8]; + + const char* pszHitboxName() + { + if( szhitboxnameindex == 0 ) + return ""; + + return ((const char*)this) + szhitboxnameindex; + } + + mstudiobbox_t() {} + +private: + // No copy constructors allowed + mstudiobbox_t(const mstudiobbox_t& vOther); +}; + +// demand loaded sequence groups +struct mstudiomodelgroup_t +{ + DECLARE_BYTESWAP_DATADESC(); + int szlabelindex; // textual name + inline char * const pszLabel( void ) const { return ((char *)this) + szlabelindex; } + int sznameindex; // file name + inline char * const pszName( void ) const { return ((char *)this) + sznameindex; } +}; + +struct mstudiomodelgrouplookup_t +{ + int modelgroup; + int indexwithingroup; +}; + +// events +struct mstudioevent_t +{ + DECLARE_BYTESWAP_DATADESC(); + float cycle; + int event; + int type; + inline const char * pszOptions( void ) const { return options; } + char options[64]; + + int szeventindex; + inline char * const pszEventName( void ) const { return ((char *)this) + szeventindex; } +}; + +#define ATTACHMENT_FLAG_WORLD_ALIGN 0x10000 + +// attachment +struct mstudioattachment_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char * const pszName( void ) const { return ((char *)this) + sznameindex; } + unsigned int flags; + int localbone; + matrix3x4_t local; // attachment point + int unused[8]; +}; + +#define IK_SELF 1 +#define IK_WORLD 2 +#define IK_GROUND 3 +#define IK_RELEASE 4 +#define IK_ATTACHMENT 5 +#define IK_UNLATCH 6 + +struct mstudioikerror_t +{ + DECLARE_BYTESWAP_DATADESC(); + Vector pos; + Quaternion q; + + mstudioikerror_t() {} + +private: + // No copy constructors allowed + mstudioikerror_t(const mstudioikerror_t& vOther); +}; + +union mstudioanimvalue_t; + +struct mstudiocompressedikerror_t +{ + DECLARE_BYTESWAP_DATADESC(); + float scale[6]; + short offset[6]; + inline mstudioanimvalue_t *pAnimvalue( int i ) const { if (offset[i] > 0) return (mstudioanimvalue_t *)(((byte *)this) + offset[i]); else return NULL; }; + mstudiocompressedikerror_t(){} + +private: + // No copy constructors allowed + mstudiocompressedikerror_t(const mstudiocompressedikerror_t& vOther); +}; + +struct mstudioikrule_t +{ + DECLARE_BYTESWAP_DATADESC(); + int index; + + int type; + int chain; + + int bone; + + int slot; // iktarget slot. Usually same as chain. + float height; + float radius; + float floor; + Vector pos; + Quaternion q; + + int compressedikerrorindex; + inline mstudiocompressedikerror_t *pCompressedError() const { return (mstudiocompressedikerror_t *)(((byte *)this) + compressedikerrorindex); }; + int unused2; + + int iStart; + int ikerrorindex; + inline mstudioikerror_t *pError( int i ) const { return (ikerrorindex) ? (mstudioikerror_t *)(((byte *)this) + ikerrorindex) + (i - iStart) : NULL; }; + + float start; // beginning of influence + float peak; // start of full influence + float tail; // end of full influence + float end; // end of all influence + + float unused3; // + float contact; // frame footstep makes ground concact + float drop; // how far down the foot should drop when reaching for IK + float top; // top of the foot box + + int unused6; + int unused7; + int unused8; + + int szattachmentindex; // name of world attachment + inline char * const pszAttachment( void ) const { return ((char *)this) + szattachmentindex; } + + int unused[7]; + + mstudioikrule_t() {} + +private: + // No copy constructors allowed + mstudioikrule_t(const mstudioikrule_t& vOther); +}; + + +struct mstudioiklock_t +{ + DECLARE_BYTESWAP_DATADESC(); + int chain; + float flPosWeight; + float flLocalQWeight; + int flags; + + int unused[4]; +}; + + +struct mstudiolocalhierarchy_t +{ + DECLARE_BYTESWAP_DATADESC(); + int iBone; // bone being adjusted + int iNewParent; // the bones new parent + + float start; // beginning of influence + float peak; // start of full influence + float tail; // end of full influence + float end; // end of all influence + + int iStart; // first frame + + int localanimindex; + inline mstudiocompressedikerror_t *pLocalAnim() const { return (mstudiocompressedikerror_t *)(((byte *)this) + localanimindex); }; + + int unused[4]; +}; + + + +// animation frames +union mstudioanimvalue_t +{ + struct + { + byte valid; + byte total; + } num; + short value; +}; + +struct mstudioanim_valueptr_t +{ + DECLARE_BYTESWAP_DATADESC(); + short offset[3]; + inline mstudioanimvalue_t *pAnimvalue( int i ) const { if (offset[i] > 0) return (mstudioanimvalue_t *)(((byte *)this) + offset[i]); else return NULL; }; +}; + +#define STUDIO_ANIM_RAWPOS 0x01 // Vector48 +#define STUDIO_ANIM_RAWROT 0x02 // Quaternion48 +#define STUDIO_ANIM_ANIMPOS 0x04 // mstudioanim_valueptr_t +#define STUDIO_ANIM_ANIMROT 0x08 // mstudioanim_valueptr_t +#define STUDIO_ANIM_DELTA 0x10 +#define STUDIO_ANIM_RAWROT2 0x20 // Quaternion64 + + +// per bone per animation DOF and weight pointers +struct mstudioanim_t +{ + DECLARE_BYTESWAP_DATADESC(); + byte bone; + byte flags; // weighing options + + // valid for animating data only + inline byte *pData( void ) const { return (((byte *)this) + sizeof( struct mstudioanim_t )); }; + inline mstudioanim_valueptr_t *pRotV( void ) const { return (mstudioanim_valueptr_t *)(pData()); }; + inline mstudioanim_valueptr_t *pPosV( void ) const { return (mstudioanim_valueptr_t *)(pData()) + ((flags & STUDIO_ANIM_ANIMROT) != 0); }; + + // valid if animation unvaring over timeline + inline Quaternion48 *pQuat48( void ) const { return (Quaternion48 *)(pData()); }; + inline Quaternion64 *pQuat64( void ) const { return (Quaternion64 *)(pData()); }; + inline Vector48 *pPos( void ) const { return (Vector48 *)(pData() + ((flags & STUDIO_ANIM_RAWROT) != 0) * sizeof( *pQuat48() ) + ((flags & STUDIO_ANIM_RAWROT2) != 0) * sizeof( *pQuat64() ) ); }; + + short nextoffset; + inline mstudioanim_t *pNext( void ) const { if (nextoffset != 0) return (mstudioanim_t *)(((byte *)this) + nextoffset); else return NULL; }; +}; + +struct mstudiomovement_t +{ + DECLARE_BYTESWAP_DATADESC(); + int endframe; + int motionflags; + float v0; // velocity at start of block + float v1; // velocity at end of block + float angle; // YAW rotation at end of this blocks movement + Vector vector; // movement vector relative to this blocks initial angle + Vector position; // relative to start of animation??? + + mstudiomovement_t(){} +private: + // No copy constructors allowed + mstudiomovement_t(const mstudiomovement_t& vOther); +}; + +struct studiohdr_t; + +// used for piecewise loading of animation data +struct mstudioanimblock_t +{ + DECLARE_BYTESWAP_DATADESC(); + int datastart; + int dataend; +}; + +struct mstudioanimsections_t +{ + DECLARE_BYTESWAP_DATADESC(); + int animblock; + int animindex; +}; + +struct mstudioanimdesc_t +{ + DECLARE_BYTESWAP_DATADESC(); + int baseptr; + inline studiohdr_t *pStudiohdr( void ) const { return (studiohdr_t *)(((byte *)this) + baseptr); } + + int sznameindex; + inline char * const pszName( void ) const { return ((char *)this) + sznameindex; } + + float fps; // frames per second + int flags; // looping/non-looping flags + + int numframes; + + // piecewise movement + int nummovements; + int movementindex; + inline mstudiomovement_t * const pMovement( int i ) const { return (mstudiomovement_t *)(((byte *)this) + movementindex) + i; }; + + int unused1[6]; // remove as appropriate (and zero if loading older versions) + + int animblock; + int animindex; // non-zero when anim data isn't in sections + mstudioanim_t *pAnimBlock( int block, int index ) const; // returns pointer to a specific anim block (local or external) + mstudioanim_t *pAnim( int *piFrame, float &flStall ) const; // returns pointer to data and new frame index + mstudioanim_t *pAnim( int *piFrame ) const; // returns pointer to data and new frame index + + int numikrules; + int ikruleindex; // non-zero when IK data is stored in the mdl + int animblockikruleindex; // non-zero when IK data is stored in animblock file + mstudioikrule_t *pIKRule( int i ) const; + + int numlocalhierarchy; + int localhierarchyindex; + mstudiolocalhierarchy_t *pHierarchy( int i ) const; + + int sectionindex; + int sectionframes; // number of frames used in each fast lookup section, zero if not used + inline mstudioanimsections_t * const pSection( int i ) const { return (mstudioanimsections_t *)(((byte *)this) + sectionindex) + i; } + + short zeroframespan; // frames per span + short zeroframecount; // number of spans + int zeroframeindex; + byte *pZeroFrameData( ) const { if (zeroframeindex) return (((byte *)this) + zeroframeindex); else return NULL; }; + mutable float zeroframestalltime; // saved during read stalls + + mstudioanimdesc_t(){} +private: + // No copy constructors allowed + mstudioanimdesc_t(const mstudioanimdesc_t& vOther); +}; + +struct mstudioikrule_t; + +struct mstudioautolayer_t +{ + DECLARE_BYTESWAP_DATADESC(); +//private: + short iSequence; + short iPose; +//public: + int flags; + float start; // beginning of influence + float peak; // start of full influence + float tail; // end of full influence + float end; // end of all influence +}; + +// sequence descriptions +struct mstudioseqdesc_t +{ + DECLARE_BYTESWAP_DATADESC(); + int baseptr; + inline studiohdr_t *pStudiohdr( void ) const { return (studiohdr_t *)(((byte *)this) + baseptr); } + + int szlabelindex; + inline char * const pszLabel( void ) const { return ((char *)this) + szlabelindex; } + + int szactivitynameindex; + inline char * const pszActivityName( void ) const { return ((char *)this) + szactivitynameindex; } + + int flags; // looping/non-looping flags + + int activity; // initialized at loadtime to game DLL values + int actweight; + + int numevents; + int eventindex; + inline mstudioevent_t *pEvent( int i ) const { Assert( i >= 0 && i < numevents); return (mstudioevent_t *)(((byte *)this) + eventindex) + i; }; + + Vector bbmin; // per sequence bounding box + Vector bbmax; + + int numblends; + + // Index into array of shorts which is groupsize[0] x groupsize[1] in length + int animindexindex; + + inline int anim( int x, int y ) const + { + if ( x >= groupsize[0] ) + { + x = groupsize[0] - 1; + } + + if ( y >= groupsize[1] ) + { + y = groupsize[ 1 ] - 1; + } + + int offset = y * groupsize[0] + x; + short *blends = (short *)(((byte *)this) + animindexindex); + int value = (int)blends[ offset ]; + return value; + } + + int movementindex; // [blend] float array for blended movement + int groupsize[2]; + int paramindex[2]; // X, Y, Z, XR, YR, ZR + float paramstart[2]; // local (0..1) starting value + float paramend[2]; // local (0..1) ending value + int paramparent; + + float fadeintime; // ideal cross fate in time (0.2 default) + float fadeouttime; // ideal cross fade out time (0.2 default) + + int localentrynode; // transition node at entry + int localexitnode; // transition node at exit + int nodeflags; // transition rules + + float entryphase; // used to match entry gait + float exitphase; // used to match exit gait + + float lastframe; // frame that should generation EndOfSequence + + int nextseq; // auto advancing sequences + int pose; // index of delta animation between end and nextseq + + int numikrules; + + int numautolayers; // + int autolayerindex; + inline mstudioautolayer_t *pAutolayer( int i ) const { Assert( i >= 0 && i < numautolayers); return (mstudioautolayer_t *)(((byte *)this) + autolayerindex) + i; }; + + int weightlistindex; + inline float *pBoneweight( int i ) const { return ((float *)(((byte *)this) + weightlistindex) + i); }; + inline float weight( int i ) const { return *(pBoneweight( i)); }; + + // FIXME: make this 2D instead of 2x1D arrays + int posekeyindex; + float *pPoseKey( int iParam, int iAnim ) const { return (float *)(((byte *)this) + posekeyindex) + iParam * groupsize[0] + iAnim; } + float poseKey( int iParam, int iAnim ) const { return *(pPoseKey( iParam, iAnim )); } + + int numiklocks; + int iklockindex; + inline mstudioiklock_t *pIKLock( int i ) const { Assert( i >= 0 && i < numiklocks); return (mstudioiklock_t *)(((byte *)this) + iklockindex) + i; }; + + // Key values + int keyvalueindex; + int keyvaluesize; + inline const char * KeyValueText( void ) const { return keyvaluesize != 0 ? ((char *)this) + keyvalueindex : NULL; } + + int cycleposeindex; // index of pose parameter to use as cycle index + + int unused[7]; // remove/add as appropriate (grow back to 8 ints on version change!) + + mstudioseqdesc_t(){} +private: + // No copy constructors allowed + mstudioseqdesc_t(const mstudioseqdesc_t& vOther); +}; + + +struct mstudioposeparamdesc_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char * const pszName( void ) const { return ((char *)this) + sznameindex; } + int flags; // ???? + float start; // starting value + float end; // ending value + float loop; // looping range, 0 for no looping, 360 for rotations, etc. +}; + +struct mstudioflexdesc_t +{ + DECLARE_BYTESWAP_DATADESC(); + int szFACSindex; + inline char * const pszFACS( void ) const { return ((char *)this) + szFACSindex; } +}; + + + +struct mstudioflexcontroller_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sztypeindex; + inline char * const pszType( void ) const { return ((char *)this) + sztypeindex; } + int sznameindex; + inline char * const pszName( void ) const { return ((char *)this) + sznameindex; } + mutable int localToGlobal; // remapped at load time to master list + float min; + float max; +}; + + +enum FlexControllerRemapType_t +{ + FLEXCONTROLLER_REMAP_PASSTHRU = 0, + FLEXCONTROLLER_REMAP_2WAY, // Control 0 -> ramps from 1-0 from 0->0.5. Control 1 -> ramps from 0-1 from 0.5->1 + FLEXCONTROLLER_REMAP_NWAY, // StepSize = 1 / (control count-1) Control n -> ramps from 0-1-0 from (n-1)*StepSize to n*StepSize to (n+1)*StepSize. A second control is needed to specify amount to use + FLEXCONTROLLER_REMAP_EYELID +}; + + +class CStudioHdr; +struct mstudioflexcontrollerui_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char * const pszName( void ) const { return ((char *)this) + sznameindex; } + + // These are used like a union to save space + // Here are the possible configurations for a UI controller + // + // SIMPLE NON-STEREO: 0: control 1: unused 2: unused + // STEREO: 0: left 1: right 2: unused + // NWAY NON-STEREO: 0: control 1: unused 2: value + // NWAY STEREO: 0: left 1: right 2: value + + int szindex0; + int szindex1; + int szindex2; + + inline const mstudioflexcontroller_t *pController( void ) const + { + return !stereo ? (mstudioflexcontroller_t *)( (char *)this + szindex0 ) : NULL; + } + inline char * const pszControllerName( void ) const { return !stereo ? pController()->pszName() : NULL; } + inline int controllerIndex( const CStudioHdr &cStudioHdr ) const; + + inline const mstudioflexcontroller_t *pLeftController( void ) const + { + return stereo ? (mstudioflexcontroller_t *)( (char *)this + szindex0 ) : NULL; + } + inline char * const pszLeftName( void ) const { return stereo ? pLeftController()->pszName() : NULL; } + inline int leftIndex( const CStudioHdr &cStudioHdr ) const; + + inline const mstudioflexcontroller_t *pRightController( void ) const + { + return stereo ? (mstudioflexcontroller_t *)( (char *)this + szindex1 ): NULL; + } + inline char * const pszRightName( void ) const { return stereo ? pRightController()->pszName() : NULL; } + inline int rightIndex( const CStudioHdr &cStudioHdr ) const; + + inline const mstudioflexcontroller_t *pNWayValueController( void ) const + { + return remaptype == FLEXCONTROLLER_REMAP_NWAY ? (mstudioflexcontroller_t *)( (char *)this + szindex2 ) : NULL; + } + inline char * const pszNWayValueName( void ) const { return remaptype == FLEXCONTROLLER_REMAP_NWAY ? pNWayValueController()->pszName() : NULL; } + inline int nWayValueIndex( const CStudioHdr &cStudioHdr ) const; + + // Number of controllers this ui description contains, 1, 2 or 3 + inline int Count() const { return ( stereo ? 2 : 1 ) + ( remaptype == FLEXCONTROLLER_REMAP_NWAY ? 1 : 0 ); } + inline const mstudioflexcontroller_t *pController( int index ) const; + + unsigned char remaptype; // See the FlexControllerRemapType_t enum + bool stereo; // Is this a stereo control? + byte unused[2]; +}; + + +// this is the memory image of vertex anims (16-bit fixed point) +struct mstudiovertanim_t +{ + DECLARE_BYTESWAP_DATADESC(); + unsigned short index; + byte speed; // 255/max_length_in_flex + byte side; // 255/left_right + +protected: + // JasonM changing this type a lot, to prefer fixed point 16 bit... + union + { + short delta[3]; + float16 flDelta[3]; + }; + + union + { + short ndelta[3]; + float16 flNDelta[3]; + }; + +public: + inline void ConvertToFixed( float flVertAnimFixedPointScale ) + { + delta[0] = flDelta[0].GetFloat() / flVertAnimFixedPointScale; + delta[1] = flDelta[1].GetFloat() / flVertAnimFixedPointScale; + delta[2] = flDelta[2].GetFloat() / flVertAnimFixedPointScale; + ndelta[0] = flNDelta[0].GetFloat() / flVertAnimFixedPointScale; + ndelta[1] = flNDelta[1].GetFloat() / flVertAnimFixedPointScale; + ndelta[2] = flNDelta[2].GetFloat() / flVertAnimFixedPointScale; + } + + inline Vector GetDeltaFixed( float flVertAnimFixedPointScale ) + { + return Vector( delta[0] * flVertAnimFixedPointScale, delta[1] * flVertAnimFixedPointScale, delta[2] * flVertAnimFixedPointScale ); + } + inline Vector GetNDeltaFixed( float flVertAnimFixedPointScale ) + { + return Vector( ndelta[0] * flVertAnimFixedPointScale, ndelta[1] * flVertAnimFixedPointScale, ndelta[2] * flVertAnimFixedPointScale ); + } + inline void GetDeltaFixed4DAligned( Vector4DAligned *vFillIn, float flVertAnimFixedPointScale ) + { + vFillIn->Set( delta[0] * flVertAnimFixedPointScale, delta[1] * flVertAnimFixedPointScale, delta[2] * flVertAnimFixedPointScale, 0.0f ); + } + inline void GetNDeltaFixed4DAligned( Vector4DAligned *vFillIn, float flVertAnimFixedPointScale ) + { + vFillIn->Set( ndelta[0] * flVertAnimFixedPointScale, ndelta[1] * flVertAnimFixedPointScale, ndelta[2] * flVertAnimFixedPointScale, 0.0f ); + } + inline Vector GetDeltaFloat() + { + return Vector (flDelta[0].GetFloat(), flDelta[1].GetFloat(), flDelta[2].GetFloat()); + } + inline Vector GetNDeltaFloat() + { + return Vector (flNDelta[0].GetFloat(), flNDelta[1].GetFloat(), flNDelta[2].GetFloat()); + } + inline void SetDeltaFixed( const Vector& vInput, float flVertAnimFixedPointScale ) + { + delta[0] = vInput.x / flVertAnimFixedPointScale; + delta[1] = vInput.y / flVertAnimFixedPointScale; + delta[2] = vInput.z / flVertAnimFixedPointScale; + } + inline void SetNDeltaFixed( const Vector& vInputNormal, float flVertAnimFixedPointScale ) + { + ndelta[0] = vInputNormal.x / flVertAnimFixedPointScale; + ndelta[1] = vInputNormal.y / flVertAnimFixedPointScale; + ndelta[2] = vInputNormal.z / flVertAnimFixedPointScale; + } + + // Ick...can also force fp16 data into this structure for writing to file in legacy format... + inline void SetDeltaFloat( const Vector& vInput ) + { + flDelta[0].SetFloat( vInput.x ); + flDelta[1].SetFloat( vInput.y ); + flDelta[2].SetFloat( vInput.z ); + } + inline void SetNDeltaFloat( const Vector& vInputNormal ) + { + flNDelta[0].SetFloat( vInputNormal.x ); + flNDelta[1].SetFloat( vInputNormal.y ); + flNDelta[2].SetFloat( vInputNormal.z ); + } + + class CSortByIndex + { + public: + bool operator()(const mstudiovertanim_t &left, const mstudiovertanim_t & right)const + { + return left.index < right.index; + } + }; + friend class CSortByIndex; + + mstudiovertanim_t(){} +//private: +// No copy constructors allowed, but it's needed for std::sort() +// mstudiovertanim_t(const mstudiovertanim_t& vOther); +}; + + +// this is the memory image of vertex anims (16-bit fixed point) +struct mstudiovertanim_wrinkle_t : public mstudiovertanim_t +{ + DECLARE_BYTESWAP_DATADESC(); + + short wrinkledelta; + + inline void SetWrinkleFixed( float flWrinkle, float flVertAnimFixedPointScale ) + { + int nWrinkleDeltaInt = flWrinkle / flVertAnimFixedPointScale; + wrinkledelta = clamp( nWrinkleDeltaInt, -32767, 32767 ); + } + + inline Vector4D GetDeltaFixed( float flVertAnimFixedPointScale ) + { + return Vector4D( delta[0] * flVertAnimFixedPointScale, delta[1] * flVertAnimFixedPointScale, delta[2] * flVertAnimFixedPointScale, wrinkledelta * flVertAnimFixedPointScale ); + } + + inline void GetDeltaFixed4DAligned( Vector4DAligned *vFillIn, float flVertAnimFixedPointScale ) + { + vFillIn->Set( delta[0] * flVertAnimFixedPointScale, delta[1] * flVertAnimFixedPointScale, delta[2] * flVertAnimFixedPointScale, wrinkledelta * flVertAnimFixedPointScale ); + } + + inline float GetWrinkleDeltaFixed( float flVertAnimFixedPointScale ) + { + return wrinkledelta * flVertAnimFixedPointScale; + } +}; + + +enum StudioVertAnimType_t +{ + STUDIO_VERT_ANIM_NORMAL = 0, + STUDIO_VERT_ANIM_WRINKLE, +}; + +struct mstudioflex_t +{ + DECLARE_BYTESWAP_DATADESC(); + int flexdesc; // input value + + float target0; // zero + float target1; // one + float target2; // one + float target3; // zero + + int numverts; + int vertindex; + + inline mstudiovertanim_t *pVertanim( int i ) const { Assert( vertanimtype == STUDIO_VERT_ANIM_NORMAL ); return (mstudiovertanim_t *)(((byte *)this) + vertindex) + i; }; + inline mstudiovertanim_wrinkle_t *pVertanimWrinkle( int i ) const { Assert( vertanimtype == STUDIO_VERT_ANIM_WRINKLE ); return (mstudiovertanim_wrinkle_t *)(((byte *)this) + vertindex) + i; }; + + inline byte *pBaseVertanim( ) const { return ((byte *)this) + vertindex; }; + inline int VertAnimSizeBytes() const { return ( vertanimtype == STUDIO_VERT_ANIM_NORMAL ) ? sizeof(mstudiovertanim_t) : sizeof(mstudiovertanim_wrinkle_t); } + + int flexpair; // second flex desc + unsigned char vertanimtype; // See StudioVertAnimType_t + unsigned char unusedchar[3]; + int unused[6]; +}; + + +struct mstudioflexop_t +{ + DECLARE_BYTESWAP_DATADESC(); + int op; + union + { + int index; + float value; + } d; +}; + +struct mstudioflexrule_t +{ + DECLARE_BYTESWAP_DATADESC(); + int flex; + int numops; + int opindex; + inline mstudioflexop_t *iFlexOp( int i ) const { return (mstudioflexop_t *)(((byte *)this) + opindex) + i; }; +}; + +// 16 bytes +struct mstudioboneweight_t +{ + DECLARE_BYTESWAP_DATADESC(); + float weight[MAX_NUM_BONES_PER_VERT]; + char bone[MAX_NUM_BONES_PER_VERT]; + byte numbones; + +// byte material; +// short firstref; +// short lastref; +}; + +// NOTE: This is exactly 48 bytes +struct mstudiovertex_t +{ + DECLARE_BYTESWAP_DATADESC(); + mstudioboneweight_t m_BoneWeights; + Vector m_vecPosition; + Vector m_vecNormal; + Vector2D m_vecTexCoord; + + mstudiovertex_t() {} + +private: + // No copy constructors allowed + mstudiovertex_t(const mstudiovertex_t& vOther); +}; + +// skin info +struct mstudiotexture_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char * const pszName( void ) const { return ((char *)this) + sznameindex; } + int flags; + int used; + int unused1; + mutable IMaterial *material; // fixme: this needs to go away . .isn't used by the engine, but is used by studiomdl + mutable void *clientmaterial; // gary, replace with client material pointer if used + + int unused[10]; +}; + +// eyeball +struct mstudioeyeball_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char * const pszName( void ) const { return ((char *)this) + sznameindex; } + int bone; + Vector org; + float zoffset; + float radius; + Vector up; + Vector forward; + int texture; + + int unused1; + float iris_scale; + int unused2; + + int upperflexdesc[3]; // index of raiser, neutral, and lowerer flexdesc that is set by flex controllers + int lowerflexdesc[3]; + float uppertarget[3]; // angle (radians) of raised, neutral, and lowered lid positions + float lowertarget[3]; + + int upperlidflexdesc; // index of flex desc that actual lid flexes look to + int lowerlidflexdesc; + int unused[4]; // These were used before, so not guaranteed to be 0 + bool m_bNonFACS; // Never used before version 44 + char unused3[3]; + int unused4[7]; + + mstudioeyeball_t(){} +private: + // No copy constructors allowed + mstudioeyeball_t(const mstudioeyeball_t& vOther); +}; + + +// ikinfo +struct mstudioiklink_t +{ + DECLARE_BYTESWAP_DATADESC(); + int bone; + Vector kneeDir; // ideal bending direction (per link, if applicable) + Vector unused0; // unused + + mstudioiklink_t(){} +private: + // No copy constructors allowed + mstudioiklink_t(const mstudioiklink_t& vOther); +}; + +struct mstudioikchain_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char * const pszName( void ) const { return ((char *)this) + sznameindex; } + int linktype; + int numlinks; + int linkindex; + inline mstudioiklink_t *pLink( int i ) const { return (mstudioiklink_t *)(((byte *)this) + linkindex) + i; }; + // FIXME: add unused entries +}; + + +struct mstudioiface_t +{ + unsigned short a, b, c; // Indices to vertices +}; + + +struct mstudiomodel_t; + +struct mstudio_modelvertexdata_t +{ + DECLARE_BYTESWAP_DATADESC(); + Vector *Position( int i ) const; + Vector *Normal( int i ) const; + Vector4D *TangentS( int i ) const; + Vector2D *Texcoord( int i ) const; + mstudioboneweight_t *BoneWeights( int i ) const; + mstudiovertex_t *Vertex( int i ) const; + bool HasTangentData( void ) const; + int GetGlobalVertexIndex( int i ) const; + int GetGlobalTangentIndex( int i ) const; + + // base of external vertex data stores + const void *pVertexData; + const void *pTangentData; +}; + +struct mstudio_meshvertexdata_t +{ + DECLARE_BYTESWAP_DATADESC(); + Vector *Position( int i ) const; + Vector *Normal( int i ) const; + Vector4D *TangentS( int i ) const; + Vector2D *Texcoord( int i ) const; + mstudioboneweight_t *BoneWeights( int i ) const; + mstudiovertex_t *Vertex( int i ) const; + bool HasTangentData( void ) const; + int GetModelVertexIndex( int i ) const; + int GetGlobalVertexIndex( int i ) const; + + // indirection to this mesh's model's vertex data + const mstudio_modelvertexdata_t *modelvertexdata; + + // used for fixup calcs when culling top level lods + // expected number of mesh verts at desired lod + int numLODVertexes[MAX_NUM_LODS]; +}; + +struct mstudiomesh_t +{ + DECLARE_BYTESWAP_DATADESC(); + int material; + + int modelindex; + mstudiomodel_t *pModel() const; + + int numvertices; // number of unique vertices/normals/texcoords + int vertexoffset; // vertex mstudiovertex_t + + // Access thin/fat mesh vertex data (only one will return a non-NULL result) + const mstudio_meshvertexdata_t *GetVertexData( void *pModelData = NULL ); + const thinModelVertices_t *GetThinVertexData( void *pModelData = NULL ); + + int numflexes; // vertex animation + int flexindex; + inline mstudioflex_t *pFlex( int i ) const { return (mstudioflex_t *)(((byte *)this) + flexindex) + i; }; + + // special codes for material operations + int materialtype; + int materialparam; + + // a unique ordinal for this mesh + int meshid; + + Vector center; + + mstudio_meshvertexdata_t vertexdata; + + int unused[8]; // remove as appropriate + + mstudiomesh_t(){} +private: + // No copy constructors allowed + mstudiomesh_t(const mstudiomesh_t& vOther); +}; + +// studio models +struct mstudiomodel_t +{ + DECLARE_BYTESWAP_DATADESC(); + inline const char * pszName( void ) const { return name; } + char name[64]; + + int type; + + float boundingradius; + + int nummeshes; + int meshindex; + inline mstudiomesh_t *pMesh( int i ) const { return (mstudiomesh_t *)(((byte *)this) + meshindex) + i; }; + + // cache purposes + int numvertices; // number of unique vertices/normals/texcoords + int vertexindex; // vertex Vector + int tangentsindex; // tangents Vector + + // These functions are defined in application-specific code: + const vertexFileHeader_t *CacheVertexData( void *pModelData ); + + // Access thin/fat mesh vertex data (only one will return a non-NULL result) + const mstudio_modelvertexdata_t *GetVertexData( void *pModelData = NULL ); + const thinModelVertices_t *GetThinVertexData( void *pModelData = NULL ); + + int numattachments; + int attachmentindex; + + int numeyeballs; + int eyeballindex; + inline mstudioeyeball_t *pEyeball( int i ) { return (mstudioeyeball_t *)(((byte *)this) + eyeballindex) + i; }; + + mstudio_modelvertexdata_t vertexdata; + + int unused[8]; // remove as appropriate +}; + +inline bool mstudio_modelvertexdata_t::HasTangentData( void ) const +{ + return (pTangentData != NULL); +} + +inline int mstudio_modelvertexdata_t::GetGlobalVertexIndex( int i ) const +{ + mstudiomodel_t *modelptr = (mstudiomodel_t *)((byte *)this - offsetof(mstudiomodel_t, vertexdata)); + Assert( ( modelptr->vertexindex % sizeof( mstudiovertex_t ) ) == 0 ); + return ( i + ( modelptr->vertexindex / sizeof( mstudiovertex_t ) ) ); +} + +inline int mstudio_modelvertexdata_t::GetGlobalTangentIndex( int i ) const +{ + mstudiomodel_t *modelptr = (mstudiomodel_t *)((byte *)this - offsetof(mstudiomodel_t, vertexdata)); + Assert( ( modelptr->tangentsindex % sizeof( Vector4D ) ) == 0 ); + return ( i + ( modelptr->tangentsindex / sizeof( Vector4D ) ) ); +} + +inline mstudiovertex_t *mstudio_modelvertexdata_t::Vertex( int i ) const +{ + return (mstudiovertex_t *)pVertexData + GetGlobalVertexIndex( i ); +} + +inline Vector *mstudio_modelvertexdata_t::Position( int i ) const +{ + return &Vertex(i)->m_vecPosition; +} + +inline Vector *mstudio_modelvertexdata_t::Normal( int i ) const +{ + return &Vertex(i)->m_vecNormal; +} + +inline Vector4D *mstudio_modelvertexdata_t::TangentS( int i ) const +{ + // NOTE: The tangents vector is 16-bytes in a separate array + // because it only exists on the high end, and if I leave it out + // of the mstudiovertex_t, the vertex is 64-bytes (good for low end) + return (Vector4D *)pTangentData + GetGlobalTangentIndex( i ); +} + +inline Vector2D *mstudio_modelvertexdata_t::Texcoord( int i ) const +{ + return &Vertex(i)->m_vecTexCoord; +} + +inline mstudioboneweight_t *mstudio_modelvertexdata_t::BoneWeights( int i ) const +{ + return &Vertex(i)->m_BoneWeights; +} + +inline mstudiomodel_t *mstudiomesh_t::pModel() const +{ + return (mstudiomodel_t *)(((byte *)this) + modelindex); +} + +inline bool mstudio_meshvertexdata_t::HasTangentData( void ) const +{ + return modelvertexdata->HasTangentData(); +} + +inline const mstudio_meshvertexdata_t *mstudiomesh_t::GetVertexData( void *pModelData ) +{ + // get this mesh's model's vertex data (allow for mstudiomodel_t::GetVertexData + // returning NULL if the data has been converted to 'thin' vertices) + this->pModel()->GetVertexData( pModelData ); + vertexdata.modelvertexdata = &( this->pModel()->vertexdata ); + + if ( !vertexdata.modelvertexdata->pVertexData ) + return NULL; + + return &vertexdata; +} + +inline const thinModelVertices_t * mstudiomesh_t::GetThinVertexData( void *pModelData ) +{ + // get this mesh's model's thin vertex data + return this->pModel()->GetThinVertexData( pModelData ); +} + +inline int mstudio_meshvertexdata_t::GetModelVertexIndex( int i ) const +{ + mstudiomesh_t *meshptr = (mstudiomesh_t *)((byte *)this - offsetof(mstudiomesh_t,vertexdata)); + return meshptr->vertexoffset + i; +} + +inline int mstudio_meshvertexdata_t::GetGlobalVertexIndex( int i ) const +{ + return modelvertexdata->GetGlobalVertexIndex( GetModelVertexIndex( i ) ); +} + +inline Vector *mstudio_meshvertexdata_t::Position( int i ) const +{ + return modelvertexdata->Position( GetModelVertexIndex( i ) ); +}; + +inline Vector *mstudio_meshvertexdata_t::Normal( int i ) const +{ + return modelvertexdata->Normal( GetModelVertexIndex( i ) ); +}; + +inline Vector4D *mstudio_meshvertexdata_t::TangentS( int i ) const +{ + return modelvertexdata->TangentS( GetModelVertexIndex( i ) ); +} + +inline Vector2D *mstudio_meshvertexdata_t::Texcoord( int i ) const +{ + return modelvertexdata->Texcoord( GetModelVertexIndex( i ) ); +}; + +inline mstudioboneweight_t *mstudio_meshvertexdata_t::BoneWeights( int i ) const +{ + return modelvertexdata->BoneWeights( GetModelVertexIndex( i ) ); +}; + +inline mstudiovertex_t *mstudio_meshvertexdata_t::Vertex( int i ) const +{ + return modelvertexdata->Vertex( GetModelVertexIndex( i ) ); +} + +// a group of studio model data +enum studiomeshgroupflags_t +{ + MESHGROUP_IS_FLEXED = 0x1, + MESHGROUP_IS_HWSKINNED = 0x2, + MESHGROUP_IS_DELTA_FLEXED = 0x4 +}; + + +// ---------------------------------------------------------- +// runtime stuff +// ---------------------------------------------------------- + +struct studiomeshgroup_t +{ + IMesh *m_pMesh; + int m_NumStrips; + int m_Flags; // see studiomeshgroupflags_t + OptimizedModel::StripHeader_t *m_pStripData; + unsigned short *m_pGroupIndexToMeshIndex; + int m_NumVertices; + int *m_pUniqueTris; // for performance measurements + unsigned short *m_pIndices; + bool m_MeshNeedsRestore; + short m_ColorMeshID; + IMorph *m_pMorph; + + inline unsigned short MeshIndex( int i ) const { return m_pGroupIndexToMeshIndex[m_pIndices[i]]; } +}; + + +// studio model data +struct studiomeshdata_t +{ + int m_NumGroup; + studiomeshgroup_t* m_pMeshGroup; +}; + +struct studioloddata_t +{ + // not needed - this is really the same as studiohwdata_t.m_NumStudioMeshes + //int m_NumMeshes; + studiomeshdata_t *m_pMeshData; // there are studiohwdata_t.m_NumStudioMeshes of these. + float m_SwitchPoint; + // one of these for each lod since we can switch to simpler materials on lower lods. + int numMaterials; + IMaterial **ppMaterials; /* will have studiohdr_t.numtextures elements allocated */ + // hack - this needs to go away. + int *pMaterialFlags; /* will have studiohdr_t.numtextures elements allocated */ + + // For decals on hardware morphing, we must actually do hardware skinning + // For this to work, we have to hope that the total # of bones used by + // hw flexed verts is < than the max possible for the dx level we're running under + int *m_pHWMorphDecalBoneRemap; + int m_nDecalBoneCount; +}; + +struct studiohwdata_t +{ + int m_RootLOD; // calced and clamped, nonzero for lod culling + int m_NumLODs; + studioloddata_t *m_pLODs; + int m_NumStudioMeshes; + + inline float LODMetric( float unitSphereSize ) const { return ( unitSphereSize != 0.0f ) ? (100.0f / unitSphereSize) : 0.0f; } + inline int GetLODForMetric( float lodMetric ) const + { + if ( !m_NumLODs ) + return 0; + + // shadow lod is specified on the last lod with a negative switch + // never consider shadow lod as viable candidate + int numLODs = (m_pLODs[m_NumLODs-1].m_SwitchPoint < 0.0f) ? m_NumLODs-1 : m_NumLODs; + + for ( int i = m_RootLOD; i < numLODs-1; i++ ) + { + if ( m_pLODs[i+1].m_SwitchPoint > lodMetric ) + return i; + } + + return numLODs-1; + } +}; + +// ---------------------------------------------------------- +// ---------------------------------------------------------- + +// body part index +struct mstudiobodyparts_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char * const pszName( void ) const { return ((char *)this) + sznameindex; } + int nummodels; + int base; + int modelindex; // index into models array + inline mstudiomodel_t *pModel( int i ) const { return (mstudiomodel_t *)(((byte *)this) + modelindex) + i; }; +}; + + +struct mstudiomouth_t +{ + DECLARE_BYTESWAP_DATADESC(); + int bone; + Vector forward; + int flexdesc; + + mstudiomouth_t(){} +private: + // No copy constructors allowed + mstudiomouth_t(const mstudiomouth_t& vOther); +}; + +struct mstudiohitboxset_t +{ + DECLARE_BYTESWAP_DATADESC(); + int sznameindex; + inline char * const pszName( void ) const { return ((char *)this) + sznameindex; } + int numhitboxes; + int hitboxindex; + inline mstudiobbox_t *pHitbox( int i ) const { return (mstudiobbox_t *)(((byte *)this) + hitboxindex) + i; }; +}; + + +//----------------------------------------------------------------------------- +// Src bone transforms are transformations that will convert .dmx or .smd-based animations into .mdl-based animations +// NOTE: The operation you should apply is: pretransform * bone transform * posttransform +//----------------------------------------------------------------------------- +struct mstudiosrcbonetransform_t +{ + DECLARE_BYTESWAP_DATADESC(); + + int sznameindex; + inline const char *pszName( void ) const { return ((char *)this) + sznameindex; } + matrix3x4_t pretransform; + matrix3x4_t posttransform; +}; + + +// ---------------------------------------------------------- +// Purpose: Load time results on model compositing +// ---------------------------------------------------------- + +class virtualgroup_t +{ +public: + virtualgroup_t( void ) { cache = NULL; }; + // tool dependant. In engine this is a model_t, in tool it's a direct pointer + void *cache; + // converts cache entry into a usable studiohdr_t * + const studiohdr_t *GetStudioHdr( void ) const; + + CUtlVector< int > boneMap; // maps global bone to local bone + CUtlVector< int > masterBone; // maps local bone to global bone + CUtlVector< int > masterSeq; // maps local sequence to master sequence + CUtlVector< int > masterAnim; // maps local animation to master animation + CUtlVector< int > masterAttachment; // maps local attachment to global + CUtlVector< int > masterPose; // maps local pose parameter to global + CUtlVector< int > masterNode; // maps local transition nodes to global +}; + +struct virtualsequence_t +{ +#ifdef _XBOX + short flags; + short activity; + short group; + short index; +#else + int flags; + int activity; + int group; + int index; +#endif +}; + +struct virtualgeneric_t +{ +#ifdef _XBOX + short group; + short index; +#else + int group; + int index; +#endif +}; + + +struct virtualmodel_t +{ + void AppendSequences( int group, const studiohdr_t *pStudioHdr ); + void AppendAnimations( int group, const studiohdr_t *pStudioHdr ); + void AppendAttachments( int ground, const studiohdr_t *pStudioHdr ); + void AppendPoseParameters( int group, const studiohdr_t *pStudioHdr ); + void AppendBonemap( int group, const studiohdr_t *pStudioHdr ); + void AppendNodes( int group, const studiohdr_t *pStudioHdr ); + void AppendTransitions( int group, const studiohdr_t *pStudioHdr ); + void AppendIKLocks( int group, const studiohdr_t *pStudioHdr ); + void AppendModels( int group, const studiohdr_t *pStudioHdr ); + void UpdateAutoplaySequences( const studiohdr_t *pStudioHdr ); + + virtualgroup_t *pAnimGroup( int animation ) { return &m_group[ m_anim[ animation ].group ]; } // Note: user must manage mutex for this + virtualgroup_t *pSeqGroup( int sequence ) + { + // Check for out of range access that is causing crashes on some servers. + // Perhaps caused by sourcemod bugs. Typical sequence in these cases is ~292 + // when the count is 234. Using unsigned math allows for free range + // checking against zero. + if ( (unsigned)sequence >= (unsigned)m_seq.Count() ) + { + Assert( 0 ); + return 0; + } + return &m_group[ m_seq[ sequence ].group ]; + } // Note: user must manage mutex for this + + CThreadFastMutex m_Lock; + + CUtlVector< virtualsequence_t > m_seq; + CUtlVector< virtualgeneric_t > m_anim; + CUtlVector< virtualgeneric_t > m_attachment; + CUtlVector< virtualgeneric_t > m_pose; + CUtlVector< virtualgroup_t > m_group; + CUtlVector< virtualgeneric_t > m_node; + CUtlVector< virtualgeneric_t > m_iklock; + CUtlVector< unsigned short > m_autoplaySequences; +}; + +// 'thin' vertex data, used to do model decals (see Studio_CreateThinVertexes()) +struct thinModelVertices_t +{ + void Init( int numBoneInfluences, Vector *positions, unsigned short *normals, float *boneWeights, char *boneIndices ) + { + Assert( positions != NULL ); + Assert( normals != NULL ); + Assert( ( numBoneInfluences >= 0 ) && ( numBoneInfluences <= 3 ) ); + Assert( numBoneInfluences > 0 ? !!boneIndices : !boneIndices ); + Assert( numBoneInfluences > 1 ? !!boneWeights : !boneWeights ); + m_numBoneInfluences = numBoneInfluences; + m_vecPositions = positions; + m_vecNormals = normals; + m_boneWeights = boneWeights; + m_boneIndices = boneIndices; + } + + void SetPosition( int vertIndex, const Vector & position ) + { + Assert( m_vecPositions ); + m_vecPositions[ vertIndex ] = position; + } + + void SetNormal( int vertIndex, const Vector & normal ) + { + Assert( m_vecNormals ); + unsigned int packedNormal; + PackNormal_UBYTE4( normal.x, normal.y, normal.z, &packedNormal ); + m_vecNormals[ vertIndex ] = (unsigned short)( 0x0000FFFF & packedNormal ); + } + + void SetBoneWeights( int vertIndex, const mstudioboneweight_t & boneWeights ) + { + Assert( ( m_numBoneInfluences >= 1 ) && ( m_numBoneInfluences <= 3 ) ); + Assert( ( boneWeights.numbones >= 1 ) && ( boneWeights.numbones <= m_numBoneInfluences ) ); + int numStoredWeights = max( 0, ( m_numBoneInfluences - 1 ) ); + float *pBaseWeight = m_boneWeights + vertIndex*numStoredWeights; + char *pBaseIndex = m_boneIndices + vertIndex*m_numBoneInfluences; + for ( int i = 0; i < m_numBoneInfluences; i++ ) + { + pBaseIndex[i] = boneWeights.bone[i]; + } + for ( int i = 0; i < numStoredWeights; i++ ) + { + pBaseWeight[i] = boneWeights.weight[i]; + } + } + + void GetMeshPosition( mstudiomesh_t *pMesh, int meshIndex, Vector *pPosition ) const + { + Assert( pMesh ); + GetPosition( pMesh->vertexdata.GetGlobalVertexIndex( meshIndex ), pPosition ); + } + + void GetMeshNormal( mstudiomesh_t *pMesh, int meshIndex, Vector *pNormal ) const + { + Assert( pMesh ); + GetNormal( pMesh->vertexdata.GetGlobalVertexIndex( meshIndex ), pNormal ); + } + + void GetMeshBoneWeights( mstudiomesh_t *pMesh, int meshIndex, mstudioboneweight_t *pBoneWeights ) const + { + Assert( pMesh ); + GetBoneWeights( pMesh->vertexdata.GetGlobalVertexIndex( meshIndex ), pBoneWeights ); + } + + void GetModelPosition( mstudiomodel_t *pModel, int modelIndex, Vector *pPosition ) const + { + Assert( pModel ); + GetPosition( pModel->vertexdata.GetGlobalVertexIndex( modelIndex ), pPosition ); + } + + void GetModelNormal( mstudiomodel_t *pModel, int modelIndex, Vector *pNormal ) const + { + Assert( pModel ); + GetNormal( pModel->vertexdata.GetGlobalVertexIndex( modelIndex ), pNormal ); + } + + void GetModelBoneWeights( mstudiomodel_t *pModel, int modelIndex, mstudioboneweight_t *pBoneWeights ) const + { + Assert( pModel ); + GetBoneWeights( pModel->vertexdata.GetGlobalVertexIndex( modelIndex ), pBoneWeights ); + } + +private: + void GetPosition( int vertIndex, Vector *pPosition ) const + { + Assert( pPosition ); + Assert( m_vecPositions ); + *pPosition = m_vecPositions[ vertIndex ]; + } + + void GetNormal( int vertIndex, Vector *pNormal ) const + { + Assert( pNormal ); + Assert( m_vecNormals ); + unsigned int packedNormal = 0x0000FFFF & m_vecNormals[ vertIndex ]; + UnpackNormal_UBYTE4( &packedNormal, pNormal->Base() ); + } + + void GetBoneWeights( int vertIndex, mstudioboneweight_t *pBoneWeights ) const + { + Assert( pBoneWeights ); + Assert( ( m_numBoneInfluences <= 1 ) || ( m_boneWeights != NULL ) ); + Assert( ( m_numBoneInfluences <= 0 ) || ( m_boneIndices != NULL ) ); + int numStoredWeights = max( 0, ( m_numBoneInfluences - 1 ) ); + float *pBaseWeight = m_boneWeights + vertIndex*numStoredWeights; + char *pBaseIndex = m_boneIndices + vertIndex*m_numBoneInfluences; + float sum = 0.0f; + for (int i = 0;i < MAX_NUM_BONES_PER_VERT;i++) + { + if ( i < ( m_numBoneInfluences - 1 ) ) + pBoneWeights->weight[i] = pBaseWeight[i]; + else + pBoneWeights->weight[i] = 1.0f - sum; + sum += pBoneWeights->weight[i]; + + pBoneWeights->bone[i] = ( i < m_numBoneInfluences ) ? pBaseIndex[i] : 0; + } + + // Treat 'zero weights' as '100% binding to bone zero': + pBoneWeights->numbones = m_numBoneInfluences ? m_numBoneInfluences : 1; + } + + int m_numBoneInfluences;// Number of bone influences per vertex, N + float *m_boneWeights; // This array stores (N-1) weights per vertex (unless N is zero) + char *m_boneIndices; // This array stores N indices per vertex + Vector *m_vecPositions; + unsigned short *m_vecNormals; // Normals are compressed into 16 bits apiece (see PackNormal_UBYTE4() ) +}; + +// ---------------------------------------------------------- +// Studio Model Vertex Data File +// Position independent flat data for cache manager +// ---------------------------------------------------------- + +// little-endian "IDSV" +#define MODEL_VERTEX_FILE_ID (('V'<<24)+('S'<<16)+('D'<<8)+'I') +#define MODEL_VERTEX_FILE_VERSION 4 +// this id (IDCV) is used once the vertex data has been compressed (see CMDLCache::CreateThinVertexes) +#define MODEL_VERTEX_FILE_THIN_ID (('V'<<24)+('C'<<16)+('D'<<8)+'I') + +struct vertexFileHeader_t +{ + DECLARE_BYTESWAP_DATADESC(); + int id; // MODEL_VERTEX_FILE_ID + int version; // MODEL_VERTEX_FILE_VERSION + int checksum; // same as studiohdr_t, ensures sync + int numLODs; // num of valid lods + int numLODVertexes[MAX_NUM_LODS]; // num verts for desired root lod + int numFixups; // num of vertexFileFixup_t + int fixupTableStart; // offset from base to fixup table + int vertexDataStart; // offset from base to vertex block + int tangentDataStart; // offset from base to tangent block + +public: + + // Accessor to fat vertex data + const mstudiovertex_t *GetVertexData() const + { + if ( ( id == MODEL_VERTEX_FILE_ID ) && ( vertexDataStart != 0 ) ) + return ( mstudiovertex_t * ) ( vertexDataStart + (byte *)this ); + else + return NULL; + } + // Accessor to (fat) tangent vertex data (tangents aren't stored in compressed data) + const Vector4D *GetTangentData() const + { + if ( ( id == MODEL_VERTEX_FILE_ID ) && ( tangentDataStart != 0 ) ) + return ( Vector4D * ) ( tangentDataStart + (byte *)this ); + else + return NULL; + } + // Accessor to thin vertex data + const thinModelVertices_t *GetThinVertexData() const + { + if ( ( id == MODEL_VERTEX_FILE_THIN_ID ) && ( vertexDataStart != 0 ) ) + return ( thinModelVertices_t * ) ( vertexDataStart + (byte *)this ); + else + return NULL; + } +}; + +// model vertex data accessor (defined here so vertexFileHeader_t can be used) +inline const mstudio_modelvertexdata_t * mstudiomodel_t::GetVertexData( void *pModelData ) +{ + const vertexFileHeader_t * pVertexHdr = CacheVertexData( pModelData ); + if ( !pVertexHdr ) + { + vertexdata.pVertexData = NULL; + vertexdata.pTangentData = NULL; + return NULL; + } + + vertexdata.pVertexData = pVertexHdr->GetVertexData(); + vertexdata.pTangentData = pVertexHdr->GetTangentData(); + + if ( !vertexdata.pVertexData ) + return NULL; + + return &vertexdata; +} + +// model thin vertex data accessor (defined here so vertexFileHeader_t can be used) +inline const thinModelVertices_t * mstudiomodel_t::GetThinVertexData( void *pModelData ) +{ + const vertexFileHeader_t * pVertexHdr = CacheVertexData( pModelData ); + if ( !pVertexHdr ) + return NULL; + + return pVertexHdr->GetThinVertexData(); +} + +// apply sequentially to lod sorted vertex and tangent pools to re-establish mesh order +struct vertexFileFixup_t +{ + DECLARE_BYTESWAP_DATADESC(); + int lod; // used to skip culled root lod + int sourceVertexID; // absolute index from start of vertex/tangent blocks + int numVertexes; +}; + +// This flag is set if no hitbox information was specified +#define STUDIOHDR_FLAGS_AUTOGENERATED_HITBOX ( 1 << 0 ) + +// NOTE: This flag is set at loadtime, not mdl build time so that we don't have to rebuild +// models when we change materials. +#define STUDIOHDR_FLAGS_USES_ENV_CUBEMAP ( 1 << 1 ) + +// Use this when there are translucent parts to the model but we're not going to sort it +#define STUDIOHDR_FLAGS_FORCE_OPAQUE ( 1 << 2 ) + +// Use this when we want to render the opaque parts during the opaque pass +// and the translucent parts during the translucent pass +#define STUDIOHDR_FLAGS_TRANSLUCENT_TWOPASS ( 1 << 3 ) + +// This is set any time the .qc files has $staticprop in it +// Means there's no bones and no transforms +#define STUDIOHDR_FLAGS_STATIC_PROP ( 1 << 4 ) + +// NOTE: This flag is set at loadtime, not mdl build time so that we don't have to rebuild +// models when we change materials. +#define STUDIOHDR_FLAGS_USES_FB_TEXTURE ( 1 << 5 ) + +// This flag is set by studiomdl.exe if a separate "$shadowlod" entry was present +// for the .mdl (the shadow lod is the last entry in the lod list if present) +#define STUDIOHDR_FLAGS_HASSHADOWLOD ( 1 << 6 ) + +// NOTE: This flag is set at loadtime, not mdl build time so that we don't have to rebuild +// models when we change materials. +#define STUDIOHDR_FLAGS_USES_BUMPMAPPING ( 1 << 7 ) + +// NOTE: This flag is set when we should use the actual materials on the shadow LOD +// instead of overriding them with the default one (necessary for translucent shadows) +#define STUDIOHDR_FLAGS_USE_SHADOWLOD_MATERIALS ( 1 << 8 ) + +// NOTE: This flag is set when we should use the actual materials on the shadow LOD +// instead of overriding them with the default one (necessary for translucent shadows) +#define STUDIOHDR_FLAGS_OBSOLETE ( 1 << 9 ) + +#define STUDIOHDR_FLAGS_UNUSED ( 1 << 10 ) + +// NOTE: This flag is set at mdl build time +#define STUDIOHDR_FLAGS_NO_FORCED_FADE ( 1 << 11 ) + +// NOTE: The npc will lengthen the viseme check to always include two phonemes +#define STUDIOHDR_FLAGS_FORCE_PHONEME_CROSSFADE ( 1 << 12 ) + +// This flag is set when the .qc has $constantdirectionallight in it +// If set, we use constantdirectionallightdot to calculate light intensity +// rather than the normal directional dot product +// only valid if STUDIOHDR_FLAGS_STATIC_PROP is also set +#define STUDIOHDR_FLAGS_CONSTANT_DIRECTIONAL_LIGHT_DOT ( 1 << 13 ) + +// Flag to mark delta flexes as already converted from disk format to memory format +#define STUDIOHDR_FLAGS_FLEXES_CONVERTED ( 1 << 14 ) + +// Indicates the studiomdl was built in preview mode +#define STUDIOHDR_FLAGS_BUILT_IN_PREVIEW_MODE ( 1 << 15 ) + +// Ambient boost (runtime flag) +#define STUDIOHDR_FLAGS_AMBIENT_BOOST ( 1 << 16 ) + +// Don't cast shadows from this model (useful on first-person models) +#define STUDIOHDR_FLAGS_DO_NOT_CAST_SHADOWS ( 1 << 17 ) + +// alpha textures should cast shadows in vrad on this model (ONLY prop_static!) +#define STUDIOHDR_FLAGS_CAST_TEXTURE_SHADOWS ( 1 << 18 ) + + +// flagged on load to indicate no animation events on this model +#define STUDIOHDR_FLAGS_VERT_ANIM_FIXED_POINT_SCALE ( 1 << 21 ) + +// NOTE! Next time we up the .mdl file format, remove studiohdr2_t +// and insert all fields in this structure into studiohdr_t. +struct studiohdr2_t +{ + // NOTE: For forward compat, make sure any methods in this struct + // are also available in studiohdr_t so no leaf code ever directly references + // a studiohdr2_t structure + DECLARE_BYTESWAP_DATADESC(); + int numsrcbonetransform; + int srcbonetransformindex; + + int illumpositionattachmentindex; + inline int IllumPositionAttachmentIndex() const { return illumpositionattachmentindex; } + + float flMaxEyeDeflection; + inline float MaxEyeDeflection() const { return flMaxEyeDeflection != 0.0f ? flMaxEyeDeflection : 0.866f; } // default to cos(30) if not set + + int linearboneindex; + inline mstudiolinearbone_t *pLinearBones() const { return (linearboneindex) ? (mstudiolinearbone_t *)(((byte *)this) + linearboneindex) : NULL; } + + int sznameindex; + inline char *pszName() { return (sznameindex) ? (char *)(((byte *)this) + sznameindex ) : NULL; } + + int m_nBoneFlexDriverCount; + int m_nBoneFlexDriverIndex; + inline mstudioboneflexdriver_t *pBoneFlexDriver( int i ) const { Assert( i >= 0 && i < m_nBoneFlexDriverCount ); return (mstudioboneflexdriver_t *)(((byte *)this) + m_nBoneFlexDriverIndex) + i; } + + int reserved[56]; +}; + +struct studiohdr_t +{ + DECLARE_BYTESWAP_DATADESC(); + int id; + int version; + + int checksum; // this has to be the same in the phy and vtx files to load! + + inline const char * pszName( void ) const { if (studiohdr2index && pStudioHdr2()->pszName()) return pStudioHdr2()->pszName(); else return name; } + char name[64]; + int length; + + + Vector eyeposition; // ideal eye position + + Vector illumposition; // illumination center + + Vector hull_min; // ideal movement hull size + Vector hull_max; + + Vector view_bbmin; // clipping bounding box + Vector view_bbmax; + + int flags; + + int numbones; // bones + int boneindex; + inline mstudiobone_t *pBone( int i ) const { Assert( i >= 0 && i < numbones); return (mstudiobone_t *)(((byte *)this) + boneindex) + i; }; + int RemapSeqBone( int iSequence, int iLocalBone ) const; // maps local sequence bone to global bone + int RemapAnimBone( int iAnim, int iLocalBone ) const; // maps local animations bone to global bone + + int numbonecontrollers; // bone controllers + int bonecontrollerindex; + inline mstudiobonecontroller_t *pBonecontroller( int i ) const { Assert( i >= 0 && i < numbonecontrollers); return (mstudiobonecontroller_t *)(((byte *)this) + bonecontrollerindex) + i; }; + + int numhitboxsets; + int hitboxsetindex; + + // Look up hitbox set by index + mstudiohitboxset_t *pHitboxSet( int i ) const + { + Assert( i >= 0 && i < numhitboxsets); + return (mstudiohitboxset_t *)(((byte *)this) + hitboxsetindex ) + i; + }; + + // Calls through to hitbox to determine size of specified set + inline mstudiobbox_t *pHitbox( int i, int set ) const + { + mstudiohitboxset_t const *s = pHitboxSet( set ); + if ( !s ) + return NULL; + + return s->pHitbox( i ); + }; + + // Calls through to set to get hitbox count for set + inline int iHitboxCount( int set ) const + { + mstudiohitboxset_t const *s = pHitboxSet( set ); + if ( !s ) + return 0; + + return s->numhitboxes; + }; + + // file local animations? and sequences +//private: + int numlocalanim; // animations/poses + int localanimindex; // animation descriptions + inline mstudioanimdesc_t *pLocalAnimdesc( int i ) const { if (i < 0 || i >= numlocalanim) i = 0; return (mstudioanimdesc_t *)(((byte *)this) + localanimindex) + i; }; + + int numlocalseq; // sequences + int localseqindex; + inline mstudioseqdesc_t *pLocalSeqdesc( int i ) const { if (i < 0 || i >= numlocalseq) i = 0; return (mstudioseqdesc_t *)(((byte *)this) + localseqindex) + i; }; + +//public: + bool SequencesAvailable() const; + int GetNumSeq() const; + mstudioanimdesc_t &pAnimdesc( int i ) const; + mstudioseqdesc_t &pSeqdesc( int i ) const; + int iRelativeAnim( int baseseq, int relanim ) const; // maps seq local anim reference to global anim index + int iRelativeSeq( int baseseq, int relseq ) const; // maps seq local seq reference to global seq index + +//private: + mutable int activitylistversion; // initialization flag - have the sequences been indexed? + mutable int eventsindexed; +//public: + int GetSequenceActivity( int iSequence ); + void SetSequenceActivity( int iSequence, int iActivity ); + int GetActivityListVersion( void ); + void SetActivityListVersion( int version ) const; + int GetEventListVersion( void ); + void SetEventListVersion( int version ); + + // raw textures + int numtextures; + int textureindex; + inline mstudiotexture_t *pTexture( int i ) const { Assert( i >= 0 && i < numtextures ); return (mstudiotexture_t *)(((byte *)this) + textureindex) + i; }; + + + // raw textures search paths + int numcdtextures; + int cdtextureindex; + inline char *pCdtexture( int i ) const { return (((char *)this) + *((int *)(((byte *)this) + cdtextureindex) + i)); }; + + // replaceable textures tables + int numskinref; + int numskinfamilies; + int skinindex; + inline short *pSkinref( int i ) const { return (short *)(((byte *)this) + skinindex) + i; }; + + int numbodyparts; + int bodypartindex; + inline mstudiobodyparts_t *pBodypart( int i ) const { return (mstudiobodyparts_t *)(((byte *)this) + bodypartindex) + i; }; + + // queryable attachable points +//private: + int numlocalattachments; + int localattachmentindex; + inline mstudioattachment_t *pLocalAttachment( int i ) const { Assert( i >= 0 && i < numlocalattachments); return (mstudioattachment_t *)(((byte *)this) + localattachmentindex) + i; }; +//public: + int GetNumAttachments( void ) const; + const mstudioattachment_t &pAttachment( int i ) const; + int GetAttachmentBone( int i ); + // used on my tools in hlmv, not persistant + void SetAttachmentBone( int iAttachment, int iBone ); + + // animation node to animation node transition graph +//private: + int numlocalnodes; + int localnodeindex; + int localnodenameindex; + inline char *pszLocalNodeName( int iNode ) const { Assert( iNode >= 0 && iNode < numlocalnodes); return (((char *)this) + *((int *)(((byte *)this) + localnodenameindex) + iNode)); } + inline byte *pLocalTransition( int i ) const { Assert( i >= 0 && i < (numlocalnodes * numlocalnodes)); return (byte *)(((byte *)this) + localnodeindex) + i; }; + +//public: + int EntryNode( int iSequence ); + int ExitNode( int iSequence ); + char *pszNodeName( int iNode ); + int GetTransition( int iFrom, int iTo ) const; + + int numflexdesc; + int flexdescindex; + inline mstudioflexdesc_t *pFlexdesc( int i ) const { Assert( i >= 0 && i < numflexdesc); return (mstudioflexdesc_t *)(((byte *)this) + flexdescindex) + i; }; + + int numflexcontrollers; + int flexcontrollerindex; + inline mstudioflexcontroller_t *pFlexcontroller( LocalFlexController_t i ) const { Assert( numflexcontrollers == 0 || ( i >= 0 && i < numflexcontrollers ) ); return (mstudioflexcontroller_t *)(((byte *)this) + flexcontrollerindex) + i; }; + + int numflexrules; + int flexruleindex; + inline mstudioflexrule_t *pFlexRule( int i ) const { Assert( i >= 0 && i < numflexrules); return (mstudioflexrule_t *)(((byte *)this) + flexruleindex) + i; }; + + int numikchains; + int ikchainindex; + inline mstudioikchain_t *pIKChain( int i ) const { Assert( i >= 0 && i < numikchains); return (mstudioikchain_t *)(((byte *)this) + ikchainindex) + i; }; + + int nummouths; + int mouthindex; + inline mstudiomouth_t *pMouth( int i ) const { Assert( i >= 0 && i < nummouths); return (mstudiomouth_t *)(((byte *)this) + mouthindex) + i; }; + +//private: + int numlocalposeparameters; + int localposeparamindex; + inline mstudioposeparamdesc_t *pLocalPoseParameter( int i ) const { Assert( i >= 0 && i < numlocalposeparameters); return (mstudioposeparamdesc_t *)(((byte *)this) + localposeparamindex) + i; }; +//public: + int GetNumPoseParameters( void ) const; + const mstudioposeparamdesc_t &pPoseParameter( int i ); + int GetSharedPoseParameter( int iSequence, int iLocalPose ) const; + + int surfacepropindex; + inline char * const pszSurfaceProp( void ) const { return ((char *)this) + surfacepropindex; } + + // Key values + int keyvalueindex; + int keyvaluesize; + inline const char * KeyValueText( void ) const { return keyvaluesize != 0 ? ((char *)this) + keyvalueindex : NULL; } + + int numlocalikautoplaylocks; + int localikautoplaylockindex; + inline mstudioiklock_t *pLocalIKAutoplayLock( int i ) const { Assert( i >= 0 && i < numlocalikautoplaylocks); return (mstudioiklock_t *)(((byte *)this) + localikautoplaylockindex) + i; }; + + int GetNumIKAutoplayLocks( void ) const; + const mstudioiklock_t &pIKAutoplayLock( int i ); + int CountAutoplaySequences() const; + int CopyAutoplaySequences( unsigned short *pOut, int outCount ) const; + int GetAutoplayList( unsigned short **pOut ) const; + + // The collision model mass that jay wanted + float mass; + int contents; + + // external animations, models, etc. + int numincludemodels; + int includemodelindex; + inline mstudiomodelgroup_t *pModelGroup( int i ) const { Assert( i >= 0 && i < numincludemodels); return (mstudiomodelgroup_t *)(((byte *)this) + includemodelindex) + i; }; + // implementation specific call to get a named model + const studiohdr_t *FindModel( void **cache, char const *modelname ) const; + + // implementation specific back pointer to virtual data + mutable void *virtualModel; + virtualmodel_t *GetVirtualModel( void ) const; + + // for demand loaded animation blocks + int szanimblocknameindex; + inline char * const pszAnimBlockName( void ) const { return ((char *)this) + szanimblocknameindex; } + int numanimblocks; + int animblockindex; + inline mstudioanimblock_t *pAnimBlock( int i ) const { Assert( i > 0 && i < numanimblocks); return (mstudioanimblock_t *)(((byte *)this) + animblockindex) + i; }; + mutable void *animblockModel; + byte * GetAnimBlock( int i ) const; + + int bonetablebynameindex; + inline const byte *GetBoneTableSortedByName() const { return (byte *)this + bonetablebynameindex; } + + // used by tools only that don't cache, but persist mdl's peer data + // engine uses virtualModel to back link to cache pointers + void *pVertexBase; + void *pIndexBase; + + // if STUDIOHDR_FLAGS_CONSTANT_DIRECTIONAL_LIGHT_DOT is set, + // this value is used to calculate directional components of lighting + // on static props + byte constdirectionallightdot; + + // set during load of mdl data to track *desired* lod configuration (not actual) + // the *actual* clamped root lod is found in studiohwdata + // this is stored here as a global store to ensure the staged loading matches the rendering + byte rootLOD; + + // set in the mdl data to specify that lod configuration should only allow first numAllowRootLODs + // to be set as root LOD: + // numAllowedRootLODs = 0 means no restriction, any lod can be set as root lod. + // numAllowedRootLODs = N means that lod0 - lod(N-1) can be set as root lod, but not lodN or lower. + byte numAllowedRootLODs; + + byte unused[1]; + + int unused4; // zero out if version < 47 + + int numflexcontrollerui; + int flexcontrolleruiindex; + mstudioflexcontrollerui_t *pFlexControllerUI( int i ) const { Assert( i >= 0 && i < numflexcontrollerui); return (mstudioflexcontrollerui_t *)(((byte *)this) + flexcontrolleruiindex) + i; } + + float flVertAnimFixedPointScale; + inline float VertAnimFixedPointScale() const { return ( flags & STUDIOHDR_FLAGS_VERT_ANIM_FIXED_POINT_SCALE ) ? flVertAnimFixedPointScale : 1.0f / 4096.0f; } + + int unused3[1]; + + // FIXME: Remove when we up the model version. Move all fields of studiohdr2_t into studiohdr_t. + int studiohdr2index; + studiohdr2_t* pStudioHdr2() const { return (studiohdr2_t *)( ( (byte *)this ) + studiohdr2index ); } + + // Src bone transforms are transformations that will convert .dmx or .smd-based animations into .mdl-based animations + int NumSrcBoneTransforms() const { return studiohdr2index ? pStudioHdr2()->numsrcbonetransform : 0; } + const mstudiosrcbonetransform_t* SrcBoneTransform( int i ) const { Assert( i >= 0 && i < NumSrcBoneTransforms()); return (mstudiosrcbonetransform_t *)(((byte *)this) + pStudioHdr2()->srcbonetransformindex) + i; } + + inline int IllumPositionAttachmentIndex() const { return studiohdr2index ? pStudioHdr2()->IllumPositionAttachmentIndex() : 0; } + + inline float MaxEyeDeflection() const { return studiohdr2index ? pStudioHdr2()->MaxEyeDeflection() : 0.866f; } // default to cos(30) if not set + + inline mstudiolinearbone_t *pLinearBones() const { return studiohdr2index ? pStudioHdr2()->pLinearBones() : NULL; } + + inline int BoneFlexDriverCount() const { return studiohdr2index ? pStudioHdr2()->m_nBoneFlexDriverCount : 0; } + inline const mstudioboneflexdriver_t* BoneFlexDriver( int i ) const { Assert( i >= 0 && i < BoneFlexDriverCount() ); return studiohdr2index ? pStudioHdr2()->pBoneFlexDriver( i ) : NULL; } + + // NOTE: No room to add stuff? Up the .mdl file format version + // [and move all fields in studiohdr2_t into studiohdr_t and kill studiohdr2_t], + // or add your stuff to studiohdr2_t. See NumSrcBoneTransforms/SrcBoneTransform for the pattern to use. + int unused2[1]; + + studiohdr_t() {} + +private: + // No copy constructors allowed + studiohdr_t(const studiohdr_t& vOther); + + friend struct virtualmodel_t; +}; + + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +class IDataCache; +class IMDLCache; + +class CStudioHdr +{ +public: + CStudioHdr( void ); + CStudioHdr( const studiohdr_t *pStudioHdr, IMDLCache *mdlcache = NULL ); + ~CStudioHdr() { Term(); } + + void Init( const studiohdr_t *pStudioHdr, IMDLCache *mdlcache = NULL ); + void Term(); + +public: + inline bool IsVirtual( void ) { return (m_pVModel != NULL); }; + inline bool IsValid( void ) { return (m_pStudioHdr != NULL); }; + inline bool IsReadyForAccess( void ) const { return (m_pStudioHdr != NULL); }; + inline virtualmodel_t *GetVirtualModel( void ) const { return m_pVModel; }; + inline const studiohdr_t *GetRenderHdr( void ) const { return m_pStudioHdr; }; + const studiohdr_t *pSeqStudioHdr( int sequence ); + const studiohdr_t *pAnimStudioHdr( int animation ); + +private: + mutable const studiohdr_t *m_pStudioHdr; + mutable virtualmodel_t *m_pVModel; + + const virtualmodel_t * ResetVModel( const virtualmodel_t *pVModel ) const; + const studiohdr_t *GroupStudioHdr( int group ); + mutable CUtlVector< const studiohdr_t * > m_pStudioHdrCache; + + mutable int m_nFrameUnlockCounter; + int * m_pFrameUnlockCounter; + CThreadFastMutex m_FrameUnlockCounterMutex; + +public: + inline int numbones( void ) const { return m_pStudioHdr->numbones; }; + inline mstudiobone_t *pBone( int i ) const { return m_pStudioHdr->pBone( i ); }; + int RemapAnimBone( int iAnim, int iLocalBone ) const; // maps local animations bone to global bone + int RemapSeqBone( int iSequence, int iLocalBone ) const; // maps local sequence bone to global bone + + bool SequencesAvailable() const; + int GetNumSeq( void ) const; + mstudioanimdesc_t &pAnimdesc( int i ); + mstudioseqdesc_t &pSeqdesc( int iSequence ); + int iRelativeAnim( int baseseq, int relanim ) const; // maps seq local anim reference to global anim index + int iRelativeSeq( int baseseq, int relseq ) const; // maps seq local seq reference to global seq index + + int GetSequenceActivity( int iSequence ); + void SetSequenceActivity( int iSequence, int iActivity ); + int GetActivityListVersion( void ); + void SetActivityListVersion( int version ); + int GetEventListVersion( void ); + void SetEventListVersion( int version ); + + int GetNumAttachments( void ) const; + const mstudioattachment_t &pAttachment( int i ); + int GetAttachmentBone( int i ); + // used on my tools in hlmv, not persistant + void SetAttachmentBone( int iAttachment, int iBone ); + + int EntryNode( int iSequence ); + int ExitNode( int iSequence ); + char *pszNodeName( int iNode ); + // FIXME: where should this one be? + int GetTransition( int iFrom, int iTo ) const; + + int GetNumPoseParameters( void ) const; + const mstudioposeparamdesc_t &pPoseParameter( int i ); + int GetSharedPoseParameter( int iSequence, int iLocalPose ) const; + + int GetNumIKAutoplayLocks( void ) const; + const mstudioiklock_t &pIKAutoplayLock( int i ); + + inline int CountAutoplaySequences() const { return m_pStudioHdr->CountAutoplaySequences(); }; + inline int CopyAutoplaySequences( unsigned short *pOut, int outCount ) const { return m_pStudioHdr->CopyAutoplaySequences( pOut, outCount ); }; + inline int GetAutoplayList( unsigned short **pOut ) const { return m_pStudioHdr->GetAutoplayList( pOut ); }; + + inline int GetNumBoneControllers( void ) const { return m_pStudioHdr->numbonecontrollers; }; + inline mstudiobonecontroller_t *pBonecontroller( int i ) const { return m_pStudioHdr->pBonecontroller( i ); }; + + inline int numikchains() const { return m_pStudioHdr->numikchains; }; + inline int GetNumIKChains( void ) const { return m_pStudioHdr->numikchains; }; + inline mstudioikchain_t *pIKChain( int i ) const { return m_pStudioHdr->pIKChain( i ); }; + + inline int numflexrules() const { return m_pStudioHdr->numflexrules; }; + inline mstudioflexrule_t *pFlexRule( int i ) const { return m_pStudioHdr->pFlexRule( i ); }; + + inline int numflexdesc() const{ return m_pStudioHdr->numflexdesc; }; + inline mstudioflexdesc_t *pFlexdesc( int i ) const { return m_pStudioHdr->pFlexdesc( i ); }; + + inline LocalFlexController_t numflexcontrollers() const{ return (LocalFlexController_t)m_pStudioHdr->numflexcontrollers; }; + inline mstudioflexcontroller_t *pFlexcontroller( LocalFlexController_t i ) const { return m_pStudioHdr->pFlexcontroller( i ); }; + + inline int numflexcontrollerui() const{ return m_pStudioHdr->numflexcontrollerui; }; + inline mstudioflexcontrollerui_t *pFlexcontrollerUI( int i ) const { return m_pStudioHdr->pFlexControllerUI( i ); }; + + //inline const char *name() const { return m_pStudioHdr->name; }; // deprecated -- remove after full xbox merge + inline const char *pszName() const { return m_pStudioHdr->pszName(); }; + + inline int numbonecontrollers() const { return m_pStudioHdr->numbonecontrollers; }; + + inline int numhitboxsets() const { return m_pStudioHdr->numhitboxsets; }; + inline mstudiohitboxset_t *pHitboxSet( int i ) const { return m_pStudioHdr->pHitboxSet( i ); }; + + inline mstudiobbox_t *pHitbox( int i, int set ) const { return m_pStudioHdr->pHitbox( i, set ); }; + inline int iHitboxCount( int set ) const { return m_pStudioHdr->iHitboxCount( set ); }; + + inline int numbodyparts() const { return m_pStudioHdr->numbodyparts; }; + inline mstudiobodyparts_t *pBodypart( int i ) const { return m_pStudioHdr->pBodypart( i ); }; + + inline int numskinfamilies() const { return m_pStudioHdr->numskinfamilies; } + + inline Vector eyeposition() const { return m_pStudioHdr->eyeposition; }; + + inline int flags() const { return m_pStudioHdr->flags; }; + + inline char *const pszSurfaceProp( void ) const { return m_pStudioHdr->pszSurfaceProp(); }; + + inline float mass() const { return m_pStudioHdr->mass; }; + inline int contents() const { return m_pStudioHdr->contents; } + + inline const byte *GetBoneTableSortedByName() const { return m_pStudioHdr->GetBoneTableSortedByName(); }; + + inline Vector illumposition() const { return m_pStudioHdr->illumposition; }; + + inline Vector hull_min() const { return m_pStudioHdr->hull_min; }; // ideal movement hull size + inline Vector hull_max() const { return m_pStudioHdr->hull_max; }; + + inline Vector view_bbmin() const { return m_pStudioHdr->view_bbmin; }; // clipping bounding box + inline Vector view_bbmax() const { return m_pStudioHdr->view_bbmax; }; + + inline int numtextures() const { return m_pStudioHdr->numtextures; }; + + inline int IllumPositionAttachmentIndex() const { return m_pStudioHdr->IllumPositionAttachmentIndex(); } + + inline float MaxEyeDeflection() const { return m_pStudioHdr->MaxEyeDeflection(); } + + inline mstudiolinearbone_t *pLinearBones() const { return m_pStudioHdr->pLinearBones(); } + + inline int BoneFlexDriverCount() const { return m_pStudioHdr->BoneFlexDriverCount(); } + inline const mstudioboneflexdriver_t *BoneFlexDriver( int i ) const { return m_pStudioHdr->BoneFlexDriver( i ); } + + inline float VertAnimFixedPointScale() const { return m_pStudioHdr->VertAnimFixedPointScale(); } + +public: + int IsSequenceLooping( int iSequence ); + float GetSequenceCycleRate( int iSequence ); + + void RunFlexRules( const float *src, float *dest ); + + +public: + inline int boneFlags( int iBone ) const { return m_boneFlags[ iBone ]; } + inline int boneParent( int iBone ) const { return m_boneParent[ iBone ]; } + +private: + CUtlVector< int > m_boneFlags; + CUtlVector< int > m_boneParent; + +public: + // This class maps an activity to sequences allowed for that activity, accelerating the resolution + // of SelectWeightedSequence(), especially on PowerPC. Iterating through every sequence + // attached to a model turned out to be a very destructive cache access pattern on 360. + // + // I've encapsulated this behavior inside a nested class for organizational reasons; there is + // no particular programmatic or efficiency benefit to it. It just makes clearer what particular + // code in the otherwise very complicated StudioHdr class has to do with this particular + // optimization, and it lets you collapse the whole definition down to a single line in Visual + // Studio. + class CActivityToSequenceMapping /* final */ + { + public: + // A tuple of a sequence and its corresponding weight. Lists of these correspond to activities. + struct SequenceTuple + { + short seqnum; + short weight; // the absolute value of the weight from the sequence header + }; + + // The type of the hash's stored data, a composite of both key and value + // (because that's how CUtlHash works): + // key: an int, the activity # + // values: an index into the m_pSequenceTuples array, a count of the + // total sequences present for an activity, and the sum of their + // weights. + // Note this struct is 128-bits wide, exactly coincident to a PowerPC + // cache line and VMX register. Please consider very carefully the + // performance implications before adding any additional fields to this. + // You could probably do away with totalWeight if you really had to. + struct HashValueType + { + // KEY (hashed) + int activityIdx; + + // VALUE (not hashed) + int startingIdx; + int count; + int totalWeight; + + HashValueType(int _actIdx, int _stIdx, int _ct, int _tW) : + activityIdx(_actIdx), startingIdx(_stIdx), count(_ct), totalWeight(_tW) {} + + // default constructor (ought not to be actually used) + HashValueType() : activityIdx(-1), startingIdx(-1), count(-1), totalWeight(-1) + { AssertMsg(false, "Don't use default HashValueType()!"); } + + + class HashFuncs + { + public: + // dummy constructor (gndn) + HashFuncs( int ) {} + + // COMPARE + // compare two entries for uniqueness. We should never have two different + // entries for the same activity, so we only compare the activity index; + // this allows us to use the utlhash as a dict by constructing dummy entries + // as hash lookup keys. + bool operator()( const HashValueType &lhs, const HashValueType &rhs ) const + { + return lhs.activityIdx == rhs.activityIdx; + } + + // HASH + // We only hash on the activity index; everything else is data. + unsigned int operator()( const HashValueType &item ) const + { + return HashInt( item.activityIdx ); + } + }; + }; + + typedef CUtlHash ActivityToValueIdxHash; + + // These must be here because IFM does not compile/link studio.cpp (?!?) + + // ctor + CActivityToSequenceMapping( void ) + : m_pSequenceTuples(NULL), m_iSequenceTuplesCount(0), m_ActToSeqHash(8,0,0), m_expectedPStudioHdr(NULL), m_expectedVModel(NULL) +#if STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE + , m_bIsInitialized(false) +#endif + {}; + + // dtor -- not virtual because this class has no inheritors + ~CActivityToSequenceMapping() + { + if ( m_pSequenceTuples != NULL ) + { + delete[] m_pSequenceTuples; + } + } + + /// Get the list of sequences for an activity. Returns the pointer to the + /// first sequence tuple. Output parameters are a count of sequences present, + /// and the total weight of all the sequences. (it would be more LHS-friendly + /// to return these on registers, if only C++ offered more than one return + /// value....) + const SequenceTuple *GetSequences( int forActivity, int *outSequenceCount, int *outTotalWeight ); + + /// The number of sequences available for an activity. + int NumSequencesForActivity( int forActivity ); + +#if STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE + inline bool IsInitialized( void ) { return m_bIsInitialized; } +#endif + + private: + + /// Allocate my internal array. (It is freed in the destructor.) Also, + /// build the hash of activities to sequences and populate m_pSequenceTuples. + void Initialize( CStudioHdr *pstudiohdr ); + + /// Force Initialize() to occur again, even if it has already occured. + void Reinitialize( CStudioHdr *pstudiohdr ); + + /// A more efficient version of the old SelectWeightedSequence() function in animation.cpp. + int SelectWeightedSequence( CStudioHdr *pstudiohdr, int activity, int curSequence ); + + // Actually a big array, into which the hash values index. + SequenceTuple *m_pSequenceTuples; + unsigned int m_iSequenceTuplesCount; // (size of the whole array) +#if STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE + bool m_bIsInitialized; +#endif + + // we don't store an outer pointer because we can't initialize it at construction time + // (warning c4355) -- there are ways around this but it's easier to just pass in a + // pointer to the CStudioHdr when we need it, since this class isn't supposed to + // export its interface outside the studio header anyway. + // CStudioHdr * const m_pOuter; + + ActivityToValueIdxHash m_ActToSeqHash; + + // we store these so we can know if the contents of the studiohdr have changed + // from underneath our feet (this is an emergency data integrity check) + const void *m_expectedPStudioHdr; + const void *m_expectedVModel; + + // double-check that the data I point to hasn't changed + bool ValidateAgainst( const CStudioHdr * RESTRICT pstudiohdr ); + void SetValidationPair( const CStudioHdr *RESTRICT pstudiohdr ); + + friend class CStudioHdr; + }; + + CActivityToSequenceMapping m_ActivityToSequence; + + /// A more efficient version of the old SelectWeightedSequence() function in animation.cpp. + /// Returns -1 on failure to find a sequence + inline int SelectWeightedSequence( int activity, int curSequence ) + { +#if STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE + // We lazy-initialize the header on demand here, because CStudioHdr::Init() is + // called from the constructor, at which time the this pointer is illegitimate. + if ( !m_ActivityToSequence.IsInitialized() ) + { + m_ActivityToSequence.Initialize(this); + } +#endif + return m_ActivityToSequence.SelectWeightedSequence( this, activity, curSequence ); + } + + /// True iff there is at least one sequence for the given activity. + inline bool HaveSequenceForActivity( int activity ) + { +#if STUDIO_SEQUENCE_ACTIVITY_LAZY_INITIALIZE + if ( !m_ActivityToSequence.IsInitialized() ) + { + m_ActivityToSequence.Initialize(this); + } +#endif + return (m_ActivityToSequence.NumSequencesForActivity( activity ) > 0); + } + + // Force this CStudioHdr's activity-to-sequence mapping to be reinitialized + inline void ReinitializeSequenceMapping(void) + { + m_ActivityToSequence.Reinitialize(this); + } + +#ifdef STUDIO_ENABLE_PERF_COUNTERS +public: + inline void ClearPerfCounters( void ) + { + m_nPerfAnimatedBones = 0; + m_nPerfUsedBones = 0; + m_nPerfAnimationLayers = 0; + }; + + // timing info + mutable int m_nPerfAnimatedBones; + mutable int m_nPerfUsedBones; + mutable int m_nPerfAnimationLayers; +#endif + + +}; + +/* +class CModelAccess +{ +public: + CModelAccess(CStudioHdr *pSemaphore) + : m_pStudioHdr(pSemaphore) + { + m_pStudioHdr->IncrementAccess(); + } + + ~CModelAccess() + { + m_pStudioHdr->DecrementAccess(); + } + +private: + CStudioHdr *m_pStudioHdr; +}; + +#define ENABLE_MODEL_ACCESS( a ) \ + CModelAccess ModelAccess##__LINE__( a->m_pStudioHdr ) +*/ + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +struct flexweight_t +{ + DECLARE_BYTESWAP_DATADESC(); + int key; + float weight; + float influence; +}; + +struct flexsetting_t +{ + DECLARE_BYTESWAP_DATADESC(); + int nameindex; + + inline char *pszName( void ) const + { + return (char *)(((byte *)this) + nameindex); + } + + // Leaving this for legacy support + int obsolete1; + + // Number of flex settings + int numsettings; + int index; + + // OBSOLETE: + int obsolete2; + + // Index of start of contiguous array of flexweight_t structures + int settingindex; + + //----------------------------------------------------------------------------- + // Purpose: Retrieves a pointer to the flexweight_t, including resolving + // any markov chain hierarchy. Because of this possibility, we return + // the number of settings in the weights array returned. We'll generally + // call this function with i == 0 + // Input : *base - + // i - + // **weights - + // Output : int + //----------------------------------------------------------------------------- + inline int psetting( byte *base, int i, flexweight_t **weights ) const; +}; + + +struct flexsettinghdr_t +{ + DECLARE_BYTESWAP_DATADESC(); + int id; + int version; + + inline const char * pszName( void ) const { return name; } + char name[64]; + int length; + + int numflexsettings; + int flexsettingindex; + inline flexsetting_t *pSetting( int i ) const { return (flexsetting_t *)(((byte *)this) + flexsettingindex) + i; }; + int nameindex; + + // look up flex settings by "index" + int numindexes; + int indexindex; + + inline flexsetting_t *pIndexedSetting( int index ) const + { + if ( index < 0 || index >= numindexes ) + { + return NULL; + } + + int i = *((int *)(((byte *)this) + indexindex) + index); + + if (i == -1) + { + return NULL; + } + + return pSetting( i ); + } + + // index names of "flexcontrollers" + int numkeys; + int keynameindex; + inline char *pLocalName( int i ) const { return (char *)(((byte *)this) + *((int *)(((byte *)this) + keynameindex) + i)); }; + + int keymappingindex; + inline int *pLocalToGlobal( int i ) const { return (int *)(((byte *)this) + keymappingindex) + i; }; + inline int LocalToGlobal( int i ) const { return *pLocalToGlobal( i ); }; +}; + +//----------------------------------------------------------------------------- +// Purpose: Retrieves a pointer to the flexweight_t. +// Input : *base - flexsettinghdr_t * pointer +// i - index of flex setting to retrieve +// **weights - destination for weights array starting at index i. +// Output : int +//----------------------------------------------------------------------------- +inline int flexsetting_t::psetting( byte *base, int i, flexweight_t **weights ) const +{ + // Grab array pointer + *weights = (flexweight_t *)(((byte *)this) + settingindex) + i; + // Return true number of settings + return numsettings; +}; + + +//----------------------------------------------------------------------------- +// For a given flex controller ui struct, these return the index of the +// studiohdr_t flex controller that correspond to the the left and right +// flex controllers if the ui controller is a stereo control. +// nWayValueIndex returns the index of the flex controller that is the value +// flex controller for an NWAY combination +// If these functions are called and the ui controller isn't of the type +// specified then -1 is returned +//----------------------------------------------------------------------------- +inline int mstudioflexcontrollerui_t::controllerIndex( const CStudioHdr &cStudioHdr ) const +{ + return !stereo ? pController() - cStudioHdr.pFlexcontroller( (LocalFlexController_t)0 ) : -1; +} + + +inline int mstudioflexcontrollerui_t::rightIndex( const CStudioHdr &cStudioHdr ) const +{ + return stereo ? pRightController() - cStudioHdr.pFlexcontroller( (LocalFlexController_t)0 ) : -1; +} + + +inline int mstudioflexcontrollerui_t::leftIndex( const CStudioHdr &cStudioHdr ) const +{ + return stereo ? pLeftController() - cStudioHdr.pFlexcontroller((LocalFlexController_t) 0 ) : -1; +} + + +inline int mstudioflexcontrollerui_t::nWayValueIndex( const CStudioHdr &cStudioHdr ) const +{ + return remaptype == FLEXCONTROLLER_REMAP_NWAY ? pNWayValueController() - cStudioHdr.pFlexcontroller( (LocalFlexController_t)0 ) : -1; +} + + +inline const mstudioflexcontroller_t *mstudioflexcontrollerui_t::pController( int index ) const +{ + if ( index < 0 || index > Count() ) + return NULL; + + if ( remaptype == FLEXCONTROLLER_REMAP_NWAY ) + { + if ( stereo ) + return (mstudioflexcontroller_t *)( ( char * ) this ) + *( &szindex0 + index ); + + if ( index == 0 ) + return pController(); + + if ( index == 1 ) + return pNWayValueController(); + + return NULL; + } + + if ( index > 1 ) + return NULL; + + if ( stereo ) + return (mstudioflexcontroller_t *)( ( char * ) this ) + *( &szindex0 + index ); + + if ( index > 0 ) + return NULL; + + return pController(); +} + + +#define STUDIO_CONST 1 // get float +#define STUDIO_FETCH1 2 // get Flexcontroller value +#define STUDIO_FETCH2 3 // get flex weight +#define STUDIO_ADD 4 +#define STUDIO_SUB 5 +#define STUDIO_MUL 6 +#define STUDIO_DIV 7 +#define STUDIO_NEG 8 // not implemented +#define STUDIO_EXP 9 // not implemented +#define STUDIO_OPEN 10 // only used in token parsing +#define STUDIO_CLOSE 11 +#define STUDIO_COMMA 12 // only used in token parsing +#define STUDIO_MAX 13 +#define STUDIO_MIN 14 +#define STUDIO_2WAY_0 15 // Fetch a value from a 2 Way slider for the 1st value RemapVal( 0.0, 0.5, 0.0, 1.0 ) +#define STUDIO_2WAY_1 16 // Fetch a value from a 2 Way slider for the 2nd value RemapVal( 0.5, 1.0, 0.0, 1.0 ) +#define STUDIO_NWAY 17 // Fetch a value from a 2 Way slider for the 2nd value RemapVal( 0.5, 1.0, 0.0, 1.0 ) +#define STUDIO_COMBO 18 // Perform a combo operation (essentially multiply the last N values on the stack) +#define STUDIO_DOMINATE 19 // Performs a combination domination operation +#define STUDIO_DME_LOWER_EYELID 20 // +#define STUDIO_DME_UPPER_EYELID 21 // + +// motion flags +#define STUDIO_X 0x00000001 +#define STUDIO_Y 0x00000002 +#define STUDIO_Z 0x00000004 +#define STUDIO_XR 0x00000008 +#define STUDIO_YR 0x00000010 +#define STUDIO_ZR 0x00000020 + +#define STUDIO_LX 0x00000040 +#define STUDIO_LY 0x00000080 +#define STUDIO_LZ 0x00000100 +#define STUDIO_LXR 0x00000200 +#define STUDIO_LYR 0x00000400 +#define STUDIO_LZR 0x00000800 + +#define STUDIO_LINEAR 0x00001000 + +#define STUDIO_TYPES 0x0003FFFF +#define STUDIO_RLOOP 0x00040000 // controller that wraps shortest distance + +// sequence and autolayer flags +#define STUDIO_LOOPING 0x0001 // ending frame should be the same as the starting frame +#define STUDIO_SNAP 0x0002 // do not interpolate between previous animation and this one +#define STUDIO_DELTA 0x0004 // this sequence "adds" to the base sequences, not slerp blends +#define STUDIO_AUTOPLAY 0x0008 // temporary flag that forces the sequence to always play +#define STUDIO_POST 0x0010 // +#define STUDIO_ALLZEROS 0x0020 // this animation/sequence has no real animation data +// 0x0040 +#define STUDIO_CYCLEPOSE 0x0080 // cycle index is taken from a pose parameter index +#define STUDIO_REALTIME 0x0100 // cycle index is taken from a real-time clock, not the animations cycle index +#define STUDIO_LOCAL 0x0200 // sequence has a local context sequence +#define STUDIO_HIDDEN 0x0400 // don't show in default selection views +#define STUDIO_OVERRIDE 0x0800 // a forward declared sequence (empty) +#define STUDIO_ACTIVITY 0x1000 // Has been updated at runtime to activity index +#define STUDIO_EVENT 0x2000 // Has been updated at runtime to event index +#define STUDIO_WORLD 0x4000 // sequence blends in worldspace +// autolayer flags +// 0x0001 +// 0x0002 +// 0x0004 +// 0x0008 +#define STUDIO_AL_POST 0x0010 // +// 0x0020 +#define STUDIO_AL_SPLINE 0x0040 // convert layer ramp in/out curve is a spline instead of linear +#define STUDIO_AL_XFADE 0x0080 // pre-bias the ramp curve to compense for a non-1 weight, assuming a second layer is also going to accumulate +// 0x0100 +#define STUDIO_AL_NOBLEND 0x0200 // animation always blends at 1.0 (ignores weight) +// 0x0400 +// 0x0800 +#define STUDIO_AL_LOCAL 0x1000 // layer is a local context sequence +// 0x2000 +#define STUDIO_AL_POSE 0x4000 // layer blends using a pose parameter instead of parent cycle + + +// Insert this code anywhere that you need to allow for conversion from an old STUDIO_VERSION +// to a new one. +// If we only support the current version, this function should be empty. +inline bool Studio_ConvertStudioHdrToNewVersion( studiohdr_t *pStudioHdr ) +{ + COMPILE_TIME_ASSERT( STUDIO_VERSION == 48 ); // put this to make sure this code is updated upon changing version. + + int version = pStudioHdr->version; + if ( version == STUDIO_VERSION ) + return true; + + bool bResult = true; + if (version < 46) + { + // some of the anim index data is incompatible + for (int i = 0; i < pStudioHdr->numlocalanim; i++) + { + mstudioanimdesc_t *pAnim = (mstudioanimdesc_t *)pStudioHdr->pLocalAnimdesc( i ); + + // old ANI files that used sections (v45 only) are not compatible + if ( pAnim->sectionframes != 0 ) + { + // zero most everything out + memset( &(pAnim->numframes), 0, (byte *)(pAnim + 1) - (byte *)&(pAnim->numframes) ); + + pAnim->numframes = 1; + pAnim->animblock = -1; // disable animation fetching + bResult = false; + } + } + } + + if (version < 47) + { + // used to contain zeroframe cache data + if (pStudioHdr->unused4 != 0) + { + pStudioHdr->unused4 = 0; + bResult = false; + } + for (int i = 0; i < pStudioHdr->numlocalanim; i++) + { + mstudioanimdesc_t *pAnim = (mstudioanimdesc_t *)pStudioHdr->pLocalAnimdesc( i ); + pAnim->zeroframeindex = 0; + pAnim->zeroframespan = 0; + } + } + else if (version == 47) + { + for (int i = 0; i < pStudioHdr->numlocalanim; i++) + { + mstudioanimdesc_t *pAnim = (mstudioanimdesc_t *)pStudioHdr->pLocalAnimdesc( i ); + if (pAnim->zeroframeindex != 0) + { + pAnim->zeroframeindex = 0; + pAnim->zeroframespan = 0; + bResult = false; + } + } + } + + // for now, just slam the version number since they're compatible + pStudioHdr->version = STUDIO_VERSION; + + return bResult; +} + +// must be run to fixup with specified rootLOD +inline void Studio_SetRootLOD( studiohdr_t *pStudioHdr, int rootLOD ) +{ + // honor studiohdr restriction of root lod in case requested root lod exceeds restriction. + if ( pStudioHdr->numAllowedRootLODs > 0 && + rootLOD >= pStudioHdr->numAllowedRootLODs ) + { + rootLOD = pStudioHdr->numAllowedRootLODs - 1; + } + + Assert( rootLOD >= 0 && rootLOD < MAX_NUM_LODS ); + Clamp( rootLOD, 0, MAX_NUM_LODS - 1 ); + + // run the lod fixups that culls higher detail lods + // vertexes are external, fixups ensure relative offsets and counts are cognizant of shrinking data + // indexes are built in lodN..lod0 order so higher detail lod data can be truncated at load + // the fixup lookup arrays are filled (or replicated) to ensure all slots valid + int vertexindex = 0; + int tangentsindex = 0; + int bodyPartID; + for ( bodyPartID = 0; bodyPartID < pStudioHdr->numbodyparts; bodyPartID++ ) + { + mstudiobodyparts_t *pBodyPart = pStudioHdr->pBodypart( bodyPartID ); + int modelID; + for ( modelID = 0; modelID < pBodyPart->nummodels; modelID++ ) + { + mstudiomodel_t *pModel = pBodyPart->pModel( modelID ); + int totalMeshVertexes = 0; + int meshID; + for ( meshID = 0; meshID < pModel->nummeshes; meshID++ ) + { + mstudiomesh_t *pMesh = pModel->pMesh( meshID ); + + // get the fixup, vertexes are reduced + pMesh->numvertices = pMesh->vertexdata.numLODVertexes[rootLOD]; + pMesh->vertexoffset = totalMeshVertexes; + totalMeshVertexes += pMesh->numvertices; + } + + // stay in sync + pModel->numvertices = totalMeshVertexes; + pModel->vertexindex = vertexindex; + pModel->tangentsindex = tangentsindex; + + vertexindex += totalMeshVertexes*sizeof(mstudiovertex_t); + tangentsindex += totalMeshVertexes*sizeof(Vector4D); + } + } + + // track the set desired configuration + pStudioHdr->rootLOD = rootLOD; +} + +// Determines allocation requirements for vertexes +inline int Studio_VertexDataSize( const vertexFileHeader_t *pVvdHdr, int rootLOD, bool bNeedsTangentS ) +{ + // the quantity of vertexes necessary for root lod and all lower detail lods + // add one extra vertex to each section + // the extra vertex allows prefetch hints to read ahead 1 vertex without faulting + int numVertexes = pVvdHdr->numLODVertexes[rootLOD] + 1; + int dataLength = pVvdHdr->vertexDataStart + numVertexes*sizeof(mstudiovertex_t); + if (bNeedsTangentS) + { + dataLength += numVertexes*sizeof(Vector4D); + } + + // allocate this much + return dataLength; +} + +// Load the minimum quantity of verts and run fixups +inline int Studio_LoadVertexes( const vertexFileHeader_t *pTempVvdHdr, vertexFileHeader_t *pNewVvdHdr, int rootLOD, bool bNeedsTangentS ) +{ + int i; + int target; + int numVertexes; + vertexFileFixup_t *pFixupTable; + + numVertexes = pTempVvdHdr->numLODVertexes[rootLOD]; + + // copy all data up to start of vertexes + memcpy((void*)pNewVvdHdr, (void*)pTempVvdHdr, pTempVvdHdr->vertexDataStart); + + for ( i = 0; i < rootLOD; i++) + { + pNewVvdHdr->numLODVertexes[i] = pNewVvdHdr->numLODVertexes[rootLOD]; + } + + // fixup data starts + if (bNeedsTangentS) + { + // tangent data follows possibly reduced vertex data + pNewVvdHdr->tangentDataStart = pNewVvdHdr->vertexDataStart + numVertexes*sizeof(mstudiovertex_t); + } + else + { + // no tangent data will be available, mark for identification + pNewVvdHdr->tangentDataStart = 0; + } + + if (!pNewVvdHdr->numFixups) + { + // fixups not required + // transfer vertex data + memcpy( + (byte *)pNewVvdHdr+pNewVvdHdr->vertexDataStart, + (byte *)pTempVvdHdr+pTempVvdHdr->vertexDataStart, + numVertexes*sizeof(mstudiovertex_t) ); + + if (bNeedsTangentS) + { + // transfer tangent data to cache memory + memcpy( + (byte *)pNewVvdHdr+pNewVvdHdr->tangentDataStart, + (byte *)pTempVvdHdr+pTempVvdHdr->tangentDataStart, + numVertexes*sizeof(Vector4D) ); + } + + return numVertexes; + } + + // fixups required + // re-establish mesh ordered vertexes into cache memory, according to table + target = 0; + pFixupTable = (vertexFileFixup_t *)((byte *)pTempVvdHdr + pTempVvdHdr->fixupTableStart); + for (i=0; inumFixups; i++) + { + if (pFixupTable[i].lod < rootLOD) + { + // working bottom up, skip over copying higher detail lods + continue; + } + + // copy vertexes + memcpy( + (mstudiovertex_t *)((byte *)pNewVvdHdr+pNewVvdHdr->vertexDataStart) + target, + (mstudiovertex_t *)((byte *)pTempVvdHdr+pTempVvdHdr->vertexDataStart) + pFixupTable[i].sourceVertexID, + pFixupTable[i].numVertexes*sizeof(mstudiovertex_t) ); + + if (bNeedsTangentS) + { + // copy tangents + memcpy( + (Vector4D *)((byte *)pNewVvdHdr+pNewVvdHdr->tangentDataStart) + target, + (Vector4D *)((byte *)pTempVvdHdr+pTempVvdHdr->tangentDataStart) + pFixupTable[i].sourceVertexID, + pFixupTable[i].numVertexes*sizeof(Vector4D) ); + } + + // data is placed consecutively + target += pFixupTable[i].numVertexes; + } + + pNewVvdHdr->numFixups = 0; + + return target; +} + +#endif // STUDIO_H diff --git a/sp/src/public/studio_generic_io.cpp b/sp/src/public/studio_generic_io.cpp new file mode 100644 index 00000000..7345e9af --- /dev/null +++ b/sp/src/public/studio_generic_io.cpp @@ -0,0 +1,156 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include + +#include "studio.h" +#include "utlrbtree.h" + +extern studiohdr_t *FindOrLoadGroupFile( char const *modelname ); + +virtualmodel_t *studiohdr_t::GetVirtualModel( void ) const +{ + if (numincludemodels == 0) + { + return NULL; + } + + virtualmodel_t *pVModel = (virtualmodel_t *)virtualModel; + + if (pVModel == NULL) + { + pVModel = new virtualmodel_t; + + // !!! Set cache handle? Set pointer to local virtual model?? + virtualModel = (void *)pVModel; + + int group = pVModel->m_group.AddToTail( ); + pVModel->m_group[ group ].cache = (void *)this; + pVModel->AppendModels( 0, this ); + } + + return pVModel; +} + + +const studiohdr_t *studiohdr_t::FindModel( void **cache, char const *modelname ) const +{ + studiohdr_t *hdr = (studiohdr_t *)(*cache); + + if (hdr) + { + return hdr; + } + + hdr = FindOrLoadGroupFile( modelname ); + + *cache = (void *)hdr; + + return hdr; +} + +const studiohdr_t *virtualgroup_t::GetStudioHdr( void ) const +{ + return (studiohdr_t *)cache; +} + + +byte *studiohdr_t::GetAnimBlock( int i ) const +{ + byte *hdr = (byte *)animblockModel; + + if (!hdr) + { + hdr = (byte *)FindOrLoadGroupFile( pszAnimBlockName() ); + animblockModel = hdr; + } + + return hdr + pAnimBlock( i )->datastart; +} + +//----------------------------------------------------------------------------- +// Purpose: Builds up a dictionary of autoplay indices by studiohdr_t * +// NOTE: This list never gets freed even if the model gets unloaded, but we're in a tool so we can probably live with that +//----------------------------------------------------------------------------- +struct AutoPlayGeneric_t +{ +public: + + AutoPlayGeneric_t() : + hdr( 0 ) + { + } + + // Implement copy constructor + AutoPlayGeneric_t( const AutoPlayGeneric_t& src ) + { + hdr = src.hdr; + autoplaylist.EnsureCount( src.autoplaylist.Count() ); + autoplaylist.CopyArray( src.autoplaylist.Base(), src.autoplaylist.Count() ); + } + + static bool AutoPlayGenericLessFunc( const AutoPlayGeneric_t& lhs, const AutoPlayGeneric_t& rhs ) + { + return lhs.hdr < rhs.hdr; + } + +public: + // Data + const studiohdr_t *hdr; + CUtlVector< unsigned short > autoplaylist; +}; + +// A global array to track this data +static CUtlRBTree< AutoPlayGeneric_t, int > g_AutoPlayGeneric( 0, 0, AutoPlayGeneric_t::AutoPlayGenericLessFunc ); + +int studiohdr_t::GetAutoplayList( unsigned short **pAutoplayList ) const +{ + virtualmodel_t *pVirtualModel = GetVirtualModel(); + if ( pVirtualModel ) + { + if ( pAutoplayList && pVirtualModel->m_autoplaySequences.Count() ) + { + *pAutoplayList = pVirtualModel->m_autoplaySequences.Base(); + } + return pVirtualModel->m_autoplaySequences.Count(); + } + + AutoPlayGeneric_t *pData = NULL; + + // Search for this studiohdr_t ptr in the global list + AutoPlayGeneric_t search; + search.hdr = this; + int index = g_AutoPlayGeneric.Find( search ); + if ( index == g_AutoPlayGeneric.InvalidIndex() ) + { + // Not there, so add it + index = g_AutoPlayGeneric.Insert( search ); + pData = &g_AutoPlayGeneric[ index ]; + // And compute the autoplay info this one time + int autoPlayCount = CountAutoplaySequences(); + pData->autoplaylist.EnsureCount( autoPlayCount ); + CopyAutoplaySequences( pData->autoplaylist.Base(), autoPlayCount ); + } + else + { + // Refer to existing data + pData = &g_AutoPlayGeneric[ index ]; + } + + // Oops!!! + if ( !pData ) + { + return 0; + } + + // Give back data if it's being requested + if ( pAutoplayList ) + { + *pAutoplayList = pData->autoplaylist.Base(); + } + return pData->autoplaylist.Count(); +} diff --git a/sp/src/public/studio_virtualmodel.cpp b/sp/src/public/studio_virtualmodel.cpp new file mode 100644 index 00000000..0a658df6 --- /dev/null +++ b/sp/src/public/studio_virtualmodel.cpp @@ -0,0 +1,594 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include +#include "studio.h" +#include "tier1/utlmap.h" +#include "tier1/utldict.h" +#include "tier1/utlbuffer.h" +#include "filesystem.h" +#include "tier0/icommandline.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +extern IFileSystem * g_pFileSystem; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +// a string table to speed up searching for sequences in the current virtual model +struct modellookup_t +{ + CUtlDict seqTable; + CUtlDict animTable; +}; + +static CUtlVector g_ModelLookup; +static int g_ModelLookupIndex = -1; + +inline bool HasLookupTable() +{ + return g_ModelLookupIndex >= 0 ? true : false; +} + +inline CUtlDict *GetSeqTable() +{ + return &g_ModelLookup[g_ModelLookupIndex].seqTable; +} + +inline CUtlDict *GetAnimTable() +{ + return &g_ModelLookup[g_ModelLookupIndex].animTable; +} + +class CModelLookupContext +{ +public: + CModelLookupContext(int group, const studiohdr_t *pStudioHdr); + ~CModelLookupContext(); + +private: + int m_lookupIndex; +}; + +CModelLookupContext::CModelLookupContext(int group, const studiohdr_t *pStudioHdr) +{ + m_lookupIndex = -1; + if ( group == 0 && pStudioHdr->numincludemodels ) + { + m_lookupIndex = g_ModelLookup.AddToTail(); + g_ModelLookupIndex = g_ModelLookup.Count()-1; + } +} + +CModelLookupContext::~CModelLookupContext() +{ + if ( m_lookupIndex >= 0 ) + { + Assert(m_lookupIndex == (g_ModelLookup.Count()-1)); + g_ModelLookup.FastRemove(m_lookupIndex); + g_ModelLookupIndex = g_ModelLookup.Count()-1; + } +} + +void virtualmodel_t::AppendModels( int group, const studiohdr_t *pStudioHdr ) +{ + AUTO_LOCK_( CThreadTerminalMutex, m_Lock ); + + // build a search table if necesary + CModelLookupContext ctx(group, pStudioHdr); + + AppendSequences( group, pStudioHdr ); + AppendAnimations( group, pStudioHdr ); + AppendBonemap( group, pStudioHdr ); + AppendAttachments( group, pStudioHdr ); + AppendPoseParameters( group, pStudioHdr ); + AppendNodes( group, pStudioHdr ); + AppendIKLocks( group, pStudioHdr ); + + struct HandleAndHeader_t + { + void *handle; + const studiohdr_t *pHdr; + }; + HandleAndHeader_t list[64]; + + // determine quantity of valid include models in one pass only + // temporarily cache results off, otherwise FindModel() causes ref counting problems + int j; + int nValidIncludes = 0; + for (j = 0; j < pStudioHdr->numincludemodels; j++) + { + // find model (increases ref count) + void *tmp = NULL; + const studiohdr_t *pTmpHdr = pStudioHdr->FindModel( &tmp, pStudioHdr->pModelGroup( j )->pszName() ); + if ( pTmpHdr ) + { + if ( nValidIncludes >= ARRAYSIZE( list ) ) + { + // would cause stack overflow + Assert( 0 ); + break; + } + + list[nValidIncludes].handle = tmp; + list[nValidIncludes].pHdr = pTmpHdr; + nValidIncludes++; + } + } + + if ( nValidIncludes ) + { + m_group.EnsureCapacity( m_group.Count() + nValidIncludes ); + for (j = 0; j < nValidIncludes; j++) + { + MEM_ALLOC_CREDIT(); + int group = m_group.AddToTail(); + m_group[group].cache = list[j].handle; + AppendModels( group, list[j].pHdr ); + } + } + + UpdateAutoplaySequences( pStudioHdr ); +} + +void virtualmodel_t::AppendSequences( int group, const studiohdr_t *pStudioHdr ) +{ + AUTO_LOCK_( CThreadTerminalMutex, m_Lock ); + int numCheck = m_seq.Count(); + + int j, k; + + MEM_ALLOC_CREDIT(); + + CUtlVector< virtualsequence_t > seq; + + seq = m_seq; + + m_group[ group ].masterSeq.SetCount( pStudioHdr->numlocalseq ); + + for (j = 0; j < pStudioHdr->numlocalseq; j++) + { + const mstudioseqdesc_t *seqdesc = pStudioHdr->pLocalSeqdesc( j ); + char *s1 = seqdesc->pszLabel(); + + if ( HasLookupTable() ) + { + k = numCheck; + short index = GetSeqTable()->Find( s1 ); + if ( index != GetSeqTable()->InvalidIndex() ) + { + k = GetSeqTable()->Element(index); + } + } + else + { + for (k = 0; k < numCheck; k++) + { + const studiohdr_t *hdr = m_group[ seq[k].group ].GetStudioHdr(); + char *s2 = hdr->pLocalSeqdesc( seq[k].index )->pszLabel(); + if ( !stricmp( s1, s2 ) ) + { + break; + } + } + } + // no duplication + if (k == numCheck) + { + virtualsequence_t tmp; + tmp.group = group; + tmp.index = j; + tmp.flags = seqdesc->flags; + tmp.activity = seqdesc->activity; + k = seq.AddToTail( tmp ); + } + else if (m_group[ seq[k].group ].GetStudioHdr()->pLocalSeqdesc( seq[k].index )->flags & STUDIO_OVERRIDE) + { + // the one in memory is a forward declared sequence, override it + virtualsequence_t tmp; + tmp.group = group; + tmp.index = j; + tmp.flags = seqdesc->flags; + tmp.activity = seqdesc->activity; + seq[k] = tmp; + } + m_group[ group ].masterSeq[ j ] = k; + } + + if ( HasLookupTable() ) + { + for ( j = numCheck; j < seq.Count(); j++ ) + { + const studiohdr_t *hdr = m_group[ seq[j].group ].GetStudioHdr(); + const char *s1 = hdr->pLocalSeqdesc( seq[j].index )->pszLabel(); + GetSeqTable()->Insert( s1, j ); + } + } + + m_seq = seq; +} + + +void virtualmodel_t::UpdateAutoplaySequences( const studiohdr_t *pStudioHdr ) +{ + AUTO_LOCK_( CThreadTerminalMutex, m_Lock ); + int autoplayCount = pStudioHdr->CountAutoplaySequences(); + m_autoplaySequences.SetCount( autoplayCount ); + pStudioHdr->CopyAutoplaySequences( m_autoplaySequences.Base(), autoplayCount ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void virtualmodel_t::AppendAnimations( int group, const studiohdr_t *pStudioHdr ) +{ + AUTO_LOCK_( CThreadTerminalMutex, m_Lock ); + int numCheck = m_anim.Count(); + + CUtlVector< virtualgeneric_t > anim; + anim = m_anim; + + MEM_ALLOC_CREDIT(); + + int j, k; + + m_group[ group ].masterAnim.SetCount( pStudioHdr->numlocalanim ); + + for (j = 0; j < pStudioHdr->numlocalanim; j++) + { + char *s1 = pStudioHdr->pLocalAnimdesc( j )->pszName(); + if ( HasLookupTable() ) + { + k = numCheck; + short index = GetAnimTable()->Find( s1 ); + if ( index != GetAnimTable()->InvalidIndex() ) + { + k = GetAnimTable()->Element(index); + } + } + else + { + for (k = 0; k < numCheck; k++) + { + char *s2 = m_group[ anim[k].group ].GetStudioHdr()->pLocalAnimdesc( anim[k].index )->pszName(); + if (stricmp( s1, s2 ) == 0) + { + break; + } + } + } + // no duplication + if (k == numCheck) + { + virtualgeneric_t tmp; + tmp.group = group; + tmp.index = j; + k = anim.AddToTail( tmp ); + } + + m_group[ group ].masterAnim[ j ] = k; + } + + if ( HasLookupTable() ) + { + for ( j = numCheck; j < anim.Count(); j++ ) + { + const char *s1 = m_group[ anim[j].group ].GetStudioHdr()->pLocalAnimdesc( anim[j].index )->pszName(); + GetAnimTable()->Insert( s1, j ); + } + } + + m_anim = anim; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void virtualmodel_t::AppendBonemap( int group, const studiohdr_t *pStudioHdr ) +{ + AUTO_LOCK_( CThreadTerminalMutex, m_Lock ); + MEM_ALLOC_CREDIT(); + + const studiohdr_t *pBaseStudioHdr = m_group[ 0 ].GetStudioHdr( ); + + m_group[ group ].boneMap.SetCount( pBaseStudioHdr->numbones ); + m_group[ group ].masterBone.SetCount( pStudioHdr->numbones ); + + int j, k; + + if (group == 0) + { + for (j = 0; j < pStudioHdr->numbones; j++) + { + m_group[ group ].boneMap[ j ] = j; + m_group[ group ].masterBone[ j ] = j; + } + } + else + { + for (j = 0; j < pBaseStudioHdr->numbones; j++) + { + m_group[ group ].boneMap[ j ] = -1; + } + for (j = 0; j < pStudioHdr->numbones; j++) + { + // NOTE: studiohdr has a bone table - using the table is ~5% faster than this for alyx.mdl on a P4/3.2GHz + for (k = 0; k < pBaseStudioHdr->numbones; k++) + { + if (stricmp( pStudioHdr->pBone( j )->pszName(), pBaseStudioHdr->pBone( k )->pszName() ) == 0) + { + break; + } + } + if (k < pBaseStudioHdr->numbones) + { + m_group[ group ].masterBone[ j ] = k; + m_group[ group ].boneMap[ k ] = j; + + // FIXME: these runtime messages don't display in hlmv + if ((pStudioHdr->pBone( j )->parent == -1) || (pBaseStudioHdr->pBone( k )->parent == -1)) + { + if ((pStudioHdr->pBone( j )->parent != -1) || (pBaseStudioHdr->pBone( k )->parent != -1)) + { + Warning( "%s/%s : missmatched parent bones on \"%s\"\n", pBaseStudioHdr->pszName(), pStudioHdr->pszName(), pStudioHdr->pBone( j )->pszName() ); + } + } + else if (m_group[ group ].masterBone[ pStudioHdr->pBone( j )->parent ] != m_group[ 0 ].masterBone[ pBaseStudioHdr->pBone( k )->parent ]) + { + Warning( "%s/%s : missmatched parent bones on \"%s\"\n", pBaseStudioHdr->pszName(), pStudioHdr->pszName(), pStudioHdr->pBone( j )->pszName() ); + } + } + else + { + m_group[ group ].masterBone[ j ] = -1; + } + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void virtualmodel_t::AppendAttachments( int group, const studiohdr_t *pStudioHdr ) +{ + AUTO_LOCK_( CThreadTerminalMutex, m_Lock ); + int numCheck = m_attachment.Count(); + + CUtlVector< virtualgeneric_t > attachment; + attachment = m_attachment; + + MEM_ALLOC_CREDIT(); + + int j, k, n; + + m_group[ group ].masterAttachment.SetCount( pStudioHdr->numlocalattachments ); + + for (j = 0; j < pStudioHdr->numlocalattachments; j++) + { + + n = m_group[ group ].masterBone[ pStudioHdr->pLocalAttachment( j )->localbone ]; + + // skip if the attachments bone doesn't exist in the root model + if (n == -1) + { + continue; + } + + + char *s1 = pStudioHdr->pLocalAttachment( j )->pszName(); + for (k = 0; k < numCheck; k++) + { + char *s2 = m_group[ attachment[k].group ].GetStudioHdr()->pLocalAttachment( attachment[k].index )->pszName(); + + if (stricmp( s1, s2 ) == 0) + { + break; + } + } + // no duplication + if (k == numCheck) + { + virtualgeneric_t tmp; + tmp.group = group; + tmp.index = j; + k = attachment.AddToTail( tmp ); + + // make sure bone flags are set so attachment calculates + if ((m_group[ 0 ].GetStudioHdr()->pBone( n )->flags & BONE_USED_BY_ATTACHMENT) == 0) + { + while (n != -1) + { + m_group[ 0 ].GetStudioHdr()->pBone( n )->flags |= BONE_USED_BY_ATTACHMENT; + + if (m_group[ 0 ].GetStudioHdr()->pLinearBones()) + { + *m_group[ 0 ].GetStudioHdr()->pLinearBones()->pflags(n) |= BONE_USED_BY_ATTACHMENT; + } + + n = m_group[ 0 ].GetStudioHdr()->pBone( n )->parent; + } + continue; + } + } + + m_group[ group ].masterAttachment[ j ] = k; + } + + m_attachment = attachment; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void virtualmodel_t::AppendPoseParameters( int group, const studiohdr_t *pStudioHdr ) +{ + AUTO_LOCK_( CThreadTerminalMutex, m_Lock ); + int numCheck = m_pose.Count(); + + CUtlVector< virtualgeneric_t > pose; + pose = m_pose; + + MEM_ALLOC_CREDIT(); + + int j, k; + + m_group[ group ].masterPose.SetCount( pStudioHdr->numlocalposeparameters ); + + for (j = 0; j < pStudioHdr->numlocalposeparameters; j++) + { + char *s1 = pStudioHdr->pLocalPoseParameter( j )->pszName(); + for (k = 0; k < numCheck; k++) + { + char *s2 = m_group[ pose[k].group ].GetStudioHdr()->pLocalPoseParameter( pose[k].index )->pszName(); + + if (stricmp( s1, s2 ) == 0) + { + break; + } + } + if (k == numCheck) + { + // no duplication + virtualgeneric_t tmp; + tmp.group = group; + tmp.index = j; + k = pose.AddToTail( tmp ); + } + else + { + // duplicate, reset start and end to fit full dynamic range + mstudioposeparamdesc_t *pPose1 = pStudioHdr->pLocalPoseParameter( j ); + mstudioposeparamdesc_t *pPose2 = m_group[ pose[k].group ].GetStudioHdr()->pLocalPoseParameter( pose[k].index ); + float start = min( pPose2->end, min( pPose1->end, min( pPose2->start, pPose1->start ) ) ); + float end = max( pPose2->end, max( pPose1->end, max( pPose2->start, pPose1->start ) ) ); + pPose2->start = start; + pPose2->end = end; + } + + m_group[ group ].masterPose[ j ] = k; + } + + m_pose = pose; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +void virtualmodel_t::AppendNodes( int group, const studiohdr_t *pStudioHdr ) +{ + AUTO_LOCK_( CThreadTerminalMutex, m_Lock ); + int numCheck = m_node.Count(); + + CUtlVector< virtualgeneric_t > node; + node = m_node; + + MEM_ALLOC_CREDIT(); + + int j, k; + + m_group[ group ].masterNode.SetCount( pStudioHdr->numlocalnodes ); + + for (j = 0; j < pStudioHdr->numlocalnodes; j++) + { + char *s1 = pStudioHdr->pszLocalNodeName( j ); + for (k = 0; k < numCheck; k++) + { + char *s2 = m_group[ node[k].group ].GetStudioHdr()->pszLocalNodeName( node[k].index ); + + if (stricmp( s1, s2 ) == 0) + { + break; + } + } + // no duplication + if (k == numCheck) + { + virtualgeneric_t tmp; + tmp.group = group; + tmp.index = j; + k = node.AddToTail( tmp ); + } + + m_group[ group ].masterNode[ j ] = k; + } + + m_node = node; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + + +void virtualmodel_t::AppendIKLocks( int group, const studiohdr_t *pStudioHdr ) +{ + AUTO_LOCK_( CThreadTerminalMutex, m_Lock ); + int numCheck = m_iklock.Count(); + + CUtlVector< virtualgeneric_t > iklock; + iklock = m_iklock; + + int j, k; + + for (j = 0; j < pStudioHdr->numlocalikautoplaylocks; j++) + { + int chain1 = pStudioHdr->pLocalIKAutoplayLock( j )->chain; + for (k = 0; k < numCheck; k++) + { + int chain2 = m_group[ iklock[k].group ].GetStudioHdr()->pLocalIKAutoplayLock( iklock[k].index )->chain; + + if (chain1 == chain2) + { + break; + } + } + // no duplication + if (k == numCheck) + { + MEM_ALLOC_CREDIT(); + + virtualgeneric_t tmp; + tmp.group = group; + tmp.index = j; + k = iklock.AddToTail( tmp ); + } + } + + m_iklock = iklock; + + // copy knee directions for uninitialized knees + if ( group != 0 ) + { + studiohdr_t *pBaseHdr = (studiohdr_t *)m_group[ 0 ].GetStudioHdr(); + if ( pStudioHdr->numikchains == pBaseHdr->numikchains ) + { + for (j = 0; j < pStudioHdr->numikchains; j++) + { + if ( pBaseHdr->pIKChain( j )->pLink(0)->kneeDir.LengthSqr() == 0.0f ) + { + if ( pStudioHdr->pIKChain( j )->pLink(0)->kneeDir.LengthSqr() > 0.0f ) + { + pBaseHdr->pIKChain( j )->pLink(0)->kneeDir = pStudioHdr->pIKChain( j )->pLink(0)->kneeDir; + } + } + } + } + } +} diff --git a/sp/src/public/surfinfo.h b/sp/src/public/surfinfo.h new file mode 100644 index 00000000..a4d4dba9 --- /dev/null +++ b/sp/src/public/surfinfo.h @@ -0,0 +1,31 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// +#ifndef SURFINFO_H +#define SURFINFO_H +#ifdef _WIN32 +#pragma once +#endif + +#include "mathlib/vplane.h" + +//#include "mathlib/vector.h" +#define MAX_SURFINFO_VERTS 16 +class SurfInfo +{ +public: + // Shape of the surface. + Vector m_Verts[ MAX_SURFINFO_VERTS ]; + unsigned long m_nVerts; + + // Plane of the surface. + VPlane m_Plane; + + // For engine use only.. + void *m_pEngineData; +}; + +#endif // SURFINFO_H diff --git a/sp/src/public/terrainmorph.cpp b/sp/src/public/terrainmorph.cpp new file mode 100644 index 00000000..829dacfd --- /dev/null +++ b/sp/src/public/terrainmorph.cpp @@ -0,0 +1,27 @@ + +#include "terrainmorph.h" + + +public void ApplyTerrainMorph(ITerrainMod* pMod) +{ +#if 1 + + int nVertCount = CDispCollTree().GetSize(); + for (int iVert = 0; iVert < nVertCount; ++iVert) + { + Vector pos; + pMod->ApplyMod(CDispCollTree().m_aVerts[iVert] + Vector(0, 0, 10), CDispCollTree().m_aVerts[iVert]); + //pMod->ApplyMod(m_aVerts[iVert], m_aVerts[iVert]); + } + + // Setup/create the leaf nodes first so the recursion can use this data to stop. + CDispCollTree().AABBTree_CreateLeafs(); + + // Generate bounding boxes. + //AABBTree_GenerateBoxes(); + + // Create the bounding box of the displacement surface + the base face. + CDispCollTree().AABBTree_CalcBounds(); +#endif + +} \ No newline at end of file diff --git a/sp/src/public/terrainmorph.h b/sp/src/public/terrainmorph.h new file mode 100644 index 00000000..1e9e8095 --- /dev/null +++ b/sp/src/public/terrainmorph.h @@ -0,0 +1,5 @@ + +#include "eifacev21.h" +#include "DISPCOLL_COMMON.H" + +void ApplyTerrainMorph(ITerrainMod* pMod); //Morphing displacement \ No newline at end of file diff --git a/sp/src/public/texture_group_names.h b/sp/src/public/texture_group_names.h new file mode 100644 index 00000000..b30ed35a --- /dev/null +++ b/sp/src/public/texture_group_names.h @@ -0,0 +1,43 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//===========================================================================// + +#ifndef TEXTURE_GROUP_NAMES_H +#define TEXTURE_GROUP_NAMES_H +#ifdef _WIN32 +#pragma once +#endif + +// These are given to FindMaterial to reference the texture groups that show up on the +#define TEXTURE_GROUP_LIGHTMAP "Lightmaps" +#define TEXTURE_GROUP_WORLD "World textures" +#define TEXTURE_GROUP_MODEL "Model textures" +#define TEXTURE_GROUP_VGUI "VGUI textures" +#define TEXTURE_GROUP_PARTICLE "Particle textures" +#define TEXTURE_GROUP_DECAL "Decal textures" +#define TEXTURE_GROUP_SKYBOX "SkyBox textures" +#define TEXTURE_GROUP_CLIENT_EFFECTS "ClientEffect textures" +#define TEXTURE_GROUP_OTHER "Other textures" +#define TEXTURE_GROUP_PRECACHED "Precached" // TODO: assign texture groups to the precached materials +#define TEXTURE_GROUP_CUBE_MAP "CubeMap textures" +#define TEXTURE_GROUP_RENDER_TARGET "RenderTargets" +#define TEXTURE_GROUP_UNACCOUNTED "Unaccounted textures" // Textures that weren't assigned a texture group. +//#define TEXTURE_GROUP_STATIC_VERTEX_BUFFER "Static Vertex" +#define TEXTURE_GROUP_STATIC_INDEX_BUFFER "Static Indices" +#define TEXTURE_GROUP_STATIC_VERTEX_BUFFER_DISP "Displacement Verts" +#define TEXTURE_GROUP_STATIC_VERTEX_BUFFER_COLOR "Lighting Verts" +#define TEXTURE_GROUP_STATIC_VERTEX_BUFFER_WORLD "World Verts" +#define TEXTURE_GROUP_STATIC_VERTEX_BUFFER_MODELS "Model Verts" +#define TEXTURE_GROUP_STATIC_VERTEX_BUFFER_OTHER "Other Verts" +#define TEXTURE_GROUP_DYNAMIC_INDEX_BUFFER "Dynamic Indices" +#define TEXTURE_GROUP_DYNAMIC_VERTEX_BUFFER "Dynamic Verts" +#define TEXTURE_GROUP_DEPTH_BUFFER "DepthBuffer" +#define TEXTURE_GROUP_VIEW_MODEL "ViewModel" +#define TEXTURE_GROUP_PIXEL_SHADERS "Pixel Shaders" +#define TEXTURE_GROUP_VERTEX_SHADERS "Vertex Shaders" +#define TEXTURE_GROUP_RENDER_TARGET_SURFACE "RenderTarget Surfaces" +#define TEXTURE_GROUP_MORPH_TARGETS "Morph Targets" + +#endif // TEXTURE_GROUP_NAMES_H diff --git a/sp/src/public/trace.h b/sp/src/public/trace.h new file mode 100644 index 00000000..765acd57 --- /dev/null +++ b/sp/src/public/trace.h @@ -0,0 +1,69 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef TRACE_H +#define TRACE_H + +#ifdef _WIN32 +#pragma once +#endif + + +#include "mathlib/mathlib.h" + +// Note: These flags need to match the bspfile.h DISPTRI_TAG_* flags. +#define DISPSURF_FLAG_SURFACE (1<<0) +#define DISPSURF_FLAG_WALKABLE (1<<1) +#define DISPSURF_FLAG_BUILDABLE (1<<2) +#define DISPSURF_FLAG_SURFPROP1 (1<<3) +#define DISPSURF_FLAG_SURFPROP2 (1<<4) + +//============================================================================= +// Base Trace Structure +// - shared between engine/game dlls and tools (vrad) +//============================================================================= + +class CBaseTrace +{ +public: + + // Displacement flags tests. + bool IsDispSurface( void ) { return ( ( dispFlags & DISPSURF_FLAG_SURFACE ) != 0 ); } + bool IsDispSurfaceWalkable( void ) { return ( ( dispFlags & DISPSURF_FLAG_WALKABLE ) != 0 ); } + bool IsDispSurfaceBuildable( void ) { return ( ( dispFlags & DISPSURF_FLAG_BUILDABLE ) != 0 ); } + bool IsDispSurfaceProp1( void ) { return ( ( dispFlags & DISPSURF_FLAG_SURFPROP1 ) != 0 ); } + bool IsDispSurfaceProp2( void ) { return ( ( dispFlags & DISPSURF_FLAG_SURFPROP2 ) != 0 ); } + +public: + + // these members are aligned!! + Vector startpos; // start position + Vector endpos; // final position + cplane_t plane; // surface normal at impact + + float fraction; // time completed, 1.0 = didn't hit anything + + int contents; // contents on other side of surface hit + unsigned short dispFlags; // displacement flags for marking surfaces with data + + bool allsolid; // if true, plane is not valid + bool startsolid; // if true, the initial point was in a solid area + + CBaseTrace() {} + +private: + // No copy constructors allowed + CBaseTrace(const CBaseTrace& vOther); +}; + +#endif // TRACE_H diff --git a/sp/src/public/vallocator.cpp b/sp/src/public/vallocator.cpp new file mode 100644 index 00000000..be717033 --- /dev/null +++ b/sp/src/public/vallocator.cpp @@ -0,0 +1,36 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#if !defined(_STATIC_LINKED) || defined(_SHARED_LIB) + +#include +#include "vallocator.h" +#include "basetypes.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +VStdAllocator g_StdAllocator; + +void* VStdAllocator::Alloc(unsigned long size) +{ + if(size) + { + void *ret = malloc(size); + return ret; + } + else + return 0; +} + +void VStdAllocator::Free(void *ptr) +{ + free(ptr); +} + +#endif // !_STATIC_LINKED || _SHARED_LIB diff --git a/sp/src/public/vallocator.h b/sp/src/public/vallocator.h new file mode 100644 index 00000000..d9f2130a --- /dev/null +++ b/sp/src/public/vallocator.h @@ -0,0 +1,84 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +// These classes let you write your own allocators to be used with new and delete. +// If you have an allocator: VAllocator *pAlloc, you can call new and delete like this: +// +// ptr = VNew(pAlloc) ClassName; +// VDelete(pAlloc, ptr); +// +// Note: allocating and freeing arrays of objects will not work using VAllocators. + + + +#ifndef VALLOCATOR_H +#define VALLOCATOR_H + + +class VAllocator +{ +public: + virtual void* Alloc(unsigned long size)=0; + virtual void Free(void *ptr)=0; +}; + + +// This allocator just uses malloc and free. +class VStdAllocator : public VAllocator +{ +public: + virtual void* Alloc(unsigned long size); + virtual void Free(void *ptr); +}; +extern VStdAllocator g_StdAllocator; + + + +// Use these to allocate classes through VAllocator. +// Allocating arrays of classes is not supported. +#define VNew(pAlloc) new +#define VDelete(pAlloc, ptr) delete ptr + +// Used internally.. just makes sure we call the right operator new. +class DummyAllocatorHelper +{ +public: + int x; +}; + +inline void* operator new(size_t size, void *ptr, DummyAllocatorHelper *asdf) +{ + asdf=asdf; // compiler warning. + size=size; + return ptr; +} + +inline void operator delete(void *ptrToDelete, void *ptr, DummyAllocatorHelper *asdf) +{ + asdf=asdf; // compiler warning. + ptr=ptr; + ptrToDelete=ptrToDelete; +} + +// Use these to manually construct and destruct lists of objects. +template +inline void VAllocator_CallConstructors(T *pObjects, int count=1) +{ + for(int i=0; i < count; i++) + new(&pObjects[i], (DummyAllocatorHelper*)0) T; +} + +template +inline void VAllocator_CallDestructors(T *pObjects, int count) +{ + for(int i=0; i < count; i++) + pObjects[i].~T(); +} + +#endif + diff --git a/sp/src/public/vcollide.h b/sp/src/public/vcollide.h new file mode 100644 index 00000000..f4ebf62c --- /dev/null +++ b/sp/src/public/vcollide.h @@ -0,0 +1,26 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef VCOLLIDE_H +#define VCOLLIDE_H +#ifdef _WIN32 +#pragma once +#endif + +class CPhysCollide; + +struct vcollide_t +{ + unsigned short solidCount : 15; + unsigned short isPacked : 1; + unsigned short descSize; + // VPhysicsSolids + CPhysCollide **solids; + char *pKeyValues; +}; + +#endif // VCOLLIDE_H diff --git a/sp/src/public/vcollide_parse.h b/sp/src/public/vcollide_parse.h new file mode 100644 index 00000000..675c4569 --- /dev/null +++ b/sp/src/public/vcollide_parse.h @@ -0,0 +1,68 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef VCOLLIDE_PARSE_H +#define VCOLLIDE_PARSE_H +#ifdef _WIN32 +#pragma once +#endif + +#include "vphysics_interface.h" + +struct solid_t +{ + int index; + char name[512]; + char parent[512]; + char surfaceprop[512]; + Vector massCenterOverride; + objectparams_t params; +}; + +struct fluid_t +{ + int index; + char surfaceprop[512]; + + fluidparams_t params; + + fluid_t() {} + fluid_t( fluid_t const& src ) : params(src.params) + { + index = src.index; + } +}; + +//----------------------------------------------------------------------------- +// Purpose: Pass this into the parser to handle the keys that vphysics does not +// parse. +//----------------------------------------------------------------------------- +class IVPhysicsKeyHandler +{ +public: + virtual void ParseKeyValue( void *pData, const char *pKey, const char *pValue ) = 0; + virtual void SetDefaults( void *pData ) = 0; +}; + + +class IVPhysicsKeyParser +{ +public: + virtual ~IVPhysicsKeyParser() {} + + virtual const char *GetCurrentBlockName( void ) = 0; + virtual bool Finished( void ) = 0; + virtual void ParseSolid( solid_t *pSolid, IVPhysicsKeyHandler *unknownKeyHandler ) = 0; + virtual void ParseFluid( fluid_t *pFluid, IVPhysicsKeyHandler *unknownKeyHandler ) = 0; + virtual void ParseRagdollConstraint( constraint_ragdollparams_t *pConstraint, IVPhysicsKeyHandler *unknownKeyHandler ) = 0; + virtual void ParseSurfaceTable( int *table, IVPhysicsKeyHandler *unknownKeyHandler ) = 0; + virtual void ParseCustom( void *pCustom, IVPhysicsKeyHandler *unknownKeyHandler ) = 0; + virtual void ParseVehicle( vehicleparams_t *pVehicle, IVPhysicsKeyHandler *unknownKeyHandler ) = 0; + virtual void SkipBlock( void ) = 0; +}; + +#endif // VCOLLIDE_PARSE_H diff --git a/sp/src/public/view_shared.h b/sp/src/public/view_shared.h new file mode 100644 index 00000000..a5af4d3e --- /dev/null +++ b/sp/src/public/view_shared.h @@ -0,0 +1,136 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef VIEW_SHARED_H +#define VIEW_SHARED_H + +#ifdef _WIN32 +#pragma once +#endif + +#include "convar.h" +#include "mathlib/vector.h" +#include "materialsystem/MaterialSystemUtil.h" + + +//----------------------------------------------------------------------------- +// Flags passed in with view setup +//----------------------------------------------------------------------------- +enum ClearFlags_t +{ + VIEW_CLEAR_COLOR = 0x1, + VIEW_CLEAR_DEPTH = 0x2, + VIEW_CLEAR_FULL_TARGET = 0x4, + VIEW_NO_DRAW = 0x8, + VIEW_CLEAR_OBEY_STENCIL = 0x10, // Draws a quad allowing stencil test to clear through portals + VIEW_CLEAR_STENCIL = 0x20, +}; + +enum StereoEye_t +{ + STEREO_EYE_MONO = 0, + STEREO_EYE_LEFT = 1, + STEREO_EYE_RIGHT = 2, + STEREO_EYE_MAX = 3, +}; + + +//----------------------------------------------------------------------------- +// Purpose: Renderer setup data. +//----------------------------------------------------------------------------- +class CViewSetup +{ +public: + CViewSetup() + { + m_flAspectRatio = 0.0f; + m_bRenderToSubrectOfLargerScreen = false; + m_bDoBloomAndToneMapping = true; + m_bOrtho = false; + m_bOffCenter = false; + m_bCacheFullSceneState = false; +// m_bUseExplicitViewVector = false; + m_bViewToProjectionOverride = false; + m_eStereoEye = STEREO_EYE_MONO; + } + +// shared by 2D & 3D views + + // left side of view window + int x; + int m_nUnscaledX; + // top side of view window + int y; + int m_nUnscaledY; + // width of view window + int width; + int m_nUnscaledWidth; + // height of view window + int height; + // which eye are we rendering? + StereoEye_t m_eStereoEye; + int m_nUnscaledHeight; + +// the rest are only used by 3D views + + // Orthographic projection? + bool m_bOrtho; + // View-space rectangle for ortho projection. + float m_OrthoLeft; + float m_OrthoTop; + float m_OrthoRight; + float m_OrthoBottom; + + // horizontal FOV in degrees + float fov; + // horizontal FOV in degrees for in-view model + float fovViewmodel; + + // 3D origin of camera + Vector origin; + + // heading of camera (pitch, yaw, roll) + QAngle angles; + // local Z coordinate of near plane of camera + float zNear; + // local Z coordinate of far plane of camera + float zFar; + + // local Z coordinate of near plane of camera ( when rendering view model ) + float zNearViewmodel; + // local Z coordinate of far plane of camera ( when rendering view model ) + float zFarViewmodel; + + // set to true if this is to draw into a subrect of the larger screen + // this really is a hack, but no more than the rest of the way this class is used + bool m_bRenderToSubrectOfLargerScreen; + + // The aspect ratio to use for computing the perspective projection matrix + // (0.0f means use the viewport) + float m_flAspectRatio; + + // Controls for off-center projection (needed for poster rendering) + bool m_bOffCenter; + float m_flOffCenterTop; + float m_flOffCenterBottom; + float m_flOffCenterLeft; + float m_flOffCenterRight; + + // Control that the SFM needs to tell the engine not to do certain post-processing steps + bool m_bDoBloomAndToneMapping; + + // Cached mode for certain full-scene per-frame varying state such as sun entity coverage + bool m_bCacheFullSceneState; + + // If using VR, the headset calibration will feed you a projection matrix per-eye. + // This does NOT override the Z range - that will be set up as normal (i.e. the values in this matrix will be ignored). + bool m_bViewToProjectionOverride; + VMatrix m_ViewToProjection; +}; + + + +#endif // VIEW_SHARED_H diff --git a/sp/src/public/vphysics_interface.h b/sp/src/public/vphysics_interface.h new file mode 100644 index 00000000..d6e61935 --- /dev/null +++ b/sp/src/public/vphysics_interface.h @@ -0,0 +1,1176 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Public interfaces to vphysics DLL +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef VPHYSICS_INTERFACE_H +#define VPHYSICS_INTERFACE_H +#ifdef _WIN32 +#pragma once +#endif + + +#include "tier1/interface.h" +#include "appframework/IAppSystem.h" +#include "mathlib/vector.h" +#include "mathlib/vector4d.h" +#include "vcollide.h" + + +// ------------------------------------------------------------------------------------ +// UNITS: +// ------------------------------------------------------------------------------------ +// NOTE: Coordinates are in HL units. 1 unit == 1 inch. X is east (forward), Y is north (left), Z is up (up) +// QAngle are pitch (around y), Yaw (around Z), Roll (around X) +// AngularImpulse are exponetial maps (an axis in HL units scaled by a "twist" angle in degrees) +// They can be transformed like normals/covectors and added linearly +// mass is kg, volume is in^3, acceleration is in/s^2, velocity is in/s + +// density is kg/m^3 (water ~= 998 at room temperature) +// preferably, these would be in kg/in^3, but the range of those numbers makes them not very human readable +// having water be about 1000 is really convenient for data entry. +// Since volume is in in^3 and density is in kg/m^3: +// density = (mass / volume) * CUBIC_METERS_PER_CUBIC_INCH +// Force is applied using impulses (kg*in/s) +// Torque is applied using impulses (kg*degrees/s) +// ------------------------------------------------------------------------------------ + +#define METERS_PER_INCH (0.0254f) +#define CUBIC_METERS_PER_CUBIC_INCH (METERS_PER_INCH*METERS_PER_INCH*METERS_PER_INCH) +// 2.2 lbs / kg +#define POUNDS_PER_KG (2.2f) +#define KG_PER_POUND (1.0f/POUNDS_PER_KG) + +// convert from pounds to kg +#define lbs2kg(x) ((x)*KG_PER_POUND) +#define kg2lbs(x) ((x)*POUNDS_PER_KG) + +const float VPHYSICS_MIN_MASS = 0.1f; +const float VPHYSICS_MAX_MASS = 5e4f; + +class IPhysicsObject; +class IPhysicsEnvironment; +class IPhysicsSurfaceProps; +class IPhysicsConstraint; +class IPhysicsConstraintGroup; +class IPhysicsFluidController; +class IPhysicsSpring; +class IPhysicsVehicleController; +class IConvexInfo; +class IPhysicsObjectPairHash; +class IPhysicsCollisionSet; +class IPhysicsPlayerController; +class IPhysicsFrictionSnapshot; + +struct Ray_t; +struct constraint_ragdollparams_t; +struct constraint_hingeparams_t; +struct constraint_fixedparams_t; +struct constraint_ballsocketparams_t; +struct constraint_slidingparams_t; +struct constraint_pulleyparams_t; +struct constraint_lengthparams_t; +struct constraint_groupparams_t; + +struct vehicleparams_t; +struct matrix3x4_t; + +struct fluidparams_t; +struct springparams_t; +struct objectparams_t; +struct debugcollide_t; +class CGameTrace; +typedef CGameTrace trace_t; +struct physics_stats_t; +struct physics_performanceparams_t; +struct virtualmeshparams_t; + +//enum PhysInterfaceId_t; +struct physsaveparams_t; +struct physrestoreparams_t; +struct physprerestoreparams_t; + +enum PhysInterfaceId_t +{ + PIID_UNKNOWN, + PIID_IPHYSICSOBJECT, + PIID_IPHYSICSFLUIDCONTROLLER, + PIID_IPHYSICSSPRING, + PIID_IPHYSICSCONSTRAINTGROUP, + PIID_IPHYSICSCONSTRAINT, + PIID_IPHYSICSSHADOWCONTROLLER, + PIID_IPHYSICSPLAYERCONTROLLER, + PIID_IPHYSICSMOTIONCONTROLLER, + PIID_IPHYSICSVEHICLECONTROLLER, + PIID_IPHYSICSGAMETRACE, + + PIID_NUM_TYPES +}; + + +class ISave; +class IRestore; + + +#define VPHYSICS_DEBUG_OVERLAY_INTERFACE_VERSION "VPhysicsDebugOverlay001" + +abstract_class IVPhysicsDebugOverlay +{ +public: + virtual void AddEntityTextOverlay(int ent_index, int line_offset, float duration, int r, int g, int b, int a, PRINTF_FORMAT_STRING const char *format, ...) = 0; + virtual void AddBoxOverlay(const Vector& origin, const Vector& mins, const Vector& max, QAngle const& orientation, int r, int g, int b, int a, float duration) = 0; + virtual void AddTriangleOverlay(const Vector& p1, const Vector& p2, const Vector& p3, int r, int g, int b, int a, bool noDepthTest, float duration) = 0; + virtual void AddLineOverlay(const Vector& origin, const Vector& dest, int r, int g, int b,bool noDepthTest, float duration) = 0; + virtual void AddTextOverlay(const Vector& origin, float duration, PRINTF_FORMAT_STRING const char *format, ...) = 0; + virtual void AddTextOverlay(const Vector& origin, int line_offset, float duration, PRINTF_FORMAT_STRING const char *format, ...) = 0; + virtual void AddScreenTextOverlay(float flXPos, float flYPos,float flDuration, int r, int g, int b, int a, const char *text) = 0; + virtual void AddSweptBoxOverlay(const Vector& start, const Vector& end, const Vector& mins, const Vector& max, const QAngle & angles, int r, int g, int b, int a, float flDuration) = 0; + virtual void AddTextOverlayRGB(const Vector& origin, int line_offset, float duration, float r, float g, float b, float alpha, PRINTF_FORMAT_STRING const char *format, ...) = 0; +}; + +#define VPHYSICS_INTERFACE_VERSION "VPhysics031" + +abstract_class IPhysics : public IAppSystem +{ +public: + virtual IPhysicsEnvironment *CreateEnvironment( void ) = 0; + virtual void DestroyEnvironment( IPhysicsEnvironment * ) = 0; + virtual IPhysicsEnvironment *GetActiveEnvironmentByIndex( int index ) = 0; + + // Creates a fast hash of pairs of objects + // Useful for maintaining a table of object relationships like pairs that do not collide. + virtual IPhysicsObjectPairHash *CreateObjectPairHash() = 0; + virtual void DestroyObjectPairHash( IPhysicsObjectPairHash *pHash ) = 0; + + // holds a cache of these by id. So you can get by id to search for the previously created set + // UNDONE: Sets are currently limited to 32 elements. More elements will return NULL in create. + // NOTE: id is not allowed to be zero. + virtual IPhysicsCollisionSet *FindOrCreateCollisionSet( unsigned int id, int maxElementCount ) = 0; + virtual IPhysicsCollisionSet *FindCollisionSet( unsigned int id ) = 0; + virtual void DestroyAllCollisionSets() = 0; +}; + + +// CPhysConvex is a single convex solid +class CPhysConvex; +// CPhysPolysoup is an abstract triangle soup mesh +class CPhysPolysoup; +class ICollisionQuery; +class IVPhysicsKeyParser; +struct convertconvexparams_t; +class CPackedPhysicsDescription; + +class CPolyhedron; + +// UNDONE: Find a better place for this? Should be in collisionutils, but it's needs VPHYSICS' solver. +struct truncatedcone_t +{ + Vector origin; + Vector normal; + float h; // height of the cone (hl units) + float theta; // cone angle (degrees) +}; + + +#define VPHYSICS_COLLISION_INTERFACE_VERSION "VPhysicsCollision007" + +abstract_class IPhysicsCollision +{ +public: + virtual ~IPhysicsCollision( void ) {} + + // produce a convex element from verts (convex hull around verts) + virtual CPhysConvex *ConvexFromVerts( Vector **pVerts, int vertCount ) = 0; + // produce a convex element from planes (csg of planes) + virtual CPhysConvex *ConvexFromPlanes( float *pPlanes, int planeCount, float mergeDistance ) = 0; + // calculate volume of a convex element + virtual float ConvexVolume( CPhysConvex *pConvex ) = 0; + + virtual float ConvexSurfaceArea( CPhysConvex *pConvex ) = 0; + // store game-specific data in a convex solid + virtual void SetConvexGameData( CPhysConvex *pConvex, unsigned int gameData ) = 0; + // If not converted, free the convex elements with this call + virtual void ConvexFree( CPhysConvex *pConvex ) = 0; + virtual CPhysConvex *BBoxToConvex( const Vector &mins, const Vector &maxs ) = 0; + // produce a convex element from a convex polyhedron + virtual CPhysConvex *ConvexFromConvexPolyhedron( const CPolyhedron &ConvexPolyhedron ) = 0; + // produce a set of convex triangles from a convex polygon, normal is assumed to be on the side with forward point ordering, which should be clockwise, output will need to be able to hold exactly (iPointCount-2) convexes + virtual void ConvexesFromConvexPolygon( const Vector &vPolyNormal, const Vector *pPoints, int iPointCount, CPhysConvex **pOutput ) = 0; + + // concave objects + // create a triangle soup + virtual CPhysPolysoup *PolysoupCreate( void ) = 0; + // destroy the container and memory + virtual void PolysoupDestroy( CPhysPolysoup *pSoup ) = 0; + // add a triangle to the soup + virtual void PolysoupAddTriangle( CPhysPolysoup *pSoup, const Vector &a, const Vector &b, const Vector &c, int materialIndex7bits ) = 0; + // convert the convex into a compiled collision model + virtual CPhysCollide *ConvertPolysoupToCollide( CPhysPolysoup *pSoup, bool useMOPP ) = 0; + + // Convert an array of convex elements to a compiled collision model (this deletes the convex elements) + virtual CPhysCollide *ConvertConvexToCollide( CPhysConvex **pConvex, int convexCount ) = 0; + virtual CPhysCollide *ConvertConvexToCollideParams( CPhysConvex **pConvex, int convexCount, const convertconvexparams_t &convertParams ) = 0; + // Free a collide that was created with ConvertConvexToCollide() + virtual void DestroyCollide( CPhysCollide *pCollide ) = 0; + + // Get the memory size in bytes of the collision model for serialization + virtual int CollideSize( CPhysCollide *pCollide ) = 0; + // serialize the collide to a block of memory + virtual int CollideWrite( char *pDest, CPhysCollide *pCollide, bool bSwap = false ) = 0; + // unserialize the collide from a block of memory + virtual CPhysCollide *UnserializeCollide( char *pBuffer, int size, int index ) = 0; + + // compute the volume of a collide + virtual float CollideVolume( CPhysCollide *pCollide ) = 0; + // compute surface area for tools + virtual float CollideSurfaceArea( CPhysCollide *pCollide ) = 0; + + // Get the support map for a collide in the given direction + virtual Vector CollideGetExtent( const CPhysCollide *pCollide, const Vector &collideOrigin, const QAngle &collideAngles, const Vector &direction ) = 0; + + // Get an AABB for an oriented collision model + virtual void CollideGetAABB( Vector *pMins, Vector *pMaxs, const CPhysCollide *pCollide, const Vector &collideOrigin, const QAngle &collideAngles ) = 0; + + virtual void CollideGetMassCenter( CPhysCollide *pCollide, Vector *pOutMassCenter ) = 0; + virtual void CollideSetMassCenter( CPhysCollide *pCollide, const Vector &massCenter ) = 0; + // get the approximate cross-sectional area projected orthographically on the bbox of the collide + // NOTE: These are fractional areas - unitless. Basically this is the fraction of the OBB on each axis that + // would be visible if the object were rendered orthographically. + // NOTE: This has been precomputed when the collide was built or this function will return 1,1,1 + virtual Vector CollideGetOrthographicAreas( const CPhysCollide *pCollide ) = 0; + virtual void CollideSetOrthographicAreas( CPhysCollide *pCollide, const Vector &areas ) = 0; + + // query the vcollide index in the physics model for the instance + virtual int CollideIndex( const CPhysCollide *pCollide ) = 0; + + // Convert a bbox to a collide + virtual CPhysCollide *BBoxToCollide( const Vector &mins, const Vector &maxs ) = 0; + virtual int GetConvexesUsedInCollideable( const CPhysCollide *pCollideable, CPhysConvex **pOutputArray, int iOutputArrayLimit ) = 0; + + + // Trace an AABB against a collide + virtual void TraceBox( const Vector &start, const Vector &end, const Vector &mins, const Vector &maxs, const CPhysCollide *pCollide, const Vector &collideOrigin, const QAngle &collideAngles, trace_t *ptr ) = 0; + virtual void TraceBox( const Ray_t &ray, const CPhysCollide *pCollide, const Vector &collideOrigin, const QAngle &collideAngles, trace_t *ptr ) = 0; + virtual void TraceBox( const Ray_t &ray, unsigned int contentsMask, IConvexInfo *pConvexInfo, const CPhysCollide *pCollide, const Vector &collideOrigin, const QAngle &collideAngles, trace_t *ptr ) = 0; + + // Trace one collide against another + virtual void TraceCollide( const Vector &start, const Vector &end, const CPhysCollide *pSweepCollide, const QAngle &sweepAngles, const CPhysCollide *pCollide, const Vector &collideOrigin, const QAngle &collideAngles, trace_t *ptr ) = 0; + + // relatively slow test for box vs. truncated cone + virtual bool IsBoxIntersectingCone( const Vector &boxAbsMins, const Vector &boxAbsMaxs, const truncatedcone_t &cone ) = 0; + + // loads a set of solids into a vcollide_t + virtual void VCollideLoad( vcollide_t *pOutput, int solidCount, const char *pBuffer, int size, bool swap = false ) = 0; + // destroyts the set of solids created by VCollideLoad + virtual void VCollideUnload( vcollide_t *pVCollide ) = 0; + + // begins parsing a vcollide. NOTE: This keeps pointers to the text + // If you free the text and call members of IVPhysicsKeyParser, it will crash + virtual IVPhysicsKeyParser *VPhysicsKeyParserCreate( const char *pKeyData ) = 0; + // Free the parser created by VPhysicsKeyParserCreate + virtual void VPhysicsKeyParserDestroy( IVPhysicsKeyParser *pParser ) = 0; + + // creates a list of verts from a collision mesh + virtual int CreateDebugMesh( CPhysCollide const *pCollisionModel, Vector **outVerts ) = 0; + // destroy the list of verts created by CreateDebugMesh + virtual void DestroyDebugMesh( int vertCount, Vector *outVerts ) = 0; + + // create a queryable version of the collision model + virtual ICollisionQuery *CreateQueryModel( CPhysCollide *pCollide ) = 0; + // destroy the queryable version + virtual void DestroyQueryModel( ICollisionQuery *pQuery ) = 0; + + virtual IPhysicsCollision *ThreadContextCreate( void ) = 0; + virtual void ThreadContextDestroy( IPhysicsCollision *pThreadContex ) = 0; + + virtual CPhysCollide *CreateVirtualMesh( const virtualmeshparams_t ¶ms ) = 0; + virtual bool SupportsVirtualMesh() = 0; + + + virtual bool GetBBoxCacheSize( int *pCachedSize, int *pCachedCount ) = 0; + + + // extracts a polyhedron that defines a CPhysConvex's shape + virtual CPolyhedron *PolyhedronFromConvex( CPhysConvex * const pConvex, bool bUseTempPolyhedron ) = 0; + + // dumps info about the collide to Msg() + virtual void OutputDebugInfo( const CPhysCollide *pCollide ) = 0; + virtual unsigned int ReadStat( int statID ) = 0; +}; + +// this can be used to post-process a collision model +abstract_class ICollisionQuery +{ +public: + virtual ~ICollisionQuery() {} + // number of convex pieces in the whole solid + virtual int ConvexCount( void ) = 0; + // triangle count for this convex piece + virtual int TriangleCount( int convexIndex ) = 0; + // get the stored game data + virtual unsigned int GetGameData( int convexIndex ) = 0; + // Gets the triangle's verts to an array + virtual void GetTriangleVerts( int convexIndex, int triangleIndex, Vector *verts ) = 0; + + // UNDONE: This doesn't work!!! + virtual void SetTriangleVerts( int convexIndex, int triangleIndex, const Vector *verts ) = 0; + + // returns the 7-bit material index + virtual int GetTriangleMaterialIndex( int convexIndex, int triangleIndex ) = 0; + // sets a 7-bit material index for this triangle + virtual void SetTriangleMaterialIndex( int convexIndex, int triangleIndex, int index7bits ) = 0; +}; + +//----------------------------------------------------------------------------- +// Purpose: Ray traces from game engine. +//----------------------------------------------------------------------------- +abstract_class IPhysicsGameTrace +{ +public: + virtual void VehicleTraceRay( const Ray_t &ray, void *pVehicle, trace_t *pTrace ) = 0; + virtual void VehicleTraceRayWithWater( const Ray_t &ray, void *pVehicle, trace_t *pTrace ) = 0; + virtual bool VehiclePointInWater( const Vector &vecPoint ) = 0; +}; + +// The caller should implement this to return contents masks per convex on a collide +abstract_class IConvexInfo +{ +public: + virtual unsigned int GetContents( int convexGameData ) = 0; +}; + +class CPhysicsEventHandler; +abstract_class IPhysicsCollisionData +{ +public: + virtual void GetSurfaceNormal( Vector &out ) = 0; // normal points toward second object (object index 1) + virtual void GetContactPoint( Vector &out ) = 0; // contact point of collision (in world space) + virtual void GetContactSpeed( Vector &out ) = 0; // speed of surface 1 relative to surface 0 (in world space) +}; + + +struct vcollisionevent_t +{ + IPhysicsObject *pObjects[2]; + int surfaceProps[2]; + bool isCollision; + bool isShadowCollision; + float deltaCollisionTime; + + float collisionSpeed; // only valid at postCollision + IPhysicsCollisionData *pInternalData; // may change pre/post collision +}; + +abstract_class IPhysicsCollisionEvent +{ +public: + // returns the two objects that collided, time between last collision of these objects + // and an opaque data block of collision information + // NOTE: PreCollision/PostCollision ALWAYS come in matched pairs!!! + virtual void PreCollision( vcollisionevent_t *pEvent ) = 0; + virtual void PostCollision( vcollisionevent_t *pEvent ) = 0; + + // This is a scrape event. The object has scraped across another object consuming the indicated energy + virtual void Friction( IPhysicsObject *pObject, float energy, int surfaceProps, int surfacePropsHit, IPhysicsCollisionData *pData ) = 0; + + virtual void StartTouch( IPhysicsObject *pObject1, IPhysicsObject *pObject2, IPhysicsCollisionData *pTouchData ) = 0; + virtual void EndTouch( IPhysicsObject *pObject1, IPhysicsObject *pObject2, IPhysicsCollisionData *pTouchData ) = 0; + + virtual void FluidStartTouch( IPhysicsObject *pObject, IPhysicsFluidController *pFluid ) = 0; + virtual void FluidEndTouch( IPhysicsObject *pObject, IPhysicsFluidController *pFluid ) = 0; + + virtual void PostSimulationFrame() = 0; + + virtual void ObjectEnterTrigger( IPhysicsObject *pTrigger, IPhysicsObject *pObject ) {} + virtual void ObjectLeaveTrigger( IPhysicsObject *pTrigger, IPhysicsObject *pObject ) {} +}; + + +abstract_class IPhysicsObjectEvent +{ +public: + // these can be used to optimize out queries on sleeping objects + // Called when an object is woken after sleeping + virtual void ObjectWake( IPhysicsObject *pObject ) = 0; + // called when an object goes to sleep (no longer simulating) + virtual void ObjectSleep( IPhysicsObject *pObject ) = 0; +}; + +abstract_class IPhysicsConstraintEvent +{ +public: + // the constraint is now inactive, the game code is required to delete it or re-activate it. + virtual void ConstraintBroken( IPhysicsConstraint * ) = 0; +}; + +struct hlshadowcontrol_params_t +{ + Vector targetPosition; + QAngle targetRotation; + float maxAngular; + float maxDampAngular; + float maxSpeed; + float maxDampSpeed; + float dampFactor; + float teleportDistance; +}; + +// UNDONE: At some point allow this to be parameterized using hlshadowcontrol_params_t. +// All of the infrastructure is in place to do that. +abstract_class IPhysicsShadowController +{ +public: + virtual ~IPhysicsShadowController( void ) {} + + virtual void Update( const Vector &position, const QAngle &angles, float timeOffset ) = 0; + virtual void MaxSpeed( float maxSpeed, float maxAngularSpeed ) = 0; + virtual void StepUp( float height ) = 0; + + // If the teleport distance is non-zero, the object will be teleported to + // the target location when the error exceeds this quantity. + virtual void SetTeleportDistance( float teleportDistance ) = 0; + virtual bool AllowsTranslation() = 0; + virtual bool AllowsRotation() = 0; + + // There are two classes of shadow objects: + // 1) Game physics controlled, shadow follows game physics (this is the default) + // 2) Physically controlled - shadow position is a target, but the game hasn't guaranteed that the space can be occupied by this object + virtual void SetPhysicallyControlled( bool isPhysicallyControlled ) = 0; + virtual bool IsPhysicallyControlled() = 0; + virtual void GetLastImpulse( Vector *pOut ) = 0; + virtual void UseShadowMaterial( bool bUseShadowMaterial ) = 0; + virtual void ObjectMaterialChanged( int materialIndex ) = 0; + + + //Basically get the last inputs to IPhysicsShadowController::Update(), returns last input to timeOffset in Update() + virtual float GetTargetPosition( Vector *pPositionOut, QAngle *pAnglesOut ) = 0; + + virtual float GetTeleportDistance( void ) = 0; + virtual void GetMaxSpeed( float *pMaxSpeedOut, float *pMaxAngularSpeedOut ) = 0; +}; + +class CPhysicsSimObject; +class IPhysicsMotionController; + +// Callback for simulation +class IMotionEvent +{ +public: + // These constants instruct the simulator as to how to apply the values copied to linear & angular + // GLOBAL/LOCAL refer to the coordinate system of the values, whereas acceleration/force determine whether or not + // mass is divided out (forces must be divided by mass to compute acceleration) + enum simresult_e { SIM_NOTHING = 0, SIM_LOCAL_ACCELERATION, SIM_LOCAL_FORCE, SIM_GLOBAL_ACCELERATION, SIM_GLOBAL_FORCE }; + virtual simresult_e Simulate( IPhysicsMotionController *pController, IPhysicsObject *pObject, float deltaTime, Vector &linear, AngularImpulse &angular ) = 0; +}; + + + +abstract_class IPhysicsMotionController +{ +public: + virtual ~IPhysicsMotionController( void ) {} + virtual void SetEventHandler( IMotionEvent *handler ) = 0; + virtual void AttachObject( IPhysicsObject *pObject, bool checkIfAlreadyAttached ) = 0; + virtual void DetachObject( IPhysicsObject *pObject ) = 0; + + // returns the number of objects currently attached to the controller + virtual int CountObjects( void ) = 0; + // NOTE: pObjectList is an array with at least CountObjects() allocated + virtual void GetObjects( IPhysicsObject **pObjectList ) = 0; + // detaches all attached objects + virtual void ClearObjects( void ) = 0; + // wakes up all attached objects + virtual void WakeObjects( void ) = 0; + + enum priority_t + { + LOW_PRIORITY = 0, + MEDIUM_PRIORITY = 1, + HIGH_PRIORITY = 2, + }; + virtual void SetPriority( priority_t priority ) = 0; +}; + +// ------------------- +// Collision filter function. Return 0 if objects should not be tested for collisions, nonzero otherwise +// Install with IPhysicsEnvironment::SetCollisionFilter() +// ------------------- +abstract_class IPhysicsCollisionSolver +{ +public: + virtual int ShouldCollide( IPhysicsObject *pObj0, IPhysicsObject *pObj1, void *pGameData0, void *pGameData1 ) = 0; + virtual int ShouldSolvePenetration( IPhysicsObject *pObj0, IPhysicsObject *pObj1, void *pGameData0, void *pGameData1, float dt ) = 0; + + // pObject has already done the max number of collisions this tick, should we freeze it to save CPU? + virtual bool ShouldFreezeObject( IPhysicsObject *pObject ) = 0; + + // The system has already done too many collision checks, performance will suffer. + // How many more should it do? + virtual int AdditionalCollisionChecksThisTick( int currentChecksDone ) = 0; + + // This list of objects is in a connected contact graph that is too large to solve quickly + // return true to freeze the system, false to solve it + virtual bool ShouldFreezeContacts( IPhysicsObject **pObjectList, int objectCount ) = 0; +}; + +enum PhysicsTraceType_t +{ + VPHYSICS_TRACE_EVERYTHING = 0, + VPHYSICS_TRACE_STATIC_ONLY, + VPHYSICS_TRACE_MOVING_ONLY, + VPHYSICS_TRACE_TRIGGERS_ONLY, + VPHYSICS_TRACE_STATIC_AND_MOVING, +}; + +abstract_class IPhysicsTraceFilter +{ +public: + virtual bool ShouldHitObject( IPhysicsObject *pObject, int contentsMask ) = 0; + virtual PhysicsTraceType_t GetTraceType() const = 0; +}; + +abstract_class IPhysicsEnvironment +{ +public: + virtual ~IPhysicsEnvironment( void ) {} + + virtual void SetDebugOverlay( CreateInterfaceFn debugOverlayFactory ) = 0; + virtual IVPhysicsDebugOverlay *GetDebugOverlay( void ) = 0; + + // gravity is a 3-vector in in/s^2 + virtual void SetGravity( const Vector &gravityVector ) = 0; + virtual void GetGravity( Vector *pGravityVector ) const = 0; + + // air density is in kg / m^3 (water is 1000) + // This controls drag, air that is more dense has more drag. + virtual void SetAirDensity( float density ) = 0; + virtual float GetAirDensity( void ) const = 0; + + // object creation + // create a polygonal object. pCollisionModel was created by the physics builder DLL in a pre-process. + virtual IPhysicsObject *CreatePolyObject( const CPhysCollide *pCollisionModel, int materialIndex, const Vector &position, const QAngle &angles, objectparams_t *pParams ) = 0; + // same as above, but this one cannot move or rotate (infinite mass/inertia) + virtual IPhysicsObject *CreatePolyObjectStatic( const CPhysCollide *pCollisionModel, int materialIndex, const Vector &position, const QAngle &angles, objectparams_t *pParams ) = 0; + // Create a perfectly spherical object + virtual IPhysicsObject *CreateSphereObject( float radius, int materialIndex, const Vector &position, const QAngle &angles, objectparams_t *pParams, bool isStatic ) = 0; + // destroy an object created with CreatePolyObject() or CreatePolyObjectStatic() + virtual void DestroyObject( IPhysicsObject * ) = 0; + + // Create a polygonal fluid body out of the specified collision model + // This object will affect any other objects that collide with the collision model + virtual IPhysicsFluidController *CreateFluidController( IPhysicsObject *pFluidObject, fluidparams_t *pParams ) = 0; + // Destroy an object created with CreateFluidController() + virtual void DestroyFluidController( IPhysicsFluidController * ) = 0; + + // Create a simulated spring that connects 2 objects + virtual IPhysicsSpring *CreateSpring( IPhysicsObject *pObjectStart, IPhysicsObject *pObjectEnd, springparams_t *pParams ) = 0; + virtual void DestroySpring( IPhysicsSpring * ) = 0; + + // Create a constraint in the space of pReferenceObject which is attached by the constraint to pAttachedObject + virtual IPhysicsConstraint *CreateRagdollConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_ragdollparams_t &ragdoll ) = 0; + virtual IPhysicsConstraint *CreateHingeConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_hingeparams_t &hinge ) = 0; + virtual IPhysicsConstraint *CreateFixedConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_fixedparams_t &fixed ) = 0; + virtual IPhysicsConstraint *CreateSlidingConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_slidingparams_t &sliding ) = 0; + virtual IPhysicsConstraint *CreateBallsocketConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_ballsocketparams_t &ballsocket ) = 0; + virtual IPhysicsConstraint *CreatePulleyConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_pulleyparams_t &pulley ) = 0; + virtual IPhysicsConstraint *CreateLengthConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_lengthparams_t &length ) = 0; + + virtual void DestroyConstraint( IPhysicsConstraint * ) = 0; + + virtual IPhysicsConstraintGroup *CreateConstraintGroup( const constraint_groupparams_t &groupParams ) = 0; + virtual void DestroyConstraintGroup( IPhysicsConstraintGroup *pGroup ) = 0; + + virtual IPhysicsShadowController *CreateShadowController( IPhysicsObject *pObject, bool allowTranslation, bool allowRotation ) = 0; + virtual void DestroyShadowController( IPhysicsShadowController * ) = 0; + + virtual IPhysicsPlayerController *CreatePlayerController( IPhysicsObject *pObject ) = 0; + virtual void DestroyPlayerController( IPhysicsPlayerController * ) = 0; + + virtual IPhysicsMotionController *CreateMotionController( IMotionEvent *pHandler ) = 0; + virtual void DestroyMotionController( IPhysicsMotionController *pController ) = 0; + + virtual IPhysicsVehicleController *CreateVehicleController( IPhysicsObject *pVehicleBodyObject, const vehicleparams_t ¶ms, unsigned int nVehicleType, IPhysicsGameTrace *pGameTrace ) = 0; + virtual void DestroyVehicleController( IPhysicsVehicleController * ) = 0; + + // install a function to filter collisions/penentration + virtual void SetCollisionSolver( IPhysicsCollisionSolver *pSolver ) = 0; + + // run the simulator for deltaTime seconds + virtual void Simulate( float deltaTime ) = 0; + // true if currently running the simulator (i.e. in a callback during physenv->Simulate()) + virtual bool IsInSimulation() const = 0; + + // Manage the timestep (period) of the simulator. The main functions are all integrated with + // this period as dt. + virtual float GetSimulationTimestep() const = 0; + virtual void SetSimulationTimestep( float timestep ) = 0; + + // returns the current simulation clock's value. This is an absolute time. + virtual float GetSimulationTime() const = 0; + virtual void ResetSimulationClock() = 0; + // returns the current simulation clock's value at the next frame. This is an absolute time. + virtual float GetNextFrameTime( void ) const = 0; + + // Collision callbacks (game code collision response) + virtual void SetCollisionEventHandler( IPhysicsCollisionEvent *pCollisionEvents ) = 0; + virtual void SetObjectEventHandler( IPhysicsObjectEvent *pObjectEvents ) = 0; + virtual void SetConstraintEventHandler( IPhysicsConstraintEvent *pConstraintEvents ) = 0; + + virtual void SetQuickDelete( bool bQuick ) = 0; + + virtual int GetActiveObjectCount() const = 0; + virtual void GetActiveObjects( IPhysicsObject **pOutputObjectList ) const = 0; + virtual const IPhysicsObject **GetObjectList( int *pOutputObjectCount ) const = 0; + virtual bool TransferObject( IPhysicsObject *pObject, IPhysicsEnvironment *pDestinationEnvironment ) = 0; + + virtual void CleanupDeleteList( void ) = 0; + virtual void EnableDeleteQueue( bool enable ) = 0; + + // Save/Restore methods + virtual bool Save( const physsaveparams_t ¶ms ) = 0; + virtual void PreRestore( const physprerestoreparams_t ¶ms ) = 0; + virtual bool Restore( const physrestoreparams_t ¶ms ) = 0; + virtual void PostRestore() = 0; + + // Debugging: + virtual bool IsCollisionModelUsed( CPhysCollide *pCollide ) const = 0; + + // Physics world version of the enginetrace API: + virtual void TraceRay( const Ray_t &ray, unsigned int fMask, IPhysicsTraceFilter *pTraceFilter, trace_t *pTrace ) = 0; + virtual void SweepCollideable( const CPhysCollide *pCollide, const Vector &vecAbsStart, const Vector &vecAbsEnd, + const QAngle &vecAngles, unsigned int fMask, IPhysicsTraceFilter *pTraceFilter, trace_t *pTrace ) = 0; + + // performance tuning + virtual void GetPerformanceSettings( physics_performanceparams_t *pOutput ) const = 0; + virtual void SetPerformanceSettings( const physics_performanceparams_t *pSettings ) = 0; + + // perf/cost statistics + virtual void ReadStats( physics_stats_t *pOutput ) = 0; + virtual void ClearStats() = 0; + + virtual unsigned int GetObjectSerializeSize( IPhysicsObject *pObject ) const = 0; + virtual void SerializeObjectToBuffer( IPhysicsObject *pObject, unsigned char *pBuffer, unsigned int bufferSize ) = 0; + virtual IPhysicsObject *UnserializeObjectFromBuffer( void *pGameData, unsigned char *pBuffer, unsigned int bufferSize, bool enableCollisions ) = 0; + + + virtual void EnableConstraintNotify( bool bEnable ) = 0; + virtual void DebugCheckContacts(void) = 0; +}; + +enum callbackflags +{ + CALLBACK_GLOBAL_COLLISION = 0x0001, + CALLBACK_GLOBAL_FRICTION = 0x0002, + CALLBACK_GLOBAL_TOUCH = 0x0004, + CALLBACK_GLOBAL_TOUCH_STATIC = 0x0008, + CALLBACK_SHADOW_COLLISION = 0x0010, + CALLBACK_GLOBAL_COLLIDE_STATIC = 0x0020, + CALLBACK_IS_VEHICLE_WHEEL = 0x0040, + CALLBACK_FLUID_TOUCH = 0x0100, + CALLBACK_NEVER_DELETED = 0x0200, // HACKHACK: This means this object will never be deleted (set on the world) + CALLBACK_MARKED_FOR_DELETE = 0x0400, // This allows vphysics to skip some work for this object since it will be + // deleted later this frame. (Set automatically by destroy calls) + CALLBACK_ENABLING_COLLISION = 0x0800, // This is active during the time an object is enabling collisions + // allows us to skip collisions between "new" objects and objects marked for delete + CALLBACK_DO_FLUID_SIMULATION = 0x1000, // remove this to opt out of fluid simulations + CALLBACK_IS_PLAYER_CONTROLLER= 0x2000, // HACKHACK: Set this on players until player cotrollers are unified with shadow controllers + CALLBACK_CHECK_COLLISION_DISABLE = 0x4000, + CALLBACK_MARKED_FOR_TEST = 0x8000, // debug -- marked object is being debugged +}; + +abstract_class IPhysicsObject +{ +public: + virtual ~IPhysicsObject( void ) {} + + // returns true if this object is static/unmoveable + // NOTE: returns false for objects that are not created static, but set EnableMotion(false); + // Call IsMoveable() to find if the object is static OR has motion disabled + virtual bool IsStatic() const = 0; + virtual bool IsAsleep() const = 0; + virtual bool IsTrigger() const = 0; + virtual bool IsFluid() const = 0; // fluids are special triggers with fluid controllers attached, they return true to IsTrigger() as well! + virtual bool IsHinged() const = 0; + virtual bool IsCollisionEnabled() const = 0; + virtual bool IsGravityEnabled() const = 0; + virtual bool IsDragEnabled() const = 0; + virtual bool IsMotionEnabled() const = 0; + virtual bool IsMoveable() const = 0; // legacy: IsMotionEnabled() && !IsStatic() + virtual bool IsAttachedToConstraint(bool bExternalOnly) const = 0; + + // Enable / disable collisions for this object + virtual void EnableCollisions( bool enable ) = 0; + // Enable / disable gravity for this object + virtual void EnableGravity( bool enable ) = 0; + // Enable / disable air friction / drag for this object + virtual void EnableDrag( bool enable ) = 0; + // Enable / disable motion (pin / unpin the object) + virtual void EnableMotion( bool enable ) = 0; + + // Game can store data in each object (link back to game object) + virtual void SetGameData( void *pGameData ) = 0; + virtual void *GetGameData( void ) const = 0; + // This flags word can be defined by the game as well + virtual void SetGameFlags( unsigned short userFlags ) = 0; + virtual unsigned short GetGameFlags( void ) const = 0; + virtual void SetGameIndex( unsigned short gameIndex ) = 0; + virtual unsigned short GetGameIndex( void ) const = 0; + + // setup various callbacks for this object + virtual void SetCallbackFlags( unsigned short callbackflags ) = 0; + // get the current callback state for this object + virtual unsigned short GetCallbackFlags( void ) const = 0; + + // "wakes up" an object + // NOTE: ALL OBJECTS ARE "Asleep" WHEN CREATED + virtual void Wake( void ) = 0; + virtual void Sleep( void ) = 0; + // call this when the collision filter conditions change due to this + // object's state (e.g. changing solid type or collision group) + virtual void RecheckCollisionFilter() = 0; + // NOTE: Contact points aren't updated when collision rules change, call this to force an update + // UNDONE: Force this in RecheckCollisionFilter() ? + virtual void RecheckContactPoints() = 0; + + // mass accessors + virtual void SetMass( float mass ) = 0; + virtual float GetMass( void ) const = 0; + // get 1/mass (it's cached) + virtual float GetInvMass( void ) const = 0; + virtual Vector GetInertia( void ) const = 0; + virtual Vector GetInvInertia( void ) const = 0; + virtual void SetInertia( const Vector &inertia ) = 0; + + virtual void SetDamping( const float *speed, const float *rot ) = 0; + virtual void GetDamping( float *speed, float *rot ) const = 0; + + // coefficients are optional, pass either + virtual void SetDragCoefficient( float *pDrag, float *pAngularDrag ) = 0; + virtual void SetBuoyancyRatio( float ratio ) = 0; // Override bouyancy + + // material index + virtual int GetMaterialIndex() const = 0; + virtual void SetMaterialIndex( int materialIndex ) = 0; + + // contents bits + virtual unsigned int GetContents() const = 0; + virtual void SetContents( unsigned int contents ) = 0; + + // Get the radius if this is a sphere object (zero if this is a polygonal mesh) + virtual float GetSphereRadius() const = 0; + virtual float GetEnergy() const = 0; + virtual Vector GetMassCenterLocalSpace() const = 0; + + // NOTE: This will teleport the object + virtual void SetPosition( const Vector &worldPosition, const QAngle &angles, bool isTeleport ) = 0; + virtual void SetPositionMatrix( const matrix3x4_t&matrix, bool isTeleport ) = 0; + + virtual void GetPosition( Vector *worldPosition, QAngle *angles ) const = 0; + virtual void GetPositionMatrix( matrix3x4_t *positionMatrix ) const = 0; + // force the velocity to a new value + // NOTE: velocity is in worldspace, angularVelocity is relative to the object's + // local axes (just like pev->velocity, pev->avelocity) + virtual void SetVelocity( const Vector *velocity, const AngularImpulse *angularVelocity ) = 0; + + // like the above, but force the change into the simulator immediately + virtual void SetVelocityInstantaneous( const Vector *velocity, const AngularImpulse *angularVelocity ) = 0; + + // NOTE: velocity is in worldspace, angularVelocity is relative to the object's + // local axes (just like pev->velocity, pev->avelocity) + virtual void GetVelocity( Vector *velocity, AngularImpulse *angularVelocity ) const = 0; + + // NOTE: These are velocities, not forces. i.e. They will have the same effect regardless of + // the object's mass or inertia + virtual void AddVelocity( const Vector *velocity, const AngularImpulse *angularVelocity ) = 0; + // gets a velocity in the object's local frame of reference at a specific point + virtual void GetVelocityAtPoint( const Vector &worldPosition, Vector *pVelocity ) const = 0; + // gets the velocity actually moved by the object in the last simulation update + virtual void GetImplicitVelocity( Vector *velocity, AngularImpulse *angularVelocity ) const = 0; + // NOTE: These are here for convenience, but you can do them yourself by using the matrix + // returned from GetPositionMatrix() + // convenient coordinate system transformations (params - dest, src) + virtual void LocalToWorld( Vector *worldPosition, const Vector &localPosition ) const = 0; + virtual void WorldToLocal( Vector *localPosition, const Vector &worldPosition ) const = 0; + + // transforms a vector (no translation) from object-local to world space + virtual void LocalToWorldVector( Vector *worldVector, const Vector &localVector ) const = 0; + // transforms a vector (no translation) from world to object-local space + virtual void WorldToLocalVector( Vector *localVector, const Vector &worldVector ) const = 0; + + // push on an object + // force vector is direction & magnitude of impulse kg in / s + virtual void ApplyForceCenter( const Vector &forceVector ) = 0; + virtual void ApplyForceOffset( const Vector &forceVector, const Vector &worldPosition ) = 0; + // apply torque impulse. This will change the angular velocity on the object. + // HL Axes, kg degrees / s + virtual void ApplyTorqueCenter( const AngularImpulse &torque ) = 0; + + // Calculates the force/torque on the center of mass for an offset force impulse (pass output to ApplyForceCenter / ApplyTorqueCenter) + virtual void CalculateForceOffset( const Vector &forceVector, const Vector &worldPosition, Vector *centerForce, AngularImpulse *centerTorque ) const = 0; + // Calculates the linear/angular velocities on the center of mass for an offset force impulse (pass output to AddVelocity) + virtual void CalculateVelocityOffset( const Vector &forceVector, const Vector &worldPosition, Vector *centerVelocity, AngularImpulse *centerAngularVelocity ) const = 0; + // calculate drag scale + virtual float CalculateLinearDrag( const Vector &unitDirection ) const = 0; + virtual float CalculateAngularDrag( const Vector &objectSpaceRotationAxis ) const = 0; + + // returns true if the object is in contact with another object + // if true, puts a point on the contact surface in contactPoint, and + // a pointer to the object in contactObject + // NOTE: You can pass NULL for either to avoid computations + // BUGBUG: Use CreateFrictionSnapshot instead of this - this is a simple hack + virtual bool GetContactPoint( Vector *contactPoint, IPhysicsObject **contactObject ) const = 0; + + // refactor this a bit - move some of this to IPhysicsShadowController + virtual void SetShadow( float maxSpeed, float maxAngularSpeed, bool allowPhysicsMovement, bool allowPhysicsRotation ) = 0; + virtual void UpdateShadow( const Vector &targetPosition, const QAngle &targetAngles, bool tempDisableGravity, float timeOffset ) = 0; + + // returns number of ticks since last Update() call + virtual int GetShadowPosition( Vector *position, QAngle *angles ) const = 0; + virtual IPhysicsShadowController *GetShadowController( void ) const = 0; + virtual void RemoveShadowController() = 0; + // applies the math of the shadow controller to this object. + // for use in your own controllers + // returns the new value of secondsToArrival with dt time elapsed + virtual float ComputeShadowControl( const hlshadowcontrol_params_t ¶ms, float secondsToArrival, float dt ) = 0; + + + virtual const CPhysCollide *GetCollide( void ) const = 0; + virtual const char *GetName() const = 0; + + virtual void BecomeTrigger() = 0; + virtual void RemoveTrigger() = 0; + + // sets the object to be hinged. Fixed it place, but able to rotate around one axis. + virtual void BecomeHinged( int localAxis ) = 0; + // resets the object to original state + virtual void RemoveHinged() = 0; + + // used to iterate the contact points of an object + virtual IPhysicsFrictionSnapshot *CreateFrictionSnapshot() = 0; + virtual void DestroyFrictionSnapshot( IPhysicsFrictionSnapshot *pSnapshot ) = 0; + + // dumps info about the object to Msg() + virtual void OutputDebugInfo() const = 0; + +}; + + +abstract_class IPhysicsSpring +{ +public: + virtual ~IPhysicsSpring( void ) {} + virtual void GetEndpoints( Vector *worldPositionStart, Vector *worldPositionEnd ) = 0; + virtual void SetSpringConstant( float flSpringContant) = 0; + virtual void SetSpringDamping( float flSpringDamping) = 0; + virtual void SetSpringLength( float flSpringLenght) = 0; + + // Get the starting object + virtual IPhysicsObject *GetStartObject( void ) = 0; + + // Get the end object + virtual IPhysicsObject *GetEndObject( void ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Purpose: These properties are defined per-material. This is accessible at +// each triangle in a collision mesh +//----------------------------------------------------------------------------- +struct surfacephysicsparams_t +{ +// vphysics physical properties + float friction; + float elasticity; // collision elasticity - used to compute coefficient of restitution + float density; // physical density (in kg / m^3) + float thickness; // material thickness if not solid (sheet materials) in inches + float dampening; +}; + +struct surfaceaudioparams_t +{ +// sounds / audio data + float reflectivity; // like elasticity, but how much sound should be reflected by this surface + float hardnessFactor; // like elasticity, but only affects impact sound choices + float roughnessFactor; // like friction, but only affects scrape sound choices + +// audio thresholds + float roughThreshold; // surface roughness > this causes "rough" scrapes, < this causes "smooth" scrapes + float hardThreshold; // surface hardness > this causes "hard" impacts, < this causes "soft" impacts + float hardVelocityThreshold; // collision velocity > this causes "hard" impacts, < this causes "soft" impacts + // NOTE: Hard impacts must meet both hardnessFactor AND velocity thresholds +}; + +struct surfacesoundnames_t +{ + unsigned short stepleft; + unsigned short stepright; + + unsigned short impactSoft; + unsigned short impactHard; + + unsigned short scrapeSmooth; + unsigned short scrapeRough; + + unsigned short bulletImpact; + unsigned short rolling; + + unsigned short breakSound; + unsigned short strainSound; +}; + +struct surfacesoundhandles_t +{ + short stepleft; + short stepright; + + short impactSoft; + short impactHard; + + short scrapeSmooth; + short scrapeRough; + + short bulletImpact; + short rolling; + + short breakSound; + short strainSound; +}; + +struct surfacegameprops_t +{ +// game movement data + float maxSpeedFactor; // Modulates player max speed when walking on this surface + float jumpFactor; // Indicates how much higher the player should jump when on the surface +// Game-specific data + unsigned short material; + // Indicates whether or not the player is on a ladder. + unsigned char climbable; + unsigned char pad; +}; + +//----------------------------------------------------------------------------- +// Purpose: Each different material has an entry like this +//----------------------------------------------------------------------------- +struct surfacedata_t +{ + surfacephysicsparams_t physics; // physics parameters + surfaceaudioparams_t audio; // audio parameters + surfacesoundnames_t sounds; // names of linked sounds + surfacegameprops_t game; // Game data / properties + + surfacesoundhandles_t soundhandles; + +#ifdef MAPBASE_VSCRIPT + // These functions are for the VScript class description. + + float GetFriction() { return physics.friction; } + float GetThickness() { return physics.thickness; } + + float GetJumpFactor() { return game.jumpFactor; } + char GetMaterialChar() { return game.material; } + +#if defined(CLIENT_DLL) || defined(GAME_DLL) + const char* GetSoundStepLeft(); + const char* GetSoundStepRight(); + const char* GetSoundImpactSoft(); + const char* GetSoundImpactHard(); + const char* GetSoundScrapeSmooth(); + const char* GetSoundScrapeRough(); + const char* GetSoundBulletImpact(); + const char* GetSoundRolling(); + const char* GetSoundBreak(); + const char* GetSoundStrain(); +#endif + +#endif +}; + +#define VPHYSICS_SURFACEPROPS_INTERFACE_VERSION "VPhysicsSurfaceProps001" +abstract_class IPhysicsSurfaceProps +{ +public: + virtual ~IPhysicsSurfaceProps( void ) {} + + // parses a text file containing surface prop keys + virtual int ParseSurfaceData( const char *pFilename, const char *pTextfile ) = 0; + // current number of entries in the database + virtual int SurfacePropCount( void ) const = 0; + + virtual int GetSurfaceIndex( const char *pSurfacePropName ) const = 0; + virtual void GetPhysicsProperties( int surfaceDataIndex, float *density, float *thickness, float *friction, float *elasticity ) const = 0; + + virtual surfacedata_t *GetSurfaceData( int surfaceDataIndex ) = 0; + virtual const char *GetString( unsigned short stringTableIndex ) const = 0; + + + virtual const char *GetPropName( int surfaceDataIndex ) const = 0; + + // sets the global index table for world materials + // UNDONE: Make this per-CPhysCollide + virtual void SetWorldMaterialIndexTable( int *pMapArray, int mapSize ) = 0; + + // NOTE: Same as GetPhysicsProperties, but maybe more convenient + virtual void GetPhysicsParameters( int surfaceDataIndex, surfacephysicsparams_t *pParamsOut ) const = 0; +}; + +abstract_class IPhysicsFluidController +{ +public: + virtual ~IPhysicsFluidController( void ) {} + + virtual void SetGameData( void *pGameData ) = 0; + virtual void *GetGameData( void ) const = 0; + + virtual void GetSurfacePlane( Vector *pNormal, float *pDist ) const = 0; + virtual float GetDensity() const = 0; + virtual void WakeAllSleepingObjects() = 0; + virtual int GetContents() const = 0; +}; + + +//----------------------------------------------------------------------------- +// Purpose: parameter block for creating fluid dynamic motion +// UNDONE: Expose additional fluid model paramters? +//----------------------------------------------------------------------------- +struct fluidparams_t +{ + Vector4D surfacePlane; // x,y,z normal, dist (plane constant) fluid surface + Vector currentVelocity; // velocity of the current in inches/second + float damping; // damping factor for buoyancy (tweak) + float torqueFactor; + float viscosityFactor; + void *pGameData; + bool useAerodynamics;// true if this controller should calculate surface pressure + int contents; + + fluidparams_t() {} + fluidparams_t( fluidparams_t const& src ) + { + Vector4DCopy( src.surfacePlane, surfacePlane ); + VectorCopy( src.currentVelocity, currentVelocity ); + damping = src.damping; + torqueFactor = src.torqueFactor; + viscosityFactor = src.viscosityFactor; + contents = src.contents; + } +}; + +//----------------------------------------------------------------------------- +// Purpose: parameter block for creating linear springs +// UNDONE: Expose additional spring model paramters? +//----------------------------------------------------------------------------- +struct springparams_t +{ + springparams_t() + { + memset( this, 0, sizeof(*this) ); + } + float constant; // spring constant + float naturalLength;// relaxed length + float damping; // damping factor + float relativeDamping; // relative damping (damping proportional to the change in the relative position of the objects) + Vector startPosition; + Vector endPosition; + bool useLocalPositions; // start & end Position are in local space to start and end objects if this is true + bool onlyStretch; // only apply forces when the length is greater than the natural length +}; + +//----------------------------------------------------------------------------- +// Purpose: parameter block for creating polygonal objects +//----------------------------------------------------------------------------- +struct objectparams_t +{ + Vector *massCenterOverride; + float mass; + float inertia; + float damping; + float rotdamping; + float rotInertiaLimit; + const char *pName; // used only for debugging + void *pGameData; + float volume; + float dragCoefficient; + bool enableCollisions; +}; + +struct convertconvexparams_t +{ + bool buildOuterConvexHull; + bool buildDragAxisAreas; + bool buildOptimizedTraceTables; + float dragAreaEpsilon; + CPhysConvex *pForcedOuterHull; + + void Defaults() + { + dragAreaEpsilon = 0.25f; // 0.5in x 0.5in square + buildOuterConvexHull = false; + buildDragAxisAreas = false; + buildOptimizedTraceTables = false; + pForcedOuterHull = NULL; + } +}; + +//----------------------------------------------------------------------------- +// Physics interface IDs +// +// Note that right now the order of the enum also defines the order of save/load + + +//----------------------------------------------------------------------------- +// Purpose: parameter blocks for save and load operations +//----------------------------------------------------------------------------- +struct physsaveparams_t +{ + ISave *pSave; + void *pObject; + PhysInterfaceId_t type; +}; + +struct physrestoreparams_t +{ + IRestore *pRestore; + void **ppObject; + PhysInterfaceId_t type; + void *pGameData; + const char *pName; // used only for debugging + const CPhysCollide *pCollisionModel; + IPhysicsEnvironment *pEnvironment; + IPhysicsGameTrace *pGameTrace; +}; + +struct physrecreateparams_t +{ + void *pOldObject; + void *pNewObject; +}; + +struct physprerestoreparams_t +{ + int recreatedObjectCount; + physrecreateparams_t recreatedObjectList[1]; +}; + +//------------------------------------- + +#define DEFINE_PIID( type, enumval ) \ + template <> inline PhysInterfaceId_t GetPhysIID( type ** ) { return enumval; } + +template inline PhysInterfaceId_t GetPhysIID(PHYSPTR **); // will get link error if no match + +DEFINE_PIID( IPhysicsObject, PIID_IPHYSICSOBJECT ); +DEFINE_PIID( IPhysicsFluidController, PIID_IPHYSICSFLUIDCONTROLLER ); +DEFINE_PIID( IPhysicsSpring, PIID_IPHYSICSSPRING ); +DEFINE_PIID( IPhysicsConstraintGroup, PIID_IPHYSICSCONSTRAINTGROUP ); +DEFINE_PIID( IPhysicsConstraint, PIID_IPHYSICSCONSTRAINT ); +DEFINE_PIID( IPhysicsShadowController, PIID_IPHYSICSSHADOWCONTROLLER ); +DEFINE_PIID( IPhysicsPlayerController, PIID_IPHYSICSPLAYERCONTROLLER ); +DEFINE_PIID( IPhysicsMotionController, PIID_IPHYSICSMOTIONCONTROLLER ); +DEFINE_PIID( IPhysicsVehicleController, PIID_IPHYSICSVEHICLECONTROLLER ); +DEFINE_PIID( IPhysicsGameTrace, PIID_IPHYSICSGAMETRACE ); + +//----------------------------------------------------------------------------- + +#endif // VPHYSICS_INTERFACE_H diff --git a/sp/src/public/vphysics_interfaceV30.h b/sp/src/public/vphysics_interfaceV30.h new file mode 100644 index 00000000..a431aebb --- /dev/null +++ b/sp/src/public/vphysics_interfaceV30.h @@ -0,0 +1,1064 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Public interfaces to vphysics DLL +// +// $NoKeywords: $ +//============================================================================= + +#ifndef VPHYSICS_INTERFACE_V30_H +#define VPHYSICS_INTERFACE_V30_H +#ifdef _WIN32 +#pragma once +#endif + +#include "interface.h" +#include "mathlib/vector.h" +#include "mathlib/vector4d.h" +#include "vcollide.h" + + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class IPhysicsObjectPairHash; +class IPhysicsConstraint; +class IPhysicsConstraintGroup; +class IPhysicsFluidController; +class IPhysicsSpring; +class IPhysicsVehicleController; +class IPhysicsCollisionSet; +class IPhysicsPlayerController; +class IPhysicsFrictionSnapshot; +struct Ray_t; +struct constraint_ragdollparams_t; +struct constraint_hingeparams_t; +struct constraint_fixedparams_t; +struct constraint_ballsocketparams_t; +struct constraint_slidingparams_t; +struct constraint_pulleyparams_t; +struct constraint_lengthparams_t; +struct constraint_groupparams_t; +struct vehicleparams_t; +struct matrix3x4_t; +struct fluidparams_t; +struct springparams_t; +struct objectparams_t; +struct debugcollide_t; +class CGameTrace; +typedef CGameTrace trace_t; +struct physics_stats_t; +struct physics_performanceparams_t; +struct physsaveparams_t; +struct physrestoreparams_t; +struct physprerestoreparams_t; + +namespace VPhysicsInterfaceV30 +{ + +//----------------------------------------------------------------------------- +// Forward declarations +//----------------------------------------------------------------------------- +class IPhysicsObject; +class IPhysicsEnvironment; +class IPhysicsSurfaceProps; +class IConvexInfo; + +enum PhysInterfaceId_t +{ + PIID_UNKNOWN, + PIID_IPHYSICSOBJECT, + PIID_IPHYSICSFLUIDCONTROLLER, + PIID_IPHYSICSSPRING, + PIID_IPHYSICSCONSTRAINTGROUP, + PIID_IPHYSICSCONSTRAINT, + PIID_IPHYSICSSHADOWCONTROLLER, + PIID_IPHYSICSPLAYERCONTROLLER, + PIID_IPHYSICSMOTIONCONTROLLER, + PIID_IPHYSICSVEHICLECONTROLLER, + PIID_IPHYSICSGAMETRACE, + + PIID_NUM_TYPES +}; + + +class ISave; +class IRestore; + + +#define VPHYSICS_DEBUG_OVERLAY_INTERFACE_VERSION_1 "VPhysicsDebugOverlay001" + +abstract_class IVPhysicsDebugOverlay +{ +public: + virtual void AddEntityTextOverlay(int ent_index, int line_offset, float duration, int r, int g, int b, int a, PRINTF_FORMAT_STRING const char *format, ...) = 0; + virtual void AddBoxOverlay(const Vector& origin, const Vector& mins, const Vector& max, QAngle const& orientation, int r, int g, int b, int a, float duration) = 0; + virtual void AddTriangleOverlay(const Vector& p1, const Vector& p2, const Vector& p3, int r, int g, int b, int a, bool noDepthTest, float duration) = 0; + virtual void AddLineOverlay(const Vector& origin, const Vector& dest, int r, int g, int b,bool noDepthTest, float duration) = 0; + virtual void AddTextOverlay(const Vector& origin, float duration, PRINTF_FORMAT_STRING const char *format, ...) = 0; + virtual void AddTextOverlay(const Vector& origin, int line_offset, float duration, PRINTF_FORMAT_STRING const char *format, ...) = 0; + virtual void AddScreenTextOverlay(float flXPos, float flYPos,float flDuration, int r, int g, int b, int a, const char *text) = 0; + virtual void AddSweptBoxOverlay(const Vector& start, const Vector& end, const Vector& mins, const Vector& max, const QAngle & angles, int r, int g, int b, int a, float flDuration) = 0; + virtual void AddTextOverlayRGB(const Vector& origin, int line_offset, float duration, float r, float g, float b, float alpha, PRINTF_FORMAT_STRING const char *format, ...) = 0; +}; + +#define VPHYSICS_INTERFACE_VERSION_30 "VPhysics030" + +abstract_class IPhysics +{ +public: + virtual IPhysicsEnvironment *CreateEnvironment( void ) = 0; + virtual void DestroyEnvironment( IPhysicsEnvironment * ) = 0; + virtual IPhysicsEnvironment *GetActiveEnvironmentByIndex( int index ) = 0; + + // Creates a fast hash of pairs of objects + // Useful for maintaining a table of object relationships like pairs that do not collide. + virtual IPhysicsObjectPairHash *CreateObjectPairHash() = 0; + virtual void DestroyObjectPairHash( IPhysicsObjectPairHash *pHash ) = 0; + + // holds a cache of these by id. So you can get by id to search for the previously created set + // UNDONE: Sets are currently limited to 32 elements. More elements will return NULL in create. + // NOTE: id is not allowed to be zero. + virtual IPhysicsCollisionSet *FindOrCreateCollisionSet( unsigned int id, int maxElementCount ) = 0; + virtual IPhysicsCollisionSet *FindCollisionSet( unsigned int id ) = 0; + virtual void DestroyAllCollisionSets() = 0; +}; + + +// CPhysConvex is a single convex solid +class CPhysConvex; +// CPhysPolysoup is an abstract triangle soup mesh +class CPhysPolysoup; +class ICollisionQuery; +class IVPhysicsKeyParser; +struct convertconvexparams_t; + +// UNDONE: Find a better place for this? Should be in collisionutils, but it's needs VPHYSICS' solver. +struct truncatedcone_t +{ + Vector origin; + Vector normal; + float h; // height of the cone (hl units) + float theta; // cone angle (degrees) +}; + + +#define VPHYSICS_COLLISION_INTERFACE_VERSION_7 "VPhysicsCollision007" + +abstract_class IPhysicsCollision +{ +public: + virtual ~IPhysicsCollision( void ) {} + + // produce a convex element from verts (convex hull around verts) + virtual CPhysConvex *ConvexFromVerts( Vector **pVerts, int vertCount ) = 0; + // produce a convex element from planes (csg of planes) + virtual CPhysConvex *ConvexFromPlanes( float *pPlanes, int planeCount, float mergeDistance ) = 0; + // calculate volume of a convex element + virtual float ConvexVolume( CPhysConvex *pConvex ) = 0; + + // Convert an array of convex elements to a compiled collision model (this deletes the convex elements) + virtual CPhysCollide *ConvertConvexToCollide( CPhysConvex **pConvex, int convexCount ) = 0; + + virtual float ConvexSurfaceArea( CPhysConvex *pConvex ) = 0; + // store game-specific data in a convex solid + virtual void SetConvexGameData( CPhysConvex *pConvex, unsigned int gameData ) = 0; + // If not converted, free the convex elements with this call + virtual void ConvexFree( CPhysConvex *pConvex ) = 0; + + // concave objects + // create a triangle soup + virtual CPhysPolysoup *PolysoupCreate( void ) = 0; + // destroy the container and memory + virtual void PolysoupDestroy( CPhysPolysoup *pSoup ) = 0; + // add a triangle to the soup + virtual void PolysoupAddTriangle( CPhysPolysoup *pSoup, const Vector &a, const Vector &b, const Vector &c, int materialIndex7bits ) = 0; + // convert the convex into a compiled collision model + virtual CPhysCollide *ConvertPolysoupToCollide( CPhysPolysoup *pSoup, bool useMOPP ) = 0; + + // Get the memory size in bytes of the collision model for serialization + virtual int CollideSize( CPhysCollide *pCollide ) = 0; + // serialize the collide to a block of memory + virtual int CollideWrite( char *pDest, CPhysCollide *pCollide ) = 0; + + // Free a collide that was created with ConvertConvexToCollide() + // UNDONE: Move this up near the other Collide routines when the version is changed + virtual void DestroyCollide( CPhysCollide *pCollide ) = 0; + // compute the volume of a collide + virtual float CollideVolume( CPhysCollide *pCollide ) = 0; + // compute surface area for tools + virtual float CollideSurfaceArea( CPhysCollide *pCollide ) = 0; + + // Get the support map for a collide in the given direction + virtual Vector CollideGetExtent( const CPhysCollide *pCollide, const Vector &collideOrigin, const QAngle &collideAngles, const Vector &direction ) = 0; + + // Get an AABB for an oriented collision model + virtual void CollideGetAABB( Vector &mins, Vector &maxs, const CPhysCollide *pCollide, const Vector &collideOrigin, const QAngle &collideAngles ) = 0; + + // Convert a bbox to a collide + virtual CPhysCollide *BBoxToCollide( const Vector &mins, const Vector &maxs ) = 0; + + + // Trace an AABB against a collide + virtual void TraceBox( const Vector &start, const Vector &end, const Vector &mins, const Vector &maxs, const CPhysCollide *pCollide, const Vector &collideOrigin, const QAngle &collideAngles, trace_t *ptr ) = 0; + virtual void TraceBox( const Ray_t &ray, const CPhysCollide *pCollide, const Vector &collideOrigin, const QAngle &collideAngles, trace_t *ptr ) = 0; + + // Trace one collide against another + virtual void TraceCollide( const Vector &start, const Vector &end, const CPhysCollide *pSweepCollide, const QAngle &sweepAngles, const CPhysCollide *pCollide, const Vector &collideOrigin, const QAngle &collideAngles, trace_t *ptr ) = 0; + + // loads a set of solids into a vcollide_t + virtual void VCollideLoad( vcollide_t *pOutput, int solidCount, const char *pBuffer, int size ) = 0; + // destroyts the set of solids created by VCollideLoad + virtual void VCollideUnload( vcollide_t *pVCollide ) = 0; + + // begins parsing a vcollide. NOTE: This keeps pointers to the text + // If you free the text and call members of IVPhysicsKeyParser, it will crash + virtual IVPhysicsKeyParser *VPhysicsKeyParserCreate( const char *pKeyData ) = 0; + // Free the parser created by VPhysicsKeyParserCreate + virtual void VPhysicsKeyParserDestroy( IVPhysicsKeyParser *pParser ) = 0; + + // creates a list of verts from a collision mesh + virtual int CreateDebugMesh( CPhysCollide const *pCollisionModel, Vector **outVerts ) = 0; + // destroy the list of verts created by CreateDebugMesh + virtual void DestroyDebugMesh( int vertCount, Vector *outVerts ) = 0; + + // create a queryable version of the collision model + virtual ICollisionQuery *CreateQueryModel( CPhysCollide *pCollide ) = 0; + // destroy the queryable version + virtual void DestroyQueryModel( ICollisionQuery *pQuery ) = 0; + + virtual IPhysicsCollision *ThreadContextCreate( void ) = 0; + virtual void ThreadContextDestroy( IPhysicsCollision *pThreadContex ) = 0; + + virtual unsigned int ReadStat( int statID ) = 0; + + // UNDONE: Move this up when changing the interface version + virtual void TraceBox( const Ray_t &ray, unsigned int contentsMask, IConvexInfo *pConvexInfo, const CPhysCollide *pCollide, const Vector &collideOrigin, const QAngle &collideAngles, trace_t *ptr ) = 0; + virtual void CollideGetMassCenter( CPhysCollide *pCollide, Vector *pOutMassCenter ) = 0; + virtual void CollideSetMassCenter( CPhysCollide *pCollide, const Vector &massCenter ) = 0; + + // query the collide index in the physics model for the instance + virtual int CollideIndex( const CPhysCollide *pCollide ) = 0; + + virtual CPhysCollide *ConvertConvexToCollideParams( CPhysConvex **pConvex, int convexCount, const convertconvexparams_t &convertParams ) = 0; + virtual CPhysConvex *BBoxToConvex( const Vector &mins, const Vector &maxs ) = 0; + + // get the approximate cross-sectional area projected orthographically on the bbox of the collide + // NOTE: These are fractional areas - unitless. Basically this is the fraction of the OBB on each axis that + // would be visible if the object were rendered orthographically. + // NOTE: This has been precomputed when the collide was built or this function will return 1,1,1 + virtual Vector CollideGetOrthographicAreas( const CPhysCollide *pCollide ) = 0; + + // dumps info about the collide to Msg() + virtual void OutputDebugInfo( const CPhysCollide *pCollide ) = 0; + + // relatively slow test for box vs. truncated cone + virtual bool IsBoxIntersectingCone( const Vector &boxAbsMins, const Vector &boxAbsMaxs, const truncatedcone_t &cone ) = 0; +}; + +// this can be used to post-process a collision model +abstract_class ICollisionQuery +{ +public: + virtual ~ICollisionQuery() {} + // number of convex pieces in the whole solid + virtual int ConvexCount( void ) = 0; + // triangle count for this convex piece + virtual int TriangleCount( int convexIndex ) = 0; + // get the stored game data + virtual unsigned int GetGameData( int convexIndex ) = 0; + // Gets the triangle's verts to an array + virtual void GetTriangleVerts( int convexIndex, int triangleIndex, Vector *verts ) = 0; + + // UNDONE: This doesn't work!!! + virtual void SetTriangleVerts( int convexIndex, int triangleIndex, const Vector *verts ) = 0; + + // returns the 7-bit material index + virtual int GetTriangleMaterialIndex( int convexIndex, int triangleIndex ) = 0; + // sets a 7-bit material index for this triangle + virtual void SetTriangleMaterialIndex( int convexIndex, int triangleIndex, int index7bits ) = 0; +}; + +//----------------------------------------------------------------------------- +// Purpose: Ray traces from game engine. +//----------------------------------------------------------------------------- +abstract_class IPhysicsGameTrace +{ +public: + virtual void VehicleTraceRay( const Ray_t &ray, void *pVehicle, trace_t *pTrace ) = 0; + virtual void VehicleTraceRayWithWater( const Ray_t &ray, void *pVehicle, trace_t *pTrace ) = 0; + virtual bool VehiclePointInWater( const Vector &vecPoint ) = 0; +}; + +// The caller should implement this to return contents masks per convex on a collide +abstract_class IConvexInfo +{ +public: + virtual unsigned int GetContents( int convexGameData ) = 0; +}; + +class CPhysicsEventHandler; +abstract_class IPhysicsCollisionData +{ +public: + virtual void GetSurfaceNormal( Vector &out ) = 0; // normal points toward second object (object index 1) + virtual void GetContactPoint( Vector &out ) = 0; // contact point of collision (in world space) + virtual void GetContactSpeed( Vector &out ) = 0; // speed of surface 1 relative to surface 0 (in world space) +}; + + +struct vcollisionevent_t +{ + IPhysicsObject *pObjects[2]; + int surfaceProps[2]; + bool isCollision; + bool isShadowCollision; + float deltaCollisionTime; + + float collisionSpeed; // only valid at postCollision + IPhysicsCollisionData *pInternalData; // may change pre/post collision +}; + +abstract_class IPhysicsCollisionEvent +{ +public: + // returns the two objects that collided, time between last collision of these objects + // and an opaque data block of collision information + // NOTE: PreCollision/PostCollision ALWAYS come in matched pairs!!! + virtual void PreCollision( vcollisionevent_t *pEvent ) = 0; + virtual void PostCollision( vcollisionevent_t *pEvent ) = 0; + + // This is a scrape event. The object has scraped across another object consuming the indicated energy + virtual void Friction( IPhysicsObject *pObject, float energy, int surfaceProps, int surfacePropsHit, IPhysicsCollisionData *pData ) = 0; + + virtual void StartTouch( IPhysicsObject *pObject1, IPhysicsObject *pObject2, IPhysicsCollisionData *pTouchData ) = 0; + virtual void EndTouch( IPhysicsObject *pObject1, IPhysicsObject *pObject2, IPhysicsCollisionData *pTouchData ) = 0; + + virtual void FluidStartTouch( IPhysicsObject *pObject, IPhysicsFluidController *pFluid ) = 0; + virtual void FluidEndTouch( IPhysicsObject *pObject, IPhysicsFluidController *pFluid ) = 0; + + virtual void PostSimulationFrame() = 0; + + virtual void ObjectEnterTrigger( IPhysicsObject *pTrigger, IPhysicsObject *pObject ) {} + virtual void ObjectLeaveTrigger( IPhysicsObject *pTrigger, IPhysicsObject *pObject ) {} +}; + + +abstract_class IPhysicsObjectEvent +{ +public: + // these can be used to optimize out queries on sleeping objects + // Called when an object is woken after sleeping + virtual void ObjectWake( IPhysicsObject *pObject ) = 0; + // called when an object goes to sleep (no longer simulating) + virtual void ObjectSleep( IPhysicsObject *pObject ) = 0; +}; + +class IPhysicsConstraintEvent +{ +public: + // the constraint is now inactive, the game code is required to delete it or re-activate it. + virtual void ConstraintBroken( IPhysicsConstraint * ) = 0; +}; + +struct hlshadowcontrol_params_t +{ + Vector targetPosition; + QAngle targetRotation; + float maxAngular; + float maxDampAngular; + float maxSpeed; + float maxDampSpeed; + float dampFactor; + float teleportDistance; +}; + +// UNDONE: At some point allow this to be parameterized using hlshadowcontrol_params_t. +// All of the infrastructure is in place to do that. +abstract_class IPhysicsShadowController +{ +public: + virtual ~IPhysicsShadowController( void ) {} + + virtual void Update( const Vector &position, const QAngle &angles, float timeOffset ) = 0; + virtual void MaxSpeed( float maxSpeed, float maxAngularSpeed ) = 0; + virtual void StepUp( float height ) = 0; + + // If the teleport distance is non-zero, the object will be teleported to + // the target location when the error exceeds this quantity. + virtual void SetTeleportDistance( float teleportDistance ) = 0; + virtual bool AllowsTranslation() = 0; + virtual bool AllowsRotation() = 0; + + // There are two classes of shadow objects: + // 1) Game physics controlled, shadow follows game physics (this is the default) + // 2) Physically controlled - shadow position is a target, but the game hasn't guaranteed that the space can be occupied by this object + virtual void SetPhysicallyControlled( bool isPhysicallyControlled ) = 0; + virtual bool IsPhysicallyControlled() = 0; + virtual void GetLastImpulse( Vector *pOut ) = 0; + virtual void UseShadowMaterial( bool bUseShadowMaterial ) = 0; + virtual void ObjectMaterialChanged( int materialIndex ) = 0; +}; + +class CPhysicsSimObject; +class IPhysicsMotionController; + +// Callback for simulation +class IMotionEvent +{ +public: + // These constants instruct the simulator as to how to apply the values copied to linear & angular + // GLOBAL/LOCAL refer to the coordinate system of the values, whereas acceleration/force determine whether or not + // mass is divided out (forces must be divided by mass to compute acceleration) + enum simresult_e { SIM_NOTHING = 0, SIM_LOCAL_ACCELERATION, SIM_LOCAL_FORCE, SIM_GLOBAL_ACCELERATION, SIM_GLOBAL_FORCE }; + virtual simresult_e Simulate( IPhysicsMotionController *pController, IPhysicsObject *pObject, float deltaTime, Vector &linear, AngularImpulse &angular ) = 0; +}; + + + +abstract_class IPhysicsMotionController +{ +public: + virtual ~IPhysicsMotionController( void ) {} + virtual void SetEventHandler( IMotionEvent *handler ) = 0; + virtual void AttachObject( IPhysicsObject *pObject, bool checkIfAlreadyAttached ) = 0; + virtual void DetachObject( IPhysicsObject *pObject ) = 0; + + // returns the number of objects currently attached to the controller + virtual int CountObjects( void ) = 0; + // NOTE: pObjectList is an array with at least CountObjects() allocated + virtual void GetObjects( IPhysicsObject **pObjectList ) = 0; + // detaches all attached objects + virtual void ClearObjects( void ) = 0; + + // wakes up all attached objects + virtual void WakeObjects( void ) = 0; + enum priority_t + { + LOW_PRIORITY = 0, + MEDIUM_PRIORITY = 1, + HIGH_PRIORITY = 2, + }; + virtual void SetPriority( priority_t priority ) = 0; +}; + +// ------------------- +// Collision filter function. Return 0 if objects should not be tested for collisions, nonzero otherwise +// Install with IPhysicsEnvironment::SetCollisionFilter() +// ------------------- +abstract_class IPhysicsCollisionSolver +{ +public: + virtual int ShouldCollide( IPhysicsObject *pObj0, IPhysicsObject *pObj1, void *pGameData0, void *pGameData1 ) = 0; + virtual int ShouldSolvePenetration( IPhysicsObject *pObj0, IPhysicsObject *pObj1, void *pGameData0, void *pGameData1, float dt ) = 0; + + // pObject has already done the max number of collisions this tick, should we freeze it to save CPU? + virtual bool ShouldFreezeObject( IPhysicsObject *pObject ) = 0; + + // The system has already done too many collision checks, performance will suffer. + // How many more should it do? + virtual int AdditionalCollisionChecksThisTick( int currentChecksDone ) = 0; +}; + +enum PhysicsTraceType_t +{ + VPHYSICS_TRACE_EVERYTHING = 0, + VPHYSICS_TRACE_STATIC_ONLY, + VPHYSICS_TRACE_MOVING_ONLY, + VPHYSICS_TRACE_TRIGGERS_ONLY, + VPHYSICS_TRACE_STATIC_AND_MOVING, +}; + +abstract_class IPhysicsTraceFilter +{ +public: + virtual bool ShouldHitObject( IPhysicsObject *pObject, int contentsMask ) = 0; + virtual PhysicsTraceType_t GetTraceType() const = 0; +}; + +abstract_class IPhysicsEnvironment +{ +public: + virtual ~IPhysicsEnvironment( void ) {} + + virtual void SetDebugOverlay( CreateInterfaceFn debugOverlayFactory ) = 0; + virtual IVPhysicsDebugOverlay *GetDebugOverlay( void ) = 0; + + // gravity is a 3-vector in in/s^2 + virtual void SetGravity( const Vector &gravityVector ) = 0; + virtual void GetGravity( Vector &gravityVector ) = 0; + + // air density is in kg / m^3 (water is 1000) + // This controls drag, air that is more dense has more drag. + virtual void SetAirDensity( float density ) = 0; + virtual float GetAirDensity( void ) = 0; + + // object creation + // create a polygonal object. pCollisionModel was created by the physics builder DLL in a pre-process. + virtual IPhysicsObject *CreatePolyObject( const CPhysCollide *pCollisionModel, int materialIndex, const Vector &position, const QAngle &angles, objectparams_t *pParams ) = 0; + // same as above, but this one cannot move or rotate (infinite mass/inertia) + virtual IPhysicsObject *CreatePolyObjectStatic( const CPhysCollide *pCollisionModel, int materialIndex, const Vector &position, const QAngle &angles, objectparams_t *pParams ) = 0; + // Create a perfectly spherical object + virtual IPhysicsObject *CreateSphereObject( float radius, int materialIndex, const Vector &position, const QAngle &angles, objectparams_t *pParams, bool isStatic ) = 0; + // Create a polygonal fluid body out of the specified collision model + // This object will affect any other objects that collide with the collision model + virtual IPhysicsFluidController *CreateFluidController( IPhysicsObject *pFluidObject, fluidparams_t *pParams ) = 0; + + // Create a simulated spring that connects 2 objects + virtual IPhysicsSpring *CreateSpring( IPhysicsObject *pObjectStart, IPhysicsObject *pObjectEnd, springparams_t *pParams ) = 0; + + // Create a constraint in the space of pReferenceObject which is attached by the constraint to pAttachedObject + virtual IPhysicsConstraint *CreateRagdollConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_ragdollparams_t &ragdoll ) = 0; + virtual IPhysicsConstraint *CreateHingeConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_hingeparams_t &hinge ) = 0; + virtual IPhysicsConstraint *CreateFixedConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_fixedparams_t &fixed ) = 0; + virtual IPhysicsConstraint *CreateSlidingConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_slidingparams_t &sliding ) = 0; + virtual IPhysicsConstraint *CreateBallsocketConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_ballsocketparams_t &ballsocket ) = 0; + virtual IPhysicsConstraint *CreatePulleyConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_pulleyparams_t &pulley ) = 0; + virtual IPhysicsConstraint *CreateLengthConstraint( IPhysicsObject *pReferenceObject, IPhysicsObject *pAttachedObject, IPhysicsConstraintGroup *pGroup, const constraint_lengthparams_t &length ) = 0; + + virtual IPhysicsConstraintGroup *CreateConstraintGroup( const constraint_groupparams_t &groupParams ) = 0; + + // destroy an object created with CreatePolyObject() or CreatePolyObjectStatic() + virtual void DestroyObject( IPhysicsObject * ) = 0; + virtual void DestroySpring( IPhysicsSpring * ) = 0; + // Destroy an object created with CreateFluidController() + virtual void DestroyFluidController( IPhysicsFluidController * ) = 0; + virtual void DestroyConstraint( IPhysicsConstraint * ) = 0; + virtual void DestroyConstraintGroup( IPhysicsConstraintGroup *pGroup ) = 0; + + // install a function to filter collisions/penentration + virtual void SetCollisionSolver( IPhysicsCollisionSolver *pSolver ) = 0; + + // run the simulator for deltaTime seconds + virtual void Simulate( float deltaTime ) = 0; + // true if currently running the simulator (i.e. in a callback during physenv->Simulate()) + virtual bool IsInSimulation( void ) const = 0; + + // Manage the timestep (period) of the simulator. The main functions are all integrated with + // this period as dt. + virtual float GetSimulationTimestep( void ) = 0; + virtual void SetSimulationTimestep( float timestep ) = 0; + + // returns the current simulation clock's value. This is an absolute time. + virtual float GetSimulationTime( void ) = 0; + virtual void ResetSimulationClock( void ) = 0; + + // Collision callbacks (game code collision response) + virtual void SetCollisionEventHandler( IPhysicsCollisionEvent *pCollisionEvents ) = 0; + virtual void SetObjectEventHandler( IPhysicsObjectEvent *pObjectEvents ) = 0; + virtual void SetConstraintEventHandler( IPhysicsConstraintEvent *pConstraintEvents ) = 0; + + virtual IPhysicsShadowController *CreateShadowController( IPhysicsObject *pObject, bool allowTranslation, bool allowRotation ) = 0; + virtual void DestroyShadowController( IPhysicsShadowController * ) = 0; + + virtual IPhysicsPlayerController *CreatePlayerController( IPhysicsObject *pObject ) = 0; + virtual void DestroyPlayerController( IPhysicsPlayerController * ) = 0; + + virtual IPhysicsMotionController *CreateMotionController( IMotionEvent *pHandler ) = 0; + virtual void DestroyMotionController( IPhysicsMotionController *pController ) = 0; + + virtual IPhysicsVehicleController *CreateVehicleController( IPhysicsObject *pVehicleBodyObject, const vehicleparams_t ¶ms, unsigned int nVehicleType, IPhysicsGameTrace *pGameTrace ) = 0; + virtual void DestroyVehicleController( IPhysicsVehicleController * ) = 0; + + virtual void SetQuickDelete( bool bQuick ) = 0; + + virtual int GetActiveObjectCount( void ) = 0; + virtual void GetActiveObjects( IPhysicsObject **pOutputObjectList ) = 0; + + virtual void CleanupDeleteList( void ) = 0; + virtual void EnableDeleteQueue( bool enable ) = 0; + + // Save/Restore methods + virtual bool Save( const physsaveparams_t ¶ms ) = 0; + virtual void PreRestore( const physprerestoreparams_t ¶ms ) = 0; + virtual bool Restore( const physrestoreparams_t ¶ms ) = 0; + virtual void PostRestore() = 0; + + // Debugging: + virtual bool IsCollisionModelUsed( CPhysCollide *pCollide ) = 0; + + // Physics world version of the enginetrace API: + virtual void TraceRay( const Ray_t &ray, unsigned int fMask, IPhysicsTraceFilter *pTraceFilter, trace_t *pTrace ) = 0; + virtual void SweepCollideable( const CPhysCollide *pCollide, const Vector &vecAbsStart, const Vector &vecAbsEnd, + const QAngle &vecAngles, unsigned int fMask, IPhysicsTraceFilter *pTraceFilter, trace_t *pTrace ) = 0; + + // performance tuning + virtual void GetPerformanceSettings( physics_performanceparams_t *pOutput ) = 0; + virtual void SetPerformanceSettings( const physics_performanceparams_t *pSettings ) = 0; + + // perf/cost statistics + virtual void ReadStats( physics_stats_t *pOutput ) = 0; + virtual void ClearStats() = 0; +}; + +enum callbackflags +{ + CALLBACK_GLOBAL_COLLISION = 0x0001, + CALLBACK_GLOBAL_FRICTION = 0x0002, + CALLBACK_GLOBAL_TOUCH = 0x0004, + CALLBACK_GLOBAL_TOUCH_STATIC = 0x0008, + CALLBACK_SHADOW_COLLISION = 0x0010, + CALLBACK_GLOBAL_COLLIDE_STATIC = 0x0020, + CALLBACK_IS_VEHICLE_WHEEL = 0x0040, + CALLBACK_FLUID_TOUCH = 0x0100, + CALLBACK_NEVER_DELETED = 0x0200, // HACKHACK: This means this object will never be deleted (set on the world) + CALLBACK_MARKED_FOR_DELETE = 0x0400, // This allows vphysics to skip some work for this object since it will be + // deleted later this frame. (Set automatically by destroy calls) + CALLBACK_ENABLING_COLLISION = 0x0800, // This is active during the time an object is enabling collisions + // allows us to skip collisions between "new" objects and objects marked for delete + CALLBACK_DO_FLUID_SIMULATION = 0x1000, // remove this to opt out of fluid simulations + CALLBACK_IS_PLAYER_CONTROLLER= 0x2000, // HACKHACK: Set this on players until player cotrollers are unified with shadow controllers + CALLBACK_CHECK_COLLISION_DISABLE = 0x4000, + CALLBACK_MARKED_FOR_TEST = 0x8000, // debug -- marked object is being debugged +}; + +abstract_class IPhysicsObject +{ +public: + virtual ~IPhysicsObject( void ) {} + + // returns true if this object is static/unmoveable + // NOTE: returns false for objects that are not created static, but set EnableMotion(false); + // Call IsMoveable() to find if the object is static OR has motion disabled + virtual bool IsStatic( void ) = 0; + + // "wakes up" an object + // NOTE: ALL OBJECTS ARE "Asleep" WHEN CREATED + virtual void Wake( void ) = 0; + virtual void Sleep( void ) = 0; + virtual bool IsAsleep( void ) = 0; + + // Game can store data in each object (link back to game object) + virtual void SetGameData( void *pGameData ) = 0; + virtual void *GetGameData( void ) const = 0; + // This flags word can be defined by the game as well + virtual void SetGameFlags( unsigned short userFlags ) = 0; + virtual unsigned short GetGameFlags( void ) const = 0; + virtual void SetGameIndex( unsigned short gameIndex ) = 0; + virtual unsigned short GetGameIndex( void ) const = 0; + + // setup various callbacks for this object + virtual void SetCallbackFlags( unsigned short callbackflags ) = 0; + // get the current callback state for this object + virtual unsigned short GetCallbackFlags( void ) = 0; + + // mass accessors + virtual void SetMass( float mass ) = 0; + virtual float GetMass( void ) const = 0; + // get 1/mass (it's cached) + virtual float GetInvMass( void ) const = 0; + virtual Vector GetInertia( void ) const = 0; + virtual Vector GetInvInertia( void ) const = 0; + virtual void SetInertia( const Vector &inertia ) = 0; + + virtual void SetDamping( const float *speed, const float *rot ) = 0; + virtual void GetDamping( float *speed, float *rot ) = 0; + + // material index + virtual int GetMaterialIndex() const = 0; + virtual void SetMaterialIndex( int materialIndex ) = 0; + + // Enable / disable collisions for this object + virtual void EnableCollisions( bool enable ) = 0; + // Enable / disable gravity for this object + virtual void EnableGravity( bool enable ) = 0; + // Enable / disable air friction / drag for this object + virtual void EnableDrag( bool enable ) = 0; + // Enable / disable motion (pin / unpin the object) + virtual void EnableMotion( bool enable ) = 0; + + // call this when the collision filter conditions change due to this + // object's state (e.g. changing solid type or collision group) + virtual void RecheckCollisionFilter() = 0; + + // NOTE: These are here for convenience, but you can do them yourself by using the matrix + // returned from GetPositionMatrix() + // convenient coordinate system transformations (params - dest, src) + virtual void LocalToWorld( Vector *worldPosition, const Vector &localPosition ) = 0; + virtual void WorldToLocal( Vector *localPosition, const Vector &worldPosition ) = 0; + + // transforms a vector (no translation) from object-local to world space + virtual void LocalToWorldVector( Vector *worldVector, const Vector &localVector ) = 0; + // transforms a vector (no translation) from world to object-local space + virtual void WorldToLocalVector( Vector *localVector, const Vector &worldVector ) = 0; + + // push on an object + // force vector is direction & magnitude of impulse kg in / s + virtual void ApplyForceCenter( const Vector &forceVector ) = 0; + virtual void ApplyForceOffset( const Vector &forceVector, const Vector &worldPosition ) = 0; + + // Calculates the force/torque on the center of mass for an offset force impulse (pass output to ApplyForceCenter / ApplyTorqueCenter) + virtual void CalculateForceOffset( const Vector &forceVector, const Vector &worldPosition, Vector *centerForce, AngularImpulse *centerTorque ) = 0; + // Calculates the linear/angular velocities on the center of mass for an offset force impulse (pass output to AddVelocity) + virtual void CalculateVelocityOffset( const Vector &forceVector, const Vector &worldPosition, Vector *centerVelocity, AngularImpulse *centerAngularVelocity ) = 0; + + // apply torque impulse. This will change the angular velocity on the object. + // HL Axes, kg degrees / s + virtual void ApplyTorqueCenter( const AngularImpulse &torque ) = 0; + + // NOTE: This will teleport the object + virtual void SetPosition( const Vector &worldPosition, const QAngle &angles, bool isTeleport ) = 0; + virtual void SetPositionMatrix( const matrix3x4_t&matrix, bool isTeleport ) = 0; + + virtual void GetPosition( Vector *worldPosition, QAngle *angles ) = 0; + virtual void GetPositionMatrix( matrix3x4_t *positionMatrix ) = 0; + // force the velocity to a new value + // NOTE: velocity is in worldspace, angularVelocity is relative to the object's + // local axes (just like pev->velocity, pev->avelocity) + virtual void SetVelocity( const Vector *velocity, const AngularImpulse *angularVelocity ) = 0; + + // like the above, but force the change into the simulator immediately + virtual void SetVelocityInstantaneous( const Vector *velocity, const AngularImpulse *angularVelocity ) = 0; + + // NOTE: velocity is in worldspace, angularVelocity is relative to the object's + // local axes (just like pev->velocity, pev->avelocity) + virtual void GetVelocity( Vector *velocity, AngularImpulse *angularVelocity ) = 0; + + // NOTE: These are velocities, not forces. i.e. They will have the same effect regardless of + // the object's mass or inertia + virtual void AddVelocity( const Vector *velocity, const AngularImpulse *angularVelocity ) = 0; + virtual void GetVelocityAtPoint( const Vector &worldPosition, Vector &velocity ) = 0; + + virtual float GetEnergy() = 0; + + // returns true if the object is in contact with another object + // if true, puts a point on the contact surface in contactPoint, and + // a pointer to the object in contactObject + // NOTE: You can pass NULL for either to avoid computations + // JAY: This is still an experiment + virtual bool GetContactPoint( Vector *contactPoint, IPhysicsObject **contactObject ) = 0; + + // refactor this a bit - move some of this to IPhysicsShadowController + virtual void SetShadow( float maxSpeed, float maxAngularSpeed, bool allowPhysicsMovement, bool allowPhysicsRotation ) = 0; + virtual void UpdateShadow( const Vector &targetPosition, const QAngle &targetAngles, bool tempDisableGravity, float timeOffset ) = 0; + + // returns number of ticks since last Update() call + virtual int GetShadowPosition( Vector *position, QAngle *angles ) = 0; + virtual IPhysicsShadowController *GetShadowController( void ) const = 0; + + + virtual const CPhysCollide *GetCollide( void ) const = 0; + virtual const char *GetName() = 0; + virtual void RemoveShadowController() = 0; + virtual bool IsMoveable() = 0; + + // applies the math of the shadow controller to this object. + // for use in your own controllers + // returns the new value of secondsToArrival with dt time elapsed + virtual float ComputeShadowControl( const hlshadowcontrol_params_t ¶ms, float secondsToArrival, float dt ) = 0; + + // coefficients are optional, pass either + virtual void SetDragCoefficient( float *pDrag, float *pAngularDrag ) = 0; + + // Get the radius if this is a sphere object (zero if this is a polygonal mesh) + virtual float GetSphereRadius() = 0; + + virtual float CalculateLinearDrag( const Vector &unitDirection ) const = 0; + virtual float CalculateAngularDrag( const Vector &objectSpaceRotationAxis ) const = 0; + virtual void SetBuoyancyRatio( float ratio ) = 0; // Override bouyancy + + virtual void BecomeTrigger() = 0; + virtual void RemoveTrigger() = 0; + virtual bool IsTrigger() = 0; + virtual bool IsFluid() = 0; // fluids are special triggers with fluid controllers attached, they return true to IsTrigger() as well! + + // sets the object to be hinged. Fixed it place, but able to rotate around one axis. + virtual void BecomeHinged( int localAxis ) = 0; + // resets the object to original state + virtual void RemoveHinged() = 0; + virtual bool IsHinged() = 0; + + virtual unsigned int GetContents() = 0; + virtual void SetContents( unsigned int contents ) = 0; + virtual Vector GetMassCenterLocalSpace() = 0; + + // used to iterate the contact points of an object + virtual IPhysicsFrictionSnapshot *CreateFrictionSnapshot() = 0; + virtual void DestroyFrictionSnapshot( IPhysicsFrictionSnapshot *pSnapshot ) = 0; + + // dumps info about the object to Msg() + virtual void OutputDebugInfo() = 0; + virtual void GetImplicitVelocity( Vector *velocity, AngularImpulse *angularVelocity ) = 0; + // this is a hack to recheck current contacts + // some of them may not be valid if the object's collision rules have recently changed + // UNDONE: Force this in RecheckCollisionFilter() ? + virtual void RecheckContactPoints() = 0; +}; + + +abstract_class IPhysicsSpring +{ +public: + virtual ~IPhysicsSpring( void ) {} + virtual void GetEndpoints( Vector *worldPositionStart, Vector *worldPositionEnd ) = 0; + virtual void SetSpringConstant( float flSpringContant) = 0; + virtual void SetSpringDamping( float flSpringDamping) = 0; + virtual void SetSpringLength( float flSpringLenght) = 0; + + // Get the starting object + virtual IPhysicsObject *GetStartObject( void ) = 0; + + // Get the end object + virtual IPhysicsObject *GetEndObject( void ) = 0; +}; + + +//----------------------------------------------------------------------------- +// Purpose: These properties are defined per-material. This is accessible at +// each triangle in a collision mesh +//----------------------------------------------------------------------------- +struct surfacephysicsparams_t +{ +// vphysics physical properties + float friction; + float elasticity; // collision elasticity - used to compute coefficient of restitution + float density; // physical density (in kg / m^3) + float thickness; // material thickness if not solid (sheet materials) in inches + float dampening; +}; + +struct surfaceaudioparams_t +{ +// sounds / audio data + float reflectivity; // like elasticity, but how much sound should be reflected by this surface + float hardnessFactor; // like elasticity, but only affects impact sound choices + float roughnessFactor; // like friction, but only affects scrape sound choices + +// audio thresholds + float roughThreshold; // surface roughness > this causes "rough" scrapes, < this causes "smooth" scrapes + float hardThreshold; // surface hardness > this causes "hard" impacts, < this causes "soft" impacts + float hardVelocityThreshold; // collision velocity > this causes "hard" impacts, < this causes "soft" impacts + // NOTE: Hard impacts must meet both hardnessFactor AND velocity thresholds +}; + +struct surfacesoundnames_t +{ + unsigned short stepleft; + unsigned short stepright; + + unsigned short impactSoft; + unsigned short impactHard; + + unsigned short scrapeSmooth; + unsigned short scrapeRough; + + unsigned short bulletImpact; + unsigned short rolling; + + unsigned short breakSound; + unsigned short strainSound; +}; + +struct surfacegameprops_t +{ +// game movement data + float maxSpeedFactor; // Modulates player max speed when walking on this surface + float jumpFactor; // Indicates how much higher the player should jump when on the surface +// Game-specific data + unsigned short material; + // Indicates whether or not the player is on a ladder. + unsigned char climbable; + unsigned char pad; +}; + +//----------------------------------------------------------------------------- +// Purpose: Each different material has an entry like this +//----------------------------------------------------------------------------- +struct surfacedata_t +{ + surfacephysicsparams_t physics; // physics parameters + surfaceaudioparams_t audio; // audio parameters + surfacesoundnames_t sounds; // names of linked sounds + surfacegameprops_t game; // Game data / properties + + +}; + +#define VPHYSICS_SURFACEPROPS_INTERFACE_VERSION_1 "VPhysicsSurfaceProps001" +abstract_class IPhysicsSurfaceProps +{ +public: + virtual ~IPhysicsSurfaceProps( void ) {} + + // parses a text file containing surface prop keys + virtual int ParseSurfaceData( const char *pFilename, const char *pTextfile ) = 0; + // current number of entries in the database + virtual int SurfacePropCount( void ) = 0; + + virtual int GetSurfaceIndex( const char *pSurfacePropName ) = 0; + virtual void GetPhysicsProperties( int surfaceDataIndex, float *density, float *thickness, float *friction, float *elasticity ) = 0; + + virtual surfacedata_t *GetSurfaceData( int surfaceDataIndex ) = 0; + virtual const char *GetString( unsigned short stringTableIndex ) = 0; + + + virtual const char *GetPropName( int surfaceDataIndex ) = 0; + + // sets the global index table for world materials + virtual void SetWorldMaterialIndexTable( int *pMapArray, int mapSize ) = 0; + + // NOTE: Same as GetPhysicsProperties, but maybe more convenient + virtual void GetPhysicsParameters( int surfaceDataIndex, surfacephysicsparams_t *pParamsOut ) = 0; +}; + +abstract_class IPhysicsFluidController +{ +public: + virtual ~IPhysicsFluidController( void ) {} + + virtual void SetGameData( void *pGameData ) = 0; + virtual void *GetGameData( void ) const = 0; + + virtual void GetSurfacePlane( Vector *pNormal, float *pDist ) = 0; + virtual float GetDensity() = 0; + virtual void WakeAllSleepingObjects() = 0; + virtual int GetContents() const = 0; +}; + + +//----------------------------------------------------------------------------- +// Purpose: parameter block for creating fluid dynamic motion +// UNDONE: Expose additional fluid model paramters? +//----------------------------------------------------------------------------- +struct fluidparams_t +{ + Vector4D surfacePlane; // x,y,z normal, dist (plane constant) fluid surface + Vector currentVelocity; // velocity of the current in inches/second + float damping; // damping factor for buoyancy (tweak) + float torqueFactor; + float viscosityFactor; + void *pGameData; + bool useAerodynamics;// true if this controller should calculate surface pressure + int contents; + + fluidparams_t() {} + fluidparams_t( fluidparams_t const& src ) + { + Vector4DCopy( src.surfacePlane, surfacePlane ); + VectorCopy( src.currentVelocity, currentVelocity ); + damping = src.damping; + torqueFactor = src.torqueFactor; + viscosityFactor = src.viscosityFactor; + contents = src.contents; + } +}; + +//----------------------------------------------------------------------------- +// Purpose: parameter block for creating linear springs +// UNDONE: Expose additional spring model paramters? +//----------------------------------------------------------------------------- +struct springparams_t +{ + springparams_t() + { + memset( this, 0, sizeof(*this) ); + } + float constant; // spring constant + float naturalLength;// relaxed length + float damping; // damping factor + float relativeDamping; // relative damping (damping proportional to the change in the relative position of the objects) + Vector startPosition; + Vector endPosition; + bool useLocalPositions; // start & end Position are in local space to start and end objects if this is true + bool onlyStretch; // only apply forces when the length is greater than the natural length +}; + +//----------------------------------------------------------------------------- +// Purpose: parameter block for creating polygonal objects +//----------------------------------------------------------------------------- +struct objectparams_t +{ + Vector *massCenterOverride; + float mass; + float inertia; + float damping; + float rotdamping; + float rotInertiaLimit; + const char *pName; // used only for debugging + void *pGameData; + float volume; + float dragCoefficient; + bool enableCollisions; +}; + +struct convertconvexparams_t +{ + bool buildOuterConvexHull; + bool buildDragAxisAreas; + bool buildOptimizedTraceTables; + float dragAreaEpsilon; + CPhysConvex *pForcedOuterHull; + + void Defaults() + { + dragAreaEpsilon = 0.25f; // 0.5in x 0.5in square + buildOuterConvexHull = false; + buildDragAxisAreas = false; + buildOptimizedTraceTables = false; + pForcedOuterHull = NULL; + } +}; + +//----------------------------------------------------------------------------- +// Physics interface IDs +// +// Note that right now the order of the enum also defines the order of save/load + + +//----------------------------------------------------------------------------- +// Purpose: parameter blocks for save and load operations +//----------------------------------------------------------------------------- +struct physsaveparams_t +{ + ISave *pSave; + void *pObject; + PhysInterfaceId_t type; +}; + +struct physrestoreparams_t +{ + IRestore *pRestore; + void **ppObject; + PhysInterfaceId_t type; + void *pGameData; + const char *pName; // used only for debugging + const CPhysCollide *pCollisionModel; + IPhysicsEnvironment *pEnvironment; + IPhysicsGameTrace *pGameTrace; +}; + +struct physrecreateparams_t +{ + void *pOldObject; + void *pNewObject; +}; + +struct physprerestoreparams_t +{ + int recreatedObjectCount; + physrecreateparams_t recreatedObjectList[1]; +}; + + +//------------------------------------- + +#define DEFINE_PIID( type, enumval ) \ + template <> inline PhysInterfaceId_t GetPhysIID( type ** ) { return enumval; } + +template inline PhysInterfaceId_t GetPhysIID(PHYSPTR **); // will get link error if no match + +DEFINE_PIID( IPhysicsObject, PIID_IPHYSICSOBJECT ); +DEFINE_PIID( IPhysicsFluidController, PIID_IPHYSICSFLUIDCONTROLLER ); +DEFINE_PIID( IPhysicsSpring, PIID_IPHYSICSSPRING ); +DEFINE_PIID( IPhysicsConstraintGroup, PIID_IPHYSICSCONSTRAINTGROUP ); +DEFINE_PIID( IPhysicsConstraint, PIID_IPHYSICSCONSTRAINT ); +DEFINE_PIID( IPhysicsShadowController, PIID_IPHYSICSSHADOWCONTROLLER ); +DEFINE_PIID( IPhysicsPlayerController, PIID_IPHYSICSPLAYERCONTROLLER ); +DEFINE_PIID( IPhysicsMotionController, PIID_IPHYSICSMOTIONCONTROLLER ); +DEFINE_PIID( IPhysicsVehicleController, PIID_IPHYSICSVEHICLECONTROLLER ); +DEFINE_PIID( IPhysicsGameTrace, PIID_IPHYSICSGAMETRACE ); + +//----------------------------------------------------------------------------- + +} // end namespace VPhysicsInterfaceV30 + +#endif // VPHYSICS_INTERFACE_V30_H diff --git a/sp/src/public/wadtypes.h b/sp/src/public/wadtypes.h new file mode 100644 index 00000000..cee496f7 --- /dev/null +++ b/sp/src/public/wadtypes.h @@ -0,0 +1,99 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#ifndef WADTYPES_H +#define WADTYPES_H +#pragma once + +#include "basetypes.h" + +// --------------------------------------------------------- +// +// This should include ONLY types (no function prototypes) +// in or related to WADs that are shared among the engine +// and tools +// +// --------------------------------------------------------- + +//=============== +// TYPES +//=============== + +#define CMP_NONE 0 +#define CMP_LZSS 1 + +#define TYP_NONE 0 +#define TYP_LABEL 1 + +#define TYP_LUMPY 64 +#define TYP_PALETTE 64 +#define TYP_COLORMAP 65 +#define TYP_QPIC 66 +#define TYP_MIPTEX 67 +#define TYP_RAW 68 +#define TYP_COLORMAP2 69 +#define TYP_FONT 70 +#define TYP_SOUND 71 +#define TYP_QTEX 72 + + +#define __QPIC_T +typedef struct qpic_s +{ + int width, height; + byte data[4]; // variably sized +} qpic_t; + +#define WAD_ID MAKEID( 'W', 'A', 'D', '5' ) +#define WAD_IDNAME "WAD5" + +typedef struct wadinfo_s +{ + char identification[4]; // should be WAD2 or 2DAW + int numlumps; + int infotableofs; +} wadinfo_t; + +#ifndef TEXTURE_NAME_LENGTH +#define TEXTURE_NAME_LENGTH 128 +#endif + +typedef struct lumpinfo_s +{ + int filepos; + int disksize; + int size; // uncompressed + char type; + char compression; + char pad1, pad2; + char name[TEXTURE_NAME_LENGTH]; // must be null terminated +} lumpinfo_t; + +typedef struct +{ + lumpinfo_t lump; + int iTexFile; // index of the wad this texture is located in +} texlumpinfo_t; + +#define MIPLEVELS 4 +typedef struct miptex_s // New WAD4 files +{ + char name[TEXTURE_NAME_LENGTH]; + unsigned width, height, view_width, view_height; + float reflectivity[3]; // Linear palette + unsigned offsets[MIPLEVELS]; // four mip maps stored +} miptex_t; + + +#define MAX_TEXTUREWIDTH 1024 +#define MAX_TEXTUREHEIGHT 1024 +#define MAX_TEXTURESIZE (MAX_TEXTUREWIDTH*MAX_TEXTUREHEIGHT) +#define MAXLUMP (((MAX_TEXTURESIZE * (64+16+4+1))/64) + sizeof(miptex_t) + 1024) // biggest possible lump + + +#endif // WADTYPES_H + diff --git a/sp/src/public/windows_default.manifest b/sp/src/public/windows_default.manifest new file mode 100644 index 00000000..f7bc13e5 --- /dev/null +++ b/sp/src/public/windows_default.manifest @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/sp/src/public/winlite.h b/sp/src/public/winlite.h new file mode 100644 index 00000000..c8fba07c --- /dev/null +++ b/sp/src/public/winlite.h @@ -0,0 +1,35 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#ifndef WINLITE_H +#define WINLITE_H +#pragma once + +#ifdef _WIN32 +// +// Prevent tons of unused windows definitions +// +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#define NOWINRES +#define NOSERVICE +#define NOMCX +#define NOIME +#if !defined( _X360 ) +#pragma warning(push, 1) +#pragma warning(disable: 4005) +#include +#pragma warning(pop) +#endif +#undef PostMessage + +#pragma warning( disable: 4800 ) // forcing value to bool 'true' or 'false' (performance warning) + +#endif // WIN32 +#endif // WINLITE_H diff --git a/sp/src/public/worldsize.h b/sp/src/public/worldsize.h new file mode 100644 index 00000000..957e17f1 --- /dev/null +++ b/sp/src/public/worldsize.h @@ -0,0 +1,42 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// worldsize.h -- extent of world and resolution/size of coordinate messages used in engine + +#ifndef WORLDSIZE_H +#define WORLDSIZE_H +#pragma once + + +// These definitions must match the coordinate message sizes in coordsize.h + +// Following values should be +16384, -16384, +15/16, -15/16 +// NOTE THAT IF THIS GOES ANY BIGGER THEN DISK NODES/LEAVES CANNOT USE SHORTS TO STORE THE BOUNDS +#define MAX_COORD_INTEGER (16384) +#define MIN_COORD_INTEGER (-MAX_COORD_INTEGER) +#define MAX_COORD_FRACTION (1.0-(1.0/16.0)) +#define MIN_COORD_FRACTION (-1.0+(1.0/16.0)) + +#define MAX_COORD_FLOAT (16384.0f) +#define MIN_COORD_FLOAT (-MAX_COORD_FLOAT) + +// Width of the coord system, which is TOO BIG to send as a client/server coordinate value +#define COORD_EXTENT (2*MAX_COORD_INTEGER) + +// Maximum traceable distance ( assumes cubic world and trace from one corner to opposite ) +// COORD_EXTENT * sqrt(3) +#define MAX_TRACE_LENGTH ( 1.732050807569 * COORD_EXTENT ) + +// This value is the LONGEST possible range (limited by max valid coordinate number, not 2x) +#define MAX_COORD_RANGE (MAX_COORD_INTEGER) + +#define ASSERT_COORD( v ) Assert( (v.x>=MIN_COORD_INTEGER*2) && (v.x<=MAX_COORD_INTEGER*2) && \ + (v.y>=MIN_COORD_INTEGER*2) && (v.y<=MAX_COORD_INTEGER*2) && \ + (v.z>=MIN_COORD_INTEGER*2) && (v.z<=MAX_COORD_INTEGER*2) ); \ + + +#endif // WORLDSIZE_H diff --git a/sp/src/public/xwvfile.h b/sp/src/public/xwvfile.h new file mode 100644 index 00000000..c27bad0e --- /dev/null +++ b/sp/src/public/xwvfile.h @@ -0,0 +1,85 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#ifndef XWVFILE_H +#define XWVFILE_H +#ifdef _WIN32 +#pragma once +#endif + +#pragma pack(1) + +#define XWV_ID (('X'<<24)|('W'<<16)|('V'<<8)|(' '<<0)) +#define XWV_VERSION 4 + +enum xwvSampleRate_t +{ + XWV_RATE_11025 = 0, + XWV_RATE_22050 = 1, + XWV_RATE_44100 = 2, +}; + +enum xwvFormat_t +{ + XWV_FORMAT_PCM = 0, + XWV_FORMAT_XMA = 1, + XWV_FORMAT_ADPCM = 2, +}; + +// generated in big-endian +struct xwvHeader_t +{ + unsigned int id; + unsigned int version; + unsigned int headerSize; // header only + unsigned int staticDataSize; // follows header + unsigned int dataOffset; // start of samples, possibly sector aligned + unsigned int dataSize; // length of samples in bytes + unsigned int numDecodedSamples; // for duration calcs + int loopStart; // -1 = no loop, offset of loop in samples + unsigned short loopBlock; // the xma block where the loop starts + unsigned short numLeadingSamples; // number of leading samples in the loop block to discard + unsigned short numTrailingSamples; // number of trailing samples at the final block to discard + unsigned short vdatSize; // follows seek table + byte format; + byte bitsPerSample; + byte sampleRate; + byte channels; + byte quality; + byte bHasSeekTable; // indicates presence, follows header + byte padding[2]; // created as 0 + + inline unsigned int GetPreloadSize() { return headerSize + staticDataSize; } + + inline int GetBitsPerSample() const { return bitsPerSample; } + + int GetSampleRate() const + { + int rates[] = {11025, 22050, 44100}; + int rate = sampleRate; + return rates[rate]; + } + + inline int GetChannels() const { return channels; } + + void SetSampleRate( int sampleRateIn ) + { + byte rate = ( sampleRateIn == 11025 ) ? XWV_RATE_11025 : ( sampleRateIn==22050 )? XWV_RATE_22050 : XWV_RATE_44100; + sampleRate = rate; + } + + inline void SetChannels( int channelsIn ) { channels = channelsIn; } + + inline int GetSeekTableSize() + { + // seek table is indexed by packets + return bHasSeekTable ? ( dataSize / 2048 ) * sizeof( int ) : 0; + } +}; + +#pragma pack() + +#endif // XWVFILE_H diff --git a/sp/src/public/xzp.cpp b/sp/src/public/xzp.cpp new file mode 100644 index 00000000..8a8a0f06 --- /dev/null +++ b/sp/src/public/xzp.cpp @@ -0,0 +1,1323 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#include +#endif +#include +#include +#include +#include +#include "tier1/utlbuffer.h" +#include "tier1/strtools.h" +#include "tier2/riff.h" + +#if defined( _WIN32 ) && !defined( _X360 ) +#include +#endif + +#ifdef MAKE_GAMEDATA_TOOL + #include "../public/materialsystem/shader_vcs_version.h" + #include "../public/materialsystem/imaterial.h" + #include "../public/materialsystem/hardwareverts.h" + #include "../public/vtf/vtf.h" +#else + #include "materialsystem/shader_vcs_version.h" + #include "materialsystem/imaterial.h" + #include "materialsystem/hardwareverts.h" +#endif + +#include "xwvfile.h" +#include "xzp.h" + +CByteswap g_xzpSwap; +extern IFileReadBinary *g_pSndIO; + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//----------------------------------------------------------------------------- +// Datadesc blocks for byteswapping: +//----------------------------------------------------------------------------- +BEGIN_BYTESWAP_DATADESC( xZipHeader_t ) + DEFINE_FIELD( Magic, FIELD_INTEGER ), + DEFINE_FIELD( Version, FIELD_INTEGER ), + DEFINE_FIELD( PreloadDirectoryEntries, FIELD_INTEGER ), + DEFINE_FIELD( DirectoryEntries, FIELD_INTEGER ), + DEFINE_FIELD( PreloadBytes, FIELD_INTEGER ), + DEFINE_FIELD( HeaderLength, FIELD_INTEGER ), + DEFINE_FIELD( FilenameEntries, FIELD_INTEGER ), + DEFINE_FIELD( FilenameStringsOffset, FIELD_INTEGER ), + DEFINE_FIELD( FilenameStringsLength, FIELD_INTEGER ), +END_BYTESWAP_DATADESC() + +BEGIN_BYTESWAP_DATADESC( xZipDirectoryEntry_t ) + DEFINE_FIELD( FilenameCRC, FIELD_INTEGER ), + DEFINE_FIELD( Length, FIELD_INTEGER ), + DEFINE_FIELD( StoredOffset, FIELD_INTEGER ), +END_BYTESWAP_DATADESC() + +BEGIN_BYTESWAP_DATADESC( xZipFilenameEntry_t ) + DEFINE_FIELD( FilenameCRC, FIELD_INTEGER ), + DEFINE_FIELD( FilenameOffset, FIELD_INTEGER ), + DEFINE_FIELD( TimeStamp, FIELD_INTEGER ), +END_BYTESWAP_DATADESC() + +BEGIN_BYTESWAP_DATADESC( xZipFooter_t ) + DEFINE_FIELD( Size, FIELD_INTEGER ), + DEFINE_FIELD( Magic, FIELD_INTEGER ), +END_BYTESWAP_DATADESC() + +CXZip::CXZip() +{ + // Ensure that the header doesn't contain a valid magic yet. + m_Header.Magic = 0; + m_pPreloadedData = NULL; + m_nPreloadStart = 0; + m_pDirectory = NULL; + m_pPreloadDirectory = NULL; + m_nRegular2PreloadEntryMapping = NULL; + + m_bByteSwapped = false; + + m_pFilenames = NULL; + m_hZip = NULL; + + m_pRead = NULL; + m_hUser = 0; + m_nMonitorLevel = 0; +} + +CXZip::CXZip( const char* filename ) +{ + // Ensure that the header doesn't contain a valid magic yet. + m_Header.Magic = 0; + m_nPreloadStart = 0; + m_pPreloadedData = NULL; + m_pDirectory = NULL; + m_pPreloadDirectory = NULL; + m_nRegular2PreloadEntryMapping = NULL; + + m_bByteSwapped = false; + + m_pFilenames = NULL; + m_hZip = NULL; + + m_pRead = NULL; + m_hUser = 0; + m_nMonitorLevel = 0; + + Load( filename ); +} + +CXZip::CXZip( FILE* handle, int offset, int size ) // file handle and offset of the zip file +{ + m_pRead = NULL; + m_hUser = 0; + m_nPreloadStart = 0; + m_pDirectory = NULL; + m_pPreloadDirectory = NULL; + m_nRegular2PreloadEntryMapping = NULL; + + m_bByteSwapped = false; + + m_pFilenames = NULL; + m_pPreloadedData = NULL; + m_nMonitorLevel = 0; + + Load( handle, offset, size ); +} + +CXZip::~CXZip() +{ + Unload(); +} + +bool CXZip::InstallAlternateIO( int (*read)( void* buffer, int offset, int length, int nDestLength, int hUser), int hUser ) +{ + m_pRead = read; + m_hUser = hUser; + return true; +} + + +// Loads an xZip file into memory: +bool CXZip::Load( const char* filename, bool bPreload ) +{ + FILE* hZip = fopen( filename, "rb" ); + fseek(hZip,0,SEEK_END); + int nSize = ftell( hZip ); + return Load( hZip, 0, nSize, bPreload ); +} + +bool CXZip::Load( FILE* handle, int nOffset, int nSize, bool bPreload ) // Load a pack file into this instance. Returns true on success. +{ + Unload(); + + m_bByteSwapped = false; + + m_hZip = handle; + m_nOffset = nOffset; + m_nSize = nSize; + + // Hacky, clean up: + if( m_hZip && !m_pRead ) + { + InstallAlternateIO( defaultRead, (int)m_hZip ); + } + + if( m_hZip == NULL && m_pRead == NULL ) + { + return false; + } + + // Read the header: + m_pRead( &m_Header, 0, -1, sizeof(m_Header), m_hUser ); + + // Validate the Magic number and at the same time determine if I am reading a regular or swappped xZip file: + switch( m_Swap.SourceIsNativeEndian( m_Header.Magic, xZipHeader_t::MAGIC ) ) + { + // Does the magic match exactly? + case 1: + m_Swap.ActivateByteSwapping( false ); + m_bByteSwapped = false; + break; + + // Does the magic match, but is swapped? + case 0: + m_bByteSwapped = true; + m_Swap.ActivateByteSwapping( true ); // We must be reading the opposite endianness. + m_Swap.SwapFieldsToTargetEndian( &m_Header ); + break; + + default: + assert( 0 ); + // Fail gently in release: + + // The magic doesn't match in any respect: + case -1: + { + printf("Invalid xZip file\n"); + + if( m_hZip ) + { + fclose( m_hZip ); + m_hZip = NULL; + } + return false; + } + } + + // Validate the archive version: + if( m_Header.Version != xZipHeader_t::VERSION ) + { + // Backward compatable support for version 1 + Msg("Incorrect xZip version found %u - expected %u\n", m_Header.Version, xZipHeader_t::VERSION ); + if( m_hZip ) + { + fclose( m_hZip ); + m_hZip = NULL; + } + + m_Header.Magic = xZipHeader_t::FREE; + return false; + } + + // Read the directory: + { + MEM_ALLOC_CREDIT(); + + m_pDirectory = (xZipDirectoryEntry_t*)malloc( sizeof(xZipDirectoryEntry_t) * m_Header.DirectoryEntries ); + m_pRead( m_pDirectory, m_Header.HeaderLength, -1, sizeof( xZipDirectoryEntry_t ) * m_Header.DirectoryEntries, m_hUser ); + + // Swap the directory entries if nessecary + if( m_bByteSwapped ) + { + for( unsigned nDirectoryEntry = 0; nDirectoryEntry < m_Header.DirectoryEntries; nDirectoryEntry++ ) + { + m_Swap.SwapFieldsToTargetEndian( &( m_pDirectory[nDirectoryEntry] ) ); + } + } + + + m_nPreloadStart = m_Header.HeaderLength + ( sizeof( xZipDirectoryEntry_t ) * m_Header.DirectoryEntries ); + } + + // Preload the preload chunk if desired: + if( bPreload ) + { + PreloadData(); + } + + return true; +} + +void CXZip::Unload() +{ + DiscardPreloadedData(); + + // Dump the directory: + if( m_pDirectory ) + { + free( m_pDirectory ); + m_pDirectory = NULL; + } + + if( m_pFilenames ) + { + free( m_pFilenames ); + m_pFilenames = NULL; + } + + // Invalidate the header: + m_Header.Magic = 0; + + if( m_hZip ) + { + fclose( m_hZip ); + m_hZip = NULL; + } + +} + +//----------------------------------------------------------------------------- +// CXZip::PreloadData +// +// Loads the preloaded data if it isn't already. +//----------------------------------------------------------------------------- + +void CXZip::PreloadData() +{ + Assert( IsValid() ); + + // Ensure it isn't already preloaded + if( m_pPreloadedData ) + return; + + // If I don't have a preloaded section, ignore the request. + if( !m_Header.PreloadBytes || !m_Header.PreloadDirectoryEntries ) + return; + + // Allocate and read the data block in: +#ifndef _X360 + MEM_ALLOC_CREDIT_( "xZip" ); + m_pPreloadedData = malloc( m_Header.PreloadBytes ); + + // Just drop out if allocation fails; + if ( !m_pPreloadedData ) + return; + + m_pRead( m_pPreloadedData, m_nPreloadStart, -1, m_Header.PreloadBytes, m_hUser ); +#else + int nAlignedStart = AlignValue( ( m_nPreloadStart - XBOX_HDD_SECTORSIZE ) + 1, XBOX_HDD_SECTORSIZE ); + int nBytesToRead = AlignValue( ( m_nPreloadStart - nAlignedStart ) + m_Header.PreloadBytes, XBOX_HDD_SECTORSIZE ); + int nBytesBuffer = AlignValue( nBytesToRead, XBOX_HDD_SECTORSIZE ); + byte *pReadData = (byte *)malloc( nBytesBuffer ); + + // Just drop out if allocation fails; + if ( !pReadData ) + return; + + MEM_ALLOC_CREDIT_( "xZip" ); + m_pRead( pReadData, nAlignedStart, nBytesBuffer,nBytesToRead, m_hUser ); + m_pPreloadedData = pReadData + ( m_nPreloadStart - nAlignedStart ); +#endif + + // Set up the preload directory: + m_pPreloadDirectory = (xZipDirectoryEntry_t*)m_pPreloadedData; + + // Swap the preload directory: + if ( m_bByteSwapped ) + { + for ( unsigned nDirectoryEntry = 0; nDirectoryEntry < m_Header.PreloadDirectoryEntries; nDirectoryEntry++ ) + { + m_Swap.SwapFieldsToTargetEndian( &( m_pPreloadDirectory[nDirectoryEntry] ) ); + } + } + + // Set up the regular 2 preload mapping section: + m_nRegular2PreloadEntryMapping = (unsigned short*)(((unsigned char*)m_pPreloadDirectory) + ( sizeof(xZipDirectoryEntry_t) * m_Header.PreloadDirectoryEntries )); + + // Swap the regular to preload mapping + if ( m_bByteSwapped ) + { + m_Swap.SwapBufferToTargetEndian( (short *)m_nRegular2PreloadEntryMapping, (short *)m_nRegular2PreloadEntryMapping, m_Header.DirectoryEntries ); + } + +} + +//----------------------------------------------------------------------------- +// CXZip::DiscardPreloadedData +// +// frees the preloaded data cache if it's present. +//----------------------------------------------------------------------------- + +void CXZip::DiscardPreloadedData() +{ + if ( m_pPreloadedData ) + { +#ifndef _X360 + free( m_pPreloadedData ); +#else + int nAlignedStart = AlignValue( ( m_nPreloadStart - XBOX_HDD_SECTORSIZE ) + 1, XBOX_HDD_SECTORSIZE ); + byte *pReadData = (byte *)m_pPreloadedData - ( m_nPreloadStart - nAlignedStart ); + free( pReadData ); +#endif + m_pPreloadedData = NULL; + m_pPreloadDirectory = NULL; + m_nRegular2PreloadEntryMapping = NULL; + } +} + +int CXZip::defaultRead( void* buffer, int offset, int destLength, int length, int hUser) +{ + fseek( (FILE*)hUser, offset, SEEK_SET ); + return fread( buffer, 1, length, (FILE*)hUser ); +} + +char* CXZip::GetEntryFileName( unsigned CRC, char* pDefault ) +{ + Assert( IsValid() ); + + if( IsRetail() ) + { + return pDefault; + } + else + { + + // Make sure I have a filename section: + if( m_Header.FilenameStringsOffset == 0 || m_Header.FilenameEntries == 0 || CRC == 0 ) + { + return pDefault; + } + + // If the filename chunk isn't here, load it up: + if( !m_pFilenames ) + { + MEM_ALLOC_CREDIT_("xZip"); + m_pFilenames = (xZipFilenameEntry_t*)malloc( m_Header.FilenameStringsLength ); + m_pRead( m_pFilenames, m_Header.FilenameStringsOffset, -1, m_Header.FilenameStringsLength, m_hUser ); + + // TODO: Swap! + for( unsigned int i=0; i< m_Header.FilenameEntries;i++ ) + { + m_Swap.SwapFieldsToTargetEndian(&m_pFilenames[i]); + } + } + + // Find this entry in the preload directory + xZipFilenameEntry_t entry; + entry.FilenameCRC = CRC; + + xZipFilenameEntry_t* found = (xZipFilenameEntry_t*)bsearch( &entry, m_pFilenames, m_Header.FilenameEntries, sizeof(xZipFilenameEntry_t), xZipFilenameEntry_t::xZipFilenameEntryCompare ); + + if( !found ) + return pDefault; + + return (((char*)m_pFilenames) + found->FilenameOffset) - m_Header.FilenameStringsOffset; + } +} + +// Sanity checks that the zip file is ready and readable: +bool CXZip::IsValid() +{ + if( m_Header.Magic != xZipHeader_t::MAGIC ) + return false; + + if( m_Header.Version > xZipHeader_t::VERSION ) + return false; + + if( !m_pDirectory ) + return false; + + return true; +} + +void CXZip::WarningDir() +{ + Assert( IsValid()); + + for( unsigned i = 0; i< m_Header.DirectoryEntries; i++ ) + { + Msg( GetEntryFileName( m_pDirectory[i].FilenameCRC ) ); + } +} + + +int CXZip::ReadIndex( int nEntryIndex, int nFileOffset, int nDestBytes, int nLength, void* pBuffer ) +{ + Assert( IsValid() ); + + if( nLength <=0 || nEntryIndex < 0 ) + return 0; + + // HACK HACK HACK - convert the pack file index to a local file index (ie, assuming the full file index is being passed in) + nFileOffset -= m_pDirectory[nEntryIndex].StoredOffset; + // HACK HACK HACK + + // If I've got my preload section loaded, first check there: + xZipDirectoryEntry_t* pPreloadEntry = GetPreloadEntry(nEntryIndex); + + if( pPreloadEntry ) + { + Assert( pPreloadEntry->FilenameCRC == m_pDirectory[nEntryIndex].FilenameCRC ); + + if( nFileOffset + nLength <= (int)pPreloadEntry->Length ) + { + if( m_nMonitorLevel >= 2 ) + { + char* filename = GetEntryFileName( m_pDirectory[nEntryIndex].FilenameCRC, "(!!! unknown !!!)" ); + + Msg("PACK(preload) %s: length:%i offset:%i",filename,nLength, nFileOffset); + + } + + memcpy( pBuffer, (char*)m_pPreloadedData + pPreloadEntry->StoredOffset + nFileOffset - m_nPreloadStart, nLength ); + return nLength; + } + } + + // Offset int the zip to start the read: + int ZipOffset = m_pDirectory[nEntryIndex].StoredOffset + nFileOffset; + int nBytesRead = m_pRead( pBuffer, ZipOffset, nDestBytes, nLength, m_hUser); + + if( m_nMonitorLevel ) + { + char* filename = GetEntryFileName( m_pDirectory[nEntryIndex].FilenameCRC, "(!!! unknown !!!)" ); + + unsigned preload = 0; + if( m_pPreloadedData && m_nRegular2PreloadEntryMapping[nEntryIndex] != 0xFFFF ) + { + // Find this entry in the preload directory + xZipDirectoryEntry_t* entry = &(m_pPreloadDirectory[m_nRegular2PreloadEntryMapping[nEntryIndex]]); + Assert(entry->FilenameCRC == m_pDirectory[nEntryIndex].FilenameCRC); + + preload = entry->Length; + } + + Msg("PACK %s: length:%i offset:%i (preload bytes:%i)",filename,nLength, nFileOffset, preload); + } + + return nBytesRead; +} + +bool CXZip::GetSimpleFileOffsetLength( const char* FileName, int& nBaseIndex, int &nFileOffset, int &nLength ) +{ + Assert( IsValid() ); + + xZipDirectoryEntry_t entry; + entry.FilenameCRC = xZipCRCFilename( FileName ); + + xZipDirectoryEntry_t* found = (xZipDirectoryEntry_t*)bsearch( &entry, m_pDirectory, m_Header.DirectoryEntries, sizeof(xZipDirectoryEntry_t), xZipDirectoryEntry_t::xZipDirectoryEntryFindCompare ); + + if( found == NULL ) + return false; + + nFileOffset = found[0].StoredOffset; + nLength = found[0].Length; + nBaseIndex = (((int)((char*)found - (char*)m_pDirectory))/sizeof(xZipDirectoryEntry_t)); + + return true; +} + +bool CXZip::ExtractFile( const char* FileName ) +{ + return false; +} + +// Compares to xZipDirectoryEntries. +// +// Sorts in the following order: +// FilenameCRC +// FileOffset +// Length +// StoredOffset +// +// The sort function may look overly complex, but it is actually useful for locating different pieces of +// the same file in a meaningful order. +// +int __cdecl xZipDirectoryEntry_t::xZipDirectoryEntrySortCompare( const void* left, const void* right ) +{ + xZipDirectoryEntry_t *l = (xZipDirectoryEntry_t*)left, + *r = (xZipDirectoryEntry_t*)right; + + if( l->FilenameCRC < r->FilenameCRC ) + { + return -1; + } + + else if( l->FilenameCRC > r->FilenameCRC ) + { + return 1; + } + + // else l->FileOffset == r->FileOffset + if( l->Length < r->Length ) + { + return -1; + } + else if( l->Length > r->Length ) + { + return 1; + } + + // else l->Length == r->Length + if( l->StoredOffset < r->StoredOffset ) + { + return -1; + } + else if( l->StoredOffset > r->StoredOffset ) + { + return 1; + } + + // else everything is identical: + return 0; + +} + +// Find an entry with matching CRC only +int __cdecl xZipDirectoryEntry_t::xZipDirectoryEntryFindCompare( const void* left, const void* right ) +{ + xZipDirectoryEntry_t *l = (xZipDirectoryEntry_t*)left, + *r = (xZipDirectoryEntry_t*)right; + + if( l->FilenameCRC < r->FilenameCRC ) + { + return -1; + } + + else if( l->FilenameCRC > r->FilenameCRC ) + { + return 1; + } + + return 0; + +} + +int __cdecl xZipFilenameEntry_t::xZipFilenameEntryCompare( const void* left, const void* right ) +{ + xZipFilenameEntry_t *l = (xZipFilenameEntry_t*)left, + *r = (xZipFilenameEntry_t*)right; + + if( l->FilenameCRC < r->FilenameCRC ) + { + return -1; + } + + else if( l->FilenameCRC > r->FilenameCRC ) + { + return 1; + } + + return 0; + +} + + +// CRC's an individual xZip filename: +unsigned xZipCRCFilename( const char* filename ) +{ + unsigned hash = 0xAAAAAAAA; // Alternating 1's and 0's + + for( ; *filename ; filename++ ) + { + char c = *filename; + + // Fix slashes + if( c == '/' ) + c = '\\'; + else + c = (char)tolower(c); + + hash = hash * 33 + c; + } + + return hash; +} + +#if defined( MAKE_GAMEDATA_TOOL ) + +// ------------ +xZipHeader_t Header; +xZipDirectoryEntry_t *pDirectoryEntries = NULL; +xZipDirectoryEntry_t *pPreloadDirectoryEntries = NULL; +xZipFilenameEntry_t *pFilenameEntries = NULL; +char *pFilenameData = NULL; +unsigned nFilenameDataLength = 0; + +unsigned InputFileBytes = 0; + +char* CleanFilename( char* filename ) +{ + // Trim leading white space: + while( isspace(*filename) ) + filename++; + + // Trim trailing white space: + while( isspace( filename[strlen(filename)-1] ) ) + { + filename[strlen(filename)-1] = '\0'; + } + + return filename; +} + + +bool CopyFileBytes( FILE* hDestination, FILE* hSource, unsigned nBytes ) +{ + char buffer[16384]; + + while( nBytes > 0 ) + { + int nBytesRead = fread( buffer, 1, nBytes > sizeof(buffer) ? sizeof(buffer) : nBytes, hSource ); + fwrite(buffer, 1, nBytesRead, hDestination ); + nBytes -= nBytesRead; + } + + return true; +} + +bool WriteFileBytes( FILE* hDestination, CUtlBuffer &source, unsigned nBytes ) +{ + unsigned int nBytesWritten = fwrite(source.Base(), 1, nBytes, hDestination ); + return (nBytesWritten == nBytes); +} + +void PadFileBytes(FILE* hFile, int nPreloadPadding ) +{ + if( nPreloadPadding < 0 || nPreloadPadding >= 512) + { + puts("Invalid padding"); + return; + } + + char padding[512]; + memset(padding,0,nPreloadPadding); + fwrite(padding,1,nPreloadPadding,hFile); +} + +void AddFilename( const char* filename ) +{ + unsigned CRCfilename = xZipCRCFilename( filename ); + + // If we already have this filename don't add it again: + for( int i = 0; i < (int)Header.FilenameEntries; i++ ) + { + if( pFilenameEntries[i].FilenameCRC == CRCfilename ) + { + return; + } + } + + Header.FilenameEntries++; + + // Add the file to the file string table: + pFilenameEntries = (xZipFilenameEntry_t*)realloc( pFilenameEntries, sizeof(xZipFilenameEntry_t) * Header.FilenameEntries ); + + int filenameLength = (int)strlen(filename) + 1; + pFilenameEntries[Header.FilenameEntries-1].FilenameCRC = CRCfilename; + pFilenameEntries[Header.FilenameEntries-1].FilenameOffset = nFilenameDataLength; + + // Grab the timestamp for the file: + struct stat buf; + if( stat( filename, &buf ) != -1 ) + { + pFilenameEntries[Header.FilenameEntries - 1].TimeStamp = buf.st_mtime; + } + else + { + pFilenameEntries[Header.FilenameEntries - 1].TimeStamp = 0; + } + + nFilenameDataLength += filenameLength; + pFilenameData = (char*)realloc(pFilenameData, nFilenameDataLength); + memcpy(pFilenameData + nFilenameDataLength - filenameLength, filename, filenameLength); +} + +FILE* hTempFilePreload; +FILE* hTempFileData; +FILE* hOutputFile; + +bool xZipAddFile( const char* filename, CUtlBuffer &fileBuff, bool bPrecacheEntireFile, bool bProcessPrecacheHeader, bool bProcessPrecacheHeaderOnly ) +{ + unsigned int fileSize = fileBuff.TellMaxPut(); + + // Track total input bytes for stats reasons + InputFileBytes += fileSize; + + unsigned customPreloadSize = 0; + + if( bPrecacheEntireFile ) + { + customPreloadSize = fileSize; + } + else if( bProcessPrecacheHeader ) + { + customPreloadSize = xZipComputeCustomPreloads( filename ); + } + else if( bProcessPrecacheHeaderOnly ) + { + customPreloadSize = xZipComputeCustomPreloads( filename ); + fileSize = min( fileSize, customPreloadSize ); + } + + unsigned CRC = xZipCRCFilename( filename ); + + // Does this file have a split header? + if( customPreloadSize > 0 ) + { + // Initialize the entry header: + xZipDirectoryEntry_t entry; + memset( &entry, 0, sizeof( entry ) ); + + entry.FilenameCRC = CRC; + entry.Length = customPreloadSize; + entry.StoredOffset = ftell(hTempFilePreload); + + // Add the directory entry to the preload table: + Header.PreloadDirectoryEntries++; + pPreloadDirectoryEntries = (xZipDirectoryEntry_t*)realloc( pPreloadDirectoryEntries, sizeof( xZipDirectoryEntry_t ) * Header.PreloadDirectoryEntries ); + memcpy( pPreloadDirectoryEntries + Header.PreloadDirectoryEntries - 1, &entry, sizeof( entry ) ); + + // Concatenate the data in the preload file: + fileBuff.SeekGet( CUtlBuffer::SEEK_HEAD, 0 ); + WriteFileBytes( hTempFilePreload, fileBuff, entry.Length ); + fileBuff.SeekGet( CUtlBuffer::SEEK_HEAD, 0 ); + + + // Add the filename entry: + AddFilename( filename ); + + // Spew it: + printf("+Preload: \"%s\": Length:%u\n", filename, entry.Length ); + } + + // Copy the file to the regular data region: + xZipDirectoryEntry_t entry; + memset(&entry,0,sizeof(entry)); + entry.FilenameCRC = CRC; + entry.Length = fileSize; + entry.StoredOffset = ftell(hTempFileData); + + // Add the directory entry to the table: + Header.DirectoryEntries++; + pDirectoryEntries = (xZipDirectoryEntry_t*)realloc( pDirectoryEntries, sizeof( xZipDirectoryEntry_t ) * Header.DirectoryEntries ); + memcpy( pDirectoryEntries + Header.DirectoryEntries - 1, &entry, sizeof( entry ) ); + + WriteFileBytes( hTempFileData, fileBuff, entry.Length ); + + // Align the data region to a 512 byte boundry: (has to be on last entry as well to ensure enough space to perform the final read, + // and initial alignment is taken careof by assembexzip) + int nPadding = ( XBOX_HDD_SECTORSIZE - ( ftell( hTempFileData ) % XBOX_HDD_SECTORSIZE) ) % XBOX_HDD_SECTORSIZE; + + PadFileBytes( hTempFileData, nPadding ); + + // Add the file to the file string table: + AddFilename( filename ); + + // Print a summary + printf("+File: \"%s\": Length:%u Padding:%i\n", filename, entry.Length, nPadding ); + + return true; +} + +bool xZipAddFile( const char* zipname, bool bPrecacheEntireFile, bool bProcessPrecacheHeader, bool bProcessPrecacheHeaderOnly ) +{ + // Clean up the filename: + char buffer[MAX_PATH]; + strcpy(buffer, zipname); + + // Fix slashes and convert it to lower case: + char *filename; + for( filename = buffer; *filename; filename++ ) + { + if( *filename == '/' ) + *filename = '\\'; + else + { + *filename = (char)tolower(*filename); + } + } + + // Skip leading white space: + for( filename = buffer; isspace(*filename); filename++ ) + ; + + // Obliterate trailing white space: + for(;;) + { + int len = (int)strlen( filename ); + if( len <= 0 ) + { + printf("!!!! BAD FILENAME: \"%s\"\n", filename ); + return false; + } + + if( isspace( filename[len-1] ) ) + filename[len-1]='\0'; + else + break; + } + + // Ensure we don't already have this file: + unsigned CRC = xZipCRCFilename( filename ); + + for( unsigned i=0; i < Header.DirectoryEntries; i++ ) + { + if( pDirectoryEntries[i].FilenameCRC == CRC ) + { + printf("!!!! NOT ADDING DUPLICATE FILENAME: \"%s\"\n", filename ); + return false; + } + } + + // Attempt to open the file: + FILE* hFile = fopen( filename, "rb" ); + if( !hFile ) + { + printf("!!!! FAILED TO OPEN FILE: \"%s\"\n", filename ); + return false; + } + + // Get the length of the file: + fseek(hFile,0,SEEK_END); + unsigned fileSize = ftell(hFile); + fseek(hFile,0,SEEK_SET); + + CUtlBuffer fileBuff; + fileBuff.EnsureCapacity( fileSize ); + fread( fileBuff.Base(), fileSize, 1, hFile ); + fclose( hFile ); + + fileBuff.SeekPut( CUtlBuffer::SEEK_HEAD, fileSize ); + + return xZipAddFile( zipname, fileBuff, bPrecacheEntireFile, bProcessPrecacheHeader, bProcessPrecacheHeaderOnly ); +} + +int xZipBegin( const char* fileNameXzip ) +{ + // Create and initialize the header: + memset( &Header, 0, sizeof(Header) ); // Zero out the header: + Header.Magic = xZipHeader_t::MAGIC; + Header.Version = xZipHeader_t::VERSION; + Header.HeaderLength = sizeof(Header); + + // Open the output file: + hOutputFile = fopen(fileNameXzip,"wb+"); + if( !hOutputFile ) + { + printf("Failed to open \"%s\" for writing.\n", fileNameXzip); + exit( EXIT_FAILURE); + } + + // Create a temporary file for storing the preloaded data: + hTempFilePreload = tmpfile(); + if( !hTempFilePreload ) + { + printf( "Error: failed to create temporary file\n" ); + return EXIT_FAILURE; + } + + // Create a temporary file for storing the non preloaded data + hTempFileData = tmpfile(); + if( !hTempFileData ) + { + printf( "Error: failed to create temporary file\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +bool xZipEnd() +{ + int nPreloadDirectorySize = sizeof(xZipDirectoryEntry_t)*Header.PreloadDirectoryEntries; + int nRegular2PreloadSize = sizeof(unsigned short) * Header.DirectoryEntries; + + // Compute the size of the preloaded section: + if( Header.PreloadDirectoryEntries ) + { + fseek( hTempFilePreload, 0, SEEK_END ); + Header.PreloadBytes = ftell(hTempFilePreload) + nPreloadDirectorySize + nRegular2PreloadSize; // Raw# of bytes to preload + fseek( hTempFilePreload, 0, SEEK_SET ); + } + else + { + Header.PreloadBytes = 0; + } + + // Number of bytes preceeding the preloaded section: + int nPreloadOffset = sizeof( Header ) + ( sizeof( xZipDirectoryEntry_t ) * Header.DirectoryEntries ); + + // Number of bytes to pad between the end of the preload section and the start of the data section: + int nPadding = ( 512 - ( ( nPreloadOffset + Header.PreloadBytes ) % 512) ) %512; // Number of alignment bytes after the preload section + + // Offset past the preload section: + int nDataOffset = nPreloadOffset + Header.PreloadBytes + nPadding; + + // Write out the header: (will need to be rewritten at the end as well) - note: not even bothering to byteswap at this point + fwrite(&Header,sizeof(Header),1,hOutputFile); + + + // Fixup each of the directory entries to make them relative to the beginning of the file. + for( unsigned i=0; i< Header.DirectoryEntries;i++ ) + { + xZipDirectoryEntry_t* pDir = &(pDirectoryEntries[i]); + + // Adjust files in the regular data area: + pDir->StoredOffset = nDataOffset + pDir->StoredOffset; + } + + // Sort and write the directory: + printf("Sorting and writing %i directory entries...\n",Header.DirectoryEntries); + qsort(pDirectoryEntries,Header.DirectoryEntries,sizeof(xZipDirectoryEntry_t),&xZipDirectoryEntry_t::xZipDirectoryEntrySortCompare); + + // Swap the directory entries: + for( unsigned i=0; i < Header.DirectoryEntries; i++ ) + { + g_xzpSwap.SwapFieldsToTargetEndian(&pDirectoryEntries[i]); + } + + fwrite(pDirectoryEntries,Header.DirectoryEntries*sizeof(xZipDirectoryEntry_t),1, hOutputFile); + + // Swap the directory back for later use: + for( unsigned i=0; i < Header.DirectoryEntries; i++ ) + { + g_xzpSwap.SwapFieldsToTargetEndian(&pDirectoryEntries[i]); + } + + // Copy the preload section: + if( Header.PreloadBytes > 0 ) + { + printf("Generating the preload section...(%u)\n", Header.PreloadBytes); + + + // Fixup each of the directory entries to make them relative to the beginning of the file. + for( unsigned i=0; i< Header.PreloadDirectoryEntries;i++ ) + { + xZipDirectoryEntry_t* pDir = &(pPreloadDirectoryEntries[i]); + + // Shift preload data down by preload bytes (and skipping over the directory): + pDir->StoredOffset += nPreloadOffset + nPreloadDirectorySize + nRegular2PreloadSize; + } + + printf("Sorting %u preload directory entries...\n",Header.PreloadDirectoryEntries); + qsort(pPreloadDirectoryEntries,Header.PreloadDirectoryEntries,sizeof(xZipDirectoryEntry_t),&xZipDirectoryEntry_t::xZipDirectoryEntrySortCompare); + + printf("Building regular to preload mapping table for %u entries...\n", Header.DirectoryEntries ); + unsigned short* Regular2Preload = (unsigned short*)malloc( nRegular2PreloadSize ); + for( unsigned i = 0; i < Header.DirectoryEntries; i++ ) + { + unsigned short j; + for( j = 0; j < Header.PreloadDirectoryEntries; j++ ) + { + if( pDirectoryEntries[i].FilenameCRC == pPreloadDirectoryEntries[j].FilenameCRC ) + break; + } + + // If I couldn't find it mark it as non-existant: + if( j == Header.PreloadDirectoryEntries ) + j = 0xFFFF; + + Regular2Preload[i] = j; + } + + printf("Writing preloaded directory entreis...\n" ); + + // Swap the preload directory entries: + for( unsigned i=0; i < Header.PreloadDirectoryEntries; i++ ) + { + g_xzpSwap.SwapFieldsToTargetEndian(&pPreloadDirectoryEntries[i]); + } + + fwrite( pPreloadDirectoryEntries, Header.PreloadDirectoryEntries*sizeof(xZipDirectoryEntry_t),1, hOutputFile ); + + // Swap them back: + for( unsigned i=0; i < Header.PreloadDirectoryEntries; i++ ) + { + g_xzpSwap.SwapFieldsToTargetEndian(&pPreloadDirectoryEntries[i]); + } + + printf("Writing regular to preload mapping (%u bytes)...\n", sizeof(unsigned short)*Header.DirectoryEntries ); + + // Swap regular to preload mapping: + g_xzpSwap.SwapBufferToTargetEndian((short*)Regular2Preload, (short*)Regular2Preload, nRegular2PreloadSize / sizeof(short) ); + + fwrite( Regular2Preload, nRegular2PreloadSize,1,hOutputFile ); + + // Swap it back + g_xzpSwap.SwapBufferToTargetEndian((short*)Regular2Preload, (short*)Regular2Preload, nRegular2PreloadSize / sizeof(short) ); + + printf("Copying %u Preloadable Bytes...\n", Header.PreloadBytes - nPreloadDirectorySize - nRegular2PreloadSize ); + fseek(hTempFilePreload,0,SEEK_SET); + CopyFileBytes(hOutputFile, hTempFilePreload, Header.PreloadBytes - nPreloadDirectorySize - nRegular2PreloadSize ); + } + + // Align the data section following the preload section: + if( nPadding ) + { + printf("Aligning Data Section Start by %u bytes...\n", nPadding ); + PadFileBytes(hOutputFile, nPadding ); + } + + // Copy the data section: + fseek(hTempFileData, 0, SEEK_END ); + unsigned length = ftell( hTempFileData ); + fseek(hTempFileData, 0, SEEK_SET ); + printf("Copying %u Bytes...\n",length); + + CopyFileBytes(hOutputFile, hTempFileData, length); + + // Write out the filename data if present: + if( nFilenameDataLength && Header.FilenameEntries ) + { + Header.FilenameStringsOffset = ftell(hOutputFile); + Header.FilenameStringsLength = (Header.FilenameEntries*sizeof(xZipFilenameEntry_t)) + nFilenameDataLength; + + // Adjust the offset in each of the filename offsets to absolute position in the file. + for( unsigned i=0;i(&pFilenameEntries[i]); + } + + fwrite(pFilenameEntries,1,Header.FilenameEntries*sizeof(xZipFilenameEntry_t),hOutputFile); + + // Swap them back: + for( unsigned int i = 0; i < Header.FilenameEntries; i++ ) + { + g_xzpSwap.SwapFieldsToTargetEndian(&pFilenameEntries[i]); + } + + printf("Writing %u bytes of filename data...\n",nFilenameDataLength); + fwrite(pFilenameData,1,nFilenameDataLength,hOutputFile); + } + + // Compute the total file size, including the size of the footer: + unsigned OutputFileBytes = ftell(hOutputFile) + sizeof(xZipFooter_t); + + // Write the footer: (block used to keep possibly swapped footer from being used later) + { + xZipFooter_t footer; + footer.Magic = xZipFooter_t::MAGIC; + footer.Size = OutputFileBytes; + + g_xzpSwap.SwapFieldsToTargetEndian( &footer ); // Swap the footer + fwrite( &footer, 1, sizeof(footer), hOutputFile ); + } + + // Seek back and rewrite the header (filename data changes it for example) + fseek(hOutputFile,0,SEEK_SET); + g_xzpSwap.SwapFieldsToTargetEndian( &Header ); // Swap it to write out: + fwrite(&Header,1,sizeof(Header),hOutputFile); + g_xzpSwap.SwapFieldsToTargetEndian( &Header ); // But then swap it back so we can use it in memory + + // Shut down + fclose(hOutputFile); + + // Print the summary + printf("\n\nSummary: Input:%u, XZip:%u, Directory Entries:%u (%u preloaded), Preloaded Bytes:%u\n\n",InputFileBytes,OutputFileBytes,Header.DirectoryEntries, Header.PreloadDirectoryEntries, Header.PreloadBytes); + + // Shut down: + fclose(hTempFileData); + fclose(hTempFilePreload); + + return true; +} + +#define PADD_ID MAKEID('P','A','D','D') + +//----------------------------------------------------------------------------- +// xZipComputeWAVPreload +// +// Returns the number of bytes from a xbox compliant WAV file that should go into +// the preload section: +//----------------------------------------------------------------------------- +unsigned xZipComputeWAVPreload( char *pFileName ) +{ + InFileRIFF riff( pFileName, *g_pSndIO ); + if ( riff.RIFFName() != RIFF_WAVE ) + { + return 0; + } + + IterateRIFF walk( riff, riff.RIFFSize() ); + + while ( walk.ChunkAvailable() ) + { + // xbox compliant wavs have a single PADD chunk + if ( walk.ChunkName() == PADD_ID ) + { + // want to preload data up through PADD chunk header + // and not the actual pad bytes + return walk.ChunkFilePosition() + 2*sizeof( int ); + } + walk.ChunkNext(); + } + + return 0; +} + + +//----------------------------------------------------------------------------- +// xZipComputeXWVPreload +// +// Returns the number of bytes from a XWV file that should go into the preload +// section: +//----------------------------------------------------------------------------- +unsigned xZipComputeXWVPreload( const char* filename ) +{ + FILE* hFile = fopen( filename, "rb" ); + if ( !hFile ) + { + printf( "Failed to open xwv file: %s\n", filename ); + return 0; + } + + // Read and validate the XWV header: + xwvHeader_t header; + memset( &header, 0, sizeof(header) ); + fread( &header, 1, sizeof(header), hFile ); + fclose( hFile ); + + if ( header.id != XWV_ID || header.headerSize != sizeof(header) ) + return 0; + + return header.GetPreloadSize(); +} + +unsigned xZipComputeXTFPreload( const char* filename ) +{ +#if 0 // X360TBD: Not using XTF anymore + FILE* hFile = fopen( filename, "rb" ); + if ( !hFile ) + { + printf("Failed to open file: %s\n", filename); + return 0; + } + + XTFFileHeader_t header; + memset( &header,0, sizeof( header ) ); + fread( &header,1,sizeof(header),hFile); + + fclose(hFile); + + if ( !strncmp( header.fileTypeString, "XTF", 4 ) ) + return header.preloadDataSize; +#endif + return 0; +} + +// TODO: ONLY store them in the preload section: +unsigned xZipComputeVMTPreload( const char* filename ) +{ + // Store VMT's entirely + if ( !strstr(filename,".vmt") ) + return 0; + + FILE* hFile = fopen( filename, "rb" ); + if ( !hFile ) + { + printf("Failed to open file: %s\n", filename); + return 0; + } + + fseek( hFile, 0, SEEK_END ); + unsigned offset = ftell( hFile ); + fclose( hFile ); + return offset; +} + +// TODO: ONLY store them in the preload section: +unsigned xZipComputeVHVPreload( const char* filename ) +{ + // Store VMT's entirely + if ( !strstr(filename,".vhv") ) + return 0; + + FILE* hFile = fopen( filename, "rb" ); + if ( !hFile ) + { + printf("Failed to open file: %s\n", filename); + return 0; + } + + fclose( hFile ); + + // Just load the header: + return sizeof(HardwareVerts::FileHeader_t); +} + +unsigned xZipComputeXCSPreload( const char* filename ) +{ + if( !strstr(filename,".vcs") ) + return 0; + + FILE* hFile = fopen( filename, "rb" ); + if ( !hFile ) + { + printf("Failed to open file: %s\n", filename); + return 0; + } + + XShaderHeader_t header; + fread(&header,1,sizeof(XShaderHeader_t), hFile); + fseek(hFile,0,SEEK_END); + fclose(hFile); + + if (!header.IsValid()) + return 0; + + return header.BytesToPreload(); +} + +unsigned xZipComputeCustomPreloads( const char* filename ) +{ + // X360TBD: These all need to act on a utlbuffer + Assert( 0 ); + return 0; + +// strlwr(filename); + + unsigned offset = xZipComputeXWVPreload( filename ); + if ( offset ) + return offset; + + offset = xZipComputeVMTPreload( filename ); + if ( offset ) + return offset; + + offset = xZipComputeXCSPreload( filename ); + if ( offset ) + return offset; + + offset = xZipComputeVHVPreload( filename ); + if ( offset ) + return offset; + + return xZipComputeXTFPreload( filename ); +} + +#endif // MAKE_GAMEDATA_TOOL diff --git a/sp/src/public/zip_uncompressed.h b/sp/src/public/zip_uncompressed.h new file mode 100644 index 00000000..0c8a45e6 --- /dev/null +++ b/sp/src/public/zip_uncompressed.h @@ -0,0 +1,113 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef ZIP_UNCOMPRESSED_H +#define ZIP_UNCOMPRESSED_H +#ifdef _WIN32 +#pragma once +#endif + +#include "datamap.h" + +#define PKID( a, b ) (((b)<<24)|((a)<<16)|('K'<<8)|'P') + +#pragma pack(1) + +struct ZIP_EndOfCentralDirRecord +{ + DECLARE_BYTESWAP_DATADESC(); + unsigned int signature; // 4 bytes PK56 + unsigned short numberOfThisDisk; // 2 bytes + unsigned short numberOfTheDiskWithStartOfCentralDirectory; // 2 bytes + unsigned short nCentralDirectoryEntries_ThisDisk; // 2 bytes + unsigned short nCentralDirectoryEntries_Total; // 2 bytes + unsigned int centralDirectorySize; // 4 bytes + unsigned int startOfCentralDirOffset; // 4 bytes + unsigned short commentLength; // 2 bytes + // zip file comment follows +}; + +struct ZIP_FileHeader +{ + DECLARE_BYTESWAP_DATADESC(); + unsigned int signature; // 4 bytes PK12 + unsigned short versionMadeBy; // version made by 2 bytes + unsigned short versionNeededToExtract; // version needed to extract 2 bytes + unsigned short flags; // general purpose bit flag 2 bytes + unsigned short compressionMethod; // compression method 2 bytes + unsigned short lastModifiedTime; // last mod file time 2 bytes + unsigned short lastModifiedDate; // last mod file date 2 bytes + unsigned int crc32; // crc-32 4 bytes + unsigned int compressedSize; // compressed size 4 bytes + unsigned int uncompressedSize; // uncompressed size 4 bytes + unsigned short fileNameLength; // file name length 2 bytes + unsigned short extraFieldLength; // extra field length 2 bytes + unsigned short fileCommentLength; // file comment length 2 bytes + unsigned short diskNumberStart; // disk number start 2 bytes + unsigned short internalFileAttribs; // internal file attributes 2 bytes + unsigned int externalFileAttribs; // external file attributes 4 bytes + unsigned int relativeOffsetOfLocalHeader; // relative offset of local header 4 bytes + // file name (variable size) + // extra field (variable size) + // file comment (variable size) +}; + +struct ZIP_LocalFileHeader +{ + DECLARE_BYTESWAP_DATADESC(); + unsigned int signature; //local file header signature 4 bytes PK34 + unsigned short versionNeededToExtract; // version needed to extract 2 bytes + unsigned short flags; // general purpose bit flag 2 bytes + unsigned short compressionMethod; // compression method 2 bytes + unsigned short lastModifiedTime; // last mod file time 2 bytes + unsigned short lastModifiedDate; // last mod file date 2 bytes + unsigned int crc32; // crc-32 4 bytes + unsigned int compressedSize; // compressed size 4 bytes + unsigned int uncompressedSize; // uncompressed size 4 bytes + unsigned short fileNameLength; // file name length 2 bytes + unsigned short extraFieldLength; // extra field length 2 bytes + // file name (variable size) + // extra field (variable size) +}; + +//=============================================================================// +// Valve Non standard Extension, Preload Section +// An optional first file in an aligned zip that can be loaded into ram and +// used by the FileSystem to supply header data rather than disk. +// Is is an optimization to prevent the large of amount of small I/O performed +/// by the map loading process. +//=============================================================================// + +#define PRELOAD_SECTION_NAME "__preload_section.pre" +#define PRELOAD_HDR_VERSION 3 +#define XZIP_COMMENT_LENGTH 32 +#define INVALID_PRELOAD_ENTRY ( (unsigned short)-1 ) + +struct ZIP_PreloadHeader +{ + DECLARE_BYTESWAP_DATADESC(); + unsigned int Version; // VERSION + unsigned int DirectoryEntries; // Number of zip directory entries. + unsigned int PreloadDirectoryEntries; // Number of preloaded directory entries (equal or less than the zip dir). + unsigned int Alignment; // File alignment of the zip +}; + +struct ZIP_PreloadDirectoryEntry +{ + DECLARE_BYTESWAP_DATADESC(); + unsigned int Length; // Length of the file's preload data in bytes + unsigned int DataOffset; // Offset the file data in the .zip, relative to the logical beginning of the preload file. +}; + +struct ZIP_PreloadRemapTable +{ + DECLARE_BYTESWAP_DATADESC(); + unsigned short PreloadIndex; // Index into preload directory, entry marked invalid if no preload entry present +}; + +#pragma pack() + +#endif // ZIP_UNCOMPRESSED_H diff --git a/sp/src/public/zip_utils.cpp b/sp/src/public/zip_utils.cpp new file mode 100644 index 00000000..b205aa90 --- /dev/null +++ b/sp/src/public/zip_utils.cpp @@ -0,0 +1,1718 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +// If we are going to include windows.h then we need to disable protected_things.h +// or else we get many warnings. +#undef PROTECTED_THINGS_ENABLE +#include +#ifdef IS_WINDOWS_PC +#include +#else +#define INVALID_HANDLE_VALUE (void *)0 +#define FILE_BEGIN SEEK_SET +#define FILE_END SEEK_END +#endif +#include "utlbuffer.h" +#include "utllinkedlist.h" +#include "zip_utils.h" +#include "zip_uncompressed.h" +#include "checksum_crc.h" +#include "byteswap.h" +#include "utlstring.h" + +// Data descriptions for byte swapping - only needed +// for structures that are written to file for use by the game. +BEGIN_BYTESWAP_DATADESC( ZIP_EndOfCentralDirRecord ) + DEFINE_FIELD( signature, FIELD_INTEGER ), + DEFINE_FIELD( numberOfThisDisk, FIELD_SHORT ), + DEFINE_FIELD( numberOfTheDiskWithStartOfCentralDirectory, FIELD_SHORT ), + DEFINE_FIELD( nCentralDirectoryEntries_ThisDisk, FIELD_SHORT ), + DEFINE_FIELD( nCentralDirectoryEntries_Total, FIELD_SHORT ), + DEFINE_FIELD( centralDirectorySize, FIELD_INTEGER ), + DEFINE_FIELD( startOfCentralDirOffset, FIELD_INTEGER ), + DEFINE_FIELD( commentLength, FIELD_SHORT ), +END_BYTESWAP_DATADESC() + +BEGIN_BYTESWAP_DATADESC( ZIP_FileHeader ) + DEFINE_FIELD( signature, FIELD_INTEGER ), + DEFINE_FIELD( versionMadeBy, FIELD_SHORT ), + DEFINE_FIELD( versionNeededToExtract, FIELD_SHORT ), + DEFINE_FIELD( flags, FIELD_SHORT ), + DEFINE_FIELD( compressionMethod, FIELD_SHORT ), + DEFINE_FIELD( lastModifiedTime, FIELD_SHORT ), + DEFINE_FIELD( lastModifiedDate, FIELD_SHORT ), + DEFINE_FIELD( crc32, FIELD_INTEGER ), + DEFINE_FIELD( compressedSize, FIELD_INTEGER ), + DEFINE_FIELD( uncompressedSize, FIELD_INTEGER ), + DEFINE_FIELD( fileNameLength, FIELD_SHORT ), + DEFINE_FIELD( extraFieldLength, FIELD_SHORT ), + DEFINE_FIELD( fileCommentLength, FIELD_SHORT ), + DEFINE_FIELD( diskNumberStart, FIELD_SHORT ), + DEFINE_FIELD( internalFileAttribs, FIELD_SHORT ), + DEFINE_FIELD( externalFileAttribs, FIELD_INTEGER ), + DEFINE_FIELD( relativeOffsetOfLocalHeader, FIELD_INTEGER ), +END_BYTESWAP_DATADESC() + +BEGIN_BYTESWAP_DATADESC( ZIP_LocalFileHeader ) + DEFINE_FIELD( signature, FIELD_INTEGER ), + DEFINE_FIELD( versionNeededToExtract, FIELD_SHORT ), + DEFINE_FIELD( flags, FIELD_SHORT ), + DEFINE_FIELD( compressionMethod, FIELD_SHORT ), + DEFINE_FIELD( lastModifiedTime, FIELD_SHORT ), + DEFINE_FIELD( lastModifiedDate, FIELD_SHORT ), + DEFINE_FIELD( crc32, FIELD_INTEGER ), + DEFINE_FIELD( compressedSize, FIELD_INTEGER ), + DEFINE_FIELD( uncompressedSize, FIELD_INTEGER ), + DEFINE_FIELD( fileNameLength, FIELD_SHORT ), + DEFINE_FIELD( extraFieldLength, FIELD_SHORT ), +END_BYTESWAP_DATADESC() + +BEGIN_BYTESWAP_DATADESC( ZIP_PreloadHeader ) + DEFINE_FIELD( Version, FIELD_INTEGER ), + DEFINE_FIELD( DirectoryEntries, FIELD_INTEGER ), + DEFINE_FIELD( PreloadDirectoryEntries, FIELD_INTEGER ), + DEFINE_FIELD( Alignment, FIELD_INTEGER ), +END_BYTESWAP_DATADESC() + +BEGIN_BYTESWAP_DATADESC( ZIP_PreloadDirectoryEntry ) + DEFINE_FIELD( Length, FIELD_INTEGER ), + DEFINE_FIELD( DataOffset, FIELD_INTEGER ), +END_BYTESWAP_DATADESC() + +#ifdef WIN32 +//----------------------------------------------------------------------------- +// For >2 GB File Support +//----------------------------------------------------------------------------- +class CWin32File +{ +public: + static HANDLE CreateTempFile( CUtlString &WritePath, CUtlString &FileName ) + { + char tempFileName[MAX_PATH]; + if ( WritePath.IsEmpty() ) + { + // use a safe name in the cwd + char *pBuffer = tmpnam( NULL ); + if ( !pBuffer ) + { + return INVALID_HANDLE_VALUE; + } + if ( pBuffer[0] == '\\' ) + { + pBuffer++; + } + if ( pBuffer[strlen( pBuffer )-1] == '.' ) + { + pBuffer[strlen( pBuffer )-1] = '\0'; + } + V_snprintf( tempFileName, sizeof( tempFileName ), "_%s.tmp", pBuffer ); + } + else + { + // generate safe name at the desired prefix + char uniqueFilename[MAX_PATH]; + SYSTEMTIME sysTime; \ + GetLocalTime( &sysTime ); + sprintf( uniqueFilename, "%d_%d_%d_%d_%d.tmp", sysTime.wDay, sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds ); \ + V_ComposeFileName( WritePath.String(), uniqueFilename, tempFileName, sizeof( tempFileName ) ); + } + + FileName = tempFileName; + HANDLE hFile = CreateFile( tempFileName, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); + + return hFile; + } + + static unsigned int FileSeek( HANDLE hFile, unsigned int distance, DWORD MoveMethod ) + { + LARGE_INTEGER li; + + li.QuadPart = distance; + li.LowPart = SetFilePointer( hFile, li.LowPart, &li.HighPart, MoveMethod); + if ( li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR ) + { + li.QuadPart = -1; + } + + return ( unsigned int )li.QuadPart; + } + + static unsigned int FileTell( HANDLE hFile ) + { + return FileSeek( hFile, 0, FILE_CURRENT ); + } + + static bool FileRead( HANDLE hFile, void *pBuffer, unsigned int size ) + { + DWORD numBytesRead; + BOOL bSuccess = ::ReadFile( hFile, pBuffer, size, &numBytesRead, NULL ); + return bSuccess && ( numBytesRead == size ); + } + + static bool FileWrite( HANDLE hFile, void *pBuffer, unsigned int size ) + { + DWORD numBytesWritten; + BOOL bSuccess = WriteFile( hFile, pBuffer, size, &numBytesWritten, NULL ); + return bSuccess && ( numBytesWritten == size ); + } +}; +#else +class CWin32File +{ +public: + static HANDLE CreateTempFile( CUtlString &WritePath, CUtlString &FileName ) + { + char tempFileName[MAX_PATH]; + if ( WritePath.IsEmpty() ) + { + // use a safe name in the cwd + char *pBuffer = tmpnam( NULL ); + if ( !pBuffer ) + { + return INVALID_HANDLE_VALUE; + } + if ( pBuffer[0] == '\\' ) + { + pBuffer++; + } + if ( pBuffer[strlen( pBuffer )-1] == '.' ) + { + pBuffer[strlen( pBuffer )-1] = '\0'; + } + V_snprintf( tempFileName, sizeof( tempFileName ), "_%s.tmp", pBuffer ); + } + else + { + char uniqueFilename[MAX_PATH]; + static int counter = 0; + time_t now = time( NULL ); + struct tm *tm = localtime( &now ); + sprintf( uniqueFilename, "%d_%d_%d_%d_%d.tmp", tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec, ++counter ); \ + V_ComposeFileName( WritePath.String(), uniqueFilename, tempFileName, sizeof( tempFileName ) ); + } + + FileName = tempFileName; + FILE *hFile = fopen( tempFileName, "rw+" ); + + return (HANDLE)hFile; + } + + static unsigned int FileSeek( HANDLE hFile, unsigned int distance, DWORD MoveMethod ) + { + if ( fseeko( (FILE *)hFile, distance, MoveMethod ) == 0 ) + { + return FileTell( hFile ); + } + return 0; + } + + static unsigned int FileTell( HANDLE hFile ) + { + return ftello( (FILE *)hFile ); + } + + static bool FileRead( HANDLE hFile, void *pBuffer, unsigned int size ) + { + size_t bytesRead = fread( pBuffer, 1, size, (FILE *)hFile ); + return bytesRead == size; + } + + static bool FileWrite( HANDLE hFile, void *pBuffer, unsigned int size ) + { + size_t bytesWrtitten = fwrite( pBuffer, 1, size, (FILE *)hFile ); + return bytesWrtitten == size; + } +}; +#endif + +//----------------------------------------------------------------------------- +// Purpose: Interface to allow abstraction of zip file output methods, and +// avoid duplication of code. Files may be written to a CUtlBuffer or a filestream +//----------------------------------------------------------------------------- +abstract_class IWriteStream +{ +public: + virtual void Put( const void* pMem, int size ) = 0; + virtual unsigned int Tell( void ) = 0; +}; + +//----------------------------------------------------------------------------- +// Purpose: Wrapper for CUtlBuffer methods +//----------------------------------------------------------------------------- +class CBufferStream : public IWriteStream +{ +public: + CBufferStream( CUtlBuffer& buff ) : IWriteStream(), m_buff( &buff ) {} + + // Implementing IWriteStream method + virtual void Put( const void* pMem, int size ) { m_buff->Put( pMem, size ); } + + // Implementing IWriteStream method + virtual unsigned int Tell( void ) { return m_buff->TellPut(); } + +private: + CUtlBuffer *m_buff; +}; + +//----------------------------------------------------------------------------- +// Purpose: Wrapper for file I/O methods +//----------------------------------------------------------------------------- +class CFileStream : public IWriteStream +{ +public: + CFileStream( FILE *fout ) : IWriteStream(), m_file( fout ), m_hFile( INVALID_HANDLE_VALUE ) {} + CFileStream( HANDLE hOutFile ) : IWriteStream(), m_file( NULL ), m_hFile( hOutFile ) {} + + // Implementing IWriteStream method + virtual void Put( const void* pMem, int size ) + { + if ( m_file ) + { + fwrite( pMem, size, 1, m_file ); + } +#ifdef WIN32 + else + { + DWORD numBytesWritten; + WriteFile( m_hFile, pMem, size, &numBytesWritten, NULL ); + } +#endif + } + + // Implementing IWriteStream method + virtual unsigned int Tell( void ) + { + if ( m_file ) + { + return ftell( m_file ); + } + else + { +#ifdef WIN32 + return CWin32File::FileTell( m_hFile ); +#else + return 0; +#endif + } + } + +private: + FILE *m_file; + HANDLE m_hFile; +}; + +//----------------------------------------------------------------------------- +// Purpose: Container for modifiable pak file which is embedded inside the .bsp file +// itself. It's used to allow one-off files to be stored local to the map and it is +// hooked into the file system as an override for searching for named files. +//----------------------------------------------------------------------------- +class CZipFile +{ +public: + // Construction + CZipFile( const char *pDiskCacheWritePath, bool bSortByName ); + ~CZipFile( void ); + + // Public API + // Clear all existing data + void Reset( void ); + + // Add file to zip under relative name + void AddFileToZip( const char *relativename, const char *fullpath ); + + // Delete file from zip + void RemoveFileFromZip( const char *relativename ); + + // Add buffer to zip as a file with given name + void AddBufferToZip( const char *relativename, void *data, int length, bool bTextMode ); + + // Check if a file already exists in the zip. + bool FileExistsInZip( const char *relativename ); + + // Reads a file from a zip file + bool ReadFileFromZip( const char *relativename, bool bTextMode, CUtlBuffer &buf ); + bool ReadFileFromZip( HANDLE hZipFile, const char *relativename, bool bTextMode, CUtlBuffer &buf ); + + // Initialize the zip file from a buffer + void ParseFromBuffer( void *buffer, int bufferlength ); + HANDLE ParseFromDisk( const char *pFilename ); + + // Estimate the size of the zip file (including header, padding, etc.) + unsigned int EstimateSize(); + + // Print out a directory of files in the zip. + void PrintDirectory( void ); + + // Use to iterate directory, pass 0 for first element + // returns nonzero element id with filled buffer, or -1 at list conclusion + int GetNextFilename( int id, char *pBuffer, int bufferSize, int &fileSize ); + + // Write the zip to a buffer + void SaveToBuffer( CUtlBuffer& buffer ); + // Write the zip to a filestream + void SaveToDisk( FILE *fout ); + void SaveToDisk( HANDLE hOutFile ); + + unsigned int CalculateSize( void ); + + void ForceAlignment( bool aligned, bool bCompatibleFormat, unsigned int alignmentSize ); + + unsigned int GetAlignment(); + + void SetBigEndian( bool bigEndian ); + void ActivateByteSwapping( bool bActivate ); + +private: + enum + { + MAX_FILES_IN_ZIP = 32768, + }; + + typedef struct + { + CUtlSymbol m_Name; + unsigned int filepos; + int filelen; + } TmpFileInfo_t; + + CByteswap m_Swap; + unsigned int m_AlignmentSize; + bool m_bForceAlignment; + bool m_bCompatibleFormat; + + unsigned short CalculatePadding( unsigned int filenameLen, unsigned int pos ); + void SaveDirectory( IWriteStream& stream ); + int MakeXZipCommentString( char *pComment ); + void ParseXZipCommentString( const char *pComment ); + + // Internal entry for faster searching, etc. + class CZipEntry + { + public: + CZipEntry( void ); + ~CZipEntry( void ); + + CZipEntry( const CZipEntry& src ); + + // RB tree compare function + static bool ZipFileLessFunc( CZipEntry const& src1, CZipEntry const& src2 ); + static bool ZipFileLessFunc_CaselessSort( CZipEntry const& src1, CZipEntry const& src2 ); + + // Name of entry + CUtlSymbol m_Name; + + // Lenth of data element + int m_Length; + // Raw data, could be null and data may be in disk write cache + void *m_pData; + + // Offset in Zip ( set and valid during final write ) + unsigned int m_ZipOffset; + // CRC of blob ( set and valid during final write ) + CRC32_t m_ZipCRC; + + // Location of data in disk cache + unsigned int m_DiskCacheOffset; + unsigned int m_SourceDiskOffset; + }; + + // For fast name lookup and sorting + CUtlRBTree< CZipEntry, int > m_Files; + + // Used to buffer zip data, instead of ram + bool m_bUseDiskCacheForWrites; + HANDLE m_hDiskCacheWriteFile; + CUtlString m_DiskCacheName; + CUtlString m_DiskCacheWritePath; +}; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CZipFile::CZipEntry::CZipEntry( void ) +{ + m_Name = ""; + m_Length = 0; + m_pData = NULL; + m_ZipOffset = 0; + m_ZipCRC = 0; + m_DiskCacheOffset = 0; + m_SourceDiskOffset = 0; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : src - +//----------------------------------------------------------------------------- +CZipFile::CZipEntry::CZipEntry( const CZipFile::CZipEntry& src ) +{ + m_Name = src.m_Name; + m_Length = src.m_Length; + + if ( src.m_Length > 0 && src.m_pData ) + { + m_pData = malloc( src.m_Length ); + memcpy( m_pData, src.m_pData, src.m_Length ); + } + else + { + m_pData = NULL; + } + + m_ZipOffset = src.m_ZipOffset; + m_ZipCRC = src.m_ZipCRC; + m_DiskCacheOffset = src.m_DiskCacheOffset; + m_SourceDiskOffset = src.m_SourceDiskOffset; +} + +//----------------------------------------------------------------------------- +// Purpose: Clear any leftover data +//----------------------------------------------------------------------------- +CZipFile::CZipEntry::~CZipEntry( void ) +{ + if ( m_pData ) + { + free( m_pData ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Construction +//----------------------------------------------------------------------------- +CZipFile::CZipFile( const char *pDiskCacheWritePath, bool bSortByName ) +: m_Files( 0, 32 ) +{ + m_AlignmentSize = 0; + m_bForceAlignment = false; + m_bCompatibleFormat = true; + + m_bUseDiskCacheForWrites = ( pDiskCacheWritePath != NULL ); + m_DiskCacheWritePath = pDiskCacheWritePath; + m_hDiskCacheWriteFile = INVALID_HANDLE_VALUE; + + if ( bSortByName ) + { + m_Files.SetLessFunc( CZipEntry::ZipFileLessFunc_CaselessSort ); + } + else + { + m_Files.SetLessFunc( CZipEntry::ZipFileLessFunc ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Destroy zip data +//----------------------------------------------------------------------------- +CZipFile::~CZipFile( void ) +{ + m_bUseDiskCacheForWrites = false; + Reset(); +} + +//----------------------------------------------------------------------------- +// Purpose: Delete all current data +//----------------------------------------------------------------------------- +void CZipFile::Reset( void ) +{ + m_Files.RemoveAll(); + + if ( m_hDiskCacheWriteFile != INVALID_HANDLE_VALUE ) + { +#ifdef WIN32 + CloseHandle( m_hDiskCacheWriteFile ); + DeleteFile( m_DiskCacheName.String() ); +#else + fclose( (FILE *)m_hDiskCacheWriteFile ); + unlink( m_DiskCacheName.String() ); +#endif + m_hDiskCacheWriteFile = INVALID_HANDLE_VALUE; + } + + if ( m_bUseDiskCacheForWrites ) + { + m_hDiskCacheWriteFile = CWin32File::CreateTempFile( m_DiskCacheWritePath, m_DiskCacheName ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Comparison for sorting entries +// Input : src1 - +// src2 - +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CZipFile::CZipEntry::ZipFileLessFunc( CZipEntry const& src1, CZipEntry const& src2 ) +{ + return ( src1.m_Name < src2.m_Name ); +} + +bool CZipFile::CZipEntry::ZipFileLessFunc_CaselessSort( CZipEntry const& src1, CZipEntry const& src2 ) +{ + return ( V_stricmp( src1.m_Name.String(), src2.m_Name.String() ) < 0 ); +} + +void CZipFile::ForceAlignment( bool bAligned, bool bCompatibleFormat, unsigned int alignment ) +{ + m_bForceAlignment = bAligned; + m_AlignmentSize = alignment; + m_bCompatibleFormat = bCompatibleFormat; + + if ( !bAligned ) + { + m_AlignmentSize = 0; + } + else if ( !IsPowerOfTwo( m_AlignmentSize ) ) + { + m_AlignmentSize = 0; + } +} + +unsigned int CZipFile::GetAlignment() +{ + if ( !m_bForceAlignment || !m_AlignmentSize ) + { + return 0; + } + + return m_AlignmentSize; +} + +void CZipFile::SetBigEndian( bool bigEndian ) +{ + m_Swap.SetTargetBigEndian( bigEndian ); +} + +void CZipFile::ActivateByteSwapping( bool bActivate ) +{ + m_Swap.ActivateByteSwapping( bActivate ); +} + +//----------------------------------------------------------------------------- +// Purpose: Load pak file from raw buffer +// Input : *buffer - +// bufferlength - +//----------------------------------------------------------------------------- +void CZipFile::ParseFromBuffer( void *buffer, int bufferlength ) +{ + // Throw away old data + Reset(); + + // Initialize a buffer + CUtlBuffer buf( 0, bufferlength +1 ); // +1 for null termination + + // need to swap bytes, so set the buffer opposite the machine's endian + buf.ActivateByteSwapping( m_Swap.IsSwappingBytes() ); + + buf.Put( buffer, bufferlength ); + + buf.SeekGet( CUtlBuffer::SEEK_TAIL, 0 ); + unsigned int fileLen = buf.TellGet(); + + // Start from beginning + buf.SeekGet( CUtlBuffer::SEEK_HEAD, 0 ); + + ZIP_EndOfCentralDirRecord rec = { 0 }; + + bool bFoundEndOfCentralDirRecord = false; + unsigned int offset = fileLen - sizeof( ZIP_EndOfCentralDirRecord ); + // If offset is ever greater than startOffset then it means that it has + // wrapped. This used to be a tautological >= 0 test. + ANALYZE_SUPPRESS( 6293 ); // warning C6293: Ill-defined for-loop: counts down from minimum + for ( unsigned int startOffset = offset; offset <= startOffset; offset-- ) + { + buf.SeekGet( CUtlBuffer::SEEK_HEAD, offset ); + buf.GetObjects( &rec ); + if ( rec.signature == PKID( 5, 6 ) ) + { + bFoundEndOfCentralDirRecord = true; + + // Set any xzip configuration + if ( rec.commentLength ) + { + char commentString[128]; + int commentLength = min( rec.commentLength, sizeof( commentString ) ); + buf.Get( commentString, commentLength ); + if ( commentLength == sizeof( commentString ) ) + --commentLength; + commentString[commentLength] = '\0'; + ParseXZipCommentString( commentString ); + } + break; + } + else + { + // wrong record + rec.nCentralDirectoryEntries_Total = 0; + } + } + Assert( bFoundEndOfCentralDirRecord ); + + // Make sure there are some files to parse + int numzipfiles = rec.nCentralDirectoryEntries_Total; + if ( numzipfiles <= 0 ) + { + // No files + return; + } + + buf.SeekGet( CUtlBuffer::SEEK_HEAD, rec.startOfCentralDirOffset ); + + // Allocate space for directory + TmpFileInfo_t *newfiles = new TmpFileInfo_t[numzipfiles]; + Assert( newfiles ); + + // build directory + int i; + for ( i = 0; i < rec.nCentralDirectoryEntries_Total; i++ ) + { + ZIP_FileHeader zipFileHeader; + buf.GetObjects( &zipFileHeader ); + Assert( zipFileHeader.signature == PKID( 1, 2 ) ); + Assert( zipFileHeader.compressionMethod == 0 ); + + char tmpString[1024]; + buf.Get( tmpString, zipFileHeader.fileNameLength ); + tmpString[zipFileHeader.fileNameLength] = '\0'; + Q_strlower( tmpString ); + + // can determine actual filepos, assuming a well formed zip + newfiles[i].m_Name = tmpString; + newfiles[i].filelen = zipFileHeader.compressedSize; + newfiles[i].filepos = zipFileHeader.relativeOffsetOfLocalHeader + + sizeof( ZIP_LocalFileHeader ) + + zipFileHeader.fileNameLength + + zipFileHeader.extraFieldLength; + + int nextOffset; + if ( m_bCompatibleFormat ) + { + nextOffset = zipFileHeader.extraFieldLength + zipFileHeader.fileCommentLength; + } + else + { + nextOffset = 0; + } + buf.SeekGet( CUtlBuffer::SEEK_CURRENT, nextOffset ); + } + + // Insert current data into rb tree + for ( i=0; i 0 ) + { + e.m_pData = malloc( e.m_Length ); + + // Copy in data + buf.SeekGet( CUtlBuffer::SEEK_HEAD, newfiles[i].filepos ); + buf.Get( e.m_pData, e.m_Length ); + } + else + { + e.m_pData = NULL; + } + + // Add to tree + m_Files.Insert( e ); + } + + // Through away directory + delete[] newfiles; +} + +//----------------------------------------------------------------------------- +// Purpose: Mount pak file from disk +//----------------------------------------------------------------------------- +HANDLE CZipFile::ParseFromDisk( const char *pFilename ) +{ +#ifdef WIN32 + HANDLE hFile = CreateFile( pFilename, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); + if ( hFile == INVALID_HANDLE_VALUE ) + { + // not found + return NULL; + } +#else + HANDLE hFile = fopen( pFilename, "rw+" ); + if ( !hFile ) + { + // not found + return NULL; + } +#endif + + unsigned int fileLen = CWin32File::FileSeek( hFile, 0, FILE_END ); + CWin32File::FileSeek( hFile, 0, FILE_BEGIN ); + if ( fileLen < sizeof( ZIP_EndOfCentralDirRecord ) ) + { + // bad format +#ifdef WIN32 + CloseHandle( hFile ); +#else + fclose( (FILE *)hFile ); +#endif + return NULL; + } + + // need to get the central dir + ZIP_EndOfCentralDirRecord rec = { 0 }; + unsigned int offset = fileLen - sizeof( ZIP_EndOfCentralDirRecord ); + // If offset is ever greater than startOffset then it means that it has + // wrapped. This used to be a tautological >= 0 test. + ANALYZE_SUPPRESS( 6293 ); // warning C6293: Ill-defined for-loop: counts down from minimum + for ( unsigned int startOffset = offset; offset <= startOffset; offset-- ) + { + CWin32File::FileSeek( hFile, offset, FILE_BEGIN ); + + CWin32File::FileRead( hFile, &rec, sizeof( rec ) ); + m_Swap.SwapFieldsToTargetEndian( &rec ); + + if ( rec.signature == PKID( 5, 6 ) ) + { + // Set any xzip configuration + if ( rec.commentLength ) + { + char commentString[128]; + int commentLength = min( rec.commentLength, sizeof( commentString ) ); + CWin32File::FileRead( hFile, commentString, commentLength ); + if ( commentLength == sizeof( commentString ) ) + --commentLength; + commentString[commentLength] = '\0'; + ParseXZipCommentString( commentString ); + } + break; + } + else + { + // wrong record + rec.nCentralDirectoryEntries_Total = 0; + } + } + + // Make sure there are some files to parse + int numZipFiles = rec.nCentralDirectoryEntries_Total; + if ( numZipFiles <= 0 ) + { + // No files +#ifdef WIN32 + CloseHandle( hFile ); +#else + fclose( (FILE *)hFile ); +#endif + return NULL; + } + + CWin32File::FileSeek( hFile, rec.startOfCentralDirOffset, FILE_BEGIN ); + + // read entire central dir into memory + CUtlBuffer zipDirBuff( 0, rec.centralDirectorySize, 0 ); + zipDirBuff.ActivateByteSwapping( m_Swap.IsSwappingBytes() ); + CWin32File::FileRead( hFile, zipDirBuff.Base(), rec.centralDirectorySize ); + zipDirBuff.SeekPut( CUtlBuffer::SEEK_HEAD, rec.centralDirectorySize ); + + // build directory + for ( int i = 0; i < numZipFiles; i++ ) + { + ZIP_FileHeader zipFileHeader; + zipDirBuff.GetObjects( &zipFileHeader ); + + if ( zipFileHeader.signature != PKID( 1, 2 ) || zipFileHeader.compressionMethod != 0 ) + { + // bad contents +#ifdef WIN32 + CloseHandle( hFile ); +#else + fclose( (FILE *)hFile ); +#endif + return NULL; + } + + char fileName[1024]; + zipDirBuff.Get( fileName, zipFileHeader.fileNameLength ); + fileName[zipFileHeader.fileNameLength] = '\0'; + Q_strlower( fileName ); + + // can determine actual filepos, assuming a well formed zip + CZipEntry e; + e.m_Name = fileName; + e.m_Length = zipFileHeader.compressedSize; + e.m_SourceDiskOffset = zipFileHeader.relativeOffsetOfLocalHeader + + sizeof( ZIP_LocalFileHeader ) + + zipFileHeader.fileNameLength + + zipFileHeader.extraFieldLength; + // Add to tree + m_Files.Insert( e ); + + int nextOffset; + if ( m_bCompatibleFormat ) + { + nextOffset = zipFileHeader.extraFieldLength + zipFileHeader.fileCommentLength; + } + else + { + nextOffset = 0; + } + + zipDirBuff.SeekGet( CUtlBuffer::SEEK_CURRENT, nextOffset ); + } + + return hFile; +} + +static int GetLengthOfBinStringAsText( const char *pSrc, int srcSize ) +{ + const char *pSrcScan = pSrc; + const char *pSrcEnd = pSrc + srcSize; + int numChars = 0; + for( ; pSrcScan < pSrcEnd; pSrcScan++ ) + { + if( *pSrcScan == '\n' ) + { + numChars += 2; + } + else + { + numChars++; + } + } + return numChars; +} + + +//----------------------------------------------------------------------------- +// Copies text data from a form appropriate for disk to a normal string +//----------------------------------------------------------------------------- +static void ReadTextData( const char *pSrc, int nSrcSize, CUtlBuffer &buf ) +{ + buf.EnsureCapacity( nSrcSize + 1 ); + const char *pSrcEnd = pSrc + nSrcSize; + for ( const char *pSrcScan = pSrc; pSrcScan < pSrcEnd; ++pSrcScan ) + { + if ( *pSrcScan == '\r' ) + { + if ( pSrcScan[1] == '\n' ) + { + buf.PutChar( '\n' ); + ++pSrcScan; + continue; + } + } + + buf.PutChar( *pSrcScan ); + } + + // Null terminate + buf.PutChar( '\0' ); +} + + +//----------------------------------------------------------------------------- +// Copies text data into a form appropriate for disk +//----------------------------------------------------------------------------- +static void CopyTextData( char *pDst, const char *pSrc, int dstSize, int srcSize ) +{ + const char *pSrcScan = pSrc; + const char *pSrcEnd = pSrc + srcSize; + char *pDstScan = pDst; + +#ifdef DBGFLAG_ASSERT + char *pDstEnd = pDst + dstSize; +#endif + + for ( ; pSrcScan < pSrcEnd; pSrcScan++ ) + { + if ( *pSrcScan == '\n' ) + { + *pDstScan = '\r'; + pDstScan++; + *pDstScan = '\n'; + pDstScan++; + } + else + { + *pDstScan = *pSrcScan; + pDstScan++; + } + } + Assert( pSrcScan == pSrcEnd ); + Assert( pDstScan == pDstEnd ); +} + +//----------------------------------------------------------------------------- +// Purpose: Adds a new lump, or overwrites existing one +// Input : *relativename - +// *data - +// length - +//----------------------------------------------------------------------------- +void CZipFile::AddBufferToZip( const char *relativename, void *data, int length, bool bTextMode ) +{ + // Lower case only + char name[512]; + Q_strcpy( name, relativename ); + Q_strlower( name ); + + int dstLength = length; + if ( bTextMode ) + { + dstLength = GetLengthOfBinStringAsText( ( const char * )data, length ); + } + + // See if entry is in list already + CZipEntry e; + e.m_Name = name; + int index = m_Files.Find( e ); + + // If already existing, throw away old data and update data and length + if ( index != m_Files.InvalidIndex() ) + { + CZipEntry *update = &m_Files[ index ]; + if ( update->m_pData ) + { + free( update->m_pData ); + } + + if ( bTextMode ) + { + update->m_pData = malloc( dstLength ); + CopyTextData( ( char * )update->m_pData, ( char * )data, dstLength, length ); + update->m_Length = dstLength; + } + else + { + update->m_pData = malloc( length ); + memcpy( update->m_pData, data, length ); + update->m_Length = length; + } + + if ( m_hDiskCacheWriteFile != INVALID_HANDLE_VALUE ) + { + update->m_DiskCacheOffset = CWin32File::FileTell( m_hDiskCacheWriteFile ); + CWin32File::FileWrite( m_hDiskCacheWriteFile, update->m_pData, update->m_Length ); + free( update->m_pData ); + update->m_pData = NULL; + } + } + else + { + // Create a new entry + e.m_Length = dstLength; + if ( dstLength > 0 ) + { + if ( bTextMode ) + { + e.m_pData = malloc( dstLength ); + CopyTextData( (char *)e.m_pData, ( char * )data, dstLength, length ); + } + else + { + e.m_pData = malloc( length ); + memcpy( e.m_pData, data, length ); + } + + if ( m_hDiskCacheWriteFile != INVALID_HANDLE_VALUE ) + { + e.m_DiskCacheOffset = CWin32File::FileTell( m_hDiskCacheWriteFile ); + CWin32File::FileWrite( m_hDiskCacheWriteFile, e.m_pData, e.m_Length ); + free( e.m_pData ); + e.m_pData = NULL; + } + } + else + { + e.m_pData = NULL; + } + + m_Files.Insert( e ); + } +} + + +//----------------------------------------------------------------------------- +// Reads a file from the zip +//----------------------------------------------------------------------------- +bool CZipFile::ReadFileFromZip( const char *pRelativeName, bool bTextMode, CUtlBuffer &buf ) +{ + // Lower case only + char pName[512]; + Q_strncpy( pName, pRelativeName, 512 ); + Q_strlower( pName ); + + // See if entry is in list already + CZipEntry e; + e.m_Name = pName; + int nIndex = m_Files.Find( e ); + if ( nIndex == m_Files.InvalidIndex() ) + { + // not found + return false; + } + + CZipEntry *pEntry = &m_Files[ nIndex ]; + if ( bTextMode ) + { + buf.SetBufferType( true, false ); + ReadTextData( (char*)pEntry->m_pData, pEntry->m_Length, buf ); + } + else + { + buf.SetBufferType( false, false ); + buf.Put( pEntry->m_pData, pEntry->m_Length ); + } + + return true; +} + +//----------------------------------------------------------------------------- +// Reads a file from the zip +//----------------------------------------------------------------------------- +bool CZipFile::ReadFileFromZip( HANDLE hZipFile, const char *pRelativeName, bool bTextMode, CUtlBuffer &buf ) +{ + // Lower case only + char pName[512]; + Q_strncpy( pName, pRelativeName, 512 ); + Q_strlower( pName ); + + // See if entry is in list already + CZipEntry e; + e.m_Name = pName; + int nIndex = m_Files.Find( e ); + if ( nIndex == m_Files.InvalidIndex() ) + { + // not found + return false; + } + + CZipEntry *pEntry = &m_Files[nIndex]; + + void *pData = malloc( pEntry->m_Length ); + CWin32File::FileSeek( hZipFile, pEntry->m_SourceDiskOffset, FILE_BEGIN ); + if ( !CWin32File::FileRead( hZipFile, pData, pEntry->m_Length ) ) + { + free( pData ); + return false; + } + + if ( bTextMode ) + { + buf.SetBufferType( true, false ); + ReadTextData( (const char *)pData, pEntry->m_Length, buf ); + } + else + { + buf.SetBufferType( false, false ); + buf.Put( pData, pEntry->m_Length ); + } + + free( pData ); + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Check if a file already exists in the zip. +// Input : *relativename - +//----------------------------------------------------------------------------- +bool CZipFile::FileExistsInZip( const char *pRelativeName ) +{ + // Lower case only + char pName[512]; + Q_strncpy( pName, pRelativeName, 512 ); + Q_strlower( pName ); + + // See if entry is in list already + CZipEntry e; + e.m_Name = pName; + int nIndex = m_Files.Find( e ); + + // If it is, then it exists in the pack! + return nIndex != m_Files.InvalidIndex(); +} + + +//----------------------------------------------------------------------------- +// Purpose: Adds a new file to the zip. +//----------------------------------------------------------------------------- +void CZipFile::AddFileToZip( const char *relativename, const char *fullpath ) +{ + FILE *temp = fopen( fullpath, "rb" ); + if ( !temp ) + return; + + // Determine length + fseek( temp, 0, SEEK_END ); + int size = ftell( temp ); + fseek( temp, 0, SEEK_SET ); + byte *buf = (byte *)malloc( size + 1 ); + + // Read data + fread( buf, size, 1, temp ); + fclose( temp ); + + // Now add as a buffer + AddBufferToZip( relativename, buf, size, false ); + + free( buf ); +} + +//----------------------------------------------------------------------------- +// Purpose: Removes a file from the zip. +//----------------------------------------------------------------------------- +void CZipFile::RemoveFileFromZip( const char *relativename ) +{ + CZipEntry e; + e.m_Name = relativename; + int index = m_Files.Find( e ); + + if ( index != m_Files.InvalidIndex() ) + { + CZipEntry update = m_Files[index]; + m_Files.Remove( update ); + } +} + +//--------------------------------------------------------------- +// Purpose: Calculates how many bytes should be added to the extra field +// to push the start of the file data to the next aligned boundary +// Output: Required padding size +//--------------------------------------------------------------- +unsigned short CZipFile::CalculatePadding( unsigned int filenameLen, unsigned int pos ) +{ + if ( m_AlignmentSize == 0 ) + { + return 0; + } + + unsigned int headerSize = sizeof( ZIP_LocalFileHeader ) + filenameLen; + return (unsigned short)( m_AlignmentSize - ( ( pos + headerSize ) % m_AlignmentSize ) ); +} + +//----------------------------------------------------------------------------- +// Purpose: Create the XZIP identifying comment string +// Output : Length +//----------------------------------------------------------------------------- +int CZipFile::MakeXZipCommentString( char *pCommentString ) +{ + char tempString[XZIP_COMMENT_LENGTH]; + + memset( tempString, 0, sizeof( tempString ) ); + V_snprintf( tempString, sizeof( tempString ), "XZP%c %d", m_bCompatibleFormat ? '1' : '2', m_AlignmentSize ); + if ( pCommentString ) + { + memcpy( pCommentString, tempString, sizeof( tempString ) ); + } + + // expected fixed length + return XZIP_COMMENT_LENGTH; +} + +//----------------------------------------------------------------------------- +// Purpose: An XZIP has its configuration in the ascii comment +//----------------------------------------------------------------------------- +void CZipFile::ParseXZipCommentString( const char *pCommentString ) +{ + if ( !V_strnicmp( pCommentString, "XZP", 3 ) ) + { + m_bCompatibleFormat = true; + if ( pCommentString[3] == '2' ) + { + m_bCompatibleFormat = false; + } + + // parse out the alignement configuration + if ( !m_bForceAlignment ) + { + m_AlignmentSize = 0; + sscanf( pCommentString + 4, "%d", &m_AlignmentSize ); + if ( !IsPowerOfTwo( m_AlignmentSize ) ) + { + m_AlignmentSize = 0; + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Calculate the exact size of zip file, with headers and padding +// Output : int +//----------------------------------------------------------------------------- +unsigned int CZipFile::CalculateSize( void ) +{ + unsigned int size = 0; + unsigned int dirHeaders = 0; + for ( int i = m_Files.FirstInorder(); i != m_Files.InvalidIndex(); i = m_Files.NextInorder( i ) ) + { + CZipEntry *e = &m_Files[ i ]; + + if ( e->m_Length == 0 ) + continue; + + // local file header + size += sizeof( ZIP_LocalFileHeader ); + size += strlen( e->m_Name.String() ); + + // every file has a directory header that duplicates the filename + dirHeaders += sizeof( ZIP_FileHeader ) + strlen( e->m_Name.String() ); + + // calculate padding + if ( m_AlignmentSize != 0 ) + { + // round up to next boundary + unsigned int nextBoundary = ( size + m_AlignmentSize ) & ~( m_AlignmentSize - 1 ); + + // the directory header also duplicates the padding + dirHeaders += nextBoundary - size; + + size = nextBoundary; + } + + // data size + size += e->m_Length; + } + + size += dirHeaders; + + // All processed zip files will have a comment string + size += sizeof( ZIP_EndOfCentralDirRecord ) + MakeXZipCommentString( NULL ); + + return size; +} + +//----------------------------------------------------------------------------- +// Purpose: Print a directory of files in the zip +//----------------------------------------------------------------------------- +void CZipFile::PrintDirectory( void ) +{ + for ( int i = m_Files.FirstInorder(); i != m_Files.InvalidIndex(); i = m_Files.NextInorder( i ) ) + { + CZipEntry *e = &m_Files[ i ]; + + Msg( "%s\n", e->m_Name.String() ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Iterate through directory +//----------------------------------------------------------------------------- +int CZipFile::GetNextFilename( int id, char *pBuffer, int bufferSize, int &fileSize ) +{ + if ( id == -1 ) + { + id = m_Files.FirstInorder(); + } + else + { + id = m_Files.NextInorder( id ); + } + if ( id == m_Files.InvalidIndex() ) + { + // list is empty + return -1; + } + + CZipEntry *e = &m_Files[id]; + + Q_strncpy( pBuffer, e->m_Name.String(), bufferSize ); + fileSize = e->m_Length; + + return id; +} + +//----------------------------------------------------------------------------- +// Purpose: Store data out to disk +//----------------------------------------------------------------------------- +void CZipFile::SaveToDisk( FILE *fout ) +{ + CFileStream stream( fout ); + SaveDirectory( stream ); +} + +void CZipFile::SaveToDisk( HANDLE hOutFile ) +{ + CFileStream stream( hOutFile ); + SaveDirectory( stream ); +} + +//----------------------------------------------------------------------------- +// Purpose: Store data out to a CUtlBuffer +//----------------------------------------------------------------------------- +void CZipFile::SaveToBuffer( CUtlBuffer& buf ) +{ + CBufferStream stream( buf ); + SaveDirectory( stream ); +} + +//----------------------------------------------------------------------------- +// Purpose: Store data back out to a stream (could be CUtlBuffer or filestream) +//----------------------------------------------------------------------------- +void CZipFile::SaveDirectory( IWriteStream& stream ) +{ + void *pPaddingBuffer = NULL; + if ( m_AlignmentSize ) + { + // get a temp buffer for all padding work + pPaddingBuffer = malloc( m_AlignmentSize ); + memset( pPaddingBuffer, 0x00, m_AlignmentSize ); + } + + if ( m_hDiskCacheWriteFile != INVALID_HANDLE_VALUE ) + { +#ifdef WIN32 + FlushFileBuffers( m_hDiskCacheWriteFile ); +#else + fflush( (FILE *)m_hDiskCacheWriteFile ); +#endif + } + + int i; + for ( i = m_Files.FirstInorder(); i != m_Files.InvalidIndex(); i = m_Files.NextInorder( i ) ) + { + CZipEntry *e = &m_Files[i]; + Assert( e ); + + // Fix up the offset + e->m_ZipOffset = stream.Tell(); + + if ( e->m_Length > 0 && ( m_hDiskCacheWriteFile != INVALID_HANDLE_VALUE ) ) + { + // get the data back from the write cache + e->m_pData = malloc( e->m_Length ); + if ( e->m_pData ) + { + CWin32File::FileSeek( m_hDiskCacheWriteFile, e->m_DiskCacheOffset, FILE_BEGIN ); + CWin32File::FileRead( m_hDiskCacheWriteFile, e->m_pData, e->m_Length ); + } + } + + if ( e->m_Length > 0 && e->m_pData != NULL ) + { + ZIP_LocalFileHeader hdr = { 0 }; + hdr.signature = PKID( 3, 4 ); + hdr.versionNeededToExtract = 10; // This is the version that the winzip that I have writes. + hdr.flags = 0; + hdr.compressionMethod = 0; // NO COMPRESSION! + hdr.lastModifiedTime = 0; + hdr.lastModifiedDate = 0; + + CRC32_Init( &e->m_ZipCRC ); + CRC32_ProcessBuffer( &e->m_ZipCRC, e->m_pData, e->m_Length ); + CRC32_Final( &e->m_ZipCRC ); + hdr.crc32 = e->m_ZipCRC; + + const char *pFilename = e->m_Name.String(); + hdr.compressedSize = e->m_Length; + hdr.uncompressedSize = e->m_Length; + hdr.fileNameLength = strlen( pFilename ); + hdr.extraFieldLength = CalculatePadding( hdr.fileNameLength, e->m_ZipOffset ); + int extraFieldLength = hdr.extraFieldLength; + + // Swap header in place + m_Swap.SwapFieldsToTargetEndian( &hdr ); + stream.Put( &hdr, sizeof( hdr ) ); + stream.Put( pFilename, strlen( pFilename ) ); + stream.Put( pPaddingBuffer, extraFieldLength ); + stream.Put( e->m_pData, e->m_Length ); + + if ( m_hDiskCacheWriteFile != INVALID_HANDLE_VALUE ) + { + free( e->m_pData ); + + // temp hackery for the logic below to succeed + e->m_pData = (void*)0xFFFFFFFF; + } + } + } + + if ( m_hDiskCacheWriteFile != INVALID_HANDLE_VALUE ) + { + CWin32File::FileSeek( m_hDiskCacheWriteFile, 0, FILE_END ); + } + + unsigned int centralDirStart = stream.Tell(); + if ( m_AlignmentSize ) + { + // align the central directory starting position + unsigned int newDirStart = AlignValue( centralDirStart, m_AlignmentSize ); + int padLength = newDirStart - centralDirStart; + if ( padLength ) + { + stream.Put( pPaddingBuffer, padLength ); + centralDirStart = newDirStart; + } + } + + int realNumFiles = 0; + for ( i = m_Files.FirstInorder(); i != m_Files.InvalidIndex(); i = m_Files.NextInorder( i ) ) + { + CZipEntry *e = &m_Files[i]; + Assert( e ); + + if ( e->m_Length > 0 && e->m_pData != NULL ) + { + ZIP_FileHeader hdr = { 0 }; + hdr.signature = PKID( 1, 2 ); + hdr.versionMadeBy = 20; // This is the version that the winzip that I have writes. + hdr.versionNeededToExtract = 10; // This is the version that the winzip that I have writes. + hdr.flags = 0; + hdr.compressionMethod = 0; + hdr.lastModifiedTime = 0; + hdr.lastModifiedDate = 0; + hdr.crc32 = e->m_ZipCRC; + + hdr.compressedSize = e->m_Length; + hdr.uncompressedSize = e->m_Length; + hdr.fileNameLength = strlen( e->m_Name.String() ); + hdr.extraFieldLength = CalculatePadding( hdr.fileNameLength, e->m_ZipOffset ); + hdr.fileCommentLength = 0; + hdr.diskNumberStart = 0; + hdr.internalFileAttribs = 0; + hdr.externalFileAttribs = 0; // This is usually something, but zero is OK as if the input came from stdin + hdr.relativeOffsetOfLocalHeader = e->m_ZipOffset; + int extraFieldLength = hdr.extraFieldLength; + + // Swap the header in place + m_Swap.SwapFieldsToTargetEndian( &hdr ); + stream.Put( &hdr, sizeof( hdr ) ); + stream.Put( e->m_Name.String(), strlen( e->m_Name.String() ) ); + if ( m_bCompatibleFormat ) + { + stream.Put( pPaddingBuffer, extraFieldLength ); + } + + realNumFiles++; + + if ( m_hDiskCacheWriteFile != INVALID_HANDLE_VALUE ) + { + // clear out temp hackery + e->m_pData = NULL; + } + } + } + + unsigned int centralDirEnd = stream.Tell(); + if ( m_AlignmentSize ) + { + // align the central directory starting position + unsigned int newDirEnd = AlignValue( centralDirEnd, m_AlignmentSize ); + int padLength = newDirEnd - centralDirEnd; + if ( padLength ) + { + stream.Put( pPaddingBuffer, padLength ); + centralDirEnd = newDirEnd; + } + } + + ZIP_EndOfCentralDirRecord rec = { 0 }; + rec.signature = PKID( 5, 6 ); + rec.numberOfThisDisk = 0; + rec.numberOfTheDiskWithStartOfCentralDirectory = 0; + rec.nCentralDirectoryEntries_ThisDisk = realNumFiles; + rec.nCentralDirectoryEntries_Total = realNumFiles; + rec.centralDirectorySize = centralDirEnd - centralDirStart; + rec.startOfCentralDirOffset = centralDirStart; + + char commentString[128]; + int commentLength = MakeXZipCommentString( commentString ); + rec.commentLength = commentLength; + + // Swap the header in place + m_Swap.SwapFieldsToTargetEndian( &rec ); + stream.Put( &rec, sizeof( rec ) ); + stream.Put( commentString, commentLength ); + + if ( pPaddingBuffer ) + { + free( pPaddingBuffer ); + } +} + +class CZip : public IZip +{ +public: + CZip( const char *pDiskCacheWritePath, bool bSortByName ); + virtual ~CZip(); + + virtual void Reset(); + + // Add a single file to a zip - maintains the zip's previous alignment state + virtual void AddFileToZip( const char *relativename, const char *fullpath ); + + // Whether a file is contained in a zip - maintains alignment + virtual bool FileExistsInZip( const char *pRelativeName ); + + // Reads a file from the zip - maintains alignement + virtual bool ReadFileFromZip( const char *pRelativeName, bool bTextMode, CUtlBuffer &buf ); + virtual bool ReadFileFromZip( HANDLE hZipFile, const char *relativename, bool bTextMode, CUtlBuffer &buf ); + + // Removes a single file from the zip - maintains alignment + virtual void RemoveFileFromZip( const char *relativename ); + + // Gets next filename in zip, for walking the directory - maintains alignment + virtual int GetNextFilename( int id, char *pBuffer, int bufferSize, int &fileSize ); + + // Prints the zip's contents - maintains alignment + virtual void PrintDirectory( void ); + + // Estimate the size of the Zip (including header, padding, etc.) + virtual unsigned int EstimateSize( void ); + + // Add buffer to zip as a file with given name - uses current alignment size, default 0 (no alignment) + virtual void AddBufferToZip( const char *relativename, void *data, int length, bool bTextMode ); + + // Writes out zip file to a buffer - uses current alignment size + // (set by file's previous alignment, or a call to ForceAlignment) + virtual void SaveToBuffer( CUtlBuffer& outbuf ); + + // Writes out zip file to a filestream - uses current alignment size + // (set by file's previous alignment, or a call to ForceAlignment) + virtual void SaveToDisk( FILE *fout ); + virtual void SaveToDisk( HANDLE hOutFile ); + + // Reads a zip file from a buffer into memory - sets current alignment size to + // the file's alignment size, unless overridden by a ForceAlignment call) + virtual void ParseFromBuffer( void *buffer, int bufferlength ); + virtual HANDLE ParseFromDisk( const char *pFilename ); + + // Forces a specific alignment size for all subsequent file operations, overriding files' previous alignment size. + // Return to using files' individual alignment sizes by passing FALSE. + virtual void ForceAlignment( bool aligned, bool bCompatibleFormat, unsigned int alignmentSize ); + + // Sets the endianess of the zip + virtual void SetBigEndian( bool bigEndian ); + virtual void ActivateByteSwapping( bool bActivate ); + + virtual unsigned int GetAlignment(); + +private: + CZipFile m_ZipFile; +}; + +static CUtlLinkedList< CZip* > g_ZipUtils; + +IZip *IZip::CreateZip( const char *pDiskCacheWritePath, bool bSortByName ) +{ + CZip *pZip = new CZip( pDiskCacheWritePath, bSortByName ); + g_ZipUtils.AddToTail( pZip ); + + return pZip; +} + +void IZip::ReleaseZip( IZip *pZip ) +{ + g_ZipUtils.FindAndRemove( (CZip *)pZip ); + + delete ((CZip *)pZip); +} + +CZip::CZip( const char *pDiskCacheWritePath, bool bSortByName ) : m_ZipFile( pDiskCacheWritePath, bSortByName ) +{ + m_ZipFile.Reset(); +} + +CZip::~CZip() +{ +} + +void CZip::SetBigEndian( bool bigEndian ) +{ + m_ZipFile.SetBigEndian( bigEndian ); +} + +void CZip::ActivateByteSwapping( bool bActivate ) +{ + m_ZipFile.ActivateByteSwapping( bActivate ); +} + +void CZip::AddFileToZip( const char *relativename, const char *fullpath ) +{ + m_ZipFile.AddFileToZip( relativename, fullpath ); +} + +bool CZip::FileExistsInZip( const char *pRelativeName ) +{ + return m_ZipFile.FileExistsInZip( pRelativeName ); +} + +bool CZip::ReadFileFromZip( const char *pRelativeName, bool bTextMode, CUtlBuffer &buf ) +{ + return m_ZipFile.ReadFileFromZip( pRelativeName, bTextMode, buf ); +} + +bool CZip::ReadFileFromZip( HANDLE hZipFile, const char *pRelativeName, bool bTextMode, CUtlBuffer &buf ) +{ + return m_ZipFile.ReadFileFromZip( hZipFile, pRelativeName, bTextMode, buf ); +} + +void CZip::RemoveFileFromZip( const char *relativename ) +{ + m_ZipFile.RemoveFileFromZip( relativename ); +} + +int CZip::GetNextFilename( int id, char *pBuffer, int bufferSize, int &fileSize ) +{ + return m_ZipFile.GetNextFilename( id, pBuffer, bufferSize, fileSize ); +} + +void CZip::PrintDirectory( void ) +{ + m_ZipFile.PrintDirectory(); +} + +void CZip::Reset() +{ + m_ZipFile.Reset(); +} + +unsigned int CZip::EstimateSize( void ) +{ + return m_ZipFile.CalculateSize(); +} + +// Add buffer to zip as a file with given name +void CZip::AddBufferToZip( const char *relativename, void *data, int length, bool bTextMode ) +{ + m_ZipFile.AddBufferToZip( relativename, data, length, bTextMode ); +} + +void CZip::SaveToBuffer( CUtlBuffer& outbuf ) +{ + m_ZipFile.SaveToBuffer( outbuf ); +} + +void CZip::SaveToDisk( FILE *fout ) +{ + m_ZipFile.SaveToDisk( fout ); +} + +void CZip::SaveToDisk( HANDLE hOutFile ) +{ + m_ZipFile.SaveToDisk( hOutFile ); +} + +void CZip::ParseFromBuffer( void *buffer, int bufferlength ) +{ + m_ZipFile.Reset(); + m_ZipFile.ParseFromBuffer( buffer, bufferlength ); +} + +HANDLE CZip::ParseFromDisk( const char *pFilename ) +{ + m_ZipFile.Reset(); + return m_ZipFile.ParseFromDisk( pFilename ); +} + +void CZip::ForceAlignment( bool aligned, bool bCompatibleFormat, unsigned int alignmentSize ) +{ + m_ZipFile.ForceAlignment( aligned, bCompatibleFormat, alignmentSize ); +} + +unsigned int CZip::GetAlignment() +{ + return m_ZipFile.GetAlignment(); +} + diff --git a/sp/src/public/zip_utils.h b/sp/src/public/zip_utils.h new file mode 100644 index 00000000..be1cc8dd --- /dev/null +++ b/sp/src/public/zip_utils.h @@ -0,0 +1,81 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef ZIP_UTILS_H +#define ZIP_UTILS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "utlsymbol.h" + +class CUtlBuffer; +#include "tier0/dbg.h" + +abstract_class IZip +{ +public: + virtual void Reset() = 0; + + // Add a single file to a zip - maintains the zip's previous alignment state + virtual void AddFileToZip ( const char *relativename, const char *fullpath ) = 0; + + // Whether a file is contained in a zip - maintains alignment + virtual bool FileExistsInZip ( const char *pRelativeName ) = 0; + + // Reads a file from the zip - maintains alignement + virtual bool ReadFileFromZip ( const char *pRelativeName, bool bTextMode, CUtlBuffer &buf ) = 0; + virtual bool ReadFileFromZip ( HANDLE hFile, const char *pRelativeName, bool bTextMode, CUtlBuffer &buf ) = 0; + + // Removes a single file from the zip - maintains alignment + virtual void RemoveFileFromZip ( const char *relativename ) = 0; + + // Gets next filename in zip, for walking the directory - maintains alignment + virtual int GetNextFilename ( int id, char *pBuffer, int bufferSize, int &fileSize ) = 0; + + // Prints the zip's contents - maintains alignment + virtual void PrintDirectory ( void ) = 0; + + // Estimate the size of the Zip (including header, padding, etc.) + virtual unsigned int EstimateSize ( void ) = 0; + + // Add buffer to zip as a file with given name - uses current alignment size, default 0 (no alignment) + virtual void AddBufferToZip ( const char *relativename, void *data, int length, bool bTextMode ) = 0; + + // Writes out zip file to a buffer - uses current alignment size + // (set by file's previous alignment, or a call to ForceAlignment) + virtual void SaveToBuffer ( CUtlBuffer& outbuf ) = 0; + + // Writes out zip file to a filestream - uses current alignment size + // (set by file's previous alignment, or a call to ForceAlignment) + virtual void SaveToDisk ( FILE *fout ) = 0; + virtual void SaveToDisk ( HANDLE hFileOut ) = 0; + + // Reads a zip file from a buffer into memory - sets current alignment size to + // the file's alignment size, unless overridden by a ForceAlignment call) + virtual void ParseFromBuffer ( void *buffer, int bufferlength ) = 0; + + // Mounts a zip file from the disk + // Only ReadFileFromZip() is supported because the zip file could be >2GB + virtual HANDLE ParseFromDisk ( const char *pFilename ) = 0; + + // Forces a specific alignment size for all subsequent file operations, overriding files' previous alignment size. + // Return to using files' individual alignment sizes by passing FALSE. + virtual void ForceAlignment ( bool aligned, bool bCompatibleFormat, unsigned int alignmentSize=0 ) = 0; + + virtual unsigned int GetAlignment() = 0; + + // Sets the endianess of the zip + virtual void SetBigEndian( bool bigEndian ) = 0; + virtual void ActivateByteSwapping( bool bActivate ) = 0; + + // Create/Release additional instances + // Disk Caching is necessary for large zips + static IZip *CreateZip( const char *pDiskCacheWritePath = NULL, bool bSortByName = false ); + static void ReleaseZip( IZip *zip ); +}; + +#endif // ZIP_UTILS_H