Super Mario 64s source code (from a leak on 4chan so be careful)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

276 lines
5.3 KiB

5 years ago
  1. #include <dirent.h>
  2. #include <fcntl.h>
  3. #include <stdint.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <sys/stat.h>
  8. #if defined(_MSC_VER) || defined(__MINGW32__)
  9. #include <io.h>
  10. #include <sys/utime.h>
  11. #else
  12. #include <unistd.h>
  13. #include <utime.h>
  14. #endif
  15. #include "utils.h"
  16. // global verbosity setting
  17. int g_verbosity = 0;
  18. int read_s16_be(unsigned char *buf)
  19. {
  20. unsigned tmp = read_u16_be(buf);
  21. int ret;
  22. if (tmp > 0x7FFF) {
  23. ret = -((int)0x10000 - (int)tmp);
  24. } else {
  25. ret = (int)tmp;
  26. }
  27. return ret;
  28. }
  29. float read_f32_be(unsigned char *buf)
  30. {
  31. union {uint32_t i; float f;} ret;
  32. ret.i = read_u32_be(buf);
  33. return ret.f;
  34. }
  35. int is_power2(unsigned int val)
  36. {
  37. while (((val & 1) == 0) && (val > 1)) {
  38. val >>= 1;
  39. }
  40. return (val == 1);
  41. }
  42. void fprint_hex(FILE *fp, const unsigned char *buf, int length)
  43. {
  44. int i;
  45. for (i = 0; i < length; i++) {
  46. fprint_byte(fp, buf[i]);
  47. fputc(' ', fp);
  48. }
  49. }
  50. void fprint_hex_source(FILE *fp, const unsigned char *buf, int length)
  51. {
  52. int i;
  53. for (i = 0; i < length; i++) {
  54. if (i > 0) fputs(", ", fp);
  55. fputs("0x", fp);
  56. fprint_byte(fp, buf[i]);
  57. }
  58. }
  59. void print_hex(const unsigned char *buf, int length)
  60. {
  61. fprint_hex(stdout, buf, length);
  62. }
  63. void swap_bytes(unsigned char *data, long length)
  64. {
  65. long i;
  66. unsigned char tmp;
  67. for (i = 0; i < length; i += 2) {
  68. tmp = data[i];
  69. data[i] = data[i+1];
  70. data[i+1] = tmp;
  71. }
  72. }
  73. void reverse_endian(unsigned char *data, long length)
  74. {
  75. long i;
  76. unsigned char tmp;
  77. for (i = 0; i < length; i += 4) {
  78. tmp = data[i];
  79. data[i] = data[i+3];
  80. data[i+3] = tmp;
  81. tmp = data[i+1];
  82. data[i+1] = data[i+2];
  83. data[i+2] = tmp;
  84. }
  85. }
  86. long filesize(const char *filename)
  87. {
  88. struct stat st;
  89. if (stat(filename, &st) == 0) {
  90. return st.st_size;
  91. }
  92. return -1;
  93. }
  94. void touch_file(const char *filename)
  95. {
  96. int fd;
  97. //fd = open(filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666);
  98. fd = open(filename, O_WRONLY|O_CREAT, 0666);
  99. if (fd >= 0) {
  100. utime(filename, NULL);
  101. close(fd);
  102. }
  103. }
  104. long read_file(const char *file_name, unsigned char **data)
  105. {
  106. FILE *in;
  107. unsigned char *in_buf = NULL;
  108. long file_size;
  109. long bytes_read;
  110. in = fopen(file_name, "rb");
  111. if (in == NULL) {
  112. return -1;
  113. }
  114. // allocate buffer to read from offset to end of file
  115. fseek(in, 0, SEEK_END);
  116. file_size = ftell(in);
  117. // sanity check
  118. if (file_size > 256*MB) {
  119. return -2;
  120. }
  121. in_buf = malloc(file_size);
  122. fseek(in, 0, SEEK_SET);
  123. // read bytes
  124. bytes_read = fread(in_buf, 1, file_size, in);
  125. if (bytes_read != file_size) {
  126. return -3;
  127. }
  128. fclose(in);
  129. *data = in_buf;
  130. return bytes_read;
  131. }
  132. long write_file(const char *file_name, unsigned char *data, long length)
  133. {
  134. FILE *out;
  135. long bytes_written;
  136. // open output file
  137. out = fopen(file_name, "wb");
  138. if (out == NULL) {
  139. perror(file_name);
  140. return -1;
  141. }
  142. bytes_written = fwrite(data, 1, length, out);
  143. fclose(out);
  144. return bytes_written;
  145. }
  146. void generate_filename(const char *in_name, char *out_name, char *extension)
  147. {
  148. char tmp_name[FILENAME_MAX];
  149. int len;
  150. int i;
  151. strcpy(tmp_name, in_name);
  152. len = strlen(tmp_name);
  153. for (i = len - 1; i > 0; i--) {
  154. if (tmp_name[i] == '.') {
  155. break;
  156. }
  157. }
  158. if (i <= 0) {
  159. i = len;
  160. }
  161. tmp_name[i] = '\0';
  162. sprintf(out_name, "%s.%s", tmp_name, extension);
  163. }
  164. char *basename(const char *name)
  165. {
  166. const char *base = name;
  167. while (*name) {
  168. if (*name++ == '/') {
  169. base = name;
  170. }
  171. }
  172. return (char *)base;
  173. }
  174. void make_dir(const char *dir_name)
  175. {
  176. struct stat st = {0};
  177. if (stat(dir_name, &st) == -1) {
  178. mkdir(dir_name, 0755);
  179. }
  180. }
  181. long copy_file(const char *src_name, const char *dst_name)
  182. {
  183. unsigned char *buf;
  184. long bytes_written;
  185. long bytes_read;
  186. bytes_read = read_file(src_name, &buf);
  187. if (bytes_read > 0) {
  188. bytes_written = write_file(dst_name, buf, bytes_read);
  189. if (bytes_written != bytes_read) {
  190. bytes_read = -1;
  191. }
  192. free(buf);
  193. }
  194. return bytes_read;
  195. }
  196. void dir_list_ext(const char *dir, const char *extension, dir_list *list)
  197. {
  198. char *pool;
  199. char *pool_ptr;
  200. struct dirent *entry;
  201. DIR *dfd;
  202. int idx;
  203. dfd = opendir(dir);
  204. if (dfd == NULL) {
  205. ERROR("Can't open '%s'\n", dir);
  206. exit(1);
  207. }
  208. pool = malloc(FILENAME_MAX * MAX_DIR_FILES);
  209. pool_ptr = pool;
  210. idx = 0;
  211. while ((entry = readdir(dfd)) != NULL && idx < MAX_DIR_FILES) {
  212. if (!extension || str_ends_with(entry->d_name, extension)) {
  213. sprintf(pool_ptr, "%s/%s", dir, entry->d_name);
  214. list->files[idx] = pool_ptr;
  215. pool_ptr += strlen(pool_ptr) + 1;
  216. idx++;
  217. }
  218. }
  219. list->count = idx;
  220. closedir(dfd);
  221. }
  222. void dir_list_free(dir_list *list)
  223. {
  224. // assume first entry in array is allocated
  225. if (list->files[0]) {
  226. free(list->files[0]);
  227. list->files[0] = NULL;
  228. }
  229. }
  230. int str_ends_with(const char *str, const char *suffix)
  231. {
  232. if (!str || !suffix) {
  233. return 0;
  234. }
  235. size_t len_str = strlen(str);
  236. size_t len_suffix = strlen(suffix);
  237. if (len_suffix > len_str) {
  238. return 0;
  239. }
  240. return (0 == strncmp(str + len_str - len_suffix, suffix, len_suffix));
  241. }