// MVX DirectX 8.0 Wrapper
// M standing for Master master@lostsidedead.com Jared Bruni
// V standing for Vulcan vulcan@lostsidedead.com Eric Anderson
// X being for DirectX
// other code credits
// mp3 loading/playing code written by
// Lee Trager then modified & integrated
// into mvx by Vulcan
// REMINDER you _must_ have a directX8 SDK in order
// to run this program!
// This wrapper is free for use in any way shape or form
// It was not intended to be sold or made for commercial gain
// whatsoever. You may use this code & wrapper in your own
// programs, however we do ask that you give us some credit
// plus, e-mail us whatever you've done with the wrapper, as
// we would like to see it. Full documentation on this wrapper
// might be on its way, but only when it is fully finished.
// As this wrapper is currently (May 2001) in development
// it is expected to be updated on a rather constant basis
// be sure to keep checking back to either
// http://www.lostsidedead.com OR http://www.planet-source-code.com
// for more updates
// this wrapper is being developed mainly for use in the
// game GodSkin Online
// http://godskin.cjb.net
// look for it soon...
/*
======| \======/ |==| |==| |== \====/ ======
======| \====/ |==\ \/ /==\ \==/ /======
======| \==/ |===| || |====\ \/ /=======
======| |\ \/ /| |===| \/ |=====\ /========
======| |=\ /=| |===\ /=====/ \========
======| |==\/==| |====| |=====/ /\ \=======
======| |======| |=====\/=====/ /==\ \======
*/
// you _must_ include these library files
// d3d8.lib d3dx8.lib dinput8.lib winmm.lib dxguid.lib
// in your workspace
// (that is if you want it to work)
// Version notices
// mvx 001
// d3d inits, draws a cube thats vertex shaded *Vulcan*
// mvx 002
// a cube that is texture mapped *Vulcan*
// mvx 003
// mvx supports direct input via mouse & keyboard *Vulcan*
// mvx 004
// mvx support direct sound *Vulcan*
// mvx 005
// mvx has simple objects, known more as wireframe models *Vulcan*
// mvx 006
// updated mvx simple objects are now dynamic *Vulcan*
// mvx 007
// mvx now has mvx objects, which are basically models *Vulcan*
// mvx 008
// mvx objects are now dynamic *Vulcan*
// mvx 009
// updated code, added a d3d light *Vulcan*
// mvx 010
// updated objects, both simple & normal *Vulcan*
// added isogameworld, blocked landscape *Vulcan*
// mvx 011
// windowed mode now works *Vulcan*
// mp3 loading/playing added *Vulcan*
// mvx 012
// particle engine created, it works, but will be made better soon *Vulcan*
// mvx 013
// alpha blending particles, camera controls, updated further particles *Vulcan*
// mvx 014
// particles are buggy, fixed some problems *Vulcan*
// 2D rendering "mvxImages" added (2D Sprites) *Vulcan*
// mvx 020
// image stuff remoded
// mvx 030
// 2D particle engine withe mvx Images added *Vulcan*
// Isometric tiling engine added *Vulcan*
// Isometric particle engine added *Vulcan*
// tossed all 3D stuff *Vulcan*
#ifndef _MVX_H_
#define _MVX_H_
#define WIN32_LEAN_AND_MEAN // say no to MFC
// include files
#include <stdio.h>
#include <iostream.h>
#include <winsock2.h> // multiplayer using winsock
#include <windows.h> // include important windows stuff
#include <windowsx.h>
#include <mmsystem.h>
#include <objbase.h>
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include <stdarg.h>
#include <math.h>
#include <io.h>
#include <fcntl.h>
#include <fstream.h>
// DirectX 8 includes
#include <d3d8.h>
#include <d3dx8.h>
#include <dmusici.h>
#include <dinput.h>
#include <d3dx8math.h>
// directX utilities
#include "D3DFont.h"
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
// macros
// windows input macros
#define mvxKEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) // tests whether a key is down
#define mvxKEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1) // tests whether a key is up
// memset macros
#define mvxCLEAR(mystruct) {memset((void*)&mystruct, 0, sizeof(mystruct));}
// direct input macros
#define mvxDIKEYDOWN(name, key) (name[key] & 0x80)
#define mvxMOUSEBUTTONDOWN(name, key) (name[key] & 0x80)
// various defines
#define WINDOW_CLASS_NAME "WINCLASS1" // the windows class name
#define MVX_VERSION 0.30 // version of this wrapper
// error types & defines
#define FAIL -1 // not everything is ok
#define OK 0 // everything is OK
// mouse buttons for direct input
#define MOUSELEFTBUTTON 0
#define MOUSERIGHTBUTTON 1
#define MOUSEMIDDLEBUTTON 2
// various helper defines for functions
#define mvxRGB(r, g, b) D3DCOLOR_XRGB(r, g, b)
#define mvxARGB(a, r, g, b) D3DCOLOR_ARGB(a, r, g, b)
#define mvxTime() GetTickCount()
typedef struct CHAR32
{
char mvxChar[32];
} CHAR32, *CHAR32_PTR;
// and audio file, supports WAV format
typedef class mvxMedia
{
private:
// the sound to play
IDirectMusicSegment8* mvxAudio;
public:
// loads a WAV file
int mvxLoad(char* filename, IDirectMusicLoader8* loader, IDirectMusicPerformance8* performance);
// plays the file
int mvxPlay(IDirectMusicPerformance8* performance);
// stops playing the file
int mvxStop(IDirectMusicPerformance8* performance);
// kill, free memory
void mvxDestroy();
// constructors
mvxMedia();
~mvxMedia();
} mvxMedia, *mvxMedia_ptr;
typedef class mvxMediaX
{
public:
//gets error number
long a;
//for getshortpath
char finname[1000];
//to put string together
char todo[2000];
//error code
void error(long what)
{
mciGetErrorString(what, err, 128);
}
//this is where the error is stored
char err[10000];
//this is the alias name of the file ex. mpeg
char alias[100];
//tells u the status of a file
TCHAR statuss[40];
//tells u the position number(millisec)
TCHAR p[40];
//tells u the lenght number(millisec)
TCHAR l[40];
//opens files and dose not put them in a window
void open(char file[1000])
{
if(GetShortPathName(file, finname, 1000) != 0)
fopen(finname);
}
// if you have the short path name call to this
// by doing this the file will load faster
// opens files and dose not put them in a window
void fopen(char file[1000])
{
close();
sprintf(todo, "open %s type mpegvideo Alias %s", file, alias);
a = mciSendString(todo, 0, 0, 0);
error(a);
}
//open files and puts them in a parent space
void vidopen(char file[1000], HWND parent)
{
if(GetShortPathName(file, finname, 1000) != 0)
fvidopen(finname, parent);
}
// if you have the short path name call to this
// by doing this the file will load faster
// open files and puts them in a parent space
void fvidopen(char file[1000], HWND parent)
{
close();
sprintf(todo, "open %s type mpegvideo Alias %s parent %s Style 1073741824", file, alias, parent);
a = mciSendString(todo, 0, 0, 0);
error(a);
}
//play file
void play()
{
sprintf(todo, "Play %s from 0", alias);
a = mciSendString (todo, 0, 0, 0);
error(a);
}
//stop file
void stop()
{
sprintf(todo, "Stop %s", alias);
a = mciSendString (todo, 0, 0, 0);
error(a);
}
//pause file
void pause()
{
sprintf(todo, "Pause %s", alias);
a = mciSendString (todo, 0, 0, 0);
error(a);
}
//resume file
void resume()
{
sprintf(todo, "Resume %s", alias);
a = mciSendString (todo, 0, 0, 0);
error(a);
}
//close file
void close()
{
sprintf(todo, "Close %s", alias);
a = mciSendString (todo, 0, 0, 0);
error(a);
}
// for poistion and lenght error code will now work winmm.dll returns too big of a char
// to ask for the error code it has to be an int but since we cannt use a int we cannt use
// error code here*/
//get the poistion of a file
void poistion()
{
sprintf(todo, "set %s time format milliseconds", alias);
mciSendString (todo, 0 ,0, 0);
sprintf(todo, "status %s position", alias);
mciSendString (todo, p, strlen(p), 0);
}
//gets the lenght of a file
void lenght()
{
sprintf(todo, "set %s time format milliseconds", alias);
mciSendString (todo, 0, 0, 0);
sprintf(todo, "status %s length", alias);
mciSendString (todo, l, strlen(l), 0);
}
//changes volume sp = speaker vol = what the volume should be set at
void volume(char sp[6], long vol)
{
vol = vol * 10;
sprintf(todo, "setaudio %s %s Volume to %d", alias, sp, vol);
a = mciSendString (todo, 0, 0, 0);
error(a);
}
//resize the video
void resizevid(int left, int top, int width, int height)
{
sprintf(todo, "put %s window at %i %i %i %i", alias, left, top, width, height);
a = mciSendString (todo, 0, 0, 0);
error(a);
}
//seek somewhere with in the file
void seekto(int where)
{
where = where * 1000;
sprintf(todo, "set %s time format milliseconds", alias);
a = mciSendString(todo, 0, 0, 0);
error(a);
sprintf(todo, "play %s from %i", alias, where);
a = mciSendString(todo, 0, 0, 0);
error(a);
}
//finds out the status of whats being played
void status()
{
sprintf(todo, "status %s mode", alias);
a = mciSendString(todo, statuss, strlen(statuss), 0);
}
//set the speed of a file 1000 = normal below 1000 = slower above 1000 = faster
//changes speed will make audio only come out the frount 2 speakers
void speed(int spe)
{
sprintf(todo, "set %s speed %i", alias, spe);
a = mciSendString (todo, 0, 0, 0);
error(a);
}
//auto repeat the file repeatt = true then repeat file false it wont or will stop
void repeat(bool repeatt)
{
if (repeatt == true)
{
sprintf(todo, "play %s notify repeat", alias);
a = mciSendString(todo, 0, 0, 0);
error(a);
}
else
{
sprintf(todo, "play %s", alias);
a = mciSendString(todo, 0, 0, 0);
mvxMediaX::error(a);
}
}
} mvxMediaX, *mvxMediaX_ptr;
// A 2D image, drawn in screen space
typedef class mvxImage
{
public:
// holds the image data
LPD3DXSPRITE mvxImageData;
// the actual image
LPDIRECT3DTEXTURE8 mvxTexture;
// for various ways of drawing
RECT mvxRect;
D3DXVECTOR2 mvxScaling;
D3DXVECTOR2 mvxRotationCenter;
D3DXVECTOR2 mvxTranslation;
float mvxRotationAngle;
D3DCOLOR mvxColor;
// render long lines, but its faster
inline void mvxRender() { mvxImageData->Draw(mvxTexture, NULL, &mvxScaling, &mvxRotationCenter, mvxRotationAngle, &mvxTranslation, mvxColor); };
inline void mvxRenderRect() { mvxImageData->Draw(mvxTexture, &mvxRect, &mvxScaling, &mvxRotationCenter, mvxRotationAngle, &mvxTranslation, mvxColor); };
inline void mvxRenderThis(RECT* rect, D3DXVECTOR2* scale, D3DXVECTOR2* cntr, float ang, D3DXVECTOR2* loc, D3DCOLOR col) { mvxImageData->Draw(mvxTexture, rect, scale, cntr, ang, loc, col); };
// creates/destroys the image
bool mvxCreate(LPDIRECT3DDEVICE8 device, char* imgfilename);
void mvxInit();
void mvxDestroy();
// change params of image
inline void mvxChangeRect(int l, int r, int t, int b) { mvxRect.left = l; mvxRect.right = r; mvxRect.top = t; mvxRect.bottom = b; };
inline void mvxScale(float x, float y) { mvxScaling.x *= x; mvxScaling.y *= y; mvxRotationCenter.x *= x; mvxRotationCenter.y *= y; };
inline void mvxSetCenter(float x, float y) { mvxRotationCenter.x = x; mvxRotationCenter.y = y; };
inline void mvxSetPosition(float x, float y) { mvxTranslation.x = x; mvxTranslation.y = y; };
inline void mvxTranslate(float x, float y) { mvxTranslation.x += x; mvxTranslation.y += y; };
inline void mvxSetAngle(float theta) { mvxRotationAngle = theta; };
inline void mvxRotate(float theta) { mvxRotationAngle += theta; };
inline void mvxSetColor(D3DCOLOR color) { mvxColor = color; };
// constructors
mvxImage(LPDIRECT3DDEVICE8 device, char* imgfilename);
mvxImage();
~mvxImage();
} mvxImage, *mvxImage_ptr;
// holds location data & colors for tiles
typedef struct mvxTILE
{
D3DXVECTOR2 mvxTileLocation;
D3DXVECTOR2 mvxWall1Location;
D3DXVECTOR2 mvxWall2Location;
D3DCOLOR mvxColor;
} mvxTILE, *mvxTILE_PTR;
typedef class mvxTileSet
{
public:
int mvxNumTiles;
int mvxNumLWalls;
int mvxNumRWalls;
mvxImage** mvxTileImg; // image of tile
mvxImage** mvxWallImg1; // left side wall
mvxImage** mvxWallImg2; // right side wall
inline void mvxRenderTile(int p_index, D3DXVECTOR2* p_loc, D3DCOLOR p_color) { mvxTileImg[p_index]->mvxRenderThis(NULL, NULL, NULL, 0, p_loc, p_color); };
inline void mvxRenderLWall(int p_index, D3DXVECTOR2* p_loc, D3DCOLOR p_color) { mvxWallImg1[p_index]->mvxRenderThis(NULL, NULL, NULL, 0, p_loc, p_color); };
inline void mvxRenderRWall(int p_index, D3DXVECTOR2* p_loc, D3DCOLOR p_color) { mvxWallImg2[p_index]->mvxRenderThis(NULL, NULL, NULL, 0, p_loc, p_color); };
void mvxDestroy();
void mvxCreate(int p_numtiles, int p_numlwalls, int p_numrwalls, mvxImage** p_tileimg, mvxImage** p_wallimg1, mvxImage** p_wallimg2);
mvxTileSet();
} mvxTileSet, *mvxTileSet_ptr;
typedef class mvxViewport
{
public:
D3DXVECTOR2 mvxLocation;
D3DXVECTOR2 mvxSize;
bool mvxIsIn(D3DXVECTOR2 p_loc, D3DXVECTOR2 p_size)
{
if (p_loc.x + p_size.x >= mvxLocation.x && p_loc.x <= (mvxLocation.x + mvxSize.x) &&
p_loc.y + p_size.y >= mvxLocation.y && p_loc.y <= (mvxLocation.y + mvxSize.y))
{
return true;
}
return false;
}
// constructors
mvxViewport(D3DXVECTOR2 p_loc, D3DXVECTOR2 p_size)
{
mvxLocation = p_loc;
mvxSize = p_size;
}
} mvxViewport, *mvxViewport_ptr;
// if no tile is present, the usage is NO_TILE (-1)
#define NO_TILE -1
#define NO_DRAW -2 // tile there, but dont draw it
typedef class mvxIsoMap
{
private:
int mvxMapLength;
int mvxMapWidth;
int mvxMapHeight;
int mvxTileLength; // length of tiles *in pixels*
int mvxTileWidth; // width of tiles *in pixels*
int mvxTileHeight; // height of 1 tile *in pixels*
mvxTileSet mvxTileImg; // the tiles to use
mvxTILE* mvxTiles; // locations
int *mvxTileUsage; // what tile set to use for each block (if -1, none is drawn)
int *mvxLWallUsage; // what left wall to draw
int *mvxRWallUsage; // what right wall to draw
int *mvx_zOrder; // order to draw
public:
D3DXVECTOR2 mvxOrigin;
void mvxCompile();
void mvxRender(mvxViewport* p_view);
int mvxLoad(char* filename);
int mvxSave(char* filename);
void mvxDestroy();
void mvxCreate(int p_maplength, int p_mapwidth, int p_mapheight, int p_tilelength, int p_tilewidth, int p_tileheight);
void mvxSetTileSet(int p_numtiles, int p_numlwalls, int p_numrwalls, mvxImage** p_tileimg, mvxImage** p_wallimg1, mvxImage** p_wallimg2);
// constructors
mvxIsoMap();
~mvxIsoMap();
} mvxIsoMap, *mvxIsoMap_ptr;
#define PARTICLE_MAX 1024
typedef struct mvxISO_PARTICLE
{
D3DXVECTOR3 mvxLocation;
D3DXVECTOR3 mvxVelocity;
D3DCOLOR mvxColor;
D3DCOLOR mvxFade;
unsigned long mvxLife;
mvxISO_PARTICLE* mvxNext;
} mvxISO_PARTICLE, mvxISO_PARTICLE_PTR;
typedef class mvxIsoParticleEngine
{
private:
D3DXVECTOR2 mvxOrigin; // (0, 0, 0) in screen space
mvxImage* mvxParticleImage;
mvxISO_PARTICLE* mvxParticle;
mvxISO_PARTICLE* mvxFree;
long mvxParticleCount;
public:
void mvxRenderParticles(mvxViewport* p_view);
void mvxStart(D3DXVECTOR3 p_location, D3DXVECTOR3 p_velocity, D3DCOLOR p_color, D3DCOLOR p_fade, unsigned long p_life);
void mvxUpdate(unsigned long p_timedelta);
void mvxEmitter(D3DXVECTOR3 p_location, D3DXVECTOR3 p_initvector, D3DXVECTOR3 p_offset,
D3DCOLOR p_color, unsigned long p_maxlife, unsigned long p_count);
void mvxDestroy();
mvxIsoParticleEngine(mvxImage* p_image, D3DXVECTOR2 p_origin);
~mvxIsoParticleEngine();
} mvxIsoParticleEngine, *mvxIsoParticleEngine_ptr;
// 2d particles
typedef struct mvxPARTICLE2D
{
// where to render
D3DXVECTOR2 mvxLocation;
D3DXCOLOR mvxColor;
float mvxAngle;
D3DXVECTOR2 mvxVelocity;
bool mvxFade; // whether to fade or not
bool mvxRotate; // whether to rotate
D3DXVECTOR2 mvxScale; // scaling (for emitters)
D3DXVECTOR2 mvxRotationCenter;
D3DXCOLOR mvxFadeAmount; // how much to fade, rotate
float mvxRotateAmount;
mvxPARTICLE2D* mvxNext;
} mvxPARTICLE2D, *mvxPARTICLE2D_PTR;
// 2d particle class
typedef class mvxParticleEngine2D
{
public:
mvxImage* mvxParticleImage; // what the particles look like
mvxPARTICLE2D* mvxParticles; // linked list
mvxPARTICLE2D* mvxParticlesFree;
unsigned long mvxParticleCount;
// functions
// set the image
inline void mvxSetImage(mvxImage* p_image) { mvxParticleImage = p_image; };
// create an explosion
void mvxExplode(D3DXVECTOR2 p_point, D3DCOLOR p_col, float p_force, int p_count, bool p_fde, bool p_rot, D3DXCOLOR p_fdeamt, float p_rotamt);
// start 1 particle
void mvxStart(D3DXVECTOR2 p_point, D3DXCOLOR p_col, D3DXVECTOR2 p_vel, float p_ang, bool p_fde, bool p_rot, D3DXCOLOR p_fdeamt, float p_rotamt);
// update all particles
void mvxUpdate(unsigned long p_timedelta);
// render all particles
void mvxRender(mvxViewport* p_view);
// free up memory
void mvxDestroy();
// constuctors
mvxParticleEngine2D();
~mvxParticleEngine2D();
} mvxParticleEngine2D, *mvxParticleEngine2D_ptr;
// the basic class used to make an application
typedef class mvxEngine
{
public:
// capibilities
D3DCAPS8 mvxCaps; // what the graphics card can & cant do
// graphics
LPDIRECT3D8 mvxD3D; // used to create a D3D devixe
LPDIRECT3DDEVICE8 mvxDevice; // the rendering device
// sound, music
IDirectMusicLoader8* mvxAudioLoader; // Audio Loader
IDirectMusicPerformance8* mvxPerformance; // the sound playing device
// input
LPDIRECTINPUT8 mvxInput; // Direct input object
LPDIRECTINPUTDEVICE8 mvxKeyboard; // direct input keyboard
LPDIRECTINPUTDEVICE8 mvxMouse; // direct input mouse
char mvxKeyBuffer[256]; // keystates
DIMOUSESTATE mvxMouseState; // state of mouse
// networking DirectPlay
// video?
// general app variables
char mvxName[64]; // name of the application
HWND mvxMWH; // main window handle
bool mvxWindowed; // windowed app or not
int mvxWidth; // width of screen
int mvxHeight; // height of screen
int mvxBPP; // bits per pixel
bool mvxAudio; // whether or not to init Audio
char mvxAudioPath[64]; // search path of audio files
bool mvxDInput; // whether or not to init Input (Direct Input)
bool mvxNetwork; // whether or not to init Network (Direct Play)
bool mvxVideo; // whether or not to init Video playback (Direct Show)
bool mvxDebug; // whether or not to run in debug mode
ofstream mvxDebugOut; // filestream to debug file (debug.txt)
void mvxDebugOutTime(); // outputs the time to the debug file
int mvxInit(HINSTANCE); // initialize everything wanted to be initialized defined by flags above
// graphics functions
void mvxClear(DWORD); // clear to back buffer of video memory
void mvxBegin(); // begin scene drawing
void mvxEnd(); // stop scene drawing
void mvxShow(); // page flip (show the rendered scene)
// input functions
void mvxReadKeys(); // reads keyboard input (into mvxKeyBuffer)
void mvxReadMouse(); // gets mouse state (into mvxMouseState)
// other general app functions
bool mvxSave(char* data, int size, char* file); // save data to a file
bool mvxLoad(char* data, int size, char* file); // load data from a file
void mvxDestroy();
// constructors
mvxEngine(); // default all values when created
~mvxEngine(); // release all dX objects
} mvxEngine, *mxvEngine_ptr;
#endif