small cleanup. remove old code which was corrupting the init tags. use the obtained...
[AROS.git] / arch / all-native / hidd / vgagfx / vgagfx_bitmapclass.c
bloba754d5e65ca37a56d4c351e9747fd8d301db4a38
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Bitmap class for VGA Hidd.
6 Lang: English.
7 */
9 #define SDEBUG 0
10 #define DEBUG 0
11 #include <aros/debug.h>
13 #define __OOP_NOATTRBASES__
15 #include <proto/oop.h>
16 #include <proto/utility.h>
18 #include <exec/memory.h>
19 #include <exec/lists.h>
21 #include <graphics/rastport.h>
22 #include <graphics/gfx.h>
23 #include <oop/oop.h>
25 #include <aros/symbolsets.h>
27 #include <hidd/gfx.h>
29 #include <assert.h>
31 #include "vgagfx_support.h"
33 #include LC_LIBDEFS_FILE
35 void vgaRestore(struct vgaHWRec *);
36 int vgaInitMode(struct vgaModeDesc *, struct vgaHWRec *);
37 void vgaLoadPalette(struct vgaHWRec *, unsigned char *);
39 #define MNAME_ROOT(x) VGAGfxBM__Root__ ## x
40 #define MNAME_BM(x) VGAGfxBM__Hidd_BitMap__ ## x
42 /*********** BitMap::New() *************************************/
44 OOP_Object *VGAGfxBM__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
46 EnterFunc(bug("VGAGfx.BitMap::New()\n"));
48 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
49 D(bug("[VGAGfx:BitMap] Object created by superclass: 0x%p\n"));
50 if (o)
52 struct VGAGfxBitMapData *data;
53 OOP_Object *gfxhidd, *sync, *pf;
54 IPTR modeid = vHidd_ModeID_Invalid;
55 IPTR width, height, depth;
56 IPTR dwidth, dheight;
57 IPTR displayable = FALSE;
59 data = OOP_INST_DATA(cl, o);
61 /* clear all data */
62 memset(data, 0, sizeof(struct VGAGfxBitMapData));
64 /* Get attr values */
65 OOP_GetAttr(o, aHidd_BitMap_ModeID , &modeid );
66 OOP_GetAttr(o, aHidd_BitMap_Width , &width );
67 OOP_GetAttr(o, aHidd_BitMap_Height , &height );
68 OOP_GetAttr(o, aHidd_BitMap_Displayable, &displayable);
69 OOP_GetAttr(o, aHidd_BitMap_PixFmt , (IPTR *)&pf );
70 D(bug("[VGAGfx:BitMap] PixFmt object: 0x%p\n", pf));
71 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
73 D(bug("[VGAGfx:BitMap] Size: %lux%lu, depth: %lu\n", width, height, depth));
74 D(bug("[VGAGfx:BitMap] Displayable: %ld\n", displayable));
75 ASSERT (width != 0 && height != 0 && depth != 0);
77 data->width = width;
78 data->height = height;
79 data->bpp = depth;
81 if (modeid != vHidd_ModeID_Invalid) {
83 OOP_GetAttr(o, aHidd_BitMap_GfxHidd, (IPTR *)&gfxhidd);
84 HIDD_Gfx_GetMode(gfxhidd, modeid, &sync, &pf);
85 OOP_GetAttr(sync, aHidd_Sync_HDisp, &dwidth);
86 OOP_GetAttr(sync, aHidd_Sync_VDisp, &dheight);
87 data->disp_width = dwidth;
88 data->disp_height = dheight;
89 D(bug("[VGAGfx:BitMap] Display size: %dx%d\n", dwidth, dheight));
92 width=(width+15) & ~15;
93 data->bpr = width;
94 data->VideoData = AllocVec(width*height,MEMF_PUBLIC|MEMF_CLEAR);
95 D(bug("[VGAGfx:BitMap] Allocated videodata at 0x%p\n", data->VideoData));
96 if (data->VideoData) {
97 struct TagItem tags[2];
99 tags[0].ti_Tag = aHidd_ChunkyBM_Buffer;
100 tags[0].ti_Data = (IPTR)data->VideoData;
101 tags[1].ti_Tag = TAG_END;
102 OOP_SetAttrs(o, tags);
104 /* If the bitmap is not displayable, we're done */
105 if (!displayable)
106 ReturnPtr("VGAGfx.BitMap::New()", OOP_Object *, o);
108 data->Regs = AllocVec(sizeof(struct vgaHWRec),MEMF_PUBLIC|MEMF_CLEAR);
109 D(bug("[VGAGfx:BitMap] Registers at 0x%p\n", data->Regs));
111 Here there is brand new method of getting pixelclock data.
112 It was introduced here to make the code more portable. Besides
113 it may now be used as a base for creating other low level
114 video drivers
116 if (data->Regs) {
117 struct vgaModeDesc mode;
118 IPTR pixelc;
120 /* We should have got modeID from the bitmap */
121 if (modeid != vHidd_ModeID_Invalid)
123 mode.Width = dwidth;
124 mode.Height = dheight;
125 mode.Depth = depth;
126 OOP_GetAttr(sync, aHidd_Sync_PixelClock, &pixelc);
128 mode.clock = (pixelc > 26000000) ? 1 : 0;
129 mode.Flags = 0;
130 mode.HSkew = 0;
131 OOP_GetAttr(sync, aHidd_Sync_HDisp, &mode.HDisplay);
132 OOP_GetAttr(sync, aHidd_Sync_VDisp, &mode.VDisplay);
133 OOP_GetAttr(sync, aHidd_Sync_HSyncStart, &mode.HSyncStart);
134 OOP_GetAttr(sync, aHidd_Sync_VSyncStart, &mode.VSyncStart);
135 OOP_GetAttr(sync, aHidd_Sync_HSyncEnd, &mode.HSyncEnd);
136 OOP_GetAttr(sync, aHidd_Sync_VSyncEnd, &mode.VSyncEnd);
137 OOP_GetAttr(sync, aHidd_Sync_HTotal, &mode.HTotal);
138 OOP_GetAttr(sync, aHidd_Sync_VTotal, &mode.VTotal);
140 vgaInitMode(&mode, data->Regs);
141 vgaLoadPalette(data->Regs,(unsigned char *)NULL);
143 D(bug("[VGAGfx:BitMap] Created displayable bitmap 0x%p, data 0x%p\n", o, data));
144 return o;
147 FreeVec(data->VideoData);
151 OOP_MethodID disp_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
152 OOP_CoerceMethod(cl, o, (OOP_Msg) &disp_mid);
155 o = NULL;
156 } /* if created object */
158 ReturnPtr("VGAGfx.BitMap::New()", OOP_Object *, o);
161 /********** Bitmap::Dispose() ***********************************/
163 VOID VGAGfxBM__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
165 struct VGAGfxBitMapData *data = OOP_INST_DATA(cl, o);
166 EnterFunc(bug("VGAGfx.BitMap::Dispose()\n"));
168 FreeVec(data->VideoData);
169 FreeVec(data->Regs);
171 OOP_DoSuperMethod(cl, o, msg);
173 ReturnVoid("VGAGfx.BitMap::Dispose");
176 /********* BitMap::SetColors() ***************************/
178 void vgaDACLoad(struct vgaHWRec *, unsigned char, int);
180 BOOL MNAME_BM(SetColors)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_SetColors *msg)
182 struct VGAGfxBitMapData *data = OOP_INST_DATA(cl, o);
183 HIDDT_PixelFormat *pf;
185 ULONG xc_i, col_i;
187 HIDDT_Pixel red, green, blue;
189 pf = BM_PIXFMT(o);
191 if ( vHidd_ColorModel_StaticPalette == HIDD_PF_COLMODEL(pf)
192 || vHidd_ColorModel_TrueColor == HIDD_PF_COLMODEL(pf) ) {
194 /* Superclass takes care of this case */
196 return OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
199 /* We have a vHidd_GT_Palette bitmap */
201 if (!OOP_DoSuperMethod(cl, o, (OOP_Msg)msg)) return FALSE;
202 if (!data->Regs)
203 return TRUE;
205 if ((msg->firstColor + msg->numColors) > (1 << data->bpp))
206 return FALSE;
209 for ( xc_i = msg->firstColor, col_i = 0;
210 col_i < msg->numColors;
211 xc_i ++, col_i ++ )
213 red = msg->colors[col_i].red >> 8;
214 green = msg->colors[col_i].green >> 8;
215 blue = msg->colors[col_i].blue >> 8;
217 /* Update DAC registers */
218 data->Regs->DAC[xc_i*3] = red >> 2;
219 data->Regs->DAC[xc_i*3+1] = green >> 2;
220 data->Regs->DAC[xc_i*3+2] = blue >> 2;
222 msg->colors[col_i].pixval = xc_i;
225 /* Restore palette if displayed */
226 if (data->disp) {
227 ObtainSemaphore(&XSD(cl)->HW_acc);
228 vgaDACLoad(data->Regs, msg->firstColor, msg->numColors);
229 ReleaseSemaphore(&XSD(cl)->HW_acc);
232 return TRUE;
235 /********* BitMap::PutPixel() ***************************/
236 // FIXME: in theory we shouldn't need this method since the superclass implements it
238 VOID MNAME_BM(PutPixel)(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutPixel *msg)
240 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
241 return;
244 /*** BitMap::Set() *******************************************/
246 VOID MNAME_ROOT(Set)(OOP_Class *cl, OOP_Object *o, struct pRoot_Set *msg)
248 struct VGAGfxBitMapData *data = OOP_INST_DATA(cl, o);
249 struct TagItem *tag, *tstate;
250 ULONG idx;
251 int limit;
252 int xoffset = data->xoffset;
253 int yoffset = data->yoffset;
255 tstate = msg->attrList;
256 while((tag = NextTagItem(&tstate)))
258 if(IS_BM_ATTR(tag->ti_Tag, idx))
260 switch(idx)
262 case aoHidd_BitMap_Visible:
263 data->disp = tag->ti_Data;
264 D(bug("[VGAGfx:BitMap] Visible set to %d\n", data->disp));
265 if (data->disp) {
266 struct Box box;
268 /* Program video mode on the card */
269 bug("\x03");
270 vgaRestore(data->Regs);
271 /* If our bitmap is smaller than display area,
272 we need to clear two rectangles: to the right
273 and to the bottom of the used framebuffer
274 portion */
275 if (data->disp_width > data->width) {
276 box.x1 = data->width;
277 box.y1 = 0;
278 box.x2 = data->disp_width - 1;
279 box.y2 = data->height - 1;
280 vgaEraseArea(data, &box);
282 if (data->disp_height > data->height) {
283 box.x1 = 0;
284 box.y1 = data->height;
285 box.x2 = data->width - 1;
286 box.y2 = data->disp_height - 1;
287 vgaEraseArea(data, &box);
290 break;
291 case aoHidd_BitMap_LeftEdge:
292 xoffset = tag->ti_Data;
293 limit = data->disp_width - data->width;
294 if (xoffset > 0)
295 xoffset = 0;
296 else if (xoffset < limit)
297 xoffset = limit;
298 break;
299 case aoHidd_BitMap_TopEdge:
300 yoffset = tag->ti_Data;
301 limit = data->disp_height - data->height;
302 if (yoffset > 0)
303 yoffset = 0;
304 else if (yoffset < limit)
305 yoffset = limit;
306 break;
310 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
312 if ((xoffset != data->xoffset) || (yoffset != data->yoffset)) {
313 data->xoffset = xoffset;
314 data->yoffset = yoffset;
316 if (data->disp) {
317 struct Box box = {0, 0, data->disp_width - 1, data->disp_height - 1};
319 ObtainSemaphore(&XSD(cl)->HW_acc);
320 vgaRefreshArea(data, &box);
321 draw_mouse(XSD(cl));
322 ReleaseSemaphore(&XSD(cl)->HW_acc);
327 VOID MNAME_ROOT(Get)(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
329 struct VGAGfxBitMapData *data = OOP_INST_DATA(cl, o);
330 ULONG idx;
332 if (IS_VGABM_ATTR(msg->attrID, idx)) {
333 switch (idx) {
334 case aoHidd_VGABitMap_Drawable:
335 *msg->storage = (IPTR)data->VideoData;
336 return;
338 } else if (IS_BM_ATTR(msg->attrID, idx)) {
339 switch (idx) {
340 case aoHidd_BitMap_LeftEdge:
341 *msg->storage = data->xoffset;
342 return;
343 case aoHidd_BitMap_TopEdge:
344 *msg->storage = data->yoffset;
345 return;
346 case aoHidd_BitMap_Visible:
347 *msg->storage = data->disp;
348 return;
351 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
354 /*** BitMap::UpdateRect() *******************************************/
356 VOID VGAGfxBM__Hidd_BitMap__UpdateRect(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_UpdateRect *msg)
358 struct VGAGfxBitMapData *data = OOP_INST_DATA(cl, o);
359 int left = msg->x + data->xoffset;
360 int top = msg->y + data->yoffset;
361 int right = left + msg->width - 1;
362 int bottom = top + msg->height - 1;
364 if ((right < 0) || (bottom < 0))
365 return;
366 if (left < 0)
367 left = 0;
368 if (top < 0)
369 top = 0;
371 if (data->disp)
373 ObtainSemaphore(&XSD(cl)->HW_acc);
375 if ((msg->width == 1) && (msg->height == 1))
376 vgaRefreshPixel(data, left, top);
377 else {
378 struct Box box = {left, top, right, bottom};
380 vgaRefreshArea(data, &box);
383 if ( ( (XSD(cl)->mouseX + XSD(cl)->mouseW - 1 >= left) &&
384 (XSD(cl)->mouseX <= right) ) ||
385 ( (XSD(cl)->mouseY + XSD(cl)->mouseH - 1 >= top) &&
386 (XSD(cl)->mouseY <= bottom) ) )
387 draw_mouse(XSD(cl));
389 ReleaseSemaphore(&XSD(cl)->HW_acc);