Code:
procedure readsprites;
var h, i : integer; num : word;
data: array[0..10239] of byte;
tam, n, s, c, r, g, b, y, x,SpriteCount : integer;
t : boolean;
bmp : graphics.tbitmap;
bi : bitmapinfo; // como no editor de fandoras... para economizar velocidade e memoria
bmpdata : array[0..3071] of byte;
buffer : Array of Byte;
f : file of Byte;
b_end, b_last, b_div : Cardinal;
fo : Integer;
c_size, c_count, c_lists : Integer;
procedure initil;
var il : TImageList;
begin
inc(nvimgs);
if vimgs[nvimgs] <> nil then begin
il := vimgs[nvimgs];
vimgs[nvimgs] := nil;
il.Free;
end;
vimgs[nvimgs] := TImageList.Create(nil);
vimgs[nvimgs].AllocBy := 10;
vimgs[nvimgs].Width := 32;
vimgs[nvimgs].Height := 32;
vimgs[nvimgs].BlendColor := clnone;
vimgs[nvimgs].BkColor := clnone;
vimgs[nvimgs].Masked := true;
end;
begin
// verifica se o arquivo existe
if not fileexists( extractfilepath(paramstr(0)) + 'Tibia.spr') then begin
MessageBox(0,'Tibia.spr not found! Exiting...','Ooops',0);
Exit;
end;
assignfile(f, extractfilepath(paramstr(0)) + 'tibia.spr');
try
reset(f);
except
MessageBox(0,'Could not open Tibia.spr','Open Tibia',0);
exit
end;
{$R-}
b_end := FileSize(f);
configfile:= tinifile.Create(extractfilepath(paramstr(0))+'otclient.ini');
c_size := 99999;
c_lists := 99999;
c_count := 99999;
c_size := configfile.ReadInteger('SpriteCache','cachesize',99999);
c_count := configfile.ReadInteger('SpriteCache','cachecount',99999);
c_lists := configfile.ReadInteger('SpriteCache','cachelists',99999);
if (c_size <> 99999) and (c_count <> 99999) and (c_lists <> 99999)
and (c_size = b_end) then begin
for i := 1 to c_lists do begin
if FileExists(extractfilepath(paramstr(0)) + 'Cache\' + IntToStr(b_end) + '\SpriteCache' + IntToStr(i) + '.bin') then
vimgs[i] := ReadComponentResfile(extractfilepath(paramstr(0)) + 'Cache\' + IntToStr(b_end) + '\SpriteCache' + IntToStr(i) + '.bin', vimgs[i]) as TImageList
else begin
MessageBox(0,'Could not find SpriteCache files, Please restart.','Open Tibia',0);
configfile.WriteInteger('SpriteCache','cachesize', 0);
exit;
end;
end;
nvimgs := c_lists;
SpriteCount := c_count;
end
else
begin
//prepara o primeiro imagelist
nvimgs := 0;
initil;
// prepara o bitmap q servirá de via entre o bmpdata e o il
bmp := graphics.tbitmap.Create;
bmp.PixelFormat := pf24bit;
bmp.Height := 32;
bmp.Width := 32;
bmp.Canvas.Brush.Color := clblack;
// carrega o sprite file
b_last := 0;
SetLength(buffer, b_end);
blockread(f, buffer[0], b_end, b_end);
num := buffer[4] or buffer[5] shl 8;
{$IFDEF DEBUG}
showmessage('Num sprites: ' + inttostr(num));
{$ENDIF}
// pega todos os sprites
i := 0;
while i < num do begin
//a := 6 + i * 4;
if (i >= (b_last+(num div 100))) then begin
b_last := i;
end;
fo := buffer[6 + i * 4] or buffer[(6 + i * 4)+1] shl 8 or buffer[(6 + i * 4)+2] shl 16 or buffer[(6 + i * 4)+3] shl 24;
// fo = imagem vazia
if fo = 0 then begin
inc(i,1);
bmp.Canvas.FillRect( rect(0,0,32,32) );
if vimgs[nvimgs].Count = MAX_IMAGES_PER_IL then initil;
if vimgs[nvimgs].AddMasked(bmp, clblack ) = -1 then
messagebox(0,Pansichar(format('error at addmask (sprload): %d (wme?)',[i])),'Open Tibia',0);
continue;
end;
tam := buffer[fo+3] or buffer[fo+4] shl 8;
n := 0;
s := 0;
c := 0;
r := 0;
g := 0;
b := 0;
t := false;
fillchar(bmpdata,3072,0); // pinta de preto
// carrega cada pixel
y := 0;
while y < 32 do begin
x := 0;
while x < 32 do begin
// o inicio, quando nao há pixels
// pr fandoras:
// s = pixels transparentes
// c = o numero de pixels na imagem
// t = controla se o pixel é transparente ou nao
if (s = 0) and (c = 0) then begin
s := buffer[fo+5+n];
inc(n,1);
s := s + (buffer[fo+5+n] * 256);
inc(n,1);
c := buffer[fo+5+n];
inc(n,1);
c := c + (buffer[fo+5+n] * 256);
inc(n,1);
end;
if (s <> 0) or (n >= tam) then begin
r := 0; g := 0; b := 0;
t := false;
if s <> 0 then dec(s,1);
end else
if c <> 0 then begin
// fandoras sugeriu usar max() ao chamar cada cor do sistema rgb ;D
// assim, valores menores que 8 n passam, deixando o preto real para transparencias
r := max(8,buffer[fo+5+n]);
inc(n,1);
g := max(8,buffer[fo+5+n]);
inc(n,1);
b := max(8,buffer[fo+5+n]);
inc(n,1);
dec(c,1);
t := true;
end;
if t then begin
// se n for transparente pinta
bmpdata[(31-y)*96+x*3] := b;
bmpdata[(31-y)*96+x*3+1] := g;
bmpdata[(31-y)*96+x*3+2] := r;
bmp.Canvas.Pixels[x,y] := rgb(r,g,b);
end;
inc(x,1);
end;
inc(y,1);
end;
// estrutura para carregar o bmpdata
bi.bmiHeader.biSize := sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth := 32;
bi.bmiHeader.biHeight := 32;
bi.bmiHeader.biPlanes := 1;
bi.bmiHeader.biBitCount := 24;
bi.bmiHeader.biCompression := BI_RGB;
bi.bmiHeader.biSizeImage := 0;
bi.bmiHeader.biXPelsPerMeter := 32;
bi.bmiHeader.biYPelsPerMeter := 32;
bi.bmiHeader.biClrUsed := 0;
bi.bmiHeader.biClrImportant := 0;
SetDIBitsToDevice(bmp.Canvas.Handle,0,0,32,32,0,0,0,32,@bmpdata,bi,dib_rgb_colors);
// se estiver cheio cria um novo il
if vimgs[nvimgs].Count = MAX_IMAGES_PER_IL then initil;
if vimgs[nvimgs].AddMasked(bmp, clblack ) = -1 then
messagebox(0,Pansichar(format('error at addmask (sprload): %d (wme?)',[i])),'Open Tibia',0);
inc(SpriteCount);
inc(i,1);
end;
if not DirectoryExists('Cache') then
mkdir('Cache');
if not DirectoryExists('Cache\' + IntToStr(b_end)) then
mkdir('Cache\' + IntToStr(b_end));
for i := 1 to nvimgs do begin
WriteComponentResfile(extractfilepath(paramstr(0)) + 'Cache\' + IntToStr(b_end) + '\SpriteCache' + IntToStr(i) + '.bin', vimgs[i]);
end;
configfile.WriteInteger('spritecache','cachesize',b_end);
configfile.WriteInteger('spritecache','cachecount',spritecount);
configfile.WriteInteger('spritecache','cachelists',nvimgs);
end; // SpriteCache
closefile(f);
bmp.Free;
end;