Code Snippets http://relishgames.com/forum/index.php?p=/categories/code-snippets/p2/feed.rss Sat, 18 May 13 09:09:14 -0400 Code Snippets en-CA Ball Lens Demo http://relishgames.com/forum/index.php?p=/discussion/4474/ball-lens-demo Wed, 04 Feb 2009 16:48:14 -0500 Elem 4474@/forum/index.php?p=/discussions Source code.

Download:
http://delphi.ktop.com.tw/download.php?download=upload%2F4989a90ce944d_Ball_Lens.rar

image]]>
VKeyboard Class http://relishgames.com/forum/index.php?p=/discussion/4801/vkeyboard-class Wed, 18 Mar 2009 11:33:02 -0400 3rdInvisible 4801@/forum/index.php?p=/discussions
i??ve thought an easy class for keyhandling in HGE
perhabs its usefull for someone ....

Easy to use :)

Example A easy keyhandling :


HGE* g_phge = 0;

// in globalscape (remember its just an example
VKeyboard* Keys = 0;

// Initializing (don??t forget to delete)
Keys = new VKeyboard();

// adding the keys we want to use
Keys->AddKey(HGEK_ESCAPE);
Keys->AddKey(HGEK_F1);


bool FrameFunc()
{
if(Keys!=0)
{
// to Update the KeyStates use Update() function
// give a valid pointer to hge class to the function
Keys->Update(g_phge);


if(Keys->Hit(HGEK_A)) // Hit the "A" Key ?
{
.....
}

if(Keys->Hold(HGEK_A)) // Hold the "A" Key ?
{
.....
}

if(Keys->Released(HGEK_A)) // Hold the "A" Key ?
{
.....
}


}

// Dont forget to delete the VKeyboard class from heap
delete(Keys);

}



easy :) isn??t it ?


Example B smoother work with function pointer :




HGE* g_phge = 0;

// in globalscape (remember its just an example
VKeyboard* MoveKeys = 0;

// Initializing (don??t forget to delete)
MoveKeys = new VKeyboard();


// Function for keyhandling
// perhabs for character movement
void CharacterMoveKeyHandling(VKey Key)
{
if(Key._key == HGEK_LEFT && Hold(Key)) Player->MoveLeft();
if(Key._key == HGEK_RIGHT && Hold(Key)) Player->MoveRight();
if(Key._key == HGEK_DOWN && Hold(Key)) Player->MoveDown();
if(Key._key == HGEK_UP && Hold(Key)) Player->MoveUp();
}


// adding the keys we want to use and bind them to CharacterMoveKeyHandling function
MoveKeys->AddKey(HGEK_LEFT, CharacterMoveKeyHandling);
MoveKeys->AddKey(HGEK_RIGHT, CharacterMoveKeyHandling);
MoveKeys->AddKey(HGEK_DOWN, CharacterMoveKeyHandling);
MoveKeys->AddKey(HGEK_UP, CharacterMoveKeyHandling);


bool FrameFunc()
{
if(MoveKeys!=0)
{
// to Update the KeyStates use Update() function
// give a valid pointer to hge class to the function
Keys->Update(g_phge);

// and we??re done
// if one of our keys changes keystate
// Keystates : VK_NULL,VK_HIT,VK_HOLD,VK_RELEASED
// CharacterMoveKeyHandling function is startet
// with the key wich is acutal updatet exept keystate
// is set to VK_NULL
}


// Dont forget to delete the VKeyboard class from heap
delete(MoveKeys);










File : VKeyboard.h


#ifndef __VKEYBOARD_HEADER_INCLUDED__
#define __VKEYBOARD_HEADER_INCLUDED__

#include "hge.h"

// Virtual Keyboard Key States
typedef enum VKey_State
{
VK_NULL=0,
VK_HIT,
VK_HOLD,
VK_RELEASED
} VKey_State;

// Virtual Key
typedef struct VKey
{
int _key; // example HGEK_ESCAPE
VKey_State _state; // Key State
} VKey;

// Helperfunctions to test Keystate
bool Hit(VKey Key);
bool Hold(VKey Key);
bool Released(VKey Key);

// Functionpointer for AutoFunction KeyActivity
typedef void (*VKey_fnptr)(VKey Key);

// Virtual Key Node for list implementation
struct VKey_Node
{
VKey Key;
VKey_fnptr AutoFunc;
VKey_Node* Next;
};

// Virutal Keyboard Class
class VKeyboard
{
public:
// CTOR
VKeyboard();
// DTOR
~VKeyboard();

// Add a Key to listen to
// u can add a functionpointer to the key
// defined like VKey_fnptr typedef
void AddKey(int Key, VKey_fnptr AFunc = 0);

// Remove a Key listening to
void RemoveKey(int Key);

// Did the user hit the key
bool Hit(int Key);

// Does the user hold down the key
bool Hold(int Key);

// Has the user released the key
bool Released(int Key);

// Are we listening to this key
bool Contains(int Key);

// Update Keystates
void Update(HGE* phge);


// switch Key from Key to NewKey
// attached functions remain
void Set(int Key, int NewKey);

// Set a function to the Key
void Set(int Key, VKey_fnptr KeyFunc=0);

// Set a function to all Keys we??re listening to
void Set(VKey_fnptr KeyFunc);


private:
// Root Entry to the attached keys
VKey_Node* Root;
// Remove a key_node from the attached keys
void DeleteNode(VKey_Node* KeyNode);
// State Tester
bool KeyState(int Key, VKey_State State);

// Get a Pointer to a specific Key
// if parameter to set to false
// and key is not registered
// u??ll get 0
VKey* GetKey(int Key,bool create=true);

// Get a KeyNode Pointer including the specific Key
// if parameter to set to false
// and key is not regis // u??ll get 0
VKey_Node* GetNode(int Key,bool create=true);

};

#endif




File : VKeyboard.cpp


/*

VKeyboard Class for HGE
-----------------------------
by Frederic Czyborra in 2009
freddyczyborra@googlemail.com

*/

#include "VKeyboard.h"



bool Hit(VKey Key){ return (Key._state==VK_HIT);}
bool Hold(VKey Key){ return (Key._state==VK_HOLD);}
bool Released(VKey Key){ return (Key._state==VK_RELEASED);}


VKeyboard::VKeyboard():Root(0)
{}

VKeyboard::~VKeyboard()
{
DeleteNode(this->Root);
}

void VKeyboard::Update(HGE* phge)
{
VKey_Node* Cursor = this->Root;
while(Cursor!=0)
{
if(phge->Input_GetKeyState(Cursor->Key._key))
{
switch(Cursor->Key._state)
{
case(VK_HIT):
{
Cursor->Key._state = VK_HOLD;
if(Cursor->AutoFunc!=0) Cursor->AutoFunc(Cursor->Key);
}
break;
case(VK_HOLD): break;
default:
{
Cursor->Key._state = VK_HIT;
if(Cursor->AutoFunc!=0) Cursor->AutoFunc(Cursor->Key);
}
}

}
else
{
switch(Cursor->Key._state)
{
case(VK_HIT):
case(VK_HOLD):
Cursor->Key._state = VK_RELEASED;
if(Cursor->AutoFunc!=0) Cursor->AutoFunc(Cursor->Key);
break;
default:
Cursor->Key._state = VK_NULL;
}
}
Cursor = Cursor->Next;
}
}


void VKeyboard::AddKey(int Key,VKey_fnptr AFunc)
{
if(this->Root!=0)
{
VKey_Node* Cursor = this->Root;
if(Cursor!=0)
{
while(Cursor->Next != 0)
{
Cursor = Cursor->Next;
}

Cursor->Next = new VKey_Node();
Cursor = Cursor->Next;
if(Cursor!=0)
{
Cursor->Key._key = Key;
Cursor->Key._state = VK_NULL;
Cursor->AutoFunc = AFunc;
Cursor->Next=0;
}
}
return;
}



this->Root = new VKey_Node();
if(this->Root!=0)
{
this->Root->Key._key = Key;
this->Root->Key._state = VK_NULL;
this->Root->AutoFunc = AFunc;
this->Root->Next = 0;
}

}

void VKeyboard::DeleteNode(VKey_Node* KeyNode)
{
if(KeyNode!=0)
{
if(KeyNode->Next!=0) this->DeleteNode(KeyNode->Next);
KeyNode->Next=0;
delete KeyNode;
}
}

bool VKeyboard::Contains(int Key)
{
VKey_Node* Cursor = this->Root;
while(Cursor!=0)
{
if(Cursor->Key._key == Key) return true;
Cursor = Cursor->Next;
}
return false;
}

bool VKeyboard::Hit(int Key)
{
return this->KeyState(Key, VK_HIT);
}

bool VKeyboard::Hold(int Key)
{
return this->KeyState(Key, VK_HOLD);
}

bool VKeyboard::Released(int Key)
{
return this->KeyState(Key, VK_RELEASED);
}

bool VKeyboard::KeyState(int Key, VKey_State State)
{
VKey_Node* Cursor = this->Root;
while(Cursor!=0)
{
if(Cursor->Key._key == Key)
{
if(Cursor->Key._state == State) return true;
return false;
}
Cursor=Cursor->Next;
}
return false;
}


VKey* VKeyboard::GetKey(int Key,bool create)
{
if(!Contains(Key)&&create) AddKey(Key);
VKey_Node* Cursor = Root;
while(Cursor!=0)
{
if(Cursor->Key._key == Key) return &Cursor->Key;
Cursor=Cursor->Next;
}

return 0;
}

VKey_Node* VKeyboard::GetNode(int Key,bool create)
{
if(!Contains(Key)&&create) AddKey(Key);
VKey_Node* Cursor = Root;
while(Cursor!=0)
{
if(Cursor->Key._key == Key) return Cursor;
Cursor=Cursor->Next;
}

return 0;
}

void VKeyboard::Set(int Key, int NewKey)
{
VKey* Cursor = GetKey(Key);
if(Cursor!=0) Cursor->_key = NewKey;
}

void VKeyboard::Set(int Key, VKey_fnptr KeyFunc)
{
VKey_Node* Cursor = GetNode(Key);
if(Cursor!=0) Cursor->AutoFunc = KeyFunc;
}

void VKeyboard::Set(VKey_fnptr KeyFunc)
{
VKey_Node* Cursor = Root;
while(Cursor!=0)
{
Cursor->AutoFunc = KeyFunc;
Cursor = Cursor->Next;
}
}

void VKeyboard::RemoveKey(int Key)
{
VKey_Node* Cursor = Root;
VKey_Node* Parent = 0;
while(Cursor!=0)
{
if(Cursor->Key._key == Key)
{
if(Parent!=0)
{
Parent->Next = Cursor->Next;
Cursor->Next = 0;
delete(Cursor);
return;
}
}
Parent = Cursor;
Cursor = Cursor->Next;
}
}




if anyone finds a mistake or likes this class please post :)
i need some feedback

