ew-engine/mq engine src/gl_rscript.c

335 lines
7.7 KiB
C

/*
Copyright (C) 1996-1997 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.
*/
/*
RScript loading, parsing, and rendering.
Code syntax is similar to that of shaders
No reference to any shader material was used whilst
making this code, hence the weak and buggy state of it :)
*/
#include "quakedef.h"
#include "gl_rscript.h"
#include "bsp_render.h"
typedef struct
{
int texnum;
float sl, tl, sh, th;
} glpic_t;
extern int lightmap_textures;
extern glpoly_t *lightmap_polys[MAX_LIGHTMAPS];
extern qboolean lightmap_modified[MAX_LIGHTMAPS];
extern glRect_t lightmap_rectchange[MAX_LIGHTMAPS];
extern byte lightmaps[4*MAX_LIGHTMAPS*BLOCK_WIDTH*BLOCK_HEIGHT];
int RS_AnimTexture(int rs)
{
double rt;
if (host_time < rscripts[rs].anim.lasttime)
rscripts[rs].anim.lasttime = 0;
rt = host_time - rscripts[rs].anim.lasttime;
if (rt < rscripts[rs].flags.animtime)
return rscripts[rs].anim.texnum[rscripts[rs].anim.current];
if (rt > rscripts[rs].flags.animtime)
{
rscripts[rs].anim.current += (rt / rscripts[rs].flags.animtime);
while (rscripts[rs].anim.current >= rscripts[rs].anim.num)
rscripts[rs].anim.current = rscripts[rs].anim.current - rscripts[rs].anim.num;
rscripts[rs].anim.lasttime += rscripts[rs].flags.animtime;
}
return rscripts[rs].anim.texnum[rscripts[rs].anim.current];
}
float MakeMapXCoord(float x, int rs)
{
float txm = 0;
if (rs > MAX_RS)
rs = 0;
if (!rs)
return x;
if (rscripts[rs].usescroll)
{
txm=realtime*rscripts[rs].scroll.xspeed;
while (txm > 1 && (1-txm) > 0) txm=1-txm;
while (txm < 0 && (1+txm) > 1) txm=1+txm;
}
if (rscripts[rs].useturb)
{
float power, movediv;
power = rscripts[rs].turb.power * 0.05;
movediv = rscripts[rs].turb.movediv;
x += sin((x*0.1+realtime) * power) * sin((x*0.1+realtime))/movediv;
}
x += txm;
return x*rscripts[rs].texscale;
}
float MakeMapYCoord(float y, int rs)
{
float tym = 0;
if (rs > MAX_RS)
rs=0;
if (!rs)
return y;
if (rscripts[rs].usescroll)
{
tym=realtime*rscripts[rs].scroll.yspeed;
while (tym > 1 && (1-tym) > 0) tym=1-tym;
while (tym < 0 && (1+tym) > 1) tym=1+tym;
}
if (rscripts[rs].useturb)
{
float power, movediv;
movediv = rscripts[rs].turb.movediv;
power = rscripts[rs].turb.power *0.05;
y += sin((y*0.1+realtime) * power) * sin((y*0.1+realtime))/movediv;
}
y += tym;
return y*rscripts[rs].texscale;
}
void RS_DrawPic (int x, int y, qpic_t *pic)
{
int rs;
glpic_t *gl;
qboolean stage;
float tx,ty;
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
gl = (glpic_t *)pic->data;
stage = true;
rs = pic->rs;
while (stage)
{
if (rscripts[rs].flags.blendfunc)
glColor4f(1,1,1,rscripts[rs].flags.alpha);
if (rscripts[rs].useanim)
glBindTexture (GL_TEXTURE_2D, RS_AnimTexture(rs));
else if (rscripts[rs].texnum)
glBindTexture (GL_TEXTURE_2D, rscripts[rs].texnum);
else
glBindTexture (GL_TEXTURE_2D, gl->texnum);
glBegin (GL_QUADS);
tx = MakeMapXCoord(gl->sl,rs);
ty = MakeMapYCoord(gl->tl,rs);
glTexCoord2f (tx, ty);
glVertex2f (x, y);
tx = MakeMapXCoord(gl->sh,rs);
ty = MakeMapYCoord(gl->tl,rs);
glTexCoord2f (tx, ty);
glVertex2f (x+pic->width, y);
tx = MakeMapXCoord(gl->sh,rs);
ty = MakeMapYCoord(gl->th,rs);
glTexCoord2f (tx, ty);
glVertex2f (x+pic->width, y+pic->height);
tx = MakeMapXCoord(gl->sl,rs);
ty = MakeMapYCoord(gl->th,rs);
glTexCoord2f (tx, ty);
glVertex2f (x, y+pic->height);
glEnd ();
if (rscripts[rs].flags.blendfunc)
glColor4f(1,1,1,1);
if (rscripts[rs].nextstage)
rs = rscripts[rs].nextstage;
else
stage = false;
}
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
void FinishScripts(int i)
{
int c;
if (!strcmp(rscripts[i].scriptname,""))
return;
if (rscripts[i].nextname)
rscripts[i].nextstage = GetRSForName(rscripts[i].nextname);
if (!strcmp(rscripts[i].texname,""))
strcpy(rscripts[i].texname,rscripts[i].scriptname);
if (rscripts[i].anim.num)
{
for (c=0;c<rscripts[i].anim.num;c++)
rscripts[i].anim.texnum[c] = loadtextureimage(rscripts[i].anim.name[c].name, false, true);
}
rscripts[i].texnum = loadtextureimage(rscripts[i].texname, false, false);
}
int GetRSForName(char *name)
{
int i;
for (i=0;i<MAX_RS;i++)
{
if (!_stricmp(name,rscripts[i].scriptname))
{
FinishScripts(i);
return i;
}
}
return 0;
}
void InitRenderScripts()
{
FILE *f;
char ch[1024], sp1[1024], sp2[1024];
float fp1, fp2, fp3, fp4;
int inscript = 0, num = 1, i;
COM_FOpenFile("scripts/textures.txt", &f);
if (!f || feof(f))
{
Con_Printf(" &f9000 *Failed to load Rscript &r\n");
return;
}
ch[0] = 0;
sp1[0] = 0;
sp2[0] = 0;
Con_Printf(" *Loaded Rscript\n");
do
{
fscanf(f,"%s",ch);
if (inscript)
{
if (!_stricmp(ch,"turb"))
{ // turb effect
fscanf(f,"%f",&fp1); fscanf(f,"%f",&fp2);
rscripts[num].turb.power = fp1;
rscripts[num].turb.movediv = fp2;
rscripts[num].useturb = true;
}
else if (!_stricmp(ch,"turbvert"))
{ // vertex turb effect
fscanf(f,"%f",&fp1); fscanf(f,"%f",&fp2); fscanf(f,"%f",&fp3); fscanf(f,"%f",&fp4);
rscripts[num].vturb.power = fp1;
rscripts[num].usevturb = true;
}
else if (!_stricmp(ch,"scroll"))
{ // scrolling texture
fscanf(f,"%f",&fp1); fscanf(f,"%f",&fp2);
rscripts[num].scroll.xspeed = fp1;
rscripts[num].scroll.yspeed = fp2;
rscripts[num].usescroll = true;
}
else if (!_stricmp(ch,"stage"))
{ // next stage
fscanf(f,"%s",sp1);
strcpy(rscripts[num].nextname, sp1);
}
else if (!_stricmp(ch,"map"))
{ // texture
fscanf(f,"%s",sp1);
strcpy(rscripts[num].texname, sp1);
rscripts[num].texexist = true;
}
else if (!_stricmp(ch,"anim"))
{ // anim map
fscanf(f,"%f",&fp1);
rscripts[num].anim.num = fp1;
for (i=0; i<fp1; i++)
{
if (i > MAX_ANIM_FRAMES-1)
continue;
fscanf(f,"%s",sp1);
strcpy(rscripts[num].anim.name[i].name,sp1);
}
rscripts[num].useanim=true;
}
else if (!_stricmp(ch,"set"))
{ // set texture flags
fscanf(f,"%s",sp1); fscanf(f,"%f",&fp1);
if (!_stricmp(sp1, "alpha")) // alpha amount
rscripts[num].flags.alpha = fp1;
else if (!_stricmp(sp1, "blendfunc")) // use blendfunc?
rscripts[num].flags.blendfunc = fp1;
else if (!_stricmp(sp1, "texscale")) // texture scaling
rscripts[num].texscale = fp1;
else if (!_stricmp(sp1, "animtime")) // animation timing (ms)
rscripts[num].flags.animtime = fp1;
}
else if (!_stricmp(ch,"}"))
{
inscript=0;
num++;
}
}
else
{
if (_stricmp(ch,"{"))
{
strcpy(rscripts[num].scriptname,ch);
}
else
{
rscripts[num].flags.alpha = 1;
rscripts[num].texscale = 1;
rscripts[num].flags.animtime = 1;
inscript = 1;
}
}
} while (!feof(f));
fclose(f);
}