2016-01-27 00:49:52 chip
Page 1544
📢 PUBLIC
WinMain.c:
1/*************************************************************************/
2/** Main.cpp: Manages the main window, game creation, run, destruction. **/
3/** (C)2016 nlited systems, Chip Doran **/
4/*************************************************************************/
5#include <Windows.h>
6#include "Util.h"
7#include "MyD2D.h"
8#include "Globals.h"
9
10
11class Main {
12public:
13 static __inline Main *Ptr(HMAIN hMain);
14 static __inline Main *PtrWnd(HWND hWnd);
15 static int Create(HMAIN *phMain);
16 int Destroy(void);
17 int Loop(void);
18 //Data
19 UINT32 Signature;
20private:
21 Main(void);
22 ~Main(void);
23 int Create2(void);
24 int CreateClass(void);
25 static LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParm, LPARAM lParm);
26 LRESULT MsgCreate(HWND hWnd);
27 LRESULT MsgDestroy(void);
28 LRESULT MsgClose(bool DoPrompt);
29 LRESULT MsgResized(void);
30 LRESULT MsgTimer(void);
31 LRESULT MsgPaint(void);
32 LRESULT MsgKey(UINT KeyID, UINT OnOff);
33 static DWORD CALLBACK UpdateProc(LPVOID hMain);
34 int UpdateLoop(void);
35 //Data
36 HWND hWnd;
37 RECT rClnt;
38 HIMAGE hImg;
39 HANDLE hUpdateThread;
40 DWORD UpdateThreadID;
41 volatile bool DoResize;
42 volatile bool DoExit;
43};
44
45HD2D ghD2D; //My Factory of Direct2D Factories
46HGAME ghGame;
47
48/*************************************************************************/
49/** Public interface **/
50/*************************************************************************/
51int MainCreate(HMAIN *phMain) {
52 if(IsBadPtr(phMain,sizeof(*phMain),BADPTR_WRITE))
53 return(Error(ERR_BADPTR,"MainCreate: Bad phMain[%X]",phMain));
54 return(Main::Create(phMain));
55}
56
57int MainDestroy(HMAIN hMain) {
58 Main *pMain= Main::Ptr(hMain);
59 if(!pMain)
60 return(Warn(ERR_BADHANDLE,"MainDestroy: Bad hMain[%X]",hMain));
61 return(pMain->Destroy());
62}
63
64int MainLoop(HMAIN hMain) {
65 Main *pMain= Main::Ptr(hMain);
66 if(!pMain)
67 return(ERR_BADHANDLE);
68 return(pMain->Loop());
69}
70
71void DisplayStrA(UINT Type, const char *Str) {
72}
73
74void DisplayStrW(UINT Type, const WCHAR *Str) {
75}
76
77/*************************************************************************/
78/** Public internals **/
79/*************************************************************************/
80Main *Main::Ptr(HMAIN hMain) {
81 Main *pMain= (Main*)hMain;
82 if(!hMain || IsBadPtr(pMain,sizeof(*pMain),BADPTR_RW) || pMain->Signature!=SIGNATURE_MAIN)
83 pMain= 0;
84 return(pMain);
85}
86
87Main *Main::PtrWnd(HWND hWnd) {
88 HMAIN hMain;
89 if(!IsWindow(hWnd))
90 return(0);
91 hMain= (HMAIN)GetWindowLongPtr(hWnd,GWLP_USERDATA);
92 return(Ptr(hMain));
93}
94
95int Main::Create(HMAIN *phMain) {
96 int Err= ERR_OK;
97 Main *pMain= new Main;
98 if(!pMain) {
99 Err= Error(ERR_NOMEM,"Main:Create: NoMem(%d)",sizeof(*pMain));
100 } else if(IsErr(Err= pMain->Create2())) {
101 delete pMain;
102 } else {
103 *phMain= (HMAIN)pMain;
104 }
105 return(Err);
106}
107
108int Main::Destroy(void) {
109 int Err= ERR_OK;
110 delete this;
111 return(Err);
112}
113
114int Main::Loop(void) {
115 int Err= ERR_OK;
116 MSG Msg;
117 while(IsWindow(hWnd)) {
118 if(GetMessage(&Msg,hWnd,0,0)) {
119 TranslateMessage(&Msg);
120 DispatchMessage(&Msg);
121 }
122 }
123 while(hUpdateThread)
124 Sleep(100);
125 return(Err);
126}
127
128/*************************************************************************/
129/** Private internals **/
130/*************************************************************************/
131Main::Main(void) {
132 memset(this,0,sizeof(*this));
133 Signature= SIGNATURE_MAIN;
134}
135
136Main::~Main(void) {
137 Signature|= SIGNATURE_INVALID;
138 GameDestroy(ghGame);
139 ImgDestroy(hImg);
140 MyD2DDestroy(ghD2D);
141}
142
143static const WCHAR *ClassName= {L"ROCKET_CLASS"};
144static const WCHAR *WndName= {L"Rocket2D"};
145
146int Main::Create2(void) {
147 int Err= ERR_OK;
148 DWORD Style= WS_OVERLAPPEDWINDOW;
149 DWORD StyleX= WS_EX_APPWINDOW|WS_EX_OVERLAPPEDWINDOW;
150 RECT rPos= { 100, 100, 700, 500 };
151 if(IsErr(Err= GameCreate(&ghGame))) {
152 Err= Error(Err,__FUNCTION__": Unable to create Game.");
153 } else if(IsErr(Err= MyD2DCreate(&ghD2D,ghInst))) {
154 Err= Error(Err,__FUNCTION__": Unable to create MyD2D Factory.");
155 } else if(IsErr(CreateClass())) {
156 Err= Error(ERR_SYSCREATE,__FUNCTION__": Unable to create class '%S'",ClassName);
157 } else {
158 hWnd= CreateWindowEx(StyleX,ClassName,WndName,Style,rPos.left,rPos.top,RWID(rPos),RHGT(rPos),0,0,ghInst,this);
159 if(!IsWindow(hWnd)) {
160 Err= Error(ERR_SYSCREATE,__FUNCTION__": CreateWindowEx(%S,%S) failed.",ClassName,WndName);
161 }
162 }
163 return(Err);
164}
165
166int Main::CreateClass(void) {
167 int Err= ERR_OK;
168 WNDCLASSEX Class;
169 ATOM hClass;
170 memset(&Class,0,sizeof(Class));
171 Class.cbSize= sizeof(Class);
172 Class.hCursor= LoadCursor(0,IDC_ARROW);
173 Class.hInstance= ghInst;
174 Class.lpfnWndProc= WndProc;
175 Class.lpszClassName= ClassName;
176 Class.style= CS_DBLCLKS;
177 hClass= RegisterClassEx(&Class);
178 if(!hClass) {
179 Err= Error(ERR_SYSCREATE,__FUNCTION__": Unable to register class '%S'",ClassName);
180 }
181 return(Err);
182}
183
184/*************************************************************************/
185/** Message handler **/
186/*************************************************************************/
187LRESULT CALLBACK Main::WndProc(HWND hWnd, UINT Msg, WPARAM wParm, LPARAM lParm) {
188 Main *pMain= (Msg==WM_CREATE) ? Ptr((HMAIN)((CREATESTRUCT*)lParm)->lpCreateParams) : PtrWnd(hWnd);
189 if(pMain) {
190 switch(Msg) {
191 case WM_CREATE: return(pMain->MsgCreate(hWnd));
192 case WM_DESTROY: return(pMain->MsgDestroy());
193 case WM_CLOSE: return(pMain->MsgClose(1));
194 case WM_WINDOWPOSCHANGED:
195 case WM_SIZE: return(pMain->MsgResized());
196 case WM_TIMER: return(pMain->MsgTimer());
197 case WM_ERASEBKGND: return(0);
198 case WM_PAINT: return(pMain->MsgPaint());
199 case WM_KEYDOWN: return(pMain->MsgKey((UINT)wParm,1)); break;
200 case WM_KEYUP: return(pMain->MsgKey((UINT)wParm,0)); break;
201 }
202 }
203 return(DefWindowProc(hWnd,Msg,wParm,lParm));
204}
205
206LRESULT Main::MsgCreate(HWND hWnd) {
207 this->hWnd= hWnd;
208 SetWindowLongPtr(hWnd,GWLP_USERDATA,(LONG_PTR)this);
209 ShowWindow(hWnd,SW_SHOWNORMAL);
210 return(0);
211}
212
213LRESULT Main::MsgDestroy(void) {
214 return(0);
215}
216
217LRESULT Main::MsgClose(bool DoPrompt) {
218 DoExit= true;
219 DestroyWindow(hWnd);
220 return(0);
221}
222
223LRESULT Main::MsgResized(void) {
224 RECT rNew;
225 GetClientRect(hWnd,&rNew);
226 if(RWID(rNew)!=RWID(rClnt) || RHGT(rNew)!=RHGT(rClnt)) {
227 rClnt= rNew;
228 DoResize= true;
229 }
230 return(0);
231}
232
233LRESULT Main::MsgTimer(void) {
234 return(0);
235}
236
237LRESULT Main::MsgPaint(void) {
238 if(!hImg) {
239 ImgCreate(&hImg,hWnd);
240 GameSetImage(ghGame,hImg);
241 hUpdateThread= CreateThread(0,0,UpdateProc,this,0,&UpdateThreadID);
242 }
243 ValidateRect(hWnd,0);
244 return(0);
245}
246
247LRESULT Main::MsgKey(UINT KeyID, UINT OnOff) {
248 GameSetControl(ghGame,0,KeyID,OnOff);
249 return(0);
250}
251
252/*************************************************************************/
253/** Update loop **/
254/*************************************************************************/
255DWORD Main::UpdateProc(LPVOID hMain) {
256 Main *pMain= Ptr((HMAIN)hMain);
257 if(!pMain)
258 return(Error(ERR_BADHANDLE,"Main:UpdateProc: Bad hMain[%X]",hMain));
259 return(pMain->UpdateLoop());
260}
261
262int Main::UpdateLoop(void) {
263 int Err= ERR_OK;
264 while(IsWindow(hWnd) && !DoExit) {
265 if(DoResize) {
266 GameSetArena(ghGame,&rClnt);
267 ImgResize(hImg,&rClnt);
268 DoResize= false;
269 }
270 GameUpdate(ghGame);
271 ImgPaint(hImg);
272 }
273 ImgDestroy(hImg);
274 hImg= 0;
275 hUpdateThread= 0;
276 return(Err);
277}
278
WebV7 (C)2018 nlited | Rendered by tikope in 2570.707ms | 216.73.216.190