Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: So Jul 13, 2025 12:58

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 12 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Sa Apr 02, 2005 11:22 
Offline
DGL Member

Registriert: Di Apr 27, 2004 13:38
Beiträge: 13
Hidiho.
Ich schreib grade ein Proggi das die Art.Mul von Ultima Online auslesen kann.
Die Dokus dazu sind ein wenig spärlich geraten, aber ich hab immerhin ein funnzendes Prog gefunden das alle Mul-files auslesen kann (Arachnide). Allerdings ist das ganze C++.

Nun hab ich das Problem das ich eine Procedure nicht übersetzt bekommen. Vielleicht könnt ihr mir dabei helfen?

Das Original (cpp):
Code:
  1. Sprite *MArtReader::readStaticSprite(unsigned int32 id)
  2. {
  3.   index->seek(12 * (id + STATIC_OFFSET));
  4.   unsigned int32 offset = index->read_uint32_little();
  5.   data->seek(offset + 4); // 4 to skip some header (size?)
  6.   unsigned int32 width = data->read_uint16_little();
  7.   unsigned int32 height = data->read_uint16_little();
  8. #ifdef SANE
  9.   if ((width == 0)  || (width >= 1024) ||
  10.       (height == 0) || (height >= 1024)) {
  11.     System::panic("MArtReader::readStaticSprite, invalid dimension");
  12.   }
  13. #endif
  14.   Sprite *sprite = new Sprite(width, height);
  15.   for (unsigned int32 i= 0; i< height; i++) {
  16.     linebuf[i] = data->read_uint16_little();
  17.   }
  18.   unsigned int32 mask_line = (width >> 3) + 1;
  19.   unsigned int32 mask_size = height * mask_line;
  20.   unsigned byte *mask = (unsigned byte *) malloc(mask_size, "Sprite.mask");
  21.   memset(mask, 0, mask_size);
  22.   sprite->mask = mask;
  23.   sprite->stretched = true;
  24.   unsigned int32 dstart = offset + 8 + height * 2;
  25.   unsigned int32 y = 0;
  26.   unsigned int32 x = 0;
  27.   data->seek(dstart + (linebuf[y] << 1));
  28.   unsigned int32 runs = 0;
  29.   while(y < height) {
  30.     unsigned int32 offset = data->read_uint16_little();
  31.     unsigned int32 runby  = data->read_uint16_little();
  32.     x += offset;
  33.     if (offset + runby == 0) {
  34.       y++;
  35.       data->seek(dstart + (linebuf[y] << 1));
  36.       x = 0;
  37.       runs = 0;
  38.       continue;
  39.     }
  40. #ifdef SANE
  41.     if (x + runby > width) {
  42.       System::panic("MArtReader::readStaticSprite, illegal data");
  43.     }
  44. #endif
  45.     runs++;
  46.     unsigned byte *mp = mask + (x >> 3) + y * mask_line;
  47.     unsigned int8 m  = 1 << (x & 0x7);
  48.     byte *dst = ((byte *) sprite->data) + (y * width * 2) + x * 2;
  49.     for (unsigned int32 r = 0; r < runby; r++) {      
  50.       *((unsigned int16 *) dst) = (unsigned int16) data->read_uint16_little();
  51.       *mp |= m;
  52.       dst += 2;
  53.       if ((m <<= 1) == 0) {
  54.         m = 0x01;
  55.         mp++;
  56.       }
  57.     }
  58.     x += runby;
  59.   }
  60.   return sprite;
  61. }



