#include #include #include #include #include #pragma once /* * --------------- * Global flags: * --------------- * * HANDMADE_SLOW * 0 - No slow code allowed * 1 - Slow code welcome * * HANDMADE_INTERNAL * 0 - Build for public release * 1 - Build for developer only * * HANDMADE_WIN32 * 0 - Not a windows build * 1 - This is a windows build * */ #if HANDMADE_SLOW #define Assert(Expression) if (!(Expression)) {*(volatile int *)0 = 0;} #else #define Assert(Expression) #endif #define Kilobytes(Value) (Value*1024) #define Megabytes(Value) (Kilobytes(Value)*1024) #define Gigabytes(Value) (Megabytes(Value)*1024) #define Terabytes(Value) (Gigabytes(Value)*1024) #define ArrayCount(Array) (sizeof(Array) / sizeof((Array)[0])) #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; #define MAX_SAFE_UINT32 0xFFFFFFFF inline uint32 safeTruncateUInt64(uint64 val) { Assert(val <= MAX_SAFE_UINT32); return (uint32)val; } // === Platform to game services === #if HANDMADE_INTERNAL struct DebugReadFileResult { uint32 contentsSize; void *contents; }; #define DEBUG_PLATFORM_READ_ENTIRE_FILE(name) DebugReadFileResult name(char *filename) typedef DEBUG_PLATFORM_READ_ENTIRE_FILE(DebugPlatformReadEntireFileFn); #define DEBUG_PLATFORM_FREE_FILE_MEMORY(name) void name(void *fileMemory) typedef DEBUG_PLATFORM_FREE_FILE_MEMORY(DebugPlatformFreeFileMemoryFn); #define DEBUG_PLATFORM_WRITE_ENTIRE_FILE(name) bool32 name(char *filename, uint32 memorySize, void *memory) typedef DEBUG_PLATFORM_WRITE_ENTIRE_FILE(DebugPlatformWriteEntireFileFn); #define DEBUG_PLATFORM_PRINTF(name) void name(wchar_t* format, ...) typedef DEBUG_PLATFORM_PRINTF(DebugPrintfFn); #endif // Game to platform layer services struct GameSoundOutputBuffer { int samplesPerSecond; int sampleCount; int16 *samples; }; struct GameOffscreenBuffer { void *memory; int width; int height; int bytesPerPixel; int pitch; // Bytes per row }; struct GameButtonState { int halfTransitionCount; bool32 endedDown; }; struct GameControllerInput { bool32 isAnalog; real32 stickAvgY; real32 stickAvgX; union { GameButtonState buttons[6]; struct { GameButtonState stickUp; GameButtonState stickDown; GameButtonState stickLeft; GameButtonState stickRight; GameButtonState btnUp; GameButtonState btnDown; GameButtonState btnLeft; GameButtonState btnRight; GameButtonState leftShoulder; GameButtonState rightShoulder; }; }; }; struct GameInput { GameControllerInput controllers[5]; }; struct GameMemory { bool32 isInitialised; uint64 permanentStorageSize; void *permanentStorage; // required to be initialised to zero at startup uint64 transientStorageSize; void *transientStorage; // required to be initialised to zero at startup DebugPlatformReadEntireFileFn *debugReadEntireFile; DebugPlatformFreeFileMemoryFn *debugFreeFileMemory; DebugPlatformWriteEntireFileFn *debugWriteEntireFile; DebugPrintfFn *debug_printf; }; struct GameState { int toneHz; int greenOffset; int blueOffset; real32 tSine; int playerY; int playerX; }; // === Game to platform services === #define GAME_UPDATE_AND_RENDER(name) void name(GameMemory *memory, GameOffscreenBuffer *videoBuf, GameInput *input) typedef GAME_UPDATE_AND_RENDER(GameUpdateAndRenderFn); GAME_UPDATE_AND_RENDER(gameUpdateAndRenderStub) {} #define GAME_GET_SOUND_SAMPLES(name) void name(GameMemory *memory, GameSoundOutputBuffer *soundBuf) typedef GAME_GET_SOUND_SAMPLES(GameGetSoundSamplesFn); GAME_GET_SOUND_SAMPLES(gameGetSoundSamplesStub) {}