Windows build ready. Program icon, however, exceeds string length on MSVC.
This commit is contained in:
+16
@@ -3,3 +3,19 @@ handmadehero
|
|||||||
handmadehero.dSYM
|
handmadehero.dSYM
|
||||||
libhandmade.so
|
libhandmade.so
|
||||||
libhandmade.so.dSYM
|
libhandmade.so.dSYM
|
||||||
|
|
||||||
|
handmade.dll
|
||||||
|
handmade.exp
|
||||||
|
handmade.ilk
|
||||||
|
handmade.lib
|
||||||
|
handmade.obj
|
||||||
|
handmade.pdb
|
||||||
|
handmade.rdi
|
||||||
|
handmadehero.exe
|
||||||
|
handmadehero.exp
|
||||||
|
handmadehero.ilk
|
||||||
|
handmadehero.lib
|
||||||
|
handmadehero.pdb
|
||||||
|
handmadehero.rdi
|
||||||
|
sdl_handmade.obj
|
||||||
|
vc140.pdb
|
||||||
|
|||||||
@@ -15,12 +15,6 @@ endif
|
|||||||
CC = clang
|
CC = clang
|
||||||
|
|
||||||
UFLAGS =
|
UFLAGS =
|
||||||
# NOTE: This project's code bases itself on C89 (plain C) standard, however
|
|
||||||
# allowing a few convenient features of newer standards. Mid-scope
|
|
||||||
# variable declarations, comments that begin with '//', long long,
|
|
||||||
# designated initializers, compound literals, and anonymous structures
|
|
||||||
# are allowed as they are convenient. Everything else that has come out
|
|
||||||
# of modern standards is pretty much destructive and should not be used.
|
|
||||||
FLAGS = -Wall -Wextra \
|
FLAGS = -Wall -Wextra \
|
||||||
-Wincompatible-pointer-types \
|
-Wincompatible-pointer-types \
|
||||||
-Wint-conversion -Wimplicit-int-float-conversion -Wformat \
|
-Wint-conversion -Wimplicit-int-float-conversion -Wformat \
|
||||||
@@ -43,10 +37,6 @@ else ifeq ($(DETECTED_OS),linux)
|
|||||||
INCLUDE = -I./sdl/include/
|
INCLUDE = -I./sdl/include/
|
||||||
LIBS = ./sdl/lib/x86_64-linux/libSDL2.a -lm -lX11
|
LIBS = ./sdl/lib/x86_64-linux/libSDL2.a -lm -lX11
|
||||||
FRAMEWORKS =
|
FRAMEWORKS =
|
||||||
else ifeq ($(DETECTED_OS),windows)
|
|
||||||
INCLUDE =
|
|
||||||
LIBS =
|
|
||||||
FRAMEWORKS =
|
|
||||||
else
|
else
|
||||||
INCLUDE =
|
INCLUDE =
|
||||||
LIBS =
|
LIBS =
|
||||||
@@ -58,12 +48,10 @@ EXE=handmadehero
|
|||||||
default: libhandmade $(EXE)
|
default: libhandmade $(EXE)
|
||||||
|
|
||||||
libhandmade: handmade.c
|
libhandmade: handmade.c
|
||||||
@ $(CC) $(FLAGS) $(UFLAGS) -fPIC -shared $(INCLUDE) $^ $(LIBS) \
|
@ $(CC) $(FLAGS) $(UFLAGS) -fPIC -shared $(INCLUDE) $^ $(LIBS) $(FRAMEWORKS) -o libhandmade.so
|
||||||
$(FRAMEWORKS) -o libhandmade.so
|
|
||||||
|
|
||||||
$(EXE): sdl_handmade.c libhandmade
|
$(EXE): sdl_handmade.c libhandmade
|
||||||
@ $(CC) $(FLAGS) $(UFLAGS) $(INCLUDE) sdl_handmade.c $(LIBS) \
|
@ $(CC) $(FLAGS) $(UFLAGS) $(INCLUDE) sdl_handmade.c $(LIBS) $(FRAMEWORKS) -o $@ $(ifneq $(filter $(DETECTED_OS), macos linux), /link /FORCE:MULTIPLE)
|
||||||
$(FRAMEWORKS) -o $@
|
|
||||||
|
|
||||||
run:
|
run:
|
||||||
@ ./$(EXE)
|
@ ./$(EXE)
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
@ECHO OFF
|
||||||
|
|
||||||
|
IF "%1"=="compile" (
|
||||||
|
GOTO compile
|
||||||
|
) ELSE IF "%1"=="run" (
|
||||||
|
GOTO run
|
||||||
|
) ELSE IF "%1"=="clean" (
|
||||||
|
GOTO clean
|
||||||
|
) ELSE (
|
||||||
|
ECHO Unknown command...
|
||||||
|
ECHO.Usage: build.bat [compile^|run^|clean]
|
||||||
|
)
|
||||||
|
|
||||||
|
EXIT /B 1
|
||||||
|
|
||||||
|
:compile
|
||||||
|
cl /wd4201 /wd4204 /wd4189 /wd4100 /MT /LD /Zi /Od /W4 /I sdl/include handmade.c sdl/lib/x86_64-win/SDL2.lib user32.lib gdi32.lib winmm.lib setupapi.lib oleaut32.lib version.lib Imm32.lib shell32.lib Ole32.lib Advapi32.lib /link /DEBUG /OUT:handmade.dll
|
||||||
|
|
||||||
|
cl /wd4201 /wd4204 /wd4189 /wd4100 /MT /Zi /Od /W4 /I sdl/include sdl_handmade.c sdl/lib/x86_64-win/SDL2.lib user32.lib gdi32.lib winmm.lib setupapi.lib oleaut32.lib version.lib Imm32.lib shell32.lib Ole32.lib Advapi32.lib /link /DEBUG /OUT:handmadehero.exe
|
||||||
|
EXIT /B 0
|
||||||
|
|
||||||
|
:run
|
||||||
|
handmadehero.exe
|
||||||
|
EXIT /B 0
|
||||||
|
|
||||||
|
:clean
|
||||||
|
del handmadehero.exe handmadehero.rdi handmadehero.lib handmadehero.exp
|
||||||
|
del handmade.lib handmade.dll handmade.exp handmade.rdi handmade.ilk handmade.pdb handmade.obj vc140.pdb
|
||||||
|
EXIT /B 0
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
CC = clang
|
||||||
|
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
#ifndef CORE_H_SENTRY
|
#ifndef CORE_H
|
||||||
#define CORE_H_SENTRY
|
#define CORE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
/* ---- Switches ------------------------------------------------------- */
|
/* ---- Switches ------------------------------------------------------- */
|
||||||
|
|
||||||
@@ -31,10 +33,10 @@
|
|||||||
#define ARCHITECTURE_ARM32 0
|
#define ARCHITECTURE_ARM32 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64)
|
#if defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64) || defined(_M_AMD64)
|
||||||
#undef ARCHITECTURE_X64
|
#undef ARCHITECTURE_X64
|
||||||
#define ARCHITECTURE_X64 1
|
#define ARCHITECTURE_X64 1
|
||||||
#elif defined(i386) || defined(__i386) || defined(__i386__)
|
#elif defined(i386) || defined(__i386) || defined(__i386__) || defined(_M_I86)
|
||||||
#undef ARCHITECTURE_X86
|
#undef ARCHITECTURE_X86
|
||||||
#define ARCHITECTURE_X86 1
|
#define ARCHITECTURE_X86 1
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
@@ -111,14 +113,14 @@
|
|||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef unsigned char U8;
|
typedef uint8_t U8;
|
||||||
typedef unsigned short U16;
|
typedef uint16_t U16;
|
||||||
typedef unsigned int U32;
|
typedef uint32_t U32;
|
||||||
typedef unsigned long long U64;
|
typedef uint64_t U64;
|
||||||
typedef signed char S8;
|
typedef int8_t S8;
|
||||||
typedef short S16;
|
typedef int16_t S16;
|
||||||
typedef int S32;
|
typedef int32_t S32;
|
||||||
typedef long long S64;
|
typedef int64_t S64;
|
||||||
typedef S8 B8;
|
typedef S8 B8;
|
||||||
typedef S16 B16;
|
typedef S16 B16;
|
||||||
typedef S32 B32;
|
typedef S32 B32;
|
||||||
@@ -143,7 +145,13 @@ typedef double F64;
|
|||||||
|
|
||||||
/* ---- Asserts -------------------------------------------------------- */
|
/* ---- Asserts -------------------------------------------------------- */
|
||||||
|
|
||||||
#define TRAP() __builtin_trap() // TODO: GCC and CLANG thing; not supported on MSVC.
|
#if COMPILER_CLANG || COMPILER_GCC
|
||||||
|
#define TRAP() __builtin_trap()
|
||||||
|
#elif COMPILER_MSVC
|
||||||
|
#define TRAP() __debugbreak()
|
||||||
|
#else
|
||||||
|
#error Unknow debug break for the compiler . . .
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ASSERT_ALWAYS(x) do { if(!(x)) { TRAP(); } } while(0)
|
#define ASSERT_ALWAYS(x) do { if(!(x)) { TRAP(); } } while(0)
|
||||||
#if BUILD_DEBUG
|
#if BUILD_DEBUG
|
||||||
|
|||||||
+33
-1
@@ -457,7 +457,39 @@ void UpdateAndRender(thread_context *Thread, game_memory *Memory, game_input *In
|
|||||||
PlayerRight.Offset.X += 0.5f*PlayerWidth;
|
PlayerRight.Offset.X += 0.5f*PlayerWidth;
|
||||||
PlayerRight = RecannonicalizePosition(TileMap, PlayerRight);
|
PlayerRight = RecannonicalizePosition(TileMap, PlayerRight);
|
||||||
|
|
||||||
if(IsTileMapPointEmpty(TileMap, NewPlayerP) && IsTileMapPointEmpty(TileMap, PlayerLeft) && IsTileMapPointEmpty(TileMap, PlayerRight)) {
|
B32 Collided = FALSE;
|
||||||
|
tile_map_position ColP;
|
||||||
|
memset(&ColP, 0, sizeof(ColP));
|
||||||
|
if(!IsTileMapPointEmpty(TileMap, NewPlayerP)) {
|
||||||
|
ColP = NewPlayerP;
|
||||||
|
Collided = TRUE;
|
||||||
|
}
|
||||||
|
if(!IsTileMapPointEmpty(TileMap, PlayerLeft)) {
|
||||||
|
ColP = PlayerLeft;
|
||||||
|
Collided = TRUE;
|
||||||
|
}
|
||||||
|
if(!IsTileMapPointEmpty(TileMap, PlayerRight)) {
|
||||||
|
ColP = PlayerRight;
|
||||||
|
Collided = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Collided) {
|
||||||
|
v2 r = { 0, 0 };
|
||||||
|
if(ColP.AbsTileX < GameState->PlayerP.AbsTileX) {
|
||||||
|
r = (v2){ 1, 0 };
|
||||||
|
}
|
||||||
|
if(ColP.AbsTileX > GameState->PlayerP.AbsTileX) {
|
||||||
|
r = (v2){ -1, 0 };
|
||||||
|
}
|
||||||
|
if(ColP.AbsTileY < GameState->PlayerP.AbsTileY) {
|
||||||
|
r = (v2){ 0, 1 };
|
||||||
|
}
|
||||||
|
if(ColP.AbsTileY > GameState->PlayerP.AbsTileY) {
|
||||||
|
r = (v2){ 0, -1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
GameState->dPlayerP = V2Subtract(GameState->dPlayerP, V2Multiply(1*InnerProduct(GameState->dPlayerP, r), r));
|
||||||
|
} else {
|
||||||
if(!AreOnSameTile(&GameState->PlayerP, &NewPlayerP)) {
|
if(!AreOnSameTile(&GameState->PlayerP, &NewPlayerP)) {
|
||||||
U32 NewTileValue = GetTileValueByPos(TileMap, NewPlayerP);
|
U32 NewTileValue = GetTileValueByPos(TileMap, NewPlayerP);
|
||||||
|
|
||||||
|
|||||||
+5
-6
@@ -103,14 +103,10 @@ typedef struct game_memory {
|
|||||||
B32 IsInitialized;
|
B32 IsInitialized;
|
||||||
|
|
||||||
U64 PermanentStorageSize;
|
U64 PermanentStorageSize;
|
||||||
void *PermanentStorage; /* WARNING: This memory is REQUIRED to be zero
|
void *PermanentStorage; /* WARNING: This memory is REQUIRED to be zero initialized!!! (Done by the OS layer.) */
|
||||||
initialized!!! (Done by the OS
|
|
||||||
layer.) */
|
|
||||||
|
|
||||||
U64 TransientStorageSize;
|
U64 TransientStorageSize;
|
||||||
void *TransientStorage; /* WARNING: This memory is REQUIRED to be zero
|
void *TransientStorage; /* WARNING: This memory is REQUIRED to be zero initialized!!! (Done by the OS layer.) */
|
||||||
initialized!!! (Done by the OS
|
|
||||||
layer.) */
|
|
||||||
|
|
||||||
#if BUILD_INTERNAL
|
#if BUILD_INTERNAL
|
||||||
debug_read_file_result (*DEBUGPlatformReadEntireFile)(thread_context *Thread,const char *);
|
debug_read_file_result (*DEBUGPlatformReadEntireFile)(thread_context *Thread,const char *);
|
||||||
@@ -124,6 +120,9 @@ typedef struct game_memory {
|
|||||||
F32 SecondsElapsed;
|
F32 SecondsElapsed;
|
||||||
} game_clocks;*/
|
} game_clocks;*/
|
||||||
|
|
||||||
|
#if OS_WINDOWS
|
||||||
|
__declspec(dllexport)
|
||||||
|
#endif
|
||||||
void UpdateAndRender(thread_context *Thread, game_memory *Memory,
|
void UpdateAndRender(thread_context *Thread, game_memory *Memory,
|
||||||
game_input *Input, game_offscreen_buffer *Buffer,
|
game_input *Input, game_offscreen_buffer *Buffer,
|
||||||
game_sound_output_buffer *SoundBuffer);
|
game_sound_output_buffer *SoundBuffer);
|
||||||
|
|||||||
@@ -48,7 +48,9 @@ static bit_scan_result FindLeastSignificantSetBit(U32 Value)
|
|||||||
memset(&Result, 0, sizeof(Result));
|
memset(&Result, 0, sizeof(Result));
|
||||||
|
|
||||||
#if COMPILER_MSVC
|
#if COMPILER_MSVC
|
||||||
Result.Found = _BitScanForward(&Result.Index, Value); // TODO: I have not tested this.
|
unsigned long Index;
|
||||||
|
Result.Found = _BitScanForward(&Index, Value);
|
||||||
|
Result.Index = (U32)Index;
|
||||||
#elif COMPILER_CLANG
|
#elif COMPILER_CLANG
|
||||||
Result.Index = __builtin_ffsll(Value); // NOTE: It is a GCC function, but is supported by clang compiler.
|
Result.Index = __builtin_ffsll(Value); // NOTE: It is a GCC function, but is supported by clang compiler.
|
||||||
// https://gcc.gnu.org/onlinedocs/gcc/Bit-Operation-Builtins.html
|
// https://gcc.gnu.org/onlinedocs/gcc/Bit-Operation-Builtins.html
|
||||||
|
|||||||
@@ -65,4 +65,10 @@ F32 Square(F32 A)
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
F32 InnerProduct(v2 A, v2 B)
|
||||||
|
{
|
||||||
|
F32 Result = A.X*B.X + A.Y*B.Y;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/* GIMP RGBA C-Source image dump (program_icon.c) */
|
/* GIMP RGBA C-Source image dump (program_icon.c) */
|
||||||
|
|
||||||
|
// TODO: There is no way to disable a string limit via compiler flag in MSVC.
|
||||||
static const struct {
|
static const struct {
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
|
|||||||
Binary file not shown.
+124
-80
@@ -1,31 +1,47 @@
|
|||||||
/* NOTE: This layer only supports MacOS and Linux, for now. */
|
|
||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
|
// Remove SDL's entry point.
|
||||||
|
#if OS_WINDOWS
|
||||||
|
#define SDL_MAIN_HANDLED
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "handmade.h"
|
#include "handmade.h"
|
||||||
#include "sdl_handmade.h"
|
#include "sdl_handmade.h"
|
||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <sys/mman.h> /* mmap */
|
|
||||||
#include <stdlib.h> /* malloc, calloc */
|
#include <stdlib.h> /* malloc, calloc */
|
||||||
#include <string.h> /* memset, memcpy */
|
#include <string.h> /* memset, memcpy */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <sys/stat.h> /* fstat */
|
#include <sys/stat.h> /* fstat */
|
||||||
#include <fcntl.h> /* open */
|
#include <fcntl.h> /* open */
|
||||||
#include <unistd.h> /* close, write, read, readlink, unlink */
|
|
||||||
#include <dlfcn.h> /* dlopen */
|
|
||||||
#include <sys/stat.h> /* stat */
|
#include <sys/stat.h> /* stat */
|
||||||
|
|
||||||
|
#if OS_MACOS || OS_LINUX
|
||||||
|
#include <dlfcn.h> /* dlopen */
|
||||||
|
#include <sys/mman.h> /* mmap */
|
||||||
|
#include <unistd.h> /* close, write, read, readlink, unlink */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if OS_WINDOWS
|
||||||
|
#include <windows.h> /* VirtualAlloc */
|
||||||
|
#endif
|
||||||
|
|
||||||
#if OS_MACOS
|
#if OS_MACOS
|
||||||
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
|
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* NOTE: This is so it compiles on ARM. */
|
/* NOTE: This is so it compiles on ARM. */
|
||||||
#if ARCHITECTURE_X64 || ARCHITECTURE_X86
|
#if ARCHITECTURE_X64 || ARCHITECTURE_X86
|
||||||
#include <x86intrin.h>
|
#if OS_MACOS || OS_LINUX
|
||||||
|
#include <x86intrin.h> // TODO: What is the equivalent on Windows?
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
#include "program_icon.c"
|
#include "program_icon.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define RESOLUTION_WIDTH 960
|
#define RESOLUTION_WIDTH 960
|
||||||
#define RESOLUTION_HEIGHT 540
|
#define RESOLUTION_HEIGHT 540
|
||||||
@@ -61,77 +77,65 @@ static U32 SafeTruncateUInt64(U64 Value)
|
|||||||
|
|
||||||
debug_read_file_result DEBUGPlatformReadEntireFile(thread_context *Thread, const char *Filename)
|
debug_read_file_result DEBUGPlatformReadEntireFile(thread_context *Thread, const char *Filename)
|
||||||
{
|
{
|
||||||
|
(void)Thread;
|
||||||
|
|
||||||
debug_read_file_result Result;
|
debug_read_file_result Result;
|
||||||
memset(&Result, 0, sizeof(Result));
|
memset(&Result, 0, sizeof(Result));
|
||||||
|
|
||||||
S32 FileHandle = open(Filename, O_RDONLY);
|
SDL_RWops *FileHandle = SDL_RWFromFile(Filename, "r");
|
||||||
if(FileHandle == -1) {
|
if(FileHandle) {
|
||||||
|
S64 FileSize = SDL_RWsize(FileHandle);
|
||||||
|
if(FileSize >= 0) {
|
||||||
|
Result.ContentsSize = SafeTruncateUInt64(FileSize);
|
||||||
|
} else {
|
||||||
|
Result.ContentsSize = 0;
|
||||||
|
SDL_RWclose(FileHandle);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat FileStatus;
|
|
||||||
if(fstat(FileHandle, &FileStatus) == -1) {
|
|
||||||
close(FileHandle);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
Result.ContentsSize = SafeTruncateUInt64(FileStatus.st_size);
|
|
||||||
|
|
||||||
Result.Contents = malloc(Result.ContentsSize);
|
Result.Contents = malloc(Result.ContentsSize);
|
||||||
if(!Result.Contents) {
|
if(!Result.Contents) {
|
||||||
Result.ContentsSize = 0;
|
Result.ContentsSize = 0;
|
||||||
close(FileHandle);
|
SDL_RWclose(FileHandle);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
U32 BytesToRead = Result.ContentsSize;
|
size_t ObjectsRead = SDL_RWread(FileHandle, (void *)Result.Contents, (size_t)Result.ContentsSize, 1);
|
||||||
U8 *NextByteLocation = (U8 *)Result.Contents;
|
if(ObjectsRead == 0) {
|
||||||
while(BytesToRead) {
|
|
||||||
U32 BytesRead = read(FileHandle, NextByteLocation, BytesToRead);
|
|
||||||
if(BytesRead == (U32)-1) {
|
|
||||||
free(Result.Contents);
|
free(Result.Contents);
|
||||||
Result.Contents = 0;
|
Result.Contents = 0;
|
||||||
Result.ContentsSize = 0;
|
Result.ContentsSize = 0;
|
||||||
close(FileHandle);
|
SDL_RWclose(FileHandle);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
BytesToRead -= BytesRead;
|
|
||||||
NextByteLocation += BytesRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(FileHandle);
|
SDL_RWclose(FileHandle);
|
||||||
|
}
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
B32 DEBUGPlatformWriteEntireFile(thread_context *Thread, const char *Filename, U32 MemorySize, void *Memory)
|
B32 DEBUGPlatformWriteEntireFile(thread_context *Thread, const char *Filename, U32 MemorySize, void *Memory)
|
||||||
{
|
{
|
||||||
S32 FileHandle = open(Filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
SDL_RWops *FileHandle = SDL_RWFromFile(Filename, "w");
|
||||||
if(FileHandle == -1)
|
if(FileHandle) {
|
||||||
return FALSE;
|
size_t ObjectsWritten = SDL_RWwrite(FileHandle, (void *)Memory, (size_t)MemorySize, 1);
|
||||||
|
if(ObjectsWritten == 0) {
|
||||||
U32 BytesToWrite = MemorySize;
|
SDL_RWclose(FileHandle);
|
||||||
U8 *NextByteLocation = (U8*)Memory;
|
|
||||||
while(BytesToWrite) {
|
|
||||||
U32 BytesWritten;
|
|
||||||
|
|
||||||
BytesWritten = write(FileHandle, NextByteLocation, BytesToWrite);
|
|
||||||
if(BytesWritten == (U32)-1) {
|
|
||||||
close(FileHandle);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
BytesToWrite -= BytesWritten;
|
|
||||||
NextByteLocation += BytesWritten;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(FileHandle);
|
|
||||||
|
|
||||||
|
SDL_RWclose(FileHandle);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DEBUGPlatformFreeFileMemory(thread_context *Thread, void *Memory)
|
void DEBUGPlatformFreeFileMemory(thread_context *Thread, void *Memory)
|
||||||
{
|
{
|
||||||
if(Memory)
|
if(Memory)
|
||||||
free(Memory);
|
free(Memory); // TODO: Should we accept debug_read_file_result instead of just memory.
|
||||||
}
|
}
|
||||||
|
|
||||||
static sdl_window_size SDLGetWindowSize(SDL_Window *Window)
|
static sdl_window_size SDLGetWindowSize(SDL_Window *Window)
|
||||||
@@ -187,8 +191,8 @@ static void SDLDisplayBufferInWindow(offscreen_buffer *Buffer, SDL_Window *Windo
|
|||||||
|
|
||||||
/* TODO: We temporarily introduce the target rectangle to avoid stretching the canvas. */
|
/* TODO: We temporarily introduce the target rectangle to avoid stretching the canvas. */
|
||||||
/* SDL_RenderCopy(Renderer, Buffer.Texture, 0, 0); */
|
/* SDL_RenderCopy(Renderer, Buffer.Texture, 0, 0); */
|
||||||
sdl_window_size WindowSize = SDLGetWindowSize(Window);
|
sdl_window_size WinSize = SDLGetWindowSize(Window);
|
||||||
if(WindowSize.Width >= Buffer->Width*2 && WindowSize.Height >= Buffer->Height*2) {
|
if(WinSize.Width >= Buffer->Width*2 && WinSize.Height >= Buffer->Height*2) {
|
||||||
SDL_Rect dest_rect = { OffsetX, OffsetY, Buffer->Width*2, Buffer->Height*2 };
|
SDL_Rect dest_rect = { OffsetX, OffsetY, Buffer->Width*2, Buffer->Height*2 };
|
||||||
SDL_RenderCopy(Renderer, Buffer->Texture, 0, (const SDL_Rect *)(&dest_rect));
|
SDL_RenderCopy(Renderer, Buffer->Texture, 0, (const SDL_Rect *)(&dest_rect));
|
||||||
} else {
|
} else {
|
||||||
@@ -230,7 +234,7 @@ static void SDLInitSound(S32 SamplesPerSecond, S32 BufferSize)
|
|||||||
AudioSettings.freq = SamplesPerSecond;
|
AudioSettings.freq = SamplesPerSecond;
|
||||||
AudioSettings.format = AUDIO_S16LSB;
|
AudioSettings.format = AUDIO_S16LSB;
|
||||||
AudioSettings.channels = 2;
|
AudioSettings.channels = 2;
|
||||||
AudioSettings.samples = BufferSize;
|
AudioSettings.samples = (U16)BufferSize; // TODO: Unsafe truncate from S32 to U16
|
||||||
|
|
||||||
SDL_OpenAudio(&AudioSettings, 0);
|
SDL_OpenAudio(&AudioSettings, 0);
|
||||||
|
|
||||||
@@ -381,10 +385,8 @@ static void SDLProcessMessages(sdl_state *SDLState, game_controller_input *Keybo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(WasDown) {
|
if(WasDown) {
|
||||||
/* NOTE: If your window manager already uses an Alt+F4
|
/* NOTE: If your window manager already uses an Alt+F4 keybind to close programs, then we are likely
|
||||||
* keybind to close programs, then we are likely
|
* to see SDL_QUIT event occur before our keybind. */
|
||||||
* to see SDL_QUIT event occur before our
|
|
||||||
* keybind. */
|
|
||||||
B32 AltKeyWasDown = (Event.key.keysym.mod & KMOD_ALT);
|
B32 AltKeyWasDown = (Event.key.keysym.mod & KMOD_ALT);
|
||||||
|
|
||||||
if(KeyCode == SDLK_F4 && AltKeyWasDown)
|
if(KeyCode == SDLK_F4 && AltKeyWasDown)
|
||||||
@@ -463,18 +465,38 @@ static U32 GetLastWriteTime(const char *FileName)
|
|||||||
return (U32)file_info.st_mtime;
|
return (U32)file_info.st_mtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if OS_MACOS || OS_LINUX
|
||||||
#define GAME_DLL_NAME "libhandmade.so"
|
#define GAME_DLL_NAME "libhandmade.so"
|
||||||
|
#elif OS_WINDOWS
|
||||||
|
#define GAME_DLL_NAME "handmade.dll"
|
||||||
|
#else
|
||||||
|
#error Unknown OS: please specify GAME_DLL_NAME
|
||||||
|
#endif
|
||||||
|
|
||||||
static sdl_game_code SDLLoadGameCode(char *DLLPath)
|
static sdl_game_code SDLLoadGameCode(char *DLLPath)
|
||||||
{
|
{
|
||||||
sdl_game_code Result;
|
sdl_game_code Result;
|
||||||
memset(&Result, 0, sizeof(Result));
|
memset(&Result, 0, sizeof(Result));
|
||||||
|
|
||||||
|
#if OS_MACOS || OS_LINUX
|
||||||
Result.GameCodeDLL = dlopen(DLLPath, RTLD_NOW);
|
Result.GameCodeDLL = dlopen(DLLPath, RTLD_NOW);
|
||||||
|
#elif OS_WINDOWS
|
||||||
|
Result.GameCodeDLL = LoadLibraryA(DLLPath);
|
||||||
|
#else
|
||||||
|
#error Unknown OS: implement DLL loading...
|
||||||
|
#endif
|
||||||
|
|
||||||
if(Result.GameCodeDLL) {
|
if(Result.GameCodeDLL) {
|
||||||
Result.DLLLastWriteTime = GetLastWriteTime(DLLPath);
|
Result.DLLLastWriteTime = GetLastWriteTime(DLLPath);
|
||||||
|
|
||||||
Result.UpdateAndRender = (void(*)(thread_context *, game_memory *, game_input *, game_offscreen_buffer *, game_sound_output_buffer *)) dlsym(Result.GameCodeDLL, "UpdateAndRender");
|
#if OS_MACOS || OS_LINUX
|
||||||
|
Result.UpdateAndRender = (void(*)(thread_context *, game_memory *, game_input *, game_offscreen_buffer *, game_sound_output_buffer *))dlsym(Result.GameCodeDLL, "UpdateAndRender");
|
||||||
|
#elif OS_WINDOWS
|
||||||
|
Result.UpdateAndRender = (void(*)(thread_context *, game_memory *, game_input *, game_offscreen_buffer *, game_sound_output_buffer *))GetProcAddress(Result.GameCodeDLL, "UpdateAndRender");
|
||||||
|
#else
|
||||||
|
#error Unknown OS: implement DLL loading...
|
||||||
|
#endif
|
||||||
|
|
||||||
if(!Result.UpdateAndRender) {
|
if(!Result.UpdateAndRender) {
|
||||||
/* TODO: Diagnostic. dlerror() */
|
/* TODO: Diagnostic. dlerror() */
|
||||||
}
|
}
|
||||||
@@ -493,8 +515,15 @@ static sdl_game_code SDLLoadGameCode(char *DLLPath)
|
|||||||
|
|
||||||
static void SDLUnloadGameCode(sdl_game_code *GameCode)
|
static void SDLUnloadGameCode(sdl_game_code *GameCode)
|
||||||
{
|
{
|
||||||
if(GameCode->GameCodeDLL)
|
if(GameCode->GameCodeDLL) {
|
||||||
|
#if OS_MACOS || OS_LINUX
|
||||||
dlclose(GameCode->GameCodeDLL); /* NOTE: Might fail. */
|
dlclose(GameCode->GameCodeDLL); /* NOTE: Might fail. */
|
||||||
|
#elif OS_WINDOWS
|
||||||
|
FreeLibrary(GameCode->GameCodeDLL);
|
||||||
|
#else
|
||||||
|
#error Unknown OS: implement closing of DLL
|
||||||
|
#endif
|
||||||
|
}
|
||||||
GameCode->IsValid = FALSE;
|
GameCode->IsValid = FALSE;
|
||||||
GameCode->UpdateAndRender = NULL;
|
GameCode->UpdateAndRender = NULL;
|
||||||
}
|
}
|
||||||
@@ -503,7 +532,7 @@ void GetExecutablePath(char *path, size_t path_size)
|
|||||||
{
|
{
|
||||||
#if OS_MACOS
|
#if OS_MACOS
|
||||||
U32 size;
|
U32 size;
|
||||||
#else
|
#elif OS_LINUX
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -512,18 +541,20 @@ void GetExecutablePath(char *path, size_t path_size)
|
|||||||
|
|
||||||
#if OS_MACOS
|
#if OS_MACOS
|
||||||
size = path_size;
|
size = path_size;
|
||||||
if(_NSGetExecutablePath(path, &size) != 0) { /* NOTE: Not an
|
if(_NSGetExecutablePath(path, &size) != 0) { /* NOTE: Not an absolute path. */
|
||||||
absolute
|
|
||||||
path. */
|
|
||||||
/* TODO: Diagnostics. */
|
/* TODO: Diagnostics. */
|
||||||
}
|
}
|
||||||
#else
|
#elif OS_LINUX
|
||||||
size = readlink("/proc/self/exe", path, path_size - 1);
|
size = readlink("/proc/self/exe", path, path_size - 1);
|
||||||
if(size != -1) {
|
if(size != -1) {
|
||||||
path[size] = '\0';
|
path[size] = '\0';
|
||||||
} else {
|
} else {
|
||||||
/* TODO: Diagnostics. */
|
/* TODO: Diagnostics. */
|
||||||
}
|
}
|
||||||
|
#elif OS_WINDOWS
|
||||||
|
GetModuleFileName(NULL, path, (DWORD)path_size); // TODO: hm...
|
||||||
|
#else
|
||||||
|
#error Unknown OS: Implement getting executable location.
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -533,7 +564,16 @@ static void SDLGetEXEDirPath(char *path, size_t path_size)
|
|||||||
GetExecutablePath(path, path_size);
|
GetExecutablePath(path, path_size);
|
||||||
U32 len = str_len(path);
|
U32 len = str_len(path);
|
||||||
U32 i = len;
|
U32 i = len;
|
||||||
while(path[i] != '/' || i == 0) {
|
|
||||||
|
#if OS_MACOS || OS_LINUX
|
||||||
|
char delimeter = '/';
|
||||||
|
#elif OS_WINDOWS
|
||||||
|
char delimeter = '\\';
|
||||||
|
#else
|
||||||
|
#error Unknown OS: specify whether your OS uses forward or backward slashes for paths
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while(path[i] != delimeter || i == 0) {
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
path[i+1] = '\0';
|
path[i+1] = '\0';
|
||||||
@@ -557,6 +597,7 @@ U64 __rdtsc()
|
|||||||
* drawing into a bitmap. */
|
* drawing into a bitmap. */
|
||||||
void SDLSetProgramIcon(SDL_Window *Window)
|
void SDLSetProgramIcon(SDL_Window *Window)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
U32 Rmask, Gmask, Bmask, Amask;
|
U32 Rmask, Gmask, Bmask, Amask;
|
||||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||||
S32 shift_by = (program_icon.bytes_per_pixel == 3) ? 8 : 0;
|
S32 shift_by = (program_icon.bytes_per_pixel == 3) ? 8 : 0;
|
||||||
@@ -571,19 +612,15 @@ void SDLSetProgramIcon(SDL_Window *Window)
|
|||||||
Amask = (program_icon.bytes_per_pixel == 3) ? 0 : 0xff000000;
|
Amask = (program_icon.bytes_per_pixel == 3) ? 0 : 0xff000000;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SDL_Surface * icon = SDL_CreateRGBSurfaceFrom(
|
SDL_Surface * icon = SDL_CreateRGBSurfaceFrom((void *)program_icon.pixel_data, program_icon.width, program_icon.height,
|
||||||
(void *)program_icon.pixel_data,
|
program_icon.bytes_per_pixel * 8, program_icon.bytes_per_pixel * program_icon.width, Rmask, Gmask, Bmask, Amask);
|
||||||
program_icon.width, program_icon.height,
|
|
||||||
program_icon.bytes_per_pixel * 8,
|
|
||||||
program_icon.bytes_per_pixel * program_icon.width,
|
|
||||||
Rmask, Gmask, Bmask, Amask);
|
|
||||||
if(icon) {
|
if(icon) {
|
||||||
SDL_SetWindowIcon(Window, icon);
|
SDL_SetWindowIcon(Window, icon);
|
||||||
SDL_FreeSurface(icon);
|
SDL_FreeSurface(icon);
|
||||||
} else {
|
} else {
|
||||||
/* TODO: This didn't work . . . SDL_GetError() */
|
/* TODO: This didn't work . . . SDL_GetError() */
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "handmade_intrinsics.h"
|
#include "handmade_intrinsics.h"
|
||||||
@@ -595,7 +632,7 @@ S32 main(S32 argc, char *argv[])
|
|||||||
SDLGetEXEDirPath(SDLState.EXEDirPath, sizeof(SDLState.EXEDirPath));
|
SDLGetEXEDirPath(SDLState.EXEDirPath, sizeof(SDLState.EXEDirPath));
|
||||||
SDLGetDLLPath(SDLState.DLLPath, sizeof(SDLState.DLLPath), SDLState.EXEDirPath);
|
SDLGetDLLPath(SDLState.DLLPath, sizeof(SDLState.DLLPath), SDLState.EXEDirPath);
|
||||||
|
|
||||||
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO)) {
|
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMECONTROLLER)) {
|
||||||
/* TODO: This didn't work . . . */
|
/* TODO: This didn't work . . . */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -616,9 +653,7 @@ S32 main(S32 argc, char *argv[])
|
|||||||
|
|
||||||
SDL_Renderer *Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_PRESENTVSYNC);
|
SDL_Renderer *Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_PRESENTVSYNC);
|
||||||
|
|
||||||
/* NOTE: For future reference, the custom window bar should use
|
/* NOTE: For future reference, the custom window bar should use SDL_SetWindowHitTest to define areas that will be used to drag the window. */
|
||||||
* SDL_SetWindowHitTest to define areas that will be used to
|
|
||||||
* drag the window. */
|
|
||||||
|
|
||||||
/* "Wayland needs an event loop and rendering or it won't function."
|
/* "Wayland needs an event loop and rendering or it won't function."
|
||||||
* https://github.com/libsdl-org/SDL/issues/7699#issuecomment-1545684792 */
|
* https://github.com/libsdl-org/SDL/issues/7699#issuecomment-1545684792 */
|
||||||
@@ -653,7 +688,7 @@ S32 main(S32 argc, char *argv[])
|
|||||||
SoundOutput.LatencySampleCount = SoundOutput.SamplesPerSecond / 15;
|
SoundOutput.LatencySampleCount = SoundOutput.SamplesPerSecond / 15;
|
||||||
|
|
||||||
SDLInitSound(SoundOutput.SamplesPerSecond, SoundOutput.SamplesPerSecond * SoundOutput.BytesPerSample / 60);
|
SDLInitSound(SoundOutput.SamplesPerSecond, SoundOutput.SamplesPerSecond * SoundOutput.BytesPerSample / 60);
|
||||||
SDL_PauseAudio(0);
|
SDL_PauseAudio(0); // TODO: This should be paused until we have some actual sound to play.
|
||||||
|
|
||||||
SoundOutput.Samples = calloc(SoundOutput.SamplesPerSecond, SoundOutput.BytesPerSample);
|
SoundOutput.Samples = calloc(SoundOutput.SamplesPerSecond, SoundOutput.BytesPerSample);
|
||||||
/* SoundOutput.Samples =
|
/* SoundOutput.Samples =
|
||||||
@@ -672,13 +707,18 @@ S32 main(S32 argc, char *argv[])
|
|||||||
GameMemory.PermanentStorageSize = MB(64);
|
GameMemory.PermanentStorageSize = MB(64);
|
||||||
GameMemory.TransientStorageSize = GB(1);
|
GameMemory.TransientStorageSize = GB(1);
|
||||||
GameMemory.DEBUGPlatformReadEntireFile = &DEBUGPlatformReadEntireFile;
|
GameMemory.DEBUGPlatformReadEntireFile = &DEBUGPlatformReadEntireFile;
|
||||||
GameMemory.DEBUGPlatformWriteEntireFile = &DEBUGPlatformWriteEntireFile;
|
//GameMemory.DEBUGPlatformWriteEntireFile = &DEBUGPlatformWriteEntireFile;
|
||||||
GameMemory.DEBUGPlatformFreeFileMemory = &DEBUGPlatformFreeFileMemory;
|
GameMemory.DEBUGPlatformFreeFileMemory = &DEBUGPlatformFreeFileMemory;
|
||||||
|
|
||||||
SDLState.TotalSize = GameMemory.PermanentStorageSize + GameMemory.TransientStorageSize;
|
SDLState.TotalSize = GameMemory.PermanentStorageSize + GameMemory.TransientStorageSize;
|
||||||
/* NOTE: On MacOS and Linux, mmap seems to zero-fill anonymous
|
#if OS_MACOS || OS_LINUX
|
||||||
* memory as a side-effect of security. */
|
/* NOTE: On MacOS and Linux, mmap seems to zero-fill anonymous memory as a side-effect of security. */
|
||||||
SDLState.GameMmemoryBlock = mmap(BaseAddress, (size_t)SDLState.TotalSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
|
SDLState.GameMmemoryBlock = mmap(BaseAddress, (size_t)SDLState.TotalSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||||
|
#elif OS_WINDOWS
|
||||||
|
SDLState.GameMmemoryBlock = VirtualAlloc(BaseAddress, SDLState.TotalSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||||
|
#else
|
||||||
|
#error Unknown OS: please, allocate memory for arena
|
||||||
|
#endif
|
||||||
GameMemory.PermanentStorage = SDLState.GameMmemoryBlock;
|
GameMemory.PermanentStorage = SDLState.GameMmemoryBlock;
|
||||||
GameMemory.TransientStorage = (U8 *)(GameMemory.PermanentStorage) + GameMemory.PermanentStorageSize;
|
GameMemory.TransientStorage = (U8 *)(GameMemory.PermanentStorage) + GameMemory.PermanentStorageSize;
|
||||||
|
|
||||||
@@ -701,18 +741,17 @@ S32 main(S32 argc, char *argv[])
|
|||||||
|
|
||||||
sdl_game_code Game = SDLLoadGameCode(SDLState.DLLPath);
|
sdl_game_code Game = SDLLoadGameCode(SDLState.DLLPath);
|
||||||
|
|
||||||
SDL_ShowWindow(Window); // NOTE: Everything is ready; display the window.
|
SDL_ShowWindow(Window); // Everything is ready; display the window.
|
||||||
|
|
||||||
|
U64 FPSLastCounter = SDLGetWallClock();
|
||||||
|
|
||||||
while(GlobalRunning) {
|
while(GlobalRunning) {
|
||||||
NewInput->dtForFrame = TargetSecondsPerFrame;
|
NewInput->dtForFrame = TargetSecondsPerFrame;
|
||||||
|
|
||||||
LastCounter = SDLGetWallClock();
|
LastCounter = SDLGetWallClock();
|
||||||
|
|
||||||
/* NOTE: rdtsc reports clock cylces, however it is not
|
/* NOTE: rdtsc reports clock cylces, however it is not meant for really precise profiler work as the
|
||||||
* meant for really precise profiler work as the
|
* value returned is varied. Also, __rdtsc is not available on MacOS ARM; I have not checked MacOS x64. */
|
||||||
* value returned is varied. */
|
|
||||||
/* Also, __rdtsc is not available on MacOS ARM; I
|
|
||||||
* have not checked MacOS x64. */
|
|
||||||
LastCycleCount = __rdtsc();
|
LastCycleCount = __rdtsc();
|
||||||
|
|
||||||
U32 NewDLLWriteTime = GetLastWriteTime(SDLState.DLLPath);
|
U32 NewDLLWriteTime = GetLastWriteTime(SDLState.DLLPath);
|
||||||
@@ -842,6 +881,7 @@ S32 main(S32 argc, char *argv[])
|
|||||||
if(SecondsElapsedForFrame < TargetSecondsPerFrame) {
|
if(SecondsElapsedForFrame < TargetSecondsPerFrame) {
|
||||||
while(SecondsElapsedForFrame < TargetSecondsPerFrame) {
|
while(SecondsElapsedForFrame < TargetSecondsPerFrame) {
|
||||||
SecondsElapsedForFrame = SDLGetSecondsElapsed(LastCounter, SDLGetWallClock());
|
SecondsElapsedForFrame = SDLGetSecondsElapsed(LastCounter, SDLGetWallClock());
|
||||||
|
if((TargetSecondsPerFrame - SecondsElapsedForFrame) >= 0.0f)
|
||||||
SDL_Delay((U32)((TargetSecondsPerFrame - SecondsElapsedForFrame) * 1000.0));
|
SDL_Delay((U32)((TargetSecondsPerFrame - SecondsElapsedForFrame) * 1000.0));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -859,6 +899,7 @@ S32 main(S32 argc, char *argv[])
|
|||||||
LastCounter = EndCounter;
|
LastCounter = EndCounter;
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
if(SDLGetSecondsElapsed(FPSLastCounter, SDLGetWallClock()) > 0.1f) {
|
||||||
U64 EndCycleCount = __rdtsc();
|
U64 EndCycleCount = __rdtsc();
|
||||||
U64 CyclesElapsed = EndCycleCount - LastCycleCount;
|
U64 CyclesElapsed = EndCycleCount - LastCycleCount;
|
||||||
F64 MCPF = ((F64)CyclesElapsed / (1000.0 * 1000.0));
|
F64 MCPF = ((F64)CyclesElapsed / (1000.0 * 1000.0));
|
||||||
@@ -870,6 +911,9 @@ S32 main(S32 argc, char *argv[])
|
|||||||
SDL_SetWindowTitle(Window, (const char *)fps_buffer);
|
SDL_SetWindowTitle(Window, (const char *)fps_buffer);
|
||||||
|
|
||||||
LastCycleCount = EndCycleCount;
|
LastCycleCount = EndCycleCount;
|
||||||
|
|
||||||
|
FPSLastCounter = SDLGetWallClock();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SWAP(game_input *, OldInput, NewInput);
|
SWAP(game_input *, OldInput, NewInput);
|
||||||
|
|||||||
+2
-2
@@ -34,8 +34,8 @@ typedef struct sdl_sound_output {
|
|||||||
void *Samples;
|
void *Samples;
|
||||||
} sdl_sound_output;
|
} sdl_sound_output;
|
||||||
|
|
||||||
/* NOTE: We choose 1024 only because MacOS's MAXPATHLEN says such a value.
|
/* TODO: We choose 1024 only because MacOS's MAXPATHLEN says such a value.
|
||||||
* For example, linux/limits.h PATH_MAX says 4096. */
|
* For example, linux/limits.h PATH_MAX says 4096. Windows has MAX_PATH. */
|
||||||
#define SDL_STATE_PATH_SIZE 1024
|
#define SDL_STATE_PATH_SIZE 1024
|
||||||
|
|
||||||
typedef struct sdl_state {
|
typedef struct sdl_state {
|
||||||
|
|||||||
Reference in New Issue
Block a user