//				  ATTILA 3D engine
//				  by Gozer/Condense
//			  Main purpose is demomaking

#define		ATTILANAME   "Attila v0.2"


#ifndef	PLATFORM_LINUX

#include <stdio.h>
#include <direct.h>
#include <math.h>
#include <float.h>
#include <windows.h>
#include <ddraw.h>
#include <gl\gl.h>

#include <imgManager.h>
#include <generic.h>
#include <Targa.h>
#include <Jpeg.h>
#include <Bmp.h>
#include <Iff.h>

#include "resource.h"
#include "winDefs.h"

#else

#define	ULONG unsigned long
#define	LONG 	long
#define USHORT	unsigned short
#define SHORT 	short
#define UCHAR 	unsigned char
#define CHAR 	char
#define uchar	unsigned char
#define BOOL 	bool
#define DWORD 	unsigned long
#define VOID	void
#define HRESULT	DWORD
#define S_OK	0

#include <string.h>
#include <sys/time.h>

void ZeroMemory(void *buf, int size)
{
	int i;
	for(i=0;i<size;i++) ((char*)buf)[i] = 0;
}

#endif

//#include <mathVector.h>

void quitMessage(char*, char*);
void warningMessage(char *titre, char *text);
#include "pcx.h"

ULONG MyGetTickCount()
{
//	return (ULONG)SetTimer(NULL,NULL,0xffffffff,NULL);
#ifdef PLATFORM_LINUX
//	time_t daTime;
//	time( &daTime );
//	return (daTime.tv_nsec/1000);
	struct timeval tt;
	struct timezone t;
	gettimeofday( &tt,&t );
	return ((tt.tv_sec*1000000 + tt.tv_usec)/1000);
#else
	return GetTickCount();
#endif
}

#include "GozerString.h"
#include "attilaDefs.h"
#include "GLDefs.h"
#include "filesOp.h"
#include "momoth.h"
#include "conversions.h"
#include "printToScreen.h"
#include "matrixOp.h"
#include "sceneClass.h"
#include "shadow.cpp"

long nsprite;
class sprite
{
public:;
	textu piece;
	ULONG	**datas, *glT,nplan;
	float	*plan, *cmap, maxs[12];
	void buildPlan();
	void putPlan(float);
	sprite();
}*sprt;


#include "loadLWO.cpp"
#include "initGL.cpp"
#include "openglRenderer.cpp"
#include "drawFrame.cpp"

sprite::sprite()
{
	piece.initPtr();
	float add = (0.2f * (res_x-res_y))/640.0f;
	maxs[0] = -0.5f - add;
	maxs[1] = +0.5f;
	maxs[2] = 1.0f;

	maxs[3]  =  0.5f + add;
	maxs[4] = +0.5f;
	maxs[5] = 1.0f;

	maxs[6] = 0.5f + add;
	maxs[7] = -0.5f;
	maxs[8] = 1.0f;

	maxs[9] = -0.5f - add;
	maxs[10] = -0.5f;
	maxs[11] = 1.0f;
}

void sprite::putPlan(float alpha)
{
	glColor4f(1,1,1,alpha);
	glLoadIdentity();
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA );
	glEnable(GL_TEXTURE_2D);
	long pkmap=0, pkpt=0;
	for(long i=0;i<(long)nplan;i++)
	{
		glBindTexture(GL_TEXTURE_2D, GLtexture[glT[i]]);
		glBegin(GL_POLYGON);
		for(long j=0;j<4;j++)
		{
			glTexCoord2f( cmap[pkmap],cmap[pkmap+1]);
			glVertex3f( plan[pkpt],plan[pkpt+1],-plan[pkpt+2]);
			pkmap +=2;
			pkpt  +=3;
		}
		glEnd();
	}
	glDisable(GL_BLEND);
	glDisable(GL_TEXTURE_2D);
}

