summaryrefslogtreecommitdiff
path: root/include/rgl.h
blob: ac69ed0f73ee232bb81468c6254de2c3f5077014 (plain)
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
#ifndef RGL_H
#define RGL_H

#ifdef RGL_DEBUG

static char *ERROR_MESSAGE;

#define RGL_CRASH(text)                                                        \
  do {                                                                         \
    ERROR_MESSAGE = text;                                                      \
    __builtin_trap();                                                          \
  } while (0)

#define RGL_ASSERT(cond, text)                                                 \
  if (!(cond)) {                                                               \
    RGL_CRASH(text);                                                           \
  }

#else

#define RGL_CRASH(text)
#define RGL_ASSERT(cond, text)

#endif

static int RGL_ABS(int n) {
  return n < 0 ? -n : n;
}

/* Memory */

typedef struct {
  unsigned int size;
  unsigned int capacity;

  unsigned char *data;
} RGL_Arena;

void *RGL_ArenaAlloc(RGL_Arena *arena, unsigned int size);

unsigned int RGL_ArenaCheckpoint(RGL_Arena *arena);

void RGL_ArenaRollback(RGL_Arena *arena, unsigned int checkpoint);

void RGL_ArenaReset(RGL_Arena *arena);

/* Math */

typedef unsigned int RGL_Fixed;

#define RGL_SUBPIXEL_SHIFT 8
#define RGL_SUBPIXEL_SCALE 256
#define RGL_SUBPIXEL_MASK 255

static RGL_Fixed RGL_GetFixedI(int x) {
  return (RGL_Fixed)(x << RGL_SUBPIXEL_SHIFT);
}

static RGL_Fixed RGL_GetFixedF(float x) {
  return (RGL_Fixed)(x * RGL_SUBPIXEL_SCALE);
}

static RGL_Fixed RGL_GetFixedD(double x) {
  return (RGL_Fixed)(x * RGL_SUBPIXEL_SCALE);
}

static int RGL_FixedToInt(RGL_Fixed x) {
  return x >> RGL_SUBPIXEL_SHIFT;
}

static RGL_Fixed RGL_FixedMul(RGL_Fixed a, RGL_Fixed b) {
  return (RGL_Fixed)(((long int)a * b) >> RGL_SUBPIXEL_SHIFT);
}

/* Graphics */

typedef unsigned int RGL_Color;

#define RGL_COLOR(a, r, g, b)                                                  \
  ((RGL_Color)((a << 24) | (r << 16) | (g << 8) | b))

typedef struct {
  unsigned int width, height;
  unsigned int *data;
} RGL_Buffer;

typedef struct {
  RGL_Color color;
  unsigned int x, y, width, height;
} RGL_Rectangle;

typedef struct {
  RGL_Fixed x, y;
} RGL_Point;

typedef enum { PathStroke, PathFill } RGL_PathVerb;

typedef struct {
  RGL_PathVerb verb;
  unsigned int size;
  RGL_Color color;
} RGL_PathHeader;

typedef enum {
  Rect,
  Path,
} RGL_CommandType;

typedef struct {
  RGL_CommandType type;
  union {
    RGL_Rectangle rect;
    RGL_PathHeader path;
  } data;
} RGL_Command;

typedef struct {
  RGL_Arena arena;
  unsigned int size;

  RGL_Command *commands;
} RGL_CommandQueue;

typedef struct {
  RGL_Color color;
  RGL_CommandQueue queue;

  RGL_Command *current;
} RGL_Context;

void RGL_Rect(RGL_Context *ctx, unsigned int x, unsigned int y,
              unsigned int width, unsigned int height);

void RGL_BeginPath(RGL_Context *ctx, RGL_PathVerb verb);

void RGL_PathMoveTo(RGL_Context *ctx, int x, int y);

void RGL_EndPath(RGL_Context *ctx);

void RGL_DrawRect(RGL_Buffer *buf, RGL_Command *cmd);

void RGL_DrawStroke(RGL_Buffer *buf, RGL_PathHeader *path, RGL_Point *points);

void RGL_DrawPath(RGL_Buffer *buf, RGL_PathHeader *path, RGL_Point *points);

void RGL_Draw(RGL_Context *ctx, RGL_Buffer *buf);

#endif