Arsip: Error Setelah pakai fungsi Scanline. (Map Editor u/ NexusTK)
                
                   more 18 years ago
                  
              coolmib
Dear All,
Saya sedang coba membuat Map Editor game NexusTK u/ client versi 5.33
semua sprite disimpan dlm 1 file yg ukurannya mencapai 33.1MB bernama tile.Dat
secara garis besar terdiri dari 3 jenis yaitu : 
- Tile A (28551 tile)
- Tile C (29414 tile)
- Object (dibangun dari sprite2 yg ada di tile-C, terdiri dari 12696 object)
Tahap pertama saya ingin menampilkan semua tile beserta Object2 yg ada.
khusus Tile-A dan tile-C sudah berjalan dgn baik, kecuali Object yg masih ada error
tahap berikutnya, membaca dan menampilkan gambar map yg sesungguhnya dari
file .map atau  .cmp (blm dicoding), dari pengamatan saya saat loading windows tile maupun object
kerasa sekali lambatnya, apalagi jika jml spritenya dibesarin. Dari nasehat beberapa 
rekan menyaran u/ mengantikan fungsi pixel dgn scanline, sayang saat mengunakan fungsi Scanline muncul error "Access Violation" yg sampai saat ini saya gak tau dimana
letak kesalahannya. Ada yg bisa kasih petunjuk ?? (masih byk pertanyaan, cuman u/ saat
ini, ini yg lbh penting) Berikut adalah Code Library pembacaan file Tile.Dat
[code:1:79bf6e1814]{ Thanks to Erik |Silo| Roger
  any comments/suggestions
  can email me at [email protected]
  Ver. 1.0a
}
unit DATLIB;
interface
Uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;
CONST
  PixelCountMax = 32768;
TYPE
  TRGBTripleArray = ARRAY[0..PixelCountMax-1] OF TRGBTriple;
  pRGBTripleArray = ^TRGBTripleArray;
    
Type TFileToC = record
     StartAddress : integer;
     Filename     : String;
end;
type RGBData = record
     RGB : Cardinal;
     Alpha : word;
end;
type tEPFHeader = record
     frameCount     : word;
     canvasHeight   : Word;
     canvasWidht    : Word;
     UnknownVar     : Word;
     TocOffset      : integer;
end;
Type tFrameHdr = record
     Data : array of array of byte;
     left : Smallint ;
     top  : Smallint;
     Height : Smallint;
     Width : Smallint;
     Table1 : Byte;
     Table2 : Byte;
     Loaded : Boolean;
end;
type tTilePAL = record
     TileType : Char;
     index : byte;
     TilePal: array of array [0..255] of RGBData;
end;
type tObj = record
     BlockType : Byte;
     Height : byte;
     Tile : array of word;
end;
  Procedure ReadPALfile(var SetPal:tTilePAL;StartAddress : Integer);
  Procedure ReadEPFHeader(var setEPFH:tEPFHeader;StartAddress : Integer);
  Function GetFileOffset(strFile:String) : Integer;
  Procedure LoadBitMapIndex(Index:Word;strFile:String;uEPFH:tEPFHeader;SetPal:tTilePAL);
  Procedure LoadBitMapIndexSJ(var ibitmap : tbitmap; Index:Word;strFile:String;uEPFH:tEPFHeader;SetPal:tTilePAL);
  Procedure ReadEPFFile(Index:Word; strFile:String; uEPFH:tEPFHeader);
  Procedure ReadTBLFile(Index:Word; strFile:String; uEPFH:tEPFHeader);
  Procedure ReadsObj;
Var FileToc : array of TFileToC;
    TotalFile : integer;
    FileSrc : string;
    FileName:String;
    Dat,Map  : TFileStream;
    imageFrame : tFrameHdr;
    Canvas : array of tFrameHdr;
    EPFHeader,TileAEPFHeader,TileCEPFHeader : tEPFHeader;
    PalPub,PalA, PalC : tTilePAL;
    BitMap:TBitmap;
    PalARGBData : array of array [0..255] of RGBData;
    sObj : array of tObj;