Und so sieht meine (nicht funnzende) Umsetzung aus:
Code:
  1. Procedure TArtReader.ReadStatic(id : DWord; C: TCanvas);
  2. const STATIC_OFFSET=16384;
  3.       MART_MAX_HEIGHT=1025;
  4.  
  5. var index, data : TFilestream;
  6.     Offset,Pixel : DWord;
  7.     XOffset,run,dstart, w,h,x,y : Word;
  8.     runby : Word;
  9.     runs,i : Integer;
  10.     mask_size, mask_line : Integer;
  11.     linebuf : array of Word;
  12.  
  13. begin try
  14.       index := TFileStream.Create(fIDXFile, fmopenRead);
  15.       Data  := TFileStream.Create(fArtFile, fmopenRead);
  16.  
  17.       index.Seek(12* (id+Static_offset),0);
  18.       index.read(Offset, SizeOf(Offset));
  19.       data.seek(Offset+4,0);
  20.       data.Read(w, sizeof(w));
  21.       data.Read(H, sizeof(H));
  22.     Application.MainForm.Caption :='ReadStatic: Width='+IntToStr(W)+' : Height='+IntTostr(H);
  23.  
  24.       SetLength(LineBuf, H);
  25.  
  26.       for i:=0 to H do
  27.     Data.Read(linebuf[i], SizeOf(Linebuf[i]));
  28.       mask_line := (W shr 3) +1;
  29.       mask_size := H * mask_line;
  30.       dstart := offset+8+h*2;
  31.       y := 0;
  32.       x := 0;
  33.       data.Seek(dstart+(linebuf[y]*2),0);
  34.       runs := 0;
  35.       while y < H do
  36.     begin data.Read(xoffset, SizeOf(xOffset));
  37.           data.Read(runby, SizeOf(Runby));
  38.           if (XOffset + Runby >= 2048) then break;
  39.           if (XOffset + Runby <> 0 ) then
  40.         begin x := x+XOffset;
  41.               for i:=0 to runby do
  42.             begin data.Read(Pixel, SizeOf(Pixel));
  43.                   c.Pixels[x+i,y] := Pixel;
  44.             end;
  45.               x := x+runby;
  46.         end else
  47.         begin x:= 0;
  48.               inc(y);
  49.               Data.Seek(DStart + LineBuf[y]*2,0);
  50.         end;
  51.     end;
  52.       finally
  53.       Data.free;
  54.       index.Free;
  55.       end;
  56. end;
  57.  



Die größen (W und H) werden übrigens korrekt ausgelesen. Nur was dann kommt ist schrott (steigt meistens mit XOffset + Runby >= 2048 aus ).
Das Original gibt "Sprite" zurück, für meine Funktion reicht es allerdings als Parameter das Canvas anzugeben, auf das gemalt werden soll (geht ja nur ums anzeigen).

Zwei Links hab ich noch, die die Problematik beschreiben (vielleicht sehe ich auch nur irgendwas falsch):
http://arachnide.sourceforge.net/formats/art/index.html
http://www.wpdev.org/docs/formats/art.html

Wäre dankbar über jeden Hinweis was ich falsch mache.
Danke Euch =)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Apr 02, 2005 13:53 
Offline
DGL Member

Registriert: Mo Jan 20, 2003 20:10
Beiträge: 424
Wohnort: nähe Starnberg
Code:
  1.  
  2.       for i:=0 to H do
  3.    Data.Read(linebuf[i], SizeOf(Linebuf[i]));
  4.  

Hier müßte eigentlich
Code:
  1.  
  2.       for i:=0 to (H - 1) do
  3.    Data.Read(linebuf[i], SizeOf(Linebuf[i]));
  4.  

stehen. Probiere dieses mal aus.

Gruß
KidPaddle

PS.: Das scheint nochmals der gleiche Fehler zu sein.
Code:
  1.  
  2. for i:=0 to runby do
  3.          begin data.Read(Pixel, SizeOf(Pixel));
  4.                c.Pixels[x+i,y] := Pixel;
  5.          end;
  6.  


Code:
  1.  
  2. for i:=0 to (runby - 1) do
  3.          begin data.Read(Pixel, SizeOf(Pixel));
  4.                c.Pixels[x+i,y] := Pixel;
  5.          end;
  6.  

_________________
http://www.seban.de


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Apr 02, 2005 14:41 
Offline
DGL Member