void sprite::buildPlan()
{
	long nplanx =  (piece.sizex/256);
	long nplany =  (piece.sizey/256);
	if( piece.sizex%256 ) nplanx++;
	if( piece.sizey%256 ) nplany++;

	nplan = nplanx * nplany;
	datas = new ULONG*[nplan];
	plan = new float[nplan*4*3];
	cmap = new float[nplan*4*2];
	datas = new ULONG*[nplan];
	glT = new ULONG[nplan];
	long i,j,k,ck,c;
	for(k=0;k<(long)nplan;k++) datas[k] = new ULONG[256*256];
	float worldPx = (maxs[3] - maxs[0])/((float)piece.sizex/256.0f);
	float worldPy = 1.0f/((float)piece.sizey/256.0f);
	float cx,cy;

	cy = maxs[10];
//	split texture, build plan & cmap
	for( i=0;i<nplany;i++)
	{
		cx = maxs[9];
		for(j=0;j<nplanx;j++)
		{
			// split texture
			c = (i * piece.sizex * 256) + (j * 256);
			for(k=0;k<256;k++)
			{
				for(ck=0;ck<256;ck++)
					datas[(i*nplanx)+j][(k*256)+ck] = ((ULONG*)piece.data)[(c+ck)%(piece.sizex*piece.sizey)];
				c += piece.sizex;
			}
			// build cmap of plan
			ck = ((i*nplanx)+j)*8;
			cmap[ck]   = 0;
			cmap[ck+1] = 0;

			cmap[ck+2] = 0;
			cmap[ck+3] = 1;

			cmap[ck+4] = 1;
			cmap[ck+5] = 1;

			cmap[ck+6] = 1;
			cmap[ck+7] = 0;

			// build 3d plan
			ck = ((i*nplanx)+j)*12;
			plan[ck] = cx;
			plan[ck+1] = cy;
			plan[ck+2] = 1.0f;

			plan[ck+3] = cx;
			plan[ck+4] = cy+worldPy;
			plan[ck+5] = 1.0f;

			plan[ck+6] = cx+worldPx;
			plan[ck+7] = cy+worldPy;
			plan[ck+8] = 1.0f;

			plan[ck+9] = cx+worldPx;
			plan[ck+10] = cy;
			plan[ck+11] = 1.0f;

			cx += worldPx;
		}
		cy += worldPy;
	}
//	---------------
}
/*
/////////////////////////////////////////////////////////////////////////////////////////////////


	      			***************   Engine intialisation ***************


/////////////////////////////////////////////////////////////////////////////////////////////////
*/
void initEngine()
{
	defaultTextu.sizex = 8;
	defaultTextu.sizey = 8;
	defaultTextu.decal = 3;
	defaultTextu.masqX = 7;
	defaultTextu.masqY = 7;

	defaultTextu.data = new USHORT[8*8];
	musicname[0] = 0;

	nsprite = 0;
	sprt = new class sprite[AF_MAX_SPRITES];
}

#ifndef PLATFORM_LINUX
void releaseScenes(HWND hWnd)
{
	if(scene != NULL) delete [] scene;
	scene = NULL;
	scnMan.currentScene = 0;
	appFlags &= ~(AF_RENDERING);// clear rendering flag

	ShowWindow(hwndMain, SW_HIDE);	// hide main windows
	ShowWindow(hwndDlg,  SW_SHOWNORMAL);	// show dialog box windows
	EndPaint(hWnd, &ps);
	deleteTexturesGL();
	releaseGL(); // release opengl

	ChangeDisplaySettings(NULL, 0);
	BASS_Free();

	res_x = 640;
	res_y = 480;
}
#else
void releaseScenes()
{
	if(scene != NULL) delete [] scene;
	scene = NULL;
	scnMan.currentScene = 0;
	appFlags &= ~(AF_RENDERING);// clear rendering flag

	deleteTexturesGL();

	res_x = 640;
	res_y = 480;
}
#endif

#ifndef PLATFORM_LINUX
/*
/////////////////////////////////////////////////////////////////////////////////////////////////


	      			***************   Sound intialisation ***************


/////////////////////////////////////////////////////////////////////////////////////////////////
*/

