/* ================ SoundManager::init ================ */ bool SoundManager::init( HWND hwnd ) { // Initialize direct sound and the primary sound buffer bool result = initDirectSound(hwnd); if (!result) { return false; } // Load wave audio file into secondary buffer result = loadWaveFile("data/sound01.wav", &secondaryBuffer_); if (!result) { return false; } // Play the wave file // result = playWaveFile(); return result; }
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); }