Comment on my Mario 3 clone code

CodeX

2[H]4U
Joined
Mar 21, 2006
Messages
2,879
I have been working on this for a while now, and knowing I am not exactly the most efficient programmer in the world I was wondering if I could get some general comments on the way I am doing this before I get in so deep it becomes unfeasable to change it... It's a lot already.

This is the beginning of a Mario 3 clone, written in C++ using Direct3D. Here is an overview of the files used in the project:

marioxl3cw.jpg


And here is the code:
*edit* The spacing got messed up in almost all of these, so ignore wierd spacing issues.

main.cpp

Code:
#define SCR_WIDTH 1024
#define SCR_HEIGHT 768
#define D3D_PRESENTATION_RATE 65

#include <vector>
#include <fstream>
using namespace std;

#include <MyD3DGame.h>
#include "main.h"


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{

	MakeWindow(hInstance,"Super Mario XL");
	
	InitD3D();
	InitDirectInput();
	InitTextures();
	loadScene();

	while(1)
	{
		//Handle OS Messages
		if(PeekMessage(&msg,hwnd,0,0,PM_REMOVE))
		{ 
			TranslateMessage(&msg); 
			DispatchMessage(&msg); 
		}
		
		//Get and Process User Input
		GetInput();
		if(keys[ESCAPE])break;
				
		//Process Every Game Object
		for(int i=0; i<objectVector.size(); i++) 
			objectVector[i]->process();

		//Draw Every Game Object
		BeginDrawing();

			sky.Blit(0,0);
			for(i=0; i<objectVector.size(); i++) 
				if(objectVector[i]->onScreen()) 
					objectVector[i]->draw();

		EndDrawing();
		Present();
	}

	CloseD3D();
	//Cleanup to be added
	return 0;
}


MyD3DGame.h

Code:
#pragma once

//Includes
#include <Windows.h>
#include <dinput.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <string>
#include <cstdlib>
#include <time.h>
#include <fstream>
using namespace std;

//Defines
#ifndef SCR_WIDTH 
#define SCR_WIDTH 1024 
#endif

#ifndef SCR_HEIGHT 
#define SCR_HEIGHT 768 
#endif

#ifndef D3D_PRESENTATION_RATE
#define D3D_PRESENTATION_RATE D3DPRESENT_RATE_DEFAULT
#endif

#define ESCAPE		DIK_ESCAPE
#define RETURN		DIK_RETURN
#define ENTER		DIK_RETURN
#define SPACE		DIK_SPACE
#define RIGHT		DIK_RIGHT
#define LEFT		DIK_LEFT
#define UP			DIK_UP
#define DOWN		DIK_DOWN
#define PLUS		DIK_NUMPADPLUS
#define MINUS		DIK_NUMPADMINUS
#define BACKSPACE	DIK_BACK

//Direct3D Structures
const DWORD D3DFVF_TLVERTEX = D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1;
//const DWORD D3DFVF_TLVERTEX = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1;

struct TLVERTEX
{
    float x;
    float y;
    float z;
    float rhw;
    D3DCOLOR color;
    float u;
    float v;
};


//Windows Global Variables
HWND hwnd;
MSG msg;


//DirectInput Global Variables
LPDIRECTINPUT8 lpdi;							
LPDIRECTINPUTDEVICE8 keyboard;
LPDIRECTINPUTDEVICE8 mouse;
DIMOUSESTATE mousestate;
unsigned char keys[256];


//Direct3D Global Variables
IDirect3D9* d3d;
IDirect3DDevice9* d3dDevice;
D3DCAPS9 d3dCaps;
D3DPRESENT_PARAMETERS d3dPresent;
IDirect3DVertexBuffer9* vertexBuffer;
int mousex, mousey;

D3DXMATRIX matOrtho;
D3DXMATRIX matIdentity;




//Windows Functions
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
    return DefWindowProc(hwnd,uMessage,wParam,lParam);
}

void MakeWindow(HINSTANCE hInstance, char* title)
{
    WNDCLASSEX wc;
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProcedure;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = NULL;
    wc.hCursor = NULL;
    wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "change";
    wc.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(5));
	RegisterClassEx(&wc);
    hwnd = CreateWindowEx(WS_EX_TOPMOST, "change", title, NULL, 0, 0, SCR_WIDTH, SCR_HEIGHT, NULL, NULL, hInstance, NULL);
	ShowCursor(false);
}


//DirectInput Functions
void InitDirectInput()
{
	DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&lpdi, NULL);
	lpdi->CreateDevice(GUID_SysKeyboard, &keyboard, NULL);
	keyboard->SetDataFormat(&c_dfDIKeyboard);
	keyboard->SetCooperativeLevel(hwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
	keyboard->Acquire();

	lpdi->CreateDevice(GUID_SysMouse, &mouse, NULL);
	mouse->SetCooperativeLevel(hwnd, DISCL_BACKGROUND | DISCL_EXCLUSIVE);
	mouse->SetDataFormat(&c_dfDIMouse);
	mouse->Acquire();
}

void GetInput()
{
	keyboard->GetDeviceState(sizeof(keys),&keys);
	mouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mousestate);
	mousex+=mousestate.lX;
	mousey+=mousestate.lY;

	if(mousex>SCR_WIDTH)mousex=SCR_WIDTH;
	else if(mousex<0)mousex=0;
	if(mousey>SCR_HEIGHT)mousey=SCR_HEIGHT;
	else if(mousey<0)mousey=0;
}


//Direct3D Functions
void InitD3D()
{
	d3d = Direct3DCreate9(D3D_SDK_VERSION);
	ZeroMemory(&d3dCaps, sizeof(d3dCaps));
	d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps);
	ZeroMemory(&d3dPresent,sizeof(d3dPresent));
	d3dPresent.SwapEffect = D3DSWAPEFFECT_COPY;
	d3dPresent.hDeviceWindow = hwnd;
	d3dPresent.BackBufferCount = 1;
	//d3dPresent.MultiSampleType = D3DMULTISAMPLE_NONMASKABLE;
	//d3dPresent.MultiSampleQuality = 2;
	d3dPresent.Windowed = false;
	d3dPresent.BackBufferWidth = SCR_WIDTH;
	d3dPresent.BackBufferHeight = SCR_HEIGHT;
	d3dPresent.BackBufferFormat = D3DFMT_A8R8G8B8;
	d3dPresent.EnableAutoDepthStencil  = TRUE;
	d3dPresent.AutoDepthStencilFormat  = D3DFMT_D16;
	d3dPresent.FullScreen_RefreshRateInHz = D3D_PRESENTATION_RATE;
	d3dPresent.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
	//d3dPresent.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
	if(d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)d3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dPresent, &d3dDevice);
	else d3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dPresent, &d3dDevice);
	d3dDevice->SetVertexShader(NULL);
	d3dDevice->SetFVF(D3DFVF_TLVERTEX);
	d3dDevice->CreateVertexBuffer(sizeof(TLVERTEX) * 4, NULL, D3DFVF_TLVERTEX, D3DPOOL_MANAGED, &vertexBuffer, NULL);
    d3dDevice->SetStreamSource(0, vertexBuffer, 0, sizeof(TLVERTEX));
	d3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
	d3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	d3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
	d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
	d3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	d3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
	d3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);

	D3DXMatrixOrthoLH(&matOrtho, SCR_WIDTH, SCR_HEIGHT, 1.0f, 10.0f);
	D3DXMatrixIdentity(&matIdentity);
	d3dDevice->SetTransform(D3DTS_PROJECTION, &matOrtho);
	d3dDevice->SetTransform(D3DTS_WORLD, &matIdentity);
	d3dDevice->SetTransform(D3DTS_VIEW, &matIdentity);

	
	//Setup vertices
	TLVERTEX* vertices = NULL;
    vertexBuffer->Lock(0, 4 * sizeof(TLVERTEX), (VOID**)&vertices, 0);
    
    vertices[0].color = 0xffffffff;
    vertices[0].x = 0.0f;
    vertices[0].y = 0.0f;
    vertices[0].z = 1.0f;
    vertices[0].u = 0.0f;
    vertices[0].v = 0.0f;

    vertices[1].color = 0xffffffff;
    vertices[1].x = 1.0f;
    vertices[1].y = 0.0f;
    vertices[1].z = 1.0f;
    vertices[1].u = 1.0f;
    vertices[1].v = 0.0f;

    vertices[2].color = 0xffffffff;
    vertices[2].x = 1.0f;
    vertices[2].y = -1.0f;
    vertices[2].z = 1.0f;
    vertices[2].u = 1.0f;
    vertices[2].v = 1.0f;

    vertices[3].color = 0xffffffff;
    vertices[3].x = 0.0f;
    vertices[3].y = -1.0f;
    vertices[3].z = 1.0f;
    vertices[3].u = 0.0f;
    vertices[3].v = 1.0f;

    vertexBuffer->Unlock();
}
	
void CloseD3D()
{
	if(vertexBuffer) vertexBuffer->Release();
	if(d3dDevice) d3dDevice->Release();
	if(d3d) d3d->Release();
}
	
void ClearBuffer(){d3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);}
void Present(){d3dDevice->Present(NULL, NULL, NULL, NULL);}
void BeginDrawing(){d3dDevice->BeginScene();}
void EndDrawing(){d3dDevice->EndScene ();}

