22918c0b449c99f2b9145b56af43d2df5e00278b
[wormy.git] / wormedit.pas
1 USES CRT,SHIAR;
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..4]OF STRING[8] =
8         ('NONE','LINE','FAT LINE','BAR','CIRCLE');
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�93 made with WormEdit'); {COMMENT}
16
17       HEADEDIT = ('WormEdit�93'+#0+'LVL');
18       HEADVERSION = 93;
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:(1,0,0,0,0,0,0,0);
37          LTO:(1,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       LVLPOS:BYTE = 1;
47       OBJPOS:BYTE = 1;
48
49 VAR I,I2:WORD;
50     II,III,I4:SHORTINT;
51     C:CHAR;
52     S:STRING;
53     F,FF:FILE;
54
55     L:ARRAY[1..64]OF RECORD
56       NAME:STRING[22];
57       SIZE:BYTE;
58       PEAS,DELAY:BYTE;
59       GROWTH,BSIZE:BYTE;
60       SPRSIZE:BYTE;
61       SPRITE:ARRAY[1..8]OF BYTE;
62       NRBALLS:BYTE;
63       BALLS:ARRAY[1..32]OF RECORD
64         Y,X,D:BYTE; {Z:%00=right+down, %11=left+up}
65       END; {BALLS}
66       W:ARRAY[1..4]OF RECORD
67         D,Y,X:BYTE;
68       END; {W(ORMS)}
69       FIELDX,FIELDY:BYTE;
70       FLAG1Y,FLAG1X:BYTE;
71       FLAG2Y,FLAG2X:BYTE;
72       NROBJ:BYTE;
73       OBJ:ARRAY[1..32]OF RECORD
74         TYP,X1,Y1,X2,Y2:BYTE;
75       END; {OBJ}
76     END; {L}
77
78     FILENAME:STRING[8];
79
80 PROCEDURE MAINTITLE;
81 BEGIN
82   SETTEXT; CLRSCR;
83   TEXTCOLOR(1); WRITE('���������������������������<');
84   TEXTCOLOR(14); WRITE(' WormEdit � ');
85   TEXTCOLOR(15); WRITE(' by SHIAR ');
86   TEXTCOLOR(1); WRITE('>�����������������������������');
87   WINDOW(41,2,41,25); TEXTCOLOR(7); TEXTBACKGROUND(0); WRITE(CC('�',23));
88   WINDOW(1,25,80,25); TEXTBACKGROUND(1); CLRSCR;
89   GOTOXY(75,1); TEXTCOLOR(0); WRITE('v0.93'); TEXTBACKGROUND(0);
90 END; {MAINTITLE}
91
92 PROCEDURE CIRCLE(X,Y,Z,COL:BYTE);
93 VAR XX,YY,ZZ:INTEGER;
94 BEGIN
95   XX:=-1; YY:=Z; ZZ:=-Z;
96   REPEAT
97     INC(XX);
98     LINE(X-XX,Y+YY,X+XX,Y+YY,COL,VGA);
99     LINE(X-XX,Y-YY,X+XX,Y-YY,COL,VGA);
100     LINE(X-YY,Y+XX,X+YY,Y+XX,COL,VGA);
101     LINE(X-YY,Y-XX,X+YY,Y-XX,COL,VGA);
102     IF ZZ>=0THEN BEGIN ZZ:=ZZ-(YY SHL 1)+2; DEC(YY); END;
103     ZZ:=ZZ+(XX SHL 1)+3;
104   UNTIL XX>=YY;
105 END; {CIRCLE}
106
107 PROCEDURE DISPMAP(OBJ:INTEGER);
108 VAR OBJ2:INTEGER;
109 PROCEDURE DISPOBJ(OBJ:INTEGER;COL:BYTE);
110 VAR Y:BYTE;
111 BEGIN
112   CASE L[II].OBJ[OBJ].TYP OF
113     1:LINE(L[II].OBJ[OBJ].X1,L[II].OBJ[OBJ].Y1,L[II].OBJ[OBJ].X2,L[II].OBJ[OBJ].Y2,COL,VGA);
114     2:BEGIN
115       LINE(L[II].OBJ[OBJ].X1,L[II].OBJ[OBJ].Y1,L[II].OBJ[OBJ].X2,L[II].OBJ[OBJ].Y2,COL,VGA);
116       LINE(L[II].OBJ[OBJ].X1+1,L[II].OBJ[OBJ].Y1,L[II].OBJ[OBJ].X2+1,L[II].OBJ[OBJ].Y2,COL,VGA);
117       LINE(L[II].OBJ[OBJ].X1+1,L[II].OBJ[OBJ].Y1+1,L[II].OBJ[OBJ].X2+1,L[II].OBJ[OBJ].Y2+1,COL,VGA);
118       LINE(L[II].OBJ[OBJ].X1,L[II].OBJ[OBJ].Y1+1,L[II].OBJ[OBJ].X2,L[II].OBJ[OBJ].Y2+1,COL,VGA);
119     END; {FATLINE}
120     3:BEGIN
121       FOR Y:=L[II].OBJ[OBJ].Y1 TO L[II].OBJ[OBJ].Y1+L[II].OBJ[OBJ].Y2 DO
122         LINE(L[II].OBJ[OBJ].X1,MIN(Y,191),L[II].OBJ[OBJ].X2,MIN(Y,191),COL,VGA);
123     END; {BOX}
124     4:CIRCLE(L[II].OBJ[OBJ].X1,L[II].OBJ[OBJ].Y1,L[II].OBJ[OBJ].X2,COL);
125   END; {OBJECT TYPE}
126 END; {DISPOBJ}
127 BEGIN
128   SETMCGA;
129   LINE(0,56,255,56,8,VGA); LINE(0,113,255,113,8,VGA);
130   LINE(0,170,255,170,8,VGA); {LINE(0,227,255,227,8,VGA);}
131   LINE(127,0,127,170,8,VGA); LINE(255,0,255,170,8,VGA);
132   LINE(0,0,255,0,15,VGA); LINE(0,1,255,1,15,VGA);
133   LINE(0,2,0,190-3,15,VGA); LINE(1,2,1,190-3,15,VGA);
134   LINE(L[II].FIELDX-2,2,L[II].FIELDX-2,L[II].FIELDY-1,15,VGA);
135   LINE(L[II].FIELDX-1,2,L[II].FIELDX-1,L[II].FIELDY-1,15,VGA);
136   LINE(0,L[II].FIELDY-2,L[II].FIELDX-1,L[II].FIELDY-2,15,VGA);
137   LINE(0,L[II].FIELDY-1,L[II].FIELDX-1,L[II].FIELDY-1,15,VGA);
138   FOR OBJ2:=1TO L[II].NROBJ DO IF OBJ2<>OBJ THEN DISPOBJ(OBJ2,7);
139   IF(OBJ>0)AND(OBJ<=L[II].NROBJ)THEN DISPOBJ(OBJ,14);
140   REPEAT UNTIL READKEY<>#0;
141   MAINTITLE;
142 END; {DISPMAP}
143
144 FUNCTION NR(VALUE:LONGINT):STRING;
145 VAR NRSTR:STRING;
146 BEGIN
147   STR(VALUE,NRSTR); NR:=NRSTR;
148 END; {NR}
149
150 PROCEDURE HELPBAR(HELPPAGE:BYTE);
151 BEGIN
152   WINDOW(41,14,80,24);
153   IF HELPPAGE=0THEN BEGIN
154     TEXTCOLOR(7); WRITE('�'); WINDOW(42,14,80,24); CLRSCR; EXIT;
155   END; {REMOVE}
156   TEXTBACKGROUND(1); TEXTCOLOR(7); WRITE('�'); TEXTCOLOR(15);
157   WRITE('HELP',' ':39-4); WINDOW(42,15,80,24); TEXTBACKGROUND(0); TEXTCOLOR(7);
158   CLRSCR; CASE HELPPAGE OF
159     1:WRITE('PRESS <F1> OR <H> FOR HELP');
160     2:WRITE('YOU UNDERSTAND EVERYTHING');
161     3:WRITE('THIS AIN''T A BUG, IT A FEATURE!');
162   END; {TEXT TO DISPLAY}
163 END; {HELPBAR}
164
165 PROCEDURE DISPLEVELS;
166 BEGIN
167   WINDOW(42,3,80,13); TEXTBACKGROUND(0); CLRSCR;
168   IF B.LTOTAL<1THEN WRITELN('NONE PRESENT')ELSE
169     FOR II:=LVLPOS TO MIN(B.LTOTAL,LVLPOS+9)DO BEGIN
170       WRITE(II); TEXTCOLOR(3); WRITELN(': '+L[II].NAME); TEXTCOLOR(7);
171     END; {DISP LEVELS}
172 END; {DISPLEVELS}
173
174 FUNCTION EDITMENU(EDITMENUMAX,HELPPAGE:BYTE):SHORTINT;
175 VAR EDITOK:SHORTINT;
176 BEGIN
177   EDITOK:=0; REPEAT
178     WINDOW(39,1,39,1); GOTOXY(1,1); REPEAT UNTIL KEYPRESSED; C:=READKEY;
179     IF C=' 'THEN EDITOK:=10; {10}
180     IF(C>='1')AND(C<=CHR(EDITMENUMAX+48))THEN EDITOK:=ORD(C)-48; {1..<=9}
181     IF(C=#27)OR(C='-')OR(C='+')THEN EDITOK:=-1; {EXIT}
182     IF C=#0THEN BEGIN  C:=READKEY;
183       IF(C=#80)AND(LVLPOS<B.LTOTAL-9)THEN BEGIN INC(LVLPOS); DISPLEVELS; END; {DOWN}
184       IF(C=#72)AND(LVLPOS>1)THEN BEGIN DEC(LVLPOS); DISPLEVELS; END; {DOWN}
185       IF C=#59THEN HELPBAR(HELPPAGE);
186     END; {EXTENDED}
187     IF UPCASE(C)='H'THEN HELPBAR(HELPPAGE);
188   UNTIL EDITOK<>0; EDITMENU:=EDITOK;
189 END; {EDITMENU}
190
191 FUNCTION COMPSIZE:WORD;
192 BEGIN
193   I:=$32+B.SPRSIZE+ORD(B.NAME[0])+
194      2*(1+(B.LTO[2]-B.LFROM[2])+(B.LTO[3]-B.LFROM[3]));
195   FOR II:=1TO B.LTOTAL DO INC(I,L[II].SIZE);
196   COMPSIZE:=I;
197 END; {COMPSIZE}
198
199 PROCEDURE TITLEBAR(BAR:SHORTINT;TITLNAME:STRING);
200 BEGIN
201   HELPBAR(0); WINDOW(41,2,42,2);
202   IF BAR=0THEN TEXTBACKGROUND(0)ELSE TEXTBACKGROUND(1);
203   TEXTCOLOR(7); WRITE('�'); WINDOW(42,2,80,13); TEXTBACKGROUND(0); CLRSCR;
204   TEXTCOLOR(15); TEXTBACKGROUND(1);
205   CASE BAR OF
206     1:BEGIN
207       WRITE('LEVELS',' ':39-6); DISPLEVELS;
208     END; {1:SINGLVLS}
209     2:BEGIN
210       WRITE('LEVEL OBJECTS',' ':39-13); TEXTCOLOR(7); TEXTBACKGROUND(0);
211       IF L[II].NROBJ<1THEN WRITELN('NONE')ELSE
212         FOR I4:=1TO L[II].NROBJ DO BEGIN
213           WRITE(I4); TEXTCOLOR(3); WRITE(': ',OBJTYPE[L[II].OBJ[I4].TYP]);
214           IF L[II].OBJ[I4].TYP>0THEN
215             WRITE(' (',L[II].OBJ[I4].X1,',',L[II].OBJ[I4].Y1,')-(');
216           CASE L[II].OBJ[I4].TYP OF
217             1,2:WRITELN(L[II].OBJ[I4].X2,',',L[II].OBJ[I4].Y2,')');
218             3:WRITELN(L[II].OBJ[I4].X2,',',L[II].OBJ[I4].Y1+L[II].OBJ[I4].Y2,')');
219             4:WRITELN(L[II].OBJ[I4].X2,')');
220           END; {TYPE}
221           TEXTCOLOR(7);
222         END; {DISP OBJS}
223     END; {2:SINGLVLS}
224     3:BEGIN
225       WRITE('LEVEL INFO',' ':39-10); TEXTCOLOR(7); TEXTBACKGROUND(0);
226       WRITE('LEVEL #',II);
227       IF II>B.LSINGLE THEN WRITELN(' MP #',II-B.LSINGLE)ELSE WRITELN;
228       WRITELN('LEVEL SIZE: ',L[II].SIZE);
229       IF II<=B.LSINGLE THEN WRITELN('SINGLEPLAYER')ELSE FOR I:=2TO 7DO
230         IF(II-B.LSINGLE>=B.LFROM[I])AND(II-B.LSINGLE<=B.LTO[I])THEN
231           WRITELN(GAMETYPE[I]);
232     END; {3:LEVEL}
233     4:BEGIN
234       WRITE(FILENAME,'.LVL',' ':35-ORD(FILENAME[0])); TEXTCOLOR(7);
235       TEXTBACKGROUND(0); WRITE('FILE VERSION: '); TEXTCOLOR(3);
236       WRITELN(B.VERSION); TEXTCOLOR(7); WRITE('FILE SIZE: '); TEXTCOLOR(3);
237       WRITE(FILESIZE(F)SHR 10); TEXTCOLOR(7); WRITELN('kB');
238       WRITE('COMPILED: '); TEXTCOLOR(3); WRITE(COMPSIZE); TEXTCOLOR(7);
239       WRITE(' BYTES');
240     END; {4:FILE}
241     5:BEGIN
242       WRITE('LEVELS',' ':39-6); TEXTCOLOR(7); TEXTBACKGROUND(0);
243       IF B.LTOTAL<1THEN WRITELN('NONE PRESENT')ELSE
244         FOR II:=1TO B.LTOTAL DO BEGIN
245           IF II>B.LSINGLE THEN WRITE(II-B.LSINGLE)ELSE WRITE(II);
246           TEXTCOLOR(3); WRITELN(': '+L[II].NAME); TEXTCOLOR(7);
247         END; {DISP LEVELS}
248     END; {5:LEVELS}
249   END; {BAR}
250   WINDOW(1,2,40,24);
251   TEXTBACKGROUND(1); TEXTCOLOR(15); WRITE(TITLNAME,' ':40-ORD(TITLNAME[0]));
252   WINDOW(1,3,40,24); TEXTBACKGROUND(0); CLRSCR;
253 END; {TITLEBAR}
254
255 FUNCTION INPUTSTR(ISTR,ICOM,IDEF:STRING;IMAX:BYTE):STRING;
256 VAR IVAL:STRING; IOK:BOOLEAN;
257 BEGIN
258   WINDOW(1,14,40,24);
259   TEXTBACKGROUND(1); TEXTCOLOR(15); WRITE('INPUT',' ':40-5);
260   WINDOW(1,15,40,24); TEXTBACKGROUND(0); CLRSCR;
261   REPEAT
262     TEXTCOLOR(7); WRITELN(ISTR); TEXTCOLOR(8); WRITELN(ICOM);
263     TEXTCOLOR(8); WRITELN('ENTER FOR DEFAULT:'); WRITELN(IDEF);
264     TEXTCOLOR(7); WRITE('> '); READLN(IVAL);
265     IF IVAL=''THEN IVAL:=IDEF;
266     IOK:=FALSE; IF ORD(IVAL[0])<=IMAX THEN IOK:=TRUE
267       ELSE BEGIN CLRSCR; WRITELN('OH NO, THAT''S TOO MUCH!'); END; {TOOLONG}
268   UNTIL IOK; INPUTSTR:=IVAL;
269 END; {INPUTSTR}
270
271 FUNCTION INPUTINT(ISTR,ICOM:STRING;IMIN,IDEF,IMAX:INTEGER):INTEGER;
272 FUNCTION READ:INTEGER;
273 VAR REI1:INTEGER; REI2:BYTE;
274 BEGIN {INPUTS POSITIVE INTEGER VALUE FROM KEYBOARD}
275   REI1:=0; {VALUE} REI2:=0; {SIZE}
276   REPEAT
277     REPEAT C:=READKEY; UNTIL C<>'';
278     CASE C OF
279       #8,'+','-':IF REI2>0THEN BEGIN
280         REI1:=REI1 DIV 10; DEC(REI2); WRITE(#8+' '+#8);
281       END; {BACKSPACE}
282       '0'..'9':IF REI2<4THEN BEGIN
283         REI1:=REI1*10+ORD(C)-48; INC(REI2); WRITE(C);
284       END; {NUMBER}
285       #13:IF REI2=0THEN REI1:=-1; {ENTER}
286     END; {HANDLE INPUT}
287   UNTIL C=#13; {UNTIL ENTER PRESSED}
288   READ:=REI1;
289 END; {READLN}
290 VAR IVAL:INTEGER; IOK:BOOLEAN;
291 BEGIN
292   WINDOW(1,14,40,24);
293   TEXTBACKGROUND(1); TEXTCOLOR(15); WRITE('INPUT',' ':40-5);
294   WINDOW(1,15,40,24); TEXTBACKGROUND(0); CLRSCR;
295   REPEAT
296     TEXTCOLOR(7); WRITELN(ISTR); TEXTCOLOR(8); WRITELN(ICOM);
297     TEXTCOLOR(8); WRITE('(RANGE '); TEXTCOLOR(7); WRITE(IMIN); TEXTCOLOR(8);
298     WRITE(' TO '); TEXTCOLOR(7); WRITE(IMAX); TEXTCOLOR(8);
299     WRITE('; DEFAULT VALUE '); TEXTCOLOR(7); WRITE(IDEF); TEXTCOLOR(8);
300     WRITELN(')'); TEXTCOLOR(7); WRITE('> '); IVAL:=READ; IF IVAL=-1THEN IVAL:=IDEF;
301     IOK:=FALSE; IF(IVAL>=IMIN)AND(IVAL<=IMAX)THEN IOK:=TRUE
302       ELSE BEGIN CLRSCR; WRITELN('OUT OF RANGE!'); END; {OUTOFRANGE}
303   UNTIL IOK; INPUTINT:=IVAL;
304 END; {INPUTINT}
305
306 PROCEDURE EDITGAME;
307 LABEL EDITGAME1,EDITGAME2;
308 BEGIN
309   REPEAT
310     TITLEBAR(5,'EDIT GAMETYPES'); TEXTCOLOR(14); WRITE('1');
311     TEXTCOLOR(7); WRITE(': SINGLEPLAYER ');
312     TEXTCOLOR(3); IF B.LSINGLE=0THEN WRITELN('(NO LEVELS)')
313       ELSE WRITELN('(',B.LTO[1]-B.LFROM[1]+1,' OF ',B.LSINGLE,')');
314     FOR II:=2TO 7DO BEGIN
315       TEXTCOLOR(14); WRITE(II); TEXTCOLOR(7); WRITE(': '+GAMETYPE[II],' ');
316       TEXTCOLOR(3); IF B.LFROM[II]=0THEN WRITELN('(NO LEVELS)')
317         ELSE WRITELN('(',B.LFROM[II],'-',B.LTO[II],')');
318     END; {MULTIP}
319     TEXTCOLOR(7); WRITE('8: CTF '); TEXTCOLOR(3);
320     IF B.LCTF=0THEN WRITE('(NO LEVELS)')ELSE WRITE('(',B.LCTF,')');
321
322     III:=EDITMENU(8,0);
323     IF III=1THEN BEGIN
324       B.LFROM[1]:=INPUTINT('ENTER LEVELS TO SKIP','USE THIS TO TEMPORARILY REMOVE THE FIRSTFEW LEVELS',
325         0,0,B.LSINGLE-1); INC(B.LFROM[1]);
326       B.LTO[1]:=INPUTINT('ENTER LEVELS SELECTABLE','THE HIGHEST LEVEL SOMEONE CAN START IN  WITHOUT PLAYING IT EARLIER',
327         1,1,B.LSINGLE+1-B.LFROM[1]); B.LTO[1]:=B.LTO[1]+B.LFROM[1]-1;
328     END {SINGLEPLAYER} ELSE IF III>0THEN BEGIN
329       B.LFROM[III]:=INPUTINT('ENTER NEW STARTING LEVEL',
330         'THAT LEVEL WILL BE LEVEL #1 IN GAMEMODE '+GAMETYPE[III]+'. 0=NO LEVELS',0,1,B.LMULTI);
331       IF B.LFROM[III]>0THEN
332         B.LTO[III]:=INPUTINT('ENTER LAST LEVEL NUMBER',NR(B.LMULTI)+' LEVELS PRESENT',
333           B.LFROM[III],B.LMULTI,B.LMULTI);
334     END; {MULTIPLAYER}
335   UNTIL III=-1; III:=0;
336 END; {EDITGAME}
337
338 PROCEDURE EDITOBJ;
339 LABEL EDITOBJ1;
340 BEGIN
341   REPEAT
342     TITLEBAR(2,'EDIT OBJECT #'+NR(I)+' IN LEVEL '+NR(II));
343     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITE(': OBJECT TYPE ');
344     III:=L[II].OBJ[I].TYP; TEXTCOLOR(3); WRITELN('(',III,')');
345     IF III<>0THEN BEGIN
346       TEXTCOLOR(14); WRITE('2'); TEXTCOLOR(7);
347       IF L[II].OBJ[I].TYP=4THEN WRITE(': OBJECT POSITION ')ELSE WRITE(': OBJECT BEGIN ');
348       TEXTCOLOR(3); WRITELN('(',L[II].OBJ[I].X1,',',L[II].OBJ[I].Y1,')');
349       TEXTCOLOR(14); WRITE('3'); TEXTCOLOR(7);
350       IF L[II].OBJ[I].TYP=4THEN WRITE(': OBJECT SIZE ')ELSE WRITE(': OBJECT END ');
351       TEXTCOLOR(3); CASE L[II].OBJ[I].TYP OF
352         3:WRITELN('(',L[II].OBJ[I].X2,',',L[II].OBJ[I].Y1+L[II].OBJ[I].Y2,')');
353         4:WRITELN('(',L[II].OBJ[I].X2,')');
354         ELSE WRITELN('(',L[II].OBJ[I].X2,',',L[II].OBJ[I].Y2,')');
355       END; {TYPE}
356       TEXTCOLOR(14); WRITE('4'); TEXTCOLOR(7); WRITE(': PREVIEW');
357     END; {OBJECT PROPERTIES}
358
359     IF III<>0THEN III:=EDITMENU(4,0)ELSE III:=EDITMENU(1,0);
360     CASE III OF
361       1:BEGIN
362         S:=''; FOR I4:=0TO 4DO S:=S+NR(I4)+': '+OBJTYPE[I4]+CC(' ',37-ORD(OBJTYPE[I4,0]));
363         L[II].OBJ[I].TYP:=INPUTINT('ENTER OBJECT TYPE',S,0,0,4);
364         S:='SCREEN=(0,0)-('+NR(L[II].FIELDX-2)+','+NR(L[II].FIELDY-2)+
365           '); CENTER=('+NR((L[II].FIELDX-1)SHR 1)+','+NR((L[II].FIELDY-1)SHR 1)+')';
366         IF L[II].OBJ[I].TYP=4 THEN BEGIN
367           L[II].OBJ[I].X1:=INPUTINT('ENTER X',S,2,(L[II].FIELDX-1)SHR 1,L[II].FIELDX-4);
368           L[II].OBJ[I].Y1:=INPUTINT('ENTER Y',S,2,(L[II].FIELDY-1)SHR 1,L[II].FIELDY-4);
369           L[II].OBJ[I].X2:=INPUTINT('ENTER SIZE',S,0,
370             MIN(L[II].FIELDY-4,L[II].FIELDX-4)SHR 2,MIN(L[II].FIELDY-4,L[II].FIELDX-4)SHR 1);
371           L[II].OBJ[I].Y2:=0;
372         END {CIRCLE} ELSE IF L[II].OBJ[I].TYP>0THEN BEGIN
373           IF L[II].OBJ[I].TYP=3THEN I4:=4 ELSE I4:=3;
374           L[II].OBJ[I].X1:=INPUTINT('ENTER X1',S,2,(L[II].FIELDX-1)SHR 1,L[II].FIELDX-I4);
375           L[II].OBJ[I].Y1:=INPUTINT('ENTER Y1',S,2,(L[II].FIELDY-1)SHR 1,L[II].FIELDY-I4);
376           L[II].OBJ[I].X2:=INPUTINT('ENTER X2',S,2,(L[II].FIELDX-1)SHR 1,L[II].FIELDX-I4);
377           L[II].OBJ[I].Y2:=INPUTINT('ENTER Y2',S,2,(L[II].FIELDY-1)SHR 1,L[II].FIELDY-I4);
378           IF L[II].OBJ[I].TYP=3THEN BEGIN
379             IF L[II].OBJ[I].Y2<L[II].OBJ[I].Y1 THEN BEGIN
380               I4:=L[II].OBJ[I].Y2; L[II].OBJ[I].Y2:=L[II].OBJ[I].Y1;
381               L[II].OBJ[I].Y1:=I4;
382             END; {END BEFORE START}
383             L[II].OBJ[I].Y2:=L[II].OBJ[I].Y2-L[II].OBJ[I].Y1;
384           END; {BOX}
385         END; {NORMAL OBJECT}
386       END; {TYPE}
387       2:BEGIN
388         S:='SCREEN=(0,0)-('+NR(L[II].FIELDX-2)+','+NR(L[II].FIELDY-2)+
389           '); CENTER=('+NR((L[II].FIELDX-1)SHR 1)+','+NR((L[II].FIELDY-1)SHR 1)+')';
390         IF L[II].OBJ[I].TYP=4 THEN BEGIN
391           L[II].OBJ[I].X1:=INPUTINT('ENTER X',S,2,(L[II].FIELDX-1)SHR 1,L[II].FIELDX-3);
392           L[II].OBJ[I].Y1:=INPUTINT('ENTER Y',S,2,(L[II].FIELDY-1)SHR 1,L[II].FIELDY-3);
393         END {CIRCLE} ELSE IF L[II].OBJ[I].TYP>0THEN BEGIN
394           IF L[II].OBJ[I].TYP=3THEN I4:=4 ELSE I4:=3;
395           L[II].OBJ[I].X1:=INPUTINT('ENTER BEGIN X',S,2,(L[II].FIELDX-1)SHR 1,L[II].FIELDX-I4);
396           L[II].OBJ[I].Y1:=INPUTINT('ENTER BEGIN Y',S,2,(L[II].FIELDY-1)SHR 1,L[II].FIELDY-I4);
397           IF L[II].OBJ[I].TYP=3THEN
398             L[II].OBJ[I].Y2:=L[II].OBJ[I].Y2+(I4-L[II].OBJ[I].Y1);
399         END; {NORMAL OBJECT}
400       END; {BEGIN}
401       3:BEGIN
402         IF L[II].OBJ[I].TYP=4 THEN BEGIN
403           L[II].OBJ[I].X2:=INPUTINT('ENTER SIZE','r',0,
404             MIN(L[II].FIELDY-3,L[II].FIELDX-3)SHR 2,MIN(L[II].FIELDY-3,L[II].FIELDX-3)SHR 1);
405           L[II].OBJ[I].Y2:=0;
406         END {CIRCLE} ELSE IF L[II].OBJ[I].TYP>0THEN BEGIN
407           S:='SCREEN=(0,0)-('+NR(L[II].FIELDX-2)+','+NR(L[II].FIELDY-2)+
408             '); CENTER=('+NR((L[II].FIELDX-1)SHR 1)+','+NR((L[II].FIELDY-1)SHR 1)+')';
409           IF L[II].OBJ[I].TYP=3THEN I4:=4 ELSE I4:=3;
410           L[II].OBJ[I].X2:=INPUTINT('ENTER END X',S,2,(L[II].FIELDX-1)SHR 1,L[II].FIELDX-I4);
411           L[II].OBJ[I].Y2:=INPUTINT('ENTER END Y',S,2,(L[II].FIELDY-1)SHR 1,L[II].FIELDY-I4);
412           IF L[II].OBJ[I].TYP=3THEN BEGIN
413             IF L[II].OBJ[I].Y2<L[II].OBJ[I].Y1 THEN BEGIN
414               I4:=L[II].OBJ[I].Y2; L[II].OBJ[I].Y2:=L[II].OBJ[I].Y1;
415               L[II].OBJ[I].Y1:=I4;
416             END; {END BEFORE START}
417             L[II].OBJ[I].Y2:=L[II].OBJ[I].Y2-L[II].OBJ[I].Y1;
418           END; {BOX}
419         END; {NORMAL OBJECT}
420       END; {END}
421       4:DISPMAP(I);
422     END; {HANDLE}
423   UNTIL III=-1; III:=0;
424 END; {EDITOBJ}
425
426 PROCEDURE EDITOBJS;
427 LABEL EDITOBJS1,EDITOBJS2;
428 BEGIN
429   REPEAT
430     TITLEBAR(2,'EDIT LEVEL OBJECTS');
431     IF L[II].NROBJ>0THEN TEXTCOLOR(14)ELSE TEXTCOLOR(7);
432     WRITE('1'); TEXTCOLOR(7); WRITELN(': EDIT OBJECT');
433     IF L[II].NROBJ>0THEN TEXTCOLOR(14)ELSE TEXTCOLOR(7);
434     WRITE('2'); TEXTCOLOR(7); WRITELN(': DELETE OBJECT');
435     TEXTCOLOR(14); WRITE('3'); TEXTCOLOR(7); WRITELN(': CREATE OBJECT');
436     TEXTCOLOR(14); WRITE('4'); TEXTCOLOR(7); WRITE(': VIEW OBJECT');
437
438     III:=EDITMENU(4,0);
439     CASE III OF
440       1:IF L[II].NROBJ>0THEN BEGIN
441         I:=INPUTINT('EDIT WHICH OBJECT','',1,1,L[II].NROBJ);
442         EDITOBJ;
443       END; {EDIT}
444       2:IF L[II].NROBJ>0THEN BEGIN
445         I:=INPUTINT('DELETE WHICH OBJECT','0=CANCEL',0,0,L[II].NROBJ);
446         IF I>0THEN BEGIN
447           I4:=INPUTINT('PLEASE CONFIRM OBJECT TO *REMOVE*','ENTER 0 TO CANCEL',0,0,L[II].NROBJ);
448           IF I=I4 THEN BEGIN
449             DEC(L[II].NROBJ); FOR I:=I4 TO L[II].NROBJ DO L[II].OBJ[I]:=L[II].OBJ[I+1];
450           END; {CONFIRMED}
451         END; {}
452       END; {DELETE}
453       3:BEGIN
454         INC(L[II].NROBJ); I:=L[II].NROBJ; L[II].OBJ[I].TYP:=0; EDITOBJ;
455       END; {CREATE}
456       4:BEGIN
457         I4:=INPUTINT('ENTER OBJECT TO HIGHLIGHT','0 FOR NONE',0,0,L[II].NROBJ);
458         DISPMAP(I4);
459       END; {DISP}
460     END; {HANDLE}
461   UNTIL III=-1; III:=0;
462 END; {EDITOBJS}
463
464 FUNCTION BYTE2STR(SPRITE,SPRSIZE:BYTE):STRING;
465 VAR SPRTEMP:STRING[8];
466     SPRTEMP2:BYTE;
467 BEGIN
468   SPRTEMP:='';
469   FOR SPRTEMP2:=1TO 8-SPRSIZE DO SPRITE:=SPRITE SHR 1;
470   FOR SPRTEMP2:=9-SPRSIZE TO 8DO BEGIN
471     IF SPRITE MOD 2=1THEN SPRTEMP:='X'+SPRTEMP ELSE SPRTEMP:='�'+SPRTEMP;
472     SPRITE:=SPRITE SHR 1;
473   END;
474   BYTE2STR:=SPRTEMP;
475 END; {BYTE2STR}
476
477 FUNCTION BYTE2BIN(BYI1:BYTE):LONGINT;
478 VAR BYI2:BYTE; BYI3:LONGINT;
479 BEGIN
480   BYI3:=0;
481   FOR BYI2:=0TO 7DO BEGIN
482     IF BYI1 AND 1=1THEN BYI3:=BYI3+POW(10,BYI2);
483     BYI1:=BYI1 SHR 1;
484   END;
485   BYTE2BIN:=BYI3;
486 END; {BYTE2BIN}
487
488 FUNCTION STR2BYTE(SPRITE:STRING):BYTE;
489 VAR SPRTEMP,SPRTEMP2:BYTE;
490 BEGIN
491   SPRTEMP:=0; SPRTEMP2:=1;
492   FOR SPRTEMP2:=1TO LENGTH(SPRITE)DO
493     IF SPRITE[SPRTEMP2]='1'THEN INC(SPRTEMP,1SHL(8-SPRTEMP2));
494   STR2BYTE:=SPRTEMP;
495 END; {STR2BYTE}
496
497 PROCEDURE EDITSPR;
498 BEGIN
499   REPEAT
500     TITLEBAR(0,'EDIT SPRITE');
501     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITE(': SPRITE SIZE ');
502     TEXTCOLOR(3); IF L[II].SPRSIZE=0THEN WRITELN('(',B.SPRSIZE,')')
503       ELSE WRITELN('(',L[II].SPRSIZE,')');
504     IF L[II].SPRSIZE=0THEN BEGIN
505       TEXTCOLOR(7); WRITE('2: EDIT SPRITE'); TEXTCOLOR(3); WRITELN(' (DEFAULT)');
506     END {DEF SPR} ELSE FOR I:=1TO L[II].SPRSIZE DO BEGIN
507       TEXTCOLOR(14); WRITE(I+1); TEXTCOLOR(7); WRITE(': EDIT '); TEXTCOLOR(3);
508       WRITELN(BYTE2STR(L[II].SPRITE[I],L[II].SPRSIZE));
509     END; {DISP SPRITE}
510
511     III:=EDITMENU(1+L[II].SPRSIZE,0);
512     IF III=1THEN BEGIN
513       I:=INPUTINT('ENTER NEW SPRITE SIZE','MAXIMUM HEIGHT AND WIDTH; 0=DEFAULT',0,B.SPRSIZE,8);
514       IF I>L[II].SPRSIZE THEN FOR I4:=L[II].SPRSIZE+1TO I DO L[II].SPRITE[I4]:=0;
515       L[II].SPRSIZE:=I;
516     END {SIZE} ELSE IF III>1THEN BEGIN
517       S:=INPUTSTR('ENTER NEW LINE #'+NR(III-1)+' OF SPRITE','EXAMPLE: 100101 = X��X�X',
518         ZERO(BYTE2BIN(L[II].SPRITE[III-1]),8),8);
519       L[II].SPRITE[III-1]:=STR2BYTE(S);
520     END; {APP}
521   UNTIL III=-1; III:=0;
522 END; {EDITSPR}
523
524 PROCEDURE EDITBOUNCIES;
525 BEGIN
526   REPEAT
527     TITLEBAR(0,'EDIT BALLS IN LEVEL #'+NR(II));
528     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITELN(': CREATE BALL');
529     TEXTCOLOR(14); WRITE('2'); TEXTCOLOR(7); WRITELN(': DELETE BALL');
530     FOR III:=1TO L[II].NRBALLS DO BEGIN
531       TEXTCOLOR(14); WRITE(III+2); TEXTCOLOR(7); WRITE(': BALL #',III,' (');
532       TEXTCOLOR(3); WRITE(L[II].BALLS[III].X); TEXTCOLOR(7); WRITE(',');
533       TEXTCOLOR(3); WRITE(L[II].BALLS[III].Y); TEXTCOLOR(7); WRITE(') DIR ');
534       TEXTCOLOR(3); WRITELN(L[II].BALLS[III].D);
535     END; {WORMS}
536
537     III:=EDITMENU(2+L[II].NRBALLS,0);
538     IF III=1THEN BEGIN
539         INC(L[II].NRBALLS);
540         L[II].BALLS[L[II].NRBALLS].X:=INPUTINT('ENTER X','WHERE THE BALL STARTS BOUNCING',0,63,255);
541         L[II].BALLS[L[II].NRBALLS].Y:=INPUTINT('ENTER Y','',0,27,255);
542         L[II].BALLS[L[II].NRBALLS].D:=INPUTINT('ENTER DIRECTION','0/1:DOWN; 2/3:UP; 1/3:RIGHT; 0/2:LEFT',0,0,3);
543     END {CREATE} ELSE IF III=2THEN BEGIN
544       III:=INPUTINT('ENTER THE BOUNCY BALL TO REMOVE','(0 CANCELS)',0,0,L[II].NRBALLS);
545       IF III>0THEN BEGIN
546         DEC(L[II].NRBALLS); FOR I4:=III TO L[II].NRBALLS DO L[II].BALLS[I4]:=L[II].BALLS[I4+1];
547       END; {OK2REMOVE}
548     END {DELETE} ELSE IF III>0THEN BEGIN
549         L[II].BALLS[III-2].X:=INPUTINT('ENTER X','NOTE THE BOUNCY BALLS WILL PROBABLY     BOLDLY GO SOME OTHER PLACE ANYWAY',
550           0,L[II].BALLS[III-2].X,255);
551         L[II].BALLS[III-2].Y:=INPUTINT('ENTER Y','',0,L[II].BALLS[III-2].Y,255);
552         L[II].BALLS[III-2].D:=INPUTINT('ENTER DIRECTION','0/1:DOWN; 2/3:UP; 1/3:RIGHT; 0/2:LEFT',0,L[II].BALLS[III-2].D,3);
553     END; {EDIT}
554   UNTIL III=-1; III:=0;
555 END; {EDITWORMS}
556
557 PROCEDURE EDITWORMS;
558 BEGIN
559   REPEAT
560     TITLEBAR(0,'EDIT WORMS IN LEVEL #'+NR(II));
561     IF II>B.LSINGLE THEN III:=4 ELSE III:=1;
562     FOR III:=1TO III DO BEGIN
563       TEXTCOLOR(14); WRITE(III SHL 1-1); TEXTCOLOR(7);
564       WRITE(': WORM #',III,' DIRECTION '); TEXTCOLOR(3);
565       WRITELN('(',L[II].W[III].D,')');
566       TEXTCOLOR(14); WRITE(III SHL 1); TEXTCOLOR(7);
567       WRITE(': WORM #',III,' POSITION '); TEXTCOLOR(3);
568       WRITELN('(',L[II].W[III].X,',',L[II].W[III].Y,')');
569     END; {WORMS}
570
571     IF III=4THEN III:=EDITMENU(8,0)ELSE III:=EDITMENU(2,0);
572     CASE(III+1)OF
573       2,4,6,8:BEGIN
574         I:=INPUTINT('ENTER WORM #'+NR(III SHR 1)+' STARTING DIRECTION',
575           '0=DOWN; 64=RIGHT; 128=UP; 192=LEFT',0,L[II].W[III SHR 1].D,255);
576         L[II].W[III SHR 1].D:=I;
577       END; {DIR}
578       3,5,7,9:BEGIN
579         I:=INPUTINT('ENTER WORM #'+NR(III SHR 1)+' BEGIN X-POSITION',
580           'SCREEN = 2-'+NR(L[II].FIELDX-3)+'; CENTER = '+NR((L[II].FIELDX-1)SHR 1),
581           2,L[II].W[III SHR 1].X,L[II].FIELDX-3);
582         L[II].W[III SHR 1].X:=I;
583         I:=INPUTINT('ENTER WORM #'+NR(III SHR 1)+' BEGIN Y-POSITION',
584           'SCREEN = 2-'+NR(L[II].FIELDY-3)+'; CENTER = '+NR((L[II].FIELDY-1)SHR 1),
585           2,L[II].W[III SHR 1].Y,L[II].FIELDY-3);
586         L[II].W[III SHR 1].Y:=I;
587       END; {POS}
588     END; {HANDLE}
589   UNTIL III=-1; III:=0;
590 END; {EDITWORMS}
591
592 PROCEDURE EDITLEVEL;
593 BEGIN
594   REPEAT
595     L[II].SIZE:=12+L[II].NRBALLS*3+L[II].SPRSIZE+L[II].NROBJ*5;
596     IF II>B.LSINGLE THEN INC(L[II].SIZE,9);
597     TITLEBAR(3,'EDIT LEVEL #'+NR(II));
598     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITE(': DESCRIPTION ');
599       TEXTCOLOR(3); WRITELN('(',L[II].NAME,')');
600     TEXTCOLOR(14); WRITE('2'); TEXTCOLOR(7); WRITE(': NUMBER OF PEAS ');
601       TEXTCOLOR(3); WRITELN('(',L[II].PEAS,')');
602     TEXTCOLOR(14); WRITE('3'); TEXTCOLOR(7); WRITE(': GAME DELAY ');
603       TEXTCOLOR(3); WRITELN('(',L[II].DELAY,')');
604     TEXTCOLOR(14); WRITE('4'); TEXTCOLOR(7); WRITE(': GROWTH ');
605       TEXTCOLOR(3); WRITELN('(',L[II].GROWTH,'+',L[II].BSIZE,')');
606     TEXTCOLOR(14); WRITE('5'); TEXTCOLOR(7); WRITE(': SPRITE ');
607       TEXTCOLOR(3); IF L[II].SPRSIZE=0THEN WRITELN('(DEFAULT)')
608                     ELSE WRITELN('(',L[II].SPRSIZE,')');
609     TEXTCOLOR(14); WRITE('6'); TEXTCOLOR(7); WRITE(': BOUNCY BALLS ');
610       TEXTCOLOR(3); WRITELN('(',L[II].NRBALLS,')');
611     TEXTCOLOR(14); WRITE('7'); TEXTCOLOR(7); WRITE(': WORMS '); TEXTCOLOR(3);
612       IF II>B.LSINGLE THEN BEGIN
613         WRITELN('(',L[II].W[1].D,';',L[II].W[2].D,';',L[II].W[3].D,';',L[II].W[4].D,')');
614       END {FOUR WORMS} ELSE
615         WRITELN('(',L[II].W[1].X,',',L[II].W[1].Y,':',L[II].W[1].D,')');
616     TEXTCOLOR(14); WRITE('8'); TEXTCOLOR(7); WRITE(': FIELD SIZE ');
617       TEXTCOLOR(3); WRITELN('(',L[II].FIELDX,',',L[II].FIELDY,')');
618     TEXTCOLOR(14); WRITE('9'); TEXTCOLOR(7); WRITE(': OBJECTS ');
619       TEXTCOLOR(3); WRITE('(',L[II].NROBJ,')');
620
621     III:=EDITMENU(10,0);
622     CASE III OF
623       1:L[II].NAME:=INPUTSTR('ENTER DESCRIPTION FOR THIS LEVEL',
624         'THIS WON''T BE DISPLAYED DURING THE GAME,IT''S JUST TO MAKE EDITING EASIER',L[II].NAME,22); {DESCR}
625       2:L[II].PEAS:=INPUTINT('ENTER TOTAL NUMBER OF PEAS','TOO MANY PEAS WILL MAKE A LEVEL BORING',1,L[II].PEAS,255);
626       3:L[II].DELAY:=INPUTINT('ENTER NEW DELAY','0=FASTEST; 4=AVERAGE; 10=SLOW',0,L[II].DELAY,255);
627       4:BEGIN
628         L[II].GROWTH:=INPUTINT('ENTER GROWTH PER PEA','0=NO GROWTH; 15=NORMAL',0,L[II].GROWTH,255);
629         L[II].BSIZE:=INPUTINT('ENTER WORM BEGIN SIZE','15=NORMAL; TOO SHORT WORMS WILL BE HARD TO PLAY WITH',
630           1,L[II].BSIZE,255);
631       END; {GROWTH}
632       5:EDITSPR;
633       6:EDITBOUNCIES;
634       7:EDITWORMS;
635       8:BEGIN
636         FOR III:=L[II].NROBJ DOWNTO 1DO
637          IF L[II].OBJ[III].Y2+L[II].OBJ[III].Y1=255THEN BEGIN
638           DEC(L[II].NROBJ); FOR I4:=III TO L[II].NROBJ DO L[II].OBJ[I4]:=L[II].OBJ[I4+1];
639         END; {REMOVE OLD BARS}
640         L[II].FIELDX:=INPUTINT('ENTER FIELD WIDTH','128=ONE SCREEN; MORE WILL SCROLL THE    SCREEN',5,L[II].FIELDX,255);
641         IF L[II].FIELDX<128THEN BEGIN
642           INC(L[II].NROBJ); L[II].OBJ[L[II].NROBJ].X1:=L[II].FIELDX;
643           L[II].OBJ[L[II].NROBJ].Y2:=255; L[II].OBJ[L[II].NROBJ].TYP:=3;
644           L[II].OBJ[L[II].NROBJ].X2:=255; L[II].OBJ[L[II].NROBJ].Y1:=0;
645         END; {PUT BAR}
646         L[II].FIELDY:=INPUTINT('ENTER FIELD HEIGHT','57=ONE SCREEN; MORE WILL SCROLL THE     SCREEN',5,L[II].FIELDY,255);
647         IF L[II].FIELDY<57THEN BEGIN
648           INC(L[II].NROBJ); L[II].OBJ[L[II].NROBJ].X1:=2;
649           L[II].OBJ[L[II].NROBJ].Y2:=255-L[II].FIELDY;
650           L[II].OBJ[L[II].NROBJ].X2:=L[II].FIELDX-1; L[II].OBJ[L[II].NROBJ].TYP:=3;
651           L[II].OBJ[L[II].NROBJ].Y1:=L[II].FIELDY;
652         END; {PUT BAR}
653       END; {FIELD}
654       9:EDITOBJS;
655       10:DISPMAP(0);
656     END; {HANDLE}
657   UNTIL III=-1; III:=0;
658 END; {EDITLEVEL}
659
660 PROCEDURE EDITLVL;
661 LABEL EDITHLVL1,EDITHLVL2;
662 BEGIN
663   REPEAT
664     TITLEBAR(1,'EDIT LEVELS');
665     IF B.LTOTAL>0THEN TEXTCOLOR(14)ELSE TEXTCOLOR(7);
666     WRITE('1'); TEXTCOLOR(7); WRITELN(': EDIT LEVEL');
667     IF B.LTOTAL>0THEN TEXTCOLOR(14)ELSE TEXTCOLOR(7);
668     WRITE('2'); TEXTCOLOR(7); WRITELN(': COPY LEVEL');
669     IF B.LTOTAL>0THEN TEXTCOLOR(7)ELSE TEXTCOLOR(7);
670     WRITE('3'); TEXTCOLOR(7); WRITELN(': MOVE LEVEL');
671     IF B.LTOTAL>0THEN TEXTCOLOR(14)ELSE TEXTCOLOR(7);
672     WRITE('4'); TEXTCOLOR(7); WRITELN(': DELETE LEVEL');
673     TEXTCOLOR(14); WRITE('5'); TEXTCOLOR(7); WRITELN(': CREATE SINGLEPLAYER LEVEL');
674     TEXTCOLOR(14); WRITE('6'); TEXTCOLOR(7); WRITELN(': CREATE MULTIPLAYER LEVEL');
675     TEXTCOLOR(7); WRITE('7'); TEXTCOLOR(7); WRITELN(': CREATE CTF LEVEL');
676     TEXTCOLOR(7); WRITELN; III:=EDITMENU(6,0);
677
678     CASE III OF
679       1:IF B.LTOTAL>0THEN BEGIN
680         II:=INPUTINT('EDIT WHICH LEVEL','0=CANCEL',0,0,B.LTOTAL);
681         IF II<>0THEN EDITLEVEL;
682       END; {EDIT}
683       2:IF B.LTOTAL>0THEN BEGIN
684         II:=INPUTINT('COPY WHICH LEVEL','0=CANCEL',0,0,B.LTOTAL);
685         IF II<>0THEN BEGIN
686           INC(B.LTOTAL);
687           IF II<=B.LSINGLE THEN BEGIN
688             INC(B.LSINGLE);
689             FOR I:=B.LTOTAL DOWNTO B.LSINGLE+1DO L[I]:=L[I-1];
690             L[B.LSINGLE]:=L[II]; II:=B.LSINGLE
691           END {SP} ELSE BEGIN
692             FOR I:=2TO 7DO IF B.LTO[I]=B.LMULTI THEN BEGIN
693               INC(B.LTO[I]); IF B.LFROM[I]=0THEN INC(B.LFROM[I]);
694             END; {ALL GAMETYPES}
695             INC(B.LMULTI); L[B.LTOTAL]:=L[II]; II:=B.LTOTAL;
696           END; {MP}
697           L[II].NAME:='Copy of '+L[II].NAME;
698         END; {>0}
699       END; {COPY}
700       4:IF B.LTOTAL>0THEN BEGIN
701         II:=INPUTINT('DELETE WHICH LEVEL','0=CANCEL',0,0,B.LTOTAL);
702         IF II<>0THEN BEGIN
703           I:=INPUTINT('PLEASE CONFIRM LEVEL TO *REMOVE*','ENTER 0 TO CANCEL',0,0,B.LTOTAL);
704           IF I=II THEN BEGIN
705             IF I<=B.LSINGLE THEN DEC(B.LSINGLE)ELSE
706               IF I<=B.LMULTI+B.LSINGLE THEN DEC(B.LMULTI)ELSE
707                 DEC(B.LCTF);
708             DEC(B.LTOTAL); FOR I:=II TO B.LTOTAL DO L[I]:=L[I+1];
709             FOR I:=2TO 7DO BEGIN
710               IF B.LTO[I]>B.LMULTI THEN B.LTO[I]:=B.LMULTI;
711               IF B.LFROM[I]>B.LTO[I]THEN B.LFROM[I]:=B.LTO[I];
712             END; {CHECK}
713           END; {CONFIRMED}
714         END; {}
715       END; {DELETE}
716       5:BEGIN
717         INC(B.LSINGLE); INC(B.LTOTAL); II:=B.LSINGLE;
718         FOR I:=B.LTOTAL DOWNTO II+1DO L[I]:=L[I-1];
719         L[II].NAME:='Level #'+NR(II);
720         L[II].PEAS:=8; L[II].DELAY:=4; L[II].GROWTH:=15; L[II].BSIZE:=15;
721         L[II].SPRSIZE:=0; L[II].NRBALLS:=0; L[II].W[1].D:=0; L[II].W[1].X:=63;
722         L[II].W[1].Y:=2; L[II].FIELDX:=128; L[II].FIELDY:=57; L[II].NROBJ:=0;
723         EDITLEVEL;
724       END; {CREATE SP}
725       6:BEGIN
726         FOR I:=2TO 7DO IF B.LTO[I]=B.LMULTI THEN BEGIN
727           INC(B.LTO[I]); IF B.LFROM[I]=0THEN INC(B.LFROM[I]);
728         END; {}
729         INC(B.LTOTAL); INC(B.LMULTI); II:=B.LSINGLE+B.LMULTI;
730         FOR I:=B.LTOTAL DOWNTO II+1DO L[I]:=L[I-1];
731         L[II].NAME:='Arena #'+NR(B.LMULTI);
732         L[II].DELAY:=4; L[II].GROWTH:=15; L[II].BSIZE:=15; L[II].SPRSIZE:=0;
733         L[II].W[1].D:=$40; L[II].W[1].Y:=28; L[II].W[1].X:=2;
734         L[II].W[2].D:=$C0; L[II].W[2].Y:=28; L[II].W[2].X:=125;
735         L[II].W[3].D:=$00; L[II].W[3].Y:=02; L[II].W[3].X:=63;
736         L[II].W[4].D:=$80; L[II].W[4].Y:=54; L[II].W[4].X:=63;
737         L[II].NRBALLS:=0; L[II].FIELDX:=128; L[II].FIELDY:=57;
738         L[II].NROBJ:=0; EDITLEVEL;
739       END; {CREATE MP}
740     END; {HANDLE}
741   UNTIL III=-1; III:=0;
742 END; {EDITLVL}
743
744 PROCEDURE EDITDSPR;
745 BEGIN
746   REPEAT
747     TITLEBAR(0,'EDIT DEFAULT SPRITE');
748     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITE(': SPRITE SIZE ');
749     TEXTCOLOR(3); WRITELN('(',B.SPRSIZE,')');
750     FOR I:=1TO B.SPRSIZE DO BEGIN
751       TEXTCOLOR(14); WRITE(I+1); TEXTCOLOR(7); WRITE(': EDIT '); TEXTCOLOR(3);
752       WRITELN(BYTE2STR(B.SPRITE[I],B.SPRSIZE));
753     END; {DISP SPRITE}
754
755     III:=EDITMENU(1+B.SPRSIZE,0);
756     IF III=1THEN BEGIN
757       I:=INPUTINT('ENTER THE DEFAULT SPRITE SIZE','CAN BE CHANGED PER LEVEL',1,B.SPRSIZE,8);
758       IF I>B.SPRSIZE THEN FOR I4:=B.SPRSIZE+1TO I DO B.SPRITE[I4]:=0;
759       B.SPRSIZE:=I;
760     END {SIZE} ELSE IF III>1THEN BEGIN
761       S:=INPUTSTR('ENTER NEW LINE #'+NR(III-1)+' OF SPRITE','EXAMPLE: 100101 = X��X�X',
762         ZERO(BYTE2BIN(B.SPRITE[III-1]),8),8);
763       B.SPRITE[III-1]:=STR2BYTE(S);
764     END; {APP}
765   UNTIL III=-1; III:=0;
766 END; {EDITDSPR}
767
768 PROCEDURE EDITSPEND;
769 BEGIN
770   REPEAT
771     TITLEBAR(0,'SINGLEPLAYER ENDING');
772     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITE(': END TYPE ');
773       TEXTCOLOR(3); WRITELN(' (',ENDTYPE[B.ENDTYPE],')'); TEXTCOLOR(14);
774     CASE B.ENDTYPE OF
775       -1:BEGIN
776         WRITE('2'); TEXTCOLOR(7); WRITE(': EDIT MESSAGE');
777         TEXTCOLOR(3); WRITE(' (',COPY(B.ENDDATA,1,18));
778         IF LENGTH(B.ENDDATA)>18THEN WRITELN('...)')ELSE WRITELN(')');
779       END; {MSG}
780     END; {TYPE}
781
782     III:=EDITMENU(2,0);
783     CASE III OF
784       1:BEGIN
785         FOR II:=0TO 1DO WRITE(NR(II)+': '+ENDTYPE[-II]+CC(' ',40-ORD(ENDTYPE[-II,0])));
786         B.ENDTYPE:=INPUTINT('ENTER NEW END TYPE',S,0,0,1);
787         IF B.ENDTYPE=-1THEN B.ENDDATA:='Congratulations!!';
788       END; {TITLE}
789       2:IF B.ENDTYPE=-1THEN
790           B.ENDDATA:=INPUTSTR('ENTER NEW END MESSAGE','MAX 255 CHARS','Congratulations!!',255);
791     END; {HANDLE}
792   UNTIL III=-1; III:=0;
793 END; {EDITSPEND}
794
795
796 PROCEDURE EDITMAIN;
797 BEGIN
798   REPEAT
799     TITLEBAR(4,UPCS(B.NAME));
800     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITELN(': EDIT TITLE');
801     TEXTCOLOR(14); WRITE('2'); TEXTCOLOR(7); WRITE(': DEFAULT SPRITE');
802       TEXTCOLOR(3); WRITELN(' (',B.SPRSIZE,')');
803     TEXTCOLOR(14); WRITE('3'); TEXTCOLOR(7); WRITELN(': GAME TYPES');
804     TEXTCOLOR(14); WRITE('4'); TEXTCOLOR(7); WRITE(': SP ENDING');
805       TEXTCOLOR(3); WRITELN(' (',ENDTYPE[B.ENDTYPE],')');
806     TEXTCOLOR(14); WRITE('5'); TEXTCOLOR(7); WRITE(': LEVELS');
807       TEXTCOLOR(3); WRITE(' (',B.LTOTAL,')');
808
809     III:=EDITMENU(5,3);
810     CASE III OF
811       1:B.NAME:=INPUTSTR('ENTER NEW TITLE FOR THIS LEVELFILE','NOTE TI-86 DISPLAYS ONLY 22 CHARS ON THEFIRST LINE',
812           B.NAME,32); {TITLE}
813       2:EDITDSPR;
814       3:EDITGAME;
815       4:EDITSPEND;
816       5:EDITLVL;
817     END; {HANDLE}
818   UNTIL III=-1; III:=0;
819 END; {EDITMAIN}
820
821 PROCEDURE OPENFILE;
822 BEGIN
823   ASSIGN(F,FILENAME+'.LVL'); {$I-} RESET(F,1); {$I+} I:=IORESULT;
824   IF I<>0THEN BEGIN
825     TEXTCOLOR(15); WRITE('WARNING!! '); TEXTCOLOR(7);
826     WRITELN('FAILED OPENING LEVEL FILE!'); WRITELN('RUNTIME ERROR #',I); HALT;
827   END; {CAN'T OPEN}
828   {$I-} BLOCKREAD(F,B,SIZEOF(B)); BLOCKREAD(F,L,SIZEOF(L)); {$I+}
829   IF(IORESULT<>0)OR(B.HEAD<>HEADEDIT)THEN BEGIN
830     TEXTCOLOR(15); WRITE('WARNING!! '); TEXTCOLOR(7);
831     WRITELN('ERROR READING LEVEL FILE!');
832     CLOSE(F); HALT;
833   END; {ERROR}
834   IF B.VERSION<>HEADVERSION THEN BEGIN
835     WRITELN('CAN''T READ FILE VERSION ',B.VERSION,'.'); CLOSE(F); HALT;
836   END; {VERSION}
837 END; {OPENFILE}
838
839 PROCEDURE FILESAVE;
840 BEGIN
841   ASSIGN(F,FILENAME+'.LVL'); REWRITE(F,1);
842   BLOCKWRITE(F,B,SIZEOF(B)); BLOCKWRITE(F,L,SIZEOF(L)); CLOSE(F);
843 END; {FILESAVE}
844
845 PROCEDURE FILECOMP;
846 VAR ISTACK:WORD;
847 BEGIN
848   ASSIGN(FF,FILENAME+'.86S'); REWRITE(FF,1);
849
850   BLOCKWRITE(FF,HEAD86S[1],ORD(HEAD86S[0])); {86S-HEADER}
851   ISTACK:=$12+6+B.SPRSIZE+ORD(B.NAME[0])+24+2+
852     2*(1+(B.LTO[2]-B.LFROM[2])+(B.LTO[3]-B.LFROM[3]));
853   FOR II:=B.LFROM[1]TO B.LTOTAL DO INC(ISTACK,L[II].SIZE);
854   BLOCKWRITE(FF,ISTACK,2); {FILE LENGTH (x+$12)}
855   I:=$000C; BLOCKWRITE(FF,I,2); {STRING ID}
856   DEC(ISTACK,$10); BLOCKWRITE(FF,ISTACK,2); {DATA LENGTH (x+2)}
857
858   I:=$080C; BLOCKWRITE(FF,I,2); {STRING ID}
859   S:='wormlvl1'; BLOCKWRITE(FF,S[1],8); {PRGNAME}
860   BLOCKWRITE(FF,ISTACK,2); {DATA LENGTH (x+2)}
861   DEC(ISTACK,2); BLOCKWRITE(FF,ISTACK,2); {PROG LENGTH (x)}
862
863   C:='w'; BLOCKWRITE(FF,C,1); {WORM ID}
864   I:=HEADVERSION; BLOCKWRITE(FF,I,1); {VERSION}
865   BLOCKWRITE(FF,B.NAME[0],ORD(B.NAME[0])+1); {TITLE}
866   I:=1+B.SPRSIZE+2; FOR II:=B.LFROM[1]TO B.LTOTAL DO I:=I+L[II].SIZE;
867   BLOCKWRITE(FF,I,2); {SIZE}
868
869   I2:=0; I:=$F401+B.SPRSIZE;
870   IF B.LSINGLE=0THEN BLOCKWRITE(FF,I2,2)ELSE BEGIN
871     BLOCKWRITE(FF,I,2); FOR II:=B.LFROM[1]TO B.LSINGLE DO INC(I,L[II].SIZE);
872   END; {SINGLLVLS} INC(I,2);
873   ISTACK:=I; FOR II:=2TO 7DO BEGIN
874     I:=ISTACK; IF B.LFROM[II]=0THEN I:=0 ELSE
875       FOR III:=B.LSINGLE TO B.LSINGLE+B.LFROM[II]-2DO
876         INC(I,L[III].SIZE);
877     BLOCKWRITE(FF,I,2);
878   END; {LOC}
879   FOR II:=B.LSINGLE+B.LMULTI+1TO B.LTOTAL DO INC(ISTACK,L[II].SIZE);
880   I:=0; IF B.LCTF=0THEN BLOCKWRITE(FF,I,2)ELSE BLOCKWRITE(FF,ISTACK,2);
881
882   FOR II:=1TO 7DO BEGIN
883     IF B.LFROM[II]=0THEN I:=0 ELSE I:=B.LTO[II]-B.LFROM[II]+1;
884     BLOCKWRITE(FF,I,1);
885   END; {NR}
886   BLOCKWRITE(FF,B.LCTF,1);
887
888   BLOCKWRITE(FF,B.SPRSIZE,1);
889   BLOCKWRITE(FF,B.SPRITE,B.SPRSIZE);
890
891   FOR II:=B.LFROM[1]TO B.LSINGLE DO BEGIN
892     BLOCKWRITE(FF,L[II].PEAS,1);
893     BLOCKWRITE(FF,L[II].DELAY,1);
894     BLOCKWRITE(FF,L[II].GROWTH,1);
895     BLOCKWRITE(FF,L[II].BSIZE,1);
896     BLOCKWRITE(FF,L[II].SPRSIZE,1);
897     BLOCKWRITE(FF,L[II].SPRITE,L[II].SPRSIZE);
898     BLOCKWRITE(FF,L[II].NRBALLS,1);
899     BLOCKWRITE(FF,L[II].BALLS,L[II].NRBALLS*3);
900     BLOCKWRITE(FF,L[II].W[1].D,3); {D,X,Y}
901     BLOCKWRITE(FF,L[II].FIELDX,2); {FIELDX,FIELDY}
902     FOR I:=1TO L[II].NROBJ DO BEGIN
903       BLOCKWRITE(FF,L[II].OBJ[I].TYP,5);
904     END; {OBJS}
905     I:=0; BLOCKWRITE(FF,I,1); {LVL END}
906   END; {LEVELS SINGLEPL}
907
908   I:=255; BLOCKWRITE(FF,I,1); {END}
909   I:=$C9; BLOCKWRITE(FF,I,1); {RET}
910
911   FOR II:=B.LSINGLE+1TO B.LSINGLE+B.LMULTI DO BEGIN
912     BLOCKWRITE(FF,L[II].PEAS,1);
913     BLOCKWRITE(FF,L[II].DELAY,1);
914     BLOCKWRITE(FF,L[II].GROWTH,1);
915     BLOCKWRITE(FF,L[II].BSIZE,1);
916     BLOCKWRITE(FF,L[II].SPRSIZE,1);
917     BLOCKWRITE(FF,L[II].SPRITE,L[II].SPRSIZE);
918     BLOCKWRITE(FF,L[II].NRBALLS,1);
919     BLOCKWRITE(FF,L[II].BALLS,L[II].NRBALLS*3);
920     BLOCKWRITE(FF,L[II].W[1].D,3*4); {D,X,Y}
921     BLOCKWRITE(FF,L[II].FIELDX,2); {FIELDX,FIELDY}
922     FOR I:=1TO L[II].NROBJ DO BEGIN
923       BLOCKWRITE(FF,L[II].OBJ[I].TYP,5);
924     END; {OBJS}
925     I:=0; BLOCKWRITE(FF,I,1); {LVL END}
926   END; {LEVELS MULTIPL}
927
928   I:=0; FOR II:=1TO 1+(B.LTO[2]-B.LFROM[2])+(B.LTO[3]-B.LFROM[3])DO
929     BLOCKWRITE(FF,I,2); {HI}
930
931   SEEK(FF,$37); I2:=0; I:=0;
932   REPEAT INC(I,I2); BLOCKREAD(FF,I2,1,ISTACK); UNTIL ISTACK<>1;
933   BLOCKWRITE(FF,I,2); {CHECKSUM}
934 END; {FILECOMP}
935
936 PROCEDURE EDITQUIT;
937 BEGIN
938   REPEAT
939     TITLEBAR(0,'CHOOSE LEVELFILE');
940     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITELN(': COMPILE, SAVE AND QUIT');
941     TEXTCOLOR(14); WRITE('2'); TEXTCOLOR(7); WRITE(': SAVE ');
942       TEXTCOLOR(3); WRITELN(FILENAME,'.LVL');
943     TEXTCOLOR(14); WRITE('3'); TEXTCOLOR(7); WRITELN(': QUIT');
944     TEXTCOLOR(14); WRITE('4'); TEXTCOLOR(7); WRITELN(': CONTINUE EDITING');
945     WRITELN; III:=EDITMENU(4,0);
946     CASE III OF
947       1:BEGIN
948         FILESAVE; FILECOMP; HALT;
949       END; {COMPILE}
950       2:FILESAVE;
951       3:BEGIN
952         WINDOW(1,8,40,8);
953         WRITE('REALLY QUIT '); TEXTCOLOR(8); WRITE('[Y/N]'); TEXTCOLOR(7);
954         WRITE('> '); REPEAT C:=READKEY; UNTIL(UPCASE(C)='Y')OR(UPCASE(C)='N');
955         IF UPCASE(C)<>'Y'THEN III:=0;
956       END; {QUIT}
957       4:EDITMAIN;
958     END; {HANDLE}
959   UNTIL III=3; HALT;
960 END; {EDITQUIT}
961
962 PROCEDURE EDITFILE;
963 BEGIN
964   REPEAT
965     TITLEBAR(0,'CHOOSE LEVELFILE');
966     TEXTCOLOR(14); WRITE('1'); TEXTCOLOR(7); WRITELN(': CREATE NEW FILE');
967     TEXTCOLOR(14); WRITE('2'); TEXTCOLOR(7); WRITELN(': EDIT EXISTING');
968     TEXTCOLOR(14); WRITE('3'); TEXTCOLOR(7); WRITE(': EDIT'); TEXTCOLOR(3);
969     WRITE(' WORMLVL1.LVL');
970
971     III:=EDITMENU(3,2);
972     CASE III OF
973       1:BEGIN
974         FILENAME:=INPUTSTR('ENTER LEVELNAME','8 CHARS MAX; W/O EXTENSION','WORMLVL1',8);
975         IF NOT FILEEXIST(FILENAME+'.LVL')THEN FILESAVE;
976         OPENFILE; EDITMAIN; EDITQUIT;
977       END; {NEW}
978       2:BEGIN
979         FILENAME:=INPUTSTR('ENTER FILENAME','W/O EXTENSION','WORMLVL1',8);
980         OPENFILE; EDITMAIN; EDITQUIT;
981       END; {EDIT}
982       3:BEGIN
983         FILENAME:='WORMLVL1'; OPENFILE; EDITMAIN; EDITQUIT;
984       END; {WORMLVL1}
985     END; {HANDLE}
986   UNTIL III=-1;
987 END; {EDITFILE}
988
989
990 BEGIN
991   MAINTITLE; EDITFILE;
992 END.