-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlinux_ichigo.cpp
More file actions
368 lines (315 loc) · 16.4 KB
/
linux_ichigo.cpp
File metadata and controls
368 lines (315 loc) · 16.4 KB
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
#include <SDL2/SDL.h>
#include <SDL2/SDL_events.h>
#include <SDL2/SDL_scancode.h>
#include <SDL2/SDL_timer.h>
#include <SDL2/SDL_video.h>
#include <cstdio>
#include <unistd.h>
#include <ctime>
#include "common.hpp"
#include "ichigo.hpp"
#ifdef ICHIGO_DEBUG
#include "thirdparty/imgui/imgui_impl_sdl2.h"
#endif
u32 Ichigo::Internal::window_width = 1600;
u32 Ichigo::Internal::window_height = 900;
OpenGL Ichigo::Internal::gl{};
Ichigo::KeyState Ichigo::Internal::keyboard_state[Ichigo::Keycode::IK_ENUM_COUNT] = {};
f32 Ichigo::Internal::dt = 0.0f;
f32 Ichigo::Internal::dpi_scale = 0.0f;
Ichigo::Gamepad Ichigo::Internal::gamepad{};
Ichigo::Mouse Ichigo::Internal::mouse{};
static SDL_Window *window;
static SDL_GLContext gl_context;
static bool init_completed = false;
struct Ichigo::Internal::PlatformFile {
std::FILE *file_fd;
};
static Ichigo::Internal::PlatformFile open_files[32] = {};
Ichigo::Internal::PlatformFile *Ichigo::Internal::platform_open_file_write(const Bana::String path) {
MAKE_STACK_STRING(path_cstr, path.length + 1);
string_concat(path_cstr, path);
string_concat(path_cstr, '\0');
std::FILE *fd = std::fopen(path_cstr.data, "wb");
if (!fd) {
ICHIGO_ERROR("Failed to open file for writing!");
return nullptr;
}
for (u32 i = 0; i < ARRAY_LEN(open_files); ++i) {
if (open_files[i].file_fd == nullptr) {
open_files[i].file_fd = fd;
return &open_files[i];
}
}
ICHIGO_ERROR("Too many files open!");
return nullptr;
}
void Ichigo::Internal::platform_write_entire_file_sync(const char *path, const u8 *data, usize data_size) {
std::FILE *fd = std::fopen(path, "wb");
if (!fd) {
ICHIGO_ERROR("Failed to open file for writing!");
return;
}
std::fwrite(data, 1, data_size, fd);
std::fclose(fd);
}
void Ichigo::Internal::platform_append_file_sync(Ichigo::Internal::PlatformFile *file, const u8 *data, usize data_size) {
std::fwrite(data, 1, data_size, file->file_fd);
}
void Ichigo::Internal::platform_close_file(Ichigo::Internal::PlatformFile *file) {
std::fclose(file->file_fd);
file->file_fd = nullptr;
}
Bana::Optional<Bana::FixedArray<u8>> Ichigo::Internal::platform_read_entire_file_sync(const Bana::String path, Bana::Allocator allocator) {
MAKE_STACK_STRING(path_cstr, path.length + 1);
string_concat(path_cstr, path);
string_concat(path_cstr, '\0');
std::FILE *fd = std::fopen(path_cstr.data, "rb");
if (!fd) {
ICHIGO_ERROR("Failed to open file for reading!");
return {};
}
std::fseek(fd, 0, SEEK_END);
usize file_size = std::ftell(fd);
std::fseek(fd, 0, SEEK_SET);
Bana::FixedArray<u8> ret = make_fixed_array<u8>(file_size, allocator);
ret.size = file_size;
std::fread(ret.data, 1, file_size, fd);
std::fclose(fd);
return ret;
}
bool Ichigo::Internal::platform_file_exists(const char *path) {
return access(path, F_OK) == 0;
}
void Ichigo::Internal::platform_sleep(f64 t) {
usleep(static_cast<u64>(t * 1000 * 1000));
}
f64 Ichigo::Internal::platform_get_current_time() {
timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec + (ts.tv_nsec / (f64) 1e9);
}
void Ichigo::Internal::platform_pause_audio() {
ICHIGO_INFO("platform_pause_audio: audio not implemented on linux!");
}
void Ichigo::Internal::platform_resume_audio() {
ICHIGO_INFO("platform_resume_audio: audio not implemented on linux!");
}
i32 main() {
assert(SDL_Init(SDL_INIT_VIDEO) >= 0);
window = SDL_CreateWindow("MUSEKININ", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, Ichigo::Internal::window_width, Ichigo::Internal::window_height, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_RESIZABLE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
gl_context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, gl_context);
SDL_GL_SetSwapInterval(0);
#define GET_ADDR_OF_OPENGL_FUNCTION(FUNC_NAME) Ichigo::Internal::gl.FUNC_NAME = (Type_##FUNC_NAME *) SDL_GL_GetProcAddress(#FUNC_NAME); assert(Ichigo::Internal::gl.FUNC_NAME != nullptr)
GET_ADDR_OF_OPENGL_FUNCTION(glViewport);
GET_ADDR_OF_OPENGL_FUNCTION(glClearColor);
GET_ADDR_OF_OPENGL_FUNCTION(glClear);
GET_ADDR_OF_OPENGL_FUNCTION(glGetString);
GET_ADDR_OF_OPENGL_FUNCTION(glPolygonMode);
GET_ADDR_OF_OPENGL_FUNCTION(glGetError);
GET_ADDR_OF_OPENGL_FUNCTION(glTexParameterf);
GET_ADDR_OF_OPENGL_FUNCTION(glTexParameterfv);
GET_ADDR_OF_OPENGL_FUNCTION(glTexParameteri);
GET_ADDR_OF_OPENGL_FUNCTION(glTexParameteriv);
GET_ADDR_OF_OPENGL_FUNCTION(glTexImage2D);
GET_ADDR_OF_OPENGL_FUNCTION(glEnable);
GET_ADDR_OF_OPENGL_FUNCTION(glEnablei);
GET_ADDR_OF_OPENGL_FUNCTION(glDisable);
GET_ADDR_OF_OPENGL_FUNCTION(glDisablei);
GET_ADDR_OF_OPENGL_FUNCTION(glBlendFunc);
GET_ADDR_OF_OPENGL_FUNCTION(glBlendFunci);
GET_ADDR_OF_OPENGL_FUNCTION(glGenBuffers);
GET_ADDR_OF_OPENGL_FUNCTION(glGenVertexArrays);
GET_ADDR_OF_OPENGL_FUNCTION(glGenTextures);
GET_ADDR_OF_OPENGL_FUNCTION(glBindBuffer);
GET_ADDR_OF_OPENGL_FUNCTION(glBindVertexArray);
GET_ADDR_OF_OPENGL_FUNCTION(glBindTexture);
GET_ADDR_OF_OPENGL_FUNCTION(glBufferData);
GET_ADDR_OF_OPENGL_FUNCTION(glCreateShader);
GET_ADDR_OF_OPENGL_FUNCTION(glShaderSource);
GET_ADDR_OF_OPENGL_FUNCTION(glCompileShader);
GET_ADDR_OF_OPENGL_FUNCTION(glGetShaderiv);
GET_ADDR_OF_OPENGL_FUNCTION(glGetProgramiv);
GET_ADDR_OF_OPENGL_FUNCTION(glGetShaderInfoLog);
GET_ADDR_OF_OPENGL_FUNCTION(glGetProgramInfoLog);
GET_ADDR_OF_OPENGL_FUNCTION(glCreateProgram);
GET_ADDR_OF_OPENGL_FUNCTION(glAttachShader);
GET_ADDR_OF_OPENGL_FUNCTION(glLinkProgram);
GET_ADDR_OF_OPENGL_FUNCTION(glUseProgram);
GET_ADDR_OF_OPENGL_FUNCTION(glDeleteShader);
GET_ADDR_OF_OPENGL_FUNCTION(glVertexAttribPointer);
GET_ADDR_OF_OPENGL_FUNCTION(glEnableVertexAttribArray);
GET_ADDR_OF_OPENGL_FUNCTION(glDisableVertexAttribArray);
GET_ADDR_OF_OPENGL_FUNCTION(glDrawArrays);
GET_ADDR_OF_OPENGL_FUNCTION(glDrawElements);
GET_ADDR_OF_OPENGL_FUNCTION(glGetUniformLocation);
GET_ADDR_OF_OPENGL_FUNCTION(glTexParameterIiv);
GET_ADDR_OF_OPENGL_FUNCTION(glTexParameterIuiv);
GET_ADDR_OF_OPENGL_FUNCTION(glGenerateMipmap);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform1f);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform2f);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform3f);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform4f);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform1i);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform2i);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform3i);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform4i);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform1ui);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform2ui);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform3ui);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform4ui);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform1ui);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform2ui);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform3ui);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform4ui);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform1fv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform2fv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform3fv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform4fv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform1iv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform2iv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform3iv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform4iv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform1uiv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform2uiv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform3uiv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniform4uiv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniformMatrix2fv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniformMatrix3fv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniformMatrix4fv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniformMatrix2x3fv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniformMatrix3x2fv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniformMatrix2x4fv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniformMatrix4x2fv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniformMatrix3x4fv);
GET_ADDR_OF_OPENGL_FUNCTION(glUniformMatrix4x3fv);
GET_ADDR_OF_OPENGL_FUNCTION(glFinish);
GET_ADDR_OF_OPENGL_FUNCTION(glBindVertexBuffer);
GET_ADDR_OF_OPENGL_FUNCTION(glVertexAttribBinding);
GET_ADDR_OF_OPENGL_FUNCTION(glVertexAttribFormat);
GET_ADDR_OF_OPENGL_FUNCTION(glVertexAttribIFormat);
GET_ADDR_OF_OPENGL_FUNCTION(glDepthRange);
GET_ADDR_OF_OPENGL_FUNCTION(glDepthRangef);
GET_ADDR_OF_OPENGL_FUNCTION(glBindBufferBase);
Ichigo::Internal::init();
#ifdef ICHIGO_DEBUG
ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
#endif
init_completed = true;
static f64 last_tick_time = 0.0;
for (;;) {
f64 frame_begin = Ichigo::Internal::platform_get_current_time();
SDL_Event event;
while (SDL_PollEvent(&event)) {
#ifdef ICHIGO_DEBUG
ImGui_ImplSDL2_ProcessEvent(&event);
#endif
if (event.type == SDL_QUIT) {
std::printf("deinit() now\n");
Ichigo::Internal::deinit();
return 0;
}
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED) {
Ichigo::Internal::window_width = event.window.data1;
Ichigo::Internal::window_height = event.window.data2;
}
}
#ifdef ICHIGO_DEBUG
ImGui_ImplSDL2_NewFrame();
#endif
// SDL_PumpEvents();
u32 mouse_button_state = SDL_GetMouseState(&Ichigo::Internal::mouse.pos.x, &Ichigo::Internal::mouse.pos.y);
#define SET_MOUSE_BTN_STATE(MOUSE_BUTTON, SDL_BUTTON_CODE) \
do { \
Ichigo::Internal::mouse.MOUSE_BUTTON.down_this_frame = (mouse_button_state & SDL_BUTTON(SDL_BUTTON_CODE)) && !Ichigo::Internal::mouse.MOUSE_BUTTON.down; \
Ichigo::Internal::mouse.MOUSE_BUTTON.down = mouse_button_state & SDL_BUTTON(SDL_BUTTON_CODE); \
Ichigo::Internal::mouse.MOUSE_BUTTON.up = !(mouse_button_state & SDL_BUTTON(SDL_BUTTON_CODE)); \
Ichigo::Internal::mouse.MOUSE_BUTTON.up_this_frame = !(mouse_button_state & SDL_BUTTON(SDL_BUTTON_CODE)) && Ichigo::Internal::mouse.MOUSE_BUTTON.down; \
} while (0)
#ifdef ICHIGO_DEBUG
if (!ImGui::GetIO().WantCaptureMouse) {
#else
{
#endif
SET_MOUSE_BTN_STATE(left_button, 1);
SET_MOUSE_BTN_STATE(middle_button, 2);
SET_MOUSE_BTN_STATE(right_button, 3);
}
#undef SET_MOUSE_BTN_STATE
i32 sdl_keycount;
const u8 *keystate = SDL_GetKeyboardState(&sdl_keycount);
#define SET_KEY_STATE(IK_KEY) Ichigo::Internal::keyboard_state[IK_KEY].down_this_frame = Ichigo::Internal::keyboard_state[IK_KEY].up && keystate[i] ? 1 : 0; Ichigo::Internal::keyboard_state[IK_KEY].down = keystate[i] == 1; Ichigo::Internal::keyboard_state[IK_KEY].up = keystate[i] == 0
#ifdef ICHIGO_DEBUG
if (!ImGui::GetIO().WantCaptureKeyboard) {
#else
{
#endif
for (i32 i = 0; i < sdl_keycount; ++i) {
if (i >= SDL_SCANCODE_A && i <= SDL_SCANCODE_Z) {
SET_KEY_STATE(i + Ichigo::IK_A - SDL_SCANCODE_A);
}
switch (i) {
case SDL_SCANCODE_BACKSPACE: SET_KEY_STATE(Ichigo::IK_BACKSPACE); break;
case SDL_SCANCODE_TAB: SET_KEY_STATE(Ichigo::IK_TAB); break;
case SDL_SCANCODE_RETURN: SET_KEY_STATE(Ichigo::IK_ENTER); break;
case SDL_SCANCODE_LSHIFT: SET_KEY_STATE(Ichigo::IK_LEFT_SHIFT); break;
case SDL_SCANCODE_LCTRL: SET_KEY_STATE(Ichigo::IK_LEFT_CONTROL); break;
case SDL_SCANCODE_RSHIFT: SET_KEY_STATE(Ichigo::IK_RIGHT_SHIFT); break;
case SDL_SCANCODE_RCTRL: SET_KEY_STATE(Ichigo::IK_RIGHT_CONTROL); break;
case SDL_SCANCODE_LALT: SET_KEY_STATE(Ichigo::IK_LEFT_ALT); break;
case SDL_SCANCODE_ESCAPE: SET_KEY_STATE(Ichigo::IK_ESCAPE); break;
case SDL_SCANCODE_SPACE: SET_KEY_STATE(Ichigo::IK_SPACE); break;
case SDL_SCANCODE_PAGEUP: SET_KEY_STATE(Ichigo::IK_PAGE_UP); break;
case SDL_SCANCODE_PAGEDOWN: SET_KEY_STATE(Ichigo::IK_PAGE_DOWN); break;
case SDL_SCANCODE_END: SET_KEY_STATE(Ichigo::IK_END); break;
case SDL_SCANCODE_HOME: SET_KEY_STATE(Ichigo::IK_HOME); break;
case SDL_SCANCODE_LEFT: SET_KEY_STATE(Ichigo::IK_LEFT); break;
case SDL_SCANCODE_UP: SET_KEY_STATE(Ichigo::IK_UP); break;
case SDL_SCANCODE_RIGHT: SET_KEY_STATE(Ichigo::IK_RIGHT); break;
case SDL_SCANCODE_DOWN: SET_KEY_STATE(Ichigo::IK_DOWN); break;
case SDL_SCANCODE_PRINTSCREEN: SET_KEY_STATE(Ichigo::IK_PRINT_SCREEN); break;
case SDL_SCANCODE_INSERT: SET_KEY_STATE(Ichigo::IK_INSERT); break;
case SDL_SCANCODE_DELETE: SET_KEY_STATE(Ichigo::IK_DELETE); break;
case SDL_SCANCODE_0: SET_KEY_STATE(Ichigo::IK_0); break;
case SDL_SCANCODE_1: SET_KEY_STATE(Ichigo::IK_1); break;
case SDL_SCANCODE_2: SET_KEY_STATE(Ichigo::IK_2); break;
case SDL_SCANCODE_3: SET_KEY_STATE(Ichigo::IK_3); break;
case SDL_SCANCODE_4: SET_KEY_STATE(Ichigo::IK_4); break;
case SDL_SCANCODE_5: SET_KEY_STATE(Ichigo::IK_5); break;
case SDL_SCANCODE_6: SET_KEY_STATE(Ichigo::IK_6); break;
case SDL_SCANCODE_7: SET_KEY_STATE(Ichigo::IK_7); break;
case SDL_SCANCODE_8: SET_KEY_STATE(Ichigo::IK_8); break;
case SDL_SCANCODE_9: SET_KEY_STATE(Ichigo::IK_9); break;
case SDL_SCANCODE_F1: SET_KEY_STATE(Ichigo::IK_F1); break;
case SDL_SCANCODE_F2: SET_KEY_STATE(Ichigo::IK_F2); break;
case SDL_SCANCODE_F3: SET_KEY_STATE(Ichigo::IK_F3); break;
case SDL_SCANCODE_F4: SET_KEY_STATE(Ichigo::IK_F4); break;
case SDL_SCANCODE_F5: SET_KEY_STATE(Ichigo::IK_F5); break;
case SDL_SCANCODE_F6: SET_KEY_STATE(Ichigo::IK_F6); break;
case SDL_SCANCODE_F7: SET_KEY_STATE(Ichigo::IK_F7); break;
case SDL_SCANCODE_F8: SET_KEY_STATE(Ichigo::IK_F8); break;
case SDL_SCANCODE_F9: SET_KEY_STATE(Ichigo::IK_F9); break;
case SDL_SCANCODE_F10: SET_KEY_STATE(Ichigo::IK_F10); break;
case SDL_SCANCODE_F11: SET_KEY_STATE(Ichigo::IK_F11); break;
case SDL_SCANCODE_F12: SET_KEY_STATE(Ichigo::IK_F12); break;
}
}
}
f64 new_tick_time = Ichigo::Internal::platform_get_current_time();
f64 delta = new_tick_time - last_tick_time;
last_tick_time = new_tick_time;
Ichigo::Internal::dt = delta;
Ichigo::Internal::dpi_scale = 1.0f; // TODO: ?
Ichigo::Internal::do_frame();
f64 frame_time = Ichigo::Internal::platform_get_current_time() - frame_begin;
f64 sleep_time = Ichigo::Internal::target_frame_time - frame_time;
if (sleep_time > 0.0)
Ichigo::Internal::platform_sleep(sleep_time);
SDL_GL_SwapWindow(window);
}
return 0;
}