PageRenderTime 47ms CodeModel.GetById 14ms app.highlight 29ms RepoModel.GetById 1ms app.codeStats 0ms

/src/app/app.cpp

https://bitbucket.org/vivkin/gam3b00bs/
C++ | 347 lines | 258 code | 76 blank | 13 comment | 40 complexity | 8dc94ca391adc8e2040b56379e9be273 MD5 | raw file
  1
  2
  3#include "common.h"
  4#include "app.h"
  5#include "network/network.h"
  6#include "sound/sound.h"
  7#include "renderer/device.h"
  8#include "log.h"
  9#include <stdio.h>
 10#include <windows.h>
 11
 12#define CONFIG_FILE "./b00bs.ini"
 13
 14namespace app
 15{
 16	struct state
 17	{
 18		timings   time;
 19		int64     ticks_prev;
 20		int64     ticks_cur;
 21
 22		HWND      hwnd;
 23	};
 24	static state g_app = {};
 25
 26	namespace input
 27	{
 28		static state key_states[INPUT_KEYS_MAX];
 29		static state button_states[INPUT_BUTTONS_MAX];
 30		static int16 cursor_rel[2], wheel_rel;
 31		static RECT  old_clip;
 32
 33		bool init()
 34		{
 35			ASSERT(g_app.hwnd);
 36
 37			RAWINPUTDEVICE rid[2]; // keyboard & mouse
 38			RECT rect;
 39
 40			memset(key_states, 0, sizeof(state) * INPUT_KEYS_MAX);
 41			memset(button_states, 0, sizeof(state) * INPUT_BUTTONS_MAX);
 42			cursor_rel[0] = cursor_rel[1] = wheel_rel = 0;
 43
 44			GetWindowRect(g_app.hwnd, &rect);
 45			SetCursorPos((rect.left + rect.right) / 2, (rect.bottom + rect.top) / 2);
 46
 47			GetClipCursor(&old_clip);
 48			ClipCursor(&rect);
 49			//ShowCursor(FALSE); // orly?
 50
 51			rid[0].usUsagePage = 0x01;
 52			rid[0].usUsage     = 0x02; // mouse
 53			rid[0].dwFlags     = 0; //RIDEV_NOLEGACY;
 54			rid[0].hwndTarget  = g_app.hwnd;
 55
 56			rid[1].usUsagePage = 0x01;
 57			rid[1].usUsage     = 0x06; // keyboard
 58			rid[1].dwFlags     = 0; //RIDEV_NOLEGACY;
 59			rid[1].hwndTarget  = g_app.hwnd;
 60
 61			return RegisterRawInputDevices(rid, 2, sizeof(RAWINPUTDEVICE)) != 0;
 62		}
 63
 64		void term()
 65		{
 66			ClipCursor(&old_clip);
 67		}
 68
 69		bool tick()
 70		{
 71			uint32_t i;
 72
 73			cursor_rel[0] = cursor_rel[1] = wheel_rel = 0;
 74
 75			for (i = 0; i < INPUT_KEYS_MAX; ++i)
 76				if (key_states[i] == DOWN)
 77					key_states[i] = PRESSED;
 78
 79			for (i = 0; i < INPUT_BUTTONS_MAX; ++i)
 80				if (button_states[i] == DOWN)
 81					button_states[i] = PRESSED;
 82
 83			return true;
 84		}
 85
 86		state get_key_state(uint16 key)
 87		{
 88			ASSERT(key < INPUT_KEYS_MAX);
 89
 90			return key_states[key];
 91		}
 92
 93		state get_button_state(uint16 button)
 94		{
 95			ASSERT(button < INPUT_BUTTONS_MAX);
 96
 97			return button_states[button];
 98		}
 99
100		int16 get_wheel_rel()
101		{
102			return wheel_rel;
103		}
104
105		void get_cursor_pos(int16 *x, int16 *y)
106		{
107			ASSERT(x && y);
108
109			POINT pt;
110
111			GetCursorPos(&pt);
112			ScreenToClient(g_app.hwnd, &pt);
113
114			*x = (int16)pt.x;
115			*y = (int16)pt.y;
116		}
117
118		void get_cursor_rel(int16 *xr, int16 *yr)
119		{
120			ASSERT(xr && yr);
121
122			*xr = cursor_rel[0];
123			*yr = cursor_rel[1];
124		}
125	}
126
127	///////////////////////////////////////////////////////////////////////
128	uint32 get_config_int(const char* param_name, const char* section, uint32 default_val)
129	{
130		return GetPrivateProfileIntA(section,param_name,default_val,CONFIG_FILE);
131	}
132
133	///////////////////////////////////////////////////////////////////////
134
135	inline static int64 get_ticks()
136	{
137		int64 ticks;
138		QueryPerformanceCounter( (LARGE_INTEGER*) &ticks );
139		return ticks;
140	}
141
142	inline static int64 get_freq()
143	{
144		int64 f;
145		QueryPerformanceFrequency( (LARGE_INTEGER*) &f );
146		return f;
147	}
148
149	static void time_update()
150	{
151		g_app.ticks_cur = get_ticks();
152		double dt = (g_app.ticks_cur - g_app.ticks_prev) / (double)get_freq();
153		g_app.time.dt =  (float) dt;
154		g_app.time.T  += dt;
155		g_app.ticks_prev = g_app.ticks_cur;
156	}
157
158	//////////////////////////////////////////////////////////////////////////
159
160	static LRESULT APIENTRY wndproc( HWND, UINT, unsigned, long );
161
162	static bool init_window()
163	{
164		//WNDCLASSA wc = { 0, wndproc, 0, 0, GetModuleHandleA(0), LoadIcon(0,IDI_APPLICATION), LoadCursor(0,IDC_ARROW), (HBRUSH)GetStockObject(NULL_BRUSH), 0, "wndclass.4" };
165		WNDCLASSA wc = { 0, wndproc, 0, 0, GetModuleHandleA(0), LoadIcon(0,IDI_APPLICATION), LoadCursor(0,IDC_ARROW), (HBRUSH)GetStockObject(WHITE_BRUSH), 0, "wndclass.4" };
166		RegisterClassA( &wc );
167		g_app.hwnd = CreateWindowA( "wndclass.4", "Render window", WS_VISIBLE | WS_OVERLAPPEDWINDOW, 100, 100, 800, 600, 0, 0, GetModuleHandleA(0), 0 );
168		return g_app.hwnd != 0;
169	}
170
171
172	//////////////////////////////////////////////////////////////////////////
173
174
175	// TODO: add more subsystem init here, in the required order
176	bool   init()
177	{
178		g_app.ticks_cur = g_app.ticks_prev  = get_ticks();
179
180		init_window();
181		if( !g_app.hwnd )
182		{
183			fprintf( stderr, "Error: could not create window\n" );
184			return false;
185		}
186		if (!input::init())
187		{
188			log_write("Error: could not initialize input layer\n");
189			return false;
190		}
191
192		size_t network_pool_sz = get_config_int("network_pool","engine",8 * 1024 * 1024);
193		if (!network::init(malloc(network_pool_sz), network_pool_sz))
194		{
195			fprintf( stderr, "Error: could not initialize network layer\n" );
196			return false;
197		}
198		size_t sound_pool_sz = get_config_int("sound_pool","engine",256 * 1024 * 1024);
199		size_t sound_decoder_sz = get_config_int("decoder_pool","engine",8 * 1024 * 1024);
200		if (!snd::init(malloc(sound_pool_sz),sound_pool_sz,sound_decoder_sz))
201		{
202			fprintf( stderr, "Error: could not sound system\n" );
203			return false;
204		}
205
206		RECT rect;
207		GetClientRect(g_app.hwnd, &rect);
208		renderer_desc_t renderer_desc;
209		renderer_desc.depth = D3DFMT_D24X8;
210		renderer_desc.width = rect.left - rect.right;
211		renderer_desc.height = rect.bottom - rect.top;
212		renderer_desc.window = g_app.hwnd;
213		renderer_desc.windowed = true;
214		renderer_desc.vsync = false;
215		renderer_desc.refresh_rate = 0;
216		renderer_desc.multisampling = 8;
217		if( renderer::init(renderer_desc) )
218		{
219			log_write("Error: could not initialize gfx layer");
220			return false;
221		}
222
223		if( !test_init() )
224		{
225			log_write("Error: test data initialization failed");
226			return false;
227		}
228		// moar!
229		
230
231		return true;
232	}
233
234	void   term()
235	{
236		renderer::term();
237		network::term();
238		input::term();
239
240		DestroyWindow(g_app.hwnd);
241		UnregisterClass("wndclass.4", GetModuleHandleA(0));
242		g_app.hwnd = NULL;
243	}
244
245	// moves the frame
246	bool   tick()
247	{
248	    MSG msg = {};
249		while( TRUE == PeekMessageA(&msg,0,0,0,PM_REMOVE ) )
250		{
251			if( msg.message == WM_QUIT )
252				return false;
253			TranslateMessage( &msg );
254			DispatchMessageA( &msg );
255		}
256
257		time_update();
258
259		// TODO: do stuff
260//		renderer::tick();
261
262		Sleep(5);
263		return true;
264	}
265
266	// returns timings for the last tick
267	timings   time()
268	{
269		return g_app.time;
270	}
271
272
273	///////////////////////////////////////////
274
275
276	static LRESULT APIENTRY wndproc( HWND hwnd, UINT msg, UINT wp, LONG lp )
277	{
278		static bool dont_resize_yet = false;
279		static bool resizing = false;
280		static RECT rcwnd = {0};
281		static RAWINPUT ri;
282		static UINT risize;
283
284		switch( msg )
285		{
286		case WM_CREATE:
287			GetClientRect( hwnd, &rcwnd );
288			break;
289
290		case WM_DESTROY: PostQuitMessage(0); return 0;
291
292		case WM_ENTERSIZEMOVE: break;
293		case WM_SIZE: break;
294		case WM_EXITSIZEMOVE: break;
295
296		case WM_INPUT:
297		{
298			risize = sizeof(ri);
299
300			if (GetRawInputData((HRAWINPUT)lp, RID_INPUT, (PBYTE)&ri, &risize, sizeof(RAWINPUTHEADER)) == (UINT)(-1))
301				return FALSE;
302
303			if (ri.header.dwType == RIM_TYPEKEYBOARD && ri.data.keyboard.VKey < INPUT_KEYS_MAX)
304			{
305				input::state state = input::key_states[ri.data.keyboard.VKey];
306
307				if (ri.data.keyboard.Flags & RI_KEY_BREAK)
308					state = input::UP;
309				else if (state == input::UP)
310					state = input::DOWN;
311
312				input::key_states[ri.data.keyboard.VKey] = state;
313			} else if (ri.header.dwType == RIM_TYPEMOUSE) 
314			{
315				for (uint32 i = 0, d, u; i < INPUT_BUTTONS_MAX; ++i)
316				{
317					input::state state = input::button_states[i];
318
319					d = 1 << (i << 1);
320					u = d << 1;
321
322					if ((ri.data.mouse.usButtonFlags & d) && state == input::UP)
323						state = input::DOWN;
324					else if (ri.data.mouse.usButtonFlags & u)
325						state = input::UP;
326
327					input::button_states[i] = state;
328				}
329
330				if (ri.data.mouse.usButtonFlags & RI_MOUSE_WHEEL)
331					input::wheel_rel += (int16)ri.data.mouse.usButtonData;
332
333				if (ri.data.mouse.usFlags == MOUSE_MOVE_RELATIVE)
334				{
335					input::cursor_rel[0] += (int16)ri.data.mouse.lLastX;
336					input::cursor_rel[1] += (int16)ri.data.mouse.lLastY;
337				}
338			}
339
340			return FALSE;
341		}
342		}
343		return DefWindowProcA( hwnd, msg, wp, lp );
344	}
345
346}
347