... | ... |
@@ -19,29 +19,32 @@ WITH REGARD TO THIS SOFTWARE. |
19 | 19 |
#include <sys/stat.h> |
20 | 20 |
#include <unistd.h> |
21 | 21 |
|
22 |
-static FILE *f; |
|
23 |
-static DIR *dir; |
|
24 |
-static char *current_filename = ""; |
|
25 |
-static struct dirent *de; |
|
26 |
- |
|
27 |
-static enum { IDLE, |
|
28 |
- FILE_READ, |
|
29 |
- FILE_WRITE, |
|
30 |
- DIR_READ } state; |
|
22 |
+typedef struct { |
|
23 |
+ FILE *f; |
|
24 |
+ DIR *dir; |
|
25 |
+ char *current_filename; |
|
26 |
+ struct dirent *de; |
|
27 |
+ enum { IDLE, |
|
28 |
+ FILE_READ, |
|
29 |
+ FILE_WRITE, |
|
30 |
+ DIR_READ } state; |
|
31 |
+} UxnFile; |
|
32 |
+ |
|
33 |
+static UxnFile uxn_file[POLYFILEY]; |
|
31 | 34 |
|
32 | 35 |
static void |
33 |
-reset(void) |
|
36 |
+reset(UxnFile *c) |
|
34 | 37 |
{ |
35 |
- if(f != NULL) { |
|
36 |
- fclose(f); |
|
37 |
- f = NULL; |
|
38 |
+ if(c->f != NULL) { |
|
39 |
+ fclose(c->f); |
|
40 |
+ c->f = NULL; |
|
38 | 41 |
} |
39 |
- if(dir != NULL) { |
|
40 |
- closedir(dir); |
|
41 |
- dir = NULL; |
|
42 |
+ if(c->dir != NULL) { |
|
43 |
+ closedir(c->dir); |
|
44 |
+ c->dir = NULL; |
|
42 | 45 |
} |
43 |
- de = NULL; |
|
44 |
- state = IDLE; |
|
46 |
+ c->de = NULL; |
|
47 |
+ c->state = IDLE; |
|
45 | 48 |
} |
46 | 49 |
|
47 | 50 |
static Uint16 |
... | ... |
@@ -61,20 +64,20 @@ get_entry(char *p, Uint16 len, const char *pathname, const char *basename, int f |
61 | 64 |
} |
62 | 65 |
|
63 | 66 |
static Uint16 |
64 |
-file_read_dir(char *dest, Uint16 len) |
|
67 |
+file_read_dir(UxnFile *c, char *dest, Uint16 len) |
|
65 | 68 |
{ |
66 | 69 |
static char pathname[4096]; |
67 | 70 |
char *p = dest; |
68 |
- if(de == NULL) de = readdir(dir); |
|
69 |
- for(; de != NULL; de = readdir(dir)) { |
|
71 |
+ if(c->de == NULL) c->de = readdir(c->dir); |
|
72 |
+ for(; c->de != NULL; c->de = readdir(c->dir)) { |
|
70 | 73 |
Uint16 n; |
71 |
- if(de->d_name[0] == '.' && de->d_name[1] == '\0') |
|
74 |
+ if(c->de->d_name[0] == '.' && c->de->d_name[1] == '\0') |
|
72 | 75 |
continue; |
73 |
- if(strlen(current_filename) + 1 + strlen(de->d_name) < sizeof(pathname)) |
|
74 |
- sprintf(pathname, "%s/%s", current_filename, de->d_name); |
|
76 |
+ if(strlen(c->current_filename) + 1 + strlen(c->de->d_name) < sizeof(pathname)) |
|
77 |
+ sprintf(pathname, "%s/%s", c->current_filename, c->de->d_name); |
|
75 | 78 |
else |
76 | 79 |
pathname[0] = '\0'; |
77 |
- n = get_entry(p, len, pathname, de->d_name, 1); |
|
80 |
+ n = get_entry(p, len, pathname, c->de->d_name, 1); |
|
78 | 81 |
if(!n) break; |
79 | 82 |
p += n; |
80 | 83 |
len -= n; |
... | ... |
@@ -83,68 +86,69 @@ file_read_dir(char *dest, Uint16 len) |
83 | 86 |
} |
84 | 87 |
|
85 | 88 |
static Uint16 |
86 |
-file_init(void *filename) |
|
89 |
+file_init(UxnFile *c, void *filename) |
|
87 | 90 |
{ |
88 |
- reset(); |
|
89 |
- current_filename = filename; |
|
91 |
+ reset(c); |
|
92 |
+ c->current_filename = filename; |
|
90 | 93 |
return 0; |
91 | 94 |
} |
92 | 95 |
|
93 | 96 |
static Uint16 |
94 |
-file_read(void *dest, Uint16 len) |
|
97 |
+file_read(UxnFile *c, void *dest, Uint16 len) |
|
95 | 98 |
{ |
96 |
- if(state != FILE_READ && state != DIR_READ) { |
|
97 |
- reset(); |
|
98 |
- if((dir = opendir(current_filename)) != NULL) |
|
99 |
- state = DIR_READ; |
|
100 |
- else if((f = fopen(current_filename, "rb")) != NULL) |
|
101 |
- state = FILE_READ; |
|
99 |
+ if(c->state != FILE_READ && c->state != DIR_READ) { |
|
100 |
+ reset(c); |
|
101 |
+ if((c->dir = opendir(c->current_filename)) != NULL) |
|
102 |
+ c->state = DIR_READ; |
|
103 |
+ else if((c->f = fopen(c->current_filename, "rb")) != NULL) |
|
104 |
+ c->state = FILE_READ; |
|
102 | 105 |
} |
103 |
- if(state == FILE_READ) |
|
104 |
- return fread(dest, 1, len, f); |
|
105 |
- if(state == DIR_READ) |
|
106 |
- return file_read_dir(dest, len); |
|
106 |
+ if(c->state == FILE_READ) |
|
107 |
+ return fread(dest, 1, len, c->f); |
|
108 |
+ if(c->state == DIR_READ) |
|
109 |
+ return file_read_dir(c, dest, len); |
|
107 | 110 |
return 0; |
108 | 111 |
} |
109 | 112 |
|
110 | 113 |
static Uint16 |
111 |
-file_write(void *src, Uint16 len, Uint8 flags) |
|
114 |
+file_write(UxnFile *c, void *src, Uint16 len, Uint8 flags) |
|
112 | 115 |
{ |
113 | 116 |
Uint16 ret = 0; |
114 |
- if(state != FILE_WRITE) { |
|
115 |
- reset(); |
|
116 |
- if((f = fopen(current_filename, (flags & 0x01) ? "ab" : "wb")) != NULL) |
|
117 |
- state = FILE_WRITE; |
|
117 |
+ if(c->state != FILE_WRITE) { |
|
118 |
+ reset(c); |
|
119 |
+ if((c->f = fopen(c->current_filename, (flags & 0x01) ? "ab" : "wb")) != NULL) |
|
120 |
+ c->state = FILE_WRITE; |
|
118 | 121 |
} |
119 |
- if(state == FILE_WRITE) { |
|
120 |
- if((ret = fwrite(src, 1, len, f)) > 0 && fflush(f) != 0) |
|
122 |
+ if(c->state == FILE_WRITE) { |
|
123 |
+ if((ret = fwrite(src, 1, len, c->f)) > 0 && fflush(c->f) != 0) |
|
121 | 124 |
ret = 0; |
122 | 125 |
} |
123 | 126 |
return ret; |
124 | 127 |
} |
125 | 128 |
|
126 | 129 |
static Uint16 |
127 |
-file_stat(void *dest, Uint16 len) |
|
130 |
+file_stat(UxnFile *c, void *dest, Uint16 len) |
|
128 | 131 |
{ |
129 |
- char *basename = strrchr(current_filename, '/'); |
|
132 |
+ char *basename = strrchr(c->current_filename, '/'); |
|
130 | 133 |
if(basename != NULL) |
131 | 134 |
basename++; |
132 | 135 |
else |
133 |
- basename = current_filename; |
|
134 |
- return get_entry(dest, len, current_filename, basename, 0); |
|
136 |
+ basename = c->current_filename; |
|
137 |
+ return get_entry(dest, len, c->current_filename, basename, 0); |
|
135 | 138 |
} |
136 | 139 |
|
137 | 140 |
static Uint16 |
138 |
-file_delete(void) |
|
141 |
+file_delete(UxnFile *c) |
|
139 | 142 |
{ |
140 |
- return unlink(current_filename); |
|
143 |
+ return unlink(c->current_filename); |
|
141 | 144 |
} |
142 | 145 |
|
143 | 146 |
/* IO */ |
144 | 147 |
|
145 | 148 |
void |
146 |
-file_deo(Device *d, Uint8 port) |
|
149 |
+file_i_deo(int instance, Device *d, Uint8 port) |
|
147 | 150 |
{ |
151 |
+ UxnFile *c = &uxn_file[instance]; |
|
148 | 152 |
Uint16 addr, len, res; |
149 | 153 |
switch(port) { |
150 | 154 |
case 0x5: |
... | ... |
@@ -152,16 +156,16 @@ file_deo(Device *d, Uint8 port) |
152 | 156 |
DEVPEEK16(len, 0xa); |
153 | 157 |
if(len > 0x10000 - addr) |
154 | 158 |
len = 0x10000 - addr; |
155 |
- res = file_stat(&d->u->ram[addr], len); |
|
159 |
+ res = file_stat(c, &d->u->ram[addr], len); |
|
156 | 160 |
DEVPOKE16(0x2, res); |
157 | 161 |
break; |
158 | 162 |
case 0x6: |
159 |
- res = file_delete(); |
|
163 |
+ res = file_delete(c); |
|
160 | 164 |
DEVPOKE16(0x2, res); |
161 | 165 |
break; |
162 | 166 |
case 0x9: |
163 | 167 |
DEVPEEK16(addr, 0x8); |
164 |
- res = file_init(&d->u->ram[addr]); |
|
168 |
+ res = file_init(c, (char *)&d->u->ram[addr]); |
|
165 | 169 |
DEVPOKE16(0x2, res); |
166 | 170 |
break; |
167 | 171 |
case 0xd: |
... | ... |
@@ -169,7 +173,7 @@ file_deo(Device *d, Uint8 port) |
169 | 173 |
DEVPEEK16(len, 0xa); |
170 | 174 |
if(len > 0x10000 - addr) |
171 | 175 |
len = 0x10000 - addr; |
172 |
- res = file_read(&d->u->ram[addr], len); |
|
176 |
+ res = file_read(c, &d->u->ram[addr], len); |
|
173 | 177 |
DEVPOKE16(0x2, res); |
174 | 178 |
break; |
175 | 179 |
case 0xf: |
... | ... |
@@ -177,8 +181,14 @@ file_deo(Device *d, Uint8 port) |
177 | 181 |
DEVPEEK16(len, 0xa); |
178 | 182 |
if(len > 0x10000 - addr) |
179 | 183 |
len = 0x10000 - addr; |
180 |
- res = file_write(&d->u->ram[addr], len, d->dat[0x7]); |
|
184 |
+ res = file_write(c, &d->u->ram[addr], len, d->dat[0x7]); |
|
181 | 185 |
DEVPOKE16(0x2, res); |
182 | 186 |
break; |
183 | 187 |
} |
184 | 188 |
} |
189 |
+ |
|
190 |
+Uint8 |
|
191 |
+file_i_dei(int instance, Device *d, Uint8 port) |
|
192 |
+{ |
|
193 |
+ return d->dat[port]; |
|
194 |
+} |
... | ... |
@@ -10,4 +10,7 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
10 | 10 |
WITH REGARD TO THIS SOFTWARE. |
11 | 11 |
*/ |
12 | 12 |
|
13 |
-void file_deo(Device *d, Uint8 port); |
|
13 |
+#define POLYFILEY 1 |
|
14 |
+ |
|
15 |
+void file_i_deo(int instance, Device *d, Uint8 port); |
|
16 |
+Uint8 file_i_dei(int instance, Device *d, Uint8 port); |
... | ... |
@@ -17,6 +17,8 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
17 | 17 |
WITH REGARD TO THIS SOFTWARE. |
18 | 18 |
*/ |
19 | 19 |
|
20 |
+static Device *devfile0; |
|
21 |
+ |
|
20 | 22 |
static int |
21 | 23 |
error(char *msg, const char *err) |
22 | 24 |
{ |
... | ... |
@@ -42,6 +44,18 @@ console_deo(Device *d, Uint8 port) |
42 | 44 |
} |
43 | 45 |
} |
44 | 46 |
|
47 |
+static void |
|
48 |
+file_deo(Device *d, Uint8 port) |
|
49 |
+{ |
|
50 |
+ file_i_deo(d - devfile0, d, port); |
|
51 |
+} |
|
52 |
+ |
|
53 |
+static Uint8 |
|
54 |
+file_dei(Device *d, Uint8 port) |
|
55 |
+{ |
|
56 |
+ return file_i_dei(d - devfile0, d, port); |
|
57 |
+} |
|
58 |
+ |
|
45 | 59 |
static Uint8 |
46 | 60 |
nil_dei(Device *d, Uint8 port) |
47 | 61 |
{ |
... | ... |
@@ -102,7 +116,7 @@ start(Uxn *u) |
102 | 116 |
/* empty */ uxn_port(u, 0x7, nil_dei, nil_deo); |
103 | 117 |
/* empty */ uxn_port(u, 0x8, nil_dei, nil_deo); |
104 | 118 |
/* empty */ uxn_port(u, 0x9, nil_dei, nil_deo); |
105 |
- /* file */ uxn_port(u, 0xa, nil_dei, file_deo); |
|
119 |
+ /* file */ devfile0 = uxn_port(u, 0xa, file_dei, file_deo); |
|
106 | 120 |
/* datetime */ uxn_port(u, 0xb, datetime_dei, nil_deo); |
107 | 121 |
/* empty */ uxn_port(u, 0xc, nil_dei, nil_deo); |
108 | 122 |
/* empty */ uxn_port(u, 0xd, nil_dei, nil_deo); |
... | ... |
@@ -42,7 +42,7 @@ static SDL_Rect gRect; |
42 | 42 |
|
43 | 43 |
/* devices */ |
44 | 44 |
|
45 |
-static Device *devscreen, *devmouse, *devctrl, *devaudio0; |
|
45 |
+static Device *devscreen, *devmouse, *devctrl, *devaudio0, *devfile0; |
|
46 | 46 |
static Uint8 zoom = 1; |
47 | 47 |
static Uint32 stdin_event, audio0_event; |
48 | 48 |
|
... | ... |
@@ -207,6 +207,18 @@ audio_deo(Device *d, Uint8 port) |
207 | 207 |
} |
208 | 208 |
} |
209 | 209 |
|
210 |
+static void |
|
211 |
+file_deo(Device *d, Uint8 port) |
|
212 |
+{ |
|
213 |
+ file_i_deo(d - devfile0, d, port); |
|
214 |
+} |
|
215 |
+ |
|
216 |
+static Uint8 |
|
217 |
+file_dei(Device *d, Uint8 port) |
|
218 |
+{ |
|
219 |
+ return file_i_dei(d - devfile0, d, port); |
|
220 |
+} |
|
221 |
+ |
|
210 | 222 |
static Uint8 |
211 | 223 |
nil_dei(Device *d, Uint8 port) |
212 | 224 |
{ |
... | ... |
@@ -253,7 +265,7 @@ start(Uxn *u, char *rom) |
253 | 265 |
/* unused */ uxn_port(u, 0x7, nil_dei, nil_deo); |
254 | 266 |
/* control */ devctrl = uxn_port(u, 0x8, nil_dei, nil_deo); |
255 | 267 |
/* mouse */ devmouse = uxn_port(u, 0x9, nil_dei, nil_deo); |
256 |
- /* file */ uxn_port(u, 0xa, nil_dei, file_deo); |
|
268 |
+ /* file */ devfile0 = uxn_port(u, 0xa, file_dei, file_deo); |
|
257 | 269 |
/* datetime */ uxn_port(u, 0xb, datetime_dei, nil_deo); |
258 | 270 |
/* unused */ uxn_port(u, 0xc, nil_dei, nil_deo); |
259 | 271 |
/* unused */ uxn_port(u, 0xd, nil_dei, nil_deo); |