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>
29 #include "vgagfx_support.h"
30 #include "vgagfx_intern.h"
31 #include "vgagfx_hidd.h"
32 #include "vgagfx_bitmap.h"
34 #include LC_LIBDEFS_FILE
36 void vgaRestore(struct vgaHWRec
*);
37 int vgaInitMode(struct vgaModeDesc
*, struct vgaHWRec
*);
38 void vgaLoadPalette(struct vgaHWRec
*, unsigned char *);
40 #define MNAME_ROOT(x) VGAGfxBM__Root__ ## x
41 #define MNAME_BM(x) VGAGfxBM__Hidd_BitMap__ ## x
43 /*********** BitMap::New() *************************************/
45 OOP_Object
*VGAGfxBM__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
47 EnterFunc(bug("VGAGfx.BitMap::New()\n"));
49 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
) msg
);
50 D(bug("[VGAGfx:BitMap] Object created by superclass: 0x%p\n"));
53 struct VGAGfxBitMapData
*data
;
54 OOP_Object
*gfxhidd
, *sync
, *pf
;
55 IPTR modeid
= vHidd_ModeID_Invalid
;
56 IPTR width
, height
, depth
;
58 IPTR displayable
= FALSE
;
60 data
= OOP_INST_DATA(cl
, o
);
63 memset(data
, 0, sizeof(struct VGAGfxBitMapData
));
66 OOP_GetAttr(o
, aHidd_BitMap_ModeID
, &modeid
);
67 OOP_GetAttr(o
, aHidd_BitMap_Width
, &width
);
68 OOP_GetAttr(o
, aHidd_BitMap_Height
, &height
);
69 OOP_GetAttr(o
, aHidd_BitMap_Displayable
, &displayable
);
70 OOP_GetAttr(o
, aHidd_BitMap_PixFmt
, (IPTR
*)&pf
);
71 D(bug("[VGAGfx:BitMap] PixFmt object: 0x%p\n", pf
));
72 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &depth
);
74 D(bug("[VGAGfx:BitMap] Size: %lux%lu, depth: %lu\n", width
, height
, depth
));
75 D(bug("[VGAGfx:BitMap] Displayable: %ld\n", displayable
));
76 ASSERT (width
!= 0 && height
!= 0 && depth
!= 0);
79 data
->height
= height
;
82 if (modeid
!= vHidd_ModeID_Invalid
) {
84 OOP_GetAttr(o
, aHidd_BitMap_GfxHidd
, (IPTR
*)&gfxhidd
);
85 HIDD_Gfx_GetMode(gfxhidd
, modeid
, &sync
, &pf
);
86 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &dwidth
);
87 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &dheight
);
88 data
->disp_width
= dwidth
;
89 data
->disp_height
= dheight
;
90 D(bug("[VGAGfx:BitMap] Display size: %dx%d\n", dwidth
, dheight
));
93 width
=(width
+15) & ~15;
95 data
->VideoData
= AllocVec(width
*height
,MEMF_PUBLIC
|MEMF_CLEAR
);
96 D(bug("[VGAGfx:BitMap] Allocated videodata at 0x%p\n", data
->VideoData
));
97 if (data
->VideoData
) {
98 struct TagItem tags
[2];
100 tags
[0].ti_Tag
= aHidd_ChunkyBM_Buffer
;
101 tags
[0].ti_Data
= (IPTR
)data
->VideoData
;
102 tags
[1].ti_Tag
= TAG_END
;
103 OOP_SetAttrs(o
, tags
);
105 /* If the bitmap is not displayable, we're done */
107 ReturnPtr("VGAGfx.BitMap::New()", OOP_Object
*, o
);
109 data
->Regs
= AllocVec(sizeof(struct vgaHWRec
),MEMF_PUBLIC
|MEMF_CLEAR
);
110 D(bug("[VGAGfx:BitMap] Registers at 0x%p\n", data
->Regs
));
112 Here there is brand new method of getting pixelclock data.
113 It was introduced here to make the code more portable. Besides
114 it may now be used as a base for creating other low level
118 struct vgaModeDesc mode
;
121 /* We should have got modeID from the bitmap */
122 if (modeid
!= vHidd_ModeID_Invalid
)
125 mode
.Height
= dheight
;
127 OOP_GetAttr(sync
, aHidd_Sync_PixelClock
, &pixelc
);
129 mode
.clock
= (pixelc
> 26000000) ? 1 : 0;
132 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &mode
.HDisplay
);
133 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &mode
.VDisplay
);
134 OOP_GetAttr(sync
, aHidd_Sync_HSyncStart
, &mode
.HSyncStart
);
135 OOP_GetAttr(sync
, aHidd_Sync_VSyncStart
, &mode
.VSyncStart
);
136 OOP_GetAttr(sync
, aHidd_Sync_HSyncEnd
, &mode
.HSyncEnd
);
137 OOP_GetAttr(sync
, aHidd_Sync_VSyncEnd
, &mode
.VSyncEnd
);
138 OOP_GetAttr(sync
, aHidd_Sync_HTotal
, &mode
.HTotal
);
139 OOP_GetAttr(sync
, aHidd_Sync_VTotal
, &mode
.VTotal
);
141 vgaInitMode(&mode
, data
->Regs
);
142 vgaLoadPalette(data
->Regs
,(unsigned char *)NULL
);
144 D(bug("[VGAGfx:BitMap] Created displayable bitmap 0x%p, data 0x%p\n", o
, data
));
148 FreeVec(data
->VideoData
);
152 OOP_MethodID disp_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
153 OOP_CoerceMethod(cl
, o
, (OOP_Msg
) &disp_mid
);
157 } /* if created object */
159 ReturnPtr("VGAGfx.BitMap::New()", OOP_Object
*, o
);
162 /********** Bitmap::Dispose() ***********************************/
164 VOID
VGAGfxBM__Root__Dispose(OOP_Class
*cl
, OOP_Object
*o
, OOP_Msg msg
)
166 struct VGAGfxBitMapData
*data
= OOP_INST_DATA(cl
, o
);
167 EnterFunc(bug("VGAGfx.BitMap::Dispose()\n"));
169 FreeVec(data
->VideoData
);
172 OOP_DoSuperMethod(cl
, o
, msg
);
174 ReturnVoid("VGAGfx.BitMap::Dispose");
177 /********* BitMap::SetColors() ***************************/
179 void vgaDACLoad(struct vgaHWRec
*, unsigned char, int);
181 BOOL
MNAME_BM(SetColors
)(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_SetColors
*msg
)
183 struct VGAGfxBitMapData
*data
= OOP_INST_DATA(cl
, o
);
184 HIDDT_PixelFormat
*pf
;
188 HIDDT_Pixel red
, green
, blue
;
192 if ( vHidd_ColorModel_StaticPalette
== HIDD_PF_COLMODEL(pf
)
193 || vHidd_ColorModel_TrueColor
== HIDD_PF_COLMODEL(pf
) ) {
195 /* Superclass takes care of this case */
197 return OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
200 /* We have a vHidd_GT_Palette bitmap */
202 if (!OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
)) return FALSE
;
206 if ((msg
->firstColor
+ msg
->numColors
) > (1 << data
->bpp
))
210 for ( xc_i
= msg
->firstColor
, col_i
= 0;
211 col_i
< msg
->numColors
;
214 red
= msg
->colors
[col_i
].red
>> 8;
215 green
= msg
->colors
[col_i
].green
>> 8;
216 blue
= msg
->colors
[col_i
].blue
>> 8;
218 /* Update DAC registers */
219 data
->Regs
->DAC
[xc_i
*3] = red
>> 2;
220 data
->Regs
->DAC
[xc_i
*3+1] = green
>> 2;
221 data
->Regs
->DAC
[xc_i
*3+2] = blue
>> 2;
223 msg
->colors
[col_i
].pixval
= xc_i
;
226 /* Restore palette if displayed */
228 ObtainSemaphore(&XSD(cl
)->HW_acc
);
229 vgaDACLoad(data
->Regs
, msg
->firstColor
, msg
->numColors
);
230 ReleaseSemaphore(&XSD(cl
)->HW_acc
);
236 /********* BitMap::PutPixel() ***************************/
237 // FIXME: in theory we shouldn't need this method since the superclass implements it
239 VOID
MNAME_BM(PutPixel
)(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutPixel
*msg
)
241 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
245 /*** BitMap::Set() *******************************************/
247 VOID
MNAME_ROOT(Set
)(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Set
*msg
)
249 struct VGAGfxBitMapData
*data
= OOP_INST_DATA(cl
, o
);
250 struct TagItem
*tag
, *tstate
;
253 int xoffset
= data
->xoffset
;
254 int yoffset
= data
->yoffset
;
256 tstate
= msg
->attrList
;
257 while((tag
= NextTagItem(&tstate
)))
259 if(IS_BM_ATTR(tag
->ti_Tag
, idx
))
263 case aoHidd_BitMap_Visible
:
264 data
->disp
= tag
->ti_Data
;
265 D(bug("[VGAGfx:BitMap] Visible set to %d\n", data
->disp
));
269 /* Program video mode on the card */
271 vgaRestore(data
->Regs
);
272 /* If our bitmap is smaller than display area,
273 we need to clear two rectangles: to the right
274 and to the bottom of the used framebuffer
276 if (data
->disp_width
> data
->width
) {
277 box
.x1
= data
->width
;
279 box
.x2
= data
->disp_width
- 1;
280 box
.y2
= data
->height
- 1;
281 vgaEraseArea(data
, &box
);
283 if (data
->disp_height
> data
->height
) {
285 box
.y1
= data
->height
;
286 box
.x2
= data
->width
- 1;
287 box
.y2
= data
->disp_height
- 1;
288 vgaEraseArea(data
, &box
);
292 case aoHidd_BitMap_LeftEdge
:
293 xoffset
= tag
->ti_Data
;
294 limit
= data
->disp_width
- data
->width
;
297 else if (xoffset
< limit
)
300 case aoHidd_BitMap_TopEdge
:
301 yoffset
= tag
->ti_Data
;
302 limit
= data
->disp_height
- data
->height
;
305 else if (yoffset
< limit
)
311 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
313 if ((xoffset
!= data
->xoffset
) || (yoffset
!= data
->yoffset
)) {
314 data
->xoffset
= xoffset
;
315 data
->yoffset
= yoffset
;
318 struct Box box
= {0, 0, data
->disp_width
- 1, data
->disp_height
- 1};
320 ObtainSemaphore(&XSD(cl
)->HW_acc
);
321 vgaRefreshArea(data
, &box
);
323 ReleaseSemaphore(&XSD(cl
)->HW_acc
);
328 VOID
MNAME_ROOT(Get
)(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
330 struct VGAGfxBitMapData
*data
= OOP_INST_DATA(cl
, o
);
333 if (IS_VGABM_ATTR(msg
->attrID
, idx
)) {
335 case aoHidd_VGABitMap_Drawable
:
336 *msg
->storage
= (IPTR
)data
->VideoData
;
339 } else if (IS_BM_ATTR(msg
->attrID
, idx
)) {
341 case aoHidd_BitMap_LeftEdge
:
342 *msg
->storage
= data
->xoffset
;
344 case aoHidd_BitMap_TopEdge
:
345 *msg
->storage
= data
->yoffset
;
347 case aoHidd_BitMap_Visible
:
348 *msg
->storage
= data
->disp
;
352 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
355 /*** BitMap::UpdateRect() *******************************************/
357 VOID
VGAGfxBM__Hidd_BitMap__UpdateRect(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_UpdateRect
*msg
)
359 struct VGAGfxBitMapData
*data
= OOP_INST_DATA(cl
, o
);
360 int left
= msg
->x
+ data
->xoffset
;
361 int top
= msg
->y
+ data
->yoffset
;
362 int right
= left
+ msg
->width
- 1;
363 int bottom
= top
+ msg
->height
- 1;
365 if ((right
< 0) || (bottom
< 0))
374 ObtainSemaphore(&XSD(cl
)->HW_acc
);
376 if ((msg
->width
== 1) && (msg
->height
== 1))
377 vgaRefreshPixel(data
, left
, top
);
379 struct Box box
= {left
, top
, right
, bottom
};
381 vgaRefreshArea(data
, &box
);
384 if ( ( (XSD(cl
)->mouseX
+ XSD(cl
)->mouseW
- 1 >= left
) &&
385 (XSD(cl
)->mouseX
<= right
) ) ||
386 ( (XSD(cl
)->mouseY
+ XSD(cl
)->mouseH
- 1 >= top
) &&
387 (XSD(cl
)->mouseY
<= bottom
) ) )
390 ReleaseSemaphore(&XSD(cl
)->HW_acc
);