diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 5b1f8a2..0000000 --- a/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "src/minarch/libretro-common"] - path = src/minarch/libretro-common - url = https://github.com/libretro/libretro-common -[submodule "other/DinguxCommander"] - path = other/DinguxCommander - url = https://github.com/shauninman/DinguxCommander.git diff --git a/other/DinguxCommander b/other/DinguxCommander deleted file mode 160000 index 2b8b290..0000000 --- a/other/DinguxCommander +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2b8b29042c172dbca78eadbbb989e51a0b9b635d diff --git a/other/DinguxCommander/.gitignore b/other/DinguxCommander/.gitignore new file mode 100644 index 0000000..ea1472e --- /dev/null +++ b/other/DinguxCommander/.gitignore @@ -0,0 +1 @@ +output/ diff --git a/other/DinguxCommander/Makefile b/other/DinguxCommander/Makefile new file mode 100644 index 0000000..8ccb968 --- /dev/null +++ b/other/DinguxCommander/Makefile @@ -0,0 +1,76 @@ + +########################################################### + +ifeq (,$(PLATFORM)) +PLATFORM=$(UNION_PLATFORM) +endif + +ifeq (,$(PLATFORM)) +$(error please specify PLATFORM, eg. make PLATFORM=trimui) +endif +ifeq (,$(CROSS_COMPILE)) +$(error missing CROSS_COMPILE for this toolchain) +endif + +########################################################### + +CXX:=$(CROSS_COMPILE)g++ +CXXFLAGS:=-DPLATFORM_$(shell echo $(PLATFORM) | tr a-z A-Z) -O3 -fomit-frame-pointer -ffast-math -funroll-loops + +ifeq (miyoomini,$(PLATFORM)) +CXXFLAGS+= -marm -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7ve -O3 +endif + +ifeq (rg35xx,$(PLATFORM)) +CXXFLAGS+= -marm -mtune=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -march=armv7-a -O3 +endif + +RESDIR:=res + +CXXFLAGS+= -Wno-unknown-pragmas -Wno-format -Wno-write-strings # -Wall +CXXFLAGS+=-DRESDIR="\"$(RESDIR)\"" +LINKFLAGS+=-s +LINKFLAGS+=-lSDL -lSDL_image -lSDL_ttf + +ifdef V + CMD:= + SUM:=@\# +else + CMD:=@ + SUM:=@echo +endif + +OUTDIR:=output + +EXECUTABLE:=$(OUTDIR)/DinguxCommander + +OBJS:=main.o sdlutils.o resourceManager.o fileLister.o commander.o panel.o \ + dialog.o window.o fileutils.o viewer.o keyboard.o + +DEPFILES:=$(patsubst %.o,$(OUTDIR)/%.d,$(OBJS)) + +.PHONY: all clean + +all: $(EXECUTABLE) + +$(EXECUTABLE): $(addprefix $(OUTDIR)/,$(OBJS)) + $(SUM) " LINK $@" + $(CMD)$(CXX) $(LINKFLAGS) -o $@ $^ + +$(OUTDIR)/%.o: src/%.cpp + @mkdir -p $(@D) + $(SUM) " CXX $@" + $(CMD)$(CXX) $(CXXFLAGS) -MP -MMD -MF $(@:%.o=%.d) -c $< -o $@ + @touch $@ # Force .o file to be newer than .d file. + +clean: + $(SUM) " RM $(OUTDIR)" + $(CMD)rm -rf $(OUTDIR) + +# Load dependency files. +-include $(DEPFILES) + +# Generate dependencies that do not exist yet. +# This is only in case some .d files have been deleted; +# in normal operation this rule is never triggered. +$(DEPFILES): diff --git a/other/DinguxCommander/README.md b/other/DinguxCommander/README.md new file mode 100644 index 0000000..83e7a27 --- /dev/null +++ b/other/DinguxCommander/README.md @@ -0,0 +1,8 @@ +DinguxCommander +=============== + +DinguxCommander is a two-pane file manager in the style of Norton Commander. + +Original site: http://beyondds.free.fr/index.php?Dingoo-dinguxcommander + +This repository contains customizations to make it integrate better with OpenDingux. diff --git a/other/DinguxCommander/README.txt b/other/DinguxCommander/README.txt new file mode 100644 index 0000000..1178ad5 --- /dev/null +++ b/other/DinguxCommander/README.txt @@ -0,0 +1,82 @@ +DinguxCommander for Dingux +-------------------------- + + +History +------- + +2011-03-09 : Version 2.1 + - Rename a file/dir + - Create new dir + - Minor fixes + +2011-02-16 : Version 2.0 + - Execute file + - View file + - Disk information + - Disk used by a list of selected files/dirs + - New button mapping + - Small fixes + +2011-02-05 : Version 1.0 : Initial version. + + +Introduction +------------ + +DinguxCommander is a file manager for Dingoo (Dingux). +It uses two vertical panels side by side, one being the source and the other the +destination, like many 'commander-style' file managers such as Norton Commander +or Midnight Commander. +DinguxCommander allows to: + o Copy, move and delete multiple files. + o View a file + o Execute a file + o Rename a file or directory + o Create a new directory + o Display disk space used by a list of selected files/dirs + o Display disk information (used, available, total) + +Installation +------------ + +As usual: + +o Extract the archive, keeping the directory structure +o Copy the directory 'DinguxCommander' and its contents somewhere on your SD + card under '/boot/local' (for example: in /boot/local/apps/) +o Create a shortcut to DinguxCommander.dge in your favorite menu. + + +Controls +-------- + +o D-pad Move +o L/R Page up/page down +o A For a directory: open + For a file: view or execute +o B Go to parent directory / cancel +o Y System actions: + - Select all items + - Select no items + - Create new directory + - Display disk information + - Quit program +o X Actions on selected items: + - Copy to destination directory + - Move to destination directory + - Rename (appears only if 1 item is selected) + - Delete + - Display disk used +o SELECT Select highlighted item. + Selected items are displayed in red. +o START Open highlighted directory in destination panel. + If a file is highlighted, open current directory in destination panel. + + +Credits +------- + +Homepage: http://beyondds.free.fr/ +Development: Mia +Font: Beycan Çetin diff --git a/other/DinguxCommander/res/Commander-11.ttf b/other/DinguxCommander/res/Commander-11.ttf new file mode 100644 index 0000000..de148fc Binary files /dev/null and b/other/DinguxCommander/res/Commander-11.ttf differ diff --git a/other/DinguxCommander/res/Fiery_Turk.ttf b/other/DinguxCommander/res/Fiery_Turk.ttf new file mode 100644 index 0000000..c9f4bca Binary files /dev/null and b/other/DinguxCommander/res/Fiery_Turk.ttf differ diff --git a/other/DinguxCommander/res/background.png b/other/DinguxCommander/res/background.png new file mode 100644 index 0000000..339b034 Binary files /dev/null and b/other/DinguxCommander/res/background.png differ diff --git a/other/DinguxCommander/res/file.png b/other/DinguxCommander/res/file.png new file mode 100644 index 0000000..23a2d18 Binary files /dev/null and b/other/DinguxCommander/res/file.png differ diff --git a/other/DinguxCommander/res/folder.png b/other/DinguxCommander/res/folder.png new file mode 100644 index 0000000..d6fc760 Binary files /dev/null and b/other/DinguxCommander/res/folder.png differ diff --git a/other/DinguxCommander/res/icon.png b/other/DinguxCommander/res/icon.png new file mode 100644 index 0000000..1f1bc8e Binary files /dev/null and b/other/DinguxCommander/res/icon.png differ diff --git a/other/DinguxCommander/res/up.png b/other/DinguxCommander/res/up.png new file mode 100644 index 0000000..27eceb5 Binary files /dev/null and b/other/DinguxCommander/res/up.png differ diff --git a/other/DinguxCommander/src/commander.cpp b/other/DinguxCommander/src/commander.cpp new file mode 100644 index 0000000..53624e7 --- /dev/null +++ b/other/DinguxCommander/src/commander.cpp @@ -0,0 +1,353 @@ +#include +#include +#include "commander.h" +#include "resourceManager.h" +#include "sdlutils.h" +#include "def.h" +#include "dialog.h" +#include "fileutils.h" +#include "viewer.h" +#include "keyboard.h" + +#define X_LEFT 1 +#define X_RIGHT 162 + +CCommander::CCommander(const std::string &p_pathL, const std::string &p_pathR): + CWindow::CWindow(), + m_panelLeft(p_pathL, X_LEFT), + m_panelRight(p_pathR, X_RIGHT), + m_panelSource(NULL), + m_panelTarget(NULL), + m_background(CResourceManager::instance().getSurface(CResourceManager::T_SURFACE_BG)) +{ + m_panelSource = &m_panelLeft; + m_panelTarget = &m_panelRight; +} + +CCommander::~CCommander(void) +{ +} + +void CCommander::render(const bool p_focus) const +{ + INHIBIT(std::cout << "CCommander::render fullscreen: " << isFullScreen() << " focus: " << p_focus << std::endl;) + // Draw background image + SDL_utils::applySurface(0, 0, m_background, Globals::g_screen); + // Draw panels + m_panelLeft.render(p_focus && (m_panelSource == &m_panelLeft)); + m_panelRight.render(p_focus && (m_panelSource == &m_panelRight)); +} + +const bool CCommander::keyPress(const SDL_Event &p_event) +{ + CWindow::keyPress(p_event); + bool l_ret(false); + switch (p_event.key.keysym.sym) + { + case MYKEY_SYSTEM: + case MYKEY_MENU: + if (openSystemMenu()) + m_panelSource->refresh(); + l_ret = true; + break; + case MYKEY_UP: + l_ret = m_panelSource->moveCursorUp(1); + break; + case MYKEY_DOWN: + l_ret = m_panelSource->moveCursorDown(1); + break; + case MYKEY_PAGEUP: + l_ret = m_panelSource->moveCursorUp(NB_VISIBLE_LINES - 1); + break; + case MYKEY_PAGEDOWN: + l_ret = m_panelSource->moveCursorDown(NB_VISIBLE_LINES - 1); + break; + case MYKEY_LEFT: + if (m_panelSource == &m_panelRight) + { + m_panelSource = &m_panelLeft; + m_panelTarget = &m_panelRight; + l_ret = true; + } + break; + case MYKEY_RIGHT: + if (m_panelSource == &m_panelLeft) + { + m_panelSource = &m_panelRight; + m_panelTarget = &m_panelLeft; + l_ret = true; + } + break; + case MYKEY_OPEN: + if (m_panelSource->isDirectoryHighlighted()) + { + // It's a dir => open it + l_ret = m_panelSource->open(); + } + else + { + // It's a file => open execute menu + openExecuteMenu(); + l_ret = true; + } + break; + case MYKEY_PARENT: + l_ret = m_panelSource->goToParentDir(); + break; + case MYKEY_OPERATION: + // If there's no file in the select list, add current file + if (m_panelSource->getSelectList().empty() && m_panelSource->getHighlightedItem() != "..") + m_panelSource->addToSelectList(false); + if (!m_panelSource->getSelectList().empty()) + { + if (openCopyMenu()) + { + // Refresh file lists + m_panelSource->refresh(); + m_panelTarget->refresh(); + } + else + { + if (m_panelSource->getSelectList().size() == 1 && (*m_panelSource->getSelectList().begin()) == m_panelSource->getHighlightedIndex()) + m_panelSource->selectNone(); + } + l_ret = true; + } + break; + case MYKEY_SELECT: + l_ret = m_panelSource->addToSelectList(true); + break; + case MYKEY_TRANSFER: + if (m_panelSource->isDirectoryHighlighted() && m_panelSource->getHighlightedItem() != "..") + l_ret = m_panelTarget->open(m_panelSource->getHighlightedItemFull()); + else + l_ret = m_panelTarget->open(m_panelSource->getCurrentPath()); + break; + default: + break; + } + return l_ret; +} + +const bool CCommander::keyHold(void) +{ + bool l_ret(false); + switch(m_lastPressed) + { + case MYKEY_UP: + if (tick(SDL_GetKeyState(NULL)[MYKEY_UP])) + l_ret = m_panelSource->moveCursorUp(1); + break; + case MYKEY_DOWN: + if (tick(SDL_GetKeyState(NULL)[MYKEY_DOWN])) + l_ret = m_panelSource->moveCursorDown(1); + break; + case MYKEY_PAGEUP: + if (tick(SDL_GetKeyState(NULL)[MYKEY_PAGEUP])) + l_ret = m_panelSource->moveCursorUp(NB_VISIBLE_LINES - 1); + break; + case MYKEY_PAGEDOWN: + if (tick(SDL_GetKeyState(NULL)[MYKEY_PAGEDOWN])) + l_ret = m_panelSource->moveCursorDown(NB_VISIBLE_LINES - 1); + break; + case MYKEY_SELECT: + if (tick(SDL_GetKeyState(NULL)[MYKEY_SELECT])) + l_ret = m_panelSource->addToSelectList(true); + break; + default: + break; + } + return l_ret; +} + +const bool CCommander::openCopyMenu(void) const +{ + bool l_ret(false); + int l_dialogRetVal(0); + bool l_rename(false); + // List of selected files + std::vector l_list; + m_panelSource->getSelectList(l_list); + // The rename option appears only if one item is selected + l_rename = (l_list.size() == 1); + { + bool l_loop(false); + std::ostringstream l_stream; + l_stream << l_list.size() << " selected:"; + // File operation dialog + CDialog l_dialog(l_stream.str(), 0, Y_LIST + m_panelSource->getHighlightedIndexRelative() * LINE_HEIGHT); + l_dialog.addOption(m_panelSource == &m_panelLeft ? "Copy >" : "< Copy"); + l_dialog.addOption(m_panelSource == &m_panelLeft ? "Move >" : "< Move"); + if (l_rename) + l_dialog.addOption("Rename"); + l_dialog.addOption("Delete"); + l_dialog.addOption("Disk used"); + l_dialog.init(); + do + { + l_loop = false; + l_dialogRetVal = l_dialog.execute(); + if (l_dialogRetVal == 3 + l_rename) + { + CDialog l_dialog2("", l_dialog.getX() + l_dialog.getImage()->w - DIALOG_BORDER, l_dialog.getY() + DIALOG_BORDER + (l_dialog.getHighlightedIndex() + 1) * LINE_HEIGHT); + l_dialog2.addOption("Yes"); + l_dialog2.addOption("No"); + l_dialog2.init(); + if (l_dialog2.execute() != 1) + l_loop = true; + } + } + while (l_loop); + } + // Perform operation + switch (l_dialogRetVal) + { + case 1: + // Copy + File_utils::copyFile(l_list, m_panelTarget->getCurrentPath()); + l_ret = true; + break; + case 2: + // Move + File_utils::moveFile(l_list, m_panelTarget->getCurrentPath()); + l_ret = true; + break; + case 3: + if (l_rename) + { + // Rename + CKeyboard l_keyboard(m_panelSource->getHighlightedItem()); + if (l_keyboard.execute() == 1 && !l_keyboard.getInputText().empty() && l_keyboard.getInputText() != m_panelSource->getHighlightedItem()) + { + File_utils::renameFile(m_panelSource->getHighlightedItemFull(), m_panelSource->getCurrentPath() + (m_panelSource->getCurrentPath() == "/" ? "" : "/") + l_keyboard.getInputText()); + l_ret = true; + } + } + else + { + // Delete + File_utils::removeFile(l_list); + l_ret = true; + } + break; + case 4: + if (l_rename) + { + // Delete + File_utils::removeFile(l_list); + l_ret = true; + } + else + // Disk used + File_utils::diskUsed(l_list); + break; + case 5: + if (l_rename) + // Disk used + File_utils::diskUsed(l_list); + break; + default: + break; + } + return l_ret; +} + +const bool CCommander::openSystemMenu(void) +{ + bool l_ret(false); + int l_dialogRetVal(0); + // Selection dialog + { + CDialog l_dialog("System:", 0, Y_LIST + m_panelSource->getHighlightedIndexRelative() * LINE_HEIGHT); + l_dialog.addOption("Select all"); + l_dialog.addOption("Select none"); + l_dialog.addOption("New directory"); + l_dialog.addOption("Disk info"); + l_dialog.addOption("Quit"); + l_dialog.init(); + l_dialogRetVal = l_dialog.execute(); + } + switch (l_dialogRetVal) + { + case 1: + // Select all + m_panelSource->selectAll(); + break; + case 2: + // Select none + m_panelSource->selectNone(); + break; + case 3: + // New dir + { + CKeyboard l_keyboard(""); + if (l_keyboard.execute() == 1 && !l_keyboard.getInputText().empty()) + { + File_utils::makeDirectory(m_panelSource->getCurrentPath() + (m_panelSource->getCurrentPath() == "/" ? "" : "/") + l_keyboard.getInputText()); + l_ret = true; + } + } + break; + case 4: + // Disk info + File_utils::diskInfo(); + break; + case 5: + // Quit + m_retVal = -1; + break; + default: + break; + } + return l_ret; +} + +void CCommander::openExecuteMenu(void) const +{ + int l_dialogRetVal(0); + // Dialog + { + CDialog l_dialog(m_panelSource->getHighlightedItem() + ":", 0, Y_LIST + m_panelSource->getHighlightedIndexRelative() * LINE_HEIGHT); + l_dialog.addOption("View"); + l_dialog.addOption("Execute"); + l_dialog.init(); + l_dialogRetVal = l_dialog.execute(); + } + // Perform operation + switch (l_dialogRetVal) + { + case 1: + // View + { + // Check size + const std::string l_file(m_panelSource->getHighlightedItemFull()); + INHIBIT(std::cout << "File size: " << File_utils::getFileSize(l_file) << std::endl;) + if (File_utils::getFileSize(l_file) > VIEWER_SIZE_MAX) + { + // File is too big to be viewed! + CDialog l_dialog("Error:", 0, 0); + l_dialog.addLabel("File is too big!"); + l_dialog.addOption("OK"); + l_dialog.init(); + l_dialog.execute(); + } + else + { + CViewer l_viewer(m_panelSource->getHighlightedItemFull()); + l_viewer.execute(); + } + } + break; + case 2: + // Execute + File_utils::executeFile(m_panelSource->getHighlightedItemFull()); + break; + default: + break; + } +} + +const bool CCommander::isFullScreen(void) const +{ + return true; +} diff --git a/other/DinguxCommander/src/commander.h b/other/DinguxCommander/src/commander.h new file mode 100644 index 0000000..c25f8f9 --- /dev/null +++ b/other/DinguxCommander/src/commander.h @@ -0,0 +1,54 @@ +#ifndef _COMMANDER_H_ +#define _COMMANDER_H_ + +#include +#include "panel.h" +#include "window.h" + +class CCommander : public CWindow +{ + public: + + // Constructor + CCommander(const std::string &p_pathL, const std::string &p_pathR); + + // Destructor + virtual ~CCommander(void); + + private: + + // Forbidden + CCommander(void); + CCommander(const CCommander &p_source); + const CCommander &operator =(const CCommander &p_source); + + // Key press management + virtual const bool keyPress(const SDL_Event &p_event); + + // Key hold management + virtual const bool keyHold(void); + + // Draw + virtual void render(const bool p_focus) const; + + // Is window full screen? + virtual const bool isFullScreen(void) const; + + // Open the file operation menus + const bool openCopyMenu(void) const; + void openExecuteMenu(void) const; + + // Open the selection menu + const bool openSystemMenu(void); + + // The two panels + CPanel m_panelLeft; + CPanel m_panelRight; + CPanel* m_panelSource; + CPanel* m_panelTarget; + + // Pointers to resources + SDL_Surface *m_background; +}; + +#endif diff --git a/other/DinguxCommander/src/def.h b/other/DinguxCommander/src/def.h new file mode 100644 index 0000000..86e84d5 --- /dev/null +++ b/other/DinguxCommander/src/def.h @@ -0,0 +1,124 @@ +#ifndef _DEF_H_ +#define _DEF_H_ + +//~ #define INHIBIT(X) X +#define INHIBIT(X) /* X */ + +#define SCREEN_WIDTH 320 +#define SCREEN_HEIGHT 240 +#define SCREEN_BPP 16 +#define SURFACE_FLAGS SDL_SWSURFACE +#define MS_PER_FRAME 33 +// Panel +#define LINE_HEIGHT 15 +#define NB_VISIBLE_LINES 14 +#define Y_LIST 17 +#define Y_HEADER 3 +#if defined(PLATFORM_TRIMUI) +#define Y_OFFSET 2 // added for larger Commander-11.ttf +#else +#define Y_OFFSET 0 +#endif +#define Y_FOOTER 228 +#define H_FOOTER 13 +// Dialogs +#define DIALOG_BORDER 2 +#define DIALOG_MARGIN 8 +// Colors +#define COLOR_KEY 255,0,255 +#define COLOR_TEXT_NORMAL 70,27,10 +#define COLOR_TEXT_TITLE 233,229,227 +#define COLOR_TEXT_DIR 75,70,164 +#define COLOR_TEXT_SELECTED 255,0,0 +#define COLOR_CURSOR_1 232,152,80 +#define COLOR_CURSOR_2 232,201,173 +#define COLOR_BG_1 255,255,255 +#define COLOR_BG_2 232,228,224 +#define COLOR_BORDER 102,85,74 + +#define DINGOO_X SDLK_LSHIFT +#define DINGOO_Y SDLK_LALT + +#if defined(PLATFORM_TRIMUI) +#define MYKEY_UP SDLK_UP // Up +#define MYKEY_RIGHT SDLK_RIGHT // Right +#define MYKEY_DOWN SDLK_DOWN // Down +#define MYKEY_LEFT SDLK_LEFT // Left +#define MYKEY_SYSTEM SDLK_LALT // Y +#define MYKEY_PAGEUP SDLK_TAB // L +#define MYKEY_PAGEDOWN SDLK_BACKSPACE // R +#define MYKEY_OPEN SDLK_SPACE // A +#define MYKEY_PARENT SDLK_LCTRL // B +#define MYKEY_OPERATION SDLK_LSHIFT // X +#define MYKEY_SELECT SDLK_RCTRL // SELECT +#define MYKEY_TRANSFER SDLK_RETURN // START +#define MYKEY_MENU SDLK_ESCAPE // MENU +#define PATH_DEFAULT "/" +#define FILE_SYSTEM "/dev/mmcblk0p1" +#elif defined(PLATFORM_RG35XX) +#define MYKEY_UP SDLK_KATAKANA +#define MYKEY_RIGHT SDLK_KATAKANAHIRAGANA +#define MYKEY_DOWN SDLK_HIRAGANA +#define MYKEY_LEFT SDLK_HENKAN +#define MYKEY_SYSTEM SDLK_RCTRL // Y +#define MYKEY_PAGEUP SDLK_RALT // L +#define MYKEY_PAGEDOWN SDLK_BREAK // R +#define MYKEY_OPEN SDLK_MUHENKAN // A +#define MYKEY_PARENT SDLK_KP_JPCOMMA // B +#define MYKEY_OPERATION SDLK_KP_ENTER // X +#define MYKEY_SELECT SDLK_PRINT // SELECT +#define MYKEY_TRANSFER SDLK_KP_DIVIDE // START +#define MYKEY_MENU SDLK_PAGEUP // MENU +#define PATH_DEFAULT "/" +#define FILE_SYSTEM "/dev/mmcblk0p1" +#elif defined(PLATFORM_MIYOOMINI) +#define MYKEY_UP SDLK_UP // Up +#define MYKEY_RIGHT SDLK_RIGHT // Right +#define MYKEY_DOWN SDLK_DOWN // Down +#define MYKEY_LEFT SDLK_LEFT // Left +#define MYKEY_SYSTEM SDLK_LALT // Y +#define MYKEY_PAGEUP SDLK_e // L +#define MYKEY_PAGEDOWN SDLK_t // R +#define MYKEY_OPEN SDLK_SPACE // A +#define MYKEY_PARENT SDLK_LCTRL // B +#define MYKEY_OPERATION SDLK_LSHIFT // X +#define MYKEY_SELECT SDLK_RCTRL // SELECT +#define MYKEY_TRANSFER SDLK_RETURN // START +#define MYKEY_MENU SDLK_ESCAPE // MENU +#define PATH_DEFAULT "/" +#define FILE_SYSTEM "/dev/mmcblk0p1" +#elif defined(PLATFORM_RG350) || defined(PLATFORM_ODBETA) +#define MYKEY_UP SDLK_UP // Up +#define MYKEY_RIGHT SDLK_RIGHT // Right +#define MYKEY_DOWN SDLK_DOWN // Down +#define MYKEY_LEFT SDLK_LEFT // Left +#define MYKEY_SYSTEM SDLK_LSHIFT // X +#define MYKEY_PAGEUP SDLK_TAB // L +#define MYKEY_PAGEDOWN SDLK_BACKSPACE // R +#define MYKEY_OPEN SDLK_LCTRL // A +#define MYKEY_PARENT SDLK_LALT // B +#define MYKEY_OPERATION SDLK_SPACE // Y +#define MYKEY_SELECT SDLK_ESCAPE // SELECT +#define MYKEY_TRANSFER SDLK_RETURN // START +#define MYKEY_MENU SDLK_HOME // POWER +#define PATH_DEFAULT "/" +#define FILE_SYSTEM "/dev/mmcblk0p1" +#elif defined(PLATFORM_RETROFW) +#define MYKEY_UP SDLK_UP // Up +#define MYKEY_RIGHT SDLK_RIGHT // Right +#define MYKEY_DOWN SDLK_DOWN // Down +#define MYKEY_LEFT SDLK_LEFT // Left +#define MYKEY_SYSTEM SDLK_LSHIFT // X +#define MYKEY_PAGEUP SDLK_TAB // L +#define MYKEY_PAGEDOWN SDLK_BACKSPACE // R +#define MYKEY_OPEN SDLK_LCTRL // A +#define MYKEY_PARENT SDLK_LALT // B +#define MYKEY_OPERATION SDLK_SPACE // Y +#define MYKEY_SELECT SDLK_ESCAPE // SELECT +#define MYKEY_TRANSFER SDLK_RETURN // START +#define MYKEY_MENU SDLK_END // POWER +#define PATH_DEFAULT "/" +#define FILE_SYSTEM "/dev/mmcblk0p1" +#endif + +#endif diff --git a/other/DinguxCommander/src/dialog.cpp b/other/DinguxCommander/src/dialog.cpp new file mode 100644 index 0000000..8a094ca --- /dev/null +++ b/other/DinguxCommander/src/dialog.cpp @@ -0,0 +1,260 @@ +#include +#include "dialog.h" +#include "sdlutils.h" +#include "resourceManager.h" +#include "def.h" + +CDialog::CDialog(const std::string &p_title, const Sint16 p_x, const Sint16 p_y): + CWindow(), + m_nbTitle(false), + m_nbLabels(0), + m_nbOptions(0), + m_highlightedLine(0), + m_image(NULL), + m_cursor1(NULL), + m_cursor2(NULL), + m_x(p_x), + m_y(p_y), + m_cursorX(0), + m_cursorY(0), + m_font(CResourceManager::instance().getFont()), + m_font_sm(CResourceManager::instance().getSmallFont()) +{ + // Title + if (!p_title.empty()) + { + m_nbTitle = true; + m_lines.push_back(p_title); + } + // Init clip + m_clip.x = 0; + m_clip.y = 0; + m_clip.w = 0; + m_clip.h = 0; +} + +CDialog::~CDialog(void) +{ + // Free surfaces + if (m_image != NULL) + { + SDL_FreeSurface(m_image); + m_image = NULL; + } + if (m_cursor1 != NULL) + { + SDL_FreeSurface(m_cursor1); + m_cursor1 = NULL; + } + if (m_cursor2 != NULL) + { + SDL_FreeSurface(m_cursor2); + m_cursor2 = NULL; + } + for (std::vector::iterator l_it = m_linesImg.begin(); l_it != m_linesImg.end(); ++l_it) + { + if (*l_it != NULL) + { + SDL_FreeSurface(*l_it); + *l_it = NULL; + } + } +} + +void CDialog::addLabel(const std::string &p_label) +{ + m_lines.push_back(p_label); + ++m_nbLabels; +} + +void CDialog::addOption(const std::string &p_option) +{ + m_lines.push_back(p_option); + ++m_nbOptions; +} + +void CDialog::init(void) +{ + // The width of the window depends on the width of the largest line + int l_width(0); + int l_cursorWidth(0); + SDL_Surface *l_surfaceTmp(NULL); + // Render every line + for (std::vector::const_iterator l_it = m_lines.begin(); l_it != m_lines.end(); ++l_it) + { + // Render line + l_surfaceTmp = SDL_utils::renderText(m_font, *l_it, (m_nbTitle && l_it == m_lines.begin()) ? Globals::g_colorTextTitle : Globals::g_colorTextNormal); + if (l_surfaceTmp->w > l_width) + l_width = l_surfaceTmp->w; + m_linesImg.push_back(l_surfaceTmp); + } + // Cursor width + l_cursorWidth = l_width + 2 * DIALOG_MARGIN; + if (l_cursorWidth > SCREEN_WIDTH - 2 * DIALOG_BORDER) + l_cursorWidth = SCREEN_WIDTH - 2 * DIALOG_BORDER; + // Line clip + m_clip.h = m_linesImg.front()->h; + m_clip.w = l_cursorWidth - DIALOG_MARGIN - 1; + // Adjust image width + l_width = l_width + 2 * DIALOG_MARGIN + 2 * DIALOG_BORDER; + if (l_width > SCREEN_WIDTH) + l_width = SCREEN_WIDTH; + // Create dialog image + m_image = SDL_utils::createImage(l_width, m_linesImg.size() * LINE_HEIGHT + 2 * DIALOG_BORDER, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER)); + { + SDL_Rect l_rect; + l_rect.x = DIALOG_BORDER; + l_rect.y = DIALOG_BORDER + m_nbTitle * LINE_HEIGHT; + l_rect.w = m_image->w - 2 * DIALOG_BORDER; + l_rect.h = m_image->h - 2 * DIALOG_BORDER - m_nbTitle * LINE_HEIGHT; + SDL_FillRect(m_image, &l_rect, SDL_MapRGB(m_image->format, COLOR_BG_1)); + } + // Create cursor image + m_cursor1 = SDL_utils::createImage(l_cursorWidth, LINE_HEIGHT, SDL_MapRGB(Globals::g_screen->format, COLOR_CURSOR_1)); + m_cursor2 = SDL_utils::createImage(l_cursorWidth, LINE_HEIGHT, SDL_MapRGB(Globals::g_screen->format, COLOR_CURSOR_2)); + // Adjust dialog coordinates + if (!m_x) + m_x = (SCREEN_WIDTH - m_image->w) >> 1; + if (!m_y) + { + m_y = (SCREEN_HEIGHT - m_image->h) >> 1; + } + else + { + m_y = m_y - (m_image->h >> 1) + (LINE_HEIGHT >> 1); + if (m_y < Y_LIST) + m_y = Y_LIST; + if (m_y + m_image->h > Y_FOOTER + 1) + m_y = Y_FOOTER + 1 - m_image->h; + } + // Cursor coordinates + m_cursorX = m_x + DIALOG_BORDER; + m_cursorY = m_y + DIALOG_BORDER + (m_nbTitle + m_nbLabels) * LINE_HEIGHT; +} + +void CDialog::render(const bool p_focus) const +{ + INHIBIT(std::cout << "CDialog::render fullscreen: " << isFullScreen() << " focus: " << p_focus << std::endl;) + // Draw background + SDL_utils::applySurface(m_x, m_y, m_image, Globals::g_screen); + // Draw cursor + SDL_utils::applySurface(m_cursorX, m_cursorY + m_highlightedLine * LINE_HEIGHT, p_focus ? m_cursor1 : m_cursor2, Globals::g_screen); + // Draw lines text + Sint16 l_y(m_y + 4); + for (std::vector::const_iterator l_it = m_linesImg.begin(); l_it != m_linesImg.end(); ++l_it) + { + SDL_utils::applySurface(m_cursorX + DIALOG_MARGIN, (m_nbTitle && l_it == m_linesImg.begin()) ? l_y - 1 - Y_OFFSET : l_y - Y_OFFSET, *l_it, Globals::g_screen, &m_clip); + l_y += LINE_HEIGHT; + } +} + +const bool CDialog::keyPress(const SDL_Event &p_event) +{ + CWindow::keyPress(p_event); + bool l_ret(false); + switch (p_event.key.keysym.sym) + { + case MYKEY_PARENT: + m_retVal = -1; + l_ret = true; + break; + case MYKEY_UP: + l_ret = moveCursorUp(true); + break; + case MYKEY_DOWN: + l_ret = moveCursorDown(true); + break; + case MYKEY_PAGEUP: + if (m_highlightedLine) + { + m_highlightedLine = 0; + l_ret = true; + } + break; + case MYKEY_PAGEDOWN: + if (m_highlightedLine + 1 < m_nbOptions) + { + m_highlightedLine = m_nbOptions - 1; + l_ret = true; + } + break; + case MYKEY_OPEN: + m_retVal = m_highlightedLine + 1; + l_ret = true; + break; + default: + break; + } + return l_ret; +} + +const bool CDialog::moveCursorUp(const bool p_loop) +{ + bool l_ret(false); + if (m_highlightedLine) + { + --m_highlightedLine; + l_ret = true; + } + else if (p_loop && m_highlightedLine + 1 < m_nbOptions) + { + m_highlightedLine = m_nbOptions - 1; + l_ret = true; + } + return l_ret; +} + +const bool CDialog::moveCursorDown(const bool p_loop) +{ + bool l_ret(false); + if (m_highlightedLine + 1 < m_nbOptions) + { + ++m_highlightedLine; + l_ret = true; + } + else if (p_loop && m_highlightedLine) + { + m_highlightedLine = 0; + l_ret = true; + } + return l_ret; +} + +const bool CDialog::keyHold(void) +{ + bool l_ret(false); + switch(m_lastPressed) + { + case MYKEY_UP: + if (tick(SDL_GetKeyState(NULL)[MYKEY_UP])) + l_ret = moveCursorUp(false); + break; + case MYKEY_DOWN: + if (tick(SDL_GetKeyState(NULL)[MYKEY_DOWN])) + l_ret = moveCursorDown(false); + break; + default: + break; + } + return l_ret; +} + +const Sint16 &CDialog::getX(void) const +{ + return m_x; +} + +const Sint16 &CDialog::getY(void) const +{ + return m_y; +} + +const SDL_Surface * const CDialog::getImage(void) const +{ + return m_image; +} + +const unsigned int &CDialog::getHighlightedIndex(void) const +{ + return m_highlightedLine; +} diff --git a/other/DinguxCommander/src/dialog.h b/other/DinguxCommander/src/dialog.h new file mode 100644 index 0000000..bdc4ae5 --- /dev/null +++ b/other/DinguxCommander/src/dialog.h @@ -0,0 +1,89 @@ +#ifndef _DIALOG_H_ +#define _DIALOG_H_ + +#include +#include +#include +#include +#include "window.h" + +class CDialog : public CWindow +{ + public: + + // Constructor + // Coordinates = 0 => centered + CDialog(const std::string &p_title, const Sint16 p_x, const Sint16 p_y); + + // Destructor + virtual ~CDialog(void); + + // Add a label + void addLabel(const std::string &p_label); + + // Add a menu option + void addOption(const std::string &p_option); + + // Init. Call after all options are added. + void init(void); + + // Accessors + const Sint16 &getX(void) const; + const Sint16 &getY(void) const; + const SDL_Surface * const getImage(void) const; + const unsigned int &getHighlightedIndex(void) const; + + private: + + // Forbidden + CDialog(void); + CDialog(const CDialog &p_source); + const CDialog &operator =(const CDialog &p_source); + + // Key press management + virtual const bool keyPress(const SDL_Event &p_event); + + // Key hold management + virtual const bool keyHold(void); + + // Draw + virtual void render(const bool p_focus) const; + + // Move cursor + const bool moveCursorUp(const bool p_loop); + const bool moveCursorDown(const bool p_loop); + + // Number of titles (0 or 1), labels, and options + bool m_nbTitle; + unsigned char m_nbLabels; + unsigned char m_nbOptions; + + // List of lines + std::vector m_lines; + std::vector m_linesImg; + + // The highlighted item + unsigned int m_highlightedLine; + + // The image representing the dialog + SDL_Surface *m_image; + + // The cursor + SDL_Surface *m_cursor1; + SDL_Surface *m_cursor2; + + // Coordinates + Sint16 m_x; + Sint16 m_y; + Sint16 m_cursorX; + Sint16 m_cursorY; + + // Line clip + mutable SDL_Rect m_clip; + + // Pointers to resources + TTF_Font *m_font; + TTF_Font *m_font_sm; +}; + +#endif diff --git a/other/DinguxCommander/src/fileLister.cpp b/other/DinguxCommander/src/fileLister.cpp new file mode 100644 index 0000000..a539cda --- /dev/null +++ b/other/DinguxCommander/src/fileLister.cpp @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include +#include "fileLister.h" + +bool compareNoCase(const T_FILE& p_s1, const T_FILE& p_s2) +{ + return strcasecmp(p_s1.m_name.c_str(), p_s2.m_name.c_str()) <= 0; +} + +CFileLister::CFileLister(void) +{ +} + +CFileLister::~CFileLister(void) +{ +} + +const bool CFileLister::list(const std::string &p_path) +{ + // Open dir + DIR *l_dir = opendir(p_path.c_str()); + if (l_dir == NULL) + { + std::cerr << "CFileLister::list: Error opening dir " << p_path << std::endl; + return false; + } + // Clean up + m_listFiles.clear(); + m_listDirs.clear(); + // Read dir + std::string l_file(""); + std::string l_fileFull(""); + struct stat l_stat; + struct dirent *l_dirent = readdir(l_dir); + while (l_dirent != NULL) + { + l_file = l_dirent->d_name; + // Filter the '.' and '..' dirs + if (l_file != "." && l_file != "..") + { + // Stat the file + l_fileFull = p_path + "/" + l_file; + if (stat(l_fileFull.c_str(), &l_stat) == -1) + { + std::cerr << "CFileLister::list: Error stat " << l_fileFull << std::endl; + } + else + { + // Check type + if (S_ISDIR(l_stat.st_mode)) + // It's a directory + m_listDirs.push_back(T_FILE(l_file, l_stat.st_size)); + else + // It's a file + m_listFiles.push_back(T_FILE(l_file, l_stat.st_size)); + } + } + // Next + l_dirent = readdir(l_dir); + } + // Close dir + closedir(l_dir); + // Sort lists + sort(m_listFiles.begin(), m_listFiles.end(), compareNoCase); + sort(m_listDirs.begin(), m_listDirs.end(), compareNoCase); + // Add "..", always at the first place + m_listDirs.insert(m_listDirs.begin(), T_FILE("..", 0)); + return true; +} + +const T_FILE &CFileLister::operator[](const unsigned int p_i) const +{ + if (p_i < m_listDirs.size()) + return m_listDirs[p_i]; + else + return m_listFiles[p_i - m_listDirs.size()]; +} + +const unsigned int CFileLister::getNbDirs(void) const +{ + return m_listDirs.size(); +} + +const unsigned int CFileLister::getNbFiles(void) const +{ + return m_listFiles.size(); +} + +const unsigned int CFileLister::getNbTotal(void) const +{ + return m_listDirs.size() + m_listFiles.size(); +} + +const bool CFileLister::isDirectory(const unsigned int p_i) const +{ + return p_i < m_listDirs.size(); +} + +const unsigned int CFileLister::searchDir(const std::string &p_name) const +{ + unsigned int l_ret = 0; + bool l_found = false; + // Search name in dirs + for (std::vector::const_iterator l_it = m_listDirs.begin(); (!l_found) && (l_it != m_listDirs.end()); ++l_it) + { + if ((*l_it).m_name == p_name) + l_found = true; + else + ++l_ret; + } + return l_found ? l_ret : 0; +} diff --git a/other/DinguxCommander/src/fileLister.h b/other/DinguxCommander/src/fileLister.h new file mode 100644 index 0000000..f1b4f82 --- /dev/null +++ b/other/DinguxCommander/src/fileLister.h @@ -0,0 +1,58 @@ +#ifndef _FILE_LISTER_H_ +#define _FILE_LISTER_H_ + +#include +#include + +// Class used to store file info +struct T_FILE +{ + T_FILE(void): m_name(""), m_size(0) {} + T_FILE(const std::string &p_name, const unsigned long int &p_size): m_name(p_name), m_size(p_size) {} + T_FILE(const T_FILE &p_source): m_name(p_source.m_name), m_size(p_source.m_size) {} + ~T_FILE(void) {} + const T_FILE &operator =(const T_FILE &p_source) { m_name = p_source.m_name; m_size = p_source.m_size; return *this; } + std::string m_name; + unsigned long int m_size; +}; + +class CFileLister +{ + public: + + // Constructor + CFileLister(void); + + // Destructor + virtual ~CFileLister(void); + + // Read the contents of the given path + // Returns false if the path does not exist + const bool list(const std::string &p_path); + + // Get an element in the list (dirs and files combined) + const T_FILE &operator[](const unsigned int p_i) const; + + // Get the number of dirs/files + const unsigned int getNbDirs(void) const; + const unsigned int getNbFiles(void) const; + const unsigned int getNbTotal(void) const; + + // True => directory, false => file + const bool isDirectory(const unsigned int p_i) const; + + // Get index of the given dir name, 0 if not found + const unsigned int searchDir(const std::string &p_name) const; + + private: + + // Forbidden + CFileLister(const CFileLister &p_source); + const CFileLister &operator =(const CFileLister &p_source); + + // The list of files/dir + std::vector m_listDirs; + std::vector m_listFiles; +}; + +#endif diff --git a/other/DinguxCommander/src/fileutils.cpp b/other/DinguxCommander/src/fileutils.cpp new file mode 100644 index 0000000..f97e5cc --- /dev/null +++ b/other/DinguxCommander/src/fileutils.cpp @@ -0,0 +1,356 @@ +#include +#include +#include +#include +#include +#include +#include "fileutils.h" +#include "def.h" +#include "dialog.h" +#include "sdlutils.h" + +#define SPECIAL_CHARS "\\`$();|{}&'\"*?<>[]!^~-#\n\r " + +void File_utils::copyFile(const std::vector &p_src, const std::string &p_dest) +{ + std::string l_command(""); + std::string l_destFile(""); + std::string l_fileName(""); + bool l_loop(true); + bool l_confirm(true); + bool l_execute(true); + for (std::vector::const_iterator l_it = p_src.begin(); l_loop && (l_it != p_src.end()); ++l_it) + { + l_execute = true; + // Check if destination files already exists + if (l_confirm) + { + l_fileName = getFileName(*l_it); + l_destFile = p_dest + (p_dest.at(p_dest.size() - 1) == '/' ? "" : "/") + l_fileName; + if (fileExists(l_destFile)) + { + INHIBIT(std::cout << "File " << l_destFile << " already exists => ask for confirmation" << std::endl;) + CDialog l_dialog("Question:", 0, 0); + l_dialog.addLabel("Overwrite " + l_fileName + "?"); + l_dialog.addOption("Yes"); + l_dialog.addOption("Yes to all"); + l_dialog.addOption("No"); + l_dialog.addOption("Cancel"); + l_dialog.init(); + switch (l_dialog.execute()) + { + case 1: + // Yes + break; + case 2: + // Yes to all + l_confirm = false; + break; + case 3: + // No + l_execute = false; + break; + default: + // Cancel + l_execute = false; + l_loop = false; + break; + } + } + } + if (l_execute) + { + // Waiting message + SDL_utils::pleaseWait(); + l_command = "\\cp -r " + specialChars(*l_it) + " " + specialChars(p_dest); + INHIBIT(std::cout << "Command: " << l_command << std::endl;) + system(l_command.c_str()); + } + } +} + +void File_utils::moveFile(const std::vector &p_src, const std::string &p_dest) +{ + std::string l_command(""); + std::string l_destFile(""); + std::string l_fileName(""); + bool l_loop(true); + bool l_confirm(true); + bool l_execute(true); + for (std::vector::const_iterator l_it = p_src.begin(); l_loop && (l_it != p_src.end()); ++l_it) + { + l_execute = true; + // Check if destination files already exists + if (l_confirm) + { + l_fileName = getFileName(*l_it); + l_destFile = p_dest + (p_dest.at(p_dest.size() - 1) == '/' ? "" : "/") + l_fileName; + if (fileExists(l_destFile)) + { + INHIBIT(std::cout << "File " << l_destFile << " already exists => ask for confirmation" << std::endl;) + CDialog l_dialog("Question:", 0, 0); + l_dialog.addLabel("Overwrite " + l_fileName + "?"); + l_dialog.addOption("Yes"); + l_dialog.addOption("Yes to all"); + l_dialog.addOption("No"); + l_dialog.addOption("Cancel"); + l_dialog.init(); + switch (l_dialog.execute()) + { + case 1: + // Yes + break; + case 2: + // Yes to all + l_confirm = false; + break; + case 3: + // No + l_execute = false; + break; + default: + // Cancel + l_execute = false; + l_loop = false; + break; + } + } + } + if (l_execute) + { + // Waiting message + SDL_utils::pleaseWait(); + l_command = "\\mv " + specialChars(*l_it) + " " + specialChars(p_dest); + INHIBIT(std::cout << "Command: " << l_command << std::endl;) + system(l_command.c_str()); + } + } +} + +void File_utils::renameFile(const std::string &p_file1, const std::string &p_file2) +{ + bool l_execute(true); + // Check if destination files already exists + if (fileExists(p_file2)) + { + INHIBIT(std::cout << "File " << p_file2 << " already exists => ask for confirmation" << std::endl;) + CDialog l_dialog("Question:", 0, 0); + l_dialog.addLabel("Overwrite " + getFileName(p_file2) + "?"); + l_dialog.addOption("Yes"); + l_dialog.addOption("No"); + l_dialog.init(); + if (l_dialog.execute() != 1) + l_execute = false; + } + if (l_execute) + { + std::string l_command = "\\mv " + specialChars(p_file1) + " " + specialChars(p_file2); + INHIBIT(std::cout << "Command: " << l_command << std::endl;) + system(l_command.c_str()); + } +} + +void File_utils::removeFile(const std::vector &p_files) +{ + std::string l_command(""); + for (std::vector::const_iterator l_it = p_files.begin(); l_it != p_files.end(); ++l_it) + { + l_command = "\\rm -rf " + specialChars(*l_it); + INHIBIT(std::cout << "Command: " << l_command << std::endl;) + system(l_command.c_str()); + } +} + +void File_utils::makeDirectory(const std::string &p_file) +{ + std::string l_command = "\\mkdir -p " + specialChars(p_file); + INHIBIT(std::cout << "Command: " << l_command << std::endl;) + system(l_command.c_str()); +} + +const bool File_utils::fileExists(const std::string &p_path) +{ + struct stat l_stat; + return stat(p_path.c_str(), &l_stat) == 0; +} + +const std::string File_utils::getFileName(const std::string &p_path) +{ + size_t l_pos = p_path.rfind('/'); + return p_path.substr(l_pos + 1); +} + +const std::string File_utils::getPath(const std::string &p_path) +{ + size_t l_pos = p_path.rfind('/'); + return p_path.substr(0, l_pos); +} + +void File_utils::executeFile(const std::string &p_file) +{ + // Command + std::string l_command = "./" + specialChars(getFileName(p_file)); + INHIBIT(std::cout << "File_utils::executeFile: " << l_command << " in " << getPath(p_file) << std::endl;) + // CD to the file's location + chdir(getPath(p_file).c_str()); + // Quit + SDL_utils::hastalavista(); + // Execute file + execlp("/bin/sh", "/bin/sh", "-c", l_command.c_str(), NULL); + // If we're here, there was an error with the execution + std::cerr << "Error executing file " << p_file << std::endl; + // Relaunch DinguxCommander + l_command = "./" + specialChars(getSelfExecutionName()); + INHIBIT(std::cout << "File_utils::executeFile: " << l_command << " in " << getSelfExecutionPath() << std::endl;) + chdir(getSelfExecutionPath().c_str()); + execlp(l_command.c_str(), l_command.c_str(), NULL); +} + +const std::string File_utils::getSelfExecutionPath(void) +{ + // Get execution path + std::string l_exePath(""); + char l_buff[255]; + int l_i = readlink("/proc/self/exe", l_buff, 255); + l_exePath = l_buff; + l_exePath = l_exePath.substr(0, l_i); + l_i = l_exePath.rfind("/"); + l_exePath = l_exePath.substr(0, l_i); + return l_exePath; +} + +const std::string File_utils::getSelfExecutionName(void) +{ + // Get execution path + std::string l_exePath(""); + char l_buff[255]; + int l_i = readlink("/proc/self/exe", l_buff, 255); + l_exePath = l_buff; + l_exePath = l_exePath.substr(0, l_i); + l_i = l_exePath.rfind("/"); + l_exePath = l_exePath.substr(l_i + 1); + return l_exePath; +} + +void File_utils::stringReplace(std::string &p_string, const std::string &p_search, const std::string &p_replace) +{ + // Replace all occurrences of p_search by p_replace in p_string + size_t l_pos = p_string.find(p_search, 0); + while (l_pos != std::string::npos) + { + p_string.replace(l_pos, p_search.length(), p_replace); + l_pos = p_string.find(p_search, l_pos + p_replace.length()); + } +} + +const std::string File_utils::specialChars(const std::string &p_string) +{ + // Insert a '\' before special characters + std::string l_ret(p_string); + const std::string l_specialChars(SPECIAL_CHARS); + const size_t l_length = l_specialChars.size(); + std::string l_char(""); + for (unsigned int l_i = 0; l_i < l_length; ++l_i) + { + l_char = l_specialChars.substr(l_i, 1); + stringReplace(l_ret, l_char, "\\" + l_char); + } + return l_ret; +} + +const unsigned long int File_utils::getFileSize(const std::string &p_file) +{ + unsigned long int l_ret(0); + struct stat l_stat; + if (stat(p_file.c_str(), &l_stat) == -1) + std::cerr << "File_utils::getFileSize: Error stat " << p_file << std::endl; + else + l_ret = l_stat.st_size; + return l_ret; +} + +void File_utils::diskInfo(void) +{ + std::string l_line(""); + // Execute command df -h + { + char l_buffer[256]; + FILE *l_pipe = popen("df -h", "r"); + if (l_pipe == NULL) + { + std::cerr << "File_utils::diskInfo: Error popen" << std::endl; + return; + } + while (l_line.empty() && fgets(l_buffer, sizeof(l_buffer), l_pipe) != NULL) + if (strstr(l_buffer, FILE_SYSTEM) != NULL) + l_line = l_buffer; + pclose(l_pipe); + } + if (!l_line.empty()) + { + // Separate line by spaces + std::istringstream l_iss(l_line); + std::vector l_tokens; + copy(std::istream_iterator(l_iss), std::istream_iterator(), std::back_inserter >(l_tokens)); + // Display dialog + CDialog l_dialog("Disk information:", 0, 0); + l_dialog.addLabel("Size: " + l_tokens[1]); + l_dialog.addLabel("Used: " + l_tokens[2] + " (" + l_tokens[4] + ")"); + l_dialog.addLabel("Available: " + l_tokens[3]); + l_dialog.addOption("OK"); + l_dialog.init(); + l_dialog.execute(); + } + else + std::cerr << "File_utils::diskInfo: Unable to find " << FILE_SYSTEM << std::endl; +} + +void File_utils::diskUsed(const std::vector &p_files) +{ + std::string l_line(""); + // Waiting message + SDL_utils::pleaseWait(); + // Build and execute command + { + std::string l_command("du -csh"); + for (std::vector::const_iterator l_it = p_files.begin(); l_it != p_files.end(); ++l_it) + l_command = l_command + " \"" + *l_it + "\""; + char l_buffer[256]; + FILE *l_pipe = popen(l_command.c_str(), "r"); + if (l_pipe == NULL) + { + std::cerr << "File_utils::diskUsed: Error popen" << std::endl; + return; + } + while (fgets(l_buffer, sizeof(l_buffer), l_pipe) != NULL); + l_line = l_buffer; + pclose(l_pipe); + } + // Separate line by spaces + { + std::istringstream l_iss(l_line); + std::vector l_tokens; + copy(std::istream_iterator(l_iss), std::istream_iterator(), std::back_inserter >(l_tokens)); + l_line = l_tokens[0]; + } + // Dialog + std::ostringstream l_stream; + CDialog l_dialog("Disk used:", 0, 0); + l_stream << p_files.size() << " items selected"; + l_dialog.addLabel(l_stream.str()); + l_dialog.addLabel("Disk used: " + l_line); + l_dialog.addOption("OK"); + l_dialog.init(); + l_dialog.execute(); +} + +void File_utils::formatSize(std::string &p_size) +{ + // Format 123456789 to 123,456,789 + int l_i = p_size.size() - 3; + while (l_i > 0) + { + p_size.insert(l_i, ","); + l_i -= 3; + } +} diff --git a/other/DinguxCommander/src/fileutils.h b/other/DinguxCommander/src/fileutils.h new file mode 100644 index 0000000..e8dbe62 --- /dev/null +++ b/other/DinguxCommander/src/fileutils.h @@ -0,0 +1,50 @@ +#ifndef _FILEUTILS_H_ +#define _FILEUTILS_H_ + +#include +#include + +namespace File_utils +{ + // File operations + + void copyFile(const std::vector &p_src, const std::string &p_dest); + + void moveFile(const std::vector &p_src, const std::string &p_dest); + + void removeFile(const std::vector &p_files); + + void executeFile(const std::string &p_file); + + void makeDirectory(const std::string &p_file); + + void renameFile(const std::string &p_file1, const std::string &p_file2); + + // File utilities + + const bool fileExists(const std::string &p_path); + + const unsigned long int getFileSize(const std::string &p_file); + + void formatSize(std::string &p_size); + + const std::string getFileName(const std::string &p_path); + + const std::string getPath(const std::string &p_path); + + const std::string getSelfExecutionPath(void); + + const std::string getSelfExecutionName(void); + + void stringReplace(std::string &p_string, const std::string &p_search, const std::string &p_replace); + + const std::string specialChars(const std::string &p_string); + + // Dialogs + + void diskInfo(void); + + void diskUsed(const std::vector &p_files); +} + +#endif diff --git a/other/DinguxCommander/src/keyboard.cpp b/other/DinguxCommander/src/keyboard.cpp new file mode 100644 index 0000000..2d7629c --- /dev/null +++ b/other/DinguxCommander/src/keyboard.cpp @@ -0,0 +1,483 @@ +#include +#include "keyboard.h" +#include "sdlutils.h" +#include "resourceManager.h" +#include "def.h" + +#define KB_X 28 +#define KB_Y 128 +#define FIELD_Y 98 +#define FIELD_W 258 + +CKeyboard::CKeyboard(const std::string &p_inputText): + CWindow(), + m_imageKeyboard(NULL), + m_textField(NULL), + m_inputText(p_inputText), + m_selected(0), + m_footer(NULL), + m_keySet(0), + m_font(CResourceManager::instance().getFont()), + m_font_sm(CResourceManager::instance().getSmallFont()) +{ + // Key sets + m_keySets[0] = "abcdefghijklmnopqrstuvwxyz0123456789., "; + m_keySets[1] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789., "; + m_keySets[2] = "!#$%&'()[]{}+-;=@^_`´~¡¿¢£¤¥¦§«»±×÷©®° "; + m_keySets[3] = "áàäâãåéèëêæœçíìïîóòöôõðøñþúùüûýÿøßµ¹²³ "; + m_keySets[4] = "ÁÀÄÂÃÅÉÈËÊÆŒÇÍÌÏÎÓÒÖÔÕÐØÑÞÚÙÜÛÝŸØßµ¼½¾ "; + // Create keyboard image + { + SDL_Rect l_rect; + // Create keyboard image + m_imageKeyboard = SDL_utils::createImage(265, 84, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER)); + l_rect.x = 2; + l_rect.y = 2; + l_rect.w = 261; + l_rect.h = 80; + SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BG_2)); + // Keys + for (unsigned int l_y = 0; l_y < 3; ++l_y) + { + for (unsigned int l_x = 0; l_x < 13; ++l_x) + { + l_rect.x = 3 + 20 * l_x; + l_rect.y = 3 + 20 * l_y; + l_rect.w = 19; + l_rect.h = 18; + SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BORDER)); + ++l_rect.x; + ++l_rect.y; + l_rect.w -= 2; + l_rect.h -= 2; + SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BG_1)); + } + } + // Buttons Cancel and OK + l_rect.x = 3; + l_rect.y = 63; + l_rect.w = 129; + l_rect.h = 18; + SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BORDER)); + l_rect.x = 133; + SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BORDER)); + l_rect.w -= 2; + l_rect.h -= 2; + ++l_rect.y; + l_rect.x = 4; + SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BG_1)); + l_rect.x = 134; + SDL_FillRect(m_imageKeyboard, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BG_1)); + // Create text field image + m_textField = SDL_utils::createImage(265, 19, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER)); + l_rect.x = 2; + l_rect.y = 2; + l_rect.w = 261; + l_rect.h = 15; + SDL_FillRect(m_textField, &l_rect, SDL_MapRGB(m_imageKeyboard->format, COLOR_BG_1)); + } + // Create footer + m_footer = SDL_utils::createImage(SCREEN_WIDTH, H_FOOTER, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER)); + SDL_utils::applyText(SCREEN_WIDTH >> 1, 1, m_footer, m_font_sm, "A-Input B-Cancel START-OK L/R-Change Y-Backspace X-Space", Globals::g_colorTextTitle, SDL_utils::T_TEXT_ALIGN_CENTER); +} + +CKeyboard::~CKeyboard(void) +{ + // Free surfaces + if (m_imageKeyboard != NULL) + { + SDL_FreeSurface(m_imageKeyboard); + m_imageKeyboard = NULL; + } + if (m_textField != NULL) + { + SDL_FreeSurface(m_textField); + m_textField = NULL; + } + if (m_footer != NULL) + { + SDL_FreeSurface(m_footer); + m_footer = NULL; + } +} + +void CKeyboard::render(const bool p_focus) const +{ + INHIBIT(std::cout << "CKeyboard::render fullscreen: " << isFullScreen() << " focus: " << p_focus << std::endl;) + // Draw input text field + SDL_utils::applySurface(KB_X, FIELD_Y, m_textField, Globals::g_screen); + // Input text + if (!m_inputText.empty()) + { + SDL_Surface *l_surfaceTmp = SDL_utils::renderText(m_font, m_inputText, Globals::g_colorTextNormal); + if (l_surfaceTmp->w > FIELD_W) + { + // Text is too big => clip it + SDL_Rect l_rect; + l_rect.x = l_surfaceTmp->w - FIELD_W; + l_rect.y = 0; + l_rect.w = FIELD_W; + l_rect.h = l_surfaceTmp->h; + SDL_utils::applySurface(KB_X + 5, FIELD_Y + 4 - Y_OFFSET, l_surfaceTmp, Globals::g_screen, &l_rect); + } + else + SDL_utils::applySurface(KB_X + 5, FIELD_Y + 4 - Y_OFFSET, l_surfaceTmp, Globals::g_screen); + } + // Draw keyboard + SDL_utils::applySurface(KB_X, KB_Y, m_imageKeyboard, Globals::g_screen); + // Cursor + { + SDL_Rect l_rect; + if (m_selected < 39) + { + // A letter is selected + l_rect.w = 17; + l_rect.h = 16; + l_rect.x = KB_X + 4; + if (m_selected >= 26) + { + l_rect.x = KB_X + 4 + (m_selected - 26) * 20; + l_rect.y = KB_Y + 44; + } + else if (m_selected >= 13) + { + l_rect.x = KB_X + 4 + (m_selected - 13) * 20; + l_rect.y = KB_Y + 24; + } + else + { + l_rect.x = KB_X + 4 + m_selected * 20; + l_rect.y = KB_Y + 4; + } + } + else + { + l_rect.w = 127; + l_rect.h = 16; + l_rect.x = KB_X + 4 + (m_selected == 40) * 130; + l_rect.y = KB_Y + 64; + } + SDL_FillRect(Globals::g_screen, &l_rect, SDL_MapRGB(Globals::g_screen->format, COLOR_CURSOR_1)); + } + // Draw keys text + { + unsigned int l_i(0); + unsigned int l_x(0); + unsigned int l_y(0); + std::string l_text(""); + for (l_y = 0; l_y < 3; ++l_y) + { + for (l_x = 0; l_x < 13; ++l_x) + { + if (utf8Code(m_keySets[m_keySet].at(l_i))) + { + l_text = m_keySets[m_keySet].substr(l_i, 2); + l_i += 2; + } + else + { + l_text = m_keySets[m_keySet].substr(l_i, 1); + l_i += 1; + } + SDL_utils::applyText(KB_X + 20 * l_x + 13, KB_Y + 7 + 20 * l_y - Y_OFFSET, Globals::g_screen, m_font, l_text, Globals::g_colorTextNormal, SDL_utils::T_TEXT_ALIGN_CENTER); + } + } + } + // Buttons text + SDL_utils::applyText(KB_X + 67, KB_Y + 67 - Y_OFFSET, Globals::g_screen, m_font, "Cancel", Globals::g_colorTextNormal, SDL_utils::T_TEXT_ALIGN_CENTER); + SDL_utils::applyText(KB_X + 197, KB_Y + 67 - Y_OFFSET, Globals::g_screen, m_font, "OK", Globals::g_colorTextNormal, SDL_utils::T_TEXT_ALIGN_CENTER); + // Draw footer + SDL_utils::applySurface(0, 227, m_footer, Globals::g_screen); +} + +const bool CKeyboard::keyPress(const SDL_Event &p_event) +{ + CWindow::keyPress(p_event); + bool l_ret(false); + switch (p_event.key.keysym.sym) + { + case MYKEY_PARENT: + // B => Cancel + m_retVal = -1; + l_ret = true; + break; + case MYKEY_UP: + l_ret = moveCursorUp(true); + break; + case MYKEY_DOWN: + l_ret = moveCursorDown(true); + break; + case MYKEY_LEFT: + l_ret = moveCursorLeft(true); + break; + case MYKEY_RIGHT: + l_ret = moveCursorRight(true); + break; + case MYKEY_SYSTEM: + // Y => Backspace + l_ret = backspace(); + break; + case MYKEY_OPERATION: + // X => Space + l_ret = type(" "); + break; + case MYKEY_OPEN: + // A => Button pressed + if (m_selected == 39) + { + // Button Cancel + m_retVal = -1; + l_ret = true; + } + else if (m_selected == 40) + { + // Button OK + m_retVal = 1; + l_ret = true; + } + else + // A letter button + l_ret = type(); + break; + case MYKEY_PAGEDOWN: + // R => Change keys forward + m_keySet = (m_keySet + 1) % NB_KEY_SETS; + l_ret = true; + break; + case MYKEY_PAGEUP: + // L => Change keys backward + m_keySet = m_keySet ? m_keySet - 1 : NB_KEY_SETS - 1; + l_ret = true; + break; + case MYKEY_TRANSFER: + // START => OK + m_retVal = 1; + l_ret = true; + default: + break; + } + return l_ret; +} + +const bool CKeyboard::keyHold(void) +{ + bool l_ret(false); + switch(m_lastPressed) + { + case MYKEY_UP: + if (tick(SDL_GetKeyState(NULL)[MYKEY_UP])) + l_ret = moveCursorUp(false); + break; + case MYKEY_DOWN: + if (tick(SDL_GetKeyState(NULL)[MYKEY_DOWN])) + l_ret = moveCursorDown(false); + break; + case MYKEY_LEFT: + if (tick(SDL_GetKeyState(NULL)[MYKEY_LEFT])) + l_ret = moveCursorLeft(false); + break; + case MYKEY_RIGHT: + if (tick(SDL_GetKeyState(NULL)[MYKEY_RIGHT])) + l_ret = moveCursorRight(false); + break; + case MYKEY_OPEN: + // A => Add letter + if (tick(SDL_GetKeyState(NULL)[MYKEY_OPEN])) + l_ret = type(); + break; + case MYKEY_SYSTEM: + // Y => Backspace + if (tick(SDL_GetKeyState(NULL)[MYKEY_SYSTEM])) + l_ret = backspace(); + break; + case MYKEY_OPERATION: + // X => Space + if (tick(SDL_GetKeyState(NULL)[MYKEY_OPERATION])) + l_ret = type(" "); + break; + default: + break; + } + return l_ret; +} + +const bool CKeyboard::moveCursorUp(const bool p_loop) +{ + bool l_ret(false); + if (m_selected == 39) + { + m_selected = 29; + l_ret = true; + } + else if (m_selected == 40) + { + m_selected = 35; + l_ret = true; + } + else if (m_selected >= 13) + { + m_selected -= 13; + l_ret = true; + } + else if (m_selected >= 6) + { + if (p_loop) + { + m_selected = 40; + l_ret = true; + } + } + else + { + if (p_loop) + { + m_selected = 39; + l_ret = true; + } + } + return l_ret; +} + +const bool CKeyboard::moveCursorDown(const bool p_loop) +{ + bool l_ret(false); + if (m_selected == 39) + { + if (p_loop) + { + m_selected = 3; + l_ret = true; + } + } + else if (m_selected == 40) + { + if (p_loop) + { + m_selected = 9; + l_ret = true; + } + } + else if (m_selected >= 32) + { + m_selected = 40; + l_ret = true; + } + else if (m_selected >= 26) + { + m_selected = 39; + l_ret = true; + } + else + { + m_selected += 13; + l_ret = true; + } + return l_ret; +} + +const bool CKeyboard::moveCursorLeft(const bool p_loop) +{ + bool l_ret(false); + switch (m_selected) + { + case 0: + case 13: + case 26: + if (p_loop) + { + m_selected += 12; + l_ret = true; + } + break; + case 39: + if (p_loop) + { + m_selected = 40; + l_ret = true; + } + break; + default: + --m_selected; + l_ret = true; + break; + } + return l_ret; +} + +const bool CKeyboard::moveCursorRight(const bool p_loop) +{ + bool l_ret(false); + switch (m_selected) + { + case 12: + case 25: + case 38: + if (p_loop) + { + m_selected -= 12; + l_ret = true; + } + break; + case 40: + if (p_loop) + { + m_selected = 39; + l_ret = true; + } + break; + default: + ++m_selected; + l_ret = true; + break; + } + return l_ret; +} + +const bool CKeyboard::type(const std::string &p_text) +{ + if (p_text.empty()) + { + // Append selected character to the input text + if (m_selected < 39) + { + // Get real index + unsigned char l_index(0); + for (unsigned char l_c = 0; l_c < m_selected; ++l_c) + l_index += 1 + utf8Code(m_keySets[m_keySet].at(l_index)); + // Get size + size_t l_size = 1 + utf8Code(m_keySets[m_keySet].at(l_index)); + // Append text + m_inputText += m_keySets[m_keySet].substr(l_index, l_size); + } + else + std::cerr << "CKeyboard::type : unexpected value: " << m_selected << std::endl; + } + else + // Append given text + m_inputText += p_text; + return true; +} + +const std::string &CKeyboard::getInputText(void) const +{ + return m_inputText; +} + +const bool CKeyboard::backspace(void) +{ + bool l_ret(false); + if (!m_inputText.empty()) + { + if (m_inputText.size() >= 2 && utf8Code(m_inputText.at(m_inputText.size() - 2))) + m_inputText.resize(m_inputText.size() - 2); + else + m_inputText.resize(m_inputText.size() - 1); + l_ret = true; + } + return l_ret; +} + +const bool CKeyboard::utf8Code(const unsigned char p_c) const +{ + return (p_c >= 194 && p_c <= 198) || p_c == 208 || p_c == 209; +} diff --git a/other/DinguxCommander/src/keyboard.h b/other/DinguxCommander/src/keyboard.h new file mode 100644 index 0000000..0af0592 --- /dev/null +++ b/other/DinguxCommander/src/keyboard.h @@ -0,0 +1,79 @@ +#ifndef _KEYBOARD_H_ +#define _KEYBOARD_H_ + +#include +#include +#include +#include "window.h" + +#define NB_KEY_SETS 5 + +class CKeyboard : public CWindow +{ + public: + + // Constructor + CKeyboard(const std::string &p_inputText); + + // Destructor + virtual ~CKeyboard(void); + + // Get input text + const std::string &getInputText(void) const; + + private: + + // Forbidden + CKeyboard(void); + CKeyboard(const CKeyboard &p_source); + const CKeyboard &operator =(const CKeyboard &p_source); + + // Key press management + virtual const bool keyPress(const SDL_Event &p_event); + + // Key hold management + virtual const bool keyHold(void); + + // Draw + virtual void render(const bool p_focus) const; + + // Move cursor + const bool moveCursorUp(const bool p_loop); + const bool moveCursorDown(const bool p_loop); + const bool moveCursorLeft(const bool p_loop); + const bool moveCursorRight(const bool p_loop); + + // Type a letter + const bool type(const std::string &p_text = ""); + + // Remove last letter + const bool backspace(void); + + // UTF8 character or not + const bool utf8Code(const unsigned char p_c) const; + + // The image representing the keyboard + SDL_Surface *m_imageKeyboard; + + // The image representing the input text field + SDL_Surface *m_textField; + + // The input text + std::string m_inputText; + + // The cursor index + unsigned char m_selected; + + // The footer + SDL_Surface *m_footer; + + // Key sets + std::string m_keySets[NB_KEY_SETS]; + unsigned char m_keySet; + + // Pointers to resources + TTF_Font *m_font; + TTF_Font *m_font_sm; +}; + +#endif diff --git a/other/DinguxCommander/src/main.cpp b/other/DinguxCommander/src/main.cpp new file mode 100644 index 0000000..0f72734 --- /dev/null +++ b/other/DinguxCommander/src/main.cpp @@ -0,0 +1,89 @@ +#include +#include +#include +#include +#include "def.h" +#include "sdlutils.h" +#include "resourceManager.h" +#include "commander.h" + +// Globals +SDL_Surface *Globals::g_screen = NULL; +#if defined(PLATFORM_MIYOOMINI) || defined(PLATFORM_RG35XX) +SDL_Surface *Globals::g_scaled = NULL; +#endif +const SDL_Color Globals::g_colorTextNormal = {COLOR_TEXT_NORMAL}; +const SDL_Color Globals::g_colorTextTitle = {COLOR_TEXT_TITLE}; +const SDL_Color Globals::g_colorTextDir = {COLOR_TEXT_DIR}; +const SDL_Color Globals::g_colorTextSelected = {COLOR_TEXT_SELECTED}; +std::vector Globals::g_windows; + +int main(int argc, char** argv) +{ + // Avoid crash due to the absence of mouse + { + char l_s[]="SDL_NOMOUSE=1"; + putenv(l_s); + } + +#if defined(PLATFORM_RG35XX) + // we launch in an overclocked state on rg35xx + system("echo 504000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed"); +#endif + + // Init SDL + SDL_Init(SDL_INIT_VIDEO); + + // Hide cursor + SDL_ShowCursor(SDL_DISABLE); + SDL_EnableKeyRepeat(300,100); + + // Screen +#if defined(PLATFORM_MIYOOMINI) || defined(PLATFORM_RG35XX) + Globals::g_scaled = SDL_SetVideoMode(640, 480, SCREEN_BPP, SURFACE_FLAGS); + if (Globals::g_scaled == NULL) + { + std::cerr << "SDL_SetVideoMode failed: " << SDL_GetError() << std::endl; + return 1; + } + Globals::g_screen = SDL_CreateRGBSurface(SURFACE_FLAGS, SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, 0,0,0,0); + if (Globals::g_screen == NULL) + { + std::cerr << "SDL_CreateRGBSurface (screen) failed: " << SDL_GetError() << std::endl; + return 1; + } +#else + Globals::g_screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SURFACE_FLAGS); + if (Globals::g_screen == NULL) + { + std::cerr << "SDL_SetVideoMode failed: " << SDL_GetError() << std::endl; + return 1; + } +#endif + + // Init font + if (TTF_Init() == -1) + { + std::cerr << "TTF_Init failed: " << SDL_GetError() << std::endl; + return 1; + } + +#if defined(PLATFORM_RG350) || defined(PLATFORM_ODBETA) + SDL_utils::checkIPU(); + SDL_utils::setIPUSharpness("0"); +#endif + + // Create instances + CResourceManager::instance(); + char *home = getenv("HOME"); + std::string l_path = home ? home : PATH_DEFAULT; + CCommander l_commander(l_path, l_path); + + // Main loop + l_commander.execute(); + + //Quit + SDL_utils::hastalavista(); + + return 0; +} diff --git a/other/DinguxCommander/src/panel.cpp b/other/DinguxCommander/src/panel.cpp new file mode 100644 index 0000000..d140752 --- /dev/null +++ b/other/DinguxCommander/src/panel.cpp @@ -0,0 +1,339 @@ +#include +#include +#include "panel.h" +#include "resourceManager.h" +#include "sdlutils.h" +#include "fileutils.h" + +#define PANEL_SIZE 158 +#define NAME_SIZE 140 + +CPanel::CPanel(const std::string &p_path, const Sint16 p_x): + m_currentPath(""), + m_camera(0), + m_x(p_x), + m_highlightedLine(0), + m_iconDir(CResourceManager::instance().getSurface(CResourceManager::T_SURFACE_FOLDER)), + m_iconFile(CResourceManager::instance().getSurface(CResourceManager::T_SURFACE_FILE)), + m_iconUp(CResourceManager::instance().getSurface(CResourceManager::T_SURFACE_UP)), + m_cursor1(CResourceManager::instance().getSurface(CResourceManager::T_SURFACE_CURSOR1)), + m_cursor2(CResourceManager::instance().getSurface(CResourceManager::T_SURFACE_CURSOR2)), + m_font(CResourceManager::instance().getFont()) +{ + // List the given path + if (m_fileLister.list(p_path)) + { + // Path OK + m_currentPath = p_path; + } + else + { + // The path is wrong => take default + m_fileLister.list(PATH_DEFAULT); + m_currentPath = PATH_DEFAULT; + } +} + +CPanel::~CPanel(void) +{ +} + +void CPanel::render(const bool p_active) const +{ + // Draw cursor + SDL_utils::applySurface(m_x - 1, Y_LIST + (m_highlightedLine - m_camera) * LINE_HEIGHT, p_active ? m_cursor1 : m_cursor2, Globals::g_screen); + // Draw panel + const Sint16 l_x = m_x + m_iconDir->w + 2; + const unsigned int l_nbTotal = m_fileLister.getNbTotal(); + Sint16 l_y = Y_LIST; + SDL_Surface *l_surfaceTmp = NULL; + const SDL_Color *l_color = NULL; + SDL_Rect l_rect; + // Current dir + l_surfaceTmp = SDL_utils::renderText(m_font, m_currentPath, Globals::g_colorTextTitle); + if (l_surfaceTmp->w > PANEL_SIZE) + { + l_rect.x = l_surfaceTmp->w - PANEL_SIZE; + l_rect.y = 0; + l_rect.w = PANEL_SIZE; + l_rect.h = l_surfaceTmp->h; + SDL_utils::applySurface(m_x, Y_HEADER - Y_OFFSET, l_surfaceTmp, Globals::g_screen, &l_rect); + } + else + { + SDL_utils::applySurface(m_x, Y_HEADER - Y_OFFSET, l_surfaceTmp, Globals::g_screen); + } + SDL_FreeSurface(l_surfaceTmp); + // Content + for (unsigned int l_i = m_camera; l_i < m_camera + NB_VISIBLE_LINES && l_i < l_nbTotal; ++l_i) + { + // Icon and color + if (m_fileLister.isDirectory(l_i)) + { + // Icon + if (m_fileLister[l_i].m_name == "..") + l_surfaceTmp = m_iconUp; + else + l_surfaceTmp = m_iconDir; + // Color + if (m_selectList.find(l_i) != m_selectList.end()) + l_color = &Globals::g_colorTextSelected; + else + l_color = &Globals::g_colorTextDir; + } + else + { + // Icon + l_surfaceTmp = m_iconFile; + // Color + if (m_selectList.find(l_i) != m_selectList.end()) + l_color = &Globals::g_colorTextSelected; + else + l_color = &Globals::g_colorTextNormal; + } + SDL_utils::applySurface(m_x, l_y, l_surfaceTmp, Globals::g_screen); + // Text + l_surfaceTmp = SDL_utils::renderText(m_font, m_fileLister[l_i].m_name, *l_color); + if (l_surfaceTmp->w > NAME_SIZE) + { + l_rect.x = 0; + l_rect.y = 0; + l_rect.w = NAME_SIZE; + l_rect.h = l_surfaceTmp->h; + SDL_utils::applySurface(l_x, l_y + 2 - Y_OFFSET, l_surfaceTmp, Globals::g_screen, &l_rect); + } + else + { + SDL_utils::applySurface(l_x, l_y + 2 - Y_OFFSET, l_surfaceTmp, Globals::g_screen); + } + SDL_FreeSurface(l_surfaceTmp); + // Next line + l_y += LINE_HEIGHT; + } + // Footer + std::string l_footer("-"); + if (!m_fileLister.isDirectory(m_highlightedLine)) + { + std::ostringstream l_s; + l_s << m_fileLister[m_highlightedLine].m_size; + l_footer = l_s.str(); + File_utils::formatSize(l_footer); + } + SDL_utils::applyText(m_x + 2, Y_FOOTER - Y_OFFSET, Globals::g_screen, m_font, "Size:", Globals::g_colorTextTitle); + SDL_utils::applyText(m_x + PANEL_SIZE - 2, Y_FOOTER - Y_OFFSET, Globals::g_screen, m_font, l_footer, Globals::g_colorTextTitle, SDL_utils::T_TEXT_ALIGN_RIGHT); +} + +const bool CPanel::moveCursorUp(unsigned char p_step) +{ + bool l_ret(false); + if (m_highlightedLine) + { + // Move cursor + if (m_highlightedLine > p_step) + m_highlightedLine -= p_step; + else + m_highlightedLine = 0; + // Adjust camera + adjustCamera(); + // Return true for new render + l_ret = true; + } + return l_ret; +} + +const bool CPanel::moveCursorDown(unsigned char p_step) +{ + bool l_ret(false); + const unsigned int l_nb = m_fileLister.getNbTotal(); + if (m_highlightedLine < l_nb - 1) + { + // Move cursor + if (m_highlightedLine + p_step > l_nb - 1) + m_highlightedLine = l_nb - 1; + else + m_highlightedLine += p_step; + // Adjust camera + adjustCamera(); + // Return true for new render + l_ret = true; + } + return l_ret; +} + +const bool CPanel::open(const std::string &p_path) +{ + bool l_ret(false); + std::string l_newPath(""); + std::string l_oldDir(""); + if (p_path.empty()) + { + // Open highlighted dir + if (m_fileLister[m_highlightedLine].m_name == "..") + { + // Go to parent dir + size_t l_pos = m_currentPath.rfind('/'); + // Remove the last dir in the path + l_newPath = m_currentPath.substr(0, l_pos); + if (l_newPath.empty()) + // We're at / + l_newPath = "/"; + l_oldDir = m_currentPath.substr(l_pos + 1); + } + else + { + l_newPath = m_currentPath + (m_currentPath == "/" ? "" : "/") + m_fileLister[m_highlightedLine].m_name; + } + } + else + { + // Open given dir + if (p_path == m_currentPath) + return false; + l_newPath = p_path; + } + // List the new path + if (m_fileLister.list(l_newPath)) + { + // Path OK + m_currentPath = l_newPath; + // If it's a back movement, restore old dir + if (!l_oldDir.empty()) + m_highlightedLine = m_fileLister.searchDir(l_oldDir); + else + m_highlightedLine = 0; + // Camera + adjustCamera(); + // Clear select list + m_selectList.clear(); + // New render + l_ret = true; + } + INHIBIT(std::cout << "open - new current path: " << m_currentPath << std::endl;) + return l_ret; +} + +const bool CPanel::goToParentDir(void) +{ + bool l_ret(false); + // Select ".." and open it + if (m_currentPath != "/") + { + m_highlightedLine = 0; + l_ret = open(); + } + return l_ret; +} + +void CPanel::adjustCamera(void) +{ + if (m_fileLister.getNbTotal() <= NB_VISIBLE_LINES) + m_camera = 0; + else if (m_highlightedLine < m_camera) + m_camera = m_highlightedLine; + else if (m_highlightedLine > m_camera + NB_VISIBLE_LINES - 1) + m_camera = m_highlightedLine - NB_VISIBLE_LINES + 1; +} + +const std::string &CPanel::getHighlightedItem(void) const +{ + return m_fileLister[m_highlightedLine].m_name; +} + +const std::string CPanel::getHighlightedItemFull(void) const +{ + return m_currentPath + (m_currentPath == "/" ? "" : "/") + m_fileLister[m_highlightedLine].m_name; +} + +const std::string &CPanel::getCurrentPath(void) const +{ + return m_currentPath; +} + +const unsigned int &CPanel::getHighlightedIndex(void) const +{ + return m_highlightedLine; +} + +const unsigned int CPanel::getHighlightedIndexRelative(void) const +{ + return m_highlightedLine - m_camera; +} + +void CPanel::refresh(void) +{ + // List current path + if (m_fileLister.list(m_currentPath)) + { + // Adjust selected line + if (m_highlightedLine > m_fileLister.getNbTotal() - 1) + m_highlightedLine = m_fileLister.getNbTotal() - 1; + } + else + { + // Current path doesn't exist anymore => default + m_fileLister.list(PATH_DEFAULT); + m_currentPath = PATH_DEFAULT; + m_highlightedLine = 0; + } + // Camera + adjustCamera(); + // Clear select list + m_selectList.clear(); +} + +const bool CPanel::addToSelectList(const bool p_step) +{ + if (m_fileLister[m_highlightedLine].m_name != "..") + { + // Search highlighted element in select list + std::set::iterator l_it = m_selectList.find(m_highlightedLine); + if (l_it == m_selectList.end()) + // Element not present => we add it + m_selectList.insert(m_highlightedLine); + else + // Element present => we remove it from the list + m_selectList.erase(m_highlightedLine); + if (p_step) + moveCursorDown(1); + return true; + } + else + { + return false; + } +} + +const std::set &CPanel::getSelectList(void) const +{ + return m_selectList; +} + +void CPanel::getSelectList(std::vector &p_list) const +{ + p_list.clear(); + // Insert full path of selected files + for (std::set::const_iterator l_it = m_selectList.begin(); l_it != m_selectList.end(); ++l_it) + { + if (m_currentPath == "/") + p_list.push_back(m_currentPath + m_fileLister[*l_it].m_name); + else + p_list.push_back(m_currentPath + "/" + m_fileLister[*l_it].m_name); + } +} + +void CPanel::selectAll(void) +{ + const unsigned int l_nb = m_fileLister.getNbTotal(); + for (unsigned int l_i = 1; l_i < l_nb; ++l_i) + m_selectList.insert(l_i); +} + +void CPanel::selectNone(void) +{ + m_selectList.clear(); +} + +const bool CPanel::isDirectoryHighlighted(void) const +{ + return m_fileLister.isDirectory(m_highlightedLine); +} diff --git a/other/DinguxCommander/src/panel.h b/other/DinguxCommander/src/panel.h new file mode 100644 index 0000000..7fcecec --- /dev/null +++ b/other/DinguxCommander/src/panel.h @@ -0,0 +1,101 @@ +#ifndef _PANEL_H_ +#define _PANEL_H_ + +#include +#include +#include +#include +#include "fileLister.h" +#include "def.h" + +class CPanel +{ + public: + + // Constructor + CPanel(const std::string &p_path, const Sint16 p_x); + + // Destructor + virtual ~CPanel(void); + + // Draw the panel on the screen + void render(const bool p_active) const; + + // Move cursor + const bool moveCursorUp(unsigned char p_step); + const bool moveCursorDown(unsigned char p_step); + + // Open selected item + const bool open(const std::string &p_path = ""); + + // Refresh current directory + void refresh(void); + + // Go to parent dir + const bool goToParentDir(void); + + // Selected file with just the name + const std::string &getHighlightedItem(void) const; + + // Selected file with full path + const std::string getHighlightedItemFull(void) const; + + // Current path + const std::string &getCurrentPath(void) const; + + // Selected index + const unsigned int &getHighlightedIndex(void) const; + const unsigned int getHighlightedIndexRelative(void) const; + + // True => directory, false => file, or dir ".." + const bool isDirectoryHighlighted(void) const; + + // Add/remove current file to the select list + const bool addToSelectList(const bool p_step); + + // Get select list + const std::set &getSelectList(void) const; + void getSelectList(std::vector &p_list) const; + + // Clear select list + void selectAll(void); + void selectNone(void); + + private: + + // Forbidden + CPanel(void); + CPanel(const CPanel &p_source); + const CPanel &operator =(const CPanel &p_source); + + // Adjust camera + void adjustCamera(void); + + // File lister + CFileLister m_fileLister; + + // Current path + std::string m_currentPath; + + // Index of the first displayed line + unsigned int m_camera; + + // X coordinate + const Sint16 m_x; + + // Highlighted line + unsigned int m_highlightedLine; + + // Selection list + std::set m_selectList; + + // Pointers to resources + SDL_Surface *m_iconDir; + SDL_Surface *m_iconFile; + SDL_Surface *m_iconUp; + SDL_Surface *m_cursor1; + SDL_Surface *m_cursor2; + TTF_Font *m_font; +}; + +#endif diff --git a/other/DinguxCommander/src/resourceManager.cpp b/other/DinguxCommander/src/resourceManager.cpp new file mode 100644 index 0000000..992eada --- /dev/null +++ b/other/DinguxCommander/src/resourceManager.cpp @@ -0,0 +1,71 @@ +#include +#include "resourceManager.h" +#include "def.h" +#include "sdlutils.h" +#include "def.h" + +CResourceManager& CResourceManager::instance(void) +{ + static CResourceManager l_singleton; + return l_singleton; +} + +CResourceManager::CResourceManager(void) : + m_font(NULL) +{ + // Load images + m_surfaces[T_SURFACE_BG] = SDL_utils::loadImage(RESDIR "/background.png"); + m_surfaces[T_SURFACE_FILE] = SDL_utils::loadImage(RESDIR "/file.png"); + m_surfaces[T_SURFACE_FOLDER] = SDL_utils::loadImage(RESDIR "/folder.png"); + m_surfaces[T_SURFACE_UP] = SDL_utils::loadImage(RESDIR "/up.png"); + m_surfaces[T_SURFACE_CURSOR1] = SDL_utils::createImage(159, 15, SDL_MapRGB(Globals::g_screen->format, COLOR_CURSOR_1)); + m_surfaces[T_SURFACE_CURSOR2] = SDL_utils::createImage(159, 15, SDL_MapRGB(Globals::g_screen->format, COLOR_CURSOR_2)); + // Load fonts +#if defined(PLATFORM_TRIMUI) + m_font = SDL_utils::loadFont(RESDIR "/Commander-11.ttf", 11); +#else + m_font = SDL_utils::loadFont(RESDIR "/Fiery_Turk.ttf", 8); +#endif + m_font_sm = SDL_utils::loadFont(RESDIR "/Fiery_Turk.ttf", 8); +} + +void CResourceManager::sdlCleanup(void) +{ + INHIBIT(std::cout << "CResourceManager::sdlCleanup" << std::endl;) + int l_i(0); + // Free surfaces + for (l_i = 0; l_i < NB_SURFACES; ++l_i) + { + if (m_surfaces[l_i] != NULL) + { + SDL_FreeSurface(m_surfaces[l_i]); + m_surfaces[l_i] = NULL; + } + } + // Free fonts + if (m_font != NULL) + { + TTF_CloseFont(m_font); + m_font = NULL; + } + if (m_font_sm != NULL) + { + TTF_CloseFont(m_font_sm); + m_font_sm = NULL; + } +} + +SDL_Surface *CResourceManager::getSurface(const T_SURFACE p_surface) const +{ + return m_surfaces[p_surface]; +} + +TTF_Font *CResourceManager::getFont(void) const +{ + return m_font; +} + +TTF_Font *CResourceManager::getSmallFont(void) const +{ + return m_font_sm; +} diff --git a/other/DinguxCommander/src/resourceManager.h b/other/DinguxCommander/src/resourceManager.h new file mode 100644 index 0000000..f9559ac --- /dev/null +++ b/other/DinguxCommander/src/resourceManager.h @@ -0,0 +1,52 @@ +#ifndef _RESOURCEMANAGER_H_ +#define _RESOURCEMANAGER_H_ + +#include +#include + +#define NB_SURFACES 6 + +class CResourceManager +{ + public: + + typedef enum + { + T_SURFACE_BG = 0, + T_SURFACE_FILE, + T_SURFACE_FOLDER, + T_SURFACE_UP, + T_SURFACE_CURSOR1, + T_SURFACE_CURSOR2 + } + T_SURFACE; + + // Method to get the instance + static CResourceManager& instance(void); + + // Cleanup all resources + void sdlCleanup(void); + + // Get a loaded surface + SDL_Surface *getSurface(const T_SURFACE p_surface) const; + + // Get the loaded fonts + TTF_Font *getFont(void) const; + TTF_Font *getSmallFont(void) const; + + private: + + // Forbidden + CResourceManager(void); + CResourceManager(const CResourceManager &p_source); + const CResourceManager &operator =(const CResourceManager &p_source); + + // Images + SDL_Surface *m_surfaces[NB_SURFACES]; + + // Fonts + TTF_Font *m_font; + TTF_Font *m_font_sm; +}; + +#endif diff --git a/other/DinguxCommander/src/sdlutils.cpp b/other/DinguxCommander/src/sdlutils.cpp new file mode 100644 index 0000000..b9dad35 --- /dev/null +++ b/other/DinguxCommander/src/sdlutils.cpp @@ -0,0 +1,322 @@ +#include +#include "sdlutils.h" +#include +#include "def.h" +#include "resourceManager.h" + + +#if defined(PLATFORM_RG350) || defined(PLATFORM_ODBETA) +#include +std::string ipuscaling = "NONE"; + +// copied from gambatte-dms +void SDL_utils::checkIPU(void) { + FILE *aspect_ratio_file = NULL; + DIR *ipu_dir = NULL; + std::string ipu_OpenDinguxLegacy = ("/sys/devices/platform/jz-lcd.0/keep_aspect_ratio"); + std::string ipu_RetroFW10 = ("/proc/jz/ipu_ratio"); + std::string ipu_RetroFW20 = ("/proc/jz/ipu"); + std::string ipu_OpenDingux = ("/sys/devices/platform/13080000.ipu"); + + aspect_ratio_file = fopen(ipu_OpenDinguxLegacy.c_str(), "r+"); + if (aspect_ratio_file != NULL) { + fclose(aspect_ratio_file); + ipuscaling = ipu_OpenDinguxLegacy; + printf("Detected IPU scaling - OpenDinguxLegacy\n"); + return; + } + aspect_ratio_file = fopen(ipu_RetroFW10.c_str(), "r+"); + if (aspect_ratio_file != NULL) { + fclose(aspect_ratio_file); + ipuscaling = ipu_RetroFW10; + printf("Detected IPU scaling - RetroFW 1.X\n"); + return; + } + aspect_ratio_file = fopen("/proc/jz/gpio", "r+"); //workaround to check if the fw is retrofw2 + if (aspect_ratio_file != NULL) { + fclose(aspect_ratio_file); + ipuscaling = ipu_RetroFW20; + printf("Detected IPU scaling - RetroFW 2.X\n"); + return; + } + ipu_dir = opendir("/sys/devices/platform/13080000.ipu"); + if (ipu_dir != NULL) { + closedir(ipu_dir); + ipuscaling = "NEW_OD_IPU"; + printf("Detected IPU scaling - OpenDingux\n"); + return; + } + printf("Could not detect IPU scaling\n"); + return; +} + +void SDL_utils::setIPUSharpness(const char *svalue){ + if (ipuscaling == "NONE") return; + else if (ipuscaling == "NEW_OD_IPU") { + if(svalue == "0"){ + SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=0"); + } else if(svalue == "1"){ + SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=1"); + } else if(svalue == "2"){ + SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=2"); + } else if(svalue == "3"){ + SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=3"); + } else if(svalue == "4"){ + SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=4"); + } else if(svalue == "5"){ + SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=5"); + } else if(svalue == "6"){ + SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=6"); + } else if(svalue == "7"){ + SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=7"); + } else if(svalue == "8"){ + SDL_putenv("SDL_VIDEO_KMSDRM_SCALING_SHARPNESS=8"); + } + return; + } + FILE *sharpness_file = NULL; + sharpness_file = fopen("/sys/devices/platform/jz-lcd.0/sharpness_upscaling", "r+"); + if (sharpness_file != NULL) { + fclose(sharpness_file); + sharpness_file = fopen("/sys/devices/platform/jz-lcd.0/sharpness_upscaling", "w"); + fwrite(svalue, 1, 1, sharpness_file); + fclose(sharpness_file); + } +} +#endif + +// Load an image using SDL_image +SDL_Surface *SDL_utils::loadImage(const std::string &p_filename) +{ + INHIBIT(std::cout << "SDL_utils::loadImage(" << p_filename << ")" << std::endl;) + // Load image + SDL_Surface* l_img = IMG_Load(p_filename.c_str()); + SDL_Surface* l_img2 = NULL; + if(l_img != NULL) + { + // Optimize the image + l_img2 = SDL_DisplayFormat(l_img); + // Free the first image + SDL_FreeSurface(l_img); + // Set color key + if (l_img2 != NULL) + SDL_SetColorKey(l_img2, SDL_SRCCOLORKEY, SDL_MapRGB(l_img2->format, COLOR_KEY)); + } + // Check errors + if (l_img2 == NULL) + std::cerr << "SDL_utils::loadImage: " << SDL_GetError() << std::endl; + return l_img2; +} + +void SDL_utils::applySurface(const Sint16 p_x, const Sint16 p_y, SDL_Surface* p_source, SDL_Surface* p_destination, SDL_Rect *p_clip) +{ + // Rectangle to hold the offsets + SDL_Rect l_offset; + // Set offsets + l_offset.x = p_x; + l_offset.y = p_y; + //Blit the surface + SDL_BlitSurface(p_source, p_clip, p_destination, &l_offset); +} + +TTF_Font *SDL_utils::loadFont(const std::string &p_font, const int p_size) +{ + INHIBIT(std::cout << "SDL_utils::loadFont(" << p_font << ", " << p_size << ")" << std::endl;) + TTF_Font *l_font = TTF_OpenFont(p_font.c_str(), p_size); + if (l_font == NULL) + std::cerr << "SDL_utils::loadFont: " << SDL_GetError() << std::endl; + return l_font; +} + +SDL_Surface *SDL_utils::renderText(TTF_Font *p_font, const std::string &p_text, const SDL_Color &p_fg) +{ + return TTF_RenderUTF8_Solid(p_font, p_text.c_str(), p_fg); +} + +void SDL_utils::applyText(const Sint16 p_x, const Sint16 p_y, SDL_Surface* p_destination, TTF_Font *p_font, const std::string &p_text, const SDL_Color &p_fg, const T_TEXT_ALIGN p_align) +{ + SDL_Surface *l_text = renderText(p_font, p_text, p_fg); + switch (p_align) + { + case T_TEXT_ALIGN_LEFT: + applySurface(p_x, p_y, l_text, p_destination); + break; + case T_TEXT_ALIGN_RIGHT: + applySurface(p_x - l_text->w, p_y, l_text, p_destination); + break; + case T_TEXT_ALIGN_CENTER: + applySurface(p_x - l_text->w / 2, p_y, l_text, p_destination); + break; + default: + break; + } + SDL_FreeSurface(l_text); +} + +SDL_Surface *SDL_utils::createImage(const int p_width, const int p_height, const Uint32 p_color) +{ + // Create image in the same format as the screen + SDL_Surface *l_ret = SDL_CreateRGBSurface(SURFACE_FLAGS, p_width, p_height, Globals::g_screen->format->BitsPerPixel, Globals::g_screen->format->Rmask, Globals::g_screen->format->Gmask, Globals::g_screen->format->Bmask, Globals::g_screen->format->Amask); + if (l_ret == NULL) + std::cerr << "SDL_utils::createImage: " << SDL_GetError() << std::endl; + // Fill image with the given color + SDL_FillRect(l_ret, NULL, p_color); + return l_ret; +} + +void SDL_utils::renderAll(void) +{ + if (Globals::g_windows.empty()) + return; + // First window to draw is the last fullscreen + unsigned int l_i = Globals::g_windows.size() - 1; + while (l_i && !Globals::g_windows[l_i]->isFullScreen()) + --l_i; + // Draw windows + for (std::vector::iterator l_it = Globals::g_windows.begin() + l_i; l_it != Globals::g_windows.end(); ++l_it) + (*l_it)->render(l_it + 1 == Globals::g_windows.end()); +} + +void SDL_utils::hastalavista(void) +{ + // Destroy all dialogs except the first one (the commander) + while (Globals::g_windows.size() > 1) + delete Globals::g_windows.back(); + // Free resources + CResourceManager::instance().sdlCleanup(); + +#if defined(PLATFORM_MIYOOMINI) || defined(PLATFORM_RG35XX) + SDL_FreeSurface(Globals::g_screen); +#endif + + // Quit SDL + TTF_Quit(); + SDL_Quit(); +} + +void SDL_utils::pleaseWait(void) +{ + SDL_Surface *l_surfaceTmp = renderText(CResourceManager::instance().getFont(), "Please wait...", Globals::g_colorTextNormal); + SDL_Rect l_rect; + l_rect.x = (SCREEN_WIDTH - (l_surfaceTmp->w + 2 * DIALOG_MARGIN + 2 * DIALOG_BORDER)) >> 1; + l_rect.y = (SCREEN_HEIGHT - (l_surfaceTmp->h + 9)) >> 1; + l_rect.w = l_surfaceTmp->w + 2 * DIALOG_MARGIN + 2 * DIALOG_BORDER; + l_rect.h = l_surfaceTmp->h + 9; + SDL_FillRect(Globals::g_screen, &l_rect, SDL_MapRGB(Globals::g_screen->format, COLOR_BORDER)); + l_rect.x += DIALOG_BORDER; + l_rect.y += DIALOG_BORDER; + l_rect.w -= 2 * DIALOG_BORDER; + l_rect.h -= 2 * DIALOG_BORDER; + SDL_FillRect(Globals::g_screen, &l_rect, SDL_MapRGB(Globals::g_screen->format, COLOR_BG_1)); + applySurface((SCREEN_WIDTH - l_surfaceTmp->w) >> 1, (SCREEN_HEIGHT - l_surfaceTmp->h) >> 1, l_surfaceTmp, Globals::g_screen); + SDL_FreeSurface(l_surfaceTmp); +#if defined(PLATFORM_MIYOOMINI) || defined(PLATFORM_RG35XX) + upscale16NEON(Globals::g_screen->pixels, Globals::g_scaled->pixels); + SDL_Flip(Globals::g_scaled); +#else + SDL_Flip(Globals::g_screen); +#endif +} + +#if defined(PLATFORM_MIYOOMINI) || defined(PLATFORM_RG35XX) +// eggs amazing SW integer scaler +void upscale16NEON(void* src, void* dst) { + asm volatile ( + " vmov.u64 d1,#0xFFFFFFFF ;" + " vmvn.u64 d0,#0xFFFFFFFF ;" + " add r2,%0,#(320*240*2) ;" + "1: add r3,%1,#(640*1*2) ;" + " add lr,%1,#(640*2*2) ;" + "2: vldmia %0!,{q8-q11} ;" + " vdup.16 d2,d23[3] ;" + " vand d2,d2,d0 ;" + " vdup.16 d3,d23[2] ;" + " vand d3,d3,d1 ;" + " vorr d31,d2,d3 ;" + " vdup.16 d2,d23[1] ;" + " vand d2,d2,d0 ;" + " vdup.16 d3,d23[0] ;" + " vand d3,d3,d1 ;" + " vorr d30,d2,d3 ;" + " vdup.16 d2,d22[3] ;" + " vand d2,d2,d0 ;" + " vdup.16 d3,d22[2] ;" + " vand d3,d3,d1 ;" + " vorr d29,d2,d3 ;" + " vdup.16 d2,d22[1] ;" + " vand d2,d2,d0 ;" + " vdup.16 d3,d22[0] ;" + " vand d3,d3,d1 ;" + " vorr d28,d2,d3 ;" + " vdup.16 d2,d21[3] ;" + " vand d2,d2,d0 ;" + " vdup.16 d3,d21[2] ;" + " vand d3,d3,d1 ;" + " vorr d27,d2,d3 ;" + " vdup.16 d2,d21[1] ;" + " vand d2,d2,d0 ;" + " vdup.16 d3,d21[0] ;" + " vand d3,d3,d1 ;" + " vorr d26,d2,d3 ;" + " vdup.16 d2,d20[3] ;" + " vand d2,d2,d0 ;" + " vdup.16 d3,d20[2] ;" + " vand d3,d3,d1 ;" + " vorr d25,d2,d3 ;" + " vdup.16 d2,d20[1] ;" + " vand d2,d2,d0 ;" + " vdup.16 d3,d20[0] ;" + " vand d3,d3,d1 ;" + " vorr d24,d2,d3 ;" + " vdup.16 d2,d19[3] ;" + " vand d2,d2,d0 ;" + " vdup.16 d3,d19[2] ;" + " vand d3,d3,d1 ;" + " vorr d23,d2,d3 ;" + " vdup.16 d2,d19[1] ;" + " vand d2,d2,d0 ;" + " vdup.16 d3,d19[0] ;" + " vand d3,d3,d1 ;" + " vorr d22,d2,d3 ;" + " vdup.16 d2,d18[3] ;" + " vand d2,d2,d0 ;" + " vdup.16 d3,d18[2] ;" + " vand d3,d3,d1 ;" + " vorr d21,d2,d3 ;" + " vdup.16 d2,d18[1] ;" + " vand d2,d2,d0 ;" + " vdup.16 d3,d18[0] ;" + " vand d3,d3,d1 ;" + " vorr d20,d2,d3 ;" + " vdup.16 d2,d17[3] ;" + " vand d2,d2,d0 ;" + " vdup.16 d3,d17[2] ;" + " vand d3,d3,d1 ;" + " vorr d19,d2,d3 ;" + " vdup.16 d2,d17[1] ;" + " vand d2,d2,d0 ;" + " vdup.16 d3,d17[0] ;" + " vand d3,d3,d1 ;" + " vorr d18,d2,d3 ;" + " vdup.16 d2,d16[3] ;" + " vand d2,d2,d0 ;" + " vdup.16 d3,d16[2] ;" + " vand d3,d3,d1 ;" + " vorr d17,d2,d3 ;" + " vdup.16 d2,d16[1] ;" + " vand d2,d2,d0 ;" + " vdup.16 d3,d16[0] ;" + " vand d3,d3,d1 ;" + " vorr d16,d2,d3 ;" + " vstmia %1!,{q8-q15} ;" + " vstmia r3!,{q8-q15} ;" + " cmp r3,lr ;" + " bne 2b ;" + " cmp %0,r2 ;" + " mov %1,lr ;" + " bne 1b " + :: "r"(src), "r"(dst) + : "r2","r3","lr","q0","q1","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" + ); +} +#endif \ No newline at end of file diff --git a/other/DinguxCommander/src/sdlutils.h b/other/DinguxCommander/src/sdlutils.h new file mode 100644 index 0000000..294977f --- /dev/null +++ b/other/DinguxCommander/src/sdlutils.h @@ -0,0 +1,76 @@ +#ifndef _SDLUTILS_H_ +#define _SDLUTILS_H_ + +#include +#include +#include +#include +#include "window.h" + +namespace SDL_utils +{ + // Text alignment + typedef enum + { + T_TEXT_ALIGN_LEFT = 0, + T_TEXT_ALIGN_RIGHT, + T_TEXT_ALIGN_CENTER + } + T_TEXT_ALIGN; + +#if defined(PLATFORM_RG350) || defined(PLATFORM_ODBETA) + // identify IPU if available + void checkIPU(void); + void setIPUSharpness(const char *svalue); +#endif + + // Load an image using SDL_image + SDL_Surface *loadImage(const std::string &p_filename); + + // Load a TTF font + TTF_Font *loadFont(const std::string &p_font, const int p_size); + + // Apply a surface on another surface + void applySurface(const Sint16 p_x, const Sint16 p_y, SDL_Surface* p_source, SDL_Surface* p_destination, SDL_Rect *p_clip = NULL); + + // Render a text + SDL_Surface *renderText(TTF_Font *p_font, const std::string &p_text, const SDL_Color &p_fg); + + // Render a text and apply on a given surface + void applyText(const Sint16 p_x, const Sint16 p_y, SDL_Surface* p_destination, TTF_Font *p_font, const std::string &p_text, const SDL_Color &p_fg, const T_TEXT_ALIGN p_align = T_TEXT_ALIGN_LEFT); + + // Create an image filled with the given color + SDL_Surface *createImage(const int p_width, const int p_height, const Uint32 p_color); + + // Render all opened windows + void renderAll(void); + + // Cleanup and quit + void hastalavista(void); + + // Display a waiting window + void pleaseWait(void); +} + +// Globals +namespace Globals +{ + // Screen + extern SDL_Surface *g_screen; +#if defined(PLATFORM_MIYOOMINI) || defined(PLATFORM_RG35XX) + extern SDL_Surface *g_scaled; +#endif + // Colors + extern const SDL_Color g_colorTextNormal; + extern const SDL_Color g_colorTextTitle; + extern const SDL_Color g_colorTextDir; + extern const SDL_Color g_colorTextSelected; + // The list of opened windows + extern std::vector g_windows; +} + +#if defined(PLATFORM_MIYOOMINI) || defined(PLATFORM_RG35XX) +void upscale16NEON(void* src, void* dst); +#endif + +#endif diff --git a/other/DinguxCommander/src/viewer.cpp b/other/DinguxCommander/src/viewer.cpp new file mode 100644 index 0000000..204735a --- /dev/null +++ b/other/DinguxCommander/src/viewer.cpp @@ -0,0 +1,219 @@ +#include +#include +#include "viewer.h" +#include "resourceManager.h" +#include "def.h" +#include "sdlutils.h" + +CViewer::CViewer(const std::string &p_fileName): + CWindow(), + m_fileName(p_fileName), + m_firstLine(0), + m_image(NULL), + m_font(CResourceManager::instance().getFont()) +{ + // Init clip rect + m_clip.x = 0; + m_clip.y = 0; + m_clip.w = SCREEN_WIDTH - 2 * VIEWER_MARGIN; + // Create background image + m_image = SDL_utils::createImage(SCREEN_WIDTH, SCREEN_HEIGHT, SDL_MapRGB(Globals::g_screen->format, COLOR_BG_1)); + { + SDL_Rect l_rect; + l_rect.x = 0; + l_rect.y = 0; + l_rect.w = SCREEN_WIDTH; + l_rect.h = Y_LIST; + SDL_FillRect(m_image, &l_rect, SDL_MapRGB(m_image->format, COLOR_BORDER)); + } + // Print title + SDL_Surface *l_surfaceTmp = SDL_utils::renderText(m_font, m_fileName, Globals::g_colorTextTitle); + if (l_surfaceTmp->w > m_image->w - 2 * VIEWER_MARGIN) + { + SDL_Rect l_rect; + l_rect.x = l_surfaceTmp->w - (m_image->w - 2 * VIEWER_MARGIN); + l_rect.y = 0; + l_rect.w = m_image->w - 2 * VIEWER_MARGIN; + l_rect.h = l_surfaceTmp->h; + SDL_utils::applySurface(VIEWER_MARGIN, Y_HEADER, l_surfaceTmp, m_image, &l_rect); + } + else + { + SDL_utils::applySurface(VIEWER_MARGIN, Y_HEADER, l_surfaceTmp, m_image); + } + m_clip.h = l_surfaceTmp->h; + SDL_FreeSurface(l_surfaceTmp); + // Read file + std::ifstream l_file(m_fileName.c_str()); + if (l_file.is_open()) + { + std::string l_line(""); + while (std::getline(l_file, l_line)) + { + m_lines.push_back(l_line); + } + l_file.close(); + } + else + std::cerr << "Error: unable to open file " << m_fileName << std::endl; + INHIBIT(std::cout << "CViewer: " << m_lines.size() << " lines read" << std::endl;) +} + +CViewer::~CViewer(void) +{ + // Free surfaces + if (m_image != NULL) + { + SDL_FreeSurface(m_image); + m_image = NULL; + } +} + +void CViewer::render(const bool p_focus) const +{ + INHIBIT(std::cout << "CViewer::render fullscreen: " << isFullScreen() << " focus: " << p_focus << std::endl;) + // Draw background + SDL_utils::applySurface(0, 0, m_image, Globals::g_screen); + // Draw lines + SDL_Surface *l_surfaceTmp(NULL); + unsigned int l_i(0); + std::vector::const_iterator l_it = m_lines.begin() + m_firstLine; + while (l_it != m_lines.end() && l_i < VIEWER_NB_LINES) + { + if (!l_it->empty()) + { + l_surfaceTmp = SDL_utils::renderText(m_font, *l_it, Globals::g_colorTextNormal); + SDL_utils::applySurface(VIEWER_MARGIN, VIEWER_Y_LIST + l_i * VIEWER_LINE_HEIGHT - Y_OFFSET, l_surfaceTmp, Globals::g_screen, &m_clip); + SDL_FreeSurface(l_surfaceTmp); + } + // Next line + ++l_it; + ++l_i; + } +} + +const bool CViewer::keyPress(const SDL_Event &p_event) +{ + CWindow::keyPress(p_event); + bool l_ret(false); + switch (p_event.key.keysym.sym) + { + case MYKEY_PARENT: + case MYKEY_MENU: + m_retVal = -1; + l_ret = true; + break; + case MYKEY_UP: + l_ret = moveUp(1); + break; + case MYKEY_DOWN: + l_ret = moveDown(1); + break; + case MYKEY_PAGEUP: + l_ret = moveUp(VIEWER_NB_LINES - 1); + break; + case MYKEY_PAGEDOWN: + l_ret = moveDown(VIEWER_NB_LINES - 1); + break; + case MYKEY_LEFT: + l_ret = moveLeft(); + break; + case MYKEY_RIGHT: + moveRight(); + l_ret = true; + break; + default: + break; + } + return l_ret; +} + +const bool CViewer::keyHold(void) +{ + bool l_ret(false); + switch(m_lastPressed) + { + case MYKEY_UP: + if (tick(SDL_GetKeyState(NULL)[MYKEY_UP])) + l_ret = moveUp(1); + break; + case MYKEY_DOWN: + if (tick(SDL_GetKeyState(NULL)[MYKEY_DOWN])) + l_ret = moveDown(1); + break; + case MYKEY_PAGEUP: + if (tick(SDL_GetKeyState(NULL)[MYKEY_PAGEUP])) + l_ret = moveUp(VIEWER_NB_LINES - 1); + break; + case MYKEY_PAGEDOWN: + if (tick(SDL_GetKeyState(NULL)[MYKEY_PAGEDOWN])) + l_ret = moveDown(VIEWER_NB_LINES - 1); + break; + case MYKEY_LEFT: + if (tick(SDL_GetKeyState(NULL)[MYKEY_LEFT])) + l_ret = moveLeft(); + break; + case MYKEY_RIGHT: + if (tick(SDL_GetKeyState(NULL)[MYKEY_RIGHT])) + { + moveRight(); + l_ret = true; + } + break; + default: + break; + } + return l_ret; +} + +const bool CViewer::isFullScreen(void) const +{ + return true; +} + +const bool CViewer::moveUp(const unsigned int p_step) +{ + bool l_ret(false); + if (m_firstLine) + { + if (m_firstLine > p_step) + m_firstLine -= p_step; + else + m_firstLine = 0; + l_ret = true; + } + return l_ret; +} + +const bool CViewer::moveDown(const unsigned int p_step) +{ + bool l_ret(false); + if (m_firstLine + VIEWER_NB_LINES + 1 < m_lines.size()) + { + if (m_firstLine + VIEWER_NB_LINES + 1 + p_step > m_lines.size()) + m_firstLine = m_lines.size() - VIEWER_NB_LINES - 1; + else + m_firstLine += p_step; + l_ret = true; + } + return l_ret; +} + +const bool CViewer::moveLeft(void) +{ + bool l_ret(false); + if (m_clip.x > 0) + { + if (m_clip.x > VIEWER_X_STEP) + m_clip.x -= VIEWER_X_STEP; + else + m_clip.x = 0; + l_ret = true; + } + return l_ret; +} + +void CViewer::moveRight(void) +{ + m_clip.x += VIEWER_X_STEP; +} diff --git a/other/DinguxCommander/src/viewer.h b/other/DinguxCommander/src/viewer.h new file mode 100644 index 0000000..52094ca --- /dev/null +++ b/other/DinguxCommander/src/viewer.h @@ -0,0 +1,69 @@ +#ifndef _VIEWER_H_ +#define _VIEWER_H_ + +#include +#include +#include +#include +#include "window.h" + +#define VIEWER_LINE_HEIGHT 13 +#define VIEWER_NB_LINES 17 +#define VIEWER_Y_LIST 18 +#define VIEWER_MARGIN 1 +#define VIEWER_X_STEP 32 +#define VIEWER_SIZE_MAX 16777216 // = 16 MB + +class CViewer : public CWindow +{ + public: + + // Constructor + CViewer(const std::string &p_fileName); + + // Destructor + virtual ~CViewer(void); + + private: + + // Forbidden + CViewer(void); + CViewer(const CViewer &p_source); + const CViewer &operator =(const CViewer &p_source); + + // Key press management + virtual const bool keyPress(const SDL_Event &p_event); + + // Key hold management + virtual const bool keyHold(void); + + // Draw + virtual void render(const bool p_focus) const; + + // Is window full screen? + virtual const bool isFullScreen(void) const; + + // Scroll + const bool moveUp(const unsigned int p_step); + const bool moveDown(const unsigned int p_step); + const bool moveLeft(void); + void moveRight(void); + + // The viewed file name + std::string m_fileName; + + // Coordinates + unsigned int m_firstLine; + mutable SDL_Rect m_clip; + + // Background image + SDL_Surface *m_image; + + // List of read lines + std::vector m_lines; + + // Pointers to resources + TTF_Font *m_font; +}; + +#endif diff --git a/other/DinguxCommander/src/window.cpp b/other/DinguxCommander/src/window.cpp new file mode 100644 index 0000000..22f751a --- /dev/null +++ b/other/DinguxCommander/src/window.cpp @@ -0,0 +1,138 @@ +#include +#include "window.h" +#include "def.h" +#include "sdlutils.h" + +#define KEYHOLD_TIMER_FIRST 6 +#define KEYHOLD_TIMER 2 + +CWindow::CWindow(void): + m_timer(0), +#if defined(PLATFORM_RG35XX) + m_lastPressed(0), +#else + m_lastPressed(SDLK_0), +#endif + m_retVal(0) +{ + // Add window to the lists for render + Globals::g_windows.push_back(this); +} + +CWindow::~CWindow(void) +{ + // Remove last window + Globals::g_windows.pop_back(); +} + +const int CWindow::execute(void) +{ + m_retVal = 0; + Uint32 l_time(0); + SDL_Event l_event; + bool l_loop(true); + bool l_render(true); + // Main loop + while (l_loop) + { + l_time = SDL_GetTicks(); + // Handle key press + while (SDL_PollEvent(&l_event)) + { + if (l_event.type == SDL_KEYDOWN) + { + l_render = this->keyPress(l_event); + if (m_retVal) + l_loop = false; + } + else if (l_event.type == SDL_QUIT) + { + // Re-insert event so we exit from nested menus + SDL_PushEvent(&l_event); + l_loop = false; + break; + } + } + // Handle key hold + if (l_loop) + l_render = this->keyHold() || l_render; + // Render if necessary + if (l_render && l_loop) + { + SDL_utils::renderAll(); +#if defined(PLATFORM_MIYOOMINI) || defined(PLATFORM_RG35XX) + upscale16NEON(Globals::g_screen->pixels, Globals::g_scaled->pixels); + SDL_Flip(Globals::g_scaled); +#else + SDL_Flip(Globals::g_screen); +#endif + l_render = false; + INHIBIT(std::cout << "Render time: " << SDL_GetTicks() - l_time << "ms"<< std::endl;) + } + // Cap the framerate + l_time = MS_PER_FRAME - (SDL_GetTicks() - l_time); + if (l_time <= MS_PER_FRAME) SDL_Delay(l_time); + } + return m_retVal; +} + +const bool CWindow::keyPress(const SDL_Event &p_event) +{ + // Reset timer if running + if (m_timer) + m_timer = 0; +#if defined(PLATFORM_RG35XX) + m_lastPressed = p_event.key.keysym.scancode; +#else + m_lastPressed = p_event.key.keysym.sym; +#endif + return false; +} + +const bool CWindow::keyHold(void) +{ + // Default behavior + return false; +} + +const bool CWindow::tick(const Uint8 p_held) +{ + bool l_ret(false); + if (p_held) + { + if (m_timer) + { + --m_timer; + if (!m_timer) + { + // Trigger! + l_ret = true; + // Timer continues + m_timer = KEYHOLD_TIMER; + } + } + else + { + // Start timer + m_timer = KEYHOLD_TIMER_FIRST; + } + } + else + { + // Stop timer if running + if (m_timer) + m_timer = 0; + } + return l_ret; +} + +const int CWindow::getReturnValue(void) const +{ + return m_retVal; +} + +const bool CWindow::isFullScreen(void) const +{ + // Default behavior + return false; +} diff --git a/other/DinguxCommander/src/window.h b/other/DinguxCommander/src/window.h new file mode 100644 index 0000000..a998e62 --- /dev/null +++ b/other/DinguxCommander/src/window.h @@ -0,0 +1,58 @@ +#ifndef _WINDOW_H_ +#define _WINDOW_H_ + +#include + +class CWindow +{ + public: + + // Destructor + virtual ~CWindow(void); + + // Execute main loop of the window + const int execute(void); + + // Return value + const int getReturnValue(void) const; + + // Draw window + virtual void render(const bool p_focus) const = 0; + + // Is window full screen? + virtual const bool isFullScreen(void) const; + + protected: + + // Constructor + CWindow(void); + + // Key press management + virtual const bool keyPress(const SDL_Event &p_event); + + // Key hold management + virtual const bool keyHold(void); + + // Timer tick + const bool tick(const Uint8 p_held); + + // Timer for key hold + unsigned int m_timer; +#if defined(PLATFORM_RG35XX) + uint8_t m_lastPressed; +#else + SDLKey m_lastPressed; +#endif + + // Return value + int m_retVal; + + private: + + // Forbidden + CWindow(const CWindow &p_source); + const CWindow &operator =(const CWindow &p_source); + +}; + +#endif diff --git a/src/minarch/libretro-common b/src/minarch/libretro-common deleted file mode 160000 index 458bcd8..0000000 --- a/src/minarch/libretro-common +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 458bcd842bc48f730e12732fe8b3280e834d45ff diff --git a/src/minarch/libretro-common/.gitignore b/src/minarch/libretro-common/.gitignore new file mode 100644 index 0000000..4e88cc3 --- /dev/null +++ b/src/minarch/libretro-common/.gitignore @@ -0,0 +1,6 @@ +glsm/ +*.[od] +*.dll +*.so +*.dylib +*.exe diff --git a/src/minarch/libretro-common/Makefile.test b/src/minarch/libretro-common/Makefile.test new file mode 100644 index 0000000..4e1deed --- /dev/null +++ b/src/minarch/libretro-common/Makefile.test @@ -0,0 +1,58 @@ + +OBJDIR = ../obj-unix + +TEST_UNIT_CFLAGS = $(CFLAGS) -Iinclude $(LDFLAGS) -lcheck $(LIBCHECK_CFLAGS) -Werror -Wdeclaration-after-statement -fsanitize=address -fsanitize=undefined -ftest-coverage -fprofile-arcs -ggdb + +TEST_GENERIC_QUEUE = test/queues/test_generic_queue +TEST_GENERIC_QUEUE_SRC = test/queues/test_generic_queue.c queues/generic_queue.c + +TEST_LINKED_LIST = test/lists/test_linked_list +TEST_LINKED_LIST_SRC = test/lists/test_linked_list.c lists/linked_list.c + +TEST_STDSTRING = test/string/test_stdstring +TEST_STDSTRING_SRC = test/string/test_stdstring.c string/stdstring.c encodings/encoding_utf.c \ + compat/compat_strl.c + +TEST_UTILS = test/utils/test_utils +TEST_UTILS_SRC = test/utils/test_utils.c utils/md5.c encodings/encoding_crc32.c \ + streams/file_stream.c vfs/vfs_implementation.c file/file_path.c \ + compat/compat_strl.c time/rtime.c string/stdstring.c encodings/encoding_utf.c + +TEST_HASH = test/hash/test_hash +TEST_HASH_SRC = test/hash/test_hash.c hash/lrc_hash.c \ + streams/file_stream.c vfs/vfs_implementation.c file/file_path.c \ + compat/compat_strl.c time/rtime.c string/stdstring.c encodings/encoding_utf.c + +all: + # Build and execute tests in order, to avoid coverage file collision + # string + $(CC) $(TEST_UNIT_CFLAGS) $(TEST_STDSTRING_SRC) -o $(TEST_STDSTRING) + $(TEST_STDSTRING) + lcov -c -d . -o `dirname $(TEST_STDSTRING)`/coverage.info + # utils + $(CC) $(TEST_UNIT_CFLAGS) $(TEST_UTILS_SRC) -o $(TEST_UTILS) + $(TEST_UTILS) + lcov -c -d . -o `dirname $(TEST_UTILS)`/coverage.info + # utils + $(CC) $(TEST_UNIT_CFLAGS) $(TEST_HASH_SRC) -o $(TEST_HASH) + $(TEST_HASH) + lcov -c -d . -o `dirname $(TEST_HASH)`/coverage.info + # list + $(CC) $(TEST_UNIT_CFLAGS) $(TEST_LINKED_LIST_SRC) -o $(TEST_LINKED_LIST) + $(TEST_LINKED_LIST) + lcov -c -d . -o `dirname $(TEST_LINKED_LIST)`/coverage.info + # queue + $(CC) $(TEST_UNIT_CFLAGS) $(TEST_GENERIC_QUEUE_SRC) -o $(TEST_GENERIC_QUEUE) + $(TEST_GENERIC_QUEUE) + lcov -c -d . -o `dirname $(TEST_GENERIC_QUEUE)`/coverage.info + + lcov -o test/coverage.info \ + -a test/utils/coverage.info \ + -a test/string/coverage.info \ + -a test/lists/coverage.info \ + -a test/queues/coverage.info + genhtml -o test/coverage/ test/coverage.info + +clean: + rm -f *.gcda *.gcno + diff --git a/src/minarch/libretro-common/audio/audio_mix.c b/src/minarch/libretro-common/audio/audio_mix.c new file mode 100644 index 0000000..eb138ed --- /dev/null +++ b/src/minarch/libretro-common/audio/audio_mix.c @@ -0,0 +1,377 @@ +/* Copyright (C) 2010-2020 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (audio_mix.c). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include + +#if defined(__SSE2__) +#include +#elif defined(__ALTIVEC__) +#include +#endif + +#include +#include