diff --git a/README.md b/README.md index b6e3bd3..d6604d9 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ ``` This demo includes: + - "Gymnopedie No.1" (Erik Satie) - "12 Variationen über ein französisches Lied 'Ah, vous dirai-je, maman'" (Wolfgang Amadeus Mozart) @@ -31,8 +32,8 @@ or [mjapa.jp](https://music-school.mjapa.jp/) style (Both are quite similar). - Reference: - - [Mabinogi MML](https://wikiwiki.jp/mabinogi/%E9%9F%B3%E6%A5%BD/MML) - - [mjapa.jp MML](https://music-school.mjapa.jp/mml_to_midi_converter.html#mml_image) + - [Mabinogi MML](https://wikiwiki.jp/mabinogi/%E9%9F%B3%E6%A5%BD/MML) + - [mjapa.jp MML](https://music-school.mjapa.jp/mml_to_midi_converter.html#mml_image) Now basic manual is available: [MML Style Overview](./mml/AboutMMLStyle.md) @@ -46,13 +47,42 @@ If you get ready: It converts MML to C array format. -Copy the output, paste the array definitions beginning with `const` to above `songs` array in the file `src/songdata.c`, -and paste the line of `{xxx_1, xxx_2, xxx_3, xxx_4},` into `songs`. +(TODO: automate procedures from here.) + +Copy the output, paste the array definitions beginning with `const` to the separate file in the `src/` (e.g. `song_newsong.c`). + +Add the declaration of tracks of your song to the file (e.g. `const unsigned char *tracks_newsong[4] ={xxx_1, xxx_2, xxx_3, xxx_4}`). `xxx` is your song name. +Create a new header (e.g. `src/song_newsong.h`) with contents similar to the following: + +```c +extern const unsigned char *tracks_gymno1[4]; +``` + +(TODO: automate procedures until here.) + +Modify `songdata.c` to include the header file, and add the track to `songs` array, like: + +```c +#include "song_newsong.h" + +const uint8 **songs[] = { + tracks_gymno1, tracks_ttls, tracks_newsong + 0 // sentinel +}; +``` + +Then add the object file requisites to `OSONGS` in `Makefile`. It will look like this: + + OSONGS = \ + song_ttls.o \ + song_gymno1.o \ + song_newsong.o + Finally, run `make` in `src` directory, and play the ROM. -Song index is your song's index in `songs` array. +The songs are indexed in the order of `songs` array. ### About `mml2dmg` diff --git a/TODO.md b/TODO.md index 6744939..6414acb 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,7 @@ # TODO -##### (1,2,3) is priority. 1 is the highest. +The priority is shown in parentheses. 1 is the highest. - (1) 2021-09-14 Want to add the changeability of the envelope steps +- [ ] (2) 2021-09-14 Want to add the changeability of the envelope steps +- [ ] (2) 2024-01-01 Make MML converter with flex/bison for completeness +- [ ] (2) 2024-01-01 Use `getopt` to parse options correctly diff --git a/src/Makefile b/src/Makefile index e1ce510..566b735 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,27 +1,35 @@ -AS = arm-none-eabi-as -CC = arm-none-eabi-gcc -LIBGCC = `arm-none-eabi-gcc -print-libgcc-file-name` -CFLAGS = -Wall -O -fno-builtin -fomit-frame-pointer -finhibit-size-directive \ --fno-ident +# include songs/songs.mk + +## Set this value correctly if the compiler tools are NOT in your PATH +BINDIR = /opt/devkitpro/devkitARM/bin/ + +AS = $(BINDIR)arm-none-eabi-as +CC = $(BINDIR)arm-none-eabi-gcc +LD = $(BINDIR)arm-none-eabi-ld +OBJCOPY = $(BINDIR)arm-none-eabi-objcopy +LIBGCC = `$(CC) -print-libgcc-file-name` +CFLAGS = -Wall -O -fno-builtin -fomit-frame-pointer -finhibit-size-directive -fno-ident OUTNAME = main -FILES = \ - crt.o ${OUTNAME}.o \ + +OSONGS = \ + song_ttls.o \ + song_gymno1.o + +OFILES = \ + crt.o $(OUTNAME).o \ sounddrv.o songdata.o \ char_gfx/misaki_gothic_2nd_nega.o \ char_gfx/misaki_gothic_2nd.o \ - bgobjmgr.o keyinput.o - + bgobjmgr.o keyinput.o \ + $(OSONGS) -${OUTNAME}.bin: ${FILES} *.h - arm-none-eabi-ld -o ${OUTNAME}.out -T gcc.ls \ - ${FILES} ${LIBGCC} - arm-none-eabi-objcopy -O binary ${OUTNAME}.out ${OUTNAME}.bin -all: clean ${OUTNAME}.bin +.PHONY: all clean -emu: ${OUTNAME}.bin - mv ${OUTNAME}.bin ${OUTNAME}.gba && mgba-qt ${OUTNAME}.gba +$(OUTNAME).gba: $(OFILES) *.h + $(LD) -o $(OUTNAME).out -T gcc.ls $(OFILES) $(LIBGCC) + $(OBJCOPY) -O binary $(OUTNAME).out $(OUTNAME).gba clean: - rm -f *.o *.out *.sav *.gba + -rm -f *.o *.out *.sav *.gba diff --git a/src/exgba.h b/src/exgba.h index d3140e9..e103beb 100644 --- a/src/exgba.h +++ b/src/exgba.h @@ -9,9 +9,9 @@ /// Type definitions -typedef unsigned char byte; -typedef unsigned short hword; -typedef unsigned int word; +typedef unsigned char byte, uint8; +typedef unsigned short hword, uint16; +typedef unsigned int word, uint32; /// Register access diff --git a/src/song_gymno1.c b/src/song_gymno1.c new file mode 100644 index 0000000..46e5b03 --- /dev/null +++ b/src/song_gymno1.c @@ -0,0 +1,36 @@ +#include "meta.h" + +// GymnopedieNo1.mml, ID = GymnopedieNo1_mml +static const unsigned char GymnopedieNo1_mml_1[] = { + 134, 60, 129, 2, 138, 1, 132, 128, 133, 4, 129, 4, 138, 0, 128, + 78, 81, 79, 78, 73, 71, 73, 74, 130, 2, 131, 1, 69, 130, 1, + 131, 1, 66, 130, 1, 131, 1, 128, 128, 78, 81, 79, 78, 73, 71, + 73, 74, 130, 2, 131, 1, 69, 129, 2, 138, 1, 73, 78, 130, 1, + 131, 1, 64, 128, 129, 4, 138, 0, 69, 71, 72, 76, 74, 71, 74, + 72, 71, 130, 1, 74, 128, 74, 76, 77, 79, 81, 72, 74, 76, 74, + 71, 130, 1, 74, 128, 74, 130, 2, 131, 1, 79, 130, 2, 131, 1, + 78, 71, 69, 71, 73, 74, 76, 73, 74, 76, 66, 62, 67, 130, 2, + 131, 1, 72, 130, 2, 131, 1, 74, TERM}; +static const unsigned char GymnopedieNo1_mml_2[] = { + 132, 128, 130, 8, 59, 130, 8, 62, 66, 128, 130, 8, 57, 130, 8, + 61, 66, 133, 8, 128, 130, 8, 57, 130, 8, 61, 66, 128, 130, 8, + 59, 130, 8, 62, 66, 128, 55, 59, 128, 130, 8, 59, 130, 8, 62, + 67, 128, 130, 8, 53, 130, 8, 57, 62, 128, 130, 8, 57, 130, 8, + 60, 64, 128, 130, 8, 55, 130, 8, 59, 64, 129, 8, 130, 4, 128, + 50, 55, 59, 64, 130, 4, 128, 48, 52, 57, 62, 130, 4, 128, 48, + 54, 57, 62, 130, 4, 128, 57, 60, 130, 4, 65, 130, 4, 128, 57, + 60, 130, 4, 64, 130, 4, 128, 50, 55, 59, 64, 130, 4, 128, 48, + 52, 57, 62, 130, 4, 128, 48, 54, 57, 62, 130, 4, 128, 59, 64, + 130, 4, 67, 130, 4, 128, 57, 61, 130, 4, 66, 130, 4, 128, 59, + 62, 130, 4, 66, 130, 4, 128, 61, 64, 130, 4, 69, 130, 4, 128, + 57, 61, 66, 69, 130, 4, 128, 130, 4, 57, 130, 4, 57, 130, 2, + 131, 1, 60, 130, 2, 131, 1, 62, TERM}; +static const unsigned char GymnopedieNo1_mml_3[] = { + 129, 2, 138, 1, 132, 43, 38, 133, 8, 42, 47, 40, + 40, 38, 45, 132, 38, 133, 9, 40, 42, 47, 40, 40, + 130, 4, 40, 130, 4, 47, 130, 4, 52, 45, 38, TERM}; +static const unsigned char GymnopedieNo1_mml_4[] = {TERM}; + +const unsigned char *tracks_gymno1[4] = { + GymnopedieNo1_mml_1, GymnopedieNo1_mml_2, GymnopedieNo1_mml_3, + GymnopedieNo1_mml_4}; diff --git a/src/song_gymno1.h b/src/song_gymno1.h new file mode 100644 index 0000000..5208d78 --- /dev/null +++ b/src/song_gymno1.h @@ -0,0 +1 @@ +extern const unsigned char *tracks_gymno1[4]; diff --git a/src/song_ttls.c b/src/song_ttls.c new file mode 100644 index 0000000..09be807 --- /dev/null +++ b/src/song_ttls.c @@ -0,0 +1,35 @@ +static const unsigned char Tinkle2LittleStar_cpped_1[] = { + 60, 60, 67, 67, 69, 69, 67, 128, 65, 65, 64, 64, 62, 62, 60, 128, + 67, 67, 65, 65, 64, 64, 62, 128, 67, 67, 65, 65, 64, 64, 62, 128, + 60, 60, 67, 67, 69, 69, 67, 128, 65, 65, 64, 64, 62, 62, 60, 128, + 132, 129, 16, 62, 60, 59, 60, 59, 60, 59, 60, 69, 67, 66, 67, 66, + 67, 66, 67, 68, 69, 72, 71, 74, 72, 71, 69, 69, 67, 76, 74, 72, + 71, 69, 67, 67, 65, 74, 72, 71, 69, 67, 65, 65, 64, 72, 71, 69, + 67, 65, 64, 129, 8, 62, 69, 67, 59, 130, 2, 60, 133, 2, 129, 16, + 69, 67, 66, 67, 66, 67, 69, 67, 67, 65, 64, 65, 64, 65, 67, 65, + 65, 64, 63, 64, 63, 64, 65, 64, 64, 62, 61, 62, 61, 62, 64, 62, + 69, 67, 66, 67, 76, 72, 69, 67, 67, 65, 64, 65, 74, 71, 67, 65, + 65, 64, 63, 64, 72, 67, 65, 64, 130, 8, 131, 1, 67, 64, 130, 4, + 62, 129, 16, 62, 60, 59, 60, 59, 60, 59, 60, 69, 67, 66, 67, 66, + 67, 66, 67, 68, 69, 72, 71, 74, 72, 71, 69, 69, 67, 76, 74, 72, + 71, 69, 67, 67, 65, 74, 72, 71, 69, 67, 65, 65, 64, 72, 71, 69, + 67, 65, 64, 129, 8, 62, 69, 67, 59, 130, 2, 60, 255, +}; +static const unsigned char Tinkle2LittleStar_cpped_2[] = { + 36, 48, 52, 48, 53, 48, 52, 48, 50, 47, 48, 45, 41, 43, 36, 128, 52, + 43, 50, 43, 48, 43, 47, 43, 52, 43, 50, 43, 48, 48, 43, 128, 36, 48, + 52, 48, 53, 48, 52, 48, 50, 47, 48, 45, 41, 43, 36, 128, 132, 36, 48, + 52, 48, 53, 48, 52, 48, 50, 47, 48, 45, 41, 43, 36, 128, 133, 2, 52, + 43, 50, 43, 48, 43, 47, 43, 52, 43, 50, 43, 48, 48, 43, 128, 36, 48, + 52, 48, 53, 48, 52, 48, 50, 47, 48, 45, 41, 43, 36, 128, 255, +}; +static const unsigned char Tinkle2LittleStar_cpped_3[] = { + 255, +}; +static const unsigned char Tinkle2LittleStar_cpped_4[] = { + 255, +}; + +const unsigned char *tracks_ttls[4] = { + Tinkle2LittleStar_cpped_1, Tinkle2LittleStar_cpped_2, + Tinkle2LittleStar_cpped_3, Tinkle2LittleStar_cpped_4}; diff --git a/src/song_ttls.h b/src/song_ttls.h new file mode 100644 index 0000000..a7ab0fd --- /dev/null +++ b/src/song_ttls.h @@ -0,0 +1 @@ +extern const unsigned char *tracks_ttls[4]; diff --git a/src/songdata.c b/src/songdata.c index 05d89e2..0d88e54 100644 --- a/src/songdata.c +++ b/src/songdata.c @@ -1,23 +1,10 @@ #include "meta.h" +#include "song_ttls.h" +#include "song_gymno1.h" -// Tinkle2LittleStar.cpped, ID = Tinkle2LittleStar_cpped -const unsigned char Tinkle2LittleStar_cpped_1[] = {60, 60, 67, 67, 69, 69, 67, 128, 65, 65, 64, 64, 62, 62, 60, 128, 67, 67, 65, 65, 64, 64, 62, 128, 67, 67, 65, 65, 64, 64, 62, 128, 60, 60, 67, 67, 69, 69, 67, 128, 65, 65, 64, 64, 62, 62, 60, 128, 132, 129, 16, 62, 60, 59, 60, 59, 60, 59, 60, 69, 67, 66, 67, 66, 67, 66, 67, 68, 69, 72, 71, 74, 72, 71, 69, 69, 67, 76, 74, 72, 71, 69, 67, 67, 65, 74, 72, 71, 69, 67, 65, 65, 64, 72, 71, 69, 67, 65, 64, 129, 8, 62, 69, 67, 59, 130, 2, 60, 133, 2, 129, 16, 69, 67, 66, 67, 66, 67, 69, 67, 67, 65, 64, 65, 64, 65, 67, 65, 65, 64, 63, 64, 63, 64, 65, 64, 64, 62, 61, 62, 61, 62, 64, 62, 69, 67, 66, 67, 76, 72, 69, 67, 67, 65, 64, 65, 74, 71, 67, 65, 65, 64, 63, 64, 72, 67, 65, 64, 130, 8, 131, 1, 67, 64, 130, 4, 62, 129, 16, 62, 60, 59, 60, 59, 60, 59, 60, 69, 67, 66, 67, 66, 67, 66, 67, 68, 69, 72, 71, 74, 72, 71, 69, 69, 67, 76, 74, 72, 71, 69, 67, 67, 65, 74, 72, 71, 69, 67, 65, 65, 64, 72, 71, 69, 67, 65, 64, 129, 8, 62, 69, 67, 59, 130, 2, 60, 255, }; -const unsigned char Tinkle2LittleStar_cpped_2[] = {36, 48, 52, 48, 53, 48, 52, 48, 50, 47, 48, 45, 41, 43, 36, 128, 52, 43, 50, 43, 48, 43, 47, 43, 52, 43, 50, 43, 48, 48, 43, 128, 36, 48, 52, 48, 53, 48, 52, 48, 50, 47, 48, 45, 41, 43, 36, 128, 132, 36, 48, 52, 48, 53, 48, 52, 48, 50, 47, 48, 45, 41, 43, 36, 128, 133, 2, 52, 43, 50, 43, 48, 43, 47, 43, 52, 43, 50, 43, 48, 48, 43, 128, 36, 48, 52, 48, 53, 48, 52, 48, 50, 47, 48, 45, 41, 43, 36, 128, 255, }; -const unsigned char Tinkle2LittleStar_cpped_3[] = {255, }; -const unsigned char Tinkle2LittleStar_cpped_4[] = {255, }; - -// GymnopedieNo1.mml, ID = GymnopedieNo1_mml -const unsigned char GymnopedieNo1_mml_1[] = {134, 60, 129, 2, 138, 1, 132, 128, 133, 4, 129, 4, 138, 0, 128, 78, 81, 79, 78, 73, 71, 73, 74, 130, 2, 131, 1, 69, 130, 1, 131, 1, 66, 130, 1, 131, 1, 128, 128, 78, 81, 79, 78, 73, 71, 73, 74, 130, 2, 131, 1, 69, 129, 2, 138, 1, 73, 78, 130, 1, 131, 1, 64, 128, 129, 4, 138, 0, 69, 71, 72, 76, 74, 71, 74, 72, 71, 130, 1, 74, 128, 74, 76, 77, 79, 81, 72, 74, 76, 74, 71, 130, 1, 74, 128, 74, 130, 2, 131, 1, 79, 130, 2, 131, 1, 78, 71, 69, 71, 73, 74, 76, 73, 74, 76, 66, 62, 67, 130, 2, 131, 1, 72, 130, 2, 131, 1, 74, TERM}; -const unsigned char GymnopedieNo1_mml_2[] = {132, 128, 130, 8, 59, 130, 8, 62, 66, 128, 130, 8, 57, 130, 8, 61, 66, 133, 8, 128, 130, 8, 57, 130, 8, 61, 66, 128, 130, 8, 59, 130, 8, 62, 66, 128, 55, 59, 128, 130, 8, 59, 130, 8, 62, 67, 128, 130, 8, 53, 130, 8, 57, 62, 128, 130, 8, 57, 130, 8, 60, 64, 128, 130, 8, 55, 130, 8, 59, 64, 129, 8, 130, 4, 128, 50, 55, 59, 64, 130, 4, 128, 48, 52, 57, 62, 130, 4, 128, 48, 54, 57, 62, 130, 4, 128, 57, 60, 130, 4, 65, 130, 4, 128, 57, 60, 130, 4, 64, 130, 4, 128, 50, 55, 59, 64, 130, 4, 128, 48, 52, 57, 62, 130, 4, 128, 48, 54, 57, 62, 130, 4, 128, 59, 64, 130, 4, 67, 130, 4, 128, 57, 61, 130, 4, 66, 130, 4, 128, 59, 62, 130, 4, 66, 130, 4, 128, 61, 64, 130, 4, 69, 130, 4, 128, 57, 61, 66, 69, 130, 4, 128, 130, 4, 57, 130, 4, 57, 130, 2, 131, 1, 60, 130, 2, 131, 1, 62, TERM}; -const unsigned char GymnopedieNo1_mml_3[] = {129, 2, 138, 1, 132, 43, 38, 133, 8, 42, 47, 40, 40, 38, 45, 132, 38, 133, 9, 40, 42, 47, 40, 40, 130, 4, 40, 130, 4, 47, 130, 4, 52, 45, 38, TERM}; -const unsigned char GymnopedieNo1_mml_4[] = {TERM}; - -const unsigned char *songs[][MAX_CHAN] = { - {GymnopedieNo1_mml_1, GymnopedieNo1_mml_2, GymnopedieNo1_mml_3, GymnopedieNo1_mml_4}, - {Tinkle2LittleStar_cpped_1, Tinkle2LittleStar_cpped_2, Tinkle2LittleStar_cpped_3, Tinkle2LittleStar_cpped_4}, - 0 // sentinel +const uint8 **songs[] = { + tracks_gymno1, tracks_ttls, + 0 // sentinel }; -const unsigned char *GetSongData(int index, int ch) { - return songs[index][ch]; -} +const unsigned char *GetSongData(int index, int ch) { return songs[index][ch]; }