2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
5 Desc: Bitmap class for VGA hidd.
11 #include <aros/debug.h>
13 #include <proto/oop.h>
14 #include <proto/utility.h>
16 #include <exec/memory.h>
17 #include <exec/lists.h>
19 #include <graphics/rastport.h>
20 #include <graphics/gfx.h>
23 #include <aros/symbolsets.h>
25 #include <hidd/graphics.h>
35 #include LC_LIBDEFS_FILE
37 void vgaRestore(struct vgaHWRec
*);
38 int vgaInitMode(struct vgaModeDesc
*, struct vgaHWRec
*);
39 void vgaLoadPalette(struct vgaHWRec
*, unsigned char *);
41 #define MNAME_ROOT(x) PCVGABM__Root__ ## x
42 #define MNAME_BM(x) PCVGABM__Hidd_BitMap__ ## x
44 /*********** BitMap::New() *************************************/
46 OOP_Object
*PCVGABM__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
48 EnterFunc(bug("VGAGfx.BitMap::New()\n"));
50 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
) msg
);
51 D(bug("[VGABitMap] Object created by superclass: 0x%p\n"));
54 struct bitmap_data
*data
;
55 OOP_Object
*gfxhidd
, *sync
, *pf
;
56 IPTR modeid
= vHidd_ModeID_Invalid
;
57 IPTR width
, height
, depth
;
59 IPTR displayable
= FALSE
;
61 data
= OOP_INST_DATA(cl
, o
);
64 memset(data
, 0, sizeof(struct bitmap_data
));
67 OOP_GetAttr(o
, aHidd_BitMap_ModeID
, &modeid
);
68 OOP_GetAttr(o
, aHidd_BitMap_Width
, &width
);
69 OOP_GetAttr(o
, aHidd_BitMap_Height
, &height
);
70 OOP_GetAttr(o
, aHidd_BitMap_Displayable
, &displayable
);
71 OOP_GetAttr(o
, aHidd_BitMap_PixFmt
, (IPTR
*)&pf
);
72 D(bug("[VGABitMap] PixFmt object: 0x%p\n", pf
));
73 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &depth
);
75 D(bug("[VGABitMap] Size: %lux%lu, depth: %lu\n", width
, height
, depth
));
76 D(bug("[VGABitMap] Displayable: %ld\n", displayable
));
77 ASSERT (width
!= 0 && height
!= 0 && depth
!= 0);
80 data
->height
= height
;
83 if (modeid
!= vHidd_ModeID_Invalid
) {
85 OOP_GetAttr(o
, aHidd_BitMap_GfxHidd
, (IPTR
*)&gfxhidd
);
86 HIDD_Gfx_GetMode(gfxhidd
, modeid
, &sync
, &pf
);
87 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &dwidth
);
88 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &dheight
);
89 data
->disp_width
= dwidth
;
90 data
->disp_height
= dheight
;
91 D(bug("[VGABitMap] Display size: %dx%d\n", dwidth
, dheight
));
94 width
=(width
+15) & ~15;
96 data
->VideoData
= AllocVec(width
*height
,MEMF_PUBLIC
|MEMF_CLEAR
);
97 D(bug("[VGABitMap] Allocated videodata at 0x%p\n", data
->VideoData
));
98 if (data
->VideoData
) {
99 struct TagItem tags
[2];
101 tags
[0].ti_Tag
= aHidd_ChunkyBM_Buffer
;
102 tags
[0].ti_Data
= (IPTR
)data
->VideoData
;
103 tags
[1].ti_Tag
= TAG_END
;
104 OOP_SetAttrs(o
, tags
);
106 /* If the bitmap is not displayable, we're done */
108 ReturnPtr("VGAGfx.BitMap::New()", OOP_Object
*, o
);
110 data
->Regs
= AllocVec(sizeof(struct vgaHWRec
),MEMF_PUBLIC
|MEMF_CLEAR
);
111 D(bug("[VGABitMap] Registers at 0x%p\n", data
->Regs
));
113 Here there is brand new method of getting pixelclock data.
114 It was introduced here to make the code more portable. Besides
115 it may now be used as a base for creating other low level
119 struct vgaModeDesc mode
;
122 /* We should have got modeID from the bitmap */
123 if (modeid
!= vHidd_ModeID_Invalid
)
126 mode
.Height
= dheight
;
128 OOP_GetAttr(sync
, aHidd_Sync_PixelClock
, &pixelc
);
130 mode
.clock
= (pixelc
> 26000000) ? 1 : 0;
133 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &mode
.HDisplay
);
134 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &mode
.VDisplay
);
135 OOP_GetAttr(sync
, aHidd_Sync_HSyncStart
, &mode
.HSyncStart
);
136 OOP_GetAttr(sync
, aHidd_Sync_VSyncStart
, &mode
.VSyncStart
);
137 OOP_GetAttr(sync
, aHidd_Sync_HSyncEnd
, &mode
.HSyncEnd
);
138 OOP_GetAttr(sync
, aHidd_Sync_VSyncEnd
, &mode
.VSyncEnd
);
139 OOP_GetAttr(sync
, aHidd_Sync_HTotal
, &mode
.HTotal
);
140 OOP_GetAttr(sync
, aHidd_Sync_VTotal
, &mode
.VTotal
);
142 vgaInitMode(&mode
, data
->Regs
);
143 vgaLoadPalette(data
->Regs
,(unsigned char *)NULL
);
145 D(bug("[VGABitMap] Created displayable bitmap 0x%p, data 0x%p\n", o
, data
));
149 FreeVec(data
->VideoData
);
153 OOP_MethodID disp_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
154 OOP_CoerceMethod(cl
, o
, (OOP_Msg
) &disp_mid
);
158 } /* if created object */
160 ReturnPtr("VGAGfx.BitMap::New()", OOP_Object
*, o
);
163 /********** Bitmap::Dispose() ***********************************/
165 VOID
PCVGABM__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
167 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
168 EnterFunc(bug("VGAGfx.BitMap::Dispose()\n"));
170 FreeVec(data
->VideoData
);
173 OOP_DoSuperMethod(cl
, o
, msg
);
175 ReturnVoid("VGAGfx.BitMap::Dispose");
178 /********* BitMap::SetColors() ***************************/
180 void vgaDACLoad(struct vgaHWRec
*, unsigned char, int);
182 BOOL
MNAME_BM(SetColors
)(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_SetColors
*msg
)
184 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
185 HIDDT_PixelFormat
*pf
;
189 HIDDT_Pixel red
, green
, blue
;
193 if ( vHidd_ColorModel_StaticPalette
== HIDD_PF_COLMODEL(pf
)
194 || vHidd_ColorModel_TrueColor
== HIDD_PF_COLMODEL(pf
) ) {
196 /* Superclass takes care of this case */
198 return OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
201 /* We have a vHidd_GT_Palette bitmap */
203 if (!OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
)) return FALSE
;
207 if ((msg
->firstColor
+ msg
->numColors
) > (1 << data
->bpp
))
211 for ( xc_i
= msg
->firstColor
, col_i
= 0;
212 col_i
< msg
->numColors
;
215 red
= msg
->colors
[col_i
].red
>> 8;
216 green
= msg
->colors
[col_i
].green
>> 8;
217 blue
= msg
->colors
[col_i
].blue
>> 8;
219 /* Update DAC registers */
220 data
->Regs
->DAC
[xc_i
*3] = red
>> 2;
221 data
->Regs
->DAC
[xc_i
*3+1] = green
>> 2;
222 data
->Regs
->DAC
[xc_i
*3+2] = blue
>> 2;
224 msg
->colors
[col_i
].pixval
= xc_i
;
227 /* Restore palette if displayed */
229 ObtainSemaphore(&XSD(cl
)->HW_acc
);
230 vgaDACLoad(data
->Regs
, msg
->firstColor
, msg
->numColors
);
231 ReleaseSemaphore(&XSD(cl
)->HW_acc
);
237 /********* BitMap::PutPixel() ***************************/
238 // FIXME: in theory we shouldn't need this method since the superclass implements it
240 VOID
MNAME_BM(PutPixel
)(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutPixel
*msg
)
242 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
246 /*** BitMap::Set() *******************************************/
248 VOID
MNAME_ROOT(Set
)(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Set
*msg
)
250 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
251 struct TagItem
*tag
, *tstate
;
254 int xoffset
= data
->xoffset
;
255 int yoffset
= data
->yoffset
;
257 tstate
= msg
->attrList
;
258 while((tag
= NextTagItem(&tstate
)))
260 if(IS_BM_ATTR(tag
->ti_Tag
, idx
))
264 case aoHidd_BitMap_Visible
:
265 data
->disp
= tag
->ti_Data
;
266 D(bug("[VGAGfx] BitMap::Visible set to %d\n", data
->disp
));
270 /* Program video mode on the card */
272 vgaRestore(data
->Regs
);
273 /* If our bitmap is smaller than display area,
274 we need to clear two rectangles: to the right
275 and to the bottom of the used framebuffer
277 if (data
->disp_width
> data
->width
) {
278 box
.x1
= data
->width
;
280 box
.x2
= data
->disp_width
- 1;
281 box
.y2
= data
->height
- 1;
282 vgaEraseArea(data
, &box
);
284 if (data
->disp_height
> data
->height
) {
286 box
.y1
= data
->height
;
287 box
.x2
= data
->width
- 1;
288 box
.y2
= data
->disp_height
- 1;
289 vgaEraseArea(data
, &box
);
293 case aoHidd_BitMap_LeftEdge
:
294 xoffset
= tag
->ti_Data
;
295 limit
= data
->disp_width
- data
->width
;
298 else if (xoffset
< limit
)
301 case aoHidd_BitMap_TopEdge
:
302 yoffset
= tag
->ti_Data
;
303 limit
= data
->disp_height
- data
->height
;
306 else if (yoffset
< limit
)
312 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
314 if ((xoffset
!= data
->xoffset
) || (yoffset
!= data
->yoffset
)) {
315 data
->xoffset
= xoffset
;
316 data
->yoffset
= yoffset
;
319 struct Box box
= {0, 0, data
->disp_width
- 1, data
->disp_height
- 1};
321 ObtainSemaphore(&XSD(cl
)->HW_acc
);
322 vgaRefreshArea(data
, &box
);
324 ReleaseSemaphore(&XSD(cl
)->HW_acc
);
329 VOID
MNAME_ROOT(Get
)(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
331 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
334 if (IS_VGABM_ATTR(msg
->attrID
, idx
)) {
336 case aoHidd_VGABitMap_Drawable
:
337 *msg
->storage
= (IPTR
)data
->VideoData
;
340 } else if (IS_BM_ATTR(msg
->attrID
, idx
)) {
342 case aoHidd_BitMap_LeftEdge
:
343 *msg
->storage
= data
->xoffset
;
345 case aoHidd_BitMap_TopEdge
:
346 *msg
->storage
= data
->yoffset
;
348 case aoHidd_BitMap_Visible
:
349 *msg
->storage
= data
->disp
;
353 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
356 /*** BitMap::UpdateRect() *******************************************/
358 VOID
PCVGABM__Hidd_BitMap__UpdateRect(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_UpdateRect
*msg
)
360 struct bitmap_data
*data
= OOP_INST_DATA(cl
, o
);
361 int left
= msg
->x
+ data
->xoffset
;
362 int top
= msg
->y
+ data
->yoffset
;
363 int right
= left
+ msg
->width
- 1;
364 int bottom
= top
+ msg
->height
- 1;
366 if ((right
< 0) || (bottom
< 0))
375 ObtainSemaphore(&XSD(cl
)->HW_acc
);
377 if ((msg
->width
== 1) && (msg
->height
== 1))
378 vgaRefreshPixel(data
, left
, top
);
380 struct Box box
= {left
, top
, right
, bottom
};
382 vgaRefreshArea(data
, &box
);
385 if ( ( (XSD(cl
)->mouseX
+ XSD(cl
)->mouseW
- 1 >= left
) &&
386 (XSD(cl
)->mouseX
<= right
) ) ||
387 ( (XSD(cl
)->mouseY
+ XSD(cl
)->mouseH
- 1 >= top
) &&
388 (XSD(cl
)->mouseY
<= bottom
) ) )
391 ReleaseSemaphore(&XSD(cl
)->HW_acc
);