refactor
This commit is contained in:
parent
6481d640f3
commit
f857a9e258
BIN
.cache/clangd/index/fastlz.c.8A18BA9F336ADC07.idx
Normal file
BIN
.cache/clangd/index/fastlz.c.8A18BA9F336ADC07.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/fastlz.h.923513FC4EC1A70F.idx
Normal file
BIN
.cache/clangd/index/fastlz.h.923513FC4EC1A70F.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/main.cpp.E75C1826F3CA04A7.idx
Normal file
BIN
.cache/clangd/index/main.cpp.E75C1826F3CA04A7.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/raylibds.hpp.BEB3D2E4A936324F.idx
Normal file
BIN
.cache/clangd/index/raylibds.hpp.BEB3D2E4A936324F.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/rcore.cpp.B26817C90F5925C9.idx
Normal file
BIN
.cache/clangd/index/rcore.cpp.B26817C90F5925C9.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/rshapes.cpp.A8EDB11A130CB5D0.idx
Normal file
BIN
.cache/clangd/index/rshapes.cpp.A8EDB11A130CB5D0.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/rtextures.cpp.A33887F0F1FEC268.idx
Normal file
BIN
.cache/clangd/index/rtextures.cpp.A33887F0F1FEC268.idx
Normal file
Binary file not shown.
30
.gitignore
vendored
30
.gitignore
vendored
@ -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
|
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
@ -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
|
||||
}
|
||||
}
|
@ -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
293
Makefile
Normal 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)
|
@ -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)
|
@ -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;
|
||||
}
|
@ -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
|
||||
ffmpeg -i $video -f s16le -filter:a "atempo=1.25" -vn -ac 1 -ar 22050 -y music.raw
|
@ -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
|
||||
|
237
encoder/main.cpp
237
encoder/main.cpp
@ -1,13 +1,8 @@
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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<int> usingRLE = {999999};
|
||||
// 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};
|
||||
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);
|
||||
printf("Generating palette map...\n");
|
||||
int pal_w, pal_h, pal_n;
|
||||
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;
|
||||
unsigned char r = palette_raw[index];
|
||||
unsigned char g = palette_raw[index + 1];
|
||||
unsigned char b = palette_raw[index + 2];
|
||||
|
||||
palette_map[i] = RGB15(r, g, b);
|
||||
// printf("%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<const char*>(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<const char*>(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<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++)
|
||||
{
|
||||
int index = rgb*3;
|
||||
unsigned char r = frame_raw[index];
|
||||
unsigned char g = frame_raw[index + 1];
|
||||
unsigned char b = frame_raw[index + 2];
|
||||
ss.str("");
|
||||
ss << ASSETS_PATH "/out/out_" << itemIndex+1 << ".bmp";
|
||||
|
||||
uint16_t palette_value = RGB15(r, g, b);
|
||||
int palette_index = -1;
|
||||
// printf("loading %s\n", ss.str().c_str());
|
||||
|
||||
for (int i=0; i<256; i++)
|
||||
{
|
||||
if (palette_map[i] == palette_value) {
|
||||
palette_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
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_index == -1) printf("frame %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]);
|
||||
}
|
||||
|
||||
printf("%i) frame %i/%i (%1.f%s)> 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<const char*>(&compress_size), sizeof(uint32_t));
|
||||
file_out.write(reinterpret_cast<const char*>(compress_buffer), compress_size);
|
||||
|
||||
bool isRLE = false;
|
||||
printf("write chunk %i bytes %i/%i\n", compress_size, i, numIterations-1);
|
||||
}
|
||||
|
||||
for (auto y : usingRLE)
|
||||
if (chunk_current == y)
|
||||
isRLE = true;
|
||||
// Handle remaining frame
|
||||
if (remainingItems > 0) {
|
||||
memset(frame_buffer, 0, FRAME_SIZE*CHUNK_SIZE);
|
||||
|
||||
if (isRLE)
|
||||
{
|
||||
char *temp = RLE_Code(compress_data, frame_size*chunk_size, (int*)&compress_size);
|
||||
compress_flag = (compress_size << 2) | 0xfffffffd;
|
||||
int i_chunk = 0;
|
||||
for (int k = frame_total-remainingItems; k<frame_total; k++) {
|
||||
ss.str("");
|
||||
ss << ASSETS_PATH "/out/out_" << k+1 << ".bmp";
|
||||
|
||||
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("loading %s\n", ss.str().c_str());
|
||||
|
||||
printf("rle > ");
|
||||
rle_total++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
compress_size = fastlz_compress_level(1, frame_map, frame_size*chunk_size, compress_data);
|
||||
compress_flag = (compress_size << 2);
|
||||
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 (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++;
|
||||
Frame_RAWtoRGB15(frame_raw, &frame_buffer[i_chunk*FRAME_SIZE]);
|
||||
i_chunk++;
|
||||
}
|
||||
|
||||
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 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<double>(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<FRAME_SIZE; rgb++)
|
||||
{
|
||||
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
|
||||
rgb15 |= 1 << 15;
|
||||
uint16_t palette_value = RGBtoRGB15(r, g, b);
|
||||
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;
|
||||
}
|
||||
}
|
121
encoder/rle.c
121
encoder/rle.c
@ -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 --*/
|
||||
/*----------------------------------------------------------------------------*/
|
@ -1 +1 @@
|
||||
Subproject commit d93b30d1b1f60d10adac7734b2d2cef8aee581f7
|
||||
Subproject commit a55a77fd3e960f472655ee3b9bbe9329202c8a50
|
0
nitrofs/.keep
Normal file
0
nitrofs/.keep
Normal file
326
src/main.cpp
326
src/main.cpp
@ -1,31 +1,28 @@
|
||||
#include "fastlz.h"
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <malloc.h>
|
||||
#include <mm_types.h>
|
||||
#include "filesystem.h"
|
||||
#include "nds/arm9/console.h"
|
||||
#include "raylibds.hpp"
|
||||
#include <algorithm>
|
||||
#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 <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);
|
||||
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);
|
||||
|
||||
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");
|
||||
}
|
||||
else if (flag == 0x10) // RAW
|
||||
{
|
||||
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);
|
||||
fread(frame_decompress, sizeof(uint8_t), compress_size, file_image);
|
||||
fastlz_decompress(frame_decompress, compress_size, output, FRAME_SIZE*CHUNK_SIZE);
|
||||
}
|
||||
|
||||
size_t LoadFile(const char* file, unsigned char **buffer)
|
||||
{
|
||||
FILE *in = fopen(file, "rb");
|
||||
if (in == NULL) wait_forever("cannot load file!");
|
||||
mm_word on_stream_request( mm_word length, mm_addr dest, mm_stream_formats format ) {
|
||||
|
||||
fseek(in, 0, SEEK_END);
|
||||
long file_size = ftell(in);
|
||||
rewind(in);
|
||||
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 len = length*samplesize;
|
||||
|
||||
*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)
|
||||
if (feof(file_music))
|
||||
{
|
||||
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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user