--- /dev/null
+library SVG;
+
+{$R *.res}
+
+uses
+ Windows, Classes, SysUtils, Graphics, IniFiles;
+
+const
+ SurfaceWidth = 48;
+ SurfaceHeight = 64;
+ ConfigFile = 'SVG.ini';
+
+var
+ MyPath: String;
+ GhostFile: String;
+ Ghost2File: TStringList;
+
+// DLL\83\8d\81[\83h\8e\9e\81A\82¨\82æ\82ÑDLL\8dÄ\8f\89\8aú\89»\8e\9e\82É\8cÄ\82Î\82ê\82é\81B
+// \93Ç\82Ý\8d\9e\82Ü\82ê\82½\89æ\91\9c\82Í\81ABottle Client\91¤\82Å\81u\83T\81[\83t\83B\83X\8dÄ\93Ç\82Ý\8d\9e\82Ý\81v\82ð
+// \96¾\8e¦\93I\82É\8ew\92è\82³\82ê\82È\82¢\8cÀ\82è\82Í Bottle Client \91¤\82Å\83L\83\83\83b\83V\83\85\82³\82ê\82é\82Ì\82Å\81A
+// DLL\82Å\89æ\91\9c\82Ì\83L\83\83\83b\83V\83\85\82È\82Ç\82ð\8dl\82¦\82é\95K\97v\82Í\8aî\96{\93I\82É\82È\82¢\81B
+// \82Æ\82Í\82¢\82¦\83T\81[\83t\83B\83X\92è\8b`\83t\83@\83C\83\8b\82È\82Ç\82ð\90æ\82É\89ð\90Í\82µ\82Ä\82¨\82\95K\97v\82ª\82 \82é\82È\82ç\81A
+// \82±\82±\82Å\93Ç\82Ý\8d\9e\82ñ\82Å\82¨\82\82Æ\97Ç\82¢\81BPath\82ÉDLL\82Ì\83p\83X\82ª\93n\82³\82ê\82é\81B
+procedure Load(Path: PChar); cdecl;
+var Ini: TIniFile;
+begin
+ MyPath := Path;
+ Ini := TIniFile.Create(MyPath + ConfigFile);
+ try
+ GhostFile := Ini.ReadString('SVG', 'GhostFile', '');
+ finally
+ Ini.Free;
+ end;
+ Ghost2File := TStringList.Create;
+end;
+
+// DLL\83A\83\93\83\8d\81[\83h\8e\9e\82É\8cÄ\82Î\82ê\82é\81B
+// \82½\82Ô\82ñ\82â\82é\82±\82Æ\82Í\82È\82¢\81B
+procedure Unload; cdecl;
+begin
+ Ghost2File.Free;
+end;
+
+// DLL\82Ì\96¼\91O\82¨\82æ\82Ñ\83o\81[\83W\83\87\83\93\82ð\95Ô\82·\81B
+// DLLName\82É\82ÍDLL\82Ì\96¼\8fÌ\82â\8dì\8eÒ\81ADLL\96{\91Ì\82Ì\83o\81[\83W\83\87\83\93\82È\82Ç\82ð\82ð\8aÈ\8c\89\82É\8ew\92è\82·\82é\81B
+// NameLen\83o\83C\83g\82ð\92´\82¦\82Ä\82Í\82È\82ç\82È\82¢\81B
+// version\82É\82Í\82Æ\82è\82 \82¦\82¸1\82ð\95Ô\82·\82±\82Æ\81Bversion\82ÍSSTP Bottle Client\82Æ\82Ì
+// \92Ê\90M\82Ì\83C\83\93\83^\81[\83t\83F\81[\83X\82Ì\83o\81[\83W\83\87\83\93\82Å\82 \82Á\82ÄDLL\82Ì\83o\81[\83W\83\87\83\93\82Æ\82©\82Å\82Í\82È\82¢\82±\82Æ\82É
+// \92\8d\88Ó(Bottle Client\82ÍDLL\82Ì\83o\81[\83W\83\87\83\93\94Ô\8d\86\82È\82¼\8b»\96¡\82È\82¢\82Ì\82Å)\81B
+// CanConfigure\82Í\81AConfigure\82ð\8cÄ\82Î\82ê\82Ä\82â\82é\82±\82Æ\82ª\82 \82é\82©\82Ç\82¤\82©\82ð\95Ô\82·\81B
+function GetVersion(DLLName: PChar; NameLen: integer;
+ var Version: integer; var CanConfigure: boolean): integer; cdecl;
+const ThisDLL = 'SVG Surface Loader';
+begin
+ Version := 1;
+ CanConfigure := true;
+ StrLCopy(DLLName, ThisDLL, NameLen);
+ Result := Length(ThisDLL) + 1;
+end;
+
+function LoadDefinitionFile(Ghost: String;
+ Surface: integer; FileName: String; out Pos: integer): String;
+var Lines, ALine, SurfaceMap: TStringList;
+ i, j, p: integer;
+begin
+ // \93à\95\94\8aÖ\90\94\81B\83S\81[\83X\83g\92è\8b`\83t\83@\83C\83\8b\82ð\89ð\90Í\82µ\82Ä\81A
+ // \96Ú\93I\82Ì\83S\81[\83X\83g\82Ì\8aÜ\82Ü\82ê\82½\83t\83@\83C\83\8b\82©\82Ç\82¤\82©\94»\92f\82·\82é
+ Lines := TStringList.Create;
+ try
+ Lines.LoadFromFile(FileName);
+ ALine := TStringList.Create;
+ try
+ ALine.CommaText := Lines[0];
+ if (ALine[0] <> 'GHOST') or (ALine[1] <> Ghost) then
+ Exit;
+ // \96Ú\93I\82Ì\83S\81[\83X\83g\94\8c©
+
+ SurfaceMap := TStringList.Create;
+ try
+ for i := 1 to Lines.Count-1 do
+ begin
+ SurfaceMap.CommaText := Lines[i];
+ for j := 0 to SurfaceMap.Count-1 do
+ begin
+ try
+ p := System.Pos(':', SurfaceMap[j]);
+ if p = 0 then
+ Continue;
+ if StrToInt(Copy(SurfaceMap[j], 1, p-1)) = Surface then
+ begin
+ Pos := StrToInt(Copy(SurfaceMap[j], p+1, High(integer)));
+ Result := ALine[4]; // BMP\83t\83@\83C\83\8b\96¼
+ Exit;
+ end;
+ except
+ on EConvertError do; // nothing. \92P\82È\82é\83R\83\81\83\93\83g\8ds\88µ\82¢
+ end;
+ end;
+ end;
+ finally
+ SurfaceMap.Free;
+ end;
+
+ // BASIC\82Ì\8fê\8d\87\82Ì\8f\88\97\9d
+ if AnsiCompareText('BASIC', ALine[3]) = 0 then
+ begin
+ if (Surface >= 0) and (Surface <= 11) then
+ begin
+ Result := ALine[4]; // BMP\83t\83@\83C\83\8b\96¼
+ Pos := Surface; // BASIC\82Ì\8fê\8d\87\82Í\88Ê\92u\82Æ\83T\81[\83t\83B\83X\94Ô\8d\86\82ª\88ê\91Î\88ê\91Î\89\9e\82µ\82Ä\82¢\82é
+ Exit;
+ end;
+ end;
+
+ finally
+ ALine.Free;
+ end;
+ finally
+ Lines.Free;
+ end;
+end;
+
+function FetchBmpFileAndPosition(Ghost: String;
+ Surface: integer; out Pos: integer): String;
+var Ghosts, AGhost: TStringList;
+ i, dum: integer;
+ Dir, DefFileName, BmpFileName: String;
+begin
+ if Ghost2File.Values[Ghost] <> '' then // \82·\82Å\82É\82»\82Ì\83S\81[\83X\83g\82Ì\83t\83@\83C\83\8b\82ð\8bL\89¯\82µ\82Ä\82é
+ begin
+ DefFileName := Ghost2File.Values[Ghost];
+ BmpFileName := LoadDefinitionFile(Ghost, Surface,
+ DefFileName, dum);
+ if BmpFileName <> '' then
+ begin
+ Result := ExtractFilePath(DefFileName) + BmpFileName;
+ Pos := dum;
+ Exit;
+ end;
+ end;
+
+ // \93à\95\94\8aÖ\90\94\81Bghost.txt\82ð\93Ç\82Ý\8d\9e\82Þ\81B
+ Dir := ExtractFilePath(GhostFile);
+ Ghosts := TStringList.Create;
+ try
+ Ghosts.LoadFromFile(GhostFile);
+ for i := 0 to Ghosts.Count-1 do
+ begin
+ AGhost := TStringList.Create;
+ try
+ AGhost.CommaText := Ghosts[i];
+ if AGhost[0] <> 'GHOST' then
+ Continue;
+ DefFileName := Dir + AGhost[3];
+ // \92è\8b`\83t\83@\83C\83\8b\82ð\93Ç\82Ý\8d\9e\82Þ
+ BmpFileName := LoadDefinitionFile(Ghost, Surface,
+ DefFileName, dum);
+ if BmpFileName <> '' then
+ begin
+ // \94\8c©!
+ Ghost2File.Values[Ghost] := DefFileName; // \8e\9f\82©\82ç\82Ì\82½\82ß\82É\92è\8b`\83t\83@\83C\83\8b\96¼\82ð\8bL\89¯
+ Result := ExtractFilePath(DefFileName) + BmpFileName;
+ Pos := dum;
+ Break;
+ end;
+ finally
+ AGhost.Free;
+ end;
+ end;
+ finally
+ Ghosts.Free;
+ end;
+end;
+
+// Ghost\82Å\8ew\92è\82³\82ê\82é\83S\81[\83X\83g\82ÌSurface\94Ô\82Ì\83T\81[\83t\83B\83X\83C\83\81\81[\83W\82ð\8eÀ\8dÛ\82É\93Ç\82Ý\8fo\82·\81B
+// H\82Å\8ew\92è\82³\82ê\82Ä\82¢\82é\83r\83b\83g\83}\83b\83v\82É\8f\91\82«\8fo\82·\82±\82Æ\81B
+function GetImage(Ghost: PChar; Surface: integer; H: HBITMAP): integer; cdecl;
+var Bmp, Bmp2: TBitmap;
+ BmpFile: String;
+ Position, x, y, nCol: integer;
+begin
+ try
+ BmpFile := FetchBmpFileAndPosition(Ghost, Surface, Position);
+ if BmpFile = '' then // \82»\82Ì\82æ\82¤\82È\83S\81[\83X\83g\82Ì\82»\82Ì\82æ\82¤\82È\83T\81[\83t\83B\83X\82Í\8c©\82Â\82©\82ç\82È\82¢
+ begin
+ Result := 1;
+ Exit;
+ end;
+ except
+ on Exception do // \83t\83@\83C\83\8b\82ª\8c©\82Â\82©\82Á\82Ä\82È\82¢\89Â\94\\90«\82ª\82à\82Á\82Æ\82à\8d\82\82¢
+ begin
+ Result := 1;
+ Exit;
+ end;
+ end;
+
+ Bmp := TBitmap.Create;
+ try
+ Bmp.Handle := H;
+ Bmp2 := TBitmap.Create;
+ try
+ Bmp2.LoadFromFile(BmpFile);
+ nCol := Bmp2.Width div SurfaceWidth;
+ x := SurfaceWidth * (Position mod nCol);
+ y := SurfaceHeight * (Position div nCol);
+ Bmp.Canvas.CopyRect(
+ Rect(0, 0, Bmp.Width, Bmp.Height),
+ Bmp2.Canvas,
+ Rect(x, y, x+SurfaceWidth, y+SurfaceHeight)
+ );
+ finally
+ Bmp2.Free;
+ end;
+ finally
+ Bmp.ReleaseHandle;
+ Bmp.Free;
+ end;
+ Result := 0;
+end;
+
+// \83C\83\81\81[\83W\82Ì\91å\82«\82³\82ð\95Ô\82·\81B
+// \91å\92ï\82Ì\8fê\8d\87\83C\83\81\81[\83W\82Ì\91å\82«\82³\82Í\82à\82Æ\82©\82ç\95ª\82©\82Á\82Ä\82¢\82é\82Æ\8ev\82¤\82Ì\82Å\81A
+// \82»\82ê\82È\82ç\92P\8f\83\82É\92è\90\94\82ð\95Ô\82µ\82Ä\8d·\82µ\8ex\82¦\82È\82¢\81B
+// \83C\83\81\81[\83W\82Ì\91å\82«\82³\82ª\83S\81[\83X\83g\82â\83T\81[\83t\83B\83X\94Ô\8d\86\82É\82æ\82Á\82Ä\95Ï\82í\82é\82È\82ç\82»\82Ì\82æ\82¤\82É\81B
+function GetImageSize(Ghost: PChar; Surface: integer;
+ var w, h: integer): integer; cdecl;
+begin
+ w := SurfaceWidth;
+ h := SurfaceHeight;
+ Result := 0;
+end;
+
+
+// DLL\8cÅ\97L\82Ì\90Ý\92è\82ð\8ds\82¤\81B
+//
+procedure Configure; cdecl;
+begin
+end;
+
+exports
+ Load,
+ Unload,
+ GetVersion,
+ Configure,
+ GetImage,
+ GetImageSize;
+
+begin
+
+end.