ID3DXFont* CreateD3DFont(char* fontname, int size)
{
	ID3DXFont* font=NULL;
	D3DXCreateFont(d3dDevice,size,0,FW_NORMAL,1,false,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,ANTIALIASED_QUALITY,DEFAULT_PITCH|FF_DONTCARE,fontname,&font);
	return font;
}

void DrawText(char* text, int x, int y, int width, int height, ID3DXFont* font, int color = 0xFFFFFFFF)
{
	RECT fontrect = {x,y,x+width,y+height};
	font->DrawText(NULL,text,-1,&fontrect,DT_LEFT|DT_NOCLIP,color);
}

//Texture Class
class Texture
{
private:
	
	char* Filename;
	IDirect3DTexture9* d3dTexture;
	int width;
	int height;

public:
	
	//Constructor:
	//Load the image into a IDirect3DTexture9 structure and extract its attributes
	Texture(){}

	Texture(char* fname){Filename = fname;}

	void Init(char* fname)
	{
		D3DSURFACE_DESC surfaceDesc;
		D3DXIMAGE_INFO SrcInfo;
	    D3DCOLOR colorkey = 0xFFFF00FF;
		Filename = fname;
		D3DXCreateTextureFromFileEx(d3dDevice, Filename, 0, 0, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_DEFAULT, colorkey, &SrcInfo, NULL, &d3dTexture);
		d3dTexture->GetLevelDesc(0, &surfaceDesc);
		width = surfaceDesc.Width;
		height = surfaceDesc.Height;
	}

	void Init()
	{
		D3DSURFACE_DESC surfaceDesc;
		D3DXIMAGE_INFO SrcInfo;
	    D3DCOLOR colorkey = 0xFFFF00FF;
		D3DXCreateTextureFromFileEx(d3dDevice, Filename, 0, 0, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_DEFAULT, colorkey, &SrcInfo, NULL, &d3dTexture);
		d3dTexture->GetLevelDesc(0, &surfaceDesc);
		width = surfaceDesc.Width;
		height = surfaceDesc.Height;
	}

	//Blit the image with rotation
	//NOTE: This must be called between calls to BeginDrawing() and EndDrawing()
	void Blit(int x, int y, float rotate = 0, D3DCOLOR vertexColor = 0xFFFFFFFF)
	{
		//D3DCOLOR vertexColor = 0xFFFFFFFF;
		RECT rDest;
		rDest.left = x;
		rDest.right = x + width;
		rDest.top = y;
		rDest.bottom = y + height;
		
		TLVERTEX* vertices;

		//Lock the vertex buffer
		vertexBuffer->Lock(0, 0, (void **)&vertices, NULL);
				
		//Set up the vertices
		vertices[0].color = vertexColor;
		vertices[0].x = (float) rDest.left - 0.5f;
		vertices[0].y = (float) rDest.top - 0.5f;
		vertices[0].z = 0.0f;
		vertices[0].rhw = 1.0f;
		vertices[0].u = 0.0f;
		vertices[0].v = 0.0f;

		vertices[1].color = vertexColor;
		vertices[1].x = (float) rDest.right - 0.5f;
		vertices[1].y = (float) rDest.top - 0.5f;
		vertices[1].z = 0.0f;
		vertices[1].rhw = 1.0f;
		vertices[1].u = 1.0f;
		vertices[1].v = 0.0f;

		vertices[2].color = vertexColor;
		vertices[2].x = (float) rDest.right - 0.5f;
		vertices[2].y = (float) rDest.bottom - 0.5f;
		vertices[2].z = 0.0f;
		vertices[2].rhw = 1.0f;
		vertices[2].u = 1.0f;
		vertices[2].v = 1.0f;

		vertices[3].color = vertexColor;
		vertices[3].x = (float) rDest.left - 0.5f;
		vertices[3].y = (float) rDest.bottom - 0.5f;
		vertices[3].z = 0.0f;
		vertices[3].rhw = 1.0f;
		vertices[3].u = 0.0f;
		vertices[3].v = 1.0f;

		//If the image is rotated apply the rotation
		if(rotate != 0)
		{
			RECT rOrigin;
			float centerX, centerY;
			
			centerX = (float)(rDest.left + rDest.right) / 2;
			centerY = (float)(rDest.top + rDest.bottom) / 2;
      
			rOrigin.top = rDest.top - (int)(centerY);
			rOrigin.bottom = rDest.bottom - (int)(centerY);
			rOrigin.left = rDest.left - (int)(centerX);
			rOrigin.right = rDest.right - (int)(centerX);

			//Rotate vertices about the origin
			vertices[0].x = rOrigin.left * cosf(rotate) - rOrigin.top * sinf(rotate);
			vertices[0].y = rOrigin.left * sinf(rotate) + rOrigin.top * cosf(rotate);
			vertices[1].x = rOrigin.right * cosf(rotate) - rOrigin.top * sinf(rotate);
			vertices[1].y = rOrigin.right * sinf(rotate) + rOrigin.top * cosf(rotate);
		    vertices[2].x = rOrigin.right * cosf(rotate) - rOrigin.bottom * sinf(rotate);
			vertices[2].y = rOrigin.right * sinf(rotate) + rOrigin.bottom * cosf(rotate);
		    vertices[3].x = rOrigin.left * cosf(rotate) - rOrigin.bottom * sinf(rotate);
			vertices[3].y = rOrigin.left * sinf(rotate) + rOrigin.bottom * cosf(rotate);

			//Translate vertices to proper position
			vertices[0].x += centerX;
			vertices[0].y += centerY;
			vertices[1].x += centerX;
			vertices[1].y += centerY;
			vertices[2].x += centerX;
			vertices[2].y += centerY;
			vertices[3].x += centerX;
			vertices[3].y += centerY;
		}

		//Unlock the vertex buffer
		vertexBuffer->Unlock();

		//Set the texture to the quad and draw to the screen
		d3dDevice->SetTexture(0, d3dTexture);
		d3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
	}

	void Blit2(int x, int y)
	{

		D3DXMATRIX matTranslation;
		D3DXMATRIX matScaling;
		D3DXMATRIX matTransform;
		RECT rDest;
		
		x-=(int)0.5*SCR_WIDTH;
		y=0-y;
		y+=(int)0.5*SCR_HEIGHT;

		rDest.left = x;
		rDest.right = x + width;
		rDest.top = y;
		rDest.bottom = y + height;
		
		D3DXMatrixScaling(&matScaling, (float)(rDest.right - rDest.left), (float)(rDest.bottom - rDest.top), 1.0);
		D3DXMatrixTranslation(&matTranslation, (float)x, (float)y, 1.0);

		matTransform = matScaling * matTranslation;
		d3dDevice->SetTransform(D3DTS_WORLD, &matTransform);
		
		//Set the texture to the quad and draw to the screen
		d3dDevice->SetTexture(0, d3dTexture);
		d3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
	}
	
	void Delete()
	{
		d3dTexture->Release();
	}

	int getWidth(){return width;}
	int getHeight(){return height;}
};
 
main.h

Code:
#include <fmod.h>
#include <time.h>
#include "flags.h"
#include "timer.h"

#define DIRRIGHT 0
#define DIRLEFT 1
#define DIRUP 2
#define DIRDOWN 3

#define JUMPKEY DIK_X
#define RUNKEY	DIK_Z

int worldX=0, worldY=0;
double bkgX=0, bkgY=0;

//bool dead=false;

//Background textures
Texture sky;
Texture clouds1;
Texture clouds2;
Texture bushLarge;
Texture bush;

//Platform textues
Texture platform1;
Texture platform2;

//Ground textures
Texture groundTopCenter;

//Pipe textures
Texture pipeTop;
Texture pipe64;

//Fireball textures
Texture fireball1;
Texture fireball2;
Texture fireball3;
Texture fireball4;

//Goomba textures
Texture goombaFrame1;
Texture goombaFrame2;
Texture goombaSquished;
Texture goombaDying;

//Turtle textures
Texture turtleRight1;				
Texture turtleRight2;
Texture turtleLeft1;
Texture turtleLeft2;

//Turtle shell textures
Texture turtleShell1;

//Mushroom textures
Texture mushroom;

//Pirhana plant textures
Texture pirhanaLeftUpOpen;
Texture pirhanaRightUpOpen;
Texture pirhanaLeftDownOpen;
Texture pirhanaRightDownOpen;

//Brick textures
Texture brick1;
Texture brick2;
Texture brick3;
Texture brick4;
Texture brick5;
Texture brickPiece;

//Question block textures
Texture qblock1;			
Texture qblock2;
Texture qblock3;
Texture qblock4;
Texture qblockInactive;

//Coin textures
Texture coin1;
Texture coin2;
Texture coin3;
Texture coin4;
Texture coin5;
Texture coin6;

//Mario textures
Texture marioStandingRight;
Texture marioStandingLeft;
Texture marioJumpingRight;
Texture marioJumpingLeft;
Texture marioWalkingRight;
Texture marioWalkingLeft;
Texture marioRunningRight;
Texture marioRunningLeft;
Texture marioDuckingRight;
Texture marioDuckingLeft;

Texture marioSmallStandingRight;
Texture marioSmallWalkingRight;
Texture marioSmallStandingLeft;
Texture marioSmallWalkingLeft;
Texture marioSmallJumpingRight;
Texture marioSmallJumpingLeft;

#include "object.h"

vector<Object*> objectVector;
Object* mario;

#include "backgroundObject.h"
#include "mario.h"
#include "ground.h"
#include "platform.h"
#include "goomba.h"
#include "brick.h"
#include "qblock.h"
#include "pipe.h"



