-
Notifications
You must be signed in to change notification settings - Fork 0
/
punity.h
616 lines (516 loc) · 14.4 KB
/
punity.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
/**
* Copyright (c) 2016 martincohen
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MIT license. See LICENSE for details.
*/
/**
* Version 1.4
* - Fixed audio clipping problems by providing a soft-clip.
* - Added master and per-sound volume controls.
* Version 1.3
* - Fixed RGB in bitmap loader on Windows.
* Version 1.2
* - Replaced usage of `_` prefixes with `PUNP_` prefixes to not violate reserved identifiers.
* Version 1.1
* - Fixed timing issues and frame counting.
* - Fixed KEY_* constants being not correct for Windows platform.
* - Added draw_rect().
* Version 1.0
* - Initial release
*/
#ifndef PUNITY_H
#define PUNITY_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#ifndef NO_CONFIG
#include "config.h"
#endif
#define PLATFORM_WINDOWS 1
#ifndef SOUND_CHANNELS
#define SOUND_CHANNELS 4
#endif
#ifndef SOUND_SAMPLE_RATE
#define SOUND_SAMPLE_RATE 48000
#endif
#ifndef CANVAS_WIDTH
#define CANVAS_WIDTH 128
#endif
#ifndef CANVAS_HEIGHT
#define CANVAS_HEIGHT 128
#endif
#ifndef CANVAS_SCALE
#define CANVAS_SCALE 2
#endif
#ifndef STACK_CAPACITY
#define STACK_CAPACITY megabytes(1)
#endif
#ifndef STORAGE_CAPACITY
#define STORAGE_CAPACITY megabytes(1)
#endif
#ifndef USE_STB_IMAGE
#define USE_STB_IMAGE 0
#endif
#ifndef USE_STB_VORBIS
#define USE_STB_VORBIS 0
#endif
#if PLATFORM_WINDOWS
#define COLOR_CHANNELS b, g, r, a
#endif
typedef uint8_t u8;
typedef int8_t i8;
typedef uint16_t u16;
typedef int16_t i16;
typedef uint32_t u32;
typedef int32_t i32;
typedef uint64_t u64;
typedef int64_t i64;
typedef float f32;
typedef double f64;
typedef u32 b32;
#define unused(x) (void)x
#define align_to(value, N) ((value + (N-1)) & ~(N-1))
#define maximum(a, b) (a) > (b) ? (a) : (b)
#define minimum(a, b) (a) < (b) ? (a) : (b)
#define clamp(x, a, b) (maximum(a, minimum(x, b)))
#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923
#endif
//
// Utility
//
typedef struct
{
f64 stamp;
f32 delta;
}
PerfSpan;
f64 perf_get();
// Sets the stamp, keeps the delta.
//
void perf_from(PerfSpan *span);
// Sets the stamp and delta.
//
void perf_to(PerfSpan *span);
// Returns current delta.
f32 perf_delta(const PerfSpan *span);
//
// Memory
//
#define kilobytes(n) (1024*(n))
#define megabytes(n) (1024*kilobytes(n))
#define gigabytes(n) (1024*megabytes(n))
typedef struct
{
u8 *begin;
u8 *end;
u8 *it;
}
Bank;
void *virtual_reserve(void* ptr, u32 size);
void *virtual_commit(void *ptr, u32 size);
void virtual_decommit(void *ptr, u32 size);
void virtual_free(void *ptr, u32 size);
void *virtual_alloc(void* ptr, u32 size);
void bank_init(Bank *bank, u32 capacity);
void *bank_push(Bank *bank, u32 size);
void bank_pop(Bank *bank, void *ptr);
typedef struct
{
Bank state;
Bank *bank;
}
BankState;
BankState bank_begin(Bank *bank);
void bank_end(BankState *state);
//
// File I/O
//
void *file_read(const char *path, size_t *size);
//
//
//
#define COLOR_TRANSPARENT 0
typedef union
{
struct
{
u8 COLOR_CHANNELS;
};
u32 rgba;
}
Color;
Color color_make(u8 r, u8 g, u8 b, u8 a);
typedef struct
{
Color colors[256];
u8 colors_count;
}
Palette;
typedef union
{
struct {
i32 min_x;
i32 min_y;
i32 max_x;
i32 max_y;
};
struct {
i32 left;
i32 top;
i32 right;
i32 bottom;
};
i32 E[4];
}
Rect;
#define rect_tr(r, tx, ty) \
(r)->min_x += tx; \
(r)->min_y += ty; \
(r)->max_x += tx; \
(r)->max_y += ty;
inline Rect rect_make(i32 min_x, i32 min_y, i32 max_x, i32 max_y);
inline Rect rect_make_size(i32 x, i32 y, i32 w, i32 h);
typedef struct {
int x;
int y;
} Vec;
inline Vec vec_make(int x, int y);
#define RAND_NN 312
typedef struct {
int mti;
int iset;
u64 mt[RAND_NN];
} Random;
void randrom_init(Random * rand, u64 seed);
u64 random(Random * rand);
typedef struct
{
i32 width;
i32 height;
u8 *pixels;
}
Bitmap;
typedef struct
{
Bitmap bitmap;
i32 char_width;
i32 char_height;
}
Font;
#define BITMAP_8 1
#define BITMAP_32 4
// Initializes the bitmap struct and copies the data from pixels to the CORE->storage.
// If pixels is 0, the bitmap's pixel data are only allocated (not initialized)
// If pixels is not 0 then the `type` is used as follows:
//
// - BITMAP_32, it'll convert it to paletted image by adding the unknown colors to the palette.
// - BITMAP_8, the data are copied as they are.
//
void bitmap_init(Bitmap *bitmap, i32 width, i32 height, void *pixels, int type);
void bitmap_clear(Bitmap *bitmap, u8 color);
// Saves bitmap to file. Uses simple format:
//
// 0x0000 i32 width
// 0x0004 i32 height
// 0x0008 u8 pixels[width * height]
//
void bitmap_save_raw(Bitmap *bitmap, FILE *file);
// Loads bitmap from raw data format (see bitmap_save_raw())
//
void bitmap_load_raw(Bitmap *bitmap, FILE *file);
// Loads bitmap from an image file.
// This only works if USE_STB_IMAGE is defined.
#if USE_STB_IMAGE
void bitmap_load(Bitmap *bitmap, const char *path);
void bitmap_load_resource(Bitmap *bitmap, const char *resource_name);
#endif
//
//
//
// Clears the canvas.
void canvas_clear(u8 color);
// Sets clipping rectangle.
// The rectangle is intersected with the canvas rectangle [0, 0, canvas.width, canvas.height].
void clip_set(Rect rect);
// Resets clip to current canvas bitmap.
void clip_reset();
// Checks clipping rectangle whether it's valid.
bool clip_check();
// Produces a new palette B from palette A by moving colors.
// This is useful if you want to lighten or darken the colors.
// `ramp` is u8[256] array of indexes starting at darkest color as 1.
// Index of 0 means the color is not being shifted.
// TODO: void palette_shift(Palette *A, Palette *B, u8 *ramp, i32 amount);
// Draws a filled rectangle to the canvas.
void rect_draw(Rect rect, u8 color);
// Draws a frame of a rectangle to the canvas.
// TODO: void frame_draw(Rect rect, u8 color);
enum {
DrawFlags_FlipH = 0x01,
DrawFlags_Mask = 0x02
};
// Draws a bitmap to the canvas.
void bitmap_draw(i32 x, i32 y, i32 pivot_x, i32 pivot_y, Bitmap *bitmap, Rect *bitmap_rect, u32 flags, u8 color);
// Draws text to the canvas.
// Fails if CORE->font is not set, as it's using it draw the text.
void text_draw(i32 x, i32 y, const char *text, u8 color);
//
// Sound
//
typedef struct
{
f32 volume;
i32 channel_count;
u32 rate;
i16 *samples;
// Samples per channel.
size_t samples_count;
}
Sound;
void sound_play(Sound *sound);
#if USE_STB_VORBIS
void sound_load(Sound *sound, const char *path);
void sound_load_resource(Sound *sound, const char *resource_name);
#endif
//
// Resources
//
void *resource_get(const char *name, size_t *size);
//
// Core
//
void log_info(const char * mgs, ...);
#define KEYS_MAX 256
typedef struct
{
// Memory for large in-function working data.
// Use STACK_CAPACITY macro in config.h to set size.
// Ex. #define STACK_CAPACITY megabytes(4)
//
// Use this to allocate the data in the storage.
// void *my_ptr = bank_push(stack, 65536);
//
// Use this to deallocate the data from the storage.
// Don't forget to do pop before the function returns.
// bank_pop(stack, my_ptr);
//
Bank *stack;
// Storage for the application data (for example bitmaps).
// Use STACK_STORAGE macro in config.h to set size.
// Ex. #define STACK_CAPACITY megabytes(4)
//
Bank *storage;
// Set to 0 to exit.
//
b32 running;
u32 key_modifiers;
// Indexed with KEY_* constants.
// 0 for up
// 1 for down
//
u8 key_states[KEYS_MAX];
// Indexed with KEY_* constants.
// 0 for not changed in this frame
// 1 for changed in this frame
//
u8 key_deltas[KEYS_MAX];
// The mouse position
u32 mouse_x;
u32 mouse_y;
// Total frame time.
PerfSpan perf_frame;
// Total time taken to process everything except the vsync.
PerfSpan perf_frame_inner;
// Total time taken to step.
PerfSpan perf_step;
// Total time taken to process audio.
PerfSpan perf_audio;
// Total time taken to do the blit.
PerfSpan perf_blit;
PerfSpan perf_blit_cvt;
PerfSpan perf_blit_gdi;
// Current frame number.
i64 frame;
Palette palette;
Bitmap *canvas;
i32 translate_x;
i32 translate_y;
Rect clip;
Font *font;
f32 audio_volume;
}
Core;
extern Core *CORE;
void panic(const char *message, const char *description, const char *function, const char *file, int line);
#define ASSERT_MESSAGE(expression, message) \
(void)( (!!(expression)) ||\
(panic(message, #expression, __FUNCTION__, __FILE__, __LINE__), 0) )
#define ASSERT(expression) ASSERT_MESSAGE(expression, #expression)
#define ASSERT_DEBUG_MESSAGE ASSERT_MESSAGE
#define ASSERT_DEBUG ASSERT
// To be defined in main.c.
void init();
// To be defined in main.c.
void step();
//
// Keys
//
// Returns true if key held down.
//
#define key_down(key) (CORE->key_states[key])
// Returns true if key started to be held down in this frame.
//
#define key_pressed(key) (CORE->key_deltas[key] && key_down(key))
#define KEY_MOD_SHIFT 0x0001
#define KEY_MOD_CONTROL 0x0002
#define KEY_MOD_ALT 0x0004
#define KEY_MOD_SUPER 0x0008
#define KEY_UNKNOWN -1
#define KEY_INVALID -2
#define KEY_LBUTTON 1
#define KEY_RBUTTON 2
#define KEY_CANCEL 3
#define KEY_MBUTTON 4
#define KEY_BACK 8
#define KEY_TAB 9
#define KEY_CLEAR 12
#define KEY_RETURN 13
#define KEY_SHIFT 16
#define KEY_CONTROL 17
#define KEY_MENU 18
#define KEY_PAUSE 19
#define KEY_CAPITAL 20
#define KEY_KANA 0x15
#define KEY_HANGEUL 0x15
#define KEY_HANGUL 0x15
#define KEY_JUNJA 0x17
#define KEY_FINAL 0x18
#define KEY_HANJA 0x19
#define KEY_KANJI 0x19
#define KEY_ESCAPE 0x1B
#define KEY_CONVERT 0x1C
#define KEY_NONCONVERT 0x1D
#define KEY_ACCEPT 0x1E
#define KEY_MODECHANGE 0x1F
#define KEY_SPACE 32
#define KEY_PRIOR 33
#define KEY_NEXT 34
#define KEY_END 35
#define KEY_HOME 36
#define KEY_LEFT 37
#define KEY_UP 38
#define KEY_RIGHT 39
#define KEY_DOWN 40
#define KEY_SELECT 41
#define KEY_PRINT 42
#define KEY_EXEC 43
#define KEY_SNAPSHOT 44
#define KEY_INSERT 45
#define KEY_DELETE 46
#define KEY_HELP 47
#define KEY_LWIN 0x5B
#define KEY_RWIN 0x5C
#define KEY_APPS 0x5D
#define KEY_SLEEP 0x5F
#define KEY_NUMPAD0 0x60
#define KEY_NUMPAD1 0x61
#define KEY_NUMPAD2 0x62
#define KEY_NUMPAD3 0x63
#define KEY_NUMPAD4 0x64
#define KEY_NUMPAD5 0x65
#define KEY_NUMPAD6 0x66
#define KEY_NUMPAD7 0x67
#define KEY_NUMPAD8 0x68
#define KEY_NUMPAD9 0x69
#define KEY_MULTIPLY 0x6A
#define KEY_ADD 0x6B
#define KEY_SEPARATOR 0x6C
#define KEY_SUBTRACT 0x6D
#define KEY_DECIMAL 0x6E
#define KEY_DIVIDE 0x6F
#define KEY_F1 0x70
#define KEY_F2 0x71
#define KEY_F3 0x72
#define KEY_F4 0x73
#define KEY_F5 0x74
#define KEY_F6 0x75
#define KEY_F7 0x76
#define KEY_F8 0x77
#define KEY_F9 0x78
#define KEY_F10 0x79
#define KEY_F11 0x7A
#define KEY_F12 0x7B
#define KEY_F13 0x7C
#define KEY_F14 0x7D
#define KEY_F15 0x7E
#define KEY_F16 0x7F
#define KEY_F17 0x80
#define KEY_F18 0x81
#define KEY_F19 0x82
#define KEY_F20 0x83
#define KEY_F21 0x84
#define KEY_F22 0x85
#define KEY_F23 0x86
#define KEY_F24 0x87
#define KEY_NUMLOCK 0x90
#define KEY_SCROLL 0x91
#define KEY_LSHIFT 0xA0
#define KEY_RSHIFT 0xA1
#define KEY_LCONTROL 0xA2
#define KEY_RCONTROL 0xA3
#define KEY_LMENU 0xA4
#define KEY_RMENU 0xA5
#define KEY_SPACE 32
#define KEY_APOSTROPHE 39 /* ' */
#define KEY_COMMA 44 /* , */
#define KEY_MINUS 45 /* - */
#define KEY_PERIOD 46 /* . */
#define KEY_SLASH 47 /* / */
#define KEY_0 48
#define KEY_1 49
#define KEY_2 50
#define KEY_3 51
#define KEY_4 52
#define KEY_5 53
#define KEY_6 54
#define KEY_7 55
#define KEY_8 56
#define KEY_9 57
#define KEY_SEMICOLON 59 /* ; */
#define KEY_EQUAL 61 /* = */
#define KEY_A 65
#define KEY_B 66
#define KEY_C 67
#define KEY_D 68
#define KEY_E 69
#define KEY_F 70
#define KEY_G 71
#define KEY_H 72
#define KEY_I 73
#define KEY_J 74
#define KEY_K 75
#define KEY_L 76
#define KEY_M 77
#define KEY_N 78
#define KEY_O 79
#define KEY_P 80
#define KEY_Q 81
#define KEY_R 82
#define KEY_S 83
#define KEY_T 84
#define KEY_U 85
#define KEY_V 86
#define KEY_W 87
#define KEY_X 88
#define KEY_Y 89
#define KEY_Z 90
#define KEY_LEFT_BRACKET 91 /* [ */
#define KEY_BACKSLASH 92 /* \ */
#define KEY_RIGHT_BRACKET 93 /* ] */
#define KEY_GRAVE_ACCENT 96 /* ` */
#endif // PUNITY_H