z_mirror/sdl-osu
git clone https://git.raiguard.me/z_mirror/sdl-osu
836a89c
trunk
1#include "beatmap.h" 2#include "beatmapreader.h" 3#include "util.h" 4#include <libgen.h> 5#include <SDL3/SDL.h> 6#include <stdio.h> 7#include <stdlib.h> 8 9SDL_EnumerationResult handleBeatmapKeyValue (char * section ,char * key ,char * value ,void * userdata ) { 10struct Osu_Beatmap * beatmap = userdata ; 11 12if (strcmp (section ,"Metadata" )== 0 ) { 13if (strcmp (key ,"Title" )== 0 ) { 14SDL_asprintf (& beatmap -> title ,"%s" ,value ); 15 }else if (strcmp (key ,"TitleUnicode" )== 0 ) { 16SDL_asprintf (& beatmap -> titleUnicode ,"%s" ,value ); 17 }else if (strcmp (key ,"Artist" )== 0 ) { 18SDL_asprintf (& beatmap -> artist ,"%s" ,value ); 19 }else if (strcmp (key ,"ArtistUnicode" )== 0 ) { 20SDL_asprintf (& beatmap -> artistUnicode ,"%s" ,value ); 21 }else if (strcmp (key ,"Creator" )== 0 ) { 22SDL_asprintf (& beatmap -> creator ,"%s" ,value ); 23 }else if (strcmp (key ,"Version" )== 0 ) { 24SDL_asprintf (& beatmap -> version ,"%s" ,value ); 25 }else if (strcmp (key ,"Source" )== 0 ) { 26SDL_asprintf (& beatmap -> source ,"%s" ,value ); 27 }else if (strcmp (key ,"Tags" )== 0 ) { 28SDL_asprintf (& beatmap -> tags ,"%s" ,value ); 29 }else if (strcmp (key ,"BeatmapID" )== 0 ) { 30SDL_asprintf (& beatmap -> beatmapID ,"%s" ,value ); 31 }else if (strcmp (key ,"BeatmapSetID" )== 0 ) { 32SDL_asprintf (& beatmap -> beatmapSetID ,"%s" ,value ); 33 } 34 }else if (strcmp (section ,"General" )== 0 ) { 35if (strcmp (key ,"AudioFilename" )== 0 ) { 36SDL_asprintf (& beatmap -> audioFilename ,"%s/%s" ,beatmap -> dirname ,value ); 37 }else if (strcmp (key ,"AudioLeadIn" )== 0 ) { 38beatmap -> audioLeadIn = atoi (value ); 39if (beatmap -> audioLeadIn < 0 ) { 40beatmap -> audioLeadIn = 0 ; 41 } 42 }else if (strcmp (key ,"PreviewTime" )== 0 ) { 43beatmap -> previewTime = atoi (value ); 44if (beatmap -> previewTime < 0 ) { 45beatmap -> previewTime = 0 ; 46 } 47 } 48 } 49 50// TODO: End enumeration early if all data has been read. 51 52return SDL_ENUM_CONTINUE ; 53} 54 55SDL_EnumerationResult handleBeatmapCSVRow (char * section ,char ** values ,size_t valuesLen ,void * userdata ) { 56struct Osu_Beatmap * beatmap = userdata ; 57 58SDL_assert (valuesLen > 0 ); 59if (SDL_strcmp (section ,"Events" )== 0 ) { 60SDL_assert (valuesLen > 2 ); 61if (SDL_strcmp (values [0 ],"0" )== 0 && SDL_strcmp (values [1 ],"0" )== 0 && !beatmap -> backgroundPath ) { 62const char * value = values [2 ]; 63OSU_LOG_TRACE (value ); 64char * begin = strchr (value ,'"' ); 65char * end = strrchr (value ,'"' ); 66SDL_assert (begin ); 67SDL_assert (end ); 68SDL_assert (begin < end ); 69begin ++ ; 70size_t filenameLen = end - begin ; 71OSU_LOG_TRACEF ("%z" ,filenameLen ); 72size_t totalLen = strlen (beatmap -> dirname )+ 1 + filenameLen + 1 ;// +1 for /, +1 for null terminator 73char * filepath = malloc (totalLen ); 74strncpy (filepath ,beatmap -> dirname ,strlen (beatmap -> dirname )); 75filepath [strlen (beatmap -> dirname )]= '/' ; 76strncpy (filepath + strlen (beatmap -> dirname )+ 1 ,begin ,filenameLen ); 77filepath [totalLen - 1 ]= 0 ; 78beatmap -> backgroundPath = filepath ; 79 } 80 } 81return SDL_ENUM_CONTINUE ; 82} 83 84struct Osu_Beatmap * Osu_LoadBeatmap (const char * filepath ) { 85OSU_LOG_TRACEF ("Loading beatmap file: %s" ,filepath ); 86char * file = SDL_LoadFile (filepath ,NULL ); 87if (!file ) { 88OSU_LOG_TRACEF ("Unable to load file: %s" ,SDL_GetError ()); 89return NULL ; 90 } 91 92struct Osu_Beatmap * beatmap = calloc (1 ,sizeof (struct Osu_Beatmap )); 93SDL_asprintf (& beatmap -> filepath ,"%s" ,filepath ); 94SDL_asprintf (& beatmap -> dirname ,"%s" ,filepath ); 95dirname (beatmap -> dirname ); 96 97beatmap -> audioLeadIn = 0 ; 98beatmap -> previewTime = 0 ; 99 100if (!Osu_EnumerateBeatmapData (file ,& handleBeatmapKeyValue ,& handleBeatmapCSVRow ,beatmap )) { 101Osu_DestroyBeatmap (beatmap ); 102SDL_free (file ); 103return NULL ; 104 } 105 106SDL_free (file ); 107return beatmap ; 108} 109 110void Osu_DestroyBeatmap (struct Osu_Beatmap * beatmap ) { 111if (!beatmap ) { 112return ; 113 } 114 115free (beatmap -> filepath ); 116free (beatmap -> dirname ); 117 118free (beatmap -> audioFilename ); 119 120free (beatmap -> title ); 121free (beatmap -> titleUnicode ); 122free (beatmap -> artist ); 123free (beatmap -> artistUnicode ); 124free (beatmap -> creator ); 125free (beatmap -> version ); 126free (beatmap -> source ); 127free (beatmap -> tags ); 128free (beatmap -> beatmapID ); 129free (beatmap -> beatmapSetID ); 130 131free (beatmap -> backgroundPath ); 132 133free (beatmap ); 134}