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