|
@@ -1,30 +1,9 @@ |
|
|
#include <cstdarg> |
|
|
|
|
|
#include <cstdio> |
|
|
|
|
|
#include <cstdlib> |
|
|
|
|
|
|
|
|
// Windows and Windows DLLs |
|
|
#include <windows.h> |
|
|
#include <windows.h> |
|
|
#include <stdint.h> |
|
|
|
|
|
#include <Xinput.h> |
|
|
#include <Xinput.h> |
|
|
#include <dsound.h> |
|
|
#include <dsound.h> |
|
|
#include <math.h> |
|
|
|
|
|
|
|
|
|
|
|
#define internal static // for functions |
|
|
|
|
|
#define local_persist static // for static variables in a scope |
|
|
|
|
|
#define global static // for global variables |
|
|
|
|
|
|
|
|
|
|
|
typedef uint8_t uint8; |
|
|
|
|
|
typedef uint16_t uint16; |
|
|
|
|
|
typedef uint32_t uint32; |
|
|
|
|
|
typedef uint64_t uint64; |
|
|
|
|
|
|
|
|
|
|
|
typedef int8_t int8; |
|
|
|
|
|
typedef int16_t int16; |
|
|
|
|
|
typedef int32_t int32; |
|
|
|
|
|
typedef int64_t int64; |
|
|
|
|
|
|
|
|
|
|
|
typedef float real32; |
|
|
|
|
|
typedef double real64; |
|
|
|
|
|
|
|
|
|
|
|
typedef int32_t bool32; |
|
|
|
|
|
|
|
|
#include "handmade.cpp" |
|
|
|
|
|
|
|
|
struct Win32OffscreenBuffer { |
|
|
struct Win32OffscreenBuffer { |
|
|
BITMAPINFO info; |
|
|
BITMAPINFO info; |
|
@@ -46,16 +25,6 @@ global bool running; |
|
|
global Win32OffscreenBuffer globalBackBuffer; |
|
|
global Win32OffscreenBuffer globalBackBuffer; |
|
|
global LPDIRECTSOUNDBUFFER globalSecondaryBuffer; |
|
|
global LPDIRECTSOUNDBUFFER globalSecondaryBuffer; |
|
|
|
|
|
|
|
|
void debug_printf(char* format, ...) { |
|
|
|
|
|
int bufsize = strlen(format)*10; |
|
|
|
|
|
char *output = (char*)malloc(bufsize); |
|
|
|
|
|
va_list list; |
|
|
|
|
|
va_start(list, format); |
|
|
|
|
|
vsprintf_s(output, bufsize, format, list); |
|
|
|
|
|
OutputDebugStringA(output); |
|
|
|
|
|
free(output); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// XInputGetState |
|
|
// XInputGetState |
|
|
#define X_INPUT_GET_STATE(name) DWORD WINAPI name(DWORD dwUserIndex, XINPUT_STATE *pState) |
|
|
#define X_INPUT_GET_STATE(name) DWORD WINAPI name(DWORD dwUserIndex, XINPUT_STATE *pState) |
|
|
typedef X_INPUT_GET_STATE(XInputGetStateFn); |
|
|
typedef X_INPUT_GET_STATE(XInputGetStateFn); |
|
@@ -72,21 +41,6 @@ global XInputSetStateFn *XInputSetStateDyn = XInputSetStateStub; |
|
|
|
|
|
|
|
|
typedef HRESULT WINAPI DirectSoundCreateFn(LPCGUID pcGuidDevice, LPDIRECTSOUND *ppDS, LPUNKNOWN pUnkOuter); |
|
|
typedef HRESULT WINAPI DirectSoundCreateFn(LPCGUID pcGuidDevice, LPDIRECTSOUND *ppDS, LPUNKNOWN pUnkOuter); |
|
|
|
|
|
|
|
|
internal void renderWeirdGradient(Win32OffscreenBuffer *buffer, int xOffset, int yOffset) { |
|
|
|
|
|
int bytesPerPixel = 4; |
|
|
|
|
|
int pitch = buffer->width*bytesPerPixel; |
|
|
|
|
|
uint8 *row = (uint8 *)buffer->memory; |
|
|
|
|
|
for (int y = 0; y < buffer->height; y++) { |
|
|
|
|
|
uint32 *pixel = (uint32*)row; |
|
|
|
|
|
for (int x = 0; x < buffer->width; x++) { |
|
|
|
|
|
uint8 blue = x + xOffset; |
|
|
|
|
|
uint8 green = y + yOffset; |
|
|
|
|
|
*pixel++ = (green << 8) | blue; |
|
|
|
|
|
} |
|
|
|
|
|
row += pitch; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal void resizeDIBSection(Win32OffscreenBuffer *buffer, int width, int height) { |
|
|
internal void resizeDIBSection(Win32OffscreenBuffer *buffer, int width, int height) { |
|
|
if (buffer->memory) { |
|
|
if (buffer->memory) { |
|
|
VirtualFree(buffer->memory, NULL, MEM_RELEASE); |
|
|
VirtualFree(buffer->memory, NULL, MEM_RELEASE); |
|
@@ -94,7 +48,6 @@ internal void resizeDIBSection(Win32OffscreenBuffer *buffer, int width, int heig |
|
|
|
|
|
|
|
|
buffer->width = width; |
|
|
buffer->width = width; |
|
|
buffer->height = height; |
|
|
buffer->height = height; |
|
|
buffer->bytesPerPixel = 4; |
|
|
|
|
|
|
|
|
|
|
|
buffer->info.bmiHeader.biSize = sizeof(buffer->info.bmiHeader); |
|
|
buffer->info.bmiHeader.biSize = sizeof(buffer->info.bmiHeader); |
|
|
buffer->info.bmiHeader.biWidth = buffer->width; |
|
|
buffer->info.bmiHeader.biWidth = buffer->width; |
|
@@ -103,7 +56,7 @@ internal void resizeDIBSection(Win32OffscreenBuffer *buffer, int width, int heig |
|
|
buffer->info.bmiHeader.biBitCount = 32; |
|
|
buffer->info.bmiHeader.biBitCount = 32; |
|
|
buffer->info.bmiHeader.biCompression = BI_RGB; |
|
|
buffer->info.bmiHeader.biCompression = BI_RGB; |
|
|
|
|
|
|
|
|
int bitmapSize = buffer->width*buffer->height*buffer->bytesPerPixel; |
|
|
|
|
|
|
|
|
int bitmapSize = buffer->width*buffer->height*4; |
|
|
buffer->memory = VirtualAlloc(NULL, bitmapSize, MEM_COMMIT, PAGE_READWRITE); |
|
|
buffer->memory = VirtualAlloc(NULL, bitmapSize, MEM_COMMIT, PAGE_READWRITE); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -300,17 +253,14 @@ internal void win32FillSoundBuffer(Win32SoundOutput *soundOutput, DWORD byteToLo |
|
|
} |
|
|
} |
|
|
globalSecondaryBuffer->Unlock(region1, region1Size, region2, region2Size); |
|
|
globalSecondaryBuffer->Unlock(region1, region1Size, region2, region2Size); |
|
|
} else { |
|
|
} else { |
|
|
OutputDebugStringA("No lock!\n"); |
|
|
|
|
|
|
|
|
// no lock! |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int APIENTRY WinMain( |
|
|
|
|
|
HINSTANCE instance, |
|
|
|
|
|
HINSTANCE prevInstance, |
|
|
|
|
|
PSTR commandLine, |
|
|
|
|
|
int commandShow |
|
|
|
|
|
) { |
|
|
|
|
|
win32LoadXInput(); |
|
|
|
|
|
|
|
|
int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLine, int commandShow) { |
|
|
|
|
|
LARGE_INTEGER performanceFrequencyResult; |
|
|
|
|
|
QueryPerformanceFrequency(&performanceFrequencyResult); |
|
|
|
|
|
int64 performanceFrequency = performanceFrequencyResult.QuadPart; |
|
|
|
|
|
|
|
|
WNDCLASSA windowClass = {}; |
|
|
WNDCLASSA windowClass = {}; |
|
|
windowClass.style = CS_VREDRAW | CS_HREDRAW; |
|
|
windowClass.style = CS_VREDRAW | CS_HREDRAW; |
|
@@ -356,10 +306,15 @@ int APIENTRY WinMain( |
|
|
soundOutput.bytesPerSample = sizeof(int16)*2; |
|
|
soundOutput.bytesPerSample = sizeof(int16)*2; |
|
|
soundOutput.secondaryBufferSize = soundOutput.samplesPerSecond*soundOutput.bytesPerSample; |
|
|
soundOutput.secondaryBufferSize = soundOutput.samplesPerSecond*soundOutput.bytesPerSample; |
|
|
|
|
|
|
|
|
|
|
|
win32LoadXInput(); |
|
|
win32InitSound(window, soundOutput.samplesPerSecond, soundOutput.secondaryBufferSize); |
|
|
win32InitSound(window, soundOutput.samplesPerSecond, soundOutput.secondaryBufferSize); |
|
|
|
|
|
|
|
|
win32FillSoundBuffer(&soundOutput, 0, soundOutput.secondaryBufferSize); |
|
|
win32FillSoundBuffer(&soundOutput, 0, soundOutput.secondaryBufferSize); |
|
|
globalSecondaryBuffer->Play(0, 0, DSBPLAY_LOOPING); |
|
|
globalSecondaryBuffer->Play(0, 0, DSBPLAY_LOOPING); |
|
|
|
|
|
|
|
|
|
|
|
LARGE_INTEGER lastCounter; |
|
|
|
|
|
QueryPerformanceCounter(&lastCounter); |
|
|
|
|
|
int64 lastCycleCount = __rdtsc(); |
|
|
while (running) { |
|
|
while (running) { |
|
|
while (PeekMessageA(&message, NULL, NULL, NULL, PM_REMOVE)) { |
|
|
while (PeekMessageA(&message, NULL, NULL, NULL, PM_REMOVE)) { |
|
|
if (message.message == WM_QUIT) { |
|
|
if (message.message == WM_QUIT) { |
|
@@ -402,10 +357,19 @@ int APIENTRY WinMain( |
|
|
stickXNorm = stickX / 32767.0; |
|
|
stickXNorm = stickX / 32767.0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
yOffset += stickY/5000; |
|
|
|
|
|
xOffset -= stickX/5000; |
|
|
|
|
|
|
|
|
float factor = leftShoulder ? 2.5 : 1.0; |
|
|
|
|
|
yOffset += stickY/5000.0 * factor; |
|
|
|
|
|
xOffset -= stickX/5000.0 * factor; |
|
|
|
|
|
|
|
|
renderWeirdGradient(&globalBackBuffer, xOffset, yOffset); |
|
|
|
|
|
|
|
|
GameOffscreenBuffer buffer = {}; |
|
|
|
|
|
buffer.memory = globalBackBuffer.memory; |
|
|
|
|
|
buffer.width = globalBackBuffer.width; |
|
|
|
|
|
buffer.height = globalBackBuffer.height; |
|
|
|
|
|
|
|
|
|
|
|
GameInput input = {}; |
|
|
|
|
|
input.xOffset = xOffset; |
|
|
|
|
|
input.yOffset = yOffset; |
|
|
|
|
|
gameUpdateAndRender(&buffer, &input); |
|
|
|
|
|
|
|
|
// Sound test |
|
|
// Sound test |
|
|
DWORD playCursor; |
|
|
DWORD playCursor; |
|
@@ -424,6 +388,18 @@ int APIENTRY WinMain( |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
win32DrawBufferInWindow(&globalBackBuffer, window); |
|
|
win32DrawBufferInWindow(&globalBackBuffer, window); |
|
|
|
|
|
|
|
|
|
|
|
LARGE_INTEGER endCounter; |
|
|
|
|
|
QueryPerformanceCounter(&endCounter); |
|
|
|
|
|
int64 endCycleCount = __rdtsc(); |
|
|
|
|
|
int32 cyclesElapsed = endCycleCount - lastCycleCount; |
|
|
|
|
|
lastCycleCount = endCycleCount; |
|
|
|
|
|
|
|
|
|
|
|
int64 counterElapsed = endCounter.QuadPart - lastCounter.QuadPart; |
|
|
|
|
|
real32 msElapsed = (real32)(1000.0f*counterElapsed) / performanceFrequency; |
|
|
|
|
|
real32 fps = (real32)(1000.0f*performanceFrequency/(real32)counterElapsed)/1000.0f; |
|
|
|
|
|
debug_printf(L"%f ms, %f fps, %f Mcl, %fGHz\n", msElapsed, fps, cyclesElapsed / 1000000.0f, (cyclesElapsed/(msElapsed*1000))/1000000.0f); |
|
|
|
|
|
lastCounter = endCounter; |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
// failed |
|
|
// failed |
|
@@ -434,4 +410,3 @@ int APIENTRY WinMain( |
|
|
return(0); |
|
|
return(0); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|