summaryrefslogtreecommitdiff
path: root/src/sdlutils.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/sdlutils.h')
-rw-r--r--src/sdlutils.h257
1 files changed, 257 insertions, 0 deletions
diff --git a/src/sdlutils.h b/src/sdlutils.h
new file mode 100644
index 0000000..a3dbbaf
--- /dev/null
+++ b/src/sdlutils.h
@@ -0,0 +1,257 @@
+// __-prefixed functions, structs, etc. are not advised to be used by other files
+#include <stdlib.h>
+#include <math.h>
+
+#include <SDL.h>
+#include <SDL_ttf.h>
+#include "colors.h"
+
+#define FONT_WIDTH_FACTOR 0.585 // Width of text / letter / font size
+#define FONT_HEIGHT_FACTOR 1.2 // Height of text / font size
+
+#define FONT_SIZE 12
+#define CHAR_WIDTH FONT_WIDTH_FACTOR * FONT_SIZE
+#define CHAR_HEIGHT FONT_HEIGHT_FACTOR * FONT_SIZE
+
+#define MAX_OPTIONS 1000
+
+#define ENTRY_SUBMIT 1 << 14
+
+SDL_Window* window;
+SDL_Surface* window_surface;
+SDL_Renderer* renderer;
+TTF_Font* font;
+char* editor;
+char* __sdlutils_clear;
+int __sdlutils_entry_capacity;
+int __sdlutils_entry_enabled;
+
+typedef struct
+{
+ char* text;
+ int xpos;
+ int ypos;
+ int action_id;
+ SDL_Color fg;
+ SDL_Color bg;
+ SDL_Color hl; // BG When highlighted
+} __sdlutils_option;
+
+__sdlutils_option** __sdlutils_options;
+int __sdlutils_selected = 0;
+int __sdlutils_option_count = 0;
+int __sdlutils_entry_x, __sdlutils_entry_y;
+char* __sdlutils_entry_contents;
+int __sdlutils_entry_contents_sz; // Length of string in entry
+
+char* int_to_str(int i)
+{
+ char* buffer = malloc((int)(log((double)i)/log(10))+3);
+ sprintf(buffer, "%d", i);
+ return buffer;
+}
+
+char* double_to_str(double d)
+{
+ char* buffer = malloc(32);
+ sprintf(buffer, "%f", d);
+ return buffer;
+}
+
+
+void write_text(char* text, int x, int y, SDL_Color fg, SDL_Color bg)
+{
+ if (!(text && text[0])) return;
+ SDL_Surface* text_surface = TTF_RenderText_Solid(font, text, fg);
+ SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, text_surface);
+ SDL_Rect rect = {x, y, text_surface->w, text_surface->h};
+ SDL_SetRenderDrawColor(renderer, bg.r, bg.g, bg.b, bg.a);
+ SDL_RenderFillRect(renderer, &rect);
+ SDL_RenderCopy(renderer, texture, NULL, &rect);
+ SDL_FreeSurface(text_surface);
+ SDL_DestroyTexture(texture);
+
+}
+
+void write_str(char* s, int xpos, int ypos, SDL_Color fg, SDL_Color bg)
+{
+ // For grid-like letter placement (for text-based applications1)
+ // Same as write_text, but writes in terms of the letter positions
+ write_text(s, xpos * CHAR_WIDTH, ypos * CHAR_HEIGHT, fg, bg);
+}
+
+void hcenter_str(char* s, int cols, int ypos, SDL_Color fg, SDL_Color bg)
+{
+ // Center string horizontally
+ write_str(s, cols / 2 - strlen(s) / 2, ypos, fg, bg);
+}
+
+void write_char(char c, int xpos, int ypos, SDL_Color fg, SDL_Color bg)
+{
+ char* s = malloc(2);
+ s[0] = c;
+ s[1] = 0;
+ write_str(s, xpos, ypos, fg, bg);
+}
+
+void create_option(char* text, int action_id, int x, int y, SDL_Color fg, SDL_Color bg, SDL_Color highlighted)
+{
+ __sdlutils_option* opt = malloc(sizeof(__sdlutils_option));
+ opt->text = text;
+ opt->action_id = action_id;
+ opt->xpos = x;
+ opt->ypos = y;
+ opt->fg = fg;
+ opt->bg = bg;
+ opt->hl = highlighted;
+ __sdlutils_options[__sdlutils_option_count++] = opt;
+}
+
+void draw_options()
+{
+ int i;
+ __sdlutils_option* opt;
+ for (i = 0; opt = __sdlutils_options[i]; i++)
+ {
+ write_str(opt->text, opt->xpos, opt->ypos, opt->fg, __sdlutils_selected == i ? opt->hl : opt->bg);
+ }
+}
+
+void clear_options()
+{
+ int i;
+ for (i = __sdlutils_option_count = 0; i < MAX_OPTIONS; i++)
+ {
+ __sdlutils_options[i] = NULL;
+ }
+ __sdlutils_selected = 0;
+ for (i = 0; i < __sdlutils_entry_capacity; i++) __sdlutils_entry_contents[i] = 0;
+ __sdlutils_entry_enabled = 0;
+ SDL_StopTextInput();
+}
+
+int mod(int a, int b)
+{
+ a %= b;
+ while (a < 0) a += b;
+ return a;
+}
+
+void draw_entry()
+{
+ if (__sdlutils_entry_enabled)
+ {
+ write_str(__sdlutils_clear, __sdlutils_entry_x, __sdlutils_entry_y, BLACK, BLACK);
+ write_str(__sdlutils_entry_contents, __sdlutils_entry_x, __sdlutils_entry_y, WHITE, BLACK);
+ }
+}
+
+void setup_entry(char* contents, int x, int y)
+{
+ memcpy(__sdlutils_entry_contents, contents, strlen(contents)+1);
+ __sdlutils_entry_x = x;
+ __sdlutils_entry_y = y;
+ __sdlutils_entry_enabled = 1;
+ SDL_StartTextInput();
+ draw_entry();
+}
+
+char* get_entry_contents()
+{
+ return __sdlutils_entry_contents;
+}
+
+
+
+int sdlutils_process_key(SDL_Keycode kc)
+{
+ int len;
+ switch (kc)
+ {
+ case SDLK_UP:
+ if (__sdlutils_options[0])
+ {
+ __sdlutils_selected--;
+ __sdlutils_selected = mod(__sdlutils_selected, __sdlutils_option_count);
+ draw_options();
+ }
+ break;
+ case SDLK_DOWN:
+ if (__sdlutils_options[0])
+ {
+ __sdlutils_selected++;
+ __sdlutils_selected = mod(__sdlutils_selected, __sdlutils_option_count);
+ draw_options();
+ }
+ break;
+ case SDLK_RETURN:
+ if (__sdlutils_entry_enabled) return ENTRY_SUBMIT;
+ if (__sdlutils_options[0]) return __sdlutils_options[__sdlutils_selected]->action_id;
+ break;
+ case SDLK_BACKSPACE:
+ if (!__sdlutils_entry_enabled) break;
+ len = strlen(__sdlutils_entry_contents);
+ __sdlutils_entry_contents[(len ? len : 1)-1] = 0;
+ break;
+ }
+ if (__sdlutils_options[0]) __sdlutils_selected = mod(__sdlutils_selected, __sdlutils_option_count);
+ draw_entry();
+ return 0;
+}
+
+void handle_text(char* text)
+{
+ if (!__sdlutils_entry_enabled) return;
+ strcat(__sdlutils_entry_contents, text);
+ draw_entry();
+}
+
+void quit()
+{
+ SDL_DestroyWindow(window);
+ TTF_CloseFont(font);
+ TTF_Quit();
+ SDL_Quit();
+ exit(0);
+}
+
+void sdlutils_set_capacity(int capacity)
+{
+ __sdlutils_entry_contents = malloc((__sdlutils_entry_capacity = capacity)+1);
+ __sdlutils_clear = malloc(__sdlutils_entry_capacity+1);
+ int i;
+ for (i = 0; i < __sdlutils_entry_capacity; i++)
+ {
+ __sdlutils_clear[i] = 'M'; // Wide letter for non-monospace fonts (although most of this wouldn't work for non-monospace fonts)
+ }
+ __sdlutils_clear[i] = 0;
+}
+
+void sdlutils_init(int width, int height)
+{
+ __sdlutils_options = malloc(MAX_OPTIONS*sizeof(__sdlutils_option*));
+
+ clear_options();
+
+ if (SDL_Init(SDL_INIT_VIDEO) < 0)
+ {
+ fprintf(stderr, "SDL Error: %s\n", SDL_GetError());
+ exit(1);
+ }
+ if (TTF_Init() == -1)
+ {
+ fprintf(stderr, "SDL_ttf could not initialize! SDL_ttf Error: %s\n", TTF_GetError());
+ }
+
+ window = SDL_CreateWindow("Life", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_SHOWN);
+ if (window == NULL)
+ {
+ fprintf(stderr, "SDL Error: %s\n", SDL_GetError());
+ exit(1);
+ }
+
+ window_surface = SDL_GetWindowSurface(window);
+ renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
+ // Font
+ font = TTF_OpenFont("fonts/DejaVuSansMono.ttf", FONT_SIZE);
+}