void gameUpdateAndRender(GameMemory* memory, OffScreenBuffer *buf, GameSoundOutput* sb, const InputContext* inputContext, real32_t secsSinceLastFrame) { GameState* state = (GameState*)memory->permanentStorage; if(!state->isInited) { state->tone = 512; state->isInited = true; } for(uint32_t i = 0; i < ARRAY_SIZE(inputContext->controllers); i++) { const ControllerInput* ci = &inputContext->controllers[i]; if(ci->isAnalog) { state->tone = 512 + (int)(256.0f*ci->avgY); state->blueOffset += ci->avgX * 4 * secsSinceLastFrame; state->greenOffset += ci->avgY * 4 * secsSinceLastFrame ; } else { real32_t velocity = 500 * secsSinceLastFrame; if(ci->directionLeft.isEndedDown) { state->blueOffset -= velocity; } else if(ci->directionRight.isEndedDown) { state->blueOffset += velocity; } if(ci->directionUp.isEndedDown) { state->greenOffset -= velocity; } else if(ci->directionDown.isEndedDown) { state->greenOffset += velocity; } } } outputSound(sb, state->tone); renderWeirdGradient(buf, state->blueOffset, state->greenOffset); }
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ loadXInput(); WNDCLASSA windowClass = {}; resizeDIBSection(&globalBackBuffer, 1280, 720); // TODO: Check if HREDRAW/VREDRAW/OWNDC still matter. windowClass.style = CS_HREDRAW|CS_VREDRAW; windowClass.lpfnWndProc = MainWindowProc; windowClass.hInstance = hInstance; // WindowClass.hIcon; windowClass.lpszClassName = "HandMadeHeroWindowClass"; if ( RegisterClass(&windowClass) ) { HWND windowHandle = CreateWindowEx( 0, windowClass.lpszClassName, "Handmade Hero", WS_OVERLAPPEDWINDOW|WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, 0); if ( windowHandle ) { running = true; // graphics test int xOffset = 0; int yOffset = 0; // sound test int samplesPerSecond = 48000; uint32 runningSampleIndex = 0; int toneHz = 256; int bytesPerSample = sizeof(int16)*2; int squareWavePeriod = samplesPerSecond/toneHz; int halfSquareWavePeriod = squareWavePeriod / 2; int secondaryBufferSize = samplesPerSecond*bytesPerSample; initDirectSound(windowHandle, samplesPerSecond, secondaryBufferSize); globalSecondaryBuffer->Play(0, 0, DSBPLAY_LOOPING); while ( running ) { MSG message; while ( PeekMessage(&message, 0, 0, 0, PM_REMOVE) ) { if ( message.message == WM_QUIT ) { running = false; } TranslateMessage(&message); DispatchMessage(&message); } // TODO: should we poll this more frequently? for ( DWORD controllerIdx = 0; controllerIdx < XUSER_MAX_COUNT; ++controllerIdx ) { XINPUT_STATE controllerState; // this controller is plugged in if ( XInputGetState(controllerIdx, &controllerState) == ERROR_SUCCESS ) { // see if controllerstate.dwPacketNumber increments too quickly XINPUT_GAMEPAD *pad = &controllerState.Gamepad; bool up = (pad->wButtons & XINPUT_GAMEPAD_DPAD_UP); bool down = (pad->wButtons & XINPUT_GAMEPAD_DPAD_DOWN); bool left = (pad->wButtons & XINPUT_GAMEPAD_DPAD_LEFT); bool right = (pad->wButtons & XINPUT_GAMEPAD_DPAD_RIGHT); bool start = (pad->wButtons & XINPUT_GAMEPAD_START); bool back = (pad->wButtons & XINPUT_GAMEPAD_BACK); bool leftThumb = (pad->wButtons & XINPUT_GAMEPAD_LEFT_THUMB); bool rightThumb = (pad->wButtons & XINPUT_GAMEPAD_RIGHT_THUMB); bool leftShoulder = (pad->wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER); bool rightShoulder = (pad->wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER); bool aButton = (pad->wButtons & XINPUT_GAMEPAD_A); bool bButton = (pad->wButtons & XINPUT_GAMEPAD_B); bool xButton = (pad->wButtons & XINPUT_GAMEPAD_X); bool yButton = (pad->wButtons & XINPUT_GAMEPAD_Y); int16 stickX = pad->sThumbLX; int16 stickY = pad->sThumbLY; xOffset -= stickX>>12; yOffset += stickY>>12; if ( xButton ) { XINPUT_VIBRATION vibration; vibration.wLeftMotorSpeed = 65534; vibration.wRightMotorSpeed = 65534; XInputSetState(0, &vibration); } // controller not available } else { } } renderWeirdGradient(&globalBackBuffer, xOffset, yOffset); DWORD playCursor; DWORD writeCursor; if ( SUCCEEDED(globalSecondaryBuffer->GetCurrentPosition(&playCursor, &writeCursor)) ) { // Samples: // 16bit 16bit, etc.. // [LEFT RIGHT] LEFT RIGHT LEFT RIGHT .... // direct sound output test: VOID *region1; DWORD region1Size; VOID *region2; DWORD region2Size; DWORD byteToLock = (runningSampleIndex*bytesPerSample) % secondaryBufferSize; DWORD bytesToWrite; if ( byteToLock > playCursor ) { bytesToWrite = (secondaryBufferSize - byteToLock); bytesToWrite += playCursor; } else { bytesToWrite = playCursor - byteToLock; } if ( SUCCEEDED(globalSecondaryBuffer->Lock(byteToLock,bytesToWrite, ®ion1, ®ion1Size, ®ion2, ®ion2Size, 0)) ) { int16 *sampleOut = (int16*)region1; DWORD region1SampleCount = region1Size/bytesPerSample; for ( DWORD sampleIndex = 0; sampleIndex < region1SampleCount; ++sampleIndex ) { int16 sampleValue = ((runningSampleIndex++ / halfSquareWavePeriod) % 2) ? 16000 : -16000; *sampleOut++ = sampleValue; *sampleOut++ = sampleValue; } DWORD region2SampleCount = region2Size/bytesPerSample; sampleOut = (int16*)region2; for ( DWORD sampleIndex = 0; sampleIndex < region2SampleCount; ++sampleIndex ) { int16 sampleValue = ((runningSampleIndex++ / halfSquareWavePeriod) % 2) ? 16000 : -16000; *sampleOut++ = sampleValue; *sampleOut++ = sampleValue; } } } HDC deviceContext = GetDC(windowHandle); win32_window_dimensions windowDimensions = getWindowDimensions(windowHandle); displayBufferInWindow(&globalBackBuffer, deviceContext, windowDimensions.width, windowDimensions.height); ReleaseDC(windowHandle, deviceContext); }