diff options
Diffstat (limited to 'src/liberti.c')
-rw-r--r-- | src/liberti.c | 597 |
1 files changed, 296 insertions, 301 deletions
diff --git a/src/liberti.c b/src/liberti.c index 89ea691..2bcc175 100644 --- a/src/liberti.c +++ b/src/liberti.c @@ -1,6 +1,6 @@ /* * LiberTI - TI-like calculator designed for LibreCalc - * Copyright (C) 2015-2016 Delwink, LLC + * Copyright (C) 2015-2017 Delwink, LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -23,7 +23,6 @@ #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> -#include <getopt.h> #include <wordexp.h> #include "font.h" @@ -33,342 +32,338 @@ #include "tibfunction.h" #include "tibvar.h" -#ifdef HAVE_CONFIG_H -# include "config.h" -# define VERSION_STRING PACKAGE_VERSION -# define PROG PACKAGE -#else -# define VERSION_STRING "custom build" -# define PROG "liberti" -#endif +#define VERSION_STRING "0.0.0" +#define PROG "liberti" #define USAGE_INFO "USAGE: " PROG " [options]\n\n\ OPTIONS:\n\ -\t-d, --debug\tPrints extra activity while running\n\ -\t-h, --help\tPrints this help message and exits\n\ -\t-v, --version\tPrints version info and exits\n" +\t-d\tPrints extra activity while running\n\ +\t-h\tPrints this help message and exits\n\ +\t-v\tPrints version info and exits\n" #define VERSION_INFO "LiberTI " VERSION_STRING "\n\ -Copyright (C) 2015-2016 Delwink, LLC\n\ +Copyright (C) 2015-2017 Delwink, LLC\n\ License AGPLv3: GNU AGPL version 3 only <http://gnu.org/licenses/agpl.html>.\n\ This is libre software: you are free to change and redistribute it.\n\ There is NO WARRANTY, to the extent permitted by law.\n\n\ Written by David McMackins II." #ifdef RUN_IN_PLACE -# define USER_DIR "." +#define USER_DIR "." #else -# define USER_DIR "~/.liberti" +#define USER_DIR "~/.liberti" #endif #define USER_STATE_PATH "state.conf" static Uint32 -timer (Uint32 interval, void *data) +timer(Uint32 interval, void *data) { - SDL_Event event; - SDL_UserEvent user; + SDL_Event event; + SDL_UserEvent user; - user.type = SDL_USEREVENT; - user.code = 0; - user.data1 = data; + user.type = SDL_USEREVENT; + user.code = 0; + user.data1 = data; - event.type = SDL_USEREVENT; - event.user = user; + event.type = SDL_USEREVENT; + event.user = user; - SDL_PushEvent (&event); - return interval; + SDL_PushEvent(&event); + return interval; } static char * -get_conf_path (const char *path) +get_conf_path(const char *path) { - wordexp_t w; - int rc = wordexp (USER_DIR, &w, 0); - if (rc) - return NULL; - - size_t len = strlen (w.we_wordv[0]) + strlen (path) + 2; - char *out = malloc (len * sizeof (char)); - if (out) - snprintf (out, len, "%s/%s", w.we_wordv[0], path); - - wordfree (&w); - return out; + wordexp_t w; + int rc = wordexp(USER_DIR, &w, 0); + if (rc) + return NULL; + + size_t len = strlen(w.we_wordv[0]) + strlen(path) + 2; + char *out = malloc(len * sizeof(char)); + if (out) + snprintf(out, len, "%s/%s", w.we_wordv[0], path); + + wordfree(&w); + return out; } int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { - bool user_dir_exists = false, state_file_exists = false, state_init = false; - int rc = 0; - SDL_TimerID timer_id = 0; - SDL_Window *window = NULL; - Skin *skin = NULL; - - char *skin_path = NULL, *state_path = NULL; - Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; - - struct option longopts[] = - { - {"debug", no_argument, 0, 'd'}, - {"fullscreen", no_argument, 0, 'f'}, - {"help", no_argument, 0, 'h'}, - {"skin", required_argument, 0, 's'}, - {"version", no_argument, 0, 'v'}, - {0, 0, 0, 0} - }; - - if (argc > 1) - { - int c; - int longindex; - while ((c = getopt_long (argc, argv, "dfhs:v", longopts, &longindex)) - != -1) - { - switch (c) - { - case 'd': - debug_mode = true; - break; - - case 'f': - window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; - break; - - case 'h': - puts (USAGE_INFO); - return 0; - - case 's': - skin_path = optarg; - break; - - case 'v': - puts (VERSION_INFO); - return 0; - - case '?': - return 1; - } - } - } - - gsl_set_error_handler_off (); - - rc = SDL_Init (SDL_INIT_TIMER); - if (rc) - { - critical ("Could not initialize SDL timer: %s", SDL_GetError ()); - goto end; - } - - rc = SDL_VideoInit (NULL); - if (rc) - { - critical ("Could not initialize SDL video: %s", SDL_GetError ()); - goto end; - } - - rc = IMG_Init (IMG_INIT_PNG); - if (rc != IMG_INIT_PNG) - { - critical ("Could not initialize PNG image library: %s", IMG_GetError ()); - rc = 1; - goto end; - } - - rc = font_init (); - if (rc) - goto end; - - rc = tib_keyword_init (); - if (rc) - { - critical ("Could not initialize TI-BASIC keyword lookup tree: Error %d", - rc); - goto end; - } - - rc = tib_var_init (); - if (rc) - { - critical ("Could not initialize default variables: Error %d", rc); - goto end; - } - - rc = tib_registry_init (); - if (rc) - { - critical ("Could not initialize function registry: Error %d", rc); - goto end; - } - - SDL_DisplayMode display_mode; - rc = SDL_GetCurrentDisplayMode (0, &display_mode); - if (rc) - { - critical ("Could not get screen information: %s", SDL_GetError ()); - goto end; - } - - debug ("Screen resolution: %dx%d", display_mode.w, display_mode.h); - - { - char *user_dir_path = get_conf_path (""); - if (user_dir_path) - { - rc = mkdir (user_dir_path, 0755); - free (user_dir_path); - if (rc && EEXIST != errno) - { - warn ("Failed to create config directory: %s", strerror (errno)); - } - else - { - user_dir_exists = true; - - state_path = get_conf_path (USER_STATE_PATH); - if (state_path) - { - rc = access (state_path, F_OK); - if (rc) - { - debug ("Can't open state file: %s", strerror (errno)); - info ("Loading empty state"); - } - else - { - state_file_exists = true; - info ("Loading state from %s", state_path); - } - } - } - } - else - { - warn ("Could not determine config path"); - } - } - - struct state state; - rc = load_state (&state, state_file_exists ? state_path : NULL); - if (rc) - { - critical ("Could not initialize calculator state. Error %d", rc); - goto end; - } - - state_init = true; - - timer_id = SDL_AddTimer (500, timer, &state); - if (!timer_id) - { - critical ("Could not add blink timer: %s", SDL_GetError ()); - goto end; - } - - skin = open_skin (skin_path, &state, (struct point2d) { 96, 64 }); - if (!skin) - { - critical ("Could not load skin"); - goto end; - } - - window = SDL_CreateWindow ("LiberTI " VERSION_STRING, - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - skin->size.x, - skin->size.y, - window_flags); - if (!window) - { - critical ("Could not create window: %s", SDL_GetError ()); - goto end; - } - - for (;;) - { - SDL_Surface *frame = Skin_get_frame (skin); - if (frame) - { - SDL_Surface *screen = SDL_GetWindowSurface (window); - SDL_BlitScaled (frame, NULL, screen, NULL); - SDL_FreeSurface (frame); - SDL_UpdateWindowSurface (window); - } - - SDL_Event event; - SDL_WaitEvent (NULL); - - while (SDL_PollEvent (&event)) - { - switch (event.type) - { - case SDL_KEYDOWN: - rc = Skin_input (skin, &event.key); - if (rc) - error ("Error %d processing key entry", rc); - break; - - case SDL_USEREVENT: - switch (event.user.code) - { - case 0: - { - struct state *state = event.user.data1; - state->blink_state = !state->blink_state; - } - break; - - default: - break; - } - break; - - case SDL_QUIT: - info ("Got SDL quit event"); - goto end; - - default: - break; - } - } - } + bool user_dir_exists = false, state_file_exists = false; + bool state_init = false; + int rc = 0; + SDL_TimerID timer_id = 0; + SDL_Window *window = NULL; + Skin *skin = NULL; + + char *skin_path = NULL, *state_path = NULL; + Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; + + if (argc > 1) + { + int c; + while ((c = getopt(argc, argv, ":dfhs:v")) != -1) + { + switch (c) + { + case 'd': + debug_mode = true; + break; + + case 'f': + window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + break; + + case 'h': + puts(USAGE_INFO); + return 0; + + case 's': + skin_path = optarg; + break; + + case 'v': + puts(VERSION_INFO); + return 0; + + case ':': + fprintf(stderr, + PROG ": option -%c requires an argument\n", + optopt); + // SPILLS OVER! + + case '?': + return 1; + } + } + } + + gsl_set_error_handler_off(); + + rc = SDL_Init(SDL_INIT_TIMER); + if (rc) + { + critical("Could not initialize SDL timer: %s", SDL_GetError()); + goto end; + } + + rc = SDL_VideoInit(NULL); + if (rc) + { + critical("Could not initialize SDL video: %s", SDL_GetError()); + goto end; + } + + rc = IMG_Init(IMG_INIT_PNG); + if (rc != IMG_INIT_PNG) + { + critical("Could not initialize PNG image library: %s", + IMG_GetError()); + rc = 1; + goto end; + } + + rc = font_init(); + if (rc) + goto end; + + rc = tib_keyword_init(); + if (rc) + { + critical("Could not initialize TI-BASIC keyword lookup tree: Error %d", + rc); + goto end; + } + + rc = tib_var_init(); + if (rc) + { + critical("Could not initialize default variables: Error %d", + rc); + goto end; + } + + rc = tib_registry_init(); + if (rc) + { + critical("Could not initialize function registry: Error %d", + rc); + goto end; + } + + SDL_DisplayMode display_mode; + rc = SDL_GetCurrentDisplayMode(0, &display_mode); + if (rc) + { + critical("Could not get screen information: %s", + SDL_GetError()); + goto end; + } + + debug("Screen resolution: %dx%d", display_mode.w, display_mode.h); + + char *user_dir_path = get_conf_path(""); + if (user_dir_path) + { + rc = mkdir(user_dir_path, 0755); + free(user_dir_path); + if (rc && EEXIST != errno) + { + warn("Failed to create config directory: %s", + strerror(errno)); + } + else + { + user_dir_exists = true; + + state_path = get_conf_path(USER_STATE_PATH); + if (state_path) + { + rc = access(state_path, F_OK); + if (rc) + { + debug("Can't open state file: %s", + strerror(errno)); + info("Loading empty state"); + } + else + { + state_file_exists = true; + info("Loading state from %s", + state_path); + } + } + } + } + else + { + warn("Could not determine config path"); + } + + struct state state; + rc = load_state(&state, state_file_exists ? state_path : NULL); + if (rc) + { + critical("Could not initialize calculator state. Error %d", + rc); + goto end; + } + + state_init = true; + + timer_id = SDL_AddTimer(500, timer, &state); + if (!timer_id) + { + critical("Could not add blink timer: %s", SDL_GetError()); + goto end; + } + + skin = open_skin(skin_path, &state, (struct point2d) { 96, 64 }); + if (!skin) + { + critical("Could not load skin"); + goto end; + } + + window = SDL_CreateWindow("LiberTI " VERSION_STRING, + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + skin->size.x, skin->size.y, window_flags); + if (!window) + { + critical("Could not create window: %s", SDL_GetError()); + goto end; + } + + for (;;) + { + SDL_Surface *frame = Skin_get_frame(skin); + if (frame) + { + SDL_Surface *screen = SDL_GetWindowSurface(window); + SDL_BlitScaled(frame, NULL, screen, NULL); + SDL_FreeSurface(frame); + SDL_UpdateWindowSurface(window); + } + + SDL_Event event; + SDL_WaitEvent(NULL); + + while (SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_KEYDOWN: + rc = Skin_input(skin, &event.key); + if (rc) + error("Error %d processing key entry", + rc); + break; + + case SDL_USEREVENT: + switch (event.user.code) + { + case 0: + { + struct state *state = + event.user.data1; + state->blink_state = + !state->blink_state; + } + break; + + default: + break; + } + break; + + case SDL_QUIT: + info("Got SDL quit event"); + goto end; + + default: + break; + } + } + } end: - if (timer_id) - SDL_RemoveTimer (timer_id); + if (timer_id) + SDL_RemoveTimer(timer_id); - SDL_Quit (); - SDL_VideoQuit (); - IMG_Quit (); + SDL_Quit(); + SDL_VideoQuit(); + IMG_Quit(); - font_free (); - tib_keyword_free (); - tib_registry_free (); - tib_var_free (); + font_free(); + tib_keyword_free(); + tib_registry_free(); + tib_var_free(); - if (state_init) - { - if (user_dir_exists && state_path) - { - errno = save_state (&state, state_path); - if (errno) - warn ("Failed to save state"); - } + if (state_init) + { + if (user_dir_exists && state_path) + { + errno = save_state(&state, state_path); + if (errno) + warn("Failed to save state"); + } - state_destroy (&state); - } + state_destroy(&state); + } - if (state_path) - free (state_path); + if (state_path) + free(state_path); - if (skin) - free_skin (skin); + if (skin) + free_skin(skin); - if (window) - SDL_DestroyWindow (window); + if (window) + SDL_DestroyWindow(window); - return !!rc; + return !!rc; } |