Bringing flexcat 2.15 into the main branch (again)
[AROS.git] / arch / m68k-amiga / hidd / gfx / amigavideogfx.c
blobbd31d756fe4e168440918330c04d023dbf927c42
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English.
7 */
9 #include <exec/libraries.h>
10 #include <exec/rawfmt.h>
11 #include <exec/types.h>
12 #include <exec/resident.h>
13 #include <exec/memory.h>
14 #include <graphics/displayinfo.h>
15 #include <aros/libcall.h>
16 #include <proto/alib.h>
17 #include <proto/exec.h>
18 #include <proto/graphics.h>
19 #include <proto/kernel.h>
20 #include <proto/oop.h>
21 #include <proto/utility.h>
22 #include <oop/oop.h>
24 #include <hidd/hidd.h>
25 #include <hidd/graphics.h>
27 #include <aros/symbolsets.h>
29 #include "amigavideogfx.h"
30 #include "amigavideobitmap.h"
32 #include "chipset.h"
33 #include "blitter.h"
35 #include LC_LIBDEFS_FILE
37 #define SDEBUG 0
38 #define DEBUG 0
39 #include <aros/debug.h>
41 #define SPECIALMODES 3
42 #define NATIVEMODES (3 * 4 * SPECIALMODES)
43 static const UWORD widthtable[] = { 320, 640, 1280, 0 };
44 static const UWORD heighttable[] = { 200, 256, 400, 512, 0 };
45 static const ULONG specialmask_aga[] = { 0, EXTRAHALFBRITE_KEY, HAM_KEY, 0xffffffff };
47 #define SPECIAL_MODE_MASK (EXTRAHALFBRITE_KEY | HAM_KEY)
49 ULONG AmigaVideoCl__Hidd_Gfx__ModeProperties(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_ModeProperties *msg)
51 ULONG flags = 0;
52 ULONG modeid = msg->modeID;
54 flags = DIPF_IS_SPRITES | DIPF_IS_DRAGGABLE |
55 DIPF_IS_SPRITES_ATT | DIPF_IS_SPRITES_CHNG_BASE | DIPF_IS_SPRITES_CHNG_PRI |
56 DIPF_IS_DBUFFER | DIPF_IS_BEAMSYNC | DIPF_IS_GENLOCK;
57 msg->props->NumHWSprites = 8;
58 if ((modeid & MONITOR_ID_MASK) == PAL_MONITOR_ID)
59 flags |= DIPF_IS_PAL;
60 if (modeid & LORESLACE_KEY)
61 flags |= DIPF_IS_LACE;
62 if (modeid & HAM_KEY) {
63 flags |= DIPF_IS_HAM;
64 if (modeid & SUPER_KEY)
65 flags |= DIPF_IS_AA;
67 if (modeid & EXTRAHALFBRITE_KEY) {
68 flags |= DIPF_IS_EXTRAHALFBRITE;
69 if (modeid & SUPER_KEY)
70 flags |= DIPF_IS_AA;
72 if ((modeid & SUPER_KEY) == SUPER_KEY && !(flags & DIPF_IS_AA))
73 flags |= DIPF_IS_ECS;
74 if (!(modeid & SPECIAL_MODE_MASK))
75 flags |= DIPF_IS_WB;
76 msg->props->DisplayInfoFlags = flags;
77 msg->props->CompositionFlags = COMPF_ABOVE | COMPF_BELOW; // | COMPF_LEFT | COMPF_RIGHT;
78 DB2(bug("ModeProp %08x = %08x\n", modeid, flags));
79 return sizeof(struct HIDD_ModeProperties);
82 HIDDT_ModeID *AmigaVideoCl__Hidd_Gfx__QueryModeIDs(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_QueryModeIDs *msg)
84 struct amigavideo_staticdata *csd = CSD(cl);
85 struct NativeChipsetMode *node;
86 struct TagItem *tag, *tstate;
87 ULONG minwidth = 0, maxwidth = 0xFFFFFFFF;
88 ULONG minheight = 0, maxheight = 0xFFFFFFFF;
89 HIDDT_ModeID *modeids;
90 struct Library *UtilityBase = csd->cs_UtilityBase;
91 WORD cnt;
93 if (csd->superforward)
94 return (HIDDT_ModeID*)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
96 for (tstate = msg->queryTags; (tag = NextTagItem(&tstate)); )
98 switch (tag->ti_Tag)
100 case tHidd_GfxMode_MinWidth:
101 minwidth = (ULONG)tag->ti_Tag;
102 break;
104 case tHidd_GfxMode_MaxWidth:
105 maxwidth = (ULONG)tag->ti_Tag;
106 break;
108 case tHidd_GfxMode_MinHeight:
109 minheight = (ULONG)tag->ti_Tag;
110 break;
112 case tHidd_GfxMode_MaxHeight:
113 maxheight = (ULONG)tag->ti_Tag;
114 break;
116 case tHidd_GfxMode_PixFmts:
117 /* all chipset modes have same pixelformat */
118 break;
122 DB2(bug("QueryModeIDs (%dx%d)-(%dx%d)\n", minwidth, minheight, maxwidth, maxheight));
123 cnt = 0;
124 ForeachNode(&csd->nativemodelist, node) {
125 if (node->width >= minwidth && node->width <= maxwidth && node->height >= minheight && node->height <= maxheight) {
126 cnt++;
129 modeids = AllocVec((cnt + 1) * sizeof(HIDDT_ModeID), MEMF_PUBLIC);
130 if (!modeids)
131 return NULL;
132 cnt = 0;
133 ForeachNode(&csd->nativemodelist, node) {
134 if (node->width >= minwidth && node->width <= maxwidth && node->height >= minheight && node->height <= maxheight) {
135 DB2(bug("%d: %08x\n", cnt, node->modeid));
136 modeids[cnt++] = node->modeid;
139 modeids[cnt] = vHidd_ModeID_Invalid;
140 return modeids;
143 VOID AmigaVideoCl__Hidd_Gfx__ReleaseModeIDs(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_ReleaseModeIDs *msg)
145 struct amigavideo_staticdata *csd = CSD(cl);
146 if (csd->superforward)
147 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
148 else
149 FreeVec(msg->modeIDs);
152 HIDDT_ModeID AmigaVideoCl__Hidd_Gfx__NextModeID(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_NextModeID *msg)
154 struct amigavideo_staticdata *csd = CSD(cl);
155 struct NativeChipsetMode *node = NULL;
156 HIDDT_ModeID mid = vHidd_ModeID_Invalid;
158 DB2(bug("NextModeID %08x\n", msg->modeID));
159 if (msg->modeID != vHidd_ModeID_Invalid) {
160 ForeachNode(&csd->nativemodelist, node) {
161 if (node->modeid == msg->modeID) {
162 node = (struct NativeChipsetMode*)node->node.ln_Succ;
163 break;
167 if (!node)
168 node = (struct NativeChipsetMode*)csd->nativemodelist.lh_Head;
169 if (node->node.ln_Succ) {
170 mid = node->modeid;
171 *msg->syncPtr = node->sync;
172 *msg->pixFmtPtr = node->pf;
174 DB2(bug("=%08x %p %p\n", mid, *msg->syncPtr, *msg->pixFmtPtr));
175 return mid;
178 BOOL AmigaVideoCl__Hidd_Gfx__GetMode(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_GetMode *msg)
180 struct amigavideo_staticdata *csd = CSD(cl);
181 struct NativeChipsetMode *node;
183 if (csd->superforward)
184 return (BOOL)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
186 DB2(bug("GetMode %08x\n", msg->modeID));
187 ForeachNode(&csd->nativemodelist, node) {
188 if (node->modeid == msg->modeID) {
189 *msg->syncPtr = node->sync;
190 *msg->pixFmtPtr = node->pf;
191 DB2(bug("= %p %p %dx%dx%d %d\n", node->sync, node->pf, node->width, node->height, node->depth, node->special));
192 return TRUE;
195 DB2(bug("= FAIL\n"));
196 return FALSE;
199 #define ADDTAG(tag,data) { *tagptr++ = tag; *tagptr++ = data; }
202 static void makemodename(ULONG modeid, UBYTE *bufptr)
204 BOOL special = FALSE;
206 special = (modeid & SPECIAL_MODE_MASK) != 0;
207 bufptr[0] = 0;
208 if ((modeid & MONITOR_ID_MASK) == PAL_MONITOR_ID)
209 strcat(bufptr, "PAL");
210 else if ((modeid & MONITOR_ID_MASK) == NTSC_MONITOR_ID)
211 strcat (bufptr, "NTSC");
212 strcat(bufptr, ":");
213 if ((modeid & (HIRES_KEY | SUPER_KEY)) == LORES_KEY)
214 strcat(bufptr, special ? "LowRes" : "Low Res");
215 else if ((modeid & (HIRES_KEY | SUPER_KEY)) == HIRES_KEY)
216 strcat(bufptr, special ? "HighRes" : "High Res");
217 else
218 strcat(bufptr, special ? "SuperHighRes" : "Super-High Res");
219 if (modeid & HAM_KEY)
220 strcat(bufptr, " HAM");
221 if (modeid & EXTRAHALFBRITE_KEY)
222 strcat(bufptr, " EHB");
223 if ((modeid & LORESDPF2_KEY) == LORESDPF_KEY)
224 strcat(bufptr, " DualPF");
225 if ((modeid & LORESDPF2_KEY) == LORESDPF2_KEY)
226 strcat(bufptr, " DualPF2");
227 if (modeid & LORESLACE_KEY)
228 strcat(bufptr, special ? " Interlace" : " Laced");
229 DB2(bug("%08x '%s'\n", modeid, bufptr));
232 static struct NativeChipsetMode *addmodeid(struct amigavideo_staticdata *csd, ULONG modeid, WORD w, WORD h, WORD d, UBYTE special)
234 struct NativeChipsetMode *m;
236 m = AllocMem(sizeof(struct NativeChipsetMode), MEMF_CLEAR | MEMF_PUBLIC);
237 DB2(bug("%p %08x %dx%dx%d %d\n", m, modeid, w, h, d, special));
238 m->width = w;
239 m->height = h;
240 m->depth = d;
241 m->special = special;
242 m->modeid = modeid;
243 AddTail(&csd->nativemodelist, &m->node);
244 return m;
247 /* this is SOOO HORRIBLE, do not even attempt to understand it.. */
249 OOP_Object *AmigaVideoCl__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
251 struct amigavideo_staticdata *csd = CSD(cl);
252 struct Library *OOPBase = csd->cs_OOPBase;
253 struct TagItem mytags[2];
254 struct pRoot_New mymsg;
255 ULONG allocsize = 3000, allocsizebuf = 1000;
256 WORD x, y, cnt, i, j;
258 UBYTE *buf, *bufptr;
259 ULONG *tags, *tagptr;
260 ULONG *modetags[NATIVEMODES], modeids[NATIVEMODES];
261 ULONG *pftags_aga[SPECIALMODES];
262 ULONG *pftags_ecs_shres = NULL, *pftags_ecs_hires, *pftags_ecs_lores, *pftags_ecs_6;
263 ULONG *mode_tags_aga;
264 ULONG *mode_tags_ecs;
266 if (csd->initialized)
267 return NULL;
269 NewList(&csd->nativemodelist);
270 tags = tagptr = AllocVec(allocsize, MEMF_PUBLIC | MEMF_REVERSE);
271 buf = bufptr = AllocVec(allocsizebuf, MEMF_PUBLIC | MEMF_REVERSE);
273 cnt = 0;
274 for (y = 0; heighttable[y]; y++) {
275 WORD h = heighttable[y];
276 for (x = 0; widthtable[x]; x++) {
277 WORD w = widthtable[x];
278 WORD d, res;
279 ULONG modeid;
281 modeid = 0;
282 if (w == 1280) {
283 res = 2;
284 modeid |= SUPER_KEY;
285 if (!csd->aga && !csd->ecs_denise)
286 continue;
287 d = csd->aga ? 8 : 2;
289 else if (w == 640) {
290 res = 1;
291 modeid |= HIRES_KEY;
292 d = csd->aga ? 8 : 4;
293 } else {
294 res = 0;
295 d = csd->aga ? 8 : 5;
297 if (h >= 400)
298 modeid |= LORESLACE_KEY;
299 if (h == 200 || h == 400)
300 modeid |= NTSC_MONITOR_ID;
301 else
302 modeid |= PAL_MONITOR_ID;
304 for (i = 0; i < SPECIALMODES; i++) {
305 ULONG mid = modeid;
306 UWORD d2 = d;
307 if (i == 1) {
308 if (!csd->aga && (modeid & SUPER_KEY))
309 continue;
310 mid |= EXTRAHALFBRITE_KEY;
311 d2 = 6;
312 } else if (i == 2) {
313 if (!csd->aga && (modeid & SUPER_KEY))
314 continue;
315 mid |= HAM_KEY;
316 d2 = csd->aga ? 8 : 6;
319 addmodeid(csd, mid, w, h, d2, csd->aga ? i : (i == 0 ? res : i - 1 + 3));
320 modetags[cnt] = tagptr;
321 modeids[cnt++] = mid;
323 ADDTAG(aHidd_Sync_HDisp, w);
324 ADDTAG(aHidd_Sync_VDisp, h);
325 ADDTAG(aHidd_Sync_Flags, h >= 400 ? vHidd_Sync_Interlaced : 0);
326 ADDTAG(aHidd_Sync_PixelClock, 1000000000 / (280 >> res));
327 ADDTAG(TAG_DONE, 0);
333 if (csd->aga) {
335 pftags_aga[0] = tagptr;
336 ADDTAG(aHidd_PixFmt_RedShift, 8);
337 ADDTAG(aHidd_PixFmt_GreenShift, 16);
338 ADDTAG(aHidd_PixFmt_BlueShift, 24);
339 ADDTAG(aHidd_PixFmt_AlphaShift, 0);
340 ADDTAG(aHidd_PixFmt_RedMask, 0x00FF0000);
341 ADDTAG(aHidd_PixFmt_GreenMask, 0x0000FF00);
342 ADDTAG(aHidd_PixFmt_BlueMask, 0x000000FF);
343 ADDTAG(aHidd_PixFmt_AlphaMask, 0x00000000);
344 ADDTAG(aHidd_PixFmt_CLUTMask, 0x000000FF);
345 ADDTAG(aHidd_PixFmt_CLUTShift, 0);
346 ADDTAG(aHidd_PixFmt_ColorModel, vHidd_ColorModel_Palette);
347 ADDTAG(aHidd_PixFmt_Depth, 8);
348 ADDTAG(aHidd_PixFmt_BytesPerPixel, 1);
349 ADDTAG(aHidd_PixFmt_BitsPerPixel, 8);
350 ADDTAG(aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_Plane);
351 ADDTAG(aHidd_PixFmt_BitMapType, vHidd_BitMapType_Planar);
352 ADDTAG(TAG_DONE, 0);
354 pftags_aga[1] = tagptr;
355 ADDTAG(aHidd_PixFmt_RedShift, 8);
356 ADDTAG(aHidd_PixFmt_GreenShift, 16);
357 ADDTAG(aHidd_PixFmt_BlueShift, 24);
358 ADDTAG(aHidd_PixFmt_AlphaShift, 0);
359 ADDTAG(aHidd_PixFmt_RedMask, 0x00FF0000);
360 ADDTAG(aHidd_PixFmt_GreenMask, 0x0000FF00);
361 ADDTAG(aHidd_PixFmt_BlueMask, 0x000000FF);
362 ADDTAG(aHidd_PixFmt_AlphaMask, 0x00000000);
363 ADDTAG(aHidd_PixFmt_CLUTMask, 0x000000FF);
364 ADDTAG(aHidd_PixFmt_CLUTShift, 0);
365 ADDTAG(aHidd_PixFmt_ColorModel, vHidd_ColorModel_Palette);
366 ADDTAG(aHidd_PixFmt_Depth, 6);
367 ADDTAG(aHidd_PixFmt_BytesPerPixel, 1);
368 ADDTAG(aHidd_PixFmt_BitsPerPixel, 6);
369 ADDTAG(aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_Plane);
370 ADDTAG(aHidd_PixFmt_BitMapType, vHidd_BitMapType_Planar);
371 ADDTAG(TAG_DONE, 0);
373 pftags_aga[2] = NULL;
375 mode_tags_aga = tagptr;
376 ADDTAG(aHidd_Sync_HMin, 112);
377 ADDTAG(aHidd_Sync_VMin, 112);
378 ADDTAG(aHidd_Sync_HMax, 16384);
379 ADDTAG(aHidd_Sync_VMax, 16384);
381 for (j = 0; specialmask_aga[j] != 0xffffffff; j++) {
382 if (pftags_aga[j])
383 ADDTAG(aHidd_Gfx_PixFmtTags, (IPTR)pftags_aga[j]);
384 for (i = 0; i < cnt; i++) {
385 ULONG modeid = modeids[i];
386 if ((j == 0 && !(modeid & SPECIAL_MODE_MASK)) || (j > 0 && ((modeid & SPECIAL_MODE_MASK) == specialmask_aga[j]))) {
387 makemodename(modeid, bufptr);
388 ADDTAG(aHidd_Sync_Description, (IPTR)bufptr);
389 bufptr += strlen(bufptr) + 1;
390 ADDTAG(aHidd_Gfx_SyncTags, (IPTR)modetags[i]);
395 ADDTAG(TAG_DONE, 0);
397 mytags[0].ti_Tag = aHidd_Gfx_ModeTags;
398 mytags[0].ti_Data = (IPTR)mode_tags_aga;
399 mytags[1].ti_Tag = TAG_MORE;
400 mytags[1].ti_Data = (IPTR)msg->attrList;
402 } else {
404 pftags_ecs_lores = tagptr;
405 ADDTAG(aHidd_PixFmt_RedShift, 20);
406 ADDTAG(aHidd_PixFmt_GreenShift, 24);
407 ADDTAG(aHidd_PixFmt_BlueShift, 28);
408 ADDTAG(aHidd_PixFmt_AlphaShift, 0);
409 ADDTAG(aHidd_PixFmt_RedMask, 0x00000F00);
410 ADDTAG(aHidd_PixFmt_GreenMask, 0x000000F0);
411 ADDTAG(aHidd_PixFmt_BlueMask, 0x0000000F);
412 ADDTAG(aHidd_PixFmt_AlphaMask, 0x00000000);
413 ADDTAG(aHidd_PixFmt_CLUTMask, 0x0000001F);
414 ADDTAG(aHidd_PixFmt_CLUTShift, 0);
415 ADDTAG(aHidd_PixFmt_ColorModel, vHidd_ColorModel_Palette);
416 ADDTAG(aHidd_PixFmt_Depth, 5);
417 ADDTAG(aHidd_PixFmt_BytesPerPixel, 1);
418 ADDTAG(aHidd_PixFmt_BitsPerPixel, 5);
419 ADDTAG(aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_Plane);
420 ADDTAG(aHidd_PixFmt_BitMapType, vHidd_BitMapType_Planar);
421 ADDTAG(TAG_DONE, 0);
423 pftags_ecs_hires = tagptr;
424 ADDTAG(aHidd_PixFmt_RedShift, 20);
425 ADDTAG(aHidd_PixFmt_GreenShift, 24);
426 ADDTAG(aHidd_PixFmt_BlueShift, 28);
427 ADDTAG(aHidd_PixFmt_AlphaShift, 0);
428 ADDTAG(aHidd_PixFmt_RedMask, 0x00000F00);
429 ADDTAG(aHidd_PixFmt_GreenMask, 0x000000F0);
430 ADDTAG(aHidd_PixFmt_BlueMask, 0x0000000F);
431 ADDTAG(aHidd_PixFmt_AlphaMask, 0x00000000);
432 ADDTAG(aHidd_PixFmt_CLUTMask, 0x0000001F);
433 ADDTAG(aHidd_PixFmt_CLUTShift, 0);
434 ADDTAG(aHidd_PixFmt_ColorModel, vHidd_ColorModel_Palette);
435 ADDTAG(aHidd_PixFmt_Depth, 4);
436 ADDTAG(aHidd_PixFmt_BytesPerPixel, 1);
437 ADDTAG(aHidd_PixFmt_BitsPerPixel, 4);
438 ADDTAG(aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_Plane);
439 ADDTAG(aHidd_PixFmt_BitMapType, vHidd_BitMapType_Planar);
440 ADDTAG(TAG_DONE, 0);
442 pftags_ecs_shres = tagptr;
443 ADDTAG(aHidd_PixFmt_RedShift, 20);
444 ADDTAG(aHidd_PixFmt_GreenShift, 24);
445 ADDTAG(aHidd_PixFmt_BlueShift, 28);
446 ADDTAG(aHidd_PixFmt_AlphaShift, 0);
447 ADDTAG(aHidd_PixFmt_RedMask, 0x00000F00);
448 ADDTAG(aHidd_PixFmt_GreenMask, 0x000000F0);
449 ADDTAG(aHidd_PixFmt_BlueMask, 0x0000000F);
450 ADDTAG(aHidd_PixFmt_AlphaMask, 0x00000000);
451 ADDTAG(aHidd_PixFmt_CLUTMask, 0x0000001F);
452 ADDTAG(aHidd_PixFmt_CLUTShift, 0);
453 ADDTAG(aHidd_PixFmt_ColorModel, vHidd_ColorModel_Palette);
454 ADDTAG(aHidd_PixFmt_Depth, 2);
455 ADDTAG(aHidd_PixFmt_BytesPerPixel, 1);
456 ADDTAG(aHidd_PixFmt_BitsPerPixel, 2);
457 ADDTAG(aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_Plane);
458 ADDTAG(aHidd_PixFmt_BitMapType, vHidd_BitMapType_Planar);
459 ADDTAG(TAG_DONE, 0);
461 pftags_ecs_6 = tagptr;
462 ADDTAG(aHidd_PixFmt_RedShift, 20);
463 ADDTAG(aHidd_PixFmt_GreenShift, 24);
464 ADDTAG(aHidd_PixFmt_BlueShift, 28);
465 ADDTAG(aHidd_PixFmt_AlphaShift, 0);
466 ADDTAG(aHidd_PixFmt_RedMask, 0x00000F00);
467 ADDTAG(aHidd_PixFmt_GreenMask, 0x000000F0);
468 ADDTAG(aHidd_PixFmt_BlueMask, 0x0000000F);
469 ADDTAG(aHidd_PixFmt_AlphaMask, 0x00000000);
470 ADDTAG(aHidd_PixFmt_CLUTMask, 0x0000001F);
471 ADDTAG(aHidd_PixFmt_CLUTShift, 0);
472 ADDTAG(aHidd_PixFmt_ColorModel, vHidd_ColorModel_Palette);
473 ADDTAG(aHidd_PixFmt_Depth, 6);
474 ADDTAG(aHidd_PixFmt_BytesPerPixel, 1);
475 ADDTAG(aHidd_PixFmt_BitsPerPixel, 6);
476 ADDTAG(aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_Plane);
477 ADDTAG(aHidd_PixFmt_BitMapType, vHidd_BitMapType_Planar);
478 ADDTAG(TAG_DONE, 0);
480 mode_tags_ecs = tagptr;
481 ADDTAG(aHidd_Sync_HMin, 112);
482 ADDTAG(aHidd_Sync_VMin, 112);
483 ADDTAG(aHidd_Sync_HMax, csd->ecs_agnus ? 16384 : 1008);
484 ADDTAG(aHidd_Sync_VMax, csd->ecs_agnus ? 16384 : 1008);
486 ADDTAG(aHidd_Gfx_PixFmtTags, (IPTR)pftags_ecs_lores);
487 for (i = 0; i < cnt; i++) {
488 if ((modeids[i] & SPECIAL_MODE_MASK) || (modeids[i] & SUPER_KEY) != LORES_KEY)
489 continue;
490 makemodename(modeids[i], bufptr);
491 ADDTAG(aHidd_Sync_Description, (IPTR)bufptr);
492 bufptr += strlen(bufptr) + 1;
493 ADDTAG(aHidd_Gfx_SyncTags, (IPTR)modetags[i]);
496 ADDTAG(aHidd_Gfx_PixFmtTags, (IPTR)pftags_ecs_hires);
497 for (i = 0; i < cnt; i++) {
498 if ((modeids[i] & SPECIAL_MODE_MASK) || (modeids[i] & SUPER_KEY) != HIRES_KEY)
499 continue;
500 makemodename(modeids[i], bufptr);
501 ADDTAG(aHidd_Sync_Description, (IPTR)bufptr);
502 bufptr += strlen(bufptr) + 1;
503 ADDTAG(aHidd_Gfx_SyncTags, (IPTR)modetags[i]);
506 ADDTAG(aHidd_Gfx_PixFmtTags, (IPTR)pftags_ecs_shres);
507 if (csd->ecs_denise) {
508 for (i = 0; i < cnt; i++) {
509 if ((modeids[i] & SPECIAL_MODE_MASK) || (modeids[i] & SUPER_KEY) != SUPER_KEY)
510 continue;
511 makemodename(modeids[i], bufptr);
512 ADDTAG(aHidd_Sync_Description, (IPTR)bufptr);
513 bufptr += strlen(bufptr) + 1;
514 ADDTAG(aHidd_Gfx_SyncTags, (IPTR)modetags[i]);
518 ADDTAG(aHidd_Gfx_PixFmtTags, (IPTR)pftags_ecs_6);
519 for (i = 0; i < cnt; i++) {
520 if (!(modeids[i] & SPECIAL_MODE_MASK))
521 continue;
522 makemodename(modeids[i], bufptr);
523 ADDTAG(aHidd_Sync_Description, (IPTR)bufptr);
524 bufptr += strlen(bufptr) + 1;
525 ADDTAG(aHidd_Gfx_SyncTags, (IPTR)modetags[i]);
528 ADDTAG(TAG_DONE, 0);
530 mytags[0].ti_Tag = aHidd_Gfx_ModeTags;
531 mytags[0].ti_Data = (IPTR)mode_tags_ecs;
532 mytags[1].ti_Tag = TAG_MORE;
533 mytags[1].ti_Data = (IPTR)msg->attrList;
537 D(bug("alloc=%d alloced=%d\n", allocsize, (ULONG)tagptr - (ULONG)tags));
538 D(bug("allocbuf=%d allocedbuf=%d\n", allocsizebuf, bufptr - buf));
540 EnterFunc(bug("AGFX::New()\n"));
542 mymsg.mID = msg->mID;
543 mymsg.attrList = mytags;
544 msg = &mymsg;
546 /* Register gfxmodes */
547 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
548 if (NULL != o)
550 struct amigagfx_data *data = OOP_INST_DATA(cl, o);
551 struct NativeChipsetMode *node;
552 HIDDT_ModeID *midp;
553 UWORD pfcnt;
554 OOP_MethodID HiddGfxBase = csd->cs_HiddGfxBase;
555 OOP_Object *pixelformats[8] = { 0 };
557 D(bug("AGFX::New(): Got object from super\n"));
558 NewList((struct List *)&data->bitmaps);
559 csd->initialized = 1;
561 /* this can't be the right way to match modes.. */
562 csd->superforward = TRUE;
563 midp = HIDD_Gfx_QueryModeIDs(o, NULL);
564 for (pfcnt = 0, i = 0; midp[i] != vHidd_ModeID_Invalid; i++) {
565 OOP_Object *sync, *pf;
566 HIDDT_ModeID mid = midp[i];
567 if (!HIDD_Gfx_GetMode(o, mid, &sync, &pf))
568 continue;
569 for (j = 0; j < pfcnt; j++) {
570 if (pf == pixelformats[j])
571 break;
573 if (j < pfcnt)
574 continue;
575 pixelformats[pfcnt++] = pf;
577 while (pfcnt < 8) {
578 if (csd->aga)
579 pixelformats[pfcnt] = pixelformats[0];
580 else
581 pixelformats[pfcnt] = pixelformats[pfcnt - 1];
582 pfcnt++;
584 for (i = 0; i < pfcnt; i++) {
585 DB2(bug("pf %d: %p\n", i, pixelformats[i]));
588 ForeachNode(&csd->nativemodelist, node) {
589 if (!node->pf) {
590 OOP_Object *sync = NULL;
591 for (i = 0; midp[i] != vHidd_ModeID_Invalid; i++) {
592 HIDDT_ModeID mid = midp[i];
593 IPTR dwidth, dheight;
594 OOP_Object *pf;
595 struct NativeChipsetMode *node2;
596 BOOL found = FALSE;
597 if (!HIDD_Gfx_GetMode(o, mid, &sync, &pf))
598 continue;
599 OOP_GetAttr(sync, aHidd_Sync_HDisp, &dwidth);
600 OOP_GetAttr(sync, aHidd_Sync_VDisp, &dheight);
601 if (node->width != dwidth || node->height != dheight)
602 continue;
603 ForeachNode(&csd->nativemodelist, node2) {
604 if (node->width == dwidth && node->height == dheight) {
605 if (node2->sync == sync) {
606 found = TRUE;
607 break;
611 if (!found)
612 break;
614 if (midp[i] == vHidd_ModeID_Invalid) {
615 sync = NULL;
616 D(bug("sync not found!?\n"));
618 node->sync = sync;
619 node->pf = pixelformats[node->special];
620 DB2(bug("%08x %dx%dx%d sync = %p pf = %p\n",
621 node->modeid, node->width, node->height, node->depth, node->sync, node->pf));
624 HIDD_Gfx_ReleaseModeIDs(o, midp);
625 csd->superforward = FALSE;
626 #if 1
627 ForeachNode(&csd->nativemodelist, node) {
628 DB2(bug("%08x %dx%dx%d sync = %p pf = %p\n", node->modeid, node->width, node->height, node->depth, node->sync, node->pf));
630 #endif
633 FreeVec(buf);
634 FreeVec(tags);
635 ReturnPtr("AGFX::New", OOP_Object *, o);
638 /********** GfxHidd::Dispose() ******************************/
639 VOID AmigaVideoCl__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
641 EnterFunc(bug("AGFX::Dispose(o=%p)\n", o));
643 D(bug("AGFX::Dispose: calling super\n"));
644 OOP_DoSuperMethod(cl, o, msg);
646 ReturnVoid("AGFX::Dispose");
650 OOP_Object *AmigaVideoCl__Hidd_Gfx__NewBitMap(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_NewBitMap *msg)
652 struct amigavideo_staticdata *csd = CSD(cl);
653 struct Library *UtilityBase = csd->cs_UtilityBase;
654 HIDDT_ModeID modeid;
655 struct pHidd_Gfx_NewBitMap newbitmap;
656 struct TagItem tags[2];
658 EnterFunc(bug("AGFX::NewBitMap()\n"));
660 modeid = (HIDDT_ModeID)GetTagData(aHidd_BitMap_ModeID, vHidd_ModeID_Invalid, msg->attrList);
661 D(bug("modeid=%08x\n", modeid));
662 if (modeid != vHidd_ModeID_Invalid) {
663 tags[0].ti_Tag = aHidd_BitMap_ClassPtr;
664 tags[0].ti_Data = (IPTR)CSD(cl)->amigabmclass;
665 tags[1].ti_Tag = TAG_MORE;
666 tags[1].ti_Data = (IPTR)msg->attrList;
667 newbitmap.mID = msg->mID;
668 newbitmap.attrList = tags;
669 msg = &newbitmap;
672 ReturnPtr("AGFX::NewBitMap", OOP_Object *, (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg));
675 VOID AmigaVideoCl__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
677 struct amigavideo_staticdata *csd = CSD(cl);
678 ULONG idx;
680 //bug("AmigaVideoCl__Root__Get %x\n", msg->attrID);
682 if (IS_GFX_ATTR(msg->attrID, idx))
684 //bug("=%x\n", idx);
685 switch (idx)
687 case aoHidd_Gfx_HWSpriteTypes:
688 *msg->storage = vHidd_SpriteType_3Plus1;
689 return;
690 case aoHidd_Gfx_SupportsHWCursor:
691 case aoHidd_Gfx_NoFrameBuffer:
692 *msg->storage = TRUE;
693 return;
694 case aoHidd_Gfx_IsWindowed:
695 *msg->storage = FALSE;
696 return;
697 case aoHidd_Gfx_DriverName:
698 *msg->storage = (IPTR)"AmigaVideo";
699 return;
702 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
705 VOID AmigaVideoCl__Root__Set(OOP_Class *cl, OOP_Object *obj, struct pRoot_Set *msg)
707 struct amigavideo_staticdata *csd = CSD(cl);
708 struct Library *UtilityBase = csd->cs_UtilityBase;
709 struct TagItem *tag, *tstate;
711 tstate = msg->attrList;
712 while((tag = NextTagItem(&tstate)))
714 ULONG idx;
715 D(bug("AmigaVideoCl__Root__Set %x\n", tag->ti_Tag));
716 if (IS_GFX_ATTR(tag->ti_Tag, idx)) {
717 D(bug("->%d\n", idx));
718 switch(idx)
720 case aoHidd_Gfx_ActiveCallBack:
721 csd->acb = (void *)tag->ti_Data;
722 break;
724 case aoHidd_Gfx_ActiveCallBackData:
725 csd->acbdata = (APTR)tag->ti_Data;
726 break;
730 OOP_DoSuperMethod(cl, obj, (OOP_Msg)msg);
733 ULONG AmigaVideoCl__Hidd_Gfx__ShowViewPorts(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_ShowViewPorts *msg)
735 struct amigavideo_staticdata *csd = CSD(cl);
736 struct Library *OOPBase = csd->cs_OOPBase;
737 struct HIDD_ViewPortData *vpd = msg->Data;
738 OOP_Object *bm = NULL;
740 if (vpd)
741 bm = vpd->Bitmap;
743 D(bug("AmigaShowViewPorts %p %p\n", vpd, bm));
745 if (bm) {
746 struct amigabm_data *data = OOP_INST_DATA(OOP_OCLASS(bm), bm);
747 IPTR tags[] = {aHidd_BitMap_Visible, TRUE, TAG_DONE};
748 IPTR modeid = vHidd_ModeID_Invalid;
750 OOP_GetAttr(bm, aHidd_BitMap_ModeID , &modeid);
751 csd->modeid = modeid;
752 setmode(csd, data);
753 OOP_SetAttrs(bm, (struct TagItem *)tags);
755 if (csd->acb)
756 csd->acb(csd->acbdata, NULL);
758 } else {
759 resetmode(csd);
762 return TRUE;
765 VOID AmigaVideoCl__Hidd_Gfx__CopyBox(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CopyBox *msg)
767 struct amigavideo_staticdata *csd = CSD(cl);
768 struct Library *OOPBase = csd->cs_OOPBase;
769 HIDDT_DrawMode mode = GC_DRMD(msg->gc);
770 IPTR src, dst;
771 BOOL ok = FALSE;
773 OOP_GetAttr(msg->src, aHidd_AmigaVideoBitMap_Drawable, &src);
774 OOP_GetAttr(msg->dest, aHidd_AmigaVideoBitMap_Drawable, &dst);
775 if (src && dst) {
776 struct amigabm_data *sdata = OOP_INST_DATA(OOP_OCLASS(msg->src), msg->src);
777 struct amigabm_data *ddata = OOP_INST_DATA(OOP_OCLASS(msg->dest), msg->dest);
778 ok = blit_copybox(csd, sdata->pbm, ddata->pbm, msg->srcX, msg->srcY, msg->width, msg->height, msg->destX, msg->destY, mode);
780 if (!ok)
781 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
784 BOOL AmigaVideoCl__Hidd_Gfx__CopyBoxMasked(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CopyBoxMasked *msg)
786 struct amigavideo_staticdata *csd = CSD(cl);
787 struct Library *OOPBase = csd->cs_OOPBase;
788 HIDDT_DrawMode mode = GC_DRMD(msg->gc);
789 IPTR src, dst;
790 BOOL ok = FALSE;
792 OOP_GetAttr(msg->src, aHidd_AmigaVideoBitMap_Drawable, &src);
793 OOP_GetAttr(msg->dest, aHidd_AmigaVideoBitMap_Drawable, &dst);
794 if (src && dst) {
795 struct amigabm_data *sdata = OOP_INST_DATA(OOP_OCLASS(msg->src), msg->src);
796 struct amigabm_data *ddata = OOP_INST_DATA(OOP_OCLASS(msg->dest), msg->dest);
797 ok = blit_copybox_mask(csd, sdata->pbm, ddata->pbm, msg->srcX, msg->srcY, msg->width, msg->height, msg->destX, msg->destY, mode, msg->mask);
799 if (!ok)
800 return OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
802 return TRUE;
805 BOOL AmigaVideoCl__Hidd_Gfx__SetCursorShape(OOP_Class *cl, OOP_Object *shape, struct pHidd_Gfx_SetCursorShape *msg)
807 struct amigavideo_staticdata *csd = CSD(cl);
808 struct Library *OOPBase = csd->cs_OOPBase;
809 IPTR width, height;
810 UWORD maxw, maxh;
812 OOP_GetAttr(msg->shape, aHidd_BitMap_Width, &width);
813 OOP_GetAttr(msg->shape, aHidd_BitMap_Height, &height);
815 maxw = (csd->aga ? 64 : 16);
816 maxh = maxw * 2;
818 if (width > maxw || height > maxh)
819 return FALSE;
821 return setsprite(csd, width, height, msg);
824 BOOL AmigaVideoCl__Hidd_Gfx__GetMaxSpriteSize(OOP_Class *cl, ULONG Type, ULONG *Width, ULONG *Height)
826 struct amigavideo_staticdata *csd = CSD(cl);
827 *Width = csd->aga ? 64 : 16;
828 *Height = *Width * 2;
829 return TRUE;
831 BOOL AmigaVideoCl__Hidd_Gfx__SetCursorPos(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorPos *msg)
833 struct amigavideo_staticdata *csd = CSD(cl);
834 setspritepos(csd, msg->x, msg->y);
835 return TRUE;
837 VOID AmigaVideoCl__Hidd_Gfx__SetCursorVisible(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorVisible *msg)
839 struct amigavideo_staticdata *csd = CSD(cl);
840 setspritevisible(csd, msg->visible);
843 ULONG AmigaVideoCl__Hidd_Gfx__MakeViewPort(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_MakeViewPort *msg)
845 D(struct HIDD_ViewPortData *vpd = msg->Data);
847 D(bug("AmigaVideoCl__Hidd_Gfx__MakeViewPort vp=%p bm=%p vpe=%p\n", vpd->vpe->ViewPort, vpd->Bitmap, vpd->vpe));
848 /* TODO: implement this correctly */
849 return MVP_OK;
852 void AmigaVideoCl__Hidd_Gfx__CleanViewPort(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CleanViewPort *msg)
854 struct amigavideo_staticdata *csd = CSD(cl);
855 struct Library *GfxBase = csd->cs_GfxBase;
856 struct HIDD_ViewPortData *vpd = msg->Data;
857 struct ViewPort *vp = vpd->vpe->ViewPort;
859 D(bug("AmigaVideoCl__Hidd_Gfx__CleanViewPort vp=%p bm=%p vpe=%p\n", vpd->vpe->ViewPort, vpd->Bitmap, vpd->vpe));
860 /* It's safe to call these functions on NULL pointers */
861 FreeCopList(vp->ClrIns);
862 FreeCopList(vp->DspIns);
863 FreeCopList(vp->SprIns);
865 if (vp->UCopIns)
867 FreeCopList(vp->UCopIns->FirstCopList);
868 FreeMem(vp->UCopIns, sizeof(struct UCopList));
871 /* Everything has been freed */
872 vp->ClrIns = NULL;
873 vp->DspIns = NULL;
874 vp->SprIns = NULL;
875 vp->UCopIns = NULL;
878 static void freeattrbases(struct amigavideo_staticdata *csd)
880 struct Library *OOPBase = csd->cs_OOPBase;
882 OOP_ReleaseAttrBase(IID_Hidd_BitMap);
883 OOP_ReleaseAttrBase(IID_Hidd_PlanarBM);
884 OOP_ReleaseAttrBase(IID_Hidd_AmigaVideoBitMap);
885 OOP_ReleaseAttrBase(IID_Hidd_GC);
886 OOP_ReleaseAttrBase(IID_Hidd_Sync);
887 OOP_ReleaseAttrBase(IID_Hidd_Gfx);
888 OOP_ReleaseAttrBase(IID_Hidd_PixFmt);
889 OOP_ReleaseAttrBase(IID_Hidd_ColorMap);
892 int Init_AmigaVideoClass(LIBBASETYPEPTR LIBBASE)
894 struct amigavideo_staticdata *csd = &LIBBASE->csd;
895 struct Library *OOPBase = csd->cs_OOPBase;
897 D(bug("Init_AmigaVideoClass\n"));
898 __IHidd_BitMap = OOP_ObtainAttrBase(IID_Hidd_BitMap);
899 __IHidd_PlanarBM = OOP_ObtainAttrBase(IID_Hidd_PlanarBM);
900 __IHidd_AmigaVideoBitmap = OOP_ObtainAttrBase(IID_Hidd_AmigaVideoBitMap);
901 __IHidd_GC = OOP_ObtainAttrBase(IID_Hidd_GC);
902 __IHidd_Sync = OOP_ObtainAttrBase(IID_Hidd_Sync);
903 __IHidd_Gfx = OOP_ObtainAttrBase(IID_Hidd_Gfx);
904 __IHidd_PixFmt = OOP_ObtainAttrBase(IID_Hidd_PixFmt);
905 __IHidd_ColorMap = OOP_ObtainAttrBase(IID_Hidd_ColorMap);
907 if (!__IHidd_BitMap || !__IHidd_PlanarBM || !__IHidd_AmigaVideoBitmap || !__IHidd_GC ||
908 !__IHidd_Sync || !__IHidd_Gfx || !__IHidd_PixFmt || !__IHidd_ColorMap)
910 D(bug("Init_AmigaVideoClass fail\n"));
911 freeattrbases(csd);
912 return 0;
914 return TRUE;
918 static int Expunge_AmigaVideoClass(LIBBASETYPEPTR LIBBASE)
920 struct amigavideo_staticdata *csd = &LIBBASE->csd;
921 D(bug("Expunge_AmigaVideoClass\n"));
922 freeattrbases(csd);
923 return TRUE;
926 ADD2EXPUNGELIB(Expunge_AmigaVideoClass, 1)