Mercurial > repos > blastem
comparison util.c @ 2053:3414a4423de1 segacd
Merge from default
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 15 Jan 2022 13:15:21 -0800 |
parents | 441d5d6cea2f |
children | 237068a25523 |
comparison
equal
deleted
inserted
replaced
1692:5dacaef602a7 | 2053:3414a4423de1 |
---|---|
5 #include <stdint.h> | 5 #include <stdint.h> |
6 #include <stdarg.h> | 6 #include <stdarg.h> |
7 | 7 |
8 #include <sys/types.h> | 8 #include <sys/types.h> |
9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
10 #include <unistd.h> | |
11 #include <errno.h> | 10 #include <errno.h> |
12 | 11 |
13 #ifdef __ANDROID__ | 12 #ifdef __ANDROID__ |
14 #include <android/log.h> | 13 #include <android/log.h> |
15 #define info_puts(msg) __android_log_write(ANDROID_LOG_INFO, "BlastEm", msg) | 14 #define info_puts(msg) __android_log_write(ANDROID_LOG_INFO, "BlastEm", msg) |
78 uint8_t in_var = 0; | 77 uint8_t in_var = 0; |
79 uint32_t max_var_len = 0; | 78 uint32_t max_var_len = 0; |
80 for (char *cur = base; *cur; ++cur) | 79 for (char *cur = base; *cur; ++cur) |
81 { | 80 { |
82 if (in_var) { | 81 if (in_var) { |
83 if (!(*cur == '_' || isalnum(*cur))) { | 82 if (!isalnum(*cur)) { |
84 positions[num_vars].end = cur-base; | 83 positions[num_vars].end = cur-base; |
85 if (positions[num_vars].end - positions[num_vars].start > max_var_len) { | 84 if (positions[num_vars].end - positions[num_vars].start > max_var_len) { |
86 max_var_len = positions[num_vars].end - positions[num_vars].start; | 85 max_var_len = positions[num_vars].end - positions[num_vars].start; |
87 } | 86 } |
88 num_vars++; | 87 num_vars++; |
185 if (!*text) { | 184 if (!*text) { |
186 return text; | 185 return text; |
187 } | 186 } |
188 *text = 0; | 187 *text = 0; |
189 return text+1; | 188 return text+1; |
189 } | |
190 | |
191 uint8_t startswith(const char *haystack, const char *prefix) | |
192 { | |
193 return !strncmp(haystack, prefix, strlen(prefix)); | |
190 } | 194 } |
191 | 195 |
192 void bin_to_hex(uint8_t *output, uint8_t *input, uint64_t size) | 196 void bin_to_hex(uint8_t *output, uint8_t *input, uint64_t size) |
193 { | 197 { |
194 while (size) | 198 while (size) |
435 } | 439 } |
436 va_end(args); | 440 va_end(args); |
437 exit(1); | 441 exit(1); |
438 } | 442 } |
439 | 443 |
444 #ifndef _WIN32 | |
445 #include <unistd.h> | |
446 #endif | |
447 | |
440 void warning(char *format, ...) | 448 void warning(char *format, ...) |
441 { | 449 { |
442 va_list args; | 450 va_list args; |
443 va_start(args, format); | 451 va_start(args, format); |
444 #ifndef _WIN32 | 452 #ifndef _WIN32 |
470 } | 478 } |
471 #endif | 479 #endif |
472 va_end(args); | 480 va_end(args); |
473 } | 481 } |
474 | 482 |
483 static uint8_t output_enabled = 1; | |
475 void info_message(char *format, ...) | 484 void info_message(char *format, ...) |
476 { | 485 { |
477 va_list args; | 486 va_list args; |
478 va_start(args, format); | 487 va_start(args, format); |
479 #ifndef _WIN32 | 488 #ifndef _WIN32 |
480 if (headless || (isatty(STDOUT_FILENO) && isatty(STDIN_FILENO))) { | 489 if (headless || (isatty(STDOUT_FILENO) && isatty(STDIN_FILENO))) { |
481 info_printf(format, args); | 490 if (output_enabled) { |
491 info_printf(format, args); | |
492 } | |
482 } else { | 493 } else { |
483 #endif | 494 #endif |
484 int32_t size = strlen(format) * 2; | 495 int32_t size = strlen(format) * 2; |
485 char *buf = malloc(size); | 496 char *buf = malloc(size); |
486 int32_t actual = vsnprintf(buf, size, format, args); | 497 int32_t actual = vsnprintf(buf, size, format, args); |
496 buf = malloc(actual); | 507 buf = malloc(actual); |
497 va_end(args); | 508 va_end(args); |
498 va_start(args, format); | 509 va_start(args, format); |
499 vsnprintf(buf, actual, format, args); | 510 vsnprintf(buf, actual, format, args); |
500 } | 511 } |
501 info_puts(buf); | 512 if (output_enabled) { |
513 info_puts(buf); | |
514 } | |
502 render_infobox("BlastEm Info", buf); | 515 render_infobox("BlastEm Info", buf); |
503 free(buf); | 516 free(buf); |
504 #ifndef _WIN32 | 517 #ifndef _WIN32 |
505 } | 518 } |
506 #endif | 519 #endif |
507 va_end(args); | 520 va_end(args); |
508 } | 521 } |
509 | 522 |
523 void debug_message(char *format, ...) | |
524 { | |
525 va_list args; | |
526 va_start(args, format); | |
527 if (output_enabled) { | |
528 info_printf(format, args); | |
529 } | |
530 } | |
531 | |
532 void disable_stdout_messages(void) | |
533 { | |
534 output_enabled = 0; | |
535 } | |
536 | |
537 uint8_t is_stdout_enabled(void) | |
538 { | |
539 return output_enabled; | |
540 } | |
541 | |
510 #ifdef _WIN32 | 542 #ifdef _WIN32 |
543 #define WINVER 0x501 | |
544 #include <winsock2.h> | |
511 #include <windows.h> | 545 #include <windows.h> |
512 #include <shlobj.h> | 546 #include <shlobj.h> |
513 | 547 |
514 char * get_home_dir() | 548 char * get_home_dir() |
515 { | 549 { |
653 } | 687 } |
654 free(parent); | 688 free(parent); |
655 return CreateDirectory(path, NULL); | 689 return CreateDirectory(path, NULL); |
656 } | 690 } |
657 | 691 |
692 static WSADATA wsa_data; | |
693 static void socket_cleanup(void) | |
694 { | |
695 WSACleanup(); | |
696 } | |
697 | |
698 void socket_init(void) | |
699 { | |
700 static uint8_t started; | |
701 if (!started) { | |
702 started = 1; | |
703 WSAStartup(MAKEWORD(2,2), &wsa_data); | |
704 atexit(socket_cleanup); | |
705 } | |
706 } | |
707 | |
708 int socket_blocking(int sock, int should_block) | |
709 { | |
710 u_long param = !should_block; | |
711 if (ioctlsocket(sock, FIONBIO, ¶m)) { | |
712 return WSAGetLastError(); | |
713 } | |
714 return 0; | |
715 } | |
716 | |
717 void socket_close(int sock) | |
718 { | |
719 closesocket(sock); | |
720 } | |
721 | |
722 int socket_last_error(void) | |
723 { | |
724 return WSAGetLastError(); | |
725 } | |
726 | |
727 int socket_error_is_wouldblock(void) | |
728 { | |
729 return WSAGetLastError() == WSAEWOULDBLOCK; | |
730 } | |
731 | |
658 #else | 732 #else |
733 #include <fcntl.h> | |
734 #include <signal.h> | |
735 | |
736 void socket_init(void) | |
737 { | |
738 //SIGPIPE on network sockets is not desired | |
739 //would be better to do this in a more limited way, | |
740 //but the alternatives are not portable | |
741 signal(SIGPIPE, SIG_IGN); | |
742 } | |
743 | |
744 int socket_blocking(int sock, int should_block) | |
745 { | |
746 if (fcntl(sock, F_SETFL, should_block ? 0 : O_NONBLOCK)) { | |
747 return errno; | |
748 } | |
749 return 0; | |
750 } | |
751 | |
752 void socket_close(int sock) | |
753 { | |
754 close(sock); | |
755 } | |
756 | |
757 int socket_last_error(void) | |
758 { | |
759 return errno; | |
760 } | |
761 | |
762 int socket_error_is_wouldblock(void) | |
763 { | |
764 return errno == EAGAIN || errno == EWOULDBLOCK; | |
765 } | |
659 | 766 |
660 char * get_home_dir() | 767 char * get_home_dir() |
661 { | 768 { |
662 return getenv("HOME"); | 769 return getenv("HOME"); |
663 } | 770 } |
828 void sort_dir_list(dir_entry *list, size_t num_entries) | 935 void sort_dir_list(dir_entry *list, size_t num_entries) |
829 { | 936 { |
830 qsort(list, num_entries, sizeof(dir_entry), sort_dir_alpha); | 937 qsort(list, num_entries, sizeof(dir_entry), sort_dir_alpha); |
831 } | 938 } |
832 | 939 |
940 uint8_t delete_file(char *path) | |
941 { | |
942 #ifdef _WIN32 | |
943 //TODO: Call Unicode version and prepend special string to remove max path limitation | |
944 return 0 != DeleteFileA(path); | |
945 #else | |
946 return 0 == unlink(path); | |
947 #endif | |
948 } | |
949 | |
833 #ifdef __ANDROID__ | 950 #ifdef __ANDROID__ |
834 | 951 |
835 #include <SDL.h> | 952 #include <SDL.h> |
953 #ifndef IS_LIB | |
836 char *read_bundled_file(char *name, uint32_t *sizeret) | 954 char *read_bundled_file(char *name, uint32_t *sizeret) |
837 { | 955 { |
838 SDL_RWops *rw = SDL_RWFromFile(name, "rb"); | 956 SDL_RWops *rw = SDL_RWFromFile(name, "rb"); |
839 if (!rw) { | 957 if (!rw) { |
840 if (sizeret) { | 958 if (sizeret) { |
858 ret = NULL; | 976 ret = NULL; |
859 } | 977 } |
860 SDL_RWclose(rw); | 978 SDL_RWclose(rw); |
861 return ret; | 979 return ret; |
862 } | 980 } |
981 #endif | |
863 | 982 |
864 char const *get_config_dir() | 983 char const *get_config_dir() |
865 { | 984 { |
866 return SDL_AndroidGetInternalStoragePath(); | 985 return SDL_AndroidGetInternalStoragePath(); |
867 } | 986 } |
871 return SDL_AndroidGetInternalStoragePath(); | 990 return SDL_AndroidGetInternalStoragePath(); |
872 } | 991 } |
873 | 992 |
874 #else | 993 #else |
875 | 994 |
995 #ifndef IS_LIB | |
876 char *read_bundled_file(char *name, uint32_t *sizeret) | 996 char *read_bundled_file(char *name, uint32_t *sizeret) |
877 { | 997 { |
878 char *exe_dir = get_exe_dir(); | 998 #ifdef DATA_PATH |
879 if (!exe_dir) { | 999 char *data_dir = DATA_PATH; |
1000 #else | |
1001 char *data_dir = get_exe_dir(); | |
1002 if (!data_dir) { | |
880 if (sizeret) { | 1003 if (sizeret) { |
881 *sizeret = -1; | 1004 *sizeret = -1; |
882 } | 1005 } |
883 return NULL; | 1006 return NULL; |
884 } | 1007 } |
885 char const *pieces[] = {exe_dir, PATH_SEP, name}; | 1008 #endif |
1009 char const *pieces[] = {data_dir, PATH_SEP, name}; | |
886 char *path = alloc_concat_m(3, pieces); | 1010 char *path = alloc_concat_m(3, pieces); |
887 FILE *f = fopen(path, "rb"); | 1011 FILE *f = fopen(path, "rb"); |
888 free(path); | 1012 free(path); |
889 if (!f) { | 1013 if (!f) { |
890 if (sizeret) { | 1014 if (sizeret) { |
910 ret = NULL; | 1034 ret = NULL; |
911 } | 1035 } |
912 fclose(f); | 1036 fclose(f); |
913 return ret; | 1037 return ret; |
914 } | 1038 } |
915 | 1039 #endif //ISLIB |
916 | 1040 |
917 #ifdef _WIN32 | 1041 #ifdef _WIN32 |
918 char const *get_userdata_dir() | 1042 char const *get_userdata_dir() |
919 { | 1043 { |
920 static char path[MAX_PATH]; | 1044 static char path[MAX_PATH]; |
967 } | 1091 } |
968 return savedir; | 1092 return savedir; |
969 } | 1093 } |
970 | 1094 |
971 | 1095 |
972 #endif | 1096 #endif //_WIN32 |
973 | 1097 #endif //__ANDROID__ |
974 | 1098 |
975 | |
976 #endif |