Compare commits
No commits in common. "f857a9e25878481956c134a52dd8026ea8d8cc26" and "c415f3b2e66a95fb2d078b3cb610e006b163ec9d" have entirely different histories.
f857a9e258
...
c415f3b2e6
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
30
.gitignore
vendored
@ -1,13 +1,27 @@
|
|||||||
/assets/*
|
/assets/*.*
|
||||||
/assets/out/*
|
/assets/out/*.bmp
|
||||||
!/assets/convert.sh
|
!/assets/convert.sh
|
||||||
|
|
||||||
/build/*
|
/build
|
||||||
/build*
|
/build*
|
||||||
|
|
||||||
/nitrofs/image.bin
|
/resource/image.bin
|
||||||
/nitrofs/music.raw
|
/resource/music.raw
|
||||||
/nitrofs/palette.bin
|
/resource/palette.bin
|
||||||
|
|
||||||
compile_commands.json
|
/.cache
|
||||||
*.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
|
||||||
|
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -1,6 +0,0 @@
|
|||||||
[submodule "libs/FastLZ"]
|
|
||||||
path = libs/FastLZ
|
|
||||||
url = https://github.com/ariya/FastLZ.git
|
|
||||||
[submodule "libs/RaylibDS"]
|
|
||||||
path = libs/RaylibDS
|
|
||||||
url = https://sillysagiri.my.id/sillysagiri/RaylibDS.git
|
|
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
@ -1,9 +1,5 @@
|
|||||||
{
|
{
|
||||||
"clangd.arguments": [
|
"clangd.arguments": [
|
||||||
"--query-driver=/opt/wonderful/toolchain/gcc-arm-none-eabi/bin/arm-none-eabi-*"
|
"--query-driver=/opt/devkitpro/devkitARM/bin/arm-none-eabi-g++"
|
||||||
],
|
]
|
||||||
"files.exclude": {
|
|
||||||
".cache": true,
|
|
||||||
"build": true
|
|
||||||
}
|
|
||||||
}
|
}
|
48
CMakeLists.txt
Executable file
48
CMakeLists.txt
Executable file
@ -0,0 +1,48 @@
|
|||||||
|
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
293
Makefile
@ -1,293 +0,0 @@
|
|||||||
# 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)
|
|
21
arm7/CMakeLists.txt
Executable file
21
arm7/CMakeLists.txt
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
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)
|
99
arm7/src/main.cpp
Executable file
99
arm7/src/main.cpp
Executable file
@ -0,0 +1,99 @@
|
|||||||
|
/*---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
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,15 +1,18 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
palette="palette.png"
|
palette="palette.png"
|
||||||
video="video.webm"
|
video="video.mp4"
|
||||||
# output="video_out.gif"
|
|
||||||
output="out/out_%d.bmp"
|
output="out/out_%d.bmp"
|
||||||
|
|
||||||
filters="scale=256x192:flags=lanczos:force_original_aspect_ratio=decrease,pad=256:192:-1:-1:color=black"
|
filters="fps=60,scale=256x192"
|
||||||
|
skip="-t 1 -ss 00:8"
|
||||||
|
|
||||||
# video
|
# old
|
||||||
ffmpeg -i $video -vf "$filters,palettegen=max_colors=256:reserve_transparent=0:stats_mode=diff" -y $palette
|
ffmpeg -i $video -vf "$filters,palettegen=max_colors=256:reserve_transparent=" -y $palette
|
||||||
ffmpeg -i $video -i $palette -filter_complex "$filters,setpts=0.8*PTS[x];[x][1:v]paletteuse=dither=none" -y $output
|
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
|
||||||
|
|
||||||
# audio
|
# audio
|
||||||
ffmpeg -i $video -f s16le -filter:a "atempo=1.25" -vn -ac 1 -ar 22050 -y music.raw
|
ffmpeg -i $video -f s16le -ac 1 -ar 22050 music.raw
|
@ -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://github.com/ariya/FastLZ/archive/refs/heads/master.zip)
|
FetchContent_Declare(fastlz URL https://git.sillysagiri.my.id/MirrorRepo/FastLZ/archive/master.zip)
|
||||||
FetchContent_MakeAvailable(fastlz)
|
FetchContent_MakeAvailable(fastlz)
|
||||||
|
|
||||||
file(GLOB_RECURSE PROJECT_SOURCES CONFIGURE_DEPENDS
|
file(GLOB_RECURSE PROJECT_SOURCES CONFIGURE_DEPENDS
|
||||||
|
237
encoder/main.cpp
237
encoder/main.cpp
@ -1,8 +1,13 @@
|
|||||||
|
|
||||||
#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"
|
||||||
@ -10,132 +15,177 @@
|
|||||||
|
|
||||||
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);
|
||||||
|
|
||||||
#define RGBtoRGB15(r,g,b) (((r >> 3) & 0x1F) | (((g >> 3) & 0x1F) << 5) | (((b >> 3) & 0x1F) << 10))
|
unsigned short RGB15(int r, int g, int b);
|
||||||
|
|
||||||
#define ASSETS_PATH "../assets"
|
|
||||||
|
|
||||||
#define PALETTE_SIZE 256
|
std::string path_out = "../assets/out/";
|
||||||
#define FRAME_SIZE 256*192
|
std::string path_palette = "../assets/palette.png";
|
||||||
#define CHUNK_SIZE 10
|
std::string path_resource = "../resource";
|
||||||
|
std::string path_images = "../assets/out/out_";
|
||||||
|
std::string path_test = "../assets/out/out_3667.bmp";
|
||||||
|
|
||||||
uint16_t palette_buffer[PALETTE_SIZE];
|
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};
|
||||||
|
|
||||||
size_t chunk_counter = 0;
|
|
||||||
size_t chunk_current = 0;
|
|
||||||
|
|
||||||
size_t frame_total = 0;
|
constexpr int palette_size = 256;
|
||||||
uint8_t frame_buffer[FRAME_SIZE*CHUNK_SIZE];
|
uint16_t palette_map[palette_size];
|
||||||
|
|
||||||
uint32_t compress_size;
|
constexpr int chunk_size = 10;
|
||||||
uint32_t compress_size_total;
|
volatile int chunk_counter = 0;
|
||||||
size_t compress_size_biggest;
|
volatile int chunk_current = 0;
|
||||||
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(ASSETS_PATH "/out/")) {
|
for (const auto& entry : std::filesystem::directory_iterator(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 (extpos != std::string::npos)
|
if (filename.substr(0, 4) == "out_" && filename.substr(filename.size() - 4) == ".bmp") {
|
||||||
{
|
int number = std::stoi(filename.substr(4, filename.size() - 8));
|
||||||
int number = std::stoi(filename.substr(4, extpos-4));
|
|
||||||
if (number > frame_total) frame_total = number;
|
if (number > frame_total) {
|
||||||
|
frame_total = number;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate palette
|
// Generate palette
|
||||||
printf("Generating palette map...\n");
|
printf("Generating palette map...");
|
||||||
int pal_w, pal_h, pal_n;
|
int temp_w, temp_h, temp_n;
|
||||||
unsigned char *palette_raw = stbi_load(ASSETS_PATH "/palette.png", &pal_w, &pal_h, &pal_n, 3);
|
unsigned char *palette_raw = stbi_load(path_palette.c_str(), &temp_w, &temp_h, &temp_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_buffer[i] = RGBtoRGB15(r, g, b);
|
palette_map[i] = RGB15(r, g, b);
|
||||||
|
// printf("%i> %i,%i,%i (%i)\n", i, r, g, b, palette[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Writing palette map...\n");
|
printf("Writing palette map...");
|
||||||
file_out.open(ASSETS_PATH "/palette.bin", std::ios::binary);
|
file_out.open(path_resource + "/palette.bin", std::ios::binary);
|
||||||
file_out.write(reinterpret_cast<const char*>(palette_buffer), sizeof(palette_buffer));
|
file_out.write(reinterpret_cast<const char*>(palette_map), sizeof(palette_map));
|
||||||
file_out.close();
|
file_out.close();
|
||||||
|
|
||||||
|
|
||||||
printf("Generating image map...\n");
|
printf("Generating image map...");
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
file_out.open(ASSETS_PATH "/image.bin", std::ios::binary);
|
int fastlz_total = 0;
|
||||||
|
int raw_total = 0;
|
||||||
|
int rle_total = 0;
|
||||||
|
file_out.open(path_resource + "/image.bin", std::ios::binary);
|
||||||
|
|
||||||
// Calculate the number of complete iterations needed
|
for (frame_counter=1; frame_counter<=frame_total; frame_counter++)
|
||||||
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";
|
||||||
|
|
||||||
for (int i_chunk=0; i_chunk<CHUNK_SIZE; i_chunk++) {
|
unsigned char *frame_raw = stbi_load(ss.str().c_str(), &temp_w, &temp_h, &temp_n, 3);
|
||||||
// Calculate the index of the current item within the total set
|
|
||||||
int itemIndex = i * CHUNK_SIZE + i_chunk;
|
|
||||||
|
|
||||||
ss.str("");
|
for (int rgb=0; rgb<256*192; rgb++)
|
||||||
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];
|
||||||
|
|
||||||
// printf("loading %s\n", ss.str().c_str());
|
uint16_t palette_value = RGB15(r, g, b);
|
||||||
|
int palette_index = -1;
|
||||||
|
|
||||||
int frame_w, frame_h, frame_n;
|
for (int i=0; i<256; i++)
|
||||||
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Frame_RAWtoRGB15(frame_raw, &frame_buffer[i_chunk*FRAME_SIZE]);
|
if (palette_index == -1) printf("frame %i> palette not found!!!\n", frame_counter);
|
||||||
|
else frame_map[rgb + chunk_counter*frame_size] = palette_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
compress_size = fastlz_compress_level(1, frame_buffer, FRAME_SIZE*CHUNK_SIZE, compress_buffer);
|
printf("%i) frame %i/%i (%1.f%s)> done\n", chunk_counter, frame_counter, frame_total, ((float)frame_counter/frame_total)*100, "%");
|
||||||
if ((compress_size) > compress_size_biggest) compress_size_biggest = compress_size;
|
chunk_counter++;
|
||||||
compress_size_total += compress_size;
|
|
||||||
|
|
||||||
file_out.write(reinterpret_cast<const char*>(&compress_size), sizeof(uint32_t));
|
if (chunk_counter >= chunk_size)
|
||||||
file_out.write(reinterpret_cast<const char*>(compress_buffer), compress_size);
|
{
|
||||||
|
|
||||||
printf("write chunk %i bytes %i/%i\n", compress_size, i, numIterations-1);
|
bool isRLE = false;
|
||||||
}
|
|
||||||
|
|
||||||
// Handle remaining frame
|
for (auto y : usingRLE)
|
||||||
if (remainingItems > 0) {
|
if (chunk_current == y)
|
||||||
memset(frame_buffer, 0, FRAME_SIZE*CHUNK_SIZE);
|
isRLE = true;
|
||||||
|
|
||||||
int i_chunk = 0;
|
if (isRLE)
|
||||||
for (int k = frame_total-remainingItems; k<frame_total; k++) {
|
{
|
||||||
ss.str("");
|
char *temp = RLE_Code(compress_data, frame_size*chunk_size, (int*)&compress_size);
|
||||||
ss << ASSETS_PATH "/out/out_" << k+1 << ".bmp";
|
compress_flag = (compress_size << 2) | 0xfffffffd;
|
||||||
|
|
||||||
// printf("loading %s\n", ss.str().c_str());
|
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);
|
||||||
|
|
||||||
int frame_w, frame_h, frame_n;
|
printf("rle > ");
|
||||||
unsigned char *frame_raw = stbi_load(ss.str().c_str(), &frame_w, &frame_h, &frame_n, 3);
|
rle_total++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
compress_size = fastlz_compress_level(1, frame_map, frame_size*chunk_size, compress_data);
|
||||||
|
compress_flag = (compress_size << 2);
|
||||||
|
|
||||||
Frame_RAWtoRGB15(frame_raw, &frame_buffer[i_chunk*FRAME_SIZE]);
|
if (compress_size > frame_size*chunk_size)
|
||||||
i_chunk++;
|
{
|
||||||
|
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++;
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
file_out.close();
|
||||||
@ -143,30 +193,19 @@ 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("Total Size : %1.fmb\n", static_cast<double>(compress_size_total) / (1024*1024));
|
printf("fastlz : %i\n", fastlz_total);
|
||||||
|
printf("rle : %i\n", rle_total);
|
||||||
|
printf("raw : %i\n", raw_total);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Frame_RAWtoRGB15(unsigned char *frame, unsigned char *dest)
|
unsigned short RGB15(int r, int g, int b) {
|
||||||
{
|
unsigned short rgb15 =
|
||||||
for (int rgb=0; rgb<FRAME_SIZE; rgb++)
|
((r >> 3) << 10) |
|
||||||
{
|
((g >> 3) << 5) |
|
||||||
int index = rgb*3;
|
(b >> 3);
|
||||||
unsigned char r = frame[index];
|
|
||||||
unsigned char g = frame[index + 1];
|
|
||||||
unsigned char b = frame[index + 2];
|
|
||||||
|
|
||||||
uint16_t palette_value = RGBtoRGB15(r, g, b);
|
// Set the alpha bit to 1
|
||||||
int palette_index = -1;
|
rgb15 |= 1 << 15;
|
||||||
|
|
||||||
for (int i=0; i<256; i++)
|
return rgb15;
|
||||||
{
|
|
||||||
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
Normal file
121
encoder/rle.c
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
/*-- 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 +0,0 @@
|
|||||||
Subproject commit 344eb4025f9ae866ebf7a2ec48850f7113a97a42
|
|
@ -1 +0,0 @@
|
|||||||
Subproject commit a55a77fd3e960f472655ee3b9bbe9329202c8a50
|
|
318
src/main.cpp
318
src/main.cpp
@ -1,28 +1,31 @@
|
|||||||
#include "fastlz.h"
|
#include "fastlz.h"
|
||||||
#include "filesystem.h"
|
#include <cstddef>
|
||||||
#include "nds/arm9/console.h"
|
#include <cstdlib>
|
||||||
#include "raylibds.hpp"
|
#include <malloc.h>
|
||||||
#include <algorithm>
|
#include <mm_types.h>
|
||||||
#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 PALETTE_SIZE 256
|
#define TIMER_SPEED (BUS_CLOCK/1024)
|
||||||
#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 TimerCallback();
|
void onVBL();
|
||||||
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:
|
||||||
@ -74,23 +77,48 @@ public:
|
|||||||
|
|
||||||
int ptr_background;
|
int ptr_background;
|
||||||
int ptr_subbackground;
|
int ptr_subbackground;
|
||||||
FILE *file_image = nullptr;
|
volatile int file_image = -1;
|
||||||
FILE *file_music = nullptr;
|
volatile int file_music = -1;
|
||||||
|
|
||||||
int chunk_current = 0;
|
volatile bool noQueue = false;
|
||||||
|
constexpr int queue_size = 6;
|
||||||
|
|
||||||
uint8_t *frame_decompress;
|
constexpr int chunk_size = 10;
|
||||||
uint8_t *frame_buffer;
|
volatile int chunk_counter = 0;
|
||||||
uint8_t *stream_buffer;
|
volatile int chunk_current = 0;
|
||||||
|
|
||||||
int stream_index;
|
constexpr int frame_size = 256*192;
|
||||||
int stream_buffer_current;
|
volatile int frame_counter = 0;
|
||||||
bool stream_need_update = false;
|
uint8_t frame_decompress[frame_size*chunk_size];
|
||||||
|
uint8_t frame_buffer[frame_size*chunk_size*queue_size];
|
||||||
|
CircularQueue frame_queue(queue_size);
|
||||||
|
|
||||||
CircularQueue frame_queue(QUEUE_SIZE);
|
constexpr int music_buffer_size = 4000*16;
|
||||||
CircularQueue stream_queue(STREAM_QUEUE_SIZE);
|
|
||||||
|
|
||||||
int music_buffer_size = 4000*16;
|
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 main(void) {
|
int main(void) {
|
||||||
|
|
||||||
@ -98,53 +126,74 @@ 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);
|
||||||
|
|
||||||
frame_decompress = (uint8_t*)malloc(FRAME_SIZE*CHUNK_SIZE);
|
nitroFSInit(NULL);
|
||||||
frame_buffer = (uint8_t*)malloc(FRAME_SIZE*CHUNK_SIZE*QUEUE_SIZE);
|
|
||||||
stream_buffer = (uint8_t*)malloc(STREAM_CHUNK_SIZE*STREAM_QUEUE_SIZE);
|
|
||||||
|
|
||||||
sassert(
|
file_image = open("nitro:/image.bin", O_RDONLY);
|
||||||
frame_buffer != nullptr ||
|
if (file_image == -1) wait_forever("cannot load image.bin");
|
||||||
frame_decompress != nullptr ||
|
|
||||||
stream_buffer != nullptr,
|
|
||||||
"failed to allocate memmory");
|
|
||||||
|
|
||||||
bool nitrofs = nitroFSInit(NULL);
|
file_music = open("nitro:/music.raw", O_RDONLY);
|
||||||
sassert(nitrofs, "error nitrofs");
|
if (file_music == -1) wait_forever("cannot load music.raw");
|
||||||
|
|
||||||
file_image = fopen("nitro:/image.bin", "rb");
|
unsigned char* pal = NULL;
|
||||||
sassert(file_image != nullptr, "failed to load image.bin");
|
size_t pal_len = LoadFile("nitro:/palette.bin", &pal);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
free(pal);
|
// glScreen2D();
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
@ -157,116 +206,115 @@ int main(void) {
|
|||||||
|
|
||||||
mm_stream mystream;
|
mm_stream mystream;
|
||||||
mystream.sampling_rate = 22050;
|
mystream.sampling_rate = 22050;
|
||||||
mystream.buffer_length = MMSTREAM_BUF_SIZE;
|
mystream.buffer_length = music_buffer_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 = false;
|
mystream.manual = true;
|
||||||
|
|
||||||
timerStart(0, ClockDivider_1024, TIMER_FREQ_1024(FRAMERATE), TimerCallback);
|
DC_FlushAll();
|
||||||
cothread_create(ThreadEntrypoint, NULL, 0, COTHREAD_DETACHED);
|
|
||||||
|
|
||||||
mmStreamOpen( &mystream );
|
mmStreamOpen( &mystream );
|
||||||
|
|
||||||
|
free(pal);
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
cothread_yield_irq(IRQ_VBLANK);
|
|
||||||
scanKeys();
|
|
||||||
|
|
||||||
if (keysUp() & KEY_A) break;
|
irqSet(IRQ_VBLANK, onVBL);
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
if (!frame_queue.isFull()) {
|
||||||
}
|
|
||||||
|
|
||||||
int ThreadEntrypoint(void *arg)
|
|
||||||
{
|
|
||||||
while(1) {
|
|
||||||
if (!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, "read %i\n", queue.rear);
|
||||||
}
|
}
|
||||||
cothread_yield();
|
|
||||||
|
|
||||||
if (!stream_queue.isFull())
|
if (!(frame_counter % 4)) mmStreamUpdate();
|
||||||
{
|
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameStep()
|
void onVBL()
|
||||||
{
|
{
|
||||||
// if (feof(file_image)) return;
|
// 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);
|
||||||
|
// }
|
||||||
|
|
||||||
dmaCopyAsynch(&frame_buffer[FRAME_SIZE*CHUNK_SIZE*frame_queue.front + FRAME_SIZE*chunk_current], bgGetGfxPtr(ptr_background), FRAME_SIZE);
|
chunk_counter++;
|
||||||
dmaCopyAsynch(&frame_buffer[FRAME_SIZE*CHUNK_SIZE*frame_queue.front + FRAME_SIZE*chunk_current], bgGetGfxPtr(ptr_subbackground), FRAME_SIZE);
|
frame_counter++;
|
||||||
|
|
||||||
chunk_current++;
|
if (chunk_counter >= chunk_size) {
|
||||||
|
if (!frame_queue.isEmpty()) {
|
||||||
if (chunk_current >= CHUNK_SIZE) {
|
frame_queue.pop();
|
||||||
chunk_current = 0;
|
chunk_counter = 0;
|
||||||
frame_queue.pop();
|
} else {
|
||||||
|
chunk_counter = chunk_size;
|
||||||
|
noQueue = true;
|
||||||
|
fprintf(stderr, "NO QUEUE!!!!!\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimerCallback()
|
|
||||||
{
|
|
||||||
FrameStep();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadNextChunk(void *output)
|
void LoadNextChunk(void *output)
|
||||||
{
|
{
|
||||||
uint32_t compress_size;
|
uint32_t compress_size;
|
||||||
fread(&compress_size, sizeof(uint32_t), 1, file_image);
|
read(file_image, &compress_size, sizeof(uint32_t));
|
||||||
|
|
||||||
fread(frame_decompress, sizeof(uint8_t), compress_size, file_image);
|
uint32_t flag = compress_size & 0x3;
|
||||||
fastlz_decompress(frame_decompress, compress_size, output, FRAME_SIZE*CHUNK_SIZE);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
mm_word on_stream_request( mm_word length, mm_addr dest, mm_stream_formats format ) {
|
size_t LoadFile(const char* file, unsigned char **buffer)
|
||||||
|
{
|
||||||
|
FILE *in = fopen(file, "rb");
|
||||||
|
if (in == NULL) wait_forever("cannot load file!");
|
||||||
|
|
||||||
size_t samplesize = 1;
|
fseek(in, 0, SEEK_END);
|
||||||
switch(format){
|
long file_size = ftell(in);
|
||||||
case MM_STREAM_8BIT_MONO: samplesize = 1; break;
|
rewind(in);
|
||||||
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;
|
|
||||||
|
|
||||||
if (feof(file_music))
|
*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)
|
||||||
{
|
{
|
||||||
mmStreamClose();
|
fclose(in);
|
||||||
uint8_t temp[len];
|
free(*buffer);
|
||||||
memset(temp, 0, len);
|
wait_forever("Failed to read");
|
||||||
DC_FlushAll();
|
|
||||||
dmaCopyAsynch(temp, dest, len);
|
|
||||||
return length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int bytesToCopy = std::min(len, STREAM_CHUNK_SIZE-stream_index);
|
return bytes_read;
|
||||||
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;
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user