Greets

3rdInvisible]]>
Advance sprite animation example. http://relishgames.com/forum/index.php?p=/discussion/4764/advance-sprite-animation-example. Thu, 19 Feb 2009 19:15:13 -0500 Elem 4764@/forum/index.php?p=/discussions Source code.

download:
http://delphi.ktop.com.tw/download.php?download=upload%2F499d926eb0bb3_Animation.rar

image]]>
Picture grayscale,saturation example http://relishgames.com/forum/index.php?p=/discussion/4468/picture-grayscalesaturation-example Sat, 31 Jan 2009 15:48:04 -0500 Elem 4468@/forum/index.php?p=/discussions
http://www.2shared.com/fadmin/4773087/66dbe20/Saturation.rar]]>
Plasma Ex Part2 http://relishgames.com/forum/index.php?p=/discussion/4450/plasma-ex-part2 Thu, 22 Jan 2009 10:37:39 -0500 Elem 4450@/forum/index.php?p=/discussions
P.S.
You have to wait for 3-5 second to init

http://delphi.ktop.com.tw/download.php?download=upload%2F49782d2d6d93e_Plasma2.rar]]>
Plasma Effect http://relishgames.com/forum/index.php?p=/discussion/4445/plasma-effect Mon, 19 Jan 2009 14:51:19 -0500 Elem 4445@/forum/index.php?p=/discussions
download:
http://delphi.ktop.com.tw/download.php?download=upload%2F4974759fb0c5a_Plasma.rar
image]]>
HGE window in WPF applcation http://relishgames.com/forum/index.php?p=/discussion/4288/hge-window-in-wpf-applcation Sun, 05 Oct 2008 16:44:19 -0400 ap 4288@/forum/index.php?p=/discussions
image

This is a VS2005 project and release executable, ~200 kb (rename .doc to .zip after downloading).]]>
Texture clamp state http://relishgames.com/forum/index.php?p=/discussion/4021/texture-clamp-state Mon, 26 May 2008 15:09:11 -0400 Drew 4021@/forum/index.php?p=/discussions
You can just follow the way HGE_TEXTUREFILTER is done & modify it for this, but I'll stick the code here anyway.

One thing to note is I'm using a DirectX 9 flavour of Hge. I can't imagine there's any dx9-specific code here, so in theory it should work fine for dx8 Hge too...

edit: in case you're wondering what use this is, imagine you are rendering a partially-transparent texture to a quad. Some of the texture edges are coloured in, some are transparent. When the quad gets rendered with texture filtering turned on, the edges are interpolated with the opposite side, which leads to artefacts appearing along the transparent edges thanks to the inaccuracy of 32-bit floating point. Clamping the texture prevents the wrap-round, so the transparent edges are drawn correctly. You can achieve a similar result already by turning texture filtering off but then you've got the problem of having pixellated textures, unless you're going for that look.. The only downside is you lose the ability to tile the texture on a single quad.

hge.h:

/*
** HGE System state constants
*/
enum hgeBoolState
{
...
// Andy : Texture clamping
HGE_TEXTURECLAMP = 8, // bool clamp textures? (default: false)
...
};

(if the value 8 is already being used for something else, pick another number :) )

graphics.cpp in HGE_Impl::_init_lost():

if(bTextureFilter)
{
....
}

// Andy Begin : Texture clamping
if (bTextureClamp)
{
pD3DDevice->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_CLAMP);
pD3DDevice->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_CLAMP);
}
else
{
pD3DDevice->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_WRAP);
pD3DDevice->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_WRAP);
}
// Andy: End