void loadScene()
{
	objectVector.push_back(new BackgroundObject(&bushLarge, 10, 768-64-256, 512, 256, false));	
	objectVector.push_back(new BackgroundObject(&clouds1, 400, 100, 128, 92, true));
	objectVector.push_back(new Platform(&platform2, 700, 768-64-320, 224, 320));
	objectVector.push_back(new Platform(&platform1, 600, 768-64-192, 224, 192));
	objectVector.push_back(new Ground(0,768-64,100,1,GRASS));
	objectVector.push_back(new Brick(1000, 500, 64, 64));
	objectVector.push_back(new QBlock(1064, 500, 64, 64, COINTIMED));
	objectVector.push_back(new Brick(1128, 500, 64, 64));
	objectVector.push_back(new Goomba(700, 768-64-64-200, 64, 64, true));
	objectVector.push_back(new Goomba(700, 768-64-64, 64, 64,  true));
	objectVector.push_back(new Goomba(1000, 300-64, 64, 64, false));
	objectVector.push_back(new Mario(10, -500, 56, 108));
	objectVector.push_back(new Pipe(1656,768-64-128,0));
	objectVector.push_back(new Pipe(1400,768-64-256,2,WARP,objectVector[objectVector.size()-1]));
	objectVector.push_back(new Pipe(1528,768-64-192,1));
	
	for(int i=0; i<objectVector.size(); i++)
		if(objectVector[i]->type==MARIO){ mario=objectVector[i]; break; }
}

void InitTextures()
{
	sky.Init("gfx//sky.png");
	clouds1.Init("gfx2//1cloud.dds");
	clouds2.Init("gfx//2clouds.png");

	platform1.Init("gfx2//platform1.png");
	platform2.Init("gfx2//platform2.png");

	groundTopCenter.Init("gfx2//groundTopCenter.png");

	bushLarge.Init("gfx2//bushLarge.dds");
	bush.Init("gfx//bush.png");

	pipeTop.Init("gfx2//pipeTop.png");
	pipe64.Init("gfx2//pipe64.png");
	
	fireball1.Init("gfx//fireball1.png");
	fireball2.Init("gfx//fireball2.png");
	fireball3.Init("gfx//fireball3.png");
	fireball4.Init("gfx//fireball4.png");

	goombaFrame1.Init("gfx2//goomba1.dds");
	goombaFrame2.Init("gfx2//goomba2.dds");
	goombaSquished.Init("gfx//goombaSquished.png");
	goombaDying.Init("gfx//goombaDying.png");

	turtleRight1.Init("gfx//turtleRight1.png");
	turtleRight2.Init("gfx//turtleRight2.png");
	turtleLeft1.Init("gfx//turtleLeft1.png");
	turtleLeft2.Init("gfx//turtleLeft2.png");

	turtleShell1.Init("gfx//turtleShell1.png");

	mushroom.Init("gfx//mushroom.png");

	pirhanaLeftUpOpen.Init("gfx//piranaPlantLeftUpOpen.png");
	pirhanaRightUpOpen.Init("gfx//piranaPlantRightUpOpen.png");
	pirhanaLeftDownOpen.Init("gfx//piranaPlantLeftDownOpen.png");
	pirhanaRightDownOpen.Init("gfx//piranaPlantRightDownOpen.png");

	qblock1.Init("gfx2//qblock1.png");
	qblock2.Init("gfx2//qblock2.png");
	qblock3.Init("gfx2//qblock3.png");
	qblock4.Init("gfx2//qblock4.png");	

	qblockInactive.Init("gfx//qblockInactive.png");

	brick1.Init("gfx2//brick1.dds");
	brick2.Init("gfx2//brick2.dds");
	brick3.Init("gfx2//brick3.dds");
	brick4.Init("gfx2//brick4.dds");
	brick5.Init("gfx2//brick5.dds");
	brickPiece.Init("gfx//brickPiece.png");

	coin1.Init("gfx2//coin1.png");
	coin2.Init("gfx2//coin2.png");
	coin3.Init("gfx2//coin3.png");
	coin4.Init("gfx2//coin4.png");
	coin5.Init("gfx2//coin5.png");
	coin6.Init("gfx2//coin6.png");

	marioStandingRight.	Init("gfx2//marioStandingRight.dds");
	marioStandingLeft.	Init("gfx2//marioStandingLeft.dds");
	marioJumpingRight.	Init("gfx2//marioJumpingRight.dds");
	marioJumpingLeft.	Init("gfx2//marioJumpingLeft.dds");
	marioWalkingRight.	Init("gfx2//marioWalkingRight.dds");
	marioWalkingLeft.	Init("gfx2//marioWalkingLeft.dds");
	marioRunningRight.	Init("gfx2//marioRunningRight.dds");
	marioRunningLeft.	Init("gfx2//marioRunningLeft.dds");
	marioDuckingRight.	Init("gfx2//marioDuckingRight.dds");
	marioDuckingLeft.	Init("gfx2//marioDuckingLeft.dds");

	marioSmallStandingRight.Init("gfx2//marioSmallStandingRight.dds");
	marioSmallWalkingRight.	Init("gfx2//marioSmallWalkingRight.dds");
	marioSmallStandingLeft.	Init("gfx2//marioSmallStandingLeft.dds");
	marioSmallWalkingLeft.	Init("gfx2//marioSmallWalkingLeft.dds");
	marioSmallJumpingRight.	Init("gfx2//marioSmallJumpingRight.dds");
	marioSmallJumpingLeft.	Init("gfx2//marioSmallJumpingLeft.dds");
}
 
object.h

Code:
//Abstract base class for all in-game objects

#define BACKGROUND 0
#define MARIO 1
#define GROUND 2
#define PLATFORM 3
#define GOOMBA 4
#define BRICK 5
#define QBLOCK 6
#define PIPE 7

class Object
{
public:

	int type, x, y, width, height;
	double xvel, yvel;
	bool bumped;

	const virtual RECT getRect()=0;
	const virtual void draw()=0;
	const virtual bool onScreen()=0;
	virtual bool collision(RECT, int)=0;
	virtual int process()=0;
	virtual void setFlag(int flag)=0;	//Flags for inter-object communication
};


flags.h

Code:
#define MARIOHITBYGOOMBA	1

#define BIGMARIOHITBRICK	2
#define SMALLMARIOHITBRICK	3

#define BIGMARIOHITQBLOCK	4
#define SMALLMARIOHITQBLOCK	5

#define MARIOTRYINGTOWARP	6

#define LOCKMARIO		7
#define UNLOCKMARIO		8

#define HIDEMARIO		9
#define SHOWMARIO		10

#define GOOMBA_BUMPED		11
 
backgroundObject.h

Code:
class BackgroundObject : public Object
{
private:

	Texture* texture;
	bool parallax;

public:

	BackgroundObject(Texture* t, int xa, int ya, int w, int h, bool plax)
	{
		x=xa; y=ya; width=w; height=h;
		texture = t;
		parallax = plax;
		type = BACKGROUND;
	}

	const bool onScreen()
	{
		if(x+width>bkgX && x<bkgX+SCR_WIDTH)return true;
		return false;
	}

	const RECT getRect()
	{
		RECT rect;
		rect.left = x;
		rect.top = y;
		rect.right = x+width;
		rect.bottom = y+height;
		return rect;
	}

	const void draw()
	{
		if(parallax)texture->Blit(x-bkgX, y-bkgY);
		else texture->Blit(x-worldX, y-worldY);
	}

	bool collision(RECT rect, int direction)
	{
		return false;
	}

	int process()
	{
		return 0;
	}

	void setFlag(int flag)
	{
	}
};


brick.h

Code:
class Brick : public Object
{

private:
	
	struct BrickPiece
	{
		int x, y;
		double xvel, yvel;
	};

	BrickPiece piece1, piece2, piece3, piece4;
	int timer, frame, temp;
	bool hit;

public:

	Brick(int xa, int ya, int w, int h)
	{
		x=xa; y=ya; width=w; height=h;

		piece1.x=x+16; piece2.x=x+16; piece3.x=x+16; piece4.x=x+16;
		piece1.y=y+16; piece2.y=y+16; piece3.y=y+16; piece4.y=y+16;

		piece1.xvel=5; piece2.xvel=5; piece3.xvel=-5; piece4.xvel=-5;
		piece1.yvel=-5; piece2.yvel=-15; piece3.yvel=-5; piece4.yvel=-15;

		timer=0; frame=0;
		hit=false;
		type=BRICK;
	}

	const bool onScreen()
	{
		if(x+width>worldX && x<worldX+SCR_WIDTH)return true;
		return false;
	}

	const RECT getRect()
	{
		RECT rect;
		rect.left=x;
		rect.top=y;
		rect.right=x+width;
		rect.bottom=y+height-4;
		return rect;
	}

	const void draw()
	{
		if(!hit)
		{
			if(frame==0)brick1.Blit(x-worldX,y-worldY);
			if(frame==1)brick2.Blit(x-worldX,y-worldY);
			if(frame==2)brick3.Blit(x-worldX,y-worldY);
			if(frame==3)brick4.Blit(x-worldX,y-worldY);
			if(frame==4)brick5.Blit(x-worldX,y-worldY);
		}

		else
		{
			brickPiece.Blit(piece1.x-worldX, piece1.y-worldY);
			brickPiece.Blit(piece2.x-worldX, piece2.y-worldY);
			brickPiece.Blit(piece3.x-worldX, piece3.y-worldY);
			brickPiece.Blit(piece4.x-worldX, piece4.y-worldY);
		}
	}

