aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Noonan <steven@uplinklabs.net>2019-03-20 08:43:17 -0700
committerSteven Noonan <steven@uplinklabs.net>2019-03-20 08:44:40 -0700
commit3c85d727181a04f2bfe5f511115f12834546c563 (patch)
tree16f76369dab7549eb20daf928f6eeefedc80c05d
parent06ec6136db1c80e5bf6a8e173b25df0e7de2ce2e (diff)
msvc build fixesvcf-2019
Signed-off-by: Steven Noonan <steven@uplinklabs.net>
-rw-r--r--CMakeLists.txt4
-rw-r--r--src/CMakeLists.txt7
-rw-r--r--src/avi_record.c3
-rw-r--r--src/compat/dirent.h890
-rw-r--r--src/compat/unistd.h3
-rw-r--r--src/cpu/compat.h2
-rw-r--r--src/cpu/memory.c2
-rw-r--r--src/cpu/sysdeps.h27
-rw-r--r--src/floppy.c4
-rw-r--r--src/gemdos.c5
-rw-r--r--src/gui-sdl/dlgFileSelect.c15
-rw-r--r--src/ide.c1
-rw-r--r--src/includes/file.h3
-rw-r--r--src/includes/hdc.h1
-rwxr-xr-xsrc/includes/vs-fix.h13
-rw-r--r--src/scandir.c4
-rw-r--r--src/scc.c5
-rw-r--r--src/screenSnapShot.c5
-rw-r--r--src/unzip.c3
-rw-r--r--src/zip.c4
20 files changed, 971 insertions, 30 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f101e131f..1328043cc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -209,6 +209,10 @@ if(ENABLE_OSX_BUNDLE)
endif(SDL2_FOUND)
endif(ENABLE_OSX_BUNDLE)
+if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
+ include_directories(src/compat)
+endif()
+
# ###########################
# Check for optional headers:
# ###########################
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index fe9567b7a..ab091df16 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -36,7 +36,9 @@ endif()
if(WIN32)
set(GUIWIN_SOURCES gui-win/opencon.c)
set(GUIWIN_RES gui-win/hatari-winicon.rc)
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -mwindows")
+ if(NOT CMAKE_C_COMPILER_ID MATCHES "MSVC")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -mwindows")
+ endif()
endif(WIN32)
if(ENABLE_WINUAE_CPU)
@@ -136,6 +138,9 @@ elseif(WIN32)
set_source_files_properties(${GUIWIN_RES} PROPERTIES LANGUAGE RC)
add_executable(hatari ${GUIWIN_RES} ${SOURCES} ${GUIWIN_SOURCES})
+ if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
+ target_link_options(hatari PRIVATE "/SUBSYSTEM:WINDOWS")
+ endif()
# Other targets, use default sources
else()
add_executable(hatari ${SOURCES})
diff --git a/src/avi_record.c b/src/avi_record.c
index 4d0691ec2..11890446b 100644
--- a/src/avi_record.c
+++ b/src/avi_record.c
@@ -93,6 +93,9 @@ const char AVIRecord_fileid[] = "Hatari avi_record.c : " __DATE__ " " __TIME__;
#include "sound.h"
#include "statusbar.h"
#include "avi_record.h"
+#include "file.h"
+
+#include <malloc.h>
/* after above that brings in config.h */
#if HAVE_LIBPNG
diff --git a/src/compat/dirent.h b/src/compat/dirent.h
new file mode 100644
index 000000000..60a203be5
--- /dev/null
+++ b/src/compat/dirent.h
@@ -0,0 +1,890 @@
+/*
+ * dirent.h - dirent API for Microsoft Visual Studio
+ *
+ * Copyright (C) 2006-2012 Toni Ronkko
+ *
+ * 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 TONI RONKKO 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.
+ *
+ *
+ * Version 1.13, Dec 12 2012, Toni Ronkko
+ * Use traditional 8+3 file name if the name cannot be represented in the
+ * default ANSI code page. Now compiles again with MSVC 6.0. Thanks to
+ * Konstantin Khomoutov for testing.
+ *
+ * Version 1.12.1, Oct 1 2012, Toni Ronkko
+ * Bug fix: renamed wide-character DIR structure _wDIR to _WDIR (with
+ * capital W) in order to maintain compatibility with MingW.
+ *
+ * Version 1.12, Sep 30 2012, Toni Ronkko
+ * Define PATH_MAX and NAME_MAX. Added wide-character variants _wDIR,
+ * _wdirent, _wopendir(), _wreaddir(), _wclosedir() and _wrewinddir().
+ * Thanks to Edgar Buerkle and Jan Nijtmans for ideas and code.
+ *
+ * Do not include windows.h. This allows dirent.h to be integrated more
+ * easily into programs using winsock. Thanks to Fernando Azaldegui.
+ *
+ * Version 1.11, Mar 15, 2011, Toni Ronkko
+ * Defined FILE_ATTRIBUTE_DEVICE for MSVC 6.0.
+ *
+ * Version 1.10, Aug 11, 2010, Toni Ronkko
+ * Added d_type and d_namlen fields to dirent structure. The former is
+ * especially useful for determining whether directory entry represents a
+ * file or a directory. For more information, see
+ * http://www.delorie.com/gnu/docs/glibc/libc_270.html
+ *
+ * Improved conformance to the standards. For example, errno is now set
+ * properly on failure and assert() is never used. Thanks to Peter Brockam
+ * for suggestions.
+ *
+ * Fixed a bug in rewinddir(): when using relative directory names, change
+ * of working directory no longer causes rewinddir() to fail.
+ *
+ * Version 1.9, Dec 15, 2009, John Cunningham
+ * Added rewinddir member function
+ *
+ * Version 1.8, Jan 18, 2008, Toni Ronkko
+ * Using FindFirstFileA and WIN32_FIND_DATAA to avoid converting string
+ * between multi-byte and unicode representations. This makes the
+ * code simpler and also allows the code to be compiled under MingW. Thanks
+ * to Azriel Fasten for the suggestion.
+ *
+ * Mar 4, 2007, Toni Ronkko
+ * Bug fix: due to the strncpy_s() function this file only compiled in
+ * Visual Studio 2005. Using the new string functions only when the
+ * compiler version allows.
+ *
+ * Nov 2, 2006, Toni Ronkko
+ * Major update: removed support for Watcom C, MS-DOS and Turbo C to
+ * simplify the file, updated the code to compile cleanly on Visual
+ * Studio 2005 with both unicode and multi-byte character strings,
+ * removed rewinddir() as it had a bug.
+ *
+ * Aug 20, 2006, Toni Ronkko
+ * Removed all remarks about MSVC 1.0, which is antiqued now. Simplified
+ * comments by removing SGML tags.
+ *
+ * May 14 2002, Toni Ronkko
+ * Embedded the function definitions directly to the header so that no
+ * source modules need to be included in the Visual Studio project. Removed
+ * all the dependencies to other projects so that this header file can be
+ * used independently.
+ *
+ * May 28 1998, Toni Ronkko
+ * First version.
+ *****************************************************************************/
+#ifndef DIRENT_H
+#define DIRENT_H
+
+#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
+# define _X86_
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <windef.h>
+#include <winbase.h>
+#include <wchar.h>
+#include <string.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+/* Indicates that d_type field is available in dirent structure */
+#define _DIRENT_HAVE_D_TYPE
+
+/* Indicates that d_namlen field is available in dirent structure */
+#define _DIRENT_HAVE_D_NAMLEN
+
+/* Entries missing from MSVC 6.0 */
+#if !defined(FILE_ATTRIBUTE_DEVICE)
+# define FILE_ATTRIBUTE_DEVICE 0x40
+#endif
+
+/* File type and permission flags for stat() */
+#if !defined(S_IFMT)
+# define S_IFMT _S_IFMT /* File type mask */
+#endif
+#if !defined(S_IFDIR)
+# define S_IFDIR _S_IFDIR /* Directory */
+#endif
+#if !defined(S_IFCHR)
+# define S_IFCHR _S_IFCHR /* Character device */
+#endif
+#if !defined(S_IFFIFO)
+# define S_IFFIFO _S_IFFIFO /* Pipe */
+#endif
+#if !defined(S_IFREG)
+# define S_IFREG _S_IFREG /* Regular file */
+#endif
+#if !defined(S_IREAD)
+# define S_IREAD _S_IREAD /* Read permission */
+#endif
+#if !defined(S_IWRITE)
+# define S_IWRITE _S_IWRITE /* Write permission */
+#endif
+#if !defined(S_IEXEC)
+# define S_IEXEC _S_IEXEC /* Execute permission */
+#endif
+#if !defined(S_IFIFO)
+# define S_IFIFO _S_IFIFO /* Pipe */
+#endif
+#if !defined(S_IFBLK)
+# define S_IFBLK 0 /* Block device */
+#endif
+#if !defined(S_IFLNK)
+# define S_IFLNK 0 /* Link */
+#endif
+#if !defined(S_IFSOCK)
+# define S_IFSOCK 0 /* Socket */
+#endif
+
+#if defined(_MSC_VER)
+# define S_IRUSR S_IREAD /* Read user */
+# define S_IWUSR S_IWRITE /* Write user */
+# define S_IXUSR 0 /* Execute user */
+# define S_IRGRP 0 /* Read group */
+# define S_IWGRP 0 /* Write group */
+# define S_IXGRP 0 /* Execute group */
+# define S_IROTH 0 /* Read others */
+# define S_IWOTH 0 /* Write others */
+# define S_IXOTH 0 /* Execute others */
+#endif
+
+/* Maximum length of file name */
+#if !defined(PATH_MAX)
+# define PATH_MAX MAX_PATH
+#endif
+#if !defined(FILENAME_MAX)
+# define FILENAME_MAX MAX_PATH
+#endif
+#if !defined(NAME_MAX)
+# define NAME_MAX FILENAME_MAX
+#endif
+
+/* File type flags for d_type */
+#define DT_UNKNOWN 0
+#define DT_LNK 31337
+#define DT_REG S_IFREG
+#define DT_DIR S_IFDIR
+#define DT_FIFO S_IFIFO
+#define DT_SOCK S_IFSOCK
+#define DT_CHR S_IFCHR
+#define DT_BLK S_IFBLK
+
+/* Macros for converting between st_mode and d_type */
+#define IFTODT(mode) ((mode) & S_IFMT)
+#define DTTOIF(type) (type)
+
+/*
+ * File type macros. Note that block devices, sockets and links cannot be
+ * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
+ * only defined for compatibility. These macros should always return false
+ * on Windows.
+ */
+#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
+#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
+#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
+#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
+#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
+#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
+#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
+
+/* Return the exact length of d_namlen without zero terminator */
+#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
+
+/* Return number of bytes needed to store d_namlen */
+#define _D_ALLOC_NAMLEN(p) (PATH_MAX + 1)
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Wide-character version */
+struct _wdirent {
+ long d_ino; /* Always zero */
+ unsigned short d_reclen; /* Structure size */
+ size_t d_namlen; /* Length of name without \0 */
+ int d_type; /* File type */
+ wchar_t d_name[PATH_MAX + 1]; /* File name */
+};
+typedef struct _wdirent _wdirent;
+
+struct _WDIR {
+ struct _wdirent ent; /* Current directory entry */
+ WIN32_FIND_DATAW data; /* Private file data */
+ int cached; /* True if data is valid */
+ HANDLE handle; /* Win32 search handle */
+ wchar_t *patt; /* Initial directory name */
+};
+typedef struct _WDIR _WDIR;
+
+static _WDIR *_wopendir (const wchar_t *dirname);
+static struct _wdirent *_wreaddir (_WDIR *dirp);
+static int _wclosedir (_WDIR *dirp);
+static void _wrewinddir (_WDIR* dirp);
+
+
+/* For compatibility with Symbian */
+#define wdirent _wdirent
+#define WDIR _WDIR
+#define wopendir _wopendir
+#define wreaddir _wreaddir
+#define wclosedir _wclosedir
+#define wrewinddir _wrewinddir
+
+
+/* Multi-byte character versions */
+struct dirent {
+ long d_ino; /* Always zero */
+ unsigned short d_reclen; /* Structure size */
+ size_t d_namlen; /* Length of name without \0 */
+ int d_type; /* File type */
+ char d_name[PATH_MAX + 1]; /* File name */
+};
+typedef struct dirent dirent;
+
+struct DIR {
+ struct dirent ent;
+ struct _WDIR *wdirp;
+};
+typedef struct DIR DIR;
+
+static DIR *opendir (const char *dirname);
+static struct dirent *readdir (DIR *dirp);
+static int closedir (DIR *dirp);
+static void rewinddir (DIR* dirp);
+
+
+/* Internal utility functions */
+static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
+static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
+
+static int dirent_mbstowcs_s(
+ size_t *pReturnValue,
+ wchar_t *wcstr,
+ size_t sizeInWords,
+ const char *mbstr,
+ size_t count);
+
+static int dirent_wcstombs_s(
+ size_t *pReturnValue,
+ char *mbstr,
+ size_t sizeInBytes,
+ const wchar_t *wcstr,
+ size_t count);
+
+static void dirent_set_errno (int error);
+
+/*
+ * Open directory stream DIRNAME for read and return a pointer to the
+ * internal working area that is used to retrieve individual directory
+ * entries.
+ */
+static _WDIR*
+_wopendir(
+ const wchar_t *dirname)
+{
+ _WDIR *dirp = NULL;
+ int error;
+
+ /* Must have directory name */
+ if (dirname == NULL || dirname[0] == '\0') {
+ dirent_set_errno (ENOENT);
+ return NULL;
+ }
+
+ /* Allocate new _WDIR structure */
+ dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
+ if (dirp != NULL) {
+ DWORD n;
+
+ /* Reset _WDIR structure */
+ dirp->handle = INVALID_HANDLE_VALUE;
+ dirp->patt = NULL;
+ dirp->cached = 0;
+
+ /* Compute the length of full path plus zero terminator */
+ n = GetFullPathNameW (dirname, 0, NULL, NULL);
+
+ /* Allocate room for absolute directory name and search pattern */
+ dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
+ if (dirp->patt) {
+
+ /*
+ * Convert relative directory name to an absolute one. This
+ * allows rewinddir() to function correctly even when current
+ * working directory is changed between opendir() and rewinddir().
+ */
+ n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
+ if (n > 0) {
+ wchar_t *p;
+
+ /* Append search pattern \* to the directory name */
+ p = dirp->patt + n;
+ if (dirp->patt < p) {
+ switch (p[-1]) {
+ case '\\':
+ case '/':
+ case ':':
+ /* Directory ends in path separator, e.g. c:\temp\ */
+ /*NOP*/;
+ break;
+
+ default:
+ /* Directory name doesn't end in path separator */
+ *p++ = '\\';
+ }
+ }
+ *p++ = '*';
+ *p = '\0';
+
+ /* Open directory stream and retrieve the first entry */
+ if (dirent_first (dirp)) {
+ /* Directory stream opened successfully */
+ error = 0;
+ } else {
+ /* Cannot retrieve first entry */
+ error = 1;
+ dirent_set_errno (ENOENT);
+ }
+
+ } else {
+ /* Cannot retrieve full path name */
+ dirent_set_errno (ENOENT);
+ error = 1;
+ }
+
+ } else {
+ /* Cannot allocate memory for search pattern */
+ error = 1;
+ }
+
+ } else {
+ /* Cannot allocate _WDIR structure */
+ error = 1;
+ }
+
+ /* Clean up in case of error */
+ if (error && dirp) {
+ _wclosedir (dirp);
+ dirp = NULL;
+ }
+
+ return dirp;
+}
+
+/*
+ * Read next directory entry. The directory entry is returned in dirent
+ * structure in the d_name field. Individual directory entries returned by
+ * this function include regular files, sub-directories, pseudo-directories
+ * "." and ".." as well as volume labels, hidden files and system files.
+ */
+static struct _wdirent*
+_wreaddir(
+ _WDIR *dirp)
+{
+ WIN32_FIND_DATAW *datap;
+ struct _wdirent *entp;
+
+ /* Read next directory entry */
+ datap = dirent_next (dirp);
+ if (datap) {
+ size_t n;
+ DWORD attr;
+
+ /* Pointer to directory entry to return */
+ entp = &dirp->ent;
+
+ /*
+ * Copy file name as wide-character string. If the file name is too
+ * long to fit in to the destination buffer, then truncate file name
+ * to PATH_MAX characters and zero-terminate the buffer.
+ */
+ n = 0;
+ while (n < PATH_MAX && datap->cFileName[n] != 0) {
+ entp->d_name[n] = datap->cFileName[n];
+ n++;
+ }
+ dirp->ent.d_name[n] = 0;
+
+ /* Length of file name excluding zero terminator */
+ entp->d_namlen = n;
+
+ /* File type */
+ attr = datap->dwFileAttributes;
+ if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
+ entp->d_type = DT_CHR;
+ } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
+ entp->d_type = DT_DIR;
+ } else {
+ entp->d_type = DT_REG;
+ }
+
+ /* Reset dummy fields */
+ entp->d_ino = 0;
+ entp->d_reclen = sizeof (struct _wdirent);
+
+ } else {
+
+ /* Last directory entry read */
+ entp = NULL;
+
+ }
+
+ return entp;
+}
+
+/*
+ * Close directory stream opened by opendir() function. This invalidates the
+ * DIR structure as well as any directory entry read previously by
+ * _wreaddir().
+ */
+static int
+_wclosedir(
+ _WDIR *dirp)
+{
+ int ok;
+ if (dirp) {
+
+ /* Release search handle */
+ if (dirp->handle != INVALID_HANDLE_VALUE) {
+ FindClose (dirp->handle);
+ dirp->handle = INVALID_HANDLE_VALUE;
+ }
+
+ /* Release search pattern */
+ if (dirp->patt) {
+ free (dirp->patt);
+ dirp->patt = NULL;
+ }
+
+ /* Release directory structure */
+ free (dirp);
+ ok = /*success*/0;
+
+ } else {
+ /* Invalid directory stream */
+ dirent_set_errno (EBADF);
+ ok = /*failure*/-1;
+ }
+ return ok;
+}
+
+/*
+ * Rewind directory stream such that _wreaddir() returns the very first
+ * file name again.
+ */
+static void
+_wrewinddir(
+ _WDIR* dirp)
+{
+ if (dirp) {
+ /* Release existing search handle */
+ if (dirp->handle != INVALID_HANDLE_VALUE) {
+ FindClose (dirp->handle);
+ }
+
+ /* Open new search handle */
+ dirent_first (dirp);
+ }
+}
+
+/* Get first directory entry (internal) */
+static WIN32_FIND_DATAW*
+dirent_first(
+ _WDIR *dirp)
+{
+ WIN32_FIND_DATAW *datap;
+
+ /* Open directory and retrieve the first entry */
+ dirp->handle = FindFirstFileW (dirp->patt, &dirp->data);
+ if (dirp->handle != INVALID_HANDLE_VALUE) {
+
+ /* a directory entry is now waiting in memory */
+ datap = &dirp->data;
+ dirp->cached = 1;
+
+ } else {
+
+ /* Failed to re-open directory: no directory entry in memory */
+ dirp->cached = 0;
+ datap = NULL;
+
+ }
+ return datap;
+}
+
+/* Get next directory entry (internal) */
+static WIN32_FIND_DATAW*
+dirent_next(
+ _WDIR *dirp)
+{
+ WIN32_FIND_DATAW *p;
+
+ /* Get next directory entry */
+ if (dirp->cached != 0) {
+
+ /* A valid directory entry already in memory */
+ p = &dirp->data;
+ dirp->cached = 0;
+
+ } else if (dirp->handle != INVALID_HANDLE_VALUE) {
+
+ /* Get the next directory entry from stream */
+ if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
+ /* Got a file */
+ p = &dirp->data;
+ } else {
+ /* The very last entry has been processed or an error occured */
+ FindClose (dirp->handle);
+ dirp->handle = INVALID_HANDLE_VALUE;
+ p = NULL;
+ }
+
+ } else {
+
+ /* End of directory stream reached */
+ p = NULL;
+
+ }
+
+ return p;
+}
+
+/*
+ * Open directory stream using plain old C-string.
+ */
+static DIR*
+opendir(
+ const char *dirname)
+{
+ struct DIR *dirp;
+ int error;
+
+ /* Must have directory name */
+ if (dirname == NULL || dirname[0] == '\0') {
+ dirent_set_errno (ENOENT);
+ return NULL;
+ }
+
+ /* Allocate memory for DIR structure */
+ dirp = (DIR*) malloc (sizeof (struct DIR));
+ if (dirp) {
+ wchar_t wname[PATH_MAX + 1];
+ size_t n;
+
+ /* Convert directory name to wide-character string */
+ error = dirent_mbstowcs_s(
+ &n, wname, PATH_MAX + 1, dirname, PATH_MAX);
+ if (!error) {
+
+ /* Open directory stream using wide-character name */
+ dirp->wdirp = _wopendir (wname);
+ if (dirp->wdirp) {
+ /* Directory stream opened */
+ error = 0;
+ } else {
+ /* Failed to open directory stream */
+ error = 1;
+ }
+
+ } else {
+ /*
+ * Cannot convert file name to wide-character string. This
+ * occurs if the string contains invalid multi-byte sequences or
+ * the output buffer is too small to contain the resulting
+ * string.
+ */
+ error = 1;
+ }
+
+ } else {
+ /* Cannot allocate DIR structure */
+ error = 1;
+ }
+
+ /* Clean up in case of error */
+ if (error && dirp) {
+ free (dirp);
+ dirp = NULL;
+ }
+
+ return dirp;
+}
+
+/*
+ * Read next directory entry.
+ *
+ * When working with text consoles, please note that file names returned by
+ * readdir() are represented in the default ANSI code page while any output to
+ * console is typically formatted on another code page. Thus, non-ASCII
+ * characters in file names will not usually display correctly on console. The
+ * problem can be fixed in two ways: (1) change the character set of console
+ * to 1252 using chcp utility and use Lucida Console font, or (2) use
+ * _cprintf function when writing to console. The _cprinf() will re-encode
+ * ANSI strings to the console code page so many non-ASCII characters will
+ * display correcly.
+ */
+static struct dirent*
+readdir(
+ DIR *dirp)
+{
+ WIN32_FIND_DATAW *datap;
+ struct dirent *entp;
+
+ /* Read next directory entry */
+ datap = dirent_next (dirp->wdirp);
+ if (datap) {
+ size_t n;
+ int error;
+
+ /* Attempt to convert file name to multi-byte string */
+ error = dirent_wcstombs_s(
+ &n, dirp->ent.d_name, MAX_PATH + 1, datap->cFileName, MAX_PATH);
+
+ /*
+ * If the file name cannot be represented by a multi-byte string,
+ * then attempt to use old 8+3 file name. This allows traditional
+ * Unix-code to access some file names despite of unicode
+ * characters, although file names may seem unfamiliar to the user.
+ *
+ * Be ware that the code below cannot come up with a short file
+ * name unless the file system provides one. At least
+ * VirtualBox shared folders fail to do this.
+ */
+ if (error && datap->cAlternateFileName[0] != '\0') {
+ error = dirent_wcstombs_s(
+ &n, dirp->ent.d_name, MAX_PATH + 1, datap->cAlternateFileName,
+ sizeof (datap->cAlternateFileName) /
+ sizeof (datap->cAlternateFileName[0]));
+ }
+
+ if (!error) {
+ DWORD attr;
+
+ /* Initialize directory entry for return */
+ entp = &dirp->ent;
+
+ /* Length of file name excluding zero terminator */
+ entp->d_namlen = n - 1;
+
+ /* File attributes */
+ attr = datap->dwFileAttributes;
+ if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
+ entp->d_type = DT_CHR;
+ } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
+ entp->d_type = DT_DIR;
+ } else {
+ entp->d_type = DT_REG;
+ }
+
+ /* Reset dummy fields */
+ entp->d_ino = 0;
+ entp->d_reclen = sizeof (struct dirent);
+
+ } else {
+ /*
+ * Cannot convert file name to multi-byte string so construct
+ * an errornous directory entry and return that. Note that
+ * we cannot return NULL as that would stop the processing
+ * of directory entries completely.
+ */
+ entp = &dirp->ent;
+ entp->d_name[0] = '?';
+ entp->d_name[1] = '\0';
+ entp->d_namlen = 1;
+ entp->d_type = DT_UNKNOWN;
+ entp->d_ino = 0;
+ entp->d_reclen = 0;
+ }
+
+ } else {
+ /* No more directory entries */
+ entp = NULL;
+ }
+
+ return entp;
+}
+
+/*
+ * Close directory stream.
+ */
+static int
+closedir(
+ DIR *dirp)
+{
+ int ok;
+ if (dirp) {
+
+ /* Close wide-character directory stream */
+ ok = _wclosedir (dirp->wdirp);
+ dirp->wdirp = NULL;
+
+ /* Release multi-byte character version */
+ free (dirp);
+
+ } else {
+
+ /* Invalid directory stream */
+ dirent_set_errno (EBADF);
+ ok = /*failure*/-1;
+
+ }
+ return ok;
+}
+
+/*
+ * Rewind directory stream to beginning.
+ */
+static void
+rewinddir(
+ DIR* dirp)
+{
+ /* Rewind wide-character string directory stream */
+ _wrewinddir (dirp->wdirp);
+}
+
+/* Convert multi-byte string to wide character string */
+static int
+dirent_mbstowcs_s(
+ size_t *pReturnValue,
+ wchar_t *wcstr,
+ size_t sizeInWords,
+ const char *mbstr,
+ size_t count)
+{
+ int error;
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+
+ /* Microsoft Visual Studio 2005 or later */
+ error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
+
+#else
+
+ /* Older Visual Studio or non-Microsoft compiler */
+ size_t n;
+
+ /* Convert to wide-character string */
+ n = mbstowcs (wcstr, mbstr, count);
+ if (n < sizeInWords) {
+
+ /* Zero-terminate output buffer */
+ if (wcstr) {
+ wcstr[n] = 0;
+ }
+
+ /* Length of resuting multi-byte string WITH zero terminator */
+ if (pReturnValue) {
+ *pReturnValue = n + 1;
+ }
+
+ /* Success */
+ error = 0;
+
+ } else {
+
+ /* Could not convert string */
+ error = 1;
+
+ }
+
+#endif
+
+ return error;
+}
+
+/* Convert wide-character string to multi-byte string */
+static int
+dirent_wcstombs_s(
+ size_t *pReturnValue,
+ char *mbstr,
+ size_t sizeInBytes,
+ const wchar_t *wcstr,
+ size_t count)
+{
+ int error;
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+
+ /* Microsoft Visual Studio 2005 or later */
+ error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
+
+#else
+
+ /* Older Visual Studio or non-Microsoft compiler */
+ size_t n;
+
+ /* Convert to multi-byte string */
+ n = wcstombs (mbstr, wcstr, count);
+ if (n < sizeInBytes) {
+
+ /* Zero-terminate output buffer */
+ if (mbstr) {
+ mbstr[n] = '\0';
+ }
+
+ /* Lenght of resulting multi-bytes string WITH zero-terminator */
+ if (pReturnValue) {
+ *pReturnValue = n + 1;
+ }
+
+ /* Success */
+ error = 0;
+
+ } else {
+
+ /* Cannot convert string */
+ error = 1;
+
+ }
+
+#endif
+
+ return error;
+}
+
+/* Set errno variable */
+static void
+dirent_set_errno(
+ int error)
+{
+#if defined(_MSC_VER)
+
+ /* Microsoft Visual Studio */
+ _set_errno (error);
+
+#else
+
+ /* Non-Microsoft compiler */
+ errno = error;
+
+#endif
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*DIRENT_H*/
+
diff --git a/src/compat/unistd.h b/src/compat/unistd.h
new file mode 100644
index 000000000..dd5a220de
--- /dev/null
+++ b/src/compat/unistd.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#include "vs-fix.h"
diff --git a/src/cpu/compat.h b/src/cpu/compat.h
index 36ee2ec1b..958bbf824 100644
--- a/src/cpu/compat.h
+++ b/src/cpu/compat.h
@@ -35,7 +35,7 @@ static inline void to_upper (TCHAR *s, int len) {
static inline void my_trim (TCHAR *s)
{
- int len;
+ size_t len;
while (_tcslen (s) > 0 && _tcscspn (s, _T("\t \r\n")) == 0)
memmove (s, s + 1, (_tcslen (s + 1) + 1) * sizeof (TCHAR));
len = _tcslen (s);
diff --git a/src/cpu/memory.c b/src/cpu/memory.c
index 609c58b24..a310aac8e 100644
--- a/src/cpu/memory.c
+++ b/src/cpu/memory.c
@@ -1826,7 +1826,7 @@ static void map_banks2 (addrbank *bank, int start, int size, int realsize, int q
#else
int bnr;
unsigned long int hioffs = 0, endhioffs = 0x100;
- uae_u32 realstart __attribute__((unused)) = start;
+ uae_u32 realstart UNUSED = start;
#endif
//printf ( "map %x %x 24=%d\n" , start<<16 , size<<16 , currprefs.address_space_24 );
diff --git a/src/cpu/sysdeps.h b/src/cpu/sysdeps.h
index 30fbed099..e2133055f 100644
--- a/src/cpu/sysdeps.h
+++ b/src/cpu/sysdeps.h
@@ -59,7 +59,7 @@ using namespace std;
#error unrecognized CPU type
#endif
-#ifdef _WIN32
+#if defined(_WIN32) && defined(CPU_i386)
/* Parameters are passed in ECX, EDX for both x86 and x86-64 (RCX, RDX).
* For x86-64, __fastcall is the default, so it isn't really required. */
#define JITCALL __fastcall
@@ -78,6 +78,11 @@ using namespace std;
#define REGPARAM
#define REGPARAM2 JITCALL
#define REGPARAM3 JITCALL
+#ifdef __GNUC__
+#define UNUSED __attribute__((unused))
+#else
+#define UNUSED
+#endif
#ifdef WINUAE_FOR_HATARI
#include "uae/types.h"
@@ -351,30 +356,18 @@ extern void gettimeofday( struct timeval *tv, void *blah );
#define O_RDWR _O_RDWR
#define O_CREAT _O_CREAT
#define O_TRUNC _O_TRUNC
+#ifndef strcasecmp
#define strcasecmp _tcsicmp
+#endif
+#ifndef strncasecmp
#define strncasecmp _tcsncicmp
+#endif
#define W_OK 0x2
#define R_OK 0x4
-#define STAT struct stat
-#define DIR struct DIR
-struct direct
-{
- TCHAR d_name[1];
-};
#include <sys/utime.h>
#define utimbuf __utimbuf64
#define USE_ZFILE
-#undef S_ISDIR
-#undef S_IWUSR
-#undef S_IRUSR
-#undef S_IXUSR
-#define S_ISDIR(a) (a&FILEFLAG_DIR)
-#define S_ISARC(a) (a&FILEFLAG_ARCHIVE)
-#define S_IWUSR FILEFLAG_WRITE
-#define S_IRUSR FILEFLAG_READ
-#define S_IXUSR FILEFLAG_EXECUTE
-
#endif
#endif /* _WIN32 */
diff --git a/src/floppy.c b/src/floppy.c
index acbfdac97..bac61b27c 100644
--- a/src/floppy.c
+++ b/src/floppy.c
@@ -23,6 +23,10 @@
*/
const char Floppy_fileid[] = "Hatari floppy.c : " __DATE__ " " __TIME__;
+#ifdef WIN32
+#include <windows.h>
+#endif
+
#include <sys/stat.h>
#include <assert.h>
#include <SDL_endian.h>
diff --git a/src/gemdos.c b/src/gemdos.c
index 035249cdf..781929f66 100644
--- a/src/gemdos.c
+++ b/src/gemdos.c
@@ -25,6 +25,11 @@ const char Gemdos_fileid[] = "Hatari gemdos.c : " __DATE__ " " __TIME__;
#include <config.h>
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <inttypes.h>
#include <sys/stat.h>
#if HAVE_STATVFS
#include <sys/statvfs.h>
diff --git a/src/gui-sdl/dlgFileSelect.c b/src/gui-sdl/dlgFileSelect.c
index f0891869e..65de313d7 100644
--- a/src/gui-sdl/dlgFileSelect.c
+++ b/src/gui-sdl/dlgFileSelect.c
@@ -8,6 +8,10 @@
*/
const char DlgFileSelect_fileid[] = "Hatari dlgFileSelect.c : " __DATE__ " " __TIME__;
+#ifdef WIN32
+#include <windows.h>
+#endif
+
#include <SDL.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -20,6 +24,9 @@ const char DlgFileSelect_fileid[] = "Hatari dlgFileSelect.c : " __DATE__ " " __T
#include "zip.h"
#include "log.h"
+#ifdef _MSC_VER
+#include "vs-fix.h"
+#endif
#define SGFS_NUMENTRIES 16 /* How many entries are displayed at once */
@@ -106,14 +113,6 @@ static int mouseIsOut = 0; /* used to keep info that mouse if above or under t
static float scrollbar_Ypos = 0.0; /* scrollbar heigth */
static char *dirpath; /* for get_dtype() */
-#ifndef HAVE_DIRENT_D_TYPE
-enum {
- DT_UNKNOWN,
- DT_LNK,
- DT_DIR,
- DT_REG
-};
-#endif
/* Convert file position (in file list) to scrollbar y position */
static void DlgFileSelect_Convert_ypos_to_scrollbar_Ypos(void);
diff --git a/src/ide.c b/src/ide.c
index 5183d64db..f31175d05 100644
--- a/src/ide.c
+++ b/src/ide.c
@@ -10,6 +10,7 @@
#include <SDL_endian.h>
#include <errno.h>
+#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
diff --git a/src/includes/file.h b/src/includes/file.h
index 9b8b10f8a..0efafd2fb 100644
--- a/src/includes/file.h
+++ b/src/includes/file.h
@@ -17,6 +17,9 @@
#ifndef HAVE_FTELLO
#define ftello ftell
#endif
+#ifdef _MSC_VER
+typedef long off_t;
+#endif
extern void File_CleanFileName(char *pszFileName);
extern void File_AddSlashToEndFileName(char *pszFileName);
diff --git a/src/includes/hdc.h b/src/includes/hdc.h
index 5e25edf5c..c4a2fc252 100644
--- a/src/includes/hdc.h
+++ b/src/includes/hdc.h
@@ -11,6 +11,7 @@
#ifndef HATARI_HDC_H
#define HATARI_HDC_H
+#include "file.h"
/* Opcodes */
/* The following are multi-sector transfers with seek implied */
diff --git a/src/includes/vs-fix.h b/src/includes/vs-fix.h
index 497566e09..b24fb006e 100755
--- a/src/includes/vs-fix.h
+++ b/src/includes/vs-fix.h
@@ -23,7 +23,16 @@
typedef unsigned short mode_t;
-#define strncasecmp _strnicmp
-#define strcasecmp _stricmp
+typedef long off_t;
+
+#define F_OK 0
+
+#ifndef strcasecmp
+#define strcasecmp _stricmp
+#endif
+
+#ifndef strncasecmp
+#define strncasecmp _strnicmp
+#endif
#endif
diff --git a/src/scandir.c b/src/scandir.c
index 4ebf8ce90..f41af987f 100644
--- a/src/scandir.c
+++ b/src/scandir.c
@@ -8,6 +8,10 @@
*/
const char ScanDir_fileid[] = "Hatari scandir.c : " __DATE__ " " __TIME__;
+#ifdef WIN32
+#include <Windows.h>
+#endif
+
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/src/scc.c b/src/scc.c
index f5813d300..33dd267a2 100644
--- a/src/scc.c
+++ b/src/scc.c
@@ -27,6 +27,11 @@
#include "main.h"
+#ifdef WIN32
+#include <Windows.h>
+#endif
+
+#include <dirent.h>
#if HAVE_TERMIOS_H
# include <termios.h>
# include <unistd.h>
diff --git a/src/screenSnapShot.c b/src/screenSnapShot.c
index bc83c36b8..c50add0c8 100644
--- a/src/screenSnapShot.c
+++ b/src/screenSnapShot.c
@@ -8,10 +8,15 @@
*/
const char ScreenSnapShot_fileid[] = "Hatari screenSnapShot.c : " __DATE__ " " __TIME__;
+#ifdef WIN32
+#include <windows.h>
+#endif
+
#include <SDL.h>
#include <dirent.h>
#include <string.h>
#include "main.h"
+#include "file.h"
#include "configuration.h"
#include "log.h"
#include "paths.h"
diff --git a/src/unzip.c b/src/unzip.c
index 70d820815..61a3b1a8b 100644
--- a/src/unzip.c
+++ b/src/unzip.c
@@ -33,6 +33,9 @@ const char Unzip_fileid[] = "Hatari unzip.c : " __DATE__ " " __TIME__;
# include <errno.h>
#endif
+#ifdef _MSC_VER
+#include "vs-fix.h"
+#endif
#ifndef local
# define local static
diff --git a/src/zip.c b/src/zip.c
index ba18f68b6..ae8750918 100644
--- a/src/zip.c
+++ b/src/zip.c
@@ -8,6 +8,10 @@
*/
const char ZIP_fileid[] = "Hatari zip.c : " __DATE__ " " __TIME__;
+#ifdef WIN32
+#include <Windows.h>
+#endif
+
#include "main.h"
#include <unistd.h>
#include <dirent.h>