diff --git a/.travis.yml b/.travis.yml index 9d239d5..5912994 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,7 @@ before_install: - wget https://download.sourceforge.net/devkitpro/devkitARM_r47-x86_64-linux.tar.bz2 -O devkitARM-linux.tar.bz2 - wget https://github.com/Maschell/dynamic_libs/archive/lib.tar.gz -O dynamic_libs.tar.gz - wget https://github.com/Maschell/libutils/archive/master.tar.gz -O libutils.tar.gz + - wget https://github.com/Maschell/libgui/archive/master.tar.gz -O libgui.tar.gz - wget https://github.com/aliaspider/libfat/archive/master.tar.gz -O libfat.tar.gz - wget https://github.com/dimok789/libiosuhax/archive/master.tar.gz -O libiosuhax.tar.gz - wget https://github.com/Maschell/libntfs-wiiu/archive/master.tar.gz -O libntfs.tar.gz @@ -36,6 +37,7 @@ install: - tar -xjf devkitARM-linux.tar.bz2 -C ${DEVKITPRO}/ - tar -xzvf dynamic_libs.tar.gz - tar -xzvf libutils.tar.gz + - tar -xzvf libgui.tar.gz - tar -xzvf libfat.tar.gz - tar -xzvf libiosuhax.tar.gz - tar -xzvf libntfs.tar.gz @@ -48,6 +50,7 @@ install: - (cd libntfs-wiiu-master && make wiiu-install) - (cd dynamic_libs-lib && make -j8 && make install) - (cd libutils-master && make -j8 && make install) + - (cd libgui-master && make -j8 && make install) - (cd fs_wrapper-master && make -j8 && make install) - (cd controller_patcher-master && make -j8 && make install) diff --git a/loader/Makefile b/loader/Makefile index 4c95c55..81418bf 100644 --- a/loader/Makefile +++ b/loader/Makefile @@ -33,13 +33,20 @@ print-% : ; @echo $* = $($*) TARGET := wiiupluginloader BUILD := build BUILD_DBG := $(TARGET)_dbg -SOURCES := src/libelf \ -SOURCES := src/patcher \ - src/common \ +SOURCES := src/common \ + src/libelf \ + src/menu/content \ + src/menu \ + src/modules \ src/myutils \ + src/patcher \ + src/resources \ + src/settings \ src/ -DATA := +DATA := data/images \ + data/sounds \ + data/fonts \ INCLUDES := src/libelf \ src/ @@ -66,7 +73,7 @@ MAKEFLAGS += --no-print-directory #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := -lm -lgcc -lfat -lntfs -liosuhax -lutils -ldynamiclibs +LIBS := -lgui -lm -lgcc -lfat -lntfs -liosuhax -lutils -ldynamiclibs -lfreetype -lgd -lpng -ljpeg -lz -lmad -lvorbisidec #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing @@ -93,6 +100,8 @@ 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))) @@ -120,7 +129,8 @@ export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ 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/libutils \ + -I$(PORTLIBS)/include/freetype2 -I$(PORTLIBS)/include/libgui #--------------------------------------------------------------------------------- diff --git a/loader/data/fonts/font.ttf b/loader/data/fonts/font.ttf new file mode 100644 index 0000000..04be6f5 Binary files /dev/null and b/loader/data/fonts/font.ttf differ diff --git a/loader/data/images/GithubIcon.png b/loader/data/images/GithubIcon.png new file mode 100644 index 0000000..f8e08f6 Binary files /dev/null and b/loader/data/images/GithubIcon.png differ diff --git a/loader/data/images/HomeButtonIcon.png b/loader/data/images/HomeButtonIcon.png new file mode 100644 index 0000000..22f528d Binary files /dev/null and b/loader/data/images/HomeButtonIcon.png differ diff --git a/loader/data/images/PlusButtonIcon.png b/loader/data/images/PlusButtonIcon.png new file mode 100644 index 0000000..a58807d Binary files /dev/null and b/loader/data/images/PlusButtonIcon.png differ diff --git a/loader/data/images/TwitterIcon.png b/loader/data/images/TwitterIcon.png new file mode 100644 index 0000000..4f575c9 Binary files /dev/null and b/loader/data/images/TwitterIcon.png differ diff --git a/loader/filelist.sh b/loader/filelist.sh new file mode 100644 index 0000000..ee6f75f --- /dev/null +++ b/loader/filelist.sh @@ -0,0 +1,70 @@ +#! /bin/bash +# +# Automatic resource file list generation +# Created by Dimok + +outFile="./src/resources/filelist.cpp" +count_old=$(cat $outFile 2>/dev/null | tr -d '\n\n' | sed 's/[^0-9]*\([0-9]*\).*/\1/') + +count=0 +if [[ $OSTYPE == darwin* ]]; +then + +for i in $(gfind ./data/images/ ./data/sounds/ ./data/fonts/ -maxdepth 1 -type f \( ! -printf "%f\n" \) | sort -f) +do + files[count]=$i + count=$((count+1)) +done + +else + +for i in $(find ./data/images/ ./data/sounds/ ./data/fonts/ -maxdepth 1 -type f \( ! -printf "%f\n" \) | sort -f) +do + files[count]=$i + count=$((count+1)) +done + +fi + +if [ "$count_old" != "$count" ] || [ ! -f $outFile ] +then + +echo "Generating filelist.c for $count files." >&2 +cat < $outFile +/**************************************************************************** + * Resource files. + * This file is generated automatically. + * Includes $count files. + * + * NOTE: + * Any manual modification of this file will be overwriten by the generation. + *****************************************************************************/ +#include + +EOF + +for i in ${files[@]} +do + filename=${i%.*} + extension=${i##*.} + echo 'extern const u8 '$filename'_'$extension'[];' >> $outFile + echo 'extern const u32 '$filename'_'$extension'_size;' >> $outFile + echo '' >> $outFile +done + +echo 'static ResourceFile ResourceList[] =' >> $outFile +echo '{' >> $outFile + +for i in ${files[@]} +do + filename=${i%.*} + extension=${i##*.} + echo -e '\t{"'$i'", '$filename'_'$extension', '$filename'_'$extension'_size, NULL, 0},' >> $outFile +done + +echo -e '\t{NULL, NULL, 0, NULL, 0}' >> $outFile +echo '};' >> $outFile +echo '' >> $outFile +echo 'ResourceFile * getResourceList(){ return ResourceList; }' >> $outFile +echo '' >> $outFile +fi diff --git a/loader/languages/english.lang b/loader/languages/english.lang new file mode 100644 index 0000000..ed9509b --- /dev/null +++ b/loader/languages/english.lang @@ -0,0 +1,26 @@ +# English translations for Wii U Plugin System loader +# This file is distributed under the same license as the PACKAGE package. +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-05-08 17:13+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/menu/content/ContentHome.cpp:20 +msgid "Welcome to the Wii U plugin loader" +msgstr "" + +#: src/menu/content/ContentHome.cpp:29 +msgid "Exit to HBL " +msgstr "" + +#: src/menu/content/ContentHome.cpp:32 +msgid "Apply Patches" +msgstr "" diff --git a/loader/src/Application.cpp b/loader/src/Application.cpp new file mode 100644 index 0000000..8e5c417 --- /dev/null +++ b/loader/src/Application.cpp @@ -0,0 +1,236 @@ +/**************************************************************************** + * Copyright (C) 2015 Dimok + * Modified by Maschell, 2018 for Wii U Plugin System loader + * + * 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 . + ****************************************************************************/ +#include "Application.h" +#include "common/common.h" +#include +#include +#include +#include +#include "resources/Resources.h" +#include +#include +#include "settings/CSettings.h" + +Application *Application::applicationInstance = NULL; +bool Application::exitApplication = false; + +Application::Application() + : CThread(CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff, 0, 0x20000) + , bgMusic(NULL) + , video(NULL) + , mainWindow(NULL) + , exitCode(EXIT_RELAUNCH_ON_LOAD) +{ + 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(); + + exitApplication = false; +} + +Application::~Application(){ + log_printf("Application::~Application(line %d): Destroy music\n",__LINE__); + delete bgMusic; + + log_printf("Application::~Application(line %d): Destroy controller\n",__LINE__); + + for(s32 i = 0; i < 5; i++) + delete controller[i]; + + //We may have to handle Asyncdelete in the Destructors. + log_printf("Application::~Application(line %d): Destroy async deleter\n",__LINE__); + do{ + log_printf("Application::~Application(line %d): Triggering AsyncDeleter\n",__LINE__); + AsyncDeleter::triggerDeleteProcess(); + while(!AsyncDeleter::realListEmpty()){ + os_usleep(1000); + } + }while(!AsyncDeleter::deleteListEmpty()); + AsyncDeleter::destroyInstance(); + + log_printf("Application::~Application(line %d): Clear resources\n",__LINE__); + Resources::Clear(); + + log_printf("Application::~Application(line %d): Stop sound handler\n",__LINE__); + SoundHandler::DestroyInstance(); + +} + +s32 Application::exec(){ + //! start main GX2 thread + resumeThread(); + //! now wait for thread to finish + shutdownThread(); + + return exitCode; +} + +void Application::reloadUI(){ + reloadUIflag = true; +} +void Application::fadeOut(){ + GuiImage fadeOut(video->getTvWidth(), video->getTvHeight(), (GX2Color){ 0, 0, 0, 255 }); + + for(s32 i = 0; i < 255; i += 10) + { + if(i > 255) + i = 255; + + fadeOut.setAlpha(i / 255.0f); + + //! start rendering DRC + video->prepareDrcRendering(); + mainWindow->drawDrc(video); + + GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_ALWAYS); + fadeOut.draw(video); + GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_LEQUAL); + + video->drcDrawDone(); + + //! start rendering TV + video->prepareTvRendering(); + + mainWindow->drawTv(video); + + GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_ALWAYS); + fadeOut.draw(video); + GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_LEQUAL); + + video->tvDrawDone(); + + //! as last point update the effects as it can drop elements + mainWindow->updateEffects(); + + video->waitForVSync(); + } + + //! one last cleared black screen + video->prepareDrcRendering(); + video->drcDrawDone(); + video->prepareTvRendering(); + video->tvDrawDone(); + video->waitForVSync(); + video->tvEnable(false); + video->drcEnable(false); +} + +void Application::executeThread(void){ + log_printf("Application::executeThread(line %d): Initialize video\n",__LINE__); + video = new CVideo(GX2_TV_SCAN_MODE_720P, GX2_DRC_SINGLE); + + log_printf("Application::executeThread(line %d): Video size %i x %i\n",__LINE__, video->getTvWidth(), video->getTvHeight()); + + //! setup default Font + log_printf("Application::executeThread(line %d): Initialize main font system\n",__LINE__); + 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 + } + + while(reloadUIflag){ + reloadUIflag = false; + exitCode = EXIT_RELAUNCH_ON_LOAD; + log_printf("Application::executeThread(line %d): Initialize the language\n",__LINE__); + loadLanguageFromConfig(); + log_printf("Application::executeThread(line %d): Initialize main window\n",__LINE__); + mainWindow = MainWindow::getInstance(video->getTvWidth(), video->getTvHeight()); + + log_printf("Application::executeThread(line %d): Entering main loop\n",__LINE__); + exitApplication = false; + //! main GX2 loop (60 Hz cycle with max priority on core 1) + while(!exitApplication && !reloadUIflag){ + //! Read out inputs + for(s32 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; + 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("fadeOut\n"); + fadeOut(); + DEBUG_FUNCTION_LINE("MainWindow::destroyInstance();\n"); + MainWindow::destroyInstance(); + } + DEBUG_FUNCTION_LINE("Delete fontSystem\n"); + delete fontSystem; + DEBUG_FUNCTION_LINE("Delete video\n"); + delete video; +} + +void Application::loadLanguageFromConfig(){ + if(!CSettings::getValueAsString(CSettings::AppLanguage).empty()){ + std::string languagePath = std::string(DEFAULT_LANG_PATH) + "/" + CSettings::getValueAsString(CSettings::AppLanguage) + std::string(LANGUAGE_FILE_EXT); + gettextLoadLanguage(languagePath.c_str()); + } +} diff --git a/loader/src/Application.h b/loader/src/Application.h new file mode 100644 index 0000000..a6a083f --- /dev/null +++ b/loader/src/Application.h @@ -0,0 +1,85 @@ +/**************************************************************************** + * Copyright (C) 2015 Dimok + * Modified by Maschell, 2018 for Wii U Plugin System loader + * + * 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 . + ****************************************************************************/ +#ifndef _APPLICATION_H +#define _APPLICATION_H + +#include "menu/MainWindow.h" +#include