	bool collision(RECT objBB, int dir)
	{
		if(hit)return false;

		RECT thisBB;
		thisBB.left = x;
		thisBB.top = y;
		thisBB.right = x+width;
		thisBB.bottom = y+height;
		
		if(dir==DIRRIGHT)
			if(objBB.right > thisBB.left && objBB.right < thisBB.right)
				if(objBB.top < thisBB.bottom && objBB.bottom > thisBB.top+4)
					return true;
		
		if(dir==DIRLEFT)
			if(objBB.left < thisBB.right && objBB.left > thisBB.left)
				if(objBB.top < thisBB.bottom && objBB.bottom > thisBB.top+4)
					return true;

		if(dir==DIRDOWN)
			if(objBB.right > thisBB.left+4 && objBB.left < thisBB.right-4 && objBB.bottom > thisBB.top && objBB.top < thisBB.bottom-4)
				return true;


		if(dir==DIRUP)
			if(objBB.top < thisBB.bottom+1 && objBB.top > thisBB.top && objBB.right > thisBB.left+4 && objBB.left < thisBB.right-4)
				return true;
			
		return false;
	}

	int process()
	{
		timer++;
		if(timer>4){frame++; timer=0;}
		if(frame>4) frame=0;

		if(hit)
		{
			if(piece1.yvel<25) piece1.yvel+=.8;
			if(piece2.yvel<25) piece2.yvel+=.8;
			if(piece3.yvel<25) piece3.yvel+=.8;
			if(piece4.yvel<25) piece4.yvel+=.8;

			piece1.x+=piece1.xvel;
			piece1.y+=piece1.yvel;

			piece2.x+=piece2.xvel;
			piece2.y+=piece2.yvel;
			
			piece3.x+=piece3.xvel;
			piece3.y+=piece3.yvel;
			
			piece4.x+=piece4.xvel;
			piece4.y+=piece4.yvel;

			if(piece1.y>1024 && piece2.y>1024 && piece3.y>1024 && piece4.y>1024)
			{
				for(int i=0; i<objectVector.size(); i++)
				if(objectVector[i]==this)break;

				delete this;
				objectVector.erase(objectVector.begin()+i);
			}
		}

		if(bumped)
		{
			y+=yvel;
			yvel++;
			if(y==temp) bumped=false;
			//Check to see if anything is standing on it and kill it
		}

		return 0;
	}

	void setFlag(int flag)
	{
		if(flag==BIGMARIOHITBRICK)
		{
			hit=true;

			//Check to see if a any goombas were affected
			for(int i=0; i<objectVector.size(); i++)
			{
				if(objectVector[i]->type==GOOMBA)
				{
					if(objectVector[i]->x + objectVector[i]->width > x && 
					   objectVector[i]->x < (x+width) && 
					   objectVector[i]->y +	objectVector[i]->height < y+16 &&
					   objectVector[i]->y +	objectVector[i]->height > y-16)
					{
						objectVector[i]->setFlag(GOOMBA_BUMPED);
					}
				}
			}
		}
		if(flag==SMALLMARIOHITBRICK && !bumped)
		{
			bumped=true; 
			yvel=-7; 
			temp=y;

			//Check to see if a any goombas were affected
			for(int i=0; i<objectVector.size(); i++)
			{
				if(objectVector[i]->type==GOOMBA)
				{
					if(objectVector[i]->x + objectVector[i]->width > x && 
					   objectVector[i]->x < (x+width) && 
					   objectVector[i]->y +	objectVector[i]->height < y+16 &&
					   objectVector[i]->y +	objectVector[i]->height > y-16)
					{
						objectVector[i]->setFlag(GOOMBA_BUMPED);
					}
				}
			}
		}
	}
	
};
 
goomba.h

Code:
class Goomba : public Object
{
private:

	int direction;
	int timer;
	int squishedTimer;
	bool frame;
	bool squished;
	bool deleteFlag;
	bool shellHit;
	bool shellDying;
	bool canFall;

public:
	
	Goomba(int xa, int ya, int w, int h, bool f)
	{
		x=xa; y=ya; width=w; height=h;
		type=GOOMBA;

		direction=DIRLEFT;
		
		timer=0;
		squishedTimer=0;
		frame=0;
		
		squished=false;
		shellHit=false;
		shellDying=false;
		canFall=f;
		
		xvel=3;
		yvel=0;
	}
	
	const bool onScreen()
	{
		if(x+width>worldX && x<worldX+SCR_WIDTH)return true;
		return false;
	}

	bool collision(RECT objBB, int dir)
	{
		//Nothing can collide with a dying goomba
		if(shellDying || squished)return false;

		RECT thisBB = getRect();
		
		if(dir==DIRRIGHT)
		{
			if(objBB.right-4 > thisBB.left && objBB.right < thisBB.right)
			{
				if(objBB.top < thisBB.bottom && objBB.bottom > thisBB.top)
				{
					return true;
				}
			}
		}

		if(dir==DIRLEFT)
		{
			if(objBB.left+4 < thisBB.right && objBB.left > thisBB.left)
			{
				if(objBB.top < thisBB.bottom && objBB.bottom > thisBB.top)
				{
					return true;
				}
			}
		}

		if(dir==DIRDOWN)
		{
			if(objBB.right-4 > thisBB.left && objBB.left+4 < thisBB.right && objBB.bottom > thisBB.top && objBB.bottom < thisBB.top+12)
			{
				if(!squished)
				{
					y+=32;
					squished=true;
				}
				return true; 
			}
		}

		if(dir==DIRUP)
		{
			if(objBB.top < thisBB.bottom && objBB.top > thisBB.top && objBB.right-4 > thisBB.left && objBB.left+4 < thisBB.right) return true;
		}

		return false;
	}

	const void draw()
	{
		if(squished)goombaSquished.Blit(x-worldX,y-worldY);
		else if(shellDying) goombaDying.Blit(x-worldX, y-worldY);
		else if(frame)goombaFrame1.Blit(x-worldX,y-worldY);
		else if(!frame)goombaFrame2.Blit(x-worldX, y-worldY);
	}

	const RECT getRect()
	{
		RECT rect;
		rect.left=x;
		rect.top=y;
		rect.right=x+width;
		rect.bottom=y+height-4;
		return rect;
	}

	int process()
	{

		if(yvel<25) yvel+=.8;


		//---------------------------------------------------------------------------------
		//							TIMING
		//---------------------------------------------------------------------------------
		
		timer++;
		if(squished && squishedTimer<50)squishedTimer++;

		if(timer>15)
		{
			timer=0; 
			if(frame)frame=0; 
			else frame=1;
		}

		//---------------------------------------------------------------------------------
		//							MOVE RIGHT
		//---------------------------------------------------------------------------------

		if(direction==DIRRIGHT && !squished)
		{

			bool move;
			bool fall;

			//Move one pixel at at time
			for(int j=0; j< xvel; j++)
			{
				move = true;
				fall = true;

				//Check for collision with every other in game object
				for(int k=0; k<objectVector.size(); k++)
				{
					if(objectVector[k]->type==GOOMBA)
						if(objectVector[k]->collision(getRect(), DIRRIGHT))
						{
							move = false;
							direction = DIRLEFT;
						}

					if(objectVector[k]->type==BRICK || objectVector[k]->type==QBLOCK || objectVector[k]->type==PIPE)
						if(objectVector[k]->collision(getRect(), DIRRIGHT))
						{
							move = false;
							direction = DIRLEFT;
						}

					if(objectVector[k]->type==MARIO)
						if(objectVector[k]->collision(getRect(), DIRRIGHT))
						{
							objectVector[k]->setFlag(MARIOHITBYGOOMBA);
							move = false;
							direction = DIRLEFT;
						}

					if(!canFall)
					{
						RECT rect;
						rect = getRect();
						rect.left+=width-8;
						rect.right+=width-8;

						if(objectVector[k]->collision(rect, DIRDOWN)) 
						{
							fall=false;
						}
					}
				}

				//Moving right
				if(move)
				{
					if(!canFall && fall)direction = DIRLEFT;
					else x++;
				}
			}
		}

		
		//---------------------------------------------------------------------------------
		//							MOVE LEFT
		//---------------------------------------------------------------------------------
		
		else if(direction==DIRLEFT && !squished)
		{

			bool move;
			bool fall;

			//Move one pixel at at time
			for(int j=0; j < xvel; j++)
			{
				move = true;
				fall = true;

				//Check for collision with every other in game object
				for(int k=0; k<objectVector.size(); k++)
				{
					if(objectVector[k]->type==GOOMBA)
						if(objectVector[k]->collision(getRect(), DIRLEFT))
						{
							move = false;
							direction=DIRRIGHT;
						}

					if(objectVector[k]->type==BRICK || objectVector[k]->type==QBLOCK || objectVector[k]->type==PIPE)
						if(objectVector[k]->collision(getRect(), DIRLEFT))
						{
							move = false;
							direction=DIRRIGHT;
						}

					if(objectVector[k]->type==MARIO)
						if(objectVector[k]->collision(getRect(), DIRLEFT))
						{
							objectVector[k]->setFlag(MARIOHITBYGOOMBA);
							move = false;
							direction=DIRRIGHT;
						}

					if(!canFall)
					{
						RECT rect;
						rect = getRect();
						rect.left-=width-8;
						rect.right-=width-8;

						if(objectVector[k]->collision(rect, DIRDOWN)) 
						{
							fall=false;
						}
					}

					if(x==0)
					{
						move=false;
						direction=DIRRIGHT;
					}
				}

				//Moving left
				if(move)
				{
					if(!canFall && fall)direction = DIRRIGHT;
					x--;
				}
			}
		}

				
		//---------------------------------------------------------------------------------
		//							MOVE DOWN
		//---------------------------------------------------------------------------------

		if(yvel > 0)
		{
			bool move;

			//Move one pixel at a time
			for(int j=0; j < yvel; j++)
			{
				move = true;

				//Check for collision with every other in game object
				if(!shellDying)
				{
				for(int k=0; k<objectVector.size(); k++)
				{
					//Hit ground, platform
					if(objectVector[k]->type==GROUND ||
					   objectVector[k]->type==PLATFORM ||
					   objectVector[k]->type==BRICK ||
					   objectVector[k]->type==QBLOCK)
						if(objectVector[k]->collision(getRect(), DIRDOWN))
						{
							move = false;
							yvel = 0;
						}

					//Hit goomba
					if(objectVector[k]->type==GOOMBA && objectVector[k]!=this)
						if(objectVector[k]->collision(getRect(), DIRDOWN))
						{
							move = false;
							yvel = -10;
						}

				}
				}
				
				
				//If no collision occured, then move down
				if(move)
				{
					y++;
				}
			}
		}

		//---------------------------------------------------------------------------------
		//							MOVE UP
		//---------------------------------------------------------------------------------

		else if(yvel < 0)
		{
			bool move;

			//Move one pixel at a time
			for(int j=0; j > yvel; j--)
			{
				move = true;

				//Check for collision with every other in game object
				for(int k=0; k<objectVector.size(); k++)
				{
					//Hit platform
					if(objectVector[k]->type==PLATFORM)
						if(objectVector[k]->collision(getRect(), DIRUP))
						{
							move = false;
							yvel = 0;
						}

					//Hit brick
					if(objectVector[k]->type==BRICK)
						if(objectVector[k]->collision(getRect(), DIRUP))
						{
							move = false;
							yvel = 0;
						}
				}
								
				//If no collision occured, then move down
				if(move)
				{
					y--;
				}
			}
		}

		//---------------------------------------------------------------------------------
		//								ERASE
		//---------------------------------------------------------------------------------

		if(squishedTimer==50)
		{
			for(int i=0; i<objectVector.size(); i++)
				if(objectVector[i]==this)break;

			delete this;
			objectVector.erase(objectVector.begin()+i);
		}

		return 0;
	}

