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
;
183 #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
);
200 /* next type when 't' is pressed */
201 int next_type(int type
)
203 /* static objects: b, f, j, i, w */
204 /* dynamic objects: N, F, B, S, U, R, 1, 2, 3, 4, 5, M, A, I, K */
207 case 'b': return 'f';
208 case 'f': return 'j';
209 case 'j': return 'i';
210 case 'i': return 'w';
211 case 'w': return 'N';
212 case 'N': return 'F';
213 case 'F': return 'B';
214 case 'B': return 'S';
215 case 'S': return 'U';
216 case 'U': return 'R';
217 case 'R': return '1';
218 case '1': return '2';
219 case '2': return '3';
220 case '3': return '4';
221 case '4': return '5';
222 case '5': return 'M';
223 case 'M': return 'A';
224 case 'A': return 'I';
225 case 'I': return 'K';
232 /* prev type when 'T' is pressed */
233 int prev_type(int type
)
235 /* static objects: b, f, j, i, w */
236 /* dynamic objects: N, F, B, S, U, R, 1, 2, 3, 4, 5, M, A, I, K */
237 /* but now in reverse order */
240 case 'b': return 'K';
241 case 'f': return 'b';
242 case 'j': return 'f';
243 case 'i': return 'j';
244 case 'w': return 'i';
245 case 'N': return 'w';
246 case 'F': return 'N';
247 case 'B': return 'F';
248 case 'S': return 'B';
249 case 'U': return 'S';
250 case 'R': return 'U';
251 case '1': return 'R';
252 case '2': return '1';
253 case '3': return '2';
254 case '4': return '3';
255 case '5': return '4';
256 case 'M': return '5';
257 case 'A': return 'M';
258 case 'I': return 'A';
268 FILE *data
, *dynamic
;
269 struct object_list
*p
;
270 static char txt
[1024];
271 char *LEVEL
=load_level(level_number
);
273 snprintf(txt
,1024,"%s%s%s",DATA_PATH
,LEVEL
,STATIC_DATA_SUFFIX
);
278 snprintf(msg
,256,"Can't create file \"%s\"\n",txt
);
283 snprintf(txt
,1024,"%s%s%s",DATA_PATH
,LEVEL
,DYNAMIC_DATA_SUFFIX
);
285 dynamic
=fopen(txt
,"w");
289 snprintf(msg
,256,"Can't create file \"%s\"\n",txt
);
294 #define O p->next->member
295 for(p
=&objects
;p
->next
;p
=p
->next
)
297 snprintf(txt
,sizeof(txt
),"%s %c %d %d\n",sprite_names
[O
.sprite
],O
.type
,O
.x
,O
.y
);
321 /* change size of the screen */
322 void sigwinch_handler(int signum
)
328 c_init(SCREEN_X
,SCREEN_Y
);
334 signal(SIGWINCH
,sigwinch_handler
);
340 void clear_memory(void)
342 struct object_list
*o
;
344 for (o
=&objects
;o
->next
;)
345 delete_obj(o
->next
->member
.id
);
353 int main(int argc
, char**argv
)
356 unsigned char bg
=' ';
357 unsigned char color
=0;
359 unsigned int cur_obj
=0;
360 unsigned char cur_type
='w';
364 unsigned long_long last_time
;
367 chdir_to_data_files();
375 a
=getopt(argc
, argv
, "hl:");
388 "Usage: editor [-h] [-l <level number>]\n"
393 level_number
=strtoul(optarg
,&c
,10);
394 if (*c
){ERROR("Error: Not a number.\n");EXIT(1);}
397 if (!level_number
){ERROR("Error: Number underflow.\n");EXIT(1);}
398 else {ERROR("Error: Number overflow.\n");EXIT(1);}
408 signal(SIGWINCH
,sigwinch_handler
);
410 c_get_size(&SCREEN_X
,&SCREEN_Y
);
414 LEVEL
=load_level(level_number
);
415 if (!LEVEL
){fprintf(stderr
,"Can't load level number %d\n",level_number
);exit(1);}
416 snprintf(txt
,256,"%s%s%s",DATA_PATH
,LEVEL
,LEVEL_SPRITES_SUFFIX
);
418 snprintf(txt
,256,"%s%s%s",DATA_PATH
,LEVEL
,STATIC_DATA_SUFFIX
);
420 snprintf(txt
,256,"%s%s%s",DATA_PATH
,LEVEL
,DYNAMIC_DATA_SUFFIX
);
424 c_init(SCREEN_X
,SCREEN_Y
);
428 last_time
=get_time();
440 color
=screen_a
[x
+y
*SCREEN_X
];
441 bg
=screen
[x
+y
*SCREEN_X
];
448 c_clear(0,SCREEN_Y
-1,SCREEN_X
-2,SCREEN_Y
-1);
449 c_goto(0,SCREEN_Y
-1);
452 snprintf(txt
,sizeof(txt
),"% 4d ",x
+xoffset
);
457 snprintf(txt
,sizeof(txt
),"% 4d ",y
+yoffset
);
462 snprintf(txt
,sizeof(txt
),"%-.20s ",obj
?(char*)(sprite_names
[obj
->sprite
]):"----");
467 snprintf(txt
,sizeof(txt
),"%c ",obj
?obj
->type
:'-');
477 if (c_pressed(K_NUM4
)||c_pressed('4'))
479 xoffset
-=SCREEN_X
>>2;
480 if (xoffset
<0)xoffset
=0;
484 if (c_pressed(K_NUM6
)||c_pressed('6'))
486 xoffset
+=SCREEN_X
>>2;
487 if (xoffset
>AREA_X
-1-(SCREEN_X
>>1))xoffset
=AREA_X
-1-(SCREEN_X
>>1);
491 if (c_pressed(K_NUM8
)||c_pressed('8'))
493 yoffset
-=SCREEN_Y
>>2;
494 if (yoffset
<0)yoffset
=0;
498 if (c_pressed(K_NUM2
)||c_pressed('2'))
500 yoffset
+=SCREEN_Y
>>2;
501 if (yoffset
>AREA_Y
-1-(SCREEN_Y
>>1))yoffset
=AREA_Y
-1-(SCREEN_Y
>>1);
505 if (c_pressed('q')||c_pressed(K_ESCAPE
))
509 check_memory_leaks();
513 if (c_pressed(K_RIGHT
))
516 if (x
>SCREEN_X
-1||x
+xoffset
>AREA_X
-1)x
=0;
519 if (c_pressed(K_LEFT
))
522 if (x
<0)x
=SCREEN_X
-1;
523 if (x
+xoffset
>AREA_X
-1)x
=AREA_X
-1-xoffset
;
526 if (c_pressed(K_DOWN
))
529 if (y
>SCREEN_Y
-1||y
+yoffset
>AREA_Y
-1)y
=0;
535 if (y
<0)y
=SCREEN_Y
-1;
536 if (y
+yoffset
>AREA_Y
-1)y
=AREA_Y
-1-yoffset
;
547 if (c_was_pressed('x'))
554 if (c_was_pressed('=')||c_was_pressed(K_NUM_PLUS
)|c_was_pressed(K_PGUP
))
559 obj
->sprite
%=n_sprites
;
563 if (c_was_pressed('a')||((c_pressed(K_LEFT_SHIFT
)||c_pressed(K_RIGHT_SHIFT
))&&c_pressed('a')))
568 if (obj
->x
<0)obj
->x
=0;
572 if (c_was_pressed('d')||((c_pressed(K_LEFT_SHIFT
)||c_pressed(K_RIGHT_SHIFT
))&&c_pressed('d')))
577 if (obj
->x
>AREA_X
-1)obj
->x
=AREA_X
-1;
581 if (c_was_pressed('w')||((c_pressed(K_LEFT_SHIFT
)||c_pressed(K_RIGHT_SHIFT
))&&c_pressed('w')))
586 if (obj
->y
<0)obj
->y
=0;
590 if (c_was_pressed('s')||((c_pressed(K_LEFT_SHIFT
)||c_pressed(K_RIGHT_SHIFT
))&&c_pressed('s')))
595 if (obj
->y
>AREA_Y
-1)obj
->y
=AREA_Y
-1;
599 if (c_was_pressed('-')||c_was_pressed(K_NUM_MINUS
)||c_was_pressed(K_PGDOWN
))
602 if (!obj
->sprite
)obj
->sprite
=n_sprites
-1;
608 if ((c_pressed(K_LEFT_SHIFT
)||c_pressed(K_RIGHT_SHIFT
))&&(c_was_pressed('t')||c_was_pressed(K_TAB
)))
611 obj
->type
=prev_type(obj
->type
);
616 if (!c_pressed(K_LEFT_SHIFT
)&&!c_pressed(K_RIGHT_SHIFT
)&&(c_was_pressed('t')||c_was_pressed(K_TAB
)))
619 obj
->type
=next_type(obj
->type
);
624 if (c_was_pressed('n')||c_was_pressed(K_ENTER
))
626 new_obj(id
,cur_type
,0,cur_obj
,0,0,x
+xoffset
,y
+yoffset
,0,0,0);
631 if (c_was_pressed(K_F2
))
634 sleep_until(last_time
+1000000/35);