ee61c0dc11f6c1a8ebefd924289c4757a40f5566
[wormy.git] / wormedit.pas
1 USES CRT;
2
3 CONST GAMETYPE:ARRAY[1..8]OF STRING[12] =
4         ('SINGLEPLAYER','PEAWORM','TRON','DEATHMATCH',
5          'FOODMATCH','LINKPLAY','RACE','CTF');
6
7       OBJTYPE:ARRAY[0..3]OF STRING[8] =
8         ('NONE','LINE','FAT LINE','BAR');
9
10       ENDTYPE:ARRAY[-1..0]OF STRING[8] =
11         ('MESSAGE','NONE');
12
13       HEAD86S:STRING[53] =
14         ('**TI86**'+#$1A+#$A+#0+ {HEADER}
15          'Levelfile for Worm 0�92 made with WormEdit'); {COMMENT}
16
17       HEADEDIT = ('WormEdit�92'+#0+'LVL');
18       HEADVERSION = 92;
19
20       B:RECORD
21         HEAD:ARRAY[1..15]OF CHAR;
22         VERSION:BYTE;
23         NAME:STRING[32];
24         LSINGLE,LMULTI,LCTF,LTOTAL:BYTE;
25         LFROM:ARRAY[1..8]OF BYTE;
26         LTO:ARRAY[1..8]OF BYTE;
27         SPRSIZE:BYTE;
28         SPRITE:ARRAY[1..8]OF BYTE;
29         ENDTYPE:INTEGER;
30         ENDDATA:STRING[255];
31       END {B} =
32         (HEAD:HEADEDIT;
33          VERSION:HEADVERSION;
34          NAME:'Custom Worm Level';
35          LSINGLE:0; LMULTI:0; LCTF:0; LTOTAL:0;
36          LFROM:(0,0,0,0,0,0,0,0);
37          LTO:(0,0,0,0,0,0,0,0);
38          SPRSIZE:4;
39          SPRITE:(6*16,15*16,15*16,6*16,0,0,0,0);
40            {01100000
41             11110000
42             11110000
43             01100000}
44          ENDTYPE:0);
45
46
47 VAR I,I2:WORD;
48     II,III,I4:SHORTINT;
49     C:CHAR;
50     S:STRING;
51     F,FF:FILE;
52
53     L:ARRAY[1..64]OF RECORD
54       NAME:STRING[32];
55       SIZE:BYTE;
56       PEAS,DELAY:BYTE;
57       GROWTH,BSIZE:BYTE;
58       SPRSIZE:BYTE;
59       SPRITE:ARRAY[1..8]OF BYTE;
60       NRBALLS:BYTE;
61       BALLS:ARRAY[1..32]OF RECORD
62         Y,X,D:BYTE; {Z:%00=right+down, %11=left+up}
63       END; {BALLS}
64       W:ARRAY[1..4]OF RECORD
65         D,Y,X:BYTE;
66       END; {W(ORMS)}
67       FIELDX,FIELDY:BYTE;
68       FLAG1Y,FLAG1X:BYTE;
69       FLAG2Y,FLAG2X:BYTE;
70       NROBJ:BYTE;
71       OBJ:ARRAY[1..32]OF RECORD
72         TYP,X1,Y1,X2,Y2:BYTE;
73       END; {OBJ}
74     END; {L}
75
76     FILENAME:STRING[8];
77
78 FUNCTION NR(VALUE:INTEGER):STRING;
79 VAR NRSTR:STRING;
80 BEGIN
81   STR(VALUE,NRSTR); NR:=NRSTR;
82 END; {NR}
83
84 FUNCTION EDITMENU(EDITMENUMAX:BYTE):SHORTINT;
85 BEGIN
86   REPEAT
87     REPEAT C:=READKEY;
88     UNTIL(C>='1')AND(C<=CHR(EDITMENUMAX+48))OR(C=#27);
89     IF C=#27THEN EDITMENU:=-1 ELSE EDITMENU:=ORD(C)-48;
90   UNTIL ORD(C)<>0;
91 END; {EDITMENU}
92
93 FUNCTION COMPSIZE:WORD;
94 BEGIN
95   I:=$32+B.SPRSIZE+ORD(B.NAME[0])+
96      2*(1+(B.LTO[2]-B.LFROM[2])+(B.LTO[3]-B.LFROM[3]));
97   FOR II:=1TO B.LTOTAL DO INC(I,L[II].SIZE);
98   COMPSIZE:=I;
99 END; {COMPSIZE}
100
101 PROCEDURE EDITTITLE(BAR:SHORTINT;TITLNAME:STRING);
102 BEGIN
103   WINDOW(41,2,80,20); CLRSCR; TEXTCOLOR(15); TEXTBACKGROUND(1);
104   CASE BAR OF
105     1:BEGIN
106       WRITE('LEVELS',' ':40-6); TEXTCOLOR(7); TEXTBACKGROUND(0);
107       IF B.LTOTAL<1THEN WRITELN('NONE PRESENT')ELSE
108         FOR II:=1TO B.LTOTAL DO BEGIN
109           WRITE(II); TEXTCOLOR(3); WRITELN(': '+L[II].NAME); TEXTCOLOR(7);
110         END; {DISP LEVELS}
111     END; {1:SINGLVLS}
112     2:BEGIN
113       WRITE('LEVEL OBJECTS',' ':40-13); TEXTCOLOR(7); TEXTBACKGROUND(0);
114       IF L[II].NROBJ<1THEN WRITELN('NONE')ELSE
115         FOR I:=1TO L[II].NROBJ DO BEGIN
116           WRITE(I); TEXTCOLOR(3); WRITE(': ',OBJTYPE[L[II].OBJ[I].TYP]);
117           WRITE(' (',L[II].OBJ[I].X1,',',L[II].OBJ[I].Y1,')-(');
118           IF L[II].OBJ[I].TYP=3THEN
119             WRITELN(L[II].OBJ[I].X2,',',L[II].OBJ[I].Y1+L[II].OBJ[I].Y2,')')
120             ELSE WRITELN(L[II].OBJ[I].X2,',',L[II].OBJ[I].Y2,')');
121           TEXTCOLOR(7);
122         END; {DISP OBJS}
123     END; {2:SINGLVLS}
124     3:BEGIN
125       WRITE('LEVEL INFO',' ':40-10); TEXTCOLOR(7); TEXTBACKGROUND(0);
126       WRITELN('LEVEL #',II,' MP #',II-B.LSINGLE);
127       WRITELN('LEVEL SIZE: ',L[II].SIZE);
128       IF II<=B.LSINGLE THEN WRITELN('SINGLEPLAYER')ELSE FOR I:=2TO 7DO
129         IF(II-B.LSINGLE>=B.LFROM[I])AND(II-B.LSINGLE<=B.LTO[I])THEN
130           WRITELN(GAMETYPE[I]);
131     END; {3:LEVEL}
132     4:BEGIN
133       WRITE(FILENAME,'.LVL',' ':36-ORD(FILENAME[0])); TEXTCOLOR(7);
134       TEXTBACKGROUND(0); WRITE('FILE VERSION: '); TEXTCOLOR(3);
135       WRITELN(B.VERSION); TEXTCOLOR(7); WRITE('FILE SIZE: '); TEXTCOLOR(3);
136       WRITE(FILESIZE(F)SHR 10); TEXTCOLOR(7); WRITELN('kB');
137       WRITE('COMPILED: '); TEXTCOLOR(3); WRITE(COMPSIZE); TEXTCOLOR(7);
138       WRITE(' BYTES');
139     END; {4:FILE}
140   END; {BAR}
141   WINDOW(1,2,40,20);
142   TEXTBACKGROUND(1); TEXTCOLOR(15); WRITE(TITLNAME,' ':40-ORD(TITLNAME[0]));
143   WINDOW(1,3,40,20); TEXTBACKGROUND(0); CLRSCR;
144 END; {EDITTITLE}
145
146 PROCEDURE EDITGAME;
147 LABEL EDITGAME1,EDITGAME2;
148 BEGIN
149   REPEAT
150     EDITTITLE(1,'EDIT GAMETYPES'); TEXTCOLOR(7); WRITE('1: SINGLEPLAYER ');
151     TEXTCOLOR(3); IF B.LSINGLE=0THEN WRITELN('(NO LEVELS)')
152       ELSE WRITELN('(',B.LSINGLE,')');
153     FOR II:=2TO 7DO BEGIN
154       TEXTCOLOR(14); WRITE(II); TEXTCOLOR(7); WRITE(': '+GAMETYPE[II],' ');
155       TEXTCOLOR(3); IF B.LFROM[II]=0THEN WRITELN('(NO LEVELS)')
156         ELSE WRITELN('(',B.LFROM[II]+B.LSINGLE,'-',B.LTO[II]+B.LSINGLE,')');
157     END; {MULTIP}
158     TEXTCOLOR(7); WRITE('8: CTF '); TEXTCOLOR(3);
159     IF B.LCTF=0THEN WRITELN('(NO LEVELS)')ELSE WRITELN('(',B.LCTF,')');
160      TEXTCOLOR(7); WRITELN;III:=EDITMENU(8);
161
162     IF III>1THEN BEGIN
163 EDITGAME1:
164       WRITELN('ENTER NEW STARTING LEVEL FOR '+GAMETYPE[III]); WRITE('> ');
165       READLN(B.LFROM[III]); IF B.LFROM[III]>B.LMULTI THEN BEGIN
166         TEXTCOLOR(15); WRITE('THAT LEVEL DOES NOT EXIST! ');
167         TEXTCOLOR(7); WRITELN('JUST ',B.LMULTI,' LEVELS PRESENT.');
168         GOTO EDITGAME1;
169       END; {TOO MUCH}
170       IF B.LFROM[III]=0THEN WRITELN('NO LEVELS FOR THIS GAMETYPE.') {NO LVLS}
171       ELSE BEGIN
172 EDITGAME2:
173         WRITE('ENTER LAST LEVEL #> '); READLN(B.LTO[III]);
174         IF B.LTO[III]<B.LFROM[III]THEN BEGIN
175           WRITELN('LAST LEVEL MUST BE BEHIND THE FIRST LEVEL.'); GOTO EDITGAME2;
176         END; {ERROR}
177         IF B.LTO[III]>B.LMULTI THEN BEGIN
178           TEXTCOLOR(15); WRITE('THAT LEVEL DOES NOT (YET) EXIST! ');
179           TEXTCOLOR(7); WRITELN('JUST ',B.LMULTI,' LEVELS PRESENT.');
180           GOTO EDITGAME2;
181         END; {TOO MUCH}
182       END; {ASK LTO}
183     END; {HANDLE}
184   UNTIL III=-1; III:=0;
185 END; {EDITGAME}
186
187 PROCEDURE EDITOBJ;
188 LABEL EDITOBJ1;
189 BEGIN
190   REPEAT
191     EDITTITLE(2,'EDIT OBJECT #'+NR(I)+' IN LEVEL '+NR(II));
192     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITE(': OBJECT TYPE ');
193     III:=L[II].OBJ[I].TYP; TEXTCOLOR(3); WRITELN('(',III,')');
194     IF III<>0THEN BEGIN
195       TEXTCOLOR(14); WRITE('2'); TEXTCOLOR(7); WRITE(': OBJECT BEGIN ');
196       TEXTCOLOR(3); WRITELN('(',L[II].OBJ[I].X1,',',L[II].OBJ[I].Y1,')');
197       TEXTCOLOR(14); WRITE('3'); TEXTCOLOR(7); WRITE(': OBJECT END ');
198       TEXTCOLOR(3); IF L[II].OBJ[I].TYP=3THEN
199         WRITELN('(',L[II].OBJ[I].X2,',',L[II].OBJ[I].Y1+L[II].OBJ[I].Y2,')')
200         ELSE WRITELN('(',L[II].OBJ[I].X2,',',L[II].OBJ[I].Y2,')');
201     END; {OBJECT PROPERTIES}
202     WRITELN; TEXTCOLOR(7); IF III<>0THEN III:=EDITMENU(3)ELSE III:=EDITMENU(1);
203     CASE III OF
204       1:BEGIN
205 EDITOBJ1:
206         WRITELN('ENTER OBJECT TYPE');
207         TEXTCOLOR(8); FOR I4:=0TO 3DO WRITE(I4,': ',OBJTYPE[I4],'    ');
208         TEXTCOLOR(7); WRITELN; WRITE('> '); READLN(L[II].OBJ[I].TYP);
209         IF L[II].OBJ[I].TYP>3THEN BEGIN
210           WRITELN('INVALID TYPE!'); GOTO EDITOBJ1;
211         END; {INVALID}
212         TEXTCOLOR(8); WRITELN('SCREEN=(2,2)-(',L[II].FIELDX-2,',',L[II].FIELDY-2,
213           '); CENTER=(',(L[II].FIELDX-1)SHR 1,',',(L[II].FIELDY-1)SHR 1,')');
214         TEXTCOLOR(7); WRITE('ENTER X1> '); READLN(L[II].OBJ[I].X1);
215         WRITE('ENTER Y1> '); READLN(L[II].OBJ[I].Y1);
216         WRITE('ENTER X2> '); READLN(L[II].OBJ[I].X2);
217         WRITE('ENTER Y2> '); READLN(L[II].OBJ[I].Y2);
218         IF L[II].OBJ[I].TYP=3THEN
219           L[II].OBJ[I].Y2:=L[II].OBJ[I].Y2-L[II].OBJ[I].Y1;
220       END; {TYPE}
221       2:BEGIN
222         TEXTCOLOR(8); WRITELN('SCREEN=(2,2)-(',L[II].FIELDX-2,',',L[II].FIELDY-2,
223           '); CENTER=(',(L[II].FIELDX-1)SHR 1,',',(L[II].FIELDY-1)SHR 1,')');
224         TEXTCOLOR(7); WRITE('ENTER BEGIN X> '); READLN(L[II].OBJ[I].X1);
225         WRITE('ENTER BEGIN Y> '); READLN(L[II].OBJ[I].Y1);
226       END; {BEGIN}
227       3:BEGIN
228         TEXTCOLOR(8); WRITELN('SCREEN=(2,2)-(',L[II].FIELDX-2,',',L[II].FIELDY-2,
229           '); CENTER=(',(L[II].FIELDX-1)SHR 1,',',(L[II].FIELDY-1)SHR 1,')');
230         TEXTCOLOR(7); WRITE('ENTER END X> '); READLN(L[II].OBJ[I].X2);
231         WRITE('ENTER END Y> '); READLN(L[II].OBJ[I].Y2);
232         IF L[II].OBJ[I].TYP=3THEN
233           L[II].OBJ[I].Y2:=L[II].OBJ[I].Y2-L[II].OBJ[I].Y1;
234       END; {END}
235     END; {HANDLE}
236   UNTIL III=-1; III:=0;
237 END; {EDITOBJ}
238
239 PROCEDURE EDITOBJS;
240 LABEL EDITOBJS1,EDITOBJS2;
241 BEGIN
242   REPEAT
243     EDITTITLE(2,'EDIT LEVEL OBJECTS');
244     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITELN(': CREATE OBJECT');
245     TEXTCOLOR(14); WRITE('2'); TEXTCOLOR(7); WRITELN(': EDIT OBJECT');
246     TEXTCOLOR(14); WRITE('3'); TEXTCOLOR(7); WRITELN(': DELETE OBJECT');
247     WRITELN;
248     III:=EDITMENU(3);
249
250     CASE III OF
251       1:BEGIN
252         INC(L[II].NROBJ); I:=L[II].NROBJ; EDITOBJ;
253       END; {CREATE}
254       2:BEGIN
255 EDITOBJS1:
256         WRITE('EDIT WHICH OBJECT> '); READLN(I);
257         IF I>L[II].NROBJ THEN BEGIN
258           WRITELN('JUST ',L[II].NROBJ,' OBJECTS PRESENT!');
259           GOTO EDITOBJS1;
260         END; {DNOT EXIST}
261         IF I<>0THEN EDITOBJ;
262       END; {PEAS}
263       3:BEGIN
264 EDITOBJS2:
265         WRITE('DELETE WHICH OBJECT> '); READLN(I);
266         IF I>L[II].NROBJ THEN BEGIN
267           WRITELN('I''M SORRY BUT THAT OBJECT DOES NOT EXIST');
268           GOTO EDITOBJS2;
269         END; {ERROR}
270         IF I<>0THEN BEGIN
271           WRITE('PLEASE CONFIRM OBJECT TO '); TEXTCOLOR(15); WRITE('REMOVE');
272           TEXTCOLOR(7); WRITE('> '); READLN(I4);
273           IF I=I4 THEN BEGIN
274             DEC(L[II].NROBJ); FOR I:=I4 TO L[II].NROBJ DO L[II].OBJ[I]:=L[II].OBJ[I+1];
275           END; {OK}
276         END; {SMTN}
277       END; {DELETE}
278     END; {HANDLE}
279   UNTIL III=-1; III:=0;
280 END; {EDITOBJS}
281
282 FUNCTION BYTE2STR(SPRITE,SPRSIZE:BYTE):STRING;
283 VAR SPRTEMP:STRING[8];
284     SPRTEMP2:BYTE;
285 BEGIN
286   SPRTEMP:='';
287   FOR SPRTEMP2:=1TO 8-SPRSIZE DO SPRITE:=SPRITE SHR 1;
288   FOR SPRTEMP2:=9-SPRSIZE TO 8DO BEGIN
289     IF SPRITE MOD 2=1THEN SPRTEMP:='X'+SPRTEMP ELSE SPRTEMP:='�'+SPRTEMP;
290     SPRITE:=SPRITE SHR 1;
291   END;
292   BYTE2STR:=SPRTEMP;
293 END; {BYTE2STR}
294
295 FUNCTION STR2BYTE(SPRITE:STRING):BYTE;
296 VAR SPRTEMP,SPRTEMP2:BYTE;
297 BEGIN
298   SPRTEMP:=0; SPRTEMP2:=1;
299   FOR SPRTEMP2:=1TO LENGTH(SPRITE)DO
300     IF SPRITE[SPRTEMP2]='1'THEN INC(SPRTEMP,1SHL(8-SPRTEMP2));
301   STR2BYTE:=SPRTEMP;
302 END; {STR2BYTE}
303
304 PROCEDURE EDITSPR;
305 BEGIN
306   REPEAT
307     EDITTITLE(0,'EDIT SPRITE');
308     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITE(': SPRITE SIZE ');
309       TEXTCOLOR(3); IF L[II].SPRSIZE=0THEN WRITELN('(DEFAULT)')
310         ELSE WRITELN('(',L[II].SPRSIZE,')');
311     IF L[II].SPRSIZE=0THEN BEGIN
312       TEXTCOLOR(14); WRITE('2'); TEXTCOLOR(7); WRITE(': EDIT SPRITE');
313       TEXTCOLOR(3); WRITELN(' (DEFAULT)');
314     END {DEF SPR} ELSE FOR I:=1TO L[II].SPRSIZE DO BEGIN
315       TEXTCOLOR(14); WRITE(I+1); TEXTCOLOR(7); WRITE(': EDIT '); TEXTCOLOR(3);
316       WRITELN(BYTE2STR(L[II].SPRITE[I],L[II].SPRSIZE));
317     END; {DISP SPRITE}
318     TEXTCOLOR(7); WRITELN; III:=EDITMENU(1+L[II].SPRSIZE);
319
320     IF III=1THEN BEGIN
321       WRITE('ENTER NEW SPRITE SIZE (MAX.HEIGHT/WIDTH)> '); READLN(I);
322       IF I>L[II].SPRSIZE THEN FOR I4:=L[II].SPRSIZE+1TO I DO
323         L[II].SPRITE[I4]:=0;
324       L[II].SPRSIZE:=I;
325     END {SIZE} ELSE IF III>1THEN BEGIN
326       WRITELN('ENTER NEW LINE #',III-1,' OF SPRITE'); TEXTCOLOR(8);
327       WRITE('(ex: 100101 = X��X�X)'); TEXTCOLOR(7); WRITE('> ');
328       READLN(S); L[II].SPRITE[III-1]:=STR2BYTE(S);
329     END; {APP}
330   UNTIL III=-1; III:=0;
331 END; {EDITSPR}
332
333 PROCEDURE EDITWORMS;
334 BEGIN
335   REPEAT
336     EDITTITLE(0,'EDIT WORMS IN LEVEL #'+NR(II));
337     IF II>B.LSINGLE THEN III:=4 ELSE III:=1;
338     FOR III:=1TO III DO BEGIN
339       TEXTCOLOR(14); WRITE(III SHL 1-1); TEXTCOLOR(7);
340       WRITE(': WORM #',III,' DIRECTION '); TEXTCOLOR(3);
341       WRITELN('(',L[II].W[III].D,')');
342       TEXTCOLOR(14); WRITE(III SHL 1); TEXTCOLOR(7);
343       WRITE(': WORM #',III,' POSITION '); TEXTCOLOR(3);
344       WRITELN('(',L[II].W[III].X,',',L[II].W[III].Y,')');
345     END; {}
346     TEXTCOLOR(7); WRITELN;
347     IF III=4THEN III:=EDITMENU(8)ELSE III:=EDITMENU(2);
348
349     CASE III OF
350       1,3,5,7:BEGIN
351         WRITELN('ENTER WORM #',(III+1)SHR 1,' STARTING DIRECTION'); TEXTCOLOR(8);
352         WRITELN('(0=down; 64=right; 128=up; 192=left)');
353         TEXTCOLOR(7); WRITE('> '); READLN(I); L[II].W[(III+1)SHR 1].D:=I;
354       END; {DIR}
355       2,4,6,8:BEGIN
356         WRITELN('ENTER WORM #',III SHR 1,' BEGIN X-POSITION'); TEXTCOLOR(8);
357         WRITELN('(screen = 2-',L[II].FIELDX-2,'; center = ',L[II].FIELDX DIV 2);
358         TEXTCOLOR(7); WRITE('> '); READLN(I); L[II].W[III SHR 1].X:=I;
359         WRITELN('ENTER WORM #',III SHR 1,' BEGIN Y-POSITION'); TEXTCOLOR(8);
360         WRITELN('(screen = 2-',L[II].FIELDY-2,'; center = ',L[II].FIELDY DIV 2);
361         TEXTCOLOR(7); WRITE('> '); READLN(I); L[II].W[III SHR 1].Y:=I;
362       END; {POS}
363     END; {HANDLE}
364   UNTIL III=-1; III:=0;
365 END; {EDITWORMS}
366
367 PROCEDURE EDITLEVEL;
368 BEGIN
369   REPEAT
370     L[II].SIZE:=12+L[II].NRBALLS+L[II].SPRSIZE+L[II].NROBJ*5;
371       IF II>B.LSINGLE THEN INC(L[II].SIZE,9);
372     EDITTITLE(3,'EDIT LEVEL #'+NR(II));
373     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITE(': DESCRIPTION ');
374       TEXTCOLOR(3); WRITELN('(',L[II].NAME,')');
375     TEXTCOLOR(14); WRITE('2'); TEXTCOLOR(7); WRITE(': NUMBER OF PEAS ');
376       TEXTCOLOR(3); WRITELN('(',L[II].PEAS,')');
377     TEXTCOLOR(14); WRITE('3'); TEXTCOLOR(7); WRITE(': GAME DELAY ');
378       TEXTCOLOR(3); WRITELN('(',L[II].DELAY,')');
379     TEXTCOLOR(14); WRITE('4'); TEXTCOLOR(7); WRITE(': GROWTH ');
380       TEXTCOLOR(3); WRITELN('(',L[II].GROWTH,'+',L[II].BSIZE,')');
381     TEXTCOLOR(14); WRITE('5'); TEXTCOLOR(7); WRITE(': SPRITE ');
382       TEXTCOLOR(3); IF L[II].SPRSIZE=0THEN WRITELN('(DEFAULT)')
383                     ELSE WRITELN('(',L[II].SPRSIZE,')');
384     TEXTCOLOR(14); WRITE('6'); TEXTCOLOR(7); WRITE(': BOUNCY BALLS ');
385       TEXTCOLOR(3); WRITELN('(',L[II].NRBALLS,')');
386     TEXTCOLOR(14); WRITE('7'); TEXTCOLOR(7); WRITE(': WORMS '); TEXTCOLOR(3);
387       IF II>B.LSINGLE THEN BEGIN
388         WRITELN('(',L[II].W[1].D,';',L[II].W[2].D,';',L[II].W[3].D,';',L[II].W[4].D,')');
389       END {FOUR WORMS} ELSE
390         WRITELN('(',L[II].W[1].X,',',L[II].W[1].Y,':',L[II].W[1].D,')');
391     TEXTCOLOR(14); WRITE('8'); TEXTCOLOR(7); WRITE(': FIELD SIZE ');
392       TEXTCOLOR(3); WRITELN('(',L[II].FIELDX,',',L[II].FIELDY,')');
393     TEXTCOLOR(14); WRITE('9'); TEXTCOLOR(7); WRITE(': OBJECTS ');
394       TEXTCOLOR(3); WRITELN('(',L[II].NROBJ,')');
395     TEXTCOLOR(7); WRITELN;
396     III:=EDITMENU(9);
397
398     CASE III OF
399       1:BEGIN
400         WRITELN('ENTER DESCRIPTION FOR THIS LEVEL'); WRITE('> ');
401         READLN(S); IF S<>''THEN L[II].NAME:=S;
402       END; {DESCR}
403       2:BEGIN
404         WRITE('ENTER TOTAL NUMBER OF PEAS> ');
405         READLN(I); L[II].PEAS:=I;
406       END; {PEAS}
407       3:BEGIN
408         WRITE('ENTER NEW DELAY '); TEXTCOLOR(8); WRITE('(0=fastest; 4=def.)');
409         TEXTCOLOR(7); WRITE('> '); READLN(I); L[II].DELAY:=I;
410       END; {DELAY}
411       4:BEGIN
412         WRITE('ENTER GROWTH PER PEA '); TEXTCOLOR(8); WRITE('(15=default)');
413         TEXTCOLOR(7); WRITE('> '); READLN(I); L[II].GROWTH:=I;
414         WRITE('ENTER WORM BEGIN SIZE '); TEXTCOLOR(8); WRITE('(15=default)');
415         TEXTCOLOR(7); WRITE('> '); READLN(I); L[II].BSIZE:=I;
416       END; {GROWTH}
417       5:EDITSPR;
418       7:EDITWORMS;
419       8:BEGIN
420         WRITELN('ENTER FIELD WIDTH'); TEXTCOLOR(8);
421         WRITE('(128=screen-width; 255=max.)');
422         TEXTCOLOR(7); WRITE('> '); READLN(I); L[II].FIELDX:=BYTE(I);
423         WRITELN('ENTER FIELD HEIGHT'); TEXTCOLOR(8);
424         WRITE('(57=screen-height 255=max.)');
425         TEXTCOLOR(7); WRITE('> '); READLN(I); L[II].FIELDY:=BYTE(I);
426       END; {FIELD}
427       9:EDITOBJS;
428     END; {HANDLE}
429   UNTIL III=-1; III:=0;
430 END; {EDITLEVEL}
431
432 PROCEDURE EDITLVL;
433 LABEL EDITHLVL1,EDITHLVL2;
434 BEGIN
435   REPEAT
436     EDITTITLE(1,'EDIT LEVELS');
437     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITELN(': EDIT LEVEL');
438     TEXTCOLOR(14); WRITE('2'); TEXTCOLOR(7); WRITELN(': DELETE LEVEL');
439     TEXTCOLOR(14); WRITE('3'); TEXTCOLOR(7); WRITELN(': CREATE SINGLEPLAYER LEVEL');
440     TEXTCOLOR(14); WRITE('4'); TEXTCOLOR(7); WRITELN(': CREATE MULTIPLAYER LEVEL');
441     TEXTCOLOR(7); WRITE('5'); TEXTCOLOR(7); WRITELN(': CREATE CTF LEVEL');
442     TEXTCOLOR(7); WRITELN; III:=EDITMENU(4);
443
444     CASE III OF
445       1:BEGIN
446 EDITHLVL1:
447         WRITE('EDIT WHICH LEVEL> '); READLN(II);
448         IF II>B.LTOTAL THEN BEGIN
449           WRITELN('THAT LEVEL DOES NOT EXIST!'); GOTO EDITHLVL1;
450         END; {ERROR}
451         IF II<>0THEN EDITLEVEL;
452       END; {EDIT}
453       2:BEGIN
454 EDITHLVL2:
455         WRITE('DELETE WHICH LEVEL> '); READLN(II);
456         IF II>B.LTOTAL THEN BEGIN
457           WRITELN('YOU CANNOT DELETE A LEVEL THAT DOES NOT EXIST!');
458           GOTO EDITHLVL2;
459         END; {ERROR}
460         IF II<>0THEN BEGIN
461           WRITE('PLEASE CONFIRM LEVEL TO '); TEXTCOLOR(15); WRITE('DELETE');
462           TEXTCOLOR(7); WRITE('> '); READLN(I);
463           IF I=II THEN BEGIN
464             IF I<=B.LSINGLE THEN DEC(B.LSINGLE)ELSE
465               IF I<=B.LMULTI+B.LSINGLE THEN DEC(B.LMULTI)ELSE
466                 DEC(B.LCTF);
467             DEC(B.LTOTAL); FOR I:=II TO B.LTOTAL DO L[I]:=L[I+1];
468             FOR I:=2TO 7DO BEGIN
469               IF B.LTO[I]>B.LMULTI THEN B.LTO[I]:=B.LMULTI;
470               IF B.LFROM[I]>B.LTO[I]THEN B.LFROM[I]:=B.LTO[I];
471             END; {CHECK}
472           END; {OK}
473         END; {SMTN}
474       END; {DELETE}
475
476       3:BEGIN
477         INC(B.LSINGLE); INC(B.LTOTAL); II:=B.LSINGLE;
478         FOR I:=B.LTOTAL DOWNTO II+1DO L[I]:=L[I-1];
479         L[II].NAME:='Level #'+NR(II);
480         L[II].PEAS:=8; L[II].DELAY:=4; L[II].GROWTH:=15; L[II].BSIZE:=15;
481         L[II].SPRSIZE:=0; L[II].NRBALLS:=0; L[II].W[1].D:=0; L[II].W[1].X:=63;
482         L[II].W[1].Y:=2; L[II].FIELDX:=128; L[II].FIELDY:=57; L[II].NROBJ:=0;
483         EDITLEVEL;
484       END; {CREATE SP}
485       4:BEGIN
486         FOR I:=2TO 7DO IF B.LTO[I]=B.LMULTI THEN BEGIN
487           INC(B.LTO[I]); IF B.LFROM[I]=0THEN INC(B.LFROM[I]);
488         END; {}
489         INC(B.LTOTAL); INC(B.LMULTI); II:=B.LSINGLE+B.LMULTI;
490         FOR I:=B.LTOTAL DOWNTO II+1DO L[I]:=L[I-1];
491         L[II].NAME:='Arena #'+NR(B.LMULTI);
492         L[II].DELAY:=4; L[II].GROWTH:=15; L[II].BSIZE:=15; L[II].SPRSIZE:=0;
493         L[II].W[1].D:=$40; L[II].W[1].Y:=28; L[II].W[1].X:=2;
494         L[II].W[2].D:=$C0; L[II].W[2].Y:=28; L[II].W[2].X:=125;
495         L[II].W[3].D:=$00; L[II].W[3].Y:=02; L[II].W[3].X:=63;
496         L[II].W[4].D:=$80; L[II].W[4].Y:=54; L[II].W[4].X:=63;
497         L[II].NRBALLS:=0; L[II].FIELDX:=128; L[II].FIELDY:=57;
498         L[II].NROBJ:=0; EDITLEVEL;
499       END; {CREATE MP}
500     END; {HANDLE}
501   UNTIL III=-1; III:=0;
502 END; {EDITLVL}
503
504 PROCEDURE EDITDSPR;
505 BEGIN
506   REPEAT
507     EDITTITLE(0,'EDIT DEFAULT SPRITE');
508     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITE(': SPRITE SIZE ');
509       TEXTCOLOR(3); WRITELN('(',B.SPRSIZE,')');
510     FOR I:=1TO B.SPRSIZE DO BEGIN
511       TEXTCOLOR(14); WRITE(I+1); TEXTCOLOR(7); WRITE(': EDIT '); TEXTCOLOR(3);
512       WRITELN(BYTE2STR(B.SPRITE[I],B.SPRSIZE));
513     END; {DISP SPRITE}
514     TEXTCOLOR(7); WRITELN; III:=EDITMENU(1+B.SPRSIZE);
515
516     IF III=1THEN BEGIN
517       WRITELN('ENTER THE DEFAULT SPRITE SIZE'); TEXTCOLOR(8);
518       WRITE('(1-8; can be changed per level)'); TEXTCOLOR(7); WRITE('> ');
519       READLN(I); IF(I>0)AND(I<=8)THEN BEGIN
520         IF I>B.SPRSIZE THEN FOR I4:=B.SPRSIZE+1TO I DO B.SPRITE[I4]:=0;
521         B.SPRSIZE:=I;
522       END; {OK}
523     END {SIZE} ELSE IF III>1THEN BEGIN
524       WRITELN('ENTER NEW LINE #',III-1,' OF SPRITE'); TEXTCOLOR(8);
525       WRITE('(ex: 100101 = X��X�X)'); TEXTCOLOR(7); WRITE('> ');
526       READLN(S); B.SPRITE[III-1]:=STR2BYTE(S);
527     END; {APP}
528   UNTIL III=-1; III:=0;
529 END; {EDITDSPR}
530
531 PROCEDURE EDITSPEND;
532 BEGIN
533   REPEAT
534     EDITTITLE(0,'SINGLEPLAYER ENDING');
535     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITE(': END TYPE ');
536       TEXTCOLOR(3); WRITELN(' (',ENDTYPE[B.ENDTYPE],')'); TEXTCOLOR(14);
537     CASE B.ENDTYPE OF
538       -1:BEGIN
539         WRITE('2'); TEXTCOLOR(7); WRITE(': EDIT MESSAGE');
540         TEXTCOLOR(3); WRITE(' (',COPY(B.ENDDATA,1,18));
541         IF LENGTH(B.ENDDATA)>18THEN WRITELN('...)')ELSE WRITELN(')');
542       END; {MSG}
543     END; {TYPE} TEXTCOLOR(7); WRITELN; III:=EDITMENU(2);
544     CASE III OF
545       1:BEGIN
546         WRITELN('ENTER NEW END TYPE:'); TEXTCOLOR(8);
547         FOR II:=0TO 1DO WRITE(II,': ',ENDTYPE[-II],'  '); WRITELN; TEXTCOLOR(7);
548         WRITE('> '); READLN(II); IF(II<=1)AND(II>=0)THEN B.ENDTYPE:=-II;
549         IF II=1THEN B.ENDDATA:='Congratulations!!';
550       END; {TITLE}
551       2:BEGIN
552         CASE B.ENDTYPE OF
553           -1:BEGIN
554             WRITE('ENTER NEW END MESSAGE '); TEXTCOLOR(8);
555             WRITELN('(max 255 chars)'); WRITE('> ');
556             READLN(S); IF S<>''THEN B.ENDDATA:=S;
557           END; {MSG}
558         END; {TYPE}
559       END; {EDIT}
560     END; {HANDLE}
561   UNTIL III=-1; III:=0;
562 END; {EDITSPEND}
563
564
565 PROCEDURE EDITMAIN;
566 BEGIN
567   REPEAT
568     S:=''; FOR II:=1TO LENGTH(B.NAME)DO S:=S+UPCASE(B.NAME[II]); EDITTITLE(4,S);
569     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITELN(': EDIT TITLE');
570     TEXTCOLOR(14); WRITE('2'); TEXTCOLOR(7); WRITE(': DEFAULT SPRITE');
571       TEXTCOLOR(3); WRITELN(' (',B.SPRSIZE,')');
572     TEXTCOLOR(14); WRITE('3'); TEXTCOLOR(7); WRITELN(': GAME TYPES');
573     TEXTCOLOR(14); WRITE('4'); TEXTCOLOR(7); WRITE(': SP ENDING');
574       TEXTCOLOR(3); WRITELN(' (',ENDTYPE[B.ENDTYPE],')');
575     TEXTCOLOR(14); WRITE('5'); TEXTCOLOR(7); WRITE(': LEVELS');
576       TEXTCOLOR(3); WRITELN(' (',B.LTOTAL,')');
577     TEXTCOLOR(7); WRITELN; III:=EDITMENU(5);
578     CASE III OF
579       1:BEGIN
580         WRITELN('ENTER NEW TITLE FOR THIS LEVELFILE ');
581         TEXTCOLOR(8); WRITE('enter=don''t alter; max. length 32 chars ');
582         TEXTCOLOR(7); WRITE('> '); READLN(S); IF S<>''THEN B.NAME:=S;
583       END; {TITLE}
584       2:EDITDSPR;
585       3:EDITGAME;
586       4:EDITSPEND;
587       5:EDITLVL;
588     END; {HANDLE}
589   UNTIL III=-1; III:=0;
590 END; {EDITMAIN}
591
592 PROCEDURE OPENFILE;
593 BEGIN
594   ASSIGN(F,FILENAME+'.LVL'); {$I-} RESET(F,1); {$I+} IF IORESULT=0THEN BEGIN
595     {$I-} BLOCKREAD(F,B,SIZEOF(B)); BLOCKREAD(F,L,SIZEOF(L)); {$I+}
596     IF(IORESULT<>0)OR(B.HEAD<>HEADEDIT)THEN BEGIN
597       TEXTCOLOR(15); WRITE('WARNING!! '); TEXTCOLOR(7);
598       WRITELN('ERROR READING LEVEL FILE!');
599       CLOSE(F); HALT;
600     END; {ERROR}
601     IF B.VERSION<>HEADVERSION THEN BEGIN
602       WRITELN('CAN''T READ FILE VERSION ',B.VERSION,'.'); CLOSE(F); HALT;
603     END; {VERSION}
604   END; {OPEN EXISTING FILE}
605 END; {OPENFILE}
606
607 PROCEDURE FILESAVE;
608 BEGIN
609   ASSIGN(F,FILENAME+'.LVL'); REWRITE(F,1);
610   BLOCKWRITE(F,B,SIZEOF(B)); BLOCKWRITE(F,L,SIZEOF(L)); CLOSE(F);
611 END; {FILESAVE}
612
613 PROCEDURE FILECOMP;
614 VAR ISTACK:WORD;
615 BEGIN
616   ASSIGN(FF,FILENAME+'.86S'); REWRITE(FF,1);
617
618   BLOCKWRITE(FF,HEAD86S[1],ORD(HEAD86S[0])); {86S-HEADER}
619   ISTACK:=$12+6+B.SPRSIZE+ORD(B.NAME[0])+24+2+
620     2*(1+(B.LTO[2]-B.LFROM[2])+(B.LTO[3]-B.LFROM[3]));
621   FOR II:=1TO B.LTOTAL DO INC(ISTACK,L[II].SIZE);
622   BLOCKWRITE(FF,ISTACK,2); {FILE LENGTH (x+$12)}
623   I:=$000C; BLOCKWRITE(FF,I,2); {STRING ID}
624   DEC(ISTACK,$10); BLOCKWRITE(FF,ISTACK,2); {DATA LENGTH (x+2)}
625
626   I:=$080C; BLOCKWRITE(FF,I,2); {STRING ID}
627   S:='wormlvl1'; BLOCKWRITE(FF,S[1],8); {PRGNAME}
628   BLOCKWRITE(FF,ISTACK,2); {DATA LENGTH (x+2)}
629   DEC(ISTACK,2); BLOCKWRITE(FF,ISTACK,2); {PROG LENGTH (x)}
630
631   C:='w'; BLOCKWRITE(FF,C,1); {WORM ID}
632   I:=92; BLOCKWRITE(FF,I,1); {VERSION}
633   BLOCKWRITE(FF,B.NAME[0],ORD(B.NAME[0])+1); {TITLE}
634   I:=1+B.SPRSIZE+2; FOR II:=1TO B.LTOTAL DO I:=I+L[II].SIZE;
635   BLOCKWRITE(FF,I,2); {SIZE}
636
637   I2:=0; I:=$F401+B.SPRSIZE;
638   IF B.LSINGLE=0THEN BLOCKWRITE(FF,I2,2)ELSE BEGIN
639     BLOCKWRITE(FF,I,2); FOR II:=1TO B.LSINGLE DO INC(I,L[II].SIZE);
640   END; {SINGLLVLS} INC(I,2);
641   ISTACK:=I; FOR II:=2TO 7DO BEGIN
642     I:=ISTACK; IF B.LFROM[II]=0THEN I:=0 ELSE
643       FOR III:=B.LSINGLE TO B.LSINGLE+B.LFROM[II]-2DO
644         INC(I,L[III].SIZE);
645     BLOCKWRITE(FF,I,2);
646   END; {LOC}
647   FOR II:=B.LSINGLE+B.LMULTI+1TO B.LTOTAL DO INC(ISTACK,L[II].SIZE);
648   I:=0; IF B.LCTF=0THEN BLOCKWRITE(FF,I,2)ELSE BLOCKWRITE(FF,ISTACK,2);
649
650   BLOCKWRITE(FF,B.LSINGLE,1);
651   FOR II:=2TO 7DO BEGIN
652     IF B.LFROM[II]=0THEN I:=0 ELSE I:=B.LTO[II]-B.LFROM[II]+1;
653     BLOCKWRITE(FF,I,1);
654   END; {NR}
655   BLOCKWRITE(FF,B.LCTF,1);
656
657   BLOCKWRITE(FF,B.SPRSIZE,1);
658   BLOCKWRITE(FF,B.SPRITE,B.SPRSIZE);
659
660   FOR II:=1TO B.LSINGLE DO BEGIN
661     BLOCKWRITE(FF,L[II].PEAS,1);
662     BLOCKWRITE(FF,L[II].DELAY,1);
663     BLOCKWRITE(FF,L[II].GROWTH,1);
664     BLOCKWRITE(FF,L[II].BSIZE,1);
665     BLOCKWRITE(FF,L[II].SPRSIZE,1);
666     BLOCKWRITE(FF,L[II].SPRITE,L[II].SPRSIZE);
667     BLOCKWRITE(FF,L[II].NRBALLS,1);
668     BLOCKWRITE(FF,L[II].BALLS,L[II].NRBALLS*3);
669     BLOCKWRITE(FF,L[II].W[1].D,3); {D,X,Y}
670     BLOCKWRITE(FF,L[II].FIELDX,2); {FIELDX,FIELDY}
671     FOR I:=1TO L[II].NROBJ DO BEGIN
672       BLOCKWRITE(FF,L[II].OBJ[I].TYP,5);
673     END; {OBJS}
674     I:=0; BLOCKWRITE(FF,I,1); {LVL END}
675   END; {LEVELS SINGLEPL}
676
677   I:=255; BLOCKWRITE(FF,I,1); {END}
678   I:=$C9; BLOCKWRITE(FF,I,1); {RET}
679
680   FOR II:=B.LSINGLE+1TO B.LSINGLE+B.LMULTI DO BEGIN
681     BLOCKWRITE(FF,L[II].PEAS,1);
682     BLOCKWRITE(FF,L[II].DELAY,1);
683     BLOCKWRITE(FF,L[II].GROWTH,1);
684     BLOCKWRITE(FF,L[II].BSIZE,1);
685     BLOCKWRITE(FF,L[II].SPRSIZE,1);
686     BLOCKWRITE(FF,L[II].SPRITE,L[II].SPRSIZE);
687     BLOCKWRITE(FF,L[II].NRBALLS,1);
688     BLOCKWRITE(FF,L[II].BALLS,L[II].NRBALLS*3);
689     BLOCKWRITE(FF,L[II].W[1].D,3*4); {D,X,Y}
690     BLOCKWRITE(FF,L[II].FIELDX,2); {FIELDX,FIELDY}
691     FOR I:=1TO L[II].NROBJ DO BEGIN
692       BLOCKWRITE(FF,L[II].OBJ[I].TYP,5);
693     END; {OBJS}
694     I:=0; BLOCKWRITE(FF,I,1); {LVL END}
695   END; {LEVELS MULTIPL}
696
697   I:=0; FOR II:=1TO 1+(B.LTO[2]-B.LFROM[2])+(B.LTO[3]-B.LFROM[3])DO
698     BLOCKWRITE(FF,I,2); {HI}
699
700   SEEK(FF,$37); I2:=0; I:=0;
701   REPEAT INC(I,I2); BLOCKREAD(FF,I2,1,ISTACK); UNTIL ISTACK<>1;
702   BLOCKWRITE(FF,I,2); {CHECKSUM}
703 END; {FILECOMP}
704
705 PROCEDURE EDITQUIT;
706 BEGIN
707   REPEAT
708     EDITTITLE(0,'CHOOSE LEVELFILE');
709     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITELN(': COMPILE, SAVE AND QUIT');
710     TEXTCOLOR(14); WRITE('2'); TEXTCOLOR(7); WRITE(': SAVE ');
711       TEXTCOLOR(3); WRITELN(FILENAME,'.LVL');
712     TEXTCOLOR(14); WRITE('3'); TEXTCOLOR(7); WRITELN(': QUIT');
713     TEXTCOLOR(14); WRITE('4'); TEXTCOLOR(7); WRITELN(': CONTINUE EDITING');
714     WRITELN; III:=EDITMENU(4);
715     CASE III OF
716       1:BEGIN
717         FILESAVE; FILECOMP; HALT;
718       END; {COMPILE}
719       2:FILESAVE;
720       3:BEGIN
721         WRITE('REALLY QUIT '); TEXTCOLOR(8); WRITE('[Y/N]'); TEXTCOLOR(7);
722         WRITE('> '); REPEAT C:=READKEY; UNTIL(UPCASE(C)='Y')OR(UPCASE(C)='N');
723         IF UPCASE(C)='N'THEN III:=0;
724       END; {QUIT}
725       4:EDITMAIN;
726     END; {HANDLE}
727   UNTIL III=3; HALT;
728 END; {EDITQUIT}
729
730 PROCEDURE EDITFILE;
731 BEGIN
732   REPEAT
733     EDITTITLE(0,'CHOOSE LEVELFILE');
734     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITELN(': CREATE NEW FILE');
735     TEXTCOLOR(14); WRITE('2'); TEXTCOLOR(7); WRITELN(': EDIT EXISTING');
736     TEXTCOLOR(14); WRITE('3'); TEXTCOLOR(7); WRITE(': EDIT'); TEXTCOLOR(3);
737     WRITELN(' WORMLVL1.LVL'); TEXTCOLOR(7); WRITELN; III:=EDITMENU(3);
738     CASE III OF
739       1:BEGIN
740         WRITE('ENTER FILENAME '); TEXTCOLOR(8); WRITE('(max.8 chars)');
741         TEXTCOLOR(7); WRITE('> '); READLN(FILENAME); EDITMAIN; EDITQUIT;
742       END; {NEW}
743       2:BEGIN
744         WRITE('ENTER LEVELNAME '); TEXTCOLOR(8); WRITE('(w/o extension)');
745         TEXTCOLOR(7); WRITE('> '); READLN(FILENAME); OPENFILE; EDITMAIN;
746         EDITQUIT;
747       END; {EDIT}
748       3:BEGIN
749         FILENAME:='WORMLVL1'; OPENFILE; EDITMAIN; EDITQUIT;
750       END; {WORMLVL1}
751     END; {HANDLE}
752   UNTIL III=-1;
753 END; {EDITFILE}
754
755
756 BEGIN
757   CLRSCR;
758   TEXTCOLOR(1); WRITE('���������������������������<');
759   TEXTCOLOR(14); WRITE(' WormEdit � ');
760   TEXTCOLOR(15); WRITE(' by SHIAR ');
761   TEXTCOLOR(1); WRITE('>�����������������������������');
762   EDITFILE;
763 END.