2016-01-27 00:49:52 chip
Page 1544
📢 PUBLIC
WinMain.c:
/*************************************************************************/
/** Main.cpp: Manages the main window, game creation, run, destruction. **/
/** (C)2016 nlited systems, Chip Doran **/
/*************************************************************************/
#include <Windows.h>
#include "Util.h"
#include "MyD2D.h"
#include "Globals.h"
class Main {
public:
static __inline Main *Ptr(HMAIN hMain);
static __inline Main *PtrWnd(HWND hWnd);
static int Create(HMAIN *phMain);
int Destroy(void);
int Loop(void);
//Data
UINT32 Signature;
private:
Main(void);
~Main(void);
int Create2(void);
int CreateClass(void);
static LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParm, LPARAM lParm);
LRESULT MsgCreate(HWND hWnd);
LRESULT MsgDestroy(void);
LRESULT MsgClose(bool DoPrompt);
LRESULT MsgResized(void);
LRESULT MsgTimer(void);
LRESULT MsgPaint(void);
LRESULT MsgKey(UINT KeyID, UINT OnOff);
static DWORD CALLBACK UpdateProc(LPVOID hMain);
int UpdateLoop(void);
//Data
HWND hWnd;
RECT rClnt;
HIMAGE hImg;
HANDLE hUpdateThread;
DWORD UpdateThreadID;
volatile bool DoResize;
volatile bool DoExit;
};
HD2D ghD2D; //My Factory of Direct2D Factories
HGAME ghGame;
/*************************************************************************/
/** Public interface **/
/*************************************************************************/
int MainCreate(HMAIN *phMain) {
if(IsBadPtr(phMain,sizeof(*phMain),BADPTR_WRITE))
return(Error(ERR_BADPTR,"MainCreate: Bad phMain[%X]",phMain));
return(Main::Create(phMain));
}
int MainDestroy(HMAIN hMain) {
Main *pMain= Main::Ptr(hMain);
if(!pMain)
return(Warn(ERR_BADHANDLE,"MainDestroy: Bad hMain[%X]",hMain));
return(pMain->Destroy());
}
int MainLoop(HMAIN hMain) {
Main *pMain= Main::Ptr(hMain);
if(!pMain)
return(ERR_BADHANDLE);
return(pMain->Loop());
}
void DisplayStrA(UINT Type, const char *Str) {
}
void DisplayStrW(UINT Type, const WCHAR *Str) {
}
/*************************************************************************/
/** Public internals **/
/*************************************************************************/
Main *Main::Ptr(HMAIN hMain) {
Main *pMain= (Main*)hMain;
if(!hMain || IsBadPtr(pMain,sizeof(*pMain),BADPTR_RW) || pMain->Signature!=SIGNATURE_MAIN)
pMain= 0;
return(pMain);
}
Main *Main::PtrWnd(HWND hWnd) {
HMAIN hMain;
if(!IsWindow(hWnd))
return(0);
hMain= (HMAIN)GetWindowLongPtr(hWnd,GWLP_USERDATA);
return(Ptr(hMain));
}
int Main::Create(HMAIN *phMain) {
int Err= ERR_OK;
Main *pMain= new Main;
if(!pMain) {
Err= Error(ERR_NOMEM,"Main:Create: NoMem(%d)",sizeof(*pMain));
} else if(IsErr(Err= pMain->Create2())) {
delete pMain;
} else {
*phMain= (HMAIN)pMain;
}
return(Err);
}
int Main::Destroy(void) {
int Err= ERR_OK;
delete this;
return(Err);
}
int Main::Loop(void) {
int Err= ERR_OK;
MSG Msg;
while(IsWindow(hWnd)) {
if(GetMessage(&Msg,hWnd,0,0)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
while(hUpdateThread)
Sleep(100);
return(Err);
}
/*************************************************************************/
/** Private internals **/
/*************************************************************************/
Main::Main(void) {
memset(this,0,sizeof(*this));
Signature= SIGNATURE_MAIN;
}
Main::~Main(void) {
Signature|= SIGNATURE_INVALID;
GameDestroy(ghGame);
ImgDestroy(hImg);
MyD2DDestroy(ghD2D);
}
static const WCHAR *ClassName= {L"ROCKET_CLASS"};
static const WCHAR *WndName= {L"Rocket2D"};
int Main::Create2(void) {
int Err= ERR_OK;
DWORD Style= WS_OVERLAPPEDWINDOW;
DWORD StyleX= WS_EX_APPWINDOW|WS_EX_OVERLAPPEDWINDOW;
RECT rPos= { 100, 100, 700, 500 };
if(IsErr(Err= GameCreate(&ghGame))) {
Err= Error(Err,__FUNCTION__": Unable to create Game.");
} else if(IsErr(Err= MyD2DCreate(&ghD2D,ghInst))) {
Err= Error(Err,__FUNCTION__": Unable to create MyD2D Factory.");
} else if(IsErr(CreateClass())) {
Err= Error(ERR_SYSCREATE,__FUNCTION__": Unable to create class '%S'",ClassName);
} else {
hWnd= CreateWindowEx(StyleX,ClassName,WndName,Style,rPos.left,rPos.top,RWID(rPos),RHGT(rPos),0,0,ghInst,this);
if(!IsWindow(hWnd)) {
Err= Error(ERR_SYSCREATE,__FUNCTION__": CreateWindowEx(%S,%S) failed.",ClassName,WndName);
}
}
return(Err);
}
int Main::CreateClass(void) {
int Err= ERR_OK;
WNDCLASSEX Class;
ATOM hClass;
memset(&Class,0,sizeof(Class));
Class.cbSize= sizeof(Class);
Class.hCursor= LoadCursor(0,IDC_ARROW);
Class.hInstance= ghInst;
Class.lpfnWndProc= WndProc;
Class.lpszClassName= ClassName;
Class.style= CS_DBLCLKS;
hClass= RegisterClassEx(&Class);
if(!hClass) {
Err= Error(ERR_SYSCREATE,__FUNCTION__": Unable to register class '%S'",ClassName);
}
return(Err);
}
/*************************************************************************/
/** Message handler **/
/*************************************************************************/
LRESULT CALLBACK Main::WndProc(HWND hWnd, UINT Msg, WPARAM wParm, LPARAM lParm) {
Main *pMain= (Msg==WM_CREATE) ? Ptr((HMAIN)((CREATESTRUCT*)lParm)->lpCreateParams) : PtrWnd(hWnd);
if(pMain) {
switch(Msg) {
case WM_CREATE: return(pMain->MsgCreate(hWnd));
case WM_DESTROY: return(pMain->MsgDestroy());
case WM_CLOSE: return(pMain->MsgClose(1));
case WM_WINDOWPOSCHANGED:
case WM_SIZE: return(pMain->MsgResized());
case WM_TIMER: return(pMain->MsgTimer());
case WM_ERASEBKGND: return(0);
case WM_PAINT: return(pMain->MsgPaint());
case WM_KEYDOWN: return(pMain->MsgKey((UINT)wParm,1)); break;
case WM_KEYUP: return(pMain->MsgKey((UINT)wParm,0)); break;
}
}
return(DefWindowProc(hWnd,Msg,wParm,lParm));
}
LRESULT Main::MsgCreate(HWND hWnd) {
this->hWnd= hWnd;
SetWindowLongPtr(hWnd,GWLP_USERDATA,(LONG_PTR)this);
ShowWindow(hWnd,SW_SHOWNORMAL);
return(0);
}
LRESULT Main::MsgDestroy(void) {
return(0);
}
LRESULT Main::MsgClose(bool DoPrompt) {
DoExit= true;
DestroyWindow(hWnd);
return(0);
}
LRESULT Main::MsgResized(void) {
RECT rNew;
GetClientRect(hWnd,&rNew);
if(RWID(rNew)!=RWID(rClnt) || RHGT(rNew)!=RHGT(rClnt)) {
rClnt= rNew;
DoResize= true;
}
return(0);
}
LRESULT Main::MsgTimer(void) {
return(0);
}
LRESULT Main::MsgPaint(void) {
if(!hImg) {
ImgCreate(&hImg,hWnd);
GameSetImage(ghGame,hImg);
hUpdateThread= CreateThread(0,0,UpdateProc,this,0,&UpdateThreadID);
}
ValidateRect(hWnd,0);
return(0);
}
LRESULT Main::MsgKey(UINT KeyID, UINT OnOff) {
GameSetControl(ghGame,0,KeyID,OnOff);
return(0);
}
/*************************************************************************/
/** Update loop **/
/*************************************************************************/
DWORD Main::UpdateProc(LPVOID hMain) {
Main *pMain= Ptr((HMAIN)hMain);
if(!pMain)
return(Error(ERR_BADHANDLE,"Main:UpdateProc: Bad hMain[%X]",hMain));
return(pMain->UpdateLoop());
}
int Main::UpdateLoop(void) {
int Err= ERR_OK;
while(IsWindow(hWnd) && !DoExit) {
if(DoResize) {
GameSetArena(ghGame,&rClnt);
ImgResize(hImg,&rClnt);
DoResize= false;
}
GameUpdate(ghGame);
ImgPaint(hImg);
}
ImgDestroy(hImg);
hImg= 0;
hUpdateThread= 0;
return(Err);
}
WebV7 (C)2018 nlited | Rendered by tikope in 60.777ms | 18.118.37.85