Posted: 13th Dec 2003 22:57
This is C version of my Bouncing Lines demo, using IanM's DBPro interface - minus the music. If you want to compile it yourself, you'll need Visual Studio or VS .Net

This is the DBPro shell program, needed to run the demo :

+ Code Snippet
APPDLL
end

dot 0,0                 : ` Basic2D
load object "",1        : ` Basic3D
load bitmap "",1        : ` Bitmap
autocam off             : ` Camera
cls                     : ` Core
ftp connect "","",""    : ` FTP
close file 1            : ` File
load image "",1         : ` Image
hide mouse              : ` Input
delete terrain 1        : ` LODTerrain
delete light 1          : ` Light
delete matrix 1         : ` Matrix
delete memblock 1       : ` Memblock
free net game           : ` Multiplayer
delete music 1          : ` Music
delete particles 1      : ` Particle
show window             : ` Setup
delete sound 1          : ` Sound
sprite 1,0,0,1          : ` Sprite
disable systemkeys      : ` System
text 0,0,""             : ` Text


And this is the main C code. Its not very efficient (but neither was the original) :

+ Code Snippet
// MyDemo.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include "MyDemo.h"
#include "stdafx.h"
#undef EXPORT
#include <DBPro.hpp>

// For sprintf...
#include <cstdio>

using namespace DBPro;

#define MAXLINES   4*4
#define MAXDOTS    128
#define MUSIC      7
#define SCROLLTIME 14

typedef struct __lines {
   float x; 
   float y;
   float dx; 
   float dy; 
   int r; 
   int g; 
   int b; 
	} __lines;

typedef struct dots {
   float x;
   float y;
   float dy;
   float dx;
	} dots;

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

//
//	Note!
//
//		If this DLL is dynamically linked against the MFC
//		DLLs, any functions exported from this DLL which
//		call into MFC must have the AFX_MANAGE_STATE macro
//		added at the very beginning of the function.
//
//		For example:
//
//		extern "C" BOOL PASCAL EXPORT ExportedFunction()
//		{
//			AFX_MANAGE_STATE(AfxGetStaticModuleState());
//			// normal function body here
//		}
//
//		It is very important that this macro appear in each
//		function, prior to any calls into MFC.  This means that
//		it must appear as the first statement within the 
//		function, even before any object variable declarations
//		as their constructors may generate calls into the MFC
//		DLL.
//
//		Please see MFC Technical Notes 33 and 58 for additional
//		details.
//

// CMyDemoApp

BEGIN_MESSAGE_MAP(CMyDemoApp, CWinApp)
END_MESSAGE_MAP()


// CMyDemoApp construction

CMyDemoApp::CMyDemoApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}


// The one and only CMyDemoApp object

CMyDemoApp theApp;

EXPORT void AppDLL(void)
{
char mess[4096];
char temp[4096];
int screenWidth,screenHeight,bmSize;
struct __lines l[MAXLINES+1];
struct dots d[MAXDOTS+1];
register int x,y,dotColour,count,loopc,scrollT,index;
float angle,dir,sa;
char z;

	strcpy(mess,"This is my BouncingLines demo with music being played by my BASS interface.  Press a number between 1 and 7 to load and play a different MOD tune.  Press 0 to stop playing all music.  Dont forget to visit http://www.codingarea.co.uk for a great time......................");
	SyncOn();
	SyncRate(100);

	screenWidth=ScreenWidth();
	screenHeight=ScreenHeight();
	bmSize=screenWidth*3;
	
	//Add music later
	ZeroMemory(&d,sizeof(d));
	Randomize(Timer());
	for (x=1; x<=MAXLINES; x++)
	{
		l[x].x=(Rnd(screenWidth>>1))*1.0;
		l[x].y=(Rnd(screenHeight>>1))*1.0;
		l[x].dx=(Rnd(4)+1)*0.5;
		l[x].dy=(Rnd(4)+1)*0.5;
		l[x].r=Rnd(254)+1;
		l[x].g=Rnd(254)+1;
		l[x].b=Rnd(254)+1;
	}

	Cls(0);
	Text(0,0,"Please Wait - Setting up background");
	//Print("Please Wait");
	Sync();
	Sync();

	CreateBitmap(1,bmSize,bmSize);
	SetCurrentBitmap(1);
	for (x=0; x<=bmSize; x+=8)
	{
		for (y=0; y<=bmSize; y+=8)
		{
			Box(x,y,x+8,y+8,
				Rgb(Rnd(64),Rnd(64),Rnd(64)),
				Rgb(Rnd(64),Rnd(64),Rnd(64)),
				Rgb(Rnd(64),Rnd(64),Rnd(64)),
				Rgb(Rnd(64),Rnd(64),Rnd(64)));
			if (! ProcessMessages())
			{
			}
		}
	}
	
	GetImage(1,0,0,bmSize-1,bmSize-1,1);
	SetCurrentBitmap(0);
	DrawSpritesFirst();
	Sprite(1,screenWidth>>1,screenHeight>>1,1);
	OffsetSprite(1,bmSize>>1,bmSize>>1);

	angle=0.0;
	dir=0.5;
	sa=0.0;
	count=0;
	loopc=0;
	dotColour=Rgb(Rnd(256-32),Rnd(256-32),Rnd(256-32)+32);
	scrollT=SCROLLTIME;

	Cls(0);
	Sync();

	while (! ProcessMessages())
	{
	LPSTR one=NULL;

		one=Inkey(one);
/*	LPSTR one;

		one=Inkey(one);
		if (*(one)>='1' && *(one)<='7')
		{
		}
		else
		if (*(one)=='0')
		{
		}*/

		Sprite(1,(screenWidth>>1)+(256*Sin(sa)),
				(screenHeight>>1)+(256*Cos(sa)),
				1);
		RotateSprite(1,angle);
		sa=Wrapvalue(sa+1.0);
		angle=Wrapvalue(angle+dir);

		for (x=1; x<=MAXLINES; x++)
		{
			Ink(Rgb(l[x].r,l[x].g,l[x].b),0);
			if (x<MAXLINES)
			{
				Line(l[x].x,l[x].y,l[x+1].x,l[x+1].y);
			}
			else
			{
				Line(l[x].x,l[x].y,l[1].x,l[1].y);
			}

			l[x].x+=l[x].dx;
			if (l[x].x<0.0)
			{
				l[x].x=0.0;
				l[x].dx=-l[x].dx;
				if (Rnd(100)>40)
				{
					l[x].dx=(Rnd(4)+1)*0.5;
				}
				l[x].r=(l[x].r+1) & 255;
				l[x].g=(l[x].g+1) & 255;
				l[x].b=(l[x].b+1) & 255;
			}
			else
			{
				if (l[x].x>screenWidth-1)
				{
					l[x].x=screenWidth-1;
					l[x].dx=-l[x].dx;
					if (Rnd(100)>75)
					{
						l[x].dx=(Rnd(4)+1)*0.5;
					}
					l[x].r=(l[x].r+1) & 255;
					l[x].g=(l[x].g+1) & 255;
					l[x].b=(l[x].b+1) & 255;
				}
			}

			l[x].y+=l[x].dy;
			if (l[x].y<0)
			{
				l[x].y=0;
				l[x].dy=-l[x].dy;
				if (Rnd(100)>40)
				{
					l[x].dx=(Rnd(4)+1)*0.5;
				}
				l[x].r=(l[x].r+1) & 255;
				l[x].g=(l[x].g+1) & 255;
				l[x].b=(l[x].b+1) & 255;
			}
			else
			{
				if (l[x].y>screenHeight-1)
				{
					l[x].y=screenHeight-1;
					l[x].dy=-l[x].dy;
					if (Rnd(100)<30)
					{
						l[x].dy=(Rnd(4)+1)*0.5;
					}
				}
				l[x].r=(l[x].r+1) & 255;
				l[x].g=(l[x].g+1) & 255;
				l[x].b=(l[x].b+1) & 255;
			}
		}
		
		for (index=1; index<=MAXDOTS; index++)
		{
			if (d[index].x>0.0)
			{
				Ink(dotColour,0);
				Box(d[index].x,d[index].y,d[index].x+2,d[index].y+2);
				d[index].y+=d[index].dy;
				d[index].x+=d[index].dx;
				if (d[index].y>screenHeight || d[index].x>screenWidth)
				{
					d[index].x=0.0;
					d[index].y=0.0;
				}
			}
			else
			{
				if (Rnd(10)<3)
				{
					d[index].x=Rnd(screenWidth)*1.0;
					d[index].y=0.0;
					d[index].dy=(Rnd(5)+1)*1.0;
					d[index].dx=((Rnd(5)-1)*1.0)+0.5;					
				}
			}
		}

		count++;
		if (count>screenHeight<<2)
		{
			dotColour=Rgb(Rnd(265-32),Rnd(256-32),Rnd(256-32)+32);
			count=0;
		}

		if (loopc>2000)
		{
			loopc=0;
			dir=-dir;
			if (dir>0.0)
			{
				dir+=0.5;
			}
		}
		else
		{
			loopc++;
		}

		sprintf(temp,"FPS:%d Speed:%4.4f Angle#2:%4.4f",ScreenFps(),dir,sa);
		Text(0,0,temp);

		scrollT--;
		if (scrollT<0)
		{
			z=mess[0];
			memmove((char *) &mess,(char *) &mess[1],strlen(mess));
			mess[strlen(mess)]=(char) z;
			scrollT=SCROLLTIME;
		}
		Text(0,screenHeight-32,mess);
		Sync();
	}
}

// CMyDemoApp initialization

BOOL CMyDemoApp::InitInstance()
{
	CWinApp::InitInstance();

	return TRUE;
}


I'll be putting this on my web site later on (the executable that is).
Posted: 24th Dec 2003 6:51
wow
Posted: 24th Dec 2003 16:19
I couldn't put it better myself.
Posted: 25th Dec 2003 1:45
cpp scares me
Posted: 26th Dec 2003 6:19
Not really scary, I was doing some C++ coding a week ago,

I am still having the shakes, sleepless nights etc.
Posted: 26th Dec 2003 16:50
C++ can be a pain, but C is great. I only use C++ if I need classes.
Note that the code isn't optimised - its an almost word for word conversion of the original DBPro code.