#include "Global.h" DISPLAYSETTINGS Display; //Contains resolution, color depth, z buffer depth PADDLE PaddleLeft; //Create a paddle PADDLE PaddleRight; //Create a paddle BALL Ball; //Create a ball BOOL key[256]; //Allows for smooth keyboard movement extern FMUSIC_MODULE *Song0; int currentCamera=0; //Keeps track of the current camera position HINSTANCE hInstance; BOOL CALLBACK SetupDialogProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam){ GetFocus(); switch(message){ case WM_INITDIALOG: break; case WM_COMMAND: switch(LOWORD(wParam)){ case IDC_PLAY: EndDialog(hDlg,0); break; default: return FALSE; } } return TRUE; } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int iCmdShow){ //WinMain WNDCLASS wc; HWND hWnd; //Window handle MSG msg; //Message datatype BOOL Done=FALSE; //Boolean value. If Done==TRUE, then exit HDC hDC; //Device context handle HGLRC hRC; //Rendering context handle //REGISTER WINDOW CLASS wc.style = CS_OWNDC; //Creates a private DC for the Window (DC is not shared across applications) wc.lpfnWndProc = WndProc; //Handles messages wc.cbClsExtra = 0; //No extra window data wc.cbWndExtra = 0; //No extra window data wc.hInstance = hInstance; //Set the instance wc.hIcon = LoadIcon(hInstance,"Pong3D"); //Load the Pong3D icon wc.hCursor = LoadCursor(NULL,IDC_ARROW); //Load the mouse arrow pointer wc.hbrBackground = NULL; //No background brush is required in OpenGL wc.lpszMenuName = NULL; wc.lpszClassName = "Pong3D"; if(!RegisterClass(&wc)){ //Attempt to register the class ErrorMsg("Fatal: Pong 3D was unable to register the window class. Aborting"); //If failed, display error message return 0; //Exit WinMain } DisplaySettings(&Display,1024,768,16,16); //Set the display settings if(!(hWnd=CreateWindowEx(WS_EX_APPWINDOW,"Pong3D","Pong3D",WS_POPUP|WS_CLIPSIBLINGS, //Attempt to create the window 0,0,Display.width,Display.height,NULL,NULL,hInstance,NULL))){ ErrorMsg("Fatal: Pong3D was unable to create the window. Aborting"); //If window creation fails, display error message return 0; //Exit WinMain } DEVMODE dmScreenSettings; //Device Mode memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); //Makes Sure Memory's Cleared dmScreenSettings.dmSize = sizeof(dmScreenSettings); //Size Of The Devmode Structure dmScreenSettings.dmPelsWidth = Display.width; //Selected Screen Width dmScreenSettings.dmPelsHeight = Display.height; //Selected Screen Height dmScreenSettings.dmBitsPerPel = Display.colorBits; //Selected Bits Per Pixel dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; if(ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL){ //Attempt to enter full screen device mode ErrorMsg("Your graphics card does not support full screen device mode. Aborting"); //if failed, display error message return 0; //Exit WinMain } if(!EnableOpenGL(hWnd,&hDC,&hRC)){ //Attempt to enable OpenGL for the window ErrorMsg("Fatal: OpenGL was unable to initialize. Aborting"); //If failed, display an error message return 0; //exit WinMain } LoadSounds(); //Load sfx and music into memory PlayMusic(Song0); //Stream the music SetupRC(); //Set up the rendering context ResetGame(&PaddleLeft,&PaddleRight,&Ball); //Start a new game while(!Done){ //Program main loop if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){ //Check for quit message if(msg.message==WM_QUIT) Done = TRUE; //If WM_QUIT then break the main loop else{ //If program hasnt recieved WM_QUIT... TranslateMessage(&msg); //Translates keystrokes that may be specific to this application DispatchMessage(&msg); //Pass message to Windows, WndProc, etc } } else{ ////////////////OPENGL CODING STARTS HERE//////////////// glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //Clear screen with current color MoveBall(&Ball); //Move the ball Collision(&PaddleLeft,&PaddleRight,&Ball); //Check for collisions DrawPaddle(&PaddleLeft,-PLAYFIELD_W); //Draw the left paddle to the screen DrawPaddle(&PaddleRight,PLAYFIELD_W); //Draw the right paddle to the screen DrawBall(&Ball); //Draw the ball to the screen DrawBackBoard(); //Draw the backboard ChooseCamera(currentCamera); //Use the given camera SwapBuffers(hDC); //Swap virtual screen to physical screen /////////////////OPENGL CODING ENDS HERE///////////////// ProcessKeys(); //Process user input } } FreeSounds(); //Free the sounds and music from memory ChangeDisplaySettings(NULL,0); //Switch display settings back to desktop mode if(!DisableOpenGL(hWnd,hDC,hRC)) //Attempt to shutdown OpenGL ErrorMsg("An error occurred while attempting to disable OpenGL"); //Display an error message if(!DestroyWindow(hWnd)) //Destroy the window explicitly ErrorMsg("Pong3D failed to destroy the window"); //Display an error message return msg.wParam; //Return back to the desktop } //Window Procedure (Process window messages) LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam){ //Processes messages switch(message){ case WM_DESTROY: //Application is ready to close PostQuitMessage(0); //Terminates message loop in WinMain return 0; case WM_SYSCOMMAND: //Intercept System Commands if(wParam==SC_SCREENSAVE) return 0; //Don't allow screensaver to start case WM_KEYDOWN: //If a key is being pressed if(wParam==VK_RETURN){ //If user hits the enter key if(currentCamera>=MAX_CAMERAS-1) currentCamera=-1; //If camera number exceeds MAX_CAMERAS set camera number to 0 currentCamera++; //Change the camera view } if(wParam==VK_F1) DialogBox(hInstance,"SetupDialog",hWnd,(DLGPROC)SetupDialogProc); key[wParam] = TRUE; //Set the key to true if it has been pressed return 0; case WM_KEYUP: //If a key is released key[wParam] = FALSE; //If the key is released, set it to false return 0; } return DefWindowProc(hWnd,message,wParam,lParam); //If message wasn't processed, return it to Windows } //This function attempts to get the device and rendering contexts. Returns TRUE on success, FALSE on fail BOOL EnableOpenGL(HWND hWnd,HDC *hDC,HGLRC *hRC){ //Enables OpenGL PIXELFORMATDESCRIPTOR pfd; //Pixel Format Descriptor int format; //To hold pixel format *hDC=GetDC(hWnd); //Get the device context (DC) //SET THE PIXEL FORMAT FOR THE DEVICE CONTEXT memset(&pfd,0,sizeof(pfd)); pfd.nSize = sizeof(pfd); //Size of the pfd pfd.nVersion = 1; //Always equals 1 pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER; //Pixel format: is used to draw to window, needs to support OpenGL, has double buffering capabilities pfd.iPixelType = PFD_TYPE_RGBA; //Pixel type (Red Green Blue Alpha) pfd.cColorBits = Display.colorBits; //24 bit color buffer pfd.cDepthBits = Display.depthBits; //16 bit depth buffer format = ChoosePixelFormat(*hDC,&pfd); //Choose correct pixel format SetPixelFormat(*hDC,format,&pfd); //Set the pixel format *hRC=wglCreateContext(*hDC); //Create rendering context if(!wglMakeCurrent(*hDC,*hRC)) return FALSE; //Enable rendering context return TRUE; //Return true if deinitialization was successful } //This function attempts to release the device and rendering contexts. Returns TRUE on success, FALSE on fail BOOL DisableOpenGL(HWND hWnd,HDC hDC,HGLRC hRC){ if(!wglMakeCurrent(NULL,NULL)) return FALSE; //Attempt to release the rendering context if(!wglDeleteContext(hRC)) return FALSE; //Attempt to delete the rendering context if(!ReleaseDC(hWnd,hDC)) return FALSE; //Attempt to release the device context return TRUE; //Return true if deinitialization was successful } //This function initializes the members of the DISPLAYSETTINGS structure with the given arguments VOID DisplaySettings(struct DISPLAYSETTINGS *displaySettings, int w,int h,int color,int depth){ displaySettings->colorBits=color; //Set the color depth displaySettings->depthBits=depth; //Set the depth bits displaySettings->height=h; //Set the screen height resolution displaySettings->width=w; //Set the screen width resolution } //Sets up our rendering context VOID SetupRC(void){ glEnable(GL_DEPTH_TEST); //Enable depth testing (Don't show hidden faces) glEnable(GL_CULL_FACE); //Don't draw back faces glFrontFace(GL_CCW); //Shapes have a counter-clockwise winding glEnable(GL_LIGHTING); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE); glClearColor(0.0f,0.0f,0.0f,1.0f); //Set the color glViewport(0,0,Display.width,Display.height); //Set the viewport glMatrixMode(GL_PROJECTION); //Switch to perspective mode glLoadIdentity(); //Reset the perspective matrix gluPerspective(45.0f,Display.width/Display.height,1.0,400.0); //Set to perspective mode. (Objects converge in distance) glMatrixMode(GL_MODELVIEW); //Switch to model matrix glLoadIdentity(); //Reset the model matrix SetupLights(); } VOID ErrorMsg(char *Message){ //Display an error message with the given string MessageBeep(0); //Make a beep MessageBox( GetFocus(),Message,"Pong3D - An error has occurred",MB_ICONASTERISK|MB_OK ); //Display the message }