Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3946800
renamed ScoreManager to Score
Eeveelution Jan 10, 2022
1e649c5
no more using namespace std;
Eeveelution Jan 10, 2022
7d25914
add to hit counters in score, aswell as prepare some stuff for making…
Eeveelution Jan 10, 2022
f4f4a80
fix compile error in Beatmap
Eeveelution Jan 10, 2022
03b7ca8
Working towards making pSprites clickable, making our lives easier
Eeveelution Jan 10, 2022
4e133ce
pSprites now have the ability to be clicked
Eeveelution Jan 10, 2022
9e3e75d
Fix bad jump when onclick isnt set
Eeveelution Jan 10, 2022
9990167
pDrawables!!
Eeveelution Jan 10, 2022
1cb2ed0
pDrawables can now decide how they wanna be drawn!
Eeveelution Jan 10, 2022
dede4aa
Added pText and fixed Lifebar
Eeveelution Jan 10, 2022
4310cf7
Fix compile errors and things
Eeveelution Jan 10, 2022
eaa71fd
Text doesnt like drawing but other than that the new menu is done asi…
Eeveelution Jan 10, 2022
354a1ae
Merge pull request #3 from Eeveelution/modularizing
KonPet Jan 13, 2022
54d1e90
Add Backgrounds for Player
KonPet Jan 13, 2022
c2cad26
Fixed infered int type issues
elissonandrade Nov 12, 2024
fd90fb8
Converter can now read format file 14
elissonandrade Nov 14, 2024
cebd608
Included mp3 converter, tested more formats
elissonandrade Nov 16, 2024
3bdcd4f
Fixed events other than break being added
elissonandrade Nov 17, 2024
1398fa1
Included linear slides to conversion
elissonandrade Nov 19, 2024
fa75ec1
Included sliders taht form circle adn beizer
elissonandrade Nov 19, 2024
69fc2ae
Fixed direction of circles
elissonandrade Nov 20, 2024
9f23ffe
Merge branch 'master' of https://github.com/KonPet/osu-ds into update…
elissonandrade Dec 1, 2024
ab25dea
Updated README.md with up to date instructions, merged other contribu…
elissonandrade Dec 1, 2024
4408e7b
Adjusted hp default drain value
elissonandrade Dec 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@

.idea
cmake-build-debug
build
build
.vscode
source/defines.h
20 changes: 18 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ include $(DEVKITARM)/ds_rules
# INCLUDES is a list of directories containing extra header files
# MAXMOD_SOUNDBANK contains a directory of music and sound effect files
#---------------------------------------------------------------------------------
GRIT := grit
TARGET := osuNDS
BUILD := build
SOURCES := source \
Expand All @@ -26,7 +27,8 @@ SOURCES := source \
source/GameplayElements \
source/HitObjects \
source/Rulesets \
source/Modes
source/Modes \
build
DATA := data/textures \
data/sounds
INCLUDES := source \
Expand Down Expand Up @@ -73,7 +75,8 @@ export OUTPUT := $(CURDIR)/$(TARGET)

export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
$(foreach dir,$(FONTS),$(CURDIR)/$(dir))
$(foreach dir,$(FONTS),$(CURDIR)/$(dir)) \
$(foreach dir, $(GRAPHICS), $(CURDIR)/$(dir))

export DEPSDIR := $(CURDIR)/$(BUILD)

