14 * |
14 * |
15 * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license. |
15 * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license. |
16 * Please see LICENSE.txt in the root of the source tree. |
16 * Please see LICENSE.txt in the root of the source tree. |
17 * |
17 * |
18 * SDL 1.2 falls under the LGPL license. SDL 1.3+ is zlib, like PhysicsFS. |
18 * SDL 1.2 falls under the LGPL license. SDL 1.3+ is zlib, like PhysicsFS. |
19 * You can get SDL at http://www.libsdl.org/ |
19 * You can get SDL at https://www.libsdl.org/ |
20 * |
20 * |
21 * This file was written by Ryan C. Gordon. (icculus@icculus.org). |
21 * This file was written by Ryan C. Gordon. (icculus@icculus.org). |
22 */ |
22 */ |
23 |
23 |
24 #include <stdio.h> /* used for SEEK_SET, SEEK_CUR, SEEK_END ... */ |
24 #include <stdio.h> /* used for SEEK_SET, SEEK_CUR, SEEK_END ... */ |
25 #include "physfsrwops.h" |
25 #include "physfsrwops.h" |
26 |
26 |
27 /* SDL's RWOPS interface changed a little in SDL 1.3... */ |
27 /* SDL's RWOPS interface changed a little in SDL 2.0... */ |
28 #if defined(SDL_VERSION_ATLEAST) |
28 #if defined(SDL_VERSION_ATLEAST) |
29 #if SDL_VERSION_ATLEAST(1, 3, 0) |
29 #if SDL_VERSION_ATLEAST(2, 0, 0) |
30 #define TARGET_SDL13 1 |
30 #define TARGET_SDL2 1 |
31 #endif |
31 #endif |
32 #endif |
32 #endif |
33 |
33 |
34 #if TARGET_SDL13 |
34 #if !TARGET_SDL2 |
|
35 #ifndef RW_SEEK_SET |
|
36 #define RW_SEEK_SET SEEK_SET |
|
37 #endif |
|
38 #ifndef RW_SEEK_CUR |
|
39 #define RW_SEEK_CUR SEEK_CUR |
|
40 #endif |
|
41 #ifndef RW_SEEK_END |
|
42 #define RW_SEEK_END SEEK_END |
|
43 #endif |
|
44 #endif |
|
45 |
|
46 #if TARGET_SDL2 |
35 static Sint64 SDLCALL physfsrwops_size(struct SDL_RWops *rw) |
47 static Sint64 SDLCALL physfsrwops_size(struct SDL_RWops *rw) |
36 { |
48 { |
37 PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1; |
49 PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1; |
38 return PHYSFS_fileLength(handle); |
50 return (Sint64) PHYSFS_fileLength(handle); |
39 } |
51 } /* physfsrwops_size */ |
40 #endif |
52 #endif |
41 |
53 |
42 #if TARGET_SDL13 |
54 |
|
55 #if TARGET_SDL2 |
43 static Sint64 SDLCALL physfsrwops_seek(struct SDL_RWops *rw, Sint64 offset, int whence) |
56 static Sint64 SDLCALL physfsrwops_seek(struct SDL_RWops *rw, Sint64 offset, int whence) |
44 #else |
57 #else |
45 static int physfsrwops_seek(SDL_RWops *rw, int offset, int whence) |
58 static int physfsrwops_seek(SDL_RWops *rw, int offset, int whence) |
46 #endif |
59 #endif |
47 { |
60 { |
48 PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1; |
61 PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1; |
49 PHYSFS_sint64 pos = 0; |
62 PHYSFS_sint64 pos = 0; |
50 |
63 |
51 if (whence == SEEK_SET) |
64 if (whence == RW_SEEK_SET) |
52 pos = (PHYSFS_sint64) offset; |
65 pos = (PHYSFS_sint64) offset; |
53 else if (whence == SEEK_CUR) |
66 |
|
67 else if (whence == RW_SEEK_CUR) |
54 { |
68 { |
55 const PHYSFS_sint64 current = PHYSFS_tell(handle); |
69 const PHYSFS_sint64 current = PHYSFS_tell(handle); |
56 if (current == -1) |
70 if (current == -1) |
57 { |
71 { |
58 SDL_SetError("Can't find position in file: %s", |
72 SDL_SetError("Can't find position in file: %s", |
60 return -1; |
74 return -1; |
61 } /* if */ |
75 } /* if */ |
62 |
76 |
63 if (offset == 0) /* this is a "tell" call. We're done. */ |
77 if (offset == 0) /* this is a "tell" call. We're done. */ |
64 { |
78 { |
65 #if TARGET_SDL13 |
79 #if TARGET_SDL2 |
66 return (long) current; |
80 return (Sint64) current; |
67 #else |
81 #else |
68 return (int) current; |
82 return (int) current; |
69 #endif |
83 #endif |
70 } /* if */ |
84 } /* if */ |
71 |
85 |
72 pos = current + ((PHYSFS_sint64) offset); |
86 pos = current + ((PHYSFS_sint64) offset); |
73 } /* else if */ |
87 } /* else if */ |
74 |
88 |
75 else if (whence == SEEK_END) |
89 else if (whence == RW_SEEK_END) |
76 { |
90 { |
77 const PHYSFS_sint64 len = PHYSFS_fileLength(handle); |
91 const PHYSFS_sint64 len = PHYSFS_fileLength(handle); |
78 if (len == -1) |
92 if (len == -1) |
79 { |
93 { |
80 SDL_SetError("Can't find end of file: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); |
94 SDL_SetError("Can't find end of file: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); |
93 if ( pos < 0 ) |
107 if ( pos < 0 ) |
94 { |
108 { |
95 SDL_SetError("Attempt to seek past start of file."); |
109 SDL_SetError("Attempt to seek past start of file."); |
96 return -1; |
110 return -1; |
97 } /* if */ |
111 } /* if */ |
98 |
112 |
99 if (!PHYSFS_seek(handle, (PHYSFS_uint64) pos)) |
113 if (!PHYSFS_seek(handle, (PHYSFS_uint64) pos)) |
100 { |
114 { |
101 SDL_SetError("PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); |
115 SDL_SetError("PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); |
102 return -1; |
116 return -1; |
103 } /* if */ |
117 } /* if */ |
104 |
118 |
105 #if TARGET_SDL13 |
119 #if TARGET_SDL2 |
106 return (long) pos; |
120 return (Sint64) pos; |
107 #else |
121 #else |
108 return (int) pos; |
122 return (int) pos; |
109 #endif |
123 #endif |
110 } /* physfsrwops_seek */ |
124 } /* physfsrwops_seek */ |
111 |
125 |
112 |
126 |
113 #if TARGET_SDL13 |
127 #if TARGET_SDL2 |
114 static size_t SDLCALL physfsrwops_read(struct SDL_RWops *rw, void *ptr, |
128 static size_t SDLCALL physfsrwops_read(struct SDL_RWops *rw, void *ptr, |
115 size_t size, size_t maxnum) |
129 size_t size, size_t maxnum) |
116 #else |
130 #else |
117 static int physfsrwops_read(SDL_RWops *rw, void *ptr, int size, int maxnum) |
131 static int physfsrwops_read(SDL_RWops *rw, void *ptr, int size, int maxnum) |
118 #endif |
132 #endif |
121 const PHYSFS_uint64 readlen = (PHYSFS_uint64) (maxnum * size); |
135 const PHYSFS_uint64 readlen = (PHYSFS_uint64) (maxnum * size); |
122 const PHYSFS_sint64 rc = PHYSFS_readBytes(handle, ptr, readlen); |
136 const PHYSFS_sint64 rc = PHYSFS_readBytes(handle, ptr, readlen); |
123 if (rc != ((PHYSFS_sint64) readlen)) |
137 if (rc != ((PHYSFS_sint64) readlen)) |
124 { |
138 { |
125 if (!PHYSFS_eof(handle)) /* not EOF? Must be an error. */ |
139 if (!PHYSFS_eof(handle)) /* not EOF? Must be an error. */ |
|
140 { |
126 SDL_SetError("PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); |
141 SDL_SetError("PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); |
127 } /* if */ |
142 |
128 |
143 #if TARGET_SDL2 |
129 #if TARGET_SDL13 |
144 return 0; |
130 return (size_t) rc; |
145 #else |
|
146 return -1; |
|
147 #endif |
|
148 } /* if */ |
|
149 } /* if */ |
|
150 |
|
151 #if TARGET_SDL2 |
|
152 return (size_t) rc / size; |
131 #else |
153 #else |
132 return (int) rc; |
154 return (int) rc / size; |
133 #endif |
155 #endif |
134 } /* physfsrwops_read */ |
156 } /* physfsrwops_read */ |
135 |
157 |
136 |
158 |
137 #if TARGET_SDL13 |
159 #if TARGET_SDL2 |
138 static size_t SDLCALL physfsrwops_write(struct SDL_RWops *rw, const void *ptr, |
160 static size_t SDLCALL physfsrwops_write(struct SDL_RWops *rw, const void *ptr, |
139 size_t size, size_t num) |
161 size_t size, size_t num) |
140 #else |
162 #else |
141 static int physfsrwops_write(SDL_RWops *rw, const void *ptr, int size, int num) |
163 static int physfsrwops_write(SDL_RWops *rw, const void *ptr, int size, int num) |
142 #endif |
164 #endif |
145 const PHYSFS_uint64 writelen = (PHYSFS_uint64) (num * size); |
167 const PHYSFS_uint64 writelen = (PHYSFS_uint64) (num * size); |
146 const PHYSFS_sint64 rc = PHYSFS_writeBytes(handle, ptr, writelen); |
168 const PHYSFS_sint64 rc = PHYSFS_writeBytes(handle, ptr, writelen); |
147 if (rc != ((PHYSFS_sint64) writelen)) |
169 if (rc != ((PHYSFS_sint64) writelen)) |
148 SDL_SetError("PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); |
170 SDL_SetError("PhysicsFS error: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); |
149 |
171 |
150 #if TARGET_SDL13 |
172 #if TARGET_SDL2 |
151 return (size_t) rc; |
173 return (size_t) rc; |
152 #else |
174 #else |
153 return (int) rc; |
175 return (int) rc; |
154 #endif |
176 #endif |
155 } /* physfsrwops_write */ |
177 } /* physfsrwops_write */ |
178 else |
200 else |
179 { |
201 { |
180 retval = SDL_AllocRW(); |
202 retval = SDL_AllocRW(); |
181 if (retval != NULL) |
203 if (retval != NULL) |
182 { |
204 { |
183 #if TARGET_SDL13 && !defined(EMSCRIPTEN) |
205 #if TARGET_SDL2 |
184 retval->size = physfsrwops_size; |
206 retval->size = physfsrwops_size; |
185 #endif |
207 #endif |
186 retval->seek = physfsrwops_seek; |
208 retval->seek = physfsrwops_seek; |
187 retval->read = physfsrwops_read; |
209 retval->read = physfsrwops_read; |
188 retval->write = physfsrwops_write; |
210 retval->write = physfsrwops_write; |
189 retval->close = physfsrwops_close; |
211 retval->close = physfsrwops_close; |
190 retval->hidden.unknown.data1 = handle; |
212 retval->hidden.unknown.data1 = handle; |