diff options
Diffstat (limited to 'hgehelp')
-rw-r--r-- | hgehelp/hgeanim.cpp | 165 | ||||
-rw-r--r-- | hgehelp/hgecolor.cpp | 89 | ||||
-rw-r--r-- | hgehelp/hgedistort.cpp | 242 | ||||
-rw-r--r-- | hgehelp/hgefont.cpp | 337 | ||||
-rw-r--r-- | hgehelp/hgegui.cpp | 397 | ||||
-rw-r--r-- | hgehelp/hgeguictrls.cpp | 361 | ||||
-rw-r--r-- | hgehelp/hgeparticle.cpp | 308 | ||||
-rw-r--r-- | hgehelp/hgepmanager.cpp | 96 | ||||
-rw-r--r-- | hgehelp/hgerect.cpp | 45 | ||||
-rw-r--r-- | hgehelp/hgeresource.cpp | 254 | ||||
-rw-r--r-- | hgehelp/hgesprite.cpp | 302 | ||||
-rw-r--r-- | hgehelp/hgestrings.cpp | 168 | ||||
-rw-r--r-- | hgehelp/hgevector.cpp | 69 | ||||
-rw-r--r-- | hgehelp/parser.cpp | 209 | ||||
-rw-r--r-- | hgehelp/parser.h | 77 | ||||
-rw-r--r-- | hgehelp/resources.cpp | 958 | ||||
-rw-r--r-- | hgehelp/resources.h | 165 |
17 files changed, 4242 insertions, 0 deletions
diff --git a/hgehelp/hgeanim.cpp b/hgehelp/hgeanim.cpp new file mode 100644 index 0000000..acc64ef --- /dev/null +++ b/hgehelp/hgeanim.cpp @@ -0,0 +1,165 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeAnimation helper class implementation +*/ + + +#include "../../include/hgeanim.h" + + +hgeAnimation::hgeAnimation(HTEXTURE tex, int nframes, float FPS, float x, float y, float w, float h) + : hgeSprite(tex, x, y, w, h) +{ + orig_width = hge->Texture_GetWidth(tex, true); + + fSinceLastFrame=-1.0f; + fSpeed=1.0f/FPS; + bPlaying=false; + nFrames=nframes; + + Mode=HGEANIM_FWD | HGEANIM_LOOP; + nDelta=1; + SetFrame(0); +} + +hgeAnimation::hgeAnimation(const hgeAnimation & anim) +: hgeSprite(anim) +{ + // Copy hgeAnimation parameters: + this->orig_width = anim.orig_width; + this->bPlaying = anim.bPlaying; + this->fSpeed = anim.fSpeed; + this->fSinceLastFrame = anim.fSinceLastFrame; + this->Mode = anim.Mode; + this->nDelta = anim.nDelta; + this->nFrames = anim.nFrames; + this->nCurFrame = anim.nCurFrame; +} + +void hgeAnimation::SetMode(int mode) +{ + Mode=mode; + + if(mode & HGEANIM_REV) + { + nDelta = -1; + SetFrame(nFrames-1); + } + else + { + nDelta = 1; + SetFrame(0); + } +} + + +void hgeAnimation::Play() +{ + bPlaying=true; + fSinceLastFrame=-1.0f; + if(Mode & HGEANIM_REV) + { + nDelta = -1; + SetFrame(nFrames-1); + } + else + { + nDelta = 1; + SetFrame(0); + } +} + + +void hgeAnimation::Update(float fDeltaTime) +{ + if(!bPlaying) return; + + if(fSinceLastFrame == -1.0f) + fSinceLastFrame=0.0f; + else + fSinceLastFrame += fDeltaTime; + + while(fSinceLastFrame >= fSpeed) + { + fSinceLastFrame -= fSpeed; + + if(nCurFrame + nDelta == nFrames) + { + switch(Mode) + { + case HGEANIM_FWD: + case HGEANIM_REV | HGEANIM_PINGPONG: + bPlaying = false; + break; + + case HGEANIM_FWD | HGEANIM_PINGPONG: + case HGEANIM_FWD | HGEANIM_PINGPONG | HGEANIM_LOOP: + case HGEANIM_REV | HGEANIM_PINGPONG | HGEANIM_LOOP: + nDelta = -nDelta; + break; + } + } + else if(nCurFrame + nDelta < 0) + { + switch(Mode) + { + case HGEANIM_REV: + case HGEANIM_FWD | HGEANIM_PINGPONG: + bPlaying = false; + break; + + case HGEANIM_REV | HGEANIM_PINGPONG: + case HGEANIM_REV | HGEANIM_PINGPONG | HGEANIM_LOOP: + case HGEANIM_FWD | HGEANIM_PINGPONG | HGEANIM_LOOP: + nDelta = -nDelta; + break; + } + } + + if(bPlaying) SetFrame(nCurFrame+nDelta); + } +} + +void hgeAnimation::SetFrame(int n) +{ + float tx1, ty1, tx2, ty2; + bool bX, bY, bHS; + int ncols = int(orig_width) / int(width); + + + n = n % nFrames; + if(n < 0) n = nFrames + n; + nCurFrame = n; + + // calculate texture coords for frame n + ty1 = ty; + tx1 = tx + n*width; + + if(tx1 > orig_width-width) + { + n -= int(orig_width-tx) / int(width); + tx1 = width * (n%ncols); + ty1 += height * (1 + n/ncols); + } + + tx2 = tx1 + width; + ty2 = ty1 + height; + + tx1 /= tex_width; + ty1 /= tex_height; + tx2 /= tex_width; + ty2 /= tex_height; + + quad.v[0].tx=tx1; quad.v[0].ty=ty1; + quad.v[1].tx=tx2; quad.v[1].ty=ty1; + quad.v[2].tx=tx2; quad.v[2].ty=ty2; + quad.v[3].tx=tx1; quad.v[3].ty=ty2; + + bX=bXFlip; bY=bYFlip; bHS=bHSFlip; + bXFlip=false; bYFlip=false; + SetFlip(bX,bY,bHS); +} + diff --git a/hgehelp/hgecolor.cpp b/hgehelp/hgecolor.cpp new file mode 100644 index 0000000..5ae512d --- /dev/null +++ b/hgehelp/hgecolor.cpp @@ -0,0 +1,89 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeColor*** helper classes implementation +*/ + + +#include "../../include/hgecolor.h" +#include <math.h> + +#ifndef min +#define min(x,y) ((x) < (y) ? (x) : (y)) +#endif + +#ifndef max +#define max(x,y) ((x) > (y) ? (x) : (y)) +#endif + +void hgeColorHSV::SetHWColor(DWORD col) +{ + float r, g, b; + float minv, maxv, delta; + float del_R, del_G, del_B; + + a = (col>>24) / 255.0f; + r = ((col>>16) & 0xFF) / 255.0f; + g = ((col>>8) & 0xFF) / 255.0f; + b = (col & 0xFF) / 255.0f; + + minv = min(min(r, g), b); + maxv = max(max(r, g), b); + delta = maxv - minv; + + v = maxv; + + if (delta == 0) + { + h = 0; + s = 0; + } + else + { + s = delta / maxv; + del_R = (((maxv - r) / 6) + (delta / 2)) / delta; + del_G = (((maxv - g) / 6) + (delta / 2)) / delta; + del_B = (((maxv - b) / 6) + (delta / 2)) / delta; + + if (r == maxv) {h = del_B - del_G;} + else if (g == maxv) {h = (1.0f / 3.0f) + del_R - del_B;} + else if (b == maxv) {h = (2.0f / 3.0f) + del_G - del_R;} + + if (h < 0) h += 1; + if (h > 1) h -= 1; + } +} + +DWORD hgeColorHSV::GetHWColor() const +{ + float r, g, b; + float xh, i, p1, p2, p3; + + if (s == 0) + { + r = v; + g = v; + b = v; + } + else + { + xh = h * 6; + if(xh == 6) xh=0; + i = floorf(xh); + p1 = v * (1 - s); + p2 = v * (1 - s * (xh - i)); + p3 = v * (1 - s * (1 - (xh - i))); + + if (i == 0) {r = v; g = p3; b = p1;} + else if (i == 1) {r = p2; g = v; b = p1;} + else if (i == 2) {r = p1; g = v; b = p3;} + else if (i == 3) {r = p1; g = p2; b = v; } + else if (i == 4) {r = p3; g = p1; b = v; } + else {r = v; g = p1; b = p2;} + } + + return (DWORD(a*255.0f)<<24) + (DWORD(r*255.0f)<<16) + (DWORD(g*255.0f)<<8) + DWORD(b*255.0f); +} + diff --git a/hgehelp/hgedistort.cpp b/hgehelp/hgedistort.cpp new file mode 100644 index 0000000..276ca05 --- /dev/null +++ b/hgehelp/hgedistort.cpp @@ -0,0 +1,242 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeDistortionMesh helper class implementation +*/ + +#include "../../include/hgedistort.h" + + +HGE *hgeDistortionMesh::hge=0; + + +hgeDistortionMesh::hgeDistortionMesh(int cols, int rows) +{ + int i; + + hge=hgeCreate(HGE_VERSION); + + nRows=rows; + nCols=cols; + cellw=cellh=0; + quad.tex=0; + quad.blend=BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_ZWRITE; + disp_array=new hgeVertex[rows*cols]; + + for(i=0;i<rows*cols;i++) + { + disp_array[i].x=0.0f; + disp_array[i].y=0.0f; + disp_array[i].tx=0.0f; + disp_array[i].ty=0.0f; + + disp_array[i].z=0.5f; + disp_array[i].col=0xFFFFFFFF; + } +} + +hgeDistortionMesh::hgeDistortionMesh(const hgeDistortionMesh &dm) +{ + hge=hgeCreate(HGE_VERSION); + + nRows=dm.nRows; + nCols=dm.nCols; + cellw=dm.cellw; + cellh=dm.cellh; + tx=dm.tx; + ty=dm.ty; + width=dm.width; + height=dm.height; + quad=dm.quad; + + disp_array=new hgeVertex[nRows*nCols]; + memcpy(disp_array, dm.disp_array, sizeof(hgeVertex)*nRows*nCols); +} + +hgeDistortionMesh::~hgeDistortionMesh() +{ + delete[] disp_array; + hge->Release(); +} + +hgeDistortionMesh& hgeDistortionMesh::operator= (const hgeDistortionMesh &dm) +{ + if(this!=&dm) + { + nRows=dm.nRows; + nCols=dm.nCols; + cellw=dm.cellw; + cellh=dm.cellh; + tx=dm.tx; + ty=dm.ty; + width=dm.width; + height=dm.height; + quad=dm.quad; + + delete[] disp_array; + disp_array=new hgeVertex[nRows*nCols]; + memcpy(disp_array, dm.disp_array, sizeof(hgeVertex)*nRows*nCols); + } + + return *this; + +} + +void hgeDistortionMesh::SetTexture(HTEXTURE tex) +{ + quad.tex=tex; +} + +void hgeDistortionMesh::SetTextureRect(float x, float y, float w, float h) +{ + int i,j; + float tw,th; + + tx=x; ty=y; width=w; height=h; + + if (quad.tex) + { + tw=(float)hge->Texture_GetWidth(quad.tex); + th=(float)hge->Texture_GetHeight(quad.tex); + } + else + { + tw = w; + th = h; + } + + cellw=w/(nCols-1); + cellh=h/(nRows-1); + + for(j=0; j<nRows; j++) + for(i=0; i<nCols; i++) + { + disp_array[j*nCols+i].tx=(x+i*cellw)/tw; + disp_array[j*nCols+i].ty=(y+j*cellh)/th; + + disp_array[j*nCols+i].x=i*cellw; + disp_array[j*nCols+i].y=j*cellh; + } +} + +void hgeDistortionMesh::SetBlendMode(int blend) +{ + quad.blend=blend; +} + +void hgeDistortionMesh::Clear(DWORD col, float z) +{ + int i,j; + + for(j=0; j<nRows; j++) + for(i=0; i<nCols; i++) + { + disp_array[j*nCols+i].x=i*cellw; + disp_array[j*nCols+i].y=j*cellh; + disp_array[j*nCols+i].col=col; + disp_array[j*nCols+i].z=z; + } +} + +void hgeDistortionMesh::Render(float x, float y) +{ + int i,j,idx; + + for(j=0; j<nRows-1; j++) + for(i=0; i<nCols-1; i++) + { + idx=j*nCols+i; + + quad.v[0].tx=disp_array[idx].tx; + quad.v[0].ty=disp_array[idx].ty; + quad.v[0].x=x+disp_array[idx].x; + quad.v[0].y=y+disp_array[idx].y; + quad.v[0].z=disp_array[idx].z; + quad.v[0].col=disp_array[idx].col; + + quad.v[1].tx=disp_array[idx+1].tx; + quad.v[1].ty=disp_array[idx+1].ty; + quad.v[1].x=x+disp_array[idx+1].x; + quad.v[1].y=y+disp_array[idx+1].y; + quad.v[1].z=disp_array[idx+1].z; + quad.v[1].col=disp_array[idx+1].col; + + quad.v[2].tx=disp_array[idx+nCols+1].tx; + quad.v[2].ty=disp_array[idx+nCols+1].ty; + quad.v[2].x=x+disp_array[idx+nCols+1].x; + quad.v[2].y=y+disp_array[idx+nCols+1].y; + quad.v[2].z=disp_array[idx+nCols+1].z; + quad.v[2].col=disp_array[idx+nCols+1].col; + + quad.v[3].tx=disp_array[idx+nCols].tx; + quad.v[3].ty=disp_array[idx+nCols].ty; + quad.v[3].x=x+disp_array[idx+nCols].x; + quad.v[3].y=y+disp_array[idx+nCols].y; + quad.v[3].z=disp_array[idx+nCols].z; + quad.v[3].col=disp_array[idx+nCols].col; + + hge->Gfx_RenderQuad(&quad); + } +} + +void hgeDistortionMesh::SetZ(int col, int row, float z) +{ + if(row<nRows && col<nCols) disp_array[row*nCols+col].z=z; +} + +void hgeDistortionMesh::SetColor(int col, int row, DWORD color) +{ + if(row<nRows && col<nCols) disp_array[row*nCols+col].col=color; +} + +void hgeDistortionMesh::SetDisplacement(int col, int row, float dx, float dy, int ref) +{ + if(row<nRows && col<nCols) + { + switch(ref) + { + case HGEDISP_NODE: dx+=col*cellw; dy+=row*cellh; break; + case HGEDISP_CENTER: dx+=cellw*(nCols-1)/2;dy+=cellh*(nRows-1)/2; break; + case HGEDISP_TOPLEFT: break; + } + + disp_array[row*nCols+col].x=dx; + disp_array[row*nCols+col].y=dy; + } +} + +float hgeDistortionMesh::GetZ(int col, int row) const +{ + if(row<nRows && col<nCols) return disp_array[row*nCols+col].z; + else return 0.0f; +} + +DWORD hgeDistortionMesh::GetColor(int col, int row) const +{ + if(row<nRows && col<nCols) return disp_array[row*nCols+col].col; + else return 0; +} + +void hgeDistortionMesh::GetDisplacement(int col, int row, float *dx, float *dy, int ref) const +{ + if(row<nRows && col<nCols) + { + switch(ref) + { + case HGEDISP_NODE: *dx=disp_array[row*nCols+col].x-col*cellw; + *dy=disp_array[row*nCols+col].y-row*cellh; + break; + + case HGEDISP_CENTER: *dx=disp_array[row*nCols+col].x-cellw*(nCols-1)/2; + *dy=disp_array[row*nCols+col].x-cellh*(nRows-1)/2; + break; + + case HGEDISP_TOPLEFT: *dx=disp_array[row*nCols+col].x; + *dy=disp_array[row*nCols+col].y; + break; + } + } +} + diff --git a/hgehelp/hgefont.cpp b/hgehelp/hgefont.cpp new file mode 100644 index 0000000..80fdd47 --- /dev/null +++ b/hgehelp/hgefont.cpp @@ -0,0 +1,337 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeFont helper class implementation +*/ + + +#include "../../include/hgefont.h" +#include <stdlib.h> +#include <stdio.h> + +const char FNTHEADERTAG[] = "[HGEFONT]"; +const char FNTBITMAPTAG[] = "Bitmap"; +const char FNTCHARTAG[] = "Char"; + + +HGE *hgeFont::hge=0; +char hgeFont::buffer[1024]; + + +hgeFont::hgeFont(const char *szFont, bool bMipmap) +{ + void *data; + DWORD size; + char *desc, *pdesc; + char linebuf[256]; + char buf[MAX_PATH], *pbuf; + char chr; + int i, x, y, w, h, a, c; + + // Setup variables + + hge=hgeCreate(HGE_VERSION); + + fHeight=0.0f; + fScale=1.0f; + fProportion=1.0f; + fRot=0.0f; + fTracking=0.0f; + fSpacing=1.0f; + hTexture=0; + + fZ=0.5f; + nBlend=BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE; + dwCol=0xFFFFFFFF; + + ZeroMemory( &letters, sizeof(letters) ); + ZeroMemory( &pre, sizeof(pre) ); + ZeroMemory( &post, sizeof(post) ); + + // Load font description + + data=hge->Resource_Load(szFont, &size); + if(!data) return; + + desc = new char[size+1]; + memcpy(desc,data,size); + desc[size]=0; + hge->Resource_Free(data); + + pdesc=_get_line(desc,linebuf); + if(strcmp(linebuf, FNTHEADERTAG)) + { + hge->System_Log("Font %s has incorrect format.", szFont); + delete[] desc; + return; + } + + // Parse font description + + while(pdesc = _get_line(pdesc,linebuf)) + { + if(!strncmp(linebuf, FNTBITMAPTAG, sizeof(FNTBITMAPTAG)-1 )) + { + strcpy(buf,szFont); + pbuf=strrchr(buf,'\\'); + if(!pbuf) pbuf=strrchr(buf,'/'); + if(!pbuf) pbuf=buf; + else pbuf++; + if(!sscanf(linebuf, "Bitmap = %s", pbuf)) continue; + + hTexture=hge->Texture_Load(buf, 0, bMipmap); + if(!hTexture) + { + delete[] desc; + return; + } + } + + else if(!strncmp(linebuf, FNTCHARTAG, sizeof(FNTCHARTAG)-1 )) + { + pbuf=strchr(linebuf,'='); + if(!pbuf) continue; + pbuf++; + while(*pbuf==' ') pbuf++; + if(*pbuf=='\"') + { + pbuf++; + i=(unsigned char)*pbuf++; + pbuf++; // skip " + } + else + { + i=0; + while((*pbuf>='0' && *pbuf<='9') || (*pbuf>='A' && *pbuf<='F') || (*pbuf>='a' && *pbuf<='f')) + { + chr=*pbuf; + if(chr >= 'a') chr-='a'-':'; + if(chr >= 'A') chr-='A'-':'; + chr-='0'; + if(chr>0xF) chr=0xF; + i=(i << 4) | chr; + pbuf++; + } + if(i<0 || i>255) continue; + } + sscanf(pbuf, " , %d , %d , %d , %d , %d , %d", &x, &y, &w, &h, &a, &c); + + letters[i] = new hgeSprite(hTexture, (float)x, (float)y, (float)w, (float)h); + pre[i]=(float)a; + post[i]=(float)c; + if(h>fHeight) fHeight=(float)h; + } + } + + delete[] desc; +} + + +hgeFont::~hgeFont() +{ + for(int i=0; i<256; i++) + if(letters[i]) delete letters[i]; + if(hTexture) hge->Texture_Free(hTexture); + hge->Release(); +} + +void hgeFont::Render(float x, float y, int align, const char *string) +{ + int i; + float fx=x; + + align &= HGETEXT_HORZMASK; + if(align==HGETEXT_RIGHT) fx-=GetStringWidth(string, false); + if(align==HGETEXT_CENTER) fx-=int(GetStringWidth(string, false)/2.0f); + + while(*string) + { + if(*string=='\n') + { + y += int(fHeight*fScale*fSpacing); + fx = x; + if(align == HGETEXT_RIGHT) fx -= GetStringWidth(string+1, false); + if(align == HGETEXT_CENTER) fx -= int(GetStringWidth(string+1, false)/2.0f); + } + else + { + i=(unsigned char)*string; + if(!letters[i]) i='?'; + if(letters[i]) + { + fx += pre[i]*fScale*fProportion; + letters[i]->RenderEx(fx, y, fRot, fScale*fProportion, fScale); + fx += (letters[i]->GetWidth()+post[i]+fTracking)*fScale*fProportion; + } + } + string++; + } +} + +void hgeFont::printf(float x, float y, int align, const char *format, ...) +{ + va_list vl; + + va_start(vl, format); + vsnprintf(buffer, sizeof(buffer)-1, format, vl); + va_end(vl); + + buffer[sizeof(buffer)-1] = '\0'; + + Render(x,y,align,buffer); +} + +void hgeFont::printfb(float x, float y, float w, float h, int align, const char *format, ...) +{ + char chr, *pbuf, *prevword, *linestart; + int i,lines=0; + float tx, ty, hh, ww; + va_list vl; + + va_start(vl, format); + vsnprintf(buffer, sizeof(buffer)-1, format, vl); + va_end(vl); + + buffer[sizeof(buffer)-1] = '\0'; + + linestart=buffer; + pbuf=buffer; + prevword=0; + + for(;;) + { + i=0; + while(pbuf[i] && pbuf[i]!=' ' && pbuf[i]!='\n') i++; + + chr=pbuf[i]; + pbuf[i]=0; + ww=GetStringWidth(linestart); + pbuf[i]=chr; + + if(ww > w) + { + if(pbuf==linestart) + { + pbuf[i]='\n'; + linestart=&pbuf[i+1]; + } + else + { + *prevword='\n'; + linestart=prevword+1; + } + + lines++; + } + + if(pbuf[i]=='\n') + { + prevword=&pbuf[i]; + linestart=&pbuf[i+1]; + pbuf=&pbuf[i+1]; + lines++; + continue; + } + + if(!pbuf[i]) {lines++;break;} + + prevword=&pbuf[i]; + pbuf=&pbuf[i+1]; + } + + tx=x; + ty=y; + hh=fHeight*fSpacing*fScale*lines; + + switch(align & HGETEXT_HORZMASK) + { + case HGETEXT_LEFT: break; + case HGETEXT_RIGHT: tx+=w; break; + case HGETEXT_CENTER: tx+=int(w/2); break; + } + + switch(align & HGETEXT_VERTMASK) + { + case HGETEXT_TOP: break; + case HGETEXT_BOTTOM: ty+=h-hh; break; + case HGETEXT_MIDDLE: ty+=int((h-hh)/2); break; + } + + Render(tx,ty,align,buffer); +} + +float hgeFont::GetStringWidth(const char *string, bool bMultiline) const +{ + int i; + float linew, w = 0; + + while(*string) + { + linew = 0; + + while(*string && *string != '\n') + { + i=(unsigned char)*string; + if(!letters[i]) i='?'; + if(letters[i]) + linew += letters[i]->GetWidth() + pre[i] + post[i] + fTracking; + + string++; + } + + if(!bMultiline) return linew*fScale*fProportion; + + if(linew > w) w = linew; + + while (*string == '\n' || *string == '\r') string++; + } + + return w*fScale*fProportion; +} + +void hgeFont::SetColor(DWORD col) +{ + dwCol = col; + + for(int i=0; i<256; i++) + if(letters[i]) + letters[i]->SetColor(col); +} + +void hgeFont::SetZ(float z) +{ + fZ = z; + + for(int i=0; i<256; i++) + if(letters[i]) + letters[i]->SetZ(z); +} + +void hgeFont::SetBlendMode(int blend) +{ + nBlend = blend; + + for(int i=0; i<256; i++) + if(letters[i]) + letters[i]->SetBlendMode(blend); +} + +char *hgeFont::_get_line(char *file, char *line) +{ + int i=0; + + if(!file[i]) return 0; + + while(file[i] && file[i]!='\n' && file[i]!='\r') + { + line[i]=file[i]; + i++; + } + line[i]=0; + + while(file[i] && (file[i]=='\n' || file[i]=='\r')) i++; + + return file + i; +}
\ No newline at end of file diff --git a/hgehelp/hgegui.cpp b/hgehelp/hgegui.cpp new file mode 100644 index 0000000..3867d71 --- /dev/null +++ b/hgehelp/hgegui.cpp @@ -0,0 +1,397 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeGUI helper class implementation +*/ + + +#include "../../include/hgegui.h" + + +HGE *hgeGUI::hge=0; +HGE *hgeGUIObject::hge=0; + + +hgeGUI::hgeGUI() +{ + hge=hgeCreate(HGE_VERSION); + + ctrls=0; + ctrlLock=0; + ctrlFocus=0; + ctrlOver=0; + navmode=HGEGUI_NONAVKEYS; + bLPressed=bLReleased=false; + bRPressed=bRReleased=false; + nWheel=0; + mx=my=0.0f; + nEnterLeave=0; + sprCursor=0; +} + +hgeGUI::~hgeGUI() +{ + hgeGUIObject *ctrl=ctrls, *nextctrl; + + while(ctrl) + { + nextctrl=ctrl->next; + delete ctrl; + ctrl=nextctrl; + } + + hge->Release(); +} + +void hgeGUI::AddCtrl(hgeGUIObject *ctrl) +{ + hgeGUIObject *last=ctrls; + + ctrl->gui=this; + + if(!ctrls) + { + ctrls=ctrl; + ctrl->prev=0; + ctrl->next=0; + } + else + { + while(last->next) last=last->next; + last->next=ctrl; + ctrl->prev=last; + ctrl->next=0; + } +} + +void hgeGUI::DelCtrl(int id) +{ + hgeGUIObject *ctrl=ctrls; + + while(ctrl) + { + if(ctrl->id == id) + { + if(ctrl->prev) ctrl->prev->next = ctrl->next; + else ctrls = ctrl->next; + if(ctrl->next) ctrl->next->prev = ctrl->prev; + delete ctrl; + return; + } + ctrl=ctrl->next; + } +} + +hgeGUIObject* hgeGUI::GetCtrl(int id) const +{ + hgeGUIObject *ctrl=ctrls; + + while(ctrl) + { + if(ctrl->id == id) return ctrl; + ctrl=ctrl->next; + } + + return NULL; +} + +void hgeGUI::MoveCtrl(int id, float x, float y) +{ + hgeGUIObject *ctrl=GetCtrl(id); + ctrl->rect.x2=x + (ctrl->rect.x2 - ctrl->rect.x1); + ctrl->rect.y2=y + (ctrl->rect.y2 - ctrl->rect.y1); + ctrl->rect.x1=x; + ctrl->rect.y1=y; +} + +void hgeGUI::ShowCtrl(int id, bool bVisible) +{ + GetCtrl(id)->bVisible=bVisible; +} + +void hgeGUI::EnableCtrl(int id, bool bEnabled) +{ + GetCtrl(id)->bEnabled=bEnabled; +} + +void hgeGUI::SetNavMode(int mode) +{ + navmode=mode; +} + +void hgeGUI::SetCursor(hgeSprite *spr) +{ + sprCursor=spr; +} + + +void hgeGUI::SetColor(DWORD color) +{ + hgeGUIObject *ctrl=ctrls; + + while(ctrl) + { + ctrl->SetColor(color); + ctrl=ctrl->next; + } +} + + +void hgeGUI::Reset() +{ + hgeGUIObject *ctrl=ctrls; + + while(ctrl) + { + ctrl->Reset(); + ctrl=ctrl->next; + } + + ctrlLock=0; + ctrlOver=0; + ctrlFocus=0; +} + + +void hgeGUI::Move(float dx, float dy) +{ + hgeGUIObject *ctrl=ctrls; + + while(ctrl) + { + ctrl->rect.x1 += dx; + ctrl->rect.y1 += dy; + ctrl->rect.x2 += dx; + ctrl->rect.y2 += dy; + + ctrl=ctrl->next; + } +} + + +void hgeGUI::SetFocus(int id) +{ + hgeGUIObject *ctrlNewFocus=GetCtrl(id); + + if(ctrlNewFocus==ctrlFocus) return; + if(!ctrlNewFocus) + { + if(ctrlFocus) ctrlFocus->Focus(false); + ctrlFocus=0; + } + else if(!ctrlNewFocus->bStatic && ctrlNewFocus->bVisible && ctrlNewFocus->bEnabled) + { + if(ctrlFocus) ctrlFocus->Focus(false); + if(ctrlNewFocus) ctrlNewFocus->Focus(true); + ctrlFocus=ctrlNewFocus; + } +} + +int hgeGUI::GetFocus() const +{ + if(ctrlFocus) return ctrlFocus->id; + else return 0; +} + +void hgeGUI::Enter() +{ + hgeGUIObject *ctrl=ctrls; + + while(ctrl) + { + ctrl->Enter(); + ctrl=ctrl->next; + } + + nEnterLeave=2; +} + +void hgeGUI::Leave() +{ + hgeGUIObject *ctrl=ctrls; + + while(ctrl) + { + ctrl->Leave(); + ctrl=ctrl->next; + } + + ctrlFocus=0; + ctrlOver=0; + ctrlLock=0; + nEnterLeave=1; +} + +void hgeGUI::Render() +{ + hgeGUIObject *ctrl=ctrls; + + while(ctrl) + { + if(ctrl->bVisible) ctrl->Render(); + ctrl=ctrl->next; + } + + if(hge->Input_IsMouseOver() && sprCursor) sprCursor->Render(mx,my); +} + +int hgeGUI::Update(float dt) +{ + bool bDone; + int key; + hgeGUIObject *ctrl; + +// Update the mouse variables + + hge->Input_GetMousePos(&mx, &my); + bLPressed = hge->Input_KeyDown(HGEK_LBUTTON); + bLReleased = hge->Input_KeyUp(HGEK_LBUTTON); + bRPressed = hge->Input_KeyDown(HGEK_RBUTTON); + bRReleased = hge->Input_KeyUp(HGEK_RBUTTON); + nWheel=hge->Input_GetMouseWheel(); + +// Update all controls + + ctrl=ctrls; + while(ctrl) + { + ctrl->Update(dt); + ctrl=ctrl->next; + } + +// Handle Enter/Leave + + if(nEnterLeave) + { + ctrl=ctrls; bDone=true; + while(ctrl) + { + if(!ctrl->IsDone()) { bDone=false; break; } + ctrl=ctrl->next; + } + if(!bDone) return 0; + else + { + if(nEnterLeave==1) return -1; + else nEnterLeave=0; + } + } + +// Handle keys + + key=hge->Input_GetKey(); + if(((navmode & HGEGUI_LEFTRIGHT) && key==HGEK_LEFT) || + ((navmode & HGEGUI_UPDOWN) && key==HGEK_UP)) + { + ctrl=ctrlFocus; + if(!ctrl) + { + ctrl=ctrls; + if(!ctrl) return 0; + } + do { + ctrl=ctrl->prev; + if(!ctrl && ((navmode & HGEGUI_CYCLED) || !ctrlFocus)) + { + ctrl=ctrls; + while(ctrl->next) ctrl=ctrl->next; + } + if(!ctrl || ctrl==ctrlFocus) break; + } while(ctrl->bStatic==true || ctrl->bVisible==false || ctrl->bEnabled==false); + + if(ctrl && ctrl!=ctrlFocus) + { + if(ctrlFocus) ctrlFocus->Focus(false); + if(ctrl) ctrl->Focus(true); + ctrlFocus=ctrl; + } + } + else if(((navmode & HGEGUI_LEFTRIGHT) && key==HGEK_RIGHT) || + ((navmode & HGEGUI_UPDOWN) && key==HGEK_DOWN)) + { + ctrl=ctrlFocus; + if(!ctrl) + { + ctrl=ctrls; + if(!ctrl) return 0; + while(ctrl->next) ctrl=ctrl->next; + } + do { + ctrl=ctrl->next; + if(!ctrl && ((navmode & HGEGUI_CYCLED) || !ctrlFocus)) ctrl=ctrls; + if(!ctrl || ctrl==ctrlFocus) break; + } while(ctrl->bStatic==true || ctrl->bVisible==false || ctrl->bEnabled==false); + + if(ctrl && ctrl!=ctrlFocus) + { + if(ctrlFocus) ctrlFocus->Focus(false); + if(ctrl) ctrl->Focus(true); + ctrlFocus=ctrl; + } + } + else if(ctrlFocus && key && key!=HGEK_LBUTTON && key!=HGEK_RBUTTON) + { + if(ctrlFocus->KeyClick(key, hge->Input_GetChar())) return ctrlFocus->id; + } + +// Handle mouse + + bool bLDown = hge->Input_GetKeyState(HGEK_LBUTTON); + bool bRDown = hge->Input_GetKeyState(HGEK_RBUTTON); + + if(ctrlLock) + { + ctrl=ctrlLock; + if(!bLDown && !bRDown) ctrlLock=0; + if(ProcessCtrl(ctrl)) return ctrl->id; + } + else + { + // Find last (topmost) control + + ctrl=ctrls; + if(ctrl) + while(ctrl->next) ctrl=ctrl->next; + + while(ctrl) + { + if(ctrl->rect.TestPoint(mx,my) && ctrl->bEnabled) + { + if(ctrlOver != ctrl) + { + if(ctrlOver) ctrlOver->MouseOver(false); + ctrl->MouseOver(true); + ctrlOver=ctrl; + } + + if(ProcessCtrl(ctrl)) return ctrl->id; + else return 0; + } + ctrl=ctrl->prev; + } + + if(ctrlOver) {ctrlOver->MouseOver(false); ctrlOver=0;} + + } + + return 0; +} + +bool hgeGUI::ProcessCtrl(hgeGUIObject *ctrl) +{ + bool bResult=false; + + if(bLPressed) { ctrlLock=ctrl;SetFocus(ctrl->id);bResult=bResult || ctrl->MouseLButton(true); } + if(bRPressed) { ctrlLock=ctrl;SetFocus(ctrl->id);bResult=bResult || ctrl->MouseRButton(true); } + if(bLReleased) { bResult=bResult || ctrl->MouseLButton(false); } + if(bRReleased) { bResult=bResult || ctrl->MouseRButton(false); } + if(nWheel) { bResult=bResult || ctrl->MouseWheel(nWheel); } + bResult=bResult || ctrl->MouseMove(mx-ctrl->rect.x1,my-ctrl->rect.y1); + + return bResult; +} + + + diff --git a/hgehelp/hgeguictrls.cpp b/hgehelp/hgeguictrls.cpp new file mode 100644 index 0000000..20fae4b --- /dev/null +++ b/hgehelp/hgeguictrls.cpp @@ -0,0 +1,361 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeGUI default controls implementation +*/ + + +#include "../../include/hgeguictrls.h" +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + + +/* +** hgeGUIText +*/ + +hgeGUIText::hgeGUIText(int _id, float x, float y, float w, float h, hgeFont *fnt) +{ + id=_id; + bStatic=true; + bVisible=true; + bEnabled=true; + rect.Set(x, y, x+w, y+h); + + font=fnt; + tx=x; + ty=y+(h-fnt->GetHeight())/2.0f; + + text[0]=0; +} + +void hgeGUIText::SetMode(int _align) +{ + align=_align; + if(align==HGETEXT_RIGHT) tx=rect.x2; + else if(align==HGETEXT_CENTER) tx=(rect.x1+rect.x2)/2.0f; + else tx=rect.x1; +} + +void hgeGUIText::SetText(const char *_text) +{ + strncpy(text, _text, sizeof(text)-1); + text[sizeof(text) - 1] = '\0'; +} + +void hgeGUIText::printf(const char *format, ...) +{ + va_list vl; + va_start(vl, format); + vsnprintf(text, sizeof(text)-1, format, vl); + va_end(vl); +} + +void hgeGUIText::Render() +{ + font->SetColor(color); + font->Render(tx,ty,align,text); +} + +/* +** hgeGUIButton +*/ + +hgeGUIButton::hgeGUIButton(int _id, float x, float y, float w, float h, HTEXTURE tex, float tx, float ty) +{ + id=_id; + bStatic=false; + bVisible=true; + bEnabled=true; + rect.Set(x, y, x+w, y+h); + + bPressed=false; + bTrigger=false; + + sprUp = new hgeSprite(tex, tx, ty, w, h); + sprDown = new hgeSprite(tex, tx+w, ty, w, h); +} + +hgeGUIButton::~hgeGUIButton() +{ + if(sprUp) delete sprUp; + if(sprDown) delete sprDown; +} + +void hgeGUIButton::Render() +{ + if(bPressed) sprDown->Render(rect.x1, rect.y1); + else sprUp->Render(rect.x1, rect.y1); +} + +bool hgeGUIButton::MouseLButton(bool bDown) +{ + if(bDown) + { + bOldState=bPressed; bPressed=true; + return false; + } + else + { + if(bTrigger) bPressed=!bOldState; + else bPressed=false; + return true; + } +} + +/* +** hgeGUISlider +*/ + +hgeGUISlider::hgeGUISlider(int _id, float x, float y, float w, float h, HTEXTURE tex, float tx, float ty, float sw, float sh, bool vertical) +{ + id=_id; + bStatic=false; + bVisible=true; + bEnabled=true; + bPressed=false; + bVertical=vertical; + rect.Set(x, y, x+w, y+h); + + mode=HGESLIDER_BAR; + fMin=0; fMax=100; fVal=50; + sl_w=sw; sl_h=sh; + + sprSlider=new hgeSprite(tex, tx, ty, sw, sh); +} + +hgeGUISlider::~hgeGUISlider() +{ + if(sprSlider) delete sprSlider; +} + +void hgeGUISlider::SetValue(float _fVal) +{ + if(_fVal<fMin) fVal=fMin; + else if(_fVal>fMax) fVal=fMax; + else fVal=_fVal; +} + +void hgeGUISlider::Render() +{ + float xx, yy; + float x1,y1,x2,y2; + + xx=rect.x1+(rect.x2-rect.x1)*(fVal-fMin)/(fMax-fMin); + yy=rect.y1+(rect.y2-rect.y1)*(fVal-fMin)/(fMax-fMin); + + if(bVertical) + switch(mode) + { + case HGESLIDER_BAR: x1=rect.x1; y1=rect.y1; x2=rect.x2; y2=yy; break; + case HGESLIDER_BARRELATIVE: x1=rect.x1; y1=(rect.y1+rect.y2)/2; x2=rect.x2; y2=yy; break; + case HGESLIDER_SLIDER: x1=(rect.x1+rect.x2-sl_w)/2; y1=yy-sl_h/2; x2=(rect.x1+rect.x2+sl_w)/2; y2=yy+sl_h/2; break; + } + else + switch(mode) + { + case HGESLIDER_BAR: x1=rect.x1; y1=rect.y1; x2=xx; y2=rect.y2; break; + case HGESLIDER_BARRELATIVE: x1=(rect.x1+rect.x2)/2; y1=rect.y1; x2=xx; y2=rect.y2; break; + case HGESLIDER_SLIDER: x1=xx-sl_w/2; y1=(rect.y1+rect.y2-sl_h)/2; x2=xx+sl_w/2; y2=(rect.y1+rect.y2+sl_h)/2; break; + } + + sprSlider->RenderStretch(x1, y1, x2, y2); +} + +bool hgeGUISlider::MouseLButton(bool bDown) +{ + bPressed=bDown; + return false; +} + +bool hgeGUISlider::MouseMove(float x, float y) +{ + if(bPressed) + { + if(bVertical) + { + if(y>rect.y2-rect.y1) y=rect.y2-rect.y1; + if(y<0) y=0; + fVal=fMin+(fMax-fMin)*y/(rect.y2-rect.y1); + } + else + { + if(x>rect.x2-rect.x1) x=rect.x2-rect.x1; + if(x<0) x=0; + fVal=fMin+(fMax-fMin)*x/(rect.x2-rect.x1); + } + return true; + } + + return false; +} + + +/* +** hgeGUIListbox +*/ + +hgeGUIListbox::hgeGUIListbox(int _id, float x, float y, float w, float h, hgeFont *fnt, DWORD tColor, DWORD thColor, DWORD hColor) +{ + id=_id; + bStatic=false; + bVisible=true; + bEnabled=true; + rect.Set(x, y, x+w, y+h); + font=fnt; + sprHighlight=new hgeSprite(0, 0, 0, w, fnt->GetHeight()); + sprHighlight->SetColor(hColor); + textColor=tColor; + texthilColor=thColor; + pItems=0; + nItems=0; + + nSelectedItem=0; + nTopItem=0; + mx=0; my=0; +} + +hgeGUIListbox::~hgeGUIListbox() +{ + Clear(); + if(sprHighlight) delete sprHighlight; +} + + +int hgeGUIListbox::AddItem(char *item) +{ + hgeGUIListboxItem *pItem=pItems, *pPrev=0, *pNew; + + pNew = new hgeGUIListboxItem; + memcpy(pNew->text, item, min(sizeof(pNew->text), strlen(item)+1)); + pNew->text[sizeof(pNew->text)-1]='\0'; + pNew->next=0; + + while(pItem) { pPrev=pItem; pItem=pItem->next; } + + if(pPrev) pPrev->next=pNew; + else pItems=pNew; + nItems++; + + return nItems-1; +} + +void hgeGUIListbox::DeleteItem(int n) +{ + int i; + hgeGUIListboxItem *pItem=pItems, *pPrev=0; + + if(n<0 || n>=GetNumItems()) return; + + for(i=0;i<n;i++) { pPrev=pItem; pItem=pItem->next; } + + if(pPrev) pPrev->next=pItem->next; + else pItems=pItem->next; + + delete pItem; + nItems--; +} + +char *hgeGUIListbox::GetItemText(int n) +{ + int i; + hgeGUIListboxItem *pItem=pItems; + + if(n<0 || n>=GetNumItems()) return 0; + + for(i=0;i<n;i++) pItem=pItem->next; + + return pItem->text; +} + +void hgeGUIListbox::Clear() +{ + hgeGUIListboxItem *pItem=pItems, *pNext; + + while(pItem) + { + pNext=pItem->next; + delete pItem; + pItem=pNext; + } + + pItems=0; + nItems=0; +} + +void hgeGUIListbox::Render() +{ + int i; + hgeGUIListboxItem *pItem=pItems; + + for(i=0;i<nTopItem;i++) pItem=pItem->next; + for(i=0;i<GetNumRows();i++) + { + if(i>=nItems) return; + + if(nTopItem+i == nSelectedItem) + { + sprHighlight->Render(rect.x1,rect.y1+i*font->GetHeight()); + font->SetColor(texthilColor); + } + else + font->SetColor(textColor); + + font->Render(rect.x1+3, rect.y1+i*font->GetHeight(), HGETEXT_LEFT, pItem->text); + pItem=pItem->next; + } +} + +bool hgeGUIListbox::MouseLButton(bool bDown) +{ + int nItem; + + if(bDown) + { + nItem=nTopItem+int(my)/int(font->GetHeight()); + if(nItem<nItems) + { + nSelectedItem=nItem; + return true; + } + } + return false; +} + + +bool hgeGUIListbox::MouseWheel(int nNotches) +{ + nTopItem-=nNotches; + if(nTopItem<0) nTopItem=0; + if(nTopItem>GetNumItems()-GetNumRows()) nTopItem=GetNumItems()-GetNumRows(); + + return true; +} + +bool hgeGUIListbox::KeyClick(int key, int chr) +{ + switch(key) + { + case HGEK_DOWN: + if(nSelectedItem < nItems-1) + { + nSelectedItem++; + if(nSelectedItem > nTopItem+GetNumRows()-1) nTopItem=nSelectedItem-GetNumRows()+1; + return true; + } + break; + + case HGEK_UP: + if(nSelectedItem > 0) + { + nSelectedItem--; + if(nSelectedItem < nTopItem) nTopItem=nSelectedItem; + return true; + } + break; + } + return false; +} diff --git a/hgehelp/hgeparticle.cpp b/hgehelp/hgeparticle.cpp new file mode 100644 index 0000000..9c5f678 --- /dev/null +++ b/hgehelp/hgeparticle.cpp @@ -0,0 +1,308 @@ +// PLEASE NOTE that this is not the 1.81 version of hgeparticle.cpp ... +// the game I'm working on used an older HGE that breaks with the 1.81 +// particle system. If you want 1.81, add the "byteswap" stuff to it. --ryan. + +/* +** Haaf's Game Engine 1.61 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeParticleSystem helper class implementation +*/ + + +#include "../../include/hgeparticle.h" + +HGE *hgeParticleSystem::hge=0; + +hgeParticleSystem::hgeParticleSystem(const char *filename, hgeSprite *sprite, float fps) +{ + void *psi; + + hge=hgeCreate(HGE_VERSION); + + psi=hge->Resource_Load(filename); + if(!psi) return; + + char *ptr = (char *) psi; + memset(&info, '\0', sizeof (info)); + info.sprite = sprite; + ptr += 4; // skip these bytes. + + #define SETMEMBER(typ, x) \ + { info.x = *((const typ *) ptr); ptr += sizeof (typ); BYTESWAP(info.x); } + SETMEMBER(int, nEmission); + SETMEMBER(float, fLifetime); + SETMEMBER(float, fParticleLifeMin); + SETMEMBER(float, fParticleLifeMax); + SETMEMBER(float, fDirection); + SETMEMBER(float, fSpread); + SETMEMBER(BYTE, bRelative); + ptr += 3; // padding. + SETMEMBER(float, fSpeedMin); + SETMEMBER(float, fSpeedMax); + SETMEMBER(float, fGravityMin); + SETMEMBER(float, fGravityMax); + SETMEMBER(float, fRadialAccelMin); + SETMEMBER(float, fRadialAccelMax); + SETMEMBER(float, fTangentialAccelMin); + SETMEMBER(float, fTangentialAccelMax); + SETMEMBER(float, fSizeStart); + SETMEMBER(float, fSizeEnd); + SETMEMBER(float, fSizeVar); + SETMEMBER(float, fSpinStart); + SETMEMBER(float, fSpinEnd); + SETMEMBER(float, fSpinVar); + SETMEMBER(float, colColorStart.r); + SETMEMBER(float, colColorStart.g); + SETMEMBER(float, colColorStart.b); + SETMEMBER(float, colColorStart.a); + SETMEMBER(float, colColorEnd.r); + SETMEMBER(float, colColorEnd.g); + SETMEMBER(float, colColorEnd.b); + SETMEMBER(float, colColorEnd.a); + SETMEMBER(float, fColorVar); + SETMEMBER(float, fAlphaVar); + #undef SETMEMBER + + hge->Resource_Free(psi); + + vecLocation.x=vecPrevLocation.x=0.0f; + vecLocation.y=vecPrevLocation.y=0.0f; + fTx=fTy=0; + + fEmissionResidue=0.0f; + nParticlesAlive=0; + fAge=-2.0; + if(fps!=0.0f) fUpdSpeed=1.0f/fps; + else fUpdSpeed=0.0f; + fResidue=0.0f; + + rectBoundingBox.Clear(); + bUpdateBoundingBox=false; +} + +hgeParticleSystem::hgeParticleSystem(hgeParticleSystemInfo *psi, float fps) +{ + hge=hgeCreate(HGE_VERSION); + + memcpy(&info, psi, sizeof(hgeParticleSystemInfo)); + + vecLocation.x=vecPrevLocation.x=0.0f; + vecLocation.y=vecPrevLocation.y=0.0f; + fTx=fTy=0; + + fEmissionResidue=0.0f; + nParticlesAlive=0; + fAge=-2.0; + if(fps!=0.0f) fUpdSpeed=1.0f/fps; + else fUpdSpeed=0.0f; + fResidue=0.0f; + + rectBoundingBox.Clear(); + bUpdateBoundingBox=false; +} + +hgeParticleSystem::hgeParticleSystem(const hgeParticleSystem &ps) +{ + memcpy(this, &ps, sizeof(hgeParticleSystem)); + hge=hgeCreate(HGE_VERSION); +} + +void hgeParticleSystem::Update(float fDeltaTime) +{ + if(fUpdSpeed==0.0f) _update(fDeltaTime); + else + { + fResidue+=fDeltaTime; + if(fResidue>=fUpdSpeed) + { + _update(fUpdSpeed); + while(fResidue>=fUpdSpeed) fResidue-=fUpdSpeed; + } + } +} + +void hgeParticleSystem::_update(float fDeltaTime) +{ + int i; + float ang; + hgeParticle *par; + hgeVector vecAccel, vecAccel2; + + if(fAge >= 0) + { + fAge += fDeltaTime; + if(fAge >= info.fLifetime) fAge = -2.0f; + } + + // update all alive particles + + if(bUpdateBoundingBox) rectBoundingBox.Clear(); + par=particles; + + for(i=0; i<nParticlesAlive; i++) + { + par->fAge += fDeltaTime; + if(par->fAge >= par->fTerminalAge) + { + nParticlesAlive--; + memcpy(par, &particles[nParticlesAlive], sizeof(hgeParticle)); + i--; + continue; + } + + vecAccel = par->vecLocation-vecLocation; + vecAccel.Normalize(); + vecAccel2 = vecAccel; + vecAccel *= par->fRadialAccel; + + // vecAccel2.Rotate(M_PI_2); + // the following is faster + ang = vecAccel2.x; + vecAccel2.x = -vecAccel2.y; + vecAccel2.y = ang; + + vecAccel2 *= par->fTangentialAccel; + par->vecVelocity += (vecAccel+vecAccel2)*fDeltaTime; + par->vecVelocity.y += par->fGravity*fDeltaTime; + + par->vecLocation += par->vecVelocity; + + par->fSpin += par->fSpinDelta*fDeltaTime; + par->fSize += par->fSizeDelta*fDeltaTime; + par->colColor += par->colColorDelta*fDeltaTime; + + if(bUpdateBoundingBox) rectBoundingBox.Encapsulate(par->vecLocation.x, par->vecLocation.y); + + par++; + } + + // generate new particles + + if(fAge != -2.0f) + { + float fParticlesNeeded = info.nEmission*fDeltaTime + fEmissionResidue; + int nParticlesCreated = (unsigned int)fParticlesNeeded; + fEmissionResidue=fParticlesNeeded-nParticlesCreated; + + par=&particles[nParticlesAlive]; + + for(i=0; i<nParticlesCreated; i++) + { + if(nParticlesAlive>=MAX_PARTICLES) break; + + par->fAge = 0.0f; + par->fTerminalAge = hge->Random_Float(info.fParticleLifeMin, info.fParticleLifeMax); + + par->vecLocation = vecPrevLocation+(vecLocation-vecPrevLocation)*hge->Random_Float(0.0f, 1.0f); + par->vecLocation.x += hge->Random_Float(-2.0f, 2.0f); + par->vecLocation.y += hge->Random_Float(-2.0f, 2.0f); + + ang=info.fDirection-M_PI_2+hge->Random_Float(0,info.fSpread)-info.fSpread/2.0f; + if(info.bRelative) ang += (vecPrevLocation-vecLocation).Angle()+M_PI_2; + par->vecVelocity.x = cosf(ang); + par->vecVelocity.y = sinf(ang); + par->vecVelocity *= hge->Random_Float(info.fSpeedMin, info.fSpeedMax); + + par->fGravity = hge->Random_Float(info.fGravityMin, info.fGravityMax); + par->fRadialAccel = hge->Random_Float(info.fRadialAccelMin, info.fRadialAccelMax); + par->fTangentialAccel = hge->Random_Float(info.fTangentialAccelMin, info.fTangentialAccelMax); + + par->fSize = hge->Random_Float(info.fSizeStart, info.fSizeStart+(info.fSizeEnd-info.fSizeStart)*info.fSizeVar); + par->fSizeDelta = (info.fSizeEnd-par->fSize) / par->fTerminalAge; + + par->fSpin = hge->Random_Float(info.fSpinStart, info.fSpinStart+(info.fSpinEnd-info.fSpinStart)*info.fSpinVar); + par->fSpinDelta = (info.fSpinEnd-par->fSpin) / par->fTerminalAge; + + par->colColor.r = hge->Random_Float(info.colColorStart.r, info.colColorStart.r+(info.colColorEnd.r-info.colColorStart.r)*info.fColorVar); + par->colColor.g = hge->Random_Float(info.colColorStart.g, info.colColorStart.g+(info.colColorEnd.g-info.colColorStart.g)*info.fColorVar); + par->colColor.b = hge->Random_Float(info.colColorStart.b, info.colColorStart.b+(info.colColorEnd.b-info.colColorStart.b)*info.fColorVar); + par->colColor.a = hge->Random_Float(info.colColorStart.a, info.colColorStart.a+(info.colColorEnd.a-info.colColorStart.a)*info.fAlphaVar); + + par->colColorDelta.r = (info.colColorEnd.r-par->colColor.r) / par->fTerminalAge; + par->colColorDelta.g = (info.colColorEnd.g-par->colColor.g) / par->fTerminalAge; + par->colColorDelta.b = (info.colColorEnd.b-par->colColor.b) / par->fTerminalAge; + par->colColorDelta.a = (info.colColorEnd.a-par->colColor.a) / par->fTerminalAge; + + if(bUpdateBoundingBox) rectBoundingBox.Encapsulate(par->vecLocation.x, par->vecLocation.y); + + nParticlesAlive++; + par++; + } + } + + vecPrevLocation=vecLocation; +} + +void hgeParticleSystem::MoveTo(float x, float y, bool bMoveParticles) +{ + int i; + float dx,dy; + + if(bMoveParticles) + { + dx=x-vecLocation.x; + dy=y-vecLocation.y; + + for(i=0;i<nParticlesAlive;i++) + { + particles[i].vecLocation.x += dx; + particles[i].vecLocation.y += dy; + } + + vecPrevLocation.x=vecPrevLocation.x + dx; + vecPrevLocation.y=vecPrevLocation.y + dy; + } + else + { + if(fAge==-2.0) { vecPrevLocation.x=x; vecPrevLocation.y=y; } + else { vecPrevLocation.x=vecLocation.x; vecPrevLocation.y=vecLocation.y; } + } + + vecLocation.x=x; + vecLocation.y=y; +} + +void hgeParticleSystem::FireAt(float x, float y) +{ + Stop(); + MoveTo(x,y); + Fire(); +} + +void hgeParticleSystem::Fire() +{ + if(info.fLifetime==-1.0f) fAge=-1.0f; + else fAge=0.0f; + fResidue=0.0; +} + +void hgeParticleSystem::Stop(bool bKillParticles) +{ + fAge=-2.0f; + if(bKillParticles) + { + nParticlesAlive=0; + rectBoundingBox.Clear(); + } +} + +void hgeParticleSystem::Render() +{ + int i; + DWORD col; + hgeParticle *par=particles; + + col=info.sprite->GetColor(); + + for(i=0; i<nParticlesAlive; i++) + { + info.sprite->SetColor(par->colColor.GetHWColor()); + info.sprite->RenderEx(par->vecLocation.x+fTx, par->vecLocation.y+fTy, par->fSpin*par->fAge, par->fSize); + par++; + } + + info.sprite->SetColor(col); +} + diff --git a/hgehelp/hgepmanager.cpp b/hgehelp/hgepmanager.cpp new file mode 100644 index 0000000..69e518a --- /dev/null +++ b/hgehelp/hgepmanager.cpp @@ -0,0 +1,96 @@ +// PLEASE NOTE that this is not the 1.81 version of hgeparticle.cpp ... +// the game I'm working on used an older HGE that breaks with the 1.81 +// particle system. If you want 1.81, just overwrite this file. --ryan. + +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeParticleManager helper class implementation +*/ + + +#include "../../include/hgeparticle.h" + + +hgeParticleManager::hgeParticleManager(const float fps) +{ + nPS=0; + fFPS=fps; + tX=tY=0.0f; +} + +hgeParticleManager::~hgeParticleManager() +{ + int i; + for(i=0;i<nPS;i++) delete psList[i]; +} + +void hgeParticleManager::Update(float dt) +{ + int i; + for(i=0;i<nPS;i++) + { + psList[i]->Update(dt); + if(psList[i]->GetAge()==-2.0f && psList[i]->GetParticlesAlive()==0) + { + delete psList[i]; + psList[i]=psList[nPS-1]; + nPS--; + i--; + } + } +} + +void hgeParticleManager::Render() +{ + int i; + for(i=0;i<nPS;i++) psList[i]->Render(); +} + +hgeParticleSystem* hgeParticleManager::SpawnPS(hgeParticleSystemInfo *psi, float x, float y) +{ + if(nPS==MAX_PSYSTEMS) return 0; + psList[nPS]=new hgeParticleSystem(psi,fFPS); + psList[nPS]->FireAt(x,y); + psList[nPS]->Transpose(tX,tY); + nPS++; + return psList[nPS-1]; +} + +bool hgeParticleManager::IsPSAlive(hgeParticleSystem *ps) const +{ + int i; + for(i=0;i<nPS;i++) if(psList[i]==ps) return true; + return false; +} + +void hgeParticleManager::Transpose(float x, float y) +{ + int i; + for(i=0;i<nPS;i++) psList[i]->Transpose(x,y); + tX=x; tY=y; +} + +void hgeParticleManager::KillPS(hgeParticleSystem *ps) +{ + int i; + for(i=0;i<nPS;i++) + { + if(psList[i]==ps) + { + delete psList[i]; + psList[i]=psList[nPS-1]; + nPS--; + return; + } + } +} + +void hgeParticleManager::KillAll() +{ + int i; + for(i=0;i<nPS;i++) delete psList[i]; + nPS=0; +} diff --git a/hgehelp/hgerect.cpp b/hgehelp/hgerect.cpp new file mode 100644 index 0000000..789a9a4 --- /dev/null +++ b/hgehelp/hgerect.cpp @@ -0,0 +1,45 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeRect helper class implementation +*/ + + +#include "../../include/hgerect.h" +#include <math.h> + + +void hgeRect::Encapsulate(float x, float y) +{ + if(bClean) + { + x1=x2=x; + y1=y2=y; + bClean=false; + } + else + { + if(x<x1) x1=x; + if(x>x2) x2=x; + if(y<y1) y1=y; + if(y>y2) y2=y; + } +} + +bool hgeRect::TestPoint(float x, float y) const +{ + if(x>=x1 && x<x2 && y>=y1 && y<y2) return true; + + return false; +} + +bool hgeRect::Intersect(const hgeRect *rect) const +{ + if(fabs(x1 + x2 - rect->x1 - rect->x2) < (x2 - x1 + rect->x2 - rect->x1)) + if(fabs(y1 + y2 - rect->y1 - rect->y2) < (y2 - y1 + rect->y2 - rect->y1)) + return true; + + return false; +} diff --git a/hgehelp/hgeresource.cpp b/hgehelp/hgeresource.cpp new file mode 100644 index 0000000..9224dd1 --- /dev/null +++ b/hgehelp/hgeresource.cpp @@ -0,0 +1,254 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeResourceManager helper class implementation +*/ + + +#include "../../include/hgeresource.h" +#include "parser.h" +#include "resources.h" + + +HGE *hgeResourceManager::hge=0; + + +hgeResourceManager::hgeResourceManager(const char *scriptname) +{ + hge=hgeCreate(HGE_VERSION); + + for(int i=0;i<RESTYPES;i++) res[i]=0; + _parse_script(scriptname); +} + +hgeResourceManager::~hgeResourceManager() +{ + _remove_all(); + hge->Release(); +} + +void hgeResourceManager::_parse_script(const char *scriptname) +{ + ResDesc *rc, *rcnext; + + if(scriptname) + { + RScript::Parse(this, NULL, scriptname, NULL); + + rc=res[RES_SCRIPT]; + while(rc) + { + rc->Free(); + rcnext=rc->next; + delete rc; + rc=rcnext; + } + res[RES_SCRIPT]=0; + } +} + +void hgeResourceManager::_remove_all() +{ + int i; + ResDesc *rc, *rcnext; + + for(i=0;i<RESTYPES;i++) + { + rc=res[i]; + while(rc) + { + rc->Free(); + rcnext=rc->next; + delete rc; + rc=rcnext; + } + res[i]=0; + } +} + +void hgeResourceManager::ChangeScript(const char *scriptname) +{ + _remove_all(); + _parse_script(scriptname); +} + +bool hgeResourceManager::Precache(int groupid) +{ + int i; + ResDesc *rc; + bool bResult=true; + + for(i=0;i<RESTYPES;i++) + { + rc=res[i]; + while(rc) + { + if(!groupid || groupid==rc->resgroup) bResult=bResult && (rc->Get(this)!=0); + rc=rc->next; + } + } + + return bResult; +} + +void hgeResourceManager::Purge(int groupid) +{ + int i; + ResDesc *rc; + + for(i=0;i<RESTYPES;i++) + { + rc=res[i]; + while(rc) + { + if(!groupid || groupid==rc->resgroup) rc->Free(); + rc=rc->next; + } + } +} + +void* hgeResourceManager::GetResource(const char *name, int resgroup) +{ + void *reshandle; + RResource *resource; + ResDesc *Res=FindRes(this, RES_RESOURCE, name); + + if(Res) return (void *)Res->Get(this); + else + { + reshandle=hge->Resource_Load(name); + if(reshandle) + { + resource=new RResource(); + resource->handle=(size_t)reshandle; + resource->resgroup=resgroup; + strcpy(resource->name, name); + strcpy(resource->filename, name); + AddRes(this, RES_RESOURCE, resource); + + return reshandle; + } + } + + return 0; +} + +HTEXTURE hgeResourceManager::GetTexture(const char *name, int resgroup) +{ + HTEXTURE reshandle; + RTexture *resource; + ResDesc *Res=FindRes(this, RES_TEXTURE, name); + if(Res) return (HTEXTURE)Res->Get(this); + else + { + reshandle=hge->Texture_Load(name); + if(reshandle) + { + resource=new RTexture(); + resource->handle=reshandle; + resource->resgroup=resgroup; + resource->mipmap=false; + strcpy(resource->name, name); + strcpy(resource->filename, name); + AddRes(this, RES_TEXTURE, resource); + + return reshandle; + } + } + + return 0; +} + +HEFFECT hgeResourceManager::GetEffect(const char *name, int resgroup) +{ + HEFFECT reshandle; + REffect *resource; + ResDesc *Res=FindRes(this, RES_EFFECT, name); + if(Res) return (HEFFECT)Res->Get(this); + else + { + reshandle=hge->Effect_Load(name); + if(reshandle) + { + resource=new REffect(); + resource->handle=reshandle; + resource->resgroup=resgroup; + strcpy(resource->name, name); + strcpy(resource->filename, name); + AddRes(this, RES_EFFECT, resource); + + return reshandle; + } + } + + return 0; +} + +HTARGET hgeResourceManager::GetTarget(const char *name) +{ + ResDesc *Res=FindRes(this, RES_TARGET, name); + if(Res) return (HTARGET)Res->Get(this); + else return 0; +} + +hgeSprite* hgeResourceManager::GetSprite(const char *name) +{ + ResDesc *Res=FindRes(this, RES_SPRITE, name); + if(Res) return (hgeSprite *)Res->Get(this); + else return 0; +} + +hgeAnimation* hgeResourceManager::GetAnimation(const char *name) +{ + ResDesc *Res=FindRes(this, RES_ANIMATION, name); + if(Res) return (hgeAnimation *)Res->Get(this); + else return 0; +} + +hgeFont* hgeResourceManager::GetFont(const char *name) +{ + ResDesc *Res=FindRes(this, RES_FONT, name); + if(Res) return (hgeFont *)Res->Get(this); + else return 0; +} + +hgeParticleSystem* hgeResourceManager::GetParticleSystem(const char *name) +{ + ResDesc *Res=FindRes(this, RES_PARTICLE, name); + if(Res) return (hgeParticleSystem *)Res->Get(this); + else return 0; +} + +hgeDistortionMesh* hgeResourceManager::GetDistortionMesh(const char *name) +{ + ResDesc *Res=FindRes(this, RES_DISTORT, name); + if(Res) return (hgeDistortionMesh *)Res->Get(this); + else return 0; +} + +hgeStringTable* hgeResourceManager::GetStringTable(const char *name, int resgroup) +{ + hgeStringTable *strtable; + RStringTable *resource; + ResDesc *Res=FindRes(this, RES_STRTABLE, name); + if(Res) return (hgeStringTable*)Res->Get(this); + else + { + strtable=new hgeStringTable(name); + if(strtable) + { + resource=new RStringTable(); + resource->handle=(size_t)strtable; + resource->resgroup=resgroup; + strcpy(resource->name, name); + strcpy(resource->filename, name); + AddRes(this, RES_STRTABLE, resource); + + return strtable; + } + } + + return 0; +} diff --git a/hgehelp/hgesprite.cpp b/hgehelp/hgesprite.cpp new file mode 100644 index 0000000..8e61263 --- /dev/null +++ b/hgehelp/hgesprite.cpp @@ -0,0 +1,302 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeSprite helper class implementation +*/ + + +#include "../../include/hgesprite.h" +#include <math.h> + + +HGE *hgeSprite::hge=0; + + +hgeSprite::hgeSprite(HTEXTURE texture, float texx, float texy, float w, float h) +{ + float texx1, texy1, texx2, texy2; + + hge=hgeCreate(HGE_VERSION); + + tx=texx; ty=texy; + width=w; height=h; + + if(texture) + { + tex_width = (float)hge->Texture_GetWidth(texture); + tex_height = (float)hge->Texture_GetHeight(texture); + } + else + { + tex_width = 1.0f; + tex_height = 1.0f; + } + + hotX=0; + hotY=0; + bXFlip=false; + bYFlip=false; + bHSFlip=false; + quad.tex=texture; + + texx1=texx/tex_width; + texy1=texy/tex_height; + texx2=(texx+w)/tex_width; + texy2=(texy+h)/tex_height; + + quad.v[0].tx = texx1; quad.v[0].ty = texy1; + quad.v[1].tx = texx2; quad.v[1].ty = texy1; + quad.v[2].tx = texx2; quad.v[2].ty = texy2; + quad.v[3].tx = texx1; quad.v[3].ty = texy2; + + quad.v[0].z = + quad.v[1].z = + quad.v[2].z = + quad.v[3].z = 0.5f; + + quad.v[0].col = + quad.v[1].col = + quad.v[2].col = + quad.v[3].col = 0xffffffff; + + quad.blend=BLEND_DEFAULT; +} + +hgeSprite::hgeSprite(const hgeSprite &spr) +{ + memcpy(this, &spr, sizeof(hgeSprite)); + hge=hgeCreate(HGE_VERSION); +} + +void hgeSprite::Render(float x, float y) +{ + float tempx1, tempy1, tempx2, tempy2; + + tempx1 = x-hotX; + tempy1 = y-hotY; + tempx2 = x+width-hotX; + tempy2 = y+height-hotY; + + quad.v[0].x = tempx1; quad.v[0].y = tempy1; + quad.v[1].x = tempx2; quad.v[1].y = tempy1; + quad.v[2].x = tempx2; quad.v[2].y = tempy2; + quad.v[3].x = tempx1; quad.v[3].y = tempy2; + + hge->Gfx_RenderQuad(&quad); +} + + +void hgeSprite::RenderEx(float x, float y, float rot, float hscale, float vscale) +{ + float tx1, ty1, tx2, ty2; + float sint, cost; + + if(vscale==0) vscale=hscale; + + tx1 = -hotX*hscale; + ty1 = -hotY*vscale; + tx2 = (width-hotX)*hscale; + ty2 = (height-hotY)*vscale; + + if (rot != 0.0f) + { + cost = cosf(rot); + sint = sinf(rot); + + quad.v[0].x = tx1*cost - ty1*sint + x; + quad.v[0].y = tx1*sint + ty1*cost + y; + + quad.v[1].x = tx2*cost - ty1*sint + x; + quad.v[1].y = tx2*sint + ty1*cost + y; + + quad.v[2].x = tx2*cost - ty2*sint + x; + quad.v[2].y = tx2*sint + ty2*cost + y; + + quad.v[3].x = tx1*cost - ty2*sint + x; + quad.v[3].y = tx1*sint + ty2*cost + y; + } + else + { + quad.v[0].x = tx1 + x; quad.v[0].y = ty1 + y; + quad.v[1].x = tx2 + x; quad.v[1].y = ty1 + y; + quad.v[2].x = tx2 + x; quad.v[2].y = ty2 + y; + quad.v[3].x = tx1 + x; quad.v[3].y = ty2 + y; + } + + hge->Gfx_RenderQuad(&quad); +} + + +void hgeSprite::RenderStretch(float x1, float y1, float x2, float y2) +{ + quad.v[0].x = x1; quad.v[0].y = y1; + quad.v[1].x = x2; quad.v[1].y = y1; + quad.v[2].x = x2; quad.v[2].y = y2; + quad.v[3].x = x1; quad.v[3].y = y2; + + hge->Gfx_RenderQuad(&quad); +} + + +void hgeSprite::Render4V(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3) +{ + quad.v[0].x = x0; quad.v[0].y = y0; + quad.v[1].x = x1; quad.v[1].y = y1; + quad.v[2].x = x2; quad.v[2].y = y2; + quad.v[3].x = x3; quad.v[3].y = y3; + + hge->Gfx_RenderQuad(&quad); +} + + +hgeRect* hgeSprite::GetBoundingBoxEx(float x, float y, float rot, float hscale, float vscale, hgeRect *rect) const +{ + float tx1, ty1, tx2, ty2; + float sint, cost; + + rect->Clear(); + + tx1 = -hotX*hscale; + ty1 = -hotY*vscale; + tx2 = (width-hotX)*hscale; + ty2 = (height-hotY)*vscale; + + if (rot != 0.0f) + { + cost = cosf(rot); + sint = sinf(rot); + + rect->Encapsulate(tx1*cost - ty1*sint + x, tx1*sint + ty1*cost + y); + rect->Encapsulate(tx2*cost - ty1*sint + x, tx2*sint + ty1*cost + y); + rect->Encapsulate(tx2*cost - ty2*sint + x, tx2*sint + ty2*cost + y); + rect->Encapsulate(tx1*cost - ty2*sint + x, tx1*sint + ty2*cost + y); + } + else + { + rect->Encapsulate(tx1 + x, ty1 + y); + rect->Encapsulate(tx2 + x, ty1 + y); + rect->Encapsulate(tx2 + x, ty2 + y); + rect->Encapsulate(tx1 + x, ty2 + y); + } + + return rect; +} + +void hgeSprite::SetFlip(bool bX, bool bY, bool bHotSpot) +{ + float tx, ty; + + if(bHSFlip && bXFlip) hotX = width - hotX; + if(bHSFlip && bYFlip) hotY = height - hotY; + + bHSFlip = bHotSpot; + + if(bHSFlip && bXFlip) hotX = width - hotX; + if(bHSFlip && bYFlip) hotY = height - hotY; + + if(bX != bXFlip) + { + tx=quad.v[0].tx; quad.v[0].tx=quad.v[1].tx; quad.v[1].tx=tx; + ty=quad.v[0].ty; quad.v[0].ty=quad.v[1].ty; quad.v[1].ty=ty; + tx=quad.v[3].tx; quad.v[3].tx=quad.v[2].tx; quad.v[2].tx=tx; + ty=quad.v[3].ty; quad.v[3].ty=quad.v[2].ty; quad.v[2].ty=ty; + + bXFlip=!bXFlip; + } + + if(bY != bYFlip) + { + tx=quad.v[0].tx; quad.v[0].tx=quad.v[3].tx; quad.v[3].tx=tx; + ty=quad.v[0].ty; quad.v[0].ty=quad.v[3].ty; quad.v[3].ty=ty; + tx=quad.v[1].tx; quad.v[1].tx=quad.v[2].tx; quad.v[2].tx=tx; + ty=quad.v[1].ty; quad.v[1].ty=quad.v[2].ty; quad.v[2].ty=ty; + + bYFlip=!bYFlip; + } +} + + +void hgeSprite::SetTexture(HTEXTURE tex) +{ + float tx1,ty1,tx2,ty2; + float tw,th; + + quad.tex=tex; + + if(tex) + { + tw = (float)hge->Texture_GetWidth(tex); + th = (float)hge->Texture_GetHeight(tex); + } + else + { + tw = 1.0f; + th = 1.0f; + } + + if(tw!=tex_width || th!=tex_height) + { + tx1=quad.v[0].tx*tex_width; + ty1=quad.v[0].ty*tex_height; + tx2=quad.v[2].tx*tex_width; + ty2=quad.v[2].ty*tex_height; + + tex_width=tw; + tex_height=th; + + tx1/=tw; ty1/=th; + tx2/=tw; ty2/=th; + + quad.v[0].tx=tx1; quad.v[0].ty=ty1; + quad.v[1].tx=tx2; quad.v[1].ty=ty1; + quad.v[2].tx=tx2; quad.v[2].ty=ty2; + quad.v[3].tx=tx1; quad.v[3].ty=ty2; + } +} + + +void hgeSprite::SetTextureRect(float x, float y, float w, float h, bool adjSize) +{ + float tx1, ty1, tx2, ty2; + bool bX,bY,bHS; + + tx=x; + ty=y; + + if(adjSize) + { + width=w; + height=h; + } + + tx1=tx/tex_width; ty1=ty/tex_height; + tx2=(tx+w)/tex_width; ty2=(ty+h)/tex_height; + + quad.v[0].tx=tx1; quad.v[0].ty=ty1; + quad.v[1].tx=tx2; quad.v[1].ty=ty1; + quad.v[2].tx=tx2; quad.v[2].ty=ty2; + quad.v[3].tx=tx1; quad.v[3].ty=ty2; + + bX=bXFlip; bY=bYFlip; bHS=bHSFlip; + bXFlip=false; bYFlip=false; + SetFlip(bX,bY,bHS); +} + + +void hgeSprite::SetColor(DWORD col, int i) +{ + if(i != -1) + quad.v[i].col = col; + else + quad.v[0].col = quad.v[1].col = quad.v[2].col = quad.v[3].col = col; +} + +void hgeSprite::SetZ(float z, int i) +{ + if(i != -1) + quad.v[i].z = z; + else + quad.v[0].z = quad.v[1].z = quad.v[2].z = quad.v[3].z = z; +} diff --git a/hgehelp/hgestrings.cpp b/hgehelp/hgestrings.cpp new file mode 100644 index 0000000..d4c5d2d --- /dev/null +++ b/hgehelp/hgestrings.cpp @@ -0,0 +1,168 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeStringTable helper class implementation +*/ + + +#include "../../include/hgestrings.h" +#include <ctype.h> + +const char STRHEADERTAG[]="[HGESTRINGTABLE]"; +const char STRFORMATERROR[]="String table %s has incorrect format."; + + +HGE *hgeStringTable::hge=0; + + +hgeStringTable::hgeStringTable(const char *filename) +{ + int i; + void *data; + DWORD size; + char *desc, *pdesc; + NamedString *str; + char str_name[MAXSTRNAMELENGTH]; + char *str_value, *pvalue; + + hge=hgeCreate(HGE_VERSION); + strings=0; + + // load string table file + data=hge->Resource_Load(filename, &size); + if(!data) return; + + desc = new char[size+1]; + memcpy(desc,data,size); + desc[size]=0; + hge->Resource_Free(data); + + // check header + if(memcmp(desc, STRHEADERTAG, sizeof(STRHEADERTAG)-1)) + { + hge->System_Log(STRFORMATERROR, filename); + delete[] desc; + return; + } + + pdesc=desc+sizeof(STRHEADERTAG); + str_value=new char[8192]; + + for(;;) + { + // skip whitespaces + while(isspace(*pdesc)) pdesc++; + if(!*pdesc) break; + + // skip comments + if(*pdesc==';') + { + while(*pdesc && *pdesc != '\n') pdesc++; + pdesc++; + continue; + } + + // get string name -> str_name + i=0; + while(pdesc[i] && pdesc[i]!='=' && !isspace(pdesc[i]) && i<MAXSTRNAMELENGTH) + { + str_name[i]=pdesc[i]; + i++; + } + str_name[i]=0; + pdesc+=i; + + // skip string name overflow characters + while(*pdesc && *pdesc!='=' && !isspace(*pdesc)) pdesc++; + if(!*pdesc) break; + + // skip whitespaces to '=' + while(isspace(*pdesc)) pdesc++; + if(*pdesc!='=') { hge->System_Log(STRFORMATERROR, filename); break; } + pdesc++; + + // skip whitespaces to '"' + while(isspace(*pdesc)) pdesc++; + if(*pdesc!='"') { hge->System_Log(STRFORMATERROR, filename); break; } + pdesc++; + + // parse string value till the closing '"' -> str_value + // consider: \", \n, \\, LF, CR, whitespaces at line begin/end + pvalue=str_value; + + while(*pdesc && *pdesc!='"') + { + if(*pdesc=='\n' || *pdesc=='\r') + { + while(isspace(*pdesc)) pdesc++; + + pvalue--; + while(pvalue>=str_value && isspace(*pvalue)) pvalue--; + pvalue++; *pvalue=' '; pvalue++; + + continue; + } + + if(*pdesc=='\\') + { + pdesc++; + if(!*pdesc) continue; + if(*pdesc=='n') *pvalue='\n'; + else *pvalue=*pdesc; + pvalue++; + pdesc++; + continue; + } + + *pvalue=*pdesc; pvalue++; + pdesc++; + } + + *pvalue=0; + + // add the parsed string to the list + str=new NamedString; + strcpy(str->name, str_name); + str->string=new char[strlen(str_value)+1]; + strcpy(str->string, str_value); + str->next=strings; + strings=str; + + if(!*pdesc) break; + pdesc++; + } + + delete[] str_value; + delete[] desc; +} + +hgeStringTable::~hgeStringTable() +{ + NamedString *str, *strnext; + + str=strings; + while(str) + { + strnext=str->next; + delete[] str->string; + delete str; + str=strnext; + } + + hge->Release(); +} + +char *hgeStringTable::GetString(const char *name) +{ + NamedString *str=strings; + + while(str) + { + if(!strcmp(name, str->name)) return str->string; + str=str->next; + } + + return 0; +} diff --git a/hgehelp/hgevector.cpp b/hgehelp/hgevector.cpp new file mode 100644 index 0000000..e53ad7c --- /dev/null +++ b/hgehelp/hgevector.cpp @@ -0,0 +1,69 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeVector helper class implementation +*/ + + +#include "../../include/hgevector.h" + +float InvSqrt(float x) +{ + union + { + int intPart; + float floatPart; + } convertor; + + convertor.floatPart = x; + convertor.intPart = 0x5f3759df - (convertor.intPart >> 1); + return convertor.floatPart*(1.5f - 0.4999f*x*convertor.floatPart*convertor.floatPart); +} + +/* +hgeVector *hgeVector::Normalize() +{ + float lenRcp; + + lenRcp=sqrtf(Dot(this)); + + if(lenRcp) + { + lenRcp=1.0f/lenRcp; + + x*=lenRcp; + y*=lenRcp; + } + + return this; +} +*/ + +float hgeVector::Angle(const hgeVector *v) const +{ + if(v) + { + hgeVector s=*this, t=*v; + + s.Normalize(); t.Normalize(); + return acosf(s.Dot(&t)); + } + else return atan2f(y, x); +} + +hgeVector *hgeVector::Rotate(float a) +{ + hgeVector v; + + v.x=x*cosf(a) - y*sinf(a); + v.y=x*sinf(a) + y*cosf(a); + + x=v.x; y=v.y; + + return this; +} + + + diff --git a/hgehelp/parser.cpp b/hgehelp/parser.cpp new file mode 100644 index 0000000..0386ef9 --- /dev/null +++ b/hgehelp/parser.cpp @@ -0,0 +1,209 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Resource script parser implementation +*/ + +#include "parser.h" + + +HGE *RScriptParser::hge=0; + + +struct keyword +{ + const char* word; + int code; +}; + +keyword keytable[]= +{ + { "=", TTEQUALS }, + { ":", TTBASED }, + { ",", TTSEPARATOR }, + { "{", TTOPENBLOCK }, + { "}", TTCLOSEBLOCK }, + { "true", TTBOOL }, + { "false", TTBOOL }, + + { "Include", TTRES_INCLUDE }, + { "Resource", TTRES_RESOURCE }, + { "Texture", TTRES_TEXTURE }, + { "Sound", TTRES_SOUND }, + { "Music", TTRES_MUSIC }, + { "Stream", TTRES_STREAM }, + { "Target", TTRES_TARGET }, + { "Sprite", TTRES_SPRITE }, + { "Animation", TTRES_ANIMATION }, + { "Font", TTRES_FONT }, + { "Particle", TTRES_PARTICLE }, + { "Distortion", TTRES_DISTORT }, + { "StringTable",TTRES_STRTABLE }, + + { "filename", TTPAR_FILENAME }, + { "resgroup", TTPAR_RESGROUP }, + { "mipmap", TTPAR_MIPMAP }, + { "amplify", TTPAR_AMPLIFY }, + { "size", TTPAR_SIZE }, + { "zbuffer", TTPAR_ZBUFFER }, + { "texture", TTPAR_TEXTURE }, + { "rect", TTPAR_RECT }, + { "hotspot", TTPAR_HOTSPOT }, + { "blendmode", TTPAR_BLENDMODE }, + { "color", TTPAR_COLOR }, + { "zorder", TTPAR_ZORDER }, + { "flip", TTPAR_FLIP }, + { "scale", TTPAR_SCALE }, + { "proportion", TTPAR_PROPORTION}, + { "rotation", TTPAR_ROTATION }, + { "frames", TTPAR_FRAMES }, + { "fps", TTPAR_FPS }, + { "mode", TTPAR_MODE }, + { "tracking", TTPAR_TRACKING }, + { "spacing", TTPAR_SPACING }, + { "sprite", TTPAR_SPRITE }, + { "mesh", TTPAR_MESH }, + + { "COLORMUL", TTCON_COLORMUL }, + { "COLORADD", TTCON_COLORADD }, + { "ALPHABLEND", TTCON_ALPHABLND }, + { "ALPHAADD", TTCON_ALPHAADD }, + { "ZWRITE", TTCON_ZWRITE }, + { "NOZWRITE", TTCON_NOZWRITE }, + { "FORWARD", TTCON_FORWARD }, + { "REVERSE", TTCON_REVERSE }, + { "PINGPONG", TTCON_PINGPONG }, + { "NOPINGPONG", TTCON_NOPINGPONG}, + { "LOOP", TTCON_LOOP }, + { "NOLOOP", TTCON_NOLOOP }, + { "CIRCLE", TTCON_CIRCLE }, + { "RECT", TTCON_RECT }, + { "ALPHA", TTCON_ALPHA }, + + { NULL, TTNONE } +}; + +RScriptParser::RScriptParser(char *name, char *scr) +{ + hge=hgeCreate(HGE_VERSION); + + scriptname=name; + script=scr; + tokenvalue[0]=0; + tokentype=TTNONE; + line=1; +} + +int RScriptParser::get_token() +{ + int i; + + // Skip whitespaces and comments + + for(;;) + { + while(*script==' ' || *script=='\t' || *script=='\n' || *script=='\r') + { + if(*script=='\n') line++; + script++; + } + if(*script==';') while(*script && *script!='\n' && *script!='\r') script++; + else break; + } + + // End of script + + if(!*script) { tokentype=TTEND; tokenvalue[0]=0; return tokentype; } + + // Number + + if((*script>='0' && *script<='9') || *script=='.' || *script=='-') + { + tokentype=TTNUMBER; + for(i=0;(*script>='0' && *script<='9') || *script=='.' || *script=='-';i++) + tokenvalue[i]=*script++; + + // Hexadecimal number starting with decimal digit + + if((*script>='A' && *script<='F') || (*script>='a' && *script<='f')) + { + tokentype=TTSTRING; + for(; (*script>='A' && *script<='F') || (*script>='a' && *script<='f') ; i++) + tokenvalue[i]=*script++; + } + + tokenvalue[i]=0; + return tokentype; + } + + // Quoted string + + if(*script=='"') + { + tokentype=TTSTRING; + script++; + for(i=0;*script && *script!='"' && *script!='\n' && *script!='\r';i++) + tokenvalue[i]=*script++; + tokenvalue[i]=0; + if(*script) script++; + return tokentype; + } + + // Keyword + + for(i=0;keytable[i].word;i++) + if(!strtkcmp(keytable[i].word, script)) + { + tokentype = keytable[i].code; + strcpy(tokenvalue,keytable[i].word); + script+=strlen(keytable[i].word); + return tokentype; + } + + // Unquoted string or hexadecimal number + + tokentype=TTSTRING; + for(i=0; + *script && *script!=' ' && *script!='\t' && *script!='\n' && *script!='\r' + && *script!=',' && *script!='=' && *script!='{' && *script!='}' && *script!=':'; + i++) + tokenvalue[i]=*script++; + tokenvalue[i]=0; + return tokentype; +} + +bool RScriptParser::strtkcmp(const char* str, const char* mem) +{ + int i,len=strlen(str); + for(i=0;i<len;i++) + { + if(!mem[i]) return true; + if(mem[i] != str[i]) return true; + } + return false; +} + +DWORD RScriptParser::tkn_hex() +{ + int i; + DWORD dw=0; + char chr; + for(i=0; tokenvalue[i]; i++) + { + chr=tokenvalue[i]; + if(chr >= 'a') chr-='a'-':'; + if(chr >= 'A') chr-='A'-':'; + chr-='0'; + if(chr>0xF) chr=0xF; + dw=(dw << 4) | chr; + } + return dw; +} + +void RScriptParser::ScriptPostError(const char *msg1, const char *msg2) +{ + hge->System_Log("%s, line %d: %s'%s'%s", + get_name(), get_line(), msg1, tokenvalue[0] ? tkn_string():"<EOF>", msg2); +} diff --git a/hgehelp/parser.h b/hgehelp/parser.h new file mode 100644 index 0000000..98a5b45 --- /dev/null +++ b/hgehelp/parser.h @@ -0,0 +1,77 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Resource script parser header +*/ + +#ifndef HGEPARSER_H +#define HGEPARSER_H + + +#include "../../include/hge.h" +#include <string.h> +#include <stdlib.h> + + +enum +{ + TTNONE, TTEND, TTNUMBER, TTSTRING, + + TTBOOL, TTEQUALS, TTBASED, TTSEPARATOR, TTOPENBLOCK, TTCLOSEBLOCK, + + TTRES__FIRST, + TTRES_INCLUDE, TTRES_RESOURCE, TTRES_TEXTURE, TTRES_SOUND, TTRES_MUSIC, + TTRES_STREAM, TTRES_TARGET, TTRES_SPRITE, TTRES_ANIMATION, TTRES_FONT, + TTRES_PARTICLE, TTRES_DISTORT, TTRES_STRTABLE, + TTRES__LAST, + + TTPAR__FIRST, + TTPAR_FILENAME, TTPAR_RESGROUP, TTPAR_MIPMAP, TTPAR_AMPLIFY, TTPAR_SIZE, TTPAR_ZBUFFER, + TTPAR_TEXTURE, TTPAR_RECT, TTPAR_HOTSPOT, TTPAR_BLENDMODE, TTPAR_COLOR, + TTPAR_ZORDER, TTPAR_FLIP, TTPAR_SCALE, TTPAR_PROPORTION, TTPAR_ROTATION, TTPAR_FRAMES, + TTPAR_FPS, TTPAR_MODE, TTPAR_TRACKING, TTPAR_SPACING, TTPAR_SPRITE, TTPAR_MESH, + TTPAR__LAST, + + TTCON__FIRST, + TTCON_COLORMUL, TTCON_COLORADD, TTCON_ALPHABLND, TTCON_ALPHAADD, TTCON_ZWRITE, + TTCON_NOZWRITE, TTCON_FORWARD, TTCON_REVERSE, TTCON_PINGPONG, TTCON_NOPINGPONG, + TTCON_LOOP, TTCON_NOLOOP, TTCON_CIRCLE, TTCON_RECT, TTCON_ALPHA, + TTCON__LAST +}; + + +class RScriptParser +{ +public: + RScriptParser(char *name, char *scr); + ~RScriptParser() { hge->Release(); } + + int get_token(); + void put_back() { script-=strlen(tokenvalue); } + int get_line() { return line;} + char* get_name() { return scriptname;} + + char* tkn_string() { return tokenvalue; } + int tkn_int() { return atoi(tokenvalue); } + float tkn_float() { return (float)atof(tokenvalue); } + bool tkn_bool() { return (tokenvalue[0]=='t' || tokenvalue[0]=='T') ? true : false; } + DWORD tkn_hex(); + + void ScriptPostError(const char *msg1, const char *msg2); + + int tokentype; + char tokenvalue[128]; + char* script; + char* scriptname; + int line; + +private: + bool strtkcmp(const char *str, const char *mem); + + static HGE *hge; +}; + + +#endif diff --git a/hgehelp/resources.cpp b/hgehelp/resources.cpp new file mode 100644 index 0000000..0c41495 --- /dev/null +++ b/hgehelp/resources.cpp @@ -0,0 +1,958 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeResourceManager resources implementation +*/ + + +#include "../../include/hgeresource.h" +#include "parser.h" +#include "resources.h" + + +HGE *ResDesc::hge=0; + + +/////////////// COMMON // + +void AddRes(hgeResourceManager *rm, int type, ResDesc *resource) +{ + resource->next=rm->res[type]; + rm->res[type]=resource; +} + +ResDesc *FindRes(hgeResourceManager *rm, int type, const char *name) +{ + ResDesc *rc; + + rc=rm->res[type]; + while(rc) + { + if(!strcmp(name, rc->name)) return rc; + rc=rc->next; + } + + return 0; +} + +bool ScriptSkipToNextParameter(RScriptParser *sp, bool bIgnore) +{ + bool bToBeIgnored=bIgnore; + if(bIgnore) sp->put_back(); + + for(;;) + { + sp->get_token(); + if(sp->tokentype == TTCLOSEBLOCK) { if(bIgnore) {sp->put_back(); return true;} return false; } + if((sp->tokentype > TTRES__FIRST && sp->tokentype < TTRES__LAST) || sp->tokentype == TTEND) + { + sp->put_back(); + if(bIgnore) return true; + sp->ScriptPostError("'}' missed, "," encountered."); + return false; + } + if((sp->tokentype <= TTPAR__FIRST && sp->tokentype >= TTPAR__LAST) || bToBeIgnored) + { + bToBeIgnored=false; + sp->ScriptPostError("Unsupported resource parameter ","."); + do sp->get_token(); + while((sp->tokentype <= TTPAR__FIRST || sp->tokentype >= TTPAR__LAST) && + (sp->tokentype <= TTRES__FIRST || sp->tokentype >= TTRES__LAST) && + sp->tokentype != TTCLOSEBLOCK && sp->tokentype != TTEND); + sp->put_back(); + } + else + { + if(bIgnore) sp->put_back(); + return true; + } + } +} + +void ScriptParseFileResource(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename, ResDesc *rr, int restype) +{ + RResource *rc=(RResource *)rr, *base; + + base = (RResource *)FindRes(rm, restype, basename); + if(base) *rc=*base; else + { + rc->resgroup=0; + rc->filename[0]=0; + } + rc->handle=0; strcpy(rc->name, name); + + while(ScriptSkipToNextParameter(sp,false)) + { + switch(sp->tokentype) + { + case TTPAR_FILENAME: + sp->get_token(); sp->get_token(); + strcpy(rc->filename, sp->tkn_string()); + break; + + case TTPAR_RESGROUP: + sp->get_token(); sp->get_token(); + rc->resgroup=sp->tkn_int(); + break; + + default: + ScriptSkipToNextParameter(sp,true); + break; + } + } + + AddRes(rm, restype, rc); +} + +void ScriptParseBlendMode(RScriptParser *sp, int *blend) +{ + for(;;) + { + sp->get_token(); + if(sp->tokentype != TTEQUALS && sp->tokentype != TTSEPARATOR) { sp->put_back(); return; } + + switch(sp->get_token()) + { + case TTCON_COLORMUL: + *blend &= ~BLEND_COLORADD; + break; + + case TTCON_COLORADD: + *blend |= BLEND_COLORADD; + break; + + case TTCON_ALPHABLND: + *blend |= BLEND_ALPHABLEND; + break; + + case TTCON_ALPHAADD: + *blend &= ~BLEND_ALPHABLEND; + break; + + case TTCON_ZWRITE: + *blend |= BLEND_ZWRITE; + break; + + case TTCON_NOZWRITE: + *blend &= ~BLEND_ZWRITE; + break; + + default: + sp->ScriptPostError("Unsupported value ","."); + break; + } + } +} + +void ScriptParseSpriteAnim(RScriptParser *sp, RSprite *rc, bool anim) +{ + while(ScriptSkipToNextParameter(sp,false)) + { + switch(sp->tokentype) + { + case TTPAR_TEXTURE: + sp->get_token(); sp->get_token(); + strcpy(rc->texname,sp->tkn_string()); + break; + + case TTPAR_RECT: + sp->get_token(); sp->get_token(); + rc->tx=sp->tkn_float(); + sp->get_token(); sp->get_token(); + rc->ty=sp->tkn_float(); + sp->get_token(); sp->get_token(); + rc->w=sp->tkn_float(); + sp->get_token(); sp->get_token(); + rc->h=sp->tkn_float(); + break; + + case TTPAR_HOTSPOT: + sp->get_token(); sp->get_token(); + rc->hotx=sp->tkn_float(); + sp->get_token(); sp->get_token(); + rc->hoty=sp->tkn_float(); + break; + + case TTPAR_BLENDMODE: + ScriptParseBlendMode(sp, &rc->blend); + break; + + case TTPAR_COLOR: + sp->get_token(); sp->get_token(); + rc->color=sp->tkn_hex(); + break; + + case TTPAR_ZORDER: + sp->get_token(); sp->get_token(); + rc->z=sp->tkn_float(); + break; + + case TTPAR_FLIP: + sp->get_token(); sp->get_token(); + rc->bXFlip=sp->tkn_bool(); + sp->get_token(); sp->get_token(); + rc->bYFlip=sp->tkn_bool(); + break; + + case TTPAR_RESGROUP: + sp->get_token(); sp->get_token(); + rc->resgroup=sp->tkn_int(); + break; + + case TTPAR_FRAMES: + if(anim) + { + sp->get_token(); sp->get_token(); + ((RAnimation *)rc)->frames=sp->tkn_int(); + break; + } + + case TTPAR_FPS: + if(anim) + { + sp->get_token(); sp->get_token(); + ((RAnimation *)rc)->fps=sp->tkn_float(); + break; + } + + case TTPAR_MODE: + if(anim) + { + for(;;) + { + sp->get_token(); + if(sp->tokentype != TTEQUALS && sp->tokentype != TTSEPARATOR) { sp->put_back(); break; } + + switch(sp->get_token()) + { + case TTCON_FORWARD: + ((RAnimation *)rc)->mode &= ~HGEANIM_REV; + break; + + case TTCON_REVERSE: + ((RAnimation *)rc)->mode |= HGEANIM_REV; + break; + + case TTCON_NOPINGPONG: + ((RAnimation *)rc)->mode &= ~HGEANIM_PINGPONG; + break; + + case TTCON_PINGPONG: + ((RAnimation *)rc)->mode |= HGEANIM_PINGPONG; + break; + + case TTCON_NOLOOP: + ((RAnimation *)rc)->mode &= ~HGEANIM_LOOP; + break; + + case TTCON_LOOP: + ((RAnimation *)rc)->mode |= HGEANIM_LOOP; + break; + + default: + sp->ScriptPostError("Unsupported value ","."); + break; + } + } + break; + } + + default: + ScriptSkipToNextParameter(sp,true); + break; + } + } +} + + +/////////////// RScript // + +void RScript::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *sname, const char *sbasename) +{ + RScriptParser *np; + RScript *res_script; + void *data; + DWORD size; + char *script, name[MAXRESCHARS], basename[MAXRESCHARS]; + int restype; + + if(!FindRes(rm, RES_SCRIPT, sname)) + { + res_script = new RScript(); // hack! we need an instance of RScript to access hge + // if all ok, this object is used later to keep the script + + data=hge->Resource_Load(sname, &size); + if(!data) + { + if(sp) sp->ScriptPostError("Script "," not found."); + else hge->System_Log("Script '%s' not found.",sname); + delete res_script; + return; + } + else + { + script= new char[size+1]; + memcpy(script, data, size); + script[size]=0; + hge->Resource_Free(data); + + strcpy(res_script->name, sname); + AddRes(rm, RES_SCRIPT, res_script); + np = new RScriptParser(res_script->name, script); + + for(;;) + { + np->get_token(); + if(np->tokentype == TTEND) break; + + else if(np->tokentype == TTRES_INCLUDE) + { + np->get_token(); + RScript::Parse(rm, np, np->tkn_string(), NULL); + } + + else if(np->tokentype > TTRES__FIRST && np->tokentype < TTRES__LAST) + { + restype=np->tokentype-TTRES__FIRST-1; + name[0]=basename[0]=0; + + np->get_token(); + if(FindRes(rm, restype, np->tkn_string())) + { + np->ScriptPostError("Resource "," of the same type already has been defined."); + while((np->tokentype <= TTRES__FIRST || np->tokentype >= TTRES__LAST) && np->tokentype != TTEND) np->get_token(); + np->put_back(); + continue; + } + strcpy(name, np->tkn_string()); + + np->get_token(); + + if(np->tokentype == TTBASED) + { + np->get_token(); + if(!FindRes(rm, restype, np->tkn_string())) np->ScriptPostError("Base resource "," is not defined."); + else strcpy(basename, np->tkn_string()); + np->get_token(); + } + + if(np->tokentype == TTOPENBLOCK) + { + switch(restype) + { + case RES_RESOURCE: RResource::Parse(rm, np, name, basename); break; + case RES_TEXTURE: RTexture::Parse(rm, np, name, basename); break; + case RES_EFFECT: REffect::Parse(rm, np, name, basename); break; + case RES_TARGET: RTarget::Parse(rm, np, name, basename); break; + case RES_SPRITE: RSprite::Parse(rm, np, name, basename); break; + case RES_ANIMATION: RAnimation::Parse(rm, np, name, basename); break; + case RES_FONT: RFont::Parse(rm, np, name, basename); break; + case RES_PARTICLE: RParticle::Parse(rm, np, name, basename); break; + case RES_DISTORT: RDistort::Parse(rm, np, name, basename); break; + case RES_STRTABLE: RStringTable::Parse(rm, np, name, basename); break; + } + } + else + { + np->ScriptPostError("Illegal resource syntax, "," found; '{' expected."); + while((np->tokentype <= TTRES__FIRST || np->tokentype >= TTRES__LAST) && np->tokentype != TTEND) np->get_token(); + np->put_back(); + } + } + + else + { + np->ScriptPostError("Unrecognized resource specificator ","."); + while((np->tokentype <= TTRES__FIRST || np->tokentype >= TTRES__LAST) && np->tokentype != TTEND) np->get_token(); + np->put_back(); + } + } + + delete np; + delete[] script; + } + } + else sp->ScriptPostError("Script "," already has been parsed."); +} + +/////////////// RResource // + +void RResource::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + ScriptParseFileResource(rm, sp, name, basename, new RResource(), RES_RESOURCE); +} + +DWORD RResource::Get(hgeResourceManager *rm) +{ + if(!handle) handle=(size_t)hge->Resource_Load(filename); + return handle; +} + +void RResource::Free() +{ + if(handle) hge->Resource_Free((void *)handle); + handle=0; +} + +/////////////// RTexture // + +void RTexture::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + RTexture *rc, *base; + + rc=new RTexture(); + base = (RTexture *)FindRes(rm, RES_TEXTURE, basename); + if(base) *rc=*base; + else + { + rc->resgroup=0; + rc->mipmap=false; + } + rc->handle=0; strcpy(rc->name, name); + + while(ScriptSkipToNextParameter(sp,false)) + { + switch(sp->tokentype) + { + case TTPAR_FILENAME: + sp->get_token(); sp->get_token(); + strcpy(rc->filename, sp->tkn_string()); + break; + + case TTPAR_RESGROUP: + sp->get_token(); sp->get_token(); + rc->resgroup=sp->tkn_int(); + break; + + case TTPAR_MIPMAP: + sp->get_token(); sp->get_token(); + rc->mipmap=sp->tkn_bool(); + break; + + default: + ScriptSkipToNextParameter(sp,true); + break; + } + } + + AddRes(rm, RES_TEXTURE, rc); +} + +DWORD RTexture::Get(hgeResourceManager *rm) +{ + if(!handle) handle=(DWORD)hge->Texture_Load(filename, 0, mipmap); + return handle; +} + +void RTexture::Free() +{ + if(handle) hge->Texture_Free((HTEXTURE)handle); + handle=0; +} + +/////////////// REffect // + +void REffect::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + ScriptParseFileResource(rm, sp, name, basename, new REffect(), RES_EFFECT); +} + +DWORD REffect::Get(hgeResourceManager *rm) +{ + if(!handle) handle=(DWORD)hge->Effect_Load(filename); + return handle; +} + +void REffect::Free() +{ + if(handle) hge->Effect_Free((HEFFECT)handle); + handle=0; +} + +/////////////// RTarget // + +void RTarget::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + RTarget *rc, *base; + + rc = new RTarget(); + base = (RTarget *)FindRes(rm, RES_TARGET, basename); + if(base) *rc=*base; + else + { + rc->resgroup=0; + rc->width=256; + rc->height=256; + rc->zbuffer=false; + } + rc->handle=0; strcpy(rc->name, name); + + while(ScriptSkipToNextParameter(sp, false)) + { + switch(sp->tokentype) + { + case TTPAR_SIZE: + sp->get_token(); sp->get_token(); + rc->width=sp->tkn_int(); + sp->get_token(); + sp->get_token(); + rc->height=sp->tkn_int(); + break; + + case TTPAR_ZBUFFER: + sp->get_token(); sp->get_token(); + rc->zbuffer=sp->tkn_bool(); + break; + + case TTPAR_RESGROUP: + sp->get_token(); sp->get_token(); + rc->resgroup=sp->tkn_int(); + break; + + default: + ScriptSkipToNextParameter(sp, true); + break; + } + } + + AddRes(rm, RES_TARGET, rc); +} + +DWORD RTarget::Get(hgeResourceManager *rm) +{ + if(!handle) handle=(DWORD)hge->Target_Create(width, height, zbuffer); + return handle; +} + +void RTarget::Free() +{ + if(handle) hge->Target_Free((HTARGET)handle); + handle=0; +} + +/////////////// RSprite // + +void RSprite::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + RSprite *rc, *base; + + rc = new RSprite(); + base = (RSprite *)FindRes(rm, RES_SPRITE, basename); + if(base) *rc=*base; + else + { + rc->resgroup=0; + rc->texname[0]=0; + rc->tx=rc->ty=0; + rc->w=rc->h=0; + rc->hotx=rc->hoty=0; + rc->blend=BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE; + rc->color=0xFFFFFFFF; + rc->z=0.5f; + rc->bXFlip=false; + rc->bYFlip=false; +// rc->x=rc->y=0; +// rc->scale=1.0f; +// rc->rotation=0.0f; +// rc->collision=HGECOL_RECT; + } + + rc->handle=0; + strcpy(rc->name, name); + + ScriptParseSpriteAnim(sp, rc, false); + AddRes(rm, RES_SPRITE, rc); +} + +DWORD RSprite::Get(hgeResourceManager *rm) +{ + hgeSprite *spr; + if(!handle) + { + spr = new hgeSprite(rm->GetTexture(texname, resgroup), tx, ty, w, h); + spr->SetColor(color); + spr->SetZ(z); + spr->SetBlendMode(blend); + spr->SetHotSpot(hotx,hoty); + spr->SetFlip(bXFlip, bYFlip); +// spr->MoveTo(x,y); +// spr->SetScale(scale); +// spr->SetRotation(rotation); +// spr->SetCollisionType(collision); + + handle=(size_t)spr; + } + return handle; +} + +void RSprite::Free() +{ + if(handle) delete (hgeSprite *)handle; + handle=0; +} + +/////////////// RAnimation // + +void RAnimation::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + RAnimation *rc, *base; + + rc = new RAnimation(); + base = (RAnimation *)FindRes(rm, RES_ANIMATION, basename); + if(base) *rc=*base; + else + { + rc->resgroup=0; + rc->texname[0]=0; + rc->tx=rc->ty=0; + rc->w=rc->h=0; + rc->hotx=rc->hoty=0; + rc->blend=BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE; + rc->color=0xFFFFFFFF; + rc->z=0.5f; + rc->bXFlip=false; + rc->bYFlip=false; +// rc->x=rc->y=0; +// rc->scale=1.0f; +// rc->rotation=0.0f; +// rc->collision=HGECOL_RECT; + rc->frames=1; + rc->fps=12.0f; + rc->mode=HGEANIM_FWD | HGEANIM_LOOP; + } + + rc->handle=0; + strcpy(rc->name, name); + + ScriptParseSpriteAnim(sp, rc, true); + AddRes(rm, RES_ANIMATION, rc); +} + +DWORD RAnimation::Get(hgeResourceManager *rm) +{ + hgeAnimation *spr; + if(!handle) + { + spr = new hgeAnimation(rm->GetTexture(texname, resgroup), frames, fps, tx, ty, w, h); + spr->SetColor(color); + spr->SetZ(z); + spr->SetBlendMode(blend); + spr->SetHotSpot(hotx,hoty); + spr->SetFlip(bXFlip, bYFlip); +// spr->MoveTo(x,y); +// spr->SetScale(scale); +// spr->SetRotation(rotation); +// spr->SetCollisionType(collision); + spr->SetMode(mode); + + handle=(size_t)spr; + } + return handle; +} + +void RAnimation::Free() +{ + if(handle) delete (hgeAnimation *)handle; + handle=0; +} + +/////////////// RFont // + +void RFont::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + RFont *rc, *base; + + rc = new RFont(); + base = (RFont *)FindRes(rm, RES_FONT, basename); + if(base) *rc=*base; + else + { + rc->resgroup=0; + rc->mipmap=false; + rc->filename[0]=0; + rc->blend=BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE; + rc->color=0xFFFFFFFF; + rc->z=0.5f; + rc->scale=1.0f; + rc->proportion=1.0f; + rc->tracking=0.0f; + rc->spacing=1.0f; + rc->rotation=0.0f; + } + rc->handle=0; strcpy(rc->name, name); + + while(ScriptSkipToNextParameter(sp,false)) + { + switch(sp->tokentype) + { + case TTPAR_FILENAME: + sp->get_token(); sp->get_token(); + strcpy(rc->filename, sp->tkn_string()); + break; + + case TTPAR_BLENDMODE: + ScriptParseBlendMode(sp, &rc->blend); + break; + + case TTPAR_COLOR: + sp->get_token(); sp->get_token(); + rc->color=sp->tkn_hex(); + break; + + case TTPAR_ZORDER: + sp->get_token(); sp->get_token(); + rc->z=sp->tkn_float(); + break; + + case TTPAR_SCALE: + sp->get_token(); sp->get_token(); + rc->scale=sp->tkn_float(); + break; + + case TTPAR_PROPORTION: + sp->get_token(); sp->get_token(); + rc->proportion=sp->tkn_float(); + break; + + case TTPAR_ROTATION: + sp->get_token(); sp->get_token(); + rc->rotation=sp->tkn_float(); + break; + + case TTPAR_TRACKING: + sp->get_token(); sp->get_token(); + rc->tracking=sp->tkn_float(); + break; + + case TTPAR_SPACING: + sp->get_token(); sp->get_token(); + rc->spacing=sp->tkn_float(); + break; + + case TTPAR_RESGROUP: + sp->get_token(); sp->get_token(); + rc->resgroup=sp->tkn_int(); + break; + + case TTPAR_MIPMAP: + sp->get_token(); sp->get_token(); + rc->mipmap=sp->tkn_bool(); + break; + + default: + ScriptSkipToNextParameter(sp, true); + break; + } + } + + AddRes(rm, RES_FONT, rc); +} + +DWORD RFont::Get(hgeResourceManager *rm) +{ + hgeFont *fnt; + if(!handle) + { + fnt = new hgeFont(filename, mipmap); + fnt->SetColor(color); + fnt->SetZ(z); + fnt->SetBlendMode(blend); + fnt->SetScale(scale); + fnt->SetProportion(proportion); + fnt->SetTracking(tracking); + fnt->SetSpacing(spacing); + fnt->SetRotation(rotation); + + handle=(size_t)fnt; + } + return handle; +} + +void RFont::Free() +{ + if(handle) delete (hgeFont *)handle; + handle=0; +} + +/////////////// RParticle // + +void RParticle::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + RParticle *rc, *base; + + rc = new RParticle(); + base = (RParticle *)FindRes(rm, RES_PARTICLE, basename); + if(base) *rc=*base; + else + { + rc->resgroup=0; + rc->filename[0]=0; + rc->spritename[0]=0; + } + rc->handle=0; strcpy(rc->name, name); + + while(ScriptSkipToNextParameter(sp, false)) + { + switch(sp->tokentype) + { + case TTPAR_FILENAME: + sp->get_token(); sp->get_token(); + strcpy(rc->filename, sp->tkn_string()); + break; + + case TTPAR_SPRITE: + sp->get_token(); sp->get_token(); + strcpy(rc->spritename, sp->tkn_string()); + break; + + case TTPAR_RESGROUP: + sp->get_token(); sp->get_token(); + rc->resgroup=sp->tkn_int(); + break; + + default: + ScriptSkipToNextParameter(sp, true); + break; + } + } + + AddRes(rm, RES_PARTICLE, rc); +} + +DWORD RParticle::Get(hgeResourceManager *rm) +{ + hgeParticleSystem *par; + if(!handle) + { + par = new hgeParticleSystem(filename, rm->GetSprite(spritename)); + + handle=(size_t)par; + } + return handle; +} + +void RParticle::Free() +{ + if(handle) delete (hgeParticleSystem *)handle; + handle=0; +} + +/////////////// RDistort // + +void RDistort::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + RDistort *rc, *base; + + rc = new RDistort(); + base = (RDistort *)FindRes(rm, RES_DISTORT, basename); + if(base) *rc=*base; + else + { + rc->resgroup=0; + rc->texname[0]=0; + rc->tx=rc->ty=0; + rc->w=rc->h=0; + rc->cols=rc->rows=2; + rc->blend=BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE; + rc->color=0xFFFFFFFF; + rc->z=0.5f; + } + rc->handle=0; strcpy(rc->name, name); + + while(ScriptSkipToNextParameter(sp, false)) + { + switch(sp->tokentype) + { + case TTPAR_TEXTURE: + sp->get_token(); sp->get_token(); + strcpy(rc->texname, sp->tkn_string()); + break; + + case TTPAR_RECT: + sp->get_token(); sp->get_token(); + rc->tx=sp->tkn_float(); + sp->get_token(); sp->get_token(); + rc->ty=sp->tkn_float(); + sp->get_token(); sp->get_token(); + rc->w=sp->tkn_float(); + sp->get_token(); sp->get_token(); + rc->h=sp->tkn_float(); + break; + + case TTPAR_MESH: + sp->get_token(); sp->get_token(); + rc->cols=sp->tkn_int(); + sp->get_token(); sp->get_token(); + rc->rows=sp->tkn_int(); + break; + + case TTPAR_BLENDMODE: + ScriptParseBlendMode(sp, &rc->blend); + break; + + case TTPAR_COLOR: + sp->get_token(); sp->get_token(); + rc->color=sp->tkn_hex(); + break; + + case TTPAR_ZORDER: + sp->get_token(); sp->get_token(); + rc->z=sp->tkn_float(); + break; + + case TTPAR_RESGROUP: + sp->get_token(); sp->get_token(); + rc->resgroup=sp->tkn_int(); + break; + + default: + ScriptSkipToNextParameter(sp, true); + break; + } + } + + AddRes(rm, RES_DISTORT, rc); +} + +DWORD RDistort::Get(hgeResourceManager *rm) +{ + hgeDistortionMesh *dis; + if(!handle) + { + dis = new hgeDistortionMesh(cols, rows); + dis->SetTexture(rm->GetTexture(texname, resgroup)); + dis->SetTextureRect(tx,ty,w,h); + dis->SetBlendMode(blend); + dis->Clear(color,z); + + handle=(size_t)dis; + } + return handle; +} + +void RDistort::Free() +{ + if(handle) delete (hgeDistortionMesh *)handle; + handle=0; +} + +/////////////// RStringTable // + +void RStringTable::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + ScriptParseFileResource(rm, sp, name, basename, new RStringTable(), RES_STRTABLE); +} + +DWORD RStringTable::Get(hgeResourceManager *rm) +{ + if(!handle) handle = (size_t)new hgeStringTable(filename); + return handle; +} + +void RStringTable::Free() +{ + if(handle) delete (hgeStringTable *)handle; + handle=0; +} diff --git a/hgehelp/resources.h b/hgehelp/resources.h new file mode 100644 index 0000000..87561d8 --- /dev/null +++ b/hgehelp/resources.h @@ -0,0 +1,165 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeResourceManager resources header +*/ + +#ifndef HGERESOURCES_H +#define HGERESOURCES_H + + +#include "../../include/hgeresource.h" +#include "parser.h" + + +#define RES_SCRIPT 0 + +#define RES_RESOURCE 1 +#define RES_TEXTURE 2 +#define RES_EFFECT 3 +#define RES_MUSIC 4 +#define RES_STREAM 5 +#define RES_TARGET 6 +#define RES_SPRITE 7 +#define RES_ANIMATION 8 +#define RES_FONT 9 +#define RES_PARTICLE 10 +#define RES_DISTORT 11 +#define RES_STRTABLE 12 + + +void AddRes(hgeResourceManager *rm, int type, ResDesc *resource); +ResDesc* FindRes(hgeResourceManager *rm, int type, const char *name); + + +struct RScript : public ResDesc +{ + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm) {return 0;} + virtual void Free() {} +}; + +struct RResource : public ResDesc +{ + char filename[MAXRESCHARS]; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +struct RTexture : public ResDesc +{ + char filename[MAXRESCHARS]; + bool mipmap; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +struct REffect : public ResDesc +{ + char filename[MAXRESCHARS]; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +struct RTarget : public ResDesc +{ + int width; + int height; + bool zbuffer; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +struct RSprite : public ResDesc +{ + char texname[MAXRESCHARS]; + float tx, ty, w, h; + float hotx, hoty; + int blend; + DWORD color; + float z; + bool bXFlip, bYFlip; +// float x,y; +// float scale; +// float rotation; +// int collision; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +struct RAnimation : public RSprite +{ + int frames; + float fps; + int mode; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +struct RFont : public ResDesc +{ + char filename[MAXRESCHARS]; + bool mipmap; + int blend; + DWORD color; + float z; + float scale; + float proportion; + float tracking; + float spacing; + float rotation; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +struct RParticle : public ResDesc +{ + char filename[MAXRESCHARS]; + char spritename[MAXRESCHARS]; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +struct RDistort : public ResDesc +{ + char texname[MAXRESCHARS]; + float tx, ty, w, h; + int cols, rows; + int blend; + DWORD color; + float z; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + + +struct RStringTable : public ResDesc +{ + char filename[MAXRESCHARS]; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +#endif |