Expand All @@ -82,6 +85,7 @@ CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
FONTFILES := $(foreach dir,$(FONTS),$(notdir $(wildcard $(dir)/*.bmf)))
GFXFILES := $(foreach dir, $(GRAPHICS), $(notdir $(wildcard $(dir)/*.png)))

#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
Expand All @@ -99,6 +103,7 @@ endif

export OFILES := $(addsuffix .o,$(BINFILES)) \
$(addsuffix .o,$(FONTFILES)) \
$(GFXFILES:.png=.o) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)

export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
Expand Down Expand Up @@ -135,6 +140,17 @@ $(OUTPUT).elf : $(OFILES)
@echo $(notdir $<)
@$(bin2o)


# With matching grit-file
%.c %.h : %.png %.grit
@echo $<

$(GRIT) $<

# No grit-file: try using dir.grit
# %.c %.h : %.png
# $(GRIT) $< -ff $(<D)/$(notdir $(<D)).grit

#---------------------------------------------------------------------------------
%.bmf.o : %.bmf
#---------------------------------------------------------------------------------
Expand Down
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,38 @@ As part of an effort to open source the full osu! stack, I (peppy) am splitting

No support is provided for this.

# Compiling

You need to install the [devkitPRO](https://devkitpro.org/wiki/Getting_Started) on your machine.
Download or clone this repository in a directory of your choice (let's call it "osu-ds").
Open the "osu-ds" directory and, if you are on windows, simply execute the file `build.bat`. If you are not, simply run `make` on a terminal open "osu-ds" directory.
Wait for the process to finish and if everything goes right, at the end you will have a file called `osuNDS.nds` on the "osu-ds" directory.

# Runing

If you want to run the game on a emulator, you need to enable DLDI on the emulator and set up the direcoty/file from which the files(aka, songs) will be read from.
On the emulator melonDS(0.9.5 or higher), you can do that by going into the menu Config -> Emu Setting -> Choosing the "DLDI" tab -> click on the "Enable DLDI(for homebrew)" checkbox -> click on the "Sync SD to folder" checkbox -> Choose a folder where you will put the songs.(let's call it "songs")
Now load the `osuNDS.nds` on the emulator and the game should start, even if you have no musics to pick from yet.
If you want to run this on original hardware, you will need a flash cart and the DLDI patch for the said cart. Apply the DLDI patch on the `osuNDS.nds` and copy the file to the SD card that will go on the flash cart.
Warning: the latest version of this homebrew has not been tested on any flash cart yet. Any feedback in this process is appreciatted.

# Converting songs

To convert songs from the base Osu! game, you need to compile the content of `format_downgrade` directory first.
It's a C++(17) application, so check if your compiler has support to this version.The make application is also used, so check if this application is installed as well. You also need to have the libraries `mpg123`, `samplerate` and `shlwapi` installed. Those libraries can be installed through pacman on windows.
Once those libraries and a compatible compiler are installed, the application can be compiled by runing the command `make` on the `format_downgrade` directory. This command will generate a file called `format_downgrader.exe` on windows. You can use `format_downgrader.exe` to convert songs to a format that can be played on osu-ds.

To convert a song, you will need two files: the .osu file of the song on the difficulty you want, and the corresponding mp3 music file(.ogg files and others are not supported yet).
Now, simple grab the .osu file and drop over the `format_downgrader.exe` file. This will generate two files: a .ods file and .raw file on the same directory where the .osu file was.
Those two files are compatible with the format that the osuNDS.nds can read.

As a alternative, you can also check this [other converter being created by other contributors of this project](https://github.com/KonPet/osu-ds-convert).

# Adding songs

Remenber the "songs" folder? Create a subdirectory called "osuds" there. Now, put the files .ods and .raw in this subdirectory. If you run the emulator, you should be able to see the song, and by selecting it, you can play it.


## License

This is released under the [BSD 2-Clause license](LICENSE).
39 changes: 39 additions & 0 deletions format_downgrade/BinaryFileWriter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include "BinaryFileWriter.hpp"
#include <fstream>
#include <iostream>

// Construtor
BinaryFileWriter::BinaryFileWriter(const std::string& filePath) : filePath(filePath) {}

// Método para definir o caminho do arquivo
void BinaryFileWriter::setFilePath(const std::string& filePath) {
this->filePath = filePath;
}

// Método para obter o caminho atual do arquivo
std::string BinaryFileWriter::getFilePath() const {
return filePath;
}

// Método para escrever dados binários no arquivo
bool BinaryFileWriter::write(const std::vector<uint8_t>& data) {
// Abre o arquivo em modo binário
std::ofstream outFile(filePath, std::ios::binary);
if (!outFile) {
std::cerr << "Erro ao abrir o arquivo para escrita!" << std::endl;
return false;
}

// Escreve os dados binários no arquivo
outFile.write(reinterpret_cast<const char*>(data.data()), data.size());

// Verifica se a escrita foi bem-sucedida
if (!outFile.good()) {
std::cerr << "Erro ao escrever dados no arquivo!" << std::endl;
return false;
}

// Fecha o arquivo
outFile.close();
return true;
}
26 changes: 26 additions & 0 deletions format_downgrade/BinaryFileWriter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef BINARY_FILE_WRITER_H
#define BINARY_FILE_WRITER_H

#include <vector>
#include <string>
#include <cstdint>

class BinaryFileWriter {
public:
// Construtor que aceita o caminho do arquivo
BinaryFileWriter(const std::string& filePath);

// Método para escrever dados binários no arquivo
bool write(const std::vector<uint8_t>& data);

// Método para definir o caminho do arquivo
void setFilePath(const std::string& filePath);

// Método para obter o caminho atual do arquivo
std::string getFilePath() const;

private:
std::string filePath;
};

#endif // BINARY_FILE_WRITER_H
28 changes: 28 additions & 0 deletions format_downgrade/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Variáveis do compilador
CC = g++
CFLAGS = -Wall -std=c++17
LIBS = -L/mingw64/lib -lmpg123 -lsamplerate -lshlwapi
LDFLAGS = -static # Adiciona o flag para compilação estática
INCLUDE = -I/mingw64/include

# Nome do executável
TARGET = format_downgrader

# Arquivos fonte
SOURCES = main_readfile.cpp read_file.cpp TreeNode.cpp BinaryFileWriter.cpp OldOsuExporter.cpp Mp3ToRawConverter.cpp
# Arquivos objeto
OBJECTS = $(SOURCES:.cpp=.o)

# Regras
all: $(TARGET)

$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -o $(TARGET) $(LDFLAGS) $(LIBS)

# Regra de compilação
%.o: %.cpp
$(CC) $(CFLAGS) -c $< -o $@ $(INCLUDE)

# Limpeza
clean:
rm -f $(OBJECTS) $(TARGET)
100 changes: 100 additions & 0 deletions format_downgrade/Mp3ToRawConverter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#include "Mp3ToRawConverter.h"
#include <samplerate.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <cstring>
#include <algorithm>

Mp3ToRawConverter::Mp3ToRawConverter() {
mpgHandle = nullptr;
initializeDecoder();
}

Mp3ToRawConverter::~Mp3ToRawConverter() {
cleanupDecoder();
}

bool Mp3ToRawConverter::initializeDecoder() {
if (mpg123_init() != MPG123_OK) {
std::cerr << "Erro ao inicializar a biblioteca mpg123!" << std::endl;
return false;
}
mpgHandle = mpg123_new(nullptr, nullptr);
if (!mpgHandle) {
std::cerr << "Erro ao criar o manipulador mpg123!" << std::endl;
return false;
}
mpg123_param(mpgHandle, MPG123_ADD_FLAGS, MPG123_FORCE_MONO, 0);
return true;
}

void Mp3ToRawConverter::cleanupDecoder() {
if (mpgHandle) {
mpg123_close(mpgHandle);
mpg123_delete(mpgHandle);
mpg123_exit();
}
}

int8_t Mp3ToRawConverter::convertTo8BitSigned(float sample) {
sample = std::clamp(sample, -1.0f, 1.0f);
return static_cast<int8_t>(std::round(sample * 127));
}

bool Mp3ToRawConverter::convert(const std::string& inputFilePath, const std::string& outputFilePath) {
if (mpg123_open(mpgHandle, inputFilePath.c_str()) != MPG123_OK) {
std::cerr << "Falha ao abrir o arquivo de entrada: " << inputFilePath << std::endl;
return false;
}

if (mpg123_getformat(mpgHandle, &sampleRate, &channels, &encoding) != MPG123_OK) {
std::cerr << "Falha ao obter formato de áudio!" << std::endl;
return false;
}

std::vector<unsigned char> buffer(4096);
std::vector<float> samples;
std::ofstream outputFile(outputFilePath, std::ios::binary);
size_t bytesRead;
int error;

SRC_STATE* srcState = src_new(SRC_SINC_FASTEST, channels, &error);
if (!srcState) {
std::cerr << "Erro ao inicializar o conversor de taxa de amostragem!" << std::endl;
return false;
}

SRC_DATA srcData = {};
std::vector<float> srcBuffer(4096);

while (mpg123_read(mpgHandle, buffer.data(), buffer.size(), &bytesRead) == MPG123_OK) {
for (size_t i = 0; i < bytesRead; i += channels * 2) {
int16_t sample = (buffer[i + 1] << 8) | buffer[i];
samples.push_back(static_cast<float>(sample) / 32768.0f);
}

srcData.data_in = samples.data();
srcData.input_frames = samples.size() / channels;
srcData.data_out = srcBuffer.data();
srcData.output_frames = srcBuffer.size() / channels;
srcData.src_ratio = static_cast<double>(targetSampleRate) / sampleRate;

if (src_process(srcState, &srcData) != 0) {
std::cerr << "Erro durante a conversão de taxa de amostragem!" << std::endl;
return false;
}

for (int i = 0; i < srcData.output_frames_gen; ++i) {
int8_t outSample = convertTo8BitSigned(srcBuffer[i]);
outputFile.write(reinterpret_cast<char*>(&outSample), sizeof(int8_t));
}

samples.clear();
}

src_delete(srcState);
outputFile.close();
return true;
}
34 changes: 34 additions & 0 deletions format_downgrade/Mp3ToRawConverter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef MP3_TO_RAW_CONVERTER_H
#define MP3_TO_RAW_CONVERTER_H

#include <string>
#include <cstdint>
#include <mpg123.h>

class Mp3ToRawConverter {
public:
Mp3ToRawConverter();
~Mp3ToRawConverter();

// Método para converter MP3 para RAW
bool convert(const std::string& inputFilePath, const std::string& outputFilePath);

private:
// Inicializar e limpar o decodificador mpg123
bool initializeDecoder();
void cleanupDecoder();

// Conversão de amostra para 8-bit signed
int8_t convertTo8BitSigned(float sample);

// Manipulador do mpg123
mpg123_handle *mpgHandle;
int channels, encoding;
long sampleRate;

// Definições de taxa de amostragem
static constexpr int targetSampleRate = 22050;
static constexpr int targetChannels = 1; // Mono
};

#endif // MP3_TO_RAW_CONVERTER_H
Loading