hge_impl.h:

// System States
...
...
// Andy : Texture clamping
bool bTextureClamp;


System.cpp in HGE_Impl::System_SetStateBool:

...
// Andy Begin : Texture clamping
case HGE_TEXTURECLAMP:
if (bTextureClamp == value)
{
// Minor optimisation: state hasn't changed. Early-out to avoid the _render_batch() call.
// this check isn't done for HGE_TEXTUREFILTER. Hint hint ;)
return;
}
bTextureClamp = value;
if(pD3DDevice)
{
_render_batch();
if (bTextureClamp)
{
pD3DDevice->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_CLAMP);
pD3DDevice->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_CLAMP);
}
else
{
pD3DDevice->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_WRAP);
pD3DDevice->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_WRAP);
}
}
break;
// Andy End


System.cpp in HGE_Impl::System_GetStateBool:

...
// Andy : Texture clamping
case HGE_TEXTURECLAMP: return bTextureClamp;


Ok, there are some improvements that could be made here. First off I'm not too keen on the duplication of code, that could be moved into a function (my reasons for not doing so: the rest of hge isn't done this way, & I was feeling too lazy to do the plumbing-in. Maybe later.). Additionally there's a whole host of other sampler states that could be set, though this would require an enumeration/integer implementation.


Finally, the usage:

hge->System_SetState( HGE_TEXTURECLAMP, <value> );

or...
// render something
hge->System_SetState( HGE_TEXTURECLAMP, true ); // clamp the texture
// render something that needs a clamped texture
hge->System_SetState( HGE_TEXTURECLAMP, false ); // back to default.
// render something else

You can use this at any point in the rendering pipeline - either at initialisation or within the framefunc (for individual objects), same as HGE_TEXTUREFILTER.
As with the texture filtering, an additional _render_batch() call is made every time the state is changed, so if you intend to switch between the two modes regularly it's worth ordering your geometry to keep the state changes to a minimum.]]>
Fireworks Demo http://relishgames.com/forum/index.php?p=/discussion/4243/fireworks-demo Tue, 02 Sep 2008 01:01:25 -0400 cleerline 4243@/forum/index.php?p=/discussions
I have created a set of classes for a particle based "firework" display.

There are three classes.

The basic Firework Class, for when you want to launch a single firework.
A FireworkManager, which takes care of looking after multiple fireworks on the go for you.
And a FireworkDisplay, which you pass start and end points of the firework, its colour, and how long you want to wait till launch. Set up a few fireworks and let it rip!

You can download the demo including source here:

http://cleerline.com/HGE/Fireworks.zip

After the display has finished click on the screen to launch a firework.

I used this class in the climax of my (HGE powered) game Lexiclix http://lexiclix.com]]>
hgeGUIRectBar class - an percent bar for GUI http://relishgames.com/forum/index.php?p=/discussion/3892/hgeguirectbar-class-an-percent-bar-for-gui Tue, 04 Mar 2008 05:43:12 -0500 mark_solo 3892@/forum/index.php?p=/discussions
hgeGUIRectBar.h
#ifndef ___RECTBARprofeclipserulez
#define ___RECTBARprofeclipserulez

#include
#include


//Macros para usar los valores
#define getBarCtrl(id) ((hgeGUIRectBar*)gui->GetCtrl(id))
#define getBar(id) (getBarCtrl(id)->getPercent())
#define setBar(id,per) (getBarCtrl(id)->setPercent(per))

class hgeGUIRectBar :
public hgeGUIObject
{
public:
hgeGUIRectBar(int _id, float _x, float _y, float _h, float _w, char* texto = "" );
~hgeGUIRectBar(void);
virtual void Render();
void Update(float dt);
void setPercent(float _per){ percent = _per/100; w=percent*ws; }
float getPercent(){ return percent; }



private:

hgeQuad quad, quadbg;
hgeFont * fnt;
float percent;
float x,y,h,w,ws;

char* m_label;

//para almacenar color
DWORD m_color;

};
#endif //___RECTBARprofeclipserulez


hgeGUIRectBar.cpp
#include ".\hgeguirectbar.h"

#define BORDE 5
#define VERDE ARGB(255,157,255,157)
#define AMARILLO ARGB(255,255,255,89)
#define ROJO ARGB(255,255,0,0)

hgeGUIRectBar::hgeGUIRectBar(int _id, float _x, float _y, float _h, float _w, char* texto)
{

id = _id;
bStatic = false;
bVisible = true;
bEnabled = true;

// Factor para calcular la "completitud" de la barra + valor contenedor de largo de la barra
percent = 1.0f;
w = _w;
x = _x;
y = _y;
h = _h;
ws = _w;

m_label = texto;
//TODO FOR YOU! CHOSE A FONTBAR OF YOUR ELECTION
fnt = new hgeFont("data/font/fontbar.fnt");

}

hgeGUIRectBar::~hgeGUIRectBar(void)
{

delete fnt;

}


void hgeGUIRectBar::Render()
{

//NOTA: Quad es
/* 3 -- 0
| |
| |
2 -- 1 */

//quadbg = rect??ngulo de fondo
quadbg.v[1].x = x - BORDE; quadbg.v[1].y = y + BORDE;
quadbg.v[2].x = x + ws + BORDE; quadbg.v[2].y = y + BORDE;
quadbg.v[3].x = x + ws + BORDE; quadbg.v[3].y = y - h - BORDE;
quadbg.v[0].x = x - BORDE; quadbg.v[0].y = y - h - BORDE;

quadbg.v[0].z = 1.0f;
quadbg.v[1].z = 1.0f;
quadbg.v[2].z = 1.0f;
quadbg.v[3].z = 1.0f;

// de color blanco
for (int i = 0; i <4 ; i++)<br /> {
quadbg.v[i].col = ARGB(255,255,255,255);
}

quadbg.tex = 0;
quadbg.blend = BLEND_DEFAULT;


//quad = rect??ngulo de barra
quad.v[1].x = x; quad.v[1].y = y;
quad.v[2].x = x + w; quad.v[2].y = y;
quad.v[3].x = x + w; quad.v[3].y = y - h;
quad.v[0].x = x; quad.v[0].y = y - h;

quad.v[0].z = 1.0f;
quad.v[1].z = 1.0f;
quad.v[2].z = 1.0f;
quad.v[3].z = 1.0f;

// de color seg??n el estado (DEFINE'd)
// verde claro : ARGB(255,157,255,157)
// amarillo : ARGB(255,255,255,89)
// rojo : ARGB(255,255,0,0)

for (int i = 0 ; i <4; i++)<br /> {
quad.v[i].col = m_color;
}

quad.tex = 0;
quad.blend = BLEND_DEFAULT;

//Texto

fnt->printf(x+2,y-2, HGETEXT_LEFT, "%s", m_label);

hge->Gfx_RenderQuad(&quadbg);
hge->Gfx_RenderQuad(&quad);

}

void hgeGUIRectBar::Update(float dt)
{

//default verde
//amarillo debajo 60%
//rojo debajo 20%

if(percent <= 0.6f)<br /> {
m_color = AMARILLO;
if (percent <= 0.2f)<br />
{
m_color = ROJO;
}
} else {
m_color = VERDE;
}



}