	void setFlag(int flag)
	{
		if(flag==GOOMBA_BUMPED)
		{
			yvel=-15;
			shellDying = true;
		}
	}
};

ground.h

Code:
#define GRASS 0

class Ground : public Object
{
public:

	int numw, numh, gtype;

	Ground(int xa, int ya, int w, int h, int gt)
	{
		x=xa; y=ya;
		numw=w; numh=h;
		gtype=gt;
		type=GROUND;
	}

	bool collision(RECT objRECT, int direction)
	{
		RECT groundRECT;
		groundRECT.left=x;
		groundRECT.top=y;
		groundRECT.right=x+(numw*64);
		groundRECT.bottom=y+(numh*64);
		
		if(direction == DIRDOWN)
		{
			if(objRECT.right >= groundRECT.left && 
			objRECT.left <= groundRECT.right &&
			objRECT.bottom >= groundRECT.top &&
			objRECT.top <= groundRECT.bottom) 
			return true;

			else return false;
		}

		else return false;

	}

	const RECT getRect()
	{
		RECT rect;
		rect.left = x;
		rect.top = y;
		rect.right = x+width;
		rect.bottom = y+height;
		return rect;
	}

	const bool onScreen()
	{
		return true;
	}

	const void draw()
	{
		for(int x2=0; x2<numw; x2++)
		{
			groundTopCenter.Blit(x+(x2*64)-worldX,y-worldY);
		}
	}

	int process()
	{
		return 0;
	}

	void setFlag(int flag)
	{
	}
};
 
mario.h

Code:
#define SMALL 0
#define LARGE 1
#define FIRE 2

class Mario : public Object
{
private:

	int timer;
	int frame;
	int mtype;
	
	bool facing;
	bool inAir;
	bool jumping;
	bool ducking;

	bool valid;
	bool hitFlag;

	bool locked;
	bool hidden;

public:

	Mario(int xa, int ya, int w, int h)
	{
		x=xa; y=ya; width=w; height=h;

		xvel=0;
		yvel=0;
				
		timer=0;
		frame=0;

		locked=false;
		
		mtype=LARGE;
		
		facing=true;
		inAir=true;
		jumping=false;
		ducking=false;
		valid=true;
		hitFlag=false;
		
		type=MARIO;
	}

	const void draw()
	{
		if(!hidden)
		{
		if(mtype==LARGE)
		{
			if(jumping && facing && !ducking) marioJumpingRight.Blit(x,y);
			else if(jumping && !facing && !ducking) marioJumpingLeft.Blit(x,y);

			else if(!jumping && inAir && facing && !ducking) marioStandingRight.Blit(x,y);
			else if(!jumping && inAir && !facing && !ducking) marioStandingLeft.Blit(x,y);
	
			else if(ducking && facing) marioDuckingRight.Blit(x,y);
			else if(ducking && !facing) marioDuckingLeft.Blit(x,y);

			else if(!jumping && !inAir && !ducking)
			{
				if(facing)
				{
					if(xvel==0) marioStandingRight.Blit(x,y);
				
					else
					{
						if(frame==0){marioWalkingRight.Blit(x,y);}
						else if(frame==1){marioRunningRight.Blit(x,y);}
						else if(frame==2){marioStandingRight.Blit(x,y);}
					}
				}

				else
				{
					if(xvel==0) marioStandingLeft.Blit(x,y);
				
					else
					{
						if(frame==0){marioWalkingLeft.Blit(x,y);}
						else if(frame==1){marioRunningLeft.Blit(x,y);}
						else if(frame==2){marioStandingLeft.Blit(x,y);}
					}
				}
			}
		}


		else if(mtype==SMALL)
		{
			if(jumping && facing) marioSmallJumpingRight.Blit(x,y);
			else if(jumping && !facing) marioSmallJumpingLeft.Blit(x,y);

			if(!jumping && inAir && facing) marioSmallStandingRight.Blit(x,y);
			else if(!jumping && inAir && !facing) marioSmallStandingLeft.Blit(x,y);
	
			else if(!jumping && !inAir)
			{
				if(facing)
				{
					if(xvel==0) marioSmallStandingRight.Blit(x,y+2);
				
					else
					{
						if(frame==0){marioSmallWalkingRight.Blit(x,y);}
						else if(frame==1){marioSmallStandingRight.Blit(x,y+2);}
					}
				}

				else
				{
					if(xvel==0) marioSmallStandingLeft.Blit(x,y+2);
				
					else
					{
						if(frame==0){marioSmallWalkingLeft.Blit(x,y);}
						else if(frame==1){marioSmallStandingLeft.Blit(x,y+2);}
					}
				}
			}
		}
		}
	}

	const RECT getRect()
	{
		RECT rect;
		rect.left = x+worldX;
		rect.top = y+worldY;
		rect.right = x+width+worldX;
		rect.bottom = y+height+worldY;
		return rect;
	}

	bool collision(RECT objBB, int dir)
	{
		RECT thisBB = getRect();

		
		if(dir==DIRRIGHT)
		{
			if(objBB.right > thisBB.left && objBB.right < thisBB.right)
			{
				if(objBB.top < thisBB.bottom && objBB.bottom > thisBB.top+4)
				{
					return true;
				}
			}
		}

		if(dir==DIRLEFT)
		{
			if(objBB.left < thisBB.right && objBB.left > thisBB.left)
			{
				if(objBB.top < thisBB.bottom && objBB.bottom > thisBB.top+4)
				{
					return true;
				}
			}
		}

		if(dir==DIRDOWN)
		{
			if(objBB.right > thisBB.left+4 && objBB.left < thisBB.right-4 && objBB.bottom > thisBB.top && objBB.top < thisBB.bottom-4)
			{
				return true;
			}
		}

		if(dir==DIRUP)
		{
			if(objBB.top < thisBB.bottom+1 && objBB.top > thisBB.top && objBB.right > thisBB.left+4 && objBB.left < thisBB.right-4)
			{
				return true;
			}
		}

		return false;
	}


