ENIGMA Forums

Outsourcing saves money => Programming Help => Topic started by: HitCoder on May 30, 2015, 05:02:01 PM

Title: Reading the ".osu" file format
Post by: HitCoder on May 30, 2015, 05:02:01 PM
I recently have gotten addicted to this rhythm game called "Osu!", and it uses these things called "beatmaps", the files organising them are arranged in a file format ending with ".osu", and inside are the arrangements of sequences of hit circles (circles that are timed exactly with the beat of a song by its community) and other things. In the .osu files, this is arranged like this:

Code: [Select]
[HitObjects]
252,136,2456,5,0,0:0:0:0:
356,140,2885,1,0,0:0:0:0:

in the format of

Code: [Select]
x,y,time,type,hitSound,addition
Now, onto topic here. I would like to create something in Enigma that can read these correctly. Is this possible? Would I have to code an extension to do this?

I was thinking of using the INI file reader, but that would not work at all because the only similarities are the index things "[INDEX]" (or "[HitObjects]")

Would I be able to achieve this without pointlessly wasting my entire life on this?

(More information here: https://osu.ppy.sh/wiki/Osu_%28file_format%29)
Title: Re: Reading the ".osu" file format
Post by: WizzardMaker on May 31, 2015, 03:52:09 AM
You could try to open the file and get the string from each line, you can "scan" the string and check if its a headline ([...]). You can separate the string at each "," and add a Variable (either a list/array or variables).

I dont know the function names, but look for functions with the name file_open_read(...) or something like that
Title: Re: Reading the ".osu" file format
Post by: TheExDeus on May 31, 2015, 11:32:28 AM
It is as simple as reading the text file and parsing (i.e. "exploding") the string.

Something like this:
Code: [Select]
var file;
//Open the text file
file = file_text_open_read("song.osu");
//Read lines until hit end of file
while (file_text_eof(file) == false){
var str;
//Read the whole line
str = file_text_read_string(file); file_text_readln(file);
//Check if it's a block identifier with [ beginning
if (string_char_at(str,0) == "["){ continue; }
//Split the string
int x, y , time, type, hitSound;
var addition;
int pos;
//You should maybe check with string_count() to see if the file is not corrupt and there really is 5 commas (",")
pos = string_pos(",",str); x = real(string_copy(str,0,pos)); str = string_delete(str, 0, pos);
pos = string_pos(",",str); y = real(string_copy(str,0,pos)); str = string_delete(str, 0, pos);
pos = string_pos(",",str); time = real(string_copy(str,0,pos)); str = string_delete(str, 0, pos);
pos = string_pos(",",str); type = real(string_copy(str,0,pos)); str = string_delete(str, 0, pos);
pos = string_pos(",",str); hitSound = real(string_copy(str,0,pos)); str = string_delete(str, 0, pos);
addition = str;

show_message("Loaded:# x="+string(x)+"# y="+string(y)+"# time="+string(time)+"# type="+string(type)+"# hitSound="+string(hitSound)+"# addition="+addition);
}
There are many ways to actually do this in ENIGMA (or any tool/programming language). Like this is possibility one of the slowest. A faster way is to go trough the string by character, so you don't copy and delete string all the time.
Title: Re: Reading the ".osu" file format
Post by: HitCoder on May 31, 2015, 05:29:38 PM
Ah, thanks, I see how that would work now. It seems the easiest and most obvious method, and even if it is slow, it'll do the job. Thanks. :)