/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sw_local.h" /* ** Start Added by Lewey ** ** This is where the real SIRDS code is */ //width of the repeating pattern. Increasing this will //increase the quality of the SIRD by giving it more //height levels. // //Make sure: ((R_SIRDw % 3) == 0) // && (((R_SIRDw / 3) % R_SIRDExponents) == 0) #define R_SIRDw 144 //height of the repeating pattern (not really important) #define R_SIRDh 50 //maximum offset. This is the max number of pixels //an item can be moved due to it's height, this is //is also obviously then the number of different //height layers you can have. A large R_SIRDw will //make it harder and harder to see the image, a larger //ratio of R_SIRDw (i.e. less than 3) will eventually //cause your eyes to be unable to see the pattern. #define R_SIRDmaxDiff (R_SIRDw / 3) //the number of lower powers to ignore #define R_SIRDIgnoreExponents 5 //the number of exponents (after ignored ones) to have different //height values (ones after it are rounded to the max difference) #define R_SIRDExponents 6 //the number of height levels each exponent is given #define R_SIRDstepsPerExponent (R_SIRDmaxDiff / R_SIRDExponents) //this is the z value of the sky, which logically should be 0, but //for implimentation reasons is made very high. Not my doing by the //way. If you move to a different platform, you may need to change this #define R_SIRD_ZofSky 0x8ccc //this is the number of random numbers //defined in "rand1k.h" #define R_SIRDnumRand 103 //this hold the background pattern byte r_SIRDBackground[R_SIRDw * R_SIRDh]; //these are the actual random numbers byte r_SIRDrandValues[] = { #include "rand1k.h" }; //Only used if id386 is false, this acts as a // reverse bit-scanner, and uses a sort of binary // search to find the index of the highest set bit. //You could also expand the loop 4 times to remove // the 'while' #if !id386 || !( defined _MSC_VER ) int UShortLog(int val) { int mask = 0xff00; int p = 0; int b = 8; while (b) { if (val & mask) { p += b; b >>= 1; mask &= (mask << b); } else { mask &= (mask << (b >> 1)); mask >>= b; b >>= 1; } } return p; } #endif int R_SIRDZFunc(int sub) { int e; //special case the sky. if (sub == R_SIRD_ZofSky) return 0; #if id386 && ( defined _MSC_VER ) e = sub; //calculate the log (base 2) of the number. In other //words the index of the highest set bit. bsr is undefined //if it's input is 0, so special case that. if (e!=0) { __asm { mov ebx, e bsr eax, ebx mov e, eax } } #else e = UShortLog(sub); #endif //clip the exponent if (e < R_SIRDIgnoreExponents) return 0; // based on the power, shift the z so that // it's as high as it can get while still staying // under 0x100 if (e > 8) { sub >>= (e-8); } else { if (e < 8) { sub <<= (8-e); } } // Lower the power of the number, this helps scaling and removes // small z values. e -= R_SIRDIgnoreExponents; // contruct the height value. The power is used as the primary calculator, // and then the extra bits are used to offset. In this way you // get more detail than just the log of the z value, and it works // as a pretty good approximation of it. e *= R_SIRDstepsPerExponent; e += ((sub * R_SIRDstepsPerExponent) >> 8); //make sure we stay under maximum height. return ((e<=R_SIRDmaxDiff)? e : R_SIRDmaxDiff ); } void R_ApplySIRDAlgorithum( void ) { short* curz, *oldz; short cz = 0, lastz = 0; byte* curp; byte* curbp, j = 0; int x, y, i, zinc, k; int mode = sw_drawsird->integer; //note of interest: I've made this static so that //if you like you could make it not static and see //what would happen if you didn't change the background static int ji = 0; //create the background image to tile //basically done by shifting the values around //each time and xoring them with a randomly //selected pixel for (i=0; i=0; y--) { curz = (d_pzbuffer + (vid.width * y)); oldz = (d_pzbuffer + (vid.width * ((y*WARP_HEIGHT)/vid.height) )); k = (zinc * (vid.width-1)); for (x=vid.width-1; x>=0; x--) { curz[x] = oldz[k >> 16]; k -= zinc; } } } //SIRDify each line for (y=0; y