/* Copyright (C) 2005, 2010 - Cryptic Sea This file is part of Gish. Gish 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. */ int lineintersectlevel(float *intersectpoint,float *normal,float *scale,float *startpoint,float *endpoint) { int count,count2,count3; int blocknum; int min[2],max[2]; float vec[3],vec2[3],vec3[3],vec4[3]; float intersectpointtemp[3]; float normaltemp[3]; float scaletemp; for (count=0;count<2;count++) { if (startpoint[count]255) min[count]=255; if (max[count]>255) max[count]=255; } *scale=1.0f; for (count=min[1];count<=max[1];count++) for (count2=min[0];count2<=max[0];count2++) { blocknum=level.grid[count][count2]; if (level.gridmod[count][count2]!=0) blocknum=0; for (count3=0;count3>count3)&1)==0) { vec[0]=(float)count2+block[blocknum].line[count3][0]; vec[1]=(float)count+block[blocknum].line[count3][1]; vec[2]=0.0f; vec2[0]=(float)count2+block[blocknum].line[count3][2]; vec2[1]=(float)count+block[blocknum].line[count3][3]; vec2[2]=0.0f; if (lineintersectline2(intersectpointtemp,normaltemp,&scaletemp,startpoint,endpoint,vec,vec2)) if (scaletemp<*scale) { collision.blocknum=blocknum; collision.blockx=count2; collision.blocky=count; collision.friction=block[blocknum].friction; copyvector(intersectpoint,intersectpointtemp); copyvector(normal,normaltemp); *scale=scaletemp; /* subtractvectors(vec3,endpoint,vec); subtractvectors(vec4,vec2,vec); if (dotproduct(vec3,vec4)>0.0f) { subtractvectors(vec3,endpoint,vec2); subtractvectors(vec4,vec,vec2); if (dotproduct(vec3,vec4)>0.0f) { copyvector(intersectpoint,intersectpointtemp); copyvector(normal,normaltemp); *scale=scaletemp; } } */ } } } if (*scale<1.0f) return(1); return(0); } void savelevel(char *filename) { int count,count2,count3; int blocknum; int changeddir; int version; for (count=0;count<256;count++) textureused[count]=1; for (count=0;count<256;count++) for (count2=0;count2<256;count2++) { blocknum=level.backgrid[count][count2]; textureused[blocknum]=1; if (block[blocknum].animation!=0) for (count3=1;count3<=block[blocknum].animation;count3++) textureused[blocknum+count3]=1; blocknum=level.grid[count][count2]; textureused[blocknum]=1; if (block[blocknum].animation!=0) for (count3=1;count3<=block[blocknum].animation;count3++) textureused[blocknum+count3]=1; blocknum=level.foregrid[count][count2]; textureused[blocknum]=1; if (block[blocknum].animation!=0) for (count3=1;count3<=block[blocknum].animation;count3++) textureused[blocknum+count3]=1; } /* for (count=0;count<256;count++) if (!textureused[count]) texture[count].sizex=0; */ changeddir=chdir("level"); if ((fp=fopen(filename,"wb"))!=NULL) { version=10; fwrite2(&version,4,1,fp); fwrite2(level.background,1,32,fp); fwrite2(&level.tileset,4,1,fp); fwrite2(&level.gametype,4,1,fp); fwrite2(&level.time,4,1,fp); fwrite2(level.area,4,64*4,fp); fwrite2(level.backgrid,1,256*256,fp); fwrite2(level.grid,1,256*256,fp); fwrite2(level.foregrid,1,256*256,fp); fwrite2(level.startposition,4,3,fp); fwrite2(level.ambient,4,12,fp); fwrite2(&level.numofobjects,4,1,fp); for (count=0;count=256) { fclose(fp); if (changeddir==0) chdir(".."); return; } for (count=0;count=1024) { fclose(fp); if (changeddir==0) chdir(".."); return; } for (count=0;count=1024) { fclose(fp); if (changeddir==0) chdir(".."); return; } if (texture[count].sizex!=0) { fread2(&texture[count].sizey,4,1,fp); fread2(&texture[count].magfilter,4,1,fp); fread2(&texture[count].minfilter,4,1,fp); free(texture[count].rgba[0]); texture[count].rgba[0]=(unsigned int *) malloc(texture[count].sizex*texture[count].sizey*4); fread(texture[count].rgba[0],4,texture[count].sizex*texture[count].sizey,fp); memcpy(cryptdata,texture[count].rgba[0],4*texture[count].sizex*texture[count].sizey); decryptdata(x,4*texture[count].sizex*texture[count].sizey/4); memcpy(texture[count].rgba[0],cryptdata,4*texture[count].sizex*texture[count].sizey); texture[count].mipmaplevels=1; texture[count].format=GL_RGBA; texture[count].alphamap=0; texture[count].normalmap=0; texture[count].glossmap=0; texture[count].wraps=GL_CLAMP_TO_EDGE; texture[count].wrapt=GL_CLAMP_TO_EDGE; texture[count].magfilter=GL_LINEAR; texture[count].minfilter=GL_LINEAR; if ((texture[count].sizex&(texture[count].sizex-1))==0) if ((texture[count].sizey&(texture[count].sizey-1))==0) setuptexture(count); } fread2(&block[count].numoflines,4,1,fp); if (block[count].numoflines<0 || block[count].numoflines>=64) { fclose(fp); if (changeddir==0) chdir(".."); return; } for (count2=0;count2=256) { fclose(fp); if (changeddir==0) chdir(".."); return; } for (count=0;count=1024) { fclose(fp); if (changeddir==0) chdir(".."); return; } for (count=0;count=1024) { fclose(fp); if (changeddir==0) chdir(".."); return; } if (texture[count].sizex!=0) { fread2(&texture[count].sizey,4,1,fp); fread2(&texture[count].magfilter,4,1,fp); fread2(&texture[count].minfilter,4,1,fp); free(texture[count].rgba[0]); texture[count].rgba[0]=(unsigned int *) malloc(texture[count].sizex*texture[count].sizey*4); fread(texture[count].rgba[0],4,texture[count].sizex*texture[count].sizey,fp); texture[count].mipmaplevels=1; texture[count].format=GL_RGBA; texture[count].alphamap=0; texture[count].normalmap=0; texture[count].glossmap=0; texture[count].wraps=GL_CLAMP_TO_EDGE; texture[count].wrapt=GL_CLAMP_TO_EDGE; texture[count].magfilter=GL_LINEAR; texture[count].minfilter=GL_LINEAR; if ((texture[count].sizex&(texture[count].sizex-1))==0) if ((texture[count].sizey&(texture[count].sizey-1))==0) setuptexture(count); } fread2(&block[count].numoflines,4,1,fp); if (block[count].numoflines<0 || block[count].numoflines>=64) { fclose(fp); if (changeddir==0) chdir(".."); return; } for (count2=0;count2particle[object[objectnum].particle[count]].position[count2]) min[count2]=particle[object[objectnum].particle[count]].position[count2]; if (max[count2]>count3)&1)==0) { vec[0]=(float)count2+(block[blocknum].line[count3][0]+block[blocknum].line[count3][2])*0.5f; vec[1]=(float)count+(block[blocknum].line[count3][1]+block[blocknum].line[count3][3])*0.5f; vec[2]=0.0f; vec[0]+=(block[blocknum].line[count3][3]-block[blocknum].line[count3][1])*0.5f; vec[1]-=(block[blocknum].line[count3][2]-block[blocknum].line[count3][0])*0.5f; normal[0]=-(block[blocknum].line[count3][3]-block[blocknum].line[count3][1]); normal[1]=(block[blocknum].line[count3][2]-block[blocknum].line[count3][0]); normal[2]=0.0f; normalizevector(normal,normal); levelline[numoflevellines].line[0][0]=vec[0]; levelline[numoflevellines].line[0][1]=vec[1]; levelline[numoflevellines].line[0][2]=0.0f; levelline[numoflevellines].line[1][0]=(float)count2+block[blocknum].line[count3][0]; levelline[numoflevellines].line[1][1]=(float)count+block[blocknum].line[count3][1]; levelline[numoflevellines].line[1][2]=0.0f; copyvector(levelline[numoflevellines].normal,normal); levelline[numoflevellines].friction=block[blocknum].friction; levelline[numoflevellines].blocknum=blocknum; levelline[numoflevellines].blockx=count2; levelline[numoflevellines].blocky=count; numoflevellines++; levelline[numoflevellines].line[0][0]=vec[0]; levelline[numoflevellines].line[0][1]=vec[1]; levelline[numoflevellines].line[0][2]=0.0f; levelline[numoflevellines].line[1][0]=(float)count2+block[blocknum].line[count3][2]; levelline[numoflevellines].line[1][1]=(float)count+block[blocknum].line[count3][3]; levelline[numoflevellines].line[1][2]=0.0f; copyvector(levelline[numoflevellines].normal,normal); levelline[numoflevellines].friction=block[blocknum].friction; levelline[numoflevellines].blocknum=blocknum; levelline[numoflevellines].blockx=count2; levelline[numoflevellines].blocky=count; numoflevellines++; } } } void setuplevellines(int xstart,int ystart,int xend,int yend) { int count,count2,count3,count4; int blocknum,blocknum2; if (xstart<1) xstart=1; if (ystart<1) ystart=1; if (xend>254) xend=254; if (yend>254) yend=254; for (count=ystart;count<=yend;count++) for (count2=xstart;count2<=xend;count2++) { level.gridflags[count][count2]=0; blocknum=level.grid[count][count2]; for (count3=0;count3=block[blocknum2].line[count4][0]) level.gridflags[count][count2]|=(1<=block[blocknum2].line[count4][2]) if (block[blocknum].line[count3][2]<=block[blocknum2].line[count4][0]) level.gridflags[count][count2]|=(1<=block[blocknum2].line[count4][3]) if (block[blocknum].line[count3][3]<=block[blocknum2].line[count4][1]) level.gridflags[count][count2]|=(1<=block[blocknum2].line[count4][1]) level.gridflags[count][count2]|=(1<block[blocknum].line[count3][2]) level.gridflags[count][count2]|=(1<block[blocknum].line[count3][3]) level.gridflags[count][count2]|=(1<0.0f) if (dot2>0.0f) return(0); if (dot1<0.0f) return(0); normalizevector(normal,normal); vec[0]=vertex1[0]-startpoint[0]; vec[1]=vertex1[1]-startpoint[1]; vec[2]=0.0f; *scale=dotproduct(vec,normal); vec[0]=endpoint[0]-startpoint[0]; vec[1]=endpoint[1]-startpoint[1]; vec[2]=0.0f; *scale/=dotproduct(vec,normal); scaleaddvectors(intersectpoint,startpoint,vec,*scale); vec[0]=intersectpoint[0]-vertex1[0]; vec[1]=intersectpoint[1]-vertex1[1]; vec[2]=0.0f; vec2[0]=vertex2[0]-vertex1[0]; vec2[1]=vertex2[1]-vertex1[1]; vec2[2]=0.0f; if (dotproduct(vec,vec2)<0.0f) return(0); vec[0]=intersectpoint[0]-vertex2[0]; vec[1]=intersectpoint[1]-vertex2[1]; vec[2]=0.0f; vec2[0]=vertex1[0]-vertex2[0]; vec2[1]=vertex1[1]-vertex2[1]; vec2[2]=0.0f; if (dotproduct(vec,vec2)<0.0f) return(0); vec[0]=endpoint[0]-vertex1[0]; vec[1]=endpoint[1]-vertex1[1]; vec[2]=0.0f; vec2[0]=vertex2[0]-vertex1[0]; vec2[1]=vertex2[1]-vertex1[1]; vec2[2]=0.0f; if (dotproduct(vec,vec2)<0.0f) return(0); vec[0]=endpoint[0]-vertex2[0]; vec[1]=endpoint[1]-vertex2[1]; vec[2]=0.0f; vec2[0]=vertex1[0]-vertex2[0]; vec2[1]=vertex1[1]-vertex2[1]; vec2[2]=0.0f; if (dotproduct(vec,vec2)<0.0f) return(0); return(1); } int pointintersectlevel(float *intersectpoint,float *normal,float *scale,float *point) { int count,count2,count3; int blocknum; int min[2],max[2]; float vec[3],vec2[3],vec3[3]; float intersectpointtemp[3]; float normaltemp[3]; float scaletemp; for (count=0;count<2;count++) { min[count]=point[count]-1.0f; max[count]=point[count]+1.0f; if (min[count]<0) min[count]=0; if (max[count]<0) max[count]=0; if (min[count]>255) min[count]=255; if (max[count]>255) max[count]=255; } *scale=0.0f; for (count=min[1];count<=max[1];count++) for (count2=min[0];count2<=max[0];count2++) { blocknum=level.grid[count][count2]; if (level.gridmod[count][count2]!=0) blocknum=0; for (count3=0;count3>count3)&1)==0) { vec[0]=(float)count2+block[blocknum].line[count3][0]; vec[1]=(float)count+block[blocknum].line[count3][1]; vec[2]=0.0f; vec2[0]=(float)count2+block[blocknum].line[count3][2]; vec2[1]=(float)count+block[blocknum].line[count3][3]; vec2[2]=0.0f; normaltemp[0]=vec[1]-vec2[1]; normaltemp[1]=vec2[0]-vec[0]; normaltemp[2]=0.0f; normalizevector(normaltemp,normaltemp); scaleaddvectors(vec3,point,normaltemp,0.25f); if (lineintersectline2(intersectpointtemp,normaltemp,&scaletemp,vec3,point,vec,vec2)) if (scaletemp>*scale) { collision.blocknum=blocknum; collision.blockx=count2; collision.blocky=count; collision.friction=block[blocknum].friction; copyvector(intersectpoint,intersectpointtemp); copyvector(normal,normaltemp); *scale=scaletemp; } } } if (*scale>0.0f) return(1); return(0); } int changetilesetdir(void) { int changeddir; changeddir=1; if (level.tileset==0) changeddir=chdir("tile01"); if (level.tileset==1) changeddir=chdir("tile02"); if (level.tileset==2) changeddir=chdir("tile03"); if (level.tileset==3) changeddir=chdir("tile04"); if (level.tileset==4) changeddir=chdir("tile05"); if (level.tileset==5) changeddir=chdir("tile06"); if (level.tileset==6) changeddir=chdir("tile07"); if (level.tileset==7) changeddir=chdir("tile08"); return(changeddir); } void encryptdata(unsigned int code,unsigned int codepair,int cryptdatasize) { int count; if (bigendian) byteswapdata(cryptdatasize); for (count=0;count>8)&255)<<16); temp+=(((cryptdata[count]>>16)&255)<<8)+((cryptdata[count]>>24)&255); cryptdata[count]=temp; } }