{ MapEdit 7.0 Wolfenstein Map Editor ver 7.0 (Bryan Baker, Dave Huntoon - 6/93) - Added options to only display certain level guards, treasure, or ammo & food These options are: '1' - Level 1 Guards Only '2' - Treasure and One-ups Only '3' - Level 3 Guards Only '4' - Level 4 Guards Only '5' - Boss Guards Only '6' - Ammo, Food, First Aid, and One-ups only - Added filename prompt to Read and Write floor files - Improved program startup and error display. Simplified file opening logic. This will make installation easier and almost fool proof. - Modified Legend to display only those items in the MAPDATA and OBJDATA files and in the order read from the files. - Minor bug fixes ver 6.1 (Matt Gruson - 5/93 Contact on CompuServe @ 72360,2432 or 73766,347 Prodigy @ PTJT50A GEnie @ M.GRUSON - Allowed right mouse button to have it's own value. - Allowed sepperate tracking of MAP and OBJ mode values for the different mouse buttons. - Holding down shift key while clicking on the map loads values. - Spacebar toggles between MAP and OBJECT modes. - Allowed PAGEUP and PAGEDOWN to scroll the legend display. - Removed unused code for clarity. ver 6.0 (Dave Huntooon - 5/93) - Added help display (and switch to toggle help / stats) - Added Copy, Paste and Exchange procedures - Added Write and Read procedures that will allow exporting and importing floors via a file named FLOOR.OUT - Changed the Clear procedure to fill using the currently selected map value - minor fixes ver 5.0 (Bryan Baker - 4/93) - Added display of critical map statistics to edit window: Static Objects Total Guards Doors Level 1 Guards Level 3 Guards Level 4 Guards Super Guards Secret Doors Treasure & Extra Lives ver 4.1a (Dave Huntoon) - Adds ability to open Spear of Destiny (SOD) maps. - Allows access to objects > 00FE. Needed for SOD objects - minor fix to completely clear text area below the map display when the mouse is moved outside of the map area. ver 4.1 Copyright (c) 1992 Bill Kirby } {$A+,B-,D+,E-,F-,I+,L-,N-,O-,R-,S-,V-} {$M 16384,0,655360} program mapedit; uses crt,dos,graph,mouse; const MAP_X = 6; MAP_Y = 6; TEXTLOC = 458; GAMEPATH : string = '.\'; LEVELS : word = 10; GAME_VERSION : real = 1.0; VERSION : string = '7.0'; KEYSTATADDR = $417; LEFTSHIFTMASK = $01; RIGHTSHIFTMASK = $02; {Rev 6.1} KEY_PGUP = chr(73); KEY_PGDN = chr(81); {These should be CHARs, but since Borland Pascal 7 can't evaluate CHAR constants in case statements I had to do it the ugly way} type data_block = record size : word; data : pointer; end; level_type = record map, objects, other : data_block; width, height : word; name : string[16]; end; grid = array[0..63,0..63] of word; filltype = (solid,check); doortype = (horiz,vert); var levelmap, objectmap : grid; maps : array[1..60] of level_type; show_objects, show_floor, guards_1, guards_3, guards_4, guards_s, treasure, ammofood : boolean; mapgraph, objgraph : array[0..300] of string[4]; mapnames, objnames : array[0..300] of string[20]; legmapptr, legobjptr : array[0..300] of word; mapcount, objcount : integer; themouse : resetrec; mouseloc : locrec; MAPFILENAME : string [12]; HEADFILENAME : string [12]; stats, xfer, copy, excng : boolean; tempobj, tempmap : grid; procedure decorate(x, y, c: integer); var i, j: integer; begin setfillstyle(1, c); bar(x*7+MAP_X+2, y*7+MAP_Y+2, x*7+MAP_X+4, y*7+MAP_Y+4); end; procedure box(fill: filltype; x, y, c1, c2: integer; dec: boolean); begin if fill=solid then setfillstyle(1, c1) else setfillstyle(9, c1); bar(x*7+MAP_X, y*7+MAP_Y, x*7+6+MAP_X, y*7+6+MAP_Y); if dec then decorate(x,y,c2); end; procedure outtext(x, y, color: integer; s: string); begin setcolor(color); outtextxy(x*7+MAP_X, y*7+MAP_Y, s); end; function hex(x: word): string; const digit : string[16] = '0123456789ABCDEF'; var temp : string[4]; i : integer; begin temp := ' '; for i := 4 downto 1 do begin temp[i] := digit[(x and $000f) + 1]; x := x div 16; end; hex := temp; end; function hexbyte(x: byte): string; const digit : string[16] = '0123456789ABCDEF'; var temp : string[4]; i : integer; begin temp := ' '; for i := 2 downto 1 do begin temp[i] := digit[(x and $000f) + 1]; x := x div 16; end; hexbyte := temp; end; procedure doline(x, y, x2, y2: integer); begin line(x+MAP_X, y+MAP_Y, x2+MAP_X, y2+MAP_Y); end; procedure dobar(x, y, x2, y2: integer); begin bar(x+MAP_Y, y+MAP_Y, x2+MAP_X, y2+MAP_Y); end; procedure circle(x, y, c1, c2: integer); const sprite : array[0..6,0..6] of byte = ((0,0,1,1,1,0,0), (0,1,1,1,1,1,0), (1,1,1,2,1,1,1), (1,1,2,2,2,1,1), (1,1,1,2,1,1,1), (0,1,1,1,1,1,0), (0,0,1,1,1,0,0)); var i, j, c: integer; begin for i := 0 to 6 do for j := 0 to 6 do begin case sprite[i, j] of 0: c := 0; 1: c := c1; 2: c := c2; end; putpixel(x*7+MAP_X+i, y*7+MAP_Y+j, c); end; end; procedure door(dtype: doortype; x, y, color: integer); begin case dtype of vert : begin setfillstyle(1, color); dobar(x*7+2, y*7, x*7+4, y*7+6); end; horiz : begin setfillstyle(1, color); dobar(x*7, y*7+2, x*7+6, y*7+4); end; end; end; function hexnibble(c: char): byte; begin case c of '0'..'9': hexnibble := ord(c) - ord('0'); 'a'..'f': hexnibble := ord(c) - ord('a') + 10; 'A'..'F': hexnibble := ord(c) - ord('A') + 10; else hexnibble := 0; end; end; procedure output(x, y: integer; data: string); var size : integer; temp : string[4]; c1, c2 : byte; begin if data<>'0000' then begin temp := data; c1 := hexnibble(temp[1]); c2 := hexnibble(temp[2]); case temp[3] of '0': outtext(x, y, c1, temp[4]); '1': box(solid, x, y, c1, c2, false); '2': box(check, x, y, c1, c2, false); '3': box(solid, x, y, c1, c2, true); '4': box(check, x, y, c1, c2, true); '5': circle(x, y, c1, c2); '6': door(horiz, x, y, c1); '7': door(vert, x, y, c1); '8': begin setfillstyle(1, c1); dobar(x*7, y*7, x*7+6, y*7+3); setfillstyle(1, c2); dobar(x*7, y*7+4, x*7+6, y*7+6); end; '9': putpixel(x*7+MAP_X+3, y*7+MAP_Y+3, c1); 'a': begin setfillstyle(1, c1); dobar(x*7+2, y*7+1, x*7+4, y*7+5); end; 'b': begin setfillstyle(1, c1); dobar(x*7+2, y*7+2, x*7+4, y*7+4); end; 'c': begin setfillstyle(1, c1); dobar(x*7+1, y*7+1, x*7+5, y*7+5); end; 'd': begin setcolor(c1); doline(x*7+1, y*7+1, x*7+5, y*7+5); doline(x*7+5, y*7+1, x*7+1, y*7+5); end; 'e': begin setcolor(c1); rectangle(x*7+MAP_X, y*7+MAP_Y, x*7+MAP_X+6, y*7+MAP_Y+6); end; 'f': case c2 of 2: begin {east} setcolor(c1); doline(x*7, y*7+3, x*7+6, y*7+3); doline(x*7+6, y*7+3, x*7+3, y*7); doline(x*7+6, y*7+3, x*7+3, y*7+6); end; 0: begin {north} setcolor(c1); doline(x*7+3, y*7+6, x*7+3, y*7); doline(x*7+3, y*7, x*7, y*7+3); doline(x*7+3, y*7, x*7+6, y*7+3); end; 6: begin {west} setcolor(c1); doline(x*7+6, y*7+3, x*7, y*7+3); doline(x*7, y*7+3, x*7+3, y*7); doline(x*7, y*7+3, x*7+3, y*7+6); end; 4: begin {south} setcolor(c1); doline(x*7+3, y*7, x*7+3, y*7+6); doline(x*7+3, y*7+6, x*7, y*7+3); doline(x*7+3, y*7+6, x*7+6, y*7+3); end; 1: begin {northeast} setcolor(c1); doline(x*7, y*7+6, x*7+6, y*7); doline(x*7+6, y*7, x*7+3, y*7); doline(x*7+6, y*7, x*7+6, y*7+3); end; 7: begin {northwest} setcolor(c1); doline(x*7+6, y*7+6, x*7, y*7); doline(x*7, y*7, x*7+3, y*7); doline(x*7, y*7, x*7, y*7+3); end; 3: begin {southeast} setcolor(c1); doline(x*7, y*7, x*7+6, y*7+6); doline(x*7+6, y*7+6, x*7+3, y*7+6); doline(x*7+6, y*7+6, x*7+6, y*7+3); end; 5: begin {southwest} setcolor(c1); doline(x*7+6, y*7, x*7, y*7+6); doline(x*7, y*7+6, x*7+3, y*7+6); doline(x*7 , y*7+6, x*7, y*7+3); end; end; end; end; end; procedure display_map; var i, j : integer; disp_obj : word; begin j := 63; i := 0; repeat setfillstyle(1, 0); dobar(i*7, j*7, i*7+6, j*7+6); if show_floor then output(i, j, mapgraph[levelmap[i,j]]) {Show everything} else if not (levelmap[i,j] in [$6a..$8f]) then output(i,j,mapgraph[levelmap[i,j]]); {Show walls & doors} if show_objects then begin {Show objects} disp_obj := objectmap[i,j]; if (guards_1 and (disp_obj in [$6c..$7c,$7c..$85,$8a..$8d,$d8..$df])) then output(i, j, objgraph[disp_obj]); if (guards_3 and (disp_obj in [$90..$9f,$a2..$a9,$ae..$b1,$ea..$f1])) then output(i, j, objgraph[disp_obj]); if (guards_4 and (disp_obj in [$b4..$c3,$c6..$cd,$d2..$d5])) then output(i, j, objgraph[disp_obj]); if (guards_4 and (disp_obj>$fb) and (disp_obj<$104)) then output(i, j, objgraph[disp_obj]); if (guards_s and (disp_obj in [$c4,$c5,$d6,$d7,$e0..$e3,$6a,$6b,$8e,$8f,$a0,$a1,$b2,$b3,$7d])) then output(i, j, objgraph[disp_obj]); if (treasure and (disp_obj in [$34..$38])) then output(i, j, objgraph[disp_obj]); if (ammofood and (disp_obj in [$2f,$30..$33,$38,$48,$1d])) then output(i, j, objgraph[disp_obj]); if not(guards_1 or guards_3 or guards_4 or guards_s or treasure or ammofood) then output(i, j, objgraph[disp_obj]); end; inc(i); if i=64 then begin i := 0; dec(j); end; until (j<0) or keypressed; end; procedure read_levels; var headfile, mapfile : file; s,o, size : word; idsig : string[4]; level : integer; levelptr : longint; tempstr : string[16]; map_pointer, object_pointer, other_pointer : longint; begin idsig := ' '; tempstr := ' '; assign(headfile,GAMEPATH+HEADFILENAME); {$I-} reset(headfile, 1); {$I+} if ioresult<>0 then begin writeln('error opening ',HEADFILENAME); halt(1); end; assign(mapfile,GAMEPATH+MAPFILENAME); {$I-} reset(mapfile, 1); {$I+} if ioresult<>0 then begin writeln('error opening ',MAPFILENAME); halt(1); end; for level:= 1 to LEVELS do begin seek(headfile, 2+(level-1)*4); blockread(headfile, levelptr, 4); seek(mapfile, levelptr); with maps[level] do begin blockread(mapfile, map_pointer, 4); blockread(mapfile, object_pointer, 4); blockread(mapfile, other_pointer, 4); blockread(mapfile, map.size, 2); blockread(mapfile, objects.size, 2); blockread(mapfile, other.size, 2); blockread(mapfile, width, 2); blockread(mapfile, height, 2); name[0] := #16; blockread(mapfile, name[1], 16); if GAME_VERSION=1.1 then blockread(mapfile, idsig[1], 4); seek(mapfile, map_pointer); getmem(map.data, map.size); s := seg(map.data^); o := ofs(map.data^); blockread(mapfile, mem[s:o], map.size); seek(mapfile, object_pointer); getmem(objects. data,objects.size); s := seg(objects.data^); o := ofs(objects.data^); blockread(mapfile, mem[s:o], objects.size); seek(mapfile, other_pointer); getmem(other.data, other.size); s := seg(other.data^); o := ofs(other.data^); blockread(mapfile, mem[s:o], other.size); if GAME_VERSION=1.0 then blockread(mapfile, idsig[1], 4); end; end; close(mapfile); close(headfile); end; procedure write_levels; var headfile, mapfile : file; abcd, s,o, size : word; idsig : string[4]; level : integer; levelptr : longint; tempstr : string[16]; map_pointer, object_pointer, other_pointer : longint; begin abcd := $abcd; idsig := '!ID!'; tempstr := 'TED5v1.0'; assign(headfile, GAMEPATH+HEADFILENAME); rewrite(headfile, 1); assign(mapfile, GAMEPATH+MAPFILENAME); rewrite(mapfile, 1); blockwrite(headfile, abcd, 2); blockwrite(mapfile, tempstr[1], 8); levelptr := 8; for level:=1 to LEVELS do begin with maps[level] do begin if GAME_VERSION=1.1 then begin map_pointer := levelptr; s := seg(map.data^); o := ofs(map.data^); blockwrite(mapfile, mem[s:o], map.size); inc(levelptr, map.size); object_pointer := levelptr; s := seg(objects.data^); o := ofs(objects.data^); blockwrite(mapfile, mem[s:o], objects.size); inc(levelptr, objects.size); other_pointer := levelptr; s := seg(other.data^); o := ofs(other.data^); blockwrite(mapfile, mem[s:o], other.size); inc(levelptr, other.size); blockwrite(headfile, levelptr, 4); blockwrite(mapfile, map_pointer, 4); blockwrite(mapfile, object_pointer, 4); blockwrite(mapfile, other_pointer, 4); blockwrite(mapfile, map.size, 2); blockwrite(mapfile, objects.size, 2); blockwrite(mapfile, other.size, 2); blockwrite(mapfile, width, 2); blockwrite(mapfile, height, 2); name[0] := #16; blockwrite(mapfile, name[1], 16); inc(levelptr, 38); end else begin blockwrite(headfile, levelptr, 4); map_pointer := levelptr+38; object_pointer := map_pointer+map.size; other_pointer := object_pointer+objects.size; blockwrite(mapfile, map_pointer, 4); blockwrite(mapfile, object_pointer, 4); blockwrite(mapfile, other_pointer, 4); blockwrite(mapfile, map.size, 2); blockwrite(mapfile, objects.size, 2); blockwrite(mapfile, other.size, 2); blockwrite(mapfile, width, 2); blockwrite(mapfile, height, 2); name[0] := #16; blockwrite(mapfile, name[1], 16); s := seg(map.data^); o := ofs(map.data^); blockwrite(mapfile, mem[s:o], map.size); s := seg(objects.data^); o := ofs(objects.data^); blockwrite(mapfile, mem[s:o], objects.size); s := seg(other.data^); o := ofs(other.data^); blockwrite(mapfile, mem[s:o], other.size); inc(levelptr, map.size+objects.size+other.size+38); end; blockwrite(mapfile, idsig[1], 4); inc(levelptr, 4); end; end; close(mapfile); close(headfile); end; procedure a7a8_expand(src: data_block; var dest: data_block); var s, o, s2, o2, index, index2, size, length, data, newsize : word; goback1 : byte; goback2 : word; i : integer; begin s := seg(src.data^); o := ofs(src.data^); index := 0; move(mem[s:o+index], dest.size, 2); inc(index, 2); getmem(dest.data, dest.size); s2 := seg(dest.data^); o2 := ofs(dest.data^); index2 := 0; repeat move(mem[s:o+index], data, 2); inc(index, 2); case hi(data) of $a7: begin length := lo(data); move(mem[s:o+index], goback1, 1); inc(index, 1); move(mem[s2:o2+index2-goback1*2], mem[s2:o2+index2], length*2); inc(index2,length*2); end; $a8: begin length := lo(data); move(mem[s:o+index], goback2, 2); inc(index, 2); move(mem[s2:o2+goback2*2], mem[s2:o2+index2], length*2); inc(index2, length*2); end; else begin move(data, mem[s2:o2+index2], 2); inc(index2, 2); end; end; until index=src.size; end; procedure expand(d: data_block; var g: grid); var i,x,y : integer; s,o, data, count : word; temp : data_block; begin if GAME_VERSION = 1.1 then a7a8_expand(d, temp) else temp := d; x := 0; y := 0; s := seg(temp.data^); o := ofs(temp.data^); inc(o, 2); while (y<64) do begin move(mem[s:o], data, 2); inc(o, 2); if data=$abcd then begin move(mem[s:o], count, 2); inc(o, 2); move(mem[s:o], data, 2); inc(o, 2); for i:=1 to count do begin g[x,y] := data; inc(x); if x=64 then begin x := 0; inc(y); end; end; end else begin g[x,y] := data; inc(x); if x=64 then begin x := 0; inc(y); end; end; end; if GAME_VERSION=1.1 then freemem(temp.data, temp.size); end; procedure compress(g: grid; var d: data_block); var temp : pointer; size : word; abcd, s,o, olddata, data, nextdata, count : word; x,y,i : integer; temp2 : pointer; begin abcd := $abcd; x := 0; y := 0; getmem(temp, 8194); s := seg(temp^); o := ofs(temp^); data := $2000; move(data, mem[s:o], 2); size := 2; data := g[0,0]; while (y<64) do begin count := 1; repeat inc(x); if x=64 then begin x :=0; inc(y); end; if y<64 then nextdata:= g[x,y]; inc(count); until (nextdata<>data) or (y=64); dec(count); if count<3 then begin for i:= 1 to count do begin move(data, mem[s:o+size], 2); inc(size, 2); end; end else begin move(abcd, mem[s:o+size], 2); inc(size, 2); move(count, mem[s:o+size], 2); inc(size, 2); move(data, mem[s:o+size], 2); inc(size, 2); end; data := nextdata; end; getmem(temp2, size); move(temp^, temp2^, size); freemem(temp, 8194); if GAME_VERSION=1.1 then begin getmem(temp, size+2); s := seg(temp^); o := ofs(temp^); move(size, mem[s:o], 2); move(temp2^, mem[s:o+2], size); d.data := temp; d.size := size+2; freemem(temp2, size); end else begin d.data := temp2; d.size := size; end; end; procedure copy_level; { DGH 5/93 } begin tempobj := objectmap; tempmap := levelmap; end; procedure paste_level; { DGH 5/93 } begin objectmap := tempobj; levelmap := tempmap; end; procedure exchange; { DGH 5/93 } var i, j : integer; tempobj1, tempmap1 : word; begin for i:=0 to 63 do for j:=0 to 63 do begin tempobj1 := objectmap[i,j]; tempmap1 := levelmap[i,j]; objectmap[i,j] := tempobj[i,j]; levelmap[i,j] := tempmap[i,j]; tempobj[i,j] := tempobj1; tempmap[i,j] := tempmap1; end; end; procedure print_help; {DGH 5/93 } var StartX : integer; StartY : integer; DeltaY : integer; begin StartX := MAP_X+462; StartY := MAP_Y+380; DeltaY := 9; setcolor(15); setfillstyle(1,0); bar(StartX, StartY, 639, 479); outtextxy(StartX, StartY, 'O = Toggle Objects'); StartY := StartY + DeltaY; outtextxy(StartX, StartY, 'F = Toggle Floor'); StartY := StartY + DeltaY; outtextxy(StartX, StartY, 'C = Clear Floor'); StartY := StartY + DeltaY; outtextxy(StartX, StartY, 'S = Toggle Stats/Help'); StartY := StartY + DeltaY; if copy then setcolor(14) else setcolor(15); outtextxy(StartX, StartY, 'M = Memorize Level'); StartY := StartY + DeltaY; if (excng and copy) then setcolor(14); if (excng and not copy) then setcolor (12); if not excng then setcolor(15); outtextxy(StartX, StartY, 'E = Exchange Level'); setcolor(15); if (not copy and xfer) then setcolor(12); if (copy and xfer) then setcolor(14); StartY := StartY + DeltaY; outtextxy(StartX, StartY, 'T = Transfer Level'); setcolor(15); StartY := StartY + DeltaY; outtextxy(startx, starty, 'R = Read floor file'); StartY := StartY + DeltaY; outtextxy(startx, starty, 'W = Write floor file'); StartY := StartY + DeltaY; outtextxy(startx, starty, 'SPACE = Toggle mode'); StartY := StartY + DeltaY; outtextxy(StartX, StartY, 'Q = Quit'); delay(200); end; procedure print_version; { DGH 5/93 } begin setfillstyle(1,0); bar(180, TEXTLOC, 461, 479); setcolor(12); outtextxy(188, TEXTLOC, 'Mapedit v'+VERSION); end; procedure get_filename(var filename: string); { BDB 6/93 } var FnCount, ExtCount, TotalCount, ColumnPtr : integer; key : char; Done : boolean; begin setfillstyle(1,0); bar(MAP_X, MAP_Y, MAP_X+448, MAP_Y+448); setcolor(15); outtextxy(MAP_X, MAP_Y,'Enter filename: (Press ESC to abort)'); FnCount := 0; ExtCount := -1; TotalCount := 0; filename := ''; ColumnPtr := MAP_X; Done := false; repeat repeat outtextxy(ColumnPtr, MAP_Y+10, #95); repeat until keypressed; setcolor(0); outtextxy(ColumnPtr, MAP_Y+10, #219); setcolor(15); key := readkey; if key=#0 then begin key := readkey; key := #0; end; until key in ['0'..'9','A'..'Z','a'..'z', #08, #13, #27, #46]; if ((key=#13) or (key=#27)) then Done := true { CR or ESC } else begin if (key=#08) then { Backspace } begin if TotalCount>0 then begin delete(filename, TotalCount, 1); if ExtCount>=0 then ExtCount := ExtCount - 1 else FnCount := FnCount - 1; ColumnPtr := ColumnPtr - 8; setcolor(0); outtextxy(ColumnPtr, MAP_Y+10, #219); setcolor(15); end end else if TotalCount<12 then if (((key=#46) and (ExtCount<0) and (FnCount>0)) or ((key<>#46) and not((FnCount=8) and (ExtCount<0)) and (ExtCount<3))) then begin filename := filename + key; outtextxy(ColumnPtr, MAP_Y+10, key); ColumnPtr := ColumnPtr + 8; if (key=#46) then ExtCount := ExtCount + 1 else if ExtCount >= 0 then ExtCount := ExtCount + 1 else FnCount := FnCount + 1; end; TotalCount := FnCount + ExtCount + 1; end; until Done; if key=#27 then filename := 'ABORT'; end; procedure error_read(ecode : integer); { DGH 5/93 ; BDB 6/93 } var temp : string[3]; begin str(ecode, temp); outtextxy(MAP_X, MAP_Y+50, 'Error reading floor file.'); end; procedure error_write(ecode : integer); { DGH 5/93 ; BDB 6/93 } var temp : string[3]; begin str(ecode, temp); outtextxy(MAP_X, MAP_Y+50, 'Error writing floor file.'); end; procedure read_floor; { DGH 5/93 ; BDB 6/93 } var floor_file : file; numread1 : word; numread2 : word; size : word; filename : string[12]; key : char; ior : integer; begin get_filename(filename); if filename<>'ABORT' then begin size := sizeof(tempmap); Assign(floor_file, filename); {$I-} reset(floor_file,1); {$I+} ior := ioresult; if ior <> 0 then error_read(ior) else begin blockread(floor_file, tempmap, sizeof(tempmap), numread1); blockread(floor_file, tempobj, sizeof(tempmap), numread2); if (numread1<>size) or (numread2<>size) then error_read(999) else begin copy := true; outtextxy(MAP_X, MAP_Y+50, 'Floor file read. Use "E" or "T" command to insert.'); end; close(floor_file); end; outtextxy(MAP_X, MAP_Y+70, 'Press any key to continue . . .'); repeat until keypressed; key := readkey; end; print_help; display_map; end; procedure write_floor; { DGH 5/93 ; BDB 6/93 } var floor_file : file; numwrite1 : word; numwrite2 : word; size : word; filename : string[12]; key : char; ior : integer; begin get_filename(filename); if filename<>'ABORT' then begin size := sizeof(tempmap); Assign(floor_file, filename); {$I-} rewrite(floor_file,1); {$I+} ior := ioresult; if ior <> 0 then error_write(ior) else begin blockwrite(floor_file, levelmap, sizeof(levelmap), numwrite1); blockwrite(floor_file, objectmap, sizeof(objectmap), numwrite2); if (numwrite1<>size) or (numwrite2<>size) then error_write(999); close(floor_file); outtextxy(MAP_X, MAP_Y+50, 'Floor file written.'); end; outtextxy(MAP_X, MAP_Y+70, 'Press any key to continue . . .'); repeat until keypressed; key := readkey; end; display_map; end; procedure print_stats; { BDB 4/93 } var i, j : integer; Tempstr : string; Statics : integer; L1Guards : integer; L3Guards : integer; L4Guards : integer; SGuards : integer; TGuards : integer; Prizes : integer; Doors : integer; SecDoors : integer; StartX : integer; StartY : integer; DeltaY : integer; begin if stats then begin Statics := 0; L1Guards := 0; L3Guards := 0; L4Guards := 0; SGuards := 0; TGuards := 0; Prizes := 0; Doors := 0; SecDoors := 0; StartX := MAP_X+462; StartY := MAP_Y+380; DeltaY := 9; for i:=0 to 63 do for j:=0 to 63 do begin if objectmap[i,j] in [$17..$4a] then Statics := Statics+1; if objectmap[i,j] in [$6c..$7c,$7e..$85,$8a..$8d,$d8..$df] then L1Guards := L1Guards+1; if objectmap[i,j] in [$90..$9f,$a2..$a9,$ae..$b1,$ea..$f1] then L3Guards := L3Guards+1; if objectmap[i,j] in [$b4..$c3,$c6..$cd,$d2..$d5] then L4Guards := L4Guards+1; if (objectmap[i,j]>$fb) and (objectmap[i,j]<$104) then L4Guards := L4Guards+1; if objectmap[i,j] in [$c4,$c5,$d6,$d7,$e0..$e3,$6a,$6b,$8e,$8f,$a0,$a1,$b2,$b3,$7d] then SGuards := SGuards+1; if objectmap[i,j] in [$34..$38] then Prizes := Prizes+1; if objectmap[i,j] = $62 then SecDoors := SecDoors+1; if levelmap[i, j] in [$5a..$5f,$64..$65] then Doors := Doors+1; end; TGuards := L1Guards + L3Guards + L4Guards + SGuards; setcolor(15); setfillstyle(1,0); bar(StartX, StartY, 639, 479); if Statics<400 then setcolor(15) else setcolor(12); str(Statics:4, Tempstr); outtextxy(StartX, StartY,Tempstr+' Static Objects'); if TGuards<150 then setcolor(15) else setcolor(12); StartY := StartY + DeltaY; str(TGuards:4, Tempstr); outtextxy(StartX, StartY,Tempstr+' Total Guards '); if Doors<65 then setcolor(15) else setcolor(12); StartY := StartY + DeltaY; str(Doors:4, Tempstr); outtextxy(StartX, StartY,Tempstr+' Doors '); if guards_1 then setcolor(14) else setcolor(7); StartY := StartY + DeltaY + 4; str(L1Guards:4, Tempstr); outtextxy(StartX, StartY,Tempstr+' Level 1 Guards'); if guards_3 then setcolor(14) else setcolor(7); StartY := StartY + DeltaY; str(L3Guards:4, Tempstr); outtextxy(StartX, StartY,Tempstr+' Level 3 Guards'); if guards_4 then setcolor(14) else setcolor(7); StartY := StartY + DeltaY; str(L4Guards:4, Tempstr); outtextxy(StartX, StartY,Tempstr+' Level 4 Guards'); if guards_s then setcolor(14) else setcolor(7); StartY := StartY + DeltaY; str(SGuards:4, Tempstr); outtextxy(StartX, StartY,Tempstr+' Super Guards'); setcolor(7); StartY := StartY + DeltaY + 4; str(SecDoors:4, Tempstr); outtextxy(StartX, StartY,Tempstr+' Secret Doors '); if treasure then setcolor(14) else setcolor(7); StartY := StartY + DeltaY; str(Prizes:4, Tempstr); outtextxy(StartX, StartY,Tempstr+' $$$ / One-ups '); end; end; procedure clear_level(n: integer); var x,y: integer; begin mhide; for x:=0 to 63 do for y:=0 to 63 do begin levelmap[x,y] := n; objectmap[x,y] := 0; end; for x:=0 to 63 do begin levelmap[x,0] := 1; levelmap[x,63] := 1; levelmap[0,x] := 1; levelmap[63,x] := 1; end; display_map; print_stats; mshow; end; function str_to_hex(s: string): word; var temp : word; i : integer; begin temp := 0; for i:=1 to length(s) do begin temp := temp * 16; case s[i] of '0'..'9': temp := temp + ord(s[i]) - ord('0'); 'a'..'f': temp := temp + ord(s[i]) - ord('a')+10; 'A'..'F': temp := temp + ord(s[i]) - ord('A')+10; end; end; str_to_hex := temp; end; procedure showlegend(which, start, n: integer); var i,x,y : integer; save : boolean; begin mhide; save := show_objects; show_objects := true; setfillstyle(1,0); bar(MAP_X+461, 4, 634, 350); x := 66; y := 0; for i:=start to start+n-1 do begin if which=0 then begin output(x, y, mapgraph[legmapptr[i]]); outtext(x+2, y, 15, mapnames[legmapptr[i]]); end else begin output(x, y, objgraph[legobjptr[i]]); outtext(x+2, y, 15, objnames[legobjptr[i]]); end; inc(y, 2); end; show_objects := save; mshow; end; function inside(x1, y1, x2, y2, x, y: integer): boolean; begin inside := (x>=x1) and (x<=x2) and (y>=y1) and (y<=y2); end; procedure wait_for_mouserelease; begin repeat mpos(mouseloc); until mouseloc.buttonstatus=0; end; procedure bevel(x1, y1, x2, y2, c1, c2, c3: integer); begin setfillstyle(1,c1); bar(x1, y1, x2, y2); setcolor(c2); line(x1, y1, x2, y1); line(x1+1, y1+1, x2-1, y1+1); line(x2, y1, x2, y2); line(x2-1, y1, x2-1, y2-1); setcolor(c3); line(x1, y1+1, x1, y2); line(x1+1, y1+2, x1+1, y2); line(x1, y2, x2-1, y2); line(x1+1, y2-1, x2-2, y2-1); end; function upper(s: string): string; var i: integer; begin for i:=1 to length(s) do if s[i] in ['a'..'z'] then s[i] := chr(ord(s[i]) - ord('a') + ord('A')); upper := s; end; procedure initialize; var i : integer; infile : text; path : pathstr; dir : dirstr; name : namestr; ext : extstr; filename : string; hexstr : string[4]; graphstr : string[4]; name20 : string[20]; junk : char; search : searchrec; map : string[12]; obj : string[12]; sod, wl1, wl6 : boolean; begin writeln('MapEdit Copyright (c) 1992 Bill Kirby'); writeln('Version '+version); writeln; writeln('Modifications by Dave Huntoon'); writeln(' Bryan Baker'); writeln(' Matt Gruson'); writeln; MAPFILENAME := 'maptemp.wl1'; filename := GAMEPATH + MAPFILENAME ; findfirst(filename, $ff, search); if doserror=0 then writeln('Found --> '+MAPFILENAME); if doserror<>0 then begin MAPFILENAME := 'gamemaps.wl1'; filename := GAMEPATH + MAPFILENAME ; findfirst(filename, $ff, search); if doserror=0 then writeln('Found --> '+MAPFILENAME); if doserror<>0 then begin MAPFILENAME := 'gamemaps.wl3'; filename := GAMEPATH + MAPFILENAME ; findfirst(filename, $ff, search); if doserror=0 then writeln('Found --> '+MAPFILENAME); if doserror<>0 then begin MAPFILENAME := 'gamemaps.wl6'; filename := GAMEPATH + MAPFILENAME ; findfirst(filename, $ff, search); if doserror=0 then writeln('Found --> '+MAPFILENAME); if doserror<>0 then begin MAPFILENAME := 'gamemaps.sod'; filename := GAMEPATH + MAPFILENAME ; findfirst(filename, $ff, search); if doserror=0 then writeln('Found --> '+MAPFILENAME); if doserror<>0 then begin writeln('Error finding map file.'); writeln(' Read your documentation files.'); writeln; writeln('Be sure that you installed MAPEDIT in the directory where'); writeln('Wolfenstein 3-D or Spear of Destiny is installed.'); halt(0); end; end; end; end; end; wl1 := false; wl6 := false; sod := false; filename := search.name; fsplit(filename, dir, name, ext); MAPFILENAME := upper(MAPFILENAME); if upper(ext)='.WL1' then begin LEVELS := 10; if upper(name)='MAPTEMP' then GAME_VERSION := 1.0 else GAME_VERSION := 1.1; HEADFILENAME := 'maphead.wl1'; wl1 := true; end; if upper(ext)='.WL3' then begin LEVELS := 30; GAME_VERSION :=1.1; HEADFILENAME := 'maphead.wl3'; wl6 := true; end; if upper(ext)='.WL6' then begin LEVELS := 60; GAME_VERSION := 1.1; HEADFILENAME := 'maphead.wl6'; wl6 := true; end; if upper(ext)='.SOD' then begin LEVELS := 21; GAME_VERSION := 1.1; HEADFILENAME := 'maphead.sod'; sod := true; end; filename := GAMEPATH + HEADFILENAME ; findfirst(filename, $ff, search); if doserror=0 then writeln('Found --> '+HEADFILENAME); if doserror<>0 then begin writeln('Error finding MAPHEAD file -> '+ filename); halt(0); end; map := 'mapdata.def' ; obj := 'objdata.def' ; findfirst(map, $ff, search); if doserror=0 then begin writeln('Found --> '+map); findfirst(obj, $ff, search); if doserror=0 then writeln('Found --> '+obj); if doserror<>0 then begin writeln('Error finding --> '+obj); halt(0); end; end; if doserror<>0 then begin if wl1 then begin map := 'mapdata.wl1'; obj := 'objdata.wl1'; end; if wl6 then begin map := 'mapdata.wl6'; obj := 'objdata.wl6'; end; if sod then begin map := 'mapdata.sod'; obj := 'objdata.sod'; end; findfirst(map, $ff, search); if doserror=0 then writeln('Found --> '+map); if doserror<>0 then begin writeln('Error finding -->> '+map+ ' or mapdata.def.'); halt(0); end; findfirst(obj, $ff, search); if doserror=0 then writeln('Found --> '+obj); if doserror <> 0 then begin writeln('Error finding --> '+obj); halt(0); end; end; if GAME_VERSION=1.0 then begin writeln(''); writeln('*** WARNING ***'); writeln(''); writeln('You are running a rather old version of Wolf-3D.'); writeln(''); writeln('This version supports only a limited number of map and object elements.'); writeln(''); writeln('You can upgrade to the latest shareware version at a nominal fee'); writeln('by calling Apogee. (You pay only shipping and handling.)'); writeln(''); writeln(''); writeln('(Press any key to continue)'); repeat until keypressed; junk := readkey; end; for i:= 0 to 300 do begin mapnames[i] := 'unknown '+hex(i); objnames[i] := 'unknown '+hex(i); mapgraph[i] := 'f010'; objgraph[i] := 'f010'; legmapptr[i] := 0; legobjptr[i] := 0; end; assign(infile, map); reset(infile); mapcount := -1; while not eof(infile) do begin readln(infile, hexstr, junk, graphstr, junk, name20); mapnames[str_to_hex(hexstr)] := name20; mapgraph[str_to_hex(hexstr)] := graphstr; mapcount := mapcount + 1; legmapptr[mapcount] := str_to_hex(hexstr); end; close(infile); assign(infile, obj); reset(infile); objcount := -1; while not eof(infile) do begin readln(infile, hexstr, junk, graphstr, junk, name20); objnames[str_to_hex(hexstr)] := name20; objgraph[str_to_hex(hexstr)] := graphstr; objcount := objcount + 1; legobjptr[objcount] := str_to_hex(hexstr); end; close(infile); end; {-------------------------------------------------} { } {VARs for procedure MAIN and associated procedures} { } {-------------------------------------------------} var gd,gm, i,j,x,y : integer; infile : text; level : word; oldx,oldy : integer; done : boolean; outstr, tempstr : string; legendpos : integer; legendtype: integer; newj : integer; mode : (map,obj); leftmapval : integer; {Value inserted by left button press - MAP mode} rightmapval : integer; {Value inserted by right button press - MAP mode} leftobjval : integer; {Value inserted by left button press - OBJ mode} rightobjval : integer; {Value inserted by right button press - OBJ mode} oldj,oldi : integer; key : char; control : boolean; procedure showcurrentselection; { Removed from inside code body for 6.1 to allow use in several places. Writes the little 'currently selected attribute' note in the lower-left corner of the screen. } begin setfillstyle(1,0); bar(0, TEXTLOC+10, MAP_X+192, 479); if mode=map then begin output(0, 66, mapgraph[leftmapval]); outtext(1, 66, 15, ' '+mapnames[leftmapval]+' (MAP)'); end else begin output(0, 66, objgraph[leftobjval]); outtext(1, 66, 15, ' '+objnames[leftobjval]+' (OBJ)'); end; end; procedure process_buttons; { Added for 6.1 to facilitate easier handling of new functions. } label done; begin if (mem[0:keystataddr] and leftshiftmask>0) or (mem[0:keystataddr] and rightshiftmask>0) then { User is holding down a shift key while clicking, so let him/her load an atttribute from the map } begin if mouseloc.buttonstatus=leftbutton then {Load if left button} if mode=map then begin leftmapval := levelmap[i,j]; {Load 'MAP' value} showcurrentselection; end else begin leftobjval := objectmap[i,j]; {Load 'OBJ' value} showcurrentselection; end else {Load if right button} if mode=map then rightmapval := levelmap[i,j] {Load 'MAP' value} else rightobjval := objectmap[i,j]; {Load 'OBJ' value} goto done; {Leave procedure} end; { Falls through to here is no shift key held down } if mouseloc.buttonstatus=leftbutton then if mode=map then {Draw if left button} levelmap[i,j] := leftmapval else objectmap[i,j] := leftobjval else {Draw if right button} if mode=map then levelmap[i,j] := rightmapval else objectmap[i,j] := rightobjval; done: end; procedure set_map_mode; {Broken out from code body - ver 6.1} begin; wait_for_mouserelease; legendpos := 0; legendtype := 0; mode := map; showlegend(legendtype, legendpos, 25); showcurrentselection; end; procedure set_object_mode; {Broken out from code body - ver 6.1} begin wait_for_mouserelease; legendpos := 0; legendtype := 1; mode := obj; showlegend(legendtype, legendpos, 25); showcurrentselection; end; procedure legend_up; {Broken out from code body - ver 6.1} begin wait_for_mouserelease; dec(legendpos, 25); if legendpos<0 then legendpos := 0; showlegend(legendtype, legendpos, 25); end; procedure legend_down; {Broken out from code body - ver 6.1} begin wait_for_mouserelease; inc(legendpos, 25); if legendtype=0 then begin if (legendpos+25)>mapcount then legendpos := mapcount-24; end else if (legendpos+25)>objcount then legendpos := objcount-24; showlegend(legendtype, legendpos, 25); end; {----------------------} { } { MAIN CODE BODY } { } {----------------------} begin clrscr; initialize; directvideo := false; read_levels; gd := vga; gm := vgahi; initgraph(gd, gm, ''); settextstyle(0,0,1); mreset(themouse); show_objects := true; show_floor := false; guards_1 := false; guards_3 := false; guards_4 := false; guards_s := false; treasure := false; ammofood := false; stats := false; copy := false; excng := false; xfer := false; x := port[$3da]; port[$3c0] := 0; setfillstyle(1,7); bar(0, 0, MAP_X+452, MAP_Y+452); bar(MAP_X+457, 0, 639, 380); setfillstyle(1,0); bar(2, 2, MAP_X+450, MAP_Y+450); bar(MAP_X+459, 2, 637, 352); bar(MAP_X+459, 355,637, 378); setcolor(15); outtextxy(MAP_X+463, 364, ' MAP OBJ UP DOWN'); setfillstyle(1,7); bar(MAP_X+502, 355, MAP_X+503, 378); bar(MAP_X+542, 355, MAP_X+543, 378); bar(MAP_X+572, 355, MAP_X+573, 378); legendpos := 0; legendtype := 0; mode := map; leftmapval :=1; {Default values for buttons - ver 6.1} rightmapval :=0; leftobjval :=0; rightobjval :=0; setfillstyle(1,0); bar(0, TEXTLOC+10, MAP_X+448, 479); if mode=map then begin output(0, 66, mapgraph[leftmapval]); outtext(1, 66, 15, ' '+mapnames[leftmapval]); end else begin output(0, 66, objgraph[leftmapval]); outtext(1, 66, 15, ' '+objnames[leftmapval]); end; showlegend(legendtype, legendpos, 25); x := port[$3da]; port[$3c0] := 32; mshow; level :=1; done := false; setfillstyle(1,0); setcolor(15); print_help; print_version; showcurrentselection; {-------------} { } { Main Loop } { } {-------------} repeat mhide; setfillstyle(1,0); bar(0, TEXTLOC, MAP_X+173 , TEXTLOC+9); setcolor(14); outtextxy(5, TEXTLOC, maps[level].name); setcolor(15); expand(maps[level].map, levelmap); expand(maps[level].objects, objectmap); display_map; print_stats; mshow; oldx := 0; oldy := 0; key := #0; repeat repeat mpos(mouseloc); x := mouseloc.column; y := mouseloc.row; until (oldx<>x) or (oldy<>y) or keypressed or (mouseloc.buttonstatus<>0); oldx := x; oldy := y; if (mouseloc.buttonstatus<>0) then {Mouse Button Pressed} begin if inside(MAP_X, MAP_Y, MAP_X+447, MAP_Y+447, x, y) then begin { If inside the map display } mhide; repeat i := (x-MAP_X) div 7; j := (y-MAP_Y) div 7; process_buttons; {Rev 6.1} setfillstyle(1,0); dobar(i*7, j*7, i*7+6, j*7+6); if show_floor then output(i, j, mapgraph[levelmap[i,j]]) else if not (levelmap[i,j] in [$6a..$8f]) then output(i, j, mapgraph[levelmap[i,j]]); if show_objects then output(i, j, objgraph[objectmap[i,j]]); mpos(mouseloc); x := mouseloc.column; y := mouseloc.row; until (not inside(MAP_X, MAP_Y, MAP_X+447, MAP_Y+447, x, y)) or (mouseloc.buttonstatus=0); mshow; print_stats; end; if inside(464, 355, 506, 378, x, y) then set_map_mode; {Inside MAP command box} if inside(509, 355, 546, 378, x, y) then set_object_mode; {Inside OBJ command box} if inside(549, 355, 576, 378, x, y) then legend_up; {Inside UP command box} if inside(579, 355, 637, 378, x, y) then legend_down; {Inside DOWN command box} end; if inside(464, 2, 637, 350, x, y) then begin { If inside the legend box } mhide; j := (y-2) div 14; setcolor(15); rectangle(465, j*14+3, 636, j*14+14); repeat mpos(mouseloc); newj := (mouseloc.row-2) div 14; if mouseloc.buttonstatus<>0 then begin { Set current value based on button pressed - ver 6.1 } if mode=map then if mouseloc.buttonstatus=leftbutton then leftmapval := legmapptr[legendpos+j] else rightmapval := legmapptr[legendpos+j] else if mouseloc.buttonstatus=leftbutton then leftobjval := legobjptr[legendpos+j] else rightobjval := legobjptr[legendpos+j]; showcurrentselection; end; until (newj<>j) or (mouseloc.column<464) or keypressed; setcolor(0); rectangle(465, j*14+3, 636, j*14+14); mshow; end; if inside(MAP_X, MAP_Y, MAP_X+447, MAP_Y+447, x, y) then begin { If inside the map display } i := (x-MAP_X) div 7; j := (y-MAP_Y) div 7; if (oldj<>j) or (oldi<>i) then begin outstr := '('; str(i:2, tempstr); outstr := outstr+tempstr+','; str(j:2, tempstr); outstr := outstr+tempstr+') MAP: '+mapnames[levelmap[i,j]]; setfillstyle(1,0); setcolor(15); bar(188, TEXTLOC, MAP_X+448, 479); outtextxy(188, TEXTLOC, outstr); outstr := ' OBJ: '+objnames[objectmap[i,j]]; outtextxy(188, TEXTLOC+10, outstr); oldj := j; oldi := i; end; end else begin mhide; setfillstyle(1,0); bar(188, TEXTLOC, MAP_X+448, 479); mshow; end; if keypressed then begin control := false; key := readkey; if key=#0 then begin control := true; key := readkey; end; if control then case key of 'H': begin freemem(maps[level].map.data, maps[level].map.size); freemem(maps[level].objects.data, maps[level].objects.size); compress(levelmap, maps[level].map); compress(objectmap, maps[level].objects); inc(level); end; 'P': begin freemem(maps[level].map.data, maps[level].map.size); freemem(maps[level].objects.data, maps[level].objects.size); compress(levelmap, maps[level].map); compress(objectmap, maps[level].objects); dec(level); end; {keyboard support - ver 6.1} key_pgup : legend_up; key_pgdn : legend_down; end else case key of 'q','Q': begin done := true; freemem(maps[level].map.data, maps[level].map.size); freemem(maps[level].objects.data, maps[level].objects.size); compress(levelmap, maps[level].map); compress(objectmap, maps[level].objects); end; 'c','C': begin if mode = map then clear_level(leftmapval) else clear_level($6c); end; 'o','O': begin mhide; show_objects := not show_objects; display_map; mshow; end; 'f','F': begin mhide; show_floor := not show_floor; display_map; if legendtype=0 then showlegend(legendtype,legendpos,25); mshow; end; '1': begin mhide; show_objects := true; guards_1 := true; guards_3 := false; guards_4 := false; guards_s := false; treasure := false; ammofood := false; stats := true; display_map; print_stats; mshow; end; '2': begin mhide; show_objects := true; guards_1 := false; guards_3 := false; guards_4 := false; guards_s := false; treasure := true; ammofood := false; stats := true; display_map; print_stats; mshow; end; '3': begin mhide; show_objects := true; guards_1 := false; guards_3 := true; guards_4 := false; guards_s := false; treasure := false; ammofood := false; stats := true; display_map; print_stats; mshow; end; '4': begin mhide; show_objects := true; guards_1 := false; guards_3 := false; guards_4 := true; guards_s := false; treasure := false; ammofood := false; stats := true; display_map; print_stats; mshow; end; '5': begin mhide; show_objects := true; guards_1 := false; guards_3 := false; guards_4 := false; guards_s := true; treasure := false; ammofood := false; stats := true; display_map; print_stats; mshow; end; '6': begin mhide; show_objects := true; guards_1 := false; guards_3 := false; guards_4 := false; guards_s := false; treasure := false; ammofood := true; stats := true; display_map; print_stats; mshow; end; 'A','a': begin mhide; show_objects := true; guards_1 := false; guards_3 := false; guards_4 := false; guards_s := false; treasure := false; ammofood := false; display_map; print_stats; mshow; end; 's','S': begin mhide; if (guards_1 or guards_3 or guards_4 or guards_s or treasure or ammofood) then begin guards_1 := false; guards_3 := false; guards_4 := false; guards_s := false; treasure := false; ammofood := false; display_map; end; stats := not stats; if stats then print_stats else print_help; mshow; end; 'm','M': begin copy := true; print_help; copy_level; if stats then print_stats; end; 'e','E': begin mhide; excng := true; print_help; if copy then begin exchange; display_map; end; excng := false; print_help; if stats then print_stats; mshow; end; 't','T': begin mhide; xfer := true; print_help; if copy then begin paste_level; display_map; end; xfer := false; print_help; delay(200); if stats then print_stats; mshow; end; 'r','R': begin mhide; setfillstyle(1,0); bar(180, TEXTLOC, 461, 479); setcolor(15); outtextxy(180, TEXTLOC, 'Reading Floor File'); read_floor; setfillstyle(1,0); bar(180, TEXTLOC, 461, 479); if stats then print_stats; mshow; end; 'w','W': begin mhide; setfillstyle(1,0); bar(180, TEXTLOC, 461, 479); setcolor(15); outtextxy(180, TEXTLOC, 'Writing Floor File'); write_floor; setfillstyle(1,0); bar(180,TEXTLOC,461,479); mshow; end; 'v','V': begin print_version; end; ' ' : begin {Space toggles mode MAP<->OBJ - ver 6.1} if mode=map then set_object_mode else set_map_mode; end; end; end; until done or (key in ['P','H']); if level=0 then level := LEVELS; if level=(LEVELS+1) then level := 1; until done; setfillstyle(1,0); bar(0, TEXTLOC, 462, 479); setcolor(15); outtextxy(0, TEXTLOC,' Save the current levels to disk? (Y/N) '); repeat repeat until keypressed; key := readkey; if key=#0 then begin key := readkey; key := #0; end; until key in ['y','Y','n','N']; if key in ['y','Y'] then write_levels; textmode(co80); writeln('MapEdit 4.1 Copyright (c) 1992 Bill Kirby'); writeln; writeln(' Ver. '+VERSION+' Modification'); writeln; writeln('This program is intended to be for your personal use only.'); writeln('Distribution of any modified maps may be construed as a '); writeln('copyright violation by Apogee/ID.'); writeln; end.