Start using dqnt lib
This commit is contained in:
parent
dff3495087
commit
b415f4c237
127
src/Common.h
127
src/Common.h
@ -1,127 +0,0 @@
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
#define LOCAL_PERSIST static
|
||||
#define FILE_SCOPE static
|
||||
|
||||
typedef uint32_t u32;
|
||||
typedef uint16_t u16;
|
||||
typedef uint8_t u8;
|
||||
|
||||
typedef int64_t i64;
|
||||
typedef int32_t i32;
|
||||
typedef int16_t i16;
|
||||
|
||||
typedef float f32;
|
||||
|
||||
#define INVALID_CODE_PATH 0
|
||||
|
||||
#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
|
||||
|
||||
#ifdef DEBUG_MODE
|
||||
#define ASSERT(expr) if (!(expr)) { (*((int *)0)) = 0; }
|
||||
#else
|
||||
#define ASSERT(expr)
|
||||
#endif
|
||||
|
||||
#define MATH_ABS(x) (((x) < 0) ? (-(x)) : (x))
|
||||
|
||||
typedef union v2 {
|
||||
struct { f32 x, y; };
|
||||
struct { f32 w, h; };
|
||||
} v2;
|
||||
|
||||
inline FILE_SCOPE v2 V2(f32 x, f32 y)
|
||||
{
|
||||
v2 result = {};
|
||||
result.x = x;
|
||||
result.y = y;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline FILE_SCOPE v2 V2i(i32 x, i32 y)
|
||||
{
|
||||
v2 result = V2((f32)x, (f32)y);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline FILE_SCOPE i32 common_strcmp(const char *a, const char *b)
|
||||
{
|
||||
while ((*a) == (*b))
|
||||
{
|
||||
if (!(*a)) return 0;
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
|
||||
return (((*a) < (*b)) ? -1 : 1);
|
||||
}
|
||||
|
||||
inline FILE_SCOPE i32 common_wstrcmp(const wchar_t *a, const wchar_t *b)
|
||||
{
|
||||
while ((*a) == (*b))
|
||||
{
|
||||
if (!(*a)) return 0;
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
|
||||
return (((*a) < (*b)) ? -1 : 1);
|
||||
}
|
||||
|
||||
inline FILE_SCOPE void common_wstrcat(const wchar_t *a, i32 lenA,
|
||||
const wchar_t *b, i32 lenB, wchar_t *out,
|
||||
i32 outLen)
|
||||
{
|
||||
ASSERT((lenA + lenB) < outLen);
|
||||
|
||||
i32 outIndex = 0;
|
||||
for (i32 i = 0; i < lenA; i++)
|
||||
out[outIndex++] = a[i];
|
||||
|
||||
for (i32 i = 0; i < lenB; i++)
|
||||
out[outIndex++] = b[i];
|
||||
|
||||
ASSERT(outIndex <= outLen);
|
||||
}
|
||||
|
||||
inline FILE_SCOPE wchar_t common_wchar_ascii_to_lower(wchar_t character)
|
||||
{
|
||||
if (character >= L'A' && character <= L'Z')
|
||||
{
|
||||
i32 shiftOffset = L'a' - L'A';
|
||||
character += (wchar_t)shiftOffset;
|
||||
}
|
||||
|
||||
return character;
|
||||
}
|
||||
|
||||
inline FILE_SCOPE i32 common_wstrlen(const wchar_t *a)
|
||||
{
|
||||
i32 result = 0;
|
||||
while ((*a))
|
||||
{
|
||||
result++;
|
||||
a++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline FILE_SCOPE i32 common_strlen(const char *a)
|
||||
{
|
||||
i32 result = 0;
|
||||
while ((*a))
|
||||
{
|
||||
result++;
|
||||
a++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
#include "common.h"
|
||||
#include "dchip8_platform.h"
|
||||
#include "dqnt.h"
|
||||
|
||||
typedef struct Chip8CPU
|
||||
{
|
||||
@ -54,15 +54,13 @@ typedef struct Chip8CPU
|
||||
} Chip8CPU;
|
||||
|
||||
FILE_SCOPE Chip8CPU cpu;
|
||||
FILE_SCOPE u16 opCodes[35];
|
||||
|
||||
void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
PlatformMemory memory)
|
||||
{
|
||||
ASSERT(indexRegister >= 0 && indexRegister <= 0xFFF);
|
||||
ASSERT(programCounter >= 0 && programCounter <= 0xFFF);
|
||||
DQNT_ASSERT(indexRegister >= 0 && indexRegister <= 0xFFF);
|
||||
DQNT_ASSERT(programCounter >= 0 && programCounter <= 0xFFF);
|
||||
|
||||
ASSERT(renderBuffer.bytesPerPixel == 4);
|
||||
DQNT_ASSERT(renderBuffer.bytesPerPixel == 4);
|
||||
|
||||
const i32 numPixels = renderBuffer.width * renderBuffer.height;
|
||||
u32 *bitmapBuffer = (u32 *)renderBuffer.memory;
|
||||
@ -86,7 +84,7 @@ void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
|
||||
if (!cpu.isInit)
|
||||
{
|
||||
ASSERT(memory.permanentMemSize == (4096 / 4));
|
||||
DQNT_ASSERT(memory.permanentMemSize == (4096 / 4));
|
||||
cpu.isInit = true;
|
||||
|
||||
// NOTE: Everything before 0x200 is reserved for the actual emulator
|
||||
@ -94,8 +92,11 @@ void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
cpu.programCounter = INIT_ADDRESS;
|
||||
cpu.I = 0;
|
||||
cpu.stackPointer = 0;
|
||||
|
||||
// TODO(doyle): Load rom
|
||||
}
|
||||
|
||||
#if 0
|
||||
u8 *mainMem = (u8 *)memory.permanentMem;
|
||||
u8 opHighByte = mainMem[cpu.programCounter++];
|
||||
u8 opLowByte = mainMem[cpu.programCounter++];
|
||||
@ -121,7 +122,7 @@ void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
case 0x20:
|
||||
{
|
||||
u16 loc = ((0x0F & opHighByte) << 8) | (0xFF & opLowByte);
|
||||
ASSERT(loc <= 0x0FFF);
|
||||
DQNT_ASSERT(loc <= 0x0FFF);
|
||||
|
||||
// JP addr - 1nnn - Jump to location nnn
|
||||
if (opFirstNibble == 0x10)
|
||||
@ -131,10 +132,10 @@ void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
// Call addr - 2nnn - Call subroutine at nnn
|
||||
else
|
||||
{
|
||||
ASSERT(opFirstNibble == 0x20);
|
||||
DQNT_ASSERT(opFirstNibble == 0x20);
|
||||
|
||||
cpu.stackPointer++;
|
||||
ASSERT(cpu.stackPointer < ARRAY_COUNT(cpu.stack));
|
||||
DQNT_ASSERT(cpu.stackPointer < DQNT_ARRAY_COUNT(cpu.stack));
|
||||
cpu.stack[cpu.stackPointer] = cpu.programCounter;
|
||||
}
|
||||
|
||||
@ -146,7 +147,7 @@ void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
case 0x40:
|
||||
{
|
||||
u8 regNum = (0x0F & opHighByte);
|
||||
ASSERT(regNum < ARRAY_COUNT(cpu.registerArray));
|
||||
DQNT_ASSERT(regNum < DQNT_ARRAY_COUNT(cpu.registerArray));
|
||||
u8 valToCheck = opLowByte;
|
||||
|
||||
// SE Vx, byte - 3xkk - Skip next instruction if Vx == kk
|
||||
@ -158,7 +159,7 @@ void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
// SNE Vx, byte - 4xkk - Skip next instruction if Vx == kk
|
||||
else
|
||||
{
|
||||
ASSERT(opFirstNibble == 0x40);
|
||||
DQNT_ASSERT(opFirstNibble == 0x40);
|
||||
if (cpu.registerArray[regNum] != valToCheck)
|
||||
cpu.programCounter += 2;
|
||||
}
|
||||
@ -169,10 +170,10 @@ void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
case 0x50:
|
||||
{
|
||||
u8 firstRegNum = (0x0F & opHighByte);
|
||||
ASSERT(firstRegNum < ARRAY_COUNT(cpu.registerArray));
|
||||
DQNT_ASSERT(firstRegNum < DQNT_ARRAY_COUNT(cpu.registerArray));
|
||||
|
||||
u8 secondRegNum = (0xF0 & opLowByte);
|
||||
ASSERT(secondRegNum < ARRAY_COUNT(cpu.registerArray));
|
||||
DQNT_ASSERT(secondRegNum < DQNT_ARRAY_COUNT(cpu.registerArray));
|
||||
|
||||
if (cpu.registerArray[firstRegNum] ==
|
||||
cpu.registerArray[secondRegNum])
|
||||
@ -186,7 +187,7 @@ void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
case 0x70:
|
||||
{
|
||||
u8 regNum = (0x0F & opHighByte);
|
||||
ASSERT(regNum < ARRAY_COUNT(cpu.registerArray));
|
||||
DQNT_ASSERT(regNum < DQNT_ARRAY_COUNT(cpu.registerArray));
|
||||
u8 valToOperateOn = opLowByte;
|
||||
|
||||
// LD Vx, byte - 6xkk - Set Vx = kk
|
||||
@ -197,7 +198,7 @@ void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
// ADD Vx, byte - 7xkk - Set Vx = Vx + kk
|
||||
else
|
||||
{
|
||||
ASSERT(opFirstNibble == 0x70);
|
||||
DQNT_ASSERT(opFirstNibble == 0x70);
|
||||
cpu.registerArray[regNum] += valToOperateOn;
|
||||
}
|
||||
|
||||
@ -207,10 +208,10 @@ void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
case 0x80:
|
||||
{
|
||||
u8 firstRegNum = (0x0F & opHighByte);
|
||||
ASSERT(firstRegNum < ARRAY_COUNT(cpu.registerArray));
|
||||
DQNT_ASSERT(firstRegNum < DQNT_ARRAY_COUNT(cpu.registerArray));
|
||||
|
||||
u8 secondRegNum = (0xF0 & opLowByte);
|
||||
ASSERT(secondRegNum < ARRAY_COUNT(cpu.registerArray));
|
||||
DQNT_ASSERT(secondRegNum < DQNT_ARRAY_COUNT(cpu.registerArray));
|
||||
|
||||
u8 *vx = &cpu.registerArray[firstRegNum];
|
||||
u8 *vy = &cpu.registerArray[secondRegNum];
|
||||
@ -280,7 +281,7 @@ void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
// SHL Vx {, Vy} - 8xyE - Set Vx = SHL 1
|
||||
else
|
||||
{
|
||||
ASSERT(opLowByte == 0x0E);
|
||||
DQNT_ASSERT(opLowByte == 0x0E);
|
||||
if ((*vx >> 7) == 1)
|
||||
cpu.VF = 1;
|
||||
else
|
||||
@ -295,10 +296,10 @@ void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
case 0x90:
|
||||
{
|
||||
u8 firstRegNum = (0x0F & opHighByte);
|
||||
ASSERT(firstRegNum < ARRAY_COUNT(cpu.registerArray));
|
||||
DQNT_ASSERT(firstRegNum < DQNT_ARRAY_COUNT(cpu.registerArray));
|
||||
|
||||
u8 secondRegNum = (0xF0 & opLowByte);
|
||||
ASSERT(secondRegNum < ARRAY_COUNT(cpu.registerArray));
|
||||
DQNT_ASSERT(secondRegNum < DQNT_ARRAY_COUNT(cpu.registerArray));
|
||||
|
||||
u8 *vx = &cpu.registerArray[firstRegNum];
|
||||
u8 *vy = &cpu.registerArray[secondRegNum];
|
||||
@ -327,7 +328,7 @@ void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
case 0xC0:
|
||||
{
|
||||
u8 firstRegNum = (0x0F & opHighByte);
|
||||
ASSERT(firstRegNum < ARRAY_COUNT(cpu.registerArray));
|
||||
DQNT_ASSERT(firstRegNum < DQNT_ARRAY_COUNT(cpu.registerArray));
|
||||
|
||||
u8 andBits = opLowByte;
|
||||
u8 *vx = &cpu.registerArray[firstRegNum];
|
||||
@ -360,7 +361,7 @@ void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
// Vx is not pressed
|
||||
else
|
||||
{
|
||||
ASSERT(opLowByte == 0xA1);
|
||||
DQNT_ASSERT(opLowByte == 0xA1);
|
||||
}
|
||||
|
||||
if (skipNextInstruction) cpu.programCounter += 2;
|
||||
@ -370,7 +371,7 @@ void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
case 0xF0:
|
||||
{
|
||||
u8 regNum = (0x0F & opHighByte);
|
||||
ASSERT(regNum < ARRAY_COUNT(cpu.registerArray));
|
||||
DQNT_ASSERT(regNum < DQNT_ARRAY_COUNT(cpu.registerArray));
|
||||
u8 *vx = &cpu.registerArray[regNum];
|
||||
|
||||
// LD Vx, DT - Fx07 - Set Vx = delay timer value
|
||||
@ -423,7 +424,7 @@ void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
// starting at location I.
|
||||
else
|
||||
{
|
||||
ASSERT(opLowByte == 0x65);
|
||||
DQNT_ASSERT(opLowByte == 0x65);
|
||||
for (u32 regIndex = 0; regIndex <= regNum; regIndex++)
|
||||
{
|
||||
u32 mem_offset = regIndex;
|
||||
@ -434,4 +435,5 @@ void dchip8_update(PlatformRenderBuffer renderBuffer, PlatformInput input,
|
||||
}
|
||||
break;
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef DCHIP_8_PLATFORM
|
||||
#define DCHIP_8_PLATFORM
|
||||
|
||||
#include "Common.h"
|
||||
#include "dqnt.h"
|
||||
|
||||
typedef struct PlatformRenderBuffer
|
||||
{
|
||||
|
235
src/dqnt.h
Normal file
235
src/dqnt.h
Normal file
@ -0,0 +1,235 @@
|
||||
#ifndef DQNT_H
|
||||
#define DQNT_H
|
||||
|
||||
/*
|
||||
#define DQNT_IMPLEMENTATION
|
||||
#include "dqnt.h"
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// General Purpose Operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include "stdint.h"
|
||||
#define LOCAL_PERSIST static
|
||||
#define FILE_SCOPE static
|
||||
|
||||
typedef uint64_t u64;
|
||||
typedef uint32_t u32;
|
||||
typedef uint16_t u16;
|
||||
typedef uint8_t u8;
|
||||
|
||||
typedef int32_t i64;
|
||||
typedef int32_t i32;
|
||||
typedef int64_t i16;
|
||||
|
||||
typedef float f32;
|
||||
|
||||
#define DQNT_INVALID_CODE_PATH 0
|
||||
#define DQNT_ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
|
||||
|
||||
#ifdef DEBUG_MODE
|
||||
#define DQNT_ASSERT(expr) if (!(expr)) { (*((i32 *)0)) = 0; }
|
||||
#else
|
||||
#define DQNT_ASSERT(expr)
|
||||
#endif
|
||||
|
||||
#define DQNT_MATH_ABS(x) (((x) < 0) ? (-(x)) : (x))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Vec2
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef union v2 {
|
||||
struct { f32 x, y; };
|
||||
struct { f32 w, h; };
|
||||
} v2;
|
||||
|
||||
v2 V2(f32 x, f32 y);
|
||||
// Create a 2d-vector using ints and typecast to floats
|
||||
v2 V2i(i32 x, i32 y);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// String Ops
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
i32 dqnt_strcmp(const char *a, const char *b);
|
||||
i32 dqnt_strlen(const char *a);
|
||||
|
||||
wchar_t dqnt_wchar_ascii_to_lower(wchar_t character);
|
||||
i32 dqnt_wstrcmp(const wchar_t *a, const wchar_t *b);
|
||||
void dqnt_wstrcat(const wchar_t *a, i32 lenA, const wchar_t *b, i32 lenB, wchar_t *out, i32 outLen);
|
||||
i32 dqnt_wstrlen(const wchar_t *a);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// PCG (Permuted Congruential Generator) Random Number Generator
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct RandPCGState
|
||||
{
|
||||
u64 state[2];
|
||||
} RandPCGState;
|
||||
|
||||
// Init generator with seed. The generator is not valid until it's been seeded.
|
||||
void dqnt_rnd_pcg_seed (RandPCGState *pcg, u32 seed);
|
||||
// Returns a random number N between [0, 0xFFFFFFFF]
|
||||
u32 dqnt_rnd_pcg_next (RandPCGState *pcg);
|
||||
// Returns a random integer N between [min, max]
|
||||
i32 dqnt_rnd_pcg_range(RandPCGState *pcg, i32 min, i32 max);
|
||||
|
||||
#endif /* DQNT_H */
|
||||
|
||||
#ifdef DQNT_IMPLEMENTATION
|
||||
#undef DQNT_IMPLEMENTATION
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Vec2
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
v2 V2(f32 x, f32 y)
|
||||
{
|
||||
v2 result = {};
|
||||
result.x = x;
|
||||
result.y = y;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
v2 V2i(i32 x, i32 y)
|
||||
{
|
||||
v2 result = V2((f32)x, (f32)y);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// String Ops
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
i32 dqnt_strcmp(const char *a, const char *b)
|
||||
{
|
||||
while ((*a) == (*b))
|
||||
{
|
||||
if (!(*a)) return 0;
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
|
||||
return (((*a) < (*b)) ? -1 : 1);
|
||||
}
|
||||
|
||||
i32 dqnt_wstrcmp(const wchar_t *a, const wchar_t *b)
|
||||
{
|
||||
while ((*a) == (*b))
|
||||
{
|
||||
if (!(*a)) return 0;
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
|
||||
return (((*a) < (*b)) ? -1 : 1);
|
||||
}
|
||||
|
||||
void dqnt_wstrcat(const wchar_t *a, i32 lenA, const wchar_t *b, i32 lenB,
|
||||
wchar_t *out, i32 outLen)
|
||||
{
|
||||
DQNT_ASSERT((lenA + lenB) < outLen);
|
||||
|
||||
i32 outIndex = 0;
|
||||
for (i32 i = 0; i < lenA; i++)
|
||||
out[outIndex++] = a[i];
|
||||
|
||||
for (i32 i = 0; i < lenB; i++)
|
||||
out[outIndex++] = b[i];
|
||||
|
||||
DQNT_ASSERT(outIndex <= outLen);
|
||||
}
|
||||
|
||||
wchar_t dqnt_wchar_ascii_to_lower(wchar_t character)
|
||||
{
|
||||
if (character >= L'A' && character <= L'Z')
|
||||
{
|
||||
i32 shiftOffset = L'a' - L'A';
|
||||
character += (wchar_t)shiftOffset;
|
||||
}
|
||||
|
||||
return character;
|
||||
}
|
||||
|
||||
i32 dqnt_wstrlen(const wchar_t *a)
|
||||
{
|
||||
i32 result = 0;
|
||||
while ((*a))
|
||||
{
|
||||
result++;
|
||||
a++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
i32 dqnt_strlen(const char *a)
|
||||
{
|
||||
i32 result = 0;
|
||||
while ((*a))
|
||||
{
|
||||
result++;
|
||||
a++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// PCG (Permuted Congruential Generator) Random Number Generator
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Public Domain library with thanks to Mattias Gustavsson
|
||||
// https://github.com/mattiasgustavsson/libs/blob/master/docs/rnd.md
|
||||
|
||||
// Convert a randomized u32 value to a float value x in the range 0.0f <= x
|
||||
// < 1.0f. Contributed by Jonatan Hedborg
|
||||
FILE_SCOPE f32 dqnt_rnd_f32_normalized_from_u32_(u32 value)
|
||||
{
|
||||
u32 exponent = 127;
|
||||
u32 mantissa = value >> 9;
|
||||
u32 result = (exponent << 23) | mantissa;
|
||||
f32 fresult = *(f32 *)(&result);
|
||||
return fresult - 1.0f;
|
||||
}
|
||||
|
||||
FILE_SCOPE u64 dqnt_rnd_murmur3_avalanche64_(u64 h)
|
||||
{
|
||||
h ^= h >> 33;
|
||||
h *= 0xff51afd7ed558ccd;
|
||||
h ^= h >> 33;
|
||||
h *= 0xc4ceb9fe1a85ec53;
|
||||
h ^= h >> 33;
|
||||
return h;
|
||||
}
|
||||
|
||||
void dqnt_rnd_pcg_seed(RandPCGState *pcg, u32 seed)
|
||||
{
|
||||
u64 value = (((u64)seed) << 1ULL) | 1ULL;
|
||||
value = dqnt_rnd_murmur3_avalanche64_(value);
|
||||
pcg->state[0] = 0U;
|
||||
pcg->state[1] = (value << 1ULL) | 1ULL;
|
||||
dqnt_rnd_pcg_next(pcg);
|
||||
pcg->state[0] += dqnt_rnd_murmur3_avalanche64_(value);
|
||||
dqnt_rnd_pcg_next(pcg);
|
||||
}
|
||||
|
||||
u32 dqnt_rnd_pcg_next(RandPCGState *pcg)
|
||||
{
|
||||
u64 oldstate = pcg->state[0];
|
||||
pcg->state[0] = oldstate * 0x5851f42d4c957f2dULL + pcg->state[1];
|
||||
u32 xorshifted = (u32)(((oldstate >> 18ULL) ^ oldstate) >> 27ULL);
|
||||
u32 rot = (u32)(oldstate >> 59ULL);
|
||||
return (xorshifted >> rot) | (xorshifted << ((-(i32)rot) & 31));
|
||||
}
|
||||
|
||||
f32 dqnt_rnd_pcg_nextf(RandPCGState *pcg)
|
||||
{
|
||||
return dqnt_rnd_f32_normalized_from_u32_(dqnt_rnd_pcg_next(pcg));
|
||||
}
|
||||
|
||||
i32 dqnt_rnd_pcg_range(RandPCGState *pcg, i32 min, i32 max)
|
||||
{
|
||||
i32 const range = (max - min) + 1;
|
||||
if (range <= 0) return min;
|
||||
i32 const value = (i32)(dqnt_rnd_pcg_nextf(pcg) * range);
|
||||
return min + value;
|
||||
}
|
||||
|
||||
#endif /* DQNT_IMPLEMENTATION */
|
@ -1,3 +1,5 @@
|
||||
#include "win32_dchip8.cpp"
|
||||
#define DQNT_IMPLEMENTATION
|
||||
#include "dqnt.h"
|
||||
|
||||
#include "win32_dchip8.cpp"
|
||||
#include "dchip8.cpp"
|
||||
|
@ -9,9 +9,9 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "dchip8.h"
|
||||
#include "dchip8_platform.h"
|
||||
#include "dqnt.h"
|
||||
|
||||
FILE_SCOPE bool globalRunning = false;
|
||||
FILE_SCOPE LARGE_INTEGER globalQueryPerformanceFrequency;
|
||||
@ -209,7 +209,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
renderBitmap.width = header.biWidth;
|
||||
renderBitmap.height = header.biHeight;
|
||||
renderBitmap.bytesPerPixel = header.biBitCount / 8;
|
||||
ASSERT(renderBitmap.bytesPerPixel >= 1);
|
||||
DQNT_ASSERT(renderBitmap.bytesPerPixel >= 1);
|
||||
|
||||
HDC deviceContext = GetDC(mainWindow);
|
||||
renderBitmap.handle =
|
||||
@ -230,7 +230,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
u8 stackMemory[4096] = {};
|
||||
PlatformMemory platformMemory = {};
|
||||
platformMemory.permanentMem = &stackMemory;
|
||||
platformMemory.permanentMemSize = (ARRAY_COUNT(stackMemory) / 4);
|
||||
platformMemory.permanentMemSize = (DQNT_ARRAY_COUNT(stackMemory) / 4);
|
||||
|
||||
QueryPerformanceFrequency(&globalQueryPerformanceFrequency);
|
||||
const f32 TARGET_FRAMES_PER_S = 60.0f;
|
||||
@ -292,9 +292,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
f32 msPerFrame = 1000.0f * frameTimeInS;
|
||||
|
||||
wchar_t windowTitleBuffer[128] = {};
|
||||
_snwprintf_s(windowTitleBuffer, ARRAY_COUNT(windowTitleBuffer),
|
||||
ARRAY_COUNT(windowTitleBuffer), L"dchip-8 | %5.2f ms/f",
|
||||
msPerFrame);
|
||||
_snwprintf_s(windowTitleBuffer, DQNT_ARRAY_COUNT(windowTitleBuffer),
|
||||
DQNT_ARRAY_COUNT(windowTitleBuffer),
|
||||
L"dchip-8 | %5.2f ms/f", msPerFrame);
|
||||
SetWindowText(mainWindow, windowTitleBuffer);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user