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