/* 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 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); }