Yeah pretty much. Even if its only say 5% of your users cannot ever run your game, it means massive hassle in trying to manage orders/refunds/support, it means 5% less sales at face value on a commerical product, but when you get enough bad reviews of: "game wouldn't even start" it could hurt a lot more too. Thats not even to say its going to be 5%, could be more.
I have narrowed it down to not a dependency on VC++, .NET or Direct X runtimes, not a bad download, and not anti virus, so im stumped.
Here is the latest package if that is relevant:
http://rapidshare.com/files/173872301/RPG_Engine.zip
source files:
main.cpp:
#include "DarkGDK.h"
#include "Player.h"
#include "Cell.h"
#include "multisync.h"
#include <stdio.h>
#include <string>
const int MAP_SIZE = 512;
const int CELL_SIZE = 200;
const int MAX_PLAYERS = 4;
int maxCells = 16;
Cell map[MAP_SIZE][MAP_SIZE];
Player player[MAX_PLAYERS];
void loadMap(char* fileName, int size);
void DarkGDK ( void )
{
const unsigned char MESSAGE_ID_ASSIGN_SELF_ID = 0;
const unsigned char MESSAGE_ID_PLAYER_INFO = 1;
const int SEND_GAP = 80; // miliseconds to wait before sending another packet, to avoid network congestion
int nextObject = 0;
int keypressCount = 0;
int keypressDelay = 10;
int playerId = 0;
int intResult = 0;
int lastSent = 0;
int self = 0;
unsigned short msgSize = 0;
unsigned char nextBtye = 0;
bool result = false;
bool server = true;
dbSyncOn();
dbSyncRate(60);
dbRandomize(dbTimer());
dbAutoCamOff();
dbHideMouse();
dbInk(dbRGB(255,255,255),dbRGB(0,0,0));
dbBackdropOn();
dbColorBackdrop(dbRGB(0,0,0));
dbFogOn();
dbFogColor(dbRGB(0,0,0));
dbFogDistance((maxCells*CELL_SIZE)-CELL_SIZE*8);
dbSetCameraRange(1,(maxCells*CELL_SIZE));
dbSetAmbientLight(30);
dbMakeLight(1);
dbMakeLight(2);
dbSetPointLight(1,0,0,0);
dbSetSpotLight(2,45,90);
dbSetLightRange (1, maxCells*CELL_SIZE);
dbSetLightRange (2, maxCells*CELL_SIZE);
dbColorLight(2,RGB(252,216,141));
dbColorLight(1,RGB(236,182,100));
dbHideLight(0);
result = NetConnect("127.0.0.1");
if (result==false)
{
result = NetHost(MAX_PLAYERS-1);
if (result==false)
{
while (dbReturnKey()!=1)
{
dbText(0,0,"Could not find or host a server");
dbSync();
}
} else {
server=true;
}
} else {
server=false;
}
// textures
dbLoadImage("media/wall2.jpg",1);
dbLoadImage("media/ground.jpg",2);
dbLoadImage("media/wall.jpg",3);
loadMap("media/dungeon.map",MAP_SIZE);
// walls
for (int i=10001; i<=maxCells*maxCells+10000; i++)
{
dbMakeObjectCube(i,CELL_SIZE);
dbTextureObject(i,1);
}
// floor
for (int i=20001; i<=maxCells*maxCells+20000; i++)
{
dbMakeObjectPlain(i,CELL_SIZE,CELL_SIZE);
dbRotateObject(i,90,0,0);
dbTextureObject(i,2);
}
// ceiling
for (int i=30001; i<=maxCells*maxCells+30000; i++)
{
dbMakeObjectPlain(i,CELL_SIZE,CELL_SIZE);
dbRotateObject(i,270,0,0);
dbTextureObject(i,3);
}
for (int i=40001; i<=MAX_PLAYERS+40000; i++)
{
dbLoadObject("media/cone.x",i);
dbScaleObject(i,6000,6000,6000);
dbColorObject(i,dbRGB(255,255,255));
dbXRotateObject(i,90);
dbFixObjectPivot(i);
}
// Search startpoint
for (int z=0; z<MAP_SIZE; z++)
{
for (int x=0; x<MAP_SIZE; x++)
{
if (map[x][z].cellType()==79)
{
// position player objects to player locations
for (int i=0; i<MAX_PLAYERS; i++)
{
player[i].setPosition(x,0,z);
player[i].setDirection(360);
}
}
if (map[x][z].cellType()==85)
{
// downstairs
}
}
}
while ( LoopGDK ( ) )
{
dbText(0,0,dbStr(self));
dbText(20,0,"PlayerId");
if (dbUpKey()==1 && keypressCount==0)
{
// if facing north
if (player[self].direction()==360)
{
// if the cell in front is not solid
if (map[player[self].positionX()][player[self].positionZ()+1].isSolid()==false)
{
player[self].moveNorth();
}
}
// if facing east
if (player[self].direction()==90)
{
// if the cell in front is not solid
if (map[player[self].positionX()+1][player[self].positionZ()].isSolid()==false)
{
player[self].moveEast();
}
}
// if facing south
if (player[self].direction()==180)
{
// if the cell in front is not solid
if (map[player[self].positionX()][player[self].positionZ()-1].isSolid()==false)
{
player[self].moveSouth();
}
}
// if facing west
if (player[self].direction()==270)
{
// if the cell in front is not solid
if (map[player[self].positionX()-1][player[self].positionZ()].isSolid()==false)
{
player[self].moveWest();
}
}
keypressCount=keypressDelay;
}
if (dbDownKey()==1 && keypressCount==0)
{
// if facing north
if (player[self].direction()==360)
{
// if the cell in front is not solid
if (map[player[self].positionX()][player[self].positionZ()-1].isSolid()==false)
{
player[self].moveSouth();
}
}
// if facing east
if (player[self].direction()==90)
{
// if the cell in front is not solid
if (map[player[self].positionX()-1][player[self].positionZ()].isSolid()==false)
{
player[self].moveWest();
}
}
// if facing south
if (player[self].direction()==180)
{
// if the cell in front is not solid
if (map[player[self].positionX()][player[self].positionZ()+1].isSolid()==false)
{
player[self].moveNorth();
}
}
// if facing west
if (player[self].direction()==270)
{
// if the cell in front is not solid
if (map[player[self].positionX()+1][player[self].positionZ()].isSolid()==false)
{
player[self].moveEast();
}
}
keypressCount=keypressDelay;
}
if (dbLeftKey()==1 && keypressCount==0)
{
player[self].setDirection(player[self].direction()-90);
keypressCount=keypressDelay;
}
if (dbRightKey()==1 && keypressCount==0)
{
player[self].setDirection(player[self].direction()+90);
keypressCount=keypressDelay;
}
if (keypressCount!=0) keypressCount=keypressCount-1;
dbPositionCamera(player[self].positionX()*CELL_SIZE,0,player[self].positionZ()*CELL_SIZE);
dbRotateCamera(0,player[self].direction(),0);
nextObject=0;
// displays the maxCells*maxCells area centered around the player
for (int z=(player[self].positionZ()-(maxCells/2)); z<(player[self].positionZ()+(maxCells/2)); z++)
{
for (int x=(player[self].positionX()-(maxCells/2)); x<(player[self].positionX()+(maxCells/2)); x++)
{
// don't allow it to search out of bounds
if (x<0) x=0;
if (x>MAP_SIZE) x=MAP_SIZE;
if (z<0) z=0;
if (z>MAP_SIZE) z=MAP_SIZE;
nextObject++;
// Wall
if (map[x][z].cellType()==35 || map[x][z].cellType()==83) {
dbShowObject(10000+nextObject);
dbPositionObject(10000+nextObject,x*CELL_SIZE,0.0,z*CELL_SIZE);
} else {
dbHideObject(10000+nextObject);
}
// Floor/Ceiling
if (map[x][z].cellType()==58 || map[x][z].cellType()==68 || map[x][z].cellType()==83 || map[x][z].cellType()==84) {
dbShowObject(20000+nextObject);
dbShowObject(30000+nextObject);
dbPositionObject(20000+nextObject,x*CELL_SIZE,(CELL_SIZE/2)*(-1),z*CELL_SIZE);
dbPositionObject(30000+nextObject,x*CELL_SIZE,(CELL_SIZE/2),z*CELL_SIZE);
} else {
dbHideObject(20000+nextObject);
dbHideObject(30000+nextObject);
}
}
}
if (server)
{
// allow new players to join
intResult = NetPlayerJoined();
if (intResult > 0)
{
NetPutInt(intResult);
NetPutByte(MESSAGE_ID_ASSIGN_SELF_ID);
NetSend(intResult);
}
// free up player number if player leaves
intResult = NetPlayerLeft();
if (intResult > 0)
{
}
// foward server's own player info to other players
if (lastSent+SEND_GAP<dbTimer())
{
for (int i=1; i<MAX_PLAYERS; i++)
{
if (NetPlayerConnected(i))
{
NetPutInt(self);
NetPutByte(MESSAGE_ID_PLAYER_INFO);
NetPutByte((player[self].direction())/90);
NetPutWord(player[self].positionX());
NetPutWord(player[self].positionZ());
NetSend(i);
}
}
lastSent=dbTimer();
}
}
// send own player info to server if you are a client
if (lastSent+SEND_GAP<dbTimer() && !server)
{
NetPutInt(self);
NetPutByte(MESSAGE_ID_PLAYER_INFO);
NetPutByte(player[self].direction()/90);
NetPutWord(player[self].positionX());
NetPutWord(player[self].positionZ());
NetSend(0);
lastSent=dbTimer();
}
// receive player info and forward it on if we are the server
while (NetGetMessage())
{
playerId = NetGetInt();
nextBtye = NetGetByte();
if (nextBtye == MESSAGE_ID_ASSIGN_SELF_ID) {
self = playerId;
}
if (nextBtye == MESSAGE_ID_PLAYER_INFO)
{
// Recieve player info and set it
player[playerId].setDirection(NetGetByte()*90); // player y angle
player[playerId].setPositionX(NetGetWord()); // player xPos
player[playerId].setPositionZ(NetGetWord()); // player zPos
// Forward all player info to the clients if we are the server (other than the client that originally sent this data)
if (server)
{
for (int i=1; i<MAX_PLAYERS; i++)
{
if (NetPlayerConnected(i) && i!=playerId)
{
NetPutInt(playerId);
NetPutByte(MESSAGE_ID_PLAYER_INFO);
NetPutByte(player[playerId].direction()/90);
NetPutWord(player[playerId].positionX());
NetPutWord(player[playerId].positionZ());
NetSend(i);
}
}
}
}
}
// position player objects to player locations
for (int i=0; i<MAX_PLAYERS; i++)
{
dbPositionObject(i+40001,player[i].positionX()*CELL_SIZE, -100 ,player[i].positionZ()*CELL_SIZE);
dbYRotateObject(i+40001,player[i].direction());
}
dbPositionLight(1,dbCameraPositionX(),dbCameraPositionY(),dbCameraPositionZ());
dbPositionLight(2,dbCameraPositionX(),dbCameraPositionY(),dbCameraPositionZ());
dbColorLight(1,dbRGB(200+int(dbRnd(50)-25),120,60));
dbRotateLight(2,dbCameraAngleX(),dbCameraAngleY(),dbCameraAngleZ());
if (server) dbText(0,20,dbStr(NetGetPlayerAmount()+1));
if (server) dbText(20,20,"Number of players connected");
dbSync();
}
// before quitting delete our objects
// walls
for (int i=10001; i<=maxCells*maxCells+10000; i++)
{
if(dbObjectExist(i)) dbDeleteObject(i);
}
// floor
for (int i=20001; i<=maxCells*maxCells+20000; i++)
{
if(dbObjectExist(i)) dbDeleteObject(i);
}
// ceiling
for (int i=30001; i<=maxCells*maxCells+30000; i++)
{
if(dbObjectExist(i)) dbDeleteObject(i);
}
// characters
for (int i=40001; i<=MAX_PLAYERS+40000; i++)
{
if(dbObjectExist(i)) dbDeleteObject(i);
}
// delete [] buffer;
return;
}
void loadMap(char* fileName, int size)
{
int tmp=0;
int tmp1=0;
tmp = dbFileExist(fileName);
dbOpenToRead(1, fileName);
for (int y=0; y<size; y++)
{
for (int x=0; x<size; x++)
{
tmp1=int(dbReadByte(tmp));
map[x][y].setCellType(tmp1);
}
}
dbCloseFile(1);
}
player.h
#ifndef _PLAYER_H_
#define _PLAYER_H_
class Player
{
private:
unsigned short xPos;
unsigned short yPos;
unsigned short zPos;
unsigned char theDirection;
public:
Player();
~Player();
unsigned short positionX();
unsigned short positionY();
unsigned short positionZ();
int direction();
void setPositionX(int x);
void setPositionY(int y);
void setPositionZ(int z);
void setPosition(int x, int y, int z);
void setDirection(int facing);
void turnLeft();
void turnRight();
void moveNorth();
void moveEast();
void moveSouth();
void moveWest();
};
#endif _PLAYER_H_
player.cpp
#include "Player.h"
Player::Player()
{
}
Player::~Player()
{
}
unsigned short Player::positionX()
{
return xPos;
}
unsigned short Player::positionY()
{
return yPos;
}
unsigned short Player::positionZ()
{
return zPos;
}
int Player::direction()
{
return theDirection*90;
}
void Player::setPositionX(int x)
{
xPos=x;
}
void Player::setPositionY(int y)
{
yPos=y;
}
void Player::setPositionZ(int z)
{
zPos=z;
}
void Player::setPosition(int x, int y, int z)
{
xPos=x;
yPos=y;
zPos=z;
}
void Player::setDirection(int facing)
{
// wraps the value of facing to something between 1 and 4 (N=1, E=2, S=3, W=4)
if (facing/90>4)
{
theDirection=(facing/90)-(int((facing/90)/4)*4);
} else if (facing/90<0) {
theDirection=((facing/90)*-1)-(int(((facing/90)*-1)/4)*4);
} else {
theDirection=int(facing/90);
}
if (theDirection==0) theDirection=4;
}
void Player::turnLeft()
{
theDirection--;
if (theDirection==0) theDirection=4;
}
void Player::turnRight()
{
theDirection++;
if (theDirection==5) theDirection=1;
}
void Player::moveNorth()
{
zPos++;
}
void Player::moveEast()
{
xPos++;
}
void Player::moveSouth()
{
zPos--;
}
void Player::moveWest()
{
xPos--;
}
cell.h
#ifndef _CELL_H_
#define _CELL_H_
class Cell
{
private:
bool solid;
int type;
public:
Cell(int cellType);
Cell();
~Cell();
bool isSolid();
int cellType();
void setCellType(int cellType);
};
#endif _CELL_H_
cell.cpp
#include "Cell.h"
Cell::Cell(int cellType)
{
type=cellType;
if (type==35 || type==83){
solid=true;
} else {
solid=false;
}
}
Cell::Cell()
{
type=46;
}
Cell::~Cell()
{
}
bool Cell::isSolid()
{
return solid;
}
int Cell::cellType()
{
return type;
}
void Cell::setCellType(int cellType)
{
type=cellType;
if (type==35 || type==83){
solid=true;
} else {
solid=false;
}
}
RPG Engine.vcproj
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="RPG Engine"
ProjectGUID="{C66E6B64-232C-4E08-A05C-3103DEF7C56F}"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
RuntimeLibrary="1"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
IgnoreDefaultLibraryNames="libcmtd, msvcrt, atls"
GenerateDebugInformation="true"
SubSystem="2"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
RuntimeLibrary="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
IgnoreDefaultLibraryNames="libcmtd, msvcrt, atls"
SubSystem="2"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="txt;cpp;h"n"
>
<File
RelativePath=".Cell.cpp"
>
</File>
<File
RelativePath=".Cell.h"
>
</File>
<File
RelativePath=".Main.cpp"
>
</File>
<File
RelativePath=".multisync.h"
>
</File>
<File
RelativePath=".Player.cpp"
>
</File>
<File
RelativePath=".Player.h"
>
</File>
<File
RelativePath=".ReadMe.txt"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>