· 8 years ago · Apr 09, 2018, 02:52 PM
1diff --git a/CMakeLists.txt b/CMakeLists.txt
2index 245be10..1843455 100644
3--- a/CMakeLists.txt
4+++ b/CMakeLists.txt
5@@ -65,7 +65,7 @@ if(WIN32)
6 endif()
7 endif(WIN32)
8
9-set(ALLEGRO_VERSION 4.4.2)
10+set(ALLEGRO_VERSION 4.4.3)
11 string(REGEX MATCH "^[0-9]+[.][0-9]+" ALLEGRO_SOVERSION ${ALLEGRO_VERSION})
12
13 # Mac OS X -compatibility_version.
14@@ -95,7 +95,7 @@ include(Common)
15 # Build options
16 #
17
18-option(SHARED "Build shared library for main Allegro library" on)
19+option(SHARED "Build shared library for main Allegro library and addons" on)
20 set(BUILD_SHARED_LIBS ${SHARED}) # actual CMake variable
21
22 # On some 64-bit platforms, libraries should be installed into `lib64'
23@@ -107,6 +107,7 @@ option(MAGIC_MAIN "Enable magic main (Unix)" off)
24 option(WANT_FRAMEWORKS "Want frameworks on Mac OS X" off)
25 option(WANT_EMBED
26 "Make frameworks embeddable in application bundles (Mac OS X)" on)
27+option(ENABLE_QUICKDRAW "Enable Quick Graphics on OS X" OFF)
28
29 set(FRAMEWORK_INSTALL_PREFIX "/Library/Frameworks" CACHE STRING
30 "Directory in which to install Mac OS X frameworks")
31@@ -451,6 +452,15 @@ if(ALLEGRO_UNIX) # not MACOSX
32 endif(ALSA_FOUND)
33 endif(WANT_ALSA)
34
35+ pkg_check_modules(SDL2 sdl2)
36+ if(SDL2_FOUND)
37+ set(ALLEGRO_WITH_SDL2DIGI 1)
38+ include_directories(SYSTEM ${SDL2_INCLUDE_DIRS})
39+ link_directories(${SDL2_LIBRARY_DIRS})
40+ list(APPEND PLATFORM_LIBS_NON_MODULES ${SDL2_LIBRARIES})
41+ add_our_module(alleg-sdl2digi src/unix/sdl2digi.c ${SDL2_LIBRARIES})
42+ endif(SDL2_FOUND)
43+
44 if(WANT_JACK)
45 pkg_check_modules(JACK jack)
46 if(JACK_FOUND)
47@@ -538,6 +548,7 @@ option(WANT_LINUX_CONSOLE "Want Linux console support (Linux)" off)
48 option(WANT_LINUX_VGA "Want Linux console VGA driver (Linux)" on)
49 option(WANT_LINUX_FBCON "Want Linux console fbcon driver (Linux)" on)
50 option(WANT_LINUX_SVGALIB "Want Linux console SVGAlib driver (Linux)" on)
51+option(WANT_LINUX_TSLIB "Want Linux console tslib mouse driver (Linux)" on)
52
53 if(WANT_LINUX_CONSOLE AND CMAKE_SYSTEM_NAME STREQUAL Linux)
54 set(ALLEGRO_LINUX 1)
55@@ -582,6 +593,16 @@ if(WANT_LINUX_CONSOLE AND CMAKE_SYSTEM_NAME STREQUAL Linux)
56 ${SVGALIB_LIBRARY})
57 endif()
58 endif()
59+
60+ if(WANT_LINUX_TSLIB)
61+ find_package(Tslib)
62+ if(TSLIB_FOUND)
63+ set(ALLEGRO_LINUX_TSLIB 1)
64+ include_directories(SYSTEM ${TSLIB_INCLUDE_DIR})
65+ set(CMAKE_REQUIRED_LIBRARIES ${TSLIB_LIBRARY})
66+ list(APPEND PLATFORM_LIBS ${TSLIB_LIBRARY})
67+ endif()
68+ endif()
69 endif(WANT_LINUX_CONSOLE AND CMAKE_SYSTEM_NAME STREQUAL Linux)
70
71 # -- Windows --
72@@ -637,29 +658,33 @@ endif(BEOS)
73
74 if(ALLEGRO_MACOSX)
75 list(APPEND PLATFORM_SOURCES ${ALLEGRO_SRC_MACOSX_FILES})
76+ IF(ENABLE_QUICKDRAW)
77+ SET_SOURCE_FILES_PROPERTIES(
78+ ${ALLEGRO_SRC_MACOSX_FILES}
79+ PROPERTIES
80+ COMPILE_FLAGS ENABLE_QUICKDRAW
81+ )
82+ ENDIF()
83 if(NOT SHARED)
84 list(APPEND PLATFORM_SOURCES src/macosx/main.m)
85 endif(NOT SHARED)
86
87 find_library(COCOA_LIBRARY Cocoa)
88- find_library(CARBON_LIBRARY Carbon)
89 find_library(IOKIT_LIBRARY IOKit)
90 find_library(COREAUDIO_LIBRARY CoreAudio)
91 find_library(AUDIOUNIT_LIBRARY AudioUnit)
92 find_library(AUDIOTOOLBOX_LIBRARY AudioToolbox)
93- find_package(QuickTime)
94- mark_as_advanced(COCOA_LIBRARY CARBON_LIBRARY IOKIT_LIBRARY)
95+ find_library(OPENGL_LIBRARY OpenGL)
96+ mark_as_advanced(COCOA_LIBRARY IOKIT_LIBRARY OPENGL_LIBRARY)
97 mark_as_advanced(COREAUDIO_LIBRARY AUDIOUNIT_LIBRARY AUDIOTOOLBOX_LIBRARY)
98- mark_as_advanced(QUICKTIME_INCLUDE_DIR QUICKTIME_LIBRARY)
99
100 list(APPEND PLATFORM_LIBS
101 ${COCOA_LIBRARY}
102- ${CARBON_LIBRARY}
103 ${IOKIT_LIBRARY}
104 ${COREAUDIO_LIBRARY}
105 ${AUDIOUNIT_LIBRARY}
106 ${AUDIOTOOLBOX_LIBRARY}
107- ${QUICKTIME_LIBRARY}
108+ ${OPENGL_LIBRARY}
109 )
110 endif(ALLEGRO_MACOSX)
111
112@@ -879,7 +904,7 @@ if(UNIX) # including MACOSX
113 if(BUILD_SHARED_LIBS)
114 set(FRAMEWORKS "-framework Cocoa -framework Allegro -lalleg-main${BUILD_TYPE_SUFFIX}")
115 else(BUILD_SHARED_LIBS)
116- set(FRAMEWORKS "-framework Cocoa -framework Allegro -lalleg-main${BUILD_TYPE_SUFFIX} -framework Carbon -framework IOKit -framework System -framework CoreAudio -framework AudioUnit -framework AudioToolbox -framework QuickTime")
117+ set(FRAMEWORKS "-framework Cocoa -framework Allegro -lalleg-main${BUILD_TYPE_SUFFIX} -framework IOKit -framework System -framework CoreAudio -framework AudioUnit -framework AudioToolbox")
118 endif(BUILD_SHARED_LIBS)
119 else()
120 set(ACCEPT_FRAMEWORKS no)
121@@ -907,12 +932,17 @@ option(WANT_LOADPNG "Enable loadpng" on)
122 option(WANT_LOGG "Enable logg" on)
123 option(WANT_JPGALLEG "Enable JPGAlleg" on)
124
125-if(WANT_FRAMEWORKS)
126+if (BUILD_SHARED_LIBS)
127 set(ADDON_LINKAGE SHARED)
128 else()
129 set(ADDON_LINKAGE STATIC)
130 endif()
131
132+if(WANT_FRAMEWORKS)
133+ set(ADDON_LINKAGE SHARED)
134+endif()
135+
136+
137 if(WANT_ALLEGROGL)
138 add_subdirectory(addons/allegrogl)
139 endif()
140diff --git a/addons/allegrogl/src/fontconv.c b/addons/allegrogl/src/fontconv.c
141index a660d30..ee363ff 100644
142--- a/addons/allegrogl/src/fontconv.c
143+++ b/addons/allegrogl/src/fontconv.c
144@@ -4,10 +4,10 @@
145 /** \file fontconv.c
146 * \brief Allegro FONT conversion routines.
147 *
148- * Notes: - Depends on the Allegro's FONT structure remaining
149+ * Notes: - Depends on the Allegro's FONT structure remaining
150 * intact.
151 * Bugs: - Bitmapped font support is flakey at best.
152- *
153+ *
154 */
155
156 #include <math.h>
157@@ -128,7 +128,7 @@ static int iroundf(float v) {
158 }
159 else {
160 /* distance to ceil smaller than distance to floor */
161- if ((c - v) < (v - f))
162+ if ((c - v) < (v - f))
163 return (int)f;
164 else
165 return (int)c;
166@@ -282,7 +282,7 @@ static int agl_get_font_range_end(FONT *f, int range) {
167 fad = next;
168 n++;
169 }
170-
171+
172 return -1;
173 }
174
175@@ -298,7 +298,7 @@ static int create_textured_font_call_lists(AGL_GLYPH *coords, int max, BITMAP *b
176 scale = fabs(scale);
177
178 list = glGenLists(max);
179-
180+
181 for (i = 0; i < max; i++) {
182 /* Coords of glyph in texture (texture coords) */
183 float tx = (float)coords[i].x / bmp->w;
184@@ -329,7 +329,7 @@ static int create_textured_font_call_lists(AGL_GLYPH *coords, int max, BITMAP *b
185 }
186
187 glNewList(list + i, GL_COMPILE);
188-
189+
190 glBegin(GL_QUADS);
191 glTexCoord2f(tx, ty);
192 glVertex2f(xoffs, -yoffs);
193@@ -370,14 +370,14 @@ static FONT_AGL_DATA* copy_glyph_range(FONT_AGL_DATA *fad, int start, int end,
194 count = end - start;
195
196 coords = malloc(count * sizeof (AGL_GLYPH));
197-
198+
199 /* for now, just copy glyph coords of the range */
200 for (i = 0; i < count; i++) {
201 coords[i] = fad->glyph_coords[start - fad->start + i];
202 coords[i].glyph_num = i;
203 }
204-
205- /* calculate the width of the glyphs and find the max height */
206+
207+ /* calculate the width of the glyphs and find the max height */
208 for (i = 0; i < count; i++) {
209 int hh = coords[i].h + coords[i].offset_y + coords[i].offset_h;
210 if (h < hh)
211@@ -510,7 +510,7 @@ static FONT *agl_extract_font_range(FONT *f, int start, int end) {
212 retval->data = newfad;
213 }
214 }
215-
216+
217 next = next->next;
218 }
219
220@@ -651,9 +651,9 @@ FONT *allegro_gl_convert_allegro_font(FONT *f, int type, float scale) {
221 *
222 * You should destroy the font via allegro_gl_destroy_font() when you are
223 * done with it.
224- *
225+ *
226 * <b>Scaling</b>
227- *
228+ *
229 * For #AGL_FONT_TYPE_TEXTURED fonts, glyphs in the font need to be mapped
230 * to OpenGL coordinates. The scale factor ensures that you get the scaling
231 * you need. scale reprents the number of pixels to be mapped to 1.0 OpenGL
232@@ -675,7 +675,7 @@ FONT *allegro_gl_convert_allegro_font(FONT *f, int type, float scale) {
233 * it's ignored if the conversion will lead to a font of that type.
234 *
235 * <b>Format</b>
236- *
237+ *
238 * The format specifies what internal format OpenGL should use for the texture,
239 * in the case of #AGL_FONT_TYPE_TEXTURED fonts. It has the same semantics as
240 * the internalformat parameter of glTexImage2D(). If you would like for
241@@ -698,7 +698,7 @@ FONT *allegro_gl_convert_allegro_font_ex(FONT *f, int type, float scale,
242 FONT_COLOR_DATA* cf;
243 void *ptr;
244 } dat;
245-
246+
247 if (!__allegro_gl_valid_context) {
248 return NULL;
249 }
250@@ -750,13 +750,13 @@ FONT *allegro_gl_convert_allegro_font_ex(FONT *f, int type, float scale,
251 return NULL;
252 }
253 memset(destdata, 0, sizeof(FONT_AGL_DATA) * max);
254-
255+
256 /* Construct the linked list */
257 for (i = 0; i < max - 1; i++) {
258 destdata[i].next = &destdata[i + 1];
259 }
260 destdata[max - 1].next = NULL;
261-
262+
263 /* Set up the font */
264 dest->data = destdata;
265 dest->vtable = font_vtable_agl;
266@@ -786,13 +786,13 @@ FONT *allegro_gl_convert_allegro_font_ex(FONT *f, int type, float scale,
267 aglf_convert_allegro_font_to_texture(&destdata, f, dat.ptr, &height,
268 scale, format);
269 }
270-
271+
272 if (height > dest->height) {
273 dest->height = height;
274 }
275-
276+
277 dat.ptr = (is_mono_font(f) ? (void*)dat.mf->next : (void*)dat.cf->next);
278-
279+
280 destdata = destdata->next;
281 }
282
283@@ -807,7 +807,7 @@ FONT *allegro_gl_convert_allegro_font_ex(FONT *f, int type, float scale,
284 static int sort_glyphs(const void *c1, const void *c2) {
285 AGL_GLYPH *g1 = (AGL_GLYPH*)c1;
286 AGL_GLYPH *g2 = (AGL_GLYPH*)c2;
287-
288+
289 if (g1->w < g2->w) {
290 return 1;
291 }
292@@ -826,7 +826,7 @@ static int sort_glyphs(const void *c1, const void *c2) {
293 static int unsort_glyphs(const void *c1, const void *c2) {
294 AGL_GLYPH *g1 = (AGL_GLYPH*)c1;
295 AGL_GLYPH *g2 = (AGL_GLYPH*)c2;
296-
297+
298 return g1->glyph_num - g2->glyph_num;
299 }
300
301@@ -837,7 +837,7 @@ static int unsort_glyphs(const void *c1, const void *c2) {
302 static int sort_textures(const void *c1, const void *c2) {
303 texture_size *t1 = (texture_size*)c1;
304 texture_size *t2 = (texture_size*)c2;
305-
306+
307 return t1->w * t1->h - t2->w * t2->h;
308 }
309
310@@ -875,13 +875,13 @@ static int aglf_sort_out_glyphs(BITMAP *bmp, AGL_GLYPH *glyphs, const int beg,
311 /* We now try to make all the glyphs fit on the bitmap */
312 for (i = 0; i < end - beg; i++) {
313 int collide = FALSE;
314-
315+
316 /* Place glyphs on last_line */
317 glyphs[i].x = last_x;
318 glyphs[i].y = last_line;
319-
320+
321 /* Check for collision */
322-
323+
324 for (j = 0; j < i; j++) {
325 if ((glyphs[i].x >= glyphs[j].x + glyphs[j].w)
326 || (glyphs[i].y >= glyphs[j].y + glyphs[j].h)
327@@ -893,7 +893,7 @@ static int aglf_sort_out_glyphs(BITMAP *bmp, AGL_GLYPH *glyphs, const int beg,
328 glyphs[i].x = last_x;
329 j = 0;
330 }
331-
332+
333 if ((last_x + glyphs[i].w > bmp->w)
334 || (last_line + glyphs[i].h > bmp->h)) {
335 collide = TRUE;
336@@ -946,11 +946,11 @@ static int split_font(FONT *f, void *source, void **dest1, void **dest2) {
337 union mixed_ptr range1, range2, src;
338 int colored;
339 int i;
340-
341+
342 (*dest1) = NULL;
343 (*dest2) = NULL;
344 src.ptr = source;
345-
346+
347 colored = (is_mono_font(f) ? FALSE : TRUE);
348
349 /* Allocate the ranges that we need */
350@@ -963,7 +963,7 @@ static int split_font(FONT *f, void *source, void **dest1, void **dest2) {
351 : (int)sizeof(FONT_MONO_DATA));
352 return FALSE;
353 }
354-
355+
356 range2.ptr = malloc(colored ? sizeof(FONT_COLOR_DATA)
357 : sizeof(FONT_MONO_DATA));
358 if (!range2.ptr) {
359@@ -974,23 +974,23 @@ static int split_font(FONT *f, void *source, void **dest1, void **dest2) {
360 free(range1.ptr);
361 return FALSE;
362 }
363-
364+
365 (*dest1) = range1.ptr;
366 (*dest2) = range2.ptr;
367-
368+
369 /* Now we split up the range */
370 if (colored) {
371 /* Half the range */
372 int mid = src.cf->begin + (src.cf->end - src.cf->begin) / 2;
373-
374+
375 range1.cf->begin = src.cf->begin;
376 range1.cf->end = mid;
377 range2.cf->begin = mid;
378 range2.cf->end = src.cf->end;
379-
380+
381 range1.cf->next = NULL;
382 range2.cf->next = NULL;
383-
384+
385 /* Split up the bitmaps */
386 range1.cf->bitmaps = malloc(sizeof(BITMAP*)
387 * (range1.cf->end - range1.cf->begin));
388@@ -1015,7 +1015,7 @@ static int split_font(FONT *f, void *source, void **dest1, void **dest2) {
389 return FALSE;
390 }
391
392-
393+
394 for (i = 0; i < (range1.cf->end - range1.cf->begin); i++) {
395 range1.cf->bitmaps[i] = src.cf->bitmaps[i];
396 }
397@@ -1027,15 +1027,15 @@ static int split_font(FONT *f, void *source, void **dest1, void **dest2) {
398 else {
399 /* Half the range */
400 int mid = src.mf->begin + (src.mf->end - src.mf->begin) / 2;
401-
402+
403 range1.mf->begin = src.mf->begin;
404 range1.mf->end = mid;
405 range2.mf->begin = mid;
406 range2.mf->end = src.mf->end;
407-
408+
409 range1.mf->next = NULL;
410 range2.mf->next = NULL;
411-
412+
413 /* Split up the bitmaps */
414 range1.mf->glyphs = malloc(sizeof(FONT_GLYPH*)
415 * (range1.mf->end - range1.mf->begin));
416@@ -1059,7 +1059,7 @@ static int split_font(FONT *f, void *source, void **dest1, void **dest2) {
417 free(range2.ptr);
418 return FALSE;
419 }
420-
421+
422 for (i = 0; i < (range1.mf->end - range1.mf->begin); i++) {
423 range1.mf->glyphs[i] = src.mf->glyphs[i];
424 }
425@@ -1068,7 +1068,7 @@ static int split_font(FONT *f, void *source, void **dest1, void **dest2) {
426 src.mf->glyphs[i + range2.mf->begin - range1.mf->begin];
427 }
428 }
429-
430+
431 return TRUE;
432 }
433
434@@ -1077,7 +1077,7 @@ static int split_font(FONT *f, void *source, void **dest1, void **dest2) {
435 /* Destroys a split font */
436 static void destroy_split_font(FONT *f, union mixed_ptr range1,
437 union mixed_ptr range2) {
438-
439+
440 if (!is_mono_font(f)) {
441 free(range1.cf->bitmaps);
442 free(range2.cf->bitmaps);
443@@ -1086,10 +1086,10 @@ static void destroy_split_font(FONT *f, union mixed_ptr range1,
444 free(range1.mf->glyphs);
445 free(range2.mf->glyphs);
446 }
447-
448+
449 free(range1.ptr);
450 free(range2.ptr);
451-
452+
453 return;
454 }
455
456@@ -1109,7 +1109,7 @@ static int do_crop_font_range(FONT *f, AGL_GLYPH *glyphs, int beg, int end) {
457 "bitmap of size: %ix%i!\n", 32, 32);
458 goto error;
459 }
460-
461+
462 /* Crop glyphs */
463 for (i = 0; i < max; i++) {
464 int used = 0;
465@@ -1124,7 +1124,7 @@ static int do_crop_font_range(FONT *f, AGL_GLYPH *glyphs, int beg, int end) {
466 goto error;
467 }
468 }
469- clear(temp);
470+ clear_bitmap(temp);
471
472 usetc(buf + usetc(buf, glyphs[i].glyph_num + beg), 0);
473
474@@ -1157,7 +1157,7 @@ static int do_crop_font_range(FONT *f, AGL_GLYPH *glyphs, int beg, int end) {
475 glyphs[i].w = 1;
476 continue;
477 }
478-
479+
480 /* Crop bottom */
481 j = glyphs[i].h + glyphs[i].offset_y - 1;
482 for ( /* above */; j >= glyphs[i].offset_y; j--) {
483@@ -1218,7 +1218,7 @@ static int do_crop_font_range(FONT *f, AGL_GLYPH *glyphs, int beg, int end) {
484 glyphs[i].offset_w, glyphs[i].offset_h);
485 #endif
486 }
487-
488+
489 destroy_bitmap(temp);
490
491 return TRUE;
492@@ -1228,7 +1228,7 @@ error:
493 destroy_bitmap(temp);
494 }
495
496- return FALSE;
497+ return FALSE;
498 }
499
500
501@@ -1272,7 +1272,7 @@ static int crop_font_range(FONT *f, void *src, int beg, int end,
502 /* Not placed yet */
503 glyphs[i].x = -1;
504 }
505-
506+
507 if (crop) {
508 ret = do_crop_font_range(f, glyphs, beg, end);
509 }
510@@ -1333,7 +1333,7 @@ static BITMAP* look_for_texture(int beg, int end, AGL_GLYPH *glyphs,
511
512 for (i = 0; i < NUM_TEXTURE_SIZE * NUM_TEXTURE_SIZE; i++) {
513 int num_channels;
514-
515+
516 /* Check the area - it must be larger than
517 * all the glyphs
518 */
519@@ -1344,7 +1344,7 @@ static BITMAP* look_for_texture(int beg, int end, AGL_GLYPH *glyphs,
520 if (area < total_area) {
521 continue;
522 }
523-
524+
525 /* Check against max values */
526 if ((t->h < max_h) || (t->w < max_w)) {
527 continue;
528@@ -1392,7 +1392,7 @@ static BITMAP* look_for_texture(int beg, int end, AGL_GLYPH *glyphs,
529 destroy_bitmap(bmp);
530 bmp = NULL;
531 }
532-
533+
534 return NULL;
535 }
536
537@@ -1452,7 +1452,7 @@ static int draw_glyphs(BITMAP *bmp, FONT *f, GLint format, int beg, int end,
538 #endif
539 /* Generate an alpha font */
540 BITMAP *rgbbmp = create_bitmap_ex(24, bmp->w, bmp->h);
541-
542+
543 if (!rgbbmp) {
544 TRACE(PREFIX_E "convert_allegro_font_to_texture: "
545 "Ran out of memory while creating %ix%ix%i bitmap!\n",
546@@ -1461,10 +1461,10 @@ static int draw_glyphs(BITMAP *bmp, FONT *f, GLint format, int beg, int end,
547 }
548
549 clear_bitmap(rgbbmp);
550-
551+
552 for (i = 0; i < end - beg; i++) {
553 usetc(buf + usetc(buf, glyphs[i].glyph_num + beg), 0);
554-
555+
556 textout_ex(rgbbmp, f, buf, glyphs[i].x - glyphs[i].offset_x,
557 glyphs[i].y - glyphs[i].offset_y, -1, -1);
558 }
559@@ -1533,7 +1533,7 @@ static void aglf_convert_allegro_font_to_texture(FONT_AGL_DATA **dest, FONT *f,
560 int beg = 0, end = 0;
561 int max_w, max_h;
562 int total_area, gross_area;
563-
564+
565 AGL_GLYPH *glyph_coords;
566
567 union mixed_ptr dat;
568@@ -1609,7 +1609,7 @@ static void aglf_convert_allegro_font_to_texture(FONT_AGL_DATA **dest, FONT *f,
569 dest2->is_free_chunk = TRUE;
570 dest2->format = dest1->format;
571 dest2->has_alpha = dest1->has_alpha;
572-
573+
574 if (split_font(f, dat.ptr, &f1.ptr, &f2.ptr) == FALSE) {
575 TRACE(PREFIX_E "convert_allegro_font_to_texture: Unable "
576 "to split font!\n");
577@@ -1617,7 +1617,7 @@ static void aglf_convert_allegro_font_to_texture(FONT_AGL_DATA **dest, FONT *f,
578 free(dest2);
579 return;
580 }
581-
582+
583 aglf_convert_allegro_font_to_texture(&dest1, f, f1.ptr, height, scale,
584 format);
585 height1 = (*height);
586@@ -1628,7 +1628,7 @@ static void aglf_convert_allegro_font_to_texture(FONT_AGL_DATA **dest, FONT *f,
587 if (height1 > (*height))
588 (*height) = height1;
589 (*dest) = dest2;
590-
591+
592 return;
593 }
594
595@@ -1699,26 +1699,26 @@ static void aglf_convert_allegro_font_to_bitmap(FONT_AGL_DATA *dest, FONT *f,
596 "memory while allocating %i bytes\n", (int)sizeof(FONT_GLYPH));
597 return;
598 }
599-
600+
601 *height = f->height;
602-
603- if (is_mono_font(f)) {
604-
605+
606+ if (is_mono_font(f)) {
607+
608 /* for each glyph */
609- for (i = 0; i < max; i++) {
610+ for (i = 0; i < max; i++) {
611 FONT_GLYPH *oldgl = dat.mf->glyphs[i];
612-
613+
614 int size = sizeof(FONT_GLYPH) + ((oldgl->w + 31) / 32) * 4
615 * oldgl->h;
616-
617+
618 /* create new glyph */
619 FONT_GLYPH *newgl = (FONT_GLYPH*)malloc(size);
620-
621+
622 if (!newgl)
623 break;
624-
625+
626 memset(newgl, 0, size);
627-
628+
629 newgl->w = oldgl->w;
630 newgl->h = oldgl->h;
631
632@@ -1785,7 +1785,7 @@ static void aglf_convert_allegro_font_to_bitmap(FONT_AGL_DATA *dest, FONT *f,
633 }
634 dest->list_base = list;
635 }
636-
637+
638 dest->is_free_chunk = 0;
639 dest->type = AGL_FONT_TYPE_BITMAP;
640 dest->start = beg;
641diff --git a/addons/jpgalleg/include/jpgalleg.h b/addons/jpgalleg/include/jpgalleg.h
642index a532823..64894f4 100644
643--- a/addons/jpgalleg/include/jpgalleg.h
644+++ b/addons/jpgalleg/include/jpgalleg.h
645@@ -22,6 +22,26 @@
646
647 #include <allegro.h>
648
649+
650+#if (defined JPGALLEG_DYNAMIC) && (defined ALLEGRO_WINDOWS)
651+ #ifdef JPGALLEG_SRC_BUILD
652+ #define _AJPG_DLL __declspec(dllexport)
653+ #else
654+ #define _AJPG_DLL __declspec(dllimport)
655+ #endif /* ALLEGRO_GL_SRC_BUILD */
656+#else
657+ #define _AJPG_DLL
658+#endif /* (defined JPGALLEG_DYNAMIC) && (defined ALLEGRO_WINDOWS) */
659+
660+#define AJPG_VAR(type, name) extern _AJPG_DLL type name
661+
662+#if (defined JPGALLEG_DYNAMIC) && (defined ALLEGRO_WINDOWS)
663+ #define AJPG_FUNC(type, name, args) extern _AJPG_DLL type __cdecl name args
664+#else
665+ #define AJPG_FUNC(type, name, args) extern type name args
666+#endif /* (defined JPGALLEG_DYNAMIC) && (defined ALLEGRO_WINDOWS) */
667+
668+
669 /* Library version constant and string */
670 #define JPGALLEG_VERSION 0x0206
671 #define JPGALLEG_VERSION_STRING "JPGalleg 2.6, by Angelo Mottola, 2000-2006"
672@@ -63,20 +83,20 @@ extern "C" {
673 #endif
674
675
676-extern int jpgalleg_init(void);
677+AJPG_FUNC(int, jpgalleg_init, (void));
678
679-extern BITMAP *load_jpg(AL_CONST char *filename, RGB *palette);
680-extern BITMAP *load_jpg_ex(AL_CONST char *filename, RGB *palette, void (*callback)(int progress));
681-extern BITMAP *load_memory_jpg(void *buffer, int size, RGB *palette);
682-extern BITMAP *load_memory_jpg_ex(void *buffer, int size, RGB *palette, void (*callback)(int progress));
683+AJPG_FUNC(BITMAP *, load_jpg, (AL_CONST char *filename, RGB *palette));
684+AJPG_FUNC(BITMAP *, load_jpg_ex, (AL_CONST char *filename, RGB *palette, void (*callback)(int progress)));
685+AJPG_FUNC(BITMAP *, load_memory_jpg, (void *buffer, int size, RGB *palette));
686+AJPG_FUNC(BITMAP *, load_memory_jpg_ex, (void *buffer, int size, RGB *palette, void (*callback)(int progress)));
687
688-extern int save_jpg(AL_CONST char *filename, BITMAP *image, AL_CONST RGB *palette);
689-extern int save_jpg_ex(AL_CONST char *filename, BITMAP *image, AL_CONST RGB *palette, int quality, int flags, void (*callback)(int progress));
690-extern int save_memory_jpg(void *buffer, int *size, BITMAP *image, AL_CONST RGB *palette);
691-extern int save_memory_jpg_ex(void *buffer, int *size, BITMAP *image, AL_CONST RGB *palette, int quality, int flags, void (*callback)(int progress));
692+AJPG_FUNC(int, save_jpg, (AL_CONST char *filename, BITMAP *image, AL_CONST RGB *palette));
693+AJPG_FUNC(int, save_jpg_ex, (AL_CONST char *filename, BITMAP *image, AL_CONST RGB *palette, int quality, int flags, void (*callback)(int progress)));
694+AJPG_FUNC(int, save_memory_jpg, (void *buffer, int *size, BITMAP *image, AL_CONST RGB *palette));
695+AJPG_FUNC(int, save_memory_jpg_ex, (void *buffer, int *size, BITMAP *image, AL_CONST RGB *palette, int quality, int flags, void (*callback)(int progress)));
696
697-extern int jpgalleg_error;
698-extern const char *jpgalleg_error_string(void);
699+AJPG_VAR(int, jpgalleg_error);
700+AJPG_FUNC(const char *, jpgalleg_error_string, (void));
701
702
703 #ifdef __cplusplus
704diff --git a/addons/loadpng/CHANGES.txt b/addons/loadpng/CHANGES.txt
705index 351bb6b..3759d60 100644
706--- a/addons/loadpng/CHANGES.txt
707+++ b/addons/loadpng/CHANGES.txt
708@@ -163,3 +163,6 @@
709 I haven't tested it.
710
711 Released: version 1.5.
712+
713+From December 2007, loadpng lives in the Allegro repository.
714+This file is no longer updated.
715diff --git a/addons/loadpng/LICENSE.txt b/addons/loadpng/LICENSE.txt
716new file mode 100644
717index 0000000..af62ca5
718--- /dev/null
719+++ b/addons/loadpng/LICENSE.txt
720@@ -0,0 +1,21 @@
721+Copyright (C) 1999-2012 Peter Wang
722+
723+This software is provided 'as-is', without any express or implied
724+warranty. In no event will the authors be held liable for any damages
725+arising from the use of this software.
726+
727+Permission is granted to anyone to use this software for any purpose,
728+including commercial applications, and to alter it and redistribute it
729+freely, subject to the following restrictions:
730+
731+ 1. The origin of this software must not be misrepresented; you must not
732+ claim that you wrote the original software. If you use this software
733+ in a product, an acknowledgment in the product documentation would be
734+ appreciated but is not required.
735+
736+ 2. Altered source versions must be plainly marked as such, and must not be
737+ misrepresented as being the original software.
738+
739+ 3. This notice may not be removed or altered from any source
740+ distribution.
741+
742diff --git a/addons/loadpng/README.txt b/addons/loadpng/README.txt
743index c545f61..fb9b2d0 100644
744--- a/addons/loadpng/README.txt
745+++ b/addons/loadpng/README.txt
746@@ -4,8 +4,8 @@
747
748 This wrapper is mostly a copy and paste job from example.c in the
749 libpng docs, stripping out the useless transformations and making it
750-use Allegro BITMAP and PALETTE structures. It is placed in the public
751-domain.
752+use Allegro BITMAP and PALETTE structures. It is released under the
753+terms of the zlib license. See LICENSE.txt for more information.
754
755
756 Requirements:
757diff --git a/addons/loadpng/loadpng.c b/addons/loadpng/loadpng.c
758index 95fe4b9..f45f6ac 100644
759--- a/addons/loadpng/loadpng.c
760+++ b/addons/loadpng/loadpng.c
761@@ -1,7 +1,5 @@
762 /* loadpng, Allegro wrapper routines for libpng
763 * by Peter Wang (tjaden@users.sf.net).
764- *
765- * This file is hereby placed in the public domain.
766 */
767
768
769diff --git a/addons/loadpng/loadpng.h b/addons/loadpng/loadpng.h
770index 9d584de..35111d6 100644
771--- a/addons/loadpng/loadpng.h
772+++ b/addons/loadpng/loadpng.h
773@@ -1,5 +1,4 @@
774 /* loadpng.h */
775-/* This file is hereby placed in the public domain. */
776 #ifndef _included_loadpng_h_
777 #define _included_loadpng_h_
778
779@@ -8,6 +7,25 @@ extern "C" {
780 #endif
781
782
783+#if (defined LOADPNG_DYNAMIC) && (defined ALLEGRO_WINDOWS)
784+ #ifdef LOADPNG_SRC_BUILD
785+ #define _APNG_DLL __declspec(dllexport)
786+ #else
787+ #define _APNG_DLL __declspec(dllimport)
788+ #endif /* ALLEGRO_GL_SRC_BUILD */
789+#else
790+ #define _APNG_DLL
791+#endif /* (defined LOADPNG_DYNAMIC) && (defined ALLEGRO_WINDOWS) */
792+
793+#define APNG_VAR(type, name) extern _APNG_DLL type name
794+
795+#if (defined LOADPNG_DYNAMIC) && (defined ALLEGRO_WINDOWS)
796+ #define APNG_FUNC(type, name, args) extern _APNG_DLL type __cdecl name args
797+#else
798+ #define APNG_FUNC(type, name, args) extern type name args
799+#endif /* (defined LOADPNG_DYNAMIC) && (defined ALLEGRO_WINDOWS) */
800+
801+
802
803 /* Overkill :-) */
804 #define LOADPNG_VERSION 1
805@@ -27,37 +45,37 @@ extern "C" {
806 *
807 * Otherwise, the value of _png_screen_gamma is taken as-is.
808 */
809-extern double _png_screen_gamma;
810+APNG_VAR(double, _png_screen_gamma);
811
812
813 /* Choose zlib compression level for saving file.
814 * Default is Z_BEST_COMPRESSION.
815 */
816-extern int _png_compression_level;
817+APNG_VAR(int, _png_compression_level);
818
819
820 /* Load a PNG from disk. */
821-extern BITMAP *load_png(AL_CONST char *filename, RGB *pal);
822+APNG_FUNC(BITMAP *, load_png, (AL_CONST char *filename, RGB *pal));
823
824 /* Load a PNG from some place. */
825-extern BITMAP *load_png_pf(PACKFILE *fp, RGB *pal);
826+APNG_FUNC(BITMAP *, load_png_pf, (PACKFILE *fp, RGB *pal));
827
828 /* Load a PNG from memory. */
829-extern BITMAP *load_memory_png(AL_CONST void *buffer, int buffer_size, RGB *pal);
830+APNG_FUNC(BITMAP *, load_memory_png, (AL_CONST void *buffer, int buffer_size, RGB *pal));
831
832 /* Save a bitmap to disk in PNG format. */
833-extern int save_png(AL_CONST char *filename, BITMAP *bmp, AL_CONST RGB *pal);
834+APNG_FUNC(int, save_png, (AL_CONST char *filename, BITMAP *bmp, AL_CONST RGB *pal));
835
836 /* Adds `PNG' to Allegro's internal file type table.
837 * You can then just use load_bitmap and save_bitmap as usual.
838 */
839-extern void register_png_file_type(void);
840+APNG_FUNC(void, register_png_file_type, (void));
841
842 /* Register an datafile type ID with Allegro, so that when an object
843 * with that type ID is encountered while loading a datafile, that
844 * object will be loaded as a PNG file.
845 */
846-extern void register_png_datafile_object(int id);
847+APNG_FUNC(void, register_png_datafile_object, (int id));
848
849 /* This is supposed to resemble jpgalleg_init in JPGalleg 2.0, just in
850 * case you are lazier than lazy. It contains these 3 lines of code:
851@@ -65,7 +83,7 @@ extern void register_png_datafile_object(int id);
852 * register_png_file_type();
853 * return 0;
854 */
855-extern int loadpng_init(void);
856+APNG_FUNC(int, loadpng_init, (void));
857
858
859 #ifdef __cplusplus
860diff --git a/addons/loadpng/regpng.c b/addons/loadpng/regpng.c
861index 1681e4b..1d570ea 100644
862--- a/addons/loadpng/regpng.c
863+++ b/addons/loadpng/regpng.c
864@@ -1,7 +1,5 @@
865 /* loadpng, Allegro wrapper routines for libpng
866 * by Peter Wang (tjaden@users.sf.net).
867- *
868- * This file is hereby placed in the public domain.
869 */
870
871
872diff --git a/addons/loadpng/savepng.c b/addons/loadpng/savepng.c
873index e2d04f9..5274944 100644
874--- a/addons/loadpng/savepng.c
875+++ b/addons/loadpng/savepng.c
876@@ -1,7 +1,5 @@
877 /* loadpng, Allegro wrapper routines for libpng
878 * by Peter Wang (tjaden@users.sf.net).
879- *
880- * This file is hereby placed in the public domain.
881 */
882
883
884diff --git a/addons/logg/logg.c b/addons/logg/logg.c
885index 01ee0e8..bfd7284 100644
886--- a/addons/logg/logg.c
887+++ b/addons/logg/logg.c
888@@ -2,7 +2,7 @@
889 #include "allegro.h"
890 #include "allegro/internal/aintern.h"
891
892-#include "logg.h"
893+#include "loggint.h"
894
895 /* XXX requires testing */
896 #ifdef ALLEGRO_BIG_ENDIAN
897@@ -117,7 +117,7 @@ static int read_ogg_data(LOGG_Stream* s)
898 s->current_page %= OGG_PAGES_TO_BUFFER;
899
900 memset(s->buf[page], 0, logg_bufsize);
901-
902+
903 while (read < logg_bufsize) {
904 int thisRead = ov_read(&s->ovf, s->buf[page]+read,
905 logg_bufsize-read,
906diff --git a/addons/logg/logg.h b/addons/logg/logg.h
907index 454d1c8..761c5a7 100644
908--- a/addons/logg/logg.h
909+++ b/addons/logg/logg.h
910@@ -1,40 +1,46 @@
911 #ifndef LOGG_H
912 #define LOGG_H
913
914+#include <allegro.h>
915+
916 #ifdef __cplusplus
917 extern "C" {
918 #endif
919
920-#include <allegro.h>
921-#include <vorbis/vorbisfile.h>
922-
923-#define OGG_PAGES_TO_BUFFER 2
924-
925-typedef struct {
926- char *buf[OGG_PAGES_TO_BUFFER];
927- int current_page;
928- int playing_page;
929- AUDIOSTREAM* audio_stream;
930- OggVorbis_File ovf;
931- int bits;
932- int stereo;
933- int freq;
934- int len;
935- char* filename;
936- int loop;
937- int volume;
938- int pan;
939-} LOGG_Stream;
940-
941-extern SAMPLE* logg_load(const char* filename);
942-extern int logg_get_buffer_size();
943-extern void logg_set_buffer_size(int size);
944-extern LOGG_Stream* logg_get_stream(const char* filename,
945- int volume, int pan, int loop);
946-extern int logg_update_stream(LOGG_Stream* s);
947-extern void logg_destroy_stream(LOGG_Stream* s);
948-extern void logg_stop_stream(LOGG_Stream* s);
949-extern int logg_restart_stream(LOGG_Stream* s);
950+#if (defined LOGG_DYNAMIC) && (defined ALLEGRO_WINDOWS)
951+ #ifdef LOGG_SRC_BUILD
952+ #define _AOGG_DLL __declspec(dllexport)
953+ #else
954+ #define _AOGG_DLL __declspec(dllimport)
955+ #endif /* ALLEGRO_GL_SRC_BUILD */
956+#else
957+ #define _AOGG_DLL
958+#endif /* (defined LOGG_DYNAMIC) && (defined ALLEGRO_WINDOWS) */
959+
960+#define AOGG_VAR(type, name) extern _AOGG_DLL type name
961+
962+#if (defined LOGG_DYNAMIC) && (defined ALLEGRO_WINDOWS)
963+ #define AOGG_FUNC(type, name, args) extern _AOGG_DLL type __cdecl name args
964+#else
965+ #define AOGG_FUNC(type, name, args) extern type name args
966+#endif /* (defined LOGG_DYNAMIC) && (defined ALLEGRO_WINDOWS) */
967+
968+
969+#define LOGG_VERSION 1
970+#define LOGG_SUBVERSION 0
971+#define LOGG_VERSIONSTR "1.0"
972+
973+typedef struct LOGG_Stream LOGG_Stream;
974+
975+AOGG_FUNC(SAMPLE*, logg_load,(const char* filename));
976+AOGG_FUNC(int, logg_get_buffer_size,(void));
977+AOGG_FUNC(void, logg_set_buffer_size,(int size));
978+AOGG_FUNC(LOGG_Stream*, logg_get_stream,(const char* filename,
979+ int volume, int pan, int loop));
980+AOGG_FUNC(int, logg_update_stream,(LOGG_Stream* s));
981+AOGG_FUNC(void, logg_destroy_stream,(LOGG_Stream* s));
982+AOGG_FUNC(void, logg_stop_stream,(LOGG_Stream* s));
983+AOGG_FUNC(int, logg_restart_stream,(LOGG_Stream* s));
984
985 #ifdef __cplusplus
986 }
987diff --git a/addons/logg/loggint.h b/addons/logg/loggint.h
988new file mode 100644
989index 0000000..3708f38
990--- /dev/null
991+++ b/addons/logg/loggint.h
992@@ -0,0 +1,36 @@
993+#ifndef LOGGINT_H
994+#define LOGGINT_H
995+
996+#ifdef __cplusplus
997+extern "C" {
998+#endif
999+
1000+#include <allegro.h>
1001+#include <vorbis/vorbisfile.h>
1002+
1003+#define OGG_PAGES_TO_BUFFER 2
1004+
1005+struct LOGG_Stream {
1006+ char *buf[OGG_PAGES_TO_BUFFER];
1007+ int current_page;
1008+ int playing_page;
1009+ AUDIOSTREAM* audio_stream;
1010+ OggVorbis_File ovf;
1011+ int bits;
1012+ int stereo;
1013+ int freq;
1014+ int len;
1015+ char* filename;
1016+ int loop;
1017+ int volume;
1018+ int pan;
1019+};
1020+
1021+#include "logg.h"
1022+
1023+#ifdef __cplusplus
1024+}
1025+#endif
1026+
1027+#endif
1028+
1029diff --git a/addons/logg/play_ogg.c b/addons/logg/play_ogg.c
1030index da23da8..f51a097 100644
1031--- a/addons/logg/play_ogg.c
1032+++ b/addons/logg/play_ogg.c
1033@@ -1,3 +1,4 @@
1034+#include <stdio.h>
1035 #include "logg.h"
1036
1037 int main(int argc, char** argv)
1038diff --git a/cmake/FileList.cmake b/cmake/FileList.cmake
1039index 5604958..d2a0bc4 100644
1040--- a/cmake/FileList.cmake
1041+++ b/cmake/FileList.cmake
1042@@ -245,6 +245,7 @@ set(ALLEGRO_SRC_LINUX_FILES
1043 src/linux/lvgahelp.c
1044 src/linux/svgalib.c
1045 src/linux/svgalibs.s
1046+ src/linux/tslib.c
1047 src/linux/vtswitch.c
1048 src/misc/vbeaf.c
1049 src/misc/vbeafs.s
1050@@ -257,6 +258,7 @@ set(ALLEGRO_SRC_LINUX_FILES
1051 set(ALLEGRO_SRC_UNIX_FILES
1052 src/unix/alsa9.c
1053 src/unix/alsamidi.c
1054+ src/unix/sdl2digi.c
1055 src/unix/arts.c
1056 src/unix/sgial.c
1057 src/unix/jack.c
1058@@ -307,13 +309,11 @@ set(ALLEGRO_SRC_MACOSX_FILES
1059 src/macosx/hidman.m
1060 src/macosx/keybd.m
1061 src/macosx/pcpu.m
1062- src/macosx/qtmidi.m
1063 src/macosx/quartz.m
1064- src/macosx/qzfull.m
1065 src/macosx/qzmouse.m
1066- src/macosx/qzwindow.m
1067- src/macosx/soundman.m
1068 src/macosx/system.m
1069+ src/macosx/cocoagl.m
1070+ src/macosx/cocoashared.m
1071 src/unix/ufile.c
1072 src/unix/utimer.c
1073 src/unix/uptimer.c
1074@@ -334,6 +334,19 @@ set(ALLEGRO_SRC_PSP_FILES
1075 src/psp/pvram.c
1076 src/psp/pvtable8.c
1077 )
1078+
1079+set(ALLEGRO_SRC_IOS_FILES
1080+ src/ios/idrivers.c
1081+ src/ios/isound.c
1082+ src/ios/ifile.c
1083+ src/ios/igfx.c
1084+ src/ios/ikey.c
1085+ src/ios/isystem.c
1086+ src/ios/imouse.c
1087+ src/ios/itimer.c
1088+ src/ios/ithreads.c
1089+ src/misc/colconv.c
1090+ )
1091
1092 set(ALLEGRO_INCLUDE_ALLEGRO_FILES
1093 include/allegro/3d.h
1094@@ -400,6 +413,7 @@ set(ALLEGRO_INCLUDE_ALLEGRO_PLATFORM_FILES
1095 include/allegro/platform/aintmac.h
1096 include/allegro/platform/aintosx.h
1097 include/allegro/platform/aintpsp.h
1098+ include/allegro/platform/aintios.h
1099 include/allegro/platform/aintqnx.h
1100 include/allegro/platform/aintunix.h
1101 include/allegro/platform/aintwin.h
1102@@ -421,6 +435,8 @@ set(ALLEGRO_INCLUDE_ALLEGRO_PLATFORM_FILES
1103 # include/allegro/platform/alplatf.h.cmake
1104 include/allegro/platform/alpsp.h
1105 include/allegro/platform/alpspcfg.h
1106+ include/allegro/platform/alios.h
1107+ include/allegro/platform/alioscfg.h
1108 include/allegro/platform/alqnx.h
1109 include/allegro/platform/alqnxcfg.h
1110 include/allegro/platform/alucfg.h
1111diff --git a/cmake/FindTslib.cmake b/cmake/FindTslib.cmake
1112new file mode 100644
1113index 0000000..e7605c1
1114--- /dev/null
1115+++ b/cmake/FindTslib.cmake
1116@@ -0,0 +1,20 @@
1117+# - Find tslib
1118+#
1119+# TSLIB_INCLUDE_DIR - where to find tslib.h.
1120+# TSLIB_LIBRARIES - List of libraries when using tslib.
1121+# TSLIB_FOUND - True if tslib found.
1122+
1123+if(TSLIB_INCLUDE_DIR)
1124+ # Already in cache, be silent
1125+ set(TSLIB_FIND_QUIETLY TRUE)
1126+endif(TSLIB_INCLUDE_DIR)
1127+find_path(TSLIB_INCLUDE_DIR tslib.h)
1128+find_library(TSLIB_LIBRARY NAMES ts)
1129+# Handle the QUIETLY and REQUIRED arguments and set TSLIB_FOUND
1130+# to TRUE if all listed variables are TRUE.
1131+include(FindPackageHandleStandardArgs)
1132+find_package_handle_standard_args(TSLIB DEFAULT_MSG
1133+ TSLIB_INCLUDE_DIR TSLIB_LIBRARY)
1134+
1135+mark_as_advanced(TSLIB_INCLUDE_DIR)
1136+mark_as_advanced(TSLIB_LIBRARY)
1137diff --git a/docs/src/allegro._tx b/docs/src/allegro._tx
1138index c16aa36..f6568b7 100644
1139--- a/docs/src/allegro._tx
1140+++ b/docs/src/allegro._tx
1141@@ -18,7 +18,7 @@
1142 @document_title=Allegro Manual
1143 @html_footer=Back to contents
1144 @rtfh=Allegro - a game programming library
1145-@manh="version 4.4.2" "Allegro" "Allegro manual"
1146+@manh="version 4.4.3 (SVN)" "Allegro" "Allegro manual"
1147 @mans=#include <allegro.h>
1148 @man_shortdesc_force1=allegro
1149 @man_shortdesc_force2=Allegro game programming library.
1150@@ -52,12 +52,12 @@
1151 \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
1152 \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
1153 /\____/
1154- \_/__/ Version 4.4.2
1155+ \_/__/ Version 4.4.3 (SVN)
1156
1157
1158 A game programming library.
1159
1160- By Shawn Hargreaves, May 19, 2011.
1161+ By Shawn Hargreaves, May 24, 2011.
1162
1163 See the AUTHORS file for a
1164 complete list of contributors.
1165diff --git a/docs/src/readme._tx b/docs/src/readme._tx
1166index 082ea21..aa8f677 100644
1167--- a/docs/src/readme._tx
1168+++ b/docs/src/readme._tx
1169@@ -31,12 +31,12 @@
1170 \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
1171 \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
1172 /\____/
1173- \_/__/ Version 4.4.2
1174+ \_/__/ Version 4.4.3 (SVN)
1175
1176
1177 A game programming library.
1178
1179- By Shawn Hargreaves, May 19, 2011.
1180+ By Shawn Hargreaves, May 24, 2011.
1181
1182 See the AUTHORS file for a
1183 complete list of contributors.
1184diff --git a/examples/exkeys.c b/examples/exkeys.c
1185index 9ea8485..75d3b3c 100644
1186--- a/examples/exkeys.c
1187+++ b/examples/exkeys.c
1188@@ -73,7 +73,7 @@ void keypress_handler(int scancode)
1189 color = scancode & 0x80 ? makecol(255, 255, 0) : makecol(128, 0, 0);
1190 rectfill(screen, x, y, x + 95, y + 8, color);
1191 ustrzncpy(str, sizeof(str), scancode_to_name(i), 12);
1192- textprintf_ex(screen, font, x + 1, y + 1, makecol(0, 0, 0), -1, "%s", str);
1193+ textout_ex(screen, font, str, x + 1, y + 1, makecol(0, 0, 0), -1);
1194 }
1195 END_OF_FUNCTION(keypress_handler)
1196
1197@@ -193,7 +193,7 @@ int main(void)
1198 if (key_shifts & KB_NUMLOCK_FLAG) strcat(buf, " num");
1199 if (key_shifts & KB_SCROLOCK_FLAG) strcat(buf, " scrl");
1200 scroll();
1201- textprintf_ex(screen, font, 8, SCREEN_H-16, makecol(0, 0, 0), makecol(255, 255, 255), buf);
1202+ textprintf_ex(screen, font, 8, SCREEN_H-16, makecol(0, 0, 0), makecol(255, 255, 255), "%s", buf);
1203 } while (k != 27);
1204
1205 /* various scan codes are defined in allegro.h as KEY_* constants */
1206@@ -234,7 +234,7 @@ int main(void)
1207 if (key[KEY_8]) buf[8] = '8'; else buf[8] = ' ';
1208 if (key[KEY_9]) buf[9] = '9'; else buf[9] = ' ';
1209 buf[10] = 0;
1210- textprintf_ex(screen, font, 8, SCREEN_H-16, makecol(0, 0, 0), makecol(255, 255, 255), buf);
1211+ textout_ex(screen, font, buf, 8, SCREEN_H-16, makecol(0, 0, 0), makecol(255, 255, 255));
1212 rest(1);
1213 } while (!keypressed() || (readkey() >> 8) != KEY_ESC);
1214
1215diff --git a/examples/extrans2.c b/examples/extrans2.c
1216index 4400a11..d5c1630 100644
1217--- a/examples/extrans2.c
1218+++ b/examples/extrans2.c
1219@@ -211,7 +211,7 @@ int main(int argc, char **argv)
1220 } else {
1221 msg = "no flipping";
1222 }
1223- textprintf_ex(buffer, font, 1, 1, makecol(255, 255, 255), -1, msg);
1224+ textout_ex(buffer, font, msg, 1, 1, makecol(255, 255, 255), -1);
1225
1226 /* finally blit the back buffer on the screen */
1227 blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);
1228diff --git a/include/allegro/base.h b/include/allegro/base.h
1229index 967b75c..a93736f 100644
1230--- a/include/allegro/base.h
1231+++ b/include/allegro/base.h
1232@@ -46,10 +46,10 @@
1233
1234 #define ALLEGRO_VERSION 4
1235 #define ALLEGRO_SUB_VERSION 4
1236-#define ALLEGRO_WIP_VERSION 2
1237-#define ALLEGRO_VERSION_STR "4.4.2"
1238+#define ALLEGRO_WIP_VERSION 3
1239+#define ALLEGRO_VERSION_STR "4.4.3 (SVN)"
1240 #define ALLEGRO_DATE_STR "2011"
1241-#define ALLEGRO_DATE 20110519 /* yyyymmdd */
1242+#define ALLEGRO_DATE 20110524 /* yyyymmdd */
1243
1244 /*******************************************/
1245 /************ Some global stuff ************/
1246diff --git a/include/allegro/internal/alconfig.h b/include/allegro/internal/alconfig.h
1247index 68ec3e4..948ed64 100644
1248--- a/include/allegro/internal/alconfig.h
1249+++ b/include/allegro/internal/alconfig.h
1250@@ -14,7 +14,7 @@
1251 *
1252 * See readme.txt for copyright information.
1253 */
1254-
1255+#define ALLEGRO_IOS
1256
1257 /* which color depths to include? */
1258 #define ALLEGRO_COLOR8
1259@@ -62,6 +62,8 @@
1260 #include "allegro/platform/alucfg.h"
1261 #elif defined ALLEGRO_PSP
1262 #include "allegro/platform/alpspcfg.h"
1263+ #elif defined ALLEGRO_IOS
1264+ #include "allegro/platform/alioscfg.h"
1265 #else
1266 #error platform not supported
1267 #endif
1268diff --git a/include/allegro/platform/aintios.h b/include/allegro/platform/aintios.h
1269new file mode 100644
1270index 0000000..4d18946
1271--- /dev/null
1272+++ b/include/allegro/platform/aintios.h
1273@@ -0,0 +1,31 @@
1274+/* ______ ___ ___
1275+ * /\ _ \ /\_ \ /\_ \
1276+ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
1277+ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
1278+ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
1279+ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
1280+ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
1281+ * /\____/
1282+ * \_/__/
1283+ *
1284+ * Internal header file for the Android Allegro library port.
1285+ *
1286+ * By JJS for the Adventure Game Studio runtime port.
1287+ * Based on the Allegro PSP port.
1288+ *
1289+ * See readme.txt for copyright information.
1290+ */
1291+
1292+
1293+#ifndef AINTIOS_H
1294+#define AINTIOS_H
1295+
1296+AL_FUNC(void *, _ios_create_mutex, (void));
1297+AL_FUNC(void, _ios_destroy_mutex, (void *handle));
1298+AL_FUNC(void, _ios_lock_mutex, (void *handle));
1299+AL_FUNC(void, _ios_unlock_mutex, (void *handle));
1300+
1301+void ios_mouse_setup(int left, int right, int top, int bottom, float scaling_x, float scaling_y);
1302+
1303+#endif
1304+
1305diff --git a/include/allegro/platform/aintosx.h b/include/allegro/platform/aintosx.h
1306index dcd21b2..e192019 100644
1307--- a/include/allegro/platform/aintosx.h
1308+++ b/include/allegro/platform/aintosx.h
1309@@ -42,6 +42,7 @@
1310 #define OSX_GFX_NONE 0
1311 #define OSX_GFX_WINDOW 1
1312 #define OSX_GFX_FULL 2
1313+#define OSX_GFX_GL 3
1314
1315 #define BMP_EXTRA(bmp) ((BMP_EXTRA_INFO *)((bmp)->extra))
1316
1317@@ -60,7 +61,7 @@
1318
1319
1320
1321-@interface AllegroAppDelegate : NSObject
1322+@interface AllegroAppDelegate : NSObject <NSApplicationDelegate>
1323 - (BOOL)application: (NSApplication *)theApplication openFile: (NSString *)filename;
1324 - (void)applicationDidFinishLaunching: (NSNotification *)aNotification;
1325 - (void)applicationDidChangeScreenParameters: (NSNotification *)aNotification;
1326@@ -71,21 +72,35 @@
1327
1328
1329 @interface AllegroWindow : NSWindow
1330+#ifdef ENABLE_QUICKDRAW
1331 - (void)display;
1332 - (void)miniaturize: (id)sender;
1333+#endif
1334+- (BOOL)canBecomeKeyWindow;
1335+- (BOOL)canBecomeMainWindow;
1336 @end
1337
1338
1339 @interface AllegroWindowDelegate : NSObject
1340 - (BOOL)windowShouldClose: (id)sender;
1341 - (void)windowDidDeminiaturize: (NSNotification *)aNotification;
1342+- (void)windowDidBecomeKey:(NSNotification *)notification;
1343+- (void)windowDidResignKey:(NSNotification *)notification;
1344+- (void)windowWillEnterFullScreen:(NSNotification *)notification;
1345+- (void)windowWillExitFullScreen:(NSNotification *)notification;
1346+- (void)windowDidBecomeMain:(NSNotification *)notification;
1347+- (void)windowDidResignMain:(NSNotification *)notification;
1348 @end
1349
1350-
1351+#ifdef ENABLE_QUICKDRAW
1352 @interface AllegroView: NSQuickDrawView
1353 - (void)resetCursorRects;
1354 @end
1355+#endif
1356
1357+// @interface AllegroCocoaGLView: NSOpenGLView
1358+// - (id) initWithFrame: (NSRect) frame windowed:(BOOL)windowed;
1359+// @end
1360
1361 typedef void RETSIGTYPE;
1362
1363@@ -129,7 +144,6 @@ typedef struct
1364
1365
1366 void osx_event_handler(void);
1367-int osx_bootstrap_ok(void);
1368
1369 void setup_direct_shifts(void);
1370 void osx_init_fade_system(void);
1371@@ -160,6 +174,7 @@ void osx_mouse_move(int x, int y);
1372 HID_DEVICE_COLLECTION *osx_hid_scan(int type, HID_DEVICE_COLLECTION*);
1373 void osx_hid_free(HID_DEVICE_COLLECTION *);
1374
1375+void runOnMainQueueWithoutDeadlocking(void (^block)(void));
1376
1377 AL_VAR(NSBundle *, osx_bundle);
1378 AL_VAR(void *, osx_event_mutex);
1379@@ -173,7 +188,9 @@ AL_ARRAY(char, osx_window_title);
1380 AL_VAR(int, osx_window_first_expose);
1381 AL_VAR(int, osx_skip_events_processing);
1382 AL_VAR(void *, osx_skip_events_processing_mutex);
1383+#ifdef ENABLE_QUICKDRAW
1384 AL_VAR(CGDirectPaletteRef, osx_palette);
1385+#endif
1386 AL_VAR(int, osx_palette_dirty);
1387 AL_VAR(int, osx_mouse_warped);
1388 AL_VAR(int, osx_skip_mouse_move);
1389diff --git a/include/allegro/platform/alios.h b/include/allegro/platform/alios.h
1390new file mode 100644
1391index 0000000..1d04056
1392--- /dev/null
1393+++ b/include/allegro/platform/alios.h
1394@@ -0,0 +1,65 @@
1395+/* ______ ___ ___
1396+ * /\ _ \ /\_ \ /\_ \
1397+ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
1398+ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
1399+ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
1400+ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
1401+ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
1402+ * /\____/
1403+ * \_/__/
1404+ *
1405+ * Android specific header defines.
1406+ *
1407+ * By JJS for the Adventure Game Studio runtime port.
1408+ * Based on the Allegro PSP port.
1409+ *
1410+ * See readme.txt for copyright information.
1411+ */
1412+
1413+
1414+#ifndef ALIOS_H
1415+#define ALIOS_H
1416+
1417+#ifndef ALLEGRO_IOS
1418+ #error bad include
1419+#endif
1420+
1421+#include <stdio.h>
1422+
1423+
1424+/* The Android C library doesn't include stricmp */
1425+#define stricmp strcasecmp
1426+
1427+/* System driver */
1428+#define SYSTEM_IOS AL_ID('I','O','S',' ')
1429+AL_VAR(SYSTEM_DRIVER, system_ios);
1430+
1431+/* Timer driver */
1432+#define TIMER_IOS AL_ID('I','O','S','T')
1433+AL_VAR(TIMER_DRIVER, timer_ios);
1434+
1435+/* Keyboard driver */
1436+#define KEYBOARD_IOS AL_ID('I','O','S','K')
1437+AL_VAR(KEYBOARD_DRIVER, keyboard_ios);
1438+
1439+/* Mouse drivers */
1440+#define MOUSE_IOS AL_ID('I','O','S','M')
1441+AL_VAR(MOUSE_DRIVER, mouse_ios);
1442+
1443+/* Gfx driver */
1444+#define GFX_IOS AL_ID('I','O','S','G')
1445+AL_VAR(GFX_DRIVER, gfx_ios);
1446+
1447+/* Digital sound driver */
1448+#define DIGI_IOS AL_ID('I','O','S','S')
1449+AL_VAR(DIGI_DRIVER, digi_ios);
1450+
1451+/* Joystick drivers */
1452+#define JOYSTICK_IOS AL_ID('I','O','S','J')
1453+AL_VAR(JOYSTICK_DRIVER, joystick_ios);
1454+
1455+
1456+
1457+
1458+
1459+#endif
1460diff --git a/include/allegro/platform/alioscfg.h b/include/allegro/platform/alioscfg.h
1461new file mode 100644
1462index 0000000..be35c3d
1463--- /dev/null
1464+++ b/include/allegro/platform/alioscfg.h
1465@@ -0,0 +1,70 @@
1466+/* ______ ___ ___
1467+ * /\ _ \ /\_ \ /\_ \
1468+ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
1469+ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
1470+ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
1471+ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
1472+ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
1473+ * /\____/
1474+ * \_/__/
1475+ *
1476+ * Android specific header defines.
1477+ *
1478+ * By JJS for the Adventure Game Studio runtime port.
1479+ * Based on the Allegro PSP port.
1480+ *
1481+ * See readme.txt for copyright information.
1482+ */
1483+
1484+
1485+#ifndef ALIOSCFG_H
1486+#define ALIOSCFG_H
1487+
1488+#define ALLEGRO_EXTRA_HEADER "allegro/platform/alios.h"
1489+
1490+#ifndef SCAN_DEPEND
1491+ #include <fcntl.h>
1492+ #include <unistd.h>
1493+#endif
1494+
1495+
1496+#ifndef ALLEGRO_NO_MAGIC_MAIN
1497+ #define ALLEGRO_MAGIC_MAIN
1498+ #define main _mangled_main
1499+ #undef END_OF_MAIN
1500+ #define END_OF_MAIN() void *_mangled_main_address = (void *) _mangled_main;
1501+#else
1502+ #undef END_OF_MAIN
1503+ #define END_OF_MAIN() void *_mangled_main_address;
1504+#endif
1505+
1506+#include <stdio.h>
1507+
1508+#define ALLEGRO_HAVE_DIRENT_H 1
1509+#define ALLEGRO_HAVE_INTTYPES_H 1
1510+#define ALLEGRO_HAVE_STDINT_H 1
1511+#define ALLEGRO_HAVE_SYS_TIME_H 1
1512+#define ALLEGRO_HAVE_SYS_STAT_H 1
1513+
1514+#define ALLEGRO_HAVE_LIBPTHREAD 1
1515+
1516+/* Describe this platform */
1517+#define ALLEGRO_PLATFORM_STR "iOS"
1518+#define ALLEGRO_USE_CONSTRUCTOR
1519+#define ALLEGRO_MULTITHREADED
1520+#define ALLEGRO_LITTLE_ENDIAN
1521+
1522+/* Provide implementations of missing definitions */
1523+#ifndef O_BINARY
1524+ #define O_BINARY 0
1525+#endif
1526+#define dup(X) (fcntl(X, F_DUPFD, 0))
1527+
1528+/* Exclude ASM */
1529+#ifndef ALLEGRO_NO_ASM
1530+ #define ALLEGRO_NO_ASM
1531+#endif
1532+
1533+
1534+
1535+#endif
1536diff --git a/include/allegro/platform/alosx.h b/include/allegro/platform/alosx.h
1537index 20787f3..79bd040 100644
1538--- a/include/allegro/platform/alosx.h
1539+++ b/include/allegro/platform/alosx.h
1540@@ -42,7 +42,6 @@
1541 #import <CoreAudio/CoreAudio.h>
1542 #import <AudioUnit/AudioUnit.h>
1543 #import <AudioToolbox/AudioToolbox.h>
1544- #import <QuickTime/QuickTime.h>
1545 #import <IOKit/IOKitLib.h>
1546 #import <IOKit/IOCFPlugIn.h>
1547 #import <IOKit/hid/IOHIDLib.h>
1548@@ -92,8 +91,12 @@ AL_VAR(MOUSE_DRIVER, mouse_macosx);
1549 /* Gfx drivers */
1550 #define GFX_QUARTZ_WINDOW AL_ID('Q','Z','W','N')
1551 #define GFX_QUARTZ_FULLSCREEN AL_ID('Q','Z','F','L')
1552+#define GFX_COCOAGL_WINDOW AL_ID('C','O','W','N')
1553+#define GFX_COCOAGL_FULLSCREEN AL_ID('C','O','F','L')
1554 AL_VAR(GFX_DRIVER, gfx_quartz_window);
1555 AL_VAR(GFX_DRIVER, gfx_quartz_full);
1556+AL_VAR(GFX_DRIVER, gfx_cocoagl_window);
1557+AL_VAR(GFX_DRIVER, gfx_cocoagl_full);
1558
1559 /* Digital sound drivers */
1560 #define DIGI_CORE_AUDIO AL_ID('D','C','A',' ')
1561@@ -103,9 +106,7 @@ AL_VAR(DIGI_DRIVER, digi_sound_manager);
1562
1563 /* MIDI music drivers */
1564 #define MIDI_CORE_AUDIO AL_ID('M','C','A',' ')
1565-#define MIDI_QUICKTIME AL_ID('Q','T','M',' ')
1566 AL_VAR(MIDI_DRIVER, midi_core_audio);
1567-AL_VAR(MIDI_DRIVER, midi_quicktime);
1568
1569 /* Joystick drivers */
1570 #define JOYSTICK_HID AL_ID('H','I','D','J')
1571diff --git a/include/allegro/platform/alunix.h b/include/allegro/platform/alunix.h
1572index c0196f5..f179854 100644
1573--- a/include/allegro/platform/alunix.h
1574+++ b/include/allegro/platform/alunix.h
1575@@ -69,6 +69,7 @@ AL_VAR(TIMER_DRIVER, timerdrv_unix_sigalrm);
1576 #define DIGI_ALSA AL_ID('A','L','S','A')
1577 #define MIDI_ALSA AL_ID('A','M','I','D')
1578 #define DIGI_JACK AL_ID('J','A','C','K')
1579+#define DIGI_SDL2 AL_ID('S','D','L','2')
1580
1581
1582 #ifdef ALLEGRO_WITH_OSSDIGI
1583@@ -103,6 +104,12 @@ AL_VAR(DIGI_DRIVER, digi_sgial);
1584 { DIGI_SGIAL, &digi_sgial, TRUE },
1585 #endif /* ALLEGRO_WITH_SGIALDIGI */
1586
1587+#ifdef ALLEGRO_WITH_SDL2ADIGI
1588+AL_VAR(DIGI_DRIVER, digi_sdl2);
1589+#define DIGI_DRIVER_SDL2 \
1590+ { DIGI_SDL2, &digi_sdl2, TRUE },
1591+#endif /* ALLEGRO_WITH_SDL2ADIGI */
1592+
1593 #ifdef ALLEGRO_WITH_ALSADIGI
1594 AL_VAR(DIGI_DRIVER, digi_alsa);
1595 #define DIGI_DRIVER_ALSA \
1596@@ -178,6 +185,7 @@ AL_VAR(GFX_DRIVER, gfx_xdga2_soft);
1597 #define MOUSEDRV_LINUX_MS AL_ID('M','S',' ',' ')
1598 #define MOUSEDRV_LINUX_IMS AL_ID('I','M','S',' ')
1599 #define MOUSEDRV_LINUX_EVDEV AL_ID('E','V',' ',' ')
1600+#define MOUSEDRV_LINUX_TSLIB AL_ID('T','S','L','I')
1601
1602 #define JOY_TYPE_LINUX_ANALOGUE AL_ID('L','N','X','A')
1603
1604@@ -214,6 +222,7 @@ AL_VAR(MOUSE_DRIVER, mousedrv_linux_gpmdata);
1605 AL_VAR(MOUSE_DRIVER, mousedrv_linux_ms);
1606 AL_VAR(MOUSE_DRIVER, mousedrv_linux_ims);
1607 AL_VAR(MOUSE_DRIVER, mousedrv_linux_evdev);
1608+AL_VAR(MOUSE_DRIVER, mousedrv_linux_tslib);
1609
1610 AL_FUNC_DEPRECATED(void, split_modex_screen, (int lyne));
1611
1612diff --git a/include/allegro/platform/alunixac.h.cmake b/include/allegro/platform/alunixac.h.cmake
1613index 5adb3aa..25186d0 100644
1614--- a/include/allegro/platform/alunixac.h.cmake
1615+++ b/include/allegro/platform/alunixac.h.cmake
1616@@ -123,6 +123,9 @@
1617 /* Define to enable Linux console VGA driver. */
1618 #cmakedefine ALLEGRO_LINUX_VGA
1619
1620+/* Define to enable Linux console tslib mouse driver. */
1621+#cmakedefine ALLEGRO_LINUX_TSLIB
1622+
1623 /*---------------------------------------------------------------------------*/
1624
1625 /* Define to the installed ALSA version. */
1626@@ -152,6 +155,9 @@
1627 /* Define if SGI AL DIGI driver is supported. */
1628 #cmakedefine ALLEGRO_WITH_SGIALDIGI
1629
1630+/* Define if SDL2 DIGI driver is supported. */
1631+#cmakedefine ALLEGRO_WITH_SDL2DIGI
1632+
1633 /*---------------------------------------------------------------------------*/
1634
1635 /* Define to (void *)-1, if MAP_FAILED is not defined. */
1636diff --git a/include/allegro/system.h b/include/allegro/system.h
1637index 2aa6a59..e218bff 100644
1638--- a/include/allegro/system.h
1639+++ b/include/allegro/system.h
1640@@ -66,6 +66,7 @@ AL_ARRAY(char, allegro_error);
1641 #define OSTYPE_MACOS AL_ID('M','A','C',' ')
1642 #define OSTYPE_MACOSX AL_ID('M','A','C','X')
1643 #define OSTYPE_PSP AL_ID('K','P','S','P')
1644+#define OSTYPE_IOS AL_ID('I','O','S',' ')
1645
1646 AL_VAR(int, os_type);
1647 AL_VAR(int, os_version);
1648diff --git a/misc/allegro-config.in b/misc/allegro-config.in
1649index 84223cd..d032272 100644
1650--- a/misc/allegro-config.in
1651+++ b/misc/allegro-config.in
1652@@ -12,7 +12,7 @@
1653 #
1654 # This is heavily based on a similar script from GTK.
1655
1656-version=4.4.2
1657+version=4.4.3
1658
1659 prefix=@prefix@
1660 exec_prefix=$prefix
1661diff --git a/misc/pkgreadme._tx b/misc/pkgreadme._tx
1662index 465f4b4..3a49284 100644
1663--- a/misc/pkgreadme._tx
1664+++ b/misc/pkgreadme._tx
1665@@ -12,12 +12,12 @@
1666 \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
1667 \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
1668 /\____/
1669- \_/__/ Version 4.4.2
1670+ \_/__/ Version 4.4.3 (SVN)
1671
1672
1673 A game programming library.
1674
1675- By Shawn Hargreaves, May 19, 2011.
1676+ By Shawn Hargreaves, May 24, 2011.
1677
1678 See the AUTHORS file for a
1679 complete list of contributors.
1680diff --git a/setup/setup.c b/setup/setup.c
1681index 894bacb..df56485 100644
1682--- a/setup/setup.c
1683+++ b/setup/setup.c
1684@@ -1163,7 +1163,7 @@ static void plot_joystick_state(BITMAP *bmp, int i)
1685 textprintf_ex(bmp, font, SCREEN_W/2-96, SCREEN_H/2-60+c*20, -1, -1, uconvert_ascii("%s (%d/%d)", tmp),
1686 joystick_driver->name, i+1, num_joysticks);
1687 else
1688- textprintf_ex(bmp, font, SCREEN_W/2-96, SCREEN_H/2-60+c*20, -1, -1, joystick_driver->name);
1689+ textout_ex(bmp, font, joystick_driver->name, SCREEN_W/2-96, SCREEN_H/2-60+c*20, -1, -1);
1690 c++;
1691 }
1692
1693@@ -2879,7 +2879,7 @@ int main(void)
1694 alert(uconvert_ascii("Error loading " SETUP_DATA_FILE, tmp1), NULL, NULL, uconvert_ascii("OK", tmp2), NULL, 13, 0);
1695 #else
1696 set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
1697- allegro_message(uconvert_ascii("Error loading " SETUP_DATA_FILE "\n", tmp1));
1698+ allegro_message("%s", uconvert_ascii("Error loading " SETUP_DATA_FILE "\n", tmp1));
1699 #endif
1700 return 1;
1701 }
1702diff --git a/src/config.c b/src/config.c
1703index 7824a09..c49d424 100644
1704--- a/src/config.c
1705+++ b/src/config.c
1706@@ -1,6 +1,6 @@
1707 /* ______ ___ ___
1708- * /\ _ \ /\_ \ /\_ \
1709- * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
1710+ * /\ _ \ /\_ \ /\_ \
1711+ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
1712 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
1713 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
1714 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
1715@@ -47,7 +47,7 @@ typedef struct CONFIG_HOOK
1716 int (*intgetter)(AL_CONST char *name, int def);
1717 AL_CONST char *(*stringgetter)(AL_CONST char *name, AL_CONST char *def);
1718 void (*stringsetter)(AL_CONST char *name, AL_CONST char *value);
1719- struct CONFIG_HOOK *next;
1720+ struct CONFIG_HOOK *next;
1721 } CONFIG_HOOK;
1722
1723
1724@@ -199,7 +199,7 @@ static void config_cleanup(void)
1725 if (hook->section)
1726 _AL_FREE(hook->section);
1727
1728- nexthook = hook->next;
1729+ nexthook = hook->next;
1730 _AL_FREE(hook);
1731 hook = nexthook;
1732 }
1733@@ -209,10 +209,10 @@ static void config_cleanup(void)
1734
1735 _AL_FREE(config_argv);
1736 config_argv = NULL;
1737-
1738+
1739 _AL_FREE(argv_buf);
1740 argv_buf = NULL;
1741-
1742+
1743 argv_buf_size = 0;
1744
1745 _remove_exit_func(config_cleanup);
1746@@ -523,7 +523,7 @@ void set_config_file(AL_CONST char *filename)
1747
1748
1749 /* set_config_data:
1750- * Sets the block of data to be used for all future configuration
1751+ * Sets the block of data to be used for all future configuration
1752 * operations.
1753 */
1754 void set_config_data(AL_CONST char *data, int length)
1755@@ -552,7 +552,7 @@ void override_config_file(AL_CONST char *filename)
1756
1757
1758 /* override_config_data:
1759- * Sets the block of data that will override all future configuration
1760+ * Sets the block of data that will override all future configuration
1761 * operations.
1762 */
1763 void override_config_data(AL_CONST char *data, int length)
1764@@ -631,8 +631,8 @@ static void prettify_section_name(AL_CONST char *in, char *out, int out_size)
1765
1766
1767 /* hook_config_section:
1768- * Hooks a config section to a set of getter/setter functions. This will
1769- * override the normal table of values, and give the provider of the hooks
1770+ * Hooks a config section to a set of getter/setter functions. This will
1771+ * override the normal table of values, and give the provider of the hooks
1772 * complete control over that section.
1773 */
1774 void hook_config_section(AL_CONST char *section, int (*intgetter)(AL_CONST char *, int), AL_CONST char *(*stringgetter)(AL_CONST char *, AL_CONST char *), void (*stringsetter)(AL_CONST char *, AL_CONST char *))
1775@@ -1044,7 +1044,7 @@ static CONFIG_ENTRY *insert_variable(CONFIG *the_config, CONFIG_ENTRY *p, AL_CON
1776
1777 if (p) {
1778 n->next = p->next;
1779- p->next = n;
1780+ p->next = n;
1781 }
1782 else {
1783 n->next = NULL;
1784@@ -1136,8 +1136,8 @@ void set_config_string(AL_CONST char *section, AL_CONST char *name, AL_CONST cha
1785 }
1786
1787 /* append to the end of the section */
1788- while ((p) && (p->next) &&
1789- (((p->next->name) && (ugetc(p->next->name))) ||
1790+ while ((p) && (p->next) &&
1791+ (((p->next->name) && (ugetc(p->next->name))) ||
1792 ((p->next->data) && (ugetc(p->next->data)))))
1793 p = p->next;
1794
1795@@ -1149,7 +1149,7 @@ void set_config_string(AL_CONST char *section, AL_CONST char *name, AL_CONST cha
1796 insert_variable(the_config, NULL, name, val);
1797 the_config->head->next = p;
1798 }
1799- }
1800+ }
1801 }
1802
1803 the_config->dirty = TRUE;
1804@@ -1246,7 +1246,7 @@ void _reload_config(void)
1805
1806 /* reload_config_texts:
1807 * Reads in a block of translated system text, looking for either a
1808- * user-specified file, a ??text.cfg file, or a language.dat#??TEXT_CFG
1809+ * user-specified file, a ??text.cfg file, or a language.dat#??TEXT_CFG
1810 * datafile object. If new_language is not NULL, the language config
1811 * variable will be set to new_language before reloading the
1812 * configuration files.
1813@@ -1511,6 +1511,6 @@ int list_config_sections(AL_CONST char ***names)
1814 */
1815 void free_config_entries(AL_CONST char ***names)
1816 {
1817- _AL_FREE(*names);
1818+ _AL_FREE(*((char***)(names)));
1819 *names = NULL;
1820 }
1821diff --git a/src/digmid.c b/src/digmid.c
1822index 04b82af..c823e84 100644
1823--- a/src/digmid.c
1824+++ b/src/digmid.c
1825@@ -13,6 +13,8 @@
1826 * By Shawn Hargreaves, based on code by Tom Novelli.
1827 * Chris Robinson added some optimizations and the digmid_set_pan method.
1828 *
1829+ * Modified for the Adventure Game Studio runtime port by JJS.
1830+ *
1831 * See readme.txt for copyright information.
1832 */
1833
1834@@ -520,7 +522,7 @@ static int digmid_load_patches(AL_CONST char *patches, AL_CONST char *drums)
1835 {
1836 PACKFILE *f;
1837 char dir[1024], file[1024], buf[1024], filename[1024];
1838- char todo[256][1024];
1839+ char* todo[256];
1840 char *argv[16], *p;
1841 char tmp[128];
1842 int argc;
1843@@ -530,9 +532,12 @@ static int digmid_load_patches(AL_CONST char *patches, AL_CONST char *drums)
1844 int drum_start = 0;
1845 int type, size;
1846 int i, j, c;
1847+
1848+ for (i = 0; i < 256; i++)
1849+ todo[i] = (char*)malloc(1024);
1850
1851 if (!_digmid_find_patches(dir, sizeof(dir), file, sizeof(file)))
1852- return -1;
1853+ goto error_exit;
1854
1855 for (i=0; i<256; i++)
1856 usetc(todo[i], 0);
1857@@ -542,7 +547,7 @@ static int digmid_load_patches(AL_CONST char *patches, AL_CONST char *drums)
1858
1859 f = pack_fopen(buf, F_READ);
1860 if (!f)
1861- return -1;
1862+ goto error_exit;
1863
1864 while (pack_fgets(buf, sizeof(buf), f) != 0) {
1865 argc = parse_string(buf, argv);
1866@@ -584,7 +589,7 @@ static int digmid_load_patches(AL_CONST char *patches, AL_CONST char *drums)
1867
1868 if (!patch[patchnum]) {
1869 /* need to load this sample */
1870- ustrzcpy(todo[patchnum], sizeof(todo[patchnum]), argv[1]);
1871+ ustrzcpy(todo[patchnum], 1024, argv[1]);
1872 }
1873 }
1874 }
1875@@ -608,13 +613,13 @@ static int digmid_load_patches(AL_CONST char *patches, AL_CONST char *drums)
1876
1877 f = pack_fopen(dir, F_READ_PACKED);
1878 if (!f)
1879- return -1;
1880+ goto error_exit;
1881
1882 if (((ugetc(dir) == '#') && (ustrlen(dir) == 1)) || (!ustrchr(dir, '#'))) {
1883 type = pack_mgetl(f);
1884 if (type != DAT_MAGIC) {
1885 pack_fclose(f);
1886- return -1;
1887+ goto error_exit;
1888 }
1889 }
1890
1891@@ -675,6 +680,7 @@ static int digmid_load_patches(AL_CONST char *patches, AL_CONST char *drums)
1892 pack_fseek(f, size+4);
1893 }
1894 }
1895+ pack_fclose(f);
1896 }
1897 else {
1898 /* read from regular disk files */
1899@@ -706,7 +712,16 @@ static int digmid_load_patches(AL_CONST char *patches, AL_CONST char *drums)
1900 }
1901 }
1902
1903+ for (i = 0; i < 256; i++)
1904+ free(todo[i]);
1905+
1906 return 0;
1907+
1908+error_exit:
1909+
1910+ for (i = 0; i < 256; i++)
1911+ free(todo[i]);
1912+ return -1;
1913 }
1914
1915
1916<<<<<<< HEAD
1917diff --git a/src/file.c b/src/file.c
1918index c89024c..4abecdc 100644
1919--- a/src/file.c
1920+++ b/src/file.c
1921@@ -21,6 +21,8 @@
1922 * Peter Wang added support for packfile vtables.
1923 *
1924 * See readme.txt for copyright information.
1925+ *
1926+ * ****** CJ CHANGES IN THIS FILE: Renamed pack_fopen to __old_pack_fopen
1927 */
1928
1929
1930@@ -1808,7 +1810,7 @@ PACKFILE *_pack_fdopen(int fd, AL_CONST char *mode)
1931 * it returns NULL and stores an error code in errno. An attempt to read a
1932 * normal file in packed mode will cause errno to be set to EDOM.
1933 */
1934-PACKFILE *pack_fopen(AL_CONST char *filename, AL_CONST char *mode)
1935+PACKFILE *__old_pack_fopen(AL_CONST char *filename, AL_CONST char *mode)
1936 {
1937 char tmp[1024];
1938 int fd;
1939diff --git a/src/ios/idrivers.c b/src/ios/idrivers.c
1940new file mode 100644
1941index 0000000..f5c9e20
1942--- /dev/null
1943+++ b/src/ios/idrivers.c
1944@@ -0,0 +1,75 @@
1945+/* ______ ___ ___
1946+ * /\ _ \ /\_ \ /\_ \
1947+ * \ \ \\ \\//\ \ \//\ \ __ __ _ __ ___
1948+ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
1949+ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
1950+ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
1951+ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
1952+ * /\____/
1953+ * \_/__/
1954+ *
1955+ * List of iOS drivers.
1956+ *
1957+ * By JJS for the Adventure Game Studio runtime port.
1958+ * Based on the Allegro PSP port.
1959+ *
1960+ * See readme.txt for copyright information.
1961+ */
1962+
1963+
1964+#include "allegro.h"
1965+
1966+#ifndef ALLEGRO_IOS
1967+#error Something is wrong with the makefile
1968+#endif
1969+
1970+
1971+_DRIVER_INFO _system_driver_list[] =
1972+{
1973+ { SYSTEM_IOS, &system_ios, TRUE },
1974+ { SYSTEM_NONE, &system_none, FALSE },
1975+ { 0, NULL, 0 }
1976+};
1977+
1978+
1979+_DRIVER_INFO _keyboard_driver_list[] =
1980+{
1981+ { KEYBOARD_IOS, &keyboard_ios, TRUE },
1982+ { 0, NULL, 0 }
1983+};
1984+
1985+
1986+_DRIVER_INFO _timer_driver_list[] =
1987+{
1988+ { TIMER_IOS, &timer_ios, TRUE },
1989+ { 0, NULL, 0 }
1990+};
1991+
1992+
1993+_DRIVER_INFO _mouse_driver_list[] =
1994+{
1995+ { MOUSE_IOS, &mouse_ios, TRUE },
1996+ { 0, NULL, 0 }
1997+};
1998+
1999+
2000+_DRIVER_INFO _gfx_driver_list[] =
2001+{
2002+ { GFX_IOS, &gfx_ios, TRUE },
2003+ { 0, NULL, 0 }
2004+};
2005+
2006+
2007+_DRIVER_INFO _digi_driver_list[] =
2008+{
2009+ { DIGI_IOS, &digi_ios, TRUE },
2010+ { 0, NULL, 0 }
2011+};
2012+
2013+
2014+BEGIN_MIDI_DRIVER_LIST
2015+MIDI_DRIVER_DIGMID
2016+END_MIDI_DRIVER_LIST
2017+
2018+BEGIN_JOYSTICK_DRIVER_LIST
2019+END_JOYSTICK_DRIVER_LIST
2020=======
2021
2022>>>>>>> master
2023diff --git a/src/ios/ifile.c b/src/ios/ifile.c
2024new file mode 100644
2025index 0000000..d681c90
2026--- /dev/null
2027+++ b/src/ios/ifile.c
2028@@ -0,0 +1,536 @@
2029+/* ______ ___ ___
2030+ * /\ _ \ /\_ \ /\_ \
2031+ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
2032+ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
2033+ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
2034+ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
2035+ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
2036+ * /\____/
2037+ * \_/__/
2038+ *
2039+ * Helper routines to make file.c work on the Android/iOS platform.
2040+ *
2041+ * By Michael Bukin.
2042+ *
2043+ * Modified for the Adventure Game Studio runtime port by JJS.
2044+ *
2045+ * See readme.txt for copyright information.
2046+ */
2047+
2048+/* libc should use 64-bit for file sizes when possible */
2049+#define _FILE_OFFSET_BITS 64
2050+
2051+#include <stdio.h>
2052+#include <string.h>
2053+
2054+#include "allegro.h"
2055+#include "allegro/internal/aintern.h"
2056+
2057+#ifdef ALLEGRO_HAVE_SYS_STAT_H
2058+#include <sys/stat.h>
2059+#endif
2060+
2061+#ifdef ALLEGRO_HAVE_DIRENT_H
2062+ #include <sys/types.h>
2063+ #include <dirent.h>
2064+ #define NAMLEN(dirent) (strlen((dirent)->d_name))
2065+#else
2066+ /* Apparently all new systems have `dirent.h'. */
2067+ #error ALLEGRO_HAVE_DIRENT_H not defined
2068+#endif
2069+
2070+#ifdef ALLEGRO_HAVE_SYS_TIME_H
2071+ #include <sys/time.h>
2072+#endif
2073+#ifdef ALLEGRO_HAVE_TIME_H
2074+ #include <time.h>
2075+#endif
2076+
2077+#define PREFIX_I "al-unix INFO: "
2078+
2079+#define PREFIX_I "al-unix INFO: "
2080+
2081+
2082+/* _al_file_isok:
2083+ * Helper function to check if it is safe to access a file on a floppy
2084+ * drive.
2085+ */
2086+int _al_file_isok(AL_CONST char *filename)
2087+{
2088+ return TRUE;
2089+}
2090+
2091+
2092+
2093+/* _al_file_size_ex:
2094+ * Measures the size of the specified file.
2095+ */
2096+uint64_t _al_file_size_ex(AL_CONST char *filename)
2097+{
2098+ struct stat s;
2099+ char tmp[1024];
2100+
2101+ if (stat(uconvert(filename, U_CURRENT, tmp, U_UTF8, sizeof(tmp)), &s) != 0) {
2102+ *allegro_errno = errno;
2103+ return 0;
2104+ }
2105+
2106+ return s.st_size;
2107+}
2108+
2109+
2110+
2111+/* _al_file_time:
2112+ * Returns the timestamp of the specified file.
2113+ */
2114+time_t _al_file_time(AL_CONST char *filename)
2115+{
2116+ struct stat s;
2117+ char tmp[1024];
2118+
2119+ if (stat(uconvert(filename, U_CURRENT, tmp, U_UTF8, sizeof(tmp)), &s) != 0) {
2120+ *allegro_errno = errno;
2121+ return 0;
2122+ }
2123+
2124+ return s.st_mtime;
2125+}
2126+
2127+
2128+
2129+/* ff_get_filename:
2130+ * When passed a completely specified file path, this returns a pointer
2131+ * to the filename portion.
2132+ */
2133+static char *ff_get_filename(AL_CONST char *path)
2134+{
2135+ char *p = (char*)path + strlen(path);
2136+
2137+ while ((p > path) && (*(p - 1) != '/'))
2138+ p--;
2139+
2140+ return p;
2141+}
2142+
2143+
2144+
2145+/* ff_put_backslash:
2146+ * If the last character of the filename is not a /, this routine will
2147+ * concatenate a / on to it.
2148+ */
2149+static void ff_put_backslash(char *filename, int size)
2150+{
2151+ int len = strlen(filename);
2152+
2153+ if ((len > 0) && (len < (size - 1)) && (filename[len - 1] != '/')) {
2154+ filename[len] = '/';
2155+ filename[len + 1] = 0;
2156+ }
2157+}
2158+
2159+
2160+
2161+#define FF_MATCH_TRY 0
2162+#define FF_MATCH_ONE 1
2163+#define FF_MATCH_ANY 2
2164+
2165+
2166+struct FF_MATCH_DATA
2167+{
2168+ int type;
2169+ AL_CONST char *s1;
2170+ AL_CONST char *s2;
2171+};
2172+
2173+
2174+
2175+/* ff_match:
2176+ * Matches two strings ('*' matches any number of characters,
2177+ * '?' matches any character).
2178+ */
2179+static int ff_match(AL_CONST char *s1, AL_CONST char *s2)
2180+{
2181+ static unsigned int size = 0;
2182+ static struct FF_MATCH_DATA *data = NULL;
2183+ AL_CONST char *s1end;
2184+ int index, c1, c2;
2185+
2186+ /* handle NULL arguments */
2187+ if ((!s1) && (!s2)) {
2188+ if (data) {
2189+ _AL_FREE(data);
2190+ data = NULL;
2191+ }
2192+
2193+ return 0;
2194+ }
2195+
2196+ s1end = s1 + strlen(s1);
2197+
2198+ /* allocate larger working area if necessary */
2199+ if (data && (size < strlen(s2))) {
2200+ _AL_FREE(data);
2201+ data = NULL;
2202+ }
2203+
2204+ if (!data) {
2205+ size = strlen(s2);
2206+ data = _AL_MALLOC(sizeof(struct FF_MATCH_DATA) * size * 2 + 1);
2207+ if (!data)
2208+ return 0;
2209+ }
2210+
2211+ index = 0;
2212+ data[0].s1 = s1;
2213+ data[0].s2 = s2;
2214+ data[0].type = FF_MATCH_TRY;
2215+
2216+ while (index >= 0) {
2217+ s1 = data[index].s1;
2218+ s2 = data[index].s2;
2219+ c1 = *s1;
2220+ c2 = *s2;
2221+
2222+ switch (data[index].type) {
2223+
2224+ case FF_MATCH_TRY:
2225+ if (c2 == 0) {
2226+ /* pattern exhausted */
2227+ if (c1 == 0)
2228+ return 1;
2229+ else
2230+ index--;
2231+ }
2232+ else if (c1 == 0) {
2233+ /* string exhausted */
2234+ while (*s2 == '*')
2235+ s2++;
2236+ if (*s2 == 0)
2237+ return 1;
2238+ else
2239+ index--;
2240+ }
2241+ else if (c2 == '*') {
2242+ /* try to match the rest of pattern with empty string */
2243+ data[index++].type = FF_MATCH_ANY;
2244+ data[index].s1 = s1end;
2245+ data[index].s2 = s2 + 1;
2246+ data[index].type = FF_MATCH_TRY;
2247+ }
2248+ /* do case insensitive matching */
2249+ else if ((c2 == '?') || (c1 == c2)
2250+ || ((c1 <= 90) && (c1 >= 65) && (c2 == c1 + 32))
2251+ || ((c2 <= 90) && (c2 >= 65) && (c1 == c2 + 32))) {
2252+ /* try to match the rest */
2253+ data[index++].type = FF_MATCH_ONE;
2254+ data[index].s1 = s1 + 1;
2255+ data[index].s2 = s2 + 1;
2256+ data[index].type = FF_MATCH_TRY;
2257+ }
2258+ else
2259+ index--;
2260+ break;
2261+
2262+ case FF_MATCH_ONE:
2263+ /* the rest of string did not match, try earlier */
2264+ index--;
2265+ break;
2266+
2267+ case FF_MATCH_ANY:
2268+ /* rest of string did not match, try add more chars to string tail */
2269+ if (--data[index + 1].s1 >= s1) {
2270+ data[index + 1].type = FF_MATCH_TRY;
2271+ index++;
2272+ }
2273+ else
2274+ index--;
2275+ break;
2276+
2277+ default:
2278+ /* this is a bird? This is a plane? No it's a bug!!! */
2279+ return 0;
2280+ }
2281+ }
2282+
2283+ return 0;
2284+}
2285+
2286+
2287+
2288+/* ff_get_attrib:
2289+ * Builds up the attribute list of the file pointed to by name and s.
2290+ */
2291+static int ff_get_attrib(AL_CONST char *name, struct stat *s)
2292+{
2293+ int attrib = 0;
2294+/*
2295+ uid_t euid = geteuid();
2296+
2297+ if (euid != 0) {
2298+ if (s->st_uid == euid) {
2299+ if ((s->st_mode & S_IWUSR) == 0)
2300+ attrib |= FA_RDONLY;
2301+ }
2302+ else if (s->st_gid == getegid()) {
2303+ if ((s->st_mode & S_IWGRP) == 0)
2304+ attrib |= FA_RDONLY;
2305+ }
2306+ else if ((s->st_mode & S_IWOTH) == 0) {
2307+ attrib |= FA_RDONLY;
2308+ }
2309+ }
2310+*/
2311+ if (S_ISDIR(s->st_mode))
2312+ attrib |= FA_DIREC;
2313+
2314+ if ((name[0] == '.') && ((name[1] != '.') || (name[2] != '\0')))
2315+ attrib |= FA_HIDDEN;
2316+
2317+ return attrib;
2318+}
2319+
2320+
2321+
2322+/* structure for use by the directory scanning routines */
2323+#define FF_MAXPATHLEN 1024
2324+
2325+struct FF_DATA
2326+{
2327+ DIR *dir;
2328+ char dirname[FF_MAXPATHLEN];
2329+ char pattern[FF_MAXPATHLEN];
2330+ int attrib;
2331+ uint64_t size;
2332+};
2333+
2334+
2335+
2336+/* al_findfirst:
2337+ * Initiates a directory search.
2338+ */
2339+int al_findfirst(AL_CONST char *pattern, struct al_ffblk *info, int attrib)
2340+{
2341+ struct FF_DATA *ff_data;
2342+ struct stat s;
2343+ int actual_attrib;
2344+ char tmp[1024];
2345+ char *p;
2346+
2347+ /* allocate ff_data structure */
2348+ ff_data = _AL_MALLOC(sizeof(struct FF_DATA));
2349+ if (!ff_data) {
2350+ *allegro_errno = ENOMEM;
2351+ return -1;
2352+ }
2353+
2354+ memset(ff_data, 0, sizeof *ff_data);
2355+ info->ff_data = (void *) ff_data;
2356+
2357+ /* if the pattern contains no wildcard, we use stat() */
2358+ if (!ustrpbrk(pattern, uconvert("?*", U_ASCII, tmp, U_CURRENT, sizeof(tmp)))) {
2359+
2360+ /* start the search */
2361+ errno = *allegro_errno = 0;
2362+
2363+ if (stat(uconvert(pattern, U_CURRENT, tmp, U_UTF8, sizeof(tmp)), &s) == 0) {
2364+
2365+ /* get file attributes */
2366+ actual_attrib = ff_get_attrib(ff_get_filename(uconvert(pattern, U_CURRENT, tmp, U_UTF8, sizeof(tmp))), &s);
2367+ /* does it match ? */
2368+ if ((actual_attrib & ~attrib) == 0) {
2369+ info->attrib = actual_attrib;
2370+ info->time = s.st_mtime;
2371+ info->size = s.st_size; /* overflows at 2GB */
2372+ ff_data->size = s.st_size;
2373+ ustrzcpy(info->name, sizeof(info->name), get_filename(pattern));
2374+ return 0;
2375+ }
2376+ }
2377+
2378+ _AL_FREE(ff_data);
2379+ info->ff_data = NULL;
2380+ *allegro_errno = (errno ? errno : ENOENT);
2381+ return -1;
2382+ }
2383+
2384+ ff_data->attrib = attrib;
2385+
2386+ do_uconvert(pattern, U_CURRENT, ff_data->dirname, U_UTF8, sizeof(ff_data->dirname));
2387+ p = ff_get_filename(ff_data->dirname);
2388+ _al_sane_strncpy(ff_data->pattern, p, sizeof(ff_data->pattern));
2389+ if (p == ff_data->dirname)
2390+ _al_sane_strncpy(ff_data->dirname, "./", FF_MAXPATHLEN);
2391+ else
2392+ *p = 0;
2393+
2394+ /* nasty bodge, but gives better compatibility with DOS programs */
2395+ if (strcmp(ff_data->pattern, "*.*") == 0)
2396+ _al_sane_strncpy(ff_data->pattern, "*", FF_MAXPATHLEN);
2397+
2398+ /* start the search */
2399+ errno = *allegro_errno = 0;
2400+
2401+ ff_data->dir = opendir(ff_data->dirname);
2402+ if (!ff_data->dir) {
2403+ *allegro_errno = (errno ? errno : ENOENT);
2404+ _AL_FREE(ff_data);
2405+ info->ff_data = NULL;
2406+ return -1;
2407+ }
2408+
2409+ if (al_findnext(info) != 0) {
2410+ al_findclose(info);
2411+ return -1;
2412+ }
2413+
2414+ return 0;
2415+}
2416+
2417+
2418+
2419+/* al_findnext:
2420+ * Retrieves the next file from a directory search.
2421+ */
2422+int al_findnext(struct al_ffblk *info)
2423+{
2424+ char tempname[FF_MAXPATHLEN];
2425+ char filename[FF_MAXPATHLEN];
2426+ int attrib;
2427+ struct dirent *entry;
2428+ struct stat s;
2429+ struct FF_DATA *ff_data = (struct FF_DATA *) info->ff_data;
2430+
2431+ ASSERT(ff_data);
2432+
2433+ /* if the pattern contained no wildcard */
2434+ if (!ff_data->dir)
2435+ return -1;
2436+
2437+ while (TRUE) {
2438+ /* read directory entry */
2439+ entry = readdir(ff_data->dir);
2440+ if (!entry) {
2441+ *allegro_errno = (errno ? errno : ENOENT);
2442+ return -1;
2443+ }
2444+
2445+ /* try to match file name with pattern */
2446+ tempname[0] = 0;
2447+ if (NAMLEN(entry) >= sizeof(tempname))
2448+ strncat(tempname, entry->d_name, sizeof(tempname) - 1);
2449+ else
2450+ strncat(tempname, entry->d_name, NAMLEN(entry));
2451+
2452+ if (ff_match(tempname, ff_data->pattern)) {
2453+ _al_sane_strncpy(filename, ff_data->dirname, FF_MAXPATHLEN);
2454+ ff_put_backslash(filename, sizeof(filename));
2455+ strncat(filename, tempname, sizeof(filename) - strlen(filename) - 1);
2456+
2457+ /* get file attributes */
2458+ if (stat(filename, &s) == 0) {
2459+ attrib = ff_get_attrib(tempname, &s);
2460+
2461+ /* does it match ? */
2462+ if ((attrib & ~ff_data->attrib) == 0)
2463+ break;
2464+ }
2465+ else {
2466+ /* evil! but no other way to avoid exiting for_each_file() */
2467+ *allegro_errno = 0;
2468+ }
2469+ }
2470+ }
2471+
2472+ info->attrib = attrib;
2473+ info->time = s.st_mtime;
2474+ info->size = s.st_size; /* overflows at 2GB */
2475+ ff_data->size = s.st_size;
2476+
2477+ do_uconvert(tempname, U_UTF8, info->name, U_CURRENT, sizeof(info->name));
2478+
2479+ return 0;
2480+}
2481+
2482+
2483+
2484+/* al_findclose:
2485+ * Cleans up after a directory search.
2486+ */
2487+void al_findclose(struct al_ffblk *info)
2488+{
2489+ struct FF_DATA *ff_data = (struct FF_DATA *) info->ff_data;
2490+
2491+ if (ff_data) {
2492+ if (ff_data->dir) {
2493+ closedir(ff_data->dir);
2494+ }
2495+ _AL_FREE(ff_data);
2496+ info->ff_data = NULL;
2497+
2498+ /* to avoid leaking memory */
2499+ ff_match(NULL, NULL);
2500+ }
2501+}
2502+
2503+
2504+
2505+/* _al_getdcwd:
2506+ * Returns the current directory on the specified drive.
2507+ */
2508+void _al_getdcwd(int drive, char *buf, int size)
2509+{
2510+ char tmp[1024];
2511+
2512+ if (getcwd(tmp, sizeof(tmp)))
2513+ do_uconvert(tmp, U_UTF8, buf, U_CURRENT, size);
2514+ else
2515+ usetc(buf, 0);
2516+}
2517+
2518+
2519+
2520+/* _al_ffblk_get_size:
2521+ * Returns the size out of an _al_ffblk structure.
2522+ */
2523+uint64_t al_ffblk_get_size(struct al_ffblk *info)
2524+{
2525+ struct FF_DATA *ff_data;
2526+ ASSERT(info);
2527+ ff_data = (struct FF_DATA *) info->ff_data;
2528+ ASSERT(ff_data);
2529+ return ff_data->size;
2530+}
2531+
2532+
2533+
2534+/* _al_detect_filename_encoding:
2535+ * Platform specific function to detect the filename encoding. This is called
2536+ * after setting a system driver, and even if this driver is SYSTEM_NONE.
2537+ */
2538+void _al_detect_filename_encoding(void)
2539+{
2540+ char const *encoding = "unknown";
2541+ char *locale = getenv("LC_ALL");
2542+
2543+ if (!locale || !locale[0]) {
2544+ locale = getenv("LC_CTYPE");
2545+ if (!locale || !locale[0])
2546+ locale = getenv("LANG");
2547+ }
2548+
2549+ if (locale) {
2550+ if (strstr(locale, "utf8") ||
2551+ strstr(locale, "UTF-8") ||
2552+ strstr(locale, "utf-8") ||
2553+ strstr(locale, "UTF8")) {
2554+ /* Note: UTF8 is default anyway. */
2555+ set_filename_encoding(U_UTF8);
2556+ encoding = "UTF8";
2557+ }
2558+ /* TODO: detect other encodings, and support them in Allegro */
2559+ }
2560+
2561+ TRACE(PREFIX_I "Assumed libc encoding is %s.\n", encoding);
2562+}
2563+
2564+
2565diff --git a/src/ios/igfx.c b/src/ios/igfx.c
2566new file mode 100644
2567index 0000000..ac93e31
2568--- /dev/null
2569+++ b/src/ios/igfx.c
2570@@ -0,0 +1,377 @@
2571+/* ______ ___ ___
2572+* /\ _ \ /\_ \ /\_ \
2573+* \ \ \\ \\//\ \ \//\ \ __ __ _ __ ___
2574+* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
2575+* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
2576+* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
2577+* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
2578+* /\____/
2579+* \_/__/
2580+*
2581+* Display driver.
2582+*
2583+* By JJS for the Adventure Game Studio runtime port.
2584+* Based on the Allegro PSP port.
2585+*
2586+* See readme.txt for copyright information.
2587+*/
2588+
2589+#include <../../System/Library/Frameworks/OpenGLES.framework/Headers/ES1/gl.h>
2590+
2591+#include "allegro.h"
2592+#include "allegro/internal/aintern.h"
2593+#include "allegro/platform/aintios.h"
2594+
2595+
2596+extern void ios_swap_buffers();
2597+extern void ios_select_buffer();
2598+
2599+
2600+/* Software version of some blitting methods */
2601+static void (*_orig_blit) (BITMAP * source, BITMAP * dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
2602+
2603+static BITMAP *ios_display_init(int w, int h, int v_w, int v_h, int color_depth);
2604+static void gfx_ios_enable_acceleration(GFX_VTABLE *vtable);
2605+static void ios_hw_blit(BITMAP *source, BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);
2606+
2607+
2608+void ios_render();
2609+void ios_initialize_opengl();
2610+
2611+
2612+/* Options controlled by the application */
2613+int psp_gfx_scaling = 1;
2614+int psp_gfx_smoothing = 1;
2615+
2616+
2617+BITMAP* displayed_video_bitmap;
2618+
2619+unsigned int ios_screen_texture = 0;
2620+unsigned int ios_screen_width = 320;
2621+unsigned int ios_screen_height = 200;
2622+unsigned int ios_screen_physical_width = 320;
2623+unsigned int ios_screen_physical_height = 200;
2624+unsigned int ios_screen_color_depth = 32;
2625+int ios_screen_texture_width = 0;
2626+int ios_screen_texture_height = 0;
2627+float ios_screen_ar = 1.0f;
2628+float ios_device_ar = 1.0f;
2629+
2630+volatile int ios_screen_is_dirty = 0;
2631+int ios_screen_initialized = 0;
2632+
2633+
2634+GLfloat ios_vertices[] =
2635+{
2636+ 0, 0,
2637+ 320, 0,
2638+ 0, 200,
2639+ 320, 200
2640+};
2641+
2642+GLfloat ios_texture_coordinates[] =
2643+{
2644+ 0, 200.0f / 256.0f,
2645+ 320.0f / 512.0f, 200.0f / 256.0f,
2646+ 0, 0,
2647+ 320.0f / 512.0f, 0
2648+};
2649+
2650+
2651+GFX_DRIVER gfx_ios =
2652+{
2653+ GFX_IOS,
2654+ empty_string,
2655+ empty_string,
2656+ "iOS gfx driver",
2657+ ios_display_init, /* AL_METHOD(struct BITMAP *, init, (int w, int h, int v_w, int v_h, int color_depth)); */
2658+ NULL, /* AL_METHOD(void, exit, (struct BITMAP *b)); */
2659+ NULL, /* AL_METHOD(int, scroll, (int x, int y)); */
2660+ NULL, /* AL_METHOD(void, vsync, (void)); */
2661+ NULL, /* AL_METHOD(void, set_palette, (AL_CONST struct RGB *p, int from, int to, int retracesync)); */
2662+ NULL, /* AL_METHOD(int, request_scroll, (int x, int y)); */
2663+ NULL, /* AL_METHOD(int, poll_scroll, (void)); */
2664+ NULL, /* AL_METHOD(void, enable_triple_buffer, (void)); */
2665+ NULL, /* AL_METHOD(struct BITMAP *, create_video_bitmap, (int width, int height)); */
2666+ NULL, /* AL_METHOD(void, destroy_video_bitmap, (struct BITMAP *bitmap)); */
2667+ NULL, /* AL_METHOD(int, show_video_bitmap, (BITMAP *bitmap)); */
2668+ NULL, /* AL_METHOD(int, request_video_bitmap, (BITMAP *bitmap)); */
2669+ NULL, /* AL_METHOD(BITMAP *, create_system_bitmap, (int width, int height)); */
2670+ NULL, /* AL_METHOD(void, destroy_system_bitmap, (BITMAP *bitmap)); */
2671+ NULL, /* AL_METHOD(int, set_mouse_sprite, (BITMAP *sprite, int xfocus, int yfocus)); */
2672+ NULL, /* AL_METHOD(int, show_mouse, (BITMAP *bmp, int x, int y)); */
2673+ NULL, /* AL_METHOD(void, hide_mouse, (void)); */
2674+ NULL, /* AL_METHOD(void, move_mouse, (int x, int y)); */
2675+ NULL, /* AL_METHOD(void, drawing_mode, (void)); */
2676+ NULL, /* AL_METHOD(void, save_video_state, (void)); */
2677+ NULL, /* AL_METHOD(void, restore_video_state, (void)); */
2678+ NULL, /* AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); */
2679+ NULL, /* AL_METHOD(int, fetch_mode_list, (void)); */
2680+ 0, 0, /* physical (not virtual!) screen size */
2681+ TRUE, /* true if video memory is linear */
2682+ 0, /* bank size, in bytes */
2683+ 0, /* bank granularity, in bytes */
2684+ 0, /* video memory size, in bytes */
2685+ 0, /* physical address of video memory */
2686+ FALSE /* true if driver runs windowed */
2687+};
2688+
2689+
2690+extern void ios_create_screen();
2691+
2692+static BITMAP *ios_display_init(int w, int h, int v_w, int v_h, int color_depth)
2693+{
2694+ GFX_VTABLE* vtable = _get_vtable(color_depth);
2695+
2696+ /* Do the final screen blit to a 32 bit bitmap in palette mode */
2697+ if (color_depth == 8)
2698+ color_depth = 32;
2699+
2700+ ios_screen_width = w;
2701+ ios_screen_height = h;
2702+ ios_screen_color_depth = color_depth;
2703+
2704+ displayed_video_bitmap = create_bitmap_ex(color_depth, w, h);
2705+ gfx_ios_enable_acceleration(vtable);
2706+
2707+ ios_create_screen();
2708+
2709+ return displayed_video_bitmap;
2710+}
2711+
2712+
2713+static void gfx_ios_enable_acceleration(GFX_VTABLE *vtable)
2714+{
2715+ /* Keep the original blitting methods */
2716+ _orig_blit = vtable->blit_to_self;
2717+
2718+ /* Accelerated blits. */
2719+ vtable->blit_from_memory = ios_hw_blit;
2720+ vtable->blit_to_memory = ios_hw_blit;
2721+ vtable->blit_from_system = ios_hw_blit;
2722+ vtable->blit_to_system = ios_hw_blit;
2723+ vtable->blit_to_self = ios_hw_blit;
2724+
2725+ _screen_vtable.blit_from_memory = ios_hw_blit;
2726+ _screen_vtable.blit_to_memory = ios_hw_blit;
2727+ _screen_vtable.blit_from_system = ios_hw_blit;
2728+ _screen_vtable.blit_to_system = ios_hw_blit;
2729+ _screen_vtable.blit_to_self = ios_hw_blit;
2730+
2731+ gfx_capabilities |= (GFX_HW_VRAM_BLIT | GFX_HW_MEM_BLIT);
2732+}
2733+
2734+
2735+/* All blitting goes through here, signal a screen update if the blit target is the screen bitmap */
2736+static void ios_hw_blit(BITMAP *source, BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height)
2737+{
2738+ _orig_blit(source, dest, source_x, source_y, dest_x, dest_y, width, height);
2739+
2740+ if (dest == displayed_video_bitmap)
2741+ ios_render();
2742+}
2743+
2744+
2745+int ios_get_next_power_of_2(int value)
2746+{
2747+ int test = 1;
2748+
2749+ while (test < value)
2750+ test *= 2;
2751+
2752+ return test;
2753+}
2754+
2755+
2756+/* Create the texture that holds the screen bitmap */
2757+void ios_create_screen_texture(int width, int height, int color_depth)
2758+{
2759+ char* empty;
2760+
2761+ ios_screen_texture_width = ios_get_next_power_of_2(width);
2762+ ios_screen_texture_height = ios_get_next_power_of_2(height);
2763+
2764+ empty = (char*)malloc(ios_screen_texture_width * ios_screen_texture_height * color_depth / 8);
2765+ memset(empty, 0, ios_screen_texture_width * ios_screen_texture_height * color_depth / 8);
2766+
2767+ if (ios_screen_texture != 0)
2768+ glDeleteTextures(1, &ios_screen_texture);
2769+
2770+ glGenTextures(1, &ios_screen_texture);
2771+ glBindTexture(GL_TEXTURE_2D, ios_screen_texture);
2772+
2773+ if (color_depth == 16)
2774+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ios_screen_texture_width, ios_screen_texture_height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, empty);
2775+ else
2776+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ios_screen_texture_width, ios_screen_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, empty);
2777+
2778+ free(empty);
2779+}
2780+
2781+
2782+/* Set the values for the texture coord. and vertex arrays */
2783+void ios_create_arrays()
2784+{
2785+ if (psp_gfx_scaling == 1)
2786+ {
2787+ if (ios_device_ar <= ios_screen_ar)
2788+ {
2789+ ios_vertices[2] = ios_vertices[6] = ios_screen_physical_width - 1;
2790+ ios_vertices[5] = ios_vertices[7] = ios_screen_physical_width * ((float)ios_screen_height / (float)ios_screen_width);
2791+
2792+ ios_mouse_setup(
2793+ 0,
2794+ ios_screen_physical_width - 1,
2795+ (ios_screen_physical_height - ios_vertices[5]) / 2,
2796+ ios_screen_physical_height - ((ios_screen_physical_height - ios_vertices[5]) / 2),
2797+ (float)ios_screen_width / (float)ios_screen_physical_width,
2798+ (float)ios_screen_height / ios_vertices[5]);
2799+ }
2800+ else
2801+ {
2802+ ios_vertices[2] = ios_vertices[6] = ios_screen_physical_height * ((float)ios_screen_width / (float)ios_screen_height);
2803+ ios_vertices[5] = ios_vertices[7] = ios_screen_physical_height - 1;
2804+
2805+ ios_mouse_setup(
2806+ (ios_screen_physical_width - ios_vertices[2]) / 2,
2807+ ios_screen_physical_width - ((ios_screen_physical_width - ios_vertices[2]) / 2),
2808+ 0,
2809+ ios_screen_physical_height - 1,
2810+ (float)ios_screen_width / ios_vertices[2],
2811+ (float)ios_screen_height / (float)ios_screen_physical_height);
2812+ }
2813+ }
2814+ else if (psp_gfx_scaling == 2)
2815+ {
2816+ ios_vertices[2] = ios_vertices[6] = ios_screen_physical_width - 1;
2817+ ios_vertices[5] = ios_vertices[7] = ios_screen_physical_height - 1;
2818+
2819+ ios_mouse_setup(
2820+ 0,
2821+ ios_screen_physical_width - 1,
2822+ 0,
2823+ ios_screen_physical_width - 1,
2824+ (float)ios_screen_width / (float)ios_screen_physical_width,
2825+ (float)ios_screen_height / (float)ios_screen_physical_height);
2826+ }
2827+ else
2828+ {
2829+ ios_vertices[0] = ios_vertices[4] = ios_screen_width * (-0.5f);
2830+ ios_vertices[2] = ios_vertices[6] = ios_screen_width * 0.5f;
2831+ ios_vertices[5] = ios_vertices[7] = ios_screen_height * 0.5f;
2832+ ios_vertices[1] = ios_vertices[3] = ios_screen_height * (-0.5f);
2833+
2834+ ios_mouse_setup(
2835+ (ios_screen_physical_width - ios_screen_width) / 2,
2836+ ios_screen_physical_width - ((ios_screen_physical_width - ios_screen_width) / 2),
2837+ (ios_screen_physical_height - ios_screen_height) / 2,
2838+ ios_screen_physical_height - ((ios_screen_physical_height - ios_screen_height) / 2),
2839+ 1.0f,
2840+ 1.0f);
2841+ }
2842+
2843+ ios_texture_coordinates[1] = ios_texture_coordinates[3] = (float)ios_screen_height / (float)ios_screen_texture_height;
2844+ ios_texture_coordinates[2] = ios_texture_coordinates[6] = (float)ios_screen_width / (float)ios_screen_texture_width;
2845+}
2846+
2847+
2848+/* Called from the Java app to set up the screen */
2849+void ios_initialize_renderer(int screen_width, int screen_height)
2850+{
2851+ ios_screen_physical_width = screen_width;
2852+ ios_screen_physical_height = screen_height;
2853+ ios_screen_initialized = 0;
2854+}
2855+
2856+
2857+void ios_initialize_opengl()
2858+{
2859+ ios_screen_ar = (float)ios_screen_width / (float)ios_screen_height;
2860+ ios_device_ar = (float)ios_screen_physical_width / (float)ios_screen_physical_height;
2861+
2862+ glEnable(GL_CULL_FACE);
2863+ glEnable(GL_TEXTURE_2D);
2864+ glDisable(GL_DEPTH_TEST);
2865+ glDisable(GL_LIGHTING);
2866+ glDisable(GL_BLEND);
2867+ glDisable(GL_SCISSOR_TEST);
2868+ glShadeModel(GL_FLAT);
2869+
2870+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
2871+
2872+ glViewport(0, 0, ios_screen_physical_width, ios_screen_physical_height);
2873+ glScissor(0, 0, ios_screen_physical_width, ios_screen_physical_height);
2874+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
2875+ glClear(GL_COLOR_BUFFER_BIT);
2876+
2877+ glDisableClientState(GL_COLOR_ARRAY);
2878+ glDisableClientState(GL_NORMAL_ARRAY);
2879+ glEnableClientState(GL_VERTEX_ARRAY);
2880+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
2881+ glTexCoordPointer(2, GL_FLOAT, 0, ios_texture_coordinates);
2882+ glVertexPointer(2, GL_FLOAT, 0, ios_vertices);
2883+
2884+ ios_create_screen_texture(ios_screen_width, ios_screen_height, ios_screen_color_depth);
2885+ ios_create_arrays();
2886+
2887+ glBindTexture(GL_TEXTURE_2D, ios_screen_texture);
2888+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2889+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2890+
2891+ if (psp_gfx_smoothing)
2892+ {
2893+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2894+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2895+ }
2896+ else
2897+ {
2898+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2899+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2900+ }
2901+
2902+ glViewport(0, 0, ios_screen_physical_width, ios_screen_physical_height);
2903+
2904+ glMatrixMode(GL_PROJECTION);
2905+ glLoadIdentity();
2906+
2907+ glOrthof(0, ios_screen_physical_width - 1, 0, ios_screen_physical_height - 1, 0, 1);
2908+
2909+ glMatrixMode(GL_MODELVIEW);
2910+ glLoadIdentity();
2911+
2912+ if (psp_gfx_scaling == 1)
2913+ {
2914+ if (ios_device_ar <= ios_screen_ar)
2915+ glTranslatef(0, (ios_screen_physical_height - ios_vertices[5] - 1) / 2, 0);
2916+ else
2917+ glTranslatef((ios_screen_physical_width - ios_vertices[2] - 1) / 2, 0, 0);
2918+ }
2919+ else if (psp_gfx_scaling == 0)
2920+ {
2921+ glTranslatef(ios_screen_physical_width / 2.0f, ios_screen_physical_height / 2.0f, 0);
2922+ }
2923+}
2924+
2925+
2926+void ios_render()
2927+{
2928+ ios_select_buffer();
2929+
2930+ if (!ios_screen_initialized)
2931+ {
2932+ ios_initialize_opengl();
2933+ ios_screen_initialized = 1;
2934+ }
2935+
2936+ if (ios_screen_color_depth == 16)
2937+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ios_screen_width, ios_screen_height, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, displayed_video_bitmap->line[0]);
2938+ else
2939+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ios_screen_width, ios_screen_height, GL_RGBA, GL_UNSIGNED_BYTE, displayed_video_bitmap->line[0]);
2940+
2941+ glClear(GL_COLOR_BUFFER_BIT);
2942+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2943+
2944+ glFinish();
2945+
2946+ ios_swap_buffers();
2947+}
2948diff --git a/src/ios/ikey.c b/src/ios/ikey.c
2949new file mode 100644
2950index 0000000..83d47f6
2951--- /dev/null
2952+++ b/src/ios/ikey.c
2953@@ -0,0 +1,243 @@
2954+/* ______ ___ ___
2955+* /\ _ \ /\_ \ /\_ \
2956+* \ \ \\ \\//\ \ \//\ \ __ __ _ __ ___
2957+* \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
2958+* \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
2959+* \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
2960+* \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
2961+* /\____/
2962+* \_/__/
2963+*
2964+* Keyboard driver.
2965+*
2966+* By JJS for the Adventure Game Studio runtime port.
2967+* Based on the Allegro PSP port.
2968+*
2969+* See readme.txt for copyright information.
2970+*/
2971+
2972+
2973+#include "allegro.h"
2974+#include "allegro/internal/aintern.h"
2975+#include "allegro/platform/aintios.h"
2976+
2977+#ifndef ALLEGRO_IOS
2978+#error Something is wrong with the makefile
2979+#endif
2980+
2981+
2982+static int ios_keyboard_init(void);
2983+static void ios_keyboard_exit(void);
2984+static void ios_keyboard_poll(void);
2985+static int ios_scancode_to_ascii(int scancode);
2986+
2987+extern int ios_get_last_keypress();
2988+
2989+
2990+static int ios_ascii_to_allegro[] = {
2991+ -1, // 0
2992+ -1, // 1
2993+ -1, // 2
2994+ -1, // 3
2995+ -1, // 4
2996+ -1, // 5
2997+ -1, // 6
2998+ -1, // 7
2999+ KEY_BACKSPACE, // 8
3000+ KEY_TAB, // 9
3001+ KEY_ENTER, // 10
3002+ -1, // 11
3003+ -1, // 12
3004+ KEY_ENTER, // 13
3005+ -1, // 14
3006+ -1, // 15
3007+ -1, // 16
3008+ -1, // 17
3009+ -1, // 18
3010+ -1, // 19
3011+ -1, // 20
3012+ -1, // 21
3013+ -1, // 22
3014+ -1, // 23
3015+ -1, // 24
3016+ -1, // 25
3017+ -1, // 26
3018+ KEY_ESC, // 27
3019+ -1, // 28
3020+ -1, // 29
3021+ -1, // 30
3022+ -1, // 31
3023+ KEY_SPACE, // 32
3024+ -1, // 33
3025+ KEY_QUOTE, // 34
3026+ -1, // 35
3027+ -1, // 36
3028+ -1, // 37
3029+ -1, // 38
3030+ -1, // 39
3031+ KEY_OPENBRACE, // 40
3032+ KEY_CLOSEBRACE, // 41
3033+ KEY_ASTERISK, // 42
3034+ KEY_PLUS_PAD, // 43
3035+ KEY_COMMA, // 44
3036+ -1, // 45
3037+ KEY_STOP, // 46
3038+ KEY_SLASH, // 47
3039+ KEY_0, // 48
3040+ KEY_1, // 49
3041+ KEY_2, // 50
3042+ KEY_3, // 51
3043+ KEY_4, // 52
3044+ KEY_5, // 53
3045+ KEY_6, // 54
3046+ KEY_7, // 55
3047+ KEY_8, // 56
3048+ KEY_9, // 57
3049+ KEY_COLON, // 58
3050+ KEY_SEMICOLON, // 59
3051+ -1, // 60
3052+ KEY_EQUALS, // 61
3053+ -1, // 62
3054+ -1, // 63
3055+ KEY_AT, // 64
3056+ KEY_A, // 65
3057+ KEY_B, // 66
3058+ KEY_C, // 67
3059+ KEY_D, // 68
3060+ KEY_E, // 69
3061+ KEY_F, // 70
3062+ KEY_G, // 71
3063+ KEY_H, // 72
3064+ KEY_I, // 73
3065+ KEY_J, // 74
3066+ KEY_K, // 75
3067+ KEY_L, // 76
3068+ KEY_M, // 77
3069+ KEY_N, // 78
3070+ KEY_O, // 79
3071+ KEY_P, // 80
3072+ KEY_Q, // 81
3073+ KEY_R, // 82
3074+ KEY_S, // 83
3075+ KEY_T, // 84
3076+ KEY_U, // 85
3077+ KEY_V, // 86
3078+ KEY_W, // 87
3079+ KEY_X, // 88
3080+ KEY_Y, // 89
3081+ KEY_Z, // 90
3082+ -1, // 91
3083+ KEY_BACKSLASH, // 92
3084+ -1, // 93
3085+ KEY_CIRCUMFLEX, // 94
3086+ -1, // 95
3087+ -1, // 96
3088+ KEY_A, // 97
3089+ KEY_B, // 98
3090+ KEY_C, // 99
3091+ KEY_D, // 100
3092+ KEY_E, // 101
3093+ KEY_F, // 102
3094+ KEY_G, // 103
3095+ KEY_H, // 104
3096+ KEY_I, // 105
3097+ KEY_J, // 106
3098+ KEY_K, // 107
3099+ KEY_L, // 108
3100+ KEY_M, // 109
3101+ KEY_N, // 110
3102+ KEY_O, // 111
3103+ KEY_P, // 112
3104+ KEY_Q, // 113
3105+ KEY_R, // 114
3106+ KEY_S, // 115
3107+ KEY_T, // 116
3108+ KEY_U, // 117
3109+ KEY_V, // 118
3110+ KEY_W, // 119
3111+ KEY_X, // 120
3112+ KEY_Y, // 121
3113+ KEY_Z, // 122
3114+ -1, // 123
3115+ -1, // 124
3116+ -1, // 125
3117+ KEY_TILDE, // 126
3118+ -1 // 127
3119+};
3120+
3121+
3122+KEYBOARD_DRIVER keyboard_ios =
3123+{
3124+ KEYBOARD_IOS,
3125+ empty_string,
3126+ empty_string,
3127+ "iOS keyboard",
3128+ FALSE, // int autorepeat;
3129+ ios_keyboard_init,
3130+ ios_keyboard_exit,
3131+ ios_keyboard_poll,
3132+ NULL, // AL_METHOD(void, set_leds, (int leds));
3133+ NULL, // AL_METHOD(void, set_rate, (int delay, int rate));
3134+ NULL, // AL_METHOD(void, wait_for_input, (void));
3135+ NULL, // AL_METHOD(void, stop_waiting_for_input, (void));
3136+ NULL, // AL_METHOD(int, scancode_to_ascii, (int scancode));
3137+ NULL // scancode_to_name
3138+};
3139+
3140+
3141+static int ios_last_scancode = -1;
3142+
3143+
3144+static int ios_ascii_to_allegro_keycode(int* ascii)
3145+{
3146+ if (*ascii > 127)
3147+ {
3148+ int result = *ascii - 0x1000;
3149+ *ascii = 0;
3150+ return result;
3151+ }
3152+ else
3153+ return ios_ascii_to_allegro[*ascii];
3154+}
3155+
3156+
3157+static int ios_keyboard_init(void)
3158+{
3159+ return 0;
3160+}
3161+
3162+
3163+static void ios_keyboard_exit(void)
3164+{
3165+}
3166+
3167+
3168+static void ios_keyboard_poll(void)
3169+{
3170+ int ascii_code;
3171+ int allegro_keycode;
3172+
3173+ // Hold the key down till the next keyboard poll
3174+ if (ios_last_scancode != -1)
3175+ {
3176+ _handle_key_release(ios_last_scancode);
3177+ ios_last_scancode = -1;
3178+ }
3179+
3180+ ascii_code = ios_get_last_keypress();
3181+ if (ascii_code < 1)
3182+ return;
3183+
3184+ allegro_keycode = ios_ascii_to_allegro_keycode(&ascii_code);
3185+
3186+ if (allegro_keycode == -1)
3187+ return;
3188+
3189+ // Replace LF with CR
3190+ if (ascii_code == 10)
3191+ ascii_code = 13;
3192+
3193+ _handle_key_press(ascii_code, allegro_keycode);
3194+
3195+ ios_last_scancode = allegro_keycode;
3196+}
3197diff --git a/src/ios/imouse.c b/src/ios/imouse.c
3198new file mode 100644
3199index 0000000..1212e74
3200--- /dev/null
3201+++ b/src/ios/imouse.c
3202@@ -0,0 +1,212 @@
3203+/* ______ ___ ___
3204+ * /\ _ \ /\_ \ /\_ \
3205+ * \ \ \\ \\//\ \ \//\ \ __ __ _ __ ___
3206+ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
3207+ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
3208+ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
3209+ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
3210+ * /\____/
3211+ * \_/__/
3212+ *
3213+ * Mouse driver.
3214+ *
3215+ * By JJS for the Adventure Game Studio runtime port.
3216+ * Based on the Allegro PSP port.
3217+ *
3218+ * See readme.txt for copyright information.
3219+ */
3220+
3221+#include "allegro.h"
3222+#include "allegro/internal/aintern.h"
3223+#include "allegro/platform/aintios.h"
3224+
3225+#include "math.h"
3226+
3227+#ifndef ALLEGRO_IOS
3228+#error something is wrong with the makefile
3229+#endif
3230+
3231+static int ios_mouse_init(void);
3232+static void ios_mouse_exit(void);
3233+static void ios_mouse_position(int, int);
3234+static void ios_mouse_set_range(int, int, int, int);
3235+static void ios_mouse_get_mickeys(int *, int *);
3236+static void ios_mouse_poll(void);
3237+
3238+extern void ios_poll_mouse_relative(int* x, int* y);
3239+extern void ios_poll_mouse_absolute(int* x, int* y);
3240+extern int ios_poll_mouse_buttons();
3241+
3242+static int mouse_minx = 0;
3243+static int mouse_miny = 0;
3244+static int mouse_maxx = 320;
3245+static int mouse_maxy = 200;
3246+int ios_left_mouse_stay = 0;
3247+int ios_right_mouse_stay = 0;
3248+int ios_mouse_last_x = 0;
3249+int ios_mouse_last_y = 0;
3250+int ios_mouse_clip_left = 0;
3251+int ios_mouse_clip_right = 479;
3252+int ios_mouse_clip_top = 0;
3253+int ios_mouse_clip_bottom = 319;
3254+float ios_mouse_scaling_x = 1.0f;
3255+float ios_mouse_scaling_y = 1.0f;
3256+
3257+int config_mouse_control_mode = 0; // 0 = direct, 1 = relative
3258+
3259+
3260+MOUSE_DRIVER mouse_ios =
3261+{
3262+ MOUSE_IOS,
3263+ empty_string,
3264+ empty_string,
3265+ "iOS mouse",
3266+ ios_mouse_init,
3267+ ios_mouse_exit,
3268+ ios_mouse_poll, // AL_METHOD(void, poll, (void));
3269+ NULL, // AL_METHOD(void, timer_poll, (void));
3270+ ios_mouse_position,
3271+ ios_mouse_set_range,
3272+ NULL, // AL_METHOD(void, set_speed, (int xspeed, int yspeed));
3273+ ios_mouse_get_mickeys,
3274+ NULL, // AL_METHOD(int, analyse_data, (AL_CONST char *buffer, int size));
3275+ NULL, // AL_METHOD(void, enable_hardware_cursor, (AL_CONST int mode));
3276+ NULL // AL_METHOD(int, select_system_cursor, (AL_CONST int cursor));
3277+};
3278+
3279+
3280+
3281+static int ios_mouse_init(void)
3282+{
3283+ return 3; //Num of buttons.
3284+}
3285+
3286+
3287+void ios_clip_mouse(int* x, int* y)
3288+{
3289+ if (*x < ios_mouse_clip_left)
3290+ *x = ios_mouse_clip_left;
3291+
3292+ if (*y < ios_mouse_clip_top)
3293+ *y = ios_mouse_clip_top;
3294+
3295+ if (*x > ios_mouse_clip_right)
3296+ *x = ios_mouse_clip_right;
3297+
3298+ if (*y > ios_mouse_clip_bottom)
3299+ *y = ios_mouse_clip_bottom;
3300+
3301+ *x -= ios_mouse_clip_left;
3302+ *y -= ios_mouse_clip_top;
3303+}
3304+
3305+
3306+void ios_scale_mouse(int* x, int* y)
3307+{
3308+ *x = (float)*x * ios_mouse_scaling_x;
3309+ *y = (float)*y * ios_mouse_scaling_y;
3310+}
3311+
3312+
3313+void ios_mouse_setup(int left, int right, int top, int bottom, float scaling_x, float scaling_y)
3314+{
3315+ ios_mouse_clip_left = left;
3316+ ios_mouse_clip_right = right;
3317+ ios_mouse_clip_top = top;
3318+ ios_mouse_clip_bottom = bottom;
3319+ ios_mouse_scaling_x = scaling_x;
3320+ ios_mouse_scaling_y = scaling_y;
3321+}
3322+
3323+
3324+static void ios_mouse_poll(void)
3325+{
3326+
3327+ int new_x;
3328+ int new_y;
3329+ int new_click = ios_poll_mouse_buttons();
3330+
3331+ if (config_mouse_control_mode == 1)
3332+ {
3333+ ios_poll_mouse_relative(&new_x, &new_y);
3334+ ios_scale_mouse(&new_x, &new_y);
3335+
3336+ new_x += _mouse_x;
3337+ new_y += _mouse_y;
3338+ }
3339+ else
3340+ {
3341+ ios_poll_mouse_absolute(&new_x, &new_y);
3342+ ios_clip_mouse(&new_x, &new_y);
3343+ ios_scale_mouse(&new_x, &new_y);
3344+ }
3345+
3346+ if (new_x < mouse_minx)
3347+ new_x = mouse_minx;
3348+
3349+ if (new_y < mouse_miny)
3350+ new_y = mouse_miny;
3351+
3352+ if (new_x > mouse_maxx)
3353+ new_x = mouse_maxx;
3354+
3355+ if (new_y > mouse_maxy)
3356+ new_y = mouse_maxy;
3357+
3358+ _mouse_x = new_x;
3359+ _mouse_y = new_y;
3360+
3361+
3362+ if (new_click == 1)
3363+ ios_left_mouse_stay = 10;
3364+ else if (new_click == 2)
3365+ ios_right_mouse_stay = 10;
3366+ else if (new_click == 10)
3367+ ios_left_mouse_stay = 10 * 1000 * 1000;
3368+
3369+ if (ios_left_mouse_stay > 0)
3370+ ios_left_mouse_stay--;
3371+
3372+ if (ios_right_mouse_stay > 0)
3373+ ios_right_mouse_stay--;
3374+
3375+ if (ios_left_mouse_stay > 0)
3376+ _mouse_b = 1;
3377+ else if (ios_right_mouse_stay > 0)
3378+ _mouse_b = 2;
3379+ else
3380+ _mouse_b = 0;
3381+}
3382+
3383+
3384+
3385+
3386+static void ios_mouse_position(int x, int y)
3387+{
3388+ _mouse_x = x;
3389+ _mouse_y = y;
3390+}
3391+
3392+
3393+
3394+static void ios_mouse_set_range(int x1, int y1, int x2, int y2)
3395+{
3396+ mouse_minx = x1;
3397+ mouse_miny = y1;
3398+ mouse_maxx = x2;
3399+ mouse_maxy = y2;
3400+}
3401+
3402+
3403+
3404+static void ios_mouse_get_mickeys(int *mickeyx, int *mickeyy)
3405+{
3406+
3407+}
3408+
3409+
3410+
3411+static void ios_mouse_exit(void)
3412+{
3413+}
3414+
3415diff --git a/src/ios/isound.c b/src/ios/isound.c
3416new file mode 100644
3417index 0000000..b1ca27b
3418--- /dev/null
3419+++ b/src/ios/isound.c
3420@@ -0,0 +1,223 @@
3421+/* ______ ___ ___
3422+ * /\ _ \ /\_ \ /\_ \
3423+ * \ \ \\ \\//\ \ \//\ \ __ __ _ __ ___
3424+ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
3425+ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
3426+ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
3427+ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
3428+ * /\____/
3429+ * \_/__/
3430+ *
3431+ * Audio driver.
3432+ *
3433+ * By JJS for the Adventure Game Studio runtime port.
3434+ * Based on the Allegro PSP port.
3435+ *
3436+ * See readme.txt for copyright information.
3437+ */
3438+
3439+#include <AudioToolbox/AudioToolbox.h>
3440+#include <pthread.h>
3441+#include "allegro.h"
3442+#include "allegro/internal/aintern.h"
3443+#include "allegro/platform/aintios.h"
3444+
3445+#ifndef ALLEGRO_IOS
3446+#error something is wrong with the makefile
3447+#endif
3448+
3449+
3450+#define SAMPLES_PER_BUFFER 1024
3451+
3452+
3453+static int digi_ios_detect(int);
3454+static int digi_ios_init(int, int);
3455+static void digi_ios_exit(int);
3456+static void ios_start_audio_queue();
3457+
3458+static short sound_buffer[2][SAMPLES_PER_BUFFER][2];
3459+int curr_buffer = 0;
3460+
3461+AudioQueueRef ios_queue;
3462+AudioQueueBufferRef ios_queue_buffer[3];
3463+AudioStreamBasicDescription ios_data_format;
3464+
3465+volatile int ios_audio_playing = 0;
3466+volatile int ios_audio_interrupted = 0;
3467+volatile int ios_audio_must_restart = 0;
3468+
3469+DIGI_DRIVER digi_ios =
3470+{
3471+ DIGI_IOS,
3472+ empty_string,
3473+ empty_string,
3474+ "iOS digital sound driver",
3475+ 0,
3476+ 0,
3477+ MIXER_MAX_SFX,
3478+ MIXER_DEF_SFX,
3479+
3480+ digi_ios_detect,
3481+ digi_ios_init,
3482+ digi_ios_exit,
3483+ NULL,
3484+ NULL,
3485+
3486+ NULL,
3487+ NULL,
3488+ NULL,
3489+ _mixer_init_voice,
3490+ _mixer_release_voice,
3491+ _mixer_start_voice,
3492+ _mixer_stop_voice,
3493+ _mixer_loop_voice,
3494+
3495+ _mixer_get_position,
3496+ _mixer_set_position,
3497+
3498+ _mixer_get_volume,
3499+ _mixer_set_volume,
3500+ _mixer_ramp_volume,
3501+ _mixer_stop_volume_ramp,
3502+
3503+ _mixer_get_frequency,
3504+ _mixer_set_frequency,
3505+ _mixer_sweep_frequency,
3506+ _mixer_stop_frequency_sweep,
3507+
3508+ _mixer_get_pan,
3509+ _mixer_set_pan,
3510+ _mixer_sweep_pan,
3511+ _mixer_stop_pan_sweep,
3512+
3513+ _mixer_set_echo,
3514+ _mixer_set_tremolo,
3515+ _mixer_set_vibrato,
3516+ 0, 0,
3517+ 0,
3518+ 0,
3519+ 0,
3520+ 0,
3521+ 0,
3522+ 0
3523+};
3524+
3525+
3526+
3527+static int digi_ios_detect(int input)
3528+{
3529+ return TRUE;
3530+}
3531+
3532+
3533+void ios_resume_sound()
3534+{
3535+ if (ios_audio_must_restart)
3536+ {
3537+ ios_audio_must_restart = 0;
3538+ AudioQueueStart(ios_queue, NULL);
3539+ }
3540+}
3541+
3542+
3543+void digi_ios_interruption_handler(void *inUserData, UInt32 interruptionState)
3544+{
3545+ if (interruptionState == kAudioSessionBeginInterruption)
3546+ {
3547+ ios_audio_interrupted = 1;
3548+ AudioQueueStop(ios_queue, 1);
3549+ }
3550+ else if (interruptionState == kAudioSessionEndInterruption)
3551+ {
3552+ ios_audio_interrupted = 0;
3553+ ios_start_audio_queue();
3554+ }
3555+}
3556+
3557+
3558+void digi_ios_audio_callback(void* inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer)
3559+{
3560+ void* bufptr = &sound_buffer[curr_buffer];
3561+
3562+ if (!ios_audio_playing || ios_audio_interrupted)
3563+ return;
3564+
3565+ /* Asks to the Allegro mixer to fill the buffer */
3566+ _mix_some_samples((uintptr_t)bufptr, 0, TRUE);
3567+
3568+ /* Send mixed buffer to sound card */
3569+ memcpy(inBuffer->mAudioData, bufptr, SAMPLES_PER_BUFFER * 2 * 2);
3570+ inBuffer->mAudioDataByteSize = SAMPLES_PER_BUFFER * 2 * 2;
3571+ AudioQueueEnqueueBuffer(ios_queue, inBuffer, 0, NULL);
3572+
3573+ curr_buffer = !curr_buffer;
3574+}
3575+
3576+
3577+extern volatile int is_in_foreground;
3578+
3579+static void ios_start_audio_queue()
3580+{
3581+ int i;
3582+
3583+ AudioQueueNewOutput(&ios_data_format, digi_ios_audio_callback, NULL, NULL, NULL, 0, &ios_queue);
3584+
3585+ for (i = 0; i < 3; i++)
3586+ {
3587+ AudioQueueAllocateBuffer(ios_queue, SAMPLES_PER_BUFFER * 2 * 2, &ios_queue_buffer[i]);
3588+ memset(ios_queue_buffer[i]->mAudioData, 0, SAMPLES_PER_BUFFER * 2 * 2);
3589+ ios_queue_buffer[i]->mAudioDataByteSize = SAMPLES_PER_BUFFER * 2 * 2;
3590+ AudioQueueEnqueueBuffer(ios_queue, ios_queue_buffer[i], 0, NULL);
3591+ }
3592+
3593+ ios_audio_playing = 1;
3594+
3595+ /* Error -12985 happens if the app is currently in the background.
3596+ The most likely cause for this is that an interrupting event
3597+ (like a phone call or an alarm) occured and the user dismissed it
3598+ by pressing the power button. This calls the audio resume callback
3599+ but the app is already in the background. Set a flag so that audio
3600+ gets restarted after the app has come to the foreground. */
3601+ if (AudioQueueStart(ios_queue, NULL) == -12985)
3602+ {
3603+ ios_audio_must_restart = 1;
3604+ }
3605+}
3606+
3607+
3608+static int digi_ios_init(int input, int voices)
3609+{
3610+ _sound_bits = 16;
3611+ _sound_stereo = TRUE;
3612+ _sound_freq = 44100;
3613+
3614+ digi_ios.voices = voices;
3615+
3616+ ios_data_format.mSampleRate = _sound_freq;
3617+ ios_data_format.mFormatID = kAudioFormatLinearPCM;
3618+ ios_data_format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
3619+ ios_data_format.mBytesPerPacket = 4;
3620+ ios_data_format.mFramesPerPacket = 1;
3621+ ios_data_format.mBytesPerFrame = 4;
3622+ ios_data_format.mChannelsPerFrame = (_sound_stereo ? 2 : 1);
3623+ ios_data_format.mBitsPerChannel = _sound_bits;
3624+ ios_data_format.mReserved = 0;
3625+
3626+ if (_mixer_init(SAMPLES_PER_BUFFER * 2, _sound_freq, _sound_stereo, (_sound_bits == 16), &digi_ios.voices))
3627+ return -1;
3628+
3629+#ifndef __i386__
3630+ AudioSessionInitialize(NULL, NULL, digi_ios_interruption_handler, NULL);
3631+#endif
3632+
3633+ ios_start_audio_queue();
3634+
3635+ return 0;
3636+}
3637+
3638+
3639+static void digi_ios_exit(int input)
3640+{
3641+ ios_audio_playing = 0;
3642+ AudioQueueStop(ios_queue, 0);
3643+}
3644diff --git a/src/ios/isystem.c b/src/ios/isystem.c
3645new file mode 100644
3646index 0000000..7eb7b93
3647--- /dev/null
3648+++ b/src/ios/isystem.c
3649@@ -0,0 +1,102 @@
3650+/* ______ ___ ___
3651+ * /\ _ \ /\_ \ /\_ \
3652+ * \ \ \\ \\//\ \ \//\ \ __ __ _ __ ___
3653+ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
3654+ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
3655+ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
3656+ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
3657+ * /\____/
3658+ * \_/__/
3659+ *
3660+ * System driver.
3661+ *
3662+ * By JJS for the Adventure Game Studio runtime port.
3663+ * Based on the Allegro PSP port.
3664+ *
3665+ * See readme.txt for copyright information.
3666+ */
3667+
3668+
3669+#include "allegro.h"
3670+#include "allegro/internal/aintern.h"
3671+#include "allegro/platform/aintios.h"
3672+
3673+#ifndef ALLEGRO_IOS
3674+ #error something is wrong with the makefile
3675+#endif
3676+
3677+
3678+static int ios_sys_init(void);
3679+static void ios_sys_exit(void);
3680+static void ios_get_gfx_safe_mode(int *driver, struct GFX_MODE *mode);
3681+
3682+
3683+
3684+SYSTEM_DRIVER system_ios =
3685+{
3686+ SYSTEM_IOS,
3687+ empty_string,
3688+ empty_string,
3689+ "iOS Device",
3690+ ios_sys_init,
3691+ ios_sys_exit,
3692+ NULL, /* AL_METHOD(void, get_executable_name, (char *output, int size)); */
3693+ NULL, /* AL_METHOD(int, find_resource, (char *dest, AL_CONST char *resource, int size)); */
3694+ NULL, /* AL_METHOD(void, set_window_title, (AL_CONST char *name)); */
3695+ NULL, /* AL_METHOD(int, set_close_button_callback, (AL_METHOD(void, proc, (void)))); */
3696+ NULL, /* AL_METHOD(void, message, (AL_CONST char *msg)); */
3697+ NULL, /* AL_METHOD(void, assert, (AL_CONST char *msg)); */
3698+ NULL, /* AL_METHOD(void, save_console_state, (void)); */
3699+ NULL, /* AL_METHOD(void, restore_console_state, (void)); */
3700+ NULL, /* AL_METHOD(struct BITMAP *, create_bitmap, (int color_depth, int width, int height)); */
3701+ NULL, /* AL_METHOD(void, created_bitmap, (struct BITMAP *bmp)); */
3702+ NULL, /* AL_METHOD(struct BITMAP *, create_sub_bitmap, (struct BITMAP *parent, int x, int y, int width, int height)); */
3703+ NULL, /* AL_METHOD(void, created_sub_bitmap, (struct BITMAP *bmp, struct BITMAP *parent)); */
3704+ NULL, /* AL_METHOD(int, destroy_bitmap, (struct BITMAP *bitmap)); */
3705+ NULL, /* AL_METHOD(void, read_hardware_palette, (void)); */
3706+ NULL, /* AL_METHOD(void, set_palette_range, (AL_CONST struct RGB *p, int from, int to, int retracesync)); */
3707+ NULL, /* AL_METHOD(struct GFX_VTABLE *, get_vtable, (int color_depth)); */
3708+ NULL, /* AL_METHOD(int, set_display_switch_mode, (int mode)); */
3709+ NULL, /* AL_METHOD(void, display_switch_lock, (int lock, int foreground)); */
3710+ NULL, /* AL_METHOD(int, desktop_color_depth, (void)); */
3711+ NULL, /* AL_METHOD(int, get_desktop_resolution, (int *width, int *height)); */
3712+ ios_get_gfx_safe_mode, /*AL_METHOD(void, get_gfx_safe_mode, (int *driver, struct GFX_MODE *mode));*/
3713+ NULL, /* AL_METHOD(void, yield_timeslice, (void)); */
3714+ _ios_create_mutex, /* AL_METHOD(void *, create_mutex, (void)); */
3715+ _ios_destroy_mutex, /* AL_METHOD(void, destroy_mutex, (void *handle)); */
3716+ _ios_lock_mutex, /* AL_METHOD(void, lock_mutex, (void *handle)); */
3717+ _ios_unlock_mutex, /* AL_METHOD(void, unlock_mutex, (void *handle)); */
3718+ NULL, /* AL_METHOD(_DRIVER_INFO *, gfx_drivers, (void)); */
3719+ NULL, /* AL_METHOD(_DRIVER_INFO *, digi_drivers, (void)); */
3720+ NULL, /* AL_METHOD(_DRIVER_INFO *, midi_drivers, (void)); */
3721+ NULL, /* AL_METHOD(_DRIVER_INFO *, keyboard_drivers, (void)); */
3722+ NULL, /* AL_METHOD(_DRIVER_INFO *, mouse_drivers, (void)); */
3723+ NULL, /* AL_METHOD(_DRIVER_INFO *, joystick_drivers, (void)); */
3724+ NULL /* AL_METHOD(_DRIVER_INFO *, timer_drivers, (void)); */
3725+};
3726+
3727+
3728+
3729+static int ios_sys_init(void)
3730+{
3731+ os_type = OSTYPE_IOS;
3732+
3733+ return 0;
3734+}
3735+
3736+
3737+
3738+static void ios_sys_exit(void)
3739+{
3740+
3741+}
3742+
3743+
3744+
3745+static void ios_get_gfx_safe_mode(int *driver, struct GFX_MODE *mode)
3746+{
3747+ *driver = GFX_IOS;
3748+ mode->width = 320;
3749+ mode->height = 200;
3750+ mode->bpp = 16;
3751+}
3752diff --git a/src/ios/ithreads.c b/src/ios/ithreads.c
3753new file mode 100644
3754index 0000000..35a9bc9
3755--- /dev/null
3756+++ b/src/ios/ithreads.c
3757@@ -0,0 +1,113 @@
3758+/* ______ ___ ___
3759+ * /\ _ \ /\_ \ /\_ \
3760+ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
3761+ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
3762+ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
3763+ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
3764+ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
3765+ * /\____/
3766+ * \_/__/
3767+ *
3768+ * Asynchronous event processing with pthreads.
3769+ *
3770+ * By George Foot and Peter Wang.
3771+ *
3772+ * Synchronization functions added by Eric Botcazou.
3773+ *
3774+ * Copied in part for the AGS iOS port.
3775+ *
3776+ * See readme.txt for copyright information.
3777+ */
3778+
3779+
3780+#include "allegro.h"
3781+#include "allegro/internal/aintern.h"
3782+#include "allegro/platform/aintios.h"
3783+
3784+#ifndef ALLEGRO_IOS
3785+ #error something is wrong with the makefile
3786+#endif
3787+
3788+#include <pthread.h>
3789+#include <signal.h>
3790+#include <sys/time.h>
3791+#include <limits.h>
3792+
3793+
3794+/* custom mutex that supports nested locking */
3795+struct my_mutex {
3796+ int lock_count; /* level of nested locking */
3797+ pthread_t owner; /* thread which owns the mutex */
3798+ pthread_mutex_t actual_mutex; /* underlying mutex object */
3799+};
3800+
3801+
3802+
3803+/* _ios_create_mutex:
3804+ * Creates a mutex and returns a pointer to it.
3805+ */
3806+void *_ios_create_mutex(void)
3807+{
3808+ struct my_mutex *mx;
3809+
3810+ mx = _AL_MALLOC(sizeof(struct my_mutex));
3811+ if (!mx) {
3812+ *allegro_errno = ENOMEM;
3813+ return NULL;
3814+ }
3815+
3816+ mx->lock_count = 0;
3817+ mx->owner = (pthread_t) 0;
3818+
3819+ pthread_mutex_init(&mx->actual_mutex, NULL);
3820+
3821+ return (void *)mx;
3822+}
3823+
3824+
3825+
3826+/* _ios_destroy_mutex:
3827+ * Destroys a mutex.
3828+ */
3829+void _ios_destroy_mutex(void *handle)
3830+{
3831+ struct my_mutex *mx = (struct my_mutex *)handle;
3832+
3833+ pthread_mutex_destroy(&mx->actual_mutex);
3834+
3835+ _AL_FREE(mx);
3836+}
3837+
3838+
3839+
3840+/* _ios_lock_mutex:
3841+ * Locks a mutex.
3842+ */
3843+void _ios_lock_mutex(void *handle)
3844+{
3845+ struct my_mutex *mx = (struct my_mutex *)handle;
3846+
3847+ if (mx->owner != pthread_self()) {
3848+ pthread_mutex_lock(&mx->actual_mutex);
3849+ mx->owner = pthread_self();
3850+ }
3851+
3852+ mx->lock_count++;
3853+}
3854+
3855+
3856+
3857+/* _ios_unlock_mutex:
3858+ * Unlocks a mutex.
3859+ */
3860+void _ios_unlock_mutex(void *handle)
3861+{
3862+ struct my_mutex *mx = (struct my_mutex *)handle;
3863+
3864+ mx->lock_count--;
3865+
3866+ if (mx->lock_count == 0) {
3867+ mx->owner = (pthread_t) 0;
3868+ pthread_mutex_unlock(&mx->actual_mutex);
3869+ }
3870+}
3871diff --git a/src/ios/itimer.c b/src/ios/itimer.c
3872new file mode 100644
3873index 0000000..b1c561e
3874--- /dev/null
3875+++ b/src/ios/itimer.c
3876@@ -0,0 +1,232 @@
3877+/* ______ ___ ___
3878+ * /\ _ \ /\_ \ /\_ \
3879+ * \ \ \\ \\//\ \ \//\ \ __ __ _ __ ___
3880+ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
3881+ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
3882+ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
3883+ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
3884+ * /\____/
3885+ * \_/__/
3886+ *
3887+ * Timer driver.
3888+ *
3889+ * By JJS for the Adventure Game Studio runtime port.
3890+ * Based on the Unix timer driver by Peter Wang.
3891+ *
3892+ * See readme.txt for copyright information.
3893+ */
3894+
3895+
3896+#include "allegro.h"
3897+#include "allegro/internal/aintern.h"
3898+#include "allegro/platform/aintios.h"
3899+
3900+#ifndef ALLEGRO_IOS
3901+ #error something is wrong with the makefile
3902+#endif
3903+
3904+#include <pthread.h>
3905+#include <signal.h>
3906+#include <unistd.h>
3907+#include <sys/time.h>
3908+
3909+
3910+/* See hack later. */
3911+#ifdef ALLEGRO_LINUX_VGA
3912+#ifdef ALLEGRO_HAVE_SYS_IO_H
3913+/* iopl() exists in here instead of unistd.h in glibc */
3914+#include <sys/io.h>
3915+#endif
3916+#include "allegro/platform/aintlnx.h"
3917+#endif
3918+
3919+
3920+#define TIMER_TO_USEC(x) ((long)((x) / 1.193181))
3921+#define USEC_TO_TIMER(x) ((long)((x) * (TIMERS_PER_SECOND / 1000000.)))
3922+
3923+
3924+static int ptimer_init(void);
3925+static void ptimer_exit(void);
3926+void _unix_rest(unsigned int ms, void (*callback) (void));
3927+
3928+
3929+TIMER_DRIVER timer_ios =
3930+{
3931+ TIMER_IOS,
3932+ empty_string,
3933+ empty_string,
3934+ "Unix pthreads timers",
3935+ ptimer_init,
3936+ ptimer_exit,
3937+ NULL, NULL, /* install_int, remove_int */
3938+ NULL, NULL, /* install_param_int, remove_param_int */
3939+ NULL, NULL, /* can_simulate_retrace, simulate_retrace */
3940+ _unix_rest /* rest */
3941+};
3942+
3943+
3944+
3945+static pthread_t thread;
3946+static int thread_alive;
3947+
3948+
3949+
3950+
3951+
3952+/* ptimer_thread_func:
3953+ * The timer thread.
3954+ */
3955+static void *ptimer_thread_func(void *unused)
3956+{
3957+ struct timeval old_time;
3958+ struct timeval new_time;
3959+ struct timeval delay;
3960+ long interval = 0x8000;
3961+
3962+
3963+ gettimeofday(&old_time, 0);
3964+
3965+ while (thread_alive) {
3966+ /* `select' is more accurate than `usleep' on my system. */
3967+ delay.tv_sec = interval / TIMERS_PER_SECOND;
3968+ delay.tv_usec = TIMER_TO_USEC(interval) % 1000000L;
3969+ select(0, NULL, NULL, NULL, &delay);
3970+
3971+ /* Calculate actual time elapsed. */
3972+ gettimeofday(&new_time, 0);
3973+ interval = USEC_TO_TIMER((new_time.tv_sec - old_time.tv_sec) * 1000000L
3974+ + (new_time.tv_usec - old_time.tv_usec));
3975+ old_time = new_time;
3976+
3977+ /* If the app is sent to the background, a long time will have elapsed on return. */
3978+ if ((interval < 0) || (interval > 0x8000 * 100))
3979+ interval = 0x8000;
3980+
3981+ /* Handle a tick. */
3982+ interval = _handle_timer_tick(interval);
3983+ }
3984+
3985+ return NULL;
3986+}
3987+
3988+
3989+
3990+/* ptimer_init:
3991+ * Installs the timer thread.
3992+ */
3993+static int ptimer_init(void)
3994+{
3995+ thread_alive = 1;
3996+
3997+ if (pthread_create(&thread, NULL, ptimer_thread_func, NULL) != 0) {
3998+ thread_alive = 0;
3999+ return -1;
4000+ }
4001+ return 0;
4002+}
4003+
4004+
4005+
4006+/* ptimer_exit:
4007+ * Shuts down the timer thread.
4008+ */
4009+static void ptimer_exit(void)
4010+{
4011+ if (thread_alive) {
4012+ thread_alive = 0;
4013+ pthread_join(thread, NULL);
4014+ }
4015+}
4016+
4017+
4018+
4019+
4020+
4021+
4022+
4023+
4024+/* timeval_subtract:
4025+ * Subtract the `struct timeval' values X and Y, storing the result
4026+ * in RESULT. Return 1 if the difference is negative, otherwise 0.
4027+ *
4028+ * This function is from the glibc manual. It handles weird platforms
4029+ * where the tv_sec is unsigned.
4030+ */
4031+static int timeval_subtract(struct timeval *result,
4032+ struct timeval *x,
4033+ struct timeval *y)
4034+{
4035+ /* Perform the carry for the later subtraction by updating Y. */
4036+ if (x->tv_usec < y->tv_usec) {
4037+ int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
4038+ y->tv_usec -= 1000000 * nsec;
4039+ y->tv_sec += nsec;
4040+ }
4041+ if (x->tv_usec - y->tv_usec > 1000000) {
4042+ int nsec = (x->tv_usec - y->tv_usec) / 1000000;
4043+ y->tv_usec += 1000000 * nsec;
4044+ y->tv_sec -= nsec;
4045+ }
4046+
4047+ /* Compute the time remaining to wait.
4048+ * `tv_usec' is certainly positive. */
4049+ result->tv_sec = x->tv_sec - y->tv_sec;
4050+ result->tv_usec = x->tv_usec - y->tv_usec;
4051+ /* Return 1 if result is negative. */
4052+ return x->tv_sec < y->tv_sec;
4053+}
4054+
4055+
4056+
4057+void _unix_rest(unsigned int ms, void (*callback) (void))
4058+{
4059+ if (callback) {
4060+ struct timeval tv, tv_end;
4061+
4062+ gettimeofday (&tv_end, NULL);
4063+ tv_end.tv_usec += ms * 1000;
4064+ tv_end.tv_sec += (tv_end.tv_usec / 1000000L);
4065+ tv_end.tv_usec %= 1000000L;
4066+
4067+ while (1)
4068+ {
4069+ (*callback)();
4070+ gettimeofday (&tv, NULL);
4071+ if (tv.tv_sec > tv_end.tv_sec)
4072+ break;
4073+ if (tv.tv_sec == tv_end.tv_sec && tv.tv_usec >= tv_end.tv_usec)
4074+ break;
4075+ }
4076+ }
4077+ else {
4078+ struct timeval now;
4079+ struct timeval end;
4080+ struct timeval delay;
4081+ int result;
4082+
4083+ gettimeofday(&now, NULL);
4084+
4085+ end = now;
4086+ end.tv_usec += ms * 1000;
4087+ end.tv_sec += (end.tv_usec / 1000000L);
4088+ end.tv_usec %= 1000000L;
4089+
4090+ while (1) {
4091+ if (timeval_subtract(&delay, &end, &now))
4092+ break;
4093+
4094+#ifdef ALLEGRO_MACOSX
4095+ result = usleep((delay.tv_sec * 1000000L) + delay.tv_usec);
4096+#else
4097+ result = select(0, NULL, NULL, NULL, &delay);
4098+#endif
4099+ if (result == 0) /* ok */
4100+ break;
4101+ if ((result != -1) || (errno != EINTR))
4102+ break;
4103+
4104+ /* interrupted */
4105+ gettimeofday(&now, NULL);
4106+ }
4107+ }
4108+}
4109diff --git a/src/keyboard.c b/src/keyboard.c
4110index 56f60da..7e73066 100644
4111--- a/src/keyboard.c
4112+++ b/src/keyboard.c
4113@@ -1,6 +1,6 @@
4114-/* ______ ___ ___
4115- * /\ _ \ /\_ \ /\_ \
4116- * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4117+/* ______ ___ ___
4118+ * /\ _ \ /\_ \ /\_ \
4119+ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4120 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
4121 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
4122 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
4123@@ -20,10 +20,19 @@
4124 #include "allegro/internal/aintern.h"
4125
4126
4127+/* thedmd: Keyboard driver hit GCC bug 43614.
4128+ * Details: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43614
4129+ */
4130+#if defined(NDEBUG) && defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 4)
4131+#define GCC_440_BUG_WORKAROUND __attribute__ ((optimize("O1")))
4132+#else
4133+#define GCC_440_BUG_WORKAROUND
4134+#endif
4135+
4136
4137 KEYBOARD_DRIVER *keyboard_driver = NULL; /* the active driver */
4138
4139-int _keyboard_installed = FALSE;
4140+int _keyboard_installed = FALSE;
4141
4142 static int keyboard_polled = FALSE; /* are we in polling mode? */
4143
4144@@ -252,7 +261,7 @@ int keypressed(void)
4145 * Returns the next character code from the keyboard buffer. If the
4146 * buffer is empty, it waits until a key is pressed. The low byte of
4147 * the return value contains the ASCII code of the key, and the high
4148- * byte the scan code.
4149+ * byte the scan code.
4150 */
4151 int readkey(void)
4152 {
4153@@ -387,13 +396,23 @@ END_OF_STATIC_FUNCTION(repeat_timer);
4154
4155
4156
4157+void _hack_stop_keyboard_repeat()
4158+{
4159+ if (repeat_key >= 0) {
4160+ remove_int(repeat_timer);
4161+ repeat_key = -1;
4162+ repeat_scan = -1;
4163+ }
4164+}
4165+
4166+
4167 /* install_keyboard_hooks:
4168- * You should only use this function if you *aren't* using the rest of the
4169- * keyboard handler. It can be called in the place of install_keyboard(),
4170- * and lets you provide callback routines to detect and read keypresses,
4171- * which will be used by the main keypressed() and readkey() functions. This
4172- * can be useful if you want to use Allegro's GUI code with a custom
4173- * keyboard handler, as it provides a way for the GUI to access keyboard
4174+ * You should only use this function if you *aren't* using the rest of the
4175+ * keyboard handler. It can be called in the place of install_keyboard(),
4176+ * and lets you provide callback routines to detect and read keypresses,
4177+ * which will be used by the main keypressed() and readkey() functions. This
4178+ * can be useful if you want to use Allegro's GUI code with a custom
4179+ * keyboard handler, as it provides a way for the GUI to access keyboard
4180 * input from your own code.
4181 */
4182 void install_keyboard_hooks(int (*keypressed)(void), int (*readkey)(void))
4183@@ -464,7 +483,7 @@ void _handle_key_press(int keycode, int scancode)
4184 }
4185
4186 /* autorepeat? */
4187- if ((keyboard_driver->autorepeat) && (repeat_delay) &&
4188+ if ((keyboard_driver->autorepeat) && (repeat_delay) &&
4189 (keycode >= 0) && (scancode > 0) && (scancode != KEY_PAUSE) &&
4190 ((keycode != repeat_key) || (scancode != repeat_scan))) {
4191 repeat_key = keycode;
4192@@ -519,6 +538,7 @@ END_OF_FUNCTION(_handle_key_release);
4193 * switch into polling mode and will no longer operate asynchronously
4194 * even if the driver actually does support that.
4195 */
4196+int poll_keyboard(void) GCC_440_BUG_WORKAROUND;
4197 int poll_keyboard(void)
4198 {
4199 int i;
4200@@ -549,7 +569,7 @@ int poll_keyboard(void)
4201 }
4202
4203 while (_key_buffer.start != _key_buffer.end) {
4204- add_key(&key_buffer, _key_buffer.key[_key_buffer.start],
4205+ add_key(&key_buffer, _key_buffer.key[_key_buffer.start],
4206 _key_buffer.scancode[_key_buffer.start]);
4207
4208 if (_key_buffer.start < KEY_BUFFER_SIZE-1)
4209@@ -617,7 +637,7 @@ AL_CONST char *scancode_to_name(int scancode)
4210
4211
4212 /* install_keyboard:
4213- * Installs Allegro's keyboard handler. You must call this before using
4214+ * Installs Allegro's keyboard handler. You must call this before using
4215 * any of the keyboard input routines. Returns -1 on failure.
4216 */
4217 int install_keyboard(void)
4218@@ -690,7 +710,7 @@ int install_keyboard(void)
4219
4220
4221 /* remove_keyboard:
4222- * Removes the keyboard handler. You don't normally need to call this,
4223+ * Removes the keyboard handler. You don't normally need to call this,
4224 * because allegro_exit() will do it for you.
4225 */
4226 void remove_keyboard(void)
4227diff --git a/src/linux/ljoy.c b/src/linux/ljoy.c
4228index 283b809..75c49bb 100644
4229--- a/src/linux/ljoy.c
4230+++ b/src/linux/ljoy.c
4231@@ -53,9 +53,6 @@ static int joy_init(void)
4232 AL_CONST char *device_name = NULL;
4233 char tmp[128], tmp1[128], tmp2[128];
4234 unsigned int raw_version;
4235- struct {
4236- unsigned char build, minor, major;
4237- } version;
4238 char num_axes, num_buttons;
4239 int throttle;
4240 int i, s, a, b;
4241@@ -93,14 +90,10 @@ static int joy_init(void)
4242
4243 if (ioctl(joy_fd[i], JSIOCGVERSION, &raw_version) < 0) {
4244 /* NOTE: IOCTL fails if the joystick API is version 0.x */
4245- uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Your Linux joystick API is version 0.x which is unsupported."));
4246+ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Your Linux joystick API is version 0.x which is unsupported."));
4247 return -1;
4248 }
4249
4250- version.major = (raw_version & 0xFF0000) >> 16;
4251- version.minor = (raw_version & 0xFF00) >> 8;
4252- version.build = (raw_version & 0xFF);
4253-
4254 ioctl(joy_fd[i], JSIOCGAXES, &num_axes);
4255 ioctl(joy_fd[i], JSIOCGBUTTONS, &num_buttons);
4256
4257diff --git a/src/linux/lmsedrv.c b/src/linux/lmsedrv.c
4258index ce2bfbf..0cc7bb8 100644
4259--- a/src/linux/lmsedrv.c
4260+++ b/src/linux/lmsedrv.c
4261@@ -31,7 +31,9 @@ _DRIVER_INFO _linux_mouse_driver_list[] =
4262 #ifdef ALLEGRO_HAVE_LINUX_INPUT_H
4263 { MOUSEDRV_LINUX_EVDEV, &mousedrv_linux_evdev, TRUE },
4264 #endif
4265+#ifdef ALLEGRO_LINUX_TSLIB
4266+ { MOUSEDRV_LINUX_TSLIB, &mousedrv_linux_tslib, TRUE },
4267+#endif
4268 { MOUSEDRV_NONE, &mousedrv_none, TRUE },
4269 { 0, NULL, 0 }
4270 };
4271-
4272diff --git a/src/linux/tslib.c b/src/linux/tslib.c
4273new file mode 100644
4274index 0000000..35b7631
4275--- /dev/null
4276+++ b/src/linux/tslib.c
4277@@ -0,0 +1,169 @@
4278+/* ______ ___ ___
4279+ * /\ _ \ /\_ \ /\_ \
4280+ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4281+ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
4282+ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
4283+ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
4284+ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
4285+ * /\____/
4286+ * \_/__/
4287+ *
4288+ * Linux console mouse driver for tslib (touch screens).
4289+ *
4290+ * By Tobi Vollebregt.
4291+ *
4292+ * See readme.txt for copyright information.
4293+ */
4294+
4295+#include "allegro.h"
4296+#include "allegro/internal/aintern.h"
4297+
4298+#ifdef ALLEGRO_LINUX_TSLIB
4299+
4300+#include <stdio.h>
4301+#include <tslib.h>
4302+
4303+#define PREFIX_I "al-tslib INFO: "
4304+#define PREFIX_W "al-tslib WARNING: "
4305+#define PREFIX_E "al-tslib ERROR: "
4306+
4307+#define ARRAY_SIZE(a) ((int)sizeof((a)) / (int)sizeof((a)[0]))
4308+
4309+static struct tsdev *ts;
4310+
4311+static int mouse_minx = 0; /* mouse range */
4312+static int mouse_miny = 0;
4313+static int mouse_maxx = 319;
4314+static int mouse_maxy = 199;
4315+
4316+
4317+static int al_tslib_error_callback(const char *fmt, va_list ap)
4318+{
4319+ char tmp[ALLEGRO_ERROR_SIZE];
4320+ int ret;
4321+
4322+ ret = vsnprintf(tmp, sizeof(tmp), fmt, ap);
4323+
4324+ TRACE(PREFIX_E "%s\n", tmp);
4325+ uconvert(tmp, U_ASCII, allegro_error, U_CURRENT, ALLEGRO_ERROR_SIZE);
4326+
4327+ return ret;
4328+}
4329+
4330+static int mouse_init(void)
4331+{
4332+ char tmp1[128], tmp2[128];
4333+ AL_CONST char *udevice;
4334+
4335+ /* Set custom error handling function */
4336+ ts_error_fn = al_tslib_error_callback;
4337+
4338+ /* Find the device filename */
4339+ udevice = get_config_string(uconvert_ascii("mouse", tmp1),
4340+ uconvert_ascii("mouse_device", tmp2),
4341+ NULL);
4342+
4343+ /* Open mouse device. Devices are cool. */
4344+ if (udevice) {
4345+ TRACE(PREFIX_I "Trying %s device\n", udevice);
4346+ ts = ts_open(uconvert_toascii(udevice, tmp1), TRUE);
4347+ if (ts == NULL) {
4348+ uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unable to open %s: %s"),
4349+ udevice, ustrerror(errno));
4350+ return -1;
4351+ }
4352+ }
4353+ else {
4354+ /* If not specified in the config file, try several /dev/input/event<n>
4355+ * devices. */
4356+ const char *device_name[] = { "/dev/input/event0",
4357+ "/dev/input/event1",
4358+ "/dev/input/event2",
4359+ "/dev/input/event3",
4360+ NULL };
4361+ int i;
4362+
4363+ TRACE(PREFIX_I "Trying /dev/input/event[0-3] devices\n");
4364+
4365+ for (i=0; device_name[i]; i++) {
4366+ ts = ts_open(device_name[i], TRUE);
4367+ if (ts != NULL)
4368+ break;
4369+ }
4370+
4371+ if (!device_name[i]) {
4372+ uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unable to open a touch screen device: %s"),
4373+ ustrerror(errno));
4374+ return -1;
4375+ }
4376+ }
4377+
4378+ if (ts_config(ts)) {
4379+ uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unable to configure touch screen device: %s"),
4380+ ustrerror(errno));
4381+ ts_close(ts);
4382+ return -1;
4383+ }
4384+
4385+ return 0;
4386+}
4387+
4388+static void mouse_exit(void)
4389+{
4390+ if (ts) {
4391+ ts_close(ts);
4392+ ts = NULL;
4393+ }
4394+}
4395+
4396+static void mouse_position(int x, int y)
4397+{
4398+ _mouse_x = CLAMP(mouse_minx, x, mouse_maxx);
4399+ _mouse_y = CLAMP(mouse_miny, y, mouse_maxy);
4400+}
4401+
4402+static void mouse_set_range(int x1, int y1, int x2, int y2)
4403+{
4404+ mouse_minx = x1;
4405+ mouse_miny = y1;
4406+ mouse_maxx = x2;
4407+ mouse_maxy = y2;
4408+
4409+ mouse_position(_mouse_x, _mouse_y);
4410+}
4411+
4412+static void mouse_timer_poll(void)
4413+{
4414+ struct ts_sample samp[16];
4415+ int n;
4416+
4417+ n = ts_read(ts, samp, ARRAY_SIZE(samp));
4418+ if (n > 0) {
4419+ --n;
4420+ mouse_position(samp[n].x, samp[n].y);
4421+ _mouse_b = samp[n].pressure > 0;
4422+ /*TRACE(PREFIX_I "Read %d samples. x:%3d y:%3d pressure:%3d\n",
4423+ n + 1, samp[n].x, samp[n].y, samp[n].pressure);*/
4424+ }
4425+}
4426+
4427+MOUSE_DRIVER mousedrv_linux_tslib =
4428+{
4429+ MOUSEDRV_LINUX_TSLIB,
4430+ empty_string,
4431+ empty_string,
4432+ "Linux tslib touch screen",
4433+ mouse_init,
4434+ mouse_exit,
4435+ NULL, /* poll */
4436+ mouse_timer_poll,
4437+ mouse_position,
4438+ mouse_set_range,
4439+ NULL, /* set_speed */
4440+ NULL, /* get_mickeys */
4441+ NULL, /* analyse_data */
4442+ NULL, /* enable_hardware_cursor */
4443+ NULL, /* select_system_cursor */
4444+};
4445+
4446+#endif
4447diff --git a/src/macosx/cocoagl.m b/src/macosx/cocoagl.m
4448new file mode 100644
4449index 0000000..de58ab4
4450--- /dev/null
4451+++ b/src/macosx/cocoagl.m
4452@@ -0,0 +1,618 @@
4453+/* ______ ___ ___
4454+ * /\ _ \ /\_ \ /\_ \
4455+ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4456+ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
4457+ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
4458+ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
4459+ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
4460+ * /\____/
4461+ * \_/__/
4462+ *
4463+ * MacOS X quartz windowed gfx driver
4464+ *
4465+ * By Angelo Mottola.
4466+ *
4467+ * See readme.txt for copyright information.
4468+ */
4469+
4470+
4471+#include "allegro.h"
4472+#include "allegro/internal/aintern.h"
4473+#include "allegro/platform/aintosx.h"
4474+
4475+#ifndef ALLEGRO_MACOSX
4476+ #error something is wrong with the makefile
4477+#endif
4478+
4479+#include <OpenGL/gl.h>
4480+#include <math.h>
4481+
4482+#define PREFIX_I "al-osxgl INFO: "
4483+#define PREFIX_W "al-osxgl WARNING: "
4484+
4485+@class AllegroCocoaGLView;
4486+
4487+static BITMAP *osx_gl_window_init(int, int, int, int, int);
4488+static void osx_gl_window_exit(BITMAP *);
4489+
4490+static BITMAP *osx_gl_full_init(int, int, int, int, int);
4491+static void osx_gl_full_exit(BITMAP *);
4492+
4493+static void gfx_cocoa_enable_acceleration(GFX_VTABLE *vtable);
4494+
4495+GFX_DRIVER gfx_cocoagl_window =
4496+{
4497+ GFX_COCOAGL_WINDOW,
4498+ empty_string,
4499+ empty_string,
4500+ "Cocoa GL window",
4501+ osx_gl_window_init,
4502+ osx_gl_window_exit,
4503+ NULL, /* AL_METHOD(int, scroll, (int x, int y)); */
4504+ NULL, /* AL_METHOD(void, vsync, (void)); */
4505+ NULL, /* AL_METHOD(void, set_palette, (AL_CONST struct RGB *p, int from, int to, int retracesync)); */
4506+ NULL, /* AL_METHOD(int, request_scroll, (int x, int y)); */
4507+ NULL, /* AL_METHOD(int, poll_scroll, (void)); */
4508+ NULL, /* AL_METHOD(void, enable_triple_buffer, (void)); */
4509+ NULL, /* AL_METHOD(struct BITMAP *, create_video_bitmap, (int width, int height)); */
4510+ NULL, /* AL_METHOD(void, destroy_video_bitmap, (struct BITMAP *bitmap)); */
4511+ NULL, /* AL_METHOD(int, show_video_bitmap, (BITMAP *bitmap)); */
4512+ NULL, /* AL_METHOD(int, request_video_bitmap, (BITMAP *bitmap)); */
4513+ NULL, /* AL_METHOD(BITMAP *, create_system_bitmap, (int width, int height)); */
4514+ NULL, /* AL_METHOD(void, destroy_system_bitmap, (BITMAP *bitmap)); */
4515+ osx_mouse_set_sprite, /* AL_METHOD(int, set_mouse_sprite, (BITMAP *sprite, int xfocus, int yfocus)); */
4516+ osx_mouse_show, /* AL_METHOD(int, show_mouse, (BITMAP *bmp, int x, int y)); */
4517+ osx_mouse_hide, /* AL_METHOD(void, hide_mouse, (void)); */
4518+ osx_mouse_move, /* AL_METHOD(void, move_mouse, (int x, int y)); */
4519+ NULL, /* AL_METHOD(void, drawing_mode, (void)); */
4520+ NULL, /* AL_METHOD(void, save_video_state, (void)); */
4521+ NULL, /* AL_METHOD(void, restore_video_state, (void)); */
4522+ NULL, /* AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); */
4523+ NULL, /* AL_METHOD(int, fetch_mode_list, (void)); */
4524+ 0, 0, /* physical (not virtual!) screen size */
4525+ TRUE, /* true if video memory is linear */
4526+ 0, /* bank size, in bytes */
4527+ 0, /* bank granularity, in bytes */
4528+ 0, /* video memory size, in bytes */
4529+ 0, /* physical address of video memory */
4530+ TRUE /* true if driver runs windowed */
4531+};
4532+
4533+GFX_DRIVER gfx_cocoagl_full =
4534+{
4535+ GFX_COCOAGL_FULLSCREEN,
4536+ empty_string,
4537+ empty_string,
4538+ "Cocoa GL full",
4539+ osx_gl_full_init,
4540+ osx_gl_full_exit,
4541+ NULL, /* AL_METHOD(int, scroll, (int x, int y)); */
4542+ NULL, /* AL_METHOD(void, vsync, (void)); */
4543+ NULL, /* AL_METHOD(void, set_palette, (AL_CONST struct RGB *p, int from, int to, int retracesync)); */
4544+ NULL, /* AL_METHOD(int, request_scroll, (int x, int y)); */
4545+ NULL, /* AL_METHOD(int, poll_scroll, (void)); */
4546+ NULL, /* AL_METHOD(void, enable_triple_buffer, (void)); */
4547+ NULL, /* AL_METHOD(struct BITMAP *, create_video_bitmap, (int width, int height)); */
4548+ NULL, /* AL_METHOD(void, destroy_video_bitmap, (struct BITMAP *bitmap)); */
4549+ NULL, /* AL_METHOD(int, show_video_bitmap, (BITMAP *bitmap)); */
4550+ NULL, /* AL_METHOD(int, request_video_bitmap, (BITMAP *bitmap)); */
4551+ NULL, /* AL_METHOD(BITMAP *, create_system_bitmap, (int width, int height)); */
4552+ NULL, /* AL_METHOD(void, destroy_system_bitmap, (BITMAP *bitmap)); */
4553+ osx_mouse_set_sprite, /* AL_METHOD(int, set_mouse_sprite, (BITMAP *sprite, int xfocus, int yfocus)); */
4554+ osx_mouse_show, /* AL_METHOD(int, show_mouse, (BITMAP *bmp, int x, int y)); */
4555+ osx_mouse_hide, /* AL_METHOD(void, hide_mouse, (void)); */
4556+ osx_mouse_move, /* AL_METHOD(void, move_mouse, (int x, int y)); */
4557+ NULL, /* AL_METHOD(void, drawing_mode, (void)); */
4558+ NULL, /* AL_METHOD(void, save_video_state, (void)); */
4559+ NULL, /* AL_METHOD(void, restore_video_state, (void)); */
4560+ NULL, /* AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a)); */
4561+ NULL, /* AL_METHOD(int, fetch_mode_list, (void)); */
4562+ 0, 0, /* physical (not virtual!) screen size */
4563+ TRUE, /* true if video memory is linear */
4564+ 0, /* bank size, in bytes */
4565+ 0, /* bank granularity, in bytes */
4566+ 0, /* video memory size, in bytes */
4567+ 0, /* physical address of video memory */
4568+ FALSE /* true if driver runs windowed */
4569+};
4570+
4571+
4572+static float calc_aspect_ratio(NSSize size) {
4573+ float display_aspect = ((float)size.width) / size.height;
4574+
4575+#ifdef ALLEGRO_MACOSX_ALLOW_NON_SQUARE_PIXELS
4576+ /* if 320x200 or 640x400 - non square pixels */
4577+ if ( ((size.width == 320) && (size.height == 200)) ||
4578+ ((size.width == 640) && (size.height == 400)) ) {
4579+ display_aspect = 4.0/3.0;
4580+ }
4581+#endif
4582+
4583+ return display_aspect;
4584+}
4585+
4586+static NSSize adjust_display_size(NSSize size)
4587+{
4588+ const float display_aspect = calc_aspect_ratio(size);
4589+ return NSMakeSize (ceil(size.width), ceil(size.width / display_aspect));
4590+}
4591+
4592+static NSSize scale_display_size(NSSize size)
4593+{
4594+ int display_w = size.width;
4595+ int display_h = size.height;
4596+
4597+ NSRect screenRect = [[NSScreen mainScreen] visibleFrame];
4598+ int w_scale = screenRect.size.width / display_w;
4599+ int h_scale = screenRect.size.height / display_h;
4600+ int scale = w_scale;
4601+ if (h_scale < scale) { scale = h_scale; }
4602+ if (scale < 1) { scale = 1; }
4603+
4604+ display_w = display_w * scale;
4605+ display_h = display_h * scale;
4606+
4607+ return NSMakeSize (display_w, display_h);
4608+}
4609+
4610+static BITMAP *osx_gl_real_init(int w, int h, int v_w, int v_h, int color_depth, GFX_DRIVER * driver)
4611+{
4612+ bool is_fullscreen = driver->windowed == FALSE;
4613+
4614+ GFX_VTABLE* vtable = _get_vtable(color_depth);
4615+
4616+ if (color_depth != 32 && color_depth != 16)
4617+ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported color depth"));
4618+
4619+ BITMAP *displayed_video_bitmap = create_bitmap_ex(color_depth, w, h);
4620+
4621+ driver->w = w;
4622+ driver->h = h;
4623+ driver->vid_mem = w * h * BYTES_PER_PIXEL(color_depth);
4624+
4625+ gfx_cocoa_enable_acceleration(vtable);
4626+
4627+ // Run on the main thread because we're manipulating the API
4628+ runOnMainQueueWithoutDeadlocking(^{
4629+
4630+ const NSSize suggestedSize = NSMakeSize(w, h);
4631+ const NSSize adjustedSize = adjust_display_size(suggestedSize);
4632+ const NSSize scaledSize = scale_display_size(adjustedSize);
4633+
4634+ // setup REAL window
4635+ NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask;
4636+ //if (is_fullscreen) {
4637+ // rect = [[NSScreen mainScreen] frame];
4638+ // styleMask = NSBorderlessWindowMask;
4639+ //}
4640+
4641+ osx_window = [[AllegroWindow alloc] initWithContentRect: (NSRect){.origin=NSZeroPoint, .size=scaledSize}
4642+ styleMask: styleMask
4643+ backing: NSBackingStoreBuffered
4644+ defer: NO
4645+ screen:[NSScreen mainScreen]];
4646+
4647+ AllegroWindowDelegate *osx_window_delegate = [[AllegroWindowDelegate alloc] init];
4648+ [osx_window setDelegate: (id<NSWindowDelegate>)osx_window_delegate];
4649+ [osx_window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
4650+ [osx_window center];
4651+
4652+ set_window_title(osx_window_title);
4653+
4654+ AllegroCocoaGLView *osx_gl_view = [[[AllegroCocoaGLView alloc] initWithFrame: (NSRect){.origin=NSZeroPoint, .size=scaledSize} windowed:driver->windowed backing: displayed_video_bitmap] autorelease];
4655+ [osx_window setContentView: osx_gl_view];
4656+
4657+ [osx_window setContentMinSize: adjustedSize];
4658+ [osx_window setContentAspectRatio: adjustedSize];
4659+
4660+ [osx_window setLevel: NSNormalWindowLevel];
4661+ [osx_window orderFrontRegardless];
4662+ [osx_window makeKeyAndOrderFront: nil];
4663+
4664+ });
4665+
4666+ // NS: this must be toggled after window and view has been completely configured. If not, the dock may interact
4667+ // with the mouse cursor in weird ways, showing the system cursor if you hover where the dock would appear.
4668+ // The use of 'dispatch_after' might not be necessary, but I wanted to let the runloop iterate a few times.
4669+ if (is_fullscreen) {
4670+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(50 * NSEC_PER_MSEC)), dispatch_get_main_queue(), ^{
4671+ [osx_window toggleFullScreen:nil];
4672+ });
4673+ }
4674+
4675+ osx_keyboard_focused(FALSE, 0);
4676+ clear_keybuf();
4677+
4678+ osx_skip_mouse_move = TRUE;
4679+ osx_window_first_expose = TRUE;
4680+ osx_gfx_mode = OSX_GFX_GL;
4681+
4682+ return displayed_video_bitmap;
4683+}
4684+
4685+static BITMAP *osx_gl_window_init(int w, int h, int v_w, int v_h, int color_depth)
4686+{
4687+ BITMAP *bmp = osx_gl_real_init(w, h, v_w, v_h, color_depth, &gfx_cocoagl_window);
4688+ return bmp;
4689+}
4690+
4691+
4692+static BITMAP *osx_gl_full_init(int w, int h, int v_w, int v_h, int color_depth)
4693+{
4694+ BITMAP *bmp = osx_gl_real_init(w, h, v_w, v_h, color_depth, &gfx_cocoagl_full);
4695+
4696+ _unix_lock_mutex(osx_skip_events_processing_mutex);
4697+ osx_skip_events_processing = FALSE;
4698+ _unix_unlock_mutex(osx_skip_events_processing_mutex);
4699+
4700+ return bmp;
4701+}
4702+
4703+static void osx_gl_window_exit(BITMAP *bmp)
4704+{
4705+ runOnMainQueueWithoutDeadlocking(^{
4706+ if (osx_window) {
4707+ [[osx_window contentView] stopRendering];
4708+
4709+ [osx_window close];
4710+ osx_window = nil;
4711+ }
4712+ });
4713+
4714+ osx_gfx_mode = OSX_GFX_NONE;
4715+}
4716+
4717+
4718+static void osx_gl_full_exit(BITMAP *bmp)
4719+{
4720+ _unix_lock_mutex(osx_skip_events_processing_mutex);
4721+ osx_skip_events_processing = TRUE;
4722+ _unix_unlock_mutex(osx_skip_events_processing_mutex);
4723+
4724+ osx_gl_window_exit(bmp);
4725+}
4726+
4727+static void gfx_cocoa_enable_acceleration(GFX_VTABLE *vtable)
4728+{
4729+ gfx_capabilities |= (GFX_HW_VRAM_BLIT | GFX_HW_MEM_BLIT);
4730+}
4731+
4732+
4733+/* NSOpenGLPixelFormat *init_pixel_format(int windowed)
4734+ *
4735+ * Generate a pixel format. First try and get all the 'suggested' settings.
4736+ * If this fails, just get the 'required' settings,
4737+ * or nil if no format can be found
4738+ */
4739+#define MAX_ATTRIBUTES 64
4740+
4741+static NSOpenGLPixelFormat *init_pixel_format(int windowed)
4742+{
4743+ NSOpenGLPixelFormatAttribute attribs[MAX_ATTRIBUTES], *attrib;
4744+ attrib=attribs;
4745+ *attrib++ = kCGLPFAOpenGLProfile;
4746+ *attrib++ = kCGLOGLPVersion_Legacy;
4747+ *attrib++ = NSOpenGLPFADoubleBuffer;
4748+ *attrib++ = NSOpenGLPFAColorSize;
4749+ *attrib++ = 16;
4750+
4751+// if (!windowed) {
4752+// *attrib++ = NSOpenGLPFAScreenMask;
4753+// *attrib++ = CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay);
4754+// }
4755+ *attrib = 0;
4756+
4757+ NSOpenGLPixelFormat *pf = [[NSOpenGLPixelFormat alloc] initWithAttributes: attribs];
4758+
4759+ return pf;
4760+}
4761+
4762+static CVReturn display_link_render_callback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
4763+{
4764+ @autoreleasepool {
4765+ [((AllegroCocoaGLView *)displayLinkContext) render];
4766+ }
4767+ return kCVReturnSuccess;
4768+}
4769+
4770+struct MyVertex {
4771+ GLfloat x;
4772+ GLfloat y;
4773+};
4774+
4775+@interface AllegroCocoaGLView: NSOpenGLView {
4776+
4777+ BITMAP *_displayed_video_bitmap;
4778+
4779+ int _gameWidth;
4780+ int _gameHeight;
4781+ int _colourDepth;
4782+
4783+ GLuint _osx_screen_texture;
4784+ int _osx_screen_color_depth;
4785+ GLuint _osx_texture_format;
4786+ GLenum _osx_texture_storage;
4787+
4788+ CVDisplayLinkRef _displayLink;
4789+
4790+ struct MyVertex _gl_VertexCoords[4];
4791+ struct MyVertex _gl_TextureCoords[4];
4792+}
4793+
4794+@end
4795+
4796+@implementation AllegroCocoaGLView
4797+
4798+// Used to override default cursor
4799+- (void)resetCursorRects
4800+{
4801+ [super resetCursorRects];
4802+ [self addCursorRect: [self visibleRect] cursor: osx_cursor];
4803+ [osx_cursor setOnMouseEntered: YES];
4804+
4805+ if (osx_mouse_tracking_rect != -1) {
4806+ [self removeTrackingRect: osx_mouse_tracking_rect];
4807+ }
4808+
4809+ osx_mouse_tracking_rect = [self addTrackingRect: [self visibleRect]
4810+ owner: NSApp
4811+ userData: nil
4812+ assumeInside: YES];
4813+
4814+}
4815+
4816+/* Custom view: when created, select a suitable pixel format */
4817+- (id) initWithFrame: (NSRect) frame windowed:(BOOL)windowed backing: (BITMAP *) bmp
4818+{
4819+ _displayed_video_bitmap = bmp;
4820+ _gameWidth = bmp->w;
4821+ _gameHeight = bmp->h;
4822+ _colourDepth = bmp->vtable->color_depth;
4823+
4824+ NSOpenGLPixelFormat* pf = init_pixel_format(windowed);
4825+ if (pf) {
4826+ self = [super initWithFrame:frame pixelFormat: pf];
4827+ [pf release];
4828+ return self;
4829+ }
4830+ else
4831+ {
4832+ TRACE(PREFIX_W "Unable to find suitable pixel format\n");
4833+ }
4834+
4835+ return nil;
4836+}
4837+
4838+- (void)renewGState
4839+{
4840+ // Called whenever graphics state updated (such as window resize)
4841+
4842+ // OpenGL rendering is not synchronous with other rendering on the OSX.
4843+ // Therefore, call disableScreenUpdatesUntilFlush so the window server
4844+ // doesn't render non-OpenGL content in the window asynchronously from
4845+ // OpenGL content, which could cause flickering. (non-OpenGL content
4846+ // includes the title bar and drawing done by the app with other APIs)
4847+ [[self window] disableScreenUpdatesUntilFlush];
4848+
4849+ [super renewGState];
4850+}
4851+
4852+- (void)stopRendering
4853+{
4854+ CVDisplayLinkStop(_displayLink);
4855+
4856+ CVDisplayLinkRelease(_displayLink);
4857+ _displayLink = nil;
4858+
4859+ CGLLockContext([[self openGLContext] CGLContextObj]);
4860+ @try {
4861+ [[self openGLContext] makeCurrentContext];
4862+
4863+ _displayed_video_bitmap = nil;
4864+
4865+ [self delete_osx_screen_texture];
4866+
4867+ [NSOpenGLContext clearCurrentContext];
4868+ } @finally {
4869+ CGLUnlockContext([[self openGLContext] CGLContextObj]);
4870+ }
4871+
4872+ if (osx_mouse_tracking_rect != -1) {
4873+ [self removeTrackingRect: osx_mouse_tracking_rect];
4874+ }
4875+}
4876+
4877+- (void)dealloc
4878+{
4879+ [self stopRendering];
4880+
4881+ [super dealloc];
4882+
4883+}
4884+
4885+- (void)delete_osx_screen_texture
4886+{
4887+ if (_osx_screen_texture != 0)
4888+ {
4889+ glDeleteTextures(1, &_osx_screen_texture);
4890+ _osx_screen_texture = 0;
4891+ }
4892+}
4893+
4894+- (void) prepareOpenGL
4895+{
4896+ [super prepareOpenGL];
4897+
4898+ /* Print out OpenGL version info */
4899+ TRACE(PREFIX_I "OpenGL Version: %s\n", (AL_CONST char*)glGetString(GL_VERSION));
4900+ TRACE(PREFIX_I "Vendor: %s\n", (AL_CONST char*)glGetString(GL_VENDOR));
4901+ TRACE(PREFIX_I "Renderer: %s\n", (AL_CONST char*)glGetString(GL_RENDERER));
4902+
4903+ // enable vsync
4904+ GLint swapInt = 1;
4905+ [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
4906+
4907+ [self osx_gl_setup];
4908+
4909+ [[self openGLContext] flushBuffer];
4910+
4911+ CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
4912+
4913+ CVDisplayLinkSetOutputCallback(_displayLink, &display_link_render_callback, self);
4914+
4915+ // Select the display link most optimal for the current renderer of an OpenGL context
4916+ CGLContextObj cglContext = [[self openGLContext] CGLContextObj];
4917+ CGLPixelFormatObj cglPixelFormat = [[self pixelFormat] CGLPixelFormatObj];
4918+ CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(_displayLink, cglContext, cglPixelFormat);
4919+
4920+ CVDisplayLinkStart(_displayLink);
4921+}
4922+
4923+- (void) osx_gl_setup
4924+{
4925+ [self osx_gl_setup_arrays];
4926+
4927+ glDisable(GL_DITHER);
4928+ glDisable(GL_ALPHA_TEST);
4929+ glDisable(GL_BLEND);
4930+ glDisable(GL_STENCIL_TEST);
4931+ glDisable(GL_FOG);
4932+ glDisable(GL_TEXTURE_2D);
4933+ glDisable(GL_DEPTH_TEST);
4934+ glPixelZoom(1.0,1.0);
4935+
4936+ glShadeModel(GL_FLAT);
4937+ glEnable(GL_TEXTURE_RECTANGLE_ARB);
4938+
4939+ [self reshape];
4940+
4941+ glEnableClientState(GL_VERTEX_ARRAY);
4942+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINES);
4943+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4944+ glVertexPointer(2, GL_FLOAT, sizeof(struct MyVertex), (const GLvoid*)&_gl_VertexCoords[0]);
4945+ glTexCoordPointer(2, GL_FLOAT, sizeof(struct MyVertex), (const GLvoid*)&_gl_TextureCoords[0]);
4946+
4947+ glActiveTexture(GL_TEXTURE0);
4948+ [self osx_gl_create_screen_texture];
4949+}
4950+
4951+- (void) osx_gl_create_screen_texture
4952+{
4953+ [self delete_osx_screen_texture];
4954+
4955+ switch (_colourDepth) {
4956+ case 16:
4957+ _osx_texture_format = GL_RGB;
4958+ _osx_texture_storage = GL_UNSIGNED_SHORT_5_6_5;
4959+ break;
4960+ case 32:
4961+ _osx_texture_format = GL_RGBA;
4962+ _osx_texture_storage = GL_UNSIGNED_BYTE;
4963+ break;
4964+ default:
4965+ TRACE(PREFIX_I "unsupported color depth\n");
4966+ return;
4967+ }
4968+
4969+ glGenTextures(1, &_osx_screen_texture);
4970+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _osx_screen_texture);
4971+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4972+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4973+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4974+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4975+ glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGB, _gameWidth, _gameHeight, 0, _osx_texture_format, _osx_texture_storage, NULL);
4976+}
4977+
4978+- (void) osx_gl_setup_arrays
4979+{
4980+ _gl_VertexCoords[0].x = 0;
4981+ _gl_VertexCoords[0].y = 0;
4982+ _gl_TextureCoords[0].x = 0;
4983+ _gl_TextureCoords[0].y = _gameHeight;
4984+
4985+ _gl_VertexCoords[1].x = _gameWidth;
4986+ _gl_VertexCoords[1].y = 0;
4987+ _gl_TextureCoords[1].x = _gameWidth;
4988+ _gl_TextureCoords[1].y = _gameHeight;
4989+
4990+ _gl_VertexCoords[2].x = 0;
4991+ _gl_VertexCoords[2].y = _gameHeight;
4992+ _gl_TextureCoords[2].x = 0;
4993+ _gl_TextureCoords[2].y = 0;
4994+
4995+ _gl_VertexCoords[3].x = _gameWidth;
4996+ _gl_VertexCoords[3].y = _gameHeight;
4997+ _gl_TextureCoords[3].x = _gameWidth;
4998+ _gl_TextureCoords[3].y = 0;
4999+}
5000+
5001+- (void) drawRect: (NSRect) theRect
5002+{
5003+ [self render];
5004+}
5005+
5006+
5007+- (void) render
5008+{
5009+ [[self openGLContext] makeCurrentContext];
5010+
5011+ CGLLockContext([[self openGLContext] CGLContextObj]);
5012+ @try {
5013+
5014+ if (!_displayed_video_bitmap) { return; }
5015+
5016+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
5017+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
5018+
5019+ glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0,
5020+ 0, 0, _gameWidth, _gameHeight,
5021+ _osx_texture_format, _osx_texture_storage, _displayed_video_bitmap->line[0]);
5022+
5023+ glClear(GL_COLOR_BUFFER_BIT);
5024+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5025+
5026+ CGLFlushDrawable([[self openGLContext] CGLContextObj]);
5027+ } @finally {
5028+ CGLUnlockContext([[self openGLContext] CGLContextObj]);
5029+ }
5030+}
5031+
5032+
5033+- (void) reshape
5034+{
5035+ [super reshape];
5036+
5037+ CGLLockContext([[self openGLContext] CGLContextObj]);
5038+ @try {
5039+ [[self openGLContext] makeCurrentContext];
5040+
5041+ NSSize myNSWindowSize = [ self frame ].size;
5042+
5043+ float aspect = calc_aspect_ratio(NSMakeSize(_gameWidth, _gameHeight));
5044+
5045+ NSRect viewport;
5046+ viewport.size = NSMakeSize(myNSWindowSize.height * aspect, myNSWindowSize.height);
5047+ if (viewport.size.width > myNSWindowSize.width) {
5048+ viewport.size = NSMakeSize(myNSWindowSize.width, myNSWindowSize.width/aspect);
5049+ }
5050+ viewport.origin = NSMakePoint((myNSWindowSize.width - viewport.size.width)/2, (myNSWindowSize.height - viewport.size.height)/2 );
5051+
5052+ glViewport(viewport.origin.x, viewport.origin.y, viewport.size.width, viewport.size.height);
5053+ glScissor(viewport.origin.x, viewport.origin.y, viewport.size.width, viewport.size.height);
5054+
5055+ glMatrixMode(GL_PROJECTION);
5056+ glLoadIdentity();
5057+ glOrtho(0, _gameWidth - 1, 0, _gameHeight - 1, 0, 1);
5058+
5059+ glMatrixMode(GL_MODELVIEW);
5060+ glLoadIdentity();
5061+
5062+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
5063+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
5064+ } @finally {
5065+ CGLUnlockContext([[self openGLContext] CGLContextObj]);
5066+ }
5067+
5068+}
5069+
5070+@end
5071diff --git a/src/macosx/cocoashared.m b/src/macosx/cocoashared.m
5072new file mode 100644
5073index 0000000..733666e
5074--- /dev/null
5075+++ b/src/macosx/cocoashared.m
5076@@ -0,0 +1,170 @@
5077+#include "allegro.h"
5078+#include "allegro/internal/aintern.h"
5079+#include "allegro/platform/aintosx.h"
5080+
5081+#ifndef ALLEGRO_MACOSX
5082+#error something is wrong with the makefile
5083+#endif
5084+
5085+// Quickdraw specific
5086+#ifdef ENABLE_QUICKDRAW
5087+void osx_qz_mark_dirty();
5088+void prepare_window_for_animation(int refresh_view);
5089+#endif
5090+
5091+extern void _hack_stop_keyboard_repeat();
5092+extern void osx_mouse_available();
5093+extern void osx_mouse_not_available();
5094+
5095+@implementation AllegroWindow
5096+
5097+#ifdef ENABLE_QUICKDRAW
5098+/* display:
5099+ * Called when the window is about to be deminiaturized.
5100+ */
5101+- (void)display
5102+{
5103+ [super display];
5104+ prepare_window_for_animation(TRUE);
5105+}
5106+
5107+
5108+
5109+/* miniaturize:
5110+ * Called when the window is miniaturized.
5111+ */
5112+- (void)miniaturize: (id)sender
5113+{
5114+ prepare_window_for_animation(FALSE);
5115+ [super miniaturize: sender];
5116+}
5117+#endif
5118+
5119+- (BOOL)canBecomeKeyWindow
5120+{
5121+ return YES;
5122+}
5123+
5124+- (BOOL)canBecomeMainWindow
5125+{
5126+ return YES;
5127+}
5128+
5129+@end
5130+
5131+static int _isFullScreen = 0;
5132+
5133+@implementation AllegroWindowDelegate
5134+
5135+/* windowShouldClose:
5136+ * Called when the user attempts to close the window.
5137+ * Default behaviour is to call the user callback (if any) and deny closing.
5138+ */
5139+- (BOOL)windowShouldClose: (id)sender
5140+{
5141+ if (osx_window_close_hook)
5142+ osx_window_close_hook();
5143+ return NO;
5144+}
5145+
5146+
5147+
5148+/* windowDidDeminiaturize:
5149+ * Called when the window deminiaturization animation ends; marks the whole
5150+ * window contents as dirty, so it is updated on next refresh.
5151+ */
5152+- (void)windowDidDeminiaturize: (NSNotification *)aNotification
5153+{
5154+#ifdef ENABLE_QUICKDRAW
5155+ _unix_lock_mutex(osx_window_mutex);
5156+ osx_qz_mark_dirty();
5157+ _unix_unlock_mutex(osx_window_mutex);
5158+#endif
5159+}
5160+
5161+// We call osx_mouse_* here because we sometimes don't detect mouse entering window area if alt-tabbing from another context
5162+
5163+- (void)windowDidBecomeMain:(NSNotification *)notification
5164+{
5165+ if (_isFullScreen) {
5166+ [[NSApplication sharedApplication] setPresentationOptions:NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationHideDock];
5167+ }
5168+}
5169+
5170+- (void)windowDidResignMain:(NSNotification *)notification
5171+{
5172+}
5173+
5174+/* windowDidBecomeKey:
5175+ * Sent by the default notification center immediately after an NSWindow
5176+ * object has become key.
5177+ */
5178+- (void)windowDidBecomeKey:(NSNotification *)notification
5179+{
5180+ if (_isFullScreen) {
5181+ [[NSApplication sharedApplication] setPresentationOptions:NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationHideDock];
5182+ }
5183+ _unix_lock_mutex(osx_skip_events_processing_mutex);
5184+ osx_skip_events_processing = FALSE;
5185+ _unix_unlock_mutex(osx_skip_events_processing_mutex);
5186+
5187+ osx_mouse_available();
5188+}
5189+
5190+/* windowDidResignKey:
5191+ * Sent by the default notification center immediately after an NSWindow
5192+ * object has resigned its status as key window.
5193+ */
5194+- (void)windowDidResignKey:(NSNotification *)notification
5195+{
5196+ _unix_lock_mutex(osx_skip_events_processing_mutex);
5197+ osx_skip_events_processing = TRUE;
5198+ _unix_unlock_mutex(osx_skip_events_processing_mutex);
5199+
5200+ osx_mouse_not_available();
5201+
5202+ // Stop repeating keys since we might not actually see the "key up" event.
5203+ _hack_stop_keyboard_repeat();
5204+}
5205+
5206+- (void)windowWillEnterFullScreen:(NSNotification *)notification
5207+{
5208+ [[NSApplication sharedApplication] setPresentationOptions:NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationHideDock];
5209+ _hack_stop_keyboard_repeat();
5210+}
5211+
5212+- (void)windowWillExitFullScreen:(NSNotification *)notification
5213+{
5214+ [[NSApplication sharedApplication] setPresentationOptions:NSApplicationPresentationDefault];
5215+ _hack_stop_keyboard_repeat();
5216+}
5217+
5218+- (void)windowDidEnterFullScreen:(NSNotification *)notification
5219+{
5220+ _isFullScreen = 1;
5221+}
5222+
5223+- (void)windowDidExitFullScreen:(NSNotification *)notification
5224+{
5225+ _isFullScreen = 0;
5226+}
5227+
5228+@end
5229+
5230+void runOnMainQueueWithoutDeadlocking(void (^block)(void))
5231+{
5232+ if ([NSThread isMainThread])
5233+ {
5234+ block();
5235+ }
5236+ else
5237+ {
5238+ dispatch_sync(dispatch_get_main_queue(), block);
5239+ }
5240+}
5241+
5242+/* Local variables: */
5243+/* c-basic-offset: 3 */
5244+/* indent-tabs-mode: nil */
5245+/* c-file-style: "linux" */
5246+/* End: */
5247diff --git a/src/macosx/drivers.m b/src/macosx/drivers.m
5248index 9284d67..8f28f7f 100644
5249--- a/src/macosx/drivers.m
5250+++ b/src/macosx/drivers.m
5251@@ -47,20 +47,22 @@ _DRIVER_INFO _mouse_driver_list[] =
5252
5253
5254 BEGIN_GFX_DRIVER_LIST
5255+#ifdef ENABLE_QUICKDRAW
5256 { GFX_QUARTZ_FULLSCREEN, &gfx_quartz_full, TRUE },
5257 { GFX_QUARTZ_WINDOW, &gfx_quartz_window, TRUE },
5258+#endif
5259+{ GFX_COCOAGL_WINDOW, &gfx_cocoagl_window, TRUE },
5260+{ GFX_COCOAGL_FULLSCREEN, &gfx_cocoagl_full, TRUE },
5261 END_GFX_DRIVER_LIST
5262
5263
5264 BEGIN_DIGI_DRIVER_LIST
5265 { DIGI_CORE_AUDIO, &digi_core_audio, TRUE },
5266-{ DIGI_SOUND_MANAGER, &digi_sound_manager, TRUE },
5267 END_DIGI_DRIVER_LIST
5268
5269
5270 BEGIN_MIDI_DRIVER_LIST
5271 { MIDI_CORE_AUDIO, &midi_core_audio, TRUE },
5272-{ MIDI_QUICKTIME, &midi_quicktime, TRUE },
5273 END_MIDI_DRIVER_LIST
5274
5275
5276diff --git a/src/macosx/main.m b/src/macosx/main.m
5277index 33f60fa..602a3b9 100644
5278--- a/src/macosx/main.m
5279+++ b/src/macosx/main.m
5280@@ -34,10 +34,11 @@ extern char **__crt0_argv;
5281 extern void *_mangled_main_address;
5282
5283 static char *arg0, *arg1 = NULL;
5284-static int refresh_rate = 70;
5285
5286 static volatile BOOL ready_to_terminate = NO;
5287
5288+extern void osx_add_event_monitor();
5289+
5290 static BOOL in_bundle(void)
5291 {
5292 /* This comes from the ADC tips & tricks section: how to detect if the app
5293@@ -48,12 +49,15 @@ static BOOL in_bundle(void)
5294 FSCatalogInfo processInfo;
5295 GetProcessBundleLocation(&psn, &processRef);
5296 FSGetCatalogInfo(&processRef, kFSCatInfoNodeFlags, &processInfo, NULL, NULL, NULL);
5297- if (processInfo.nodeFlags & kFSNodeIsDirectoryMask)
5298+ if (processInfo.nodeFlags & kFSNodeIsDirectoryMask)
5299 return YES;
5300 else
5301 return NO;
5302 }
5303
5304+@interface AllegroAppDelegate ()
5305+@end
5306+
5307 @implementation AllegroAppDelegate
5308
5309 - (BOOL)application: (NSApplication *)theApplication openFile: (NSString *)filename
5310@@ -63,14 +67,13 @@ static BOOL in_bundle(void)
5311 }
5312
5313
5314-
5315 /* applicationDidFinishLaunching:
5316 * Called when the app is ready to run. This runs the system events pump and
5317 * updates the app window if it exists.
5318 */
5319 - (void)applicationDidFinishLaunching: (NSNotification *)aNotification
5320 {
5321- NSAutoreleasePool *pool = NULL;
5322+
5323 CFDictionaryRef mode;
5324 NSString* exename, *resdir;
5325 NSFileManager* fm;
5326@@ -79,9 +82,8 @@ static BOOL in_bundle(void)
5327 /* create mutex */
5328 osx_event_mutex = _unix_create_mutex();
5329 osx_skip_events_processing_mutex = _unix_create_mutex();
5330-
5331- pool = [[NSAutoreleasePool alloc] init];
5332- if (in_bundle() == YES)
5333+
5334+ if (in_bundle() == YES)
5335 {
5336 /* In a bundle, so chdir to the containing directory,
5337 * or to the 'magic' resource directory if it exists.
5338@@ -92,7 +94,7 @@ static BOOL in_bundle(void)
5339 resdir = [[osx_bundle resourcePath] stringByAppendingPathComponent: exename];
5340 fm = [NSFileManager defaultManager];
5341 if ([fm fileExistsAtPath: resdir isDirectory: &isDir] && isDir) {
5342- /* Yes, it exists inside the bundle */
5343+ // Yes, it exists inside the bundle
5344 [fm changeCurrentDirectoryPath: resdir];
5345 }
5346 else {
5347@@ -106,10 +108,10 @@ static BOOL in_bundle(void)
5348 arg0 = strdup([[osx_bundle bundlePath] fileSystemRepresentation]);
5349 if (arg1) {
5350 static char *args[2];
5351- args[0] = arg0;
5352- args[1] = arg1;
5353- __crt0_argv = args;
5354- __crt0_argc = 2;
5355+ args[0] = arg0;
5356+ args[1] = arg1;
5357+ __crt0_argv = args;
5358+ __crt0_argc = 2;
5359 }
5360 else {
5361 __crt0_argv = &arg0;
5362@@ -117,57 +119,19 @@ static BOOL in_bundle(void)
5363 }
5364 }
5365 /* else: not in a bundle so don't chdir */
5366-
5367- mode = CGDisplayCurrentMode(kCGDirectMainDisplay);
5368- CFNumberGetValue(CFDictionaryGetValue(mode, kCGDisplayRefreshRate), kCFNumberSInt32Type, &refresh_rate);
5369- if (refresh_rate <= 0)
5370- refresh_rate = 70;
5371-
5372+
5373+ osx_add_event_monitor();
5374+
5375 [NSThread detachNewThreadSelector: @selector(app_main:)
5376 toTarget: [AllegroAppDelegate class]
5377 withObject: nil];
5378-
5379- while (!ready_to_terminate) {
5380- if (osx_gfx_mode == OSX_GFX_WINDOW)
5381- osx_update_dirty_lines();
5382- _unix_lock_mutex(osx_event_mutex);
5383- if (osx_gfx_mode == OSX_GFX_FULL) {
5384- if ((osx_palette) && (osx_palette_dirty)) {
5385- CGDisplaySetPalette(kCGDirectMainDisplay, osx_palette);
5386- osx_palette_dirty = FALSE;
5387- }
5388- }
5389- osx_event_handler();
5390- _unix_unlock_mutex(osx_event_mutex);
5391- usleep(1000000 / refresh_rate);
5392- }
5393-
5394- [pool release];
5395- _unix_destroy_mutex(osx_event_mutex);
5396-
5397- [NSApp terminate:self];
5398 }
5399
5400-
5401-
5402 /* applicationDidChangeScreenParameters:
5403 * Invoked when the screen did change resolution/color depth.
5404 */
5405 - (void)applicationDidChangeScreenParameters: (NSNotification *)aNotification
5406 {
5407- CFDictionaryRef mode;
5408- int new_refresh_rate;
5409-
5410- if ((osx_window) && (osx_gfx_mode == OSX_GFX_WINDOW))
5411- {
5412- osx_setup_colorconv_blitter();
5413- [osx_window display];
5414- }
5415- mode = CGDisplayCurrentMode(kCGDirectMainDisplay);
5416- CFNumberGetValue(CFDictionaryGetValue(mode, kCGDisplayRefreshRate), kCFNumberSInt32Type, &new_refresh_rate);
5417- if (new_refresh_rate <= 0)
5418- new_refresh_rate = 70;
5419- refresh_rate = new_refresh_rate;
5420 }
5421
5422
5423@@ -179,22 +143,22 @@ static void call_user_main(void)
5424 real_main(__crt0_argc, __crt0_argv);
5425 allegro_exit();
5426 ready_to_terminate = YES;
5427+ runOnMainQueueWithoutDeadlocking(^{
5428+ [NSApp terminate:nil];
5429+ });
5430 }
5431
5432-
5433-
5434 /* app_main:
5435 * Thread dedicated to the user program; real main() gets called here.
5436 */
5437 + (void)app_main: (id)arg
5438 {
5439- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
5440- call_user_main();
5441- [pool release];
5442+ @autoreleasepool {
5443+ call_user_main();
5444+ }
5445 }
5446
5447
5448-
5449 /* applicationShouldTerminate:
5450 * Called upon Command-Q or "Quit" menu item selection.
5451 * If the window close callback is set, calls it, otherwise does
5452@@ -242,37 +206,23 @@ static void call_user_main(void)
5453
5454
5455
5456-/* This prevents warnings that 'NSApplication might not
5457- * respond to setAppleMenu' on OS X 10.4
5458- */
5459-@interface NSApplication(AllegroOSX)
5460-- (void)setAppleMenu:(NSMenu *)menu;
5461-@end
5462-
5463-
5464-
5465 /* main:
5466 * Replacement for main function.
5467 */
5468 int main(int argc, char *argv[])
5469 {
5470- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
5471- AllegroAppDelegate *app_delegate = [[AllegroAppDelegate alloc] init];
5472+ @autoreleasepool {
5473+
5474 NSMenu *menu;
5475 NSMenuItem *menu_item, *temp_item;
5476
5477- /* I don't know what that NSAutoreleasePool line does but the variable was
5478- * otherwise unused --pw
5479- */
5480- (void)pool;
5481-
5482 __crt0_argc = argc;
5483 __crt0_argv = argv;
5484-
5485- if (!osx_bootstrap_ok()) /* not safe to use NSApplication */
5486- call_user_main();
5487-
5488- [NSApplication sharedApplication];
5489+
5490+ AllegroAppDelegate *app_delegate = [[AllegroAppDelegate alloc] init];
5491+
5492+ [NSApplication sharedApplication];
5493+ [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
5494
5495 /* Load the main menu nib if possible */
5496 if ((!in_bundle()) || ([NSBundle loadNibNamed: @"MainMenu"
5497@@ -281,39 +231,40 @@ int main(int argc, char *argv[])
5498 /* Didn't load the nib; create a default menu programmatically */
5499 NSString* title = nil;
5500 NSDictionary* app_dictionary = [[NSBundle mainBundle] infoDictionary];
5501- if (app_dictionary)
5502+ if (app_dictionary)
5503 {
5504 title = [app_dictionary objectForKey: @"CFBundleName"];
5505 }
5506- if (title == nil)
5507+ if (title == nil)
5508 {
5509 title = [[NSProcessInfo processInfo] processName];
5510 }
5511 [NSApp setMainMenu: [[NSMenu allocWithZone: [NSMenu menuZone]] initWithTitle: @"temp"]];
5512 menu = [[NSMenu allocWithZone: [NSMenu menuZone]] initWithTitle: @"temp"];
5513 temp_item = [[NSMenuItem allocWithZone: [NSMenu menuZone]]
5514- initWithTitle: @"temp"
5515- action: NULL
5516- keyEquivalent: @""];
5517+ initWithTitle: @"temp"
5518+ action: NULL
5519+ keyEquivalent: @""];
5520 [[NSApp mainMenu] addItem: temp_item];
5521 [[NSApp mainMenu] setSubmenu: menu forItem: temp_item];
5522 [NSApp setAppleMenu: menu];
5523 NSString *quit = [@"Quit " stringByAppendingString: title];
5524 menu_item = [[NSMenuItem allocWithZone: [NSMenu menuZone]]
5525- initWithTitle: quit
5526- action: @selector(quitAction:)
5527- keyEquivalent: @"q"];
5528+ initWithTitle: quit
5529+ action: @selector(quitAction:)
5530+ keyEquivalent: @"q"];
5531 [menu_item setKeyEquivalentModifierMask: NSCommandKeyMask];
5532 [menu_item setTarget: app_delegate];
5533 [menu addItem: menu_item];
5534 }
5535
5536 [NSApp setDelegate: app_delegate];
5537-
5538+
5539 [NSApp run];
5540 /* Can never get here */
5541-
5542+
5543 return 0;
5544+ }
5545 }
5546
5547 /* Local variables: */
5548diff --git a/src/macosx/quartz.m b/src/macosx/quartz.m
5549index e7e76e7..09fc09b 100644
5550--- a/src/macosx/quartz.m
5551+++ b/src/macosx/quartz.m
5552@@ -49,7 +49,7 @@ void setup_direct_shifts(void)
5553 _rgb_b_shift_32 = 0;
5554 }
5555
5556-
5557+#ifdef ENABLE_QUICKDRAW
5558
5559 /* osx_qz_write_line:
5560 * Line switcher for video bitmaps.
5561@@ -254,3 +254,5 @@ void osx_qz_blit_to_self(BITMAP *source, BITMAP *dest, int source_x, int source_
5562 if (!(dest->id & BMP_ID_LOCKED))
5563 UnlockPortBits(BMP_EXTRA(dest)->port);
5564 }
5565+
5566+#endif
5567\ No newline at end of file
5568diff --git a/src/macosx/qzfull.m b/src/macosx/qzfull.m
5569index 7df89ad..d4f967b 100644
5570--- a/src/macosx/qzfull.m
5571+++ b/src/macosx/qzfull.m
5572@@ -24,6 +24,7 @@
5573 #error something is wrong with the makefile
5574 #endif
5575
5576+#ifdef ENABLE_QUICKDRAW
5577
5578 #define FADE_STEPS 16
5579
5580@@ -455,3 +456,4 @@ static GFX_MODE_LIST *osx_qz_fetch_mode_list(void)
5581 return gfx_mode_list;
5582 }
5583
5584+#endif
5585diff --git a/src/macosx/qzmouse.m b/src/macosx/qzmouse.m
5586index 5da32af..0f264b1 100644
5587--- a/src/macosx/qzmouse.m
5588+++ b/src/macosx/qzmouse.m
5589@@ -103,7 +103,7 @@ void osx_mouse_handler(int ax, int ay, int x, int y, int z, int buttons)
5590
5591 if (osx_cursor != current_cursor) {
5592 if (osx_window) {
5593- NSView* vw = [osx_window contentView];
5594+ NSView *vw = [osx_window contentView];
5595 [osx_window invalidateCursorRectsForView: vw];
5596 }
5597 else {
5598@@ -211,8 +211,7 @@ static void osx_mouse_exit(void)
5599 static void osx_mouse_position(int x, int y)
5600 {
5601 CGPoint point;
5602- NSRect frame;
5603- int screen_height;
5604+ NSRect frame, screen_frame;
5605
5606 _unix_lock_mutex(osx_event_mutex);
5607
5608@@ -220,13 +219,19 @@ static void osx_mouse_position(int x, int y)
5609 _mouse_y = point.y = y;
5610
5611 if (osx_window) {
5612- CFNumberGetValue(CFDictionaryGetValue(CGDisplayCurrentMode(kCGDirectMainDisplay), kCGDisplayHeight), kCFNumberSInt32Type, &screen_height);
5613+ screen_frame = [[NSScreen mainScreen] frame];
5614 frame = [osx_window frame];
5615+ // scale position
5616+ point.x *= (frame.size.width / gfx_driver->w);
5617+ point.y *= (frame.size.height / gfx_driver->h);
5618+
5619 point.x += frame.origin.x;
5620- point.y += (screen_height - (frame.origin.y + gfx_driver->h));
5621+ point.y += (screen_frame.size.height - (frame.origin.y + frame.size.height));
5622+ }
5623+
5624+ if (osx_gfx_mode != OSX_GFX_NONE) {
5625+ CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, point);
5626 }
5627-
5628- CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, point);
5629
5630 mymickey_x = mymickey_y = 0;
5631 osx_mouse_warped = TRUE;
5632@@ -274,19 +279,12 @@ int osx_mouse_set_sprite(BITMAP *sprite, int x, int y)
5633 {
5634 int ix, iy;
5635 int sw, sh;
5636-
5637+
5638 if (!sprite)
5639 return -1;
5640 sw = sprite->w;
5641 sh = sprite->h;
5642- if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_2) {
5643- // Before MacOS X 10.3, NSCursor can handle only 16x16 cursor sprites
5644- // Pad to 16x16 or fail if the sprite is already larger.
5645- if (sw>16 || sh>16)
5646- return -1;
5647- sh = sw = 16;
5648- }
5649-
5650+
5651 // Delete the old cursor (OK to send a message to nil)
5652 [cursor release];
5653
5654diff --git a/src/macosx/qzwindow.m b/src/macosx/qzwindow.m
5655index 8e4a606..e62e6ae 100644
5656--- a/src/macosx/qzwindow.m
5657+++ b/src/macosx/qzwindow.m
5658@@ -24,6 +24,7 @@
5659 #error something is wrong with the makefile
5660 #endif
5661
5662+#ifdef ENABLE_QUICKDRAW
5663
5664 static BITMAP *osx_qz_window_init(int, int, int, int, int);
5665 static void osx_qz_window_exit(BITMAP *);
5666@@ -56,8 +57,6 @@ static GFX_VTABLE _special_vtable; /* special vtable for active video page */
5667 static GFX_VTABLE _unspecial_vtable; /* special vtable for inactive video page */
5668 static BITMAP* current_video_page = NULL;
5669
5670-void* osx_window_mutex;
5671-
5672
5673 GFX_DRIVER gfx_quartz_window =
5674 {
5675@@ -97,8 +96,6 @@ GFX_DRIVER gfx_quartz_window =
5676 TRUE
5677 };
5678
5679-
5680-
5681 /* prepare_window_for_animation:
5682 * Prepares the window for a (de)miniaturization animation.
5683 * Called by the window display method when the window is about to be
5684@@ -107,124 +104,41 @@ GFX_DRIVER gfx_quartz_window =
5685 * When called from the miniaturize window method, only the alpha value
5686 * is updated.
5687 */
5688-static void prepare_window_for_animation(int refresh_view)
5689-{
5690- struct GRAPHICS_RECT src_gfx_rect, dest_gfx_rect;
5691- unsigned int *addr;
5692- int pitch, y, x;
5693-
5694- _unix_lock_mutex(osx_window_mutex);
5695- while (![qd_view lockFocusIfCanDraw]);
5696- while (!QDDone([qd_view qdPort]));
5697- LockPortBits([qd_view qdPort]);
5698- pitch = GetPixRowBytes(GetPortPixMap([qd_view qdPort])) / 4;
5699- addr = (unsigned int *)GetPixBaseAddr(GetPortPixMap([qd_view qdPort])) +
5700- ((int)([osx_window frame].size.height) - gfx_quartz_window.h) * pitch;
5701- if (refresh_view && colorconv_blitter) {
5702- src_gfx_rect.width = gfx_quartz_window.w;
5703- src_gfx_rect.height = gfx_quartz_window.h;
5704- src_gfx_rect.pitch = pseudo_screen_pitch;
5705- src_gfx_rect.data = pseudo_screen_addr;
5706- dest_gfx_rect.pitch = pitch * 4;
5707- dest_gfx_rect.data = addr;
5708- colorconv_blitter(&src_gfx_rect, &dest_gfx_rect);
5709- }
5710- for (y = gfx_quartz_window.h; y; y--) {
5711- for (x = 0; x < gfx_quartz_window.w; x++)
5712- *(addr + x) |= 0xff000000;
5713- addr += pitch;
5714- }
5715- UnlockPortBits([qd_view qdPort]);
5716- [qd_view unlockFocus];
5717- _unix_unlock_mutex(osx_window_mutex);
5718-}
5719-
5720-
5721-
5722-@implementation AllegroWindow
5723-
5724-/* display:
5725- * Called when the window is about to be deminiaturized.
5726- */
5727-- (void)display
5728-{
5729- [super display];
5730- if (desktop_depth == 32)
5731- prepare_window_for_animation(TRUE);
5732-}
5733-
5734-
5735-
5736-/* miniaturize:
5737- * Called when the window is miniaturized.
5738- */
5739-- (void)miniaturize: (id)sender
5740-{
5741- if (desktop_depth == 32)
5742- prepare_window_for_animation(FALSE);
5743- [super miniaturize: sender];
5744-}
5745-
5746-@end
5747-
5748-
5749-
5750-@implementation AllegroWindowDelegate
5751-
5752-/* windowShouldClose:
5753- * Called when the user attempts to close the window.
5754- * Default behaviour is to call the user callback (if any) and deny closing.
5755- */
5756-- (BOOL)windowShouldClose: (id)sender
5757+void prepare_window_for_animation(int refresh_view)
5758 {
5759- if (osx_window_close_hook)
5760- osx_window_close_hook();
5761- return NO;
5762+ struct GRAPHICS_RECT src_gfx_rect, dest_gfx_rect;
5763+ unsigned int *addr;
5764+ int pitch, y, x;
5765+
5766+ if (desktop_depth != 32)
5767+ return;
5768+
5769+ _unix_lock_mutex(osx_window_mutex);
5770+ while (![qd_view lockFocusIfCanDraw]);
5771+ while (!QDDone([qd_view qdPort]));
5772+ LockPortBits([qd_view qdPort]);
5773+ pitch = GetPixRowBytes(GetPortPixMap([qd_view qdPort])) / 4;
5774+ addr = (unsigned int *)GetPixBaseAddr(GetPortPixMap([qd_view qdPort])) +
5775+ ((int)([osx_window frame].size.height) - gfx_quartz_window.h) * pitch;
5776+ if (refresh_view && colorconv_blitter) {
5777+ src_gfx_rect.width = gfx_quartz_window.w;
5778+ src_gfx_rect.height = gfx_quartz_window.h;
5779+ src_gfx_rect.pitch = pseudo_screen_pitch;
5780+ src_gfx_rect.data = pseudo_screen_addr;
5781+ dest_gfx_rect.pitch = pitch * 4;
5782+ dest_gfx_rect.data = addr;
5783+ colorconv_blitter(&src_gfx_rect, &dest_gfx_rect);
5784+ }
5785+ for (y = gfx_quartz_window.h; y; y--) {
5786+ for (x = 0; x < gfx_quartz_window.w; x++)
5787+ *(addr + x) |= 0xff000000;
5788+ addr += pitch;
5789+ }
5790+ UnlockPortBits([qd_view qdPort]);
5791+ [qd_view unlockFocus];
5792+ _unix_unlock_mutex(osx_window_mutex);
5793 }
5794
5795-
5796-
5797-/* windowDidDeminiaturize:
5798- * Called when the window deminiaturization animation ends; marks the whole
5799- * window contents as dirty, so it is updated on next refresh.
5800- */
5801-- (void)windowDidDeminiaturize: (NSNotification *)aNotification
5802-{
5803- _unix_lock_mutex(osx_window_mutex);
5804- memset(dirty_lines, 1, gfx_quartz_window.h);
5805- _unix_unlock_mutex(osx_window_mutex);
5806-}
5807-
5808-
5809-
5810-/* windowDidBecomeKey:
5811- * Sent by the default notification center immediately after an NSWindow
5812- * object has become key.
5813- */
5814-- (void)windowDidBecomeKey:(NSNotification *)notification
5815-{
5816- _unix_lock_mutex(osx_skip_events_processing_mutex);
5817- osx_skip_events_processing = FALSE;
5818- _unix_unlock_mutex(osx_skip_events_processing_mutex);
5819-}
5820-
5821-
5822-
5823-/* windowDidResignKey:
5824- * Sent by the default notification center immediately after an NSWindow
5825- * object has resigned its status as key window.
5826- */
5827-- (void)windowDidResignKey:(NSNotification *)notification
5828-{
5829- _unix_lock_mutex(osx_skip_events_processing_mutex);
5830- osx_skip_events_processing = TRUE;
5831- _unix_unlock_mutex(osx_skip_events_processing_mutex);
5832-}
5833-
5834-@end
5835-
5836-
5837-
5838 @implementation AllegroView
5839
5840 /* resetCursorRects:
5841@@ -269,7 +183,10 @@ static void osx_qz_release_win(BITMAP *bmp)
5842 _unix_unlock_mutex(osx_window_mutex);
5843 }
5844
5845-
5846+void osx_qz_mark_dirty()
5847+{
5848+ memset(dirty_lines, 1, gfx_quartz_window.h);
5849+}
5850
5851 /* osx_qz_write_line_win:
5852 * Line switcher for Quartz windowed mode.
5853@@ -810,6 +727,9 @@ static void osx_destroy_video_bitmap(BITMAP* bm)
5854 }
5855 // Otherwise it wasn't a video page
5856 }
5857+
5858+#endif
5859+
5860 /* Local variables: */
5861 /* c-basic-offset: 3 */
5862 /* indent-tabs-mode: nil */
5863diff --git a/src/macosx/system.m b/src/macosx/system.m
5864index 1b01839..6b15e5b 100644
5865--- a/src/macosx/system.m
5866+++ b/src/macosx/system.m
5867@@ -26,8 +26,6 @@
5868
5869 #ifndef SCAN_DEPEND
5870 #include <CoreFoundation/CoreFoundation.h>
5871-#include <mach/mach_port.h>
5872-#include <servers/bootstrap.h>
5873 #endif
5874
5875
5876@@ -137,268 +135,310 @@ SYSTEM_DRIVER system_macosx =
5877 static RETSIGTYPE osx_signal_handler(int num)
5878 {
5879 _unix_unlock_mutex(osx_event_mutex);
5880- _unix_unlock_mutex(osx_window_mutex);
5881-
5882+
5883 allegro_exit();
5884-
5885+
5886 _unix_destroy_mutex(osx_event_mutex);
5887- _unix_destroy_mutex(osx_window_mutex);
5888-
5889+
5890 fprintf(stderr, "Shutting down Allegro due to signal #%d\n", num);
5891 raise(num);
5892 }
5893
5894
5895-
5896-/* osx_event_handler:
5897- * Event handling function; gets repeatedly called inside a dedicated thread.
5898- */
5899-void osx_event_handler()
5900+static void osx_scale_mouse(NSPointPointer position, const NSRectPointer window, const NSRectPointer view)
5901 {
5902- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
5903- NSEvent *event;
5904- NSDate *distant_past = [NSDate distantPast];
5905+ // flip the vertical to top down
5906+ position->y = window->size.height - position->y;
5907+ if (!NSEqualSizes(window->size, view->size)) {
5908+ position->x = position->x / window->size.width * view->size.width;
5909+ position->y = position->y / window->size.height * view->size.height;
5910+ }
5911+}
5912+
5913+static NSPoint locationInView (NSEvent *event, NSView *inTermsOfView) {
5914+ NSPoint windowLocation;
5915+
5916+ NSWindow *viewWindow = [inTermsOfView window];
5917+
5918+ if (event) {
5919+ NSWindow *eventWindow = [event window];
5920+
5921+ if (eventWindow) {
5922+ if (eventWindow == viewWindow) {
5923+ windowLocation = [event locationInWindow];
5924+ } else {
5925+ // event from a completely different window.. convert to global and back to _our_ window
5926+ NSPoint globalLocation = [eventWindow convertBaseToScreen: windowLocation];
5927+ windowLocation = [viewWindow convertScreenToBase: globalLocation];
5928+ }
5929+ } else {
5930+ // if window is nil, then it's assumed to be screen coordinates.
5931+ NSPoint globalLocation = [event locationInWindow];
5932+ windowLocation = [viewWindow convertScreenToBase: globalLocation ];
5933+ }
5934+ } else {
5935+ NSPoint globalLocation = [NSEvent mouseLocation];
5936+ windowLocation = [viewWindow convertScreenToBase: globalLocation ];
5937+ }
5938+
5939+ return [inTermsOfView convertPoint: windowLocation fromView: nil];
5940+}
5941+
5942+
5943+static BOOL cursor_hidden = NO; // need to keep track because nscursor requires balanced hide/unhide
5944+static int dx = 0, dy = 0, dz = 0;
5945+static int mx=0;
5946+static int my=0;
5947+static int buttons = 0;
5948+
5949+void update_cursor() {
5950+ if (!_mouse_installed) { return; }
5951+ if (!_mouse_on) { return; }
5952+
5953 NSPoint point;
5954 NSRect frame, view;
5955- int dx = 0, dy = 0, dz = 0;
5956- int mx=_mouse_x;
5957- int my=_mouse_y;
5958- static int buttons = 0;
5959- int event_type;
5960- BOOL gotmouseevent = NO;
5961-
5962- while ((event = [NSApp nextEventMatchingMask: NSAnyEventMask
5963- untilDate: distant_past
5964- inMode: NSDefaultRunLoopMode
5965- dequeue: YES]) != nil)
5966- {
5967- _unix_lock_mutex(osx_skip_events_processing_mutex);
5968- int skip_events_processing = osx_skip_events_processing;
5969- _unix_unlock_mutex(osx_skip_events_processing_mutex);
5970-
5971- if ((skip_events_processing) || (osx_gfx_mode == OSX_GFX_NONE)) {
5972- [NSApp sendEvent: event];
5973- continue;
5974- }
5975-
5976- view = NSMakeRect(0, 0, gfx_driver->w, gfx_driver->h);
5977- point = [event locationInWindow];
5978- if (osx_window)
5979- {
5980- frame = [[osx_window contentView] frame];
5981- }
5982- else
5983- {
5984- frame = [[NSScreen mainScreen] frame];
5985+ view = NSMakeRect(0, 0, gfx_driver->w, gfx_driver->h);
5986+
5987+ point = NSMakePoint(0, 0);
5988+ if (osx_window) {
5989+ frame = [[osx_window contentView] frame];
5990+ point = locationInView (nil, [osx_window contentView]);
5991+ } else {
5992+ frame = [[NSScreen mainScreen] frame];
5993+ }
5994+ osx_scale_mouse(&point, &frame, &view);
5995+
5996+ if (NSPointInRect(point, view)) {
5997+
5998+ // hide the cursor because sometimes osx will reshow cursor for no reason
5999+ if (!cursor_hidden) {
6000+ [NSCursor hide];
6001+ cursor_hidden = YES;
6002+ } else {
6003+ // if dock is shown, having the mouse near the edge might show the cursor, so unhide/hide
6004+ [NSCursor unhide];
6005+ [NSCursor hide];
6006 }
6007- event_type = [event type];
6008- switch (event_type) {
6009-
6010- case NSKeyDown:
6011- if (_keyboard_installed)
6012- osx_keyboard_handler(TRUE, event);
6013- if ([event modifierFlags] & NSCommandKeyMask)
6014- [NSApp sendEvent: event];
6015- break;
6016-
6017- case NSKeyUp:
6018- if (_keyboard_installed)
6019- osx_keyboard_handler(FALSE, event);
6020- if ([event modifierFlags] & NSCommandKeyMask)
6021- [NSApp sendEvent: event];
6022- break;
6023-
6024- case NSFlagsChanged:
6025- if (_keyboard_installed)
6026- osx_keyboard_modifiers([event modifierFlags]);
6027- break;
6028-
6029- case NSLeftMouseDown:
6030- case NSOtherMouseDown:
6031- case NSRightMouseDown:
6032- if (![NSApp isActive]) {
6033- /* App is regaining focus */
6034- if (_mouse_installed) {
6035- if ((osx_window) && (NSPointInRect(point, view))) {
6036- mx = point.x;
6037- my = frame.size.height - point.y;
6038- buttons = 0;
6039- _mouse_on = TRUE;
6040- }
6041- }
6042- if (osx_window)
6043- [osx_window invalidateCursorRectsForView: [osx_window contentView]];
6044- if (_keyboard_installed)
6045- osx_keyboard_focused(TRUE, 0);
6046- _switch_in();
6047- gotmouseevent = YES;
6048- [NSApp sendEvent: event];
6049- break;
6050- }
6051- /* fallthrough */
6052- case NSLeftMouseUp:
6053- case NSOtherMouseUp:
6054- case NSRightMouseUp:
6055- if (osx_emulate_mouse_buttons) {
6056- if (event_type == NSLeftMouseDown) {
6057- if ((!osx_window) || (NSPointInRect(point, view))) {
6058- buttons = 0x1;
6059- if (key[KEY_ALT])
6060- buttons = 0x4;
6061- if (key[KEY_LCONTROL])
6062- buttons = 0x2;
6063- }
6064- }
6065- else if (event_type == NSLeftMouseUp)
6066- buttons &= ~0x7;
6067- }
6068- else {
6069- if ((!osx_window) || (NSPointInRect(point, view))) {
6070- /* Deliver mouse downs only if cursor is on the window */
6071- buttons |= ((event_type == NSLeftMouseDown) ? 0x1 : 0);
6072- buttons |= ((event_type == NSRightMouseDown) ? 0x2 : 0);
6073- buttons |= ((event_type == NSOtherMouseDown) ? 0x4 : 0);
6074- }
6075- buttons &= ~((event_type == NSLeftMouseUp) ? 0x1 : 0);
6076- buttons &= ~((event_type == NSRightMouseUp) ? 0x2 : 0);
6077- buttons &= ~((event_type == NSOtherMouseUp) ? 0x4 : 0);
6078- }
6079- gotmouseevent = YES;
6080- [NSApp sendEvent: event];
6081- break;
6082-
6083- case NSLeftMouseDragged:
6084- case NSRightMouseDragged:
6085- case NSOtherMouseDragged:
6086- case NSMouseMoved:
6087- dx += [event deltaX];
6088- dy += [event deltaY];
6089-
6090- mx=point.x;
6091- my=frame.size.height-point.y;
6092-
6093- [NSApp sendEvent: event];
6094- gotmouseevent = YES;
6095- break;
6096-
6097- case NSScrollWheel:
6098- dz += [event deltaY];
6099- gotmouseevent = YES;
6100- break;
6101-
6102- case NSMouseEntered:
6103- if (([event trackingNumber] == osx_mouse_tracking_rect) && ([NSApp isActive])) {
6104- if (_mouse_installed) {
6105- mx = point.x;
6106- my = frame.size.height - point.y;
6107- buttons = 0;
6108- _mouse_on = TRUE;
6109- gotmouseevent = YES;
6110- }
6111- }
6112- [NSApp sendEvent: event];
6113- break;
6114-
6115- case NSMouseExited:
6116- if ([event trackingNumber] == osx_mouse_tracking_rect) {
6117- if (_mouse_installed) {
6118- _mouse_on = FALSE;
6119- gotmouseevent = YES;
6120- }
6121- }
6122- [NSApp sendEvent: event];
6123- break;
6124-
6125- case NSAppKitDefined:
6126- switch ([event subtype]) {
6127- case NSApplicationActivatedEventType:
6128- if (osx_window) {
6129- [osx_window invalidateCursorRectsForView: [osx_window contentView]];
6130- if (_keyboard_installed)
6131- osx_keyboard_focused(TRUE, 0);
6132- }
6133- _switch_in();
6134- break;
6135-
6136- case NSApplicationDeactivatedEventType:
6137- if (osx_window && _keyboard_installed)
6138- osx_keyboard_focused(FALSE, 0);
6139- _switch_out();
6140- break;
6141-
6142- case NSWindowMovedEventType:
6143- /* This is needed to ensure the shadow gets drawn when the window is
6144- * created. It's weird, but when the window is created on another
6145- * thread, sometimes its shadow doesn't get drawn. The same applies
6146- * to the cursor rectangle, which doesn't seem to be set at window
6147- * creation (it works once you move the mouse though).
6148- */
6149- if ((osx_window) && (osx_window_first_expose)) {
6150- osx_window_first_expose = FALSE;
6151- [osx_window setHasShadow: NO];
6152- [osx_window setHasShadow: YES];
6153- [osx_window invalidateCursorRectsForView: [osx_window contentView]];
6154- }
6155- break;
6156- }
6157- [NSApp sendEvent: event];
6158- break;
6159-
6160- default:
6161- [NSApp sendEvent: event];
6162- break;
6163 }
6164+}
6165+
6166+void osx_mouse_available()
6167+{
6168+ if (!_mouse_installed) { return; }
6169+
6170+ NSPoint point;
6171+ NSRect frame, view;
6172+ view = NSMakeRect(0, 0, gfx_driver->w, gfx_driver->h);
6173+
6174+ point = NSMakePoint(0, 0);
6175+ if (osx_window) {
6176+ frame = [[osx_window contentView] frame];
6177+ point = locationInView (nil, [osx_window contentView]);
6178+ } else {
6179+ frame = [[NSScreen mainScreen] frame];
6180 }
6181- if (gotmouseevent == YES)
6182+ osx_scale_mouse(&point, &frame, &view);
6183+
6184+ if (NSPointInRect(point, view)) {
6185+
6186+ mx = point.x;
6187+ my = point.y;
6188+ buttons = 0;
6189+ _mouse_on = TRUE;
6190+
6191+ update_cursor();
6192+
6193 osx_mouse_handler(mx, my, dx, dy, dz, buttons);
6194- [pool release];
6195+ }
6196 }
6197
6198+void osx_mouse_not_available()
6199+{
6200+ if (!_mouse_installed) { return; }
6201
6202+ if (cursor_hidden) {
6203+ [NSCursor unhide];
6204+ cursor_hidden = NO;
6205+ }
6206
6207-/* osx_tell_dock:
6208- * Tell the dock about us; the origins of this hack are unknown, but it's
6209- * currently the only way to make a Cocoa app to work when started from a
6210- * console.
6211- * For the future, (10.3 and above) investigate TranformProcessType in the
6212- * HIServices framework.
6213- */
6214-static void osx_tell_dock(void)
6215-{
6216- struct CPSProcessSerNum psn;
6217+ _mouse_on = FALSE;
6218
6219- if ((!CPSGetCurrentProcess(&psn)) &&
6220- (!CPSEnableForegroundOperation(&psn, 0x03, 0x3C, 0x2C, 0x1103)) &&
6221- (!CPSSetFrontProcess(&psn)))
6222- [NSApplication sharedApplication];
6223+ osx_mouse_handler(mx, my, dx, dy, dz, buttons);
6224 }
6225
6226+void osx_add_event_monitor() {
6227
6228+ [NSEvent addLocalMonitorForEventsMatchingMask:NSAnyEventMask handler:^NSEvent * (NSEvent *event) {
6229
6230-/* osx_bootstrap_ok:
6231- * Check if the current bootstrap context is privilege. If it's not, we can't
6232- * use NSApplication, and instead have to go directly to main.
6233- * Returns 1 if ok, 0 if not.
6234- */
6235-int osx_bootstrap_ok(void)
6236-{
6237- static int _ok = -1;
6238- mach_port_t bp;
6239- kern_return_t ret;
6240- CFMachPortRef cfport;
6241-
6242- /* If have tested once, just return that answer */
6243- if (_ok >= 0)
6244- return _ok;
6245- cfport = CFMachPortCreate(NULL, NULL, NULL, NULL);
6246- task_get_bootstrap_port(mach_task_self(), &bp);
6247- ret = bootstrap_register(bp, "bootstrap-ok-test", CFMachPortGetPort(cfport));
6248- CFRelease(cfport);
6249- _ok = (ret == KERN_SUCCESS) ? 1 : 0;
6250- return _ok;
6251-}
6252+ NSDate *distant_past = [NSDate distantPast];
6253+ NSPoint point;
6254+ NSRect frame, view;
6255+ dx = 0, dy = 0, dz = 0;
6256+ mx=_mouse_x;
6257+ my=_mouse_y;
6258+ int event_type;
6259+ BOOL gotmouseevent = NO;
6260+ static int alt_left_mouse_up_event = -1;
6261+
6262+ _unix_lock_mutex(osx_skip_events_processing_mutex);
6263+ int skip_events_processing = osx_skip_events_processing;
6264+ _unix_unlock_mutex(osx_skip_events_processing_mutex);
6265+
6266+ if ((skip_events_processing) || (osx_gfx_mode == OSX_GFX_NONE)) {
6267+ return event;
6268+ }
6269+
6270+ view = NSMakeRect(0, 0, gfx_driver->w, gfx_driver->h);
6271+
6272+ point = NSMakePoint(0, 0);
6273+ if (osx_window) {
6274+ frame = [[osx_window contentView] frame];
6275+ point = locationInView (event, [osx_window contentView]);
6276+ } else {
6277+ frame = [[NSScreen mainScreen] frame];
6278+ }
6279+ osx_scale_mouse(&point, &frame, &view);
6280+
6281+ event_type = [event type];
6282+ switch (event_type) {
6283+
6284+ case NSKeyDown:
6285+ if (_keyboard_installed) {
6286+ osx_keyboard_handler(TRUE, event);
6287+ }
6288+ if (! ([event modifierFlags] & NSCommandKeyMask) )
6289+ {
6290+ event = nil;
6291+ }
6292+ break;
6293+
6294+
6295+ case NSKeyUp:
6296+ if (_keyboard_installed) {
6297+ osx_keyboard_handler(FALSE, event);
6298+ }
6299+ if (! ([event modifierFlags] & NSCommandKeyMask) )
6300+ {
6301+ event = nil;
6302+ }
6303+ break;
6304+
6305+ case NSFlagsChanged:
6306+ if (_keyboard_installed) {
6307+ osx_keyboard_modifiers([event modifierFlags]);
6308+ }
6309+ event = nil;
6310+ break;
6311+
6312+ case NSLeftMouseDown:
6313+ case NSOtherMouseDown:
6314+ case NSRightMouseDown:
6315+ if (![NSApp isActive]) {
6316+ /* App is regaining focus */
6317+ if (_mouse_installed) {
6318+ if ((osx_window) && (NSPointInRect(point, view))) {
6319+ mx = point.x;
6320+ my = point.y;
6321+ buttons = 0;
6322+ alt_left_mouse_up_event = -1;
6323+ _mouse_on = TRUE;
6324+ }
6325+ }
6326+ if (_keyboard_installed)
6327+ osx_keyboard_focused(TRUE, 0);
6328+ _switch_in();
6329+ gotmouseevent = YES;
6330+ break;
6331+ }
6332+ /* fallthrough */
6333+ case NSLeftMouseUp:
6334+ case NSOtherMouseUp:
6335+ case NSRightMouseUp:
6336+ {
6337+ int mouse_event_type = event_type;
6338+
6339+ if (mouse_event_type == NSLeftMouseDown) {
6340+ // TODO: if mouse down but hasn't clearned alt-mouse.. keep with the alt.
6341+ if (osx_emulate_mouse_buttons) {
6342+ if (key[KEY_ALT]) {
6343+ mouse_event_type = NSOtherMouseDown;
6344+ alt_left_mouse_up_event = NSOtherMouseUp;
6345+ }
6346+ if (key[KEY_LCONTROL]) {
6347+ mouse_event_type = NSRightMouseDown;
6348+ alt_left_mouse_up_event = NSRightMouseUp;
6349+ }
6350+ }
6351+ }
6352+
6353+ if ((mouse_event_type == NSLeftMouseUp) && (alt_left_mouse_up_event >= 0)) {
6354+ mouse_event_type = alt_left_mouse_up_event;
6355+ alt_left_mouse_up_event = -1;
6356+ }
6357+
6358+ if ((!osx_window) || (NSPointInRect(point, view))) {
6359+ /* Deliver mouse downs only if cursor is on the window */
6360+ buttons |= ((mouse_event_type == NSLeftMouseDown) ? 0x1 : 0);
6361+ buttons |= ((mouse_event_type == NSRightMouseDown) ? 0x2 : 0);
6362+ buttons |= ((mouse_event_type == NSOtherMouseDown) ? 0x4 : 0);
6363+ }
6364+ buttons &= ~((mouse_event_type == NSLeftMouseUp) ? 0x1 : 0);
6365+ buttons &= ~((mouse_event_type == NSRightMouseUp) ? 0x2 : 0);
6366+ buttons &= ~((mouse_event_type == NSOtherMouseUp) ? 0x4 : 0);
6367+
6368+ gotmouseevent = YES;
6369+ }
6370+ break;
6371+
6372+ case NSLeftMouseDragged:
6373+ case NSRightMouseDragged:
6374+ case NSOtherMouseDragged:
6375+ case NSMouseMoved:
6376+
6377+ // a bit dodgy but hide mouse cursor
6378+ update_cursor();
6379+
6380+ dx += [event deltaX];
6381+ dy += [event deltaY];
6382+
6383+ mx=point.x;
6384+ my=point.y;
6385+
6386+ gotmouseevent = YES;
6387+ break;
6388+
6389+ case NSScrollWheel:
6390+ dz += [event deltaY];
6391+ gotmouseevent = YES;
6392+ break;
6393+
6394+ case NSMouseEntered:
6395+ if (([event trackingNumber] == osx_mouse_tracking_rect) && ([NSApp isActive])) {
6396+ osx_mouse_available();
6397+ return event; // return immediately since osx_mouse_available will call handler.
6398+ }
6399+ break;
6400+
6401+ case NSMouseExited:
6402+ if ([event trackingNumber] == osx_mouse_tracking_rect) {
6403+ osx_mouse_not_available();
6404+ return event; // return immediately since osx_mouse_available will call handler.
6405+ }
6406+ break;
6407+
6408+ default:
6409+ break;
6410+ }
6411+
6412+ if (gotmouseevent == YES) {
6413+ osx_mouse_handler(mx, my, dx, dy, dz, buttons);
6414+ }
6415+
6416+ return event;
6417
6418+ }];
6419
6420+}
6421
6422 /* osx_sys_init:
6423 * Initalizes the MacOS X system driver.
6424@@ -406,11 +446,6 @@ int osx_bootstrap_ok(void)
6425 static int osx_sys_init(void)
6426 {
6427 long result;
6428-
6429- /* If we're in the 'dead bootstrap' environment, the Mac driver won't work. */
6430- if (!osx_bootstrap_ok()) {
6431- return -1;
6432- }
6433
6434 /* Install emergency-exit signal handlers */
6435 old_sig_abrt = signal(SIGABRT, osx_signal_handler);
6436@@ -420,21 +455,15 @@ static int osx_sys_init(void)
6437 old_sig_term = signal(SIGTERM, osx_signal_handler);
6438 old_sig_int = signal(SIGINT, osx_signal_handler);
6439 old_sig_quit = signal(SIGQUIT, osx_signal_handler);
6440-
6441-
6442
6443- if (osx_bundle == NULL) {
6444- /* If in a bundle, the dock will recognise us automatically */
6445- osx_tell_dock();
6446- }
6447-
6448+
6449 /* Setup OS type & version */
6450 os_type = OSTYPE_MACOSX;
6451 Gestalt(gestaltSystemVersion, &result);
6452 os_version = (((result >> 12) & 0xf) * 10) + ((result >> 8) & 0xf);
6453 os_revision = (result >> 4) & 0xf;
6454 os_multitasking = TRUE;
6455-
6456+
6457 /* Setup a blank cursor */
6458 cursor_data = calloc(1, 16 * 16 * 4);
6459 cursor_rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: &cursor_data
6460@@ -595,10 +624,17 @@ static int osx_sys_set_display_switch_mode(int mode)
6461 */
6462 static void osx_sys_get_gfx_safe_mode(int *driver, struct GFX_MODE *mode)
6463 {
6464+#ifdef ENABLE_QUICKDRAW
6465 *driver = GFX_QUARTZ_WINDOW;
6466 mode->width = 320;
6467 mode->height = 200;
6468 mode->bpp = 8;
6469+#else
6470+ *driver = GFX_COCOAGL_WINDOW;
6471+ mode->width = 640;
6472+ mode->height = 480;
6473+ mode->bpp = 32;
6474+#endif
6475 }
6476
6477
6478@@ -608,13 +644,10 @@ static void osx_sys_get_gfx_safe_mode(int *driver, struct GFX_MODE *mode)
6479 */
6480 static int osx_sys_desktop_color_depth(void)
6481 {
6482- CFDictionaryRef mode = NULL;
6483 int color_depth;
6484
6485- mode = CGDisplayCurrentMode(kCGDirectMainDisplay);
6486- if (!mode)
6487- return -1;
6488- CFNumberGetValue(CFDictionaryGetValue(mode, kCGDisplayBitsPerPixel), kCFNumberSInt32Type, &color_depth);
6489+ NSWindowDepth depth = [[NSScreen mainScreen] depth];
6490+ color_depth = NSBitsPerPixelFromDepth(depth);
6491
6492 return color_depth == 16 ? 15 : color_depth;
6493 }
6494@@ -625,13 +658,9 @@ static int osx_sys_desktop_color_depth(void)
6495 */
6496 static int osx_sys_get_desktop_resolution(int *width, int *height)
6497 {
6498- CFDictionaryRef mode = NULL;
6499-
6500- mode = CGDisplayCurrentMode(kCGDirectMainDisplay);
6501- if (!mode)
6502- return -1;
6503- CFNumberGetValue(CFDictionaryGetValue(mode, kCGDisplayWidth), kCFNumberSInt32Type, width);
6504- CFNumberGetValue(CFDictionaryGetValue(mode, kCGDisplayHeight), kCFNumberSInt32Type, height);
6505-
6506- return 0;
6507+ NSRect r = [[NSScreen mainScreen] frame];
6508+ *width = r.size.width;
6509+ *height = r.size.height;
6510+
6511+ return 0;
6512 }
6513diff --git a/src/mouse.c b/src/mouse.c
6514index 96b25b2..02d7bb2 100644
6515--- a/src/mouse.c
6516+++ b/src/mouse.c
6517@@ -1012,9 +1012,9 @@ static void set_mouse_etc(void)
6518 else
6519 hw_cursor_dirty = TRUE;
6520
6521+ position_mouse(SCREEN_W/2, SCREEN_H/2);
6522 set_mouse_range(0, 0, SCREEN_W-1, SCREEN_H-1);
6523 set_mouse_speed(2, 2);
6524- position_mouse(SCREEN_W/2, SCREEN_H/2);
6525 }
6526
6527
6528diff --git a/src/poly3d.c b/src/poly3d.c
6529index b950589..18b97c2 100644
6530--- a/src/poly3d.c
6531+++ b/src/poly3d.c
6532@@ -1708,7 +1708,7 @@ void _soft_triangle3d_f(BITMAP *bmp, int type, BITMAP *texture, V3D_f *v1, V3D_f
6533 */
6534 void _soft_quad3d(BITMAP *bmp, int type, BITMAP *texture, V3D *v1, V3D *v2, V3D *v3, V3D *v4)
6535 {
6536- #if (defined ALLEGRO_GCC) && (defined ALLEGRO_I386)
6537+ #if 0 && (defined ALLEGRO_GCC) && (defined ALLEGRO_I386)
6538 ASSERT(bmp);
6539
6540 /* dodgy assumption alert! See comments for triangle() */
6541@@ -1735,7 +1735,7 @@ void _soft_quad3d(BITMAP *bmp, int type, BITMAP *texture, V3D *v1, V3D *v2, V3D
6542 */
6543 void _soft_quad3d_f(BITMAP *bmp, int type, BITMAP *texture, V3D_f *v1, V3D_f *v2, V3D_f *v3, V3D_f *v4)
6544 {
6545- #if (defined ALLEGRO_GCC) && (defined ALLEGRO_I386)
6546+ #if 0 && (defined ALLEGRO_GCC) && (defined ALLEGRO_I386)
6547 ASSERT(bmp);
6548
6549 /* dodgy assumption alert! See comments for triangle() */
6550diff --git a/src/polygon.c b/src/polygon.c
6551index c39e7f3..d221046 100644
6552--- a/src/polygon.c
6553+++ b/src/polygon.c
6554@@ -260,7 +260,8 @@ void _soft_triangle(BITMAP *bmp, int x1, int y1, int x2, int y2, int x3, int y3,
6555 {
6556 ASSERT(bmp);
6557
6558- #if (defined ALLEGRO_GCC) && (defined ALLEGRO_I386)
6559+ /* Disabling this as it horribly blows up on GCC 4.2 on OS X*/
6560+ #if 0 && (defined ALLEGRO_GCC) && (defined ALLEGRO_I386)
6561
6562 /* note: this depends on a dodgy assumption about parameter passing
6563 * conventions. I assume that the point coordinates are all on the
6564diff --git a/src/tga.c b/src/tga.c
6565index d40762e..2340fbb 100644
6566--- a/src/tga.c
6567+++ b/src/tga.c
6568@@ -280,8 +280,8 @@ BITMAP *load_tga_pf(PACKFILE *f, RGB *pal)
6569 unsigned char image_id[256], image_palette[256][3];
6570 unsigned char id_length, palette_type, image_type, palette_entry_size;
6571 unsigned char bpp, descriptor_bits;
6572- short unsigned int first_color, palette_colors;
6573- short unsigned int left, top, image_width, image_height;
6574+ short unsigned int palette_colors;
6575+ short unsigned int image_width, image_height;
6576 unsigned int c, i, y, yc;
6577 int dest_depth;
6578 int compressed;
6579@@ -299,11 +299,11 @@ BITMAP *load_tga_pf(PACKFILE *f, RGB *pal)
6580 id_length = pack_getc(f);
6581 palette_type = pack_getc(f);
6582 image_type = pack_getc(f);
6583- first_color = pack_igetw(f);
6584+ /* first_color */ pack_igetw(f);
6585 palette_colors = pack_igetw(f);
6586 palette_entry_size = pack_getc(f);
6587- left = pack_igetw(f);
6588- top = pack_igetw(f);
6589+ /* left */ pack_igetw(f);
6590+ /* top */ pack_igetw(f);
6591 image_width = pack_igetw(f);
6592 image_height = pack_igetw(f);
6593 bpp = pack_getc(f);
6594diff --git a/src/unix/sdl2digi.c b/src/unix/sdl2digi.c
6595new file mode 100644
6596index 0000000..68ef461
6597--- /dev/null
6598+++ b/src/unix/sdl2digi.c
6599@@ -0,0 +1,233 @@
6600+/* ______ ___ ___
6601+ * /\ _ \ /\_ \ /\_ \
6602+ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
6603+ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
6604+ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6605+ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
6606+ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
6607+ * /\____/
6608+ * \_/__/
6609+ *
6610+ * SDL2 sound driver.
6611+ *
6612+ * By Edward Rudd.
6613+ *
6614+ * See readme.txt for copyright information.
6615+ */
6616+
6617+#include "allegro.h"
6618+
6619+#if (defined ALLEGRO_WITH_SDL2DIGI) && ((!defined ALLEGRO_WITH_MODULES) || (defined ALLEGRO_MODULE))
6620+
6621+#include "allegro/internal/aintern.h"
6622+#ifdef ALLEGRO_QNX
6623+#include "allegro/platform/aintqnx.h"
6624+#else
6625+#include "allegro/platform/aintunix.h"
6626+#endif
6627+
6628+#ifndef SCAN_DEPEND
6629+#include <string.h>
6630+#include <math.h>
6631+#include <SDL.h>
6632+#endif
6633+
6634+#define PREFIX_I "al-sdl2 INFO: "
6635+#define PREFIX_W "al-sdl2 WARNING: "
6636+#define PREFIX_E "al-sdl2 ERROR: "
6637+
6638+static int sdl2_bits, sdl2_signed, sdl2_stereo;
6639+static unsigned int sdl2_rate;
6640+
6641+static SDL_AudioSpec sdl2_audiospec;
6642+static SDL_AudioDeviceID sdl2_deviceID;
6643+
6644+static char sdl2_desc[256] = EMPTY_STRING;
6645+
6646+static int sdl2_detect(int input);
6647+static int sdl2_init(int input, int voices);
6648+static void sdl2_exit(int input);
6649+static int sdl2_set_mixer_volume(int volume);
6650+static int sdl2_get_mixer_volume(void);
6651+static int sdl2_buffer_size(void);
6652+
6653+DIGI_DRIVER digi_sdl2 = {
6654+ DIGI_SDL2,
6655+ empty_string,
6656+ empty_string,
6657+ "SDL2",
6658+ 0,
6659+ 0,
6660+ MIXER_MAX_SFX,
6661+ MIXER_DEF_SFX,
6662+
6663+ sdl2_detect,
6664+ sdl2_init,
6665+ sdl2_exit,
6666+ sdl2_set_mixer_volume,
6667+ sdl2_get_mixer_volume,
6668+
6669+ NULL,
6670+ NULL,
6671+ sdl2_buffer_size,
6672+ _mixer_init_voice,
6673+ _mixer_release_voice,
6674+ _mixer_start_voice,
6675+ _mixer_stop_voice,
6676+ _mixer_loop_voice,
6677+
6678+ _mixer_get_position,
6679+ _mixer_set_position,
6680+
6681+ _mixer_get_volume,
6682+ _mixer_set_volume,
6683+ _mixer_ramp_volume,
6684+ _mixer_stop_volume_ramp,
6685+
6686+ _mixer_get_frequency,
6687+ _mixer_set_frequency,
6688+ _mixer_sweep_frequency,
6689+ _mixer_stop_frequency_sweep,
6690+
6691+ _mixer_get_pan,
6692+ _mixer_set_pan,
6693+ _mixer_sweep_pan,
6694+ _mixer_stop_pan_sweep,
6695+
6696+ _mixer_set_echo,
6697+ _mixer_set_tremolo,
6698+ _mixer_set_vibrato,
6699+ 0, 0,
6700+ 0,
6701+ 0,
6702+ 0,
6703+ 0,
6704+ 0,
6705+ 0
6706+};
6707+
6708+#define DEFAULT_BUFFER_SIZE 1024
6709+#define MIN_BUFFER_SIZE 128
6710+
6711+static int sdl2_detect(int input) {
6712+ int ret = SDL_InitSubSystem(SDL_INIT_AUDIO) == 0 ? TRUE : FALSE;
6713+ return ret;
6714+}
6715+
6716+static void sdl2_update(int threaded) {
6717+
6718+}
6719+
6720+static void sdl2_callback(void *udata, Uint8 *stream, int len) {
6721+ if((Uint32)len == sdl2_audiospec.size) {
6722+ _mix_some_samples((uintptr_t)stream, 0, sdl2_signed);
6723+ } else {
6724+ printf("ERROR!!!\n");
6725+ }
6726+}
6727+
6728+static int sdl2_init(int input, int voices) {
6729+ char tmp1[128], tmp2[128];
6730+ SDL_AudioSpec want;
6731+
6732+ if (input) {
6733+ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported"));
6734+ return -1;
6735+ }
6736+
6737+ sdl2_bits = (_sound_bits == 8) ? 8 : 16;
6738+ sdl2_stereo = (_sound_stereo) ? 1 : 0;
6739+ sdl2_rate = (_sound_freq > 0) ? _sound_freq : 44100;
6740+
6741+ SDL_zero(want);
6742+ want.freq = sdl2_rate;
6743+ want.channels = sdl2_stereo + 1;
6744+ want.samples = DEFAULT_BUFFER_SIZE;
6745+ want.callback = sdl2_callback;
6746+
6747+ if (sdl2_bits == 8) {
6748+ want.format = AUDIO_U8;
6749+ sdl2_signed = 0;
6750+ } else if (sdl2_bits == 16) {
6751+ want.format = AUDIO_S16SYS;
6752+ sdl2_signed = 1;
6753+ } else {
6754+ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported sample format"));
6755+ return -1;
6756+ }
6757+
6758+ sdl2_deviceID = SDL_OpenAudioDevice(NULL, 0, &want, &sdl2_audiospec, 0);
6759+ if (sdl2_deviceID == 0) {
6760+ uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, "Failed to open audio: %s", SDL_GetError());
6761+ return -1;
6762+ }
6763+
6764+ digi_driver->voices = voices;
6765+
6766+ if (_mixer_init(sdl2_audiospec.samples * (sdl2_stereo ? 2 : 1), sdl2_rate,
6767+ sdl2_stereo, ((sdl2_bits == 16) ? 1 : 0),
6768+ &digi_driver->voices) != 0) {
6769+ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not init software mixer"));
6770+ SDL_CloseAudioDevice(sdl2_deviceID);
6771+ sdl2_deviceID = 0;
6772+ return -1;
6773+ }
6774+
6775+ /* Add audio interrupt. */
6776+ _unix_bg_man->register_func(sdl2_update);
6777+
6778+ uszprintf(sdl2_desc, sizeof (sdl2_desc),
6779+ get_config_text
6780+ ("SDL2: %d bits, %s, %d bps, %s"),
6781+ sdl2_bits,
6782+ uconvert_ascii((sdl2_signed ? "signed" : "unsigned"), tmp1),
6783+ sdl2_rate, uconvert_ascii((sdl2_stereo ? "stereo" : "mono"), tmp2));
6784+
6785+ digi_driver->desc = sdl2_desc;
6786+
6787+ SDL_PauseAudioDevice(sdl2_deviceID, 0);
6788+
6789+ return 0;
6790+}
6791+
6792+static void sdl2_exit(int input) {
6793+ if (input)
6794+ return;
6795+
6796+ if (sdl2_deviceID > 0) {
6797+ _unix_bg_man->unregister_func(sdl2_update);
6798+
6799+ SDL_PauseAudioDevice(sdl2_deviceID, 1);
6800+
6801+ _mixer_exit();
6802+
6803+ SDL_CloseAudioDevice(sdl2_deviceID);
6804+ }
6805+}
6806+
6807+static int sdl2_set_mixer_volume(int volume) {
6808+ /* Not implemented */
6809+ return 0;
6810+}
6811+
6812+static int sdl2_get_mixer_volume(void) {
6813+ /* Not implemented */
6814+ return 255;
6815+}
6816+
6817+static int sdl2_buffer_size(void) {
6818+ return sdl2_audiospec.samples;
6819+}
6820+
6821+#ifdef ALLEGRO_MODULE
6822+
6823+/* _module_init:
6824+ * Called when loaded as a dynamically linked module.
6825+ */
6826+void _module_init(int system_driver) {
6827+ _unix_register_digi_driver(DIGI_SDL2, &digi_sdl2, TRUE, TRUE);
6828+}
6829+
6830+#endif
6831+
6832+#endif
6833diff --git a/src/unix/umodules.c b/src/unix/umodules.c
6834index aaa070c..9511e7b 100644
6835--- a/src/unix/umodules.c
6836+++ b/src/unix/umodules.c
6837@@ -126,11 +126,11 @@ void _unix_load_modules(int system_driver)
6838 continue;
6839
6840 if (!fullpath_slash) {
6841- snprintf(fullpath, sizeof fullpath, filename);
6842+ strncpy(fullpath, filename, sizeof fullpath);
6843 fullpath[(sizeof fullpath) - 1] = 0;
6844 }
6845 else {
6846- snprintf(fullpath_slash+1, (sizeof fullpath) - (fullpath_slash - fullpath) - 1, filename);
6847+ strncpy(fullpath_slash+1, filename, (sizeof fullpath) - (fullpath_slash - fullpath) - 1);
6848 fullpath[(sizeof fullpath) - 1] = 0;
6849 }
6850
6851diff --git a/src/unix/usystem.c b/src/unix/usystem.c
6852index a8a171c..3812c8e 100644
6853--- a/src/unix/usystem.c
6854+++ b/src/unix/usystem.c
6855@@ -370,7 +370,7 @@ void _unix_get_executable_name(char *output, int size)
6856 #ifdef ALLEGRO_HAVE_SV_PROCFS_H
6857 sprintf (linkname, "/proc/%d/exe", (int)pid);
6858 fd = open(linkname, O_RDONLY);
6859- if (!fd == -1) {
6860+ if (fd != -1) {
6861 ioctl(fd, PIOCPSINFO, &psinfo);
6862 close(fd);
6863
6864diff --git a/src/win/dllver.rc b/src/win/dllver.rc
6865index d6b986b..59ecf65 100644
6866--- a/src/win/dllver.rc
6867+++ b/src/win/dllver.rc
6868@@ -5,8 +5,8 @@
6869
6870
6871 1 VERSIONINFO
6872-FILEVERSION 4, 4, 2, 0
6873-PRODUCTVERSION 4, 4, 2, 0
6874+FILEVERSION 4, 4, 3, 0
6875+PRODUCTVERSION 4, 4, 3, 0
6876 FILEOS VOS__WINDOWS32
6877 FILETYPE VFT_DLL
6878 BEGIN
6879@@ -17,12 +17,12 @@ BEGIN
6880 VALUE "Comments", "Please see AUTHORS for a list of contributors\000"
6881 VALUE "CompanyName", "Allegro Developers\000\000"
6882 VALUE "FileDescription", "Allegro\000"
6883- VALUE "FileVersion", "4.4.2\000"
6884+ VALUE "FileVersion", "4.4.3 (SVN)\000"
6885 VALUE "InternalName", "ALLEG44\000"
6886 VALUE "LegalCopyright", "Copyright © 1994-2011 Allegro Developers\000\000"
6887 VALUE "OriginalFilename", "ALLEG44.DLL\000"
6888 VALUE "ProductName", "Allegro\000"
6889- VALUE "ProductVersion", "4.4.2\000"
6890+ VALUE "ProductVersion", "4.4.3 (SVN)\000"
6891 END
6892 END
6893
6894diff --git a/src/win/wddbmpl.c b/src/win/wddbmpl.c
6895index c65a5ec..9b5b57e 100644
6896--- a/src/win/wddbmpl.c
6897+++ b/src/win/wddbmpl.c
6898@@ -113,11 +113,13 @@ void unregister_all_ddraw_surfaces(void)
6899 */
6900 int restore_all_ddraw_surfaces(void)
6901 {
6902- DDRAW_SURFACE *item = ddraw_surface_list;
6903+ DDRAW_SURFACE *item;
6904 HRESULT hr;
6905
6906 _enter_gfx_critical();
6907
6908+ item = ddraw_surface_list;
6909+
6910 while (item) {
6911 hr = IDirectDrawSurface2_Restore(item->id);
6912 if (FAILED(hr)) {
6913diff --git a/src/win/wddovl.c b/src/win/wddovl.c
6914index 02de59c..72fca29 100644
6915--- a/src/win/wddovl.c
6916+++ b/src/win/wddovl.c
6917@@ -320,7 +320,7 @@ static struct BITMAP *init_directx_ovl(int w, int h, int v_w, int v_h, int color
6918
6919 /* Paint window background with overlay color key. */
6920 overlay_brush = CreateSolidBrush(MASK_COLOR_32);
6921- SetClassLong(allegro_wnd, GCL_HBRBACKGROUND, (LONG) overlay_brush);
6922+ SetClassLongPtr(allegro_wnd, GCLP_HBRBACKGROUND, (LONG_PTR)overlay_brush);
6923
6924 if (adjust_window(w, h) != 0) {
6925 _TRACE(PREFIX_E "window size not supported.\n");
6926@@ -445,7 +445,7 @@ static void gfx_directx_ovl_exit(struct BITMAP *bmp)
6927 /* destroy the overlay surface */
6928 if (overlay_surface) {
6929 hide_overlay();
6930- SetClassLong(allegro_wnd, GCL_HBRBACKGROUND, (LONG) NULL);
6931+ SetClassLongPtr(allegro_wnd, GCLP_HBRBACKGROUND, (LONG_PTR)NULL);
6932 DeleteObject(overlay_brush);
6933 gfx_directx_destroy_surface(overlay_surface);
6934 overlay_surface = NULL;
6935diff --git a/src/win/wdispsw.c b/src/win/wdispsw.c
6936index 258565f..8707ea1 100644
6937--- a/src/win/wdispsw.c
6938+++ b/src/win/wdispsw.c
6939@@ -165,8 +165,8 @@ void _win_switch_out(void)
6940
6941 /* if the thread doesn't stop, lower its priority only if another window is active */
6942 allegro_thread_priority = GetThreadPriority(allegro_thread);
6943- if ((HINSTANCE)GetWindowLong(GetForegroundWindow(), GWL_HINSTANCE) != allegro_inst)
6944- SetThreadPriority(allegro_thread, THREAD_PRIORITY_LOWEST);
6945+ if ((HINSTANCE)GetWindowLongPtr(GetForegroundWindow(), GWLP_HINSTANCE) != allegro_inst)
6946+ SetThreadPriority(allegro_thread, THREAD_PRIORITY_LOWEST);
6947 }
6948
6949 _switch_out();
6950diff --git a/src/win/winput.c b/src/win/winput.c
6951index 3d8a095..9bad0b1 100644
6952--- a/src/win/winput.c
6953+++ b/src/win/winput.c
6954@@ -1,6 +1,6 @@
6955-/* ______ ___ ___
6956- * /\ _ \ /\_ \ /\_ \
6957- * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
6958+/* ______ ___ ___
6959+ * /\ _ \ /\_ \ /\_ \
6960+ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
6961 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
6962 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6963 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
6964@@ -59,7 +59,7 @@ static HANDLE input_thread = NULL;
6965 */
6966 static void input_thread_proc(LPVOID unused)
6967 {
6968- int result;
6969+ DWORD result;
6970
6971 _win_thread_init();
6972 _TRACE(PREFIX_I "input thread starts\n");
6973@@ -69,7 +69,7 @@ static void input_thread_proc(LPVOID unused)
6974 result = WaitForMultipleObjects(_win_input_events, _win_input_event_id, FALSE, INFINITE);
6975 if (result == WAIT_OBJECT_0 + 2)
6976 break; /* thread suicide */
6977- else if ((result >= WAIT_OBJECT_0) && (result < WAIT_OBJECT_0 + _win_input_events))
6978+ else if (result < (DWORD)(WAIT_OBJECT_0 + _win_input_events))
6979 (*_win_input_event_handler[result - WAIT_OBJECT_0])();
6980 }
6981
6982@@ -187,6 +187,12 @@ void _win_input_unregister_event(HANDLE event_id)
6983 */
6984 void _win_input_init(int need_thread)
6985 {
6986+ int i;
6987+ for (i = 0; i < MAX_EVENTS; ++i) {
6988+ _win_input_event_id[i] = 0;
6989+ _win_input_event_handler[i] = NULL;
6990+ }
6991+
6992 _win_input_event_id[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
6993 _win_input_event_handler[0] = register_pending_event;
6994 _win_input_event_id[1] = CreateEvent(NULL, FALSE, FALSE, NULL);
6995diff --git a/src/win/wjoydx.c b/src/win/wjoydx.c
6996index 655cb21..61abf3a 100644
6997--- a/src/win/wjoydx.c
6998+++ b/src/win/wjoydx.c
6999@@ -1,6 +1,6 @@
7000-/* ______ ___ ___
7001- * /\ _ \ /\_ \ /\_ \
7002- * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
7003+/* ______ ___ ___
7004+ * /\ _ \ /\_ \ /\_ \
7005+ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
7006 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
7007 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
7008 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7009@@ -12,7 +12,7 @@
7010 *
7011 * By Eric Botcazou.
7012 *
7013- * Omar Cornut fixed it to handle a weird peculiarity of
7014+ * Omar Cornut fixed it to handle a weird peculiarity of
7015 * the DirectInput joystick API.
7016 *
7017 * See readme.txt for copyright information.
7018@@ -186,17 +186,17 @@ static int joystick_dinput_poll(void)
7019
7020 /* In versions of the DirectInput joystick API earlier than 8.00, slider
7021 * data is to be found in the Z axis data member, although the object was
7022- * reported as a slider during enumeration.
7023+ * reported as a slider during enumeration.
7024 *
7025 * Very few locations seem to describe this "feature". Here is one:
7026 * http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/dx81_vb/directx_vb/Input/VB_Ref/Types/dijoystate2.asp
7027 *
7028 * The interesting part is the note at the bottom of the page:
7029 * " Note: Under Microsoft DirectX 7, sliders on some joysticks could be assigned
7030- * to the Z axis, with subsequent code retrieving data from that member.
7031- * Using DirectX 8, those same sliders will be assigned to the slider array.
7032- * This should be taken into account when porting applications to DirectX 8.
7033- * Make any necessary alterations to ensure that slider data is retrieved from
7034+ * to the Z axis, with subsequent code retrieving data from that member.
7035+ * Using DirectX 8, those same sliders will be assigned to the slider array.
7036+ * This should be taken into account when porting applications to DirectX 8.
7037+ * Make any necessary alterations to ensure that slider data is retrieved from
7038 * the slider array. "
7039 */
7040
7041@@ -333,7 +333,7 @@ static BOOL CALLBACK joystick_enum_callback(LPCDIDEVICEINSTANCE lpddi, LPVOID pv
7042 HRESULT hr;
7043 LPVOID temp;
7044 HWND allegro_wnd = win_get_window();
7045-
7046+
7047 DIPROPRANGE property_range =
7048 {
7049 /* the header */
7050@@ -438,7 +438,7 @@ static int joystick_dinput_init(void)
7051 return -1;
7052
7053 /* get the DirectInput interface */
7054- hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInput, &joystick_dinput);
7055+ hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInput, (void**)&joystick_dinput);
7056 if (FAILED(hr))
7057 return -1;
7058
7059diff --git a/src/win/wkeybd.c b/src/win/wkeybd.c
7060index d85f079..f8ab424 100644
7061--- a/src/win/wkeybd.c
7062+++ b/src/win/wkeybd.c
7063@@ -13,6 +13,9 @@
7064 * By Stefan Schimanski, hacked up by Peter Wang and Elias Pschernig.
7065 *
7066 * See readme.txt for copyright information.
7067+ *
7068+ ****** CJ CHANGE SIN THIS FILE: Made hw_to_mycode non-static;
7069+ changed key_dinput_handle_scancode to ignore windows key on Vista
7070 */
7071
7072
7073@@ -40,12 +43,12 @@
7074 static HANDLE key_input_event = NULL;
7075 static HANDLE key_input_processed_event = NULL;
7076 static LPDIRECTINPUT key_dinput = NULL;
7077-static LPDIRECTINPUTDEVICE key_dinput_device = NULL;
7078+LPDIRECTINPUTDEVICE key_dinput_device = NULL;
7079
7080
7081 /* lookup table for converting DIK_* scancodes into Allegro KEY_* codes */
7082 /* this table was from pckeys.c */
7083-static const unsigned char hw_to_mycode[256] = {
7084+const unsigned char hw_to_mycode[256] = {
7085 /* 0x00 */ 0, KEY_ESC, KEY_1, KEY_2,
7086 /* 0x04 */ KEY_3, KEY_4, KEY_5, KEY_6,
7087 /* 0x08 */ KEY_7, KEY_8, KEY_9, KEY_0,
7088@@ -322,11 +325,26 @@ static void key_dinput_handle_scancode(unsigned char scancode, int pressed)
7089 {
7090 HWND allegro_wnd = win_get_window();
7091 static int ignore_three_finger_flag = FALSE;
7092+
7093+ static BOOL just_pressed_alt = FALSE;
7094+ if (scancode == DIK_LMENU)
7095+ {
7096+ just_pressed_alt = TRUE;
7097+ }
7098+ else if (scancode != DIK_TAB)
7099+ {
7100+ just_pressed_alt = FALSE;
7101+ }
7102+
7103 /* ignore special Windows keys (alt+tab, alt+space, (ctrl|alt)+esc) */
7104 if (((scancode == DIK_TAB) && (_key_shifts & KB_ALT_FLAG))
7105 || ((scancode == DIK_SPACE) && (_key_shifts & KB_ALT_FLAG))
7106- || ((scancode == DIK_ESCAPE) && (_key_shifts & (KB_CTRL_FLAG | KB_ALT_FLAG))))
7107+ || ((scancode == DIK_ESCAPE) && (_key_shifts & (KB_CTRL_FLAG | KB_ALT_FLAG)))
7108+ || ((scancode == DIK_TAB) && (just_pressed_alt)))
7109+ {
7110+ just_pressed_alt = FALSE;
7111 return;
7112+ }
7113
7114 /* alt+F4 triggers a WM_CLOSE under Windows */
7115 if ((scancode == DIK_F4) && (_key_shifts & KB_ALT_FLAG)) {
7116@@ -676,7 +694,7 @@ static int key_dinput_init(void)
7117 };
7118
7119 /* Get DirectInput interface */
7120- hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInput, &key_dinput);
7121+ hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInput, (void**)&key_dinput);
7122 if (FAILED(hr))
7123 goto Error;
7124
7125@@ -685,7 +703,7 @@ static int key_dinput_init(void)
7126 goto Error;
7127
7128 /* Create the keyboard device */
7129- hr = IDirectInput_CreateDevice(key_dinput, &GUID_SysKeyboard, &key_dinput_device, NULL);
7130+ hr = IDirectInput_CreateDevice(key_dinput, &GUID_SysKeyboardEm2, &key_dinput_device, NULL);
7131 if (FAILED(hr))
7132 goto Error;
7133
7134diff --git a/src/win/wmouse.c b/src/win/wmouse.c
7135index ff85b73..b3d599d 100644
7136--- a/src/win/wmouse.c
7137+++ b/src/win/wmouse.c
7138@@ -1,6 +1,6 @@
7139-/* ______ ___ ___
7140- * /\ _ \ /\_ \ /\_ \
7141- * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
7142+/* ______ ___ ___
7143+ * /\ _ \ /\_ \ /\_ \
7144+ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
7145 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
7146 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
7147 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7148@@ -82,7 +82,7 @@ HCURSOR _win_hcursor = NULL; /* Hardware cursor to display */
7149 #define DINPUT_BUFFERSIZE 256
7150 static HANDLE mouse_input_event = NULL;
7151 static LPDIRECTINPUT mouse_dinput = NULL;
7152-static LPDIRECTINPUTDEVICE mouse_dinput_device = NULL;
7153+LPDIRECTINPUTDEVICE mouse_dinput_device = NULL;
7154
7155 static int dinput_buttons = 0;
7156 static int dinput_wheel = FALSE;
7157@@ -234,7 +234,7 @@ static void mouse_dinput_handle_event(int ofs, int data)
7158 mag = last_data_x*last_data_x + last_data_y*last_data_y;
7159 if (mag >= mouse_accel_thr2)
7160 data *= (mouse_accel_mult<<1);
7161- else if (mag >= mouse_accel_thr1)
7162+ else if (mag >= mouse_accel_thr1)
7163 data *= mouse_accel_mult;
7164 }
7165
7166@@ -252,7 +252,7 @@ static void mouse_dinput_handle_event(int ofs, int data)
7167 mag = last_data_x*last_data_x + last_data_y*last_data_y;
7168 if (mag >= mouse_accel_thr2)
7169 data *= (mouse_accel_mult<<1);
7170- else if (mag >= mouse_accel_thr1)
7171+ else if (mag >= mouse_accel_thr1)
7172 data *= mouse_accel_mult;
7173 }
7174
7175@@ -606,7 +606,7 @@ static int mouse_dinput_init(void)
7176 };
7177
7178 /* Get DirectInput interface */
7179- hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInput, &mouse_dinput);
7180+ hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectInput, (void**)&mouse_dinput);
7181 if (FAILED(hr))
7182 goto Error;
7183
7184@@ -615,7 +615,7 @@ static int mouse_dinput_init(void)
7185 goto Error;
7186
7187 /* Create the mouse device */
7188- hr = IDirectInput_CreateDevice(mouse_dinput, &GUID_SysMouse, &mouse_dinput_device, NULL);
7189+ hr = IDirectInput_CreateDevice(mouse_dinput, &GUID_SysMouseEm2, &mouse_dinput_device, NULL);
7190 if (FAILED(hr))
7191 goto Error;
7192
7193@@ -628,7 +628,7 @@ static int mouse_dinput_init(void)
7194 goto Error;
7195
7196 /* Check to see if the buttons are swapped (left-hand) */
7197- mouse_swap_button = GetSystemMetrics(SM_SWAPBUTTON);
7198+ mouse_swap_button = GetSystemMetrics(SM_SWAPBUTTON);
7199
7200 /* Set data format */
7201 hr = IDirectInputDevice_SetDataFormat(mouse_dinput_device, &c_dfDIMouse);
7202@@ -802,13 +802,13 @@ static void mouse_directx_enable_hardware_cursor(int mode)
7203
7204
7205 /* mouse_directx_select_system_cursor:
7206- * Select an OS native cursor
7207+ * Select an OS native cursor
7208 */
7209 static int mouse_directx_select_system_cursor (int cursor)
7210 {
7211 HCURSOR wc;
7212 HWND allegro_wnd = win_get_window();
7213-
7214+
7215 wc = NULL;
7216 switch(cursor) {
7217 case MOUSE_CURSOR_ARROW:
7218@@ -830,6 +830,6 @@ static int mouse_directx_select_system_cursor (int cursor)
7219 _win_hcursor = wc;
7220 SetCursor(_win_hcursor);
7221 PostMessage(allegro_wnd, WM_MOUSEMOVE, 0, 0);
7222-
7223+
7224 return cursor;
7225 }
7226diff --git a/src/win/wsystem.c b/src/win/wsystem.c
7227index 45008c4..7a34080 100644
7228--- a/src/win/wsystem.c
7229+++ b/src/win/wsystem.c
7230@@ -31,7 +31,7 @@
7231 #endif
7232
7233 /* DMC requires a DllMain() function, or else the DLL hangs. */
7234-#ifndef ALLEGRO_STATICLINK
7235+#if !defined(ALLEGRO_STATICLINK) && defined(ALLEGRO_DMC)
7236 BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason, LPVOID lpReserved)
7237 {
7238 return TRUE;
7239@@ -491,7 +491,7 @@ int _WinMain(void *_main, void *hInst, void *hPrev, char *Cmd, int nShow)
7240
7241 /* can't use parameter because it doesn't include the executable name */
7242 cmdline = GetCommandLine();
7243- i = strlen(cmdline) + 1;
7244+ i = (int)strlen(cmdline) + 1;
7245 argbuf = _AL_MALLOC(i);
7246 memcpy(argbuf, cmdline, i);
7247
7248diff --git a/src/win/wwnd.c b/src/win/wwnd.c
7249index fc19076..96d0cdd 100644
7250--- a/src/win/wwnd.c
7251+++ b/src/win/wwnd.c
7252@@ -1,6 +1,6 @@
7253-/* ______ ___ ___
7254- * /\ _ \ /\_ \ /\_ \
7255- * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
7256+/* ______ ___ ___
7257+ * /\ _ \ /\_ \ /\_ \
7258+ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
7259 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
7260 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
7261 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7262@@ -13,6 +13,8 @@
7263 * By Stefan Schimanski.
7264 *
7265 * See readme.txt for copyright information.
7266+ *
7267+ ****** CJ CHANGES: Made allegro_wnd non-static
7268 */
7269
7270
7271@@ -36,7 +38,7 @@
7272
7273
7274 /* general */
7275-static HWND allegro_wnd = NULL;
7276+HWND allegro_wnd = NULL;
7277 char wnd_title[WND_TITLE_SIZE]; /* ASCII string */
7278 int wnd_x = 0;
7279 int wnd_y = 0;
7280@@ -189,7 +191,7 @@ static void exit_window_modules(struct WINDOW_MODULES *wm)
7281 */
7282 int wnd_call_proc(int (*proc) (void))
7283 {
7284- return SendMessage(allegro_wnd, msg_call_proc, (DWORD) proc, 0);
7285+ return SendMessage(allegro_wnd, msg_call_proc, (WPARAM)proc, (LPARAM)0);
7286 }
7287
7288
7289@@ -200,7 +202,7 @@ int wnd_call_proc(int (*proc) (void))
7290 */
7291 void wnd_schedule_proc(int (*proc) (void))
7292 {
7293- PostMessage(allegro_wnd, msg_call_proc, (DWORD) proc, 0);
7294+ PostMessage(allegro_wnd, msg_call_proc, (WPARAM)proc, (LPARAM)0);
7295 }
7296
7297
7298@@ -213,7 +215,7 @@ static LRESULT CALLBACK directx_wnd_proc(HWND wnd, UINT message, WPARAM wparam,
7299 PAINTSTRUCT ps;
7300
7301 if (message == msg_call_proc)
7302- return ((int (*)(void))wparam) ();
7303+ return ( ( LRESULT(*)( void ) )wparam ) ( );
7304
7305 if (message == msg_suicide) {
7306 DestroyWindow(wnd);
7307@@ -224,7 +226,7 @@ static LRESULT CALLBACK directx_wnd_proc(HWND wnd, UINT message, WPARAM wparam,
7308 if (wnd_msg_pre_proc){
7309 int retval = 0;
7310 if (wnd_msg_pre_proc(wnd, message, wparam, lparam, &retval) == 0)
7311- return retval;
7312+ return (LRESULT)retval;
7313 }
7314
7315 /* See get_reverse_mapping() in wkeybd.c to see what this is for. */
7316@@ -373,7 +375,7 @@ static LRESULT CALLBACK directx_wnd_proc(HWND wnd, UINT message, WPARAM wparam,
7317
7318 case WM_MENUCHAR :
7319 return (MNC_CLOSE<<16)|(wparam&0xffff);
7320-
7321+
7322 case WM_CLOSE:
7323 if (!user_wnd_proc) {
7324 if (user_close_proc)
7325@@ -456,7 +458,7 @@ static HWND create_directx_window(void)
7326 */
7327 static void wnd_thread_proc(HANDLE setup_event)
7328 {
7329- int result;
7330+ DWORD result;
7331 MSG msg;
7332
7333 _win_thread_init();
7334@@ -477,7 +479,7 @@ static void wnd_thread_proc(HANDLE setup_event)
7335 /* message loop */
7336 while (TRUE) {
7337 result = MsgWaitForMultipleObjects(_win_input_events, _win_input_event_id, FALSE, INFINITE, QS_ALLINPUT);
7338- if ((result >= WAIT_OBJECT_0) && (result < WAIT_OBJECT_0 + _win_input_events)) {
7339+ if ((result >= WAIT_OBJECT_0) && (result < (int)(WAIT_OBJECT_0 + _win_input_events))) {
7340 /* one of the registered events is in signaled state */
7341 (*_win_input_event_handler[result - WAIT_OBJECT_0])();
7342 }
7343@@ -523,7 +525,7 @@ int init_directx_window(void)
7344 _win_input_init(TRUE);
7345
7346 /* hook the user window */
7347- user_wnd_proc = (WNDPROC) SetWindowLong(user_wnd, GWL_WNDPROC, (long)directx_wnd_proc);
7348+ user_wnd_proc = (WNDPROC) SetWindowLongPtr(user_wnd, GWLP_WNDPROC, (LONG_PTR)directx_wnd_proc);
7349 if (!user_wnd_proc)
7350 return -1;
7351
7352@@ -557,7 +559,7 @@ int init_directx_window(void)
7353
7354 default: /* thread failed to create window */
7355 return -1;
7356- }
7357+ }
7358 }
7359
7360 /* initialize gfx critical section */
7361@@ -579,7 +581,7 @@ void exit_directx_window(void)
7362 {
7363 if (user_wnd) {
7364 /* restore old window proc */
7365- SetWindowLong(user_wnd, GWL_WNDPROC, (long)user_wnd_proc);
7366+ SetWindowLongPtr(user_wnd, GWLP_WNDPROC, (LONG_PTR)user_wnd_proc);
7367 user_wnd_proc = NULL;
7368 user_wnd = NULL;
7369 allegro_wnd = NULL;
7370@@ -598,7 +600,7 @@ void exit_directx_window(void)
7371 DeleteCriticalSection(&gfx_crit_sect);
7372
7373 _win_input_exit();
7374-
7375+
7376 window_is_initialized = FALSE;
7377 }
7378
7379@@ -651,11 +653,11 @@ int adjust_window(int w, int h)
7380 }
7381 if (!user32_handle || !get_title_bar_info)
7382 tb_height = GetSystemMetrics(SM_CYSIZE);
7383-
7384+
7385 /* try to center the window relative to its last position */
7386 last_wnd_x += (last_w - w)/2;
7387 last_wnd_y += (last_h - h)/2;
7388-
7389+
7390 if (last_wnd_x + w >= working_area.right)
7391 last_wnd_x = working_area.right - w;
7392 if (last_wnd_y + h >= working_area.bottom)
7393@@ -680,7 +682,7 @@ int adjust_window(int w, int h)
7394
7395 /* retrieve the size of the decorated window */
7396 AdjustWindowRect(&win_size, GetWindowLong(allegro_wnd, GWL_STYLE), FALSE);
7397-
7398+
7399 /* display the window */
7400 MoveWindow(allegro_wnd, win_size.left, win_size.top,
7401 win_size.right - win_size.left, win_size.bottom - win_size.top, TRUE);
7402@@ -702,7 +704,7 @@ int adjust_window(int w, int h)
7403
7404
7405 /* save_window_pos:
7406- * Stores the position of the current window before closing it so that
7407+ * Stores the position of the current window before closing it so that
7408 * it can be used as the initial position for the next window.
7409 */
7410 void save_window_pos(void)
7411@@ -746,7 +748,7 @@ void win_set_window(HWND wnd)
7412 init_directx_window();
7413 init_window_modules(&wm);
7414 }
7415-
7416+
7417 window_is_initialized = TRUE;
7418 }
7419
7420diff --git a/src/x/xdga2.c b/src/x/xdga2.c
7421index 0199d49..abf087a 100644
7422--- a/src/x/xdga2.c
7423+++ b/src/x/xdga2.c
7424@@ -23,7 +23,7 @@
7425 #if (defined ALLEGRO_XWINDOWS_WITH_XF86DGA2) && ((!defined ALLEGRO_WITH_MODULES) || (defined ALLEGRO_MODULE))
7426
7427 #include <X11/Xlib.h>
7428-#include <X11/extensions/xf86dga.h>
7429+#include <X11/extensions/Xxf86dga.h>
7430
7431
7432 #define RESYNC() XDGASync(_xwin.display, _xwin.screen);
7433diff --git a/tests/play.c b/tests/play.c
7434index c282302..4885223 100644
7435--- a/tests/play.c
7436+++ b/tests/play.c
7437@@ -74,7 +74,7 @@ void usage(void)
7438
7439 strcat(msg, "\nIf you don't specify the card, Allegro will auto-detect (ie. guess :-)\n");
7440
7441- allegro_message(msg);
7442+ allegro_message("%s", msg);
7443 free(msg);
7444 }
7445
7446diff --git a/tools/pack.c b/tools/pack.c
7447index 0941853..58d7f17 100644
7448--- a/tools/pack.c
7449+++ b/tools/pack.c
7450@@ -42,7 +42,7 @@ static void err(char *s1, char *s2)
7451 printf(": %s", s1);
7452
7453 if (s2)
7454- printf(s2);
7455+ printf("%s", s2);
7456
7457 printf("\n");
7458
7459diff --git a/tools/textconv.c b/tools/textconv.c
7460index 499536b..4f44d3c 100644
7461--- a/tools/textconv.c
7462+++ b/tools/textconv.c
7463@@ -62,8 +62,8 @@ void usage(void)
7464 printf("\ta - 8 bit ASCII (Latin-1 codepage)\n");
7465 printf("\tb - 7 bit bare ASCII or codepage loaded via -f\n");
7466 printf("\tu - UTF-8 encoding\n");
7467- printf("\tw - 16 bit Unicode (current machine endianess)\n");
7468- printf("\tW - 16 bit Unicode (flip endianess)\n");
7469+ printf("\tw - 16 bit Unicode (current machine endianness)\n");
7470+ printf("\tW - 16 bit Unicode (flip endianness)\n");
7471 printf("\n");
7472 printf("Option flags:\n");
7473 printf("\t-f{file} = load alternate codepage file\n");
7474@@ -71,7 +71,7 @@ void usage(void)
7475 printf("\t-h = output data in hex format (default is binary)\n");
7476 printf("\t-d = output line breaks in DOS (CR/LF) format\n");
7477 printf("\t-u = output line breaks in Unix (LF) format\n");
7478- printf("\t-w = add an endianess watermark to Unicode output files\n");
7479+ printf("\t-w = add an endianness watermark to Unicode output files\n");
7480 printf("\t-v = verbose output\n");
7481 printf("\n");
7482 printf("If filenames are not specified, stdin and stdout will be used\n");
7483@@ -99,12 +99,12 @@ UTYPE_INFO *get_format_info(int type, char **desc, int *flip)
7484 return _find_utype(U_UTF8);
7485
7486 case 'w':
7487- *desc = "Unicode (default endianess)";
7488+ *desc = "Unicode (default endianness)";
7489 *flip = FALSE;
7490 return _find_utype(U_UNICODE);
7491
7492 case 'W':
7493- *desc = "Unicode (flip endianess)";
7494+ *desc = "Unicode (flip endianness)";
7495 *flip = TRUE;
7496 return _find_utype(U_UNICODE);
7497 }
7498@@ -430,7 +430,7 @@ int main(int argc, char *argv[])
7499
7500 if (flag_watermark) {
7501 if (flag_verbose)
7502- printf("Adding Unicode endianess watermark\n");
7503+ printf("Adding Unicode endianness watermark\n");
7504 write_output(out_file, 0xFEFF);
7505 }
7506
7507@@ -452,13 +452,13 @@ int main(int argc, char *argv[])
7508
7509 case 0xFEFF:
7510 if (flag_verbose)
7511- printf("Endianess watermark ok\n");
7512+ printf("Endianness watermark ok\n");
7513 was_cr = FALSE;
7514 continue;
7515
7516 case 0xFFFE:
7517 if (flag_verbose)
7518- printf("Bad endianess watermark! Toggling input format...\n");
7519+ printf("Bad endianness watermark! Toggling input format...\n");
7520 in_flip = !in_flip;
7521 was_cr = FALSE;
7522 continue;