Registriert: Di Apr 27, 2004 13:38
Beiträge: 13
Leider keine Änderung, trotz beiden -1.
Ich hab das dumpfe gefühl, das bei
Code:
  1.  
  2.       y := 0;
  3.       x := 0;
  4.       data.Seek(dstart+(linebuf[y]*2),0);
  5.       runs := 0;


Schon an die falsche Stelle gesprungen wird,
denn in den folgenden Stellen wird ja erst runby und xoffset eingelesen (die beide meistens über 3.000 liegen - was alleine schon ein Fehler (s.h. ff) ist)

An anderer Stelle (bei Heptazane) wird gesagt das dstart einfach die aktuelle Fileposition in Data sein soll, aber das bringt genauso Müll.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Apr 03, 2005 18:47 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Mär 09, 2005 12:26
Beiträge: 53
Wohnort: Dornbirn
Möglicherweise ist die Datei binär geschrieben und du liest sie nicht binär aus.
(Ich bin C++ Programmierer), ich hatte da nämlich das gleiche Problem. Die ersten paar bytes wurden richtig ausgelesen (reine Glückssache), dann kam nur noch Schrott, und irgendwann nur noch 0en (ende der Datei schon lnge erreicht.) Ich hab es dann einfach binär ausgelesen und voila funzte ohne Probleme, weiß aber nicht obs daran liegt, kannst aber ja mal ausprobieren.

Und die Info mit -1 ist richtig.Weil wenn da steht for (unsigned int32 i= 0; i< height; i++)
bedeutet das, dass die Schleife sagen wir wenn height 10 ist dass die Schleife dann endet wenn i = 10 ist. Weil dann das Abbruchkriterium erreicht ist, weil i dann nicht kleiner height ist sondern gleich height ist...

_________________
Good software is like sex, it's best when it's free


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 12, 2005 17:28 
Offline
DGL Member

Registriert: Do Mär 31, 2005 13:29
Beiträge: 3
falls das Problem noch aktuell ist, versuchs damit:

Code:
  1.  
  2. type    TIndexRecord = packed record
  3.                 Offset: Integer;
  4.                 Length: Integer;
  5.                 Extra: Integer
  6.         end;
  7.  
  8. var     Breite, Hoehe : Word;
  9.         LookupList : PWordArray;
  10.         XOffset, RunLength, RunColor: Word;
  11.         Start, XCoord, YCoord : Integer;
  12.         i : Integer;
  13.         IndexRec : TIndexRecord;
  14. begin
  15.         idxStream.Seek( (Id+$4000)*12, soFromBeginning );
  16.         idxStream.Read( IndexRec, sizeof( TIndexRecord ) );
  17.  
  18.         mulStream.Seek( IndexRec.Offset+4, soFromBeginning );
  19.         mulStream.Read( Breite, 2 );
  20.         mulStream.Read( Hoehe, 2 );
  21.  
  22.         GetMem( LookupList, Hoehe*2 );
  23.         mulStream.Read( LookupList^, Hoehe*2 );
  24.         Start := mulStream.Position;
  25.  
  26.         for YCoord := 0 to Hoehe-1 do begin
  27.                 mulStream.Seek( Start + LookupList^[YCoord]*2, soFromBeginning );
  28.                 XCoord := 0;
  29.  
  30.                 mulStream.Read( XOffset, 2 );
  31.                 mulStream.Read( RunLength, 2 );
  32.  
  33.                 while ( RunLength <> 0 ) do begin
  34.                         XCoord := XCoord + XOffset;
  35.  
  36.                         for i := 0 to RunLength-1 do begin
  37.                                 mulStream.Read( RunColor, 2 );
  38.                                 if ( XCoord+X+i < Bitmap.Width ) and ( YCoord+Y < Bitmap.Height ) and ( XCoord+X >= 0 ) and ( YCoord+Y >= 0 ) and ( RunColor <> 32767 ) then
  39.                                         Bitmap.Pixel[ XCoord+i+X, YCoord+Y ] := Color15to32( RunColor );
  40.                         end;
  41.  
  42.                         XCoord := XCoord + RunLength;
  43.                         mulStream.Read( XOffset, 2 );
  44.                         mulStream.Read( RunLength, 2 );
  45.                 end;
  46.         end;
  47. end;
  48.  
  49.  


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 03, 2006 15:17 
Offline
DGL Member

