diff --git a/Makefile b/Makefile index 1b18435..df15b18 100644 --- a/Makefile +++ b/Makefile @@ -61,7 +61,6 @@ LIBDIRS := $(PORTLIBS) $(WUT_ROOT) $(WUT_ROOT)/usr ifneq ($(BUILD),$(notdir $(CURDIR))) #------------------------------------------------------------------------------- FILELIST := $(shell bash ./filelist.sh) - export OUTPUT := $(CURDIR)/$(TARGET) export TOPDIR := $(CURDIR) @@ -141,17 +140,22 @@ $(OFILES_SRC) : $(HFILES_BIN) @echo $(notdir $<) @$(bin2o) -%.ogg.o %_ogg.h : %.ogg +%.jpg.o %_jpg.h : %.jpg @echo $(notdir $<) @$(bin2o) +%.ogg.o %_ogg.h : %.ogg + @echo $(notdir $<) + @$(bin2o) + %.mp3.o %_mp3.h : %.mp3 @echo $(notdir $<) - @$(bin2o) + @$(bin2o) %.ttf.o %_ttf.h : %.ttf @echo $(notdir $<) - @$(bin2o) + @$(bin2o) + -include $(DEPENDS) diff --git a/filelist.sh b/filelist.sh index 15addd3..5cf6bd0 100755 --- a/filelist.sh +++ b/filelist.sh @@ -32,7 +32,7 @@ then echo "Generating filelist.h for $count files." >&2 cat < $outFile /**************************************************************************** - * Loadiine resource files. + * Resource files. * This file is generated automatically. * Includes $count files. * @@ -57,11 +57,10 @@ for i in ${files[@]} do filename=${i%.*} extension=${i##*.} - echo 'extern const unsigned char '$filename'_'$extension'[];' >> $outFile - echo 'extern const unsigned int '$filename'_'$extension'_size;' >> $outFile - echo '' >> $outFile + echo '#include "'$filename'_'$extension'.h"' >> $outFile done +echo '' >> $outFile echo 'static RecourceFile RecourceList[] =' >> $outFile echo '{' >> $outFile diff --git a/src/Application.cpp b/src/Application.cpp index f22e12f..fa3554c 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -19,14 +19,14 @@ #include #include #include "Application.h" -#include "gui/FreeTypeGX.h" -#include "gui/VPadController.h" -#include "gui/WPadController.h" +#include +#include +#include #include "resources/Resources.h" -#include "gui/sounds/SoundHandler.hpp" +#include #include "system/memory.h" -#include "system/AsyncDeleter.h" #include "utils/logger.h" +#include "utils/AsyncExecutor.h" Application *Application::applicationInstance = NULL; bool Application::exitApplication = false; @@ -61,8 +61,8 @@ Application::~Application() { for (int i = 0; i < 5; i++) delete controller[i]; - AsyncDeleter::destroyInstance(); DEBUG_FUNCTION_LINE("Destroy async deleter"); + AsyncExecutor::destroyInstance(); DEBUG_FUNCTION_LINE("Clear resources"); Resources::Clear(); @@ -240,11 +240,6 @@ void Application::executeThread(void) { 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 diff --git a/src/game/Background.cpp b/src/game/Background.cpp index 146a119..e8301bd 100644 --- a/src/game/Background.cpp +++ b/src/game/Background.cpp @@ -23,7 +23,7 @@ * Constructor for the GuiButton class. */ -Background::Background(char *picture, float scroll_speed) { +Background::Background(const char *picture, float scroll_speed) { loc_x = 0.0f; bgImg = Resources::GetImageData(picture); diff --git a/src/game/Background.h b/src/game/Background.h index ce45cd4..170002b 100644 --- a/src/game/Background.h +++ b/src/game/Background.h @@ -27,7 +27,7 @@ //!Display, manage, and manipulate buttons in the GUI. Buttons can have images, icons, text, and sound set (all of which are optional) class Background : public GuiElement { public: - Background(char *picture, float scroll_speed); + Background(const char *picture, float scroll_speed); virtual ~Background(); diff --git a/src/menu/MainWindow.cpp b/src/menu/MainWindow.cpp index 48b3478..8880b35 100644 --- a/src/menu/MainWindow.cpp +++ b/src/menu/MainWindow.cpp @@ -21,7 +21,7 @@ #include "utils/StringTools.h" #include "utils/logger.h" #include "resources/Resources.h" -#include "system/AsyncDeleter.h" +#include "utils/AsyncExecutor.h" MainWindow::MainWindow(int w, int h) : width(w), height(h) { @@ -184,5 +184,5 @@ void MainWindow::OnOpenEffectFinish(GuiElement *element) { void MainWindow::OnCloseEffectFinish(GuiElement *element) { //! remove element from draw list and push to delete queue remove(element); - AsyncDeleter::pushForDelete(element); + AsyncExecutor::pushForDelete(element); } diff --git a/src/resources/Resources.cpp b/src/resources/Resources.cpp index a1041f2..45e9bb8 100644 --- a/src/resources/Resources.cpp +++ b/src/resources/Resources.cpp @@ -1,44 +1,52 @@ #include #include +#include #include "Resources.h" #include "filelist.h" -#include "system/AsyncDeleter.h" +#include +#include #include "fs/FSUtils.h" -#include "gui/GuiImageAsync.h" -#include "gui/GuiSound.h" +#include "utils/AsyncExecutor.h" -Resources *Resources::instance = NULL; +#include +#include +#include +#include +#include + + +Resources * Resources::instance = NULL; void Resources::Clear() { - for (int i = 0; RecourceList[i].filename != NULL; ++i) { - if (RecourceList[i].CustomFile) { + for(int32_t i = 0; RecourceList[i].filename != NULL; ++i) { + if(RecourceList[i].CustomFile) { free(RecourceList[i].CustomFile); RecourceList[i].CustomFile = NULL; } - if (RecourceList[i].CustomFileSize != 0) + if(RecourceList[i].CustomFileSize != 0) RecourceList[i].CustomFileSize = 0; } - if (instance) + if(instance) delete instance; instance = NULL; } -bool Resources::LoadFiles(const char *path) { - if (!path) +bool Resources::LoadFiles(const char * path) { + if(!path) return false; bool result = false; Clear(); - for (int i = 0; RecourceList[i].filename != NULL; ++i) { + for(int32_t i = 0; RecourceList[i].filename != NULL; ++i) { std::string fullpath(path); fullpath += "/"; fullpath += RecourceList[i].filename; - uint8_t *buffer = NULL; + uint8_t * buffer = NULL; uint32_t filesize = 0; FSUtils::LoadFileToMem(fullpath.c_str(), &buffer, &filesize); @@ -51,9 +59,9 @@ bool Resources::LoadFiles(const char *path) { return result; } -const uint8_t *Resources::GetFile(const char *filename) { - for (int i = 0; RecourceList[i].filename != NULL; ++i) { - if (strcasecmp(filename, RecourceList[i].filename) == 0) { +const uint8_t * Resources::GetFile(const char * filename) { + for(int32_t i = 0; RecourceList[i].filename != NULL; ++i) { + if(strcasecmp(filename, RecourceList[i].filename) == 0) { return (RecourceList[i].CustomFile ? RecourceList[i].CustomFile : RecourceList[i].DefaultFile); } } @@ -61,34 +69,34 @@ const uint8_t *Resources::GetFile(const char *filename) { return NULL; } -uint32_t Resources::GetFileSize(const char *filename) { - for (int i = 0; RecourceList[i].filename != NULL; ++i) { - if (strcasecmp(filename, RecourceList[i].filename) == 0) { +uint32_t Resources::GetFileSize(const char * filename) { + for(int32_t i = 0; RecourceList[i].filename != NULL; ++i) { + if(strcasecmp(filename, RecourceList[i].filename) == 0) { return (RecourceList[i].CustomFile ? RecourceList[i].CustomFileSize : RecourceList[i].DefaultFileSize); } } return 0; } -GuiImageData *Resources::GetImageData(const char *filename) { - if (!instance) +GuiImageData * Resources::GetImageData(const char * filename) { + if(!instance) instance = new Resources; - std::map >::iterator itr = instance->imageDataMap.find(std::string(filename)); - if (itr != instance->imageDataMap.end()) { + std::map >::iterator itr = instance->imageDataMap.find(std::string(filename)); + if(itr != instance->imageDataMap.end()) { itr->second.first++; return itr->second.second; } - for (int i = 0; RecourceList[i].filename != NULL; ++i) { - if (strcasecmp(filename, RecourceList[i].filename) == 0) { - const uint8_t *buff = RecourceList[i].CustomFile ? RecourceList[i].CustomFile : RecourceList[i].DefaultFile; + for(int32_t i = 0; RecourceList[i].filename != NULL; ++i) { + if(strcasecmp(filename, RecourceList[i].filename) == 0) { + const uint8_t * buff = RecourceList[i].CustomFile ? RecourceList[i].CustomFile : RecourceList[i].DefaultFile; const uint32_t size = RecourceList[i].CustomFile ? RecourceList[i].CustomFileSize : RecourceList[i].DefaultFileSize; - if (buff == NULL) + if(buff == NULL) return NULL; - GuiImageData *image = new GuiImageData(buff, size); + GuiImageData * image = new GuiImageData(buff, size); instance->imageDataMap[std::string(filename)].first = 1; instance->imageDataMap[std::string(filename)].second = image; @@ -99,15 +107,16 @@ GuiImageData *Resources::GetImageData(const char *filename) { return NULL; } -void Resources::RemoveImageData(GuiImageData *image) { - std::map >::iterator itr; +void Resources::RemoveImageData(GuiImageData * image) { + std::map >::iterator itr; - for (itr = instance->imageDataMap.begin(); itr != instance->imageDataMap.end(); itr++) { - if (itr->second.second == image) { + for(itr = instance->imageDataMap.begin(); itr != instance->imageDataMap.end(); itr++) { + if(itr->second.second == image) { itr->second.first--; - if (itr->second.first == 0) { - AsyncDeleter::pushForDelete(itr->second.second); + if(itr->second.first == 0) { + AsyncExecutor::pushForDelete(itr->second.second); + instance->imageDataMap.erase(itr); } break; @@ -115,25 +124,25 @@ void Resources::RemoveImageData(GuiImageData *image) { } } -GuiSound *Resources::GetSound(const char *filename) { - if (!instance) +GuiSound * Resources::GetSound(const char * filename) { + if(!instance) instance = new Resources; - std::map >::iterator itr = instance->soundDataMap.find(std::string(filename)); - if (itr != instance->soundDataMap.end()) { + std::map >::iterator itr = instance->soundDataMap.find(std::string(filename)); + if(itr != instance->soundDataMap.end()) { itr->second.first++; return itr->second.second; } - for (int i = 0; RecourceList[i].filename != NULL; ++i) { - if (strcasecmp(filename, RecourceList[i].filename) == 0) { - const uint8_t *buff = RecourceList[i].CustomFile ? RecourceList[i].CustomFile : RecourceList[i].DefaultFile; + for(int32_t i = 0; RecourceList[i].filename != NULL; ++i) { + if(strcasecmp(filename, RecourceList[i].filename) == 0) { + const uint8_t * buff = RecourceList[i].CustomFile ? RecourceList[i].CustomFile : RecourceList[i].DefaultFile; const uint32_t size = RecourceList[i].CustomFile ? RecourceList[i].CustomFileSize : RecourceList[i].DefaultFileSize; - if (buff == NULL) + if(buff == NULL) return NULL; - GuiSound *sound = new GuiSound(buff, size); + GuiSound * sound = new GuiSound(buff, size); instance->soundDataMap[std::string(filename)].first = 1; instance->soundDataMap[std::string(filename)].second = sound; @@ -144,15 +153,15 @@ GuiSound *Resources::GetSound(const char *filename) { return NULL; } -void Resources::RemoveSound(GuiSound *sound) { - std::map >::iterator itr; +void Resources::RemoveSound(GuiSound * sound) { + std::map >::iterator itr; - for (itr = instance->soundDataMap.begin(); itr != instance->soundDataMap.end(); itr++) { - if (itr->second.second == sound) { + for(itr = instance->soundDataMap.begin(); itr != instance->soundDataMap.end(); itr++) { + if(itr->second.second == sound) { itr->second.first--; - if (itr->second.first == 0) { - AsyncDeleter::pushForDelete(itr->second.second); + if(itr->second.first == 0) { + AsyncExecutor::pushForDelete(itr->second.second); instance->soundDataMap.erase(itr); } break; diff --git a/src/resources/Resources.h b/src/resources/Resources.h index 0ec0946..3fc2f37 100644 --- a/src/resources/Resources.h +++ b/src/resources/Resources.h @@ -1,40 +1,30 @@ -#ifndef RECOURCES_H_ -#define RECOURCES_H_ +#pragma once #include +#include //! forward declaration class GuiImageData; - class GuiSound; class Resources { public: static void Clear(); + static bool LoadFiles(const char * path); + static const uint8_t * GetFile(const char * filename); + static uint32_t GetFileSize(const char * filename); - static bool LoadFiles(const char *path); - - static const uint8_t *GetFile(const char *filename); - - static uint32_t GetFileSize(const char *filename); - - static GuiImageData *GetImageData(const char *filename); - - static void RemoveImageData(GuiImageData *image); - - static GuiSound *GetSound(const char *filename); - - static void RemoveSound(GuiSound *sound); + static GuiImageData * GetImageData(const char * filename); + static void RemoveImageData(GuiImageData * image); + static GuiSound * GetSound(const char * filename); + static void RemoveSound(GuiSound * sound); private: static Resources *instance; Resources() {} - ~Resources() {} - std::map > imageDataMap; - std::map > soundDataMap; -}; - -#endif + std::map > imageDataMap; + std::map > soundDataMap; +}; \ No newline at end of file diff --git a/src/system/AsyncDeleter.cpp b/src/system/AsyncDeleter.cpp deleted file mode 100644 index 7d81550..0000000 --- a/src/system/AsyncDeleter.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 Dimok - * - * 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 "AsyncDeleter.h" - -AsyncDeleter *AsyncDeleter::deleterInstance = NULL; - -AsyncDeleter::AsyncDeleter() - : CThread(CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff), exitApplication(false) { -} - -AsyncDeleter::~AsyncDeleter() { - exitApplication = true; -} - -void AsyncDeleter::triggerDeleteProcess(void) { - if (!deleterInstance) - deleterInstance = new AsyncDeleter; - - //! to trigger the event after GUI process is finished execution - //! this function is used to swap elements from one to next array - if (!deleterInstance->deleteElements.empty()) { - deleterInstance->deleteMutex.lock(); - while (!deleterInstance->deleteElements.empty()) { - deleterInstance->realDeleteElements.push(deleterInstance->deleteElements.front()); - deleterInstance->deleteElements.pop(); - } - deleterInstance->deleteMutex.unlock(); - deleterInstance->resumeThread(); - } -} - -void AsyncDeleter::executeThread(void) { - while (!exitApplication) { - suspendThread(); - - //! delete elements that require post process deleting - //! because otherwise they would block or do invalid access on GUI thread - while (!realDeleteElements.empty()) { - deleteMutex.lock(); - GuiElement *element = realDeleteElements.front(); - realDeleteElements.pop(); - deleteMutex.unlock(); - - delete element; - } - } - -} diff --git a/src/system/AsyncDeleter.h b/src/system/AsyncDeleter.h deleted file mode 100644 index 26d8d14..0000000 --- a/src/system/AsyncDeleter.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 Dimok - * - * 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 _ASYNC_DELETER_H -#define _ASYNC_DELETER_H - -#include -#include -#include "CThread.h" -#include "CMutex.h" - -class AsyncDeleter : public CThread { -public: - static void destroyInstance() { - delete deleterInstance; - deleterInstance = NULL; - } - - class Element { - public: - Element() {} - - virtual ~Element() {} - }; - - static void pushForDelete(GuiElement *e) { - if (!deleterInstance) - deleterInstance = new AsyncDeleter; - - deleterInstance->deleteElements.push(e); - } - - static void triggerDeleteProcess(void); - -private: - AsyncDeleter(); - - virtual ~AsyncDeleter(); - - static AsyncDeleter *deleterInstance; - - void executeThread(void); - - bool exitApplication; - std::queue deleteElements; - std::queue realDeleteElements; - CMutex deleteMutex; -}; - -#endif // _ASYNC_DELETER_H diff --git a/src/utils/AsyncExecutor.cpp b/src/utils/AsyncExecutor.cpp new file mode 100644 index 0000000..5c4b42b --- /dev/null +++ b/src/utils/AsyncExecutor.cpp @@ -0,0 +1,59 @@ +#include "AsyncExecutor.h" +#include "utils/logger.h" + +AsyncExecutor *AsyncExecutor::instance = NULL; + +void AsyncExecutor::pushForDeleteInternal(GuiElement *ptr) { + deleteListMutex.lock(); + deleteList.push(ptr); + deleteListMutex.unlock(); +} + +AsyncExecutor::AsyncExecutor() { + thread = new std::thread([&]() { + while (!exitThread) { + mutex.lock(); + bool emptyList = elements.empty(); + auto it = elements.begin(); + while (it != elements.end()) { + auto future = it; + auto status = future->wait_for(std::chrono::seconds(0)); + if (status == std::future_status::ready) { + it = elements.erase(it); + } else { + ++it; + } + } + if (!emptyList && elements.empty()) { + DEBUG_FUNCTION_LINE("All tasks are done"); + } + mutex.unlock(); + deleteListMutex.lock(); + while (!deleteList.empty()) { + GuiElement *ptr = deleteList.front(); + deleteList.pop(); + delete ptr; + } + deleteListMutex.unlock(); + + std::this_thread::sleep_for(std::chrono::milliseconds(16)); + DCFlushRange((void *) &exitThread, sizeof(exitThread)); + } + }); +} + +AsyncExecutor::~AsyncExecutor() { + exitThread = true; + DCFlushRange((void *) &exitThread, sizeof(exitThread)); + thread->join(); +} + +void AsyncExecutor::executeInternal(std::function func) { + if (elements.size() > 10) { + DEBUG_FUNCTION_LINE("Warning, many tasks running currently"); + //std::this_thread::sleep_for(std::chrono::milliseconds(16)); + } + mutex.lock(); + elements.push_back(std::async(std::launch::async, func)); + mutex.unlock(); +} diff --git a/src/utils/AsyncExecutor.h b/src/utils/AsyncExecutor.h new file mode 100644 index 0000000..6b5e01b --- /dev/null +++ b/src/utils/AsyncExecutor.h @@ -0,0 +1,53 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include "utils/logger.h" + +class AsyncExecutor { +public: + static void pushForDelete(GuiElement *element) { + if (!instance) { + instance = new AsyncExecutor(); + } + instance->pushForDeleteInternal(element); + } + + static void execute(std::function func) { + if (!instance) { + instance = new AsyncExecutor(); + } + instance->executeInternal(func); + } + + static void destroyInstance() { + if (instance) { + delete instance; + instance = NULL; + } + } + +private: + static AsyncExecutor *instance; + + AsyncExecutor(); + + ~AsyncExecutor(); + + void pushForDeleteInternal(GuiElement *element); + + void executeInternal(std::function func); + + std::recursive_mutex mutex; + std::thread *thread; + volatile bool exitThread = false; + + std::vector> elements; + + std::recursive_mutex deleteListMutex; + std::queue deleteList; +}; diff --git a/src/utils/StringTools.cpp b/src/utils/StringTools.cpp index 39a5273..34ede5a 100644 --- a/src/utils/StringTools.cpp +++ b/src/utils/StringTools.cpp @@ -37,7 +37,8 @@ BOOL StringTools::EndsWith(const std::string &a, const std::string &b) { - if (b.size() > a.size()) return false; + if (b.size() > a.size()) + return false; return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin()); } @@ -95,7 +96,7 @@ const wchar_t *StringTools::wfmt(const char *format, ...) { va_list va; va_start(va, format); if ((vsprintf(tmp, format, va) >= 0)) { - int bt; + int32_t bt; int32_t strlength = strlen(tmp); bt = mbstowcs(strWChar, tmp, (strlength < 512) ? strlength : 512); @@ -144,7 +145,7 @@ BOOL StringTools::char2wchar_t(const char *strChar, wchar_t *dest) { if (!strChar || !dest) return false; - int bt; + int32_t bt; bt = mbstowcs(dest, strChar, strlen(strChar)); if (bt > 0) { dest[bt] = 0; @@ -208,3 +209,12 @@ std::vector StringTools::stringSplit(const std::string &inValue, co } return result; } + +bool StringTools::findStringIC(const std::string &strHaystack, const std::string &strNeedle) { + auto it = std::search( + strHaystack.begin(), strHaystack.end(), + strNeedle.begin(), strNeedle.end(), + [](char ch1, char ch2) { return std::toupper(ch1) == std::toupper(ch2); } + ); + return (it != strHaystack.end()); +} diff --git a/src/utils/StringTools.h b/src/utils/StringTools.h index 5d9f2c4..07ba5d8 100644 --- a/src/utils/StringTools.h +++ b/src/utils/StringTools.h @@ -23,12 +23,13 @@ * * for WiiXplorer 2010 ***************************************************************************/ -#ifndef __STRING_TOOLS_H -#define __STRING_TOOLS_H +#pragma once #include #include #include +#include +#include class StringTools { public: @@ -53,7 +54,8 @@ public: static int32_t strextcmp(const char *string, const char *extension, char seperator); static const char *FullpathToFilename(const char *path) { - if (!path) return path; + if (!path) + return path; const char *ptr = path; const char *Filename = ptr; @@ -82,7 +84,7 @@ public: } static std::vector stringSplit(const std::string &value, const std::string &splitter); + + // https://stackoverflow.com/a/19839371 + static bool findStringIC(const std::string &strHaystack, const std::string &strNeedle); }; - -#endif /* __STRING_TOOLS_H */ - diff --git a/src/utils/utils.c b/src/utils/utils.c index ef03e74..f96117a 100644 --- a/src/utils/utils.c +++ b/src/utils/utils.c @@ -1,10 +1,7 @@ #include -#include -#include #include -#include -#include -#include +#include +#include "utils/logger.h" // https://gist.github.com/ccbrown/9722406 void dumpHex(const void *data, size_t size) { @@ -13,28 +10,28 @@ void dumpHex(const void *data, size_t size) { ascii[16] = '\0'; DEBUG_FUNCTION_LINE("0x%08X (0x0000): ", data); for (i = 0; i < size; ++i) { - log_printf("%02X ", ((unsigned char *) data)[i]); + WHBLogWritef("%02X ", ((unsigned char *) data)[i]); if (((unsigned char *) data)[i] >= ' ' && ((unsigned char *) data)[i] <= '~') { ascii[i % 16] = ((unsigned char *) data)[i]; } else { ascii[i % 16] = '.'; } if ((i + 1) % 8 == 0 || i + 1 == size) { - log_printf(" "); + WHBLogWritef(" "); if ((i + 1) % 16 == 0) { - log_printf("| %s \n", ascii); + WHBLogPrintf("| %s ", ascii); if (i + 1 < size) { DEBUG_FUNCTION_LINE("0x%08X (0x%04X); ", data + i + 1, i + 1); } } else if (i + 1 == size) { ascii[(i + 1) % 16] = '\0'; if ((i + 1) % 16 <= 8) { - log_printf(" "); + WHBLogWritef(" "); } for (j = (i + 1) % 16; j < 16; ++j) { - log_printf(" "); + WHBLogWritef(" "); } - log_printf("| %s \n", ascii); + WHBLogPrintf("| %s ", ascii); } } } diff --git a/src/utils/utils.h b/src/utils/utils.h index 1d00f98..4097970 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -1,5 +1,4 @@ -#ifndef __UTILS_H_ -#define __UTILS_H_ +#pragma once #include @@ -21,6 +20,11 @@ extern "C" { #define ALIGN4(x) (((x) + 3) & ~3) #define ALIGN32(x) (((x) + 31) & ~31) +// those work only in powers of 2 +#define ROUNDDOWN(val, align) ((val) & ~(align-1)) +#define ROUNDUP(val, align) ROUNDDOWN(((val) + (align-1)), align) + + #define le16(i) ((((uint16_t) ((i) & 0xFF)) << 8) | ((uint16_t) (((i) & 0xFF00) >> 8))) #define le32(i) ((((uint32_t)le16((i) & 0xFFFF)) << 16) | ((uint32_t)le16(((i) & 0xFFFF0000) >> 16))) #define le64(i) ((((uint64_t)le32((i) & 0xFFFFFFFFLL)) << 32) | ((uint64_t)le32(((i) & 0xFFFFFFFF00000000LL) >> 32))) @@ -30,6 +34,4 @@ void dumpHex(const void *data, size_t size); #ifdef __cplusplus } -#endif - -#endif // __UTILS_H_ +#endif \ No newline at end of file