From fd6a711cb7504ed40e424a59a95efa272a9102f8 Mon Sep 17 00:00:00 2001 From: orboditilt <45944072+orboditilt@users.noreply.github.com> Date: Wed, 14 Aug 2019 22:19:46 +0200 Subject: [PATCH] port GUI to RPX, use backend via simple IPC --- .gitignore | 16 +- .gitmodules | 4 - Makefile | 338 +- filelist.sh | 32 +- installupdateportlibs.sh | 19 - libs/portlibs.zip | Bin 38349 -> 0 bytes src/Application.cpp | 272 +- src/Application.h | 13 +- src/common/common.h | 12 - src/common/retain_vars.cpp | 26 - src/common/retain_vars.h | 31 - src/entry.c | 2 +- src/fs/CFile.cpp | 172 + src/fs/CFile.hpp | 61 + src/fs/DirList.cpp | 213 + src/fs/DirList.h | 103 + src/fs/FSUtils.cpp | 144 + src/fs/FSUtils.h | 16 + src/language/gettext.cpp | 270 ++ .../mem_utils.h => language/gettext.h} | 40 +- src/libelf/_elftc.h | 430 -- src/libelf/_libelf.h | 223 -- src/libelf/_libelf_ar.h | 56 - src/libelf/_libelf_config.h | 193 - src/libelf/elf.c | 40 - src/libelf/elf_begin.c | 91 - src/libelf/elf_cntl.c | 58 - src/libelf/elf_data.c | 254 -- src/libelf/elf_end.c | 97 - src/libelf/elf_errmsg.c | 85 - src/libelf/elf_errno.c | 43 - src/libelf/elf_fill.c | 39 - src/libelf/elf_flag.c | 198 - src/libelf/elf_getarhdr.c | 47 - src/libelf/elf_getarsym.c | 58 - src/libelf/elf_getbase.c | 48 - src/libelf/elf_getident.c | 68 - src/libelf/elf_hash.c | 56 - src/libelf/elf_kind.c | 44 - src/libelf/elf_memory.c | 47 - src/libelf/elf_next.c | 62 - src/libelf/elf_open.c | 67 - src/libelf/elf_phnum.c | 67 - src/libelf/elf_rand.c | 59 - src/libelf/elf_rawfile.c | 53 - src/libelf/elf_scn.c | 233 -- src/libelf/elf_shnum.c | 67 - src/libelf/elf_shstrndx.c | 82 - src/libelf/elf_strptr.c | 132 - src/libelf/elf_update.c | 1204 ------ src/libelf/elf_version.c | 52 - src/libelf/elfdefinitions.h | 2560 ------------ src/libelf/gelf.h | 106 - src/libelf/gelf_cap.c | 151 - src/libelf/gelf_checksum.c | 58 - src/libelf/gelf_dyn.c | 150 - src/libelf/gelf_ehdr.c | 168 - src/libelf/gelf_fsize.c | 62 - src/libelf/gelf_getclass.c | 39 - src/libelf/gelf_move.c | 157 - src/libelf/gelf_phdr.c | 178 - src/libelf/gelf_rel.c | 159 - src/libelf/gelf_rela.c | 162 - src/libelf/gelf_shdr.c | 131 - src/libelf/gelf_sym.c | 160 - src/libelf/gelf_syminfo.c | 151 - src/libelf/gelf_symshndx.c | 136 - src/libelf/gelf_xlate.c | 81 - src/libelf/libelf.h | 250 -- src/libelf/libelf_align.c | 137 - src/libelf/libelf_allocate.c | 212 - src/libelf/libelf_ar.c | 461 --- src/libelf/libelf_ar_util.c | 359 -- src/libelf/libelf_checksum.c | 100 - src/libelf/libelf_convert.c | 3465 ----------------- src/libelf/libelf_data.c | 88 - src/libelf/libelf_ehdr.c | 204 - src/libelf/libelf_extended.c | 136 - src/libelf/libelf_fsize.c | 197 - src/libelf/libelf_memory.c | 96 - src/libelf/libelf_msize.c | 196 - src/libelf/libelf_open.c | 240 -- src/libelf/libelf_phdr.c | 156 - src/libelf/libelf_shdr.c | 56 - src/libelf/libelf_xlate.c | 150 - src/link.ld | 40 - src/main.cpp | 358 +- src/main.h | 15 +- src/menu/MainWindow.cpp | 4 - src/menu/content/ContentHome.cpp | 27 +- src/menu/content/ContentHome.h | 5 +- src/mocha | 1 - src/mykernel/kernel_defs.h | 30 - src/mykernel/kernel_utils.c | 181 - src/mykernel/kernel_utils.h | 14 - src/mykernel/syscalls.h | 20 - src/mykernel/syscalls_asm.s | 30 - src/mymemory/memory_mapping.cpp | 748 ---- src/mymemory/memory_mapping.h | 201 - src/myutils/ConfigInformation.cpp | 117 - src/myutils/ConfigInformation.h | 61 - src/myutils/ConfigUtils.cpp | 395 -- src/myutils/ConfigUtils.h | 87 - src/myutils/ScreenUtils.cpp | 69 - src/myutils/ScreenUtils.h | 50 - src/myutils/libfat.cpp | 24 - src/myutils/libfat.h | 17 - src/myutils/libntfs.cpp | 40 - src/myutils/libntfs.h | 7 - src/myutils/mem_utils.cpp | 37 - src/myutils/mocha.cpp | 430 -- src/myutils/mocha.h | 16 - src/myutils/overlay_helper.cpp | 174 - src/myutils/overlay_helper.h | 24 - src/myutils/texture_utils.cpp | 174 - src/myutils/texture_utils.h | 33 - src/patcher/function_patcher.cpp | 365 -- src/patcher/function_patcher.h | 92 - src/patcher/hooks_patcher.cpp | 40 - src/patcher/hooks_patcher.h | 18 - src/patcher/hooks_patcher_static.cpp | 340 -- src/patcher/hooks_patcher_static.h | 18 - src/plugin/DynamicLinkingHelper.cpp | 197 - src/plugin/DynamicLinkingHelper.h | 94 - src/plugin/ElfTools.cpp | 501 --- src/plugin/ElfTools.h | 52 - src/plugin/ImportRPLInformation.h | 79 - src/plugin/PluginData.cpp | 43 - src/plugin/PluginData.h | 134 - src/plugin/PluginInformation.cpp | 423 -- src/plugin/PluginInformation.h | 68 +- src/plugin/PluginLoader.cpp | 610 +-- src/plugin/PluginLoader.h | 136 +- src/plugin/RelocationData.h | 79 - src/plugin/dynamic_linking_defines.h | 66 - src/resources/Resources.cpp | 188 + src/resources/Resources.h | 33 + src/resources/filelist.cpp | 79 - src/settings/CSettings.h | 1 - src/settings/ConfigSettings.cpp | 2 +- src/settings/ConfigSettings.h | 1 - src/system/AsyncDeleter.cpp | 63 + src/system/AsyncDeleter.h | 76 + .../FunctionData.h => system/CMutex.h} | 75 +- src/system/CThread.h | 133 + src/system/memory.c | 197 + src/{plugin/HookData.h => system/memory.h} | 57 +- src/utils.cpp | 162 - src/utils.h | 21 - src/utils/StringTools.cpp | 210 + src/utils/StringTools.h | 82 + src/{myutils => utils}/TcpReceiver.cpp | 37 +- src/{myutils => utils}/TcpReceiver.h | 1 - src/utils/ipcclient.cpp | 240 ++ src/utils/ipcclient.h | 67 + src/utils/logger.c | 82 + src/utils/logger.h | 39 + src/utils/net.c | 84 + src/utils/net.h | 22 + src/utils/utils.c | 41 + src/utils/utils.h | 38 + 161 files changed, 3198 insertions(+), 22766 deletions(-) delete mode 100644 installupdateportlibs.sh delete mode 100644 libs/portlibs.zip delete mode 100644 src/common/retain_vars.cpp delete mode 100644 src/common/retain_vars.h create mode 100644 src/fs/CFile.cpp create mode 100644 src/fs/CFile.hpp create mode 100644 src/fs/DirList.cpp create mode 100644 src/fs/DirList.h create mode 100644 src/fs/FSUtils.cpp create mode 100644 src/fs/FSUtils.h create mode 100644 src/language/gettext.cpp rename src/{myutils/mem_utils.h => language/gettext.h} (63%) delete mode 100644 src/libelf/_elftc.h delete mode 100644 src/libelf/_libelf.h delete mode 100644 src/libelf/_libelf_ar.h delete mode 100644 src/libelf/_libelf_config.h delete mode 100644 src/libelf/elf.c delete mode 100644 src/libelf/elf_begin.c delete mode 100644 src/libelf/elf_cntl.c delete mode 100644 src/libelf/elf_data.c delete mode 100644 src/libelf/elf_end.c delete mode 100644 src/libelf/elf_errmsg.c delete mode 100644 src/libelf/elf_errno.c delete mode 100644 src/libelf/elf_fill.c delete mode 100644 src/libelf/elf_flag.c delete mode 100644 src/libelf/elf_getarhdr.c delete mode 100644 src/libelf/elf_getarsym.c delete mode 100644 src/libelf/elf_getbase.c delete mode 100644 src/libelf/elf_getident.c delete mode 100644 src/libelf/elf_hash.c delete mode 100644 src/libelf/elf_kind.c delete mode 100644 src/libelf/elf_memory.c delete mode 100644 src/libelf/elf_next.c delete mode 100644 src/libelf/elf_open.c delete mode 100644 src/libelf/elf_phnum.c delete mode 100644 src/libelf/elf_rand.c delete mode 100644 src/libelf/elf_rawfile.c delete mode 100644 src/libelf/elf_scn.c delete mode 100644 src/libelf/elf_shnum.c delete mode 100644 src/libelf/elf_shstrndx.c delete mode 100644 src/libelf/elf_strptr.c delete mode 100644 src/libelf/elf_update.c delete mode 100644 src/libelf/elf_version.c delete mode 100644 src/libelf/elfdefinitions.h delete mode 100644 src/libelf/gelf.h delete mode 100644 src/libelf/gelf_cap.c delete mode 100644 src/libelf/gelf_checksum.c delete mode 100644 src/libelf/gelf_dyn.c delete mode 100644 src/libelf/gelf_ehdr.c delete mode 100644 src/libelf/gelf_fsize.c delete mode 100644 src/libelf/gelf_getclass.c delete mode 100644 src/libelf/gelf_move.c delete mode 100644 src/libelf/gelf_phdr.c delete mode 100644 src/libelf/gelf_rel.c delete mode 100644 src/libelf/gelf_rela.c delete mode 100644 src/libelf/gelf_shdr.c delete mode 100644 src/libelf/gelf_sym.c delete mode 100644 src/libelf/gelf_syminfo.c delete mode 100644 src/libelf/gelf_symshndx.c delete mode 100644 src/libelf/gelf_xlate.c delete mode 100644 src/libelf/libelf.h delete mode 100644 src/libelf/libelf_align.c delete mode 100644 src/libelf/libelf_allocate.c delete mode 100644 src/libelf/libelf_ar.c delete mode 100644 src/libelf/libelf_ar_util.c delete mode 100644 src/libelf/libelf_checksum.c delete mode 100644 src/libelf/libelf_convert.c delete mode 100644 src/libelf/libelf_data.c delete mode 100644 src/libelf/libelf_ehdr.c delete mode 100644 src/libelf/libelf_extended.c delete mode 100644 src/libelf/libelf_fsize.c delete mode 100644 src/libelf/libelf_memory.c delete mode 100644 src/libelf/libelf_msize.c delete mode 100644 src/libelf/libelf_open.c delete mode 100644 src/libelf/libelf_phdr.c delete mode 100644 src/libelf/libelf_shdr.c delete mode 100644 src/libelf/libelf_xlate.c delete mode 100644 src/link.ld delete mode 160000 src/mocha delete mode 100644 src/mykernel/kernel_defs.h delete mode 100644 src/mykernel/kernel_utils.c delete mode 100644 src/mykernel/kernel_utils.h delete mode 100644 src/mykernel/syscalls.h delete mode 100644 src/mykernel/syscalls_asm.s delete mode 100644 src/mymemory/memory_mapping.cpp delete mode 100644 src/mymemory/memory_mapping.h delete mode 100644 src/myutils/ConfigInformation.cpp delete mode 100644 src/myutils/ConfigInformation.h delete mode 100644 src/myutils/ConfigUtils.cpp delete mode 100644 src/myutils/ConfigUtils.h delete mode 100644 src/myutils/ScreenUtils.cpp delete mode 100644 src/myutils/ScreenUtils.h delete mode 100644 src/myutils/libfat.cpp delete mode 100644 src/myutils/libfat.h delete mode 100644 src/myutils/libntfs.cpp delete mode 100644 src/myutils/libntfs.h delete mode 100644 src/myutils/mem_utils.cpp delete mode 100644 src/myutils/mocha.cpp delete mode 100644 src/myutils/mocha.h delete mode 100644 src/myutils/overlay_helper.cpp delete mode 100644 src/myutils/overlay_helper.h delete mode 100644 src/myutils/texture_utils.cpp delete mode 100644 src/myutils/texture_utils.h delete mode 100644 src/patcher/function_patcher.cpp delete mode 100644 src/patcher/function_patcher.h delete mode 100644 src/patcher/hooks_patcher.cpp delete mode 100644 src/patcher/hooks_patcher.h delete mode 100644 src/patcher/hooks_patcher_static.cpp delete mode 100644 src/patcher/hooks_patcher_static.h delete mode 100644 src/plugin/DynamicLinkingHelper.cpp delete mode 100644 src/plugin/DynamicLinkingHelper.h delete mode 100644 src/plugin/ElfTools.cpp delete mode 100644 src/plugin/ElfTools.h delete mode 100644 src/plugin/ImportRPLInformation.h delete mode 100644 src/plugin/PluginData.cpp delete mode 100644 src/plugin/PluginData.h delete mode 100644 src/plugin/PluginInformation.cpp delete mode 100644 src/plugin/RelocationData.h delete mode 100644 src/plugin/dynamic_linking_defines.h create mode 100644 src/resources/Resources.cpp create mode 100644 src/resources/Resources.h delete mode 100644 src/resources/filelist.cpp create mode 100644 src/system/AsyncDeleter.cpp create mode 100644 src/system/AsyncDeleter.h rename src/{plugin/FunctionData.h => system/CMutex.h} (52%) create mode 100644 src/system/CThread.h create mode 100644 src/system/memory.c rename src/{plugin/HookData.h => system/memory.h} (60%) delete mode 100644 src/utils.cpp delete mode 100644 src/utils.h create mode 100644 src/utils/StringTools.cpp create mode 100644 src/utils/StringTools.h rename src/{myutils => utils}/TcpReceiver.cpp (85%) rename src/{myutils => utils}/TcpReceiver.h (96%) create mode 100644 src/utils/ipcclient.cpp create mode 100644 src/utils/ipcclient.h create mode 100644 src/utils/logger.c create mode 100644 src/utils/logger.h create mode 100644 src/utils/net.c create mode 100644 src/utils/net.h create mode 100644 src/utils/utils.c create mode 100644 src/utils/utils.h diff --git a/.gitignore b/.gitignore index 065103d..fdfb2d7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,6 @@ -build/* -*.cbp +build/ +*.rpx *.elf -*.cscope_file_list -*.layout -screenshots/* -release/* -*.mod -*.id* -*.nam -*.til -*.layout \ No newline at end of file +*.exe +src/resources/filelist.h +*.cbp diff --git a/.gitmodules b/.gitmodules index 3667759..e69de29 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +0,0 @@ -[submodule "src/mocha"] - path = src/mocha - url = https://github.com/Maschell/mocha - branch = sd_access diff --git a/Makefile b/Makefile index e026497..e214d13 100644 --- a/Makefile +++ b/Makefile @@ -1,270 +1,164 @@ -DO_LOGGING := 1 - -#--------------------------------------------------------------------------------- -# Clear the implicit built in rules -#--------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- .SUFFIXES: -#--------------------------------------------------------------------------------- -ifeq ($(strip $(DEVKITPPC)),) -$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") -endif +#------------------------------------------------------------------------------- + ifeq ($(strip $(DEVKITPRO)),) -$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") +$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=/devkitpro") endif -export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH):$(DEVKITPRO)/tools/bin -export PORTLIBS := $(DEVKITPRO)/portlibs/ppc +TOPDIR ?= $(CURDIR) -PREFIX := powerpc-eabi- +include $(DEVKITPRO)/wut/share/wut_rules -export AS := $(PREFIX)as -export CC := $(PREFIX)gcc -export CXX := $(PREFIX)g++ -export AR := $(PREFIX)ar -export OBJCOPY := $(PREFIX)objcopy - -print-% : ; @echo $* = $($*) - -#--------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- # TARGET is the name of the output # BUILD is the directory where object files & intermediate files will be placed # SOURCES is a list of directories containing source code -# INCLUDES is a list of directories containing extra header files -#--------------------------------------------------------------------------------- -TARGET := wiiupluginloader -BUILD := build -BUILD_DBG := $(TARGET)_dbg -SOURCES := src/common \ - src/custom/gui \ - src/libelf \ - src/menu/content \ - src/menu \ - src/mymemory \ - src/mykernel \ - src/myutils \ - src/patcher \ - src/plugin \ - src/resources \ - src/settings \ - src/ +# DATA is a list of directories containing data files +# INCLUDES is a list of directories containing header files +#------------------------------------------------------------------------------- +TARGET := $(notdir $(CURDIR)) +BUILD := build +SOURCES := src \ + src/custom/gui \ + src/fs \ + src/game \ + src/plugin \ + src/language \ + src/menu \ + src/menu/content \ + src/resources \ + src/settings \ + src/system \ + src/utils +DATA := data \ + data/images \ + data/sounds \ + data/fonts +INCLUDES := src -DATA := data/images \ - data/sounds \ - data/fonts \ - -INCLUDES := src/libelf \ - src/ - -#--------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- # options for code generation -#--------------------------------------------------------------------------------- -CFLAGS := -std=gnu11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \ - -O0 -D__wiiu__ -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing -D_GNU_SOURCE $(INCLUDE) -CXXFLAGS := -std=gnu++11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \ - -O0 -D__wiiu__ -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing -D_GNU_SOURCE $(INCLUDE) +#------------------------------------------------------------------------------- +CFLAGS := -g -Wall -O2 -ffunction-sections \ + $(MACHDEP) -ifeq ($(DO_LOGGING), 1) - CFLAGS += -D__LOGGING__ - CXXFLAGS += -D__LOGGING__ -endif +CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__ -ASFLAGS := -mregnames -LDFLAGS := -nostartfiles -Wl,-Map,$(notdir $@).map,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r,-wrap,valloc,-wrap,_valloc_r,-wrap,_pvalloc_r,--gc-sections +CXXFLAGS := $(CFLAGS) -#--------------------------------------------------------------------------------- -Q := @ -MAKEFLAGS += --no-print-directory -#--------------------------------------------------------------------------------- -# any extra libraries we wish to link with the project -#--------------------------------------------------------------------------------- -LIBS := -lgui -lm -lgcc -lfat -liosuhax -lutils -ldynamiclibs -lfreetype -lgd -lpng -ljpeg -lz -lmad -lvorbisidec -logg -lbz2 +ASFLAGS := -g $(ARCH) +LDFLAGS = -g $(ARCH) $(RPXSPECS) -Wl,-Map,$(notdir $*.map) -#--------------------------------------------------------------------------------- -# list of directories containing libraries, this must be the top level containing -# include and lib -#--------------------------------------------------------------------------------- -LIBDIRS := $(CURDIR) \ - $(DEVKITPPC)/lib \ - $(DEVKITPRO)/wups +LIBS := -lgui -lfreetype -lgd -lpng -ljpeg -lz -lmad -lvorbisidec -logg -lbz2 -lwut -#--------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level +# containing include and lib +#------------------------------------------------------------------------------- +LIBDIRS := $(PORTLIBS) $(WUT_ROOT) + +#------------------------------------------------------------------------------- # no real need to edit anything past this point unless you need to add additional # rules for different file extensions -#--------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- ifneq ($(BUILD),$(notdir $(CURDIR))) -#--------------------------------------------------------------------------------- -export PROJECTDIR := $(CURDIR) -export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET) -export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ - $(foreach dir,$(DATA),$(CURDIR)/$(dir)) -export DEPSDIR := $(CURDIR)/$(BUILD) - -#--------------------------------------------------------------------------------- -# automatically build a list of object files for our project -#--------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- FILELIST := $(shell bash ./filelist.sh) -LANGUAGES := $(shell bash ./updatelang.sh) -CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) -CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) -sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) -SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) -BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) -TTFFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.ttf))) -PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) - -#--------------------------------------------------------------------------------- -# use CXX for linking C++ projects, CC for standard C -#--------------------------------------------------------------------------------- -ifeq ($(strip $(CPPFILES)),) - export LD := $(CC) -else - export LD := $(CXX) -endif - -export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ - $(sFILES:.s=.o) $(SFILES:.S=.o) \ - $(PNGFILES:.png=.png.o) $(addsuffix .o,$(BINFILES)) - -#--------------------------------------------------------------------------------- -# build a list of include paths -#--------------------------------------------------------------------------------- -export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ - $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ - -I$(PORTLIBS)/include -I$(CURDIR)/$(BUILD) \ - -I$(PORTLIBS)/include/libutils \ - -I$(PORTLIBS)/include/freetype2 -I$(PORTLIBS)/include/libgui - - -#--------------------------------------------------------------------------------- -# build a list of library paths -#--------------------------------------------------------------------------------- -export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ - -L$(PORTLIBS)/lib export OUTPUT := $(CURDIR)/$(TARGET) -.PHONY: $(BUILD) clean install +export TOPDIR := $(CURDIR) -#--------------------------------------------------------------------------------- -$(BUILD): $(CURDIR)/src/mocha/ios_kernel/ios_kernel.bin.h +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#------------------------------------------------------------------------------- + export LD := $(CC) +#------------------------------------------------------------------------------- +else +#------------------------------------------------------------------------------- + export LD := $(CXX) +#------------------------------------------------------------------------------- +endif +#------------------------------------------------------------------------------- + +export OFILES_BIN := $(addsuffix .o,$(BINFILES)) +export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) +export OFILES := $(OFILES_BIN) $(OFILES_SRC) +export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES))) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) -I$(PORTLIBS_PATH)/ppc/include/freetype2 + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +.PHONY: $(BUILD) clean all + +#------------------------------------------------------------------------------- +all: $(BUILD) + +$(BUILD): @[ -d $@ ] || mkdir -p $@ @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile -$(CURDIR)/src/mocha/ios_kernel/ios_kernel.bin.h: $(CURDIR)/src/mocha/ios_usb/ios_usb.bin.h $(CURDIR)/src/mocha/ios_mcp/ios_mcp.bin.h $(CURDIR)/src/mocha/ios_fs/ios_fs.bin.h $(CURDIR)/src/mocha/ios_bsp/ios_bsp.bin.h $(CURDIR)/src/mocha/ios_acp/ios_acp.bin.h - @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/src/mocha/ios_kernel -f $(CURDIR)/src/mocha/ios_kernel/Makefile - -$(CURDIR)/src/mocha/ios_usb/ios_usb.bin.h: - @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/src/mocha/ios_usb -f $(CURDIR)/src/mocha/ios_usb/Makefile - -$(CURDIR)/src/mocha/ios_fs/ios_fs.bin.h: - @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/src/mocha/ios_fs -f $(CURDIR)/src/mocha/ios_fs/Makefile - -$(CURDIR)/src/mocha/ios_bsp/ios_bsp.bin.h: - @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/src/mocha/ios_bsp -f $(CURDIR)/src/mocha/ios_bsp/Makefile - -$(CURDIR)/src/mocha/ios_mcp/ios_mcp.bin.h: - @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/src/mocha/ios_mcp -f $(CURDIR)/src/mocha/ios_mcp/Makefile - -$(CURDIR)/src/mocha/ios_acp/ios_acp.bin.h: - @$(MAKE) -j1 --no-print-directory -C $(CURDIR)/src/mocha/ios_acp -f $(CURDIR)/src/mocha/ios_acp/Makefile - -#--------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- clean: @echo clean ... - @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf - @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_kernel -f $(CURDIR)/src/mocha/ios_kernel/Makefile clean - @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_usb -f $(CURDIR)/src/mocha/ios_usb/Makefile clean - @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_fs -f $(CURDIR)/src/mocha/ios_fs/Makefile clean - @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_bsp -f $(CURDIR)/src/mocha/ios_bsp/Makefile clean - @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_mcp -f $(CURDIR)/src/mocha/ios_mcp/Makefile clean - @$(MAKE) --no-print-directory -C $(CURDIR)/src/mocha/ios_acp -f $(CURDIR)/src/mocha/ios_acp/Makefile clean + @rm -fr $(BUILD) $(TARGET).rpx $(TARGET).elf -#--------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- else +.PHONY: all DEPENDS := $(OFILES:.o=.d) -#--------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- # main targets -#--------------------------------------------------------------------------------- -$(OUTPUT).elf: $(OFILES) +#------------------------------------------------------------------------------- +all : $(OUTPUT).rpx -#--------------------------------------------------------------------------------- -# This rule links in binary data with the .jpg extension -#--------------------------------------------------------------------------------- -%.elf: link.ld $(OFILES) - @echo "linking ... $(TARGET).elf" - $(Q)$(LD) -n -T $^ $(LDFLAGS) -o ../$(BUILD_DBG).elf $(LIBPATHS) $(LIBS) - $(Q)$(OBJCOPY) -S -R .comment -R .gnu.attributes ../$(BUILD_DBG).elf $@ +$(OUTPUT).rpx : $(OUTPUT).elf +$(OUTPUT).elf : $(OFILES) -#--------------------------------------------------------------------------------- -%.a: -#--------------------------------------------------------------------------------- - @echo $(notdir $@) - @rm -f $@ - @$(AR) -rc $@ $^ +$(OFILES_SRC) : $(HFILES_BIN) -#--------------------------------------------------------------------------------- -%.o: %.cpp +#------------------------------------------------------------------------------- +# you need a rule like this for each extension you use as binary data +#------------------------------------------------------------------------------- +%.bin.o %_bin.h : %.bin @echo $(notdir $<) - @$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER) + @$(bin2o) -#--------------------------------------------------------------------------------- -%.o: %.c +%.png.o %_png.h : %.png @echo $(notdir $<) - @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) -c $< -o $@ $(ERROR_FILTER) - -#--------------------------------------------------------------------------------- -%.o: %.S - @echo $(notdir $<) - @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ $(ERROR_FILTER) + @$(bin2o) -#--------------------------------------------------------------------------------- -%.o: %.s +%.ogg.o %_ogg.h : %.ogg @echo $(notdir $<) - @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ $(ERROR_FILTER) - -#--------------------------------------------------------------------------------- -%.png.o : %.png + @$(bin2o) + +%.mp3.o %_mp3.h : %.mp3 @echo $(notdir $<) - @bin2s -a 32 $< | $(AS) -o $(@) - -#--------------------------------------------------------------------------------- -%.jpg.o : %.jpg + @$(bin2o) + +%.ttf.o %_ttf.h : %.ttf @echo $(notdir $<) - @bin2s -a 32 $< | $(AS) -o $(@) - -#--------------------------------------------------------------------------------- -%.ttf.o : %.ttf - @echo $(notdir $<) - @bin2s -a 32 $< | $(AS) -o $(@) - -#--------------------------------------------------------------------------------- -%.bin.o : %.bin - @echo $(notdir $<) - @bin2s -a 32 $< | $(AS) -o $(@) - -#--------------------------------------------------------------------------------- -%.wav.o : %.wav - @echo $(notdir $<) - @bin2s -a 32 $< | $(AS) -o $(@) - -#--------------------------------------------------------------------------------- -%.mp3.o : %.mp3 - @echo $(notdir $<) - @bin2s -a 32 $< | $(AS) -o $(@) - -#--------------------------------------------------------------------------------- -%.ogg.o : %.ogg - @echo $(notdir $<) - @bin2s -a 32 $< | $(AS) -o $(@) - -#--------------------------------------------------------------------------------- -%.tga.o : %.tga - @echo $(notdir $<) - @bin2s -a 32 $< | $(AS) -o $(@) + @$(bin2o) -include $(DEPENDS) -#--------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- endif -#--------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- diff --git a/filelist.sh b/filelist.sh index 9d3867d..15addd3 100644 --- a/filelist.sh +++ b/filelist.sh @@ -3,7 +3,7 @@ # Automatic resource file list generation # Created by Dimok -outFile="./src/resources/filelist.cpp" +outFile="./src/resources/filelist.h" count_old=$(cat $outFile 2>/dev/null | tr -d '\n\n' | sed 's/[^0-9]*\([0-9]*\).*/\1/') count=0 @@ -29,18 +29,27 @@ fi if [ "$count_old" != "$count" ] || [ ! -f $outFile ] then -echo "Generating filelist.c for $count files." >&2 +echo "Generating filelist.h for $count files." >&2 cat < $outFile /**************************************************************************** - * Resource files. + * Loadiine resource files. * This file is generated automatically. * Includes $count files. * * NOTE: * Any manual modification of this file will be overwriten by the generation. - *****************************************************************************/ -#include -#include + ****************************************************************************/ +#ifndef _FILELIST_H_ +#define _FILELIST_H_ + +typedef struct _RecourceFile +{ + const char *filename; + const unsigned char *DefaultFile; + const unsigned int &DefaultFileSize; + unsigned char *CustomFile; + unsigned int CustomFileSize; +} RecourceFile; EOF @@ -48,12 +57,12 @@ for i in ${files[@]} do filename=${i%.*} extension=${i##*.} - echo 'extern const uint8_t '$filename'_'$extension'[];' >> $outFile - echo 'extern const uint32_t '$filename'_'$extension'_size;' >> $outFile + echo 'extern const unsigned char '$filename'_'$extension'[];' >> $outFile + echo 'extern const unsigned int '$filename'_'$extension'_size;' >> $outFile echo '' >> $outFile done -echo 'static ResourceFile ResourceList[] =' >> $outFile +echo 'static RecourceFile RecourceList[] =' >> $outFile echo '{' >> $outFile for i in ${files[@]} @@ -65,7 +74,8 @@ done echo -e '\t{NULL, NULL, 0, NULL, 0}' >> $outFile echo '};' >> $outFile + echo '' >> $outFile -echo 'ResourceFile * getResourceList(){ return ResourceList; }' >> $outFile -echo '' >> $outFile +echo '#endif' >> $outFile + fi diff --git a/installupdateportlibs.sh b/installupdateportlibs.sh deleted file mode 100644 index 6f6d891..0000000 --- a/installupdateportlibs.sh +++ /dev/null @@ -1,19 +0,0 @@ -#! /bin/bash -# -7z x -y ./libs/portlibs.zip -o${DEVKITPRO} -mkdir portlib_repos -cd portlib_repos -((git clone https://github.com/Maschell/dynamic_libs.git -b lib && (7z x -y ./dynamic_libs/libs/portlibs.zip -o${DEVKITPRO})) || (cd dynamic_libs && git pull)) -(git clone https://github.com/dimok789/libiosuhax.git || (cd libiosuhax && git pull)) -(git clone https://github.com/Maschell/libfat.git || (cd libfat && git pull)) -(git clone https://github.com/Maschell/libutils.git || (cd libutils && git pull)) -((git clone https://github.com/Maschell/libgui.git && (7z x -y ./libgui/libs/portlibs.zip -o${DEVKITPRO})) || (cd libgui && git pull)) -(git clone https://github.com/Maschell/fs_wrapper.git || (cd fs_wrapper && git pull)) -(git clone https://github.com/Maschell/controller_patcher.git || (cd controller_patcher && git pull)) -(cd dynamic_libs && ((make -j8 | grep -c "built ... ") && make install && echo "installed" ) || (echo "no need for make install" && make)) -(cd libiosuhax && make -j8 && make install) -(cd libfat && make wiiu-release && make wiiu-install) -(cd libutils && ((make -j8 | grep -c "built ... ") && make install && echo "installed" ) || (echo "no need for make install" && make)) -(cd libgui && ((make -j8 | grep -c "built ... ") && make install) || echo "no need for make install") -(cd fs_wrapper && ((make -j8 | grep -c "built ... ") && make install && echo "installed" ) || (echo "no need for make install" && make)) -(cd controller_patcher && ((make -j8 | grep -c "built ... ") && make install && echo "installed" ) || (echo "no need for make install" && make)) diff --git a/libs/portlibs.zip b/libs/portlibs.zip deleted file mode 100644 index d2a9905812cd0286c3a51cbcbecd5babc8f0d015..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38349 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 L0sxzdKU@C;&lER! diff --git a/src/Application.cpp b/src/Application.cpp index da15b99..96a989d 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -17,41 +17,46 @@ ****************************************************************************/ #include "Application.h" #include "common/common.h" -#include +#include +#include +#include +#include #include #include #include +#include "system/memory.h" #include "resources/Resources.h" -#include +#include #include #include "settings/CSettings.h" -#include "myutils/TcpReceiver.h" -#include "mymemory/memory_mapping.h" +#include "utils/TcpReceiver.h" Application *Application::applicationInstance = NULL; bool Application::exitApplication = false; +bool Application::quitRequest = false; Application::Application() : CThread(CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff, 0, 0x20000) , bgMusic(NULL) , video(NULL) , mainWindow(NULL) - , exitCode(EXIT_RELAUNCH_ON_LOAD) { + , fontSystem(NULL) + , exitCode(0) { controller[0] = new VPadController(GuiTrigger::CHANNEL_1); controller[1] = new WPadController(GuiTrigger::CHANNEL_2); controller[2] = new WPadController(GuiTrigger::CHANNEL_3); controller[3] = new WPadController(GuiTrigger::CHANNEL_4); controller[4] = new WPadController(GuiTrigger::CHANNEL_5); - CSettings::instance()->Load(); - //! create bgMusic bgMusic = new GuiSound(Resources::GetFile("bgMusic.mp3"), Resources::GetFileSize("bgMusic.mp3")); - - //! load language - loadLanguageFromConfig(); + bgMusic->SetLoop(true); + bgMusic->Play(); + bgMusic->SetVolume(50); exitApplication = false; + + ProcUIInit(OSSavesDone_ReadyToRelease); } Application::~Application() { @@ -70,7 +75,7 @@ Application::~Application() { AsyncDeleter::triggerDeleteProcess(); while(!AsyncDeleter::realListEmpty()) { DEBUG_FUNCTION_LINE("Waiting...\n"); - os_usleep(1000); + OSSleepTicks(OSMicrosecondsToTicks(1000)); } } while(!AsyncDeleter::deleteListEmpty()); AsyncDeleter::destroyInstance(); @@ -80,6 +85,8 @@ Application::~Application() { DEBUG_FUNCTION_LINE("Stop sound handler\n"); SoundHandler::DestroyInstance(); + + ProcUIShutdown(); } int32_t Application::exec() { @@ -91,15 +98,12 @@ int32_t Application::exec() { return exitCode; } -void Application::reloadUI() { - reloadUIflag = true; -} void Application::fadeOut() { GuiImage fadeOut(video->getTvWidth(), video->getTvHeight(), (GX2Color) { 0, 0, 0, 255 }); - for(int32_t i = 0; i < 255; i += 10) { + for(int i = 0; i < 255; i += 10) { if(i > 255) i = 255; @@ -109,9 +113,9 @@ void Application::fadeOut() { video->prepareDrcRendering(); mainWindow->drawDrc(video); - GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_ALWAYS); + GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_FUNC_ALWAYS); fadeOut.draw(video); - GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_LEQUAL); + GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_FUNC_LEQUAL); video->drcDrawDone(); @@ -120,9 +124,9 @@ void Application::fadeOut() { mainWindow->drawTv(video); - GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_ALWAYS); + GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_FUNC_ALWAYS); fadeOut.draw(video); - GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_LEQUAL); + GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_FUNC_LEQUAL); video->tvDrawDone(); @@ -142,109 +146,151 @@ void Application::fadeOut() { video->drcEnable(false); } -void Application::executeThread(void) { - DEBUG_FUNCTION_LINE("Initialize video\n"); - video = new CVideo(GX2_TV_SCAN_MODE_720P, GX2_DRC_SINGLE); +bool Application::procUI(void) { + bool executeProcess = false; - DEBUG_FUNCTION_LINE("Video size %i x %i\n", video->getTvWidth(), video->getTvHeight()); - - //! setup default Font - DEBUG_FUNCTION_LINE("Initialize main font system\n"); - FreeTypeGX *fontSystem = new FreeTypeGX(Resources::GetFile("font.ttf"), Resources::GetFileSize("font.ttf"), true); - GuiText::setPresetFont(fontSystem); - - reloadUIflag = true; - if(bgMusic != NULL) { - bgMusic->SetLoop(true); - bgMusic->SetVolume(50); - bgMusic->Stop(); //CHANG MEEEEEEEEEEEEEEEEEEE + switch(ProcUIProcessMessages(true)) { + case PROCUI_STATUS_EXITING: { + DEBUG_FUNCTION_LINE("PROCUI_STATUS_EXITING\n"); + exitCode = EXIT_SUCCESS; + exitApplication = true; + break; } + case PROCUI_STATUS_RELEASE_FOREGROUND: { + DEBUG_FUNCTION_LINE("PROCUI_STATUS_RELEASE_FOREGROUND\n"); + if(video != NULL) { + // we can turn of the screen but we don't need to and it will display the last image + video->tvEnable(true); + video->drcEnable(true); + DEBUG_FUNCTION_LINE("delete fontSystem\n"); + delete fontSystem; + fontSystem = NULL; - while(reloadUIflag) { - reloadUIflag = false; - exitCode = EXIT_RELAUNCH_ON_LOAD; - DEBUG_FUNCTION_LINE("Initialize the language\n"); - loadLanguageFromConfig(); - DEBUG_FUNCTION_LINE("Initialize main window\n"); - mainWindow = MainWindow::getInstance(video->getTvWidth(), video->getTvHeight()); + DEBUG_FUNCTION_LINE("delete video\n"); + delete video; + video = NULL; - exitApplication = false; - //! main GX2 loop (60 Hz cycle with max priority on core 1) - - DEBUG_FUNCTION_LINE("Starting TcpReceiver\n"); - TcpReceiver pluginReceiver(4299); - DEBUG_FUNCTION_LINE("Entering main loop\n"); - while(!exitApplication && !reloadUIflag) { - //! Read out inputs - for(int32_t i = 0; i < 5; i++) { - if(controller[i]->update(video->getTvWidth(), video->getTvHeight()) == false) - continue; - - if(controller[i]->data.buttons_d & VPAD_BUTTON_PLUS) { - exitCode = APPLICATION_CLOSE_APPLY; - if(linkPluginsCallback != NULL) { - bool result = linkPluginsCallback(); - if(!result) { - // On linking errors return to the HBL. -#warning TODO: proper error handling when linking fails. - exitCode = APPLICATION_CLOSE_MIIMAKER; - } - } - exitApplication = true; - } - - if(controller[i]->data.buttons_d & VPAD_BUTTON_MINUS) { - exitCode = APPLICATION_CLOSE_APPLY_MEMORY; - exitApplication = true; - } - - if(controller[i]->data.buttons_d & VPAD_BUTTON_HOME) { - exitCode = APPLICATION_CLOSE_MIIMAKER; - exitApplication = true; - } - - //! update controller states - mainWindow->update(controller[i]); - } - mainWindow->process(); - - //! start rendering DRC - video->prepareDrcRendering(); - mainWindow->drawDrc(video); - video->drcDrawDone(); - - //! start rendering TV - video->prepareTvRendering(); - mainWindow->drawTv(video); - video->tvDrawDone(); - - //! enable screen after first frame render - if(video->getFrameCount() == 0) { - video->tvEnable(true); - video->drcEnable(true); - } - - - //! as last point update the effects as it can drop elements - mainWindow->updateEffects(); - - video->waitForVSync(); - - //! transfer elements to real delete list here after all processes are finished - //! the elements are transfered to another list to delete the elements in a separate thread - //! and avoid blocking the GUI thread - AsyncDeleter::triggerDeleteProcess(); + DEBUG_FUNCTION_LINE("deinitialze memory\n"); + memoryRelease(); + ProcUIDrawDoneRelease(); + } else { + ProcUIDrawDoneRelease(); } - DEBUG_FUNCTION_LINE("Fading out\n"); - fadeOut(); - DEBUG_FUNCTION_LINE("Destroying the MainWindow\n"); - MainWindow::destroyInstance(); + break; } - DEBUG_FUNCTION_LINE("Delete fontSystem\n"); + case PROCUI_STATUS_IN_FOREGROUND: { + if(!quitRequest) { + if(video == NULL) { + DEBUG_FUNCTION_LINE("PROCUI_STATUS_IN_FOREGROUND\n"); + DEBUG_FUNCTION_LINE("initialze memory\n"); + memoryInitialize(); + + DEBUG_FUNCTION_LINE("Initialize video\n"); + video = new CVideo(GX2_TV_SCAN_MODE_720P, GX2_DRC_RENDER_MODE_SINGLE); + DEBUG_FUNCTION_LINE("Video size %i x %i\n", video->getTvWidth(), video->getTvHeight()); + + //! setup default Font + DEBUG_FUNCTION_LINE("Initialize main font system\n"); + FreeTypeGX *fontSystem = new FreeTypeGX(Resources::GetFile("font.ttf"), Resources::GetFileSize("font.ttf"), true); + GuiText::setPresetFont(fontSystem); + + if(mainWindow == NULL) { + DEBUG_FUNCTION_LINE("Initialize main window\n"); + Application::loadLanguageFromConfig(); + mainWindow = MainWindow::getInstance(video->getTvWidth(), video->getTvHeight()); + } + + } + executeProcess = true; + } + break; + } + case PROCUI_STATUS_IN_BACKGROUND: + default: + break; + } + + return executeProcess; +} + +void Application::executeThread(void) { + DEBUG_FUNCTION_LINE("Entering main loop\n"); + + //! main GX2 loop (60 Hz cycle with max priority on core 1) + while(!exitApplication) { + if(procUI() == false) + continue; + + //! Read out inputs + for(int i = 0; i < 5; i++) { + if(controller[i]->update(video->getTvWidth(), video->getTvHeight()) == false) + continue; + + if(controller[i]->data.buttons_d & VPAD_BUTTON_PLUS) { + if(linkPluginsCallback != NULL) { + bool result = linkPluginsCallback(); + if(!result) { + // On linking errors return to the HBL. +#warning TODO: proper error handling when linking fails. + } + } + SYSLaunchMenu(); + //quit(0); + } + + //! update controller states + mainWindow->update(controller[i]); + } + + mainWindow->process(); + + //! start rendering DRC + video->prepareDrcRendering(); + mainWindow->drawDrc(video); + video->drcDrawDone(); + + //! start rendering TV + video->prepareTvRendering(); + mainWindow->drawTv(video); + video->tvDrawDone(); + + //! enable screen after first frame render + if(video->getFrameCount() == 0) { + video->tvEnable(true); + video->drcEnable(true); + } + + //! as last point update the effects as it can drop elements + mainWindow->updateEffects(); + + video->waitForVSync(); + + //! transfer elements to real delete list here after all processes are finished + //! the elements are transfered to another list to delete the elements in a separate thread + //! and avoid blocking the GUI thread + AsyncDeleter::triggerDeleteProcess(); + } + + //! in case we exit to a homebrew let's smoothly fade out + if(video) { + fadeOut(); + } + + DEBUG_FUNCTION_LINE("delete mainWindow\n"); + MainWindow::destroyInstance(); + mainWindow = NULL; + + DEBUG_FUNCTION_LINE("delete fontSystem\n"); delete fontSystem; - DEBUG_FUNCTION_LINE("Delete video\n"); + fontSystem = NULL; + + DEBUG_FUNCTION_LINE("delete video\n"); delete video; + video = NULL; + + DEBUG_FUNCTION_LINE("deinitialze memory\n"); + memoryRelease(); } void Application::loadLanguageFromConfig() { diff --git a/src/Application.h b/src/Application.h index 0d5f33d..0a731d7 100644 --- a/src/Application.h +++ b/src/Application.h @@ -20,8 +20,9 @@ #include "menu/MainWindow.h" #include -#include