This commit is contained in:
sillysagiri 2024-07-17 22:01:06 +07:00
parent 6481d640f3
commit f857a9e258
21 changed files with 564 additions and 660 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

30
.gitignore vendored
View File

@ -1,27 +1,13 @@
/assets/*.* /assets/*
/assets/out/*.bmp /assets/out/*
!/assets/convert.sh !/assets/convert.sh
/build /build/*
/build* /build*
/resource/image.bin /nitrofs/image.bin
/resource/music.raw /nitrofs/music.raw
/resource/palette.bin /nitrofs/palette.bin
/.cache compile_commands.json
*.nds
/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

View File

@ -1,5 +1,9 @@
{ {
"clangd.arguments": [ "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
}
} }

View File

@ -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
)

293
Makefile Normal file
View File

@ -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)

View File

@ -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)

View File

@ -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 <nds.h>
#include <dswifi7.h>
#include <maxmod7.h>
#include <filesystem.h>
#include <cstdio>
#include <cstdlib>
#include <nds/debug.h>
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;
}

View File

@ -1,18 +1,15 @@
#!/bin/sh #!/bin/sh
palette="palette.png" palette="palette.png"
video="video.mp4" video="video.webm"
# output="video_out.gif"
output="out/out_%d.bmp" output="out/out_%d.bmp"
filters="fps=60,scale=256x192" filters="scale=256x192:flags=lanczos:force_original_aspect_ratio=decrease,pad=256:192:-1:-1:color=black"
skip="-t 1 -ss 00:8"
# old # video
ffmpeg -i $video -vf "$filters,palettegen=max_colors=256:reserve_transparent=" -y $palette ffmpeg -i $video -vf "$filters,palettegen=max_colors=256:reserve_transparent=0:stats_mode=diff" -y $palette
ffmpeg -i $video -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse=dither=none" -y $output ffmpeg -i $video -i $palette -filter_complex "$filters,setpts=0.8*PTS[x];[x][1:v]paletteuse=dither=none" -y $output
# unreleased
# ffmpeg -i $video -vf "$filters" out/out_%d.bmp
# audio # audio
ffmpeg -i $video -f s16le -ac 1 -ar 22050 music.raw ffmpeg -i $video -f s16le -filter:a "atempo=1.25" -vn -ac 1 -ar 22050 -y music.raw

View File

@ -9,7 +9,7 @@ project(${PROJECT_NAME})
message(STATUS "Downloading fastlz library") message(STATUS "Downloading fastlz library")
include(FetchContent) 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) FetchContent_MakeAvailable(fastlz)
file(GLOB_RECURSE PROJECT_SOURCES CONFIGURE_DEPENDS file(GLOB_RECURSE PROJECT_SOURCES CONFIGURE_DEPENDS

View File

@ -1,13 +1,8 @@
#include <cstdio> #include <cstdio>
#include <cstdlib>
#include <cstring> #include <cstring>
#include <iostream>
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
#include <sstream>
#include <stdint.h>
#include <string>
#include <vector>
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" #include "stb_image.h"
@ -15,177 +10,132 @@
extern "C" char *RLE_Code(unsigned char *raw_buffer, int raw_len, int *new_len); 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/"; #define PALETTE_SIZE 256
std::string path_palette = "../assets/palette.png"; #define FRAME_SIZE 256*192
std::string path_resource = "../resource"; #define CHUNK_SIZE 10
std::string path_images = "../assets/out/out_";
std::string path_test = "../assets/out/out_3667.bmp";
std::vector<int> usingRLE = {999999}; uint16_t palette_buffer[PALETTE_SIZE];
// std::vector<int> 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};
size_t chunk_counter = 0;
size_t chunk_current = 0;
constexpr int palette_size = 256; size_t frame_total = 0;
uint16_t palette_map[palette_size]; uint8_t frame_buffer[FRAME_SIZE*CHUNK_SIZE];
constexpr int chunk_size = 10; uint32_t compress_size;
volatile int chunk_counter = 0; uint32_t compress_size_total;
volatile int chunk_current = 0; size_t compress_size_biggest;
uint8_t compress_buffer[FRAME_SIZE*CHUNK_SIZE*2];
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];
std::ofstream file_out; std::ofstream file_out;
void Frame_RAWtoRGB15(unsigned char *frame, unsigned char *dest);
int main() int main()
{ {
printf("Finding total frame..."); printf("Finding total frame...");
// Find 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()) { if (entry.is_regular_file()) {
std::string filename = entry.path().filename().string(); std::string filename = entry.path().filename().string();
int extpos = filename.find(".bmp", 4);
if (filename.substr(0, 4) == "out_" && filename.substr(filename.size() - 4) == ".bmp") { if (extpos != std::string::npos)
int number = std::stoi(filename.substr(4, filename.size() - 8)); {
int number = std::stoi(filename.substr(4, extpos-4));
if (number > frame_total) { if (number > frame_total) frame_total = number;
frame_total = number;
}
} }
} }
} }
// Generate palette // Generate palette
printf("Generating palette map..."); printf("Generating palette map...\n");
int temp_w, temp_h, temp_n; int pal_w, pal_h, pal_n;
unsigned char *palette_raw = stbi_load(path_palette.c_str(), &temp_w, &temp_h, &temp_n, 3); unsigned char *palette_raw = stbi_load(ASSETS_PATH "/palette.png", &pal_w, &pal_h, &pal_n, 3);
for (int i=0; i<palette_size; i++) for (int i=0; i<PALETTE_SIZE; i++)
{ {
int index = i*3; int index = i*3;
unsigned char r = palette_raw[index]; unsigned char r = palette_raw[index];
unsigned char g = palette_raw[index + 1]; unsigned char g = palette_raw[index + 1];
unsigned char b = palette_raw[index + 2]; unsigned char b = palette_raw[index + 2];
palette_map[i] = RGB15(r, g, b); palette_buffer[i] = RGBtoRGB15(r, g, b);
// printf("%i> %i,%i,%i (%i)\n", i, r, g, b, palette[i]);
} }
printf("Writing palette map..."); printf("Writing palette map...\n");
file_out.open(path_resource + "/palette.bin", std::ios::binary); file_out.open(ASSETS_PATH "/palette.bin", std::ios::binary);
file_out.write(reinterpret_cast<const char*>(palette_map), sizeof(palette_map)); file_out.write(reinterpret_cast<const char*>(palette_buffer), sizeof(palette_buffer));
file_out.close(); file_out.close();
printf("Generating image map..."); printf("Generating image map...\n");
std::stringstream ss; std::stringstream ss;
int fastlz_total = 0; file_out.open(ASSETS_PATH "/image.bin", std::ios::binary);
int raw_total = 0;
int rle_total = 0;
file_out.open(path_resource + "/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<numIterations; i++)
{ {
ss.str("");
ss << path_images << frame_counter << ".bmp";
unsigned char *frame_raw = stbi_load(ss.str().c_str(), &temp_w, &temp_h, &temp_n, 3); for (int i_chunk=0; i_chunk<CHUNK_SIZE; i_chunk++) {
// Calculate the index of the current item within the total set
int itemIndex = i * CHUNK_SIZE + i_chunk;
for (int rgb=0; rgb<256*192; rgb++) ss.str("");
{ ss << ASSETS_PATH "/out/out_" << itemIndex+1 << ".bmp";
int index = rgb*3;
unsigned char r = frame_raw[index];
unsigned char g = frame_raw[index + 1];
unsigned char b = frame_raw[index + 2];
uint16_t palette_value = RGB15(r, g, b); // printf("loading %s\n", ss.str().c_str());
int palette_index = -1;
for (int i=0; i<256; i++) int frame_w, frame_h, frame_n;
{ unsigned char *frame_raw = stbi_load(ss.str().c_str(), &frame_w, &frame_h, &frame_n, 3);
if (palette_map[i] == palette_value) {
palette_index = i;
break;
}
}
if (palette_index == -1) printf("frame %i> palette not found!!!\n", frame_counter); Frame_RAWtoRGB15(frame_raw, &frame_buffer[i_chunk*FRAME_SIZE]);
else frame_map[rgb + chunk_counter*frame_size] = palette_index; }
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<const char*>(&compress_size), sizeof(uint32_t));
file_out.write(reinterpret_cast<const char*>(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<frame_total; k++) {
ss.str("");
ss << ASSETS_PATH "/out/out_" << k+1 << ".bmp";
// printf("loading %s\n", ss.str().c_str());
int frame_w, frame_h, frame_n;
unsigned char *frame_raw = stbi_load(ss.str().c_str(), &frame_w, &frame_h, &frame_n, 3);
Frame_RAWtoRGB15(frame_raw, &frame_buffer[i_chunk*FRAME_SIZE]);
i_chunk++;
} }
printf("%i) frame %i/%i (%1.f%s)> done\n", chunk_counter, frame_counter, frame_total, ((float)frame_counter/frame_total)*100, "%"); compress_size = fastlz_compress_level(1, frame_buffer, FRAME_SIZE*CHUNK_SIZE, compress_buffer);
chunk_counter++; 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<const char*>(&compress_size), sizeof(uint32_t));
{ file_out.write(reinterpret_cast<const char*>(compress_buffer), compress_size);
bool isRLE = false; printf("write remaining chunk %i bytes\n", compress_size);
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<const char*>(&compress_flag), sizeof(uint32_t));
file_out.write(reinterpret_cast<const char*>(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++;
}
} }
file_out.close(); file_out.close();
@ -193,19 +143,30 @@ int main()
// Print // Print
printf("Total Frame: %i\n", frame_total); printf("Total Frame: %i\n", frame_total);
printf("Biggest : %i\n", compress_size_biggest); printf("Biggest : %i\n", compress_size_biggest);
printf("fastlz : %i\n", fastlz_total); printf("Total Size : %1.fmb\n", static_cast<double>(compress_size_total) / (1024*1024));
printf("rle : %i\n", rle_total);
printf("raw : %i\n", raw_total);
} }
unsigned short RGB15(int r, int g, int b) { void Frame_RAWtoRGB15(unsigned char *frame, unsigned char *dest)
unsigned short rgb15 = {
((r >> 3) << 10) | for (int rgb=0; rgb<FRAME_SIZE; rgb++)
((g >> 3) << 5) | {
(b >> 3); int index = rgb*3;
unsigned char r = frame[index];
unsigned char g = frame[index + 1];
unsigned char b = frame[index + 2];
// Set the alpha bit to 1 uint16_t palette_value = RGBtoRGB15(r, g, b);
rgb15 |= 1 << 15; int palette_index = -1;
return rgb15; for (int i=0; i<256; i++)
{
if (palette_buffer[i] == palette_value) {
palette_index = i;
break;
}
}
if (palette_index == -1) dest[rgb] = 0;
else dest[rgb] = palette_index;
}
} }

View File

@ -1,121 +0,0 @@
/*----------------------------------------------------------------------------*/
/*-- rle.c - RLE coding for Nintendo GBA/DS --*/
/*-- Copyright (C) 2011 CUE --*/
/*-- --*/
/*-- This program is free software: you can redistribute it and/or modify --*/
/*-- it under the terms of the GNU General Public License as published by --*/
/*-- the Free Software Foundation, either version 3 of the License, or --*/
/*-- (at your option) any later version. --*/
/*-- --*/
/*-- This program is distributed in the hope that it will be useful, --*/
/*-- but WITHOUT ANY WARRANTY; without even the implied warranty of --*/
/*-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --*/
/*-- GNU General Public License for more details. --*/
/*-- --*/
/*-- You should have received a copy of the GNU General Public License --*/
/*-- along with this program. If not, see <http://www.gnu.org/licenses/>. --*/
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*----------------------------------------------------------------------------*/
#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 --*/
/*----------------------------------------------------------------------------*/

