|
@@ -2,49 +2,59 @@ |
|
|
|
|
|
|
|
|
#define PI32 3.141592653589f |
|
|
#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; |
|
|
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; |
|
|
int16 toneVolume = 3000; |
|
|
int wavePeriod = soundBuffer->samplesPerSecond/state->toneHz; |
|
|
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
|
int16 *sampleOut = soundBuffer->samples; |
|
|
int16 *sampleOut = soundBuffer->samples; |
|
|
for (int sampleIndex = 0; sampleIndex < soundBuffer->sampleCount; sampleIndex++) { |
|
|
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; |
|
|
*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) { |
|
|
extern "C" GAME_UPDATE_AND_RENDER(gameUpdateAndRender) { |
|
@@ -53,54 +63,81 @@ extern "C" GAME_UPDATE_AND_RENDER(gameUpdateAndRender) { |
|
|
GameState *state = (GameState*)memory->permanentStorage; |
|
|
GameState *state = (GameState*)memory->permanentStorage; |
|
|
|
|
|
|
|
|
if (!memory->isInitialised) { |
|
|
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; |
|
|
memory->isInitialised = true; |
|
|
|
|
|
state->playerX = 20.0f; |
|
|
|
|
|
state->playerY = 20.0f; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
for (int controllerIndex = 0; controllerIndex < ArrayCount(input->controllers); controllerIndex++) { |
|
|
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) { |
|
|
extern "C" GAME_GET_SOUND_SAMPLES(gameGetSoundSamples) { |
|
|
outputSineSound(soundBuf, (GameState*)memory->permanentStorage); |
|
|
|
|
|
|
|
|
outputSound(soundBuf, (GameState*)memory->permanentStorage); |
|
|
} |
|
|
} |