The code (I hope!) its self explanatory, you have to add the ctrl to your gui handler, then when your code changes a value that you want to display, just set the percent based on it (using the useful defined macros setBar and getBar): you want it filled, set 100. A half 50 and so on. Or it can be a dinamic value like a health bar, thats up to you. The bar has 3 macro for colors, Verde stands for green, Amarillo stands for yellow, and Rojo for red. You can change the values if you want to. Also the bar when rendered shows a nice fixed border just for fashion :D . Note that the border is relative to the bar rect, have this in mind when setting the bar ;)

Finaly, the text makes a little label down the bar, which is hand if you are making multiple bars like me :D

Ok, i hope that this is useful to you guys. Any feedback is appreciated!

Greetings
Marco]]>
Transitions Demo http://relishgames.com/forum/index.php?p=/discussion/4240/transitions-demo Mon, 01 Sep 2008 22:15:41 -0400 cleerline 4240@/forum/index.php?p=/discussions
I have created a transitions class which enables transitions (like fade, wipe etc) between two textures.

This has come in useful when I am switching (say) from the main menu into a sub menu, or from a menu into playing the game.

The demo and source are here :

http://www.cleerline.com/HGE/transitions_demo.zip

These transitions are also used in my (HGE powered) game LexiClix http://lexiclix.com]]>
Xbox 360 controller demo http://relishgames.com/forum/index.php?p=/discussion/4197/xbox-360-controller-demo Sun, 03 Aug 2008 18:59:51 -0400 Drew 4197@/forum/index.php?p=/discussions
This is based on an example I found on CodeProject, modified to recognise all available buttons. You could probably use it in its current state with hge, but it'd be a bit messy. Still, someone might find it helpful.
I'll post a hge-friendly version when I have time to do it.

Download]]>
AVI Video in HGE http://relishgames.com/forum/index.php?p=/discussion/3895/avi-video-in-hge Wed, 05 Mar 2008 17:16:35 -0500 chadder06 3895@/forum/index.php?p=/discussions
AVI.h
#include 
#include
using std::string;
#include

#ifndef AVI_H
#define AVI_H

class AVI {
public:
enum playMode {
PLAY_ONCE = 0,
PLAY_LOOP = 1
};

protected:
enum state {
STATE_STOP = 0,
STATE_PLAY = 1,
STATE_PAUSE = 2
};

state currentState;
playMode currentPlayMode;

HTEXTURE texture;
hgeSprite *sprite;
HGE *hge;

PAVIFILE aviFile;
PAVISTREAM aviStream;
PGETFRAME aviFrame;

int firstFrame;
int currentFrame;
int numFrames;
float frameLength;
float clipLength;
float lastDrawTime;

public:
float x;
float y;
float width;
float height;

AVI(string filename, playMode playmode, HGE *hge);
virtual ~AVI();
virtual void update();
virtual void render();

virtual void play();
virtual void pause();
virtual void stop();
virtual AVI::state getState();
};

#endif /* AVI_H */


AVI.cpp
#include 
#include
#include
#include
#include

AVI::AVI(string filename, playMode playmode, HGE *hge) {
this->hge = hge;

x=0;
y=0;

texture = NULL;
sprite = NULL;

aviFile = NULL;
aviStream = NULL;
aviFrame = NULL;
firstFrame = 0;
currentFrame = 0;
numFrames = 0;
clipLength = 0;
frameLength = 0;
lastDrawTime = -1;
currentPlayMode = playmode;
currentState = STATE_PLAY;

// Open avi File
int res=AVIFileOpen(&aviFile, filename.c_str(), OF_READ, NULL);
if (res!=AVIERR_OK) {
// Could not open file
if (aviFile!=NULL) {
AVIFileRelease(aviFile);
aviFile = NULL;
}
}

// Get file info
if(aviFile) {
AVIFILEINFO aviInfo;
AVIFileInfo(aviFile, &aviInfo, sizeof(AVIFILEINFO));

this->width = (float)aviInfo.dwWidth;
this->height = (float)aviInfo.dwHeight;

clipLength = ((float)aviInfo.dwLength*(float)aviInfo.dwScale)/((float)aviInfo.dwRate);
frameLength = (float)aviInfo.dwScale / (float)aviInfo.dwRate;

// Open Stream and read more info
int res;
res = AVIFileGetStream(aviFile, &aviStream, streamtypeVIDEO, 0);
firstFrame = AVIStreamStart(aviStream);
currentFrame = firstFrame;
numFrames = AVIStreamLength(aviStream);

if(res != AVIERR_OK ||
firstFrame == -1 ||
numFrames == -1)
{
// Error Reading File
if (aviStream!=NULL)
AVIStreamRelease(aviStream);
aviStream = NULL;
AVIFileRelease(aviFile);
aviFile = NULL;
}

if(aviStream) {
aviFrame = AVIStreamGetFrameOpen(aviStream, NULL);
}
}

texture = hge->Texture_Create((int)this->width, (int)this->height);
sprite = new hgeSprite(texture, 0, 0, this->width, this->height);
sprite->SetColor(0xFFFFFFFF);

DWORD *pixels = hge->Texture_Lock(texture, false);
if(pixels) {
std::cout << "edit" << std::endl;<br /> // Set initial texture to white
for(DWORD i = 0; i < (hge->Texture_GetWidth(texture) * this->height); i++) {
pixels[i] = 0xFFFFFFFF;
}

hge->Texture_Unlock(texture);
}
}

void AVI::update() {
if(currentState != STATE_PLAY)
return;

if(lastDrawTime == -1)
lastDrawTime = hge->Timer_GetTime();

int targetFrame = currentFrame + (int)floor((hge->Timer_GetTime() - lastDrawTime)/frameLength);
if(targetFrame != currentFrame) {
lastDrawTime += (targetFrame - currentFrame) * frameLength;
currentFrame = targetFrame;
// Movie is at end
if(currentFrame >= numFrames + firstFrame) {
if(currentPlayMode == PLAY_ONCE) {
stop();
return;
}
else if(currentPlayMode == PLAY_LOOP) {
currentFrame = firstFrame;
}
}
std::cout << "draw frame " << currentFrame << std::endl;<br /> // Get Frame Bitmap
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(aviFrame, currentFrame);
if(!lpbi) {
// Error getting frame information
return;
}
// Create pointer to Device Indepenedent Bitmap (DIB) Pixel Data (written in reverse - see Google or MSDN)
BYTE *pData = (BYTE*)(lpbi+1);
DWORD *pixels = hge->Texture_Lock(texture, false);
if(pixels) {
// Write 24 bpp Bitmap data (B8:G8:R8) to texture pixels
if(lpbi->biBitCount == 24) {
long tWidth = hge->Texture_GetWidth(texture);
long vWidth = (long)sprite->GetWidth();
long vHeight = (long)sprite->GetHeight();
long texPos;
long bitPos;
DWORD val;
for(long i = 0; i < vHeight; i++) {
for(long j = 0; j < vWidth; j++) {
texPos = tWidth*i + j;
bitPos = (vWidth*(vHeight-i-1)+(j)) * 3;
val = 0xFF000000 | pData[bitPos + 2] << 16 | pData[bitPos + 1] << 8 | pData[bitPos];<br /> pixels[texPos] = val;
}
}
}
// Write 16 bpp Bitmap data (X1:B5:G5:R5) to texture pixels
else if(lpbi->biBitCount == 16) {
WORD *pDataWord = (WORD*)pData;
long tWidth = hge->Texture_GetWidth(texture);
long vWidth = (long)sprite->GetWidth();
long vHeight = (long)sprite->GetHeight();
long texPos, bitPos;
WORD colorDat, tmp;
DWORD val;
BYTE r, g, b;
for(long i = 0; i < vHeight; i++) {
for(long j = 0; j < vWidth; j++) {
texPos = tWidth*i + j;
bitPos = vWidth*(vHeight-i-1)+(j);
colorDat = pDataWord[bitPos];
tmp = colorDat;
b = (tmp & 0x1F) << 3;<br /> tmp = tmp >> 5;
g = (tmp & 0x1F) << 3;<br /> tmp = tmp >> 5;
r = (tmp & 0x1F) << 3;<br /> val = 0xFF000000 | (r) << 16 | (g) << 8 | (b);<br /> pixels[texPos] = val;
}
}
}

hge->Texture_Unlock(texture);
}
else {
// Couldn't lock texture
}

}
}