Registriert: Di Apr 27, 2004 13:38
Beiträge: 13
Wowi - nu habbich für die nächste tng-Version schonmal wenigstens das Art-Geraffel auf eine Zeile säubern können dank Varan =)

Aaaber ... eins hätte ich da noch ... *duck*
Ich kriege die Anim.mul nicht ordentlich ausgelesen.
Habe schon versucht die Teile von InsideUO zu übernehmen, aber das Problem dabei ist jede Menge asm-Code, den ich nicht zurückübersetzt bekomme (Palettenzeuges).
Im UOCharacterViewer ist zwar eine nette Lösung drin, aber wie der auf seine Offsets kam (35000 für c_man (0x190)) ist für mich nicht nachvollziehbar.
Kann mir nicht jemand eine procedure/function posten zum auslesen einer Anim posten? (ohne anim2/3/...)

Dankä nochmal VD,
Mennowar


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 03, 2006 15:31 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Erstma denke ich das Thema waere bei dsdt.info besser aufgehoben, da ja nun wirklich 0 OGL drin ist.
Noch besser wäre es in UODev aufgehoben, denn dort ist auf VD Admin, der jenige, der bereits den Mulpatcher geschrieben hat (der editor, der alle mul und idx Dateien von UO einlesen kann) und auch den Palanthir (den neuen UO Client)...

Ansonsten wozu willst du die dinger auslesen? Editoren gibs doch genug. Ansonsten poste ma bei UODev, VD ist sicher nicht geizig mit seinen Soulutions. Und wenn du OGL kannst, freut er sich sicher auch ueber ne Hilfe um Magie zu realisieren, denn das hat er im Palanthir noch nicnh drin (wobei ich nich weiss, ob der Palanthir auf DX oder OGL basiert. Wäre mal in Erfahrung zu bringen... ich frag ihn ma)

PS: 1,5 jahre später? was hast du die ganze zeit gemacht?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 03, 2006 21:54 
Offline
DGL Member

Registriert: Di Apr 27, 2004 13:38
Beiträge: 13
> PS: 1,5 jahre später? was hast du die ganze zeit gemacht?

2 neue Releases von tng, nen TileDataEditor, nen AnimationEditor für den mulpatcher und noch ein paar andere Sachen (glaube das sagt vd was) rausgebracht, C# gelernt und verworfen weil zu lahm.

Was man halt so in 1 + 1 div 2 Jahren macht.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Okt 03, 2006 22:18 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
Leider OT aber muss sein ^^:
1 + 1div2 = 1 ^^
Aber hat mich halt ittitiert, dass du da jetz wieder drauf zu sprechen kommt. aber nur zu, wer seinen Shard verschönern will, da bin ich immer dafür. bin selber staffi und habe einige editoren und patcher geschrieben. welcher shard?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Okt 04, 2006 16:38 
Offline
DGL Member

Registriert: Di Apr 27, 2004 13:38
Beiträge: 13
Waren bis vor ein paar Monaten auf vespertales (www.vespertales.de).
Aber inzwischen basteln wir (also meine bessere Hälfte und ich) nur noch am Homeserver - und der ist inzwischen gewaltig (zumindest was neue Items (auch selbstgezeichnet/Animiert) und NPCs (teilweise auch selbst gemacht)) groß geworden ist.

.... irgendwann mache ich mal ein Backup - bestimmt ....

ps: 1+1 div 2=1 Stimmt :oops:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Okt 04, 2006 18:16 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Shaddow hat geschrieben:
bin selber staffi

Auf welchem Shard? :)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Okt 04, 2006 18:27 
Offline
DGL Member

Registriert: So Aug 20, 2006 23:19
Beiträge: 564
*g* Paradise Island


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 12 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 5 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 15 Queries | GZIP : On ]