Quake II RTX doxygen
1.0 dev
sird.c
Go to the documentation of this file.
1
/*
2
Copyright (C) 1997-2001 Id Software, Inc.
3
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or
7
(at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
13
14
You should have received a copy of the GNU General Public License along
15
with this program; if not, write to the Free Software Foundation, Inc.,
16
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
*/
18
19
#include "
sw.h
"
20
21
/*
22
** Start Added by Lewey
23
**
24
** This is where the real SIRDS code is
25
*/
26
27
//width of the repeating pattern. Increasing this will
28
//increase the quality of the SIRD by giving it more
29
//height levels.
30
//
31
//Make sure: ((R_SIRDw % 3) == 0)
32
// && (((R_SIRDw / 3) % R_SIRDExponents) == 0)
33
#define R_SIRDw 144
34
35
//height of the repeating pattern (not really important)
36
#define R_SIRDh 50
37
38
//maximum offset. This is the max number of pixels
39
//an item can be moved due to it's height, this is
40
//is also obviously then the number of different
41
//height layers you can have. A large R_SIRDw will
42
//make it harder and harder to see the image, a larger
43
//ratio of R_SIRDw (i.e. less than 3) will eventually
44
//cause your eyes to be unable to see the pattern.
45
#define R_SIRDmaxDiff (R_SIRDw / 3)
46
47
//the number of lower powers to ignore
48
#define R_SIRDIgnoreExponents 5
49
50
//the number of exponents (after ignored ones) to have different
51
//height values (ones after it are rounded to the max difference)
52
#define R_SIRDExponents 6
53
54
//the number of height levels each exponent is given
55
#define R_SIRDstepsPerExponent (R_SIRDmaxDiff / R_SIRDExponents)
56
57
//this is the z value of the sky, which logically should be 0, but
58
//for implimentation reasons is made very high. Not my doing by the
59
//way. If you move to a different platform, you may need to change this
60
#define R_SIRD_ZofSky 0x8ccc
61
62
//this is the number of random numbers
63
//defined in "rand1k.h"
64
#define R_SIRDnumRand 103
65
66
//this hold the background pattern
67
static
byte
r_SIRDBackground
[
R_SIRDw
*
R_SIRDh
*
VID_BYTES
];
68
69
//these are the actual random numbers
70
static
const
byte
r_SIRDrandValues
[] = {
71
#include "
rand1k.h
"
72
};
73
74
75
//Only used if id386 is false, this acts as a
76
// reverse bit-scanner, and uses a sort of binary
77
// search to find the index of the highest set bit.
78
//You could also expand the loop 4 times to remove
79
// the 'while'
80
#if !id386 || !(defined _MSC_VER)
81
static
int
UShortLog
(
int
val)
82
{
83
int
mask = 0xff00;
84
int
p = 0;
85
int
b = 8;
86
while
(b) {
87
if
(val & mask) {
88
p += b;
89
b >>= 1;
90
mask &= (mask << b);
91
}
else
{
92
mask &= (mask << (b >> 1));
93
mask >>= b;
94
b >>= 1;
95
}
96
}
97
return
p;
98
}
99
#endif
100
101
static
int
R_SIRDZFunc
(
int
sub)
102
{
103
int
e;
104
105
//special case the sky.
106
if
(sub ==
R_SIRD_ZofSky
)
107
return
0;
108
109
#if id386 && (defined _MSC_VER)
110
e = sub;
111
//calculate the log (base 2) of the number. In other
112
//words the index of the highest set bit. bsr is undefined
113
//if it's input is 0, so special case that.
114
if
(e != 0) {
115
__asm {
116
mov ebx, e
117
bsr eax, ebx
118
mov e, eax
119
}
120
}
121
#else
122
e =
UShortLog
(sub);
123
#endif
124
125
//clip the exponent
126
if
(e <
R_SIRDIgnoreExponents
)
127
return
0;
128
129
// based on the power, shift the z so that
130
// it's as high as it can get while still staying
131
// under 0x100
132
if
(e > 8) {
133
sub >>= (e - 8);
134
}
else
{
135
if
(e < 8) {
136
sub <<= (8 - e);
137
}
138
}
139
140
// Lower the power of the number, this helps scaling and removes
141
// small z values.
142
e -=
R_SIRDIgnoreExponents
;
143
144
// contruct the height value. The power is used as the primary calculator,
145
// and then the extra bits are used to offset. In this way you
146
// get more detail than just the log of the z value, and it works
147
// as a pretty good approximation of it.
148
e *=
R_SIRDstepsPerExponent
;
149
e += ((sub *
R_SIRDstepsPerExponent
) >> 8);
150
151
//make sure we stay under maximum height.
152
return
((e <=
R_SIRDmaxDiff
) ? e :
R_SIRDmaxDiff
);
153
}
154
155
void
R_ApplySIRDAlgorithum
(
void
)
156
{
157
short
* curz, *oldz;
158
short
cz = 0, lastz = 0;
159
byte
* curp;
160
byte
* curbp, j = 0;
161
int
x, y, i, zinc, k;
162
int
mode =
sw_drawsird
->integer;
163
164
//note of interest: I've made this static so that
165
//if you like you could make it not static and see
166
//what would happen if you didn't change the background
167
static
int
ji = 0;
168
169
//create the background image to tile
170
//basically done by shifting the values around
171
//each time and xoring them with a randomly
172
//selected pixel
173
for
(i = 0; i <
R_SIRDw
*
R_SIRDh
*
VID_BYTES
; i++) {
174
if
((i %
R_SIRDnumRand
) == 0) {
175
ji++;
176
ji %=
R_SIRDnumRand
;
177
j =
r_SIRDrandValues
[
r_SIRDrandValues
[ji] %
R_SIRDnumRand
];
178
}
179
r_SIRDBackground
[i] =
r_SIRDrandValues
[(i %
R_SIRDnumRand
) ] ^ j;
180
}
181
182
//if we are under water:
183
if
((
r_dowarp
) && (
vid
.
width
!=
WARP_WIDTH
)) {
184
//the rendering is only in the top left
185
//WARP_WIDTH by WARP_HEIGHT area, so scale the z-values
186
//to span over the whole screen
187
188
189
//why are we going backwards? so that we don't write over the
190
//values before we read from them
191
192
zinc = ((
WARP_WIDTH
* 0x10000) /
vid
.
width
);
193
for
(y =
vid
.
height
- 1; y >= 0; y--) {
194
curz = (
d_pzbuffer
+ (
vid
.
width
* y));
195
oldz = (
d_pzbuffer
+ (
vid
.
width
* ((y *
WARP_HEIGHT
) /
vid
.
height
)));
196
k = (zinc * (
vid
.
width
- 1));
197
198
for
(x =
vid
.
width
- 1; x >= 0; x--) {
199
curz[x] = oldz[k >> 16];
200
k -= zinc;
201
}
202
}
203
}
204
205
206
//SIRDify each line
207
for
(y = 0; y <
vid
.
height
; y++) {
208
curp = (
vid
.
buffer
+ (
vid
.
rowbytes
* y));
209
curz = (
d_pzbuffer
+ (
vid
.
width
* y));
210
211
if
(mode != 3) {
212
// draw the SIRD
213
214
// copy the background into the left most column
215
curbp = &(
r_SIRDBackground
[
R_SIRDw
* (y %
R_SIRDh
) ]);
216
for
(x = 0; x <
R_SIRDw
; x++) {
217
curp[0] = curbp[0];
218
curp[1] = curbp[1];
219
curp[2] = curbp[2];
220
221
curp +=
VID_BYTES
;
222
curbp +=
VID_BYTES
;
223
}
224
225
lastz = 0;
226
cz = 0;
227
curz +=
R_SIRDw
;
228
curbp = curp -
R_SIRDw
*
VID_BYTES
;
229
230
// now calculate the SIRD
231
for
(x =
R_SIRDw
; x <
vid
.
width
; x++) {
232
//only call the z-function with a new
233
//value, it is slow so this saves quite
234
//some time.
235
if
(lastz != *curz) {
236
lastz = *curz;
237
238
//convert from z to height offset
239
cz = (mode == 2) ?
R_SIRDmaxDiff
-
R_SIRDZFunc
(lastz) :
R_SIRDZFunc
(lastz);
240
241
//the "height offset" used in making SIRDS
242
//can be considered an adjustment of the
243
//frequency of repetition in the pattern.
244
//so here we are copying from bp to p, and so
245
//it simply increases or decreases the distance
246
//between the two.
247
curbp = (curp -
R_SIRDw
*
VID_BYTES
+ cz *
VID_BYTES
);
248
}
249
250
curp[0] = curbp[0];
251
curp[1] = curbp[1];
252
curp[2] = curbp[2];
253
254
curp +=
VID_BYTES
;
255
curbp +=
VID_BYTES
;
256
curz++;
257
}
258
}
else
{
259
//if we are just drawing the height map
260
//this lets you see which layers are used to
261
//create the SIRD
262
//
263
//NOTE: even though it may sort of look like
264
//a grey-scale height map, that is merely a
265
//coincidence because of how the colours are
266
//organized in the pallette.
267
268
for
(x = 0; x <
vid
.
width
; x++) {
269
if
(lastz != *curz) {
270
lastz = *curz;
271
cz =
R_SIRDZFunc
(*curz);
272
}
273
274
curp[0] = cz;
275
curp[1] = cz;
276
curp[2] = cz;
277
278
curp +=
VID_BYTES
;
279
curz++;
280
}
281
}
282
}
283
}
284
285
/*
286
** End Added by Lewey
287
*/
viddef_t::buffer
pixel_t * buffer
Definition:
sw.h:124
r_SIRDBackground
static byte r_SIRDBackground[R_SIRDw *R_SIRDh *VID_BYTES]
Definition:
sird.c:67
viddef_t::width
int width
Definition:
sw.h:127
viddef_t::height
int height
Definition:
sw.h:128
UShortLog
static int UShortLog(int val)
Definition:
sird.c:81
r_dowarp
qboolean r_dowarp
Definition:
main.c:40
R_SIRDIgnoreExponents
#define R_SIRDIgnoreExponents
Definition:
sird.c:48
r_SIRDrandValues
static const byte r_SIRDrandValues[]
Definition:
sird.c:70
WARP_WIDTH
#define WARP_WIDTH
Definition:
sw.h:64
viddef_t::rowbytes
int rowbytes
Definition:
sw.h:125
sw.h
R_SIRDstepsPerExponent
#define R_SIRDstepsPerExponent
Definition:
sird.c:55
R_ApplySIRDAlgorithum
void R_ApplySIRDAlgorithum(void)
Definition:
sird.c:155
R_SIRD_ZofSky
#define R_SIRD_ZofSky
Definition:
sird.c:60
R_SIRDh
#define R_SIRDh
Definition:
sird.c:36
R_SIRDmaxDiff
#define R_SIRDmaxDiff
Definition:
sird.c:45
VID_BYTES
#define VID_BYTES
Definition:
sw.h:49
R_SIRDZFunc
static int R_SIRDZFunc(int sub)
Definition:
sird.c:101
rand1k.h
R_SIRDw
#define R_SIRDw
Definition:
sird.c:33
d_pzbuffer
short * d_pzbuffer
Definition:
main.c:127
WARP_HEIGHT
#define WARP_HEIGHT
Definition:
sw.h:65
R_SIRDnumRand
#define R_SIRDnumRand
Definition:
sird.c:64
sw_drawsird
cvar_t * sw_drawsird
Definition:
main.c:93
vid
viddef_t vid
Definition:
main.c:22
src
refresh
sw
sird.c
Generated by
1.8.17