void Main(PlatformAPI *api) { // Application settings Application app; app.api = api; SetApplicationTitle(api, "CPU Rasterizer"); // Mouse setup app.mouse_exclusive = true; app.mouse_sensitivity = 0.8f * 0.0022f; // Sensitivity * source engine scale // Setup player properties app.player_yaw = 0.0f; app.player_pitch = 0.0f; app.player_flags = 0; // Setup camera app.camera.pos = float3(0.0f, 0.0f, -8.0f); app.camera.fov = Tau * 0.25f; // Setup scene CreateTestScene(app.scene); // Set events SetKeyboardEvent(api, &app, OnKeyboardEvent); SetMouseEvent(api, &app, OnMouseEvent); SetMouseCaptureMode(api, MouseCaptureModeExclusive); // Create software renderer app.renderer = CreateSoftwareRenderer(api, 1280, 720, false); // Load default font. app.font = CreateFontFromFile("C:\\Windows\\Fonts\\calibrib.ttf", 18.0f); // Initialize the rasterizer data { app.frame_info = NULL; // Default framebuffer app.framebuffer.width = 1280; app.framebuffer.height = 720; U32 size = GetRequiredMemoryAmount(app.framebuffer, true, true); Initialize(app.framebuffer, malloc(size), true, true); // Threads CreateRasterizerThreads(app); } // Frame update loop U64 frame_start_time = GetTime(api); app.frame_delta = 0.0001f; while (Update(api)) { // Apply player rotation to camera. app.camera.axis[0] = float3(1.0f, 0.0f, 0.0f); app.camera.axis[1] = float3(0.0f, 1.0f, 0.0f); app.camera.axis[2] = float3(0.0f, 0.0f, 1.0f); Rotate(app.camera.axis[0], float3(1.0f, 0.0f, 0.0f), app.player_pitch); Rotate(app.camera.axis[1], float3(1.0f, 0.0f, 0.0f), app.player_pitch); Rotate(app.camera.axis[2], float3(1.0f, 0.0f, 0.0f), app.player_pitch); Rotate(app.camera.axis[0], float3(0.0f, 1.0f, 0.0f), app.player_yaw); Rotate(app.camera.axis[1], float3(0.0f, 1.0f, 0.0f), app.player_yaw); Rotate(app.camera.axis[2], float3(0.0f, 1.0f, 0.0f), app.player_yaw); // Apply player movement to camera float3 player_velocity = 0.0f; if (app.player_flags & PlayerFlagMoveForward) player_velocity += app.camera.axis[2]; if (app.player_flags & PlayerFlagMoveBackward) player_velocity -= app.camera.axis[2]; if (app.player_flags & PlayerFlagMoveRight) player_velocity -= app.camera.axis[0]; if (app.player_flags & PlayerFlagMoveLeft) player_velocity += app.camera.axis[0]; if (Dot(player_velocity, player_velocity) != 0.0f) Normalize(player_velocity); player_velocity *= 5.0f * app.frame_delta; app.camera.pos += player_velocity; // Render the frame LockBufferInfo frame_info; LockBuffer(app.renderer, frame_info); RenderFrame(app, frame_info); PrintDebugStats(app, frame_info); UnlockBuffer(app.renderer); // Calculate frame delta time U64 time = GetTime(api); U64 delta = time - frame_start_time; frame_start_time = time; app.frame_delta = float(delta) / float(U64(1) << U64(32)); } }
LRESULT GameMainWindowWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg>= WM_MOUSEFIRST && msg<= WM_MOUSELAST && msg != WM_MOUSEWHEEL) { SetMouseEvent(&win_mouseEvent,msg,wParam,lParam); } else switch (msg) { case WM_CREATE: if (english_layout == NULL) english_layout = LoadKeyboardLayout("00000409",KLF_ACTIVATE); DSReportWindowCreation(hWnd); return TRUE; case WM_ENDSESSION: case WM_CLOSE: DXCloseMode(); exit(1); break; case WM_SETCURSOR: if (LOWORD(lParam) == HTCLIENT)SetCursor(NULL); else return DefWindowProc(hWnd,msg,wParam,lParam);break; return TRUE; case WM_EXTRACHAR: if (noextra) {noextra = FALSE;break; } case WM_CHAR: if (keyqueuelen<16) { memmove(keyqueue,keyqueue+1,sizeof(*keyqueue)*keyqueuelen); keyqueuelen++; keyqueue[0] = MAKEWORD(wParam,HIWORD(lParam)); } if (msg == WM_CHAR) noextra = TRUE; break; case WM_MOUSEWHEEL: { short delta = HIWORD(wParam); if (keyqueuelen<16) { memmove(keyqueue,keyqueue+1,sizeof(*keyqueue)*keyqueuelen); keyqueuelen++; keyqueue[0] = MAKEWORD(0,delta<0?wheel_mapping[0]:wheel_mapping[1]); } break; } case WM_ACTIVATE: { int fActive = LOWORD(wParam); ActiveWindow = fActive != WA_INACTIVE; break; } case WM_PAINT: { PAINTSTRUCT ps; BeginPaint(hWnd,&ps); DXCopyRects64(0,0,640,480); EndPaint(hWnd,&ps); break; } case WM_RELOADMAP: { char buff[256]; int sektor = wParam; GlobalGetAtomName((ATOM)lParam,buff,256); GlobalDeleteAtom((ATOM)lParam); send_message(E_RELOADMAP,buff,sektor); break; } default: return DefWindowProc(hWnd,msg,wParam,lParam);break; } return 0; }