BIN
icon.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -1 +1 @@
Subproject commit d93b30d1b1f60d10adac7734b2d2cef8aee581f7 Subproject commit a55a77fd3e960f472655ee3b9bbe9329202c8a50

0
nitrofs/.keep Normal file
View File

View File

@ -1,31 +1,28 @@
#include "fastlz.h" #include "fastlz.h"
#include <cstddef> #include "filesystem.h"
#include <cstdlib> #include "nds/arm9/console.h"
#include <malloc.h> #include "raylibds.hpp"
#include <mm_types.h> #include <algorithm>
#include <nds.h> #include <nds.h>
#include <filesystem.h>
#include <nds/arm9/background.h>
#include <nds/arm9/cache.h>
#include <nds/arm9/decompress.h>
#include <nds/arm9/video.h>
#include <nds/arm9/videoGL.h>
#include <nds/bios.h>
#include <nds/debug.h>
#include <nds/dma.h>
#include <nds/system.h>
#include <nds/timers.h>
#include <stdio.h>
#include <maxmod9.h> #include <maxmod9.h>
#include <fcntl.h>
#include <gl2d.h>
#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); void wait_forever(const char* msg);
size_t LoadFile(const char* file, unsigned char **buffer);
void LoadNextChunk(void *output); 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 { class CircularQueue {
public: public:
@ -77,48 +74,23 @@ public:
int ptr_background; int ptr_background;
int ptr_subbackground; int ptr_subbackground;
volatile int file_image = -1; FILE *file_image = nullptr;
volatile int file_music = -1; FILE *file_music = nullptr;
volatile bool noQueue = false; int chunk_current = 0;
constexpr int queue_size = 6;
constexpr int chunk_size = 10; uint8_t *frame_decompress;
volatile int chunk_counter = 0; uint8_t *frame_buffer;
volatile int chunk_current = 0; uint8_t *stream_buffer;
constexpr int frame_size = 256*192; int stream_index;
volatile int frame_counter = 0; int stream_buffer_current;
uint8_t frame_decompress[frame_size*chunk_size]; bool stream_need_update = false;
uint8_t frame_buffer[frame_size*chunk_size*queue_size];
CircularQueue frame_queue(queue_size);
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 ) { int music_buffer_size = 4000*16;
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 main(void) { int main(void) {
@ -126,74 +98,53 @@ int main(void) {
videoSetModeSub(MODE_5_2D); videoSetModeSub(MODE_5_2D);
vramSetBankA(VRAM_A_MAIN_BG); vramSetBankA(VRAM_A_MAIN_BG);
vramSetBankB(VRAM_B_TEXTURE);
vramSetBankC(VRAM_C_SUB_BG); vramSetBankC(VRAM_C_SUB_BG);
vramSetBankF(VRAM_F_TEX_PALETTE); vramSetBankF(VRAM_F_TEX_PALETTE);
lcdMainOnBottom();
// consoleDemoInit(); // consoleDemoInit();
consoleDebugInit(DebugDevice_NOCASH); 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); sassert(
if (file_image == -1) wait_forever("cannot load image.bin"); frame_buffer != nullptr ||
frame_decompress != nullptr ||
stream_buffer != nullptr,
"failed to allocate memmory");
file_music = open("nitro:/music.raw", O_RDONLY); bool nitrofs = nitroFSInit(NULL);
if (file_music == -1) wait_forever("cannot load music.raw"); sassert(nitrofs, "error nitrofs");
unsigned char* pal = NULL; file_image = fopen("nitro:/image.bin", "rb");
size_t pal_len = LoadFile("nitro:/palette.bin", &pal); 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_background = bgInit(3, BgType_Bmp8, BgSize_B8_256x256, 0, 0);
ptr_subbackground = bgInitSub(3, BgType_Bmp8, BgSize_B8_256x256, VRAM_C_SUB_BG, 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); 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()) { while(!frame_queue.isFull()) {
frame_queue.push(); 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(); DC_FlushAll();
@ -206,115 +157,116 @@ int main(void) {
mm_stream mystream; mm_stream mystream;
mystream.sampling_rate = 22050; mystream.sampling_rate = 22050;
mystream.buffer_length = music_buffer_size; mystream.buffer_length = MMSTREAM_BUF_SIZE;
mystream.callback = on_stream_request; mystream.callback = on_stream_request;
mystream.format = MM_STREAM_16BIT_MONO; mystream.format = MM_STREAM_16BIT_MONO;
mystream.timer = MM_TIMER2; 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 ); mmStreamOpen( &mystream );
free(pal);
while(1) { while(1) {
cothread_yield_irq(IRQ_VBLANK);
scanKeys();
irqSet(IRQ_VBLANK, onVBL); if (keysUp() & KEY_A) break;
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();
} }
return 0; return 0;
} }
void onVBL() int ThreadEntrypoint(void *arg)
{ {
// DC_FlushRange(&chunk[256*192*4 * queue.front + 256*192*chunk_counter], 256*192*4); while(1) {
dmaCopyAsynch(&frame_buffer[frame_size*chunk_size*frame_queue.front + frame_size*chunk_counter], bgGetGfxPtr(ptr_subbackground), frame_size); if (!frame_queue.isFull())
// if (frame_queue.current < frame_queue.size*0.4) { {
// fprintf(stderr, "%i\n ", chunk_counter); frame_queue.push();
// fprintf(stderr, "count: %i, %i\n ", chunk_counter, frame_queue.current); LoadNextChunk(&frame_buffer[FRAME_SIZE*CHUNK_SIZE*frame_queue.rear]);
// }
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");
} }
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) void LoadNextChunk(void *output)
{ {
uint32_t compress_size; 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; size_t samplesize = 1;
compress_size = compress_size >> 2; switch(format){
case MM_STREAM_8BIT_MONO: samplesize = 1; break;
case MM_STREAM_8BIT_STEREO: samplesize = 2; break;
if (flag == 0x01) // RLE case MM_STREAM_16BIT_MONO: samplesize = 2; break;
{ case MM_STREAM_16BIT_STEREO: samplesize = 4; break;
read(file_image, frame_decompress, compress_size);
decompress(frame_decompress, output, RLE);
// fprintf(stderr, "RLE\n");
} }
else if (flag == 0x10) // RAW int len = length*samplesize;
if (feof(file_music))
{ {
read(file_image, output, compress_size); mmStreamClose();
// fprintf(stderr, "RAW\n"); uint8_t temp[len];
} memset(temp, 0, len);
else if (flag == 0x00) // fastlz DC_FlushAll();
{ dmaCopyAsynch(temp, dest, len);
read(file_image, frame_decompress, compress_size); return length;
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");
} }
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) if (stream_index >= STREAM_CHUNK_SIZE)
{ {
fprintf(stderr, "%s\n", msg); stream_queue.pop();
fprintf(stderr, "%s\n", msg); stream_index = len - bytesToCopy;
while (1) swiWaitForVBlank(); // stream_index = 0;
dmaCopyAsynch(stream_buffer + stream_queue.front*STREAM_CHUNK_SIZE, dest+bytesToCopy, stream_index);
}
// return bytesToCopy/2;
return length;
} }