	int process()
	{
		if(locked)return 0;
		//==================================\\
		//				INPUT				\\
		//==================================\\

		if(keys[RIGHT] && !ducking)
		{
			facing=true;
			if(keys[RUNKEY] && xvel<12)xvel+=.25;
			else if(xvel < 6) xvel+=.25;
			else if(xvel >= 6) xvel-=.25;
		}
		else if(xvel > 0) xvel-=.25;


		if(keys[LEFT] && !ducking)
		{
			facing=false;
			if(keys[RUNKEY] && xvel > -12)xvel-=.25;
			else if(xvel > -6) xvel-=.25;
			else if(xvel <= -6) xvel+=.25;
		}	
		else if(xvel < 0) xvel+=.25;

		if(keys[DOWN])
		{
			for(int k=0; k<objectVector.size(); k++)
			{
				if(objectVector[k]->type==PIPE)
					if(objectVector[k]->collision(getRect(), DIRDOWN))
					{
						objectVector[k]->setFlag(MARIOTRYINGTOWARP);
						break;
					}
			}

			if(!ducking && mtype==LARGE)
			{
				y+=40;
				height-=40;
				ducking=true;
			}
		}

		if(!keys[DOWN] && ducking) 
		{
			y-=40;
			height+=40;
			ducking=false;
		}
		

		if(keys[JUMPKEY] && !inAir)
		{
			inAir=true; 
			jumping=true; 
			if(keys[RUNKEY])yvel=-25;
			else yvel=-20;
		}

		//==================================\\
		//				TIMING				\\
		//==================================\\

		timer++;
		if(xvel >= -6 && xvel <= 6 && timer > 4)
		{
			timer=0; 
			frame++; 
			if(mtype==LARGE && frame>2) frame=0;
			if(mtype==SMALL && frame>1) frame=0;
		}

		if((xvel < -6 || xvel > 6) && timer > 2)
		{
			timer=0; 
			frame++; 
			if(mtype==LARGE && frame>2)	frame=0;
			if(mtype==SMALL && frame>1) frame=0; 
		}


		//Apply gravity
		if(yvel<25) yvel+=.8;



		//==================================\\
		//			MOVE RIGHT				\\
		//==================================\\
		
		if(xvel > 0)
		{
			bool move;

			//Move one pixel at at time
			for(int j=0; j< xvel; j++)
			{
				move = true;

				//Check for collision with every other in game object
				for(int k=0; k<objectVector.size(); k++)
				{
					if(objectVector[k]->type==GOOMBA)
						if(objectVector[k]->collision(getRect(), DIRRIGHT))
						{
							setFlag(MARIOHITBYGOOMBA);
							move = false;
							xvel = 0;
						}

					if(objectVector[k]->type==BRICK || 
					   objectVector[k]->type==QBLOCK ||
					   objectVector[k]->type==PIPE)
						if(objectVector[k]->collision(getRect(), DIRRIGHT))
						{
							move = false;
							xvel = 0;
						}
				}

				//Moving right
				if(move)
				{
					if(x<500) x++;
					else{worldX+=1; bkgX+=.35;}
				}
			}
		}



		//==================================\\
		//			MOVE LEFT				\\
		//==================================\\

		else if(xvel < 0)
		{
			bool move;

			//Move one pixel at at time
			for(int j=0; j > xvel; j--)
			{
				move = true;

				//Check for collision with every other in game object
				for(int k=0; k<objectVector.size(); k++)
				{
					if(objectVector[k]->type==GOOMBA)
						if(objectVector[k]->collision(getRect(), DIRLEFT)) 
						{
							setFlag(MARIOHITBYGOOMBA);
							move = false;
							xvel = 0;
						}

					if(objectVector[k]->type==BRICK ||
					   objectVector[k]->type==QBLOCK ||
					   objectVector[k]->type==PIPE)
						if(objectVector[k]->collision(getRect(), DIRLEFT))
						{
							move = false;
							xvel = 0;
						}
				}

				
				//Move left
				if(move && xvel < 0) 
				{
					if(worldX > 0){worldX-=1; bkgX-=.35;}
					else if(worldX <= 0) if(x > 0) x--;
					else xvel=0;
				}
			}
		}



		//--------------------------------------\\
		//				MOVE DOWN				\\				
		//--------------------------------------\\

		if(yvel > 0)
		{
			bool move;

			//Move one pixel at a time
			for(int j=0; j < yvel; j++)
			{
				move = true;

				//Check for collision with every other in game object
				for(int k=0; k<objectVector.size(); k++)
				{
					//Hit ground
					if(objectVector[k]->type==GROUND	|| 
					   objectVector[k]->type==PIPE		||
					   objectVector[k]->type==PLATFORM	||
					   objectVector[k]->type==BRICK		||
					   objectVector[k]->type==QBLOCK
					   )
						if(objectVector[k]->collision(getRect(), DIRDOWN))
						{
							move = false;
							yvel = 0;
							inAir = false;
							jumping = false;
						}

					//Hit goomba
					if(objectVector[k]->type==GOOMBA)
						if(objectVector[k]->collision(getRect(), DIRDOWN))
						{
							move = false;
							if(keys[RUNKEY])yvel = -20;
							else yvel = -10;
							inAir = false;
							jumping = true;
						}
				}
				
				
				//If no collision occured, then move down
				if(move)
				{
					inAir = true;
					y++;
				}
			}
		}



		//----------------------------------\\
		//				MOVE UP				\\
		//----------------------------------\\		
		
		else if(yvel < 0)
		{
			bool move;

			//Move one pixel at a time
			for(int j=0; j > yvel; j--)
			{
				move = true;

				//Check for collision with every other in game object
				for(int k=0; k<objectVector.size(); k++)
				{
					if(objectVector[k]->type==BRICK)
						if(objectVector[k]->collision(getRect(), DIRUP))
						{

							if(mtype==LARGE)objectVector[k]->setFlag(BIGMARIOHITBRICK);
							if(mtype==SMALL)objectVector[k]->setFlag(SMALLMARIOHITBRICK);
							move = false;
							inAir = true;
							yvel = 1;
						}

					if(objectVector[k]->type==QBLOCK)
						if(objectVector[k]->collision(getRect(), DIRUP))
						{
							if(mtype==LARGE)objectVector[k]->setFlag(BIGMARIOHITQBLOCK);
							if(mtype==SMALL)objectVector[k]->setFlag(SMALLMARIOHITQBLOCK);
							move = false;
							inAir = true;
							yvel = 1;
						}
				}

				//If no collision occured, then move up
				if(move)
				{
					inAir = true;
					y--;
				}
			}
		}

		return 0;
	}



	void setFlag(int flag)
	{
		if(flag==MARIOHITBYGOOMBA)
		{
			if(mtype==LARGE)
			{
				mtype=SMALL;
				height=64;
			}
			
			/*
			else if(mtype==SMALL)
			{
				dead=true;
			}
			*/
		}

		if(flag==LOCKMARIO)locked=true;
		if(flag==UNLOCKMARIO)locked=false;
		if(flag==HIDEMARIO)hidden=true;
		if(flag==SHOWMARIO)hidden=false;
	}



	//Unused
	const bool onScreen()
	{
		return true;
	}

	
};
 
pipe.h

Code:
#define PLAIN 0
#define WARP 1
#define FIREPLANT 2
#define PLANT 3

class Pipe : public Object
{

private:

	int segments;
	int ptype;
	bool warping;
	int marioWarpOffsetX;
	int marioWarpOffsetY;
	int marioWarpDirection;
	Object* warpTarget;

public:

	Pipe(int xa, int ya, int segs, int t=PLAIN, Object* target=0)//, int w, int h)
	{
		x=xa; y=ya; segments=segs;
		width=128;
		height=128+64*segs;
		ptype=t;
		type=PIPE;

		if(ptype==WARP)
		{
			warpTarget=target;
		}
	}

	const bool onScreen()
	{
		if(x+width>worldX && x<worldX+SCR_WIDTH)return true;
		return false;
	}

	const RECT getRect()
	{
		RECT rect;
		rect.left=x;
		rect.top=y;
		rect.right=x+width;
		rect.bottom=y+height-4;
		return rect;
	}

	const void draw()
	{
		pipeTop.Blit(x-worldX,y-worldY);
		for(int i=2; i<segments+2; i++)
			pipe64.Blit(x-worldX,y+(64*i)-worldY);
	}

	bool collision(RECT objBB, int dir)
	{
		RECT thisBB;
		thisBB.left = x;
		thisBB.top = y;
		thisBB.right = x+width;
		thisBB.bottom = y+height;
		
		if(dir==DIRRIGHT)
			if(objBB.right > thisBB.left && objBB.right < thisBB.right)
				if(objBB.top < thisBB.bottom && objBB.bottom > thisBB.top+4)
					return true;
		
		if(dir==DIRLEFT)
			if(objBB.left < thisBB.right && objBB.left > thisBB.left)
				if(objBB.top < thisBB.bottom && objBB.bottom > thisBB.top+4)
					return true;

		if(dir==DIRDOWN)
			if(objBB.right > thisBB.left+4 && objBB.left < thisBB.right-4 && objBB.bottom > thisBB.top && objBB.top < thisBB.bottom-4)
				return true;


		if(dir==DIRUP)
			if(objBB.top < thisBB.bottom+1 && objBB.top > thisBB.top && objBB.right > thisBB.left+4 && objBB.left < thisBB.right-4)
				return true;
			
		return false;
	}

	int process()
	{
		if(warping)
		{
			if(marioWarpOffsetY < mario->height/2 && marioWarpDirection==DIRDOWN)
			{
				mario->y+=2;
				marioWarpOffsetY++;
			}

			else if(marioWarpOffsetY==mario->height/2 && marioWarpDirection==DIRDOWN)
			{
				mario->setFlag(HIDEMARIO);
				mario->y=warpTarget->y;

				if(worldX < warpTarget->x-512+50){worldX+=10; bkgX+=3;}
				else if(worldX > warpTarget->x-512+64){worldX-=10; bkgX-=3;}
				else{worldX=warpTarget->x-512+56; marioWarpDirection=DIRUP; mario->setFlag(SHOWMARIO);}
			}

			else if(marioWarpOffsetY > 0 && marioWarpDirection==DIRUP)
			{
				mario->y-=2;
				marioWarpOffsetY--;
				if(marioWarpOffsetY<=0)
				{
					warping=false;
					mario->setFlag(UNLOCKMARIO);
				}
			}
		}

		return 0;
	}