void AVI::render() {
if(this->width != sprite->GetWidth() || this->height != sprite->GetHeight()) {
sprite->RenderStretch(x, y, x + width, y + height);
}
else {

sprite->Render(x, y);
}
}

AVI::~AVI() {
if(aviFrame) {
AVIStreamGetFrameClose(aviFrame);
}
if(aviStream) {
AVIStreamRelease(aviStream);
}
if(aviFile) {
AVIFileRelease(aviFile);
}

if(texture)
hge->Texture_Free(texture);
if(sprite)
delete sprite;
}

void AVI::play() {
if(currentState != STATE_PLAY) {
currentState = STATE_PLAY;
lastDrawTime = hge->Timer_GetTime();
}
}

void AVI::pause() {
if(currentState == STATE_PLAY)
currentState = STATE_PAUSE;
}

void AVI::stop() {
currentFrame = firstFrame;
currentState = STATE_STOP;
}

AVI::state AVI::getState() {
return currentState;
}


Main.cpp

#include

HGE *hge = 0;
AVI *avi = NULL;

// This function will be called by HGE once per frame.
// Put your game loop code here. In this example we
// just check whether ESC key has been pressed.
bool FrameFunc()
{
if (hge->Input_GetKeyState(HGEK_ESCAPE)) return true;

avi->update();

// Continue execution
return false;
}

bool RenderFunc() {
hge->Gfx_BeginScene();
avi->render();
hge->Gfx_EndScene();
return false;
}

int _tmain(int argc, _TCHAR* argv[])
{
hge = hgeCreate(HGE_VERSION);
hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
hge->System_SetState(HGE_RENDERFUNC, RenderFunc);
hge->System_SetState(HGE_TITLE, "HGE AVI Test");
hge->System_SetState(HGE_WINDOWED, true);
hge->System_SetState(HGE_USESOUND, false);

if(hge->System_Initiate())
{
// Initialize AVI Library
AVIFileInit();

// Create AVI object
avi = new AVI("C:\\videos\\AVI_DivX.avi", AVI::PLAY_ONCE, hge);
// Move object on screen
avi->x = 30;
avi->y = 30;

// Stretch movie
avi->height = 300;
avi->width = 400;


hge->System_Start();

delete avi;

// Exit AVI Library
AVIFileExit();
}
else
{
// If HGE initialization failed show error message
MessageBox(NULL, hge->System_GetErrorMessage(), "Error", MB_OK | MB_ICONERROR | MB_APPLMODAL);
}

hge->System_Shutdown();
hge->Release();

return 0;
}


[Edited] - Noticed and fixed copy error due to HTML parsing in 16 bit Bitmap data transfer loop.

You also need to link the project with 'vfw32.lib'

On errors, the code will display a white rectangle.
If the code doesn't work for you, try adding some std::cout logging to figure out where it's exiting or try another AVI file.]]>
3D animation ( MD2/MD3/MD5) for HGE http://relishgames.com/forum/index.php?p=/discussion/4191/3d-animation-md2md3md5-for-hge Mon, 28 Jul 2008 22:12:20 -0400 progman 4191@/forum/index.php?p=/discussions Help to find please.]]> Window based GUI http://relishgames.com/forum/index.php?p=/discussion/1396/window-based-gui Thu, 16 Feb 2006 18:44:50 -0500 shoorik 1396@/forum/index.php?p=/discussions
- simple windows
- lables
- images
- threestate buttons
- edit box
- password box
- listbox (may list other GUI elements)

http://www.workzone.tsws.odessa.ua/~shoorik/hge/guiapp.rar

In progress: XML resource loading...
Thanx to Isometric God - I've used his code in some places.. :)]]>
rotation of tiles... http://relishgames.com/forum/index.php?p=/discussion/4028/rotation-of-tiles... Thu, 29 May 2008 16:02:43 -0400 ozoi 4028@/forum/index.php?p=/discussions I was wondering what would be the smoothest way to rotate a tilemap of either sprites or quads.

Is there a way to render a tileset to a quad or texture and rotate that, or should I perhaps calc for each tile position / rotation and reBlit?

Thanks!

//Ozoi]]>
HGE encapsulation in a games creation framework http://relishgames.com/forum/index.php?p=/discussion/2866/hge-encapsulation-in-a-games-creation-framework Mon, 22 Oct 2007 11:52:19 -0400 ninseineon 2866@/forum/index.php?p=/discussions
I really had a rough week experimenting with HGE's tutorials and figuring out how to wrap my code around HGE in a way that things wouldn't get unmanageable later on - and in the process review my rusty C++ skills, which I hadn't picked up in many, many years. Coding a simple game should become pretty much unbearable if we are to follow the code arrangement of the tutorials, so I eventually came up with a really simple and bare "template" for projects done in HGE.

This is of course nothing special - and I did use some code and concepts scattered around in the Internet as well as some tips scattered around in this forum - but I figured it would be of some help to someone kind of new to C++ and HGE that needs some directions for starting up.

What I basically did here was wrap my classes around HGE, so that the WinMain function becomes as simple as:


int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
Engine* ae = new Engine();
State* my = new State(ae->GetHGEEngine());

if (! ae->Init( "Simple Test Game", my ))
{
MessageBox(NULL, ae->GetHGEEngine()->System_GetErrorMessage(), "Error",
MB_OK | MB_ICONERROR | MB_APPLMODAL);
}

ae->Cleanup();
ae->Quit();

delete my;
delete ae;

return 0;
}


So, what's involved here? Two main classes (the framework really has to have more - but these should be the bare basics): Engine and State. I will give you the code in the next posts.

In the meantime, what I hope to get is people's ideas on this code and how to improve it (even if at a conceptual level), since I'm new to games programming.]]>
Tutorial: Using RakNet in HGE http://relishgames.com/forum/index.php?p=/discussion/3925/tutorial-using-raknet-in-hge Thu, 27 Mar 2008 15:59:11 -0400 woweee 3925@/forum/index.php?p=/discussions http://sourceforge.net/projects/dana

