1 /*
2 * Abuse - dark 2D side-scrolling platform game
3 * Copyright (c) 1995 Crack dot Com
4 * Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
5 *
6 * This software was released into the Public Domain. As with most public
7 * domain software, no warranty is made or implied by Crack dot Com, by
8 * Jonathan Clark, or by Sam Hocevar.
9 */
10
11 #if defined HAVE_CONFIG_H
12 # include "config.h"
13 #endif
14
15 #include <ctype.h>
16 #include <string.h>
17
18 #include "common.h"
19
20 #include "dev.h"
21 #include "input.h"
22 #include "objects.h"
23 #include "id.h"
24 #include "lisp.h"
25 #include "light.h"
26 #include "devsel.h"
27 #include "dprint.h"
28 #include "property.h"
29 #include "pmenu.h"
30 #include "filesel.h"
31 #include "tools.h"
32 #include "game.h"
33 #include "pcxread.h"
34 #include "lisp_gc.h"
35 #include "demo.h"
36 #include "profile.h"
37 #include "sbar.h"
38 #include "compiled.h"
39 #include "chat.h"
40
41 #define make_above_tile(x) ((x)|0x4000)
42 char backw_on=0,forew_on=0,show_menu_on=0,ledit_on=0,pmenu_on=0,omenu_on=0,commandw_on=0,tbw_on=0,
43 searchw_on=0,small_render_on=0,interpolate_draw=0,disable_autolight=0,fps_on=0,profile_on=0,
44 show_names=0,fg_reversed=0,
45 raise_all;
46
symbol_str(char const * name)47 char const *symbol_str(char const *name)
48 {
49 LSymbol *sym = LSymbol::FindOrCreate(name);
50 if (sym->GetValue() && item_type(sym->GetValue())==L_STRING)
51 return lstring_value(sym->GetValue());
52
53
54 // maybe english.lsp was not loaded yet, let's try to do that
55 int sp=current_space;
56 current_space=PERM_SPACE;
57
58
59 char prog[50];
60 char const *cs=prog;
61 strcpy(prog,"(setq section 'game_section)\n");
62 LObject::Compile(cs)->Eval();
63 strcpy(prog,"(load \"lisp/english.lsp\")\n");
64 cs=prog;
65 if (!LObject::Compile(cs)->Eval())
66 {
67 printf("unable to open file '%s'\n",lsf);
68 exit(0);
69 }
70 current_space=sp;
71
72
73 // check again to see if the symbol is there
74 sym = LSymbol::FindOrCreate(name);
75 if (sym->GetValue() && item_type(sym->GetValue())==L_STRING)
76 return lstring_value(sym->GetValue());
77
78
79 // check to see if there is a missing symbol definition
80 sym = LSymbol::FindOrCreate("missing_sym");
81 if (sym->GetValue() && item_type(sym->GetValue())==L_STRING)
82 return lstring_value(sym->GetValue());
83
84 // last resort, return english string
85 return "Missing language symbol!";
86 }
87
88
89 static game_object *copy_object=NULL;
90
91 pmenu *dev_menu=NULL;
92 Jwindow *mess_win=NULL,*warn_win=NULL;
93
94 game_object *edit_object;
95 dev_controll *dev_cont=NULL;
96 image *small_render=NULL;
97
98 int scale_mult,scale_div,dlastx,dlasty;
99 int last_created_type=-1;
100 char level_file[100]="levels/level00.spe";
101
102
103 class cached_image : public visual_object
104 {
105 int id;
106 public :
cached_image(int Id)107 cached_image(int Id) { id=Id; }
draw(image * screen,int x,int y,Filter * f)108 virtual void draw(image *screen, int x, int y, Filter *f)
109 {
110 if (f)
111 f->PutImage(screen, cache.img(id), vec2i(x, y));
112 else
113 cache.img(id)->put_image(screen,x,y);
114 }
width()115 virtual int width() { return cache.img(id)->Size().x; }
height()116 virtual int height() { return cache.img(id)->Size().y; }
117 } ;
118
119
120 #define DEV_MODES 3
121 cached_image *dev_mode_pict[DEV_MODES];
122
123 int dev_del,dev_move, dev_char_left,dev_char_right,dev_back,dev_front,dev_ok,dev_copy,dev_brain,
124 dev_lights,dev_objects,dev_ai,dev_mode_icon[DEV_MODES],
125 dev_forward,dev_backward;
126
127 char const *dev_mode_icon_names[DEV_MODES] =
128 {
129 "pixel_mode", "pick_mode", /* "fill_mode",
130 "line_mode","rect_mode","bar_mode", */ "area_select"
131 };
132
133 int dev_mode_ids[DEV_MODES]={ ID_DMODE_DRAW,ID_DMODE_PICK, ID_DMODE_AREA};
134
135 int edit_mode=ID_DMODE_DRAW;
136
137
138 dev_term *dev_console=NULL;
139 int ldef_width=0,ldef_height=0,ldef_r1=1,ldef_r2=100;
140
141 void make_screen_size(int w, int h);
142
143 class amb_cont : public scroller
144 {
145 public :
amb_cont(int X,int Y,ifield * Next)146 amb_cont(int X, int Y, ifield *Next) : scroller(X,Y,ID_NULL,100,wm->font()->height()+2,0,64,Next)
147 { if (player_list) sx=player_list->ambient; }
scroll_event(int newx,image * screen)148 virtual void scroll_event(int newx, image *screen)
149 {
150 screen->bar(x,y,x+l-1,y+h-1,wm->dark_color());
151 char st[100];
152 sprintf(st,"%d",newx);
153 wm->font()->put_string(screen,x+30,y+1,st,wm->bright_color());
154 if (player_list)
155 player_list->ambient=newx;
156 the_game->need_refresh();
157 }
158 } ;
159
160
confirm_quit()161 int confirm_quit()
162 {
163 Jwindow *quitw;
164 image *ok_image, *cancel_image;
165
166 ok_image = cache.img(cache.reg("art/frame.spe", "dev_ok",
167 SPEC_IMAGE, 1))->copy();
168 cancel_image = cache.img(cache.reg("art/frame.spe", "cancel",
169 SPEC_IMAGE, 1))->copy();
170
171 quitw = wm->new_window(xres / 2 + 40, yres / 2, 80, -1,
172 new button(10, wm->font()->height() + 4, ID_QUIT_OK, ok_image,
173 new button(38, wm->font()->height() + 4, ID_CANCEL, cancel_image,
174 new info_field(2, 2, ID_NULL, symbol_str("sure?"), NULL))),
175 symbol_str("quit_title"));
176
177 wm->grab_focus(quitw);
178 int fin = 0, quit = 0;
179
180 while(!fin)
181 {
182 wm->flush_screen();
183
184 event ev;
185 wm->get_event(ev);
186 if(ev.type == EV_MESSAGE && ev.message.id == ID_QUIT_OK)
187 fin = quit = 1;
188 else if(ev.type == EV_MESSAGE && ev.message.id == ID_CANCEL)
189 fin = 1;
190 else if(ev.type == EV_KEY
191 && toupper(ev.key) == toupper(*symbol_str("YES")))
192 fin = quit = 1;
193 else if(ev.type == EV_KEY
194 && toupper(ev.key) == toupper(*symbol_str("NO")))
195 fin = 1;
196 if((ev.type == EV_KEY && ev.key == JK_ESC)
197 || ev.type == EV_CLOSE_WINDOW)
198 fin = 1;
199 }
200
201 delete ok_image;
202 delete cancel_image;
203
204 the_game->reset_keymap();
205
206 wm->close_window(quitw);
207 wm->flush_screen();
208 return quit;
209 }
210
show_object_number(game_object * who)211 static void show_object_number (game_object *who)
212 {
213 int total=0,number=0;
214 game_object *c;
215 for (c=current_level->first_object(); c; c=c->next)
216 {
217 if (c->otype==who->otype)
218 total++;
219 if (c==who) number=total;
220 }
221 char msg[100];
222 sprintf(msg,"%s : %d of %d",object_names[who->otype],number,total);
223 }
224
search_backward()225 void dev_controll::search_backward()
226 { ;
227 }
228
229
single_render()230 static void single_render()
231 {
232 // enlarge clip area
233 the_game->first_view->cx2=the_game->first_view->cx1+
234 (the_game->first_view->cx2-the_game->first_view->cx1+1)*2;
235 the_game->first_view->cy2=the_game->first_view->cy1+
236 (the_game->first_view->cy2-the_game->first_view->cy1+1)*2;
237 delete small_render;
238 small_render=NULL;
239 small_render_on=0;
240 }
241
double_render()242 static void double_render()
243 {
244 small_render_on=1;
245 // reduce clip area
246 the_game->first_view->cx2=the_game->first_view->cx1+
247 (the_game->first_view->cx2-the_game->first_view->cx1+1)/2;
248 the_game->first_view->cy2=the_game->first_view->cy1+
249 (the_game->first_view->cy2-the_game->first_view->cy1+1)/2;
250
251 small_render=new image(vec2i(the_game->first_view->cx2-the_game->first_view->cx1+1, the_game->first_view->cy2-the_game->first_view->cy1+1),NULL,2);
252 }
253
254
search_forward()255 void dev_controll::search_forward()
256 {
257 if (search_window) // if no window then we can't get the object name
258 {
259 char *name=search_window->read(ID_SEARCH_TEXT);
260 int type=-1; // see if this type exsists
261 int i;
262 for (i=0; i<total_objects; i++)
263 if (!strcmp(object_names[i],name))
264 type=i;
265 if (type==-1)
266 {
267 char msg[60];
268 sprintf(msg,"Object type '%s' does not exsists!\n",name);
269 the_game->show_help(msg);
270 the_game->need_refresh();
271 } else
272 {
273 game_object *first,*find=NULL;
274 if (!search_object || search_object->otype!=type)
275 first=current_level->first_object();
276 else
277 first=search_object->next;
278 for (; !find && first; first=first->next)
279 if (first->otype==type)
280 find=first;
281 int loop=0;
282 if (!find)
283 {
284 for (first=current_level->first_object(); first && !find; first=first->next)
285 {
286 if (first->otype==type)
287 find=first;
288 }
289 loop=1;
290 }
291 if (find)
292 {
293 search_object=find;
294 show_object_number(search_object);
295 }
296 else
297 {
298 the_game->show_help("No object matching name exsist in level\n");
299
300 }
301 }
302 }
303 }
304
305
snap_x(int32_t x)306 int32_t dev_controll::snap_x(int32_t x)
307 {
308 if (wm->key_pressed(JK_CTRL_L) || wm->key_pressed(JK_CTRL_R))
309 return x-(x%the_game->ftile_width());
310 else if (wm->key_pressed(JK_ALT_L) || wm->key_pressed(JK_ALT_R))
311 return x-(x%the_game->ftile_width())+the_game->ftile_width()/2;
312 else return x;
313 }
314
snap_y(int32_t y)315 int32_t dev_controll::snap_y(int32_t y)
316 {
317 if (wm->key_pressed(JK_CTRL_L) || wm->key_pressed(JK_CTRL_R))
318 return y-(y%the_game->ftile_height())-1;
319 else if (wm->key_pressed(JK_ALT_L) || wm->key_pressed(JK_ALT_R))
320 return y-(y%the_game->ftile_height())+the_game->ftile_height()/2-1;
321 else return y;
322 }
323
make_ambient()324 void dev_controll::make_ambient()
325 {
326 if(ambw)
327 return;
328
329 ambw = wm->new_window(prop->getd("ambient x", -1),
330 prop->getd("ambient y", -1), -1, -1,
331 new amb_cont(0, 0, NULL), "ambient");
332 }
333
execute(char * st)334 void dev_term::execute(char *st)
335 {
336 if (!strcmp(st,"?"))
337 {
338 put_string("unchop x y, size x y,\n"
339 "load, esave, name\n");
340 } else
341 {
342 event ev;
343 dv->do_command(st,ev);
344 }
345 }
346
load_dev_icons()347 static void load_dev_icons()
348 {
349 char const *artf="art/dev.spe";
350 dev_del=cache.reg(artf,"dev_del",SPEC_IMAGE,0);
351 dev_move=cache.reg(artf,"dev_move",SPEC_IMAGE,0);
352 dev_char_left=cache.reg(artf,"dev_char_left",SPEC_IMAGE,0);
353 dev_char_right=cache.reg(artf,"dev_char_right",SPEC_IMAGE,0);
354 dev_back=cache.reg(artf,"dev_back",SPEC_IMAGE,0);
355 dev_front=cache.reg(artf,"dev_front",SPEC_IMAGE,0);
356 dev_ok=cache.reg(artf,"dev_ok",SPEC_IMAGE,0);
357 dev_copy=cache.reg(artf,"dev_copy",SPEC_IMAGE,0);
358 dev_brain=cache.reg(artf,"brain",SPEC_IMAGE,0);
359 dev_lights=cache.reg(artf,"lights",SPEC_IMAGE,0);
360 dev_objects=cache.reg(artf,"objects",SPEC_IMAGE,0);
361 dev_ai=cache.reg(artf,"ai",SPEC_IMAGE,0);
362 dev_forward=cache.reg(artf,"forward",SPEC_IMAGE,0);
363 dev_backward=cache.reg(artf,"backward",SPEC_IMAGE,0);
364
365 for (int i=0; i<DEV_MODES; i++)
366 dev_mode_icon[i]=cache.reg(artf,dev_mode_icon_names[i],SPEC_IMAGE,0);
367
368 }
369
scale_put(image * im,image * screen,int x,int y,short new_width,short new_height)370 void scale_put(image *im, image *screen, int x, int y, short new_width, short new_height)
371 {
372 unsigned char *sl1,*sl2;
373 int32_t xstep=(im->Size().x<<16)/new_width,
374 ystep=(im->Size().y<<16)/new_height,iy,ix,sx,ix_start,iy_start;
375 screen->AddDirty(x, y, x + new_width, y + new_height);
376
377 int cx1, cy1, cx2, cy2;
378 screen->GetClip(cx1, cy1, cx2, cy2);
379 if (cx1>cx2 || cy1>cy2 || x>cx2-1 || y>cy2-1 || x+new_width<=cx1 || y+new_height<=cy1) return ;
380 if (x<cx1)
381 {
382 ix_start=(cx1-x)*xstep;
383 new_width-=(cx1-x);
384 x=cx1;
385 } else ix_start=0;
386 if (x+new_width>cx2)
387 new_width-=x+new_width-cx2;
388 if (y<cy1)
389 {
390 iy_start=(cy1-y)*ystep;
391 new_height-=(cy1-y);
392 y=cy1;
393 } else iy_start=0;
394 if (y+new_height>cy2)
395 new_height-=y+new_height-cy2;
396
397 screen->Lock();
398 im->Lock();
399 for (iy=iy_start; new_height>0; new_height--,y++,iy+=ystep)
400 {
401 sl1=im->scan_line(iy>>16);
402 sl2=screen->scan_line(y)+x;
403 for (ix=ix_start,sx=0; sx<new_width; sx++,ix+=xstep,sl2++)
404 *sl2=sl1[ix>>16];
405 }
406 im->Unlock();
407 screen->Unlock();
408 }
409
410
scale_put_trans(image * im,image * screen,int x,int y,short new_width,short new_height)411 void scale_put_trans(image *im, image *screen, int x, int y, short new_width, short new_height)
412 {
413 unsigned char *sl1,*sl2;
414 int32_t xstep=(im->Size().x<<16)/new_width,
415 ystep=(im->Size().y<<16)/new_height,iy,ix,sx,ix_start,iy_start;
416 screen->AddDirty(x, y, x + new_width, y + new_height);
417
418 int cx1, cy1, cx2, cy2;
419 screen->GetClip(cx1, cy1, cx2, cy2);
420 if (cx1>cx2 || cy1>cy2 || x>cx2-1 || y>cy2-1 || x+new_width<=cx1 || y+new_height<=cy1) return ;
421 if (x<cx1)
422 {
423 ix_start=(cx1-x)*xstep;
424 new_width-=(cx1-x);
425 x=cx1;
426 } else ix_start=0;
427 if (x+new_width>cx2)
428 new_width-=x+new_width-cx2;
429 if (y<cy1)
430 {
431 iy_start=(cy1-y)*ystep;
432 new_height-=(cy1-y);
433 y=cy1;
434 } else iy_start=0;
435 if (y+new_height>cy2)
436 new_height-=y+new_height-cy2;
437
438 uint8_t d;
439 screen->Lock();
440 for (iy=iy_start; new_height>0; new_height--,y++,iy+=ystep)
441 {
442 sl1=im->scan_line(iy>>16);
443 sl2=screen->scan_line(y)+x;
444 for (ix=ix_start,sx=0; sx<new_width; sx++,ix+=xstep,sl2++)
445 {
446 d=sl1[ix>>16];
447 if (d)
448 *sl2=d;
449 }
450 }
451 screen->Unlock();
452 }
453
need_plus_minus()454 int dev_controll::need_plus_minus()
455 {
456 if (state==DEV_MOVE_LIGHT) return 1; else return 0;
457 }
458
need_arrows()459 int dev_controll::need_arrows()
460 {
461 if (state==DEV_MOVE_LIGHT) return 1; else return 0;
462 }
463
repeat_key_mode()464 int dev_controll::repeat_key_mode()
465 {
466 if (state==DEV_MOVE_LIGHT) return 1; else return 0;
467 }
468
469 int last_link_x=0,last_link_y=0;
470
dev_draw(view * v)471 void dev_controll::dev_draw(view *v)
472 {
473 int32_t x1,y1,x2,y2;
474 if (dev&EDIT_MODE)
475 {
476 int32_t vx=v->xoff(),vy=v->yoff();
477
478 if (dev&DRAW_LINKS)
479 {
480 for (light_source *f=first_light_source; f; f=f->next)
481 {
482 if (f->x-vx>=0 && f->x-vx<=(v->cx2-v->cx1+1) && f->y-vy>=0 && f->y-vy<=(v->cy2-v->cy1+1))
483 {
484 image *im=cache.img(light_buttons[f->type]);
485 im->put_image(screen,f->x-vx+v->cx1-im->Size().x/2,f->y-vy+v->cy1-im->Size().y/2,1);
486 screen->rectangle(f->x1-vx+v->cx1,f->y1-vy+v->cy1,f->x2-vx+v->cx1,f->y2-vy+v->cy1,
487 wm->medium_color());
488 }
489 }
490 }
491
492 if (link_object)
493 {
494 int32_t rx1,ry1;
495 the_game->game_to_mouse(link_object->x,link_object->y,v,rx1,ry1);
496 screen->line(rx1,ry1,dlastx,dlasty,yellow);
497 }
498
499 if (selected_light)
500 {
501 image *i=cache.img(light_buttons[0]);
502 int l=i->Size().x/2,h=i->Size().y/2;
503 int32_t rx1,ry1;
504 the_game->game_to_mouse(selected_light->x,selected_light->y,v,rx1,ry1);
505 screen->rectangle(rx1-l,ry1-h,rx1+l,ry1+h,wm->bright_color());
506 }
507
508 game_object *o;
509 if (show_names)
510 for (o=current_level->first_object(); o; o=o->next)
511 {
512 the_game->game_to_mouse(o->x,o->y,current_view,x1,y1);
513 char *nm=object_names[o->otype];
514 console_font->put_string(screen,x1-strlen(nm)*console_font->width()/2,y1+2,nm);
515 }
516
517 if (dev&DRAW_LINKS)
518 {
519 // draw connections between objects
520 for (o=current_level->first_object(); o; o=o->next)
521 {
522 the_game->game_to_mouse(o->x,o->y,current_view,x1,y1);
523
524 int i=0;
525 for (; i<o->total_objects(); i++)
526 {
527 game_object *other=o->get_object(i);
528 the_game->game_to_mouse(other->x,other->y,current_view,x2,y2);
529 screen->line(x1,y1,x2,y2,wm->bright_color());
530 }
531
532 for (i=0; i<o->total_lights(); i++)
533 {
534 light_source *l=o->get_light(i);
535 the_game->game_to_mouse(l->x,l->y,current_view,x2,y2);
536 screen->line(x1,y1,x2,y2,light_connection_color);
537 }
538
539 }
540 }
541
542 if (selected_object)
543 {
544 selected_object->picture_space(x1,y1,x2,y2);
545 int32_t rx1,ry1,rx2,ry2;
546 the_game->game_to_mouse(x1,y1,v,rx1,ry1);
547 the_game->game_to_mouse(x2,y2,v,rx2,ry2);
548 screen->rectangle(rx1,ry1,rx2,ry2,wm->bright_color());
549
550 the_game->game_to_mouse(selected_object->x,selected_object->y,current_view,x1,y1);
551 for (int i=0; i<selected_object->total_objects(); i++)
552 {
553 game_object *other=selected_object->get_object(i);
554 the_game->game_to_mouse(other->x,other->y,current_view,x2,y2);
555 screen->line(x1,y1,x2,y2,light_connection_color);
556 }
557 }
558
559
560 }
561 }
562
find_light(int32_t x,int32_t y)563 static light_source *find_light(int32_t x, int32_t y)
564 {
565 image *i=cache.img(light_buttons[0]);
566 int l=i->Size().x/2,h=i->Size().y/2;
567 for (light_source *f=first_light_source; f; f=f->next)
568 {
569 if (x>=f->x-l && x<=f->x+l && y>=f->y-h && y<=f->y+h)
570 return f;
571 }
572 return NULL;
573 }
574
575
toggle_toolbar()576 void dev_controll::toggle_toolbar()
577 {
578 if (tbw)
579 {
580 tbw_on=0;
581 prop->setd("toolbar x",tbw->x);
582 prop->setd("toolbar y",tbw->y);
583 wm->close_window(tbw);
584 tbw=NULL;
585 } else
586 {
587 tbw_on=1;
588 int setx=0;
589 for (int i=0; i<DEV_MODES; i++)
590 {
591 if (edit_mode==dev_mode_ids[i])
592 setx=i;
593 dev_mode_pict[i]=new cached_image(dev_mode_icon[i]);
594 }
595
596 tool_picker *tp=new tool_picker(0, 0,
597 ID_NULL,
598 5,(visual_object **)dev_mode_pict,dev_mode_ids,DEV_MODES,
599 pal,pal,NULL);
600 tbw=wm->new_window(prop->getd("toolbar x",-1),
601 prop->getd("toolbar y",-1),-1,-1,tp);
602 tp->set_x(setx,tbw->screen);
603 }
604 }
605
toggle_show_menu()606 void dev_controll::toggle_show_menu()
607 {
608 if(show_menu)
609 {
610 show_menu_on = 0;
611 prop->setd("layer x", show_menu->x);
612 prop->setd("layer y", show_menu->y);
613 wm->close_window(show_menu);
614 show_menu = NULL;
615 return;
616 }
617
618 show_menu_on = 1;
619
620 button *lnb, *lb, *cb, *bb, *bdb, *fb;
621
622 lnb = new button(0, 100, SHOW_LINKS, symbol_str("l_links"), NULL);
623 if(dev & DRAW_LINKS)
624 lnb->push();
625 lb = new button(0, 80, SHOW_LIGHT, symbol_str("l_light"), lnb);
626 if(dev & DRAW_LIGHTS)
627 lb->push();
628 cb = new button(0, 60, SHOW_CHARACTERS, symbol_str("l_char"), lb);
629 if(dev & DRAW_PEOPLE_LAYER)
630 cb->push();
631 bb = new button(0, 40, SHOW_BACKGROUND, symbol_str("l_back"), cb);
632 if(dev & DRAW_BG_LAYER)
633 bb->push();
634 bdb = new button(0, 20, SHOW_FOREGROUND_BOUND, symbol_str("l_bound"), bb);
635 if(dev & DRAW_FG_BOUND_LAYER)
636 bdb->push();
637 fb = new button(0, 0, SHOW_FOREGROUND, symbol_str("l_fore"), bdb);
638 if(dev & DRAW_FG_LAYER)
639 fb->push();
640
641 show_menu = wm->new_window(prop->getd("layer x", -1),
642 prop->getd("layer y", -1), -1, -1,
643 fb, symbol_str(symbol_str("SHOW?")));
644 }
645
646 char **listable_objs=NULL;
647 int total_listable;
648
toggle_omenu()649 void dev_controll::toggle_omenu()
650 {
651 if(omenu)
652 {
653 omenu_on = 0;
654 prop->setd("objects x", omenu->x);
655 prop->setd("objects y", omenu->y);
656 wm->close_window(omenu);
657 omenu = NULL;
658 free(listable_objs);
659 listable_objs = NULL;
660 return;
661 }
662
663 omenu_on = 1;
664 total_listable = 0;
665
666 int i, c;
667
668 for(i = 0; i < total_objects; i++)
669 if(!figures[i]->get_cflag(CFLAG_UNLISTABLE))
670 total_listable++;
671 listable_objs = (char **)malloc(sizeof(char *) * total_listable);
672
673 for(i = 0, c = 0; i < total_objects; i++)
674 if(!figures[i]->get_cflag(CFLAG_UNLISTABLE))
675 {
676 listable_objs[c] = object_names[i];
677 c++;
678 }
679
680 omenu = wm->new_window(prop->getd("objects x", 0),
681 prop->getd("objects y", 0), -1, -1,
682 new pick_list(0, 0, DEV_CREATE,
683 yres / wm->font()->height() / 2,
684 listable_objs, total_listable, 0,
685 NULL, cache.img(window_texture)));
686 }
687
get_omenu_item(int x)688 static int get_omenu_item(int x)
689 {
690 for (int i=0; i<total_objects; i++)
691 if (listable_objs[x]==object_names[i])
692 return i;
693 return 0;
694 }
695
toggle_pmenu()696 void dev_controll::toggle_pmenu()
697 {
698 if(pmenu)
699 {
700 pmenu_on = 0;
701 prop->setd("pal x", pmenu->x);
702 prop->setd("pal y", pmenu->y);
703 wm->close_window(pmenu);
704 pmenu = NULL;
705 free(pwin_list);
706 return;
707 }
708
709 if(!total_pals)
710 {
711 the_game->show_help(symbol_str("no_pals"));
712 return;
713 }
714
715 pmenu_on = 1;
716
717 pwin_list = (char **)malloc(total_pals * sizeof(char *));
718 for(int i = 0; i < total_pals; i++)
719 pwin_list[i] = pal_wins[i]->name;
720
721 pmenu = wm->new_window(prop->getd("pal x",0),
722 prop->getd("pal y",-1), -1,-1,
723 new pick_list(0, 0, DEV_PALETTE,
724 yres / wm->font()->height() / 2,
725 pwin_list, total_pals, 0, NULL,
726 cache.img(window_texture)));
727 }
728
729
toggle_fgw()730 void dev_controll::toggle_fgw()
731 {
732 if(forew)
733 {
734 forew_on = 1;
735 prop->setd("fore x", forew->x);
736 prop->setd("fore y", forew->y);
737 wm->close_window(forew);
738 forew = NULL;
739 return;
740 }
741
742 /* FIXME: shouldn't this be 1? */
743 forew_on = 0;
744 int maxh = (yres - 25) / (the_game->ftile_height() / fg_scale);
745
746 /* FIXME: previous code had 1 instead of 0, investigate */
747 tile_picker *f_tp = new tile_picker(0, 0, DEV_FG_PICKER, SPEC_FORETILE,
748 fg_scale, maxh, fg_w, NULL);
749 f_tp->reverse();
750
751 forew = wm->new_window(prop->getd("fore x", -30), prop->getd("fore y", 0),
752 -1, -1, f_tp,symbol_str("l_fg"));
753 }
754
toggle_music_window()755 void dev_controll::toggle_music_window()
756 {
757 /* if (!music_window)
758 {
759 music_window=wm->new_window(-1,30,0,0,
760 new pick_list(0,0,DEV_MUSIC_PICKLIST,10,song_list,total_songs,0,NULL));
761 wm->fnt->put_string(music_window->screen,0,1,"songs");
762 } else
763 {
764 wm->close_window(music_window);
765 music_window=NULL;
766 }*/
767 }
768
toggle_bgw()769 void dev_controll::toggle_bgw()
770 {
771 if(backw)
772 {
773 backw_on = 1;
774 prop->setd("back x", backw->x);
775 prop->setd("back y", backw->y);
776 wm->close_window(backw);
777 backw = NULL;
778 return;
779 }
780
781 /* FIXME: shouldn't this be 1? */
782 backw_on = 0;
783 int maxh = (yres - 25) / (the_game->btile_height() / bg_scale);
784
785 /* FIXME: previous code had 1 instead of 0, investigate */
786 tile_picker *f_tp = new tile_picker(0, 0, DEV_BG_PICKER, SPEC_BACKTILE,
787 bg_scale, maxh, bg_w, NULL);
788 forew = wm->new_window(prop->getd("back x", -30), prop->getd("back y", 0),
789 -1, -1, f_tp,symbol_str("l_bg"));
790 }
791
toggle_search_window()792 void dev_controll::toggle_search_window()
793 {
794 if(search_window)
795 {
796 searchw_on = 1;
797 prop->setd("searchw x", search_window->x);
798 prop->setd("searchw y", search_window->y);
799 prop->set("search name", search_window->read(ID_SEARCH_TEXT));
800 wm->close_window(search_window);
801 search_window = NULL;
802 search_object = NULL;
803 return;
804 }
805
806 int bw = cache.img(dev_forward)->Size().x;
807 /* FIXME: previous code had 1,1 instead of 0,0 -- investigate */
808 search_window = wm->new_window(prop->getd("searchw x", -30),
809 prop->getd("searchw y", 0), -1, -1,
810 new text_field(0, 0, ID_SEARCH_TEXT, "object name>",
811 "***************************",
812 prop->get("search name", ""),
813 new button(bw, wm->font()->height() + 5, ID_SEARCH_BACKWARD,
814 cache.img(dev_backward),
815 new button(bw * 3, wm->font()->height() + 5, ID_SEARCH_FOREWARD,
816 cache.img(dev_forward), NULL))), "SEARCH");
817
818 /* FIXME: shouldn't this be 1? */
819 searchw_on = 0;
820 }
821
822 int open_owin=0,open_fwin=0,open_bwin=0,start_edit=0,start_nodelay=0,start_doubled=0,start_mem=0;
823
824
825 int get_option(char const *name);
826
827
dev_init(int argc,char ** argv)828 void dev_init(int argc, char **argv)
829 {
830 scale_mult=1;
831 scale_div=1;
832 dev=0;
833 int i;
834 prop=new property_manager;
835 prop->load("defaults.prp");
836
837 for (i=1; i<argc; i++)
838 {
839 if (!strcmp(argv[i],"-edit"))
840 {
841 dev|=EDIT_MODE;
842 start_edit=1;
843 start_running=1;
844 disable_autolight=1;
845 if (get_option("-2"))
846 {
847 printf("%s\n",symbol_str("no2"));
848 exit(0);
849 }
850 }
851 else if (!strcmp(argv[i],"-fwin"))
852 open_fwin=1;
853 else if (!strcmp(argv[i],"-show_mem"))
854 start_mem=1;
855 else if (!strcmp(argv[i],"-bwin"))
856 open_bwin=1;
857 else if (!strcmp(argv[i],"-owin"))
858 open_owin=1;
859 else if (!strcmp(argv[i],"-nodelay"))
860 start_nodelay=1;
861 // AK : NOTE: Commented this out as it causes a conflict
862 /* else if (!strcmp(argv[i],"-scale"))
863 {
864 i++;
865 scale_mult=atoi(argv[i++]);
866 scale_div=atoi(argv[i]);
867 }*/
868 else if (!strcmp(argv[i],"-f"))
869 {
870 i++;
871 strncpy(level_file, argv[i], sizeof(level_file) - 1);
872 level_file[sizeof(level_file) - 1] = '\0';
873 } else if (!strcmp(argv[i],"-2"))
874 start_doubled=1;
875 else if (!strcmp(argv[i],"-demo"))
876 demo_start=1;
877
878 }
879
880 if (get_option("-no_autolight"))
881 disable_autolight=0;
882
883 if ((get_option("-size") || get_option("-vmode")) && !start_edit)
884 {
885 printf("%s\n",symbol_str("no_hirez"));
886 exit(0);
887 }
888
889 fg_reversed=prop->getd("fg_reversed",0);
890 mouse_scrolling=prop->getd("mouse_scrolling",0);
891 palettes_locked=prop->getd("palettes_locked",0);
892 view_shift_disabled=prop->getd("view_shift_disabled",0);
893 fps_on=prop->getd("fps_on",0);
894 show_names=prop->getd("show_names",0);
895 raise_all=prop->getd("raise_all",0);
896 }
897
898 static pmenu *make_menu(int x, int y);
899
900
dev_controll()901 dev_controll::dev_controll()
902 {
903 area_win=NULL;
904 current_area=NULL;
905 fg_w=bg_w=1;
906 commandw=NULL;
907 bg_scale=fg_scale=1;
908 pal_wins=NULL;
909 total_pals=0;
910 state=DEV_SELECT;
911 aiw=NULL;
912 edit_light=NULL;
913 selected_light=NULL;
914
915 tbw=NULL;
916 modew=NULL;
917 link_object=NULL;
918 selected_object=NULL;
919 edit_object=NULL;
920 ai_object=NULL;
921 search_object = NULL;
922 oedit=NULL;
923 forew=NULL;
924 backw=NULL;
925 omenu=NULL;
926 ledit=NULL;
927 pmenu=NULL;
928 lightw=NULL;
929 search_window=NULL;
930 show_menu=NULL;
931 music_window=NULL;
932 ambw=NULL;
933 load_dev_icons();
934
935 if (open_owin) toggle_omenu();
936 if (open_fwin) toggle_fgw();
937 if (open_bwin) toggle_bgw();
938 if (start_nodelay) the_game->toggle_delay();
939 yellow=pal->find_closest(255,255,0);
940 if (start_edit)
941 {
942 the_game->load_level(level_file);
943 the_game->draw();
944 }
945
946 dev_console=new dev_term(50,18,this);
947 if (start_edit)
948 dev_menu=make_menu(0,yres-wm->font()->height()-5);
949
950 if (get_option("-nolight"))
951 dev=dev^DRAW_LIGHTS;
952 }
953
954
set_state(int new_state)955 void dev_controll::set_state(int new_state)
956 {
957 if (start_doubled && new_state==RUN_STATE && !small_render)
958 double_render();
959 }
960
load_stuff()961 void dev_controll::load_stuff()
962 {
963 if (dev & EDIT_MODE)
964 {
965 char prog[100];
966 char const *cs;
967 strcpy(prog,"(compile-file \"edit.lsp\")");
968 cs=prog;
969 LObject *p = LObject::Compile(cs);
970 l_user_stack.push(p);
971 p->Eval();
972 l_user_stack.pop(1);
973 for (int i=0; i<total_pals; i++)
974 pal_wins[i]->close_window();
975 }
976
977 }
978
do_command(char const * command,event & ev)979 void dev_controll::do_command(char const *command, event &ev)
980 {
981 char fword[50];
982 char const *st;
983 int l,h,x,y,i;
984 if (command[0]=='(') // is this a lisp command?
985 {
986 LObject::Compile(command)->Eval();
987 return ;
988 }
989
990 sscanf(command,"%s",fword);
991 for (st=command; *st && *st!=' '; st++);
992 if (*st) st++;
993 if (!strcmp(fword,"active"))
994 {
995 if (current_level && current_level->first_active_object())
996 {
997 game_object *o=current_level->first_active_object();
998 while (o)
999 {
1000 dprintf("%s %d %d %d %d\n",object_names[o->otype],o->x,o->y,
1001 figures[o->otype]->rangex,
1002 figures[o->otype]->rangey
1003 );
1004 o=o->next_active;
1005 }
1006 }
1007 }
1008
1009 if (!strcmp(fword,"clear_weapons"))
1010 {
1011 view *f=NULL;
1012 for (f=player_list; f; f=f->next)
1013 {
1014 int i;
1015 for (i=0; i<total_weapons; i++)
1016 f->weapons[i]=-1;
1017
1018 if (total_weapons)
1019 f->weapons[0]=0;
1020 }
1021 }
1022
1023 if (!strcmp(fword,"reload"))
1024 {
1025 if (current_level && player_list && player_list->focus)
1026 {
1027 edit_object=selected_object=NULL;
1028 int32_t cx=player_list->focus->x,cy=player_list->focus->y;
1029
1030 // save the old weapon array
1031 int32_t *w=(int32_t *)malloc(total_weapons*sizeof(int32_t));
1032 memcpy(w,player_list->weapons,total_weapons*sizeof(int32_t));
1033
1034 char tmp[100];
1035 strcpy(tmp,current_level->name());
1036 the_game->load_level(tmp);
1037 current_level->unactivate_all();
1038
1039 if (screen) // don't draw if graphics haven't been setup yet.
1040 the_game->draw();
1041 player_list->reset_player();
1042 player_list->focus->x=cx;
1043 player_list->focus->y=cy;
1044
1045 memcpy(player_list->weapons,w,total_weapons*sizeof(int32_t));
1046 free(w);
1047
1048 the_game->need_refresh();
1049 }
1050 }
1051
1052 if (!strcmp(fword,"unchop"))
1053 {
1054 int32_t rx,ry;
1055 the_game->btile_on(dlastx,dlasty,rx,ry);
1056 if (rx>=0 && ry>=0)
1057 {
1058 if (sscanf(command,"%s%d%d",fword,&l,&h)==3)
1059 {
1060 dprintf("unchopped %dx%d to ",l,h);
1061 l=(l+the_game->btile_width()-1)/the_game->btile_width();
1062 h=(h+the_game->btile_height()-1)/the_game->btile_height();
1063 for (y=0,i=cur_bg; y<h; y++)
1064 for (x=0; x<l; x++)
1065 the_game->put_bg(rx+x,ry+y,i++);
1066 dprintf("%dx%d\n",l,h);
1067 } else dprintf(symbol_str("unchop1"));
1068
1069 }
1070 }
1071 if (!strcmp(fword,"center"))
1072 {
1073 view *v=the_game->first_view;
1074 for (; v; v=v->next)
1075 {
1076 v->pan_x=0;
1077 v->pan_y=0;
1078 }
1079 the_game->need_refresh();
1080 }
1081
1082 if (!strcmp(fword,"size"))
1083 {
1084 int l,w;
1085 if (sscanf(command,"%s%d%d",fword,&l,&w)==3)
1086 {
1087 current_level->set_size(l,w);
1088 dprintf("level is now %dx%d\n",l,w);
1089 } else dprintf(symbol_str("size1"));
1090
1091
1092 }
1093 if (!strcmp(fword,"name"))
1094 {
1095 while (*command && *command!=' ') command++;
1096 if (*command)
1097 current_level->set_name(command+1);
1098 dprintf(symbol_str("name_now"),current_level->name());
1099 }
1100 if (!strcmp(fword,"set_first_level"))
1101 {
1102 strcpy(level_file,st);
1103 dprintf("first level will be '%s'\n",level_file);
1104 }
1105
1106 if (!strcmp(fword,"load"))
1107 {
1108 if (!strcmp(st,"STARTING_LEVEL"))
1109 st=level_file;
1110
1111 dprintf("loading '%s'\n",st);
1112 the_game->load_level(st);
1113 current_level->unactivate_all();
1114
1115 the_game->need_refresh();
1116 }
1117
1118 if (!strcmp(fword,"mem"))
1119 {
1120 if (st[0])
1121 show_char_mem(st);
1122 else show_mem();
1123 }
1124
1125 if (!strcmp(fword,"esave"))
1126 {
1127 dprintf(symbol_str("esave"));
1128 save();
1129 }
1130
1131 if (!strcmp(fword,"delete"))
1132 {
1133 if (selected_object)
1134 {
1135 if (!(dev&EDIT_MODE) && current_level->is_attacker(selected_object))
1136 the_game->show_help(symbol_str("nd_player"));
1137 else
1138 {
1139 if (selected_object->controller())
1140 the_game->show_help(symbol_str("nd_player"));
1141 else
1142 {
1143 current_level->delete_object(selected_object);
1144 if (S_DELETE_SND>0) cache.sfx(S_DELETE_SND)->play(sfx_volume/2);
1145 selected_object=NULL;
1146 }
1147 }
1148 } else if (selected_light)
1149 {
1150 if (!edit_light)
1151 {
1152 if (current_level)
1153 {
1154 current_level->remove_light(selected_light);
1155 if (S_DELETE_SND>0) cache.sfx(S_DELETE_SND)->play(sfx_volume/2);
1156 }
1157 else
1158 delete_light(selected_light);
1159 selected_light=NULL;
1160 }
1161 } else the_game->show_help(symbol_str("d_nosel"));
1162 the_game->need_refresh();
1163 }
1164
1165 if (!strcmp(fword,"create"))
1166 {
1167 char oname[100];
1168 sscanf(command,"%s%s",fword,oname); // read the type of object to create
1169 int x,t=-1;
1170 for (x=0; x<total_objects; x++) // find the object type by name
1171 if (!strcmp(object_names[x],oname))
1172 t=x;
1173
1174 if (t>=0) // did we find it?
1175 {
1176 int32_t rx,ry;
1177 the_game->mouse_to_game(dlastx,dlasty,rx,ry);
1178 edit_object=create(t,rx,ry);
1179 current_level->add_object(edit_object);
1180 the_game->need_refresh();
1181 last_created_type=t;
1182 } else
1183 {
1184 sprintf(fword,"No such object type : %s\n",oname);
1185 the_game->show_help(fword);
1186 }
1187 }
1188
1189 if (!strcmp(fword,"move"))
1190 {
1191 if (selected_object)
1192 edit_object=selected_object;
1193
1194 if (edit_object)
1195 state=DEV_MOVE_OBJECT;
1196 else the_game->show_help("No object selected");
1197
1198 }
1199 if (!strcmp(fword,"move_light"))
1200 {
1201 if (selected_light)
1202 edit_light=selected_light;
1203
1204 if (edit_light)
1205 state=DEV_MOVE_LIGHT;
1206 else the_game->show_help("No light selected");
1207
1208 }
1209
1210
1211 if (!strcmp(fword,"clear_auto"))
1212 {
1213 int32_t i,j;
1214 for (i=0; i<current_level->foreground_width(); i++)
1215 for (j=0; j<current_level->foreground_height(); j++)
1216 current_level->clear_fg(i,j);
1217 }
1218
1219 if (!strcmp(fword,"fg_select"))
1220 {
1221 int32_t x,y;
1222 the_game->ftile_on(dlastx,dlasty,x,y);
1223 if (x>=0 && y>=0 && x<current_level->foreground_width() &&
1224 y<current_level->foreground_height())
1225 {
1226 cur_fg=current_level->get_fg(x,y);
1227 if (forew)
1228 ((tile_picker *)forew->read(DEV_FG_PICKER))->recenter(forew->screen);
1229 the_game->need_refresh();
1230 }
1231 }
1232
1233 if (!strcmp(fword,"toggle_fg_raise"))
1234 {
1235 int32_t x,y;
1236 the_game->ftile_on(dlastx,dlasty,x,y);
1237 if (x>=0 && y>=0 && x<current_level->foreground_width() &&
1238 y<current_level->foreground_height())
1239 current_level->fg_set_raised(x,y,!current_level->fg_raised(x,y));
1240 }
1241
1242 if (!strcmp(fword,"fg_add"))
1243 {
1244 int x;
1245 if (sscanf(st,"%d",&x))
1246 {
1247 cur_fg++;
1248 if (cur_fg<0) cur_fg=0;
1249 if (cur_fg>=nforetiles) cur_fg=nforetiles-1;
1250
1251 if (forew)
1252 ((tile_picker *)forew->read(DEV_FG_PICKER))->recenter(forew->screen);
1253 }
1254 }
1255
1256 if (!strcmp(fword,"restart"))
1257 {
1258 current_level->restart();
1259 }
1260 if (!strcmp(fword,"quit"))
1261 {
1262 the_game->end_session();
1263 }
1264
1265 if (!strcmp(fword,"to_front"))
1266 {
1267 game_object *which=selected_object;
1268 if (!selected_object) which=edit_object;
1269 if (which)
1270 current_level->to_front(which);
1271 else the_game->show_help(symbol_str("forward?"));
1272 }
1273
1274 if (!strcmp(fword,"to_back"))
1275 {
1276 game_object *which=selected_object;
1277 if (!selected_object) which=edit_object;
1278 if (which)
1279 current_level->to_back(which);
1280 else the_game->show_help(symbol_str("back?"));
1281 }
1282
1283 if (!strcmp(fword,"set_aitype"))
1284 {
1285 game_object *which=selected_object;
1286 if (!selected_object) which=edit_object;
1287 if (which)
1288 {
1289 int x;
1290 if (*st && sscanf(st,"%d",&x)!=EOF)
1291 which->change_aitype(x);
1292 else
1293 {
1294 switch (ev.key)
1295 {
1296 case '0' : which->change_aitype(0); break;
1297 case '1' : which->change_aitype(1); break;
1298 case '2' : which->change_aitype(2); break;
1299 case '3' : which->change_aitype(3); break;
1300 case '4' : which->change_aitype(4); break;
1301 case '5' : which->change_aitype(5); break;
1302 case '6' : which->change_aitype(6); break;
1303 case '7' : which->change_aitype(7); break;
1304 case '8' : which->change_aitype(8); break;
1305 case '9' : which->change_aitype(9); break;
1306 case ')' : which->change_aitype(10); break;
1307 case '!' : which->change_aitype(11); break;
1308 case '@' : which->change_aitype(12); break;
1309 case '#' : which->change_aitype(13); break;
1310 case '$' : which->change_aitype(14); break;
1311 case '%' : which->change_aitype(15); break;
1312 case '^' : which->change_aitype(16); break;
1313 case '&' : which->change_aitype(17); break;
1314 case '*' : which->change_aitype(18); break;
1315 case '(' : which->change_aitype(19); break;
1316 }
1317 }
1318 the_game->need_refresh();
1319 }
1320 else the_game->show_help(symbol_str("aitype"));
1321 }
1322 }
1323
1324
toggle_light_window()1325 void dev_controll::toggle_light_window()
1326 {
1327 if(lightw)
1328 {
1329 prop->setd("light create x", lightw->x);
1330 prop->setd("light create y", lightw->y);
1331 prop->setd("light create w", atoi(lightw->read(DEV_LIGHTW)));
1332 prop->setd("light create h", atoi(lightw->read(DEV_LIGHTH)));
1333 prop->setd("light create r1", atoi(lightw->read(DEV_LIGHTR1)));
1334 prop->setd("light create r2", atoi(lightw->read(DEV_LIGHTR2)));
1335 wm->close_window(lightw);
1336 lightw = NULL;
1337 return;
1338 }
1339
1340 int bh = 16 + 6, bw = 20 + 6, th = wm->font()->height() + 4;
1341
1342 lightw = wm->new_window(prop->getd("light create x", 0),
1343 prop->getd("light create y", 0), -1, -1,
1344 new button_box(0, 0, DEV_LIGHT_BUTTON_BOX, 1,
1345 new button(bw * 0, bh * 0, DEV_LIGHT0, cache.img(light_buttons[0]),
1346 new button(bw * 1, bh * 0, DEV_LIGHT1, cache.img(light_buttons[1]),
1347 new button(bw * 2, bh * 0, DEV_LIGHT2, cache.img(light_buttons[2]),
1348 new button(bw * 0, bh * 1, DEV_LIGHT3, cache.img(light_buttons[3]),
1349 new button(bw * 1, bh * 1, DEV_LIGHT4, cache.img(light_buttons[4]),
1350 new button(bw * 2, bh * 1, DEV_LIGHT5, cache.img(light_buttons[5]),
1351 new button(bw * 0, bh * 2, DEV_LIGHT6, cache.img(light_buttons[6]),
1352 new button(bw * 1, bh * 2, DEV_LIGHT7, cache.img(light_buttons[7]),
1353 new button(bw * 2, bh * 2, DEV_LIGHT8, cache.img(light_buttons[8]),
1354 new button(bw * 0, bh * 3, DEV_LIGHT9, cache.img(light_buttons[9]),
1355 new button(bw * 1, bh * 3, DEV_AMBIENT, cache.img(light_buttons[11]),
1356 NULL))))))))))),
1357 new text_field(0, bh * 4, DEV_LIGHTW, "W ", "******",
1358 prop->getd("light create w", 0),
1359 new text_field(0, bh * 4 + th * 1, DEV_LIGHTH, "H ", "******",
1360 prop->getd("light create h", 0),
1361 new text_field(0, bh * 4 + th * 2, DEV_LIGHTR1, "R1", "******",
1362 prop->getd("light create r1", 1),
1363 new text_field(0, bh * 4 + th * 3, DEV_LIGHTR2, "R2", "******",
1364 prop->getd("light create r2", 100), NULL))))),
1365 symbol_str("l_light"));
1366 }
1367
make_ai_window(game_object * o)1368 void dev_controll::make_ai_window(game_object *o)
1369 {
1370 ai_object=o;
1371 int th=wm->font()->height()+4,wl = 0, wh = 20;
1372 if (figures[o->otype]->total_fields)
1373 {
1374 int maxl=0;
1375 int i=0;
1376 for (; i<figures[o->otype]->total_fields; i++)
1377 if( strlen(figures[o->otype]->fields[i]->descript_name) > (unsigned)maxl )
1378 maxl=strlen(figures[o->otype]->fields[i]->descript_name);
1379
1380 int owh=wh;
1381 ifield *first=NULL,*last=NULL;
1382 for (i=0; i<figures[o->otype]->total_fields; i++)
1383 {
1384 char tmp[200];
1385 strcpy(tmp,figures[o->otype]->fields[i]->descript_name);
1386 for (int j=maxl-strlen(figures[o->otype]->fields[i]->descript_name); j; j--)
1387 strcat(tmp," ");
1388 int er;
1389 ifield *p=new text_field(wl,wh,ID_NULL,tmp,"######",
1390 (double)o->get_var_by_name(figures[o->otype]->fields[i]->real_name,er),
1391 NULL);
1392 if (last)
1393 last->next=p;
1394 else
1395 first=p;
1396 last=p;
1397 wh+=th;
1398 }
1399 aiw=wm->new_window(prop->getd("ai x",0),
1400 prop->getd("ai y",0),
1401 -1,-1,
1402 new button(wl,owh-20,DEV_AI_OK,cache.img(dev_ok),first),"ai");
1403
1404 }
1405 else
1406 {
1407 aiw=wm->new_window(prop->getd("ai x",0),
1408 prop->getd("ai y",0),
1409 -1,-1,
1410 new button(wl,wh-20,DEV_AI_OK,cache.img(dev_ok),
1411 new text_field(wl,wh+th*0, DEV_AI_XVEL, symbol_str("ai_xvel"),"#####",(double)o->xvel(),
1412 new text_field(wl,wh+th*1, DEV_AI_YVEL, symbol_str("ai_yvel"),"#####",(double)o->yvel(),
1413 new text_field(wl,wh+th*2, DEV_AI_XACEL, symbol_str("ai_xacel"),"#####",(double)o->xacel(),
1414 new text_field(wl,wh+th*3, DEV_AI_YACEL, symbol_str("ai_yacel"),"#####",(double)o->yacel(),
1415 new text_field(wl,wh+th*4, DEV_AI_STTIME, symbol_str("ai_stime"),"####",(double)o->aistate_time(),
1416 new text_field(wl,wh+th*5, DEV_AI_GRAVITY, symbol_str("ai_gravity"),"####",(double)o->gravity(),
1417 new text_field(wl,wh+th*6, DEV_AI_HEALTH, symbol_str("ai_health"),"####",(double)o->hp(),
1418 new text_field(wl,wh+th*7, DEV_AI_MORPHPR, symbol_str("ai_morph"),"####",(double)o->mp(),
1419 new text_field(wl,wh+th*8, DEV_AI_TYPE, symbol_str("ai_type"),"####",(double)o->aitype(),
1420 new text_field(wl,wh+th*9,DEV_AI_STATE, symbol_str("ai_state"),"####",(double)o->aistate(),
1421 new text_field(wl,wh+th*10,DEV_AI_FADE, symbol_str("ai_fade"),"####",(double)o->fade_count(),
1422 NULL)))))))))))),"ai");
1423 }
1424
1425 wm->grab_focus(aiw);
1426 }
1427
notify_deleted_light(light_source * l)1428 void dev_controll::notify_deleted_light(light_source *l)
1429 {
1430 if (l==edit_light)
1431 {
1432 if (ledit)
1433 {
1434 prop->setd("ledit x",ledit->x);
1435 prop->setd("ledit y",ledit->y);
1436 wm->close_window(ledit); ledit=NULL;
1437 }
1438 edit_light=NULL;
1439 }
1440 if (l==selected_light)
1441 selected_light=NULL;
1442 }
1443
notify_deleted_object(game_object * o)1444 void dev_controll::notify_deleted_object(game_object *o)
1445 {
1446 if (o==edit_object)
1447 {
1448 state=DEV_SELECT;
1449 close_oedit_window();
1450 }
1451
1452 if (o==ai_object)
1453 close_ai_window();
1454 if (o==search_object)
1455 { if (search_window)
1456 toggle_search_window();
1457 search_object=NULL;
1458 }
1459 if (o==link_object)
1460 link_object=NULL;
1461 if (o==selected_object)
1462 {
1463 selected_object=NULL;
1464 state=DEV_SELECT;
1465 }
1466
1467 }
1468
close_ai_window()1469 void dev_controll::close_ai_window()
1470 {
1471 if (aiw)
1472 {
1473 game_object *o=ai_object;
1474 int32_t x;
1475 if (o)
1476 {
1477 if (figures[o->otype]->total_fields)
1478 {
1479 ifield *f=aiw->inm->get(DEV_AI_OK)->next;
1480 for (int i=0; i<figures[o->otype]->total_fields; i++)
1481 {
1482 x=atoi(f->read());
1483 char *v=figures[o->otype]->fields[i]->real_name;
1484 int er;
1485 if (o->get_var_by_name(v,er)!=x)
1486 o->set_var_by_name(v,x);
1487 f=f->next;
1488 }
1489 }
1490 else
1491 {
1492 x=atoi(aiw->read(DEV_AI_XVEL)); if (x!=o->xvel()) o->set_xvel(x);
1493 x=atoi(aiw->read(DEV_AI_YVEL)); if (x!=o->yvel()) o->set_yvel(x);
1494
1495 x=atoi(aiw->read(DEV_AI_XACEL)); if (x!=o->xacel()) o->set_xacel(x);
1496 x=atoi(aiw->read(DEV_AI_YACEL)); if (x!=o->yacel()) o->set_yacel(x);
1497
1498 x=atoi(aiw->read(DEV_AI_STTIME)); if (x!=o->aistate_time()) o->set_aistate_time(x);
1499 x=atoi(aiw->read(DEV_AI_GRAVITY)); if (x!=o->gravity()) o->set_gravity(x);
1500
1501 x=atoi(aiw->read(DEV_AI_HEALTH)); if (x!=o->hp()) o->set_hp(x);
1502 x=atoi(aiw->read(DEV_AI_MORPHPR)); if (x!=o->mp()) o->set_mp(x);
1503
1504 x=atoi(aiw->read(DEV_AI_TYPE)); if (x!=o->aitype()) o->set_aitype(x);
1505 x=atoi(aiw->read(DEV_AI_STATE)); if (x!=o->aistate()) o->set_aistate(x);
1506 x=atoi(aiw->read(DEV_AI_FADE)); if (x!=o->fade_count()) o->set_fade_count(x);
1507 }
1508 }
1509 prop->setd("ai x",aiw->x);
1510 prop->setd("ai y",aiw->y);
1511 wm->close_window(aiw);
1512 aiw=NULL;
1513 ai_object=NULL;
1514 the_game->need_refresh();
1515 }
1516 }
1517
1518
area_handle_input(event & ev)1519 void dev_controll::area_handle_input(event &ev)
1520 {
1521
1522 if (ev.type==EV_MOUSE_BUTTON && ev.mouse_button)
1523 {
1524 int32_t gx,gy;
1525 the_game->mouse_to_game(last_demo_mx,last_demo_my,gx,gy);
1526 if (!current_level) return ;
1527 current_area=current_level->area_list=new area_controller(gx,gy,
1528 the_game->ftile_width(),
1529 the_game->ftile_height(),
1530 current_level->area_list);
1531 the_game->need_refresh();
1532 state=DEV_DRAG_AREA_BOTTOM;
1533 }
1534 }
1535
close_area_win(int read_values)1536 void dev_controll::close_area_win(int read_values)
1537 {
1538 if (area_win)
1539 {
1540 prop->setd("area_box x",area_win->x);
1541 prop->setd("area_box y",area_win->y);
1542
1543 if (current_area && read_values)
1544 {
1545 current_area->ambient=atoi(area_win->read(DEV_AREA_AMBIENT));
1546 current_area->ambient_speed=atoi(area_win->read(DEV_AREA_AMBIENT_SPEED));
1547 current_area->view_xoff=atoi(area_win->read(DEV_AREA_VIEW_XOFF));
1548 current_area->view_yoff=atoi(area_win->read(DEV_AREA_VIEW_YOFF));
1549 current_area->view_xoff_speed=atoi(area_win->read(DEV_AREA_VIEW_XOFF_SPEED));
1550 current_area->view_yoff_speed=atoi(area_win->read(DEV_AREA_VIEW_YOFF_SPEED));
1551 }
1552 wm->close_window(area_win);
1553 area_win=NULL;
1554 }
1555 }
1556
pick_handle_input(event & ev)1557 void dev_controll::pick_handle_input(event &ev)
1558 {
1559 area_controller *find=NULL;
1560 int find_top=0;
1561 if (!current_level) return;
1562 if (ev.type==EV_MOUSE_BUTTON && ev.mouse_button)
1563 {
1564 int32_t mx=last_demo_mx,my=last_demo_my;
1565 view *v=the_game->view_in(mx,my);
1566 for (area_controller *a=current_level->area_list; a; a=a->next)
1567 {
1568 int32_t x1,y1,x2,y2;
1569 the_game->game_to_mouse(a->x,a->y,v,x1,y1);
1570 the_game->game_to_mouse(a->x+a->w,a->y+a->h,v,x2,y2);
1571 if (abs(x1-mx)<2 && abs(y1-my)<2)
1572 { find=a; find_top=1; }
1573 else if (abs(x2-mx)<2 && abs(y2-my)<2)
1574 { find=a; find_top=0; }
1575 }
1576
1577 time_marker now;
1578 int dc=now.diff_time(&last_area_click)<0.5;
1579 last_area_click.get_time();
1580 if (find && current_area && dc)
1581 {
1582 if (area_win) close_area_win(0);
1583 int wl=0,wh=0,th=wm->font()->height()+12,bw=cache.img(dev_ok)->Size().x+10;
1584 area_win=wm->new_window(prop->getd("area_box x",0),
1585 prop->getd("area_box y",0),
1586 -1,-1,
1587
1588 new button(wl+bw*0,wh-8,DEV_AREA_OK,cache.img(dev_ok),
1589 new button(wl+bw*1,wh-8,DEV_AREA_DELETE,cache.img(dev_del),
1590
1591 new text_field(wl,wh+th*1,DEV_AREA_AMBIENT, symbol_str("a_ambient"),"******",current_area->ambient,
1592 new text_field(wl,wh+th*2,DEV_AREA_AMBIENT_SPEED, symbol_str("a_aspeed"),"******",current_area->ambient_speed,
1593 new text_field(wl,wh+th*3,DEV_AREA_VIEW_XOFF, symbol_str("a_view_xoff"),"******",current_area->view_xoff,
1594 new text_field(wl,wh+th*4,DEV_AREA_VIEW_YOFF, symbol_str("a_view_yoff"),"******",current_area->view_yoff,
1595 new text_field(wl,wh+th*5,DEV_AREA_VIEW_XOFF_SPEED, symbol_str("a_view_xspd"),"******",current_area->view_xoff_speed,
1596 new text_field(wl,wh+th*6,DEV_AREA_VIEW_YOFF_SPEED, symbol_str("a_view_yspd"),"******",current_area->view_yoff_speed,
1597 NULL)))))))));
1598 } else if (find)
1599 {
1600 current_area=find;
1601 current_area->active=1;
1602 if (find_top)
1603 state=DEV_DRAG_AREA_TOP;
1604 else state=DEV_DRAG_AREA_BOTTOM;
1605 the_game->need_refresh();
1606 } else if (current_area)
1607 {
1608 current_area->active=0;
1609 current_area=NULL;
1610 the_game->need_refresh();
1611 }
1612 }
1613 }
1614
close_oedit_window()1615 void dev_controll::close_oedit_window()
1616 {
1617 if (oedit)
1618 {
1619 prop->setd("oedit x",oedit->x);
1620 prop->setd("oedit y",oedit->y);
1621 wm->close_window(oedit);
1622 oedit=NULL;
1623 edit_object=NULL;
1624 }
1625 }
1626
1627 int screen_shot_on=1;
1628 int sshot_fcount=-1;
1629
handle_event(event & ev)1630 void dev_controll::handle_event(event &ev)
1631 {
1632 int32_t x,y;
1633 if (link_object && (dlastx!=last_link_x || dlasty!=last_link_y))
1634 {
1635 last_link_x=dlastx;
1636 last_link_y=dlasty;
1637 the_game->need_refresh();
1638 }
1639
1640 if (dev_menu && dev_menu->handle_event(ev,screen)) return ;
1641
1642 if (!current_level) return ;
1643
1644 for (x=0; x<total_pals; x++)
1645 pal_wins[x]->handle_event(ev);
1646 if (ev.type==EV_MOUSE_MOVE)
1647 {
1648 dlastx=last_demo_mx;
1649 dlasty=last_demo_my;
1650 }
1651 if (dev_console && dev_console->handle_event(ev))
1652 return;
1653
1654 if (ev.type==EV_KEY && ev.key==JK_F2)
1655 write_PCX(screen,pal,"scrnshot.pcx");
1656 else if (ev.type==EV_KEY && ev.key==JK_F3)
1657 {
1658 char name[100];
1659 sprintf(name,"shot%04d.pcx",screen_shot_on++);
1660 write_PCX(screen,pal,name);
1661 } else if (ev.type==EV_KEY && ev.key==JK_F5)
1662 {
1663 if (sshot_fcount!=-1)
1664 {
1665 sshot_fcount=-1;
1666 the_game->show_help(symbol_str("seqs_off"));
1667 }
1668 else
1669 {
1670 sshot_fcount=0;
1671 the_game->show_help(symbol_str("seqs_on"));
1672 }
1673 }
1674
1675 switch (state)
1676 {
1677 case DEV_MOUSE_RELEASE :
1678 {
1679 if (!ev.mouse_button)
1680 state=DEV_SELECT;
1681 } break;
1682
1683 case DEV_CREATE_OBJECT :
1684 {
1685 if (!ev.mouse_button)
1686 state=DEV_MOVE_OBJECT;
1687 } break;
1688
1689
1690 case DEV_MOVE_OBJECT :
1691 {
1692 if (!edit_object)
1693 { state=DEV_SELECT; }
1694 else
1695 {
1696 if (ev.type==EV_MOUSE_MOVE)
1697 {
1698 the_game->mouse_to_game(last_demo_mx,last_demo_my,edit_object->x,edit_object->y);
1699 edit_object->x=snap_x(edit_object->x);
1700 edit_object->y=snap_y(edit_object->y);
1701 the_game->need_refresh();
1702 }
1703 else if (ev.mouse_button==1 && ev.window==NULL)
1704 {
1705 state=DEV_MOUSE_RELEASE;
1706 selected_object=edit_object=NULL;
1707 }
1708 if (ev.window==NULL && ev.type==EV_KEY && ev.key=='d')
1709 {
1710 int32_t xv=0,yv=100;
1711 edit_object->try_move(edit_object->x,edit_object->y,xv,yv,1);
1712 edit_object->y+=yv;
1713 state=DEV_SELECT;
1714 selected_object=edit_object=NULL;
1715 }
1716 }
1717 } break;
1718
1719
1720 case DEV_MOVE_LIGHT :
1721 {
1722 if (edit_light)
1723 {
1724 if (ev.type==EV_MOUSE_MOVE)
1725 {
1726 the_game->mouse_to_game(last_demo_mx,last_demo_my,edit_light->x,edit_light->y);
1727 edit_light->x=snap_x(edit_light->x);
1728 edit_light->y=snap_y(edit_light->y);
1729
1730 edit_light->calc_range();
1731 the_game->need_refresh();
1732 } else if (ev.type==EV_KEY)
1733 {
1734 int rd=0;
1735 switch (ev.key)
1736 {
1737 case '+' :
1738 {
1739 if (edit_light->type==9)
1740 {
1741 if (edit_light->inner_radius<64)
1742 { edit_light->inner_radius++; rd=1; }
1743 } else { edit_light->outer_radius++; rd=1; }
1744 } break;
1745 case '-' :
1746 {
1747 if (edit_light->type==9)
1748 {
1749 if (edit_light->inner_radius>0)
1750 { edit_light->inner_radius--; rd=1; }
1751 } else if (edit_light->outer_radius>edit_light->inner_radius+1)
1752 { edit_light->outer_radius--; rd=1; }
1753 } break;
1754 case JK_RIGHT :
1755 {
1756 if (edit_light->type==9)
1757 { edit_light->xshift++; rd=1; }
1758 else if (edit_light->xshift>0)
1759 { edit_light->xshift--; rd=1; }
1760 } break;
1761 case JK_LEFT :
1762 {
1763 if (edit_light->type==9)
1764 {
1765 if (edit_light->xshift>1)
1766 { edit_light->xshift--; rd=1; }
1767 }
1768 else
1769 { edit_light->xshift++; rd=1; }
1770 } break;
1771 case JK_UP :
1772 {
1773 if (edit_light->type==9)
1774 { edit_light->yshift++; rd=1; }
1775 else if (edit_light->yshift>0)
1776 { edit_light->yshift--; rd=1; }
1777 } break;
1778 case JK_DOWN :
1779 {
1780 if (edit_light->type==9)
1781 {
1782 if (edit_light->yshift>1)
1783 { edit_light->yshift--; rd=1; }
1784 }
1785 else
1786 { edit_light->yshift++; rd=1; }
1787 } break;
1788
1789 }
1790 if (rd)
1791 {
1792 edit_light->calc_range();
1793 the_game->need_refresh();
1794 }
1795
1796 }
1797 }
1798
1799 if ((ev.mouse_button==1 && ev.window==NULL) || !edit_light)
1800 state=DEV_MOUSE_RELEASE;
1801 } break;
1802
1803
1804 case DEV_DRAG_AREA_BOTTOM :
1805 {
1806 if (current_area)
1807 {
1808 int32_t gx,gy;
1809 the_game->mouse_to_game(last_demo_mx,last_demo_my,gx,gy);
1810 if (gx>current_area->x && gy>current_area->y)
1811 {
1812 if (gx-current_area->x!=current_area->w || gy-current_area->y!=current_area->h)
1813 {
1814 the_game->need_refresh();
1815 current_area->w=gx-current_area->x;
1816 current_area->h=gy-current_area->y;
1817 }
1818 }
1819 if (ev.type==EV_MOUSE_BUTTON && !ev.mouse_button)
1820 {
1821 current_area->active=0;
1822 state=DEV_SELECT;
1823 }
1824 }
1825 } break;
1826
1827 case DEV_DRAG_AREA_TOP :
1828 {
1829 if (current_area)
1830 {
1831 int32_t gx,gy;
1832 the_game->mouse_to_game(last_demo_mx,last_demo_my,gx,gy);
1833 if (gx<current_area->x+current_area->w && gy<current_area->y+current_area->h)
1834 {
1835 if (gx!=current_area->x || gy!=current_area->y)
1836 {
1837 the_game->need_refresh();
1838 current_area->x=gx;
1839 current_area->y=gy;
1840 }
1841 }
1842 if (ev.type==EV_MOUSE_BUTTON && !ev.mouse_button)
1843 {
1844 current_area->active=0;
1845 state=DEV_SELECT;
1846 }
1847 }
1848 } break;
1849
1850 case DEV_SELECT :
1851 {
1852 if (dev&EDIT_MODE)
1853 {
1854 game_object *old=selected_object;
1855 selected_object=NULL;
1856 if (ev.window==NULL)
1857 {
1858 int32_t rx,ry;
1859 the_game->mouse_to_game(last_demo_mx,last_demo_my,rx,ry);
1860
1861 if (!(dev & MAP_MODE))
1862 {
1863 if (dev&DRAW_PEOPLE_LAYER)
1864 selected_object=current_level->find_object(rx,ry);
1865 light_source *old_light=selected_light;
1866 if (selected_object)
1867 selected_light=NULL;
1868 else
1869 selected_light=find_light(rx,ry);
1870 if (selected_light!=old_light)
1871 the_game->need_refresh();
1872 } else { selected_light=NULL; }
1873
1874 if (edit_mode==ID_DMODE_DRAW)
1875 {
1876 if (ev.mouse_button==1 && !selected_object && !selected_light)
1877 {
1878 int32_t xs,ys;
1879 the_game->ftile_on(last_demo_mx,last_demo_my,xs,ys);
1880 if (xs>=0 && ys>=0 && xs<current_level->foreground_width() &&
1881 ys<current_level->foreground_height())
1882 current_level->put_fg(xs,ys,raise_all ? make_above_tile(cur_fg) : cur_fg);
1883 the_game->need_refresh();
1884 } else if (ev.mouse_button==1 && !selected_object && !selected_light)
1885 {
1886 int32_t xs,ys;
1887 the_game->btile_on(last_demo_mx,last_demo_my,xs,ys);
1888 if (xs>=0 && ys>=0 && xs<current_level->background_width() &&
1889 ys<current_level->background_height())
1890 current_level->put_bg(xs,ys,cur_fg);
1891 the_game->need_refresh();
1892 }
1893 } else if (edit_mode==ID_DMODE_AREA)
1894 area_handle_input(ev);
1895 else if (edit_mode==ID_DMODE_PICK)
1896 pick_handle_input(ev);
1897 }
1898
1899 if (old!=selected_object)
1900 the_game->need_refresh();
1901
1902
1903 if (ev.mouse_button)
1904 {
1905 if (selected_object)
1906 {
1907 if (edit_object && edit_object!=selected_object)
1908 edit_object->add_object(selected_object);
1909
1910 if (oedit)
1911 close_oedit_window();
1912
1913 int bw=20+6,bh=16+6;
1914
1915 oedit=wm->new_window(prop->getd("oedit x",0),
1916 prop->getd("oedit y",0),
1917 -1,-1,new button_box(0,0,ID_NULL,1,
1918 new button(bw*0,0,DEV_OEDIT_OK,cache.img(dev_ok),
1919 new button(bw*1,0,DEV_OEDIT_MOVE,cache.img(dev_move),
1920 new button(bw*2,0,DEV_OEDIT_FRONT,cache.img(dev_front),
1921 new button(bw*3,0,DEV_OEDIT_BACK,cache.img(dev_back),
1922 new button(bw*4,0,DEV_OEDIT_COPY,cache.img(dev_copy),
1923 new button(bw*0,bh*1,DEV_OEDIT_DELETE,cache.img(dev_del),
1924 NULL)))))),
1925 new button(bw*5,bh*0,DEV_OEDIT_AI,cache.img(dev_ai),
1926
1927 new button_box(bw*1,bh*1,DEV_OEDIT_CHAR_BOX,0,
1928 new button(bw*1,bh*1,DEV_OEDIT_LEFT,cache.img(dev_char_left),
1929 new button(bw*2,bh*1,DEV_OEDIT_RIGHT,cache.img(dev_char_right),NULL)),
1930
1931 new button(bw*3,bh*1,DEV_OBJECTS_DELETE,cache.img(dev_objects),
1932 new button(bw*4,bh*1,DEV_LIGHTS_DELETE,cache.img(dev_lights),NULL))))),
1933 symbol_str("l_EDIT"));
1934
1935
1936 edit_object=selected_object;
1937 } else if (selected_light)
1938 {
1939 if (ledit)
1940 {
1941 prop->setd("ledit x",ledit->x);
1942 prop->setd("ledit x",ledit->y);
1943 wm->close_window(ledit);
1944 }
1945 int bw=20+6,bh=16+6,th=wm->font()->height()+4;
1946 edit_light=selected_light;
1947 if (edit_object)
1948 {
1949 edit_object->add_light(edit_light);
1950 edit_light->known=1;
1951 }
1952 ledit=wm->new_window(prop->getd("ledit x",0),
1953 prop->getd("ledit y",0),
1954 -1,-1,
1955 new button_box(0,0,ID_NULL,1,
1956 new button(bw*0,0,DEV_LEDIT_OK,cache.img(dev_ok),
1957 new button(bw*1,0,DEV_LEDIT_MOVE,cache.img(dev_move),
1958 new button(bw*2,0,DEV_LEDIT_COPY,cache.img(dev_copy),
1959 new button(bw*3,0,DEV_LEDIT_DEL,cache.img(dev_del),NULL)))),
1960 new text_field(0,bh,DEV_LEDIT_W, "W ","******",edit_light->xshift,
1961 new text_field(0,bh+th*1,DEV_LEDIT_H, "H ","******",edit_light->yshift,
1962 new text_field(0,bh+th*2,DEV_LEDIT_R1,"R1","******",(int)(edit_light->inner_radius),
1963 new text_field(0,bh+th*3,DEV_LEDIT_R2,"R2","******",(int)(edit_light->outer_radius),
1964 NULL))))));
1965 }
1966 else if (ev.window==NULL)
1967 {
1968 if (dlastx>=0 && dlasty>=0 && edit_mode==ID_DMODE_DRAW)
1969 {
1970 if ((dev & DRAW_FG_LAYER) && ev.mouse_button==1)
1971 {
1972 the_game->ftile_on(last_demo_mx,last_demo_my,x,y);
1973 if (x>=0 && y>=0 && x<current_level->foreground_width() &&
1974 y<current_level->foreground_height())
1975 the_game->put_fg(x,y,raise_all ? make_above_tile(cur_fg) : cur_fg);
1976 }
1977 if ((dev & DRAW_BG_LAYER) && ev.mouse_button==2)
1978 {
1979 the_game->btile_on(last_demo_mx,last_demo_my,x,y);
1980 if (x>=0 && y>=0 && x<current_level->background_width() &&
1981 y<current_level->background_height())
1982 the_game->put_bg(x,y,cur_bg);
1983 }
1984 }
1985 }
1986 }
1987 }
1988 }
1989 default:
1990 break;
1991 }
1992
1993 switch (ev.type)
1994 {
1995 case EV_MESSAGE :
1996 {
1997 switch (ev.message.id)
1998 {
1999 case ID_DMODE_DRAW :
2000 case ID_DMODE_PICK :
2001 case ID_DMODE_FILL :
2002 case ID_DMODE_LINE :
2003 case ID_DMODE_RECT :
2004 case ID_DMODE_BAR :
2005 case ID_DMODE_AREA :
2006 {
2007 edit_mode=ev.message.id;
2008 } break;
2009 /* case ID_ENLARGE_RENDER :
2010 {
2011 if (!small_render)
2012 double_render();
2013 else
2014 single_render();
2015
2016 view_shift_disabled=!view_shift_disabled;
2017 } break; */
2018
2019 case ID_SEARCH :
2020 {
2021 toggle_search_window();
2022 } break;
2023 case ID_SEARCH_FOREWARD :
2024 { search_forward();
2025 } break;
2026 case ID_SEARCH_BACKWARD :
2027 { search_forward();
2028 } break;
2029 case ID_CANCEL :
2030 {
2031 if (mess_win)
2032 {
2033 wm->close_window(mess_win);
2034 mess_win=NULL;
2035 } break;
2036 } break;
2037 case ID_LEVEL_LOAD :
2038 {
2039 if (!mess_win)
2040 {
2041 mess_win=file_dialog(symbol_str("level_name"),current_level ? current_level->name() : "",
2042 ID_LEVEL_LOAD_OK,symbol_str("ok_button"),ID_CANCEL,symbol_str("cancel_button"),
2043 symbol_str("FILENAME"),ID_MESS_STR1);
2044 wm->grab_focus(mess_win);
2045 }
2046 } break;
2047 case ID_LEVEL_LOAD_OK :
2048 {
2049 char cmd[100];
2050 sprintf(cmd,"load %s",mess_win->read(ID_MESS_STR1));
2051 dev_cont->do_command(cmd,ev);
2052 wm->push_event(new event(ID_CANCEL,NULL)); // close window
2053 } break;
2054 case ID_GAME_SAVE :
2055 {
2056 current_level->save("savegame.spe",1);
2057 the_game->show_help(symbol_str("saved_game"));
2058 the_game->need_refresh();
2059 } break;
2060 case ID_LEVEL_SAVE :
2061 { if (current_level)
2062 {
2063 if (current_level->save(current_level->name(),0))
2064 {
2065 char msg[100];
2066 sprintf(msg,symbol_str("saved_level"),current_level->name());
2067 the_game->show_help(msg);
2068 the_game->need_refresh();
2069 }
2070 }
2071 else the_game->show_help("no current level, cannot save");
2072 } break;
2073 case ID_LEVEL_SAVEAS :
2074 {
2075 if (!mess_win)
2076 {
2077 mess_win=file_dialog(symbol_str("saveas_name"),current_level ? current_level->name() : "untitled.spe",
2078 ID_LEVEL_SAVEAS_OK,symbol_str("ok_button"),
2079 ID_CANCEL,symbol_str("cancel_button"),
2080 symbol_str("FILENAME"),ID_MESS_STR1);
2081 wm->grab_focus(mess_win);
2082 }
2083 } break;
2084 case ID_LEVEL_SAVEAS_OK :
2085 {
2086 if (current_level)
2087 {
2088 current_level->set_name(mess_win->read(ID_MESS_STR1));
2089 wm->push_event(new event(ID_CANCEL,NULL)); // close window after save
2090 wm->push_event(new event(ID_LEVEL_SAVE,NULL));
2091 }
2092 } break;
2093 case ID_EDIT_SAVE :
2094 {
2095 do_command("esave",ev);
2096 the_game->show_help(symbol_str("edit_saved"));
2097 } break;
2098 case ID_CACHE_PROFILE :
2099 {
2100 if (current_level && !cache.prof_is_on())
2101 {
2102 cache.prof_init();
2103 the_game->show_help("Cache profiling is now on.");
2104 }
2105 else the_game->show_help("Cache profiling is already on!");
2106 } break;
2107
2108 case ID_CACHE_PROFILE_END : // ask the user for a file name to save as
2109 {
2110 if (cache.prof_is_on())
2111 {
2112 cache.prof_uninit();
2113 the_game->show_help(symbol_str("prof_off"));
2114 } else the_game->show_help(symbol_str("prof"));
2115 } break;
2116
2117 case ID_LEVEL_NEW :
2118 {
2119 if (!mess_win)
2120 {
2121 mess_win=wm->new_window(xres/2,yres/2,-1,-1,
2122 new button(10,20,ID_LEVEL_NEW_OK,symbol_str("YES"),
2123 new button(40,20,ID_CANCEL,symbol_str("NO"),
2124 new info_field(0,0,ID_NULL,symbol_str("sure?"),NULL))),symbol_str("New?"));
2125 wm->grab_focus(mess_win);
2126 }
2127 } break;
2128 case ID_LEVEL_NEW_OK :
2129 {
2130 wm->push_event(new event(ID_CANCEL,NULL)); // close_window
2131 if (current_level)
2132 delete current_level;
2133 current_level=new level(100,100,"untitled.spe");
2134 } break;
2135 case ID_LEVEL_RESIZE :
2136 {
2137 if (!mess_win)
2138 {
2139 int h=wm->font()->height()+8;
2140 mess_win=wm->new_window(xres/2,yres/2,-1,-1,
2141 new text_field(0,h*0,ID_MESS_STR1,symbol_str("width_"),"****",
2142 current_level ? current_level->foreground_width() : 100,
2143 new text_field(0,h*1,ID_MESS_STR2,symbol_str("height_"),"****",
2144 current_level ? current_level->foreground_height() : 100,
2145 new button(10,h*4,ID_LEVEL_RESIZE_OK,symbol_str("ok_button"),
2146 new button(40,h*4,ID_CANCEL,symbol_str("cancel_button"),NULL)))),symbol_str("_scroll"));
2147 }
2148 } break;
2149 case ID_LEVEL_RESIZE_OK :
2150 {
2151 if (current_level)
2152 {
2153 current_level->set_size(atoi(mess_win->read(ID_MESS_STR1)),
2154 atoi(mess_win->read(ID_MESS_STR2)));
2155 } else the_game->show_help("Create a level first!");
2156 wm->push_event(new event(ID_CANCEL,NULL)); // close_window
2157 } break;
2158
2159 case ID_SUSPEND :
2160 {
2161 dev^=SUSPEND_MODE;
2162 if (dev&SUSPEND_MODE)
2163 the_game->show_help(symbol_str("suspend_on"));
2164 else
2165 the_game->show_help(symbol_str("suspend_off"));
2166 } break;
2167 case ID_PLAY_MODE :
2168 {
2169 dev^=EDIT_MODE;
2170 } break;
2171 case ID_QUIT :
2172 {
2173 if (confirm_quit())
2174 do_command("quit",ev);
2175 } ;
2176 case ID_TOGGLE_MAP :
2177 {
2178 if (dev&MAP_MODE) dev-=MAP_MODE;
2179 else dev|=MAP_MODE;
2180 the_game->need_refresh();
2181 } break;
2182 case ID_TOGGLE_LIGHT :
2183 {
2184 dev^=DRAW_LIGHTS;
2185 the_game->need_refresh();
2186 } break;
2187 case ID_RECORD_DEMO :
2188 {
2189 if (!mess_win)
2190 {
2191 int h=wm->font()->height()+8;
2192 mess_win=wm->new_window(xres/2,yres/2,-1,-1,
2193 new text_field(0,h*0,ID_RECORD_DEMO_FILENAME,
2194 "demo filename","*******************",
2195 "demo.dat",
2196 new button(10,h*2,ID_RECORD_DEMO_OK,symbol_str("ok_button"),
2197 new button(40,h*2,ID_CANCEL,symbol_str("cancel_button"),NULL))));
2198 }
2199 } break;
2200
2201 case ID_RECORD_DEMO_OK :
2202 {
2203 demo_man.set_state(demo_manager::RECORDING,mess_win->read(ID_RECORD_DEMO_FILENAME));
2204 wm->push_event(new event(ID_CANCEL,NULL)); // close window
2205 } break;
2206
2207 case ID_PLAY_DEMO :
2208 {
2209 if (!mess_win)
2210 {
2211 int h=wm->font()->height()+8;
2212 mess_win=wm->new_window(xres/2,yres/2,-1,-1,
2213 new text_field(0,h*0,ID_PLAY_DEMO_FILENAME,
2214 "demo filename","*******************",
2215 "demo.dat",
2216 new button(10,h*2,ID_PLAY_DEMO_OK,symbol_str("ok_button"),
2217 new button(40,h*2,ID_CANCEL,symbol_str("cancel_button"),NULL))));
2218 }
2219 } break;
2220
2221 case ID_PLAY_DEMO_OK :
2222 {
2223 demo_man.set_state(demo_manager::PLAYING,mess_win->read(ID_PLAY_DEMO_FILENAME));
2224 wm->close_window(mess_win);
2225 mess_win=NULL;
2226 } break;
2227
2228 case ID_SET_SCROLL :
2229 {
2230 if (!mess_win)
2231 {
2232 int h=wm->font()->height()+8;
2233 mess_win=wm->new_window(xres/2,yres/2,-1,-1,
2234 new text_field(0,h*0,ID_MESS_STR1,symbol_str("x_mul"),"****",bg_xmul,
2235 new text_field(0,h*1,ID_MESS_STR2,symbol_str("x_div"),"****",bg_xdiv,
2236 new text_field(0,h*2,ID_MESS_STR3,symbol_str("y_mul"),"****",bg_ymul,
2237 new text_field(0,h*3,ID_MESS_STR4,symbol_str("y_div"),"****",bg_ydiv,
2238 new button(10,h*4,ID_SET_SCROLL_CHECK,symbol_str("ok_button"),
2239 new button(40,h*4,ID_CANCEL,symbol_str("cancel_button"),NULL)))))),symbol_str("_scroll"));
2240 }
2241 } break;
2242 case ID_SET_SCROLL_CHECK :
2243 {
2244 int tbg_xmul=atoi(mess_win->read(ID_MESS_STR1));
2245 int tbg_xdiv=atoi(mess_win->read(ID_MESS_STR2));
2246 int tbg_ymul=atoi(mess_win->read(ID_MESS_STR3));
2247 int tbg_ydiv=atoi(mess_win->read(ID_MESS_STR4));
2248
2249 if ( (((float)tbg_xmul/(float)tbg_xdiv) < ((float)bg_xmul/(float)bg_xdiv)) ||
2250 (((float)tbg_ymul/(float)tbg_ydiv) < ((float)bg_ymul/(float)bg_ydiv)))
2251 {
2252 int h=wm->font()->height()+8;
2253
2254 warn_win=wm->new_window(xres/2-40,yres/2-40,-1,-1,
2255 new info_field(0,0,ID_NULL,
2256 symbol_str("back_loss"),
2257 new button(10,h*4,ID_SET_SCROLL_OK,symbol_str("ok_button"),
2258 new button(40,h*4,ID_WARN_CANCEL,symbol_str("cancel_button"),NULL))),
2259 symbol_str("WARNING"));
2260 wm->grab_focus(warn_win);
2261 } else wm->push_event(new event(ID_SET_SCROLL_OK,NULL));
2262 } break;
2263 case ID_WARN_CANCEL :
2264 {
2265 wm->close_window(warn_win); warn_win=NULL;
2266 wm->push_event(new event(ID_CANCEL,NULL));
2267 } break;
2268 case ID_SET_SCROLL_OK :
2269 {
2270 if (warn_win) { wm->close_window(warn_win); warn_win=NULL; }
2271 bg_xmul=atoi(mess_win->read(ID_MESS_STR1));
2272 bg_xdiv=atoi(mess_win->read(ID_MESS_STR2));
2273 bg_ymul=atoi(mess_win->read(ID_MESS_STR3));
2274 bg_ydiv=atoi(mess_win->read(ID_MESS_STR4));
2275 wm->push_event(new event(ID_CANCEL,NULL)); // close window
2276 } break;
2277
2278 case ID_CENTER_PLAYER :
2279 {
2280 do_command("center",ev); break;
2281 } break;
2282
2283 case ID_INTERPOLATE_DRAW :
2284 {
2285 interpolate_draw=!interpolate_draw;
2286 } break;
2287
2288 case ID_DISABLE_AUTOLIGHT :
2289 {
2290 disable_autolight=!disable_autolight;
2291 } break;
2292
2293 case ID_ADD_PALETTE :
2294 {
2295 if (!mess_win)
2296 {
2297 int h=wm->font()->height()+8;
2298 mess_win=wm->new_window(xres/2,yres/2,-1,-1,
2299 new text_field(0,h*0,ID_MESS_STR1,symbol_str("ap_width"),"****",2,
2300 new text_field(0,h*1,ID_MESS_STR2,symbol_str("ap_height"),"****",2,
2301 new text_field(0,h*2,ID_MESS_STR3,symbol_str("ap_name"),"***********","pal",
2302 new button(10,h*3,ID_ADD_PALETTE_OK,symbol_str("ok_button"),
2303 new button(40,h*3,ID_CANCEL,symbol_str("cancel_button"),NULL))))),symbol_str("ap_pal"));
2304 }
2305 } break;
2306 case ID_ADD_PALETTE_OK :
2307 {
2308 char name[70];
2309 sprintf(name,"(add_palette \"%s\" %d %d)",mess_win->read(ID_MESS_STR3),
2310 atoi(mess_win->read(ID_MESS_STR1)),
2311 atoi(mess_win->read(ID_MESS_STR2)));
2312 char const *s=name;
2313 LObject::Compile(s)->Eval();
2314 wm->push_event(new event(ID_CANCEL,NULL)); // close window
2315 } break;
2316 case ID_TOGGLE_DELAY :
2317 {
2318 the_game->toggle_delay(); break;
2319 } break;
2320
2321 case ID_SMALL_MODE :
2322 {
2323 make_screen_size(311,160); break;
2324 } break;
2325 case ID_CLEAR_WEAPONS :
2326 {
2327 event ev;
2328 do_command("clear_weapons",ev);
2329 } break;
2330 case ID_GOD_MODE :
2331 {
2332 for (view *v=player_list; v; v=v->next)
2333 v->god=!v->god;
2334 } break;
2335 case ID_MOUSE_SCROLL :
2336 {
2337 mouse_scrolling=!mouse_scrolling;
2338 prop->setd("mouse_scrolling",mouse_scrolling);
2339 if (mouse_scrolling)
2340 the_game->show_help(symbol_str("ms_on"));
2341 else
2342 the_game->show_help(symbol_str("ms_off"));
2343 } break;
2344
2345 case ID_LOCK_PALETTES :
2346 {
2347 palettes_locked=!palettes_locked;
2348 prop->setd("palettes_locked",palettes_locked);
2349 if (palettes_locked)
2350 the_game->show_help(symbol_str("pal_lock"));
2351 else the_game->show_help(symbol_str("pal_unlock"));
2352 } break;
2353
2354 case ID_DISABLE_VIEW_SHIFT :
2355 {
2356 view_shift_disabled=!view_shift_disabled;
2357 prop->setd("view_shift_disabled",view_shift_disabled);
2358 if (view_shift_disabled)
2359 the_game->show_help(symbol_str("vs_dis"));
2360 else the_game->show_help(symbol_str("vs_en"));
2361 } break;
2362
2363 case ID_WIN_FORE :
2364 {
2365 toggle_fgw();
2366 } break;
2367 case ID_WIN_BACK :
2368 {
2369 toggle_bgw();
2370 } break;
2371 case ID_WIN_OBJECTS :
2372 {
2373 toggle_omenu();
2374 } break;
2375 case ID_WIN_PALETTES :
2376 {
2377 toggle_pmenu();
2378 } break;
2379 case ID_WIN_LIGHTING :
2380 {
2381 toggle_light_window();
2382 } break;
2383 case ID_WIN_LAYERS :
2384 {
2385 toggle_show_menu();
2386 } break;
2387 case ID_WIN_CONSOLE :
2388 {
2389 if (dev_console) dev_console->toggle();
2390 } break;
2391 case ID_WIN_TOOLBAR :
2392 {
2393 toggle_toolbar();
2394 } break;
2395
2396 case DEV_AMBIENT :
2397 { if (!ambw) make_ambient(); } break;
2398 case DEV_AREA_OK :
2399 { close_area_win(1); } break;
2400 case DEV_AREA_DELETE :
2401 { close_area_win(0);
2402 if (current_area && current_level)
2403 {
2404 if (current_level->area_list==current_area)
2405 current_level->area_list=current_level->area_list->next;
2406 else
2407 {
2408 area_controller *a=current_level->area_list,*l=NULL;
2409 for (; a!=current_area && a; a=a->next) { l=a; }
2410 l->next=a->next;
2411 delete a;
2412 }
2413 current_area=NULL;
2414 the_game->need_refresh();
2415 }
2416 } break;
2417 case DEV_AI_OK :
2418 close_ai_window(); break;
2419 case DEV_OEDIT_AI :
2420 make_ai_window(edit_object); break;
2421 case DEV_OBJECTS_DELETE :
2422 {
2423 if (edit_object)
2424 {
2425 for (int i=0; i<edit_object->total_objects(); i++)
2426 edit_object->remove_object(edit_object->get_object(0));
2427 the_game->need_refresh();
2428 }
2429 } break;
2430
2431 case DEV_LIGHTS_DELETE :
2432 {
2433 if (edit_object)
2434 {
2435 for (int i=0; i<edit_object->total_lights(); i++)
2436 edit_object->remove_light(edit_object->get_light(0));
2437 the_game->need_refresh();
2438 }
2439 } break;
2440
2441 case DEV_LEDIT_DEL :
2442 {
2443 prop->setd("ledit x",ledit->x);
2444 prop->setd("ledit y",ledit->y);
2445 wm->close_window(ledit); ledit=NULL;
2446 if (current_level)
2447 current_level->remove_light(edit_light);
2448 else
2449 delete_light(edit_light);
2450 edit_light=NULL;
2451 the_game->need_refresh();
2452 } break;
2453 case DEV_LEDIT_OK :
2454 {
2455 edit_light->xshift=atoi(ledit->read(DEV_LEDIT_W));
2456 edit_light->yshift=atoi(ledit->read(DEV_LEDIT_H));
2457 edit_light->inner_radius=atoi(ledit->read(DEV_LEDIT_R1));
2458 edit_light->outer_radius=atoi(ledit->read(DEV_LEDIT_R2));
2459 if (edit_light->outer_radius<=edit_light->inner_radius)
2460 {
2461 edit_light->inner_radius=edit_light->outer_radius-1;
2462 if (edit_light->inner_radius<1)
2463 {
2464 edit_light->inner_radius=1;
2465 edit_light->outer_radius=2;
2466 }
2467 }
2468
2469 edit_light->calc_range();
2470 edit_light=NULL;
2471 prop->setd("ledit x",ledit->x);
2472 prop->setd("ledit y",ledit->y);
2473 wm->close_window(ledit); ledit=NULL;
2474 the_game->need_refresh();
2475 } break;
2476 case DEV_LEDIT_MOVE :
2477 {
2478 prop->setd("ledit x",ledit->x);
2479 prop->setd("ledit y",ledit->y);
2480 wm->close_window(ledit); ledit=NULL;
2481 state=DEV_MOVE_LIGHT;
2482 } break;
2483 case DEV_LEDIT_COPY :
2484 {
2485 edit_light=edit_light->copy();
2486 prop->setd("ledit x",ledit->x);
2487 prop->setd("ledit y",ledit->y);
2488 wm->close_window(ledit); ledit=NULL;
2489 state=DEV_MOVE_LIGHT;
2490 } break;
2491
2492
2493 case DEV_LIGHT0 :
2494 case DEV_LIGHT1 :
2495 case DEV_LIGHT2 :
2496 case DEV_LIGHT3 :
2497 case DEV_LIGHT4 :
2498 case DEV_LIGHT5 :
2499 case DEV_LIGHT6 :
2500 case DEV_LIGHT7 :
2501 case DEV_LIGHT8 :
2502 case DEV_LIGHT9 :
2503 {
2504 int32_t lx,ly;
2505 the_game->mouse_to_game(last_demo_mx,last_demo_my,lx,ly);
2506 lx=snap_x(lx);
2507 ly=snap_y(ly);
2508 edit_light=add_light_source(ev.message.id-DEV_LIGHT0,lx,ly,
2509 atoi(lightw->read(DEV_LIGHTR1)),
2510 atoi(lightw->read(DEV_LIGHTR2)),
2511 atoi(lightw->read(DEV_LIGHTW)),
2512 atoi(lightw->read(DEV_LIGHTH)));
2513 state=DEV_MOVE_LIGHT;
2514 } break;
2515 case ID_RAISE_ALL :
2516 {
2517 raise_all=!raise_all;
2518 prop->setd("raise_all",raise_all);
2519 if (raise_all)
2520 the_game->show_help(symbol_str("fg_r"));
2521 else
2522 the_game->show_help(symbol_str("fg_l"));
2523 } break;
2524 case DEV_OEDIT_COPY :
2525 {
2526 game_object *use=copy_object;
2527 if (!use) use=edit_object;
2528 if (use)
2529 {
2530 game_object *old=use;
2531 close_oedit_window();
2532 if (use->controller())
2533 the_game->show_help(symbol_str("no_clone"));
2534 else
2535 {
2536 edit_object=old->copy();
2537
2538 current_level->add_object(edit_object);
2539 the_game->need_refresh();
2540 state=DEV_MOVE_OBJECT;
2541
2542 close_oedit_window();
2543 copy_object=NULL;
2544 }
2545 }
2546 } break;
2547 case DEV_OEDIT_LEFT :
2548 {
2549 if (edit_object)
2550 {
2551 the_game->need_refresh();
2552 edit_object->direction=-1;
2553 }
2554 } break;
2555 case DEV_OEDIT_RIGHT :
2556 {
2557 if (edit_object)
2558 {
2559 the_game->need_refresh();
2560 edit_object->direction=1;
2561 }
2562 } break;
2563
2564
2565 case DEV_COMMAND_OK :
2566 {
2567 char cmd[100];
2568 strcpy(cmd,commandw->inm->get(DEV_COMMAND)->read());
2569 prop->setd("commandw x",commandw->x);
2570 prop->setd("commandw y",commandw->y);
2571 wm->close_window(commandw);
2572 commandw=NULL;
2573 do_command(cmd,ev);
2574 } break;
2575
2576 case ID_SHOW_FPS :
2577 { fps_on=!fps_on; } break;
2578 case ID_PROFILE :
2579 { profile_toggle();
2580 profile_on=!profile_on;
2581 } break;
2582
2583 case ID_TOGGLE_NAMES : { show_names=!show_names; } break;
2584 case DEV_QUIT : the_game->end_session(); break;
2585 case DEV_EDIT_FG : dev=1; break; //the_game->draw(); break;
2586 case DEV_EDIT_BG : dev=2; break; //the_game->draw(); break;
2587 case DEV_EDIT_FGBG : dev=3; break; //the_game->draw(); break;
2588 case DEV_PLAY : dev=0; break; //the_game->draw(); break;
2589 case SHOW_FOREGROUND :
2590 { dev=dev^DRAW_FG_LAYER; the_game->need_refresh(); } break;
2591 case SHOW_FOREGROUND_BOUND :
2592 { dev=dev^DRAW_FG_BOUND_LAYER; the_game->need_refresh(); } break;
2593 case SHOW_BACKGROUND :
2594 { dev=dev^DRAW_BG_LAYER; the_game->need_refresh(); } break;
2595 case SHOW_CHARACTERS :
2596 { dev=dev^DRAW_PEOPLE_LAYER; the_game->need_refresh(); } break;
2597 case SHOW_LIGHT :
2598 { dev=dev^DRAW_LIGHTS; the_game->need_refresh(); } break;
2599 case SHOW_LINKS :
2600 { dev=dev^DRAW_LINKS; the_game->need_refresh(); } break;
2601
2602
2603 case DEV_CREATE :
2604 {
2605 int val=get_omenu_item(((pick_list *)ev.message.data)->get_selection());
2606 char cmd[100];
2607 sprintf(cmd,"create %s",object_names[val]);
2608 do_command(cmd,ev);
2609 state=DEV_CREATE_OBJECT;
2610 dev|=(EDIT_MODE | DRAW_PEOPLE_LAYER);
2611 }
2612 break;
2613
2614 case DEV_PALETTE :
2615 {
2616 int val=((pick_list *)ev.message.data)->get_selection();
2617 pal_wins[val]->open_window();
2618 } break;
2619
2620 case DEV_MUSIC_PICKLIST :
2621 {
2622 /* int *val=((int *)((pick_list *)ev.message.data)->read());
2623 if (current_song) delete current_song;
2624 current_song=new song(song_list[*val]);
2625 current_song->play(); */
2626 }
2627 break;
2628
2629 case DEV_OEDIT_OK :
2630 { close_oedit_window(); } break;
2631
2632 case DEV_OEDIT_DELETE :
2633 {
2634 selected_object=edit_object;
2635 do_command("delete",ev);
2636 close_oedit_window();
2637 }
2638 break;
2639
2640 case DEV_OEDIT_FRONT :
2641 {
2642 do_command("to_front",ev);
2643 close_oedit_window();
2644 }
2645 break;
2646
2647 case DEV_OEDIT_BACK :
2648 {
2649 do_command("to_back",ev);
2650 close_oedit_window();
2651 }
2652 break;
2653
2654 case DEV_OEDIT_MOVE :
2655 {
2656 game_object *o=edit_object;
2657 close_oedit_window();
2658 edit_object=o;
2659 do_command("move",ev);
2660 }
2661 break;
2662 }
2663 } break;
2664
2665
2666 case EV_CLOSE_WINDOW :
2667 {
2668 if (ev.window)
2669 {
2670 if (ev.window==commandw)
2671 {
2672 prop->setd("commandw x",commandw->x);
2673 prop->setd("commandw y",commandw->y);
2674 wm->close_window(commandw);
2675 commandw=NULL;
2676 } else if (ev.window==oedit)
2677 close_oedit_window();
2678 else if (ev.window==ambw)
2679 { wm->close_window(ambw); ambw=NULL; }
2680 else if (ev.window==backw) toggle_bgw();
2681 else if (ev.window==forew) toggle_fgw();
2682 else if (ev.window==lightw) toggle_light_window();
2683 else if (ev.window==show_menu) toggle_show_menu();
2684 else if (ev.window==pmenu) toggle_pmenu();
2685 else if (ev.window==tbw) toggle_toolbar();
2686 else if (ev.window==omenu) toggle_omenu();
2687 else if (ev.window==search_window) toggle_search_window();
2688 else if (profile_handle_event(ev)) profile_on=!profile_on;
2689 else if (chat->chat_event(ev)) chat->toggle();
2690
2691 }
2692 }
2693 break;
2694 case EV_KEYRELEASE :
2695 {
2696 if (ev.key==JK_CTRL_L)
2697 {
2698 if (!edit_object && link_object && selected_object && link_object!=selected_object)
2699 {
2700 link_object->add_object(selected_object);
2701 if (S_LINK_SND>0) cache.sfx(S_LINK_SND)->play(sfx_volume/2);
2702 the_game->need_refresh();
2703 }
2704
2705 link_object=NULL;
2706 }
2707 } break;
2708 case EV_KEY :
2709 {
2710 if (backw && ev.window==backw)
2711 { if (ev.key=='-' && bg_scale<the_game->btile_height()/2)
2712 { toggle_bgw();
2713 bg_scale++;
2714 toggle_bgw();
2715 } else if (ev.key=='+' && bg_scale>1)
2716 { toggle_bgw();
2717 bg_scale--;
2718 toggle_bgw();
2719 } else if (ev.key=='b') toggle_bgw();
2720 else if (ev.key=='B') { toggle_bgw(); bg_w++; if (bg_w>6) bg_w=1; toggle_bgw(); }
2721 }
2722 if (forew && ev.window==forew)
2723 { if (ev.key=='-' && fg_scale<the_game->ftile_height()/2)
2724 { toggle_fgw();
2725 fg_scale++;
2726 toggle_fgw();
2727 } else if (ev.key=='+' && fg_scale>1)
2728 { toggle_fgw();
2729 fg_scale--;
2730 toggle_fgw();
2731 } else if (ev.key=='i')
2732 {
2733 toggle_fgw();
2734 fg_reversed=!fg_reversed;
2735 prop->setd("fg_reversed",fg_reversed);
2736 toggle_fgw();
2737 } else if (ev.key=='f') toggle_fgw();
2738
2739 else if (ev.key=='F') { toggle_fgw(); fg_w++; if (fg_w>6) fg_w=1; toggle_fgw(); }
2740 }
2741 if (ev.window==NULL || ev.window==pmenu ||
2742 ev.window==forew || is_pal_win(ev.window)) // main window actions
2743 {
2744 switch (ev.key)
2745 {
2746 case JK_CTRL_L : if (!edit_object && !link_object) { link_object=selected_object; }
2747 case 'n' : current_level->next_focus(); break;
2748 // case '/' : if (dev_console) dev_console->toggle(); break;
2749 case 't' :
2750 {
2751 if (ev.window==NULL || ev.window==forew)
2752 {
2753 the_game->ftile_on(last_demo_mx,last_demo_my,x,y);
2754 fg_fill(cur_fg,x,y,NULL);
2755 }
2756 } break;
2757 case 'f' : toggle_fgw(); break;
2758 case 'M' : toggle_music_window(); break;
2759
2760 case 'b' : toggle_bgw(); break;
2761 case 'a' : toggle_toolbar(); break;
2762 case 'A' : { if (selected_object)
2763 {
2764 if (oedit) wm->push_event(new event(DEV_OEDIT_OK,NULL));
2765 make_ai_window(selected_object);
2766 }
2767 } break;
2768
2769 case 'o' : toggle_omenu(); break;
2770
2771 case '<' : do_command("to_back",ev); break;
2772
2773 case '>' : do_command("to_front",ev); break;
2774 case 'p' : toggle_pmenu(); break;
2775 case 'P' : profile_toggle(); break;
2776 case '.' :
2777 {
2778 if (last_created_type>=0)
2779 {
2780 int val=last_created_type;
2781 char cmd[100];
2782 sprintf(cmd,"create %s",object_names[val]);
2783 do_command(cmd,ev);
2784 state=DEV_CREATE_OBJECT;
2785 dev|=(EDIT_MODE | DRAW_PEOPLE_LAYER);
2786 }
2787 }
2788 break;
2789
2790
2791 case 'd' : { do_command("delete",ev); the_game->need_refresh(); } break;
2792 case 'i' :
2793 {
2794 fg_reversed=!fg_reversed;
2795 prop->setd("fg_reversed",fg_reversed);
2796 if (forew)
2797 {
2798 toggle_fgw();
2799 toggle_fgw();
2800 }
2801 } break;
2802 case 'l' : toggle_light_window(); break;
2803 case '!' :
2804 case '@' :
2805 case '#' :
2806 case '$' :
2807 case '%' :
2808 case '^' :
2809 case '&' :
2810 case '*' :
2811 case '(' :
2812 case ')' :
2813
2814 case '0' :
2815 case '1' :
2816 case '2' :
2817 case '3' :
2818 case '4' :
2819 case '5' :
2820 case '6' :
2821 case '7' :
2822 case '8' :
2823 case '9' : do_command("set_aitype",ev); break;
2824 case 'c' : do_command("center",ev); break;
2825 case 'C' :
2826 if (selected_object && selected_object->controller()==NULL)
2827 { copy_object=selected_object;
2828 wm->push_event(new event(DEV_OEDIT_COPY,NULL)); } break;
2829
2830 case 'D' : the_game->toggle_delay(); break;
2831 case 'L' : toggle_show_menu(); break;
2832 case '`' : do_command("fg_select",ev); break;
2833 case 'r' : { do_command("toggle_fg_raise",ev); the_game->need_refresh(); } break;
2834 case '[' : do_command("fg_add -1",ev); break;
2835 case ']' : do_command("fg_add 1",ev); break;
2836 case 'R' : do_command("reload",ev); break;
2837 case 'w' :
2838 {
2839 int32_t rx,ry;
2840 the_game->mouse_to_game(dlastx,dlasty,rx,ry);
2841 char msg[100]; sprintf(msg,symbol_str("mouse_at"),rx,ry);
2842 the_game->show_help(msg);
2843 the_game->need_refresh();
2844 } break;
2845 case 'k' :
2846 {
2847 if (selected_object && selected_object->total_objects())
2848 selected_object->remove_object(selected_object->get_object(0));
2849 the_game->need_refresh();
2850 } break;
2851 case 'K' :
2852 {
2853 if (selected_object && selected_object->total_objects())
2854 selected_object->remove_object(selected_object->get_object(selected_object->total_objects()-1));
2855 the_game->need_refresh();
2856 } break;
2857 case 'j' :
2858 {
2859 if (current_level && player_list && player_list->focus)
2860 {
2861 int32_t rx,ry;
2862 the_game->mouse_to_game(dlastx,dlasty,rx,ry);
2863 player_list->focus->x=rx;
2864 player_list->focus->y=ry;
2865 do_command("center",ev);
2866 the_game->need_refresh();
2867 }
2868 } break;
2869 case 'z' : do_command("clear_weapons",ev); break;
2870 case 'Z' : if (dev&EDIT_MODE)
2871 { view *v=the_game->view_in(last_demo_mx,last_demo_my);
2872 if (v)
2873 {
2874 v->god=!v->god;
2875 sbar.redraw(screen);
2876 }
2877 } break;
2878 case ' ' :
2879 {
2880 if (dev & EDIT_MODE)
2881 {
2882 if (selected_object)
2883 {
2884 if (oedit)
2885 close_oedit_window();
2886 edit_object=selected_object;
2887 do_command("move",ev);
2888 } else if (selected_light)
2889 {
2890 if (ledit)
2891 {
2892 wm->close_window(ledit);
2893 ledit=NULL;
2894 }
2895 edit_light=selected_light;
2896 do_command("move_light",ev);
2897 }
2898
2899 } break;
2900 }
2901 case 'x' :
2902 {
2903 if (selected_object)
2904 { if (selected_object->direction>0)
2905 selected_object->direction=-1;
2906 else selected_object->direction=1;
2907 }
2908 } break;
2909
2910 }
2911 }
2912 }
2913 }
2914
2915
2916 }
2917
2918
add_palette(void * args)2919 void dev_controll::add_palette(void *args)
2920 {
2921 total_pals++;
2922 pal_wins=(pal_win **)realloc(pal_wins,sizeof(pal_win *)*total_pals);
2923 pal_wins[total_pals-1]=new pal_win(args);
2924 }
2925
2926
pal_win(void * args)2927 pal_win::pal_win(void *args)
2928 {
2929 int i=0;
2930 Cell *ao=(Cell *)args;
2931
2932 name = strdup(lstring_value(CAR(args)));
2933 ao=CDR(ao);
2934 scale=w=h=1;
2935 x=y=0;
2936
2937 if (!NILP(ao))
2938 {
2939 w=lnumber_value(CAR(ao)); ao=CDR(ao);
2940 if (!NILP(ao))
2941 {
2942 h=lnumber_value(CAR(ao)); ao=CDR(ao);
2943 if (!NILP(ao))
2944 {
2945 x=lnumber_value(CAR(ao)); ao=CDR(ao);
2946 if (!NILP(ao))
2947 {
2948 y=lnumber_value(CAR(ao)); ao=CDR(ao);
2949 if (!NILP(ao))
2950 scale=lnumber_value(CAR(ao)); ao=CDR(ao);
2951 }
2952 }
2953 }
2954 }
2955
2956 if (w<=0) w=0;
2957 if (h<=0) h=0;
2958
2959 pat=(unsigned short *)malloc(w*h*sizeof(unsigned short));
2960 memset(pat,0,sizeof(unsigned short)*w*h); // set the palette to black if no parameters are given
2961 while (!NILP(ao)) // loop until we run out of parameters
2962 {
2963 if (i>w*h)
2964 {
2965 lbreak("to many parameters to add_palette ");
2966 exit(0);
2967 }
2968 pat[i]=lnumber_value(CAR(ao));
2969 // make sure the tile that they suggested exists
2970 if (pat[i]<=0 || pat[i]>nforetiles || foretiles[pat[i]]<0)
2971 pat[i]=0;
2972 ao=CDR(ao);
2973 i++;
2974 }
2975 last_selected=-1;
2976 me=NULL;
2977 open_window();
2978 }
2979
open_window()2980 void pal_win::open_window()
2981 {
2982 if (me) close_window();
2983 me=wm->new_window(x,y,w*f_wid/scale,h*f_hi/scale,NULL,name);
2984 draw();
2985 }
2986
close_window()2987 void pal_win::close_window()
2988 {
2989 if (me) // dont' close the window if the window is already closed
2990 {
2991 x=me->x; // save the old poisition of the window so that when we open it
2992 // it will be in the same spot
2993 y=me->y;
2994 wm->close_window(me);
2995 me=NULL;
2996
2997 }
2998 }
2999
draw()3000 void pal_win::draw()
3001 {
3002 int i,find=-1,d=cur_fg;
3003 if (me)
3004 {
3005 me->clear();
3006 image *im=new image(vec2i(the_game->ftile_width(),the_game->ftile_height()));
3007 int th=the_game->ftile_height()/scale,tw=the_game->ftile_width()/scale;
3008
3009 for (i=0; i<w*h; i++)
3010 {
3011 im->clear();
3012 the_game->get_fg(pat[i])->im->PutImage(im,vec2i(0,0));
3013 scale_put(im,me->screen,me->x1()+(i%w)*tw,
3014 me->y1()+(i/w)*th,tw,th);
3015 if (d==pat[i])
3016 {
3017 find=i;
3018 me->screen->rectangle(me->x1()+(i%w)*tw,
3019 me->y1()+(i/w)*th,
3020 me->x1()+(i%w)*tw+tw-1,
3021 me->y1()+(i/w)*th+th-1,wm->bright_color());
3022 }
3023 }
3024 delete im;
3025 last_selected=d;
3026 }
3027 }
3028
handle_event(event & ev)3029 void pal_win::handle_event(event &ev)
3030 {
3031 int d=cur_fg;
3032
3033 if (d!=last_selected) // if so see if we need to hilight any of our tiles.
3034 {
3035 int i,dr=0;
3036 for (i=0; i<w*h; i++)
3037 {
3038 if (pat[i]==d || pat[i]==last_selected)
3039 dr=1;
3040 }
3041 if (dr) draw();
3042 last_selected=d;
3043 }
3044
3045 if (ev.window && ev.window==me)
3046 {
3047 switch (ev.type)
3048 {
3049 case EV_MOUSE_BUTTON :
3050 {
3051 if (ev.mouse_button==1)
3052 {
3053 int selx=(last_demo_mx-me->x-me->x1())/(the_game->ftile_width()/scale),
3054 sely=(last_demo_my-me->y-me->y1())/(the_game->ftile_height()/scale);
3055 if (selx>=0 && sely>=0 && selx<w && sely<h)
3056 {
3057 cur_fg=pat[selx+sely*w];
3058 if (dev_cont->forew)
3059 ((tile_picker *)dev_cont->forew->
3060 read(DEV_FG_PICKER))->recenter(dev_cont->forew->screen);
3061 }
3062 } else if (ev.mouse_button==2)
3063 {
3064 if (palettes_locked)
3065 the_game->show_help(symbol_str("pal_lock"));
3066 else
3067 {
3068 int selx=(last_demo_mx-me->x-me->x1())/(the_game->ftile_width()/scale),
3069 sely=(last_demo_my-me->y-me->y1())/(the_game->ftile_height()/scale);
3070 if (selx>=0 && sely>=0 && selx<w && sely<h)
3071 {
3072 pat[selx+sely*w]=cur_fg;
3073 draw();
3074 }
3075 }
3076 }
3077 } break;
3078
3079 case EV_KEY :
3080 {
3081 switch (ev.key)
3082 {
3083 case '+' :
3084 { if (scale>1)
3085 {
3086 close_window();
3087 scale--;
3088 open_window();
3089 }
3090 } break;
3091 case '-' :
3092 { if (scale<the_game->ftile_height()/2)
3093 {
3094 close_window();
3095 scale++;
3096 open_window();
3097 }
3098 } break;
3099 case JK_LEFT :
3100 {
3101 if (palettes_locked) the_game->show_help(symbol_str("pal_lock"));
3102 else if (w>1) resize(-1,0);
3103 } break;
3104 case JK_RIGHT :
3105 {
3106 if (palettes_locked) the_game->show_help(symbol_str("pal_lock"));
3107 else
3108 resize(1,0);
3109 } break;
3110 case JK_UP :
3111 {
3112 if (palettes_locked) the_game->show_help(symbol_str("pal_lock"));
3113 else if (h>1) resize(0,-1);
3114 } break;
3115 case JK_DOWN :
3116 {
3117 if (palettes_locked)
3118 the_game->show_help(symbol_str("pal_lock"));
3119 else
3120 resize(0,1);
3121 } break;
3122 case JK_ESC : close_window(); break;
3123 case ' ' :
3124 {
3125 int32_t xs,ys,xx,yy;
3126 the_game->ftile_on(me->x,me->y,xs,ys);
3127
3128 for (xx=xs; xx<xs+w; xx++)
3129 {
3130 for (yy=ys; yy<ys+h; yy++)
3131 {
3132 if (xx>=0 && yy>=0 && xx<current_level->foreground_width() &&
3133 yy<current_level->foreground_height())
3134 the_game->put_fg(xx,yy,raise_all ? make_above_tile(pat[xx-xs+(yy-ys)*w]) : pat[xx-xs+(yy-ys)*w] );
3135 }
3136 }
3137 } break;
3138 case 't' :
3139 {
3140 int32_t xs,ys;
3141 the_game->ftile_on(me->x,me->y,xs,ys);
3142 dev_cont->fg_fill(-1,xs,ys,this);
3143 } break;
3144
3145 }
3146 } break;
3147
3148 case EV_CLOSE_WINDOW : close_window(); break;
3149 }
3150 }
3151
3152
3153 }
3154
3155
resize(int xa,int ya)3156 void pal_win::resize(int xa, int ya)
3157 {
3158 int i,j;
3159 unsigned short *npat;
3160 if (w+xa<1 || y+ya<1) return ;
3161
3162 npat=(unsigned short *)malloc(sizeof(unsigned short)*(w+xa)*(h+ya));
3163 memset(npat,0,sizeof(unsigned short)*(w+xa)*(h+ya));
3164 for (i=0; i<(w+xa); i++)
3165 for (j=0; j<(h+ya); j++)
3166 if (i+j*w<w*h)
3167 npat[i+j*(w+xa)]=pat[i+j*w];
3168 free(pat);
3169 w+=xa;
3170 h+=ya;
3171 pat=npat;
3172 last_selected=-1;
3173 close_window();
3174 open_window();
3175 }
3176
3177
save(FILE * fp)3178 void pal_win::save(FILE *fp)
3179 {
3180 if (me)
3181 {
3182 x=me->x;
3183 y=me->y;
3184 }
3185
3186 fprintf(fp,"(add_palette \"%s\" %ld %ld %ld %ld %ld ",name,(long)w,(long)h,(long)x,(long)y,(long)scale);
3187 int i;
3188 for (i=0; i<w*h; i++)
3189 fprintf(fp,"%d ",pat[i]&0x7fff);
3190 fprintf(fp,")\n");
3191
3192 }
3193
save()3194 void dev_controll::save()
3195 {
3196 FILE *fp=open_FILE("edit.lsp","w");
3197 if (!fp)
3198 the_game->show_help(symbol_str("no_edit.lsp"));
3199 else
3200 {
3201 fprintf(fp,"(set_zoom %d)\n",the_game->zoom);
3202
3203 int i;
3204 for (i=0; i<total_pals; i++)
3205 {
3206 pal_wins[i]->save(fp);
3207 }
3208 fprintf(fp,"\n");
3209 fclose(fp);
3210 }
3211
3212 }
3213
is_pal_win(Jwindow * win)3214 int dev_controll::is_pal_win(Jwindow *win)
3215 {
3216 int i;
3217 for (i=0; i<total_pals; i++)
3218 if (win==pal_wins[i]->me) return 1;
3219 return 0;
3220 }
3221
3222
3223 class fill_rec
3224 {
3225 public :
3226 short x,y;
3227 fill_rec *last;
fill_rec(short X,short Y,fill_rec * Last)3228 fill_rec(short X, short Y, fill_rec *Last)
3229 { x=X; y=Y; last=Last; }
3230 } ;
3231
get_color(int color,int x,int y,pal_win * p)3232 static int get_color(int color, int x, int y, pal_win *p)
3233 {
3234 if (p)
3235 {
3236 while (x<0) x+=p->width();
3237 while (y<0) y+=p->height();
3238 return p->get_pat(x%p->width(),y%p->height());
3239 }
3240 else return color;
3241 }
3242
fg_fill(int color,int x,int y,pal_win * p)3243 void dev_controll::fg_fill(int color, int x, int y, pal_win *p)
3244 {
3245 unsigned short *sl,*above,*below;
3246 fill_rec *recs=NULL,*r;
3247 unsigned short fcolor;
3248 sl=current_level->get_fgline(y);
3249 fcolor=fgvalue(sl[x]);
3250 int startx=x,starty=y;
3251 if (fcolor==color) return ;
3252 do
3253 {
3254 if (recs)
3255 { r=recs;
3256 recs=recs->last;
3257 x=r->x; y=r->y;
3258 delete r;
3259 }
3260 sl=current_level->get_fgline(y);
3261 if (fgvalue(sl[x])==fcolor)
3262 {
3263 while (x>0 && fgvalue(sl[x])==fcolor) x--;
3264 if (fgvalue(sl[x])!=fgvalue(fcolor) && x<current_level->foreground_width()-1) x++;
3265 if (y>0)
3266 {
3267 above=current_level->get_fgline(y-1);
3268 if (fgvalue(above[x])==fcolor)
3269 { r=new fill_rec(x,y-1,recs);
3270 recs=r;
3271 }
3272 }
3273 if (y<current_level->foreground_height()-1)
3274 {
3275 above=current_level->get_fgline(y+1);
3276 if (above[x]==fcolor)
3277 { r=new fill_rec(x,y+1,recs);
3278 recs=r;
3279 }
3280 }
3281
3282
3283
3284 do
3285 {
3286 sl[x]=get_color(color,x-startx,y-starty,p);
3287 if (y>0)
3288 { above=current_level->get_fgline(y-1);
3289 if (x>0 && fgvalue(above[x-1])!=fgvalue(fcolor) && fgvalue(above[x])==fgvalue(fcolor))
3290 { r=new fill_rec(x,y-1,recs);
3291 recs=r;
3292 }
3293 }
3294 if (y<current_level->foreground_height()-1)
3295 { below=current_level->get_fgline(y+1);
3296 if (x>0 && fgvalue(below[x-1])!=fgvalue(fcolor) && fgvalue(below[x])==fgvalue(fcolor))
3297 { r=new fill_rec(x,y+1,recs);
3298 recs=r;
3299 }
3300 }
3301 x++;
3302 } while (fgvalue(sl[x])==fgvalue(fcolor) && x<current_level->foreground_width());
3303 x--;
3304 if (y>0)
3305 {
3306 above=current_level->get_fgline(y-1);
3307 if (fgvalue(above[x])==fgvalue(fcolor))
3308 { r=new fill_rec(x,y-1,recs);
3309 recs=r;
3310 }
3311 }
3312 if (y<current_level->foreground_height()-1)
3313 {
3314 above=current_level->get_fgline(y+1);
3315 if (fgvalue(above[x])==fgvalue(fcolor))
3316 { r=new fill_rec(x,y+1,recs);
3317 recs=r;
3318 }
3319 }
3320 }
3321 } while (recs);
3322 the_game->need_refresh();
3323 }
3324
get_char_mem(int type,int print)3325 static int get_char_mem(int type, int print)
3326 {
3327 int t=0;
3328 for (int j=0; j<MAX_STATE; j++)
3329 {
3330 if (figures[type]->has_sequence((character_state)j))
3331 {
3332 int s=figures[type]->get_sequence((character_state)j)->MemUsage();
3333 if (print)
3334 dprintf("(%s=%d)",state_names[j],s);
3335 t+=s;
3336 }
3337 }
3338 if (print)
3339 dprintf("\ntotal=%d\n",t);
3340 return t;
3341 }
3342
show_char_mem(char const * name)3343 void dev_controll::show_char_mem(char const *name)
3344 {
3345 int find=-1;
3346 for (int i=0; i<total_objects; i++)
3347 {
3348 if (!strcmp(name,object_names[i]))
3349 find=i;
3350 }
3351 if (find<0)
3352 dprintf("No character '%s' defined\n",name);
3353 else
3354 get_char_mem(find,1);
3355
3356 }
3357
show_mem()3358 void dev_controll::show_mem()
3359 {
3360 int t=0,s=0;
3361 int i=0;
3362 for (; i<nforetiles; i++)
3363 {
3364 if (foretiles[i]>=0)
3365 {
3366 if (cache.loaded(foretiles[i]))
3367 {
3368 t++;
3369 s+=cache.foret(foretiles[i])->size();
3370 }
3371 }
3372 }
3373 dprintf("%d loaded foretiles=%d bytes\n",t,s);
3374
3375 t=0; s=0;
3376 for (i=0; i<nbacktiles; i++)
3377 {
3378 if (backtiles[i]>=0)
3379 {
3380 if (cache.loaded(foretiles[i]))
3381 {
3382 t++;
3383 s+=cache.backt(backtiles[i])->size();
3384 }
3385 }
3386 }
3387 dprintf("%d loaded backtiles=%d bytes\n",t,s);
3388
3389 t=0; s=0;
3390 for (i=0; i<total_objects; i++)
3391 {
3392 t++;
3393 s+=get_char_mem(i,0);
3394 }
3395 dprintf("%d character=%d bytes\n",t,s);
3396
3397 }
3398
3399
3400
dev_cleanup()3401 void dev_cleanup()
3402 {
3403 if (start_edit)
3404 prop->save("defaults.prp");
3405 delete prop;
3406 if (listable_objs)
3407 {
3408 free(listable_objs);
3409 listable_objs=NULL;
3410 }
3411 crc_manager.clean_up();
3412
3413 }
3414
3415
3416
3417 struct pmi
3418 {
3419 char const *name;
3420 int id;
3421 char const *on_off;
3422 int key;
3423 } ;
3424
3425
3426 static pmi filemenu[]={
3427 { "menu1_load", ID_LEVEL_LOAD,NULL,-1},
3428 { NULL,0,NULL,-1},
3429 { "menu1_save", ID_LEVEL_SAVE,NULL,-1},
3430 { "menu1_saveas", ID_LEVEL_SAVEAS,NULL,-1},
3431 { "menu1_savegame", ID_GAME_SAVE,NULL,-1},
3432 { "menu1_new", ID_LEVEL_NEW,NULL,-1},
3433 { "menu1_resize", ID_LEVEL_RESIZE,NULL,-1},
3434 { NULL,0,NULL,-1},
3435 { "menu1_suspend",ID_SUSPEND,NULL,-1},
3436 { "menu1_toggle",ID_PLAY_MODE,NULL,-1},
3437 { NULL,0,NULL,-1},
3438 { "menu1_savepal",ID_EDIT_SAVE,NULL,-1},
3439 // { "menu1_startc",ID_CACHE_PROFILE,NULL,-1},
3440 // { "menu1_endc",ID_CACHE_PROFILE_END,NULL,-1},
3441 { NULL,0,NULL,-1},
3442 { "menu1_quit", ID_QUIT,NULL,-1},
3443 { NULL,-1,NULL,-1}
3444 };
3445
3446
3447 static pmi editmenu[]={
3448 { "menu2_light", ID_TOGGLE_LIGHT,NULL,-1},
3449 { "menu2_scroll", ID_SET_SCROLL,NULL,-1},
3450 { "menu2_center", ID_CENTER_PLAYER,NULL,-1},
3451 { "menu2_addpal", ID_ADD_PALETTE,NULL,-1},
3452 { "menu2_delay", ID_TOGGLE_DELAY,NULL,-1},
3453
3454 { "menu2_god", ID_GOD_MODE,NULL,-1},
3455 { "menu2_clear", ID_CLEAR_WEAPONS,NULL,-1},
3456 { "menu2_mscroll", ID_MOUSE_SCROLL,&mouse_scrolling,-1},
3457 { "menu2_lock", ID_LOCK_PALETTES,&palettes_locked,-1},
3458 { "menu2_raise", ID_RAISE_ALL,&raise_all,-1},
3459 { "menu2_names", ID_TOGGLE_NAMES,&show_names,-1},
3460
3461 { NULL,0,NULL,-1},
3462 { "menu2_map", ID_TOGGLE_MAP,NULL,-1},
3463 // { "Shrink to 320x200 (F10)", ID_SMALL_MODE,NULL,-1},
3464 { "menu2_view", ID_DISABLE_VIEW_SHIFT,&view_shift_disabled,-1},
3465 // { "Ultra Smooth draw (U)", ID_INTERPOLATE_DRAW, &interpolate_draw,'U'},
3466 { "menu2_alight", ID_DISABLE_AUTOLIGHT, &disable_autolight,'A'},
3467 { "menu2_fps", ID_SHOW_FPS, &fps_on,-1},
3468 // { NULL,0,NULL,-1},
3469 // { "Record demo", ID_RECORD_DEMO,NULL,-1},
3470 // { "Play demo", ID_PLAY_DEMO,NULL,-1},
3471 { NULL,-1,NULL,-1}
3472 };
3473
3474
3475
3476 // Window Menus
3477 static pmi winmenu[]={
3478 { "menu3_fore", ID_WIN_FORE, &forew_on,-1},
3479 { "menu3_back", ID_WIN_BACK, &backw_on,-1},
3480 { "menu3_layers", ID_WIN_LAYERS, &show_menu_on,-1},
3481 { "menu3_light", ID_WIN_LIGHTING,&ledit_on,-1},
3482 { "menu3_pal", ID_WIN_PALETTES,&pmenu_on,-1},
3483 { "menu3_objs", ID_WIN_OBJECTS, &omenu_on,-1},
3484 // { "menu3_console", ID_WIN_CONSOLE, &commandw_on,-1},
3485 { "menu3_toolbar", ID_WIN_TOOLBAR, &tbw_on,-1},
3486 // { "Search (s)", ID_SEARCH, &searchw_on,-1},
3487 { "menu3_prof", ID_PROFILE, &profile_on,-1},
3488 { "menu3_save", ID_SAVE_WINDOWS,NULL,-1},
3489 { NULL,-1,NULL,-1}
3490 };
3491
3492
3493
3494 /*
3495 static pmi filemenu[]={
3496 { "Load Level", ID_LEVEL_LOAD,NULL,-1},
3497 { NULL,0,NULL,-1},
3498 { "Save Level (S)", ID_LEVEL_SAVE,NULL,-1},
3499 { "Save level as", ID_LEVEL_SAVEAS,NULL,-1},
3500 { "Save game", ID_GAME_SAVE,NULL,-1},
3501 { "New level", ID_LEVEL_NEW,NULL,-1},
3502 { "Resize map", ID_LEVEL_RESIZE,NULL,-1},
3503 { NULL,0,NULL,-1},
3504 { "Suspend non-players",ID_SUSPEND,NULL,-1},
3505 { "Play mode toggle (TAB)",ID_PLAY_MODE,NULL,-1},
3506 { NULL,0,NULL,-1},
3507 { "Save Palettes ",ID_EDIT_SAVE,NULL,-1},
3508 { "Start cache profile ",ID_CACHE_PROFILE,NULL,-1},
3509 { "End cache profile ",ID_CACHE_PROFILE_END,NULL,-1},
3510 { NULL,0,NULL,-1},
3511 { "Quit (Q)", ID_QUIT,NULL,-1},
3512 { NULL,-1,NULL,-1}
3513 };
3514
3515
3516 static pmi editmenu[]={
3517 { "Toggle light", ID_TOGGLE_LIGHT,NULL,-1},
3518 { "Set scroll rate", ID_SET_SCROLL,NULL,-1},
3519 { "Center on player (c)", ID_CENTER_PLAYER,NULL,-1},
3520 { "Add palette", ID_ADD_PALETTE,NULL,-1},
3521 { "Toggle Delays (D)", ID_TOGGLE_DELAY,NULL,-1},
3522
3523 { "God mode", ID_GOD_MODE,NULL,-1},
3524 { "Clear weapons (z)", ID_CLEAR_WEAPONS,NULL,-1},
3525 { "Mouse scroll", ID_MOUSE_SCROLL,&mouse_scrolling,-1},
3526 { "Lock palette windows", ID_LOCK_PALETTES,&palettes_locked,-1},
3527 { "Raise all foreground", ID_RAISE_ALL,&raise_all,-1},
3528 { "Toggle object names", ID_TOGGLE_NAMES,&show_names,-1},
3529
3530 { NULL,0,NULL,-1},
3531 { "Toggle map (m)", ID_TOGGLE_MAP,NULL,-1},
3532 // { "Shrink to 320x200 (F10)", ID_SMALL_MODE,NULL,-1},
3533 { "Disable view shifts", ID_DISABLE_VIEW_SHIFT,&view_shift_disabled,-1},
3534 // { "Ultra Smooth draw (U)", ID_INTERPOLATE_DRAW, &interpolate_draw,'U'},
3535 { "Disable Autolight (A)", ID_DISABLE_AUTOLIGHT, &disable_autolight,'A'},
3536 { "Show FPS/Obj count", ID_SHOW_FPS, &fps_on,-1},
3537 // { NULL,0,NULL,-1},
3538 // { "Record demo", ID_RECORD_DEMO,NULL,-1},
3539 // { "Play demo", ID_PLAY_DEMO,NULL,-1},
3540 { NULL,-1,NULL,-1}
3541 };
3542
3543
3544
3545 // Window Menus
3546 static pmi winmenu[]={
3547 { "Foreground (f)", ID_WIN_FORE, &forew_on,-1},
3548 { "Background (b)", ID_WIN_BACK, &backw_on,-1},
3549 { "Draw layers (L)", ID_WIN_LAYERS, &show_menu_on,-1},
3550 { "Lighting (l)", ID_WIN_LIGHTING,&ledit_on,-1},
3551 { "Palettes (p)", ID_WIN_PALETTES,&pmenu_on,-1},
3552 { "Objects (o)", ID_WIN_OBJECTS, &omenu_on,-1},
3553 { "Console (/)", ID_WIN_CONSOLE, &commandw_on,-1},
3554 { "Tool Bar (a)", ID_WIN_TOOLBAR, &tbw_on,-1},
3555 // { "Search (s)", ID_SEARCH, &searchw_on,-1},
3556 { "Profile (P)", ID_PROFILE, &profile_on,-1},
3557 { "Save positions", ID_SAVE_WINDOWS,NULL,-1},
3558 { NULL,-1,NULL,-1}
3559 };
3560
3561 */
3562
i_recurse(pmi * first)3563 static pmenu_item *i_recurse(pmi *first)
3564 {
3565 if (first->id==-1)
3566 return NULL;
3567 else
3568 return new pmenu_item(first->id,first->name ? symbol_str(first->name) : 0,first->on_off,first->key,i_recurse(first+1));
3569 }
3570
make_menu(int x,int y)3571 static pmenu *make_menu(int x, int y)
3572 {
3573 return new pmenu(x,y,
3574 new pmenu_item(symbol_str("file_top"),new psub_menu(i_recurse(filemenu),NULL),
3575 new pmenu_item(symbol_str("edit_top"),new psub_menu(i_recurse(editmenu),NULL),
3576 new pmenu_item(symbol_str("window_top"),new psub_menu(i_recurse(winmenu),NULL),NULL))),screen);
3577 }
3578
3579
3580
toggle_edit_mode()3581 void toggle_edit_mode()
3582 {
3583 dev=dev^EDIT_MODE;
3584 if (dev&EDIT_MODE)
3585 {
3586 wm->set_mouse_shape(cache.img(c_normal)->copy(),1,1);
3587 pal->load();
3588 }
3589 else
3590 {
3591 if (dev&MAP_MODE) dev-=MAP_MODE; // no map mode while playing!
3592 wm->set_mouse_shape(cache.img(c_target)->copy(),8,8);
3593 }
3594 if ((dev&EDIT_MODE) && !dev_menu)
3595 {
3596 dev_menu=make_menu(0,yres-wm->font()->height()-5);
3597 }
3598 else if (!(dev&EDIT_MODE) && dev_menu)
3599 {
3600 delete dev_menu;
3601 dev_menu=NULL;
3602 }
3603 }
3604
3605
ok_to_scroll()3606 int dev_controll::ok_to_scroll()
3607 {
3608 if (state==DEV_MOVE_LIGHT || state==DEV_MOVE_OBJECT || mouse_scrolling) return 1;
3609 else return 0;
3610 }
3611
~dev_controll()3612 dev_controll::~dev_controll()
3613 {
3614 for (int i=0; i<total_pals; i++)
3615 delete pal_wins[i];
3616 if (total_pals)
3617 free(pal_wins);
3618 }
3619
3620
3621
~pal_win()3622 pal_win::~pal_win()
3623 {
3624 free(pat);
3625 free(name);
3626 }
3627