implementation
Function GetFileOffset(strFile:String) : Integer;
Var i : word;
    j : Integer;
begin
   j :=-1;
   for i := 0 to high(fileToc) do begin
       if (UpperCase(strFile) = UpperCase(fileToc[i].Filename)) then begin
          j := filetoc[i].StartAddress;
          break;
       end;
   end;
   result := j;
end;
Procedure ReadsObj;
var i,objCount : word;
    StartOff : Integer;
    j : Byte;
begin
   StartOff:=GetFileOffset('SObj.tbl');
   dat.Seek(StartOff,soBeginning);
   dat.Read(objCount,4);
   setLength(sObj,objCount);
   sObj[0].Height := 0;
   sObj[0].BlockType := 0;
   dat.Seek(7,soCurrent);
   for i:= 1 to objCount-1 do begin
       dat.Read(sObj[i].BlockType,1);
       dat.Read(sObj[i].Height,1);
       SetLength(sObj[i].Tile,sObj[i].Height);
       for j:= 0 to  sObj[i].Height -1 do begin
           dat.Read(sObj[i].Tile[j],2);
       end;
       dat.Seek(5,soCurrent);
   end;
end;
Procedure ReadPALFile(var SetPal:tTilePAL;StartAddress : Integer);
var i,j,k : word;
    lngCheck : longword;
    bytCheck : byte;
    bRed, bGreen, bBlue : byte;
begin
    dat.Seek(StartAddress,soBeginning);
    dat.Read(j,4);
    setlength(setpal.TilePal ,j);
     for k := 0 to j -1 do begin
         repeat
            dat.Read(lngCheck,4);
            dat.seek(-3,soCurrent);
         until lngCheck = 1632652356;
         dat.Seek(23,soCurrent);
         dat.Read(bytCheck ,1);
         if bytCheck = 3 then
            dat.seek(13,soCurrent)
         else if bytCheck = 1 then
            dat.Seek(9,soCurrent)
         else
            dat.Seek(7,soCurrent);
         for i := 0 to 255 do begin
             dat.Read(bRed,1);
             dat.Read(bGreen,1);
             dat.Read(bBlue,1);
             SetPal.TilePal[k,i].RGB := RGB(bRed,bGreen,bBlue);
             dat.Read(setpal.TilePal[k,i].alpha,1);
         end;
     end;
end;
Procedure ReadEPFHeader(var setEPFH:tEPFHeader; StartAddress : Integer);
begin
     dat.Seek(StartAddress,soBeginning);
     dat.Read(setEPFH.frameCount,2);
     dat.Read(setEPFH.canvasWidht,2);
     dat.Read(setEPFH.canvasHeight,2);
     dat.Read(setEPFH.UnknownVar,2);
     dat.Read(setEPFH.TocOffset,4);
     SetLength(Canvas,setEPFH.frameCount); 
end;
Procedure ReadEPFFile(Index:Word; strFile:String; uEPFH:tEPFHeader);
Var
   iTop,iLeft, iRight, iBottom : Smallint;
   fiStartOff, startOff,endOff:Integer;
   iBuff : Byte;
   i,j : word;
begin
    if index <=1 then begin
       Canvas[0].Height := uEPFH.canvasHeight;
       Canvas[0].Width := uEPFH.canvasWidht;
       Canvas[0].Loaded := true;
       exit;  
    end;
    fiStartOff:=GetFileOffset(strFile+'.EPF');
    dat.Seek(fistartOff+uEPFH.TocOffset+12+(16(index-1)),soBeginning);
    dat.Read(ileft,2);
    dat.Read(itop,2);
    dat.Read(iRight,2);
    dat.Read(iBottom,2);
    dat.Read(startOff,4);
    dat.Read(endOff,4);
    Canvas[index].top := iTop;
    Canvas[index].Left := iLeft;
    Canvas[index].Height := abs(iRight - iLeft);
    Canvas[index].Width := abs(iBottom - iTop);
    SetLength(Canvas[index].Data,Canvas[index].Width , Canvas[Index].Height);
    dat.Seek(startOff+fistartOff+12,soFromBeginning);
    for i := 0 to canvas[index].Height -1 do
        for j := 0 to canvas[index].Width -1 do begin
            dat.Read(ibuff,1);
            canvas[index].Data[j][i]:=ibuff;
        end;
