1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** GUIX Component */
16 /** */
17 /** Synergy Simulation Display Management (Display) */
18 /** */
19 /**************************************************************************/
20
21 #define GX_SOURCE_CODE
22
23
24 /* Include necessary system files. */
25
26 #include "gx_api.h"
27 #include "gx_display.h"
28 #include "gx_context.h"
29 #include "gx_dave2d_simulation_display_driver.h"
30
31
32
33 /**************************************************************************/
34 /* */
35 /* FUNCTION RELEASE */
36 /* */
37 /* _gx_dave2d_simulation_display_driver_32bpp_horizontal */
38 /* _pixelmap_line_compressed_write */
39 /* PORTABLE C */
40 /* 6.4.0 */
41 /* AUTHOR */
42 /* */
43 /* Ting Zhu, Microsoft Corporation */
44 /* */
45 /* DESCRIPTION */
46 /* */
47 /* Internal helper function that handles writing of compressed */
48 /* pixlemap file without alpha channel. */
49 /* */
50 /* INPUT */
51 /* */
52 /* context Drawing context */
53 /* xstart x-coord of line left */
54 /* xend x-coord of line right */
55 /* y y-coord of line top */
56 /* pixelmap Pointer to GX_PIXELMAP struct */
57 /* */
58 /* OUTPUT */
59 /* */
60 /* None */
61 /* */
62 /* CALLS */
63 /* */
64 /* */
65 /* CALLED BY */
66 /* */
67 /* GUIX Internal Code */
68 /* */
69 /* RELEASE HISTORY */
70 /* */
71 /* DATE NAME DESCRIPTION */
72 /* */
73 /* 12-31-2023 Ting Zhu Initial Version 6.4.0 */
74 /* */
75 /**************************************************************************/
_gx_dave2d_simulation_display_driver_32bpp_horizontal_pixelmap_line_compressed_write(GX_DRAW_CONTEXT * context,INT xstart,INT xend,INT y,GX_FILL_PIXELMAP_INFO * info)76 static VOID _gx_dave2d_simulation_display_driver_32bpp_horizontal_pixelmap_line_compressed_write(GX_DRAW_CONTEXT *context,
77 INT xstart, INT xend, INT y, GX_FILL_PIXELMAP_INFO *info)
78 {
79 INT start_pos;
80 INT xval;
81 GX_UBYTE count;
82 GX_UBYTE alpha_value;
83 GX_COLOR pixel;
84 GX_CONST GX_UBYTE *get;
85 GX_BOOL has_alpha;
86 GX_PIXELMAP *pixelmap;
87 VOID (*write_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color);
88 VOID (*blend_func)(GX_DRAW_CONTEXT *context, INT x, INT y, GX_COLOR color, GX_UBYTE alpha);
89
90 write_func = _gx_display_driver_32bpp_pixel_write;
91 blend_func = _gx_display_driver_24xrgb_pixel_blend;
92 pixelmap = info -> pixelmap;
93
94 if ((write_func == GX_NULL) ||
95 (blend_func == GX_NULL))
96 {
97 return;
98 }
99
100 if ((info -> draw) && (xstart <= xend))
101 {
102 if (pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_ALPHA)
103 {
104 has_alpha = GX_TRUE;
105 }
106 else
107 {
108 has_alpha = GX_FALSE;
109 }
110
111 /* Calculate draw start position. */
112 start_pos = xstart - (info -> x_offset % pixelmap -> gx_pixelmap_width);
113
114 /* Repeat the draw operation to fill the whole dirty area. */
115 while (start_pos <= xend)
116 {
117 xval = start_pos;
118
119 /*Start from where we need to repeat.*/
120 get = (GX_CONST GX_UBYTE *)info -> current_pixel_ptr;
121
122 while (xval < start_pos + pixelmap -> gx_pixelmap_width)
123 {
124 count = *get++;
125 if (count & 0x80)
126 {
127 count = (GX_UBYTE)((count & 0x7f) + 1);
128 /* repeated value */
129 pixel = (*get++);
130 pixel = (ULONG)((*get++) << 8) | pixel;
131 pixel = (ULONG)((*get++) << 16) | pixel;
132
133 if (has_alpha)
134 {
135 alpha_value = *get++;
136 while (count--)
137 {
138 if (xval >= xstart && xval <= xend)
139 {
140 blend_func(context, xval, y, pixel, alpha_value);
141 }
142 xval++;
143 }
144 }
145 else
146 {
147 get += 1;
148 while (count--)
149 {
150 if (xval >= xstart && xval <= xend)
151 {
152 write_func(context, xval, y, pixel);
153 }
154 xval++;
155 }
156 }
157 }
158 else
159 {
160 count++;
161 while (count--)
162 {
163 if (xval >= xstart && xval <= xend)
164 {
165 pixel = (ULONG)((*(get)) | ((*(get + 1)) << 8) | ((*(get + 2)) << 16));
166 if (has_alpha)
167 {
168 alpha_value = *(get + 3);
169 blend_func(context, xval, y, pixel, alpha_value);
170 }
171 else
172 {
173 write_func(context, xval, y, pixel);
174 }
175 }
176 get += 4;
177 xval++;
178 }
179 }
180 }
181 start_pos += pixelmap -> gx_pixelmap_width;
182 }
183 }
184 else
185 {
186 /*Just do skip operation here. */
187 xval = 0;
188 get = (GX_CONST GX_UBYTE *)info -> current_pixel_ptr;
189 while (xval < pixelmap -> gx_pixelmap_width)
190 {
191 count = *get++;
192 if (count & 0x80)
193 {
194 count = (UCHAR)((count & 0x7f) + 1);
195 get += 4; /* skip repeated pixel value */
196 }
197 else
198 {
199 count++;
200 get += count * 4; /* skip raw pixel values */
201 }
202 xval += count;
203 }
204 }
205
206 /*This line is drawn. cache the pointer for next line draw.*/
207 info -> current_pixel_ptr = (GX_UBYTE *)get;
208 }
209
210 /**************************************************************************/
211 /* */
212 /* FUNCTION RELEASE */
213 /* */
214 /* _gx_dave2d_simulation_display_driver_32bpp_horizontal */
215 /* _pixelmap_line_draw PORTABLE C */
216 /* 6.4.0 */
217 /* AUTHOR */
218 /* */
219 /* Ting Zhu, Microsoft Corporation */
220 /* */
221 /* DESCRIPTION */
222 /* */
223 /* 32bpp screen driver horizontal pixelmap line drawing function that */
224 /* handles compressed or uncompress, with or without alpha channel. */
225 /* */
226 /* INPUT */
227 /* */
228 /* context Drawing context */
229 /* xstart x-coord of line left */
230 /* xend x-coord of line right */
231 /* y y-coord of line top */
232 /* pixelmap Pointer to GX_PIXELMAP struct */
233 /* */
234 /* OUTPUT */
235 /* */
236 /* None */
237 /* */
238 /* CALLS */
239 /* */
240 /* _gx_dave2d_simulation_display_driver_32bpp_horizontal */
241 /* _pixelmap_line_compressed_write */
242 /* _gx_display_driver_32bpp_horizontal_pixelmap_line_draw */
243 /* */
244 /* CALLED BY */
245 /* */
246 /* GUIX Internal Code */
247 /* */
248 /* RELEASE HISTORY */
249 /* */
250 /* DATE NAME DESCRIPTION */
251 /* */
252 /* 12-31-2023 Ting Zhu Initial Version 6.4.0 */
253 /* */
254 /**************************************************************************/
_gx_dave2d_simulation_display_driver_32bpp_horizontal_pixelmap_line_draw(GX_DRAW_CONTEXT * context,INT xstart,INT xend,INT y,GX_FILL_PIXELMAP_INFO * info)255 VOID _gx_dave2d_simulation_display_driver_32bpp_horizontal_pixelmap_line_draw(GX_DRAW_CONTEXT *context,
256 INT xstart, INT xend, INT y, GX_FILL_PIXELMAP_INFO *info)
257 {
258 GX_BOOL drawn = GX_FALSE;
259 GX_BOOL synergy_specific_format = GX_FALSE;
260
261 if (info -> pixelmap == GX_NULL)
262 {
263 return;
264 }
265
266 /*Format check, this pixelmap must be synergy format style.*/
267 if (info -> pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_TARGA)
268 {
269 synergy_specific_format = GX_TRUE;
270 }
271
272 if (info -> pixelmap -> gx_pixelmap_flags & GX_PIXELMAP_COMPRESSED)
273 {
274 /* compressed with or without alpha */
275 _gx_dave2d_simulation_display_driver_32bpp_horizontal_pixelmap_line_compressed_write(context, xstart, xend, y, info);
276 drawn = GX_TRUE;
277 }
278
279 if (!synergy_specific_format && !drawn)
280 {
281 _gx_display_driver_32bpp_horizontal_pixelmap_line_draw(context, xstart, xend, y, info);
282 return;
283 }
284
285 if (drawn)
286 {
287 /*Current pixelmap has gone over, so the offset pointer should be reset.*/
288 if (info -> current_pixel_ptr >= info -> pixelmap -> gx_pixelmap_data + info -> pixelmap -> gx_pixelmap_data_size)
289 {
290 info -> current_pixel_ptr = (GX_UBYTE *)info -> pixelmap -> gx_pixelmap_data;
291 info -> current_aux_ptr = (GX_UBYTE *)info -> pixelmap -> gx_pixelmap_aux_data;
292 }
293 }
294 }
295
296