Atrinik Client  4.0
painting.c
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
32 #include <global.h>
33 #include <toolkit/string.h>
34 #include <resources.h>
35 #include <toolkit/curl.h>
36 #include <toolkit/packet.h>
37 
41 typedef struct popup_painting {
42  char *resource_name;
43  char *name;
44  char *msg;
46  SDL_Surface *zoomed;
47  SDL_Rect coords;
48  int mx;
49  int my;
50  double zoom_x;
51  double zoom_y;
52  Uint32 last_redraw;
54 
63 static inline SDL_Surface *
65 {
66  HARD_ASSERT(data != NULL);
67 
68  if (data->zoomed != NULL) {
69  return data->zoomed;
70  }
71 
72  if (data->sprite != NULL) {
73  return data->sprite->bitmap;
74  }
75 
76  return NULL;
77 }
78 
85 static void
87 {
88  HARD_ASSERT(data != NULL);
89 
90  if (data->sprite != NULL) {
92  }
93 
94  if (data->zoomed != NULL) {
95  SDL_FreeSurface(data->zoomed);
96  }
97 
98  efree(data->resource_name);
99  efree(data->name);
100  efree(data->msg);
101  efree(data);
102 }
103 
105 static int
107 {
108  if (!popup->redraw) {
109  return 1;
110  }
111 
112  SDL_Rect box;
113  popup->redraw = 0;
114 
115  surface_show(popup->surface, 0, 0, NULL, texture_surface(popup->texture));
116 
117  popup_painting_t *painting_data = popup->custom_data;
118 
119  box.w = 700;
120  box.h = 26;
121  text_show_format(popup->surface,
122  FONT("logisoso", 18),
123  30,
124  25,
125  COLOR_HGOLD,
127  &box,
128  "[b]%s[/b]",
129  painting_data->name);
130 
131  box.w = 730;
132  box.h = 80;
133  text_show(popup->surface,
134  FONT_SANS14,
135  painting_data->msg,
136  35,
137  590,
138  COLOR_WHITE,
140  &box);
141 
142  resource_t *resource = resources_find(painting_data->resource_name);
143  if (resource == NULL) {
144  return 1;
145  }
146 
147  box.w = painting_data->coords.w;
148  box.h = painting_data->coords.h;
149 
150  if (!resources_is_ready(resource)) {
151  if (resource->request == NULL) {
152  text_show(popup->surface,
153  FONT_SERIF16,
154  "Painting download failed.",
155  25,
156  60,
157  COLOR_WHITE,
159  &box);
160  return 1;
161  }
162 
163  char buf[MAX_BUF];
164  curl_request_speedinfo(resource->request, VS(buf));
165  text_show_format(popup->surface,
166  FONT_SERIF16,
167  25,
168  60,
169  COLOR_WHITE,
171  &box,
172  "Downloading data, please wait...\n%s",
173  buf);
174 
175  return 1;
176  }
177 
178  if (painting_data->sprite == NULL) {
179  char path[HUGE_BUF];
180  snprintf(VS(path), "resources/%s", resource->digest);
181  painting_data->sprite = sprite_tryload_file(path, 0, NULL);
182  if (painting_data->sprite == NULL) {
183  return 1;
184  }
185 
186  if (painting_data->sprite->bitmap->w != painting_data->coords.w ||
187  painting_data->sprite->bitmap->h != painting_data->coords.h) {
188  painting_data->zoom_x = (double) painting_data->coords.w /
189  painting_data->sprite->bitmap->w;
190  painting_data->zoom_y = (double) painting_data->coords.h /
191  painting_data->sprite->bitmap->h;
192  }
193  }
194 
195  if (painting_data->zoomed == NULL &&
196  !DBL_EQUAL(painting_data->zoom_x, 1.0) &&
197  !DBL_EQUAL(painting_data->zoom_y, 1.0)) {
199  painting_data->zoomed = rotozoomSurfaceXY(painting_data->sprite->bitmap,
200  0,
201  painting_data->zoom_x,
202  painting_data->zoom_y,
203  smooth);
205  &painting_data->coords);
206  }
207 
208  surface_show(popup->surface,
209  25,
210  60,
211  &painting_data->coords,
212  popup_painting_data_surface(painting_data));
213 
214  return 1;
215 }
216 
218 static int
220 {
221  popup_painting_t *painting_data = popup->custom_data;
222 
223  resource_t *resource = resources_find(painting_data->resource_name);
224  if (resource == NULL) {
225  return 1;
226  }
227 
228  if (!resources_is_ready(resource)) {
229  if (SDL_GetTicks() - painting_data->last_redraw > 200) {
230  painting_data->last_redraw = SDL_GetTicks();
231  popup->redraw = 1;
232  }
233  } else if (painting_data->sprite == NULL) {
234  popup->redraw = 1;
235  }
236 
237  return 1;
238 }
239 
241 static int
242 popup_event_func (popup_struct *popup, SDL_Event *event)
243 {
244  popup_painting_t *painting_data = popup->custom_data;
245 
246  if (event->type == SDL_MOUSEBUTTONDOWN) {
247  if (event->button.button == SDL_BUTTON_LEFT) {
248  painting_data->mx = event->motion.x;
249  painting_data->my = event->motion.y;
250  } else if (event->button.button == SDL_BUTTON_WHEELUP ||
251  event->button.button == SDL_BUTTON_WHEELDOWN) {
252  if (painting_data->zoomed != NULL) {
253  SDL_FreeSurface(painting_data->zoomed);
254  painting_data->zoomed = NULL;
255  }
256 
257  double zoom = 0.1;
258  if (event->button.button == SDL_BUTTON_WHEELDOWN) {
259  zoom = -zoom;
260  }
261 
262  painting_data->zoom_x += zoom;
263  painting_data->zoom_x = MIN(5.0, MAX(0.1, painting_data->zoom_x));
264  painting_data->zoom_y += zoom;
265  painting_data->zoom_y = MIN(5.0, MAX(0.1, painting_data->zoom_y));
266  popup->redraw = 1;
267  }
268  } else if (event->type == SDL_MOUSEBUTTONUP) {
269  if (event->button.button == SDL_BUTTON_LEFT) {
270  painting_data->mx = painting_data->my = -1;
271  }
272  } else if (event->type == SDL_MOUSEMOTION &&
273  painting_data->mx != -1 &&
274  painting_data->my != -1) {
275  painting_data->coords.x += painting_data->mx - event->motion.x;
276  painting_data->coords.y += painting_data->my - event->motion.y;
277  painting_data->mx = event->motion.x;
278  painting_data->my = event->motion.y;
280  &painting_data->coords);
281  popup->redraw = 1;
282  }
283 
284  return -1;
285 }
286 
288 static int
290 {
291  popup_painting_t *painting_data = popup->custom_data;
292  popup_painting_data_free(painting_data);
293  popup->custom_data = NULL;
294  return 1;
295 }
296 
298 void
299 socket_command_painting (uint8_t *data, size_t len, size_t pos)
300 {
301  popup_painting_t *painting_data = ecalloc(1, sizeof(*painting_data));
302 
303  painting_data->coords.w = 750;
304  painting_data->coords.h = 500;
305  painting_data->mx = painting_data->my = -1;
306  painting_data->zoom_x = painting_data->zoom_y = 1.0;
307 
308  StringBuffer *sb = stringbuffer_new();
309  packet_to_stringbuffer(data, len, &pos, sb);
310  painting_data->resource_name = stringbuffer_finish(sb);
311 
312  sb = stringbuffer_new();
313  packet_to_stringbuffer(data, len, &pos, sb);
314  painting_data->name = stringbuffer_finish(sb);
315 
316  sb = stringbuffer_new();
317  packet_to_stringbuffer(data, len, &pos, sb);
318  painting_data->msg = stringbuffer_finish(sb);
319 
320  if (string_isempty(painting_data->resource_name) ||
321  string_isempty(painting_data->name)) {
322  LOG(PACKET, "Empty resource name or painting name");
323  popup_painting_data_free(painting_data);
324  return;
325  }
326 
327  popup_struct *popup = popup_create(texture_get(TEXTURE_TYPE_CLIENT,
328  "painting"));
329  popup->custom_data = painting_data;
330  popup->draw_func = popup_draw_func;
332  popup->event_func = popup_event_func;
334  popup->disable_texture_drawing = 1;
335  popup->button_left.button.texture = NULL;
336  popup->button_right.y = 25;
337  popup->button_right.x = popup->texture->surface->w - 25 -
338  popup->button_right.button.texture->surface->w;
339 }
#define FONT(font_name, font_size)
Definition: text.h:63
sprite_struct * sprite
Sprite of the painting.
Definition: painting.c:45
Uint32 last_redraw
Last redraw time.
Definition: painting.c:52
#define TEXT_WORD_WRAP
Definition: text.h:226
int(* event_func)(struct popup_struct *popup, SDL_Event *event)
Definition: popup.h:148
int(* draw_func)(struct popup_struct *popup)
Definition: popup.h:127
static void popup_painting_data_free(popup_painting_t *data)
Definition: painting.c:86
static int popup_draw_func(popup_struct *popup)
Definition: painting.c:106
SDL_Surface * bitmap
Definition: sprite.h:96
int(* draw_post_func)(struct popup_struct *popup)
Definition: popup.h:137
SDL_Surface * texture_surface(texture_struct *texture)
Definition: texture.c:303
int(* destroy_callback_func)(struct popup_struct *popup)
Definition: popup.h:159
int y
Definition: popup.h:41
void * custom_data
Definition: popup.h:78
void text_show(SDL_Surface *surface, font_struct *font, const char *text, int x, int y, const char *color_notation, uint64_t flags, SDL_Rect *box)
Definition: text.c:1983
button_struct button
Definition: popup.h:47
#define COLOR_HGOLD
Definition: text.h:319
int mx
Mouse X cache.
Definition: painting.c:48
texture_struct * texture_get(texture_type_t type, const char *name)
Definition: texture.c:279
#define TEXT_MARKUP
Definition: text.h:224
static int popup_draw_post_func(popup_struct *popup)
Definition: painting.c:219
#define TEXT_ALIGN_CENTER
Definition: text.h:230
SDL_Rect coords
Painting coords.
Definition: painting.c:47
static int popup_destroy_callback(popup_struct *popup)
Definition: painting.c:289
uint8_t redraw
Definition: popup.h:114
sprite_struct * sprite_tryload_file(char *fname, uint32_t flag, SDL_RWops *rwop)
Definition: sprite.c:110
int64_t setting_get_int(int cat, int setting)
Definition: settings.c:414
SDL_Surface * zoomed
Zoomed copy.
Definition: painting.c:46
double zoom_x
X zoom.
Definition: painting.c:50
char * resource_name
Resource name identifier.
Definition: painting.c:42
bool resources_is_ready(resource_t *resource)
Definition: resources.c:161
static int popup_event_func(popup_struct *popup, SDL_Event *event)
Definition: painting.c:242
void socket_command_painting(uint8_t *data, size_t len, size_t pos)
Definition: painting.c:299
#define TEXT_OUTLINE
Definition: text.h:255
texture_struct * texture
Definition: button.h:61
char * msg
Message associated with the painting.
Definition: painting.c:44
popup_button button_left
Definition: popup.h:93
int x
Definition: popup.h:38
void surface_show(SDL_Surface *surface, int x, int y, SDL_Rect *srcrect, SDL_Surface *src)
Definition: sprite.c:761
popup_button button_right
Definition: popup.h:96
double zoom_y
Y zoom.
Definition: painting.c:51
SDL_Surface * surface
Definition: popup.h:65
static SDL_Surface * popup_painting_data_surface(popup_painting_t *data)
Definition: painting.c:64
void text_show_format(SDL_Surface *surface, font_struct *font, int x, int y, const char *color_notation, uint64_t flags, SDL_Rect *box, const char *format,...)
Definition: text.c:2289
#define TEXT_VALIGN_CENTER
Definition: text.h:246
char * name
Title of the painting.
Definition: painting.c:43
void surface_pan(SDL_Surface *surface, SDL_Rect *box)
Definition: sprite.c:1151
struct popup_painting popup_painting_t
texture_struct * texture
Definition: popup.h:70
uint8_t disable_texture_drawing
Definition: popup.h:75
#define COLOR_WHITE
Definition: text.h:289
void sprite_free_sprite(sprite_struct *sprite)
Definition: sprite.c:164
int my
Mouse Y cache.
Definition: painting.c:49