diff --git a/misc/build.bat b/misc/build.bat index 709ba73..a393794 100644 --- a/misc/build.bat +++ b/misc/build.bat @@ -9,7 +9,7 @@ set commonCompilerFlags=^ -Oi %= Always use intrinsics =%^ -EHa- %= Disable exception handling =%^ -GR- %= Never use runtime type info from C++ =%^ - -WX -W4 -wd4201 -wd4100 -wd4189 %= Compiler warnings, -WX warnings as errors, -W4 warning level 4, -wdXXXX disable warning XXXX =%^ + -WX -W4 -wd4201 -wd4100 -wd4189 -wd4505 %= Compiler warnings, -WX warnings as errors, -W4 warning level 4, -wdXXXX disable warning XXXX =%^ -DHANDMADE_INTERNAL=1 -DHANDMADE_SLOW=1 -DHANDMADE_WIN32=1 %= Custom #defines =%^ -FC %= Full path of source code file in diagnostics =%^ -Zi %= Generate debugger info =% diff --git a/src/handmade.cpp b/src/handmade.cpp index efbf0cd..17dac47 100644 --- a/src/handmade.cpp +++ b/src/handmade.cpp @@ -2,49 +2,59 @@ #define PI32 3.141592653589f -internal void renderSmallRect(GameOffscreenBuffer *buffer, int playerX, int playerY) { +internal int32 roundReal32ToUInt32(real32 realNum) { + return (uint32)(realNum + 0.5f); +} + +internal int32 roundReal32ToInt32(real32 realNum) { + return (int32)(realNum + 0.5f); +} + +internal void drawRectangle(GameOffscreenBuffer *buffer, real32 realMinX, real32 realMinY, real32 realMaxX, real32 realMaxY, real32 R, real32 G, real32 B) { + int32 minX = roundReal32ToInt32(realMinX); + int32 minY = roundReal32ToInt32(realMinY); + int32 maxX = roundReal32ToInt32(realMaxX); + int32 maxY = roundReal32ToInt32(realMaxY); + + uint32 color = (roundReal32ToUInt32(R*255.0f) << 16) | + (roundReal32ToUInt32(G*255.0f) << 8) | + (roundReal32ToUInt32(B*255.0f) << 0); + + if (minX < 0) { + minX = 0; + } + + if (minY < 0) { + minY = 0; + } + + if (maxX > buffer->width) { + maxX = buffer->width; + } + + if (maxY > buffer->height) { + maxY = buffer->height; + } + uint8 *endOfBuffer = (uint8 *)buffer->memory + buffer->pitch*buffer->height; - uint32 color = 0xFFFFFFFF; - int top = playerY; - int bottom = playerY + 10; - for (int x = playerX; x < playerX + 10; x++) { - uint8 *pixel = ((uint8 *)buffer->memory + x * buffer->bytesPerPixel + top*buffer->pitch); - for (int y = top; y < bottom; y++) { - if ((pixel >= buffer->memory) && (pixel + 4 < endOfBuffer)) { - *(uint32 *)pixel = color; - } - pixel += buffer->pitch; + uint8 *row = ((uint8 *)buffer->memory + minX*buffer->bytesPerPixel + minY*buffer->pitch); + for (int y = minY; y < maxY; y++) { + uint32 *pixel = (uint32 *)row; + for (int x = minX; x < maxX; x++) { + *pixel++ = color; } + row += buffer->pitch; } - } -internal void outputSineSound(GameSoundOutputBuffer *soundBuffer, GameState *state) { +internal void outputSound(GameSoundOutputBuffer *soundBuffer, GameState *state) { int16 toneVolume = 3000; - int wavePeriod = soundBuffer->samplesPerSecond/state->toneHz; - -#if 0 int16 *sampleOut = soundBuffer->samples; for (int sampleIndex = 0; sampleIndex < soundBuffer->sampleCount; sampleIndex++) { - state->tSine += 2.0f * PI32 / (real32)wavePeriod; - int16 sampleValue = (int16)(sin(state->tSine) * (real32)toneVolume); + int16 sampleValue = 0; *sampleOut++ = sampleValue; *sampleOut++ = sampleValue; } -#endif -} - -internal void renderWeirdGradient(GameOffscreenBuffer *buffer, int xOffset, int yOffset) { - 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 = (uint8)(x + xOffset); - uint8 green = (uint8)(y + yOffset); - *pixel++ = (green << 8) | blue; - } - row += buffer->pitch; - } } extern "C" GAME_UPDATE_AND_RENDER(gameUpdateAndRender) { @@ -53,54 +63,81 @@ extern "C" GAME_UPDATE_AND_RENDER(gameUpdateAndRender) { GameState *state = (GameState*)memory->permanentStorage; if (!memory->isInitialised) { - DebugReadFileResult bmpMem = memory->debugReadEntireFile(ctx, __FILE__); - if (bmpMem.contents) { - if (false) { - memory->debugWriteEntireFile(ctx, "c:/source/repos/handmade/src/test.cpp", bmpMem.contentsSize, bmpMem.contents); - } - memory->debugFreeFileMemory(ctx, bmpMem.contents); - } - - state->toneHz = 440; - state->tSine = 0; - state->playerY = 100; - state->playerX = 100; - state->blueOffset = 0; - state->greenOffset = 0; memory->isInitialised = true; + state->playerX = 20.0f; + state->playerY = 20.0f; } for (int controllerIndex = 0; controllerIndex < ArrayCount(input->controllers); controllerIndex++) { - GameControllerInput *controllerInput = &input->controllers[controllerIndex]; + GameControllerInput *controller = &input->controllers[controllerIndex]; - if (controllerInput->btnDown.endedDown) { - state->playerY -= 30; - } + real32 dPlayerX = 0.0f; + real32 dPlayerY = 0.0f; - if (controllerInput->stickRight.endedDown) { - state->playerX += 10; + if (controller->stickUp.endedDown) { + dPlayerY = -128.0f; } - if (controllerInput->stickLeft.endedDown) { - state->playerX -= 10; + if (controller->stickDown.endedDown) { + dPlayerY = 128.0f; } - if (controllerInput->stickDown.endedDown) { - state->playerY += 10; + if (controller->stickLeft.endedDown) { + dPlayerX = -128.0f; } - if (controllerInput->stickUp.endedDown) { - state->playerY -= 10; + if (controller->stickRight.endedDown) { + dPlayerX = 128.0f; } + + state->playerX += dPlayerX * input->dtForFrame; + state->playerY += dPlayerY * input->dtForFrame; } - renderWeirdGradient(videoBuf, state->greenOffset, state->blueOffset); - renderSmallRect(videoBuf, state->playerX, state->playerY); - renderSmallRect(videoBuf, input->mouseX, input->mouseY); - for (int i = 0; i < ArrayCount(input->mouseButtons); i++) { - if (input->mouseButtons[i].endedDown) { - renderSmallRect(videoBuf, 10 + i * 20, 10); + const int TILEMAP_WIDTH = 16; + const int TILEMAP_HEIGHT = 9; + real32 upperLeftX = 0; + real32 upperLeftY = 0; + real32 tileWidth = 60; + real32 tileHeight = 60; + + uint32 tileMap[TILEMAP_HEIGHT][TILEMAP_WIDTH] = { + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}, + {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1}, + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + }; + + // clearscreen + drawRectangle(videoBuf, 0.0f, 0.0f, (real32)videoBuf->width, (real32)videoBuf->height, 1.0f, 0.0f, 1.0f); + + // tilemap + for (int row = 0; row < TILEMAP_HEIGHT; row++) { + for (int col = 0; col < TILEMAP_WIDTH; col++) { + uint32 tileID = tileMap[row][col]; + real32 fill = tileID == 1 ? 1.0f : 0.5f; + real32 minX = upperLeftX + ((real32)col)*tileWidth; + real32 minY = upperLeftY + ((real32)row)*tileHeight; + real32 maxX = minX + tileWidth; + real32 maxY = minY + tileHeight; + drawRectangle(videoBuf, minX, minY, maxX, maxY, fill, fill, fill); } } + + // player + real32 playerR = 1.0f; + real32 playerG = 0.5f; + real32 playerB = 0.0f; + real32 playerWidth = 25.0f; + real32 playerHeight = 40.0f; + real32 playerLeft = state->playerX - 0.5f * playerWidth; + real32 playerTop = state->playerY - 0.5f * playerHeight; + + drawRectangle(videoBuf, playerLeft, playerTop, state->playerX + playerWidth, state->playerY + playerHeight, playerR, playerG, playerB); } extern "C" GAME_GET_SOUND_SAMPLES(gameGetSoundSamples) { - outputSineSound(soundBuf, (GameState*)memory->permanentStorage); + outputSound(soundBuf, (GameState*)memory->permanentStorage); } diff --git a/src/handmade.h b/src/handmade.h index 693db66..154e4e3 100644 --- a/src/handmade.h +++ b/src/handmade.h @@ -137,6 +137,7 @@ struct GameInput { int32 mouseX; int32 mouseY; int32 mouseZ; + real32 dtForFrame; GameControllerInput controllers[5]; }; @@ -153,12 +154,8 @@ struct GameMemory { }; struct GameState { - int toneHz; - int greenOffset; - int blueOffset; - real32 tSine; - int playerY; - int playerX; + real32 playerX; + real32 playerY; }; // === Game to platform services === diff --git a/src/win32_handmade.cpp b/src/win32_handmade.cpp index 93189de..f1b14d3 100644 --- a/src/win32_handmade.cpp +++ b/src/win32_handmade.cpp @@ -519,8 +519,8 @@ void win32GetFullPathToLocalFile(Win32State *state, char *filename, int filename catStrings(state->onePastLastExeFilenameSlash - state->exeFilename, state->exeFilename, filenameSize, filename, (size_t)MAX_PATH, maxPathBuffer); } -#define WINDOW_WIDTH 1280 -#define WINDOW_HEIGHT 720 +#define WINDOW_WIDTH 960 +#define WINDOW_HEIGHT 540 int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLine, int commandShow) { Win32State win32State = {}; @@ -649,6 +649,8 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR commandLin int64 lastCycleCount = __rdtsc(); while (globalRunning) { + newInput->dtForFrame = targetSecondsPerFrame; + FILETIME newWriteTime = win32GetLastWriteTime(sourceGameCodeDLLFullPath); if (CompareFileTime(&newWriteTime, &game.lastWriteTime) != 0) { win32UnloadGameCode(&game);