An emulator, assembler, and disassembler for the Sega Game Gear
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 

161 lignes
4.0 KiB

  1. /* Copyright (C) 2014 Ben Kurtovic <ben.kurtovic@gmail.com>
  2. Released under the terms of the MIT License. See LICENSE for details. */
  3. #include <dirent.h>
  4. #include <errno.h>
  5. #include <stdbool.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <sys/types.h>
  10. #include "src/errors.h"
  11. #include "src/rom.h"
  12. #include "src/version.h"
  13. #define ROMS_DIR "roms"
  14. /* Print command-line help/usage. */
  15. static void print_help(char *arg1)
  16. {
  17. printf("%s [--help|-h] [--version|-v] [rom_path]\n", arg1);
  18. }
  19. /* Print crater's version. */
  20. static void print_version()
  21. {
  22. printf("crater %s\n", CRATER_VERSION);
  23. }
  24. /* Parse the command-line arguments for any special flags. */
  25. static void parse_args(int argc, char *argv[])
  26. {
  27. char *arg;
  28. int i;
  29. for (i = 1; i < argc; i++) {
  30. arg = argv[i];
  31. if (arg[0] != '-')
  32. continue;
  33. do
  34. arg++;
  35. while (arg[0] == '-');
  36. if (!strcmp(arg, "h") || !strcmp(arg, "help")) {
  37. print_help(argv[0]);
  38. exit(0);
  39. } else if (!strcmp(arg, "v") || !strcmp(arg, "version")) {
  40. print_version();
  41. exit(0);
  42. } else {
  43. printf("Error: unknown argument: %s\n", argv[i]);
  44. exit(1);
  45. }
  46. }
  47. }
  48. /* Return whether the given string ends with the given suffix. */
  49. static bool ends_with(char *input, char *suffix)
  50. {
  51. size_t ilen = strlen(input), slen = strlen(suffix);
  52. if (ilen < slen)
  53. return false;
  54. return strcmp(input + (ilen - slen), suffix) == 0;
  55. }
  56. /* Load all potential ROM files in roms/ into a data structure. */
  57. static int load_rom_paths(char ***path_ptr)
  58. {
  59. DIR *dirp;
  60. struct dirent *entry;
  61. char **paths = NULL, *path;
  62. int psize = 8, npaths = 0;
  63. dirp = opendir(ROMS_DIR);
  64. if (dirp) {
  65. paths = malloc(sizeof(char*) * psize);
  66. if (!paths)
  67. out_of_memory();
  68. while ((entry = readdir(dirp))) {
  69. path = entry->d_name;
  70. if (ends_with(path, ".gg") || ends_with(path, ".bin")) {
  71. if (npaths >= psize) {
  72. paths = realloc(paths, sizeof(char*) * (psize *= 2));
  73. if (!paths)
  74. out_of_memory();
  75. }
  76. paths[npaths] = malloc(sizeof(char*) *
  77. (strlen(path) + strlen(ROMS_DIR) + 1));
  78. if (!paths[npaths])
  79. out_of_memory();
  80. strcpy(paths[npaths], ROMS_DIR "/");
  81. strcat(paths[npaths], path);
  82. npaths++;
  83. }
  84. }
  85. closedir(dirp);
  86. } else {
  87. if (errno == ENOENT)
  88. printf("Warning: couldn't find roms/ directory.\n");
  89. else
  90. perror("Warning: couldn't open roms/ directory");
  91. }
  92. *path_ptr = paths;
  93. return npaths;
  94. }
  95. /* Find all potential ROM files in the roms/ directory, then ask the user which
  96. * one they want to run.
  97. */
  98. static char* get_rom_path_from_user()
  99. {
  100. char **paths, *path, *input = NULL;
  101. int npaths, i;
  102. long int index;
  103. size_t size = 0;
  104. ssize_t len;
  105. npaths = load_rom_paths(&paths);
  106. for (i = 0; i < npaths; i++)
  107. printf("[%2d] %s\n", i + 1, paths[i]);
  108. if (npaths)
  109. printf("Enter a ROM number from above, or the path to a ROM image: ");
  110. else
  111. printf("Enter the path to a ROM image: ");
  112. len = getline(&input, &size, stdin);
  113. if (!input)
  114. out_of_memory();
  115. if (len > 0 && input[len - 1] == '\n')
  116. input[len - 1] = '\0';
  117. index = strtol(input, NULL, 10);
  118. if (index < 1 || index > npaths)
  119. path = input;
  120. else
  121. path = paths[index - 1];
  122. for (i = 0; i < npaths; i++) {
  123. if (paths[i] != path)
  124. free(paths[i]);
  125. }
  126. if (paths)
  127. free(paths);
  128. return path;
  129. }
  130. int main(int argc, char *argv[])
  131. {
  132. char *rom_path;
  133. parse_args(argc, argv);
  134. rom_path = argc > 1 ? argv[1] : get_rom_path_from_user();
  135. // TODO: main logic hook here
  136. printf("Loading ROM: %s\n", rom_path);
  137. if (argc <= 1)
  138. free(rom_path);
  139. return 0;
  140. }