1 
2 #include "studiox_includes.h"
3 #include "gx_win32_studio_display_driver.h"
4 
5 #ifdef _DEBUG
6 #define new DEBUG_NEW
7 #endif
8 
9 #define MAX_SPRITE_FRAMES     256
10 
studio_sprite_draw(GX_SPRITE * sprite)11 static void studio_sprite_draw(GX_SPRITE* sprite)
12 {
13     GX_SPRITE_FRAME* frame;
14     GX_PIXELMAP* map;
15     GX_VALUE         xpos;
16     GX_VALUE         ypos;
17     int              theme_index;
18     res_info* info;
19     studiox_project* project = GetOpenProject();
20 
21 
22     GX_WIN32_DISPLAY_DRIVER_DATA* data = gx_win32_get_data_instance_by_thread_id(GetCurrentThreadId());
23 
24     if ((!data) || (!project))
25     {
26         return;
27     }
28 
29     /* Draw sprite background.  */
30     gx_widget_background_draw((GX_WIDGET*)sprite);
31 
32     if (sprite->gx_sprite_frame_list)
33     {
34         frame = &sprite->gx_sprite_frame_list[sprite->gx_sprite_current_frame];
35         theme_index = project->mDisplays[data->win32_display_index].active_theme;
36         info = project->FindResource(data->win32_display_index, theme_index, RES_TYPE_PIXELMAP, frame->gx_sprite_frame_pixelmap);
37 
38         if (!info)
39         {
40             return;
41         }
42 
43         if (sprite->gx_sprite_current_frame < sprite->gx_sprite_frame_count)
44         {
45             map = info->GetPixelmap(sprite->gx_sprite_current_frame);
46             if (map)
47             {
48                 xpos = (GX_VALUE)(sprite->gx_widget_size.gx_rectangle_left + frame->gx_sprite_frame_x_offset);
49                 ypos = (GX_VALUE)(sprite->gx_widget_size.gx_rectangle_top + frame->gx_sprite_frame_y_offset);
50 
51                 if (frame->gx_sprite_frame_alpha != GX_ALPHA_VALUE_OPAQUE)
52                 {
53                     gx_canvas_pixelmap_blend(xpos, ypos, map, frame->gx_sprite_frame_alpha);
54                 }
55                 else
56                 {
57                     gx_canvas_pixelmap_draw(xpos, ypos, map);
58                 }
59             }
60         }
61     }
62 
63     /* Draw children widgets of sprite widget.  */
64     gx_widget_children_draw((GX_WIDGET*)sprite);
65 }
66 
sprite_service_provider()67 sprite_service_provider::sprite_service_provider()
68 {
69 }
70 
GetVarDeclaration()71 CString sprite_service_provider::GetVarDeclaration()
72 {
73     return CString("GX_SPRITE_MEMBERS_DECLARE");
74 }
75 
DeclarePropertiesStruct()76 CString sprite_service_provider::DeclarePropertiesStruct()
77 {
78     CString out(""
79     "typedef struct\n"
80     "{\n"
81     "    GX_SPRITE_FRAME *frame_list;\n"
82     "    USHORT           frame_count;\n"
83     "} GX_SPRITE_PROPERTIES;\n\n");
84 
85     return out;
86 }
87 
88 TCHAR *sprite_background_string[] = {
89     _T("GX_SPRITE_BACKGROUND_NO_ACTION"),
90     _T("GX_SPRITE_BACKGROUND_SOLID_FILL"),
91     _T("GX_SPRITE_BACKGROUND_RESTORE")
92 };
93 
WriteExtendedProperties(screen_generator * gen,CString & prefix,widget_info * info)94 CString sprite_service_provider::WriteExtendedProperties(screen_generator *gen, CString &prefix, widget_info *info)
95 {
96     int index;
97     int back_op;
98     CString temp;
99     CString list;
100     GX_SPRITE_FRAME *frame;
101     CString propname = prefix + info->app_name;
102 
103     if (info->ewi.sprite.frame_count > 0)
104     {
105         list.Format(_T("GX_SPRITE_FRAME %s_frame_list[%d] =\n{\n"),
106             propname, info->ewi.sprite.frame_count);
107 
108         frame = info->ewi.sprite.framelist;
109         int frame_id;
110 
111         for (index = 0; index < info->ewi.sprite.frame_count; index++)
112         {
113             if (info->pixelmap_id[NORMAL_PIXELMAP_INDEX])
114             {
115                 frame_id = index;
116             }
117             else
118             {
119                 frame_id = 0;
120             }
121 
122             back_op = frame->gx_sprite_frame_background_operation;
123             if (back_op >= 3)
124             {
125                 back_op = 0;
126             }
127 
128             temp.Format(_T("    {\n")
129                         _T("        %s,  /* pixelmap id */\n")
130                         _T("        %d,  /* x offset */\n")
131                         _T("        %d,  /* y offset */\n")
132                         _T("        %d,  /* frame delay */\n")
133                         _T("        %s,  /* background operation */\n")
134                         _T("        %d  /* alpha value*/\n")
135                         _T("    }"),
136                 gen->GetPixelmapIdName(frame->gx_sprite_frame_pixelmap, frame_id),
137                 frame->gx_sprite_frame_x_offset,
138                 frame->gx_sprite_frame_y_offset,
139                 frame->gx_sprite_frame_delay,
140                 sprite_background_string[back_op],
141                 frame->gx_sprite_frame_alpha);
142 
143             if (index == info->ewi.sprite.frame_count - 1)
144             {
145                 temp += "\n";
146             }
147             else
148             {
149                 temp += ",\n";
150             }
151             list += temp;
152             frame++;
153         }
154         list += "};\n\n";
155 
156         temp.Format(_T("GX_SPRITE_PROPERTIES %s_properties =\n")
157             _T("{\n")
158             _T("    %s_frame_list,     /* address of frame list */\n")
159             _T("    %d,                /* frame count */\n")
160             _T("};\n"),
161             propname, propname, info->ewi.sprite.frame_count);
162 
163         list += temp;
164     }
165     else
166     {
167         list.Format(_T("GX_SPRITE_PROPERTIES %s_properties =\n")
168                     _T("{\n")
169                     _T("    GX_NULL,     /* address of frame list */\n")
170                     _T("    0,           /* frame count */\n")
171                     _T("};\n"),
172             propname);
173     }
174     return list;
175 }
176 
GetCreateFromDefFunctionName()177 CString sprite_service_provider::GetCreateFromDefFunctionName()
178 {
179     return CString("gx_studio_sprite_create");
180 }
181 
GetCreateFromDefFunction(int version)182 CString sprite_service_provider::GetCreateFromDefFunction(int version)
183 {
184     CString out;
185     MakeCreatePreamble("sprite", version, out);
186 
187     out += "{\n"
188         "    UINT status;\n"
189         "    GX_SPRITE *sprite = (GX_SPRITE *) control_block;\n"
190         "    GX_SPRITE_PROPERTIES *props = (GX_SPRITE_PROPERTIES *) info->properties;\n"
191         "    status = gx_sprite_create(sprite, info->widget_name, parent,\n"
192         "               props->frame_list, props->frame_count,\n"
193         "               info->style, info->widget_id, &info->size);\n"
194         "    return status;\n"
195         "}\n";
196     return out;
197 }
198 
CreateNewInstance(GX_WIDGET * parent)199 widget_info *sprite_service_provider::CreateNewInstance(GX_WIDGET *parent)
200 {
201     GX_RECTANGLE size;
202     gx_utility_rectangle_define(&size, 0, 0, 63, 63);
203     gx_utility_rectangle_center(&size, &parent->gx_widget_size);
204 
205     GX_SPRITE *sprite = new GX_SPRITE;
206     gx_sprite_create(sprite, "sprite", parent,
207         GX_NULL, 0, GX_STYLE_ENABLED, 0, &size);
208     widget_info *info = InitWidgetInfo((GX_WIDGET *) sprite);
209     info->ewi.sprite.framelist = NULL;
210     info->ewi.sprite.frame_count = 0;
211     info->ewi.sprite.apply_to_all_frames = FALSE;
212     return info;
213 }
214 
GenerateFromInfo(GX_WIDGET * parent,widget_info * info)215 GX_WIDGET *sprite_service_provider::GenerateFromInfo(GX_WIDGET *parent, widget_info *info)
216 {
217     GX_SPRITE *sprite = new GX_SPRITE;
218     ULONG style = info->style;
219 
220     gx_sprite_create(sprite,
221         (CHAR *) info->app_name.GetString(),
222         parent,
223         info->ewi.sprite.framelist, info->ewi.sprite.frame_count,
224         style, 0, &info->size);
225 
226     if (info->pixelmap_id[NORMAL_PIXELMAP_INDEX])
227     {
228         gx_widget_draw_set(sprite, studio_sprite_draw);
229     }
230 
231     gx_widget_fill_color_set((GX_WIDGET *) sprite,
232         info->color_id[NORMAL_FILL_COLOR_INDEX], info->color_id[SELECTED_FILL_COLOR_INDEX], info->color_id[DISABLED_FILL_COLOR_INDEX]);
233     return ((GX_WIDGET *) sprite);
234 }
235 
SaveToProject(xml_writer & writer,studiox_project * project,int display,widget_info * info)236 void sprite_service_provider::SaveToProject(xml_writer &writer, studiox_project *project, int display, widget_info *info)
237 {
238     int index;
239     GX_SPRITE_FRAME *frame;
240 
241     widget_service_provider::SaveToProject(writer, project, display, info);
242     WritePixelmapId(writer, project, display, "pixelmap_id", info->pixelmap_id[NORMAL_PIXELMAP_INDEX]);
243     writer.WriteInt("framecount", info->ewi.sprite.frame_count);
244     writer.WriteBool("apply_to_all_frames", info->ewi.sprite.apply_to_all_frames);
245     writer.OpenTag("framelist");
246     frame = info->ewi.sprite.framelist;
247 
248     for (index = 0; index < info->ewi.sprite.frame_count; index++)
249     {
250         writer.OpenTag("sprite_frame");
251         WritePixelmapId(writer, project, display, "pixelmap", frame->gx_sprite_frame_pixelmap);
252         writer.WriteInt("x_offset", frame->gx_sprite_frame_x_offset);
253         writer.WriteInt("y_offset", frame->gx_sprite_frame_y_offset);
254         writer.WriteInt("delay", frame->gx_sprite_frame_delay);
255         writer.WriteInt("background", frame->gx_sprite_frame_background_operation);
256         writer.WriteUnsigned("alpha", frame->gx_sprite_frame_alpha);
257         writer.CloseTag("sprite_frame");
258         frame++;
259     }
260     writer.CloseTag("framelist");
261 }
262 
ReadFromProject(xml_reader & reader,studiox_project * project,int display,widget_info * info,ULONG valid_styles)263 void sprite_service_provider::ReadFromProject(xml_reader &reader, studiox_project *project, int display, widget_info *info, ULONG valid_styles)
264 {
265     int framecount;
266     int index;
267     int val;
268     unsigned long uval;
269     GX_SPRITE_FRAME *frame;
270 
271     valid_styles |= GX_STYLE_SPRITE_AUTO|GX_STYLE_SPRITE_LOOP;
272 
273     widget_service_provider::ReadFromProject(reader, project, display, info, valid_styles);
274 
275     info->pixelmap_id[NORMAL_PIXELMAP_INDEX] = ReadPixelmapId(reader, project, display, "pixelmap_id");
276 
277     reader.ReadInt("framecount", framecount);
278     info->ewi.sprite.frame_count = framecount;
279 
280     reader.ReadBool("apply_to_all_frames", info->ewi.sprite.apply_to_all_frames);
281 
282     if (framecount)
283     {
284         info->ewi.sprite.framelist = new GX_SPRITE_FRAME[framecount];
285         memset(info->ewi.sprite.framelist, 0, sizeof(GX_SPRITE_FRAME) * framecount);
286         frame = info->ewi.sprite.framelist;
287 
288         if (reader.EnterSection("framelist"))
289         {
290             for (index = 0; index < framecount; index++)
291             {
292                 if (reader.EnterSection("sprite_frame"))
293                 {
294                     frame->gx_sprite_frame_pixelmap = ReadPixelmapId(reader, project, display, "pixelmap");
295                     reader.ReadValue("x_offset", frame->gx_sprite_frame_x_offset);
296                     reader.ReadValue("y_offset", frame->gx_sprite_frame_y_offset);
297                     reader.ReadInt("delay", val);
298                     frame->gx_sprite_frame_delay = val;
299                     reader.ReadInt("background", val);
300                     frame->gx_sprite_frame_background_operation = val;
301                     reader.ReadUnsigned("alpha", uval);
302                     frame->gx_sprite_frame_alpha = (unsigned char) uval;
303                     reader.CloseSection(TRUE);
304                 }
305                 frame++;
306             }
307             reader.CloseSection(TRUE);
308         }
309     }
310 }
311 
UpdateSpriteFrameInfo(widget_info * info)312 void sprite_service_provider::UpdateSpriteFrameInfo(widget_info *info)
313 {
314     studiox_project* project = GetOpenProject();
315 
316     if (!project)
317     {
318         return;
319     }
320 
321     int display = project->GetDisplayIndex(info);
322 
323     if (display < 0)
324     {
325         return;
326     }
327 
328     CString name;
329 
330     project->GetResourceName(display, RES_TYPE_PIXELMAP, info->pixelmap_id[0], name);
331 
332     int active_theme = project->mDisplays[display].active_theme;
333 
334     res_info* rinfo = project->FindResource(display, active_theme, RES_TYPE_PIXELMAP, name);
335 
336     if (info->ewi.sprite.framelist)
337     {
338         delete info->ewi.sprite.framelist;
339         info->ewi.sprite.framelist = NULL;
340         info->ewi.sprite.frame_count = 0;
341     }
342 
343     if (rinfo && rinfo->map_list.GetCount())
344     {
345         info->ewi.sprite.frame_count = rinfo->GetPixelmapFrameCount();
346 
347         if (info->ewi.sprite.frame_count > MAX_SPRITE_FRAMES)
348         {
349             info->ewi.sprite.frame_count = MAX_SPRITE_FRAMES;
350         }
351 
352         info->ewi.sprite.framelist = new GX_SPRITE_FRAME[info->ewi.sprite.frame_count];
353         memset(info->ewi.sprite.framelist, 0, sizeof(GX_SPRITE_FRAME) * info->ewi.sprite.frame_count);
354 
355         GX_SPRITE_FRAME* frame;
356 
357         for (int frameindex = 0; frameindex < info->ewi.sprite.frame_count; frameindex++)
358         {
359             frame = &info->ewi.sprite.framelist[frameindex];
360 
361             frame->gx_sprite_frame_alpha = 255;
362             frame->gx_sprite_frame_delay = rinfo->GetPixelmapDelayTime(frameindex);
363             frame->gx_sprite_frame_delay /= GX_SYSTEM_TIMER_MS;
364             frame->gx_sprite_frame_pixelmap = info->pixelmap_id[0];
365         }
366     }
367 
368     GX_WIDGET* widget = info->widget;
369 
370     if (widget)
371     {
372         GX_SPRITE* sprite = (GX_SPRITE*)widget;
373         gx_sprite_frame_list_set(sprite, info->ewi.sprite.framelist, info->ewi.sprite.frame_count);
374     }
375 }
376 
AssignPixelmap(widget_info * info,int index,GX_RESOURCE_ID pixmap_id)377 void sprite_service_provider::AssignPixelmap(widget_info *info, int index,
378     GX_RESOURCE_ID pixmap_id)
379  {
380     if (info->pixelmap_id[index] != pixmap_id)
381     {
382         info->pixelmap_id[index] = pixmap_id;
383 
384         UpdateSpriteFrameInfo(info);
385     }
386     else
387     {
388         GX_WIDGET* widget = info->widget;
389 
390         if (widget)
391         {
392             GX_SPRITE* sprite = (GX_SPRITE*)widget;
393             gx_sprite_frame_list_set(sprite, info->ewi.sprite.framelist, info->ewi.sprite.frame_count);
394         }
395     }
396 }
397 
Autosize(widget_info * info)398 void sprite_service_provider::Autosize(widget_info *info)
399 {
400     GX_PIXELMAP *map = NULL;
401     GX_VALUE border_width;
402     int map_index;
403 
404     int max_map_width = -1;
405     int max_map_height = -1;
406     GX_SPRITE_FRAME *frame;
407 
408     studiox_project *project = GetOpenProject();
409     int display = project->GetDisplayIndex(info);
410     int active_theme = project->mDisplays[display].active_theme;
411 
412     if (display >= 0)
413     {
414         frame = info->ewi.sprite.framelist;
415 
416         for (map_index = 0; map_index < info->ewi.sprite.frame_count; map_index++)
417         {
418             if (frame->gx_sprite_frame_pixelmap)
419             {
420                 res_info *resource = project->FindResource(display, active_theme, RES_TYPE_PIXELMAP, frame->gx_sprite_frame_pixelmap);
421 
422                 if (resource)
423                 {
424                     map = resource->GetPixelmap();
425                     if (map)
426                     {
427                         if (map->gx_pixelmap_width > max_map_width)
428                         {
429                             max_map_width = map->gx_pixelmap_width;
430                         }
431                         if (map->gx_pixelmap_height > max_map_height)
432                         {
433                             max_map_height = map->gx_pixelmap_height;
434                         }
435                     }
436                 }
437             }
438         }
439     }
440 
441     if (max_map_height <= 0 || max_map_width <= 0)
442     {
443         return;
444     }
445 
446     // check to see if new size if any different
447 
448     GX_RECTANGLE newsize = info->widget->gx_widget_size;
449     gx_widget_border_width_get(info->widget, &border_width);
450     newsize.gx_rectangle_right = newsize.gx_rectangle_left + max_map_width + (border_width * 2) - 1;
451     newsize.gx_rectangle_bottom = newsize.gx_rectangle_top + max_map_height + (border_width * 2) - 1;
452 
453     if (!gx_utility_rectangle_compare(&newsize, &info->widget->gx_widget_size))
454     {
455         gx_widget_resize(info->widget, &newsize);
456         info->size = newsize;
457         GetPropsWin()->WidgetWasMoved();
458     }
459 }
460