cart_file.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #ifdef CART_CPP
  2. #include "../reader/filereader.hpp"
  3. #if defined(GZIP_SUPPORT)
  4. #include "../reader/gzreader.hpp"
  5. #include "../reader/zipreader.hpp"
  6. #endif
  7. #if defined(JMA_SUPPORT)
  8. #include "../reader/jmareader.hpp"
  9. #endif
  10. string Cartridge::modify_extension(const char *filename_, const char *extension) const {
  11. string filename = filename_;
  12. int i;
  13. for(i = strlen(filename); i >= 0; i--) {
  14. if(filename[i] == '.') break;
  15. if(filename[i] == '/') break;
  16. if(filename[i] == '\\') break;
  17. }
  18. if(i > 0 && filename[i] == '.') filename[i] = 0;
  19. return filename << "." << extension;
  20. }
  21. string Cartridge::get_filename(const char *source, const char *extension, const char *path) const {
  22. return filepath(modify_extension(source, extension), path);
  23. }
  24. bool Cartridge::load_file(const char *fn, uint8 *&data, unsigned &size, CompressionMode compression) const {
  25. if(file::exists(fn) == false) return false;
  26. Reader::Type filetype = Reader::Normal;
  27. if(compression == CompressionInspect) filetype = Reader::detect(fn, true);
  28. if(compression == CompressionAuto) filetype = Reader::detect(fn, snes.config.file.autodetect_type);
  29. switch(filetype) { default:
  30. case Reader::Normal: {
  31. FileReader ff(fn);
  32. if(!ff.ready()) return false;
  33. size = ff.size();
  34. data = ff.read();
  35. } break;
  36. #ifdef GZIP_SUPPORT
  37. case Reader::GZIP: {
  38. GZReader gf(fn);
  39. if(!gf.ready()) return false;
  40. size = gf.size();
  41. data = gf.read();
  42. } break;
  43. case Reader::ZIP: {
  44. ZipReader zf(fn);
  45. if(!zf.ready()) return false;
  46. size = zf.size();
  47. data = zf.read();
  48. } break;
  49. #endif
  50. #ifdef JMA_SUPPORT
  51. case Reader::JMA: {
  52. try {
  53. JMAReader jf(fn);
  54. size = jf.size();
  55. data = jf.read();
  56. } catch(JMA::jma_errors jma_error) {
  57. return false;
  58. }
  59. } break;
  60. #endif
  61. }
  62. return true;
  63. }
  64. bool Cartridge::apply_patch(const uint8_t *pdata, const unsigned psize, uint8_t *&data, unsigned &size) const {
  65. uint8_t *outdata = 0;
  66. unsigned outsize;
  67. ups patcher;
  68. ups::result result = patcher.apply(pdata, psize, data, size, outdata, outsize);
  69. bool apply = false;
  70. if(result == ups::ok) apply = true;
  71. if(snes.config.file.bypass_patch_crc32 == true) {
  72. if(result == ups::input_crc32_invalid) apply = true;
  73. if(result == ups::output_crc32_invalid) apply = true;
  74. }
  75. //if patch application was successful, replace old data, size with new data, size
  76. if(apply == true) {
  77. delete[] data;
  78. data = new uint8_t[size = outsize];
  79. memcpy(data, outdata, outsize);
  80. }
  81. if(outdata) delete[] outdata;
  82. return apply;
  83. }
  84. bool Cartridge::save_file(const char *fn, uint8 *data, unsigned size) const {
  85. file fp;
  86. if(!fp.open(fn, file::mode_write)) return false;
  87. fp.write(data, size);
  88. fp.close();
  89. return true;
  90. }
  91. #endif