void initBass()
{
//	detect mp3 files
	long a = 0;
	while(musicname[a] != 0) a++;

/*
	if (BASS_GetVersion()!=MAKELONG(0,8)) {
		MessageBox(0,"BASS version 0.8 was not loaded","Incorrect BASS.DLL",0);
		return;
	}
*/
//	INIT BASS GENERAL OUTPUT
	if (!BASS_Init(-1,44100,0,hwndMain)) 
	{
		if (!BASS_Init(0,44100,0,hwndMain))
		{
			MessageBox(NULL,"Can't initialize digital sound system","kopkop",MB_OK);
			return;
		}
	}
	BASS_Start();	// Start digital output 
//	-------------------------

	// mp3 stream
	if( (musicname[a-1]=='3') && (musicname[a-2]=='p') && (musicname[a-3]=='m') )
	{
		fileOperations fop(musicname);
		if(!(strm = BASS_StreamCreateFile(TRUE,fop.qloadfile(),0,fop.getfilesize(),0))) 
			quitMessage("hop","can't load mp3");
		if( !BASS_StreamPlay(strm, TRUE, 0) )
		{
			long hop = BASS_ErrorGetCode();
			if( hop == BASS_ERROR_START ) quitMessage("aie", "bass not started");
			if( hop == BASS_ERROR_HANDLE ) quitMessage("aie", "bad handle");
			if( hop == BASS_ERROR_BUFLOST ) quitMessage("aie", "well...");
		}
	}
	// mod,xm,it
	else if(musicname[0] != 0)
	{
		fileOperations fop(musicname);

		if (!(mod=BASS_MusicLoad(TRUE, fop.qloadfile(),0,0,BASS_MUSIC_RAMP)))
			quitMessage("ho","Can't load music");

		BASS_MusicPlay( mod );
	}
}


LRESULT CALLBACK mainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK DialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam);

/*
/////////////////////////////////////////////////////////////////////////////////////////////////


	      			***************   Da WinMain procedure ***************


/////////////////////////////////////////////////////////////////////////////////////////////////
*/

int WINAPI WinMain(
	HINSTANCE hInstance,			// current instance
	HINSTANCE hPrevInstance,		// previous instance
	LPSTR lpCmdLine,				// pointer to command line
	int nCmdShow)					// show state of window
{
	_getcwd(exeDir, 256);

    MSG msg;
    WNDCLASS wc;
	HACCEL hAccel;
    // Register the window class for the main window. 
	
    if (!hPrevInstance)
    { 
        wc.style = 0; 
        wc.lpfnWndProc = (WNDPROC) mainWndProc;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hInstance = hInstance;
        wc.hIcon = LoadIcon((HINSTANCE) NULL,
            "IDI_ICON1"); 
        wc.hCursor = LoadCursor((HINSTANCE) NULL,
            IDC_ARROW);
        wc.hbrBackground = (struct HBRUSH__ *)GetStockObject(WHITE_BRUSH);
        wc.lpszMenuName =  "MainMenu";
        wc.lpszClassName = "MainWndClass";
 
        if (!RegisterClass(&wc)) 
            return FALSE;
    } 
 
    hinst = hInstance;  // save instance handle 

    hwndMain = CreateWindow("MainWndClass", ATTILANAME, 
        WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, 
        CW_USEDEFAULT, CW_USEDEFAULT, (HWND) NULL, 
        (HMENU) NULL, hinst, (LPVOID) NULL); 

    // If the main window cannot be created, terminate 
    // the application. 
    if (!hwndMain) 
        return FALSE; 

    // Load keyboard accelerators
    hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));

	// create dialog box
	hwndDlg=CreateDialog(NULL,MAKEINTRESOURCE(IDD_DIALOG1),NULL,(DLGPROC)&DialogProc);
	if(hwndDlg==NULL)
		quitMessage("WinMain", "The program is unable to create a dialog box!");
	ShowWindow(hwndDlg,SW_SHOWNORMAL);
	UpdateWindow(hwndDlg);

	// init default values of the dialog box
	CheckRadioButton(hwndDlg,IDC_OPENGL,IDC_SOFT,IDC_OPENGL);

	// get all video mode for opengl -> devmodes    + opengl infos
	GetGLDisplayModes();

	// init scenes class pointer
	scene = NULL;
	// init engine once
	initEngine();

    // Start the message loop 
    while (1)			// main loop...
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
        {
            if (!GetMessage(&msg, NULL, 0, 0 ))
                break;
            // Translate and dispatch the message
            if (0 == TranslateAccelerator(hwndMain, hAccel, &msg))// if no key pressed
            {
				TranslateMessage(&msg);
				DispatchMessage(&msg);
            }
        }
		if( (appFlags & AF_RENDERING)!=0)	// if app is rendering then draw
		{
			// start deugging info here
			if( (appFlags & AF_DEBUG) != 0) debugPrint->clear();

			if ( scnMan.playList() ) 
			{
				releaseScenes(hwndMain);
				break;
			}
			SwapBuffers(hDC);			// opengl swap
		}
    }
    // Return the exit code to Windows. 

    return msg.wParam;
}




