From 297ee9b33dab3bca9433befc81d7c7ce91450dd0 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Mon, 9 Dec 2013 21:43:09 +0100 Subject: [PATCH] rnd-20131209-1-src * ported Rocks'n'Diamonds to SDL2 --- ChangeLog | 3 + Makefile | 2 +- src/conftime.h | 2 +- src/init.c | 89 +---------------- src/libgame/android.h | 20 ++++ src/libgame/misc.c | 215 ++++++++++++++++++++++++++++++++++++++--- src/libgame/misc.h | 36 +++++++ src/libgame/platform.h | 6 ++ src/libgame/setup.c | 15 ++- src/libgame/system.c | 3 + src/libgame/system.h | 2 + 11 files changed, 294 insertions(+), 99 deletions(-) create mode 100644 src/libgame/android.h diff --git a/ChangeLog b/ChangeLog index 6a38b40d..9e1d48bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2013-12-03 + * ported Rocks'n'Diamonds to SDL2 + 2013-12-01 * version number set to 3.3.1.3 diff --git a/Makefile b/Makefile index df2f7662..96e63039 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,7 @@ SRC_DIR = src MAKE_CMD = $(MAKE) -C $(SRC_DIR) # DEFAULT_TARGET = x11 -DEFAULT_TARGET = sdl +DEFAULT_TARGET = sdl2 # ----------------------------------------------------------------------------- diff --git a/src/conftime.h b/src/conftime.h index ff48912e..ce6bfee6 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "2013-12-03 14:17" +#define COMPILE_DATE_STRING "2013-12-09 21:41" diff --git a/src/init.c b/src/init.c index 30735032..c2344a50 100644 --- a/src/init.c +++ b/src/init.c @@ -5644,91 +5644,6 @@ void InitGfx() font_height = getFontHeight(FC_RED); - - - - - - - - -#if 0 - Delay(1000); - -#if 0 - Bitmap new_bitmap; - printf("::: MARK 1.1\n"); - new_bitmap.surface = SDL_LoadBMP("TEST.bmp"); - printf("::: MARK 1.2\n"); -#endif - - char *filename = getCustomImageFilename("RocksFontSmall.pcx"); - - printf("::: FILENAME == '%s'\n", filename); - -#if 1 - Bitmap *new_bitmap = LoadImage(filename); -#else -#if 1 - Bitmap *new_bitmap = CreateBitmapStruct(); - SDL_Surface *sdl_image_tmp; - sdl_image_tmp = IMG_Load(filename); - new_bitmap->surface = SDL_DisplayFormat(sdl_image_tmp); - -#else - SDL_Surface *sdl_image_tmp = IMG_Load(filename); - SDL_Surface *sdl_image = SDL_DisplayFormat(sdl_image_tmp); -#endif -#endif - - // SDL_Surface *image = SDL_LoadBMP("TEST.bmp"); - // SDL_LoadBMP("TEST.bmp"); - - // bitmap_font_initial->surface = SDL_LoadBMP("TEST.bmp"); - -#if 0 - printf("::: MARK 1 [%08x, %08xd]\n", - (unsigned int)bitmap_font_initial->surface, - (unsigned int)backbuffer->surface); -#endif - - // SDL_BlitSurface(image, NULL, backbuffer->surface, NULL); - // SDL_BlitSurface(new_bitmap.surface, NULL,backbuffer->surface, NULL); - SDL_BlitSurface(new_bitmap->surface, NULL,backbuffer->surface, NULL); - // SDL_BlitSurface(sdl_image, NULL,backbuffer->surface, NULL); - // SDL_BlitSurface(bitmap_font_initial->surface, NULL,backbuffer->surface, NULL); - -#if 0 - printf("::: MARK 1 [%08x, %08xd, %08xd]\n", - (unsigned int)bitmap_font_initial->surface, - (unsigned int)backbuffer->surface, - (unsigned int)image); -#endif - - extern SDL_Window *sdl_window; - SDL_UpdateWindowSurface(sdl_window); - -#if 1 -#if 0 - SDL_BlitSurface(bitmap_font_initial->surface, NULL,backbuffer->surface, NULL); -#endif - // SDL_UpdateWindowSurface(sdl_window); - - Delay(1000); - exit(0); -#endif -#endif - - - - - - - - - - - #if 1 DrawInitText(getWindowTitleString(), 20, FC_YELLOW); #else @@ -6363,6 +6278,10 @@ void KeyboardAutoRepeatOffUnlessAutoplay() void DisplayExitMessage(char *format, va_list ap) { + // check if draw buffer and fonts for exit message are already available + if (drawto == NULL || font_initial[NUM_INITIAL_FONTS - 1].bitmap == NULL) + return; + int font_1 = FC_RED; int font_2 = FC_YELLOW; int font_3 = FC_BLUE; diff --git a/src/libgame/android.h b/src/libgame/android.h new file mode 100644 index 00000000..0680958b --- /dev/null +++ b/src/libgame/android.h @@ -0,0 +1,20 @@ +/*********************************************************** +* Artsoft Retro-Game Library * +*----------------------------------------------------------* +* (c) 1994-2006 Artsoft Entertainment * +* Holger Schemel * +* Detmolder Strasse 189 * +* 33604 Bielefeld * +* Germany * +* e-mail: info@artsoft.org * +*----------------------------------------------------------* +* android.h * +***********************************************************/ + +#ifndef ANDROID_H +#define ANDROID_H + +#include + + +#endif /* ANDROID_H */ diff --git a/src/libgame/misc.c b/src/libgame/misc.c index 2bff745d..9d6e0cc9 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "platform.h" @@ -42,25 +43,47 @@ /* platform independent wrappers for printf() et al. (newline aware) */ /* ------------------------------------------------------------------------- */ +#if defined(PLATFORM_ANDROID) +static int android_log_prio = ANDROID_LOG_INFO; +#endif + +#if 0 +static void vfPrintLog(FILE *stream, char *format, va_list ap) +{ +} + +static void vfPrintLog(FILE *stream, char *format, va_list ap) +{ +} + +static void fPrintLog(FILE *stream, char *format, va_list ap) +{ +} + +static void fPrintLog(FILE *stream, char *format, va_list ap) +{ +} +#endif + static void vfprintf_newline(FILE *stream, char *format, va_list ap) { +#if defined(PLATFORM_ANDROID) + __android_log_vprint(android_log_prio, program.program_title, format, ap); +#else char *newline = STRING_NEWLINE; vfprintf(stream, format, ap); - fprintf(stream, "%s", newline); +#endif } static void fprintf_newline(FILE *stream, char *format, ...) { - if (format) - { - va_list ap; + va_list ap; - va_start(ap, format); - vfprintf_newline(stream, format, ap); - va_end(ap); - } + va_start(ap, format); + vfprintf_newline(stream, format, ap); + va_end(ap); } void fprintf_line(FILE *stream, char *line_chars, int line_length) @@ -494,7 +517,7 @@ char *getRealName() else real_name = ANONYMOUS_NAME; } -#elif defined(PLATFORM_UNIX) +#elif defined(PLATFORM_UNIX) && !defined(PLATFORM_ANDROID) if (real_name == NULL) { struct passwd *pwd; @@ -632,11 +655,23 @@ char *getStringCat3(char *s1, char *s2, char *s3) char *getPath2(char *path1, char *path2) { +#if defined(PLATFORM_ANDROID) + // workaround for reading from APK assets directory -- skip leading "./" + if (strEqual(path1, ".")) + return getStringCopy(path2); +#endif + return getStringCat2WithSeparator(path1, path2, STRING_PATH_SEPARATOR); } char *getPath3(char *path1, char *path2, char *path3) { +#if defined(PLATFORM_ANDROID) + // workaround for reading from APK assets directory -- skip leading "./" + if (strEqual(path1, ".")) + return getStringCat2WithSeparator(path2, path3, STRING_PATH_SEPARATOR); +#endif + return getStringCat3WithSeparator(path1, path2, path3, STRING_PATH_SEPARATOR); } @@ -1007,6 +1042,11 @@ void Error(int mode, char *format, ...) static boolean last_line_was_separator = FALSE; char *process_name = ""; +#if defined(PLATFORM_ANDROID) + android_log_prio = (mode & ERR_WARN ? ANDROID_LOG_WARN : + mode & ERR_EXIT ? ANDROID_LOG_FATAL : ANDROID_LOG_INFO); +#endif + #if 1 /* display warnings only when running in verbose mode */ if (mode & ERR_WARN && !options.verbose) @@ -1853,6 +1893,144 @@ void dumpList(ListNode *node_first) } +/* ------------------------------------------------------------------------- */ +/* functions for reading directories */ +/* ------------------------------------------------------------------------- */ + +struct Directory *openDirectory(char *dir_name) +{ + struct Directory *dir = checked_calloc(sizeof(struct Directory)); + + dir->dir = opendir(dir_name); + + if (dir->dir != NULL) + { + dir->filename = getStringCopy(dir_name); + + return dir; + } + +#if defined(PLATFORM_ANDROID) + char *asset_toc_filename = getPath2(dir_name, ASSET_TOC_BASENAME); + + dir->asset_toc_file = SDL_RWFromFile(asset_toc_filename, MODE_READ); + + checked_free(asset_toc_filename); + + if (dir->asset_toc_file != NULL) + { + dir->directory_is_asset = TRUE; + dir->filename = getStringCopy(dir_name); + + return dir; + } +#endif + + checked_free(dir); + + return NULL; +} + +int closeDirectory(struct Directory *dir) +{ + if (dir == NULL) + return -1; + + int result; + +#if defined(PLATFORM_ANDROID) + if (dir->asset_toc_file) + result = SDL_RWclose(dir->asset_toc_file); +#endif + + if (dir->dir) + result = closedir(dir->dir); + + if (dir->dir_entry) + freeDirectoryEntry(dir->dir_entry); + + checked_free(dir->filename); + checked_free(dir); + + return result; +} + +struct DirectoryEntry *readDirectory(struct Directory *dir) +{ + if (dir->dir_entry) + freeDirectoryEntry(dir->dir_entry); + + dir->dir_entry = NULL; + +#if defined(PLATFORM_ANDROID) + if (dir->directory_is_asset) + { + char line[MAX_LINE_LEN]; + char *line_ptr = line; + char *last_line_ptr = line_ptr; + int num_bytes_read = 0; + + while (num_bytes_read < MAX_LINE_LEN && + SDL_RWread(dir->asset_toc_file, line_ptr, 1, 1) == 1 && + *line_ptr != '\n') + { + last_line_ptr = line_ptr; + line_ptr++; + num_bytes_read++; + } + + *line_ptr = '\0'; + + if (strlen(line) == 0) + return NULL; + + dir->dir_entry = checked_calloc(sizeof(struct DirectoryEntry)); + + dir->dir_entry->is_directory = FALSE; + if (line[strlen(line) - 1] = '/') + { + dir->dir_entry->is_directory = TRUE; + + line[strlen(line) - 1] = '\0'; + } + + dir->dir_entry->basename = getStringCopy(line); + dir->dir_entry->filename = getPath2(dir->filename, line); + + return dir->dir_entry; + } +#endif + + struct dirent *dir_entry = readdir(dir->dir); + + if (dir_entry == NULL) + return NULL; + + dir->dir_entry = checked_calloc(sizeof(struct DirectoryEntry)); + + dir->dir_entry->basename = getStringCopy(dir_entry->d_name); + dir->dir_entry->filename = getPath2(dir->filename, dir_entry->d_name); + + struct stat file_status; + + dir->dir_entry->is_directory = + (stat(dir->dir_entry->filename, &file_status) == 0 && + (file_status.st_mode & S_IFMT) != S_IFDIR); + + return dir->dir_entry; +} + +void freeDirectoryEntry(struct DirectoryEntry *dir_entry) +{ + if (dir_entry == NULL) + return; + + checked_free(dir_entry->basename); + checked_free(dir_entry->filename); + checked_free(dir_entry); +} + + /* ------------------------------------------------------------------------- */ /* functions for checking files and filenames */ /* ------------------------------------------------------------------------- */ @@ -1862,7 +2040,18 @@ boolean fileExists(char *filename) if (filename == NULL) return FALSE; +#if defined(PLATFORM_ANDROID) + // workaround: check if file exists by opening and closing it + SDL_RWops *file = SDL_RWFromFile(filename, MODE_READ); + boolean success = (file != NULL); + + if (success) + SDL_RWclose(file); + + return success; +#else return (access(filename, F_OK) == 0); +#endif } boolean fileHasPrefix(char *basename, char *prefix) @@ -3109,8 +3298,12 @@ void openErrorFile() InitUserDataDirectory(); if ((program.error_file = fopen(program.error_filename, MODE_WRITE)) == NULL) - fprintf_newline(stderr, "ERROR: cannot open file '%s' for writing!", - program.error_filename); + { + program.error_file = stderr; + + Error(ERR_WARN, "cannot open file '%s' for writing: %s", + program.error_filename, strerror(errno)); + } } void closeErrorFile() diff --git a/src/libgame/misc.h b/src/libgame/misc.h index b8cdbbdb..12c28c32 100644 --- a/src/libgame/misc.h +++ b/src/libgame/misc.h @@ -16,6 +16,7 @@ #include #include +#include #include "system.h" @@ -69,6 +70,36 @@ /* values for general username handling stuff */ #define MAX_USERNAME_LEN 1024 +#if defined(PLATFORM_ANDROID) +/* values for Android asset handling */ +#define ASSET_TOC_BASENAME ".toc" +#endif + + +/* structure definitions */ + +struct DirectoryEntry +{ + boolean is_directory; + char *basename; + char *filename; +}; + +struct Directory +{ + char *filename; + DIR *dir; + struct DirectoryEntry *dir_entry; + +#if defined(PLATFORM_ANDROID) + boolean directory_is_asset; + SDL_RWops *asset_toc_file; + char *current_entry; +#endif +}; + + +/* function definitions */ void fprintf_line(FILE *, char *, int); void printf_line(char *, int); @@ -181,6 +212,11 @@ void deleteNodeFromList(ListNode **, char *, void (*function)(void *)); ListNode *getNodeFromKey(ListNode *, char *); int getNumNodes(ListNode *); +struct Directory *openDirectory(char *); +int closeDirectory(struct Directory *); +struct DirectoryEntry *readDirectory(struct Directory *); +void freeDirectoryEntry(struct DirectoryEntry *); + boolean fileExists(char *); boolean FileIsGraphic(char *); boolean FileIsSound(char *); diff --git a/src/libgame/platform.h b/src/libgame/platform.h index d5d939a6..c9682559 100644 --- a/src/libgame/platform.h +++ b/src/libgame/platform.h @@ -152,6 +152,12 @@ #define PLATFORM_STRING "Windows CE" #endif +#if defined(__ANDROID__) +#define PLATFORM_ANDROID +#undef PLATFORM_STRING +#define PLATFORM_STRING "Android" +#endif + /* ========================================================================= */ /* define additional target keywords */ diff --git a/src/libgame/setup.c b/src/libgame/setup.c index ac5b78d0..921ffdad 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "platform.h" @@ -1457,7 +1458,8 @@ void createDirectory(char *dir, char *text, int permission_class) if (!fileExists(dir)) if (posix_mkdir(dir, dir_mode) != 0) - Error(ERR_WARN, "cannot create %s directory '%s'", text, dir); + Error(ERR_WARN, "cannot create %s directory '%s': %s", + text, dir, strerror(errno)); if (permission_class == PERMS_PUBLIC && !running_setgid) chmod(dir, dir_mode); @@ -3235,9 +3237,14 @@ static void LoadLevelInfoFromLevelDir(TreeInfo **node_first, struct dirent *dir_entry; boolean valid_entry_found = FALSE; +#if 1 + Error(ERR_INFO, "looking for levels in '%s' ...", level_directory); +#endif + if ((dir = opendir(level_directory)) == NULL) { Error(ERR_WARN, "cannot read level directory '%s'", level_directory); + return; } @@ -3957,6 +3964,10 @@ static void SaveLevelSetup_LastSeries_Ext(boolean deactivate_last_level_series) /* ~/./levelsetup.conf */ /* ----------------------------------------------------------------------- */ + // check if the current level directory structure is available at this point + if (leveldir_current == NULL) + return; + char *filename = getPath2(getSetupDir(), LEVELSETUP_FILENAME); char *level_subdir = leveldir_current->subdir; FILE *file; @@ -3966,7 +3977,9 @@ static void SaveLevelSetup_LastSeries_Ext(boolean deactivate_last_level_series) if (!(file = fopen(filename, MODE_WRITE))) { Error(ERR_WARN, "cannot write setup file '%s'", filename); + free(filename); + return; } diff --git a/src/libgame/system.c b/src/libgame/system.c index e3f5847d..4c43f02d 100644 --- a/src/libgame/system.c +++ b/src/libgame/system.c @@ -129,6 +129,9 @@ void InitExitFunction(void (*exit_function)(int)) void InitPlatformDependentStuff(void) { + // this is initialized in GetOptions(), but may already be used before + options.verbose = TRUE; + #if defined(PLATFORM_MSDOS) _fmode = O_BINARY; #endif diff --git a/src/libgame/system.h b/src/libgame/system.h index e3454997..9f997cf1 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -24,6 +24,8 @@ #include "windows.h" #elif defined(PLATFORM_MSDOS) #include "msdos.h" +#elif defined(PLATFORM_ANDROID) +#include "android.h" #endif #if defined(TARGET_SDL) -- 2.34.1