summaryrefslogtreecommitdiff
path: root/hgehelp
diff options
context:
space:
mode:
authorGravatar chirs241097@gmail.com <chirs241097@gmail.com@c17bf020-1265-9734-9302-a83f62007ddb> 2014-01-12 14:43:14 +0000
committerGravatar chirs241097@gmail.com <chirs241097@gmail.com@c17bf020-1265-9734-9302-a83f62007ddb> 2014-01-12 14:43:14 +0000
commitc91847d549cc1c30eb15504a15ea9a6d5aa48165 (patch)
treeb978d575f08f5f87d3c21eb9a024164636d1918a /hgehelp
downloadbullet-lab-remix-c91847d549cc1c30eb15504a15ea9a6d5aa48165.tar.xz
Diffstat (limited to 'hgehelp')
-rw-r--r--hgehelp/hgeanim.cpp165
-rw-r--r--hgehelp/hgecolor.cpp89
-rw-r--r--hgehelp/hgedistort.cpp242
-rw-r--r--hgehelp/hgefont.cpp337
-rw-r--r--hgehelp/hgegui.cpp397
-rw-r--r--hgehelp/hgeguictrls.cpp361
-rw-r--r--hgehelp/hgeparticle.cpp308
-rw-r--r--hgehelp/hgepmanager.cpp96
-rw-r--r--hgehelp/hgerect.cpp45
-rw-r--r--hgehelp/hgeresource.cpp254
-rw-r--r--hgehelp/hgesprite.cpp302
-rw-r--r--hgehelp/hgestrings.cpp168
-rw-r--r--hgehelp/hgevector.cpp69
-rw-r--r--hgehelp/parser.cpp209
-rw-r--r--hgehelp/parser.h77
-rw-r--r--hgehelp/resources.cpp958
-rw-r--r--hgehelp/resources.h165
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