/*
/////////////////////////////////////////////////////////////////////////////////////////////////


		***************   Da Main window callback procedure ***************


/////////////////////////////////////////////////////////////////////////////////////////////////
*/
LRESULT CALLBACK
mainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    LONG        lRet = 0L; 

    switch (msg) 
    { 
		case WM_CREATE:
			if( (appFlags & AF_FSCREEN) == 0) BeginPaint(hWnd, &ps);
		break;

		case WM_PAINT:

			if( (appFlags & AF_FSCREEN) == 0)	// update paint structure for opengl
			{
				EndPaint(hWnd, &ps);
				BeginPaint(hWnd, &ps);
			}

		break;

		case WM_SETCURSOR:
			if( (appFlags & AF_FSCREEN) !=0) SetCursor(NULL);
		break;

		case WM_COMMAND:
            // Handle all menu and accelerator commands
            switch (LOWORD(wParam))
			{
				case IDA_ESC:
					releaseScenes(hWnd);
				break;

				case IDA_SWAP:
					appFlags ^= 2;	// invert fullscreen mode bit
					swapGL(); // here is opengl swap code

					if( (appFlags & AF_FSCREEN) !=0)
					{
						 SendDlgItemMessage( hwndDlg, IDC_FSCREEN, BM_SETCHECK, BST_CHECKED , 0);
					}
					else
					{
						SendDlgItemMessage( hwndDlg, IDC_FSCREEN, BM_SETCHECK, BST_UNCHECKED , 0);
						SetCursor(LoadCursor((HINSTANCE) NULL, IDC_ARROW));
					}
				break;
			}
		break;

		case WM_MOVE:
			GetWindowRect(hwndMain, &videoWindow);
			onlyVideoWindow(&videoWindow);
		break;

        case WM_CLOSE:
        return 0;

		case WM_LBUTTONDOWN:
			if( (appFlags & AF_FSCREEN) ==0 )
			{
				initDragMouse.x = LOWORD(lParam);
				initDragMouse.y = HIWORD(lParam);
			}
		break;

		case WM_MOUSEMOVE:
			if( (appFlags & AF_FSCREEN) ==0 )
			{
				GetWindowRect(hwndMain, &dlgRect);
				if( (wParam & MK_LBUTTON) != 0 )
					SetWindowPos( hwndMain, HWND_TOP, dlgRect.left + LOWORD(lParam)-initDragMouse.x, +dlgRect.top+HIWORD(lParam)-initDragMouse.y, 0, 0, SWP_NOSIZE);
			}
		break;



        default: 
	            lRet = DefWindowProc( hWnd, msg, wParam, lParam ); 
            break; 
    }
    return lRet; 
}





/*
/////////////////////////////////////////////////////////////////////////////////////////////////


      			***************   Da Dialog box callback procedure ***************


/////////////////////////////////////////////////////////////////////////////////////////////////
*/
bool firstInstance = true;

