diff options
author | Raymaekers Luca <luca@spacehb.net> | 2025-07-09 15:59:10 +0200 |
---|---|---|
committer | Raymaekers Luca <luca@spacehb.net> | 2025-07-09 15:59:10 +0200 |
commit | 71baed6f2ceb93ee8b3830b3049ad9487e5de234 (patch) | |
tree | 51ebfc6f3775ba82d8f8fc8f76ae536227522a65 /code | |
parent | dd028b12f6cf44c20ecc57049eeac8fae52cd8e6 (diff) |
checkpoint
Diffstat (limited to 'code')
-rw-r--r-- | code/handmade.cpp | 510 | ||||
-rw-r--r-- | code/handmade.h | 37 | ||||
-rw-r--r-- | code/handmade_intrinsics.h | 98 | ||||
-rw-r--r-- | code/handmade_platform.h | 23 | ||||
-rw-r--r-- | code/linux_handmade.cpp | 15 |
5 files changed, 441 insertions, 242 deletions
diff --git a/code/handmade.cpp b/code/handmade.cpp index d04c63a..41155cd 100644 --- a/code/handmade.cpp +++ b/code/handmade.cpp @@ -9,6 +9,7 @@ #if HANDMADE_INTERNAL #include <stdio.h> +#define NoOp { int X = 3; } #endif internal s16 @@ -81,7 +82,7 @@ RenderWeirdGradient(game_offscreen_buffer *Buffer, int BlueOffset, int GreenOffs internal void DrawRectangle(game_offscreen_buffer *Buffer, v2 vMin, v2 vMax, - r32 R, r32 G, r32 B) + color_rgb Color) { int MinX = RoundReal32ToInt32(vMin.X); int MaxX = RoundReal32ToInt32(vMax.X); @@ -108,10 +109,10 @@ DrawRectangle(game_offscreen_buffer *Buffer, MaxY = Buffer->Height; } - u32 Color = - (RoundReal32ToUInt32(R * 255.0f) << 2*8) | - (RoundReal32ToUInt32(G * 255.0f) << 1*8) | - (RoundReal32ToUInt32(B * 255.0f) << 0*8); + u32 ColorValue = + (RoundReal32ToUInt32(Color.R * 255.0f) << 2*8) | + (RoundReal32ToUInt32(Color.G * 255.0f) << 1*8) | + (RoundReal32ToUInt32(Color.B * 255.0f) << 0*8); u8 *Row = ((u8 *)(Buffer->Memory) + MinX*Buffer->BytesPerPixel + @@ -127,7 +128,7 @@ DrawRectangle(game_offscreen_buffer *Buffer, X < MaxX; X++) { - *Pixel++ = Color; + *Pixel++ = ColorValue; } Row += Buffer->Pitch; @@ -313,81 +314,120 @@ DEBUGLoadBMP(thread_context *Thread, debug_platform_read_entire_file *DEBUGPlatf } internal void -DrawVerticalAxis(game_offscreen_buffer *Buffer, view *View, r32 PointX) +DrawCharacter(game_offscreen_buffer *Buffer, u8 *FontBitmap, + int FontWidth, int FontHeight, + int XOffset, int YOffset, + color_rgb Color) { - PointX += View->CenterOffset.X; + s32 MinX = 0; + s32 MinY = 0; + s32 MaxX = FontWidth; + s32 MaxY = FontHeight; - for(u32 Y = 0; - Y < View->SizePixels.Y; + if(XOffset < 0) + { + MinX = -XOffset; + XOffset = 0; + } + if(YOffset < 0) + { + MinY = -YOffset; + YOffset = 0; + } + if(XOffset + FontWidth > Buffer->Width) + { + MaxX -= ((XOffset + FontWidth) - Buffer->Width); + } + if(YOffset + FontHeight > Buffer->Height) + { + MaxY -= ((YOffset + FontHeight) - Buffer->Height); + } + + u8 *Row = (u8 *)(Buffer->Memory) + + (YOffset*Buffer->Pitch) + + (XOffset*Buffer->BytesPerPixel); + + for(int Y = MinY; + Y < MaxY; Y++) { - u32 X = PointX*View->PointsToPixels + View->TopLeft.X + View->PointPad.X; - - v2 LineMin = {(r32)X, (r32)Y + View->TopLeft.Y}; - v2 LineMax = LineMin + v2{1, 1}; - - DrawRectangle(Buffer, LineMin, LineMax, 0.0f, 0.0f, 1.0f); - + u32 *Pixel = (u32 *)Row; + for(int X = MinX; + X < MaxX; + X++) + { + + u8 Brightness = FontBitmap[Y*FontWidth+X]; + u32 Value = ((0xFF << 24) | + ((u32)(Color.R*Brightness) << 16) | + ((u32)(Color.G*Brightness) << 8) | + ((u32)(Color.B*Brightness) << 0)); + *Pixel++ = Value; + } + Row += Buffer->Pitch; } } internal void -DrawHorizontalAxis(game_offscreen_buffer *Buffer, view *View, r32 PointY) +DrawText(game_state *GameState, game_offscreen_buffer *Buffer, + r32 FontScale, + char *Text, u32 TextLen, v2 Offset, color_rgb Color) { - PointY += View->CenterOffset.Y; - for(u32 X = 0; - X < View->SizePixels.X; - X++) + for(u32 TextIndex = 0; + TextIndex < TextLen; + TextIndex++) { - u32 Y = PointY*View->PointsToPixels + View->TopLeft.Y + View->PointPad.Y; + int CharAt = Text[TextIndex]; - v2 LineMin = {(r32)X + View->TopLeft.X, (r32)Y}; - v2 LineMax = LineMin + v2{1, 1}; + int FontWidth, FontHeight; + int AdvanceWidth, LeftSideBearing; + int X0, Y0, X1, Y1; + u8 *FontBitmap = 0; + // TODO(luca): Get rid of malloc. + FontBitmap = stbtt_GetCodepointBitmap(&GameState->FontInfo, + FontScale, FontScale, + CharAt, + &FontWidth, &FontHeight, 0, 0); + stbtt_GetCodepointBitmapBox(&GameState->FontInfo, CharAt, + FontScale, FontScale, + &X0, &Y0, &X1, &Y1); + r32 YOffset = Offset.Y + Y0; + stbtt_GetCodepointHMetrics(&GameState->FontInfo, CharAt, &AdvanceWidth, &LeftSideBearing); + r32 XOffset = Offset.X + LeftSideBearing*FontScale; - DrawRectangle(Buffer, - LineMin, LineMax, - 1.0f, 1.0f, 0.0f); - } - -} - -internal void -DrawPoint(game_offscreen_buffer *Buffer, view *View, v2 Point, color_rgb Color, v2 PointSize = {1, 1}) -{ - Point.Y *= -1; - Point += View->CenterOffset; - v2 PointMin = Point*View->PointsToPixels + View->TopLeft + View->PointPad; - v2 PointMax = PointMin + v2{1, 1}; - PointMin += -PointSize; - PointMax += PointSize; - - b32 IsOutOfView = ((PointMin.X < View->TopLeft.X) || - (PointMin.Y < View->TopLeft.Y) || - (PointMax.X > View->BottomRight.X) || - (PointMax.Y > View->BottomRight.Y)); - if(!IsOutOfView) - { - DrawRectangle(Buffer, PointMin, PointMax, - Color.R, Color.G, Color.B); + DrawCharacter(Buffer, FontBitmap, FontWidth, FontHeight, XOffset, YOffset, Color); + + Offset.X += (AdvanceWidth*FontScale); + free(FontBitmap); } } -internal void -DrawLine(game_offscreen_buffer *Buffer, view *View, - r32 Slope, r32 B, r32 Step, - color_rgb Color) +internal b32 +ValidLetterCountInGuess(char *Word, char *Guess, char Letter) { + b32 Valid = false; - for(r32 X = -(View->CenterOffset.X + 1); - X < (View->CenterOffset.X + 1); - X += Step) + int CountInGuess = 0; + int CountInWord = 0; + for(int ScanIndex = 0; + ScanIndex < WORDLE_LENGTH; + ScanIndex++) { - r32 Y = X * Slope + B; - DrawPoint(Buffer, View, v2{X, Y}, Color, {.5, .5}); + if(Letter == Word[ScanIndex]) + { + CountInWord++; + } + if(Letter == Guess[ScanIndex]) + { + CountInGuess++; + } } + Valid = (CountInGuess <= CountInWord); + + return Valid; } extern "C" GAME_UPDATE_AND_RENDER(GameUpdateAndRender) @@ -397,81 +437,33 @@ extern "C" GAME_UPDATE_AND_RENDER(GameUpdateAndRender) Assert(sizeof(game_state) <= Memory->PermanentStorageSize); game_state *GameState = (game_state *)Memory->PermanentStorage; - local_persist stbtt_fontinfo FontInfo = {}; - local_persist unsigned char *Bitmap = 0; - local_persist int FontHeight, FontWidth; + if(!Memory->IsInitialized) { - GameState->Slope = 1.0f; - GameState->Step = 0.5f; - debug_read_file_result File = Memory->DEBUGPlatformReadEntireFile(Thread, "data/font.ttf"); - if(stbtt_InitFont(&FontInfo, (unsigned char*)File.Contents, 0)) + if(stbtt_InitFont(&GameState->FontInfo, (u8 *)File.Contents, stbtt_GetFontOffsetForIndex((u8 *)File.Contents, 0))) { - int C = 'a'; - float HeightPixels = 64; - float ScaleY = stbtt_ScaleForPixelHeight(&FontInfo, HeightPixels); + GameState->FontInfo.data = (u8 *)File.Contents; + + int X0, Y0, X1, Y1; + v2 BoundingBox[2] = {}; + stbtt_GetFontBoundingBox(&GameState->FontInfo, &X0, &Y0, &X1, &Y1); + GameState->FontBoundingBox[0] = v2{(r32)X0, (r32)Y0}; + GameState->FontBoundingBox[1] = v2{(r32)X1, (r32)Y1}; + stbtt_GetFontVMetrics(&GameState->FontInfo, &GameState->FontAscent, &GameState->FontDescent, &GameState->FontLineGap); -#if 1 - Bitmap = stbtt_GetCodepointBitmap(&FontInfo, 0, ScaleY, C, &FontWidth, &FontHeight, 0, 0); -#else - int Width = 100; - int Height = 100; - unsigned char Bitmap[Width*Height]; - stbtt_MakeCodepointBitmap(&FontInfo, Bitmap, Width, Height, Width, 0, ScaleY, 'a'); -#endif } else { - Assert(0); + // TODO(luca): Logging } - Memory->IsInitialized = true; - - } - - { - - u8 *Row = (u8 *)(Buffer->Memory); - // Rendering the font? - for(int Y = 0; - Y < FontHeight; - Y++) - { - u32 *Pixel = (u32 *)Row; - for(int X = 0; - X < FontWidth; - X++) - { - u8 Brightness = Bitmap[Y*FontWidth+X]; - u32 Color = ((0xFF << 24) | - (Brightness << 16) | - (Brightness << 8) | - (Brightness << 0)); - *Pixel++ = Color; - } - Row += Buffer->Pitch; - } + GameState->SelectedColor = SquareColor_Yellow; + Memory->IsInitialized = true; } - - v2 BufferSize = {(r32)Buffer->Width, (r32)Buffer->Height}; - - view View = {}; - View.PointsToPixels = 20; - View.SizePixels = {(r32)(Buffer->Width), (r32)(Buffer->Height)}; - // NOTE(luca): Create a square based on 16/9 aspect ratio. - View.SizePixels.X *= (1.00f - 7.0f/16.0f); - // NOTE(luca): This is truncated so that when it is scaled back to pixels we can use the "lost" pixels for centering. On top of that we make sure that it is an even number so both axises' middle align with the center.. - View.SizePoints = V2(((r32)(((u32)View.SizePixels.X / View.PointsToPixels) & (~1))), - ((r32)(((u32)View.SizePixels.Y / View.PointsToPixels) & (~1)))); - View.CenterOffset = 0.5f*View.SizePoints; - View.TopLeft = (BufferSize - View.SizePixels)/2.0f; - View.BottomRight = View.TopLeft + View.SizePixels; - View.PointPad = 0.5f*(View.SizePixels - (r32)View.PointsToPixels*View.SizePoints); - for(u32 ControllerIndex = 0; ControllerIndex < ArrayCount(Input->Controllers); ControllerIndex++) @@ -486,118 +478,242 @@ extern "C" GAME_UPDATE_AND_RENDER(GameUpdateAndRender) } else { - r32 SlopeStep = 1.0f*Input->dtForFrame; - r32 StepStep = 1.0f*Input->dtForFrame; - r32 BStep = 1.0f*Input->dtForFrame; - r32 CStep = 8.0f*Input->dtForFrame; - - if(Controller->MoveUp.EndedDown) + if(WasPressed(Input->MouseButtons[PlatformMouseButton_Right])) { - GameState->Slope += SlopeStep; + GameState->SelectedColor = (GameState->SelectedColor < SquareColor_Count- 1) ? + GameState->SelectedColor + 1: 0; } - if(Controller->MoveDown.EndedDown) - { - GameState->Slope -= SlopeStep; - } + } + } + } + + + char Text[256] = {}; + int TextLen = 0; + + r32 FontScale = 0.0f; + r32 YAdvance = 0.0f; + r32 Baseline = 0.0f; + v2 TextOffset = {}; + int AdvanceWidth = 0; + + Assert(GameState->SelectedColor < SquareColor_Count); + + r32 Width = 48.0f; + + v2 Min = {0.0f, 0.0f}; + v2 Max = {Width, Width}; + v2 Padding = {2.0f, 2.0f}; + v2 Base = {0.0f, 0.0f}; + color_rgb ColorGray = {0.23f, 0.23f, 0.24f}; + color_rgb ColorYellow = {0.71f, 0.62f, 0.23f}; + color_rgb ColorGreen = {0.32f, 0.55f, 0.31f}; + + s32 Rows = 6; + s32 Columns = 5; + Base.X = 0.5f*(Buffer->Width - Columns*Width); + Base.Y = 0.5f*(Buffer->Height - Rows*Width); + + s32 SelectedX = CeilReal32ToInt32((r32)(Input->MouseX - Base.X)/(r32)(Width + Padding.X)) - 1; + s32 SelectedY = CeilReal32ToInt32((r32)(Input->MouseY - Base.Y)/(r32)(Width + Padding.Y)) - 1; + + Min.X = Base.X; + Min.Y = Base.Y; + for(s32 Y = 0; + Y < Rows; + Y++) + { + for(s32 X = 0; + X < Columns; + X++) + { + color_rgb Color = {1.0f, 1.0f, 0.0f}; + + Max = Min + Width; + + if((X == SelectedX) && + (Y == SelectedY)) + { - if(Controller->MoveRight.EndedDown) - { - GameState->Step -= StepStep; - - } - if(Controller->MoveLeft.EndedDown) + if(Input->MouseButtons[PlatformMouseButton_Left].EndedDown) { - GameState->Step += StepStep; + GameState->PatternGrid[Y][X] = GameState->SelectedColor; } - if(GameState->Step <= 0) + if(0) {} + else if(GameState->SelectedColor == 0) { - GameState->Step = 0.001; + Color = ColorGray; } - - if(Controller->ActionUp.EndedDown) + else if(GameState->SelectedColor == 1) { - GameState->C += CStep; + Color = ColorYellow; } - if(Controller->ActionDown.EndedDown) + else if(GameState->SelectedColor == 2) { - GameState->C -= CStep; + Color = ColorGreen; } - if(Controller->ActionRight.EndedDown) + DrawRectangle(Buffer, Min, Max, color_rgb{0.0f, 0.0f, 0.0f}); + DrawRectangle(Buffer, + Min + Padding, Max - Padding, + Color); + } + else + { + u32 PatternValue = GameState->PatternGrid[Y][X]; + if(0) {} + else if(PatternValue == SquareColor_Gray) { - GameState->B += BStep; + Color = ColorGray; } - if(Controller->ActionLeft.EndedDown) + else if(PatternValue == SquareColor_Yellow) { - GameState->B -= BStep; + Color = ColorYellow; } - - if(Controller->Start.EndedDown) + else if(PatternValue == SquareColor_Green) { - GameState->Step = 0.01f; - GameState->Slope = 1.0f; - GameState->B = 0.0f; - GameState->C = 0.0f; + Color = ColorGreen; } - }; + + DrawRectangle(Buffer, Min, Max, Color); + } + + + Min.X += Padding.X + Width; } + Min.X = Base.X; + Min.Y += Padding.Y + Width; } + // Prepare drawing of the guesses. + FontScale = stbtt_ScaleForPixelHeight(&GameState->FontInfo, 24.0f); + YAdvance = FontScale*(GameState->FontAscent - + GameState->FontDescent + + GameState->FontLineGap); + Baseline = (GameState->FontAscent*FontScale); + TextOffset = v2{16.0f, 16.0f + Baseline}; - //-Rendering - - DrawRectangle(Buffer, View.TopLeft, View.BottomRight, 0.1f, 0.1f, 0.1f); - DrawHorizontalAxis(Buffer, &View, 0); - DrawVerticalAxis(Buffer, &View, 0); - - // X Points - for(r32 Col = 0; - Col <= View.SizePoints.X; - Col++) { - v2 LineMin = v2{Col, View.CenterOffset.Y - 0.5f}; - v2 LineMax = v2{Col, View.CenterOffset.Y + 0.5f}; - LineMin = (LineMin*View.PointsToPixels) + View.TopLeft + View.PointPad; - LineMax = (LineMax*View.PointsToPixels) + View.TopLeft + View.PointPad + v2{1, 1}; - - DrawRectangle(Buffer, LineMin, LineMax, 1.0f, 1.0f, 1.0f); + char Text[] = "\"novel\""; + int TextLen = sizeof(Text) - 1; + DrawText(GameState, Buffer, FontScale, Text, TextLen, TextOffset + -v2{8.0f, 0.0f}, ColorGreen); } - // Y Points - for(r32 Row = 0; - Row <= View.SizePoints.Y; - Row++) - { - v2 LineMin = v2{View.CenterOffset.X - 0.5f, Row}; - v2 LineMax = v2{View.CenterOffset.X + 0.5f, Row}; - LineMin = (LineMin*View.PointsToPixels) + View.TopLeft + View.PointPad; - LineMax = (LineMax*View.PointsToPixels) + View.TopLeft + View.PointPad + v2{1, 1}; - DrawRectangle(Buffer, LineMin, LineMax, 1.0f, 1.0f, 1.0f); - } + TextOffset.Y += YAdvance*2.0f; - // Plot some points - r32 B = GameState->B; - r32 C = GameState->C; - r32 Slope = GameState->Slope; - r32 Step = GameState->Step; + //-Matche the pattern -#if 0 - DrawLine(Buffer, &View, Slope, B, Step, {1.0f, 0.0f, 1.0f}); -#endif + char *Word = "novel"; + debug_read_file_result File = Memory->DEBUGPlatformReadEntireFile(Thread, "data/words.txt"); - for(r32 X = -(View.CenterOffset.X + 1); - X < (View.CenterOffset.X + 1); - X += Step) + int WordsCount = File.ContentsSize / WORDLE_LENGTH; + if(File.Contents) { - r32 Y = 16.0f*Slope*Sin(X + -4*B) + 2*C; - DrawPoint(Buffer, &View, v2{X, Y}, color_rgb{1.0f, 0.5f, 0.0f}, {.5, .5}); + char *Words = (char *)File.Contents; + + int PatternRowAt = 0; + int PatternRowsCount = 6; + + for(int WordsIndex = 0; + ((WordsIndex < WordsCount) && + (PatternRowAt < PatternRowsCount)); + WordsIndex++) + { + // Match the pattern's row against the guess. + // TODO(luca): Check if the guess == the word and skip it otherwise it would end the game. + int PatternMatches = 1; + char *Guess = &Words[WordsIndex*5]; + for(int CharIndex = 0; + ((CharIndex < WORDLE_LENGTH) && + (PatternMatches)); + CharIndex++) + { + char GuessCh = Guess[CharIndex]; + int PatternValue = GameState->PatternGrid[PatternRowAt][CharIndex]; + + if(PatternValue == SquareColor_Green) + { + PatternMatches = (GuessCh == Word[CharIndex]); + } + else if(PatternValue == SquareColor_Yellow) + { + PatternMatches = 0; + for(int CharAt = 0; + CharAt < WORDLE_LENGTH; + CharAt++) + { + if(Word[CharAt] == GuessCh) + { + if(CharAt != CharIndex) + { + // TODO(luca): Should also check that position does not match. + PatternMatches = ValidLetterCountInGuess(Word, Guess, GuessCh); + } + else + { + PatternMatches = 0; + } + + break; + } + } + + } + // TODO(luca): Have one that can be either yellow/green +#if 0 + else if(PatternValue == 1) + { + PatternMatches = 0; + for(int CharAt = 0; + CharAt < WORDLE_LENGTH; + CharAt++) + { + if(Word[CharAt] == GuessCh) + { + PatternMatches = ValidLetterCountInGuess(Word, Guess, GuessCh); + break; + } + } + } +#endif + else if(PatternValue == SquareColor_Gray) + { + PatternMatches = 1; + for(int CharAt = 0; + CharAt < WORDLE_LENGTH; + CharAt++) + { + if(Word[CharAt] == GuessCh) + { + PatternMatches = 0; + break; + } + } + } + } + + if(PatternMatches) + { + DrawText(GameState, Buffer, FontScale, + Guess, WORDLE_LENGTH, + TextOffset, color_rgb{1.0f, 1.0f, 1.0f}); + TextOffset.Y += YAdvance; + + WordsIndex = 0; + PatternRowAt++; + } + } + + //-Display the words + } + + } - extern "C" GAME_GET_SOUND_SAMPLES(GameGetSoundSamples) { game_state *GameState = (game_state *)Memory->PermanentStorage; diff --git a/code/handmade.h b/code/handmade.h index f64566b..3cb98e1 100644 --- a/code/handmade.h +++ b/code/handmade.h @@ -10,6 +10,18 @@ #include "handmade_platform.h" #include "handmade_math.h" +#include "libs/stb_truetype.h" + +#define WORDLE_LENGTH 5 + +typedef enum +{ + SquareColor_Gray = 0, + SquareColor_Yellow = 1, + SquareColor_Green = 2, + SquareColor_Count +} square_colors; + struct memory_arena { memory_index Size; @@ -61,27 +73,18 @@ struct color_rgb }; }; -struct view +struct game_state { - u32 PointsToPixels; + u32 PatternGrid[6][5]; - v2 SizePixels; - v2 SizePoints; + u32 SelectedColor;; - v2 TopLeft; - v2 BottomRight; - // NOTE(luca): These pixels are added to points to center them when rendering. - v2 PointPad; + stbtt_fontinfo FontInfo; + s32 FontAscent; + s32 FontDescent; + s32 FontLineGap; + v2 FontBoundingBox[2]; - v2 CenterOffset; -}; - -struct game_state -{ - r32 Slope; - r32 Step; - r32 B; - r32 C; }; #define HANDMADE_H diff --git a/code/handmade_intrinsics.h b/code/handmade_intrinsics.h index 2a3a69e..00b2769 100644 --- a/code/handmade_intrinsics.h +++ b/code/handmade_intrinsics.h @@ -3,75 +3,98 @@ #ifndef HANDMADE_INTRINSICS_H #define HANDMADE_INTRINSICS_H +#if COMPILER_GNU +#include <x86intrin.h> +#endif // // TODO(casey): Remove math.h // #include <math.h> -inline s32 -RoundReal32ToInt32(r32 Real32) +inline +s32 SignOf(s32 Value) +{ + s32 Result = (Value >= 0) ? 1 : -1; + return Result; +} + +inline +r32 AbsoluteValue(r32 Real32) +{ + r32 Result = fabs(Real32); + return Result; +} + +inline +s32 RoundReal32ToInt32(r32 Real32) { s32 Result = (s32)(roundf(Real32)); return Result; } -inline u32 -RoundReal32ToUInt32(r32 Real32) +inline +u32 RoundReal32ToUInt32(r32 Real32) { u32 Result = (u32)(roundf(Real32)); return Result; } -inline u32 -TruncateReal32ToUInt32(r32 Real32) +inline +u32 TruncateReal32ToUInt32(r32 Real32) { u32 Result = (u32)Real32; return Result; } -inline s32 -TruncateReal32ToInt32(r32 Real32) +inline +s32 TruncateReal32ToInt32(r32 Real32) { s32 Result = (s32)Real32; return Result; } -inline s32 -FloorReal32ToInt32(r32 Real32) +inline +s32 FloorReal32ToInt32(r32 Real32) { s32 Result = (s32)floorf(Real32); return Result; } -inline r32 -Sin(r32 Angle) +inline +s32 CeilReal32ToInt32(r32 Real32) +{ + s32 Result = (s32)ceilf(Real32); + return Result; +} +inline +r32 Sin(r32 Angle) { r32 Result = sinf(Angle); return Result; } -inline r32 -Cos(r32 Angle) +inline +r32 Cos(r32 Angle) { r32 Result = cosf(Angle); return Result; } -inline r32 -Atan2(r32 Y, r32 X) +inline +r32 Atan2(r32 Y, r32 X) { r32 Result = atan2f(Y, X); return Result; + } - struct bit_scan_result { b32 Found; u32 Index; -}; - -internal inline bit_scan_result -FindLeastSignificantSetBit(u32 Value) +} +; +internal inline +bit_scan_result FindLeastSignificantSetBit(u32 Value) { bit_scan_result Result = {}; @@ -100,4 +123,37 @@ FindLeastSignificantSetBit(u32 Value) return Result; } +u32 RotateLeft(u32 Value, u32 Count) +{ + u32 Result = 0; + +#if 0 +#elif COMPILER_GNU + Result = _rotl(Value, Count); +#endif + + return Result; +} + +u32 RotateRight(u32 Value, u32 Count) +{ + u32 Result = 0; + +#if 0 +#elif COMPILER_GNU + Result = _rotr(Value, Count); +#endif + + return Result; +} + + +inline +r32 SquareRoot(r32 Real32) +{ + r32 Result = sqrtf(Real32); + return Result; +} + + #endif //HANDMADE_INTRINSICS_H diff --git a/code/handmade_platform.h b/code/handmade_platform.h index 8831767..64716a7 100644 --- a/code/handmade_platform.h +++ b/code/handmade_platform.h @@ -128,10 +128,10 @@ extern "C" { { // NOTE(casey): Pixels are alwasy 32-bits wide, Memory Order BB GG RR XX void *Memory; - int Width; - int Height; - int Pitch; - int BytesPerPixel; + s32 Width; + s32 Height; + s32 Pitch; + s32 BytesPerPixel; } game_offscreen_buffer; typedef struct game_sound_output_buffer @@ -182,6 +182,14 @@ extern "C" { }; } game_controller_input; + typedef enum + { + PlatformMouseButton_Left = 0, + PlatformMouseButton_Right, + PlatformMouseButton_Middle, + PlatformMouseButton_Count + } platform_mouse_buttons; + typedef struct game_input { game_button_state MouseButtons[5]; @@ -192,6 +200,13 @@ extern "C" { game_controller_input Controllers[5]; } game_input; + inline b32 WasPressed(game_button_state State) + { + b32 Result = ((State.HalfTransitionCount > 1) || + (State.HalfTransitionCount == 1 && State.EndedDown)); + return Result; + } + typedef struct game_memory { b32 IsInitialized; diff --git a/code/linux_handmade.cpp b/code/linux_handmade.cpp index 3d6895f..fce276f 100644 --- a/code/linux_handmade.cpp +++ b/code/linux_handmade.cpp @@ -955,9 +955,18 @@ int main(int ArgC, char *Args[]) { NewInput->MouseY = MouseY; NewInput->MouseX = MouseX; - NewInput->MouseButtons[0].EndedDown = ((MouseMask & Button1Mask) > 0); - NewInput->MouseButtons[1].EndedDown = ((MouseMask & Button2Mask) > 0); - NewInput->MouseButtons[2].EndedDown = ((MouseMask & Button3Mask) > 0); + + for(u32 ButtonIndex = 0; + ButtonIndex < PlatformMouseButton_Count; + ButtonIndex++) + { + NewInput->MouseButtons[ButtonIndex].EndedDown = OldInput->MouseButtons[ButtonIndex].EndedDown; + NewInput->MouseButtons[ButtonIndex].HalfTransitionCount = 0; + } + + LinuxProcessKeyPress(&NewInput->MouseButtons[PlatformMouseButton_Left], (MouseMask & Button1Mask)); + LinuxProcessKeyPress(&NewInput->MouseButtons[PlatformMouseButton_Middle], (MouseMask & Button2Mask)); + LinuxProcessKeyPress(&NewInput->MouseButtons[PlatformMouseButton_Right], (MouseMask & Button3Mask)); } } |