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