end;
Procedure ReadTBLFile(Index:Word; strFile:String; uEPFH:tEPFHeader);
Var
  iBuff : Byte;
  fiStartOff : Integer;
  i,j:Word;
Begin
    fiStartOff:=GetFileOffset(strFile+'.TBL');
    dat.Seek(fiStartOff,soBeginning);
    dat.Read(i,4);
    if i >= uEPFH.frameCount then begin
       dat.Seek(5+ index   2,soCurrent);
       for j := 0 to uEPFH.frameCount -1 do begin
         dat.Read(iBuff,1);
         canvas[j].Table1 := iBuff;
         dat.Read(canvas[j].Table2,1);
       end;
    end;
End;
Procedure LoadBitMapIndex(Index:Word;strFile:String;uEPFH:tEPFHeader;SetPal:tTilePAL);
var j,k : word;
    cdlPixel : Cardinal;
begin
    ReadEPFFile(index,strFile,uEPFH);
    bitmap.Free;
    bitmap :=TBitmap.Create;
    Bitmap.Height := Canvas[index].Height;
    Bitmap.Width  := canvas[index].Width;
    //Process UPside Down
    bitmap.Transparent := true;
    IF not ((Bitmap.Width = 0) OR (Bitmap.Height = 0)) then begin
    FOR j := 0 TO Bitmap.height-1 DO
       BEGIN
        FOR k := 0 TO Bitmap.Width -1 DO begin
              cdlPixel := SetPal.tilepal[canvas[index].Table1,canvas[index].data[k,j]].RGB;
              bitmap.Canvas.Pixels[k,j]:=cdlPixel;
        end;
       END;
    end;
//    Bitmap.Free;
end;
Procedure LoadBitMapIndexSJ(var ibitmap : tBitmap; Index:Word;strFile:String;uEPFH:tEPFHeader;SetPal:tTilePAL);
var j,k : word;
    row : pRGBTripleArray ;
    cdlPixel : Cardinal;
begin
    ReadEPFFile(index,strFile,uEPFH);
    bitmap :=TBitmap.Create;
    try
      Bitmap.Height := Canvas[index].Height;
      Bitmap.Width  := canvas[index].Width;
      BitMap.PixelFormat := pf32bit;
       //Process UPside Down
      IF not ((Bitmap.Width = 0) OR (Bitmap.Height = 0)) then begin
         FOR j := 0 TO Bitmap.height-1 DO
             BEGIN
               row := bitmap.scanline[j];
               FOR k := 0 TO Bitmap.Width -1 DO begin
                   with row[k] do
                     begin
                       cdlPixel :=SetPal.tilepal[canvas[index].Table1,canvas[index].data[k,j]].RGB;
                       rgbtRed  := GetRValue(cdlPixel);
                       rgbtGreen  := GetGValue(cdlPixel);
                       rgbtBlue := GetBValue(cdlPixel);
                     end;
              end;
             END;
     end;
     ibitmap := bitmap;
    finally
      Bitmap.Free;
    end;
end;
end.
[/code:1:79bf6e1814]
Procedure  LoadBitMapIndex mengunakan teknik Pixel
sedangkan  LoadBitMapIndexSJ menggunakan Scanline
Source lengkap beserta file tile.datnya akan saya upload jika ada yg memerlukannya.
                
                
                   more 18 years ago
                  
              pebbie
umm, klo pake packed record gitu bukannya pake pf24bit aja. klo pake pf32bit nanti jadinya slot per empat byte dibaca pake slot per tiga byte.
                
                
                   more 18 years ago
                  
              coolmib