Steps to play the demo:
1.Run main.exe, press 'S'to start server;
2.Run main.exe (change the IP in the file 'config.ini'), press 'C' to start client.
3.Press 'N' in the first one to create a new game;
4.Play...

Download links:

BIN: http://augusgames.googlepages.com/HGERakNetBIN.rar
SRC: http://augusgames.googlepages.com/HgeRakNetSrc.rar

Note: Bloodshed Dev-C++ is required.]]>
HGE BlendAlphaMultiply http://relishgames.com/forum/index.php?p=/discussion/3851/hge-blendalphamultiply Tue, 05 Feb 2008 05:23:41 -0500 gamecoder5 3851@/forum/index.php?p=/discussions
hge->Gfx_BeginScene(tar);
dx->SetRenderState( D3DRS_SEPARATEALPHABLENDENABLE, TRUE );
dx->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
dx->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
dx->SetRenderState( D3DRS_SRCBLENDALPHA, D3DBLEND_ONE );
dx->SetRenderState( D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA );
hge->Gfx_Clear(ARGB(0, 0, 0, 0));

// Render things

hge->Gfx_EndScene();

Assuming I gained access to the d3d pointer, does anyone know the exact render states you would set to achieve this effect?

Sorry I dont understand dx code (hence why Im using hge) and especially not all the SetRenderStates.

Thank you very much.

Scott.]]>
[b]Can't create D3D device[/b] http://relishgames.com/forum/index.php?p=/discussion/3817/bcant-create-d3d-deviceb Mon, 21 Jan 2008 08:07:11 -0500 reynave 3817@/forum/index.php?p=/discussions
when i create the game just to find out that it doesn't work for my another pc and notebook. when ever I run the game then the program directly quit. and the log it said "Can't create D3D device". it the same for my notebook.
I use DirectX 8.1

________________________________________________
HGE Started..

HGE version: 1.80
Application: HGE Tutorial 02 - Using input, sound and rendering
OS: Windows 5.1.2600
Memory: 458224K total, 223136K free

D3D Driver: s3mtrio.dll
Description: S3 ViRGE GX2
Version: 5.1024.329.2
Can't create D3D device
________________________________________________

Can anybody help me?]]>
Quick 3D and motion blur http://relishgames.com/forum/index.php?p=/discussion/3291/quick-3d-and-motion-blur Wed, 19 Dec 2007 17:00:36 -0500 Kalith 3291@/forum/index.php?p=/discussions In the previous weeks, I played a bit with HGE and maths and endeded up with this :

image
DOWNLOAD


It's a program that generates a galaxy with the number of stars you want.
Each of these stars has 3d coordinates that are then converted to 2d, "on screen" coordinates. The conversion function is not efficient at all (35 FPS on my machine with a very big and moving galaxy) because I don't use matrix and all the stuff you usualy meet in 3d programming : it's only basic geometry and maths. But it works :)
On top of it, I though it would be cool to make these stars move. Why not ?
So I made them move, it wasn't very difficult. Then I added motion blur, the cool effect on the picture above. It wasn't that hard too, but the method used here only works with a black background and is heavily FPS dependent...
This effect only works if you press [F] (to make stars move). And try to use the zoom, it renders very well.

Anyway, I hope you'll find something usefull for your project(s).

(oh, and the code is an horrible mess :P good luck if you want to read it)

Edit : the conversion function has been splited all over the file to prevent redundant calculations, so it's not easy to understand. Here is the complete version :
Point to2D(float a1, float b1, float c1)
{
Point p;

// We first make a check to choose which calcultation method we'll use
float xi = cos(ca1+M_PI_2);
float yi = sin(ca1+M_PI_2);
float zi = 0; // not needed

float xj = cos(ca1)*sin(ca2+M_PI_2);
float yj = sin(ca1)*sin(ca2+M_PI_2);
float zj = 0; //not needed
//float zj = cos(ca2+M_PI_2);

if ( (fabs(xj) < 0.001) && (fabs(yj) < 0.001) )
{
// ^j is (0,0,1), we have to use a more simple formula
float X, Y;
X = a1*xi+b1*yi;
Y = c1;

p.x = (cd/500)*X+512;
p.y = -(cd/500)*Y+384;
}
else
{
float t1 = sin(ca2)*cos(ca1);
float t2 = sin(ca2)*sin(ca1);
float t3 = cos(ca2);
// We define the screen plane P :
// x*A + y*B + z*C + D = 0
// With :
float A = t1-cx;
float B = t2-cy;
float C = t3-cz;
float D = t1*cx + t2*cy + t3*cz - cd;

// Projection of the provided point on the plane :
float L = -(A*a1 + B*b1 + C*c1 + D)/(A*A+B*B+C*C);
float a2 = L*A + a1;
float b2 = L*B + b1;
float c2 = 0; // not needed
//float c2 = L*C + c1;

// We define a reference mark (O, ^i, ^j) :
// O(xo, yo, zo)
// ^i(xi, yi, zi)
// ^j(xj, yj, zj)
// With O, ^i and ^j belonging to P and ^i.^j = 0
// So :
float xo = cx+cd*t1;
float yo = cy+cd*t2;
float zo = 0; // not needed
//float zo = cz+cd*cos(ca2);

// ^i and ^j are already calcultated

// Then at last, we get the screen coordinates :
float X, Y;
X = (yj*(a2-xo)-xj*(b2-yo))/(xi*yj-xj*yi);
Y = (yi*(a2-xo)-xi*(b2-yo))/(xi*yj-xj*yi);

p.x = (cd/500)*X+512;
p.y = -(cd/500)*Y+384;
}

return p;
}


The only global variables needed here are :
ca1, ca2 : angles of view
cx, cy, cz : position of the center of the view (doesn't work if you change :P)
cd : distance of the camera from the center]]>
"3d" with matrices http://relishgames.com/forum/index.php?p=/discussion/3795/3d-with-matrices Tue, 08 Jan 2008 21:54:31 -0500 Drew 3795@/forum/index.php?p=/discussions
image

This was an exercise in teaching myself the maths I should have picked up at uni but never really got to grips with at the time. Apologies for the lack of comments, commented out blocks & generally rubbish design.

Classes worth a mention:
AdvancedSprite - this is where the matrix math & rendering happens. Not the best place for it really - in later attempts this was moved out to its own utility class. There are also a few matrix math libraries around, it may be worth considering one of these :)

ObjectManager - Update() does some matrix manipulation to each sprite before rendering. Objects store the state of each sprite, data from which is passed to AdvancedSprite. Rather than keep a bunch of pointers to sprites around all the time I use a single sprite which is rendered multiple times & update it with each object's data. The idea being objects take up less space than full blown sprites, but there is a cost associated with initialising sprites on a per object basis. I haven't noticed a significant performance hit with this approach.

SortingAlgorithms - This is used to sort the rendering order of the sprites by Z depth. only std::sort at the moment but the design allows multiple sort algorithms to be plugged in & swapped between.

