1 /*         ______   ___    ___
2  *        /\  _  \ /\_ \  /\_ \
3  *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___
4  *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
5  *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
6  *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7  *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8  *                                           /\____/
9  *                                           \_/__/
10  *
11  *      DrawSprocket graphics drivers.
12  *
13  *      By Ronaldo Hideki Yamada.
14  *
15  *      See readme.txt for copyright information.
16  */
17 #include "allegro.h"
18 #include "macalleg.h"
19 #include "allegro/platform/aintmac.h"
20 #include <string.h>
21 
22 #define TRACE_MAC_GFX 0
23 /*Our main display device the display which contains the menubar on macs with more one display*/
24 GDHandle MainGDevice;
25 /*Our main Color Table for indexed devices*/
26 CTabHandle MainCTable = NULL;
27 /*Our current deph*/
28 short dspr_depth;
29 /*Vsync has ocurred*/
30 volatile short _sync = 0;
31 /*Vsync handler installed ?*/
32 short dspr_sync_installed = 0;
33 /*the control state of dspr*/
34 short dspr_state = 0;
35 /*Our dspr context*/
36 DSpContextReference   dspr_context;
37 /*??? Used for DrawSprocket e Vsync callback*/
38 const char refconst[16];
39 
40 const RGBColor ForeDef={0,0,0};
41 const RGBColor BackDef={0xFFFF,0xFFFF,0xFFFF};
42 
43 static char dspr_desc[256]=EMPTY_STRING;
44 
45 static BITMAP *dspr_init(int w, int h, int v_w, int v_h, int color_depth);
46 static void dspr_exit(struct BITMAP *b);
47 static void dspr_vsync(void);
48 static void dspr_set_palette(const struct RGB *p, int from, int to, int retracesync);
49 static short dspr_active();
50 static short dspr_pause();
51 static short dspr_inactive();
52 static CGrafPtr dspr_get_back();
53 static CGrafPtr dspr_get_front();
54 static void dspr_swap();
55 static Boolean  dspr_vsync_interrupt(DSpContextReference inContext, void *inRefCon);
56 
57 #pragma mark GFX_DRIVER
58 GFX_DRIVER gfx_drawsprocket ={
59    GFX_DRAWSPROCKET,
60    empty_string,
61    empty_string,
62    "DrawSprocket",
63    dspr_init,
64    dspr_exit,
65    NULL,
66    dspr_vsync,
67    dspr_set_palette,
68    NULL,
69    NULL,
70    NULL,
71    NULL,
72    NULL,
73    NULL,
74    NULL,
75    _mac_create_system_bitmap,
76    _mac_destroy_system_bitmap,
77    NULL,
78    NULL,
79    NULL,
80    NULL,
81    NULL,
82    NULL,
83    NULL,
84    NULL,    // AL_METHOD(void, set_blender_mode, (int mode, int r, int g, int b, int a));
85    NULL,
86    640, 480,
87    TRUE,
88    0,
89    0,
90    0,
91    0,
92 };
93 
94 
95 
96 /*
97  * init an gfx mode return an pointer to BITMAP on sucess, NULL fails
98  */
99 #pragma mark gfx driver routines
dspr_init(int w,int h,int v_w,int v_h,int color_depth)100 static BITMAP *dspr_init(int w, int h, int v_w, int v_h, int color_depth)
101 {
102    OSStatus e;
103    CGrafPtr cg;
104    BITMAP* b;
105    DSpContextAttributes Attr;
106    Fixed myfreq;
107    int done;
108 
109 #if(TRACE_MAC_GFX)
110    fprintf(stdout,"dspr_init(%d, %d, %d, %d, %d)\n", w, h, v_w, v_h, color_depth);
111    fflush(stdout);
112 #endif
113 
114    if ((v_w != w && v_w != 0) || (v_h != h && v_h != 0)) return (NULL);
115 
116 
117    Attr.frequency = Long2Fix(_refresh_rate_request);
118    Attr.reserved1 = 0;
119    Attr.reserved2 = 0;
120    Attr.colorNeeds = kDSpColorNeeds_Require;
121    Attr.colorTable = MainCTable;
122    Attr.contextOptions = 0;
123    Attr.gameMustConfirmSwitch = false;
124    Attr.reserved3[0] = 0;
125    Attr.reserved3[1] = 0;
126    Attr.reserved3[2] = 0;
127    Attr.reserved3[3] = 0;
128    Attr.pageCount = 1;
129    Attr.displayWidth = w;
130    Attr.displayHeight = h;
131    Attr.displayBestDepth = color_depth;
132 
133    _rgb_r_shift_15 = 10;
134    _rgb_g_shift_15 = 5;
135    _rgb_b_shift_15 = 0;
136    _rgb_r_shift_16 = 10;
137    _rgb_g_shift_16 = 5;
138    _rgb_b_shift_16 = 0;
139    _rgb_r_shift_24 = 16;
140    _rgb_g_shift_24 = 8;
141    _rgb_b_shift_24 = 0;
142    _rgb_r_shift_32 = 16;
143    _rgb_g_shift_32 = 8;
144    _rgb_b_shift_32 = 0;
145 
146    switch(color_depth){
147       case 8:
148          dspr_depth = 8;
149          Attr.displayDepthMask = kDSpDepthMask_8;
150          break;
151       case 15:
152          dspr_depth = 15;
153          Attr.displayDepthMask = kDSpDepthMask_16;
154          break;
155       case 24:
156          dspr_depth = 24;
157          Attr.displayDepthMask = kDSpDepthMask_32;
158          break;
159       default:
160          goto Error;
161    }
162    Attr.backBufferBestDepth = color_depth;
163    Attr.backBufferDepthMask = Attr.displayDepthMask;
164 
165    e = DSpFindBestContext(&Attr, &dspr_context);
166    if(e != noErr){
167       Attr.frequency = 0;
168       e = DSpFindBestContext(&Attr, &dspr_context);
169    }
170    if(e != noErr) goto Error;/* I HATE "GOTO" */
171 
172    Attr.displayWidth = w;
173    Attr.displayHeight = h;
174    Attr.contextOptions = 0;
175 
176    e = DSpContext_Reserve(dspr_context, &Attr);
177    if(e != noErr) goto Error;/* I HATE "GOTO" */
178    dspr_state |= kRDDReserved;
179 
180    dspr_active();
181 
182    e = DSpContext_SetVBLProc (dspr_context, dspr_vsync_interrupt,(void *)refconst);
183    if(e == noErr){dspr_sync_installed = 1;}
184    else{dspr_sync_installed = 0;}
185 
186    cg = dspr_get_front();
187 
188    b =_CGrafPtr_to_system_bitmap(cg);
189    if(b){
190       DSpContext_GetMonitorFrequency  (dspr_context,&myfreq);
191       _set_current_refresh_rate(Fix2Long(myfreq));
192 
193       gfx_drawsprocket.w = w;
194       gfx_drawsprocket.h = h;
195 
196       uszprintf(dspr_desc, sizeof(dspr_desc), get_config_text("DrawSprocket %d x %d, %dbpp, %dhz"), w, h, dspr_depth, _current_refresh_rate);
197       gfx_drawsprocket.desc = dspr_desc;
198       return b;
199    }
200 Error:
201 #if(TRACE_MAC_GFX)
202    fprintf(stdout,"dspr_init()failed\n");
203    fflush(stdout);
204 #endif
205    dspr_exit(b);
206    return NULL;
207 }
208 
209 
210 
211 /*
212  * reservated
213  */
dspr_exit(struct BITMAP * b)214 static void dspr_exit(struct BITMAP *b)
215 {
216 #pragma unused b
217    OSStatus e;
218 #if(TRACE_MAC_GFX)
219    fprintf(stdout,"dspr_exit()\n");
220    fflush(stdout);
221 #endif
222    if((dspr_state & kRDDReserved) != 0){
223       e = DSpContext_SetState(dspr_context, kDSpContextState_Inactive);
224       e = DSpContext_Release(dspr_context);
225    }
226    dspr_state = 0;
227    gfx_drawsprocket.w = 0;
228    gfx_drawsprocket.h = 0;
229    dspr_depth = 0;
230 }
231 
232 
233 
234 /*
235  * reservated
236  */
dspr_vsync(void)237 static void dspr_vsync(void)
238 {
239    if(dspr_sync_installed){
240       _sync = 0;
241       while(!_sync){}
242    }
243 }
244 
245 
246 
247 /*
248  * reservated
249  */
dspr_set_palette(const struct RGB * p,int from,int to,int retracesync)250 static void dspr_set_palette(const struct RGB *p, int from, int to, int retracesync)
251 {
252    int i;OSErr e;
253 #if(TRACE_MAC_GFX)
254    fprintf(stdout,"set_palette");
255    fflush(stdout);
256 #endif
257    if(MainCTable == NULL){
258       MainCTable = GetCTable(8);
259       DetachResource((Handle) MainCTable);
260    }
261    for(i = from;i<= to;i ++){
262       (**MainCTable).ctTable[i].rgb.red = p[i].r*1040;
263       (**MainCTable).ctTable[i].rgb.green = p[i].g*1040;
264       (**MainCTable).ctTable[i].rgb.blue = p[i].b*1040;
265    }
266    if(retracesync)dspr_vsync();
267    if(dspr_depth == 8){
268       e = DSpContext_SetCLUTEntries(dspr_context, (**MainCTable).ctTable, from, to - from);
269    }
270 }
271 
272 
273 
274 /*
275  * reservated
276  */
dspr_active()277 static short dspr_active()
278 {
279    if(! (dspr_state & kRDDActive)){
280       if(! (dspr_state & kRDDPaused))
281 	      if(DSpContext_SetState(dspr_context , kDSpContextState_Active) != noErr)
282     	     return 1;
283       dspr_state &= (~kRDDPaused);
284       dspr_state |= kRDDActive;
285    }
286    return 0;
287 }
288 
289 
290 
291 /*
292  * reservated
293  */
dspr_pause()294 static short dspr_pause()
295 {
296    if(! (dspr_state & kRDDPaused)){
297       if(DSpContext_SetState(dspr_context, kDSpContextState_Paused) != noErr)return 1;
298       dspr_state &= (~kRDDActive);
299       dspr_state |= kRDDPaused;
300       DrawMenuBar();
301    }
302    return 0;
303 }
304 
305 
306 
307 /*
308  * reservated
309  */
dspr_inactive()310 static short dspr_inactive()
311 {
312    if(! (dspr_state & (kRDDPaused | kRDDActive))){
313       if(DSpContext_SetState(dspr_context, kDSpContextState_Inactive) != noErr)return 1;
314       dspr_state &= (~kRDDPaused);
315       dspr_state &= (~kRDDActive);
316       DrawMenuBar();
317    }
318    return 0;
319 }
320 
321 
322 
323 /*
324  * reservated
325  */
dspr_get_back()326 static CGrafPtr dspr_get_back()
327 {
328    CGrafPtr theBuffer;
329    DSpContext_GetBackBuffer(dspr_context, kDSpBufferKind_Normal, &theBuffer);
330    return theBuffer;
331 }
332 
333 
334 
335 /*
336  * reservated
337  */
dspr_get_front()338 static CGrafPtr dspr_get_front()
339 {
340    CGrafPtr theBuffer;
341    DSpContext_GetFrontBuffer(dspr_context, &theBuffer);
342    return theBuffer;
343 }
344 
345 
346 
347 
348 /*
349  * reservated
350  */
dspr_swap()351 static void dspr_swap()
352 {
353    DSpContext_SwapBuffers(dspr_context, nil, nil);
354 }
355 
356 
357 
358 /*
359  * our vsync interrupt handle
360  */
dspr_vsync_interrupt(DSpContextReference inContext,void * inRefCon)361 static Boolean dspr_vsync_interrupt (DSpContextReference inContext, void *inRefCon)
362 {
363 #pragma unused inContext, inRefCon
364    _sync = 1;
365    return false;
366 }
367 
368 
369 
370 /*
371  * drawsprocket initialization code should be called only one time
372  */
_dspr_sys_init()373 int _dspr_sys_init()
374 {
375    OSErr e;
376    MainGDevice = GetMainDevice();
377    if (MainGDevice == 0L)
378       return -1;
379    MainCTable = GetCTable(8);
380    DetachResource((Handle) MainCTable);
381    if ((Ptr) DSpStartup == (Ptr) kUnresolvedCFragSymbolAddress)
382       return -2;
383    e = DSpStartup();
384    if(e != noErr)
385       return -3;
386    dspr_state = 0;
387    HideCursor();
388    return 0;
389 }
390 
391 
392 
393 
394 /*
395  * drawsprocket exit code to should called only one time
396  */
_dspr_sys_exit()397 void _dspr_sys_exit()
398 {
399    DSpShutdown();
400    ShowCursor();
401 }
402 
403 
404 
405 
406