open-card-table/main.c

244 lines
5.9 KiB
C
Raw Normal View History

2023-01-06 19:12:24 -05:00
#include <stdio.h>
#include <lua5.3/lualib.h>
#include <lua5.3/lauxlib.h>
2023-01-06 19:12:24 -05:00
#include "termbox_render.h"
#include "oct_termbox_sprite.h"
#include "oct_networking.h"
#include "oct_log.h"
2023-01-06 19:12:24 -05:00
#define TB_IMPL
#include "termbox.h"
2023-01-06 19:12:24 -05:00
// Errors
#define OCT_NO_LUA_FILE 1
#define OCT_LUA_FILE_NOT_FOUND 2
#define OCT_LUA_FILE_MISSING_OCT_INIT 3
2023-05-22 09:57:01 -04:00
#define OCT_HELP 4
#define OCT_VERS 5
#define OCT_INVALID_ARGUMENT 6
#define OCT_MAX_FILENAME_SIZE 1024
2023-05-22 09:57:01 -04:00
#define OCT_VERSION "0.0"
#define OCT_URL "https://git.thejerks.club/j4nk/open-card-table"
int oct_type;
2023-01-06 19:12:24 -05:00
lua_State *L;
struct {
char port[6]; // max 65535 so 6 bytes needed
// Might come in handy later to keep filename
// e.g. if I ever want to allow downloading a script from peer
char lua_file[OCT_MAX_FILENAME_SIZE];
} args;
2023-05-22 09:57:01 -04:00
void usage();
void version();
int process_args(int argc, char* argv[]);
int initialize_everything(char* lua_file);
2023-01-06 19:12:24 -05:00
int deinitialize_everything();
2023-01-06 19:12:24 -05:00
int main(int argc, char* argv[]) {
int process_args_result = process_args(argc, argv);
switch (process_args_result) {
case OCT_NO_LUA_FILE:
// Can't use oct_log as logging is not guaranteed to be init
2023-05-22 09:57:01 -04:00
fprintf(stderr, "Error: No lua file given\n\n");
usage();
return EXIT_FAILURE;
break;
case OCT_LUA_FILE_NOT_FOUND:
// oct_log is init by this time, but don't want PITA bug in case this changes
2023-05-22 09:57:01 -04:00
fprintf(stderr, "Error: Could not open file: %s\n", argv[argc-1]);
deinitialize_everything();
return EXIT_FAILURE;
break;
case OCT_INVALID_ARGUMENT:
// Can't use oct_log as logging is not guaranteed to be init
fprintf(stderr, "Error: unknown argument\n");
return EXIT_FAILURE;
break;
2023-05-22 09:57:01 -04:00
case OCT_HELP:
usage();
return EXIT_SUCCESS;
break;
case OCT_VERS:
version();
return EXIT_SUCCESS;
break;
2023-01-06 19:12:24 -05:00
}
struct tb_event ev;
int finish = 0;
while (!finish) {
tb_clear();
tb_peek_event(&ev, 10);
if (ev.key == TB_KEY_ESC) {
finish = 1;
}
lua_getglobal(L, "oct_loop");
lua_pushinteger(L, ev.key);
lua_pushinteger(L, ev.ch);
lua_call(L, 2, 0);
for (uint32_t i=0; i < oct_tb_sprite_list.new_index; i++) {
oct_render_termbox_sprite(oct_tb_sprite_list.sprite_list[i]);
}
tb_present();
}
deinitialize_everything();
return EXIT_SUCCESS;
}
int process_args(int argc, char* argv[]) {
if (argc == 1) { // Didn't specify a file
return OCT_NO_LUA_FILE;
}
// Set args.port to default
strncpy(args.port, OCT_DEFAULT_PORT, 6);
int log_level = OCT_LOG_LEVEL_ERROR;
char log_file[OCT_MAX_FILENAME_SIZE];
int log_file_spec = 0;
int valid_last_argument = 0;
2023-05-22 09:57:01 -04:00
for (int i = 1; i < argc; i++) {
// argv's are guaranteed to be zero-terminated, so can use
// strcmp instead of strncmp
if (strcmp(argv[i], "-p") == 0) {
if (i+1 < argc) {
strncpy(args.port, argv[i+1], 6);
i++;
}
else {
fprintf(stderr, "Error: need to specify a port after -p\n");
return OCT_INVALID_ARGUMENT;
}
}
2023-05-22 09:57:01 -04:00
else if (strcmp(argv[i], "-h") == 0) {
return OCT_HELP;
}
else if (strcmp(argv[i], "-v") == 0) {
return OCT_VERS;
}
else if (strcmp(argv[i], "-ll") == 0) {
if (i+1 < argc) {
char* endptr = NULL;
log_level = strtoul(argv[i+1], &endptr, 10);
if (log_level == 0 && endptr == argv[i+1]) {
printf("Error: invalid log level\n");
return OCT_INVALID_ARGUMENT;
}
i++;
}
else {
fprintf(stderr, "Error: need to specify a log level after -ll\n");
return OCT_INVALID_ARGUMENT;
}
}
else if (strcmp(argv[i], "-lf") == 0) {
if (i+1 < argc) {
strncpy(log_file, argv[i+1], OCT_MAX_FILENAME_SIZE);
log_file_spec = 1;
i++;
}
else {
fprintf(stderr, "Error: need to specify a log file after -lf\n");
return OCT_INVALID_ARGUMENT;
}
}
2023-05-22 09:57:01 -04:00
else {
// This is the lua file to run
2023-05-22 09:57:01 -04:00
if (i == argc-1) {
valid_last_argument = 1;
2023-05-22 09:57:01 -04:00
break;
}
// Invalid argument
2023-05-22 09:57:01 -04:00
else {
return OCT_INVALID_ARGUMENT;
}
}
}
if (!valid_last_argument) {
return OCT_NO_LUA_FILE;
}
oct_log_init(log_file_spec ? log_file : NULL, log_level);
strncpy(args.lua_file, argv[argc-1], OCT_MAX_FILENAME_SIZE);
OCT_LOG_INFO("Running lua file: %s", args.lua_file);
return initialize_everything(argv[argc-1]); // lua file should always be last argument
}
int initialize_everything(char* lua_file) {
// Check if file exists
if (access(lua_file, F_OK) != 0) {
return OCT_LUA_FILE_NOT_FOUND;
}
2023-01-06 19:12:24 -05:00
if (!oct_tb_sprite_list_initialize()) {
return 0;
}
OCT_LOG_INFO("Initialized the sprite list");
2023-01-06 19:12:24 -05:00
L = luaL_newstate();
if (L == NULL) {
OCT_LOG_ERROR("Can't initialize Lua\n");
2023-01-06 19:12:24 -05:00
return 0;
}
OCT_LOG_INFO("Initialized lua state");
2023-01-06 19:12:24 -05:00
luaL_openlibs(L);
oct_tb_initialize_lua(L);
oct_log_init_lua(L);
if (luaL_dofile(L, lua_file)) return OCT_LUA_FILE_NOT_FOUND;
OCT_LOG_INFO("Begin running oct_init()");
2023-01-06 19:12:24 -05:00
lua_getglobal(L, "oct_init");
lua_call(L, 0, 1);
int type = lua_tointeger(L, -1);
OCT_LOG_INFO("Finish running oct_init()");
if (type == OCT_TYPE_SERVER) {
OCT_LOG_INFO("Lua script is server type");
if (!oct_network_server_init(args.port)) {
OCT_LOG_ERROR("Could not establish a socket on port %s\n", args.port);
return 0;
}
}
else if (type == OCT_TYPE_CLIENT) {
//oct_network_client_init();
}
else {
// Do nothing, offline
}
2023-01-06 19:12:24 -05:00
tb_init();
return 0;
2023-01-06 19:12:24 -05:00
}
int deinitialize_everything() {
OCT_LOG_INFO("Deinitializing everything");
2023-01-06 19:12:24 -05:00
tb_shutdown();
lua_close(L);
oct_tb_sprite_list_deinitialize();
oct_log_deinit();
2023-01-06 19:12:24 -05:00
return 1;
}
2023-05-22 09:57:01 -04:00
void usage() {
fprintf(stderr, "Open Card Table, version %s\n", OCT_VERSION);
fprintf(stderr, "%s\n", OCT_URL);
fprintf(stderr, "\n");
fprintf(stderr, "Usage: ./open_card_table [OPTIONS] FILE\n");
fprintf(stderr, "\n");
fprintf(stderr, " -p\t\tPort on which to listen\n");
fprintf(stderr, " -v\t\tPrint version and exit\n");
fprintf(stderr, " -h\t\tPrint this message and exit\n");
fprintf(stderr, " -ll\t\t Set log level: 0=err, 1=warn, 2=info, 3=debug\n");
fprintf(stderr, " -lf\t\t Specify log output file\n");
2023-05-22 09:57:01 -04:00
fprintf(stderr, "\n");
}
void version() {
fprintf(stderr, "%s\n", OCT_VERSION);
}