BOOL CALLBACK DialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	HWND hwndList;
	switch(uMsg)
	{
		case WM_INITDIALOG:
			GetWindowRect(hwndDlg, &dlgRect);
			return true;

 // button identifier 

		case WM_COMMAND:
			switch(wParam)
			{
				OPENFILENAME ofn;
				LPTSTR      fname,filenom;
				LPCTSTR     extension,initdir;
				char *p,*p2;

				case IDC_GLINFO:
					MessageBox(NULL,glInfos, "opengl informations", MB_OK);
				return true;

				case IDCANCEL:
					PostQuitMessage( 0 );	// quit Attila, the second gate to exit the app
				return true;

				case IDC_MUSIC:

					extension ="*";
					initdir =AF_DEFAULT_DIR;

					p= new char[256];
					p2= new char[256];
					p[0] = 0;
					p2[0] = 0;
					*p=0;
					fname=p;
					filenom=p2;
					memset(&ofn, 0, sizeof(OPENFILENAME));
					ofn.lStructSize = sizeof(OPENFILENAME);
					ofn.lpstrFilter = extension;
					ofn.hwndOwner = hwndDlg;
					ofn.lpstrTitle = "ATTILA           Well, let's select scene files :)";
					ofn.lpstrFileTitle = filenom;
					ofn.nMaxFileTitle = 256;
					ofn.lpstrFilter = "Bass music formats\x00";
					ofn.nFilterIndex = 0; 
					if( firstInstance)ofn.lpstrInitialDir = initdir;	// could be initdir :)
					else ofn.lpstrInitialDir = NULL;
					ofn.lpstrFile = fname;
					ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_READONLY;
					ofn.lpstrDefExt = NULL;
					ofn.nMaxFile = 256;
					if( GetOpenFileName(&ofn) )
					{
						strcpy(musicname,p);
					}
					delete p;
					delete p2;

				return true;

				case IDC_FSCREEN:
					appFlags ^= 2;	// invert bit
				return true;

				case IDC_DEBUG:
					appFlags ^= AF_DEBUG;	// invert bit
					if( (appFlags & AF_DEBUG) !=0) 
					{
						if( debugPrint == NULL)
							debugPrint = new printToScreen("d:\\gozerVrac\\dimension3\\system.pcx","abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:;<=>?@![#$%&'()*+,-./");
					}
				return true;


				case IDC_CLEAR:
					long nI,Tnbs;
					hwndList= GetDlgItem(hwndDlg, IDC_LIST1); 
					Tnbs = scnMan.nbs;
					for(nI=0;nI<Tnbs;nI++)
					{
						SendMessage(hwndList, LB_DELETESTRING, (WPARAM) 0, 0);
						scnMan.sub(0);
					}
				return true;

				case IDC_SUB:

					long nItem;

					hwndList= GetDlgItem(hwndDlg, IDC_LIST1); 
					nItem = (long) SendMessage(hwndList, LB_GETCURSEL, 0, 0);
					if(nItem>=0) 
					{
						SendMessage(hwndList, LB_DELETESTRING, (WPARAM) nItem, 0);
						scnMan.sub(nItem);
					}
				return true;

				case IDC_ADD:
					extension ="*.scn";
					initdir =AF_DEFAULT_DIR;

					p= new char[8192];
					p2= new char[8192];
					p[0] = 0;
					p2[0] = 0;
					*p=0;
					fname=p;
					filenom=p2;
					memset(&ofn, 0, sizeof(OPENFILENAME));
					ofn.lStructSize = sizeof(OPENFILENAME);
					ofn.lpstrFilter = extension;
					ofn.hwndOwner = hwndDlg;
					ofn.lpstrTitle = "ATTILA           Well, let's select scene files :)";
					ofn.lpstrFileTitle = filenom;
					ofn.nMaxFileTitle = 8192;
					ofn.lpstrFilter = "Lightwave scenes\x0*.lws\x00";
					ofn.nFilterIndex = 0; 
					if( firstInstance)ofn.lpstrInitialDir = initdir;	// could be initdir :)
					else ofn.lpstrInitialDir = NULL;
					ofn.lpstrFile = fname;
					ofn.Flags = OFN_EXPLORER | OFN_ALLOWMULTISELECT | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_READONLY;
					ofn.lpstrDefExt = NULL;
					ofn.nMaxFile = 8192;
					GetOpenFileName(&ofn);
					long hopE;
					hopE = CommDlgExtendedError();

					if( hopE == FNERR_BUFFERTOOSMALL  )
					{
						MessageBox(NULL,"Please select less files :(","Buffer to small",MB_OK);
						p[0] = 0;
						p2[0] = 0;
					}

 					if( p[0] || p2[0])
					{
						firstInstance = false;
						if(!ofn.nFileExtension)	// Multiple selection
						{
							char baseD[256];
							long n=0, m;
							while(fname[n]!=0)
								baseD[n++] = fname[n];
							if(fname[ofn.nFileOffset-2]!=92)
								baseD[n++] = 92;
							baseD[n] = 0;
							MyString filename;
							m = ofn.nFileOffset;
							while(1)
							{
								if(fname[m] ==0) break;
								filename = baseD;
								filename += fname+m;

								scnMan.add( filename.data );
								long a;
								a=0;
								while(filename.data[a++]!=0);
								while(filename.data[a--] != '\\');
								hwndList= GetDlgItem(hwndDlg, IDC_LIST1); 
								SendMessage(hwndList, LB_ADDSTRING, 0, 
										(LPARAM) (filename.data+a+2)); 

								while(fname[m++]!=0);
							}
						}
						else					// simple selection
						{
							MyString gop;
							gop = _getcwd( p, 256*256 );
							gop += "\\";
							gop += p2;
							scnMan.add( (char*) gop.data);
							long a;
							a=0;
							while(gop.data[a++]!=0);
							while(gop.data[a--] != '\\');
							hwndList= GetDlgItem(hwndDlg, IDC_LIST1); 
							SendMessage(hwndList, LB_ADDSTRING, 0, 
									(LPARAM) (gop.data+a+2)); 
						}
					}
					delete p;
					delete p2;

				return true;

				case IDC_DEMO:
					demoMode = true;
					strcpy( musicname, "C:\\trash\\sics\\Ay_chang.it");
					
					long  o;
#define nscenes  10
					char sceneName[nscenes][256];
					strcpy( sceneName[0] , "d:\\gozervrac\\dimension3\\scenes\\spacecube\\spacecube.lws");
					strcpy( sceneName[1] , "d:\\gozervrac\\dimension3\\scenes\\nipotkoi.lws");
					strcpy( sceneName[2] , "D:\\GozerVrac\\Dimension3\\scenes\\SPACE_BUILDING\\temp.lws");
					strcpy( sceneName[3] , "D:\\GozerVrac\\Dimension3\\scenes\\manu\\scenes\\atome.lws");
//					strcpy( sceneName[4] , "D:\\GozerVrac\\Dimension3\\scenes\\circles\\circleTwo.lws");
					strcpy( sceneName[4] , "D:\\GozerVrac\\Dimension3\\scenes\\manu\\manu2\\scenes\\base\\base2.lws");
					strcpy( sceneName[5] , "D:\\GozerVrac\\Dimension3\\scenes\\pyramidMirror\\pyramidMirrorScene2.lws");
					strcpy( sceneName[6] , "D:\\GozerVrac\\Dimension3\\scenes\\manu\\manu2\\scenes\\Palais DBZ\\dbz2.lws");
					strcpy( sceneName[7] , "D:\\GozerVrac\\Dimension3\\scenes\\trees\\trees.lws");
					strcpy( sceneName[8] , "D:\\GozerVrac\\Dimension3\\scenes\\circles\\circleOne.lws");
					strcpy( sceneName[9] , "D:\\GozerVrac\\Dimension3\\scenes\\EndScene\\ende.lws");
					for(o=0;o<nscenes;o++)
					{
						scnMan.add( sceneName[o] );
						long a;
						a=0;
						while(sceneName[o][a]!=0) a++;
						while(sceneName[o][a--] != '\\');
						hwndList= GetDlgItem(hwndDlg, IDC_LIST1);
						SendMessage(hwndList, LB_ADDSTRING, 0,
									(LPARAM) (sceneName[o]+a+2)); 
					}
					// continue with IDC_GO...

				case IDC_GO:
					if(scnMan.nbs==0)
					{
						MessageBox(NULL, "Arf! You're a little joker, huu? :)\n-- There is no scene to play","woops !",MB_OK);
						return true;
					}

					if(scene != NULL) quitMessage("dialog PRoc","Error Managing memory, leak on scene!!!! :(");
					scene = new scen[scnMan.nbs];
					
					// Hide dialog box
					ShowWindow(hwndDlg,SW_HIDE);

					// create temporary dialog box for waiting advice
					HWND hwndDlg2;
					hwndDlg2=CreateDialog(NULL,MAKEINTRESOURCE(IDD_DIALOG2),NULL,(DLGPROC)NULL);
					SetWindowPos( hwndDlg2, HWND_TOP, dlgRect.left, dlgRect.top, 0, 0, SWP_NOSIZE);
					ShowWindow(hwndDlg2,SW_SHOWNORMAL);
					UpdateWindow(hwndDlg2);

					for(long i=0;i<scnMan.nbs;i++)
					{
						scene[i].loadScene(scnMan.filenames[i]);
					}
					appFlags |= AF_RENDERING;

					scnMan.initAll4Play();

					// no need to keep names of objects, surfaces...
					scnMan.deleteAllNames();

					initGLWindow();
					initTexturesGL();

					// 2D effect init
					videoEffect.startTime = MyGetTickCount();
					videoEffect.videoBuffer = videoGL;
					videoEffect.Init_Textures();
					videoEffect.Init_Tunnel(0);
					videoEffect.CalculateFlower();


					DestroyWindow(hwndDlg2);

					// set the wright window size
					windowSize.x = res_x;// + borders.left + borders.right;
					windowSize.y = res_y;// + borders.top + borders.bottom;
					SetWindowPos( hwndMain, HWND_TOP, 0, 0, windowSize.x, windowSize.y, SWP_NOMOVE);
					ShowWindow(hwndMain,SW_SHOWNORMAL);
					UpdateWindow(hwndMain);
					GetWindowRect(hwndMain, &videoWindow);
					onlyVideoWindow(&videoWindow);
					if(((appFlags & AF_FSCREEN))) swapGL();

					scene[0].init4Play();	// init first scene...
					if( musicname[0] != 0) initBass();
				return true;
			}

 // mouse manager
		case WM_LBUTTONDOWN:
			initDragMouse.x = LOWORD(lParam);
			initDragMouse.y = HIWORD(lParam);
		return true;

		case WM_MOUSEMOVE:
			GetWindowRect(hwndDlg, &dlgRect);
			if( (wParam & MK_LBUTTON) != 0 )
				SetWindowPos( hwndDlg, HWND_TOP, dlgRect.left + LOWORD(lParam)-initDragMouse.x, +dlgRect.top+HIWORD(lParam)-initDragMouse.y, 0, 0, SWP_NOSIZE);
		return true;

	}
	return false;
}

#endif

/*
/////////////////////////////////////////////////////////////////////////////////////////////////


      			***************   Crash message error  ***************


/////////////////////////////////////////////////////////////////////////////////////////////////
*/
// first gate
void quitMessage(char *titre, char *text)
{
#ifndef PLATFORM_LINUX
	ChangeDisplaySettings(NULL, 0);
	MessageBox(NULL, text, titre, MB_OK | MB_ICONERROR);
#else
	printf("%s\n%s\n", titre, text);
#endif
	exit(-1);
}

void warningMessage(char *titre, char *text)
{
#ifndef PLATFORM_LINUX
	ChangeDisplaySettings(NULL, 0);
	MessageBox(NULL, text, titre, MB_OK);
#else
	printf("%s\n%s\n", titre, text);	
#endif
}