mirror of
https://github.com/id-Software/Wolf3D-iOS.git
synced 2026-03-19 16:39:49 +01:00
519 lines
12 KiB
C
519 lines
12 KiB
C
/*
|
|
|
|
Copyright (C) 2004 Michael Liebscher
|
|
Copyright (C) 2000-2002 by DarkOne the Hacker
|
|
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.
|
|
|
|
*/
|
|
|
|
/*
|
|
* wolf_opengl.c: Wolfenstein3-D OpenGL renderer.
|
|
*
|
|
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
|
* Date: 2004
|
|
*
|
|
* Acknowledgement:
|
|
* Portion of this code was derived from NewWolf, and was originally
|
|
* written by DarkOne the Hacker.
|
|
*
|
|
* Portion of this code was derived from Quake II, and was originally
|
|
* written by Id Software, Inc.
|
|
*
|
|
*/
|
|
|
|
#include "../wolfiphone.h"
|
|
|
|
// width and height in 2D
|
|
#define WIDTH_2D 640
|
|
#define HEIGHT_2D 480
|
|
|
|
|
|
|
|
|
|
/*
|
|
-----------------------------------------------------------------------------
|
|
Function:
|
|
|
|
Parameters:
|
|
|
|
Returns:
|
|
|
|
Notes:
|
|
|
|
-----------------------------------------------------------------------------
|
|
*/
|
|
PUBLIC void GL_SetDefaultState( void )
|
|
{
|
|
pfglClearColor( 1,0, 0.5 , 0.5 );
|
|
pfglCullFace( GL_FRONT );
|
|
pfglEnable( GL_TEXTURE_2D );
|
|
pfglDisable( GL_DEPTH_TEST );
|
|
pfglDisable( GL_CULL_FACE );
|
|
pfglDisable( GL_BLEND );
|
|
pfglColor4f( 1, 1, 1, 1 );
|
|
pfglShadeModel( GL_FLAT );
|
|
pfglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
-----------------------------------------------------------------------------
|
|
Function:
|
|
|
|
Parameters:
|
|
|
|
Returns:
|
|
|
|
Notes:
|
|
|
|
-----------------------------------------------------------------------------
|
|
*/
|
|
PUBLIC void R_DrawBox( int x, int y, int w, int h, W32 color )
|
|
{
|
|
pfglDisable( GL_TEXTURE_2D );
|
|
|
|
// pfglEnable( GL_BLEND );
|
|
// pfglBlendFunc( GL_SRC_COLOR, GL_DST_COLOR );
|
|
|
|
pfglColor4ubv( (GLubyte *) & color );
|
|
|
|
pfglBegin( GL_QUADS );
|
|
|
|
pfglVertex2i( x, y );
|
|
pfglVertex2i( x, y + h);
|
|
pfglVertex2i( x + w, y + h );
|
|
pfglVertex2i( x + w, y );
|
|
|
|
pfglEnd();
|
|
|
|
pfglColor3f( 1, 1, 1 );
|
|
// pfglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
|
// pfglDisable( GL_BLEND );
|
|
pfglEnable( GL_TEXTURE_2D );
|
|
}
|
|
|
|
|
|
/*
|
|
====================
|
|
LoadWallTexture
|
|
|
|
Returns with the texture bound and glColor set to the right intensity.
|
|
Loads an image from the filesystem if necessary.
|
|
Used both during gameplay and for preloading during level parse.
|
|
|
|
Wolfenstein was very wasteful with texture usage, making almost half of
|
|
the textures just dim versions to provide "lighting" on the different
|
|
wall sides. With only a few exceptions for things like the elevator tiles
|
|
and outdoor tiles that could only be used in particular orientations
|
|
====================
|
|
*/
|
|
float wallBrightness[1000];
|
|
void LoadWallTexture( int wallPicNum ) {
|
|
assert( wallPicNum >= 0 && wallPicNum < 1000 );
|
|
texture_t *twall = wallTextures[wallPicNum];
|
|
if ( !twall ) {
|
|
if ( ( wallPicNum & 1 ) &&
|
|
wallPicNum != 31 &&
|
|
wallPicNum != 41 &&
|
|
wallPicNum != 43 &&
|
|
wallPicNum != 133 ) {
|
|
// this wallPicNum is just a dim version of another image
|
|
|
|
// load the brighter version
|
|
LoadWallTexture( wallPicNum - 1 );
|
|
// use the same texture
|
|
twall = wallTextures[wallPicNum] = wallTextures[wallPicNum - 1];
|
|
// at a dimmer intensity
|
|
wallBrightness[wallPicNum] = 0.7f;
|
|
} else {
|
|
// this wallPicNum has a real image associated with it
|
|
char name[1024];
|
|
my_snprintf( name, sizeof( name ), "walls/%.3d.tga", wallPicNum );
|
|
twall = wallTextures[wallPicNum] = TM_FindTexture( name, TT_Wall );
|
|
wallBrightness[wallPicNum] = 1.0f;
|
|
}
|
|
}
|
|
|
|
R_Bind( twall->texnum );
|
|
|
|
// almost half of the walls are just slightly dimmer versions of
|
|
// the "bright side", and are not stored as separate textures
|
|
float f = wallBrightness[wallPicNum];
|
|
pfglColor3f( f, f, f );
|
|
}
|
|
|
|
/*
|
|
-----------------------------------------------------------------------------
|
|
Function:
|
|
|
|
Parameters:
|
|
|
|
Returns:
|
|
|
|
Notes:
|
|
|
|
north (y)
|
|
__________
|
|
| |
|
|
west (x) | | east (x)
|
|
|________|
|
|
south (y)
|
|
|
|
-----------------------------------------------------------------------------
|
|
*/
|
|
PUBLIC void R_Draw_Wall( float x, float y, float z1, float z2, int type, int tex )
|
|
{
|
|
float x1, x2, y1, y2;
|
|
|
|
switch( type )
|
|
{
|
|
// X wall
|
|
case dir4_east:
|
|
x1 = x2 = x + 1;
|
|
y1 = -1 - y;
|
|
y2 = -y;
|
|
break;
|
|
|
|
case dir4_west:
|
|
x1 = x2 = x;
|
|
y1 = -y;
|
|
y2 = -1 - y;
|
|
break;
|
|
|
|
// Y wall
|
|
case dir4_north:
|
|
y1 = y2 = -y - 1;
|
|
x1 = x;
|
|
x2 = x + 1;
|
|
break;
|
|
|
|
case dir4_south:
|
|
y1 = y2 = -y;
|
|
x1 = x + 1;
|
|
x2 = x;
|
|
break;
|
|
}
|
|
|
|
LoadWallTexture( tex );
|
|
|
|
pfglBegin( GL_QUADS );
|
|
|
|
pfglTexCoord2f( 1.0, 0.0 ); pfglVertex3f( x1, z2, y1 );
|
|
pfglTexCoord2f( 0.0, 0.0 ); pfglVertex3f( x2, z2, y2 );
|
|
pfglTexCoord2f( 0.0, 1.0 ); pfglVertex3f( x2, z1, y2 );
|
|
pfglTexCoord2f( 1.0, 1.0 ); pfglVertex3f( x1, z1, y1 );
|
|
|
|
pfglEnd();
|
|
}
|
|
|
|
/*
|
|
-----------------------------------------------------------------------------
|
|
Function:
|
|
|
|
Parameters:
|
|
|
|
Returns:
|
|
|
|
Notes:
|
|
|
|
-----------------------------------------------------------------------------
|
|
*/
|
|
PUBLIC void R_Draw_Door( int x, int y, float z1, float z2, _boolean vertical, _boolean backside, int tex, int amount )
|
|
{
|
|
float x1, x2, y1, y2, amt;
|
|
|
|
if( amount == DOOR_FULLOPEN )
|
|
{
|
|
return;
|
|
}
|
|
|
|
amt = (float)amount / DOOR_FULLOPEN;
|
|
|
|
|
|
if( vertical )
|
|
{
|
|
x1 = x2 = (float)x + 0.5f;
|
|
y1 = -((float)y - amt);
|
|
y2 = -((float)y - amt); // -1
|
|
if( backside )
|
|
{
|
|
y1 -= 1;
|
|
}
|
|
else
|
|
{
|
|
y2 -= 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
y1 = y2 = -(float)y - 0.5f;
|
|
x1 = (float)x + amt; // +1
|
|
x2 = (float)x + amt;
|
|
if( backside )
|
|
{
|
|
x2 += 1;
|
|
}
|
|
else
|
|
{
|
|
x1 += 1;
|
|
}
|
|
}
|
|
|
|
LoadWallTexture( tex );
|
|
|
|
pfglBegin( GL_QUADS );
|
|
|
|
pfglTexCoord2f( backside ? 0.0f : 1.0f, 0.0 ); pfglVertex3f( x1, z2, y1 );
|
|
pfglTexCoord2f( backside ? 1.0f : 0.0f, 0.0 ); pfglVertex3f( x2, z2, y2 );
|
|
pfglTexCoord2f( backside ? 1.0f : 0.0f, 1.0 ); pfglVertex3f( x2, z1, y2 );
|
|
pfglTexCoord2f( backside ? 0.0f : 1.0f, 1.0 ); pfglVertex3f( x1, z1, y1 );
|
|
|
|
pfglEnd();
|
|
}
|
|
|
|
|
|
/*
|
|
-----------------------------------------------------------------------------
|
|
Function: R_DrawSprites -Draws all visible sprites.
|
|
|
|
Parameters: Nothing.
|
|
|
|
Returns: Nothing.
|
|
|
|
Notes:
|
|
|
|
-----------------------------------------------------------------------------
|
|
*/
|
|
PUBLIC void R_DrawSprites( void )
|
|
{
|
|
float sina, cosa;
|
|
float Ex, Ey, Dx, Dy;
|
|
int n_sprt, n, ang;
|
|
texture_t *twall;
|
|
extern cvar_t *cropSprites;
|
|
|
|
// build visible sprites list
|
|
n_sprt = Sprite_CreateVisList();
|
|
if( ! n_sprt )
|
|
{
|
|
return; // nothing to draw
|
|
}
|
|
|
|
// prepare values for billboarding
|
|
ang = NormalizeAngle( Player.position.angle + ANG_90 );
|
|
sina = (float)(0.5 * SinTable[ ang ]);
|
|
cosa = (float)(0.5 * CosTable[ ang ]);
|
|
|
|
pfglEnable( GL_BLEND );
|
|
qglDepthMask( GL_FALSE );
|
|
for( n = 0; n < n_sprt; ++n )
|
|
{
|
|
int texnum = vislist[ n ].tex;
|
|
if( vislist[ n ].dist < MINDIST / 2 )
|
|
{
|
|
continue; // little hack to save speed & z-buffer
|
|
}
|
|
|
|
|
|
|
|
assert( texnum >= 0 && texnum < 1000 );
|
|
twall = spriteTextures[texnum];
|
|
if ( !twall ) {
|
|
char name[1024];
|
|
my_snprintf( name, sizeof( name ), "%s/%.3d.tga", spritelocation, (vislist[ n ].tex) );
|
|
twall = spriteTextures[texnum] = TM_FindTexture( name, TT_Wall );
|
|
}
|
|
R_Bind( twall->texnum );
|
|
|
|
pfglBegin( GL_QUADS );
|
|
|
|
if ( cropSprites->value && twall->header.numBounds > 0 ) {
|
|
// draw one or two subrects to avoid blending all the empty space
|
|
int b;
|
|
|
|
for ( b = 0 ; b < twall->header.numBounds ; b++ ) {
|
|
// include a bit extra for filtering
|
|
float x1 = (float)(twall->header.bounds[b][0][0]-1) / (twall->header.uploadWidth-1);
|
|
float y1 = (float)(twall->header.bounds[b][0][1]-1) / (twall->header.uploadHeight-1);
|
|
float x2 = (float)(twall->header.bounds[b][1][0]+1) / (twall->header.uploadWidth-1);
|
|
float y2 = (float)(twall->header.bounds[b][1][1]+1) / (twall->header.uploadHeight-1);
|
|
if ( x1 < 0 ) {
|
|
x1 = 0;
|
|
} else if ( x2 > 1.0 ) {
|
|
x2 = 1.0;
|
|
}
|
|
if ( y1 < 0 ) {
|
|
y1 = 0;
|
|
} else if ( y2 > 1.0 ) {
|
|
y2 = 1.0;
|
|
}
|
|
Ex = vislist[ n ].x / FLOATTILE + cosa;
|
|
Ey = vislist[ n ].y / FLOATTILE + sina;
|
|
|
|
pfglTexCoord2f( x1, y1 ); pfglVertex3f( Ex - x1 * 2*cosa, -(LOWERZCOORD + (UPPERZCOORD - LOWERZCOORD) * y1), -Ey + x1 * 2*sina );
|
|
pfglTexCoord2f( x1, y2 ); pfglVertex3f( Ex - x1 * 2*cosa, -(LOWERZCOORD + (UPPERZCOORD - LOWERZCOORD) * y2), -Ey + x1 * 2*sina );
|
|
pfglTexCoord2f( x2, y2 ); pfglVertex3f( Ex - x2 * 2*cosa, -(LOWERZCOORD + (UPPERZCOORD - LOWERZCOORD) * y2), -Ey + x2 * 2*sina );
|
|
pfglTexCoord2f( x2, y1 ); pfglVertex3f( Ex - x2 * 2*cosa, -(LOWERZCOORD + (UPPERZCOORD - LOWERZCOORD) * y1), -Ey + x2 * 2*sina );
|
|
}
|
|
} else {
|
|
Ex = Dx = vislist[ n ].x / FLOATTILE;
|
|
Ey = Dy = vislist[ n ].y / FLOATTILE;
|
|
Ex += cosa; Ey += sina;
|
|
Dx -= cosa; Dy -= sina;
|
|
|
|
pfglTexCoord2f( 0.0, 0.0 ); pfglVertex3f( Ex, UPPERZCOORD, -Ey );
|
|
pfglTexCoord2f( 0.0, 1.0 ); pfglVertex3f( Ex, LOWERZCOORD, -Ey );
|
|
pfglTexCoord2f( 1.0, 1.0 ); pfglVertex3f( Dx, LOWERZCOORD, -Dy );
|
|
pfglTexCoord2f( 1.0, 0.0 ); pfglVertex3f( Dx, UPPERZCOORD, -Dy );
|
|
}
|
|
|
|
pfglEnd();
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
-----------------------------------------------------------------------------
|
|
Function:
|
|
|
|
Parameters:
|
|
|
|
Returns:
|
|
|
|
Notes:
|
|
|
|
-----------------------------------------------------------------------------
|
|
*/
|
|
PUBLIC void R_DrawNumber( int x, int y, int number )
|
|
{
|
|
texture_t *tex;
|
|
int col;
|
|
float fcol;
|
|
static float w = 0.1f;
|
|
int i;
|
|
char string[ 20 ];
|
|
W32 length;
|
|
|
|
|
|
my_snprintf( string, sizeof( string ), "%d", number );
|
|
length = strlen( string );
|
|
|
|
tex = TM_FindTexture( "pics/N_NUMPIC.tga", TT_Pic );
|
|
|
|
|
|
pfglEnable( GL_TEXTURE_2D );
|
|
|
|
R_Bind( tex->texnum );
|
|
|
|
pfglBegin( GL_QUADS );
|
|
|
|
for( i = length-1 ; i >= 0 ; --i )
|
|
{
|
|
col = string[ i ] - 48;
|
|
|
|
fcol = col * w;
|
|
|
|
pfglTexCoord2f( fcol, 0 ); pfglVertex2i( x, y );
|
|
pfglTexCoord2f( fcol+w, 0 ); pfglVertex2i( x+18, y );
|
|
pfglTexCoord2f( fcol+w, 1 ); pfglVertex2i( x+18, y+32 );
|
|
pfglTexCoord2f( fcol, 1 ); pfglVertex2i( x, y+32 );
|
|
|
|
x -= 18;
|
|
}
|
|
|
|
pfglEnd();
|
|
|
|
}
|
|
|
|
|
|
W8 wfont[ ] = {
|
|
32, 15, 32, 32, 32, 32, 32, 12, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 16, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32 };
|
|
|
|
/*
|
|
-----------------------------------------------------------------------------
|
|
Function:
|
|
|
|
Parameters:
|
|
|
|
Returns:
|
|
|
|
Notes:
|
|
|
|
-----------------------------------------------------------------------------
|
|
*/
|
|
PUBLIC void R_put_line( int x, int y, const char *string )
|
|
{
|
|
texture_t *tex;
|
|
int mx = x;
|
|
int num;
|
|
float frow, fcol;
|
|
static float h = 0.25f; // (32 / 128.0f);
|
|
static float w = 0.0625f; // (32 / 512.0f);
|
|
|
|
|
|
tex = TM_FindTexture( "pics/L_FONTPIC.tga", TT_Pic );
|
|
|
|
|
|
R_Bind( tex->texnum );
|
|
|
|
pfglBegin( GL_QUADS );
|
|
|
|
while( *string )
|
|
{
|
|
if( *string == '\n' )
|
|
{
|
|
mx = x;
|
|
y += 32;
|
|
++string;
|
|
continue;
|
|
}
|
|
|
|
num = *string;
|
|
|
|
num &= 255;
|
|
|
|
if( (num & 127) == 32 )
|
|
{
|
|
mx += 32;
|
|
++string;
|
|
continue; // space
|
|
}
|
|
|
|
|
|
frow = ((num >> 4) - 2) * h;
|
|
fcol = (num & 15) * w;
|
|
|
|
|
|
pfglTexCoord2f( fcol, frow ); pfglVertex2i( mx, y );
|
|
pfglTexCoord2f( fcol+w, frow ); pfglVertex2i( mx+32, y );
|
|
pfglTexCoord2f( fcol+w, frow+h ); pfglVertex2i( mx+32, y+32 );
|
|
pfglTexCoord2f( fcol, frow+h ); pfglVertex2i( mx, y+32 );
|
|
|
|
|
|
|
|
mx += wfont[ (num & 127) - 32 ];
|
|
++string;
|
|
}
|
|
|
|
pfglEnd();
|
|
}
|
|
|