	void setFlag(int flag)
	{
		if(flag==MARIOTRYINGTOWARP && ptype==WARP)
		{
			worldX=x-512+50;
			mario->setFlag(LOCKMARIO);
			warping=true;
			marioWarpOffsetY=0;
			marioWarpOffsetX=0;
			marioWarpDirection=DIRDOWN;
		}
	}
};


platfrom.h

Code:
class Platform : public Object
{
public:

	Texture* texture;			//Texture file
	int x, y, width, height;	//Coordinates and dimensions
	RECT rect;					//Bounding rect

	Platform(Texture* t, int xa, int ya, int w, int h) : 
	texture(t), x(xa), y(ya), width(w), height(h)
	{
		type=PLATFORM;
	}
	
	const bool onScreen()
	{
		if(x+width>worldX && x<worldX+SCR_WIDTH)return true;
		return false;
	}

	bool collision(RECT objBB, int dir)
	{
		RECT thisBB;
		thisBB.left = x;
		thisBB.top = y;
		thisBB.right = x+width;
		thisBB.bottom = y+height;
		
		if(dir==DIRDOWN)
		{
			if(objBB.right-4 > thisBB.left && objBB.left+4 < thisBB.right-40 && objBB.bottom > thisBB.top && objBB.bottom < thisBB.top+2)return true;
		}

		return false;
	}

	const void draw()
	{
		texture->Blit(x-worldX,y-worldY);
	}

	const RECT getRect()
	{
		return rect;
	}

	//Unused
	int process()
	{
		return 0;
	}

	void setFlag(int flag)
	{
	}
};
 
qblock.h

Code:
#define ITEM		0
#define COIN		1
#define COINTIMED	2
#define STAR		3

class QBlock : public Object
{

private:

	class Coin
	{
	public:

		int coinY;
		int coinX;
		int coinYVel;
		int coinFrame;
		int coinTimer;
		int coinTimer2;

		Coin(int x, int y, int yvel)
		{
			coinX = x;
			coinY = y;
			coinYVel = yvel;

			coinFrame = 0;
			coinTimer = 0;
			coinTimer2 = 0;
		}
	};

	int timer, frame, temp;
	int coinTimer;
	bool active;
	int itype;

	//For coin blocks
	bool doCoin;
	vector<Coin*> coinVector;
	
	

public:

	QBlock(int xa, int ya, int w, int h, int t)
	{
		x=xa; y=ya; width=w; height=h;
		timer=0; frame=0;
		itype=t;
		bumped=false;
		active=true;

		doCoin=false;
		coinTimer=0;
		type=QBLOCK;
	}

	const bool onScreen()
	{
		if(x+width>worldX && x<worldX+SCR_WIDTH)return true;
		return false;
	}

	const RECT getRect()
	{
		RECT rect;
		rect.left=x;
		rect.top=y;
		rect.right=x+width;
		rect.bottom=y+height-4;
		return rect;
	}

	const void draw()
	{
		if(doCoin)
		{
			for(int i=0; i<coinVector.size(); i++)
			{
				if(coinVector[i]->coinFrame==0)coin1.Blit(coinVector[i]->coinX-worldX,coinVector[i]->coinY-worldY);
				if(coinVector[i]->coinFrame==1)coin2.Blit(coinVector[i]->coinX-worldX,coinVector[i]->coinY-worldY);
				if(coinVector[i]->coinFrame==2)coin3.Blit(coinVector[i]->coinX-worldX,coinVector[i]->coinY-worldY);
				if(coinVector[i]->coinFrame==3)coin4.Blit(coinVector[i]->coinX-worldX,coinVector[i]->coinY-worldY);
				if(coinVector[i]->coinFrame==4)coin5.Blit(coinVector[i]->coinX-worldX,coinVector[i]->coinY-worldY);
				if(coinVector[i]->coinFrame==5)coin6.Blit(coinVector[i]->coinX-worldX,coinVector[i]->coinY-worldY);
			}
		}

		if(active)
		{
			if(frame==0)qblock1.Blit(x-worldX,y-worldY);
			if(frame==1)qblock2.Blit(x-worldX,y-worldY);
			if(frame==2)qblock3.Blit(x-worldX,y-worldY);
			if(frame==3)qblock4.Blit(x-worldX,y-worldY);
		}

		else qblockInactive.Blit(x-worldX,y-worldY);

		
	}

	bool collision(RECT objBB, int dir)
	{

		RECT thisBB;
		thisBB.left = x;
		thisBB.top = y;
		thisBB.right = x+width;
		thisBB.bottom = y+height;
		
		if(dir==DIRRIGHT)
			if(objBB.right > thisBB.left && objBB.right < thisBB.right)
				if(objBB.top < thisBB.bottom && objBB.bottom > thisBB.top+4)
					return true;
		
		if(dir==DIRLEFT)
			if(objBB.left < thisBB.right && objBB.left > thisBB.left)
				if(objBB.top < thisBB.bottom && objBB.bottom > thisBB.top+4)
					return true;

		if(dir==DIRDOWN)
			if(objBB.right > thisBB.left+4 && objBB.left < thisBB.right-4 && objBB.bottom > thisBB.top && objBB.top < thisBB.bottom-32)
				return true;


		if(dir==DIRUP)
			if(objBB.top < thisBB.bottom+1 && objBB.top > thisBB.top && objBB.right > thisBB.left+4 && objBB.left < thisBB.right-4)
				return true;
			
		return false;
	}

	int process()
	{
		timer++;
		if(timer>4){frame++; timer=0;}
		if(frame>3) frame=0;

		if(itype==COINTIMED && coinTimer>0)
		{
			coinTimer++;
			if(coinTimer>200)active=false;
		}


		if(bumped)
		{
			if(mario->y<y+height)mario->y+=yvel+4; //Prevents Mario's head from getting stuck in the falling block
			y+=yvel;
			yvel+=1;
			if(y>=temp){y=temp; bumped=false;}
		}

		if(doCoin)
		{
			for(int i=0; i<coinVector.size(); i++)
			{
				coinVector[i]->coinTimer++;
				coinVector[i]->coinTimer2++;
				if(coinVector[i]->coinTimer>1)
				{
					coinVector[i]->coinFrame++; 
					coinVector[i]->coinTimer=0;
				}

				if(coinVector[i]->coinFrame>5)coinVector[i]->coinFrame=0;

				coinVector[i]->coinY+=coinVector[i]->coinYVel;
				if(coinVector[i]->coinYVel<20)coinVector[i]->coinYVel++;

				if(coinVector[i]->coinTimer2>40)
				{
					delete coinVector[i];
					coinVector.erase(coinVector.begin()+i);
					if(coinVector.size()==0)doCoin=false;
				}
			}
		}

		return 0;
	}

	void setFlag(int flag)
	{
		if((flag==BIGMARIOHITQBLOCK || flag==SMALLMARIOHITQBLOCK) && active && !bumped)
		{
			bumped=true; 
			//active=false;
			yvel=-7; 
			temp=y;


			if(itype==COIN || itype==COINTIMED)
			{
				doCoin=true;
				coinVector.push_back(new Coin(x,y,-20));
				if(coinTimer==0)coinTimer=1;
			}
			
			//Find out if anything was on it and kill it
			for(int i=0; i<objectVector.size(); i++)
			{
				if(objectVector[i]->type==GOOMBA)
				{
					if(objectVector[i]->x + objectVector[i]->width > x && 
					   objectVector[i]->x < (x+width) && 
					   objectVector[i]->y +	objectVector[i]->height < y+16 &&
					   objectVector[i]->y +	objectVector[i]->height > y-16)
					{
						objectVector[i]->setFlag(GOOMBA_BUMPED);
					}
				}
			}
		}

	}
};
 
I'd be happy to review the code and make comments, but it's a little awkward picking through these tiny "CODE" windows for so many different files. Maybe it would be easiest if you'd post a ZIP of the project someplace and let us download it.

Initially:

  • Your message loop has a few problems. Your application exits only when the user presses ESC, not when they close the window -- you just keep looping. You'll want to exit the loop in response to a quit message.
  • Another problem is that you're going to handle one message, then go do your game loop. What if Windows has sent you a bunch of messages? This seems a little iffy.
  • Your Main.H file is declaring variables, which is wrong. This is going to lead to unexpected results unless you fix it.
  • MyD3DGame.h is a header. You have lots of code in it, which isn't right. You should move those function implementations to their own C++ file.
  • I don't think the "const" declrations on the members of your Object class are correct. "const virtual void draw()=0;" doesn't make much sense to me.
  • You've got lots of global variables. This is C++; you really should end up with very few and ideally none.
  • You're doing just about zero error checking.
  • You're not coding defensively at all. What if you accidentaly call Texture:Init() twice in a row, for instance? You'll silently leak a texture. You're doing a poor job of managing the filename in that class, too.
 
Thanks mike, I will post a visual studio project file shortly

mikeblas said:
Initially:
Your message loop has a few problems. Your application exits only when the user presses ESC, not when they close the window -- you just keep looping. You'll want to exit the loop in response to a quit message.

The application is full screen so there won't ever be a close window button. ctrl-alt-del, alt-tab, alt-esc, alt-f4 all still work, and will break the program. Ideally I want to either figure out how to disable those, or figure out how to come back from them successfully.

mikeblas said:
Another problem is that you're going to handle one message, then go do your game loop. What if Windows has sent you a bunch of messages? This seems a little iffy.

