/src/app/app.cpp
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