1 #include "Renderer_16bpp.h"
6 Renderer_16bpp::Renderer_16bpp(char *baseAddress
, int width
, int height
, int bytesPerRow
, color_space cspace
)
7 : Renderer(baseAddress
, width
, height
, bytesPerRow
, cspace
)
11 fTransparentColor
= TRANS555COLOR
;
14 fTransparentColor
= TRANS565COLOR
;
18 fTransparentColor
= 0;
22 const unsigned kBottom
= 1;
23 const unsigned kTop
= 2;
24 const unsigned kLeft
= 4;
25 const unsigned kRight
= 8;
27 #define clipmask(x, y, rect) \
28 ({ unsigned int mask = 0; \
29 if (x < rect.left) mask |= kLeft; \
30 else if (x > rect.right) mask |= kRight; \
31 if (y < rect.top) mask |= kTop; \
32 else if (y > rect.bottom) mask |= kBottom; \
35 void Renderer_16bpp::CopyRect(const Rect
&source
, const Rect
&dest
)
37 ASSERT(source
.Width() == dest
.Width());
38 ASSERT(source
.Height() == dest
.Height());
44 if (dest
.left
> source
.left
&& dest
.left
< source
.right
) {
45 // overlap left side, copy backward
47 startX
= source
.right
;
53 if (dest
.top
> source
.top
&& dest
.top
< source
.bottom
) {
54 // overlap bottom, copy top up
55 dY
= -((BufferBytesPerRow() / 2) + dX
* source
.Width()) + 1;
56 startY
= source
.bottom
;
58 dY
= ((BufferBytesPerRow() / 2) - dX
* source
.Width()) - 1;
62 uint16
*srcptr
= (uint16
*)BufferBaseAddress() + startX
+ startY
* (BufferBytesPerRow() / 2);
63 int offset
= (dest
.left
- source
.left
) + (dest
.top
- source
.top
)
64 * (BufferBytesPerRow() / 2);
66 for (int y
= source
.top
; y
<= source
.bottom
; y
++) {
67 for (int x
= source
.left
; x
<= source
.right
; x
++) {
68 *((uint16
*) srcptr
+ offset
) = *srcptr
;
76 void Renderer_16bpp::FillRect(int x1
, int y1
, int x2
, int y2
, color32 _color
, color_space cspace
)
78 ASSERT(x1
>= 0 && x1
<= BufferWidth());
79 ASSERT(x2
>= 0 && x2
<= BufferWidth());
80 ASSERT(y1
>= 0 && y1
<= BufferWidth());
81 ASSERT(y2
>= 0 && y2
<= BufferWidth());
85 color16
*ptr
= (color16
*)BufferBaseAddress() + x1
+ y1
* (BufferBytesPerRow() / 2);
86 color16 color
= ColorTranslate(_color
, cspace
, GetColorspace());
87 uint32 longcolor
= ((uint32
)color
& 0xffff) | ((uint32
)color
<< 16);
89 int wrap
= BufferWidth() - (x2
- x1
) - 1;
90 for (int y
= y1
; y
<= y2
; y
++) {
92 while (x
<= x2
&& (x
& 3) != 0) {
98 *((uint32
*) ptr
) = longcolor
;
112 void Renderer_16bpp::FillRect(const Rect
&rect
, color32 color
, color_space cspace
)
114 FillRect(rect
.left
, rect
.top
, rect
.right
, rect
.bottom
, color
, cspace
);
117 void Renderer_16bpp::DrawLine(int x1
, int y1
, int x2
, int y2
, color32 _color
, color_space cspace
)
119 ASSERT(x1
>= 0 && x1
< BufferWidth());
120 ASSERT(x2
>= 0 && x2
< BufferWidth());
121 ASSERT(y1
>= 0 && y1
< BufferWidth());
122 ASSERT(y2
>= 0 && y2
< BufferWidth());
125 // Swap if necessary so we always draw top to bottom
136 int deltaY
= y2
- y1
;
137 int deltaX
= x2
> x1
? x2
- x1
: x1
- x2
;
138 int xDir
= x2
> x1
? 1 : -1;
140 color16
*ptr
= (color16
*)BufferBaseAddress() + x1
+ y1
* (BufferBytesPerRow() / 2);
141 color16 color
= ColorTranslate(_color
, cspace
, GetColorspace());
145 for (int y
= deltaY
; y
>= 0; y
--) {
147 ptr
+= (BufferBytesPerRow() / 2);
149 } else if (deltaY
== 0) {
151 for (int x
= deltaX
; x
>= 0; x
--) {
155 } else if (deltaX
> deltaY
) {
156 // Diagonal with horizontal major axis
157 x2
+= xDir
; // Want to quit on pixel past last. Ugly, I know.
158 for (int x
= x1
; x
!= x2
; x
+= xDir
) {
162 if (error
> deltaX
) {
163 ptr
+= (BufferBytesPerRow() / 2);
170 // Diagonal with vertical major axis
171 for (int y
= y1
; y
<= y2
; y
++) {
175 if (error
> deltaY
) {
180 ptr
+= (BufferBytesPerRow() / 2);
185 void Renderer_RGB555::Blit(int x
, int y
, const void *image
, color_space cspace
, int imageWidth
,
186 int imageHeight
, int imageStrideWidth
)
188 ASSERT(x
>= 0 && x
+ imageWidth
<= BufferWidth());
189 ASSERT(y
>= 0 && y
+ imageHeight
<= BufferWidth());
191 uint16
*screen_ptr
= (uint16
*)BufferBaseAddress() + x
+ y
* (BufferBytesPerRow() / 2);
192 color16
*image_ptr16
= (color16
*)image
;
193 color32
*image_ptr32
= (color32
*)image
;
194 int imageOffs
= imageStrideWidth
- imageWidth
;
195 int screenOffs
= (BufferBytesPerRow() / 2) - imageWidth
;
197 if(cspace
== CSPACE_RGB555
) {
198 for (int i
= 0; i
< imageHeight
; i
++) {
199 for (int j
= 0; j
< imageWidth
; j
++) {
200 if(*image_ptr16
!= TRANS555COLOR
)
201 *screen_ptr
= *image_ptr16
;
205 image_ptr16
+= imageOffs
;
206 screen_ptr
+= screenOffs
;
208 } else if(cspace
== CSPACE_RGB888
) {
209 for (int i
= 0; i
< imageHeight
; i
++) {
210 for (int j
= 0; j
< imageWidth
; j
++) {
211 if(*image_ptr32
!= TRANS888COLOR
)
212 *screen_ptr
= Color888to555(*image_ptr32
);
216 image_ptr32
+= imageOffs
;
217 screen_ptr
+= screenOffs
;
219 } else if(cspace
== CSPACE_RGB565
) {
220 for (int i
= 0; i
< imageHeight
; i
++) {
221 for (int j
= 0; j
< imageWidth
; j
++) {
222 if(*image_ptr16
!= TRANS565COLOR
)
223 *screen_ptr
= Color565to555(*image_ptr16
);
227 image_ptr16
+= imageOffs
;
228 screen_ptr
+= screenOffs
;
234 void Renderer_RGB555::StretchBlit(const Rect
&imageRect
, const Rect
&displayRect
, const void *image
, color_space cspace
,
235 int imageStrideWidth
)
238 ASSERT(imageRect
.Valid());
239 ASSERT(displayRect
.Valid());
240 ASSERT(imageRect
.left
>= 0);
241 ASSERT(imageRect
.top
>= 0);
242 ASSERT(imageRect
.right
< imageStrideWidth
);
245 char *screen_ptr
= BufferBaseAddress() + displayRect
.left
+ displayRect
.top
246 * BufferBytesPerRow();
247 color888
*current_image_line
= image
+ imageRect
.left
+ imageRect
.top
*
249 int screenOffs
= BufferBytesPerRow() - displayRect
.Width() - 1;
251 for (int y
= displayRect
.top
; y
<= displayRect
.bottom
; y
++) {
252 color888
*image_ptr
= current_image_line
;
254 for (int x
= displayRect
.left
; x
<= displayRect
.right
; x
++) {
255 if (*image_ptr
!= TRANS888COLOR
)
256 *screen_ptr
= *image_ptr
;
258 herror
+= imageRect
.Width();
259 while (herror
>= displayRect
.Width()) {
260 herror
-= displayRect
.Width();
267 verror
+= imageRect
.Height();
268 while (verror
> displayRect
.Height()) {
269 verror
-= displayRect
.Height();
270 current_image_line
+= imageStrideWidth
;
273 screen_ptr
+= screenOffs
;