mia.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #include "mia.hpp"
  2. namespace mia {
  3. vector<shared_pointer<Media>> media;
  4. auto locate(string name) -> string {
  5. string location = {Path::program(), name};
  6. if(inode::exists(location)) return location;
  7. directory::create({Path::userData(), "mia/"});
  8. return {Path::userData(), "mia/", name};
  9. }
  10. auto operator+=(string& lhs, const string& rhs) -> string& {
  11. lhs.append(rhs);
  12. return lhs;
  13. }
  14. #include "settings/settings.cpp"
  15. #include "media/media.cpp"
  16. #include "cartridge/cartridge.cpp"
  17. #include "compact-disc/compact-disc.cpp"
  18. #include "floppy-disk/floppy-disk.cpp"
  19. #include "program/program.cpp"
  20. auto construct() -> void {
  21. media.append(new BSMemory);
  22. media.append(new ColecoVision);
  23. media.append(new Famicom);
  24. media.append(new FamicomDisk);
  25. media.append(new GameBoy);
  26. media.append(new GameBoyAdvance);
  27. media.append(new GameBoyColor);
  28. media.append(new GameGear);
  29. media.append(new MasterSystem);
  30. media.append(new MegaCD);
  31. media.append(new MegaDrive);
  32. media.append(new MSX);
  33. media.append(new MSX2);
  34. media.append(new NeoGeoPocket);
  35. media.append(new NeoGeoPocketColor);
  36. media.append(new Nintendo64);
  37. media.append(new Nintendo64DD);
  38. media.append(new PCEngine);
  39. media.append(new PCEngineCD);
  40. media.append(new PlayStation);
  41. media.append(new PocketChallengeV2);
  42. media.append(new SC3000);
  43. media.append(new SG1000);
  44. media.append(new SufamiTurbo);
  45. media.append(new SuperFamicom);
  46. media.append(new SuperGrafx);
  47. media.append(new WonderSwan);
  48. media.append(new WonderSwanColor);
  49. for(auto& medium : media) medium->construct();
  50. }
  51. auto medium(const string& name) -> shared_pointer<Media> {
  52. for(auto& medium : media) {
  53. if(medium->name() == name) return medium;
  54. }
  55. return {};
  56. }
  57. auto identify(const string& filename) -> string {
  58. auto extension = Location::suffix(filename).trimLeft(".", 1L).downcase();
  59. if(extension == "zip") {
  60. Decode::ZIP archive;
  61. if(archive.open(filename)) {
  62. for(auto& file : archive.file) {
  63. auto match = Location::suffix(file.name).trimLeft(".", 1L).downcase();
  64. for(auto& medium : media) {
  65. if(medium->extensions().find(match)) {
  66. extension = match;
  67. }
  68. }
  69. }
  70. }
  71. }
  72. for(auto& medium : media) {
  73. if(medium->extensions().find(extension)) {
  74. if(auto manifest = medium->manifest(filename)) {
  75. return medium->name();
  76. }
  77. }
  78. }
  79. return {}; //unable to identify
  80. }
  81. auto main(Arguments arguments) -> void {
  82. Application::setName("mia");
  83. construct();
  84. if(auto document = file::read({Path::userSettings(), "mia/settings.bml"})) {
  85. settings.unserialize(document);
  86. }
  87. if(arguments.take("--name")) {
  88. return print("mia");
  89. }
  90. if(string filename; arguments.take("--identify", filename)) {
  91. return print(identify(filename), "\n");
  92. }
  93. if(string system; arguments.take("--system", system)) {
  94. for(auto& medium : media) {
  95. if(medium->name() != system) continue;
  96. if(string manifest; arguments.take("--manifest", manifest)) {
  97. if(auto result = medium->manifest(manifest)) return print(result);
  98. if(medium->extensions().find("cue")) {
  99. //audio CD-ROM fallback
  100. string result;
  101. result.append("game\n");
  102. result.append(" name: ", medium->name(manifest), "\n");
  103. result.append(" label: ", medium->name(manifest), "\n");
  104. return print(result);
  105. }
  106. return;
  107. }
  108. if(string import; arguments.take("--import", import)) {
  109. return (void)medium->import(import);
  110. }
  111. if(arguments.take("--import")) {
  112. if(auto import = BrowserDialog()
  113. .setTitle({"Import ", system, " Game"})
  114. .setPath(settings.recent)
  115. .setAlignment(Alignment::Center)
  116. .openFile()
  117. ) {
  118. if(auto error = medium->import(import)) {
  119. MessageDialog()
  120. .setTitle("Error")
  121. .setAlignment(Alignment::Center)
  122. .setText({"Failed to import: ", Location::file(import), "\n\nError: ", error, "."})
  123. .error();
  124. }
  125. }
  126. return;
  127. }
  128. }
  129. }
  130. Instances::programWindow.construct();
  131. #if defined(PLATFORM_MACOS)
  132. Application::Cocoa::onAbout([&] { programWindow.aboutAction.doActivate(); });
  133. Application::Cocoa::onPreferences([&] {});
  134. Application::Cocoa::onQuit([&] { Application::quit(); });
  135. #endif
  136. programWindow.setVisible();
  137. Application::run();
  138. directory::create({Path::userSettings(), "mia/"});
  139. file::write({Path::userSettings(), "mia/settings.bml"}, settings.serialize());
  140. Instances::programWindow.destruct();
  141. }
  142. }
  143. #if !defined(MIA_LIBRARY)
  144. #include <ares/resource/resource.cpp>
  145. #include <nall/main.hpp>
  146. auto nall::main(Arguments arguments) -> void {
  147. mia::main(arguments);
  148. }
  149. #endif