I hadn't thought about that, I use the same win32 base code for most of my programs, I'll have to change it now. So instead of checking to see if there is a message I should loop until their isn't?

mikeblas said:
Your Main.H file is declaring variables, which is wrong. This is going to lead to unexpected results unless you fix it.

You've got lots of global variables. This is C++; you really should end up with very few and ideally none.

To fix both of these I am thinking about putting each texture variable and its instantiation with the object that it belongs. For example, I will put all of the brick related textures as private members of the Brick class and then instantiate them in the constructor. What do you think?

*edit* nevermind, thats not a good idea, that will create a new instance of each texture for each object, which is unnecessary. I will just put all of the texture creation code in a function in main.cpp.

mikeblas said:
MyD3DGame.h is a header. You have lots of code in it, which isn't right. You should move those function implementations to their own C++ file.

Yeah, I know that and all of my object classes should be seperated into .h and .cpp files, I'm just not used to doing that. What is the reason to do that, because it seems to work the same either way?


mikeblas said:
I don't think the "const" declrations on the members of your Object class are correct. "const virtual void draw()=0;" doesn't make much sense to me.

Hmm... well it's not syntactically wrong because it will compile and run fine as is, and I don't think it is logically wrong either because the draw function is constant, nothing is changed in it... Can you be more specific?

mikeblas said:
[*]You're doing just about zero error checking.
[*]You're not coding defensively at all. What if you accidentaly call Texture:Init() twice in a row, for instance? You'll silently leak a texture. You're doing a poor job of managing the filename in that class, too.

Yeah, I have no error checking at all right now. I guess I don't focus on that much because I am the only person working on the project, I haven't had much experience working in groups. So, I know for a fact I won't call a Texture's init() twice, because I am the only one writing the code... but you are right I do need to add a lot of error checking.

What do you mean by "you're doing a poor job managing the filename..."? Do you mean I am not making sure it is a valid file before trying to use it? I should probably do that... :)
 
CodeX said:
The application is full screen so there won't ever be a close window button. ctrl-alt-del, alt-tab, alt-esc, alt-f4 all still work, and will break the program. Ideally I want to either figure out how to disable those, or figure out how to come back from them successfully.
What do you mean by "break"? I can't see how ALT+F4 would make your program terminate. The window can close, but that doesn't mean the application will exit. I think that if you start an instance of your game, press ALT+F4, then look at task manger, you'll still see your program running.

CodeX said:
What is the reason to do that, because it seems to work the same either way?
If code is in the header, you recompile it every

CodeX said:
Hmm... well it's not syntactically wrong because it will compile and run fine as is, and I don't think it is logically wrong either because the draw function is constant, nothing is changed in it... Can you be more specific?

Logically, it's nonsense. "const void" means nothing; you have nothing (void), so how could it be const? Or not? I think you meant to declare the function const, not the return vaue:

Code:
bool onScreen() const;
void draw() const;
// instead of
// const bool onScreen();
// const void draw();


CodeX said:
Yeah, I have no error checking at all right now. I guess I don't focus on that much because I am the only person working on the project, I haven't had much experience working in groups. So, I know for a fact I won't call a Texture's init() twice, because I am the only one writing the code... but you are right I do need to add a lot of error checking.
You really don't know that for a fact. Not to harsh your deal, but you can't be successful if you think you're infallible. Some day, maybe even on this project, you'll build something that is bigger than you can completely think of at one time. That certainly comes with working on a project with other devs, but it happens when you're working by yourself, too. You really can't remember everything and guarantee everything, and the sooner you learn to rely on the language and tools to help you with those guarantees and memories, the sooner you'll develop better habits.

As you're learning, checking errors and testing conditions is going to help you find problems faster. You're working on this code iteratively. You think it works great; the texture code must work just fine because you've been running it for weeks. What if you make some seemingly unrelated change that alters the way textures work? (You're about to do that, since you're thinking about making the class structure different.) How do you know the code still works?

Dumping something to the debugger output is very helpful for code that's getting developed the way you're going.

If you're so sure that you're not going to call Init() twice (or call the filename constructor, then call the filename Init()), then why not use assert to enforce that? If you accidentally do make the bad calls, then you'll end up firing the assert immediately, and you'll have no problem correcting your error quickly.


CodeX said:
What do you mean by "you're doing a poor job managing the filename..."? Do you mean I am not making sure it is a valid file before trying to use it? I
I can't even find that class again; I'm going cross-eyed scrolling through the post to scroll through the different individual files. When you can provide a buildable project, I'll be better able to comment about the class and file structures and find the filename code again.

What book or tutorial are you working through, BTW?
 
mikeblas said:
What do you mean by "break"? I can't see how ALT+F4 would make your program terminate. The window can close, but that doesn't mean the application will exit. I think that if you start an instance of your game, press ALT+F4, then look at task manger, you'll still see your program running.

Well, when you try to switch focus back to the game, the screen stays black and does not reinitialize D3D. I need to learn how to either make it so nothing can steal focus from my app, or to make it respond properly when that happens.

mikeblas said:
If code is in the header, you recompile it every time


Oh okay, thanks for clearing that up.


mikeblas said:
Logically, it's nonsense. "const void" means nothing; you have nothing (void), so how could it be const? Or not? I think you meant to declare the function const, not the return vaue:

Code:
bool onScreen() const;
void draw() const;
// instead of
// const bool onScreen();
// const void draw();

That makes more sense, I will change it, thanks.

mikeblas said:
You really don't know that for a fact. Not to harsh your deal, but you can't be successful if you think you're infallible. Some day, maybe even on this project, you'll build something that is bigger than you can completely think of at one time. That certainly comes with working on a project with other devs, but it happens when you're working by yourself, too. You really can't remember everything and guarantee everything, and the sooner you learn to rely on the language and tools to help you with those guarantees and memories, the sooner you'll develop better habits.

As you're learning, checking errors and testing conditions is going to help you find problems faster. You're working on this code iteratively. You think it works great; the texture code must work just fine because you've been running it for weeks. What if you make some seemingly unrelated change that alters the way textures work? (You're about to do that, since you're thinking about making the class structure different.) How do you know the code still works?

Dumping something to the debugger output is very helpful for code that's getting developed the way you're going.

If you're so sure that you're not going to call Init() twice (or call the filename constructor, then call the filename Init()), then why not use assert to enforce that? If you accidentally do make the bad calls, then you'll end up firing the assert immediately, and you'll have no problem correcting your error quickly.

Yeah, you're right, I see how working on a very large project might get confusing, and how making seemingly unrelated changes might break something. I will add error checking, thanks again.

mikeblas said:
What book or tutorial are you working through, BTW?

I am not working out of any book or tutorial at the moment. The knowledge I have of win32 came from the MSDN, and my dinput and d3d code in my MyD3DGame.h file came from a tutorial on gamedev.net that I can't seem to find right now, I did heavily change it though.

I am still looking for a host for the project file. If you want the graphics files too (which are needed to run the program, but not compile it) it will be about 5mb.
 
CodeX said:
I am still looking for a host for the project file. If you want the graphics files too (which are needed to run the program, but not compile it) it will be about 5mb.

I forgot about the magic of compression :rolleyes:

It's about 800kb here
 
Okay, so here's more code review notes. It's really way easier going through this with the project. The CODE tags are fine for most of the trivial progrmas that people around here post, but it just breaks down for more than a hundred lines or more than two files.

Use #include "" instead of #include <> for your own files. "" searches the current directory; <> doesn't.

There's two problems with your headers; they have code, and they have data.

The code is not a real problem because the linker will notice the duplicate code and get rid of it. This isn't broken, but it's a very bad practice. Some linkers aren't as smart as the VC++ linker, and might not do that removal. Some linkers might even error.

You have two kinds of code in your headers: global functions and member functions. Member functions delcared the way you've done it are interpreted as inline declarations. The compiler will figure out if they should be inlined, or emit out of line declarations. (It usually does both and lets the linker sort it out in case some other compiland someplace takes the address of the function.) Many of your functions obviously shouldn't be inlined, so you can speed compilation a tiny bit by making the functions out of line (that is, in a CPP file).

That compilation win isn't worth noticing, and isn't the primary reason to factor the code in that way. Ease of maintenance is.

The functions in MyD3DGame.h are only ever referenced in one other place; from Main.CPP. They should be moved to that CPP file and marked static.

Putting data in your headers is much worse. You're lucky this code works -- the only reason it does is because you've only got one *.CPP file. As soon as you add another *.CPP file that includes My3DGame.h, for example, you're going to get errors about the data in that header being redefined. You should learn to use the "extern" keyword.

The problem with filename in CTexture is that you keep the pointer passed. What if that pointer goes out of scope?

Code:
Texture ThisWillBreak()
{
   char szPath[1024];
   GetDefaultDirectory(szPath);
   strcat(szPath, "\\TheFileName.texture");
   return Texture(szPath);
}
The returned texture points, now, at invalid memory.

Those are the big things, I Guess. There's a few code style issues, but I don't think they're so consequential.
 
Awesome, thanks Mike. I will go over this tomorrow and tell you how it goes. :)

*edit* Just noticed something, your first comment about using include "" instead of include <>, I already do. The only one that is wrong is #include <MyD3DGame.h> but that is because on my machine I have that file in the visual studio include folder, not local. I should have mentioned that
 
Sure. Let me know if you have any other Q's.

I'll try to get it building (I don't have the DX9 SDK installed) but I have the discs from MSDN I'm sure. Then, I can tell you what's going with your main loop.
 
Back
Top