a4020af3449912385fb02428ffa1794eedd8c16f
[picodrive.git] / platform / win32 / plat.c
1 /*
2  * PicoDrive
3  * (C) notaz, 2009,2010
4  *
5  * This work is licensed under the terms of MAME license.
6  * See COPYING file in the top-level directory.
7  */
8 #include <windows.h>
9 #include <stdio.h>
10 #include <dirent.h>
11
12 #include "../libpicofe/plat.h"
13 #include "../libpicofe/posix.h"
14 #include "../common/emu.h"
15 #include <pico/pico_int.h>
16
17 int plat_is_dir(const char *path)
18 {
19         return (GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
20 }
21
22 unsigned int plat_get_ticks_ms(void)
23 {
24         return GetTickCount();
25 }
26
27 unsigned int plat_get_ticks_us(void)
28 {
29         // XXX: maybe performance counters?
30         return GetTickCount() * 1000;
31 }
32
33 void plat_sleep_ms(int ms)
34 {
35         Sleep(ms);
36 }
37
38 int plat_wait_event(int *fds_hnds, int count, int timeout_ms)
39 {
40         return -1;
41 }
42
43 int plat_get_root_dir(char *dst, int len)
44 {
45         int ml;
46
47         ml = GetModuleFileName(NULL, dst, len);
48         while (ml > 0 && dst[ml] != '\\')
49                 ml--;
50         if (ml != 0)
51                 ml++;
52
53         dst[ml] = 0;
54         return ml;
55 }
56
57 int plat_get_skin_dir(char *dst, int len)
58 {
59         int ml;
60
61         ml = GetModuleFileName(NULL, dst, len);
62         while (ml > 0 && dst[ml] != '\\')
63                 ml--;
64         if (ml != 0)
65                 dst[ml++] = '\\';
66         memcpy(dst + ml, "skin\\", sizeof("skin\\"));
67         dst[ml + sizeof("skin\\")] = 0;
68         return ml + sizeof("skin\\") - 1;
69 }
70
71 int plat_get_data_dir(char *dst, int len)
72 {
73         return plat_get_root_dir(dst, len);
74 }
75
76 void *plat_mmap(unsigned long addr, size_t size, int need_exec, int is_fixed)
77 {
78         void *ptr;
79         unsigned long old;
80
81         ptr = VirtualAlloc(NULL, size, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
82         if (ptr && need_exec)
83                 VirtualProtect(ptr, size, PAGE_EXECUTE_READWRITE, &old);
84         return ptr;
85 }
86
87 void plat_munmap(void *ptr, size_t size)
88 {
89         VirtualFree(ptr, 0, MEM_RELEASE);
90 }
91
92 void *plat_mremap(void *ptr, size_t oldsize, size_t newsize)
93 {
94         void *ret = plat_mmap(0, newsize, 0, 0);
95         if (ret != NULL) {
96                 memcpy(ret, ptr, oldsize);
97                 plat_munmap(ptr, oldsize);
98         }
99         return ret;
100 }
101
102 int   plat_mem_set_exec(void *ptr, size_t size)
103 {
104         unsigned long old;
105
106         return -(VirtualProtect(ptr, size, PAGE_EXECUTE_READWRITE, &old) == 0);
107 }
108
109 // other
110 void lprintf(const char *fmt, ...)
111 {
112   char buf[512];
113   va_list val;
114
115   va_start(val, fmt);
116   vsnprintf(buf, sizeof(buf), fmt, val);
117   va_end(val);
118   OutputDebugString(buf);
119   printf("%s", buf);
120 }
121
122 // missing from mingw32
123 int scandir(const char *dir, struct dirent ***namelist, int (*select)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **)) {
124     HANDLE handle;
125     WIN32_FIND_DATA info;
126     char path[MAX_PATH];
127     struct dirent **entries = NULL;
128     size_t count = 0;
129
130     snprintf(path, sizeof(path), "%s\\*", dir);
131     handle = FindFirstFile(path, &info);
132     if (handle == INVALID_HANDLE_VALUE)
133         return -1;
134
135     do {
136         struct dirent *entry = (struct dirent *)malloc(sizeof(struct dirent));
137         if (!entry) {
138             free(entries);
139             FindClose(handle);
140             return -1;
141         }
142
143         strcpy(entry->d_name, info.cFileName);
144         entry->d_type = (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? DT_DIR : DT_REG;
145
146         if (!select || select(entry)) {
147             entries = realloc(entries, (count + 1) * sizeof(struct dirent *));
148             entries[count++] = entry;
149         } else
150             free(entry);
151     } while (FindNextFile(handle, &info));
152
153     FindClose(handle);
154
155     // Sort entries if a comparison function is provided
156     if (compar) {
157         qsort(entries, count, sizeof(struct dirent *), (int (*)(const void *, const void *))compar);
158     }
159
160     *namelist = entries;
161     return count;
162 }
163
164 int alphasort(const struct dirent **a, const struct dirent **b) {
165     return strcmp((*a)->d_name, (*b)->d_name);
166 }