TextureManager: Virtually pointless at present, just saves me having to type HTEXTURE manually :)

last but not least (and not actually a class), MMGR. Great little memory manager from Fluid Studios

WinMain contains the setup code for the various objects in the scene.

Bugs:
- Zooming doesn't work for negative values of Z.
- Some of the marines at the back aren't spaced evenly in terms of Z depth, but they should be.

There's plenty of improvements to make to this project, but it's a start - I suspect there are subtle errors in the maths so if you spot anything let me know.

and finally..
Download]]>
a simple linear interpolator for transition effects http://relishgames.com/forum/index.php?p=/discussion/2856/a-simple-linear-interpolator-for-transition-effects Sun, 14 Oct 2007 21:16:10 -0400 buddapalm 2856@/forum/index.php?p=/discussions
For example, you could peg the transparency alpha to an interpolator so you get a smooth fade-in/fade-out over a period of time. But you could use them for other types of smooth time-based transitions, like going from one 2dvector to another.

Header
class CLinearInterpolator
{
public:
bool Init(float from, float to, float duration);
bool Update(float dt);
float GetValue();
private:
float value;
float max;
float step;
float remainingTime;

};


cpp

///  pass a from and to value to span over the given time
bool CLinearInterpolator::Init(float from, float to, float duration)
{
if(duration<0) return false;<br />
value = from;
max = to; // our target
remainingTime = duration; // how much time is left
step = (to-from)/duration; /// we use this to calculate even, linear steps.
return true;

}

/// called each frame and gets the value closer to its target
bool CLinearInterpolator::Update(float dt)
{
if (remainingTime <=0) <br /> {
if (value!=max) value=max; // let make sure we land on the original 'to' value
return true; /// we're done, return true
}

remainingTime -= dt; // decrement the amount of time remaining
value += step*dt; /// move the value we're tracking
return false;
}
/// called to determine what the current value is
float CLinearInterpolator::GetValue()
{
return value;
}




Usage:


CLinearInterpolator *objectLerp=new CLinearInterpolator;
objectLerp->Init(0,1,2); /// go from 0 to 1 in 2 seconds

/// in your update frame call this
objectLerp->Update(dt); // where dt is from your delta timer

/// when rendering...
// random sprite will scale vertically when pegged to lerp
sprite->RenderEx(600,600,0,1.0f,objectLerp->GetValue());


It's pretty simple, but it seems to work for me. a way to improve it is to support different math beyond linear increments (like cubic / exponential curves). I'm also interested if someone refactors or finds a better usage/design pattern.]]>
First experience: scaling http://relishgames.com/forum/index.php?p=/discussion/994/first-experience-scaling Mon, 14 Nov 2005 08:49:37 -0500 blueglasses 994@/forum/index.php?p=/discussions
A few moments ago i discovered the sprite's ability to be scaled and rotated via HGE RenderEx function. Too late, i already got my own scaling code finished for quads and was about to begin a rotation function. Well, now i'm not quite sure if the work for this function was unnecessary.

When comparing vertex based objects and sprites in HGE i come to the conclusion that vertex based objects are almost solely used as static objects (ie. as background), while sprites cover the moving part. Is this right? But why skip quads (and triples)? As i understand quads are more complex due to the ability of manipulating every vertex's coordinates, while sprites always have symmetric sides.

With those thoughts in mind i still think that the following code is useful for scaling quads - for quads with asymmetric sides in particular. If not, please tell me how to do this with sprites, so i don't waste time for a vertex based rotation function, thanks.



struct paraEdges // a parallelogram can be defined by two opposing coords due to its symmetry.
{
float minX, minY, maxX, maxY;
};

// Calculating the upper left and lower right corner of the parallelogram which surrounds the quad,
// needed for scaling and rotation. When rotating, only the center of the parallelogram is needed,
// corresponding to the center of the quad (although this isn't always quite right), but that's done
// by the rotating function itself with the help of the two outer points calculated here.
// Note: I'm using "frame" as a synonym for this parallelogram, because it's a (symmetric) frame of the quad.
void getPara(const hgeQuad& quadS, paraEdges& quadD)
{
quadD.minX = (quadS.v[0].x < quadS.v[1].x) ? quadS.v[0].x : quadS.v[1].x;
quadD.minX = (quadD.minX < quadS.v[2].x) ? quadD.minX : quadS.v[2].x;
quadD.minX = (quadD.minX < quadS.v[3].x) ? quadD.minX : quadS.v[3].x;

quadD.maxX = (quadS.v[0].x > quadS.v[1].x) ? quadS.v[0].x : quadS.v[1].x;
quadD.maxX = (quadD.maxX > quadS.v[2].x) ? quadD.maxX : quadS.v[2].x;
quadD.maxX = (quadD.maxX > quadS.v[3].x) ? quadD.maxX : quadS.v[3].x;

quadD.minY = (quadS.v[0].y < quadS.v[1].y) ? quadS.v[0].y : quadS.v[1].y;
quadD.minY = (quadD.minY < quadS.v[2].y) ? quadD.minY : quadS.v[2].y;
quadD.minY = (quadD.minY < quadS.v[3].y) ? quadD.minY : quadS.v[3].y;

quadD.maxY = (quadS.v[0].y > quadS.v[1].y) ? quadS.v[0].y : quadS.v[1].y;
quadD.maxY = (quadD.maxY > quadS.v[2].y) ? quadD.maxY : quadS.v[2].y;
quadD.maxY = (quadD.maxY > quadS.v[3].y) ? quadD.maxY : quadS.v[3].y;
}

// scaling an object. amount in percent/100. I don't call this function "scaleQuad" due to overloading capabilities of C++,
// so there will be a function which scales triples, too.
// So what is it doing? First, we calculate the outer points of the frame (see getPara();). Then this frame will be scaled by
// the amount given, and last the old quad coords are being projected onto the new frame via distance calculation.
void scaleObject(hgeQuad& quad, float amount)
{
if (amount==0) exit; // no scaling

float x[4], y[4];
paraEdges paraShort;

getPara(quad, paraShort); // we need the two edges of the parallelogram, our "frame"

// we need to calc the distance every vertex of the object has from the upper left frame origin (for final frame-to-quad scaling projection)

for (int i=0; i<4; i++)<br /> {
x[i] = quad.v[i].x - paraShort.minX;
y[i] = quad.v[i].y - paraShort.minY;
}

// alright, now we need the coordinates of the scaled frame

float amountX = ((paraShort.maxX - paraShort.minX) * amount) / 2; // here we calc the length each side has to be extended in both directions
float amountY = ((paraShort.maxY - paraShort.minY) * amount) / 2;

paraShort.minX -= amountX; // scaling the frame
// paraShort.maxX += amountX; // we don't need the lower right corner for the scaling projection

paraShort.minY -= amountY;
// paraShort.maxY += amountY;

// Ok, we got the new coordinates of the frame. Now we have to project the old quad coords onto this new frame.

for (int i=0; i<4; i++)<br /> {
quad.v[i].x = paraShort.minX + x[i] + x[i] * amount;
quad.v[i].y = paraShort.minY + y[i] + y[i] * amount;
}

// scaling finished.
}



For those who don't want to read the code now / for describing purposes i got a pic here:

image

