home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Devil's Doorknob BBS Capture (1996-2003)
/
devilsdoorknobbbscapture1996-2003.iso
/
Dloads
/
MISSING
/
CIVMAP21.ZIP
/
civmap21.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-06-20
|
25KB
|
552 lines
{ Civilization Map Changer Version 2.1 (6/20/93)
written by Holger Eichmann
Changes the interrupts $f1 and $f2. If you insert a call of these
interrupts into the right places of the civ.exe file (see writeln text
in the main program), you are able to change important attributes of
single points of the map while playing civ.exe. Because civ.exe has no
list of improvements of map points (like coal, oasis or fish), but only
calculate these points, this program generates its own list. Consider
that this list will not be saved automatically, too, when you save your
game. While playing you will get the cheat menu when you right click
a distant field like normally getting informations of the landscape type
of this field.
In this version the program should work together with all versions of
civ.exe (I hope so).
Please send your comments to:
Holger.Eichmann@cdc2.atomare-prozesse.physik.uni-hannover.dbp.de}
{$M $800,0,0}
uses dos, crt;
const maxlist = 200; { max. length of improvement list (contains the
coordinates of the fields with changed improvement
like coal or horses) }
{$F+}
var counter,i, masterw : word;
x, y : array[1..maxlist] of word;
turn_on : boolean;
regs : registers;
colorlist : array[1..771] of byte;
{$L c:\tp\programs\asm\civext21.obj}
procedure civext21(var segm_dark, off_dark, dark_pos, segm_data, row,
column, error: word); external;
{$L c:\tp\programs\asm\civint2.obj}
procedure civint2; external;
procedure editor; interrupt;
var key : char;
filelength : longint;
mode, landtype, sm_map, attr, dark, all_dark : byte;
norm_impr, improve, exist, ende : boolean;
row, column, segm_data, segm_dark, off_land, off_smap, off_attr1,
off_attr2, off_dark, im_pos, i, j, dark_pos, error : word;
s : array[1..25] of char;
s1, s2, length : string[7];
fname : string;
f : text;
begin
{ correct one of the changes of civ.exe (mov ax,32 -> int F1) }
inline($b8/$32/$00/$36/$89/$46/$10); {mov ax,32h; mov ss:[bp+10h],ax}
if turn_on then
begin
{ get colors }
regs.ax := $1017;
regs.bx := 0;
regs.cx := 256;
regs.es := seg(colorlist);
regs.dx := ofs(colorlist);
intr($10, regs);
{ get video mode }
regs.ah := $0f;
intr($10, regs);
mode := regs.al;
{ set video mode to 80*25 text }
regs.ah := 0;
regs.al := 03;
intr($10, regs);
textcolor(15);
{ get coordinates of the map field and the addresses of the data in memory
segm_dark:off_dark : places known or unknown; your civilization is stored
at position dark_pos of each byte
segm_data:... : map informations like type of landscape
row, column : coordinates of field}
civext21(segm_dark, off_dark, dark_pos, segm_data, row, column, error);
if error = 1 then
begin
clrscr;
writeln;
writeln('Fatal Error: Unknown Civilization Version !!!!!!');
writeln;
writeln('If you want to use civ_map, then try another Civilization version !');
writeln('Please send a mail to the author !');
key := readkey;
end
else if (row = 0) or (row = 1) then
begin
clrscr;
writeln;
writeln('Sorry, no changes of row 0 and 1 allowed !!!!!!');
writeln('(that would confuse the data search function)');
key := readkey
end
else
begin
{ calculate segment and offset addresses of the interesting data }
off_land := row*$140+column;
off_smap := off_land + $f0;
off_attr1 := off_land + $7d00;
off_attr2 := off_land + $7d50;
{ get the properties of the map field }
landtype := mem[segm_data:off_land]; { type of landscape (ocean, ...) }
sm_map := mem[segm_data:off_smap]; { appearance in small map }
attr := mem[segm_data:off_attr1]; { attributes (roads,...) }
dark := mem[segm_dark:column*$32 + row + off_dark]; { is it dark ? }
exist := false; { already in improvement list ? }
ende := false;
im_pos := 0; { position there }
all_dark := 0; { all fields set dark or clear ? }
{ calculation if it normally is improved; the variable masterw will
be set by civint2.asm automatically }
norm_impr := (((column shr 2) * $000d + (row shr 2) * $000b
+ masterw) and $000f = (column and 3) shl 2
+ (row and 3));
improve := norm_impr;
{ test, whether it is in the improvement list }
for i := 1 to counter do
if (x[i] = column) and (y[i] = row) then
begin
improve := not norm_impr;
exist := true;
im_pos := i
end;
repeat
{ some text lines will be marked by a * }
s[1] := char(integer(landtype=1) * 10 + 32);
s[2] := char(integer(landtype=2) * 10 + 32);
s[3] := char(integer(landtype=3) * 10 + 32);
s[4] := char(integer(landtype=6) * 10 + 32);
s[5] := char(integer(landtype=7) * 10 + 32);
s[6] := char(integer(landtype=9) * 10 + 32);
s[7] := char(integer(landtype=10) * 10 + 32);
s[8] := char(integer(landtype=11) * 10 + 32);
s[9] := char(integer(landtype=12) * 10 + 32);
s[10] := char(integer(landtype=13) * 10 + 32);
s[11] := char(integer(landtype=14) * 10 + 32);
s[12] := char(integer(landtype=15) * 10 + 32);
s[16] := char(integer(attr and 2=2) * 10 + 32);
s[17] := char(integer(attr and 4=4) * 10 + 32);
s[18] := char(integer(attr and 8=8) * 10 + 32);
s[19] := char(integer(attr and 16=16) * 10 + 32);
s[20] := char(integer(attr and 32=32) * 10 + 32);
s[21] := char(integer(attr and 64=64) * 10 + 32);
if dark and dark_pos = dark_pos then s1 := 'un' else s1 := '';
if improve then s2 := 'remove' else s2 := 'create';
str(counter,length);
clrscr;
writeln ('Civilization Map Changer Version 2.1 written by Holger Eichmann');
writeln ('(C) 1993 by Sirius Cybernetics Corporation, Sirius Star System I-III');
writeln;
writeln ('Position: row: ',row,', column: ', column);
writeln('Landscape: ',s[1],' (0) ocean Attributes: ',s[16],' (f) irrigation');
writeln(' ',s[2],' (1) forest ',s[17],' (g) mines');
writeln(' ',s[3],' (2) swamp ',s[18],' (h) roads');
writeln(' ',s[4],' (3) plain ',s[19],' (i) railroad');
writeln(' ',s[5],' (4) tundra ',s[20],' (j) fortification');
writeln(' ',s[6],' (5) river ',s[21],' (k) pollution');
writeln(' ',s[7],' (6) grassland');
writeln(' ',s[8],' (7) jungle (l) make this place ',s1,'known');
writeln(' ',s[9],' (8) hill (m) make whole map known');
writeln(' ',s[10],' (9) mountain (n) make whole map unknown');
writeln(' ',s[11],' (a) desert');
writeln(' ',s[12],' (b) arctic (o) ',s2,' improvement');
writeln(' (p) clear improvement list');
writeln('(c) load whole map (q) load list');
writeln('(d) save whole map (r) save list');
writeln(' list length: ',length);
writeln;
writeln(' (x) exit');
key := readkey;
{ what do you want to change ? }
case key of
'0' : landtype := 1;
'1' : landtype := 2;
'2' : landtype := 3;
'3' : landtype := 6;
'4' : landtype := 7;
'5' : landtype := 9;
'6' : landtype := 10;
'7' : landtype := 11;
'8' : landtype := 12;
'9' : landtype := 13;
'a','A' : landtype := 14;
'b','B' : landtype := 15;
'c','C' : begin
writeln('Are you sure that you want to load the whole map ?');
key := readkey;
if (key = 'y') or (key = 'Y') then
begin
all_dark := 100;
ende := true
end
end;
'd','D' : begin
writeln('Are you sure that you want to save the whole map ?');
key := readkey;
if (key = 'y') or (key = 'Y') then
begin
all_dark := 101;
ende := true
end
end;
'f','F' : attr := attr xor 2;
'g','G' : attr := attr xor 4;
'h','H' : attr := attr xor 8;
'i','I' : attr := attr xor 16;
'j','J' : attr := attr xor 32;
'k','K' : attr := attr xor 64;
'l','L' : dark := dark xor dark_pos;
'm','M' : begin
writeln('Are you sure that you want to make the whole map known ?');
key := readkey;
if (key = 'y') or (key = 'Y') then
begin
all_dark := 1;
ende := true
end
end;
'n','N' : begin
writeln('Are you sure that you want to make the whole map unknown ?');
key := readkey;
if (key = 'y') or (key = 'Y') then
begin
all_dark := 2;
ende := true
end
end;
'o','O' : improve := not improve;
'p','P' : begin counter := 0; improve := norm_impr;
exist := false end;
'q','Q' : begin
improve := norm_impr;
exist := false;
write ('Filename: ');
readln (fname);
{$I-}
assign (f, fname);
reset (f);
{$I+}
if ioresult <> 0 then
begin
writeln('Error by opening of file');
key := readkey
end
else
begin
counter := 0;
repeat
inc (counter);
readln(f, x[counter], y[counter]);
until eof(f);
ende := true;
close(f)
end;
end;
'r','R' : begin
improve := norm_impr;
exist := false;
write ('Filename: ');
readln (fname);
{$I-}
assign (f, fname);
rewrite (f);
{$I+}
if ioresult <> 0 then
begin
writeln('Error by opening of file');
key := readkey
end
else
begin
for i := 1 to counter do
writeln(f, x[i],' ',y[i]);
close(f)
end
end;
'x','X' : ende := true;
chr(0) : key := readkey;
end;
until ende;
{ calculate small map }
if (dark and dark_pos = 0) then sm_map := 0
else if landtype = 1 then sm_map := 1
else sm_map := 2;
{ store back the field properties }
mem[segm_data:off_land] := landtype;
mem[segm_data:off_smap] := sm_map;
mem[segm_data:off_attr1] := attr;
mem[segm_data:off_attr2] := attr;
mem[segm_dark:column*$32 + row + off_dark] := dark;
if not exist and (improve xor norm_impr) then
{ insert new line in improvement list }
if counter < maxlist then
begin
inc(counter);
x[counter] := column;
y[counter] := row;
end;
if exist and not (improve xor norm_impr) then
{ delete line in improvement list }
begin
for i := im_pos to counter-1 do
begin
x[i] := x[i+1];
y[i] := y[i+1];
end;
dec(counter);
end;
if all_dark = 1 then
{ mark all fields as known }
begin
for i := 0 to 3999 do
mem[segm_dark:off_dark+i] := mem [segm_dark:off_dark+i]
or dark_pos;
{change small map}
for i := 0 to 79 do
for j := 0 to 49 do
mem[segm_data:$f0+j*$140+i] :=
2-integer(mem [segm_data:j*$140+i] = 1);
end;
if all_dark = 2 then
{ make all fields dark }
begin
for i := 0 to 3999 do
mem[segm_dark:off_dark+i] := mem [segm_dark:off_dark+i]
and not dark_pos;
{change small map}
for i := 0 to 79 do
for j := 0 to 49 do
mem[segm_data:$f0+j*$140+i] := 0;
end;
if all_dark = 100 then
begin
clrscr;
writeln;
writeln ('Now the memory part which contains the informations of the map will be loaded.');
writeln ('For further informations see the .inf file');
writeln ('Warning: Only the file length will be checked ! When you load the wrong map,');
writeln (' unexpected errors can occur !');
writeln;
write ('Filename: ');
readln (fname);
fname := fname + chr(0);
{ copy file directly to memory; this costs the least memory }
{ open file }
regs.ds := seg(fname[1]);
regs.dx := ofs(fname[1]);
regs.ax := $3d42;
msdos(regs); {o.k. -> Carry flag, handle -> ax}
if regs.flags and 1 <> 0 then
begin
writeln('Error by file opening');
key := readkey
end
else
begin
{ get file length (file pointer to end of file) }
regs.bx := regs.ax;
regs.cx := 0;
regs.dx := 0;
regs.ax := $4202;
msdos (regs);
filelength := regs.dx * $10000 + regs.ax;
{ file pointer back to start }
regs.cx := 0;
regs.dx := 0;
regs.ax := $4200;
msdos (regs);
if (filelength <> 64000) and (filelength <> 68000) then
begin
writeln('Error: wrong filelength; is the filename correct ?');
key := readkey;
end
else
begin
{ read data }
regs.ds := segm_data;
regs.dx := 0;
regs.cx := $fa00; {number (all blocks; see .inf file)}
regs.ah := $3f;
msdos(regs);
if filelength = 68000 then
begin
writeln('Should the known <-> unknown informations be loaded, too ?');
repeat
key := readkey;
until key in ['y','Y','n','N'];
if (key = 'y') or (key = 'Y') then
begin
regs.ds := segm_dark;
regs.dx := off_dark;
regs.cx := $0fa0; {number (50*80 pieces)}
regs.ah := $3f;
msdos(regs);
end;
end;
{ close file }
regs.ah := $3e;
msdos(regs);
end
end
end;
if all_dark = 101 then
begin
clrscr;
writeln;
writeln ('Now the memory part which contains the informations of the map will be saved.');
writeln ('For further informations see the .inf file. This saves not the improvement list');
writeln ('Warning: Do not change the first 80 Bytes (otherwise the data search function');
writeln (' will not work) !!!');
writeln;
write ('Filename: ');
readln (fname);
fname := fname + chr(0);
{ copy memory directly to file; this costs the least memory }
{ open file }
regs.cx := 0;
regs.ds := seg(fname[1]);
regs.dx := ofs(fname[1]);
regs.ah := $3c;
msdos(regs); {o.k. -> Carry flag, handle -> ax}
if regs.flags and 1 <> 0 then
begin
writeln('Error by file opening');
key := readkey
end
else
begin
{ save data }
regs.bx := regs.ax;
regs.ds := segm_data;
regs.dx := 0;
regs.cx := $fa00; {number (all blocks; see .inf file)}
regs.ah := $40;
msdos(regs);
writeln('Should the known <-> unknown informations be saved, too ?');
repeat
key := readkey;
until key in ['y','Y','n','N'];
if (key = 'y') or (key = 'Y') then
begin
regs.ds := segm_dark;
regs.dx := off_dark;
regs.cx := $0fa0; {number (50*80 pieces)}
regs.ah := $40;
msdos(regs);
end;
{ close file }
regs.ah := $3e;
msdos(regs);
end
end;
end;
{ reset video mode }
regs.ah := 0;
regs.al := mode;
intr($10,regs);
{ restore colors }
regs.ax := $1012;
regs.bx := 0;
regs.cx := 256;
regs.es := seg(colorlist);
regs.dx := ofs(colorlist);
intr($10, regs);
end
end;
procedure switch_on; interrupt;
var mode : byte;
key : char;
begin
turn_on := not turn_on;
{ get colors }
regs.ax := $1017;
regs.bx := 0;
regs.cx := 256;
regs.es := seg(colorlist);
regs.dx := ofs(colorlist);
intr($10, regs);
{ get video mode }
regs.ah := $0f;
intr($10, regs);
mode := regs.al;
{ set video mode to 80*25 text }
regs.ah := 0;
regs.al := 03;
intr($10, regs);
textcolor(15);
clrscr;
writeln;
write('Map Changing Mode is turned ');
if turn_on then writeln('on')
else writeln('off');
key := readkey;
{ reset video mode }
regs.ah := 0;
regs.al := mode;
intr($10,regs);
{ restore colors }
regs.ax := $1012;
regs.bx := 0;
regs.cx := 256;
regs.es := seg(colorlist);
regs.dx := ofs(colorlist);
intr($10, regs);
end;
{$F-}
begin
writeln;
writeln ('Civilization Map Changer Version 2.1');
writeln ('(C) Sirius Cybernetics Corporations, Sirius Star System I-III');
writeln ('written by Holger Eichmann');
writeln('Copying and code changing strictly allowed! No rights reserved!');
writeln;
writeln('To use this tool you have to change the following bytes in civ.exe:');
writeln('version 1 + 2(?): E9 54 00 B8 32 00 -> E9 54 00 CD F1 90');
writeln('version 3 + 4: 02 75 53 B8 32 00 -> 02 75 53 CD F1 90');
writeln('version 5: E9 59 00 B8 32 00 -> E9 59 00 CD F1 90');
writeln('all versions: 3B C1 75 BB B8 01 00 -> CD F2 90 90 90 90 90');
writeln;
writeln('Press ''Print Screen'' to turn Map Changer on/off.');
writeln;
turn_on := false;
for i := 1 to maxlist do
begin
x[i] := $ffff;
y[i] := $ffff
end;
counter := 0;
setintvec($05, @switch_on);
setintvec($f1, @editor);
setintvec($f2, @civint2);
keep(0)
end.