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