Mercurial > MadButterfly
annotate src/mbaf/animated_menu.c @ 842:76fe4afce640
The inkscape:bbox is defined as the global coordinate system. However, the center.x and center.y must be the coordiante system of the parent group of the SVG entity. Therefore, we need to do coordinate transformation from the global coordination system to the local coordination system.
author | wycc |
---|---|
date | Sat, 18 Sep 2010 21:23:51 +0800 |
parents | 586e50f82c1f |
children | 152bc503dc99 |
rev | line source |
---|---|
822
586e50f82c1f
Unify coding style tag for emacs and vim.
Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
parents:
757
diff
changeset
|
1 // -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*- |
586e50f82c1f
Unify coding style tag for emacs and vim.
Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
parents:
757
diff
changeset
|
2 // vim: sw=4:ts=8:sts=4 |
318 | 3 #include <stdio.h> |
4 #include <mb.h> | |
5 #include <string.h> | |
325 | 6 //#include "menu.h" |
456
26c302b47de1
Change name of header files.
Thinker K.F. Li <thinker@branda.to>
parents:
455
diff
changeset
|
7 #include "mb_af.h" |
26c302b47de1
Change name of header files.
Thinker K.F. Li <thinker@branda.to>
parents:
455
diff
changeset
|
8 #include "mb_ani_menu.h" |
344 | 9 static void mb_animated_menu_update(mb_animated_menu_t *m); |
318 | 10 static void set_text(coord_t *g, char *text) |
11 { | |
12 geo_t *geo; | |
13 shape_t *shape; | |
14 | |
15 FOR_COORD_MEMBERS(g, geo) { | |
16 shape = geo_get_shape(geo); | |
17 if(shape->obj.obj_type == MBO_TEXT) { | |
18 sh_text_set_text(shape, text); | |
19 } | |
20 } | |
21 } | |
22 | |
23 static void mb_animated_menu_fillMenuContent(mb_animated_menu_t *m) | |
24 { | |
25 int i; | |
26 coord_t *textgroup; | |
27 coord_t *group; | |
28 coord_t *lightbar; | |
29 | |
30 // fill new item | |
31 for(i=0;i<8;i++) { | |
32 group = (coord_t *) m->objects[m->items[i]]; | |
33 if (i < m->max) | |
34 set_text(group, m->titles[m->top+i]); | |
35 else | |
36 set_text(group, ""); | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
37 rdman_coord_changed(MBAF_RDMAN(m->app),group); |
318 | 38 } |
39 | |
40 | |
41 textgroup = (coord_t *) m->objects[m->items[i]]; | |
42 coord_hide(textgroup); | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
43 rdman_coord_changed(MBAF_RDMAN(m->app),textgroup); |
318 | 44 |
45 lightbar = (coord_t *) m->lightbar; | |
46 group = (coord_t *) m->objects[m->cur]; | |
47 coord_y(lightbar) = coord_y(group); | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
48 rdman_coord_changed(MBAF_RDMAN(m->app),lightbar); |
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
49 rdman_redraw_changed(MBAF_RDMAN(m->app)); |
318 | 50 } |
51 | |
52 static void mb_animated_menu_complete(event_t *ev,void *arg) | |
53 { | |
54 mb_animated_menu_t *m = (mb_animated_menu_t *) arg; | |
55 | |
56 m->ready++; | |
57 } | |
58 | |
59 static void mb_animated_menu_fillMenuContentUp(mb_animated_menu_t *m) | |
60 { | |
61 int i; | |
62 coord_t *textgroup; | |
63 coord_t *group; | |
64 coord_t *lightbar; | |
65 int tmp; | |
66 mb_timeval_t start, playing, now; | |
67 mb_progm_t *progm; | |
68 mb_word_t *word; | |
69 | |
70 | |
71 // fill new item | |
72 group = (coord_t *) m->objects[m->items[8]]; | |
73 set_text(group, m->titles[m->top]); | |
74 | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
75 m->progm = progm = mb_progm_new(2, MBAF_RDMAN(m->app)); |
318 | 76 MB_TIMEVAL_SET(&start, 0, 0); |
77 MB_TIMEVAL_SET(&playing, 0, m->speed); | |
78 word = mb_progm_next_word(progm, &start, &playing); | |
79 get_now(&now); | |
80 | |
81 for(i=0;i<7;i++) { | |
82 //shift to the next item | |
83 textgroup = (coord_t *) m->objects[m->items[i]]; | |
84 mb_shift_new(0,m->menus_y[i+1]-coord_y(textgroup), textgroup,word); | |
85 } | |
86 // fade out the item[7] | |
87 textgroup = (coord_t *) m->objects[m->items[7]]; | |
88 mb_shift_new(0,100, textgroup,word); | |
89 | |
90 // fade in the item[8] | |
91 textgroup = (coord_t *) m->objects[m->items[8]]; | |
92 group = (coord_t *) m->objects[m->items[0]]; | |
93 coord_y(textgroup) = m->menus_y[0]-100; | |
94 coord_show(textgroup); | |
95 mb_shift_new(0,100, textgroup,word); | |
96 | |
97 lightbar = (coord_t *) m->lightbar; | |
98 mb_shift_new(0,m->menus_y[m->cur]-coord_y(lightbar),lightbar,word); | |
822
586e50f82c1f
Unify coding style tag for emacs and vim.
Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
parents:
757
diff
changeset
|
99 |
318 | 100 MB_TIMEVAL_SET(&start, 0, m->speed); |
101 MB_TIMEVAL_SET(&playing, 0, 0); | |
102 word = mb_progm_next_word(progm, &start, &playing); | |
103 textgroup = (coord_t *) m->objects[m->items[7]]; | |
104 mb_visibility_new(VIS_HIDDEN, textgroup,word); | |
105 | |
106 mb_progm_free_completed(progm); | |
107 m->ready--; | |
108 subject_add_observer(mb_progm_get_complete(progm), mb_animated_menu_complete,m); | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
109 mb_progm_start(progm, X_MB_tman(MBAF_RDMAN(m->app)->rt), &now); |
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
110 rdman_redraw_changed(MBAF_RDMAN(m->app)); |
318 | 111 tmp = m->items[8]; |
112 for(i=8;i>0;i--) { | |
113 m->items[i] = m->items[i-1]; | |
114 } | |
115 m->items[0] = tmp; | |
116 } | |
117 | |
118 | |
119 static void mb_animated_menu_fillMenuContentDown(mb_animated_menu_t *m) | |
120 { | |
121 int i; | |
122 int tmp; | |
123 mb_timeval_t start, playing, now; | |
124 mb_progm_t *progm; | |
125 mb_word_t *word; | |
126 | |
127 | |
128 // fill new item | |
129 set_text((coord_t *)m->objects[m->items[8]], m->titles[m->top+7]); | |
130 | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
131 m->progm = progm = mb_progm_new(2, MBAF_RDMAN(m->app)); |
318 | 132 MB_TIMEVAL_SET(&start, 0, 0); |
133 MB_TIMEVAL_SET(&playing, 0, m->speed); | |
134 word = mb_progm_next_word(progm, &start, &playing); | |
135 get_now(&now); | |
136 | |
137 for(i=1;i<8;i++) { | |
138 //shift to the next item | |
139 mb_shift_new(0,m->menus_y[i-1]-coord_y((coord_t *)m->objects[m->items[i]]), (coord_t *) m->objects[m->items[i]],word); | |
140 } | |
141 // fade out the item[0] | |
142 mb_shift_new(0,-100, (coord_t *)m->objects[m->items[0]],word); | |
143 | |
144 // fade in the item[8] | |
145 coord_y((coord_t *)m->objects[m->items[8]]) = m->menus_y[7]+100; | |
146 coord_show(((coord_t *)(m->objects[m->items[8]]))); | |
147 mb_shift_new(0,-100, (coord_t *)m->objects[m->items[8]],word); | |
148 | |
149 mb_shift_new(0,m->menus_y[m->cur]-coord_y((coord_t *)m->lightbar),((coord_t *)(m->lightbar)),word); | |
150 | |
151 MB_TIMEVAL_SET(&start, 0, m->speed); | |
152 MB_TIMEVAL_SET(&playing, 0, 0); | |
153 word = mb_progm_next_word(progm, &start, &playing); | |
154 mb_visibility_new(VIS_VISIBLE, (coord_t *) m->objects[m->items[0]],word); | |
155 | |
156 mb_progm_free_completed(progm); | |
157 m->ready--; | |
158 subject_add_observer(mb_progm_get_complete(progm), mb_animated_menu_complete,m); | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
159 mb_progm_start(progm, X_MB_tman(MBAF_RDMAN(m->app)->rt), &now); |
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
160 rdman_redraw_changed(MBAF_RDMAN(m->app)); |
318 | 161 tmp = m->items[0]; |
162 for(i=0;i<8;i++) { | |
163 m->items[i] = m->items[i+1]; | |
164 } | |
165 m->items[8] = tmp; | |
166 } | |
167 | |
168 void mb_animated_menu_moveLightBar(mb_animated_menu_t *m) | |
169 { | |
170 mb_timeval_t start, playing, now; | |
171 mb_progm_t *progm; | |
172 mb_word_t *word; | |
173 coord_t *lightbar; | |
174 | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
175 m->progm = progm = mb_progm_new(1, MBAF_RDMAN(m->app)); |
318 | 176 MB_TIMEVAL_SET(&start, 0, 0); |
177 MB_TIMEVAL_SET(&playing, 0, m->speed); | |
178 word = mb_progm_next_word(progm, &start, &playing); | |
179 get_now(&now); | |
180 | |
181 lightbar = (coord_t *) m->lightbar; | |
182 mb_shift_new(0,m->menus_y[m->cur]-coord_y(lightbar),lightbar,word); | |
183 mb_progm_free_completed(progm); | |
184 m->ready--; | |
185 subject_add_observer(mb_progm_get_complete(progm), mb_animated_menu_complete,m); | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
186 mb_progm_start(progm, X_MB_tman(MBAF_RDMAN(m->app)->rt), &now); |
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
187 rdman_redraw_changed(MBAF_RDMAN(m->app)); |
318 | 188 } |
189 | |
190 static void mb_animated_menu_up(mb_animated_menu_t *m) | |
191 { | |
192 if (m->cur > 5) { | |
193 m->cur--; | |
194 mb_animated_menu_moveLightBar(m); | |
344 | 195 mb_animated_menu_update(m); |
318 | 196 } else { |
197 if (m->top > 0) { | |
198 m->top--; | |
199 mb_animated_menu_fillMenuContentUp(m); | |
344 | 200 mb_animated_menu_update(m); |
318 | 201 } else { |
822
586e50f82c1f
Unify coding style tag for emacs and vim.
Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
parents:
757
diff
changeset
|
202 if (m->cur == 0) |
318 | 203 return; |
204 m->cur--; | |
205 mb_animated_menu_moveLightBar(m); | |
344 | 206 mb_animated_menu_update(m); |
318 | 207 } |
208 } | |
209 } | |
210 static void mb_animated_menu_down(mb_animated_menu_t *m) | |
211 { | |
212 | |
213 if (m->cur < 5) { | |
214 if (m->top+m->cur <= m->max) { | |
215 m->cur++; | |
216 mb_animated_menu_moveLightBar(m); | |
344 | 217 mb_animated_menu_update(m); |
318 | 218 } |
219 } else { | |
220 if ((m->top+8) < m->max-1) { | |
221 m->top++; | |
222 mb_animated_menu_fillMenuContentDown(m); | |
344 | 223 mb_animated_menu_update(m); |
318 | 224 } else { |
225 if (m->cur+m->top < m->max-1) { | |
226 m->cur++; | |
227 mb_animated_menu_moveLightBar(m); | |
344 | 228 mb_animated_menu_update(m); |
318 | 229 } else |
230 return; | |
231 } | |
232 } | |
233 } | |
234 | |
344 | 235 void mb_animated_menu_set_update_callback(mb_animated_menu_t *m, void (*f)(mb_animated_menu_t *m, int sel)) |
236 { | |
237 m->update_callback = f; | |
238 } | |
318 | 239 void mb_animated_menu_set_callback(mb_animated_menu_t *m, void (*f)(mb_animated_menu_t *m, int sel)) |
240 { | |
241 m->callback = f; | |
242 } | |
344 | 243 static void mb_animated_menu_update(mb_animated_menu_t *m) |
244 { | |
245 if (m->update_callback) | |
246 m->update_callback(m,m->top+m->cur); | |
247 | |
248 } | |
318 | 249 static void mb_animated_menu_select(mb_animated_menu_t *m) |
250 { | |
251 if (m->callback) | |
252 m->callback(m,m->top+m->cur); | |
253 } | |
254 | |
332
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
255 // Send the pending key in the animation progm complete callback |
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
256 static void mb_animated_menu_keyHandler(event_t *ev, void *arg); |
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
257 static void mb_animated_menu_send_pending_key(event_t *ev,void *arg) |
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
258 { |
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
259 mb_animated_menu_t *m = (mb_animated_menu_t *) arg; |
455
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
260 X_kb_event_t *xkey; |
822
586e50f82c1f
Unify coding style tag for emacs and vim.
Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
parents:
757
diff
changeset
|
261 |
455
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
262 xkey = &m->pending_keys[m->pending_pos]; |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
263 m->pending_pos = (m->pending_pos + 1) & 0xf; |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
264 mb_animated_menu_keyHandler((event_t *) xkey, m); |
332
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
265 } |
318 | 266 static void mb_animated_menu_keyHandler(event_t *ev, void *arg) |
267 { | |
268 mb_animated_menu_t *m = (mb_animated_menu_t *) arg; | |
269 X_kb_event_t *xkey = (X_kb_event_t *)ev; | |
270 if(xkey->event.type != EVT_KB_PRESS) { | |
271 return; | |
272 } | |
332
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
273 if (m->ready<=0) { |
455
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
274 m->pending_keys[m->pending_last++] = *xkey; |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
275 m->pending_last &= 0xf; |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
276 if(m->pending_last == m->pending_pos) |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
277 m->pending_last = (m->pending_last - 1) & 0xf; |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
278 else |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
279 subject_add_observer(mb_progm_get_complete(m->progm), |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
280 mb_animated_menu_send_pending_key, |
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
281 m); |
332
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
282 return; |
f90c60967a9c
Add mb_progm_finish to terminate the current animation and put all objects in the final position.
wycc
parents:
329
diff
changeset
|
283 } |
318 | 284 switch(xkey->sym) { |
285 case 0xff51: /* left */ | |
286 break; | |
287 | |
288 case 0xff52: /* up */ | |
289 mb_animated_menu_up(m); | |
290 break; | |
291 | |
292 case 0xff53: /* right */ | |
293 break; | |
294 | |
295 case 0xff54: /* down */ | |
296 mb_animated_menu_down(m); | |
297 break; | |
298 | |
299 case 0xff0d: /* enter */ | |
300 mb_animated_menu_select(m); | |
301 break; | |
302 default: | |
303 return; | |
304 } | |
305 } | |
306 | |
822
586e50f82c1f
Unify coding style tag for emacs and vim.
Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
parents:
757
diff
changeset
|
307 /** \brief Create an instace of animated menu. |
318 | 308 * |
822
586e50f82c1f
Unify coding style tag for emacs and vim.
Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
parents:
757
diff
changeset
|
309 * The objectnames is used to extract symbols from the SVG file. |
318 | 310 * ${objectnames}0 - ${objectnames}8 is the text object. |
311 * ${objectnames}_lightbar is the lightbar. | |
312 * | |
313 */ | |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
314 mb_animated_menu_t *mb_animated_menu_new(mbaf_t *app,mb_sprite_t *sp,char *objnames,char *menus[]) |
318 | 315 { |
316 mb_animated_menu_t *m; | |
757
f43224bf3524
Remove unused variables and refactor to X_MB_init_with_win
Thinker K.F. Li <thinker@codemud.net>
parents:
456
diff
changeset
|
317 int i; |
318 | 318 char name[255]; |
319 mb_obj_t *l; | |
320 int ii; | |
321 | |
322 if (menus == NULL) | |
323 i=0; | |
324 else | |
325 for(i=0;menus[i];i++); | |
326 ii=9; | |
822
586e50f82c1f
Unify coding style tag for emacs and vim.
Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
parents:
757
diff
changeset
|
327 |
318 | 328 m = (mb_animated_menu_t *) malloc(sizeof(mb_animated_menu_t)); |
329 m->items = (int *) malloc(sizeof(int)*ii*2+sizeof(mb_obj_t *)*ii); | |
330 m->app = app; | |
331 m->sprite = sp; | |
332 m->top = 0; | |
333 m->cur = 0; | |
334 m->ready = 1; | |
335 m->max = i; | |
336 m->menus_y = (int *) (m->items+ii); | |
337 m->objects = (mb_obj_t **) (m->menus_y+ii); | |
338 m->callback = NULL; | |
344 | 339 m->update_callback = NULL; |
318 | 340 m->speed = 300000; |
341 for(i=0;i<9;i++) { | |
342 m->items[i] = i; | |
343 snprintf(name,sizeof(name),"%s%d", objnames, i+1); | |
344 l = MB_SPRITE_GET_OBJ(sp,name); | |
345 if (l == NULL) { | |
346 fprintf(stderr,"Can not find symbol %s\n",name); | |
347 } | |
348 m->objects[i] = (mb_obj_t *) l; | |
349 m->menus_y[i] = coord_y((coord_t*)l); | |
350 } | |
351 m->titles = menus; | |
352 snprintf(name,sizeof(name), "%s_lightbar", objnames); | |
353 m->lightbar = (mb_obj_t *) MB_SPRITE_GET_OBJ(sp,name); | |
354 if (m->lightbar==NULL) | |
355 fprintf(stderr,"Can not find object %s\n",name); | |
455
58b6337fb3b2
Fix bugs of pending keys of animated menu.
Thinker K.F. Li <thinker@branda.to>
parents:
454
diff
changeset
|
356 m->pending_pos = m->pending_last = 0; |
318 | 357 mb_animated_menu_fillMenuContent(m); |
454
9b8dda201ccb
Make naming convention consistent with MadButterfly.
Thinker K.F. Li <thinker@branda.to>
parents:
368
diff
changeset
|
358 subject_add_observer(MBAF_KB_SUBJECT(app), mb_animated_menu_keyHandler,m); |
318 | 359 return m; |
360 } | |
361 | |
362 void mb_animated_menu_set_titles(mb_animated_menu_t *m, char *menus[]) | |
363 { | |
364 int i; | |
365 for(i=0;menus[i];i++); | |
366 | |
367 m->max = i; | |
368 m->top = 0; | |
369 m->cur = 0; | |
370 m->titles = menus; | |
371 mb_animated_menu_fillMenuContent(m); | |
329
740844ee48c4
Update position of light-bar after update menu item
Thinker K.F. Li <thinker@branda.to>
parents:
328
diff
changeset
|
372 mb_animated_menu_moveLightBar(m); |
318 | 373 } |
374 | |
375 | |
376 void mb_animated_menu_set_speed(mb_animated_menu_t *m,int speed) | |
377 { | |
378 m->speed = speed*1000; | |
379 } | |
380 | |
381 int mb_animated_menu_get_speed(mb_animated_menu_t *m) | |
382 { | |
383 return m->speed/1000; | |
384 } |