diff -Nru atari800-3.1.0/src/atari.c atari800-3.1.0-android/src/atari.c --- atari800-3.1.0/src/atari.c 2014-03-03 11:24:13.000000000 +0200 +++ atari800-3.1.0-android/src/atari.c 2016-08-27 20:52:01.111419183 +0300 @@ -416,11 +416,11 @@ } *argc = j; } -#ifndef ANDROID +//#ifndef ANDROID got_config = CFG_LoadConfig(rtconfig_filename); -#else - got_config = TRUE; /* pretend we got a config file -- not needed in Android */ -#endif +//#else +// got_config = TRUE; /* pretend we got a config file -- not needed in Android */ +//#endif /* try to find ROM images if the configuration file is not found or it does not specify some ROM paths (blank paths count as specified) */ @@ -1227,7 +1227,11 @@ #ifdef SOUND Sound_Pause(); #endif +#ifdef GUICHAN_GUI +int startgui = gui_open(); +#else UI_Run(); +#endif #ifdef SOUND Sound_Continue(); #endif diff -Nru atari800-3.1.0/src/autogen.sh atari800-3.1.0-android/src/autogen.sh --- atari800-3.1.0/src/autogen.sh 1970-01-01 03:00:00.000000000 +0300 +++ atari800-3.1.0-android/src/autogen.sh 2016-08-27 20:52:01.111419183 +0300 @@ -0,0 +1,58 @@ +#! /bin/sh +# Run this to generate all the initial makefiles, etc. +# This was lifted from the BasiliskII, and adapted slightly by +# Milan Jurik. + +DIE=0 + +PROG="ARAnyM" + +# Check for GNU make + +test -z "$MAKE" && MAKE=make + +# Check how echo works in this /bin/sh +case `echo -n` in +-n) _echo_n= _echo_c='\c';; +*) _echo_n=-n _echo_c=;; +esac + +(autoconf --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have autoconf installed to compile $PROG." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + DIE=1 +} + +(aclocal --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: Missing aclocal. The version of automake" + echo "installed doesn't appear recent enough." + echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 +} + +if test "$DIE" -eq 1; then + exit 1 +fi + +if [ -z "$*" -a -z "$NO_CONFIGURE" ]; then + echo "I am going to run ./configure with no arguments - if you wish " + echo "to pass any to it, please specify them on the $0 command line." +fi + +ACLOCAL_FLAGS="-I m4" +aclocalinclude="$ACLOCAL_FLAGS"; \ +(echo $_echo_n " + Running aclocal: $_echo_c"; \ + aclocal $aclocalinclude; \ + echo "done.") && \ +(echo $_echo_n " + Running autoheader: $_echo_c"; \ + autoheader; \ + echo "done.") && \ +(echo $_echo_n " + Running autoconf: $_echo_c"; \ + autoconf; \ + echo "done.") + +echo all done diff -Nru atari800-3.1.0/src/config.h.in atari800-3.1.0-android/src/config.h.in --- atari800-3.1.0/src/config.h.in 2014-04-12 17:00:06.000000000 +0300 +++ atari800-3.1.0-android/src/config.h.in 2016-08-27 21:31:09.313424966 +0300 @@ -539,6 +539,11 @@ /* Target: X11 with XView. */ #undef XVIEW +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS diff -Nru atari800-3.1.0/src/config.sub atari800-3.1.0-android/src/config.sub --- atari800-3.1.0/src/config.sub 2006-04-08 15:07:36.000000000 +0300 +++ atari800-3.1.0-android/src/config.sub 2016-08-27 20:52:01.111419183 +0300 @@ -1206,7 +1206,7 @@ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -udi* | -eabi* | -androideabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ diff -Nru atari800-3.1.0/src/configure atari800-3.1.0-android/src/configure --- atari800-3.1.0/src/configure 2014-04-12 17:00:06.000000000 +0300 +++ atari800-3.1.0-android/src/configure 2016-08-27 22:22:50.164432577 +0300 @@ -4594,7 +4594,7 @@ case "$a8_target" in default) if [ "$a8_host" != "dos" ]; then - CFLAGS="$CFLAGS -ansi" + CFLAGS="$CFLAGS -DGUICHAN_GUI" fi CFLAGS="$CFLAGS -pedantic -Waggregate-return -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Winline" if [ "$a8_host" != "beos" ]; then @@ -10939,6 +10939,7 @@ echo echo "Main build variables:" echo " CC......: \"$CC\"" +echo " CXX.....: \"$CXX\"" echo " CFLAGS..: \"$CFLAGS\"" echo " CPPFLAGS: \"$CPPFLAGS\"" echo " LDFLAGS.: \"$LDFLAGS\"" diff -Nru atari800-3.1.0/src/configure.ac atari800-3.1.0-android/src/configure.ac --- atari800-3.1.0/src/configure.ac 2014-04-12 16:58:16.000000000 +0300 +++ atari800-3.1.0-android/src/configure.ac 2016-08-27 20:52:01.119418863 +0300 @@ -271,7 +271,7 @@ default) if [[ "$a8_host" != "dos" ]]; then dnl In DJGPP building with zlib fails with -ansi. - CFLAGS="$CFLAGS -ansi" + CFLAGS="$CFLAGS -DGUICHAN_GUI" fi CFLAGS="$CFLAGS -pedantic -Waggregate-return -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Winline" if [[ "$a8_host" != "beos" ]]; then @@ -1204,6 +1204,7 @@ echo echo "Main build variables:" echo " CC......: \"$CC\"" +echo " CXX......: \"$CXX\"" echo " CFLAGS..: \"$CFLAGS\"" echo " CPPFLAGS: \"$CPPFLAGS\"" echo " LDFLAGS.: \"$LDFLAGS\"" diff -Nru atari800-3.1.0/src/guichan/guichan-gui.cpp atari800-3.1.0-android/src/guichan/guichan-gui.cpp --- atari800-3.1.0/src/guichan/guichan-gui.cpp 1970-01-01 03:00:00.000000000 +0300 +++ atari800-3.1.0-android/src/guichan/guichan-gui.cpp 2015-01-28 18:31:10.000000000 +0200 @@ -0,0 +1,382 @@ +#include +#ifdef ANDROID +#include +#endif +#include +#include +#include +#include +#include +#include "sdltruetypefont.hpp" +#include + +#define PANDORA + +#if defined(ANDROID) +#include +#endif + +extern SDL_Surface* SDL_VIDEO_screen; +int emulating; +bool running = false; +int rungame=0; +bool menu_onscreen = true; + +#define GUI_WIDTH 640 +#define GUI_HEIGHT 480 + +/* What is being loaded */ +#define MENU_SELECT_FILE 1 +#define MENU_ADD_DIR 2 + +char currentDir[300]; +char launchDir[300]; + +namespace globals +{ +gcn::Gui* gui; +} + +namespace sdl +{ +// Main objects to draw graphics and get user input +gcn::SDLGraphics* graphics; +gcn::SDLInput* input; +gcn::SDLImageLoader* imageLoader; + +void init() +{ +#ifdef PANDORA + char layersize[20]; + snprintf(layersize, 20, "%dx%d", GUI_WIDTH, GUI_HEIGHT); + + char bordercut[20]; + snprintf(bordercut, 20, "0,0,0,0"); + +#endif + SDL_VIDEO_screen = SDL_SetVideoMode(GUI_WIDTH, GUI_HEIGHT, 16, SDL_SWSURFACE); + SDL_EnableUNICODE(1); + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); + +#ifdef PANDORA + SDL_ShowCursor(SDL_ENABLE); +#endif + + imageLoader = new gcn::SDLImageLoader(); + gcn::Image::setImageLoader(imageLoader); + + graphics = new gcn::SDLGraphics(); + graphics->setTarget(SDL_VIDEO_screen); + + input = new gcn::SDLInput(); + + globals::gui = new gcn::Gui(); + globals::gui->setGraphics(graphics); + globals::gui->setInput(input); +} + + +void halt() +{ + delete globals::gui; + delete imageLoader; + delete input; + delete graphics; +} + + +void run() +{ + // The main loop + while(running) { + // Check user input + SDL_Event event; + while(SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT) { + running = false; + break; + } else if (event.type == SDL_KEYDOWN) { + switch(event.key.keysym.sym) { + case SDLK_ESCAPE: + case SDLK_F1: + running = false; + break; + +#ifndef PANDORA + case SDLK_f: + if (event.key.keysym.mod & KMOD_CTRL) { + // Works with X11 only + SDL_WM_ToggleFullScreen(SDL_VIDEO_screen); + } + break; +#endif + } + } + input->pushInput(event); + } + // Now we let the Gui object perform its logic. + globals::gui->logic(); + // Now we let the Gui object draw itself. + globals::gui->draw(); + // Finally we update the screen. + SDL_Flip(SDL_VIDEO_screen); + } +} + +} + + +namespace widgets +{ +extern void run_menuLoad_guichan(char *curr_path, int aLoadType); +extern gcn::Window *window_load; +extern gcn::Window *window_warning; +extern gcn::Window *window_savestate; +void show_settings(void); +void menuSaveState_Init(void); +void menuSaveState_Exit(void); +void loadMenu_Init(void); +void loadMenu_Exit(void); +void menuMessage_Init(void); +void menuMessage_Exit(void); +std::string selectedFilePath; + +gcn::Color baseCol; +gcn::Color baseColLabel; +gcn::Container* top; +gcn::contrib::SDLTrueTypeFont* font; + +// Presets + +// Main buttons +gcn::Image *background_image; +gcn::Icon* background; +gcn::Button* button_reset; +gcn::Button* button_resume; +gcn::Button* button_quit; +gcn::Button* button_savestate; +gcn::Container* backgrd_onscreen; +gcn::CheckBox* checkBox_onscreen; + +extern "C" { + void Atari800_Exit(bool); + int AFILE_OpenFile(const char *filename, int reboot, int diskno, int readonly); +} + +class QuitButtonActionListener : public gcn::ActionListener +{ +public: + void action(const gcn::ActionEvent& actionEvent) { + running = false; + Atari800_Exit(false); + exit(0); + } +}; +QuitButtonActionListener* quitButtonActionListener; + + +class ResetButtonActionListener : public gcn::ActionListener +{ +public: + void action(const gcn::ActionEvent& actionEvent) { + run_menuLoad_guichan(currentDir, MENU_SELECT_FILE); + } +}; +ResetButtonActionListener* resetButtonActionListener; + + +class ResumeButtonActionListener : public gcn::ActionListener +{ +public: + void action(const gcn::ActionEvent& actionEvent) { + running = false; + } +}; +ResumeButtonActionListener* resumeButtonActionListener; + +class StateButtonActionListener : public gcn::ActionListener +{ +public: + void action(const gcn::ActionEvent& actionEvent) { + window_savestate->setVisible(true); + } +}; +StateButtonActionListener* stateButtonActionListener; + +class OnscreenActionListener : public gcn::ActionListener +{ +public: + void action(const gcn::ActionEvent& actionEvent) { + if (actionEvent.getSource() == checkBox_onscreen) + if (checkBox_onscreen->isSelected()) + menu_onscreen=true; + else + menu_onscreen=false; + } +}; +OnscreenActionListener* onscreenActionListener; + +void init() +{ + baseCol.r = 192; + baseCol.g = 192; + baseCol.b = 208; + baseColLabel.r = baseCol.r; + baseColLabel.g = baseCol.g; + baseColLabel.b = baseCol.b; + baseColLabel.a = 192; + + top = new gcn::Container(); + top->setDimension(gcn::Rectangle(0, 0, 640, 480)); + top->setBaseColor(baseCol); + globals::gui->setTop(top); + + TTF_Init(); + font = new gcn::contrib::SDLTrueTypeFont("data/FreeSans.ttf", 17); + gcn::Widget::setGlobalFont(font); + + background_image = gcn::Image::load("data/background.jpg"); + background = new gcn::Icon(background_image); + + //-------------------------------------------------- + // Create main buttons + //-------------------------------------------------- + + button_quit = new gcn::Button("Quit"); + button_quit->setSize(90,50); + button_quit->setBaseColor(baseCol); + button_quit->setId("Quit"); + quitButtonActionListener = new QuitButtonActionListener(); + button_quit->addActionListener(quitButtonActionListener); + + button_reset = new gcn::Button("Run"); + button_reset->setSize(90,50); + button_reset->setBaseColor(baseCol); + button_reset->setId("Reset"); + resetButtonActionListener = new ResetButtonActionListener(); + button_reset->addActionListener(resetButtonActionListener); + + button_resume = new gcn::Button("Resume"); + button_resume->setSize(90,50); + button_resume->setBaseColor(baseCol); + button_resume->setId("Resume"); + resumeButtonActionListener = new ResumeButtonActionListener(); + button_resume->addActionListener(resumeButtonActionListener); + + button_savestate = new gcn::Button("SaveStates"); + button_savestate->setSize(100,50); + button_savestate->setBaseColor(baseCol); + button_savestate->setId("SaveStates"); + stateButtonActionListener = new StateButtonActionListener(); + button_savestate->addActionListener(stateButtonActionListener); + + checkBox_onscreen = new gcn::CheckBox("On-Screen Control"); + checkBox_onscreen->setPosition(4,2); + checkBox_onscreen->setId("onScrCtrl"); + checkBox_onscreen->setBaseColor(baseColLabel); + onscreenActionListener = new OnscreenActionListener(); + checkBox_onscreen->addActionListener(onscreenActionListener); + + backgrd_onscreen = new gcn::Container(); + backgrd_onscreen->setOpaque(true); + backgrd_onscreen->setBaseColor(baseColLabel); + backgrd_onscreen->setPosition(20, 350); + backgrd_onscreen->setSize(190, 27); + backgrd_onscreen->add(checkBox_onscreen); + backgrd_onscreen->setVisible(true); + + menuSaveState_Init(); + menuMessage_Init(); + loadMenu_Init(); + + //-------------------------------------------------- + // Place everything on main form + //-------------------------------------------------- + top->add(background, 0, 0); + top->add(button_reset, 210, 410); + top->add(button_resume, 320, 410); + top->add(button_quit, 430, 410); + top->add(button_savestate, 20, 410); + top->add(backgrd_onscreen); + top->add(window_savestate); + top->add(window_load, 120, 20); + top->add(window_warning, 170, 220); + + show_settings(); +} + +//-------------------------------------------------- +// Initialize focus handling +//-------------------------------------------------- +// button_reset->setFocusable(true); +// button_resume->setFocusable(true); +// button_quit->setFocusable(true); + +void halt() +{ + menuSaveState_Exit(); + menuMessage_Exit(); + loadMenu_Exit(); + + delete button_reset; + delete button_resume; + delete button_quit; + delete button_savestate; + delete backgrd_onscreen; + delete checkBox_onscreen; + + delete resumeButtonActionListener; + delete resetButtonActionListener; + delete quitButtonActionListener; + delete stateButtonActionListener; + delete onscreenActionListener; + + delete background; + delete background_image; + + delete font; + delete top; + +} + +//----------------------------------------------- +// Start of helper functions +//----------------------------------------------- +void show_settings() +{ + if (menu_onscreen==true) + checkBox_onscreen->setSelected(true); + else + checkBox_onscreen->setSelected(false); +} + +} + +extern "C" { + int gui_open(); + int VIDEOMODE_Update(); +} + +int gui_open() +{ + getcwd(launchDir, 250); + strcpy(currentDir,"."); +// strcmp(currentDir,launchDir); +#ifdef ANDROID + SDL_ANDROID_SetScreenKeyboardShown(0); +#endif + running = true; + + sdl::init(); + widgets::init(); + sdl::run(); + widgets::halt(); + sdl::halt(); +#ifdef ANDROID + if (menu_onscreen) + SDL_ANDROID_SetScreenKeyboardShown(1); +#endif + if (!VIDEOMODE_Update()) + return false; + return -1; +} diff -Nru atari800-3.1.0/src/guichan/menuLoad_guichan.cpp atari800-3.1.0-android/src/guichan/menuLoad_guichan.cpp --- atari800-3.1.0/src/guichan/menuLoad_guichan.cpp 1970-01-01 03:00:00.000000000 +0300 +++ atari800-3.1.0-android/src/guichan/menuLoad_guichan.cpp 2015-01-28 18:31:32.000000000 +0200 @@ -0,0 +1,571 @@ +#include +#ifdef ANDROID +#include +#include +#endif +#include +#include +#include +#include +#include +#include "sdltruetypefont.hpp" +#include "rw_config.h" +#include +#include + +#if defined(WIN32) +#define realpath(N,R) _fullpath((R),(N),_MAX_PATH) +#endif + +#ifndef PATH_MAX +#define PATH_MAX 256 +#endif + +#define extterms files[q].size()>=4 && files[q].substr(files[q].size()-4) +#define fileterms extterms!=".atr" && extterms!=".ATR" && extterms!=".Atr" && extterms!=".exe" && extterms!=".EXE" && extterms!=".Exe" && extterms!=".com" && extterms!=".COM" && extterms!=".Com" && extterms!=".cas" && extterms!=".CAS" && extterms!=".Cas" + +extern bool running; +bool confirmselection = false; +int menuLoad_extfilter=1; + +#define _XOPEN_SOURCE 500 +#if defined(AROS) +#include + +#if defined(__GP2X__) || defined(__WIZ__) || defined(__CAANOO__) || defined(__amigaos__) +// This is a random default value ... +#define PATH_MAX 32768 +#endif + +static char *sep(char *path) +{ + char *tmp, c; + + tmp = strrchr(path, '/'); + if(tmp) { + c = tmp[1]; + tmp[1] = 0; + if (chdir(path)) { + return NULL; + } + tmp[1] = c; + + return tmp + 1; + } + return path; +} + +char *realpath(const char *_path, char *resolved_path) +{ + int fd = open(".", O_RDONLY), l; + char current_dir_path[PATH_MAX]; + char path[PATH_MAX], lnk[PATH_MAX], *tmp = (char *)""; + + if (fd < 0) { + return NULL; + } + getcwd(current_dir_path,PATH_MAX); + strncpy(path, _path, PATH_MAX); + + if (chdir(path)) { + if (errno == ENOTDIR) { +#if defined(__WIN32__) || defined(__MORPHOS__) || defined(__amigaos__) + // No symbolic links and no readlink() + l = -1; +#else + l = readlink(path, lnk, PATH_MAX); +#endif + if (!(tmp = sep(path))) { + resolved_path = NULL; + goto abort; + } + if (l < 0) { + if (errno != EINVAL) { + resolved_path = NULL; + goto abort; + } + } else { + lnk[l] = 0; + if (!(tmp = sep(lnk))) { + resolved_path = NULL; + goto abort; + } + } + } else { + resolved_path = NULL; + goto abort; + } + } + + if(resolved_path==NULL) // if we called realpath with null as a 2nd arg + resolved_path = (char*) malloc( PATH_MAX ); + + if (!getcwd(resolved_path, PATH_MAX)) { + resolved_path = NULL; + goto abort; + } + + if(strcmp(resolved_path, "..") && *tmp) { + strcat(resolved_path, ".."); + } + + strcat(resolved_path, tmp); +abort: + chdir(current_dir_path); + close(fd); + return resolved_path; +} + +#endif + +/* What is being loaded, floppy/hd dir/hdf */ +int menu_load_type; + +namespace widgets +{ +void show_settings(void); +static void unraise_loadMenu_guichan(); +static void checkfilename (char *currentfilename); +extern std::string selectedFilePath; + +extern gcn::Color baseCol; +gcn::Window *window_load; +gcn::Button* button_ok; +gcn::Button* button_select; +gcn::Button* button_open; +gcn::Button* button_cancel; +#ifdef ANDROID +gcn::CheckBox* checkBox_extfilter; +#endif +gcn::ListBox* listBox; +gcn::ScrollArea* listBoxScrollArea; + +gcn::Widget* activateAfterClose = NULL; + +int lastSelectedIndex = 0; + + +class DirListModel : public gcn::ListModel +{ + std::vector dirs, files; + +public: + DirListModel(const char * path) { + changeDir(path); + } + + int getNumberOfElements() { + if (menu_load_type != MENU_ADD_DIR) + return dirs.size() + files.size(); + else + return dirs.size(); + } + + std::string getElementAt(int i) { + if(i >= dirs.size() + files.size() || i < 0) + return "---"; + if(i < dirs.size()) + return dirs[i]; + if (menu_load_type != MENU_ADD_DIR) + return files[i - dirs.size()]; + } + + void changeDir(const char * path) { + dirs.clear(); + files.clear(); + DIR *dir; + struct dirent *dent; + dir = opendir(path); + if(dir != NULL) { + while((dent=readdir(dir))!=NULL) { + if(dent->d_type == DT_DIR) + dirs.push_back(dent->d_name); + else if (menu_load_type != MENU_ADD_DIR) + files.push_back(dent->d_name); + } + + if(dirs.size() > 0 && dirs[0] == ".") + dirs.erase(dirs.begin()); + + closedir(dir); + } + + if(dirs.size() == 0) + dirs.push_back(".."); + + std::sort(dirs.begin(), dirs.end()); + if (menu_load_type != MENU_ADD_DIR) + std::sort(files.begin(), files.end()); +#ifdef ANDROID + if (menuLoad_extfilter==1) +#endif + for (int q=0; qgetSelected(); + lastSelectedIndex = selected_item; + strcpy(filename, ""); + strcat(filename, currentDir); + strcat(filename, "/"); + strcat(filename, dirList.getElementAt(selected_item).c_str()); + confirmselection=true; + checkfilename(filename); + } +}; +OkButtonActionListener* okButtonActionListener; + + +class SelectButtonActionListener : public gcn::ActionListener +{ +public: + void action(const gcn::ActionEvent& actionEvent) { + int selected_item; + char filename[256]=""; + + selected_item = listBox->getSelected(); + lastSelectedIndex = selected_item; + strcpy(filename, ""); + strcat(filename, currentDir); + strcat(filename, "/"); + strcat(filename, dirList.getElementAt(selected_item).c_str()); + if (menu_load_type == MENU_ADD_DIR) { +// strcpy(uae4all_hard_dir, filename); + } + unraise_loadMenu_guichan(); + } +}; +SelectButtonActionListener* selectButtonActionListener; + + +class OpenButtonActionListener : public gcn::ActionListener +{ +public: + void action(const gcn::ActionEvent& actionEvent) { + int selected_item; + char filename[256]=""; + + selected_item = listBox->getSelected(); + lastSelectedIndex = selected_item; + strcpy(filename, ""); + strcat(filename, currentDir); + strcat(filename, "/"); + strcat(filename, dirList.getElementAt(selected_item).c_str()); + checkfilename(filename); + } +}; +OpenButtonActionListener* openButtonActionListener; + + +class CancelButtonActionListener : public gcn::ActionListener +{ +public: + void action(const gcn::ActionEvent& actionEvent) { + unraise_loadMenu_guichan(); + } +}; +CancelButtonActionListener* cancelButtonActionListener; + + +class ListBoxActionListener : public gcn::ActionListener +{ +public: + void action(const gcn::ActionEvent& actionEvent) { + confirmselection=false; +#if defined(WIN32) || defined(ANDROID) || defined(AROS) || defined(RASPBERRY) + if (menu_load_type != MENU_ADD_DIR) { +#endif + + int selected_item; + char filename[256]=""; + + selected_item = listBox->getSelected(); + lastSelectedIndex = selected_item; + strcpy(filename, ""); + strcat(filename, currentDir); + strcat(filename, "/"); + strcat(filename, dirList.getElementAt(selected_item).c_str()); + checkfilename(filename); +#if defined(WIN32) || defined(ANDROID) || defined(AROS) || defined(RASPBERRY) + } +#endif + } +}; +ListBoxActionListener* listBoxActionListener; + + +class ListBoxKeyListener : public gcn::KeyListener +{ +public: + void keyPressed(gcn::KeyEvent& keyEvent) { + bool bHandled = false; + + Uint8 *keystate; + gcn::Key key = keyEvent.getKey(); + if (key.getValue() == gcn::Key::UP) { + keystate = SDL_GetKeyState(NULL); + if(keystate[SDLK_RSHIFT]) { + int selected = listBox->getSelected() - 10; + if(selected < 0) + selected = 0; + listBox->setSelected(selected); + bHandled = true; + } + } + if (key.getValue() == gcn::Key::DOWN) { + keystate = SDL_GetKeyState(NULL); + if(keystate[SDLK_RSHIFT]) { + int selected = listBox->getSelected() + 10; + if(selected >= dirList.getNumberOfElements()) + selected = dirList.getNumberOfElements() - 1; + listBox->setSelected(selected); + bHandled = true; + } + } + + if(!bHandled) + listBox->keyPressed(keyEvent); + } +}; +ListBoxKeyListener* listBoxKeyListener; + +#ifdef ANDROID +class ExtfilterActionListener : public gcn::ActionListener +{ +public: + void action(const gcn::ActionEvent& actionEvent) { + if (actionEvent.getSource() == checkBox_extfilter) { + if (checkBox_extfilter->isSelected()) + menuLoad_extfilter=1; + else + menuLoad_extfilter=0; + } + dirList=currentDir; + } +}; +ExtfilterActionListener* extfilterActionListener; +#endif + +void loadMenu_Init() +{ + window_load = new gcn::Window("Load"); + window_load->setSize(400,370); + window_load->setBaseColor(baseCol); + + button_ok = new gcn::Button("Ok"); + button_ok->setPosition(231,318); + button_ok->setSize(70, 26); + button_ok->setBaseColor(baseCol); + okButtonActionListener = new OkButtonActionListener(); + button_ok->addActionListener(okButtonActionListener); + button_select = new gcn::Button("Select"); + button_select->setPosition(145,318); + button_select->setSize(70, 26); + button_select->setBaseColor(baseCol); + selectButtonActionListener = new SelectButtonActionListener(); + button_select->addActionListener(selectButtonActionListener); + button_open = new gcn::Button("Open"); + button_open->setPosition(231, 318); + button_open->setSize(70, 26); + button_open->setBaseColor(baseCol); + openButtonActionListener = new OpenButtonActionListener(); + button_open->addActionListener(openButtonActionListener); + button_cancel = new gcn::Button("Cancel"); + button_cancel->setPosition(316,318); + button_cancel->setSize(70, 26); + button_cancel->setBaseColor(baseCol); + cancelButtonActionListener = new CancelButtonActionListener(); + button_cancel->addActionListener(cancelButtonActionListener); + + listBox = new gcn::ListBox(&dirList); + listBox->setSize(650,220); + listBox->setBaseColor(baseCol); + listBox->setWrappingEnabled(true); + listBoxScrollArea = new gcn::ScrollArea(listBox); + listBoxScrollArea->setFrameSize(1); + listBoxScrollArea->setPosition(10,10); + listBoxScrollArea->setSize(376,298); + listBoxScrollArea->setScrollbarWidth(20); + listBoxScrollArea->setBaseColor(baseCol); + listBoxActionListener = new ListBoxActionListener(); + listBox->addActionListener(listBoxActionListener); + listBoxKeyListener = new ListBoxKeyListener(); + listBox->removeKeyListener(listBox); + listBox->addKeyListener(listBoxKeyListener); +#ifdef ANDROID + checkBox_extfilter = new gcn::CheckBox("ext. filter"); + checkBox_extfilter->setPosition(10,320); + checkBox_extfilter->setId("extFilter"); + extfilterActionListener = new ExtfilterActionListener(); + checkBox_extfilter->addActionListener(extfilterActionListener); +#endif + window_load->add(button_ok); + window_load->add(button_select); + window_load->add(button_open); + window_load->add(button_cancel); + window_load->add(listBoxScrollArea); +#ifdef ANDROID + window_load->add(checkBox_extfilter); +#endif + window_load->setVisible(false); +} + + +void loadMenu_Exit() +{ + delete listBox; + delete listBoxScrollArea; + + delete button_ok; + delete button_select; + delete button_open; + delete button_cancel; +#ifdef ANDROID + delete checkBox_extfilter; +#endif + + delete okButtonActionListener; + delete selectButtonActionListener; + delete openButtonActionListener; + delete cancelButtonActionListener; + delete listBoxActionListener; + delete listBoxKeyListener; +#ifdef ANDROID + delete extfilterActionListener; +#endif + + delete window_load; +} + + +static void unraise_loadMenu_guichan() +{ + window_load->releaseModalFocus(); + window_load->setVisible(false); + if(activateAfterClose != NULL) + activateAfterClose->requestFocus(); + activateAfterClose = NULL; + show_settings(); +} + + +static void raise_loadMenu_guichan() +{ + if (menu_load_type != MENU_ADD_DIR) { + button_ok->setVisible(true); + button_select->setVisible(false); + button_open->setVisible(false); + button_ok->setId("cmdOk"); + button_select->setId("cmdSelect"); + button_open->setId("cmdOpen"); + button_cancel->setId("cmdCancel1"); + listBox->setId("dirList1"); + } else { + button_ok->setVisible(false); + button_select->setVisible(true); + button_open->setVisible(true); + button_ok->setId("cmdOk"); + button_select->setId("cmdSelect"); + button_open->setId("cmdOpen"); + button_cancel->setId("cmdCancel2"); + listBox->setId("dirList2"); + } +#ifdef ANDROID + if (menuLoad_extfilter==0) + checkBox_extfilter->setSelected(false); + else if (menuLoad_extfilter==1) + checkBox_extfilter->setSelected(true); +#endif + window_load->setVisible(true); + window_load->requestModalFocus(); + listBox->requestFocus(); +} + + +static int menuLoadLoop(char *curr_path) +{ + char *ret = NULL; + char *fname = NULL; + DIR *dir; + + // is this a dir or a full path? + if ((dir = opendir(curr_path))) + closedir(dir); + else { + char *p; + for (p = curr_path + strlen(curr_path) - 1; p > curr_path && *p != '/'; p--); + *p = 0; + fname = p+1; + } + dirList = curr_path; + + if (menu_load_type == MENU_ADD_DIR) + window_load->setCaption(" Select HD-dir "); + else if (menu_load_type == MENU_SELECT_FILE) + window_load->setCaption(" Select File to Run "); + else + window_load->setCaption("File Manager"); + + if(lastSelectedIndex >= 0 && lastSelectedIndex < dirList.getNumberOfElements()) + listBox->setSelected(lastSelectedIndex); +} + +void run_menuLoad_guichan(char *curr_path, int aLoadType) +{ + menu_load_type = aLoadType; + raise_loadMenu_guichan(); + int ret = menuLoadLoop(curr_path); +} + +extern "C" { + int AFILE_OpenFile(const char *filename, int reboot, int diskno, int readonly); +} + +void checkfilename (char *currentfilename) +{ + char *ret = NULL, *fname = NULL; + char *ptr; + char actualpath [PATH_MAX]; + struct dirent **namelist; + DIR *dir; + + if ((dir = opendir(currentfilename))) { + dirList=currentfilename; + ptr = realpath(currentfilename, actualpath); + strcpy(currentDir, ptr); + closedir(dir); + } else { + if ((menu_load_type == MENU_SELECT_FILE) && confirmselection) { + selectedFilePath=currentfilename; + int err = AFILE_OpenFile(selectedFilePath.c_str(), 1, 1, 1); +#ifdef ANDROID + SDL_ANDROID_SetScreenKeyboardShown(1); +#endif + running = false; + } + + if (confirmselection) + unraise_loadMenu_guichan(); + } +} +} diff -Nru atari800-3.1.0/src/guichan/menuMessage.cpp atari800-3.1.0-android/src/guichan/menuMessage.cpp --- atari800-3.1.0/src/guichan/menuMessage.cpp 1970-01-01 03:00:00.000000000 +0300 +++ atari800-3.1.0-android/src/guichan/menuMessage.cpp 2015-01-28 18:31:40.000000000 +0200 @@ -0,0 +1,138 @@ +#include +#ifdef ANDROIDSDL +#include +#endif +#include +#include +#include +#include +#include +#include "sdltruetypefont.hpp" + +namespace widgets +{ +static void unraise_Message(); + +extern gcn::Color baseCol; +extern gcn::Button* button_reset; + +gcn::Window *window_warning; +gcn::Button* button_warning; +gcn::Label* label_text; +gcn::Label* label2_text; + +gcn::Widget* activateAfterMsg = NULL; + + +class WarningButtonActionListener : public gcn::ActionListener +{ +public: + void action(const gcn::ActionEvent& actionEvent) { + unraise_Message(); + } +}; +WarningButtonActionListener* warningButtonActionListener; + + +void menuMessage_Init() +{ + button_warning = new gcn::Button(" Ok "); + button_warning->setPosition(115,45); + button_warning->setSize(70, 26); + button_warning->setBaseColor(baseCol); + warningButtonActionListener = new WarningButtonActionListener(); + button_warning->addActionListener(warningButtonActionListener); + + label_text = new gcn::Label(""); + label_text->setPosition(4, 4); + label_text->setSize(290, 15); + + label2_text = new gcn::Label(""); + label2_text->setPosition(4, 23); + label2_text->setSize(430, 15); + + window_warning = new gcn::Window("Warning"); + window_warning->add(button_warning); + window_warning->add(label_text); + window_warning->add(label2_text); + window_warning->setMovable(false); + window_warning->setSize(300,95); + window_warning->setBaseColor(baseCol); + window_warning->setVisible(false); +} + + +void menuMessage_Exit() +{ + delete button_warning; + delete label_text; + delete label2_text; + + delete warningButtonActionListener; + + delete window_warning; +} + + +static void unraise_Message() +{ + window_warning->releaseModalFocus(); + window_warning->setVisible(false); + if(activateAfterMsg != NULL) + activateAfterMsg->requestFocus(); + else + button_reset->requestFocus(); + activateAfterMsg = NULL; +} + + +void adjustSize(const char *msg2) +{ + if(msg2 == "") { + window_warning->setPosition(210, 220); + window_warning->setSize(240,95); + button_warning->setPosition(85,45); + } else { + window_warning->setPosition(100, 220); + window_warning->setSize(440,95); + button_warning->setPosition(185,45); + } +} + + +void showInfo(const char *msg, const char *msg2 = "") +{ + label_text->setCaption(msg); + label2_text->setCaption(msg2); + adjustSize(msg2); + window_warning->setCaption("Information"); + window_warning->setVisible(true); + window_warning->requestModalFocus(); + button_warning->requestFocus(); +} + + +void showWarning(const char *msg, const char *msg2 = "") +{ + label_text->setCaption(msg); + label2_text->setCaption(msg2); + adjustSize(msg2); + window_warning->setCaption("Warning"); + window_warning->setVisible(true); + window_warning->requestModalFocus(); + button_warning->requestFocus(); +} + + +void show_error(const char *msg, const char *msg2 = "") +{ + label_text->setCaption(msg); + label2_text->setCaption(msg2); + adjustSize(msg2); + window_warning->setCaption("Error"); + window_warning->setVisible(true); + window_warning->requestModalFocus(); + button_warning->requestFocus(); +} + +} diff -Nru atari800-3.1.0/src/guichan/menuSaveState.cpp atari800-3.1.0-android/src/guichan/menuSaveState.cpp --- atari800-3.1.0/src/guichan/menuSaveState.cpp 1970-01-01 03:00:00.000000000 +0300 +++ atari800-3.1.0-android/src/guichan/menuSaveState.cpp 2015-01-28 18:31:24.000000000 +0200 @@ -0,0 +1,283 @@ +#include +#include +#include +#ifdef ANDROID +#include +#endif +#include +#include +#include +#include +#include +#include "sdltruetypefont.hpp" + +extern "C" +{ +#include "statesav.h" +} + +extern bool running; + +#define extterms files[q].size()>=4 && files[q].substr(files[q].size()-4) +#define ssterms extterms!=".sav" && extterms!=".SAV" && extterms!=".Sav" +#define ext2terms ssstring.size()>=4 && ssstring.substr(ssstring.size()-4) +#define ss2terms ext2terms!=".sav" && ext2terms!=".SAV" && ext2terms!=".Sav" + +static char savestate_filename_default[255]= { + '/', 't', 'm', 'p', '/', 'n', 'u', 'l', 'l', '.', 's', 'a', 'v', '\0' +}; + +char *savestate_filename=(char *)&savestate_filename_default[0]; + +extern char launchDir[300]; + +static void BuildBaseDir(char *filename) +{ + strcpy(filename, ""); + strcat(filename, launchDir); + strcat(filename, "/savestates"); +// strcpy(filename, prefs_get_attr ("savestate_path")); +} + +namespace widgets +{ +void show_settings_SaveState(void); +void showWarning(const char *msg, const char *msg2 = ""); +void showInfo(const char *msg, const char *msg2 = ""); + +extern gcn::Color baseCol; +extern gcn::Color baseColLabel; +extern gcn::Container* top; +extern gcn::contrib::SDLTrueTypeFont* font2; + +// Tab Main +gcn::Window *window_savestate; + +gcn::Button* button_ss_load; +gcn::Button* button_ss_save; +gcn::Button* button_ss_delete; +gcn::Button* button_ss_cancel; +gcn::TextField* textField_ss; +gcn::ListBox* savestatelistBox; +gcn::ScrollArea* savestateScrollArea; + +class SavestateListModel : public gcn::ListModel +{ + std::vector files; + +public: + SavestateListModel(const char * path) { + changeDir(path); + } + + int getNumberOfElements() { + return files.size(); + } + + std::string getElementAt(int i) { + if(i >= files.size() || i < 0) + return "---"; + return files[i]; + } + + void changeDir(const char * path) { + files.clear(); + DIR *dir; + struct dirent *dent; + dir = opendir(path); + if(dir != NULL) { + while((dent=readdir(dir))!=NULL) { + if(!(dent->d_type == DT_DIR)) + files.push_back(dent->d_name); + } + closedir(dir); + } + std::sort(files.begin(), files.end()); + for (int q=0; qgetSelected(); + BuildBaseDir(savestate_filename); + strcat(savestate_filename, "/"); + strcat(savestate_filename, savestateList.getElementAt(selected_item).c_str()); + int result; + result = StateSav_ReadAtariState(savestate_filename, "rb"); + if (result) { + window_savestate->setVisible(false); + running=false; + } else + showInfo("Savestate failed."); + } +}; +SsLoadButtonActionListener* ssloadButtonActionListener; + + +class SsSaveButtonActionListener : public gcn::ActionListener +{ +public: + void action(const gcn::ActionEvent& actionEvent) { + char filename[256]=""; + std::string ssstring; + BuildBaseDir(savestate_filename); + strcat(savestate_filename, "/"); + ssstring = textField_ss->getText().c_str(); + strcat(savestate_filename, textField_ss->getText().c_str()); + // check extension of editable name + if (ss2terms || ssstring.size()<5) + strcat(savestate_filename, ".sav"); + window_savestate->setVisible(false); + int result; + result = StateSav_SaveAtariState(savestate_filename, "wb", TRUE); + if (result) + showInfo("Savestate file saved."); + else + showInfo("Savestate failed."); +// running=false; +// save_state(savestate_filename, 0); +// showInfo("Savestate file saved."); + BuildBaseDir(savestate_filename); + savestateList = savestate_filename; + + } +}; +SsSaveButtonActionListener* sssaveButtonActionListener; + +class SsDeleteButtonActionListener : public gcn::ActionListener +{ +public: + void action(const gcn::ActionEvent& actionEvent) { + int selected_item; + selected_item = savestatelistBox->getSelected(); + BuildBaseDir(savestate_filename); + strcat(savestate_filename, "/"); + strcat(savestate_filename, savestateList.getElementAt(selected_item).c_str()); + if(unlink(savestate_filename)) { + showWarning("Failed to delete savestate."); + } else { + BuildBaseDir(savestate_filename); + savestateList = savestate_filename; + } + } +}; +SsDeleteButtonActionListener* ssdeleteButtonActionListener; + +class SsCancelButtonActionListener : public gcn::ActionListener +{ +public: + void action(const gcn::ActionEvent& actionEvent) { + window_savestate->setVisible(false); + } +}; +SsCancelButtonActionListener* sscancelButtonActionListener; + +class SavestatelistBoxActionListener : public gcn::ActionListener +{ +public: + void action(const gcn::ActionEvent& actionEvent) { + int selected_item; + selected_item = savestatelistBox->getSelected(); + textField_ss->setText(savestateList.getElementAt(selected_item).c_str()); + } +}; +SavestatelistBoxActionListener* savestatelistBoxActionListener; + +void menuSaveState_Init() +{ + button_ss_load = new gcn::Button("Load"); + button_ss_load->setId("ssLoad"); + button_ss_load->setPosition(316,10); + button_ss_load->setSize(70, 26); + button_ss_load->setBaseColor(baseCol); + ssloadButtonActionListener = new SsLoadButtonActionListener(); + button_ss_load->addActionListener(ssloadButtonActionListener); + button_ss_save = new gcn::Button("Save"); + button_ss_save->setId("ssSave"); + button_ss_save->setPosition(316,65); + button_ss_save->setSize(70, 26); + button_ss_save->setBaseColor(baseCol); + sssaveButtonActionListener = new SsSaveButtonActionListener(); + button_ss_save->addActionListener(sssaveButtonActionListener); + button_ss_delete = new gcn::Button("Delete"); + button_ss_delete->setId("ssDelete"); + button_ss_delete->setPosition(316,120); + button_ss_delete->setSize(70, 26); + button_ss_delete->setBaseColor(baseCol); + ssdeleteButtonActionListener = new SsDeleteButtonActionListener(); + button_ss_delete->addActionListener(ssdeleteButtonActionListener); + button_ss_cancel = new gcn::Button("Cancel"); + button_ss_cancel->setId("ssCancel"); + button_ss_cancel->setPosition(316,175); + button_ss_cancel->setSize(70, 26); + button_ss_cancel->setBaseColor(baseCol); + sscancelButtonActionListener = new SsCancelButtonActionListener(); + button_ss_cancel->addActionListener(sscancelButtonActionListener); + + + textField_ss = new gcn::TextField(""); + textField_ss->setId("ssText"); + textField_ss->setPosition(10,10); + textField_ss->setSize(295,22); + textField_ss->setBaseColor(baseCol); + + savestatelistBox = new gcn::ListBox(&savestateList); + savestatelistBox->setId("savestateList"); + savestatelistBox->setSize(650,150); + savestatelistBox->setBaseColor(baseCol); + savestatelistBox->setWrappingEnabled(true); + savestatelistBoxActionListener = new SavestatelistBoxActionListener(); + savestatelistBox->addActionListener(savestatelistBoxActionListener); + savestateScrollArea = new gcn::ScrollArea(savestatelistBox); + savestateScrollArea->setFrameSize(1); + savestateScrollArea->setPosition(10,40); + savestateScrollArea->setSize(295,228); + savestateScrollArea->setScrollbarWidth(20); + savestateScrollArea->setBaseColor(baseCol); + + window_savestate = new gcn::Window("SaveState"); + window_savestate->setPosition(120,90); + window_savestate->setMovable(false); + window_savestate->setSize(400,300); + window_savestate->setBaseColor(baseCol); + window_savestate->setVisible(false); + + window_savestate->add(button_ss_load); + window_savestate->add(button_ss_save); + window_savestate->add(button_ss_delete); + window_savestate->add(button_ss_cancel); + window_savestate->add(textField_ss); + window_savestate->add(savestateScrollArea); +} + +void menuSaveState_Exit() +{ + + delete button_ss_load; + delete button_ss_save; + delete button_ss_delete; + delete button_ss_cancel; + delete textField_ss; + delete savestatelistBox; + delete savestateScrollArea; + + delete window_savestate; +} + +void show_settings_SaveState() +{ + +} + +} diff -Nru atari800-3.1.0/src/guichan/rw_config.h atari800-3.1.0-android/src/guichan/rw_config.h --- atari800-3.1.0/src/guichan/rw_config.h 1970-01-01 03:00:00.000000000 +0300 +++ atari800-3.1.0-android/src/guichan/rw_config.h 2014-12-10 20:56:10.000000000 +0200 @@ -0,0 +1,6 @@ + +/* What is being loaded */ +#define MENU_SELECT_FILE 1 +#define MENU_ADD_DIR 2 + +extern char currentDir[300]; \ Наприкінці файлу немає нового рядка diff -Nru atari800-3.1.0/src/guichan/sdltruetypefont.cpp atari800-3.1.0-android/src/guichan/sdltruetypefont.cpp --- atari800-3.1.0/src/guichan/sdltruetypefont.cpp 1970-01-01 03:00:00.000000000 +0300 +++ atari800-3.1.0-android/src/guichan/sdltruetypefont.cpp 2014-05-22 23:40:29.000000000 +0300 @@ -0,0 +1,171 @@ +/* _______ __ __ __ ______ __ __ _______ __ __ + * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\ + * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / / + * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / / + * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / / + * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ / + * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/ + * + * Copyright (c) 2004 - 2008 Olof Naessn and Per Larsson + * + * + * Per Larsson a.k.a finalman + * Olof Naessn a.k.a jansem/yakslem + * + * Visit: http://guichan.sourceforge.net + * + * License: (BSD) + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of Guichan nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * For comments regarding functions please see the header file. + */ + +#include "sdltruetypefont.hpp" + +#include "guichan/exception.hpp" +#include "guichan/image.hpp" +#include "guichan/graphics.hpp" +#include "guichan/sdl/sdlgraphics.hpp" + +namespace gcn +{ + namespace contrib + { + SDLTrueTypeFont::SDLTrueTypeFont (const std::string& filename, int size) + { + mRowSpacing = 0; + mGlyphSpacing = 0; + mAntiAlias = true; + mFilename = filename; + mFont = NULL; + + mFont = TTF_OpenFont(filename.c_str(), size); + + if (mFont == NULL) + { + throw GCN_EXCEPTION("SDLTrueTypeFont::SDLTrueTypeFont. "+std::string(TTF_GetError())); + } + } + + SDLTrueTypeFont::~SDLTrueTypeFont() + { + TTF_CloseFont(mFont); + } + + int SDLTrueTypeFont::getWidth(const std::string& text) const + { + int w, h; + TTF_SizeText(mFont, text.c_str(), &w, &h); + + return w; + } + + int SDLTrueTypeFont::getHeight() const + { + return TTF_FontHeight(mFont) + mRowSpacing; + } + + void SDLTrueTypeFont::drawString(gcn::Graphics* graphics, const std::string& text, const int x, const int y) + { + if (text == "") + { + return; + } + + gcn::SDLGraphics *sdlGraphics = dynamic_cast(graphics); + + if (sdlGraphics == NULL) + { + throw GCN_EXCEPTION("SDLTrueTypeFont::drawString. Graphics object not an SDL graphics object!"); + return; + } + + // This is needed for drawing the Glyph in the middle if we have spacing + int yoffset = getRowSpacing() / 2; + + Color col = sdlGraphics->getColor(); + + SDL_Color sdlCol; + sdlCol.b = col.b; + sdlCol.r = col.r; + sdlCol.g = col.g; + + SDL_Surface *textSurface; + if (mAntiAlias) + { + textSurface = TTF_RenderText_Blended(mFont, text.c_str(), sdlCol); + } + else + { + textSurface = TTF_RenderText_Solid(mFont, text.c_str(), sdlCol); + } + + SDL_Rect dst, src; + dst.x = x; + dst.y = y + yoffset; + src.w = textSurface->w; + src.h = textSurface->h; + src.x = 0; + src.y = 0; + + sdlGraphics->drawSDLSurface(textSurface, src, dst); + SDL_FreeSurface(textSurface); + } + + void SDLTrueTypeFont::setRowSpacing(int spacing) + { + mRowSpacing = spacing; + } + + int SDLTrueTypeFont::getRowSpacing() + { + return mRowSpacing; + } + + void SDLTrueTypeFont::setGlyphSpacing(int spacing) + { + mGlyphSpacing = spacing; + } + + int SDLTrueTypeFont::getGlyphSpacing() + { + return mGlyphSpacing; + } + + void SDLTrueTypeFont::setAntiAlias(bool antiAlias) + { + mAntiAlias = antiAlias; + } + + bool SDLTrueTypeFont::isAntiAlias() + { + return mAntiAlias; + } + } +} + diff -Nru atari800-3.1.0/src/guichan/sdltruetypefont.hpp atari800-3.1.0-android/src/guichan/sdltruetypefont.hpp --- atari800-3.1.0/src/guichan/sdltruetypefont.hpp 1970-01-01 03:00:00.000000000 +0300 +++ atari800-3.1.0-android/src/guichan/sdltruetypefont.hpp 2013-12-03 21:22:16.000000000 +0200 @@ -0,0 +1,156 @@ +/* _______ __ __ __ ______ __ __ _______ __ __ + * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\ + * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / / + * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / / + * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / / + * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ / + * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/ + * + * Copyright (c) 2004 - 2008 Olof Naessn and Per Larsson + * + * + * Per Larsson a.k.a finalman + * Olof Naessn a.k.a jansem/yakslem + * + * Visit: http://guichan.sourceforge.net + * + * License: (BSD) + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of Guichan nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GCN_CONTRIB_SDLTRUETYPEFONT_HPP +#define GCN_CONTRIB_SDLTRUETYPEFONT_HPP + +#include +#include + +#include + +#include "guichan/font.hpp" +#include "guichan/platform.hpp" + +namespace gcn +{ + class Graphics; + namespace contrib + { + + /** + * SDL True Type Font implementation of Font. It uses the SDL_ttf library + * to display True Type Fonts with SDL. + * + * NOTE: You must initialize the SDL_ttf library before using this + * class. Also, remember to call the SDL_ttf libraries quit + * function. + * + * @author Walluce Pinkham + * @author Olof Naessn + */ + class GCN_EXTENSION_DECLSPEC SDLTrueTypeFont: public Font + { + public: + + /** + * Constructor. + * + * @param filename the filename of the True Type Font. + * @param size the size the font should be in. + */ + SDLTrueTypeFont (const std::string& filename, int size); + + /** + * Destructor. + */ + virtual ~SDLTrueTypeFont(); + + /** + * Sets the spacing between rows in pixels. Default is 0 pixels. + * The spacing can be negative. + * + * @param spacing the spacing in pixels. + */ + virtual void setRowSpacing (int spacing); + + /** + * Gets the spacing between rows in pixels. + * + * @return the spacing. + */ + virtual int getRowSpacing(); + + /** + * Sets the spacing between letters in pixels. Default is 0 pixels. + * The spacing can be negative. + * + * @param spacing the spacing in pixels. + */ + virtual void setGlyphSpacing(int spacing); + + /** + * Gets the spacing between letters in pixels. + * + * @return the spacing. + */ + virtual int getGlyphSpacing(); + + /** + * Sets the use of anti aliasing.. + * + * @param antaAlias true for use of antia aliasing. + */ + virtual void setAntiAlias(bool antiAlias); + + /** + * Checks if anti aliasing is used. + * + * @return true if anti aliasing is used. + */ + virtual bool isAntiAlias(); + + + // Inherited from Font + + virtual int getWidth(const std::string& text) const; + + virtual int getHeight() const; + + virtual void drawString(Graphics* graphics, const std::string& text, int x, int y); + + protected: + TTF_Font *mFont; + + int mHeight; + int mGlyphSpacing; + int mRowSpacing; + + std::string mFilename; + bool mAntiAlias; + }; + } +} + +#endif + diff -Nru atari800-3.1.0/src/Makefile.in atari800-3.1.0-android/src/Makefile.in --- atari800-3.1.0/src/Makefile.in 2013-05-02 14:59:13.000000000 +0300 +++ atari800-3.1.0-android/src/Makefile.in 2016-08-27 21:53:32.307310727 +0300 @@ -1,8 +1,9 @@ CC = @CC@ +CXX = /home/lubomyr/android/android-ndk-r12b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++ RC = windres DEFS = @DEFS@ -LIBS = @LIBS@ +LIBS = @LIBS@ -lgnustl_static TARGET_BASE_NAME = atari800 TARGET = $(TARGET_BASE_NAME)@EXEEXT@ CONFIGURE_TARGET = @CONFIGURE_TARGET@ @@ -60,6 +61,7 @@ sio.o \ sysrom.o \ util.o \ + guichan/guichan-gui.o guichan/menuLoad_guichan.o guichan/menuMessage.o guichan/menuSaveState.o guichan/sdltruetypefont.o \ @OBJS@ @@ -75,6 +77,9 @@ win32/%.o: win32/%.c $(CC) -c -o $@ $(DEFS) -I. $(patsubst -pedantic,,$(patsubst -ansi,,$(CFLAGS))) $< +guichan/%.o: guichan/%.cpp + $(CXX) -c -o $@ $(DEFS) -I. $(CFLAGS) $< + ide.o: ide.c ide.h ide_internal.h $(CC) -c -o $@ $(DEFS) -I. $(CFLAGS:-ansi=) $< @@ -116,7 +121,7 @@ .PHONY: android $(TARGET): $(OBJS) - $(CC) -o $@ $(LDFLAGS) $(OBJS) $(LIBS) + $(CXX) -o $@ $(LDFLAGS) $(OBJS) $(LIBS) dep: @if ! makedepend -Y $(DEFS) -I. ${OBJS:.o=.c} 2>/dev/null; \ @@ -128,6 +133,7 @@ rm -f falcon/*.o falcon/*.bak falcon/*~ rm -f sdl/*.o sdl/*.bak sdl/*~ rm -f win32/*.o win32/*.ro win32/*.bak win32/*~ + rm -f guichan/*.o guichan/*.ro guichan/*.bak guichan/*~ rm -f javanvm/*.o javanvm/*.bak javanvm/*~ rm -f atari_ntsc/*.o atari_ntsc/*.bak atari_ntsc/*~ rm -rf android/libs android/obj android/bin android/gen diff -Nru atari800-3.1.0/src/sdl/input.c atari800-3.1.0-android/src/sdl/input.c --- atari800-3.1.0/src/sdl/input.c 2014-03-11 01:14:34.000000000 +0200 +++ atari800-3.1.0-android/src/sdl/input.c 2016-08-27 20:52:01.127418544 +0300 @@ -22,9 +22,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef ANDROID #ifdef __linux__ #define LPTJOY 1 #endif +#endif #ifdef LPTJOY #include @@ -1391,6 +1393,9 @@ int stick0, stick1; stick0 = stick1 = INPUT_STICK_CENTRE; + if( !kbhits ) + return; + if (PLATFORM_kbd_joy_0_enabled) { if (kbhits[KBD_STICK_0_LEFT]) stick0 &= INPUT_STICK_LEFT; @@ -1437,6 +1442,9 @@ int trig0, trig1; trig0 = trig1 = 1; + if( !kbhits ) + return; + if (PLATFORM_kbd_joy_0_enabled) { trig0 = !kbhits[KBD_TRIG_0]; } diff -Nru atari800-3.1.0/src/ui_basic.c atari800-3.1.0-android/src/ui_basic.c --- atari800-3.1.0/src/ui_basic.c 2014-03-11 01:14:34.000000000 +0200 +++ atari800-3.1.0-android/src/ui_basic.c 2016-08-27 20:52:01.127418544 +0300 @@ -91,7 +91,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -#define KB_DELAY 20 +#define KB_DELAY 35 #define KB_AUTOREPEAT 3 static int GetKeyPress(void) diff -Nru atari800-3.1.0/src/videomode.c atari800-3.1.0-android/src/videomode.c --- atari800-3.1.0/src/videomode.c 2013-04-23 19:57:39.000000000 +0300 +++ atari800-3.1.0-android/src/videomode.c 2016-08-27 20:52:01.127418544 +0300 @@ -47,6 +47,10 @@ #include "xep80.h" #endif +#if defined(ANDROID) +#include +#endif + #if defined(XEP80_EMULATION) || defined(PBI_PROTO80) || defined(AF80) #define COLUMN_80 1 #else @@ -590,8 +594,76 @@ return TRUE; } +#ifdef ANDROID +void onscreen_position() +{ + // setup position of on-screen buttons + int pos_x_textinput=0; + int pos_y_textinput=0; + int pos_x_dpad=4; + int pos_y_dpad=215; + int pos_x_button1=417; + int pos_y_button1=278; + int pos_x_button2=49; + int pos_y_button2=6; + int pos_x_button3=240; + int pos_y_button3=11; + int pos_x_button4=300; + int pos_y_button4=11; + int pos_x_button5=361; + int pos_y_button5=10; + int pos_x_button6=421; + int pos_y_button6=9; + // apply position of on-screen buttons + SDL_Rect pos_textinput, pos_dpad, pos_button1, pos_button2, pos_button3, pos_button4, pos_button5, pos_button6; + pos_textinput.x = pos_x_textinput*(SDL_ListModes(NULL, 0)[0]->w/(float)480); + pos_textinput.y = pos_y_textinput*(SDL_ListModes(NULL, 0)[0]->h/(float)360); + pos_textinput.h=SDL_ListModes(NULL, 0)[0]->h / (float)10; + pos_textinput.w=pos_textinput.h; + SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT, &pos_textinput); + pos_dpad.x = pos_x_dpad*(SDL_ListModes(NULL, 0)[0]->w/(float)480); + pos_dpad.y = pos_y_dpad*(SDL_ListModes(NULL, 0)[0]->h/(float)360); + pos_dpad.h=SDL_ListModes(NULL, 0)[0]->h / (float)2.5; + pos_dpad.w=pos_dpad.h; + SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD, &pos_dpad); + pos_button1.x = pos_x_button1*(SDL_ListModes(NULL, 0)[0]->w/(float)480); + pos_button1.y = pos_y_button1*(SDL_ListModes(NULL, 0)[0]->h/(float)360); + pos_button1.h=SDL_ListModes(NULL, 0)[0]->h / (float)4; + pos_button1.w=pos_button1.h; + SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, &pos_button1); + pos_button2.x = pos_x_button2*(SDL_ListModes(NULL, 0)[0]->w/(float)480); + pos_button2.y = pos_y_button2*(SDL_ListModes(NULL, 0)[0]->h/(float)360); + pos_button2.h=SDL_ListModes(NULL, 0)[0]->h / (float)6; + pos_button2.w=pos_button2.h; + SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_1, &pos_button2); + pos_button3.x = pos_x_button3*(SDL_ListModes(NULL, 0)[0]->w/(float)480); + pos_button3.y = pos_y_button3*(SDL_ListModes(NULL, 0)[0]->h/(float)360); + pos_button3.h=SDL_ListModes(NULL, 0)[0]->h / (float)6; + pos_button3.w=pos_button3.h; + SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, &pos_button3); + pos_button4.x = pos_x_button4*(SDL_ListModes(NULL, 0)[0]->w/(float)480); + pos_button4.y = pos_y_button4*(SDL_ListModes(NULL, 0)[0]->h/(float)360); + pos_button4.h=SDL_ListModes(NULL, 0)[0]->h / (float)6; + pos_button4.w=pos_button4.h; + SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_3, &pos_button4); + pos_button5.x = pos_x_button5*(SDL_ListModes(NULL, 0)[0]->w/(float)480); + pos_button5.y = pos_y_button5*(SDL_ListModes(NULL, 0)[0]->h/(float)360); + pos_button5.h=SDL_ListModes(NULL, 0)[0]->h / (float)6; + pos_button5.w=pos_button5.h; + SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_4, &pos_button5); + pos_button6.x = pos_x_button6*(SDL_ListModes(NULL, 0)[0]->w/(float)480); + pos_button6.y = pos_y_button6*(SDL_ListModes(NULL, 0)[0]->h/(float)360); + pos_button6.h=SDL_ListModes(NULL, 0)[0]->h / (float)6; + pos_button6.w=pos_button6.h; + SDL_ANDROID_SetScreenKeyboardButtonPos(SDL_ANDROID_SCREENKEYBOARD_BUTTON_5, &pos_button6); +} +#endif + int VIDEOMODE_Update(void) { +#ifdef ANDROID + onscreen_position(); +#endif if (VIDEOMODE_windowed || force_windowed) return UpdateVideoWindowed(FALSE); else