Advertisement
Kitomas

2024-07-19 (7/13)

Jul 19th, 2024
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 31.47 KB | None | 0 0
  1. /******************************************************************************/
  2. /******************************************************************************/
  3. //"kw32g\src\save.cpp":
  4. #include <save.hpp>
  5. #include <player.hpp>
  6. #include <tile.hpp>
  7. #include <object.hpp>
  8.  
  9. using namespace kit;
  10.  
  11. //since this is in a code block, data will be gc'd pretty much immediately
  12. #define READ_DATA(_path, _thing_ptr, _thing_size, _err_text) { \
  13.   if(!fileio::fileExists(_path)) throw _err_text;              \
  14.   BinaryData data(_path);                                      \
  15.   if(data.getSize() != _thing_size) throw _err_text;           \
  16.   memory::copy(_thing_ptr, data.getData(), _thing_size);       }
  17.  
  18.  
  19. static const char fpath_gl_player[]        = "save/gl_player.bin";
  20. static const char fpath_gl_scene_indices[] = "save/gl_scene_indices.bin";
  21. static const char fpath_gl_scene[]         = "save/gl_scene.bin";
  22. static const char fpath_gl_objcache[]      = "save/gl_objsCache_%u.bin";
  23. static const char fpath_system_states[]    = "dat/system_states.bin";
  24.  
  25. #define FPATH_GL_PLAYER        fpath_gl_player
  26. #define FPATH_GL_SCENE_INDICES fpath_gl_scene_indices
  27. #define FPATH_GL_SCENE         fpath_gl_scene
  28. #define FPATH_GL_OBJCACHE      fpath_gl_objcache
  29. #define FPATH_SYSTEM_STATES    fpath_system_states
  30.  
  31.  
  32. #define SCENE_MIN_OFFSET (sizeof(Bitmap*) + sizeof(gl_scene.pat_mg) + sizeof(gl_scene.pat_fg))
  33. #define SCENE_MIN_SIZE   (sizeof(gl_scene) - SCENE_MIN_OFFSET)
  34. #define SCENE_MIN        PTR_OFFSET(&gl_scene, SCENE_MIN_OFFSET, Scene)
  35.  
  36.  
  37. //assumes object pointer is called "obj"
  38. #define OBJCAST_UNINIT(_type) ((_type*)obj)->init = false
  39. #define DELETE_SAVE_FILE(_path) { if(fileio::fileExists(_path)) fileio::deleteFile(_path); }
  40.  
  41.  
  42.  
  43.  
  44.  
  45. struct SystemStates {
  46.   bool fullscreen;
  47. };
  48.  
  49.  
  50.  
  51.  
  52. void saveReadSystem(){
  53.   SystemStates system_states;
  54.  
  55.   {
  56.     if(!fileio::fileExists(FPATH_SYSTEM_STATES)) return;
  57.     BinaryData data(FPATH_SYSTEM_STATES);
  58.     if(data.getSize() != sizeof(system_states))
  59.       throw "failed to read system save data";
  60.     memory::copy(&system_states, data.getData(), sizeof(system_states));
  61.   }
  62.  
  63.  
  64.   //fullscreen
  65.   system_states.fullscreen &= 1; //just in case
  66.   if(system_states.fullscreen != gl_fullscreen){
  67.     gl_fullscreen = system_states.fullscreen;
  68.     gl_win->setFullscreen(gl_fullscreen);
  69.  
  70.   }
  71.  
  72. }
  73.  
  74.  
  75.  
  76. void saveWriteSystem(){
  77.   SystemStates system_states;
  78.  
  79.   system_states.fullscreen = gl_fullscreen;
  80.  
  81.   fileio::writeToFile(FPATH_SYSTEM_STATES, &system_states, sizeof(system_states));
  82.  
  83. }
  84.  
  85.  
  86.  
  87. void saveWipeSystem(){
  88.   DELETE_SAVE_FILE(FPATH_SYSTEM_STATES);
  89.  
  90. }
  91.  
  92.  
  93.  
  94.  
  95.  
  96. static inline void uninit_object(Object* obj){
  97.   switch(obj->type){
  98.     case 1 :  OBJCAST_UNINIT(_obj_1lever         );  break;
  99.     case 2 :  OBJCAST_UNINIT(_obj_ability        );  break;
  100.     case 3 :  OBJCAST_UNINIT(_obj_ability_remover);  break;
  101.     case 4 :  OBJCAST_UNINIT(_obj_generic_sprite );  break;
  102.     case 5 :  OBJCAST_UNINIT(_obj_msgbox         );  break;
  103.     case 6 :  OBJCAST_UNINIT(_obj_save_interface );  break;
  104.     case 7 :  OBJCAST_UNINIT(_obj_teleporter     );  break;
  105.     case 8 :  OBJCAST_UNINIT(_obj_death_zone     );  break;
  106.     case 9 :  OBJCAST_UNINIT(_obj_death_ball     );  break;
  107.     default:;
  108.  
  109.   }
  110.  
  111. }
  112.  
  113.  
  114.  
  115.  
  116. //returns whether or not there is a save to load (just checks if gl_player.bin exists lol)
  117. //(make sure pointers aren't being used when loading relevant data; includes sfx)
  118. bool saveRead(){
  119.   if(!fileio::fileExists(FPATH_GL_PLAYER)) return false;
  120.   if(gl_player.dying) return false;
  121.  
  122.  
  123.   READ_DATA(FPATH_GL_PLAYER, &gl_player, sizeof(gl_player), "failed to read player save data");
  124.   gl_player.sfx_footstep = gl_sfx[1];
  125.   gl_player.sfx_jumping  = gl_sfx[2];
  126.   gl_player.sfx_landing  = gl_sfx[3];
  127.   gl_player.going_left  = false;
  128.   gl_player.going_right = false;
  129.  
  130.  
  131.   READ_DATA(FPATH_GL_SCENE_INDICES, gl_scene_indices, sizeof(gl_scene_indices),
  132.             "failed to read scene index data");
  133.  
  134.   BinaryData _scene_indices(gl_scene_indices, sizeof(gl_scene_indices));
  135.   u16* _scene_indices_ptr = (u16*)_scene_indices.getData();
  136.  
  137.   for(u32 i=1; i<(gl_scenes_len+1); ++i){
  138.     delete gl_scenes[i];
  139.     gl_scenes[i] = new SceneDescriptor(i);
  140.     swapScene(gl_scene_indices[i], _scene_indices_ptr[i]);
  141.  
  142.   }
  143.  
  144.  
  145.   READ_DATA(FPATH_GL_SCENE, SCENE_MIN, SCENE_MIN_SIZE, "failed to read current scene data");
  146.   loadScene(gl_scene.scene);
  147.  
  148.  
  149.  
  150.   //for every scene
  151.   for(u32 i=1; i<(gl_scenes_len+1); ++i){
  152.     u16 objs_len = gl_scenes[i]->objs_len;
  153.  
  154.     //if scene actually has objects in it
  155.     if(objs_len){
  156.       size_t cache_size = sizeof(Object) * objs_len;
  157.  
  158.       READ_DATA(gl_fstr->fmt(FPATH_GL_OBJCACHE, i), gl_objsCache[i], cache_size,
  159.                 gl_fstr->fmt("failed to read object cache %u", i));
  160.  
  161.       //for each object in scene, uninitialize them so their pointers refresh
  162.       Object* obj_cache = gl_objsCache[i];
  163.       for(u16 o=0; o<objs_len; ++o){ //(object cache is zero-indexed)
  164.         Object* obj = &obj_cache[o];
  165.         obj->update = gl_objCallbacks[obj->type]; //(also update the callback ptr)
  166.         uninit_object(obj);
  167.  
  168.       }
  169.  
  170.     }
  171.  
  172.   }
  173.  
  174.  
  175.  
  176.   gl_saveRead_called = true;
  177.   return true;
  178.  
  179. }
  180.  
  181.  
  182.  
  183.  
  184.  
  185. void saveWrite(){
  186.   fileio::writeToFile(FPATH_GL_PLAYER, &gl_player, sizeof(gl_player));
  187.  
  188.  
  189.   fileio::writeToFile(FPATH_GL_SCENE_INDICES, gl_scene_indices,
  190.                       sizeof(gl_scene_indices));
  191.  
  192.  
  193.   fileio::writeToFile(FPATH_GL_SCENE, SCENE_MIN, SCENE_MIN_SIZE);
  194.  
  195.  
  196.   for(u32 i=1; i<(gl_scenes_len+1); ++i){
  197.     size_t cache_size = sizeof(Object) * gl_scenes[i]->objs_len;
  198.  
  199.     if(cache_size){
  200.       fileio::writeToFile(gl_fstr->fmt(FPATH_GL_OBJCACHE, i),
  201.                           gl_objsCache[i], cache_size);
  202.  
  203.     }
  204.  
  205.   }
  206.  
  207. }
  208.  
  209.  
  210.  
  211.  
  212.  
  213. void saveWipe(){
  214.   DELETE_SAVE_FILE(FPATH_GL_PLAYER);
  215.  
  216.  
  217.   DELETE_SAVE_FILE(FPATH_GL_SCENE_INDICES);
  218.  
  219.  
  220.   DELETE_SAVE_FILE(FPATH_GL_SCENE);
  221.  
  222.  
  223.   char* fstr_ptr = gl_fstr->ptr(); //valid for as long as gl_fstr exists
  224.  
  225.   for(u32 i=1; i<(gl_scenes_len+1); ++i){
  226.     gl_fstr->fmt(FPATH_GL_OBJCACHE, i);
  227.     DELETE_SAVE_FILE(fstr_ptr);
  228.  
  229.   }
  230.  
  231. }
  232. /******************************************************************************/
  233. /******************************************************************************/
  234. //"kw32g\src\tile.cpp":
  235. #include <tile.hpp>
  236. #include <object.hpp>
  237.  
  238. using namespace kit;
  239.  
  240.  
  241.  
  242.  
  243.  
  244. void Scene::drawBg(){
  245.   //don't draw background at all if scene = 0
  246.   if(!scene) return;
  247.   //if background is nullptr, use the 'missing tileset' bitmap instead
  248.    //(since an error would occur during init if the background is invalid,
  249.    // it should be impossible for bmp_bg to be nullptr in the first place)
  250.   if(bmp_bg == nullptr){ gl_tileset_missing->blitRect(nullptr, nullptr); return; }
  251.   shape::point sizeBmp = bmp_bg->getSize();
  252.   if(sizeBmp.x<1 || sizeBmp.y<1) return;
  253.  
  254.  
  255.   if(!repeat_bg){ //stretch entire background to entire canvas
  256.     bmp_bg->blitRect();
  257.  
  258.  
  259.   } else { //otherwise, repeat background bitmap in a tile pattern
  260.     shape::rect dst; //destination rectangle
  261.     dst.w = sizeBmp.x;
  262.     dst.h = sizeBmp.y;
  263.  
  264.     shape::point sizeCanvas = gl_win->getCanvasSize();
  265.  
  266.     //increase x, then y until the entire canvas is drawn to
  267.     for(dst.y = 0;  dst.y < sizeCanvas.y;  dst.y += dst.h)
  268.     for(dst.x = 0;  dst.x < sizeCanvas.x;  dst.x += dst.w)
  269.     {
  270.       bmp_bg->blitRect(&dst, nullptr); //whole bitmap is used when src = nullptr
  271.     }
  272.  
  273.  
  274.   }
  275.  
  276. }
  277.  
  278.  
  279.  
  280.  
  281.  
  282. //note: if slowdown gets to a point where it's noticable,
  283.  //implement a scene pattern cache
  284.  //(as in, bake the 2 layers as bitmaps when loading a new
  285.  // scene, before blitting those bitmaps every draw call)
  286. void Scene::drawTiles(bool drawForeground){
  287.   if(!scene) return; //don't draw any tiles for scene 0
  288.   Tile*              tiles = pat_mg;
  289.   if(drawForeground) tiles = pat_fg;
  290.  
  291.   if(tileset_a > gl_tilesets_len  ||  tileset_b > gl_tilesets_len)
  292.     throw "tileset index is out of bounds";
  293.  
  294.   Bitmap* tileset[2];
  295.   tileset[0] = gl_tilesets[tileset_a];
  296.   tileset[1] = gl_tilesets[tileset_b];
  297.  
  298.   shape::rect src(0, 0, 24, 24); //determines section of tileset to copy from
  299.   shape::rect dst(0, 0, 24, 24); //determines section of canvas to paste to
  300.  
  301.   shape::point sizeCanvas = gl_win->getCanvasSize();
  302.  
  303.  
  304.  
  305.   //for accessing each tile independent of the 2 for loops
  306.   u32 tileindex = -1; //(set to -1 so i can use preincrement while indexing)
  307.  
  308.   //increase x, then y until the entire canvas is drawn to
  309.   for(dst.y = 0;  dst.y < sizeCanvas.y;  dst.y += dst.h)
  310.   for(dst.x = 0;  dst.x < sizeCanvas.x;  dst.x += dst.w)
  311.   {
  312.     Tile tile = tiles[++tileindex];
  313.     if(!tile.id) continue; //tile 0 is always transparent, so it can be skipped
  314.     src.x = ( tile.id    &0b1111) * src.w; //bits 0-3 are the tileset atlas' x
  315.     src.y = ((tile.id>>4)& 0b111) * src.h; //bits 4-6 are the tileset atlas' y
  316.  
  317.  
  318.     Bitmap* _tileset = tileset[tile.tileset]; //(tile.tileset is 1 bit in size)
  319.     if(_tileset != nullptr){
  320.       _tileset->blitRect(&dst, &src, 0xff00ff); //transparency color is magenta
  321.  
  322.     } else { //tileset doesn't exist; draw 'missing tileset' tile
  323.       gl_tileset_missing->blitRect(&dst, nullptr); //transparency is not used
  324.  
  325.     }
  326.  
  327.   }
  328.  
  329. }
  330.  
  331.  
  332.  
  333.  
  334.  
  335. //(also used by both SceneDescriptor's constructor and destructor!)
  336. void SceneDescriptor::unload(){
  337.   if(fileData == nullptr) return;
  338.  
  339.   BinaryData* _fileData = fileData;
  340.   fileData = nullptr;
  341.   delete _fileData;
  342. }
  343.  
  344.  
  345.  
  346.  
  347.  
  348. #define etThrow(_text, _label) { errorText = _text; goto _label; }
  349. #define dfdThrow(_text) etThrow(_text, _DelFD)
  350. SceneDescriptor::SceneDescriptor(u16 scene_id){
  351.   const char* errorText = "(no error)";
  352.   if(0){ //entered into in the event of an exception
  353.     _DelFD: NULLDELETE(fileData);
  354.     throw errorText;
  355.   }
  356.  
  357.  
  358.  
  359.   if(scene_id > gl_scenes_len)
  360.     throw "scene_id > gl_scenes_len";
  361.  
  362.   unload(); //clean up any previous data, if any exists
  363.  
  364.   if(!fileio::fileExists(gl_fstr->fmt("dat/scene/scene_%u.ksd", scene_id)))
  365.     dfdThrow((const char*)gl_fstr->fmt("\"dat/scene/scene_%u.ksd\" doesn't exist", scene_id));
  366.  
  367.   fileData = new BinaryData(gl_fstr->ptr());
  368.   char* _fileData = fileData->getData();
  369.   size_t fileSize = fileData->getSize();
  370.  
  371.  
  372.  
  373.   //handle header data (-sizeof(BinaryData*) used here as to not overwrite fileData!)
  374.   memory::copy(this, _fileData, sizeof(SceneDescriptor)-sizeof(BinaryData*));
  375.   char* data_end = PTR_OFFSET(_fileData, fileSize, char);
  376.   char* objs_end = PTR_OFFSET(data_end, -(s64)sizeof(Object), char);
  377.   char*  pat_end = PTR_OFFSET(data_end, -(s64)sizeof(Tile)*2, char); //*2 for rle data + tile
  378.  
  379.  
  380.  
  381.   if(magic != KSD_MAGIC)
  382.     dfdThrow("file is not a scene descriptor");
  383.   if(dataSize != (fileSize-sizeof(SceneDescriptor)))
  384.     dfdThrow("data size is inconsistent with actual file size");
  385.  
  386.  
  387.   //convert file offsets to their actual pointer value (only if offset != 0)
  388.   if(objs  ) objs   = PTR_OFFSET(_fileData, objs, Object); //(these will remain
  389.   if(pat_mg) pat_mg = PTR_OFFSET(_fileData, pat_mg, Tile);  //as nullptr if they
  390.   if(pat_fg) pat_fg = PTR_OFFSET(_fileData, pat_fg, Tile);  //were already)
  391.   if(((char*)objs  ) > objs_end) dfdThrow("objs goes past file data");
  392.   if(((char*)pat_mg) >  pat_end) dfdThrow("pat_mg goes past file data");
  393.   if(((char*)pat_fg) >  pat_end) dfdThrow("pat_fg goes past file data");
  394.  
  395.  
  396.   if(bmp_bg > gl_backgrounds_len)
  397.     dfdThrow("bmp_bg is out of range");
  398.  
  399.  
  400.   if( (objs == nullptr)  !=  (objs_len == 0) )
  401.     dfdThrow("objs_len is inconsistent with obj file offset");
  402.  
  403.   //set objs' funcUpdate based on its type id
  404.   for(u32 i=0; i<objs_len; ++i){ //(loop will not run at all if objs_len is 0)
  405.     //objects of type 0 are technically allowed,
  406.      //but they just don't do anything (lol)
  407.     if(objs[i].type > gl_objCallbacks_len) dfdThrow("invalid object type");
  408.     objs[i].update = gl_objCallbacks[objs[i].type];
  409.     if(objs[i].update == nullptr) dfdThrow("object callback was null");
  410.  
  411.   }
  412.  
  413.  
  414.   if(tileset_a > gl_tilesets_len) dfdThrow("tileset_a out of range");
  415.   if(tileset_b > gl_tilesets_len) dfdThrow("tileset_b out of range");
  416.  
  417.  
  418.   if(edge_n > gl_scenes_len) dfdThrow("edge_n out of range");
  419.   if(edge_s > gl_scenes_len) dfdThrow("edge_s out of range");
  420.   if(edge_w > gl_scenes_len) dfdThrow("edge_w out of range");
  421.   if(edge_e > gl_scenes_len) dfdThrow("edge_e out of range");
  422.   if(scene != scene_id     ) dfdThrow("scene id in file inconsistent with actual id");
  423.  
  424.   if(music      != 0xFFFF  &&  music      > gl_music_len   ) dfdThrow("music out of range");
  425.   if(ambience_a != 0xFFFF  &&  ambience_a > gl_ambience_len) dfdThrow("ambience_a out of range");
  426.   if(ambience_b != 0xFFFF  &&  ambience_b > gl_ambience_len) dfdThrow("ambience_b out of range");
  427.  
  428. }
  429.  
  430.  
  431.  
  432.  
  433.  
  434. void loadScene(u16 scene_id){
  435.   if(!scene_id) return; //0 is a special case for most, if not all asset arrays
  436.   if(scene_id > gl_scenes_len) throw "scene_id > gl_scenes_len";
  437.   if(gl_scenes[scene_id] == nullptr) throw "gl_scenes[scene_id] = nullptr";
  438.  
  439.   //(former bug: sceneNew used to be a stack object set to *gl_scenes[scene_id],
  440.    //but doing so causes its destructor to trigger, making .fileData invalid,
  441.    //which breaks things during the program's uninitialization phase.)
  442.   SceneDescriptor* sceneNew = gl_scenes[scene_id];
  443.  
  444.  
  445. //gl_scene.bmp_bg   = gl_backgrounds[sceneNew->bmp_bg]; //handled later
  446.  
  447.   gl_scene.scene      = sceneNew->scene;
  448.  
  449.   gl_scene.music      = sceneNew->music;
  450.   gl_scene.ambience_a = sceneNew->ambience_a;
  451.   gl_scene.ambience_b = sceneNew->ambience_b;
  452.  
  453.   gl_scene.tileset_a  = sceneNew->tileset_a;
  454.   gl_scene.tileset_b  = sceneNew->tileset_b;
  455. //gl_scene.obj_reset  = 3; //this is handled separately
  456.   gl_scene.repeat_bg  = sceneNew->repeat_bg;
  457.  
  458.  
  459.  
  460.   struct rle_data {
  461.     u16   run;
  462.     Tile tile;
  463.     rle_data() : run(0), tile(0) {}
  464.   };
  465.  
  466.   char*  file_start = sceneNew->fileData->getData();
  467.   size_t file_size  = sceneNew->fileData->getSize();
  468.   char*  data_start = PTR_OFFSET(file_start, sizeof(SceneDescriptor), char);
  469.   char*  data_end   = PTR_OFFSET(file_start, file_size,               char);
  470.  
  471.  
  472.  
  473.   //copy bg and tile data to the scene
  474.   if(sceneNew->fileData == nullptr) return;
  475.  
  476.   gl_scene.bmp_bg = nullptr;
  477.   if(sceneNew->bmp_bg <= gl_backgrounds_len)
  478.     gl_scene.bmp_bg = gl_backgrounds[sceneNew->bmp_bg];
  479.  
  480.   rle_data  tile_mg, tile_fg;
  481.   rle_data* rle_mg   = (rle_data*)sceneNew->pat_mg;
  482.   rle_data* rle_fg   = (rle_data*)sceneNew->pat_fg;
  483.   #define   rle_end    ((rle_data*)data_end)
  484.   rle_data* rle_last = PTR_OFFSET(rle_end, -(s64)sizeof(rle_data), rle_data);
  485.   //^^data_last is the location of the last element of the rle
  486.  
  487.  
  488.   if(rle_mg != nullptr){
  489.     for(u32 i=0; i<PATTERN_LEN; ++i){
  490.       if(tile_mg.run == 0){
  491.         if(rle_mg == rle_end) break;
  492.         if(rle_mg > rle_last) throw "rle_mg went past file data";
  493.         tile_mg = *(rle_mg++);
  494.       }
  495.       gl_scene.pat_mg[i] = tile_mg.tile;
  496.       --tile_mg.run;
  497.  
  498.     }
  499.  
  500.   } else {
  501.     memset0(gl_scene.pat_mg);
  502.  
  503.   }
  504.  
  505.  
  506.   if(rle_fg != nullptr){
  507.     for(u32 i=0; i<PATTERN_LEN; ++i){
  508.       if(tile_fg.run == 0){
  509.         if(rle_fg == rle_end) break;
  510.         if(rle_fg > rle_last) throw "rle_fg went past file data";
  511.         tile_fg = *(rle_fg++);
  512.       }
  513.       gl_scene.pat_fg[i] = tile_fg.tile;
  514.       --tile_fg.run;
  515.  
  516.     }
  517.  
  518.   } else {
  519.     memset0(gl_scene.pat_fg);
  520.  
  521.   }
  522.  
  523. }
  524.  
  525.  
  526.  
  527.  
  528.  
  529. void swapScene(u16 scene_id_old, u16 scene_id_new){
  530.   if(!scene_id_old || !scene_id_new) return;
  531.   if(scene_id_old > gl_scenes_len) throw "scene_id_old > gl_scenes_len";
  532.   if(scene_id_new > gl_scenes_len) throw "scene_id_new > gl_scenes_len";
  533.   if(gl_scenes[scene_id_old] == nullptr) throw "gl_scenes[scene_id_old] = nullptr";
  534.   if(gl_scenes[scene_id_new] == nullptr) throw "gl_scenes[scene_id_new] = nullptr";
  535.  
  536.   SceneDescriptor* scene_old = gl_scenes[scene_id_old];
  537.   SceneDescriptor* scene_new = gl_scenes[scene_id_new];
  538.  
  539.  
  540.   //swap object information to prevent scene identity mismatches
  541.    //(as in, scene 1's objects should always refer to the obj cache at index 1 )
  542.   Object* objs_old = scene_old->objs;
  543.   Object* objs_new = scene_new->objs;
  544.   u16 objs_len_old = scene_old->objs_len;
  545.   u16 objs_len_new = scene_new->objs_len;
  546.  
  547.   scene_old->objs     = objs_new;
  548.   scene_new->objs     = objs_old;
  549.   scene_old->objs_len = objs_len_new;
  550.   scene_new->objs_len = objs_len_old;
  551.  
  552.  
  553.   //swap the scene ids
  554.   scene_old->scene               = scene_id_new;
  555.   scene_new->scene               = scene_id_old;
  556.   gl_scene_indices[scene_id_old] = scene_id_new;
  557.   gl_scene_indices[scene_id_new] = scene_id_old;
  558.  
  559.   //swap the scene pointers
  560.   gl_scenes[scene_id_old] = scene_new;
  561.   gl_scenes[scene_id_new] = scene_old;
  562.  
  563.  
  564.   //if current scene is being swapped, load the new scene
  565.   if(gl_scene.scene == scene_id_old) loadScene(gl_scene.scene);
  566. }
  567. /******************************************************************************/
  568. /******************************************************************************/
  569. //"kit_xmp_sfx\src\kit_xmp_sfx\kit_qoa.h":
  570. /*
  571.  
  572. Copyright (c) 2023, Dominic Szablewski - https://phoboslab.org
  573. SPDX-License-Identifier: MIT
  574.  
  575. QOA - The "Quite OK Audio" format for fast, lossy audio compression
  576.  
  577. */
  578.  
  579.  
  580.  
  581. /* -----------------------------------------------------------------------------
  582.     Header - Public functions */
  583.  
  584. #ifndef QOA_H
  585. #define QOA_H
  586.  
  587. #ifdef __cplusplus
  588. extern "C" {
  589. #endif
  590.  
  591. #define QOA_MIN_FILESIZE 16
  592. #define QOA_MAX_CHANNELS 8
  593.  
  594. #define QOA_SLICE_LEN 20
  595. #define QOA_SLICES_PER_FRAME 256
  596. #define QOA_FRAME_LEN (QOA_SLICES_PER_FRAME * QOA_SLICE_LEN)
  597. #define QOA_LMS_LEN 4
  598. #define QOA_MAGIC 0x716f6166 /* 'qoaf' */
  599.  
  600. #define QOA_FRAME_SIZE(channels, slices) \
  601.     (8 + QOA_LMS_LEN * 4 * channels + 8 * slices * channels)
  602.  
  603. typedef struct {
  604.     s32 history[QOA_LMS_LEN];
  605.     s32 weights[QOA_LMS_LEN];
  606. } qoa_lms_t;
  607.  
  608. typedef struct {
  609.     u32 channels;
  610.     u32 samplerate;
  611.     u32 samples;
  612.     qoa_lms_t lms[QOA_MAX_CHANNELS];
  613.     #ifdef QOA_RECORD_TOTAL_ERROR
  614.         f64 error;
  615.     #endif
  616. } qoa_desc;
  617.  
  618. u32 qoa_max_frame_size(qoa_desc *qoa);
  619. u32 qoa_decode_header(const u8* bytes, s32 size, qoa_desc* qoa);
  620. u32 qoa_decode_frame(const u8* bytes, u32 size, qoa_desc* qoa, s16* sample_data, u32* frame_len);
  621. s16* qoa_decode(const u8* bytes, s32 size, qoa_desc *file);
  622.  
  623.  
  624. #ifdef __cplusplus
  625. }
  626. #endif
  627. #endif /* QOA_H */
  628.  
  629.  
  630. /* -----------------------------------------------------------------------------
  631.     Implementation */
  632.  
  633. #ifdef QOA_IMPLEMENTATION
  634.  
  635. #ifndef QOA_MALLOC
  636.     #define QOA_MALLOC(sz) memory::alloc(sz);
  637.     #define QOA_FREE(p) memory::free(&(p));
  638. #endif
  639.  
  640. typedef unsigned long long qoa_uint64_t;
  641.  
  642.  
  643. /* The quant_tab provides an index into the dequant_tab for residuals in the
  644. range of -8 .. 8. It maps this range to just 3bits and becomes less accurate at
  645. the higher end. Note that the residual zero is identical to the lowest positive
  646. value. This is mostly fine, since the qoa_div() function always rounds away
  647. from zero. */
  648.  
  649. static const int qoa_quant_tab[17] = {
  650.     7, 7, 7, 5, 5, 3, 3, 1, /* -8..-1 */
  651.     0,                      /*  0     */
  652.     0, 2, 2, 4, 4, 6, 6, 6  /*  1.. 8 */
  653. };
  654.  
  655.  
  656. /* We have 16 different scalefactors. Like the quantized residuals these become
  657. less accurate at the higher end. In theory, the highest scalefactor that we
  658. would need to encode the highest 16bit residual is (2**16)/8 = 8192. However we
  659. rely on the LMS filter to predict samples accurately enough that a maximum
  660. residual of one quarter of the 16 bit range is sufficient. I.e. with the
  661. scalefactor 2048 times the quant range of 8 we can encode residuals up to 2**14.
  662.  
  663. The scalefactor values are computed as:
  664. scalefactor_tab[s] <- round(pow(s + 1, 2.75)) */
  665.  
  666. static const int qoa_scalefactor_tab[16] = {
  667.     1, 7, 21, 45, 84, 138, 211, 304, 421, 562, 731, 928, 1157, 1419, 1715, 2048
  668. };
  669.  
  670.  
  671. /* The reciprocal_tab maps each of the 16 scalefactors to their rounded
  672. reciprocals 1/scalefactor. This allows us to calculate the scaled residuals in
  673. the encoder with just one multiplication instead of an expensive division. We
  674. do this in .16 fixed point with integers, instead of floats.
  675.  
  676. The reciprocal_tab is computed as:
  677. reciprocal_tab[s] <- ((1<<16) + scalefactor_tab[s] - 1) / scalefactor_tab[s] */
  678.  
  679. static const int qoa_reciprocal_tab[16] = {
  680.     65536, 9363, 3121, 1457, 781, 475, 311, 216, 156, 117, 90, 71, 57, 47, 39, 32
  681. };
  682.  
  683.  
  684. /* The dequant_tab maps each of the scalefactors and quantized residuals to
  685. their unscaled & dequantized version.
  686.  
  687. Since qoa_div rounds away from the zero, the smallest entries are mapped to 3/4
  688. instead of 1. The dequant_tab assumes the following dequantized values for each
  689. of the quant_tab indices and is computed as:
  690. float dqt[8] = {0.75, -0.75, 2.5, -2.5, 4.5, -4.5, 7, -7};
  691. dequant_tab[s][q] <- round_ties_away_from_zero(scalefactor_tab[s] * dqt[q])
  692.  
  693. The rounding employed here is "to nearest, ties away from zero",  i.e. positive
  694. and negative values are treated symmetrically.
  695. */
  696.  
  697. static const int qoa_dequant_tab[16][8] = {
  698.     {   1,    -1,    3,    -3,    5,    -5,     7,     -7},
  699.     {   5,    -5,   18,   -18,   32,   -32,    49,    -49},
  700.     {  16,   -16,   53,   -53,   95,   -95,   147,   -147},
  701.     {  34,   -34,  113,  -113,  203,  -203,   315,   -315},
  702.     {  63,   -63,  210,  -210,  378,  -378,   588,   -588},
  703.     { 104,  -104,  345,  -345,  621,  -621,   966,   -966},
  704.     { 158,  -158,  528,  -528,  950,  -950,  1477,  -1477},
  705.     { 228,  -228,  760,  -760, 1368, -1368,  2128,  -2128},
  706.     { 316,  -316, 1053, -1053, 1895, -1895,  2947,  -2947},
  707.     { 422,  -422, 1405, -1405, 2529, -2529,  3934,  -3934},
  708.     { 548,  -548, 1828, -1828, 3290, -3290,  5117,  -5117},
  709.     { 696,  -696, 2320, -2320, 4176, -4176,  6496,  -6496},
  710.     { 868,  -868, 2893, -2893, 5207, -5207,  8099,  -8099},
  711.     {1064, -1064, 3548, -3548, 6386, -6386,  9933,  -9933},
  712.     {1286, -1286, 4288, -4288, 7718, -7718, 12005, -12005},
  713.     {1536, -1536, 5120, -5120, 9216, -9216, 14336, -14336},
  714. };
  715.  
  716.  
  717. /* The Least Mean Squares Filter is the heart of QOA. It predicts the next
  718. sample based on the previous 4 reconstructed samples. It does so by continuously
  719. adjusting 4 weights based on the residual of the previous prediction.
  720.  
  721. The next sample is predicted as the sum of (weight[i] * history[i]).
  722.  
  723. The adjustment of the weights is done with a "Sign-Sign-LMS" that adds or
  724. subtracts the residual to each weight, based on the corresponding sample from
  725. the history. This, surprisingly, is sufficient to get worthwhile predictions.
  726.  
  727. This is all done with fixed point integers. Hence the right-shifts when updating
  728. the weights and calculating the prediction. */
  729.  
  730. static int qoa_lms_predict(qoa_lms_t *lms) {
  731.     int prediction = 0;
  732.     for (int i = 0; i < QOA_LMS_LEN; i++) {
  733.         prediction += lms->weights[i] * lms->history[i];
  734.     }
  735.     return prediction >> 13;
  736. }
  737.  
  738. static void qoa_lms_update(qoa_lms_t *lms, int sample, int residual) {
  739.     int delta = residual >> 4;
  740.     for (int i = 0; i < QOA_LMS_LEN; i++) {
  741.         lms->weights[i] += lms->history[i] < 0 ? -delta : delta;
  742.     }
  743.  
  744.     for (int i = 0; i < QOA_LMS_LEN-1; i++) {
  745.         lms->history[i] = lms->history[i+1];
  746.     }
  747.     lms->history[QOA_LMS_LEN-1] = sample;
  748. }
  749.  
  750.  
  751. /* qoa_div() implements a rounding division, but avoids rounding to zero for
  752. small numbers. E.g. 0.1 will be rounded to 1. Note that 0 itself still
  753. returns as 0, which is handled in the qoa_quant_tab[].
  754. qoa_div() takes an index into the .16 fixed point qoa_reciprocal_tab as an
  755. argument, so it can do the division with a cheaper integer multiplication. */
  756.  
  757. static inline int qoa_div(int v, int scalefactor) {
  758.     int reciprocal = qoa_reciprocal_tab[scalefactor];
  759.     int n = (v * reciprocal + (1 << 15)) >> 16;
  760.     n = n + ((v > 0) - (v < 0)) - ((n > 0) - (n < 0)); /* round away from 0 */
  761.     return n;
  762. }
  763.  
  764. static inline int qoa_clamp(int v, int min, int max) {
  765.     if (v < min) { return min; }
  766.     if (v > max) { return max; }
  767.     return v;
  768. }
  769.  
  770. /* This specialized clamp function for the signed 16 bit range improves decode
  771. performance quite a bit. The extra if() statement works nicely with the CPUs
  772. branch prediction as this branch is rarely taken. */
  773.  
  774. static inline int qoa_clamp_s16(int v) {
  775.     if ((unsigned int)(v + 32768) > 65535) {
  776.         if (v < -32768) { return -32768; }
  777.         if (v >  32767) { return  32767; }
  778.     }
  779.     return v;
  780. }
  781.  
  782. static inline qoa_uint64_t qoa_read_u64(const unsigned char *bytes, unsigned int *p) {
  783.     bytes += *p;
  784.     *p += 8;
  785.     return
  786.         ((qoa_uint64_t)(bytes[0]) << 56) | ((qoa_uint64_t)(bytes[1]) << 48) |
  787.         ((qoa_uint64_t)(bytes[2]) << 40) | ((qoa_uint64_t)(bytes[3]) << 32) |
  788.         ((qoa_uint64_t)(bytes[4]) << 24) | ((qoa_uint64_t)(bytes[5]) << 16) |
  789.         ((qoa_uint64_t)(bytes[6]) <<  8) | ((qoa_uint64_t)(bytes[7]) <<  0);
  790. }
  791.  
  792. static inline void qoa_write_u64(qoa_uint64_t v, unsigned char *bytes, unsigned int *p) {
  793.     bytes += *p;
  794.     *p += 8;
  795.     bytes[0] = (v >> 56) & 0xff;
  796.     bytes[1] = (v >> 48) & 0xff;
  797.     bytes[2] = (v >> 40) & 0xff;
  798.     bytes[3] = (v >> 32) & 0xff;
  799.     bytes[4] = (v >> 24) & 0xff;
  800.     bytes[5] = (v >> 16) & 0xff;
  801.     bytes[6] = (v >>  8) & 0xff;
  802.     bytes[7] = (v >>  0) & 0xff;
  803. }
  804.  
  805.  
  806. /* -----------------------------------------------------------------------------
  807.     Decoder */
  808.  
  809. unsigned int qoa_max_frame_size(qoa_desc *qoa) {
  810.     return QOA_FRAME_SIZE(qoa->channels, QOA_SLICES_PER_FRAME);
  811. }
  812.  
  813. unsigned int qoa_decode_header(const unsigned char *bytes, int size, qoa_desc *qoa) {
  814.     unsigned int p = 0;
  815.     if (size < QOA_MIN_FILESIZE) {
  816.         return 0;
  817.     }
  818.  
  819.  
  820.     /* Read the file header, verify the magic number ('qoaf') and read the
  821.     total number of samples. */
  822.     qoa_uint64_t file_header = qoa_read_u64(bytes, &p);
  823.  
  824.     if ((file_header >> 32) != QOA_MAGIC) {
  825.         return 0;
  826.     }
  827.  
  828.     qoa->samples = file_header & 0xffffffff;
  829.     if (!qoa->samples) {
  830.         return 0;
  831.     }
  832.  
  833.     /* Peek into the first frame header to get the number of channels and
  834.     the samplerate. */
  835.     qoa_uint64_t frame_header = qoa_read_u64(bytes, &p);
  836.     qoa->channels   = (frame_header >> 56) & 0x0000ff;
  837.     qoa->samplerate = (frame_header >> 32) & 0xffffff;
  838.  
  839.     if (qoa->channels == 0 || qoa->samples == 0 || qoa->samplerate == 0) {
  840.         return 0;
  841.     }
  842.  
  843.     return 8;
  844. }
  845.  
  846. unsigned int qoa_decode_frame(const unsigned char *bytes, unsigned int size, qoa_desc *qoa, short *sample_data, unsigned int *frame_len) {
  847.     unsigned int p = 0;
  848.     *frame_len = 0;
  849.  
  850.     if (size < 8 + QOA_LMS_LEN * 4 * qoa->channels) {
  851.         return 0;
  852.     }
  853.  
  854.     /* Read and verify the frame header */
  855.     qoa_uint64_t frame_header = qoa_read_u64(bytes, &p);
  856.     int channels   = (frame_header >> 56) & 0x0000ff;
  857.     int samplerate = (frame_header >> 32) & 0xffffff;
  858.     int samples    = (frame_header >> 16) & 0x00ffff;
  859.     u32 frame_size = (frame_header      ) & 0x00ffff;
  860.  
  861.     int data_size = frame_size - 8 - QOA_LMS_LEN * 4 * channels;
  862.     int num_slices = data_size / 8;
  863.     int max_total_samples = num_slices * QOA_SLICE_LEN;
  864.  
  865.     if (
  866.         channels != qoa->channels ||
  867.         samplerate != qoa->samplerate ||
  868.         frame_size > size ||
  869.         samples * channels > max_total_samples
  870.     ) {
  871.         return 0;
  872.     }
  873.  
  874.  
  875.     /* Read the LMS state: 4 x 2 bytes history, 4 x 2 bytes weights per channel */
  876.     for (int c = 0; c < channels; c++) {
  877.         qoa_uint64_t history = qoa_read_u64(bytes, &p);
  878.         qoa_uint64_t weights = qoa_read_u64(bytes, &p);
  879.         for (int i = 0; i < QOA_LMS_LEN; i++) {
  880.             qoa->lms[c].history[i] = ((signed short)(history >> 48));
  881.             history <<= 16;
  882.             qoa->lms[c].weights[i] = ((signed short)(weights >> 48));
  883.             weights <<= 16;
  884.         }
  885.     }
  886.  
  887.  
  888.     /* Decode all slices for all channels in this frame */
  889.     for (int sample_index = 0; sample_index < samples; sample_index += QOA_SLICE_LEN) {
  890.         for (int c = 0; c < channels; c++) {
  891.             qoa_uint64_t slice = qoa_read_u64(bytes, &p);
  892.  
  893.             int scalefactor = (slice >> 60) & 0xf;
  894.             int slice_start = sample_index * channels + c;
  895.             int slice_end = qoa_clamp(sample_index + QOA_SLICE_LEN, 0, samples) * channels + c;
  896.  
  897.             for (int si = slice_start; si < slice_end; si += channels) {
  898.                 int predicted = qoa_lms_predict(&qoa->lms[c]);
  899.                 int quantized = (slice >> 57) & 0x7;
  900.                 int dequantized = qoa_dequant_tab[scalefactor][quantized];
  901.                 int reconstructed = qoa_clamp_s16(predicted + dequantized);
  902.  
  903.                 sample_data[si] = reconstructed;
  904.                 slice <<= 3;
  905.  
  906.                 qoa_lms_update(&qoa->lms[c], reconstructed, dequantized);
  907.             }
  908.         }
  909.     }
  910.  
  911.     *frame_len = samples;
  912.     return p;
  913. }
  914.  
  915. short *qoa_decode(const unsigned char *bytes, int size, qoa_desc *qoa) {
  916.     unsigned int p = qoa_decode_header(bytes, size, qoa);
  917.     if (!p) {
  918.         return NULL;
  919.     }
  920.  
  921.     /* Calculate the required size of the sample buffer and allocate */
  922.     int total_samples = qoa->samples * qoa->channels;
  923.     short *sample_data = (s16*)QOA_MALLOC(total_samples * sizeof(short));
  924.  
  925.     unsigned int sample_index = 0;
  926.     unsigned int frame_len;
  927.     unsigned int frame_size;
  928.  
  929.     /* Decode all frames */
  930.     do {
  931.         short *sample_ptr = sample_data + sample_index * qoa->channels;
  932.         frame_size = qoa_decode_frame(bytes + p, size - p, qoa, sample_ptr, &frame_len);
  933.  
  934.         p += frame_size;
  935.         sample_index += frame_len;
  936.     } while (frame_size && sample_index < qoa->samples);
  937.  
  938.     qoa->samples = sample_index;
  939.     return sample_data;
  940. }
  941.  
  942. #endif /* QOA_IMPLEMENTATION */
  943. /******************************************************************************/
  944. /******************************************************************************/
  945. //"kit_w32\include\kit\all.hpp":
  946. #ifndef _KIT_INC_ALL_HPP
  947. #define _KIT_INC_ALL_HPP
  948.  
  949. #include "commondef.hpp"
  950. #include "misc.hpp"
  951. #include "video.hpp"
  952. #include "audio.hpp"
  953.  
  954.  
  955. #endif /* _KIT_INC_ALL_HPP */
  956. /******************************************************************************/
  957. /******************************************************************************/
  958. //"kit_w32\include\kit\audio.hpp":
  959. #ifndef _KIT_INC_AUDIO_HPP
  960. #define _KIT_INC_AUDIO_HPP
  961.  
  962. #include "commondef.hpp"
  963. #include "misc.hpp"
  964. #include "_audio_AudioStream.hpp"
  965. #include "_audio_func.hpp"
  966.  
  967.  
  968. #endif /* _KIT_INC_AUDIO_HPP */
  969. /******************************************************************************/
  970. /******************************************************************************/
  971. //"kit_w32\include\kit\commondef.hpp":
  972. #ifndef _KIT_INC_COMMONDEF_HPP
  973. #define _KIT_INC_COMMONDEF_HPP
  974.  
  975. namespace kit {
  976.  
  977.  
  978.  
  979.  
  980. #ifndef   MIN
  981. #define   MIN(a,b) ( ((a)<(b)) ? (a) : (b) )
  982. #endif /* MIN(a,b) */
  983.  
  984. #ifndef   MAX
  985. #define   MAX(a,b) ( ((a)>(b)) ? (a) : (b) )
  986. #endif /* MAX(a,b) */
  987.  
  988. #ifndef   CLAMP
  989. #define   CLAMP(n, mn, mx) MIN(MAX(n,mn),mx)
  990. #endif /* CLAMP(n, mn, mx) */
  991.  
  992.  
  993.  
  994. // integer bounds
  995. #define KIT_U8_MAX  (0xFF)
  996. #define KIT_U16_MAX (0xFFFF)
  997. #define KIT_U32_MAX (0xFFFFFFFF)
  998. #define KIT_U64_MAX (0xFFFFFFFFFFFFFFFF)
  999.  //
  1000. #define KIT_S8_MIN  (0x80)
  1001. #define KIT_S8_MAX  (0x7F)
  1002. #define KIT_S16_MIN (0x8000)
  1003. #define KIT_S16_MAX (0x7FFF)
  1004. #define KIT_S32_MIN (0x80000000)
  1005. #define KIT_S32_MAX (0x7FFFFFFF)
  1006. #define KIT_S64_MIN (0x8000000000000000)
  1007. #define KIT_S64_MAX (0x7FFFFFFFFFFFFFFF)
  1008.  
  1009.  
  1010. // most significant bits/Bytes
  1011. #define KIT_MSb_8  (0x80)
  1012. #define KIT_MSb_16 (0x8000)
  1013. #define KIT_MSb_32 (0x80000000)
  1014. #define KIT_MSb_64 (0x8000000000000000)
  1015.  //
  1016. #define KIT_MSB_8  (0xFF)
  1017. #define KIT_MSB_16 (0xFF00)
  1018. #define KIT_MSB_32 (0xFF000000)
  1019. #define KIT_MSB_64 (0xFF00000000000000)
  1020.  
  1021.  
  1022.  
  1023.  
  1024. #if defined(_STDINT) || defined(_CSTDINT_)
  1025. typedef uint8_t  u8 ;
  1026. typedef uint16_t u16;
  1027. typedef uint32_t u32;
  1028. typedef uint64_t u64;
  1029. typedef int8_t  s8 ;
  1030. typedef int16_t s16;
  1031. typedef int32_t s32;
  1032. typedef int64_t s64;
  1033.  
  1034. #else
  1035. typedef unsigned char      u8 ;
  1036. typedef unsigned short     u16;
  1037. typedef unsigned int       u32;
  1038. typedef unsigned long long u64;
  1039. typedef signed char      s8 ;
  1040. typedef signed short     s16;
  1041. typedef signed int       s32;
  1042. typedef signed long long s64;
  1043.  
  1044. #endif
  1045.  
  1046. // for consistency
  1047. typedef float  f32;
  1048. typedef double f64;
  1049.  
  1050.  
  1051.  
  1052. typedef void* _GenericOpaquePtr;
  1053.  
  1054.  
  1055.  
  1056. };
  1057.  
  1058. #endif /* _KIT_INC_COMMONDEF_HPP */
  1059.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement