16 /* defines for help */
18 #define HELP_HEIGHT 22
19 #define HELP_X ((SCREEN_X-2-HELP_WIDTH)>>1)
20 #define HELP_Y ((SCREEN_Y-2-HELP_HEIGHT)>>1)
23 unsigned long id
; /* id of last object */
24 int xoffset
=0,yoffset
=0; /* coordinates of upper left corner of the screen */
25 int x
=0,y
=0; /* cursor coordinates on the screen */
26 int oldx
=0,oldy
=0; /* old cursor position */
28 struct object_list objects
;
29 struct object_list
*last_obj
;
33 void catch_signal(int sig_num
)
40 void catch_sigsegv(int sig_num
)
50 struct sigaction sa_old
;
51 struct sigaction sa_new
;
53 sa_new
.sa_handler
= catch_signal
;
54 sigemptyset(&sa_new
.sa_mask
);
56 sigaction(SIGINT
,&sa_new
,&sa_old
);
57 sigaction(SIGQUIT
,&sa_new
,&sa_old
);
58 sigaction(SIGTERM
,&sa_new
,&sa_old
);
59 sigaction(SIGABRT
,&sa_new
,&sa_old
);
60 sigaction(SIGILL
,&sa_new
,&sa_old
);
61 sigaction(SIGFPE
,&sa_new
,&sa_old
);
62 sigaction(SIGBUS
,&sa_new
,&sa_old
);
64 sa_new
.sa_handler
= catch_sigsegv
;
65 sigemptyset(&sa_new
.sa_mask
);
67 sigaction(SIGSEGV
,&sa_new
,&sa_old
);
71 /* shows the help window */
74 draw_frame(HELP_X
,HELP_Y
,HELP_WIDTH
,HELP_HEIGHT
,14);
75 print2screen(HELP_X
+((HELP_WIDTH
-4)>>1),HELP_Y
+1,12,"HELP");
76 print2screen(HELP_X
+((HELP_WIDTH
-9)>>1),HELP_Y
+3,11,"SCROLLING");
78 /* cursor moving help */
79 print2screen(HELP_X
+8,HELP_Y
+4,4,"CURSOR MOVING:");
80 print2screen(HELP_X
+13,HELP_Y
+5,8,"UP");
81 print2screen(HELP_X
+12,HELP_Y
+6,8,"[/\\]");
82 print2screen(HELP_X
+2,HELP_Y
+7,8,"LEFT [<-] [\\/] [->] RIGHT");
83 print2screen(HELP_X
+12,HELP_Y
+8,8,"DOWN");
85 /* screen moving help */
86 print2screen(HELP_X
+31,HELP_Y
+4,4,"SCROLLING (NUMPAD!):");
87 print2screen(HELP_X
+39,HELP_Y
+5,8,"UP");
88 print2screen(HELP_X
+39,HELP_Y
+6,8,"[8]");
89 print2screen(HELP_X
+31,HELP_Y
+7,8,"LEFT [4] [6] RIGHT");
90 print2screen(HELP_X
+39,HELP_Y
+8,8,"[2]");
91 print2screen(HELP_X
+38,HELP_Y
+9,8,"DOWN");
93 /* item moving help */
94 print2screen(HELP_X
+60,HELP_Y
+4,4,"ITEM MOVING:");
95 print2screen(HELP_X
+65,HELP_Y
+5,8,"UP");
96 print2screen(HELP_X
+64,HELP_Y
+6,8,"[W]");
97 print2screen(HELP_X
+55,HELP_Y
+7,8,"LEFT [A] [S] [D] RIGHT");
98 print2screen(HELP_X
+64,HELP_Y
+8,8,"DOWN");
101 print2screen(HELP_X
+((HELP_WIDTH
-4)>>1),HELP_Y
+11,11,"KEYS");
102 print2screen(HELP_X
+((HELP_WIDTH
-11)>>1),HELP_Y
+12,8,"BUILD - [N]");
103 print2screen(HELP_X
+((HELP_WIDTH
-12)>>1),HELP_Y
+13,8,"DELETE - [X]");
104 print2screen(HELP_X
+((HELP_WIDTH
-19)>>1),HELP_Y
+14,8,"TYPE CHANGE - [TAB], [T] (+ [SHIFT] =reverse)");
105 print2screen(HELP_X
+((HELP_WIDTH
-11)>>1),HELP_Y
+15,8,"SAVE - [F2]");
106 print2screen(HELP_X
+((HELP_WIDTH
-11)>>1),HELP_Y
+16,8,"HELP - [F1]");
107 print2screen(HELP_X
+((HELP_WIDTH
-26)>>1),HELP_Y
+17,8,"ITEM CHANGE - ([+] and [-])");
115 /* load static data */
116 void load_room(char * filename
)
119 static char line
[1024];
123 if (!(stream
=fopen(filename
,"rb")))
126 snprintf(msg
,sizeof(msg
),"Can't open file \"%s\"!\n",filename
);
130 while(fgets(line
,1024,stream
))
134 for (name
=p
;(*p
)!=' '&&(*p
)!=9&&(*p
)!=10&&(*p
);p
++);
144 if (find_sprite(name
,&n
))
147 snprintf(msg
,sizeof(msg
),"Unknown bitmap name \"%s\"!\n",name
);
151 new_obj(id
,t
,0,n
,0,0,x
,y
,0,0,0);
160 void draw_scene(void)
162 struct object_list
*p
;
164 for(p
=&objects
;p
->next
;p
=p
->next
)
167 p
->next
->member
.anim_pos
++;
168 p
->next
->member
.anim_pos
%=sprites
[p
->next
->member
.sprite
].n_steps
;
170 p
->next
->member
.x
-xoffset
,
171 p
->next
->member
.y
-yoffset
,
172 sprites
[p
->next
->member
.sprite
].positions
+sprites
[p
->next
->member
.sprite
].steps
[p
->next
->member
.anim_pos
],0
178 /* find object under cursor */
179 struct it
* find_object(void)
181 struct object_list
*p
;
182 #define O p->next->member
184 for(p
=&objects
;p
->next
;p
=p
->next
)
188 O
.x
+sprites
[O
.sprite
].positions
[0].lines
[0].len
-1>=x
+xoffset
&&
190 O
.y
+sprites
[O
.sprite
].positions
[0].n
-1>=y
+yoffset
192 return &(p
->next
->member
);
198 /* next type when 't' is pressed */
199 int next_type(int type
)
201 /* static objects: b, f, j, i, w */
202 /* dynamic objects: N, F, B, S, U, R, 1, 2, 3, 4, 5, M, A, I, K */
205 case 'b': return 'f';
206 case 'f': return 'j';
207 case 'j': return 'i';
208 case 'i': return 'w';
209 case 'w': return 'N';
210 case 'N': return 'F';
211 case 'F': return 'B';
212 case 'B': return 'S';
213 case 'S': return 'U';
214 case 'U': return 'R';
215 case 'R': return '1';
216 case '1': return '2';
217 case '2': return '3';
218 case '3': return '4';
219 case '4': return '5';
220 case '5': return 'M';
221 case 'M': return 'A';
222 case 'A': return 'I';
223 case 'I': return 'K';
230 /* prev type when 'T' is pressed */
231 int prev_type(int type
)
233 /* static objects: b, f, j, i, w */
234 /* dynamic objects: N, F, B, S, U, R, 1, 2, 3, 4, 5, M, A, I, K */
235 /* but now in reverse order */
238 case 'b': return 'K';
239 case 'f': return 'b';
240 case 'j': return 'f';
241 case 'i': return 'j';
242 case 'w': return 'i';
243 case 'N': return 'w';
244 case 'F': return 'N';
245 case 'B': return 'F';
246 case 'S': return 'B';
247 case 'U': return 'S';
248 case 'R': return 'U';
249 case '1': return 'R';
250 case '2': return '1';
251 case '3': return '2';
252 case '4': return '3';
253 case '5': return '4';
254 case 'M': return '5';
255 case 'A': return 'M';
256 case 'I': return 'A';
266 FILE *data
, *dynamic
;
267 struct object_list
*p
;
268 static char txt
[1024];
269 char *LEVEL
=load_level(level_number
);
271 snprintf(txt
,1024,"%s%s%s",DATA_PATH
,LEVEL
,STATIC_DATA_SUFFIX
);
276 snprintf(msg
,256,"Can't create file \"%s\"\n",txt
);
281 snprintf(txt
,1024,"%s%s%s",DATA_PATH
,LEVEL
,DYNAMIC_DATA_SUFFIX
);
283 dynamic
=fopen(txt
,"w");
287 snprintf(msg
,256,"Can't create file \"%s\"\n",txt
);
292 #define O p->next->member
294 for(p
=&objects
;p
->next
;p
=p
->next
)
296 snprintf(txt
,sizeof(txt
),"%s %c %d %d\n",sprite_names
[O
.sprite
],O
.type
,O
.x
,O
.y
);
318 /* change size of the screen */
319 void sigwinch_handler(int signum
)
325 c_init(SCREEN_X
,SCREEN_Y
);
331 signal(SIGWINCH
,sigwinch_handler
);
337 void clear_memory(void)
339 struct object_list
*o
;
341 for (o
=&objects
;o
->next
;)
342 delete_obj(o
->next
->member
.id
);
350 int main(int argc
, char**argv
)
353 unsigned char bg
=' ';
354 unsigned char color
=0;
356 unsigned int cur_obj
=0;
357 unsigned char cur_type
='w';
361 unsigned long_long last_time
;
364 chdir_to_data_files();
372 a
=getopt(argc
, argv
, "hl:");
385 "Usage: editor [-h] [-l <level number>]\n"
390 level_number
=strtoul(optarg
,&c
,10);
391 if (*c
){ERROR("Error: Not a number.\n");EXIT(1);}
394 if (!level_number
){ERROR("Error: Number underflow.\n");EXIT(1);}
395 else {ERROR("Error: Number overflow.\n");EXIT(1);}
405 signal(SIGWINCH
,sigwinch_handler
);
407 c_get_size(&SCREEN_X
,&SCREEN_Y
);
411 LEVEL
=load_level(level_number
);
412 if (!LEVEL
){fprintf(stderr
,"Can't load level number %d\n",level_number
);exit(1);}
413 snprintf(txt
,256,"%s%s%s",DATA_PATH
,LEVEL
,LEVEL_SPRITES_SUFFIX
);
415 snprintf(txt
,256,"%s%s%s",DATA_PATH
,LEVEL
,STATIC_DATA_SUFFIX
);
417 snprintf(txt
,256,"%s%s%s",DATA_PATH
,LEVEL
,DYNAMIC_DATA_SUFFIX
);
421 c_init(SCREEN_X
,SCREEN_Y
);
425 last_time
=get_time();
437 color
=screen_a
[x
+y
*SCREEN_X
];
438 bg
=screen
[x
+y
*SCREEN_X
];
445 c_clear(0,SCREEN_Y
-1,SCREEN_X
-2,SCREEN_Y
-1);
446 c_goto(0,SCREEN_Y
-1);
449 snprintf(txt
,sizeof(txt
),"% 4d ",x
+xoffset
);
454 snprintf(txt
,sizeof(txt
),"% 4d ",y
+yoffset
);
459 snprintf(txt
,sizeof(txt
),"%-.20s ",obj
?(char*)(sprite_names
[obj
->sprite
]):"----");
464 snprintf(txt
,sizeof(txt
),"%c ",obj
?obj
->type
:'-');
474 if (c_pressed(K_NUM4
)||c_pressed('4'))
476 xoffset
-=SCREEN_X
>>2;
477 if (xoffset
<0)xoffset
=0;
481 if (c_pressed(K_NUM6
)||c_pressed('6'))
483 xoffset
+=SCREEN_X
>>2;
484 if (xoffset
>AREA_X
-1-(SCREEN_X
>>1))xoffset
=AREA_X
-1-(SCREEN_X
>>1);
488 if (c_pressed(K_NUM8
)||c_pressed('8'))
490 yoffset
-=SCREEN_Y
>>2;
491 if (yoffset
<0)yoffset
=0;
495 if (c_pressed(K_NUM2
)||c_pressed('2'))
497 yoffset
+=SCREEN_Y
>>2;
498 if (yoffset
>AREA_Y
-1-(SCREEN_Y
>>1))yoffset
=AREA_Y
-1-(SCREEN_Y
>>1);
502 if (c_pressed('q')||c_pressed(K_ESCAPE
))
506 check_memory_leaks();
510 if (c_pressed(K_RIGHT
))
513 if (x
>SCREEN_X
-1||x
+xoffset
>AREA_X
-1)x
=0;
516 if (c_pressed(K_LEFT
))
519 if (x
<0)x
=SCREEN_X
-1;
520 if (x
+xoffset
>AREA_X
-1)x
=AREA_X
-1-xoffset
;
523 if (c_pressed(K_DOWN
))
526 if (y
>SCREEN_Y
-1||y
+yoffset
>AREA_Y
-1)y
=0;
532 if (y
<0)y
=SCREEN_Y
-1;
533 if (y
+yoffset
>AREA_Y
-1)y
=AREA_Y
-1-yoffset
;
544 if (c_was_pressed('x'))
551 if (c_was_pressed('=')||c_was_pressed(K_NUM_PLUS
)|c_was_pressed(K_PGUP
))
556 obj
->sprite
%=n_sprites
;
560 if (c_was_pressed('a')||((c_pressed(K_LEFT_SHIFT
)||c_pressed(K_RIGHT_SHIFT
))&&c_pressed('a')))
565 if (obj
->x
<0)obj
->x
=0;
569 if (c_was_pressed('d')||((c_pressed(K_LEFT_SHIFT
)||c_pressed(K_RIGHT_SHIFT
))&&c_pressed('d')))
574 if (obj
->x
>AREA_X
-1)obj
->x
=AREA_X
-1;
578 if (c_was_pressed('w')||((c_pressed(K_LEFT_SHIFT
)||c_pressed(K_RIGHT_SHIFT
))&&c_pressed('w')))
583 if (obj
->y
<0)obj
->y
=0;
587 if (c_was_pressed('s')||((c_pressed(K_LEFT_SHIFT
)||c_pressed(K_RIGHT_SHIFT
))&&c_pressed('s')))
592 if (obj
->y
>AREA_Y
-1)obj
->y
=AREA_Y
-1;
596 if (c_was_pressed('-')||c_was_pressed(K_NUM_MINUS
)||c_was_pressed(K_PGDOWN
))
599 if (!obj
->sprite
)obj
->sprite
=n_sprites
-1;
605 if ((c_pressed(K_LEFT_SHIFT
)||c_pressed(K_RIGHT_SHIFT
))&&(c_was_pressed('t')||c_was_pressed(K_TAB
)))
608 obj
->type
=prev_type(obj
->type
);
613 if (!c_pressed(K_LEFT_SHIFT
)&&!c_pressed(K_RIGHT_SHIFT
)&&(c_was_pressed('t')||c_was_pressed(K_TAB
)))
616 obj
->type
=next_type(obj
->type
);
621 if (c_was_pressed('n')||c_was_pressed(K_ENTER
))
623 new_obj(id
,cur_type
,0,cur_obj
,0,0,x
+xoffset
,y
+yoffset
,0,0,0);
628 if (c_was_pressed(K_F2
))
631 sleep_until(last_time
+1000000/35);