/* =========================================================================== Copyright (C) 2023 Gian 'myT' Schellenbaum This file is part of Challenge Quake 3 (CNQ3). Challenge Quake 3 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Challenge Quake 3 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Challenge Quake 3. If not, see . =========================================================================== */ // Gameplay Rendering Pipeline - defines all pre-compiled uber pixel shader combinations #pragma once // format: stage_count global_state (stage_state_in_hex)+ #define UBER_SHADER_PS_LIST(PS) \ PS(1_0_0) \ PS(1_0_13) \ PS(1_0_22) \ PS(1_0_23) \ PS(1_0_25) \ PS(1_0_40000000) \ PS(1_0_40000022) \ PS(1_0_40000065) \ PS(1_0_41) \ PS(1_0_62) \ PS(1_0_65) \ PS(1_0_83) \ PS(1_1_0) \ PS(1_1_13) \ PS(1_1_22) \ PS(1_1_23) \ PS(1_1_25) \ PS(1_1_40000000) \ PS(1_1_40000022) \ PS(1_1_40000065) \ PS(1_1_41) \ PS(1_1_62) \ PS(1_1_65) \ PS(1_1_83) \ PS(1_2_22) \ PS(1_2_25) \ PS(1_2_62) \ PS(1_2_65) \ PS(1_3_22) \ PS(1_3_25) \ PS(1_3_62) \ PS(1_3_65) \ PS(2_0_0_13) \ PS(2_0_0_20000000) \ PS(2_0_0_22) \ PS(2_0_0_23) \ PS(2_0_0_53) \ PS(2_0_0_62) \ PS(2_0_0_65) \ PS(2_0_0_78) \ PS(2_0_0_83) \ PS(2_0_13_13) \ PS(2_0_22_22) \ PS(2_0_40000000_13) \ PS(2_1_0_13) \ PS(2_1_0_20000000) \ PS(2_1_0_22) \ PS(2_1_0_23) \ PS(2_1_0_53) \ PS(2_1_0_62) \ PS(2_1_0_65) \ PS(2_1_0_78) \ PS(2_1_0_83) \ PS(2_1_13_13) \ PS(2_1_22_22) \ PS(2_1_40000000_13) \ PS(2_2_13_13) \ PS(2_2_22_22) \ PS(2_3_13_13) \ PS(2_3_22_22) \ PS(3_0_0_0_22) \ PS(3_0_0_0_65) \ PS(3_0_0_13_22) \ PS(3_0_0_13_61) \ PS(3_0_0_22_13) \ PS(3_0_0_22_22) \ PS(3_0_0_22_62) \ PS(3_0_0_22_65) \ PS(3_0_0_23_23) \ PS(3_0_0_40000065_13) \ PS(3_0_0_56_13) \ PS(3_0_0_62_13) \ PS(3_0_0_64_13) \ PS(3_0_0_65_13) \ PS(3_0_0_65_22) \ PS(3_0_0_65_83) \ PS(3_0_0_83_13) \ PS(3_0_22_22_22) \ PS(3_1_0_0_22) \ PS(3_1_0_0_65) \ PS(3_1_0_13_22) \ PS(3_1_0_13_61) \ PS(3_1_0_22_13) \ PS(3_1_0_22_22) \ PS(3_1_0_22_62) \ PS(3_1_0_22_65) \ PS(3_1_0_23_23) \ PS(3_1_0_40000065_13) \ PS(3_1_0_56_13) \ PS(3_1_0_62_13) \ PS(3_1_0_64_13) \ PS(3_1_0_65_13) \ PS(3_1_0_65_22) \ PS(3_1_0_65_83) \ PS(3_1_0_83_13) \ PS(3_1_22_22_22) \ PS(3_2_22_22_22) \ PS(3_3_22_22_22) \ PS(4_0_0_0_40000062_83) \ PS(4_0_0_13_22_22) \ PS(4_0_0_13_65_65) \ PS(4_0_0_22_22_13) \ PS(4_0_0_22_65_13) \ PS(4_0_0_22_65_83) \ PS(4_0_0_51_52_13) \ PS(4_0_0_53_22_13) \ PS(4_0_0_56_13_22) \ PS(4_0_0_56_56_13) \ PS(4_0_0_62_13_22) \ PS(4_0_0_65_13_22) \ PS(4_0_0_65_22_62) \ PS(4_0_0_65_65_22) \ PS(4_0_0_65_65_83) \ PS(4_0_22_22_22_22) \ PS(4_0_25_25_25_25) \ PS(4_0_40000000_65_13_13) \ PS(4_1_0_0_40000062_83) \ PS(4_1_0_13_22_22) \ PS(4_1_0_13_65_65) \ PS(4_1_0_22_22_13) \ PS(4_1_0_22_65_13) \ PS(4_1_0_22_65_83) \ PS(4_1_0_51_52_13) \ PS(4_1_0_53_22_13) \ PS(4_1_0_56_13_22) \ PS(4_1_0_56_56_13) \ PS(4_1_0_62_13_22) \ PS(4_1_0_65_13_22) \ PS(4_1_0_65_22_62) \ PS(4_1_0_65_65_22) \ PS(4_1_0_65_65_83) \ PS(4_1_22_22_22_22) \ PS(4_1_25_25_25_25) \ PS(4_1_40000000_65_13_13) \ PS(4_2_25_25_25_25) \ PS(4_3_25_25_25_25) \ PS(5_0_0_13_22_22_22) \ PS(5_0_0_22_22_13_22) \ PS(5_0_0_22_22_22_40000065) \ PS(5_0_0_22_22_65_83) \ PS(5_0_0_22_23_65_83) \ PS(5_0_0_22_65_83_22) \ PS(5_0_0_65_13_22_22) \ PS(5_0_0_65_13_22_25) \ PS(5_0_22_22_22_22_22) \ PS(5_1_0_13_22_22_22) \ PS(5_1_0_22_22_13_22) \ PS(5_1_0_22_22_22_40000065) \ PS(5_1_0_22_22_65_83) \ PS(5_1_0_22_23_65_83) \ PS(5_1_0_22_65_83_22) \ PS(5_1_0_65_13_22_22) \ PS(5_1_0_65_13_22_25) \ PS(5_1_22_22_22_22_22) \ PS(5_2_22_22_22_22_22) \ PS(5_3_22_22_22_22_22) \ PS(6_0_0_22_22_22_65_13) \ PS(6_1_0_22_22_22_65_13) struct UberPixelShaderState { int stageStates[8] = {}; int stageCount = 0; int globalState = 0; // bit mask of UBERPS_*_BIT macros }; #define UBERPS_DITHER_BIT 1 #define UBERPS_DEPTHFADE_BIT 2 static bool ParseUberPixelShaderState(UberPixelShaderState& state, const char* stateString) { const char* scanStrings[8] = { "%X_%X", "%X_%X_%X", "%X_%X_%X_%X", "%X_%X_%X_%X_%X", "%X_%X_%X_%X_%X_%X", "%X_%X_%X_%X_%X_%X_%X", "%X_%X_%X_%X_%X_%X_%X_%X", "%X_%X_%X_%X_%X_%X_%X_%X_%X" }; if(sscanf(stateString, "%d", &state.stageCount) != 1 || state.stageCount < 1 || state.stageCount > 8) { return false; } stateString += 2; const char* scanString = scanStrings[state.stageCount - 1]; if(sscanf(stateString, scanString, &state.globalState, &state.stageStates[0], &state.stageStates[1], &state.stageStates[2], &state.stageStates[3], &state.stageStates[4], &state.stageStates[5], &state.stageStates[6], &state.stageStates[7]) != state.stageCount + 1) { return false; } return true; }