aboutsummaryrefslogtreecommitdiff
path: root/platform.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform.c')
-rw-r--r--platform.c391
1 files changed, 391 insertions, 0 deletions
diff --git a/platform.c b/platform.c
new file mode 100644
index 0000000..3cb457a
--- /dev/null
+++ b/platform.c
@@ -0,0 +1,391 @@
+#include "config.h"
+#include "render.h"
+#include "input.h"
+
+#if defined(plat_posix)
+#define _POSIX_SOURCE
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+void platform_log(const char* message, ...) {
+ va_list args;
+ va_start(args, message);
+ vfprintf(stdout, message, args);
+ va_end(args);
+}
+
+void platform_err(const char* message, ...) {
+ va_list args;
+ va_start(args, message);
+
+ if (isatty(fileno(stderr))) {
+ fprintf(stderr, "\033[31;31m");
+ }
+
+ vfprintf(stderr, message, args);
+
+ if (isatty(fileno(stderr))) {
+ fprintf(stderr, "\033[0m");
+ }
+
+ va_end(args);
+}
+
+void platform_abort(int code) {
+#if defined(DEBUG) && defined(plat_x86)
+ __asm__("int3;");
+#else
+ exit(code);
+#endif
+}
+#endif
+
+#if defined(plat_sdl2)
+
+#define max_joysticks 16
+
+#include <SDL2/SDL.h>
+#include <stdio.h>
+#include <string.h>
+
+extern void on_init(int argc, char** argv);
+extern void on_update();
+extern void on_deinit();
+
+int held_btns[btn_count];
+int pressed_btns[btn_count];
+int released_btns[btn_count];
+int app_running = 1;
+
+int texture_w = default_window_w, texture_h = default_window_h;
+
+int button_pressed(Button btn) {
+ return held_btns[btn];
+}
+
+int button_just_pressed(Button btn) {
+ return pressed_btns[btn];
+}
+
+int button_just_released(Button btn) {
+ return released_btns[btn];
+}
+
+Button sdl_to_btn(const SDL_Event* event) {
+ switch (event->key.keysym.sym) {
+ case SDLK_z:
+ case SDLK_RETURN:
+ return btn_jump;
+ case SDLK_x:
+ return btn_shoot;
+ case SDLK_LEFT:
+ case SDLK_h:
+ return btn_dpad_left;
+ case SDLK_RIGHT:
+ case SDLK_l:
+ return btn_dpad_right;
+ case SDLK_UP:
+ case SDLK_k:
+ return btn_dpad_up;
+ case SDLK_DOWN:
+ case SDLK_j:
+ return btn_dpad_down;
+ case SDLK_ESCAPE:
+ return btn_pause;
+ case SDLK_F12:
+ return btn_edit;
+ case SDLK_s:
+ return btn_save_level;
+ default: return btn_unknown;
+ }
+}
+
+Button joy_btn_to_btn(int button) {
+ switch (button) {
+ case 0:
+ return btn_jump;
+ case 2:
+ return btn_shoot;
+ case 7:
+ return btn_pause;
+ default: return btn_unknown;
+ }
+}
+
+void reset_dpad() {
+ int i;
+
+ for (
+ i = btn_dpad_left;
+ i <= btn_dpad_down;
+ i++
+ ) {
+ if (held_btns[i]) {
+ held_btns[i] = 0;
+ released_btns[i] = 1;
+ }
+ }
+}
+
+void update_dpad(Button btn) {
+ reset_dpad();
+
+ held_btns[btn] = 1;
+ pressed_btns[btn] = 1;
+}
+
+int audio_len, audio_pos;
+int ticker;
+
+void fill_audio(void *udata, Uint8 *stream, int len) {
+ /*if (audio_len == 0) {
+ audio_len = 1024;
+ audio_pos = 0;
+ }
+
+ len = (len > audio_len ? audio_len : len);
+
+ sound_sys.mix(((unsigned short*)stream), len);
+
+ audio_pos += len;
+ audio_len -= len;*/
+}
+
+void reset_input() {
+ int i;
+
+ for (i = 0; i < btn_count; i++) {
+ pressed_btns[i] = 0;
+ released_btns[i] = 0;
+ }
+}
+
+void platform_quit() {
+ app_running = 0;
+}
+
+int main(int argc, char** argv) {
+ SDL_Window* window;
+ SDL_Renderer* renderer;
+ SDL_Texture* backbuffer;
+ void* bb_pixels;
+ SDL_Event event;
+ SDL_Rect src_rect, dst_rect;
+#if !no_sound
+ SDL_AudioSpec aud_spec;
+#endif
+ Button button;
+ int ww, wh, bb_pitch, ntw, nth;
+ int to_sleep, begin_time, end_time;
+ SDL_Joystick* joysticks[max_joysticks];
+
+ audio_pos = 0;
+ audio_len = 1024;
+ ticker = 0;
+
+ SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK);
+
+ SDL_CreateWindowAndRenderer(
+ default_window_w,
+ default_window_h,
+ SDL_WINDOW_RESIZABLE,
+ &window,
+ &renderer
+ );
+
+ SDL_SetWindowTitle(window, game_name);
+
+#if !no_sound
+ aud_spec.freq = 22050;
+ aud_spec.format = AUDIO_U16;
+ aud_spec.channels = 1;
+ aud_spec.samples = 1024;
+ aud_spec.callback = fill_audio;
+ aud_spec.userdata = 0;
+
+ if (SDL_OpenAudio(&aud_spec, 0) < 0) {
+ fprintf(
+ stderr,
+ "Sound error: %s.\n",
+ SDL_GetError()
+ );
+ }
+ SDL_PauseAudio(0);
+#endif
+
+ on_init(argc, argv);
+
+ backbuffer = SDL_CreateTexture(
+ renderer,
+ SDL_PIXELFORMAT_ABGR8888,
+ SDL_TEXTUREACCESS_STREAMING,
+ renderer_w,
+ renderer_h
+ );
+
+ while (app_running) {
+ begin_time = SDL_GetTicks();
+
+ reset_input();
+
+ while (SDL_PollEvent(&event)) {
+ switch (event.type) {
+ case SDL_QUIT:
+ app_running = 0;
+ break;
+ case SDL_KEYDOWN:
+ button = sdl_to_btn(&event);
+ held_btns[(int)button] = 1;
+ pressed_btns[(int)button] = 1;
+ break;
+ case SDL_KEYUP:
+ button = sdl_to_btn(&event);
+ held_btns[(int)button] = 0;
+ released_btns[(int)button] = 1;
+ break;
+ case SDL_JOYDEVICEADDED:
+ joysticks[event.jdevice.which] =
+ SDL_JoystickOpen(event.jdevice.which);
+ break;
+ case SDL_JOYDEVICEREMOVED:
+ SDL_JoystickClose(joysticks[event.jdevice.which]);
+ break;
+ case SDL_JOYHATMOTION:
+ switch (event.jhat.value) {
+ case SDL_HAT_LEFT:
+ update_dpad(btn_dpad_left);
+ break;
+ case SDL_HAT_UP:
+ update_dpad(btn_dpad_up);
+ break;
+ case SDL_HAT_RIGHT:
+ update_dpad(btn_dpad_right);
+ break;
+ case SDL_HAT_DOWN:
+ update_dpad(btn_dpad_down);
+ break;
+ case SDL_HAT_CENTERED:
+ reset_dpad();
+ default:
+ break;
+ }
+ break;
+ case SDL_JOYBUTTONDOWN:
+ button = joy_btn_to_btn(event.jbutton.button);
+ held_btns[(int)button] = 1;
+ pressed_btns[(int)button] = 1;
+ break;
+ case SDL_JOYBUTTONUP:
+ button = joy_btn_to_btn(event.jbutton.button);
+ held_btns[(int)button] = 0;
+ released_btns[(int)button] = 1;
+ break;
+ case SDL_WINDOWEVENT:
+ switch (event.window.event) {
+ case SDL_WINDOWEVENT_RESIZED:
+ ntw = renderer_w;
+ nth = renderer_h;
+ texture_w = ntw;
+ texture_h = nth;
+
+ /* This is kinda shit lmao. */
+ while (1) {
+ ntw *= 2;
+ nth *= 2;
+
+ if (
+ ntw > event.window.data1 ||
+ nth > event.window.data2
+ ) {
+ break;
+ }
+
+ texture_w = ntw;
+ texture_h = nth;
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ on_update();
+
+ SDL_GetWindowSize(window, &ww, &wh);
+
+ src_rect.x = 0;
+ src_rect.y = 0;
+ src_rect.w = renderer_w;
+ src_rect.h = renderer_h;
+
+ src_rect.x = 0;
+ src_rect.y = 0;
+ src_rect.w = renderer_w;
+ src_rect.h = renderer_h;
+
+ dst_rect.x = ww / 2 - texture_w / 2;
+ dst_rect.y = wh / 2 - texture_h / 2;
+ dst_rect.w = texture_w;
+ dst_rect.h = texture_h;
+
+ SDL_LockTexture(
+ backbuffer,
+ 0,
+ &bb_pixels,
+ &bb_pitch
+ );
+
+ memcpy(bb_pixels,
+ get_render_pixels(),
+ renderer_w * renderer_h * sizeof(Colour)
+ );
+
+ SDL_UnlockTexture(backbuffer);
+
+ SDL_UpdateTexture(
+ backbuffer,
+ 0,
+ get_render_pixels(),
+ renderer_w * sizeof(Colour)
+ );
+
+ SDL_RenderClear(renderer);
+ SDL_RenderCopy(
+ renderer,
+ backbuffer,
+ &src_rect,
+ &dst_rect
+ );
+ SDL_RenderPresent(renderer);
+
+ end_time = SDL_GetTicks();
+
+ to_sleep = 20 - ((end_time - begin_time));
+ if (to_sleep > 0) {
+ SDL_Delay(to_sleep);
+ }
+ }
+
+ on_deinit();
+
+ SDL_DestroyTexture(backbuffer);
+ SDL_DestroyRenderer(renderer);
+ SDL_DestroyWindow(window);
+
+#if !no_sound
+ SDL_CloseAudio();
+#endif
+
+ SDL_Quit();
+
+ return 0;
+}
+
+#else
+#define No platform defined.
+#endif