I've imported the file into paint (windows 10 version), and exported it with every different option and tried it, but it hasn't worked. I've also tried renaming the ".bmp" extension to both ".BMP" and ".BM" (don't ask why, I don't know), but I only did this with one file not with every version paint outputs. I've also tested in game (both classic and Unity) to see if it does actually change anything, again with just one version of the file, and it didn't. I know nothing about programming but could this bit of the code (presumably, i'm not sure if it actually reads this file or if it's all contained in the exe) be the problem?*filename*.bmp is not a valid BMP file"
Specifically the part saying:
Code: Select all
else if (BMHead.ID <> 'BM') then
writeln(FNbuf, ' is not a valid BMP file!')
More of the code:
Code: Select all
IDNO: begin // BMP -> SmallMap
FNbuf[1] := #0;
BMPOFN.lpstrTitle := LoadSmallBMPTitle;
BMPOFN.Flags := OFN_EXPLORER + OFN_FILEMUSTEXIST + OFN_HIDEREADONLY;
if GetOpenFileName(@BMPOFN) then
begin
BMP[SmallMap, 1] := CreateFile(@FNbuf, (GENERIC_READ + GENERIC_WRITE), FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, 0);
if (BMP[SmallMap, 1] = INVALID_HANDLE_VALUE) then
writeln('Error ', GetLastError, ' opening ', FNbuf, '!')
else
begin
write('Importing ', FNbuf, '...');
ReadFile(BMP[SmallMap, 1], BMHead, SizeOf(BMHead), BytesRead, 0);
SetFilePointer(BMP[SmallMap, 1], BMHead.Offset, 0, FILE_BEGIN);
if not ReadFile(BMP[SmallMap, 1], BMHead, SizeOf(BMHead), BytesRead, 0) then
writeln('Error ', GetLastError, ' reading WLD header!')
else if (BMHead.ID <> 'BM') then
writeln(FNbuf, ' is not a valid BMP file!')
else if (BMHead.Compress <> 0) then
writeln('BMP is compressed!')
else if (BMHead.BitCount <> 8) then
writeln('BMP is the wrong color depth!')
else if (BMHead.Width <> Header.Width) then
writeln('Width of BMP is not equal to ', Header.Width, '!')
else if (BMHead.Height <> Header.Height) then
writeln('Height of BMP is not equal to ', Header.Height, '!')
else if (Header.Width < SizeOf(buf)) then
for Y := (Header.Height - 1) downto 0 do
begin
ReadFile(BMP[SmallMap, 1], buf, Header.Width, BytesRead, 0);
if ((BytesRead mod 4) > 0) and (Y > 0) then // BMP is padded to 32-bit boundary
SetFilePointer(BMP[SmallMap, 1], (4 - (BytesRead mod 4)), 0, FILE_CURRENT);
Z := (Y * Header.Width) + Header.SmallMapOffset;
SetFilePointer(WLD, Z, 0, FILE_BEGIN);
WriteFile(WLD, buf, BytesRead, BytesWritten, 0);
end
else
writeln('We''re going to need a bigger boat.');
CloseHandle(BMP[SmallMap, 1]);
writeln('Done!');
The full code:
Code: Select all
program woods;
uses Windows;
const
VerData = ' WLDThing v3.00 beta 2 ';
WLDFilter: packed array[1..17] of char = (
'W', 'O', 'O', 'D', 'S', '.', 'W', 'L', 'D', #0, '*', '.', 'W', 'L', 'D', #0,
#0);
OpenWLDTitle: pchar = 'Open WOODS.WLD';
BMPFilter: packed array[1..28] of char = (
'B', 'i', 't', 'm', 'a', 'p', ' ', 'f', 'i', 'l', 'e', 's', ' ', '(', '*', '.', 'b', 'm', 'p', ')', #0, '*', '.', 'B', 'M', 'P', #0,
#0);
BMPDefExt: pchar = 'BMP';
BMPTitle : array[0..5, 0..1] of pchar = (
('Export SmallMap BMP', 'Import SmallMap BMP'),
('Export Number1 BMP', 'Import Number1 BMP'),
('Export ClimateType BMP', 'Import ClimateType BMP'),
('Export LandType BMP', 'Import LandType BMP'),
('Export LandHeight BMP', 'Import LandHeight BMP'),
('Export LargeMap BMP', 'Import LargeMap BMP')
);
SaveSmallBMPTitle: pchar = 'Export SmallMap BMP';
LoadSmallBMPTitle: pchar = 'Import SmallMap BMP';
GenericBMPIOConfirmation: pchar = 'Do you wish to export this data to a BMP file?' + #10 + 'Choose ''No'' to import data instead, or ''Cancel'' to skip.';
// BMP handle indices
SmallMap = 0;
Number1 = 1;
ClimateType = 2;
LandType = 3;
LandHeight = 4;
LargeMap = 5;
type
TWLDHeader = packed record
OffsetSize: longword;
Width: longword;
Height: longword;
NullValue: longword;
Data1Offset: longword;
Unknown1: longword;
Unknown2: longword;
SmallMapOffset: longword;
NullValues: array[1..28] of longword;
end;
TWLDLMData = packed record
Number1: word;
NullValue1: longword;
ClimateType: word; // Terrain texture file number
LandType: byte; // Temperate, Mountain, Desert
LandHeight: byte;
NullValues: array[1..3] of longword;
MapData: packed array[0..4,0..4] of byte;
end;
TLazyRGBQuad = packed record
B: byte;
G: byte;
R: byte;
O: byte; // Always 0
end;
TLazyBMPFileHeader = packed record
// BITMAPFILEHEADER
ID: packed array[1..2] of char; // BM
FileSize: longword; // DataSize + Offset
Res1: word;
Res2: word;
Offset: longword; // 1078
// BITMAPINFO <CORE>
IHSize: longword; // 40
Width: longword;
Height: longword;
Planes: word; // 1
BitCount: word; // 8
// </CORE>
Compress: longword;
DataSize: longword; // Width * Height
XPxPerMeter: longword;
YPxPerMeter: longword;
Colors: longword; // 256
IColors: longword; // 256
// bmiColors
Palette: array[0..255] of TLazyRGBQuad;
end;
TLazierBMPHeader = packed record
ID: packed array[1..2] of char;
FileSize: longword;
Res1: word;
Res2: word;
Offset: longword;
IHSize: longword;
Width: longword;
Height: longword;
Planes: word;
BitCount: word; // 8
Compress: longword;
DataSize: longword;
end;
var
WLD: HANDLE;
BMP: array[0..5, 0..1] of HANDLE;
Importing, Exporting: array[0..5] of boolean;
ImportingAnything, ExportingAnything: boolean;
WLDOFN, BMPOFN: OPENFILENAME;
FNbuf: array[1..320] of char;
Header: TWLDHeader;
BMPHeader: TLazyBMPFileHeader; // Standard header, for saving
BMHead: TLazierBMPHeader; // Bare essentials, for loading purposes
X, Y, Z, BytesRead, BytesWritten: longword;
LMOffset: ^longword;
LMData: TWLDLMData;
buf: array[1..2048] of byte;
i, j: word;
begin
writeln(#201, StringOfChar(#205, length(VerData)), #187);
writeln(#186, VerData, #186);
writeln(#200, StringOfChar(#205, length(VerData)), #188);
// Skip this if command line gives a filename?
WLDOFN.lStructSize := sizeof(WLDOFN);
WLDOFN.lpstrFilter := @WLDFilter;
WLDOFN.lpstrFile := @FNbuf;
WLDOFN.nMaxFile := sizeof(FNbuf);
WLDOFN.lpstrTitle := OpenWLDTitle;
WLDOFN.Flags := OFN_EXPLORER + OFN_FILEMUSTEXIST + OFN_HIDEREADONLY;
if GetOpenFileName(@WLDOFN) then
writeln('Loading ', FNbuf, '...')
else // We have no WOODS.WLD to edit.
exit;
WLD := CreateFile(@FNbuf, (GENERIC_READ + GENERIC_WRITE), FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, 0);
if (WLD = INVALID_HANDLE_VALUE) then
begin
writeln('Error ', GetLastError, ' opening ', FNbuf, '!');
exit;
end;
if not ReadFile(WLD, Header, SizeOf(Header), BytesRead, 0) then
begin
writeln('Error ', GetLastError, ' reading WLD header!');
exit;
end;
writeln;
writeln('Header info:');
writeln(' OffsetSize: ', Header.OffsetSize);
writeln(' Width: ', Header.Width);
writeln(' Height: ', Header.Height);
writeln(' NullValue: ', Header.NullValue);
writeln(' Data1Offset: ', Header.Data1Offset);
writeln(' Unknown1: ', Header.Unknown1);
writeln(' Unknown2: ', Header.Unknown2);
writeln(' SmallMapOffset: ', Header.SmallMapOffset);
writeln;
GetMem(LMOffset, (Header.Width * 4));
// These never change, so init them here and forget about them:
BMPOFN.lStructSize := sizeof(BMPOFN);
BMPOFN.lpstrFilter := @BMPFilter;
BMPOFN.lpstrFile := @FNbuf;
BMPOFN.nMaxFile := SizeOf(FNbuf);
BMPOFN.lpstrDefExt := BMPDefExt;
BMPHeader.ID := 'BM';
BMPHeader.Offset := SizeOf(BMPHeader);
BMPHeader.IHSize := 40;
BMPHeader.Planes := 1;
BMPHeader.BitCount := 8;
BMPHeader.XPxPerMeter := 2835;
BMPHeader.YPxPerMeter := 2835;
BMPHeader.Colors := 256;
BMPHeader.IColors := 256;
for i := 0 to 255 do // Greyscale palette
begin
BMPHeader.Palette[i].R := i;
BMPHeader.Palette[i].G := i;
BMPHeader.Palette[i].B := i;
end;
// ***************************************************************************
// ******************************* SmallMap IO *******************************
// ***************************************************************************
case MessageBox(0, GenericBMPIOConfirmation, SaveSmallBMPTitle, MB_YESNOCANCEL) of
IDYES: begin // SmallMap -> BMP
FNbuf := 'smallmap.bmp';
BMPOFN.lpstrTitle := SaveSmallBMPTitle;
// I'm going to go out on a limb here and assume that there's
// no need to specify OFN_HIDEREADONLY for save dialogs.
BMPOFN.Flags := OFN_EXPLORER + OFN_OVERWRITEPROMPT;
if GetSaveFileName(@BMPOFN) then
begin
BMP[SmallMap, 0] := CreateFile(@FNbuf, (GENERIC_READ + GENERIC_WRITE), 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, 0);
if (BMP[SmallMap, 0] = INVALID_HANDLE_VALUE) then
writeln('Error ', GetLastError, ' creating ', FNbuf, '!')
else
begin
write('Writing ', FNbuf, '...');
BMPHeader.Width := Header.Width;
BMPHeader.Height := Header.Height;
BMPHeader.DataSize := BMPHeader.Width * BMPHeader.Height;
BMPHeader.FileSize := BMPHeader.DataSize + BMPHeader.Offset;
if not WriteFile(BMP[SmallMap, 0], BMPHeader, SizeOf(BMPHeader), BytesWritten, 0) then
writeln('Error ', GetLastError, ' writing BMP header!')
else if (Header.Width < SizeOf(buf)) then
for Y := (Header.Height - 1) downto 0 do
begin
Z := (Y * Header.Width) + Header.SmallMapOffset;
SetFilePointer(WLD, Z, 0, FILE_BEGIN);
ReadFile(WLD, buf, Header.Width, BytesRead, 0);
if ((BytesRead mod 4) > 0) then inc(BytesRead, 4 - (BytesRead mod 4));
WriteFile(BMP[SmallMap, 0], buf, BytesRead, BytesWritten, 0);
end
else // This will never happen with the original files, but I like Finagle-proofing.
writeln('We''re going to need a bigger boat.');
CloseHandle(BMP[SmallMap, 0]);
writeln('Done!');
end;
end;
end;
IDNO: begin // BMP -> SmallMap
FNbuf[1] := #0;
BMPOFN.lpstrTitle := LoadSmallBMPTitle;
BMPOFN.Flags := OFN_EXPLORER + OFN_FILEMUSTEXIST + OFN_HIDEREADONLY;
if GetOpenFileName(@BMPOFN) then
begin
BMP[SmallMap, 1] := CreateFile(@FNbuf, (GENERIC_READ + GENERIC_WRITE), FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, 0);
if (BMP[SmallMap, 1] = INVALID_HANDLE_VALUE) then
writeln('Error ', GetLastError, ' opening ', FNbuf, '!')
else
begin
write('Importing ', FNbuf, '...');
ReadFile(BMP[SmallMap, 1], BMHead, SizeOf(BMHead), BytesRead, 0);
SetFilePointer(BMP[SmallMap, 1], BMHead.Offset, 0, FILE_BEGIN);
if not ReadFile(BMP[SmallMap, 1], BMHead, SizeOf(BMHead), BytesRead, 0) then
writeln('Error ', GetLastError, ' reading WLD header!')
else if (BMHead.ID <> 'BM') then
writeln(FNbuf, ' is not a valid BMP file!')
else if (BMHead.Compress <> 0) then
writeln('BMP is compressed!')
else if (BMHead.BitCount <> 8) then
writeln('BMP is the wrong color depth!')
else if (BMHead.Width <> Header.Width) then
writeln('Width of BMP is not equal to ', Header.Width, '!')
else if (BMHead.Height <> Header.Height) then
writeln('Height of BMP is not equal to ', Header.Height, '!')
else if (Header.Width < SizeOf(buf)) then
for Y := (Header.Height - 1) downto 0 do
begin
ReadFile(BMP[SmallMap, 1], buf, Header.Width, BytesRead, 0);
if ((BytesRead mod 4) > 0) and (Y > 0) then // BMP is padded to 32-bit boundary
SetFilePointer(BMP[SmallMap, 1], (4 - (BytesRead mod 4)), 0, FILE_CURRENT);
Z := (Y * Header.Width) + Header.SmallMapOffset;
SetFilePointer(WLD, Z, 0, FILE_BEGIN);
WriteFile(WLD, buf, BytesRead, BytesWritten, 0);
end
else
writeln('We''re going to need a bigger boat.');
CloseHandle(BMP[SmallMap, 1]);
writeln('Done!');
end;
end;
end;
end;
// ***************************************************************************
// ******************************* LargeMap IO *******************************
// ***************************************************************************
for i := 3 to 5 do
case MessageBox(0, GenericBMPIOConfirmation, BMPTitle[i, 0], MB_YESNOCANCEL) of
IDYES: begin
case i of
SmallMap: FNbuf := 'smallmap.bmp';
Number1: FNbuf := 'number1.bmp';
ClimateType: FNbuf := 'climate.bmp';
LandType: FNbuf := 'landtype.bmp';
LandHeight: FNbuf := 'lmheight.bmp';
LargeMap: FNbuf := 'largemap.bmp';
end;
BMPOFN.lpstrTitle := BMPTitle[i, 0];
BMPOFN.Flags := OFN_EXPLORER + OFN_OVERWRITEPROMPT;
if GetSaveFileName(@BMPOFN) then
begin
BMP[i, 0] := CreateFile(@FNbuf, (GENERIC_READ + GENERIC_WRITE), 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, 0);
if (BMP[i, 0] = INVALID_HANDLE_VALUE) then
writeln('Error ', GetLastError, ' creating ', FNbuf, '!')
else
begin
write('Writing BMP header to ', FNbuf, '...');
BMPHeader.Width := Header.Width;
BMPHeader.Height := Header.Height;
if (i = LargeMap) then
begin
BMPHeader.Width := BMPHeader.Width * 5;
BMPHeader.Height := BMPHeader.Height * 5;
end;
BMPHeader.DataSize := BMPHeader.Width * BMPHeader.Height;
BMPHeader.FileSize := BMPHeader.DataSize + BMPHeader.Offset;
if (i = LandType) then
begin
BMPHeader.Palette[0].R := 0;
BMPHeader.Palette[0].G := 128;
BMPHeader.Palette[0].B := 0;
BMPHeader.Palette[1].R := 128;
BMPHeader.Palette[1].G := 128;
BMPHeader.Palette[1].B := 128;
BMPHeader.Palette[2].R := 255;
BMPHeader.Palette[2].G := 255;
BMPHeader.Palette[2].B := 0;
end;
if not WriteFile(BMP[i, 0], BMPHeader, SizeOf(BMPHeader), BytesWritten, 0) then
writeln('Error ', GetLastError, ' writing BMP header!')
else
Exporting[i] := true;
if (i = LandType) then
for j := 0 to 3 do
begin // Undo palette changes
BMPHeader.Palette[j].R := j;
BMPHeader.Palette[j].G := j;
BMPHeader.Palette[j].B := j;
end;
if not Exporting[i] then
CloseHandle(BMP[i, 0])
else
writeln('Done!');
end;
end;
end;
IDNO: begin
FNbuf[1] := #0;
BMPOFN.lpstrTitle := BMPTitle[i, 1];
BMPOFN.Flags := OFN_EXPLORER + OFN_FILEMUSTEXIST + OFN_HIDEREADONLY;
if GetOpenFileName(@BMPOFN) then
begin
BMP[i, 1] := CreateFile(@FNbuf, (GENERIC_READ + GENERIC_WRITE), FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, 0);
if (BMP[i, 1] = INVALID_HANDLE_VALUE) then
writeln('Error ', GetLastError, ' opening ', FNbuf, '!')
else
begin
write('Reading ', FNbuf, ' header...');
ReadFile(BMP[i, 1], BMHead, SizeOf(BMHead), BytesRead, 0);
SetFilePointer(BMP[i, 1], BMHead.Offset, 0, FILE_BEGIN);
if not ReadFile(BMP[i, 1], BMHead, SizeOf(BMHead), BytesRead, 0) then
writeln('Error ', GetLastError, ' reading WLD header!')
else if (BMHead.ID <> 'BM') then
writeln(FNbuf, ' is not a valid BMP file!')
else if (BMHead.Compress <> 0) then
writeln('BMP is compressed!')
else if (BMHead.BitCount <> 8) then
writeln('BMP is the wrong color depth!')
else if (i = LargeMap) and (BMHead.Width <> (Header.Width * 5)) then
writeln('Width of BMP is not equal to ', (Header.Width * 5), '!')
else if (i = LargeMap) and (BMHead.Height <> (Header.Height * 5)) then
writeln('Height of BMP is not equal to ', (Header.Height * 5), '!')
else if (i <> LargeMap) and (BMHead.Width <> Header.Width) then
writeln('Width of BMP is not equal to ', Header.Width, '!')
else if (i <> LargeMap) and (BMHead.Height <> Header.Height) then
writeln('Height of BMP is not equal to ', Header.Height, '!')
else
Importing[i] := true;
if not Importing[i] then
CloseHandle(BMP[i, 1])
else
writeln('Done!');
end;
end;
end;
end;
writeln;
ImportingAnything := Importing[Number1] or Importing[ClimateType] or Importing[LandType] or Importing[LandHeight] or Importing[LargeMap];
ExportingAnything := Exporting[Number1] or Exporting[ClimateType] or Exporting[LandType] or Exporting[LandHeight] or Exporting[LargeMap];
if ImportingAnything or ExportingAnything then
begin
write('Reading and writing LM data...');
if Importing[LargeMap] or Exporting[LargeMap] then
begin // Make LargeMap BMP offset calculations less of a pain in the ass
BMPHeader.Height := Header.Height * 5;
BMPHeader.Width := Header.Width * 5;
if BMPHeader.Width mod 4 > 0 then // BMP is padded to 32-bit boundary
inc(BMPHeader.Width, (4 - (BMPHeader.Width mod 4)));
end;
for Y := (Header.Height - 1) downto 0 do
begin
Z := SizeOf(Header) + (Y * (Header.Width * 4));
SetFilePointer(WLD, Z, 0, FILE_BEGIN);
ReadFile(WLD, LMOffset^, (Header.Width * 4), BytesRead, 0);
for X := 0 to (Header.Width - 1) do
begin
SetFilePointer(WLD, LMOffset[X], 0, FILE_BEGIN);
ReadFile(WLD, LMData, SizeOf(LMData), BytesRead, 0);
// Export old data
if Exporting[LargeMap] then
for i := 4 downto 0 do
begin
Z := SizeOf(BMPHeader) + (((BMPHeader.Height - 1) - ((Y * 5) + i)) * BMPHeader.Width) + (X * 5);
SetFilePointer(BMP[LargeMap, 0], Z, 0, FILE_BEGIN);
WriteFile(BMP[LargeMap, 0], LMData.MapData[i], 5, BytesWritten, 0)
end;
if Exporting[LandType] then
WriteFile(BMP[LandType, 0], LMData.LandType, 1, BytesWritten, 0);
if Exporting[LandHeight] then
WriteFile(BMP[LandHeight, 0], LMData.LandHeight, 1, BytesWritten, 0);
if ImportingAnything then
begin // Read new data into LMData struct
if Importing[LargeMap] then
for i := 4 downto 0 do
begin
Z := SizeOf(BMPHeader) + (((BMPHeader.Height - 1) - ((Y * 5) + i)) * BMPHeader.Width) + (X * 5);
SetFilePointer(BMP[LargeMap, 1], Z, 0, FILE_BEGIN);
ReadFile(BMP[LargeMap, 1], LMData.MapData[i], 5, BytesRead, 0)
end;
if Importing[LandType] then
begin
ReadFile(BMP[LandType, 1], LMData.LandType, 1, BytesRead, 0);
if (LMData.LandType > 2) then LMData.LandType := 0;
end;
if Importing[LandHeight] then
ReadFile(BMP[LandHeight, 1], LMData.LandHeight, 1, BytesRead, 0);
// Write modified LMData to WLD
SetFilePointer(WLD, LMOffset[X], 0, FILE_BEGIN);
WriteFile(WLD, LMData, SizeOf(LMData), BytesWritten, 0);
end;
end;
if ((Header.Width mod 4) > 0) then
for i := 1 to 4 do
begin // BMP is padded to 32-bit boundary
if Exporting[i] then
SetFilePointer(BMP[i, 0], (4 - (Header.Width mod 4)), 0, FILE_CURRENT);
if Importing[i] then
SetFilePointer(BMP[i, 1], (4 - (Header.Width mod 4)), 0, FILE_CURRENT);
end;
end;
for i := 1 to 5 do
begin
if Exporting[i] then
CloseHandle(BMP[i, 0]);
if Importing[i] then
CloseHandle(BMP[i, 1]);
end;
writeln('Done!');
end;
CloseHandle(WLD);
FreeMem(LMOffset, (Header.Width * 4));
end.