diff --git a/.cache/clangd/index/fastlz.c.8A18BA9F336ADC07.idx b/.cache/clangd/index/fastlz.c.8A18BA9F336ADC07.idx new file mode 100644 index 0000000..530d611 Binary files /dev/null and b/.cache/clangd/index/fastlz.c.8A18BA9F336ADC07.idx differ diff --git a/.cache/clangd/index/fastlz.h.923513FC4EC1A70F.idx b/.cache/clangd/index/fastlz.h.923513FC4EC1A70F.idx new file mode 100644 index 0000000..bceee08 Binary files /dev/null and b/.cache/clangd/index/fastlz.h.923513FC4EC1A70F.idx differ diff --git a/.cache/clangd/index/main.cpp.E75C1826F3CA04A7.idx b/.cache/clangd/index/main.cpp.E75C1826F3CA04A7.idx new file mode 100644 index 0000000..6326cb4 Binary files /dev/null and b/.cache/clangd/index/main.cpp.E75C1826F3CA04A7.idx differ diff --git a/.cache/clangd/index/raylibds.hpp.BEB3D2E4A936324F.idx b/.cache/clangd/index/raylibds.hpp.BEB3D2E4A936324F.idx new file mode 100644 index 0000000..8309768 Binary files /dev/null and b/.cache/clangd/index/raylibds.hpp.BEB3D2E4A936324F.idx differ diff --git a/.cache/clangd/index/rcore.cpp.B26817C90F5925C9.idx b/.cache/clangd/index/rcore.cpp.B26817C90F5925C9.idx new file mode 100644 index 0000000..33c2ad8 Binary files /dev/null and b/.cache/clangd/index/rcore.cpp.B26817C90F5925C9.idx differ diff --git a/.cache/clangd/index/rshapes.cpp.A8EDB11A130CB5D0.idx b/.cache/clangd/index/rshapes.cpp.A8EDB11A130CB5D0.idx new file mode 100644 index 0000000..3aa5daa Binary files /dev/null and b/.cache/clangd/index/rshapes.cpp.A8EDB11A130CB5D0.idx differ diff --git a/.cache/clangd/index/rtextures.cpp.A33887F0F1FEC268.idx b/.cache/clangd/index/rtextures.cpp.A33887F0F1FEC268.idx new file mode 100644 index 0000000..fdc9486 Binary files /dev/null and b/.cache/clangd/index/rtextures.cpp.A33887F0F1FEC268.idx differ diff --git a/.gitignore b/.gitignore index af7e047..61d738d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,27 +1,13 @@ -/assets/*.* -/assets/out/*.bmp +/assets/* +/assets/out/* !/assets/convert.sh -/build +/build/* /build* -/resource/image.bin -/resource/music.raw -/resource/palette.bin +/nitrofs/image.bin +/nitrofs/music.raw +/nitrofs/palette.bin -/.cache - -/NDS/nitrofiles/* -!/NDS/nitrofiles/.gitignore -/NDS/cmake -/NDS/compile_commands.json -/NDS/.cache -/NDS/build -/NDS/dist - -/encoder/node_modules -/encoder/data_compress -/encoder/temp -/encoder/cpp/lzss - -/temp +compile_commands.json +*.nds \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 9ba109b..3d382b2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,9 @@ { "clangd.arguments": [ - "--query-driver=/opt/devkitpro/devkitARM/bin/arm-none-eabi-g++" - ] + "--query-driver=/opt/wonderful/toolchain/gcc-arm-none-eabi/bin/arm-none-eabi-*" + ], + "files.exclude": { + ".cache": true, + "build": true + } } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100755 index feb000e..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -cmake_minimum_required(VERSION 3.27) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -set(PROJECT_NAME "badapple") - -set(NDSTOOL_NAME ${PROJECT_NAME} CACHE BOOL "") -set(NDSTOOL_SUBTITLE1 "Created by sillysagiri" CACHE BOOL "") -set(NDSTOOL_SUBTITLE2 "sillysagiri.my.id" CACHE BOOL "") -set(NDSTOOL_NITROFS "resource" CACHE BOOL "") - -message(STATUS "Downloading fastlz library") -include(FetchContent) -FetchContent_Declare(fastlz URL https://git.sillysagiri.my.id/MirrorRepo/FastLZ/archive/master.zip) -FetchContent_MakeAvailable(fastlz) - -set(NDSTOOL_ARM7 "${CMAKE_BINARY_DIR}/arm7/arm7.elf" CACHE BOOL "") -# set(NDSTOOL_ARM9 arm9 CACHE BOOL "") - -project(${PROJECT_NAME}) - -file(GLOB_RECURSE PROJECT_SOURCES CONFIGURE_DEPENDS - "src/*.cpp" - ${fastlz_SOURCE_DIR}/fastlz.c) - -set(PROJECT_INCLUDE - "src" - ${fastlz_SOURCE_DIR}) - -set(PROJECT_VENDOR - "filesystem" - "fat" - "mm9") - -add_executable(${PROJECT_NAME} ${PROJECT_SOURCES}) -target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_INCLUDE}) -target_link_libraries(${PROJECT_NAME} PUBLIC ${PROJECT_VENDOR}) - -nds_create_rom(${PROJECT_NAME}) - -# yeah i know its stupid, but its working!! -add_custom_command( - TARGET ${PROJECT_NAME} PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/arm7 - COMMAND ${DEVKITPRO}/portlibs/nds/bin/arm-none-eabi-cmake -S ${CMAKE_SOURCE_DIR}/arm7 ${CMAKE_BINARY_DIR}/arm7 - COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/arm7 -) \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9cd4266 --- /dev/null +++ b/Makefile @@ -0,0 +1,293 @@ +# SPDX-License-Identifier: CC0-1.0 +# +# SPDX-FileContributor: Antonio Niño Díaz, 2023 + +export BLOCKSDS ?= /opt/blocksds/core +export BLOCKSDSEXT ?= /opt/blocksds/external + +export WONDERFUL_TOOLCHAIN ?= /opt/wonderful +ARM_NONE_EABI_PATH ?= $(WONDERFUL_TOOLCHAIN)/toolchain/gcc-arm-none-eabi/bin/ + +# User config +# =========== + +NAME := badapple + +GAME_TITLE := Bad Apple +GAME_SUBTITLE := Built with BlocksDS +GAME_AUTHOR := sillysagiri +GAME_ICON := icon.bmp + +# DLDI and internal SD slot of DSi +# -------------------------------- + +# Root folder of the SD image +SDROOT := sdroot +# Name of the generated image it "DSi-1.sd" for no$gba in DSi mode +SDIMAGE := image.bin + +# Source code paths +# ----------------- + +SOURCEDIRS := src libs/FastLZ/fastlz.c libs/RaylibDS +INCLUDEDIRS := src libs/FastLZ libs/RaylibDS +GFXDIRS := +BINDIRS := +AUDIODIRS := +# A single directory that is the root of NitroFS: +NITROFSDIR := nitrofs + +# Defines passed to all files +# --------------------------- + +DEFINES := -DARM9 + +# Libraries +# --------- + +LIBS := -lmm9 -lnds9 +LIBDIRS := $(BLOCKSDS)/libs/maxmod \ + $(BLOCKSDS)/libs/libnds + +# Build artifacts +# --------------- + +BUILDDIR := build/$(NAME) +ELF := build/$(NAME).elf +DUMP := build/$(NAME).dump +MAP := build/$(NAME).map +ROM := $(NAME).nds + +# If NITROFSDIR is set, the output of mmutil will be placed in that directory +SOUNDBANKINFODIR := $(BUILDDIR)/maxmod +ifeq ($(strip $(NITROFSDIR)),) + SOUNDBANKDIR := $(BUILDDIR)/maxmod +else + SOUNDBANKDIR := $(NITROFSDIR) +endif + +# Tools +# ----- + +PREFIX := $(ARM_NONE_EABI_PATH)arm-none-eabi- +CC := $(PREFIX)gcc +CXX := $(PREFIX)g++ +LD := $(PREFIX)gcc +OBJDUMP := $(PREFIX)objdump +MKDIR := mkdir +RM := rm -rf + +# Verbose flag +# ------------ + +ifeq ($(VERBOSE),1) +V := +else +V := @ +endif + +# Source files +# ------------ + +ifneq ($(BINDIRS),) + SOURCES_BIN := $(shell find -L $(BINDIRS) -name "*.bin") + INCLUDEDIRS += $(addprefix $(BUILDDIR)/,$(BINDIRS)) +endif +ifneq ($(GFXDIRS),) + SOURCES_PNG := $(shell find -L $(GFXDIRS) -name "*.png") + INCLUDEDIRS += $(addprefix $(BUILDDIR)/,$(GFXDIRS)) +endif +ifneq ($(AUDIODIRS),) + SOURCES_AUDIO := $(shell find -L $(AUDIODIRS) -regex '.*\.\(it\|mod\|s3m\|wav\|xm\)') + ifneq ($(SOURCES_AUDIO),) + INCLUDEDIRS += $(SOUNDBANKINFODIR) + endif +endif + +SOURCES_S := $(shell find -L $(SOURCEDIRS) -name "*.s") +SOURCES_C := $(shell find -L $(SOURCEDIRS) -name "*.c") +SOURCES_CPP := $(shell find -L $(SOURCEDIRS) -name "*.cpp") + +# Compiler and linker flags +# ------------------------- + +ARCH := -mthumb -mcpu=arm946e-s+nofp + +SPECS := $(BLOCKSDS)/sys/crts/ds_arm9.specs + +WARNFLAGS := -Wall + +ifeq ($(SOURCES_CPP),) + LIBS += -lc +else + LIBS += -lstdc++ -lc +endif + +INCLUDEFLAGS := $(foreach path,$(INCLUDEDIRS),-I$(path)) \ + $(foreach path,$(LIBDIRS),-I$(path)/include) + +LIBDIRSFLAGS := $(foreach path,$(LIBDIRS),-L$(path)/lib) + +ASFLAGS += -x assembler-with-cpp $(DEFINES) $(INCLUDEFLAGS) \ + $(ARCH) -ffunction-sections -fdata-sections \ + -specs=$(SPECS) + +CFLAGS += -std=gnu17 $(WARNFLAGS) $(DEFINES) $(INCLUDEFLAGS) \ + $(ARCH) -O2 -ffunction-sections -fdata-sections \ + -specs=$(SPECS) + +CXXFLAGS += -std=gnu++17 $(WARNFLAGS) $(DEFINES) $(INCLUDEFLAGS) \ + $(ARCH) -O2 -ffunction-sections -fdata-sections \ + -fno-exceptions -fno-rtti \ + -specs=$(SPECS) + +LDFLAGS := $(ARCH) $(LIBDIRSFLAGS) -Wl,-Map,$(MAP) $(DEFINES) \ + -Wl,--start-group $(LIBS) -Wl,--end-group -specs=$(SPECS) + +# Intermediate build files +# ------------------------ + +OBJS_ASSETS := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN))) \ + $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_PNG))) + +HEADERS_ASSETS := $(patsubst %.bin,%_bin.h,$(addprefix $(BUILDDIR)/,$(SOURCES_BIN))) \ + $(patsubst %.png,%.h,$(addprefix $(BUILDDIR)/,$(SOURCES_PNG))) + +ifneq ($(SOURCES_AUDIO),) + ifeq ($(strip $(NITROFSDIR)),) + OBJS_ASSETS += $(SOUNDBANKDIR)/soundbank.c.o + endif + HEADERS_ASSETS += $(SOUNDBANKINFODIR)/soundbank.h +endif + +OBJS_SOURCES := $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_S))) \ + $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_C))) \ + $(addsuffix .o,$(addprefix $(BUILDDIR)/,$(SOURCES_CPP))) + +OBJS := $(OBJS_ASSETS) $(OBJS_SOURCES) + +DEPS := $(OBJS:.o=.d) + +# Targets +# ------- + +.PHONY: all clean dump dldipatch sdimage + +all: $(ROM) + +ifneq ($(strip $(NITROFSDIR)),) +# Additional arguments for ndstool +NDSTOOL_ARGS := -d $(NITROFSDIR) + +# Make the NDS ROM depend on the filesystem only if it is needed +$(ROM): $(NITROFSDIR) +endif + +# Combine the title strings +ifeq ($(strip $(GAME_SUBTITLE)),) + GAME_FULL_TITLE := $(GAME_TITLE);$(GAME_AUTHOR) +else + GAME_FULL_TITLE := $(GAME_TITLE);$(GAME_SUBTITLE);$(GAME_AUTHOR) +endif + +$(ROM): $(ELF) + @echo " NDSTOOL $@" + $(V)$(BLOCKSDS)/tools/ndstool/ndstool -c $@ \ + -7 $(BLOCKSDS)/sys/default_arm7/arm7.elf -9 $(ELF) \ + -b $(GAME_ICON) "$(GAME_FULL_TITLE)" \ + $(NDSTOOL_ARGS) + +$(ELF): $(OBJS) + @echo " LD $@" + $(V)$(LD) -o $@ $(OBJS) $(LDFLAGS) + +$(DUMP): $(ELF) + @echo " OBJDUMP $@" + $(V)$(OBJDUMP) -h -C -S $< > $@ + +dump: $(DUMP) + +clean: + @echo " CLEAN" + $(V)$(RM) $(ROM) $(DUMP) build $(SDIMAGE) \ + $(SOUNDBANKDIR)/soundbank.bin + +sdimage: + @echo " MKFATIMG $(SDIMAGE) $(SDROOT)" + $(V)$(BLOCKSDS)/tools/mkfatimg/mkfatimg -t $(SDROOT) $(SDIMAGE) + +dldipatch: $(ROM) + @echo " DLDIPATCH $(ROM)" + $(V)$(BLOCKSDS)/tools/dldipatch/dldipatch patch \ + $(BLOCKSDS)/sys/dldi_r4/r4tf.dldi $(ROM) + +# Rules +# ----- + +$(BUILDDIR)/%.s.o : %.s + @echo " AS $<" + @$(MKDIR) -p $(@D) + $(V)$(CC) $(ASFLAGS) -MMD -MP -c -o $@ $< + +$(BUILDDIR)/%.c.o : %.c + @echo " CC $<" + @$(MKDIR) -p $(@D) + $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $@ $< + +$(BUILDDIR)/%.arm.c.o : %.arm.c + @echo " CC $<" + @$(MKDIR) -p $(@D) + $(V)$(CC) $(CFLAGS) -MMD -MP -marm -mlong-calls -c -o $@ $< + +$(BUILDDIR)/%.cpp.o : %.cpp + @echo " CXX $<" + @$(MKDIR) -p $(@D) + $(V)$(CXX) $(CXXFLAGS) -MMD -MP -c -o $@ $< + +$(BUILDDIR)/%.arm.cpp.o : %.arm.cpp + @echo " CXX $<" + @$(MKDIR) -p $(@D) + $(V)$(CXX) $(CXXFLAGS) -MMD -MP -marm -mlong-calls -c -o $@ $< + +$(BUILDDIR)/%.bin.o $(BUILDDIR)/%_bin.h : %.bin + @echo " BIN2C $<" + @$(MKDIR) -p $(@D) + $(V)$(BLOCKSDS)/tools/bin2c/bin2c $< $(@D) + $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(BUILDDIR)/$*.bin.o $(BUILDDIR)/$*_bin.c + +$(BUILDDIR)/%.png.o $(BUILDDIR)/%.h : %.png %.grit + @echo " GRIT $<" + @$(MKDIR) -p $(@D) + $(V)$(BLOCKSDS)/tools/grit/grit $< -ftc -W1 -o$(BUILDDIR)/$* + $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(BUILDDIR)/$*.png.o $(BUILDDIR)/$*.c + $(V)touch $(BUILDDIR)/$*.png.o $(BUILDDIR)/$*.h + +ifneq ($(SOURCES_AUDIO),) + +$(SOUNDBANKINFODIR)/soundbank.h: $(SOURCES_AUDIO) + @echo " MMUTIL $^" + @$(MKDIR) -p $(@D) + @$(BLOCKSDS)/tools/mmutil/mmutil $^ -d \ + -o$(SOUNDBANKDIR)/soundbank.bin -h$(SOUNDBANKINFODIR)/soundbank.h + +ifeq ($(strip $(NITROFSDIR)),) +$(SOUNDBANKDIR)/soundbank.c.o: $(SOUNDBANKINFODIR)/soundbank.h + @echo " BIN2C soundbank.bin" + $(V)$(BLOCKSDS)/tools/bin2c/bin2c $(SOUNDBANKDIR)/soundbank.bin \ + $(SOUNDBANKDIR) + @echo " CC.9 soundbank_bin.c" + $(V)$(CC) $(CFLAGS) -MMD -MP -c -o $(SOUNDBANKDIR)/soundbank.c.o \ + $(SOUNDBANKDIR)/soundbank_bin.c +endif + +endif + +# All assets must be built before the source code +# ----------------------------------------------- + +$(SOURCES_S) $(SOURCES_C) $(SOURCES_CPP): $(HEADERS_ASSETS) + +# Include dependency files if they exist +# -------------------------------------- + +-include $(DEPS) diff --git a/arm7/CMakeLists.txt b/arm7/CMakeLists.txt deleted file mode 100755 index 9eb3196..0000000 --- a/arm7/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -# armv5te arm9 -# armv4t arm7 -set(CMAKE_SYSTEM_PROCESSOR "armv4t") - -project(arm7) - -set(PROJECT_INCLUDE - "src") - -file(GLOB PROJECT_SOURCES CONFIGURE_DEPENDS - "src/*.cpp" - "src/**/*.cpp") - -add_executable(arm7 ${PROJECT_SOURCES}) -target_include_directories(arm7 PRIVATE ${PROJECT_INCLUDE}) -target_link_libraries(arm7 PUBLIC dswifi7 mm7 filesystem fat) diff --git a/arm7/src/main.cpp b/arm7/src/main.cpp deleted file mode 100755 index cc23440..0000000 --- a/arm7/src/main.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/*--------------------------------------------------------------------------------- - - default ARM7 core - - Copyright (C) 2005 - 2010 - Michael Noland (joat) - Jason Rogers (dovoto) - Dave Murphy (WinterMute) - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any - damages arising from the use of this software. - - Permission is granted to anyone to use this software for any - purpose, including commercial applications, and to alter it and - redistribute it freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you - must not claim that you wrote the original software. If you use - this software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and - must not be misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. - ----------------------------------------------------------------------------------*/ -#include -#include -#include -#include -#include -#include -#include - -static FILE *in_music = NULL; - - -void VblankHandler(void) { - Wifi_Update(); -} - - -void VcountHandler() { - inputGetAndSend(); -} - -volatile bool exitflag = false; - -void powerButtonCB() { - exitflag = true; -} - - - -int main() { - // clear sound registers - dmaFillWords(0, (void*)0x04000400, 0x100); - - REG_SOUNDCNT |= SOUND_ENABLE; - writePowerManagement(PM_CONTROL_REG, ( readPowerManagement(PM_CONTROL_REG) & ~PM_SOUND_MUTE ) | PM_SOUND_AMP ); - powerOn(POWER_SOUND); - - readUserSettings(); - ledBlink(0); - - irqInit(); - // Start the RTC tracking IRQ - initClockIRQ(); - fifoInit(); - touchInit(); - - mmInstall(FIFO_MAXMOD); - - SetYtrigger(80); - - installWifiFIFO(); - installSoundFIFO(); - - installSystemFIFO(); - - irqSet(IRQ_VCOUNT, VcountHandler); - irqSet(IRQ_VBLANK, VblankHandler); - - irqEnable( IRQ_VBLANK | IRQ_VCOUNT | IRQ_NETWORK); - - setPowerButtonCB(powerButtonCB); - - // Keep the ARM7 mostly idle - while (!exitflag) { - if ( 0 == (REG_KEYINPUT & (KEY_A | KEY_B))) { - exitflag = true; - } - swiWaitForVBlank(); - } - return 0; -} diff --git a/assets/convert.sh b/assets/convert.sh index 642a5f5..b0f428d 100644 --- a/assets/convert.sh +++ b/assets/convert.sh @@ -1,18 +1,15 @@ #!/bin/sh palette="palette.png" -video="video.mp4" +video="video.webm" +# output="video_out.gif" output="out/out_%d.bmp" -filters="fps=60,scale=256x192" -skip="-t 1 -ss 00:8" +filters="scale=256x192:flags=lanczos:force_original_aspect_ratio=decrease,pad=256:192:-1:-1:color=black" -# old -ffmpeg -i $video -vf "$filters,palettegen=max_colors=256:reserve_transparent=" -y $palette -ffmpeg -i $video -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse=dither=none" -y $output - -# unreleased -# ffmpeg -i $video -vf "$filters" out/out_%d.bmp +# video +ffmpeg -i $video -vf "$filters,palettegen=max_colors=256:reserve_transparent=0:stats_mode=diff" -y $palette +ffmpeg -i $video -i $palette -filter_complex "$filters,setpts=0.8*PTS[x];[x][1:v]paletteuse=dither=none" -y $output # audio -ffmpeg -i $video -f s16le -ac 1 -ar 22050 music.raw \ No newline at end of file +ffmpeg -i $video -f s16le -filter:a "atempo=1.25" -vn -ac 1 -ar 22050 -y music.raw \ No newline at end of file diff --git a/encoder/CMakeLists.txt b/encoder/CMakeLists.txt index 9c4ee00..70cebb7 100644 --- a/encoder/CMakeLists.txt +++ b/encoder/CMakeLists.txt @@ -9,7 +9,7 @@ project(${PROJECT_NAME}) message(STATUS "Downloading fastlz library") include(FetchContent) -FetchContent_Declare(fastlz URL https://git.sillysagiri.my.id/MirrorRepo/FastLZ/archive/master.zip) +FetchContent_Declare(fastlz URL https://github.com/ariya/FastLZ/archive/refs/heads/master.zip) FetchContent_MakeAvailable(fastlz) file(GLOB_RECURSE PROJECT_SOURCES CONFIGURE_DEPENDS diff --git a/encoder/main.cpp b/encoder/main.cpp index 577f086..a1c1f5f 100644 --- a/encoder/main.cpp +++ b/encoder/main.cpp @@ -1,13 +1,8 @@ + #include -#include #include -#include #include #include -#include -#include -#include -#include #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" @@ -15,177 +10,132 @@ extern "C" char *RLE_Code(unsigned char *raw_buffer, int raw_len, int *new_len); -unsigned short RGB15(int r, int g, int b); +#define RGBtoRGB15(r,g,b) (((r >> 3) & 0x1F) | (((g >> 3) & 0x1F) << 5) | (((b >> 3) & 0x1F) << 10)) +#define ASSETS_PATH "../assets" -std::string path_out = "../assets/out/"; -std::string path_palette = "../assets/palette.png"; -std::string path_resource = "../resource"; -std::string path_images = "../assets/out/out_"; -std::string path_test = "../assets/out/out_3667.bmp"; +#define PALETTE_SIZE 256 +#define FRAME_SIZE 256*192 +#define CHUNK_SIZE 10 -std::vector usingRLE = {999999}; -// std::vector usingRLE = {840, 841, 842, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1041, 1459, 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481, 1482, 1483, 1484, 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519, 1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1532, 1533, 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1626, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1664, 1666, 1719, 1720, 1723, 1724, 1725, 1726, 1727, 1728, 1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1800, 1801, 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823, 1824, 1825, 1826, 1827, 1828, 1829, 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1843, 1844, 1845, 1846, 1847, 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855, 1856, 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870, 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1878, 1879, 1880, 1881, 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 1891, 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1914, 1915, 1916, 1917, 1918, 1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 3191, 3192, 3193, 3196, 3197, 3198, 3225, 3227, 3228, 3229}; +uint16_t palette_buffer[PALETTE_SIZE]; +size_t chunk_counter = 0; +size_t chunk_current = 0; -constexpr int palette_size = 256; -uint16_t palette_map[palette_size]; +size_t frame_total = 0; +uint8_t frame_buffer[FRAME_SIZE*CHUNK_SIZE]; -constexpr int chunk_size = 10; -volatile int chunk_counter = 0; -volatile int chunk_current = 0; - -constexpr int frame_size = 256*192; -volatile int frame_total = -1; -volatile int frame_counter = 0; -uint8_t frame_map[frame_size*chunk_size]; - -uint32_t compress_size, compress_flag; -volatile int compress_size_biggest; -uint8_t compress_data[frame_size*chunk_size*2]; +uint32_t compress_size; +uint32_t compress_size_total; +size_t compress_size_biggest; +uint8_t compress_buffer[FRAME_SIZE*CHUNK_SIZE*2]; std::ofstream file_out; +void Frame_RAWtoRGB15(unsigned char *frame, unsigned char *dest); + int main() { printf("Finding total frame..."); // Find total frame - for (const auto& entry : std::filesystem::directory_iterator(path_out)) { + for (const auto& entry : std::filesystem::directory_iterator(ASSETS_PATH "/out/")) { if (entry.is_regular_file()) { std::string filename = entry.path().filename().string(); - - if (filename.substr(0, 4) == "out_" && filename.substr(filename.size() - 4) == ".bmp") { - int number = std::stoi(filename.substr(4, filename.size() - 8)); - - if (number > frame_total) { - frame_total = number; - } + int extpos = filename.find(".bmp", 4); + if (extpos != std::string::npos) + { + int number = std::stoi(filename.substr(4, extpos-4)); + if (number > frame_total) frame_total = number; } } } // Generate palette - printf("Generating palette map..."); - int temp_w, temp_h, temp_n; - unsigned char *palette_raw = stbi_load(path_palette.c_str(), &temp_w, &temp_h, &temp_n, 3); - - for (int i=0; i %i,%i,%i (%i)\n", i, r, g, b, palette[i]); + palette_buffer[i] = RGBtoRGB15(r, g, b); } - printf("Writing palette map..."); - file_out.open(path_resource + "/palette.bin", std::ios::binary); - file_out.write(reinterpret_cast(palette_map), sizeof(palette_map)); + printf("Writing palette map...\n"); + file_out.open(ASSETS_PATH "/palette.bin", std::ios::binary); + file_out.write(reinterpret_cast(palette_buffer), sizeof(palette_buffer)); file_out.close(); - printf("Generating image map..."); + printf("Generating image map...\n"); std::stringstream ss; - int fastlz_total = 0; - int raw_total = 0; - int rle_total = 0; - file_out.open(path_resource + "/image.bin", std::ios::binary); + file_out.open(ASSETS_PATH "/image.bin", std::ios::binary); - for (frame_counter=1; frame_counter<=frame_total; frame_counter++) + // Calculate the number of complete iterations needed + int numIterations = frame_total / CHUNK_SIZE; + + // Calculate the number of remaining items + int remainingItems = frame_total % CHUNK_SIZE; + + for (int i=0; i palette not found!!!\n", frame_counter); - else frame_map[rgb + chunk_counter*frame_size] = palette_index; + Frame_RAWtoRGB15(frame_raw, &frame_buffer[i_chunk*FRAME_SIZE]); + } + + compress_size = fastlz_compress_level(1, frame_buffer, FRAME_SIZE*CHUNK_SIZE, compress_buffer); + if ((compress_size) > compress_size_biggest) compress_size_biggest = compress_size; + compress_size_total += compress_size; + + file_out.write(reinterpret_cast(&compress_size), sizeof(uint32_t)); + file_out.write(reinterpret_cast(compress_buffer), compress_size); + + printf("write chunk %i bytes %i/%i\n", compress_size, i, numIterations-1); + } + + // Handle remaining frame + if (remainingItems > 0) { + memset(frame_buffer, 0, FRAME_SIZE*CHUNK_SIZE); + + int i_chunk = 0; + for (int k = frame_total-remainingItems; k done\n", chunk_counter, frame_counter, frame_total, ((float)frame_counter/frame_total)*100, "%"); - chunk_counter++; + compress_size = fastlz_compress_level(1, frame_buffer, FRAME_SIZE*CHUNK_SIZE, compress_buffer); + if ((compress_size) > compress_size_biggest) compress_size_biggest = compress_size; + compress_size_total += compress_size; - if (chunk_counter >= chunk_size) - { + file_out.write(reinterpret_cast(&compress_size), sizeof(uint32_t)); + file_out.write(reinterpret_cast(compress_buffer), compress_size); - bool isRLE = false; - - for (auto y : usingRLE) - if (chunk_current == y) - isRLE = true; - - if (isRLE) - { - char *temp = RLE_Code(compress_data, frame_size*chunk_size, (int*)&compress_size); - compress_flag = (compress_size << 2) | 0xfffffffd; - - if (compress_size > frame_size*chunk_size) - { - free(temp); - compress_size = frame_size*chunk_size; - compress_flag = (compress_size << 2) | 0xfffffffe; - memcpy(compress_data, frame_map, compress_size); - printf("raw > "); - raw_total++; - } - else - { - memcpy(compress_data, temp, compress_size); - free(temp); - - printf("rle > "); - rle_total++; - } - } - else - { - compress_size = fastlz_compress_level(1, frame_map, frame_size*chunk_size, compress_data); - compress_flag = (compress_size << 2); - - if (compress_size > frame_size*chunk_size) - { - compress_size = frame_size*chunk_size; - compress_flag = (compress_size << 2) | 0xfffffffe; - memcpy(compress_data, frame_map, compress_size); - printf("raw > "); - raw_total++; - } - else - { - printf("fastlz > "); - fastlz_total++; - } - } - - file_out.write(reinterpret_cast(&compress_flag), sizeof(uint32_t)); - file_out.write(reinterpret_cast(compress_data), compress_size); - - chunk_counter = 0; - if ((compress_size) > compress_size_biggest) compress_size_biggest = compress_size; - printf("write batch %i %i/%i\n", compress_size, chunk_current, frame_total/chunk_size); - - chunk_current++; - } + printf("write remaining chunk %i bytes\n", compress_size); } file_out.close(); @@ -193,19 +143,30 @@ int main() // Print printf("Total Frame: %i\n", frame_total); printf("Biggest : %i\n", compress_size_biggest); - printf("fastlz : %i\n", fastlz_total); - printf("rle : %i\n", rle_total); - printf("raw : %i\n", raw_total); + printf("Total Size : %1.fmb\n", static_cast(compress_size_total) / (1024*1024)); } -unsigned short RGB15(int r, int g, int b) { - unsigned short rgb15 = - ((r >> 3) << 10) | - ((g >> 3) << 5) | - (b >> 3); +void Frame_RAWtoRGB15(unsigned char *frame, unsigned char *dest) +{ + for (int rgb=0; rgb. --*/ -/*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -#include -#include -#include - -/*----------------------------------------------------------------------------*/ -#define CMD_DECODE 0x00 // decode -#define CMD_CODE_30 0x30 // RLE magic number - -#define RLE_CHECK 1 // bits to check -#define RLE_MASK 0x80 // bits position: - // ((((1 << RLE_CHECK) - 1) << (8 - RLE_CHECK) -#define RLE_LENGTH 0x7F // length, (0xFF & ~RLE_MASK) - -#define RLE_THRESHOLD 2 // max number of bytes to not encode -#define RLE_N 0x80 // max store, (RLE_LENGTH + 1) -#define RLE_F 0x82 // max coded, (RLE_LENGTH + RLE_THRESHOLD + 1) - -#define RAW_MINIM 0x00000000 // empty file, 0 bytes -#define RAW_MAXIM 0x00FFFFFF // 3-bytes length, 16MB - 1 - -#define RLE_MINIM 0x00000004 // header only (empty RAW file) -#define RLE_MAXIM 0x01400000 // 0x01020003, padded to 20MB: - // * header, 4 - // * length, RAW_MAXIM - // * flags, (RAW_MAXIM + RLE_N - 1) / RLE_N - // 4 + 0x00FFFFFF + 0x00020000 + padding - -/*----------------------------------------------------------------------------*/ -#define BREAK(text) { printf(text); return; } -#define EXIT(text) { printf(text); exit(-1); } - -/*----------------------------------------------------------------------------*/ -void Title(void); -void Usage(void); - -char *Load(char *filename, int *length, int min, int max); -void Save(char *filename, char *buffer, int length); -char *Memory(int length, int size); - -void RLE_Decode(char *filename); -void RLE_Encode(char *filename); -char *RLE_Code(unsigned char *raw_buffer, int raw_len, int *new_len); - - -/*----------------------------------------------------------------------------*/ -char *Memory(int length, int size) { - char *fb; - - fb = (char *) calloc(length, size); - if (fb == NULL) EXIT("\nMemory error\n"); - - return(fb); -} - -/*----------------------------------------------------------------------------*/ -char *RLE_Code(unsigned char *raw_buffer, int raw_len, int *new_len) { - unsigned char *pak_buffer, *pak, *raw, *raw_end, store[RLE_N]; - unsigned int pak_len, len, store_len, count; - - pak_len = 4 + raw_len + ((raw_len + RLE_N - 1) / RLE_N); - pak_buffer = (unsigned char *) Memory(pak_len, sizeof(char)); - - *(unsigned int *)pak_buffer = CMD_CODE_30 | (raw_len << 8); - - pak = pak_buffer + 4; - raw = raw_buffer; - raw_end = raw_buffer + raw_len; - - store_len = 0; - while (raw < raw_end) { - for (len = 1; len < RLE_F; len++) { - if (raw + len == raw_end) break; - if (*(raw + len) != *raw) break; - } - - if (len <= RLE_THRESHOLD) store[store_len++] = *raw++; - - if ((store_len == RLE_N) || (store_len && (len > RLE_THRESHOLD))) { - *pak++ = store_len - 1; - for (count = 0; count < store_len; count++) *pak++ = store[count]; - store_len = 0; - } - - if (len > RLE_THRESHOLD) { - *pak++ = RLE_MASK | (len - (RLE_THRESHOLD + 1)); - *pak++ = *raw; - raw += len; - } - } - if (store_len) { - *pak++ = store_len - 1; - for (count = 0; count < store_len; count++) *pak++ = store[count]; - } - - *new_len = pak - pak_buffer; - - return(pak_buffer); -} - -/*----------------------------------------------------------------------------*/ -/*-- EOF Copyright (C) 2011 CUE --*/ -/*----------------------------------------------------------------------------*/ diff --git a/icon.bmp b/icon.bmp new file mode 100644 index 0000000..c5a571c Binary files /dev/null and b/icon.bmp differ diff --git a/libs/RaylibDS b/libs/RaylibDS index d93b30d..a55a77f 160000 --- a/libs/RaylibDS +++ b/libs/RaylibDS @@ -1 +1 @@ -Subproject commit d93b30d1b1f60d10adac7734b2d2cef8aee581f7 +Subproject commit a55a77fd3e960f472655ee3b9bbe9329202c8a50 diff --git a/nitrofs/.keep b/nitrofs/.keep new file mode 100644 index 0000000..e69de29 diff --git a/src/main.cpp b/src/main.cpp index d8d6dc6..b2973e5 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,31 +1,28 @@ #include "fastlz.h" -#include -#include -#include -#include +#include "filesystem.h" +#include "nds/arm9/console.h" +#include "raylibds.hpp" +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#define TIMER_SPEED (BUS_CLOCK/1024) +#define PALETTE_SIZE 256 +#define FRAME_SIZE 256*192 +#define CHUNK_SIZE 10 +#define QUEUE_SIZE 6 +#define FRAMERATE 30 + +#define STREAM_CHUNK_SIZE 32000 +#define STREAM_QUEUE_SIZE 4 +#define MMSTREAM_BUF_SIZE 9600 void wait_forever(const char* msg); -size_t LoadFile(const char* file, unsigned char **buffer); void LoadNextChunk(void *output); -void onVBL(); +void TimerCallback(); +void VBLCallback(); +void FrameStep(); +int ThreadEntrypoint(void *arg); +mm_word on_stream_request( mm_word length, mm_addr dest, mm_stream_formats format ); class CircularQueue { public: @@ -77,48 +74,23 @@ public: int ptr_background; int ptr_subbackground; -volatile int file_image = -1; -volatile int file_music = -1; +FILE *file_image = nullptr; +FILE *file_music = nullptr; -volatile bool noQueue = false; -constexpr int queue_size = 6; +int chunk_current = 0; -constexpr int chunk_size = 10; -volatile int chunk_counter = 0; -volatile int chunk_current = 0; +uint8_t *frame_decompress; +uint8_t *frame_buffer; +uint8_t *stream_buffer; -constexpr int frame_size = 256*192; -volatile int frame_counter = 0; -uint8_t frame_decompress[frame_size*chunk_size]; -uint8_t frame_buffer[frame_size*chunk_size*queue_size]; -CircularQueue frame_queue(queue_size); +int stream_index; +int stream_buffer_current; +bool stream_need_update = false; -constexpr int music_buffer_size = 4000*16; +CircularQueue frame_queue(QUEUE_SIZE); +CircularQueue stream_queue(STREAM_QUEUE_SIZE); -mm_word on_stream_request( mm_word length, mm_addr dest, mm_stream_formats format ) { - if(file_music){ - size_t samplesize = 1; - switch(format){ - case MM_STREAM_8BIT_MONO: samplesize = 1; break; - case MM_STREAM_8BIT_STEREO: samplesize = 2; break; - case MM_STREAM_16BIT_MONO: samplesize = 2; break; - case MM_STREAM_16BIT_STEREO: samplesize = 4; break; - } - - int res = read(file_music, dest, length*samplesize); - - if(res){ - length = res/samplesize; - } else { - mmStreamClose(); - close(file_music); - length = 0; - } - - } - - return length; -} +int music_buffer_size = 4000*16; int main(void) { @@ -126,74 +98,53 @@ int main(void) { videoSetModeSub(MODE_5_2D); vramSetBankA(VRAM_A_MAIN_BG); - vramSetBankB(VRAM_B_TEXTURE); vramSetBankC(VRAM_C_SUB_BG); vramSetBankF(VRAM_F_TEX_PALETTE); - lcdMainOnBottom(); - // consoleDemoInit(); consoleDebugInit(DebugDevice_NOCASH); - nitroFSInit(NULL); + frame_decompress = (uint8_t*)malloc(FRAME_SIZE*CHUNK_SIZE); + frame_buffer = (uint8_t*)malloc(FRAME_SIZE*CHUNK_SIZE*QUEUE_SIZE); + stream_buffer = (uint8_t*)malloc(STREAM_CHUNK_SIZE*STREAM_QUEUE_SIZE); - file_image = open("nitro:/image.bin", O_RDONLY); - if (file_image == -1) wait_forever("cannot load image.bin"); + sassert( + frame_buffer != nullptr || + frame_decompress != nullptr || + stream_buffer != nullptr, + "failed to allocate memmory"); - file_music = open("nitro:/music.raw", O_RDONLY); - if (file_music == -1) wait_forever("cannot load music.raw"); + bool nitrofs = nitroFSInit(NULL); + sassert(nitrofs, "error nitrofs"); - unsigned char* pal = NULL; - size_t pal_len = LoadFile("nitro:/palette.bin", &pal); + file_image = fopen("nitro:/image.bin", "rb"); + sassert(file_image != nullptr, "failed to load image.bin"); + + file_music = fopen("nitro:/music.raw", "rb"); + sassert(file_image != nullptr, "failed to load music.raw"); + + int pal_len; + unsigned char* pal = Raylib::LoadFile("nitro:/palette.bin", pal_len); ptr_background = bgInit(3, BgType_Bmp8, BgSize_B8_256x256, 0, 0); ptr_subbackground = bgInitSub(3, BgType_Bmp8, BgSize_B8_256x256, VRAM_C_SUB_BG, 0); + DC_FlushRange(pal, pal_len); + dmaCopy(pal, BG_PALETTE, pal_len); dmaCopy(pal, BG_PALETTE_SUB, pal_len); - // glScreen2D(); + free(pal); - // glLoadTileSet( - // img_washer, - // 512, 512, - // 512, 521, - // GL_RGB256, - // TEXTURE_SIZE_512, TEXTURE_SIZE_512, - // GL_TEXTURE_WRAP_S|GL_TEXTURE_WRAP_T|TEXGEN_OFF|GL_TEXTURE_COLOR0_TRANSPARENT, - // 8, - // (u16*)sagiri_washer_pal, - // (u8*)sagiri_washer); - - // DC_FlushAll(); - - // fprintf(stderr, "start debug\n"); - // int cframe = 0; - // int hframe = 0; - // int ticks = 0; - - - // while(!feof(in)) - // { - // timerStart(0, ClockDivider_1024, 0, NULL); - // readNextBatch(in , chunk); - // ticks = timerStop(0); - // int milis = ((ticks%TIMER_SPEED)*1000) /TIMER_SPEED; - - // if (milis > 50) fprintf(stderr, "%i\n", cframe); - // cframe++; - // } - - // fprintf(stderr, "%i\n", hframe); - - - // fseek(in, 0, SEEK_SET); - - fprintf(stderr, "preload start\n"); while(!frame_queue.isFull()) { frame_queue.push(); - LoadNextChunk(&frame_buffer[frame_size*chunk_size*frame_queue.rear]); + LoadNextChunk(&frame_buffer[FRAME_SIZE*CHUNK_SIZE*frame_queue.rear]); } - fprintf(stderr, "preload done %i\n", frame_queue.current); + + while(!stream_queue.isFull()) { + stream_queue.push(); + fread(&stream_buffer[STREAM_CHUNK_SIZE*stream_queue.rear], sizeof(uint8_t), STREAM_CHUNK_SIZE, file_music); + } + stream_index = 0; DC_FlushAll(); @@ -206,115 +157,116 @@ int main(void) { mm_stream mystream; mystream.sampling_rate = 22050; - mystream.buffer_length = music_buffer_size; + mystream.buffer_length = MMSTREAM_BUF_SIZE; mystream.callback = on_stream_request; mystream.format = MM_STREAM_16BIT_MONO; mystream.timer = MM_TIMER2; - mystream.manual = true; + mystream.manual = false; - DC_FlushAll(); + timerStart(0, ClockDivider_1024, TIMER_FREQ_1024(FRAMERATE), TimerCallback); + cothread_create(ThreadEntrypoint, NULL, 0, COTHREAD_DETACHED); mmStreamOpen( &mystream ); - free(pal); - while(1) { + cothread_yield_irq(IRQ_VBLANK); + scanKeys(); - irqSet(IRQ_VBLANK, onVBL); - - if (!frame_queue.isFull()) { - frame_queue.push(); - LoadNextChunk(&frame_buffer[frame_size*chunk_size*frame_queue.rear]); - // fprintf(stderr, "read %i\n", queue.rear); - } - - if (!(frame_counter % 4)) mmStreamUpdate(); + if (keysUp() & KEY_A) break; } return 0; } -void onVBL() +int ThreadEntrypoint(void *arg) { - // DC_FlushRange(&chunk[256*192*4 * queue.front + 256*192*chunk_counter], 256*192*4); - dmaCopyAsynch(&frame_buffer[frame_size*chunk_size*frame_queue.front + frame_size*chunk_counter], bgGetGfxPtr(ptr_subbackground), frame_size); - // if (frame_queue.current < frame_queue.size*0.4) { - // fprintf(stderr, "%i\n ", chunk_counter); - // fprintf(stderr, "count: %i, %i\n ", chunk_counter, frame_queue.current); - // } - - chunk_counter++; - frame_counter++; - - if (chunk_counter >= chunk_size) { - if (!frame_queue.isEmpty()) { - frame_queue.pop(); - chunk_counter = 0; - } else { - chunk_counter = chunk_size; - noQueue = true; - fprintf(stderr, "NO QUEUE!!!!!\n"); + while(1) { + if (!frame_queue.isFull()) + { + frame_queue.push(); + LoadNextChunk(&frame_buffer[FRAME_SIZE*CHUNK_SIZE*frame_queue.rear]); } + cothread_yield(); + + if (!stream_queue.isFull()) + { + stream_queue.push(); + + fread(stream_buffer+ stream_queue.rear*STREAM_CHUNK_SIZE, sizeof(uint8_t), STREAM_CHUNK_SIZE, file_music); + if (feof(file_music)) { + memset(stream_buffer+ stream_queue.rear*STREAM_CHUNK_SIZE, 0, STREAM_CHUNK_SIZE); + mmStreamClose(); + } + } + cothread_yield(); } + + return 0; +} + +void FrameStep() +{ + // if (feof(file_image)) return; + + dmaCopyAsynch(&frame_buffer[FRAME_SIZE*CHUNK_SIZE*frame_queue.front + FRAME_SIZE*chunk_current], bgGetGfxPtr(ptr_background), FRAME_SIZE); + dmaCopyAsynch(&frame_buffer[FRAME_SIZE*CHUNK_SIZE*frame_queue.front + FRAME_SIZE*chunk_current], bgGetGfxPtr(ptr_subbackground), FRAME_SIZE); + + chunk_current++; + + if (chunk_current >= CHUNK_SIZE) { + chunk_current = 0; + frame_queue.pop(); + } +} + +void TimerCallback() +{ + FrameStep(); } void LoadNextChunk(void *output) { uint32_t compress_size; - read(file_image, &compress_size, sizeof(uint32_t)); + fread(&compress_size, sizeof(uint32_t), 1, file_image); + + fread(frame_decompress, sizeof(uint8_t), compress_size, file_image); + fastlz_decompress(frame_decompress, compress_size, output, FRAME_SIZE*CHUNK_SIZE); +} + +mm_word on_stream_request( mm_word length, mm_addr dest, mm_stream_formats format ) { - uint32_t flag = compress_size & 0x3; - compress_size = compress_size >> 2; - - - if (flag == 0x01) // RLE - { - read(file_image, frame_decompress, compress_size); - decompress(frame_decompress, output, RLE); - // fprintf(stderr, "RLE\n"); + size_t samplesize = 1; + switch(format){ + case MM_STREAM_8BIT_MONO: samplesize = 1; break; + case MM_STREAM_8BIT_STEREO: samplesize = 2; break; + case MM_STREAM_16BIT_MONO: samplesize = 2; break; + case MM_STREAM_16BIT_STEREO: samplesize = 4; break; } - else if (flag == 0x10) // RAW + int len = length*samplesize; + + if (feof(file_music)) { - read(file_image, output, compress_size); - // fprintf(stderr, "RAW\n"); - } - else if (flag == 0x00) // fastlz - { - read(file_image, frame_decompress, compress_size); - fastlz_decompress(frame_decompress, compress_size, output, frame_size*chunk_size); - // fprintf(stderr, "fastlz\n"); - } - chunk_current++; - noQueue = false; - // DC_FlushRange(output, 256*192*4); -} - -size_t LoadFile(const char* file, unsigned char **buffer) -{ - FILE *in = fopen(file, "rb"); - if (in == NULL) wait_forever("cannot load file!"); - - fseek(in, 0, SEEK_END); - long file_size = ftell(in); - rewind(in); - - *buffer = (unsigned char*)malloc(file_size); - if (*buffer == NULL) wait_forever("Failed to malloc!"); - - size_t bytes_read = fread(*buffer, 1, file_size, in); - if (bytes_read != file_size) - { - fclose(in); - free(*buffer); - wait_forever("Failed to read"); + mmStreamClose(); + uint8_t temp[len]; + memset(temp, 0, len); + DC_FlushAll(); + dmaCopyAsynch(temp, dest, len); + return length; } - return bytes_read; -} + int bytesToCopy = std::min(len, STREAM_CHUNK_SIZE-stream_index); + dmaCopyAsynch(stream_buffer + stream_queue.front*STREAM_CHUNK_SIZE + stream_index, dest, bytesToCopy); + stream_index += bytesToCopy; -void wait_forever(const char* msg) -{ - fprintf(stderr, "%s\n", msg); - fprintf(stderr, "%s\n", msg); - while (1) swiWaitForVBlank(); + if (stream_index >= STREAM_CHUNK_SIZE) + { + stream_queue.pop(); + stream_index = len - bytesToCopy; + // stream_index = 0; + + dmaCopyAsynch(stream_buffer + stream_queue.front*STREAM_CHUNK_SIZE, dest+bytesToCopy, stream_index); + } + + // return bytesToCopy/2; + return length; } \ No newline at end of file