TYPE
  TRGBTripleArray = ARRAY OF TRGBTriple;
  pRGBTripleArray = ^TRGBTripleArray; 
Kalo yg dimaksud antara TRGBTriple sama TRGBQuad , saya rasa gak efek deh khan 1 byte
lagi reserved (dipake u/ alpha). 
Ada yg pernah coba pake component2 DelphiX / UnDelphiX ?? kelihatannya menarik.
bisa share gak??
Oh iya ini screen Shot map editor (baru ngeload tile2 dan object) cuman masih pake teknik Pixel
http://i109.photobucket.com/albums/n69/coolmib/Screen1.jpg
                
                
                   more 18 years ago
                  
              pebbie
efeknya di 
                
FOR k := 0 TO Bitmap.Width -1 DO begin 
                   with row[k] do //<---------------------------sini
                     begin 
                       cdlPixel :=SetPal.tilepal[canvas[index].Table1,canvas[index].data[k,j]].RGB; 
                       rgbtRed  := GetRValue(cdlPixel); 
                       rgbtGreen  := GetGValue(cdlPixel); 
                       rgbtBlue := GetBValue(cdlPixel); 
                     end; 
              end; 
more ...
              - Pages:
 - 1
 
                    
                     reply  |
                     Report Obsolete
                  
                AI Forward
            
🚀 We're thrilled to partner with Alibaba Cloud for "AI Forward - Alibaba Cloud Global Developer Summit 2025" in Jakarta! Join us and explore the future of AI. Register now: 
https://int.alibabacloud.com/m/1000400772/
#AlibabaCloud #DeveloperSummit #Jakarta #AIFORWARD
Last Articles
Last Topic
- PascalTalk #6: (Podcast) Kuliah IT di luar negeri, susah gak sih?
by LuriDarmawan in Tutorial & Community Project more 5 years ago - PascalTalk #5: UX: Research, Design and Engineer
by LuriDarmawan in Tutorial & Community Project more 5 years ago - PascalTalk #4: Obrolan Ringan Seputar IT
by LuriDarmawan in Tutorial & Community Project more 5 years ago - PascalTalk #2: Membuat Sendiri SMART HOME
by LuriDarmawan in Tutorial & Community Project more 5 years ago - PascalTalk #3: RADically Fast and Easy Mobile Apps Development with Delphi
by LuriDarmawan in Tutorial & Community Project more 5 years ago - PascalTalk #1: Pemanfaatan Artificial Intelligence di Masa Covid-19
by LuriDarmawan in Tutorial & Community Project more 5 years ago - Tempat Latihan Posting
by LuriDarmawan in OOT more 5 years ago - Archive
 - Looping lagi...
by idhiel in Hal umum tentang Pascal Indonesia more 13 years ago - [ask] koneksi ke ODBC user Dsn saat runtime dengan ado
by halimanh in FireBird more 13 years ago - Validasi menggunakan data tanggal
by mas_kofa in Hal umum tentang Pascal Indonesia more 13 years ago 
Random Topic
- Programming Language Popularity
by DelphiExpert in OOT more 18 years ago - StringGrid or DBGrid???
by n3o_cybertech in Tutorial & Community Project more 18 years ago - pletak pletuk mysqLL
by nurez in MySQL more 20 years ago - Progress bar ketika Execute query
by dkhosuma in Hal umum tentang Pascal Indonesia more 18 years ago - mohon perhatiannya sebentar
by shadri in OOT more 18 years ago - [help] menampilkan data database pada combobox
by binyo in Lain-lain more 13 years ago - delphi-id lagi sakit
by ganang in Kritik & Saran more 17 years ago - membuat nomor urut di query ms access
by jajang in Hal umum tentang Pascal Indonesia more 14 years ago - mengubah warna pada TbitButton
by divanda in Tip n Trik Pemrograman more 18 years ago - absolute database
by insan in Lain-lain more 13 years ago