- Added bootmenu.resource and bootloader.resource to Mingw32 build
[AROS.git] / arch / all-sdl / hidd / gfxclass.c
blobf9e2b89766cd21c7d9bb0683eb00b849fbf9aeef
1 /*
2 * sdl.hidd - SDL graphics/sound/keyboard for AROS hosted
3 * Copyright (c) 2007 Robert Norris. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the same terms as AROS itself.
7 */
9 #define __OOP_NOATTRBASES__
11 #include <aros/symbolsets.h>
13 #include <hidd/hidd.h>
14 #include <hidd/graphics.h>
15 #include <utility/tagitem.h>
16 #include <oop/oop.h>
18 #include <proto/exec.h>
19 #include <proto/oop.h>
20 #include <proto/utility.h>
22 #include "sdl_intern.h"
24 #include LC_LIBDEFS_FILE
26 #define DEBUG 0
27 #include <aros/debug.h>
29 static OOP_AttrBase HiddPixFmtAttrBase;
30 static OOP_AttrBase HiddBitMapAttrBase;
31 static OOP_AttrBase HiddSyncAttrBase;
32 static OOP_AttrBase HiddGfxAttrBase;
33 static OOP_AttrBase HiddSDLBitMapAttrBase;
35 static struct OOP_ABDescr attrbases[] = {
36 { IID_Hidd_PixFmt, &HiddPixFmtAttrBase },
37 { IID_Hidd_BitMap, &HiddBitMapAttrBase },
38 { IID_Hidd_Sync, &HiddSyncAttrBase },
39 { IID_Hidd_Gfx, &HiddGfxAttrBase },
40 { IID_Hidd_SDLBitMap, &HiddSDLBitMapAttrBase },
41 { NULL, NULL }
44 static int sdl_gfxclass_init(LIBBASETYPEPTR LIBBASE) {
45 D(bug("[sdl] sdl_gfxclass_init\n"));
47 return OOP_ObtainAttrBases(attrbases);
50 static int sdl_gfxclass_expunge(LIBBASETYPEPTR LIBBASE) {
51 D(bug("[sdl] sdl_gfxclass_expunge\n"));
53 OOP_ReleaseAttrBases(attrbases);
54 return TRUE;
57 ADD2INITLIB(sdl_gfxclass_init , 0)
58 ADD2EXPUNGELIB(sdl_gfxclass_expunge, 0)
60 #define SDLGfxBase ((LIBBASETYPEPTR) cl->UserData)
62 static const SDL_Rect mode_1600_1200 = { .w = 1600, .h = 1200 };
63 static const SDL_Rect mode_1280_1024 = { .w = 1280, .h = 1024 };
64 static const SDL_Rect mode_1280_960 = { .w = 1280, .h = 960 };
65 static const SDL_Rect mode_1152_864 = { .w = 1152, .h = 864 };
66 static const SDL_Rect mode_1024_768 = { .w = 1024, .h = 768 };
67 static const SDL_Rect mode_800_600 = { .w = 800, .h = 600 };
69 static const SDL_Rect *default_modes[] = {
70 &mode_1600_1200,
71 &mode_1280_1024,
72 &mode_1280_960,
73 &mode_1152_864,
74 &mode_1024_768,
75 &mode_800_600,
76 NULL
79 OOP_Object *SDLGfx__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg) {
80 const SDL_VideoInfo *info;
81 const SDL_PixelFormat *pixfmt;
82 char driver[128] = "";
83 Uint32 surftype;
84 SDL_Rect **modes;
85 struct TagItem *pftags;
86 int nmodes, i;
87 APTR tagpool;
88 struct TagItem **synctags, *modetags, *msgtags;
89 char *desc;
90 struct pRoot_New supermsg;
92 S(SDL_VideoDriverName, driver, sizeof(driver));
93 info = S(SDL_GetVideoInfo);
94 pixfmt = info->vfmt;
96 kprintf("sdlgfx: using %s driver\n", driver);
98 D(bug("[sdl] window manager: %savailable\n", info->wm_available ? "" : "not "));
99 D(bug("[sdl] hardware surfaces: %savailable\n", info->hw_available ? "" : "not "));
101 LIBBASE->use_hwsurface = info->hw_available ? TRUE : FALSE;
102 surftype = LIBBASE->use_hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE;
104 D(bug("[sdl] colour model: %s\n", pixfmt->palette == NULL ? "truecolour" : "palette"));
105 if (pixfmt->palette == NULL) {
106 D(bug("[sdl] colour mask: alpha=0x%08x red=0x%08x green=0x%08x blue=0x%08x\n", pixfmt->Amask, pixfmt->Rmask, pixfmt->Gmask, pixfmt->Bmask, pixfmt->Amask));
107 D(bug("[sdl] colour shift: alpha=%d red=%d green=%d blue=%d\n", pixfmt->Ashift, pixfmt->Rshift, pixfmt->Gshift, pixfmt->Bshift, pixfmt->Ashift));
110 if (pixfmt->palette != NULL) {
111 /* XXX deal with palette (CLUT) modes */
114 else {
115 /* select an appropriate AROS pixel format based on the SDL format */
116 int stdpixfmt = vHidd_StdPixFmt_Unknown;
117 int alpha_shift, red_shift, green_shift, blue_shift;
119 if (pixfmt->BitsPerPixel == 32) {
120 if (pixfmt->Amask == 0x000000ff && pixfmt->Rmask == 0x0000ff00 &&
121 pixfmt->Gmask == 0x00ff0000 && pixfmt->Bmask == 0xff000000) {
122 stdpixfmt = vHidd_StdPixFmt_ARGB32;
123 alpha_shift = 24;
124 red_shift = 16;
125 green_shift = 8;
126 blue_shift = 0;
129 else if (pixfmt->Amask == 0xff000000 && pixfmt->Rmask == 0x00ff0000 &&
130 pixfmt->Gmask == 0x0000ff00 && pixfmt->Bmask == 0x000000ff) {
131 stdpixfmt = vHidd_StdPixFmt_BGRA32;
132 alpha_shift = 0;
133 red_shift = 8;
134 green_shift = 16;
135 blue_shift = 24;
138 else if (pixfmt->Amask == 0xff000000 && pixfmt->Rmask == 0x000000ff &&
139 pixfmt->Gmask == 0x0000ff00 && pixfmt->Bmask == 0x00ff0000) {
140 stdpixfmt = vHidd_StdPixFmt_RGBA32;
141 alpha_shift = 0;
142 red_shift = 24;
143 green_shift = 16;
144 blue_shift = 8;
147 else if (pixfmt->Amask == 0x000000ff && pixfmt->Rmask == 0xff000000 &&
148 pixfmt->Gmask == 0x00ff0000 && pixfmt->Bmask == 0x0000ff00) {
149 stdpixfmt = vHidd_StdPixFmt_ABGR32;
150 alpha_shift = 24;
151 red_shift = 0;
152 green_shift = 8;
153 blue_shift = 16;
156 else if (pixfmt->Amask == 0x00000000 && pixfmt->Rmask == 0x0000ff00 &&
157 pixfmt->Gmask == 0x00ff0000 && pixfmt->Bmask == 0xff000000) {
158 stdpixfmt = vHidd_StdPixFmt_0RGB32;
159 alpha_shift = 0;
160 red_shift = 16;
161 green_shift = 8;
162 blue_shift = 0;
165 else if (pixfmt->Amask == 0x00000000 && pixfmt->Rmask == 0x00ff0000 &&
166 pixfmt->Gmask == 0x0000ff00 && pixfmt->Bmask == 0x000000ff) {
167 stdpixfmt = vHidd_StdPixFmt_BGR032;
168 alpha_shift = 0;
169 red_shift = 8;
170 green_shift = 16;
171 blue_shift = 24;
174 else if (pixfmt->Amask == 0x00000000 && pixfmt->Rmask == 0x000000ff &&
175 pixfmt->Gmask == 0x0000ff00 && pixfmt->Bmask == 0x00ff0000) {
176 stdpixfmt = vHidd_StdPixFmt_RGB032;
177 alpha_shift = 0;
178 red_shift = 24;
179 green_shift = 16;
180 blue_shift = 8;
183 else if (pixfmt->Amask == 0x00000000 && pixfmt->Rmask == 0xff000000 &&
184 pixfmt->Gmask == 0x00ff0000 && pixfmt->Bmask == 0x0000ff00) {
185 stdpixfmt = vHidd_StdPixFmt_0BGR32;
186 alpha_shift = 0;
187 red_shift = 0;
188 green_shift = 8;
189 blue_shift = 16;
193 else if (pixfmt->BitsPerPixel == 24) {
194 /* XXX implement
195 vHidd_StdPixFmt_RGB24
196 vHidd_StdPixFmt_BGR24
200 else if (pixfmt->BitsPerPixel == 16) {
201 /* XXX implement
202 vHidd_StdPixFmt_RGB16
203 vHidd_StdPixFmt_RGB16_LE
204 vHidd_StdPixFmt_BGR16
205 vHidd_StdPixFmt_BGR16_LE
209 else if (pixfmt->BitsPerPixel == 15) {
210 /* XXX implement
211 vHidd_StdPixFmt_RGB15,
212 vHidd_StdPixFmt_RGB15_LE,
213 vHidd_StdPixFmt_BGR15,
214 vHidd_StdPixFmt_BGR15_LE,
218 if (stdpixfmt == vHidd_StdPixFmt_Unknown) {
219 stdpixfmt = vHidd_StdPixFmt_Native;
220 alpha_shift = pixfmt->Ashift;
221 red_shift = pixfmt->Rshift;
222 green_shift = pixfmt->Gshift;
223 blue_shift = pixfmt->Bshift;
226 D(bug("[sdl] selected pixel format %d\n", stdpixfmt));
228 pftags = TAGLIST(
229 aHidd_PixFmt_ColorModel, vHidd_ColorModel_TrueColor,
230 aHidd_PixFmt_RedShift, red_shift,
231 aHidd_PixFmt_GreenShift, green_shift,
232 aHidd_PixFmt_BlueShift, blue_shift,
233 aHidd_PixFmt_AlphaShift, alpha_shift,
234 aHidd_PixFmt_RedMask, pixfmt->Rmask,
235 aHidd_PixFmt_GreenMask, pixfmt->Gmask,
236 aHidd_PixFmt_BlueMask, pixfmt->Bmask,
237 aHidd_PixFmt_AlphaMask, pixfmt->Amask,
238 aHidd_PixFmt_Depth, pixfmt->BitsPerPixel,
239 aHidd_PixFmt_BitsPerPixel, pixfmt->BitsPerPixel,
240 aHidd_PixFmt_BytesPerPixel, pixfmt->BytesPerPixel,
241 aHidd_PixFmt_StdPixFmt, stdpixfmt,
242 aHidd_PixFmt_BitMapType, vHidd_BitMapType_Chunky
246 LIBBASE->use_fullscreen = CFG_WANT_FULLSCREEN ? TRUE : FALSE;
248 modes = S(SDL_ListModes, NULL, surftype | LIBBASE->use_fullscreen ? SDL_FULLSCREEN : 0);
250 D(bug("[sdl] available modes:"));
251 if (modes == NULL) {
252 D(bug(" none\n"));
253 nmodes = 0;
255 else {
256 if (modes == (SDL_Rect **) -1) {
257 D(bug(" (default)"));
258 modes = default_modes;
260 for (nmodes = 0; modes[nmodes] != NULL && modes[nmodes]->w != 0; nmodes++)
261 D(bug(" %dx%d", modes[nmodes]->w, modes[nmodes]->h));
262 D(bug("\n"));
265 D(bug("[sdl] building %d mode sync items\n", nmodes));
267 tagpool = CreatePool(MEMF_CLEAR, 1024, 128);
269 synctags = AllocPooled(tagpool, sizeof(struct TagItem *) * (nmodes+1));
271 for (i = 0; i < nmodes; i++) {
272 /* remove modes larger than the current screen res */
273 if (modes[i]->w > info->current_w || modes[i]->h > info->current_h) {
274 synctags[i] = NULL;
275 continue;
278 desc = AllocPooled(tagpool, 16);
279 sprintf(desc, "SDL:%dx%d", modes[i]->w, modes[i]->h);
281 synctags[i] = AllocPooled(tagpool, sizeof(struct TagItem) * 4);
282 synctags[i][0].ti_Tag = aHidd_Sync_HDisp; synctags[i][0].ti_Data = modes[i]->w;
283 synctags[i][1].ti_Tag = aHidd_Sync_VDisp; synctags[i][1].ti_Data = modes[i]->h;
284 synctags[i][2].ti_Tag = aHidd_Sync_Description; synctags[i][2].ti_Data = (IPTR) desc;
285 synctags[i][3].ti_Tag = TAG_DONE;
288 modetags = AllocPooled(tagpool, sizeof(struct TagItem) * (nmodes+9));
290 modetags[0].ti_Tag = aHidd_Gfx_PixFmtTags; modetags[0].ti_Data = (IPTR) pftags;
291 modetags[1].ti_Tag = aHidd_Sync_PixelClock; modetags[1].ti_Data = 100000000;
292 modetags[2].ti_Tag = aHidd_Sync_LeftMargin; modetags[2].ti_Data = 0;
293 modetags[3].ti_Tag = aHidd_Sync_RightMargin; modetags[3].ti_Data = 0;
294 modetags[4].ti_Tag = aHidd_Sync_UpperMargin; modetags[4].ti_Data = 0;
295 modetags[5].ti_Tag = aHidd_Sync_LowerMargin; modetags[5].ti_Data = 0;
296 modetags[6].ti_Tag = aHidd_Sync_HSyncLength; modetags[6].ti_Data = 0;
297 modetags[7].ti_Tag = aHidd_Sync_VSyncLength; modetags[7].ti_Data = 0;
299 for (i = 0; i < nmodes; i++) {
300 if (synctags[i] == NULL) {
301 modetags[8+i].ti_Tag = TAG_IGNORE;
302 continue;
305 modetags[8+i].ti_Tag = aHidd_Gfx_SyncTags;
306 modetags[8+i].ti_Data = (IPTR) synctags[i];
309 modetags[8+i].ti_Tag = TAG_DONE;
311 msgtags = TAGLIST(
312 aHidd_Gfx_ModeTags, (IPTR) modetags,
313 TAG_MORE, (IPTR) msg->attrList
316 supermsg.mID = msg->mID;
317 supermsg.attrList = msgtags;
319 D(bug("[sdl] hidd tags built, calling supermethod\n"));
321 o = (OOP_Object *) OOP_DoSuperMethod(cl, o, (OOP_Msg) &supermsg);
323 DeletePool(tagpool);
325 if (o == NULL) {
326 D(bug("[sdl] supermethod failed, bailing out\n"));
327 return NULL;
330 return (OOP_Object *) o;
333 VOID SDLGfx__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg) {
334 SDL_Surface *s;
336 D(bug("[sdl] SDLGfx::Dispose\n"));
338 s = S(SDL_GetVideoSurface);
339 if (s != NULL) {
340 D(bug("[sdl] freeing existing video surface\n"));
341 SV(SDL_FreeSurface, s);
344 OOP_DoSuperMethod(cl, o, msg);
346 return;
349 OOP_Object *SDLGfx__Hidd_Gfx__NewBitMap(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_NewBitMap *msg) {
350 OOP_Object *bmclass = NULL, *friend, *gfxhidd;
351 BOOL displayable;
352 HIDDT_ModeID modeid;
353 HIDDT_StdPixFmt stdpixfmt;
354 struct TagItem *msgtags;
355 struct pHidd_Gfx_NewBitMap supermsg;
357 D(bug("[sdl] SDLGfx::NewBitMap\n"));
359 if (GetTagData(aHidd_BitMap_FrameBuffer, FALSE, msg->attrList)) {
360 D(bug("[sdl] framebuffer bitmap, we can handle it\n"));
361 bmclass = LIBBASE->bmclass;
364 else if (GetTagData(aHidd_BitMap_Displayable, FALSE, msg->attrList)) {
365 D(bug("[sdl] displayable bitmap, we can handle it\n"));
366 bmclass = LIBBASE->bmclass;
369 else if ((HIDDT_ModeID) GetTagData(aHidd_BitMap_ModeID, vHidd_ModeID_Invalid, msg->attrList) != vHidd_ModeID_Invalid) {
370 D(bug("[sdl] bitmap with valid mode, we can handle it\n"));
371 bmclass = LIBBASE->bmclass;
374 else if ((HIDDT_StdPixFmt) GetTagData(aHidd_BitMap_StdPixFmt, vHidd_StdPixFmt_Unknown, msg->attrList) == vHidd_StdPixFmt_Unknown) {
375 friend = (OOP_Object *) GetTagData(aHidd_BitMap_Friend, NULL, msg->attrList);
376 if (friend != NULL) {
377 OOP_GetAttr(friend, aHidd_BitMap_GfxHidd, (APTR) &gfxhidd);
378 if (gfxhidd == o) {
379 D(bug("[sdl] bitmap with unknown pixel format and sdl friend bitmap, we can handle it\n"));
380 bmclass = LIBBASE->bmclass;
385 if (bmclass != NULL)
386 msgtags = TAGLIST(
387 aHidd_BitMap_ClassPtr, (IPTR) LIBBASE->bmclass,
388 TAG_MORE, (IPTR) msg->attrList
391 else
392 msgtags = msg->attrList;
394 supermsg.mID = msg->mID;
395 supermsg.attrList = msgtags;
397 o = (OOP_Object *) OOP_DoSuperMethod(cl, o, (OOP_Msg) &supermsg);
399 return o;
402 VOID SDLGfx__Hidd_Gfx__CopyBox(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CopyBox *msg) {
403 struct SDL_Surface *src, *dest;
404 struct SDL_Rect srect, drect;
405 BOOL is_onscreen;
407 D(bug("[sdl] SDLGfx::CopyBox\n"));
409 OOP_GetAttr(msg->src, aHidd_SDLBitMap_Surface, &src);
410 OOP_GetAttr(msg->dest, aHidd_SDLBitMap_Surface, &dest);
412 if (src == NULL || dest == NULL) {
413 D(bug("[sdl] missing a surface: src is 0x%08x, dest is 0x%08x. letting the superclass deal with it\n", src, dest));
415 OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
417 return;
420 srect.x = msg->srcX;
421 srect.y = msg->srcY;
422 srect.w = msg->width;
423 srect.h = msg->height;
425 drect.x = msg->destX;
426 drect.y = msg->destY;
428 D(bug("[sdl] blitting %dx%d rect from src 0x%08x [%d,%d] to dest 0x%08x [%d,%d]\n", msg->width, msg->height, src, msg->srcX, msg->srcY, dest, msg->destX, msg->destY));
430 S(SDL_BlitSurface, src, &srect, dest, &drect);
432 OOP_GetAttr(msg->dest, aHidd_SDLBitMap_IsOnScreen, &is_onscreen);
433 if (is_onscreen) {
434 D(bug("[sdl] refreshing onscreen surface 0x%08x\n", dest));
436 SV(SDL_UpdateRect, dest, msg->destX, msg->destY, msg->width, msg->height);
439 return;