Explanation:
The black coloured object is the quad, the red coloured object is the surrounding parallelogram (the "frame"), which can be painted for every quad. Due to its symmetry only S (blue) and the opposing corner need to be calculated to get the length of each side.
So S is the coordinate for the upper left corner of the frame which is of special significance for my scaling function: The distance (x, y) of S->a, S->b, S->c, S->d is being calculated. Now follows the calculation of the length of the frame sides, then the lengths are being scaled using amount. The new S is the new projection point for the distances, which also need to be scaled with amount, so the new quad coordinates can be calculated.

Hope i've explained it comprehensible ;).]]>
Timer Twitch - hge->Timer_GetDelta() http://relishgames.com/forum/index.php?p=/discussion/2340/timer-twitch-hge-timer_getdelta Sat, 10 Feb 2007 08:20:43 -0500 InspiredIdea 2340@/forum/index.php?p=/discussions
Some of the Windows time functions have resolution of 1 ms, but are not gauranteed to be accurate in the short term. Over time, the sum of time is accurate but within each frame, it is not. Here's an alternative that is more accurate:

#include <time>

int CurTick;
void InitDelta()
{
CurTick = (int)GetTickCount();
}

float GetDelta()
{
int t, t2;
t = (int)GetTickCount();
t2 = t - CurTick;
CurTick = t;
return((float)t2 / 1000.0f);
}


I hope this is helpful...]]>
Button Class http://relishgames.com/forum/index.php?p=/discussion/2791/button-class Thu, 06 Sep 2007 11:17:51 -0400 coder121 2791@/forum/index.php?p=/discussions
This button class allows for 4 different frames: Disable, Release (or "Normal" for lack of a better word), Hovered, and Pressed. It also uses a resource file for obtaining the graphics. Hope this is helpful to someone!

On a side note, it would be pretty easy to add sound effects or darker/brighter font for the different button states.

THE CPP


#include "GuiCtrls.h"

GuiButton::GuiButton(int id, float x, float y, char* caption)
{
this->id = id;
this->caption = caption;

state = 0;

bStatic = false;
bVisible = true;
bEnabled = true;

rect.Set(x, y, x + 90, y + 20);

disable = GET_RES->GetSprite("buttonDisable");
release = GET_RES->GetSprite("buttonRelease");
hovered = GET_RES->GetSprite("buttonHovered");
pressed = GET_RES->GetSprite("buttonPressed");
}

void GuiButton::Render()
{
if (!bEnabled) disable->Render(rect.x1, rect.y1);

switch (state) {
case 0:
release->Render(rect.x1, rect.y1);
GET_FNT->Render(rect.x1 + 45, rect.y1, HGETEXT_CENTER, caption);
break;

case 1:
hovered->Render(rect.x1, rect.y1);
GET_FNT->Render(rect.x1 + 45, rect.y1, HGETEXT_CENTER, caption);
break;

case 2:
pressed->Render(rect.x1, rect.y1);
GET_FNT->Render(rect.x1 + 45, rect.y1, HGETEXT_CENTER, caption);
break;
}
}

void CtrlButton::MouseOver(bool bOver)
{
if (bOver) state = 1;
else state = 0;
}

bool CtrlButton::MouseLButton(bool bDown)
{
if(bDown) {
state = 2;
return false;
}

else {
state = 0;
gui->SetFocus(id);
return true;
}
}


THE HEADER



#ifndef GUICTRLS_H
#define GUICTRLS_H

#include
#include
#include "SomeClassThatContainsResourceStuff.h"

class GuiButton : public hgeGUIObject
{
public:

GuiButton(int id, float x, float y, char* caption);

void Render();

void MouseOver(bool bOver);

bool MouseLButton(bool bDown);

private:

BYTE state;

char* caption;

hgeSprite* disable;
hgeSprite* release;
hgeSprite* hovered;
hgeSprite* pressed;
};

#endif
]]>
Destructors and stl's vector http://relishgames.com/forum/index.php?p=/discussion/2759/destructors-and-stls-vector Tue, 21 Aug 2007 15:40:10 -0400 Mifferz 2759@/forum/index.php?p=/discussions
This is currently in my ammo class

class ammo
{
public:
virtual ~ammo();
virtual void Fire_Animation();

int ammoNum;
float velocity;
float radius; //for hitbox use
float timer;
float nowTime;
float lastTime;
bool fireKey; //fire animation
HTEXTURE texAmmo;
hgeRect *hitbox;
hgeVector vPosition;
hgeVector vDirection;
hgeAnimation *animAmmo;
hgeParticleSystem *par; //particle system

};



ammo::~ammo()
{
delete hitbox;
delete par;
hge->Target_Free(texAmmo);
}


That's what I currently have.


vector ListofAmmo;
ammo *newAmmo = new ammo();
ListofAmmo.push_back(newAmmo);
ListofAmmo.clear();


Will clear run the destructor so it destroys the objects and its members AND the pointers?
Getting memory leaks and trying to clean up *sigh*]]>
Pathfinder http://relishgames.com/forum/index.php?p=/discussion/2533/pathfinder Sat, 19 May 2007 18:03:23 -0400 Kalith 2533@/forum/index.php?p=/discussions Here is the latest version of my pathfinder : Click

image

If the first path has been found, press the space bar and it will find a new one.
You can adjust the speed by changing the max "FPS" in config.ini, the number of iteration to do between two frames, and the size of the nodes with "precision".

Hope you'll like it :)

Changelog :
- Improved performance.
- Changed the algorythm : the path found is now the real shortest one.
The changes made to the code require more nodes to be visited than the
previous version (about twice more !), and it impacts severely on performances.]]>
Fonted with more space between letters http://relishgames.com/forum/index.php?p=/discussion/2596/fonted-with-more-space-between-letters Mon, 18 Jun 2007 15:15:02 -0400 Kalith 2596@/forum/index.php?p=/discussions I was in trouble making an outlined font with fonted because the letters were too close from eachother.
So I modified fonted a bit to include more space between each letter (the space added is relative to the font size). This amount is not modifiable in the program itself but you can deal with it in "generate.cpp", line 86-87 and 136.
I also had to remove some letters (?—, ??, , , ??, ?¶, , ??, ??) to prevent the program from crashing when the texture would have to be larger than 1024/1024 (thus it depends on the font you use : with arial the program crashes if the size is above 54 and all letters selected, with some others you can reach 80 with all letters selected and bold checked).

Here is the link : Click me
(source provided, .exe compiled with HGE 1.7 and directX9)]]>
EXAMPLE CODE - Empty HGE Project (with separated files) http://relishgames.com/forum/index.php?p=/discussion/2636/example-code-empty-hge-project-with-separated-files Sat, 30 Jun 2007 15:15:56 -0400 eggnog 2636@/forum/index.php?p=/discussions
I had some difficulty working out how I could separate a project into multiple files (Not really surprising as I am still a newbie in the c++ department XD).

Anyway I worked it out a while back and thought I would post an example almost empty project.

I was hoping that it will help someone out there :D

Also I was hoping that some of the more experianced members around here could take a look and point out anything that may be wrong with it or anything they would do differently.

Here's the link: http://themissingink.net/games/blankhge.zip]]>