2 SSTP Bottle Surface Preview Plug-In for "SVG"
3 (C)2003 naru, Mikage Sawatari / SSTP Bottle
11 Windows, Classes, SysUtils, Graphics, IniFiles, Dialogs, PngImage, jpeg;
16 ConfigFile = 'SVG.ini';
21 Ghost2File: TStringList;
23 Pic: TPicture; //
\93Ç
\82Ý
\8eæ
\82Á
\82½
\89æ
\91\9c(*.png, *.bmp, *.jpg)
24 PicFileName: String; //
\82»
\82Ì
\83t
\83@
\83C
\83\8b\96¼
26 // 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
27 //
\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ð
28 //
\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
29 // 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
30 //
\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
31 //
\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
32 procedure Load(Path: PChar); cdecl;
36 Ini := TIniFile.Create(MyPath + ConfigFile);
38 GhostFile := Ini.ReadString('SVG', 'GhostFile', '');
42 if not FileExists(GhostFile) then
43 ShowMessage('SVG.dll Warning: Ghost file is not specified');
44 Ghost2File := TStringList.Create;
45 Pic := TPicture.Create;
49 // DLL
\83A
\83\93\83\8d\81[
\83h
\8e\9e\82É
\8cÄ
\82Î
\82ê
\82é
\81B
50 procedure Unload; cdecl;
56 // DLL
\82Ì
\96¼
\91O
\82¨
\82æ
\82Ñ
\83o
\81[
\83W
\83\87\83\93\82ð
\95Ô
\82·
\81B
57 // 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
58 // NameLen
\83o
\83C
\83g
\82ð
\92´
\82¦
\82Ä
\82Í
\82È
\82ç
\82È
\82¢
\81B
59 // version
\82É
\82Í
\82Æ
\82è
\82 \82¦
\82¸1
\82ð
\95Ô
\82·
\82±
\82Æ
\81Bversion
\82ÍSSTP Bottle Client
\82Æ
\82Ì
60 //
\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É
61 //
\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
62 // CanConfigure
\82Í
\81AConfigure
\82ð
\8cÄ
\82Î
\82ê
\82Ä
\82â
\82é
\82±
\82Æ
\82ª
\82 \82é
\82©
\82Ç
\82¤
\82©
\82ð
\95Ô
\82·
\81B
63 function GetVersion(DLLName: PChar; NameLen: integer;
64 var Version: integer; var CanConfigure: boolean): integer; cdecl;
65 const ThisDLL = 'SVG Surface Loader Ver. 2.3';
69 StrLCopy(DLLName, ThisDLL, NameLen);
70 Result := Length(ThisDLL) + 1;
73 function LoadDefinitionFileVer2(Ghost: String;
74 Surface: integer; Lines: TStringList; const FileName: String;
75 out Pos: integer): String;
76 var ALine, SurfaceMap: TStringList;
77 i, j, p, sur, oldpos: integer;
80 //
\93à
\95\94\8aÖ
\90\94\81B
\83S
\81[
\83X
\83g
\92è
\8b`
\83t
\83@
\83C
\83\8b\82ð
\89ð
\90Í
\82µ
\82Ä
\81A
81 //
\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é
82 ALine := TStringList.Create;
84 ALine.CommaText := Lines[0];
85 if (ALine[0] <> 'GHOST') then
88 Ghost2File.Values[Ghost] := FileName; //
\8e\9f\82©
\82ç
\82Ì
\83V
\83\87\81[
\83g
\83J
\83b
\83g
89 if (ALine[1] <> Ghost) then
94 //
\96Ú
\93I
\82Ì
\83S
\81[
\83X
\83g
\94
\8c©
96 SurfaceMap := TStringList.Create;
98 for i := 1 to Lines.Count-1 do
100 SurfaceMap.CommaText := Lines[i];
101 for j := 0 to SurfaceMap.Count-1 do
104 p := System.Pos(':', SurfaceMap[j]);
107 sur := StrToInt(Copy(SurfaceMap[j], 1, p-1));
108 posstr := Copy(SurfaceMap[j], p+1, High(integer));
112 Pos := StrToInt(posstr);
113 if sur = Surface then
115 Result := ALine[4]; // BMP
\83t
\83@
\83C
\83\8b\96¼
120 on EConvertError do; // nothing.
\92P
\82È
\82é
\83R
\83\81\83\93\83g
\8ds
\88µ
\82¢
128 // BASIC
\82Ì
\8fê
\8d\87\82Ì
\8f\88\97\9d
129 if AnsiCompareText('BASIC', ALine[3]) = 0 then
131 if (Surface >= 0) and (Surface <= 11) then
133 Result := ALine[4]; // BMP
\83t
\83@
\83C
\83\8b\96¼
134 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é
144 procedure ParseKeyVal(const Line: String; out Key, Val: String);
147 // Key=Value
\8c`
\8e®
\82Ì
\95¶
\8e\9a\97ñ
\82©
\82çKey
\82ÆValue
\82ð
\8eæ
\82è
\8fo
\82·
148 // Value
\82Í""
\82Å
\88Í
\82ñ
\82Å
\82à
\82æ
\82¢
\81BKey
\82Í
\8f¬
\95¶
\8e\9a\82É
\82±
\82Ì
\92i
\8aK
\82Å
\93\9d\88ê
152 Key := AnsiLowerCase(Copy(Line, 1, p-1));
153 Val := AnsiDequotedStr(Copy(Line, p+1, High(integer)), '"');
156 Val := AnsiDequotedStr(Line, '"');
160 procedure SplitBlocks(Lines, Blocks: TStringList);
164 Start: integer; //
\8c»
\8dÝ
\92\8d\96Ú
\82µ
\82Ä
\82¢
\82é
\83u
\83\8d\83b
\83N
\82Ì
\90æ
\93ª
\82Ì
\95¶
\8e\9a\83C
\83\93\83f
\83b
\83N
\83X
165 InLead: boolean; // DBCS
\82ÌLeadBytes
\82ð
\8c©
\82Ä
\82¢
\82é
\82©
\82Ç
\82¤
\82©
\82ð
\95Û
\8e\9d
167 // SVG
\82Ì
\8ae
\8ds
\82ð
\83u
\83\8d\83b
\83N
\82É
\95Ï
\8a·
168 //
\83R
\83\81\83\93\83g
\82ð
\8eæ
\82è
\8aO
\82µ
\81A/EOF
\88È
\8d~
\82ð
\93K
\90Ø
\82É
\96³
\8e\8b\82·
\82é
173 while (i < Length(Str)) do
180 end else if Str[i] in LeadBytes then
186 if Str[i] in [',', #13, #10] then
191 Block := Copy(Str, Start, i-Start);
192 if Block = '/EOF' then
194 else if Block[1] <> '/' then //
\83R
\83\81\83\93\83g
\82Í
\96³
\8e\8b
203 function LoadDefinitionFileVer3(Ghost: String;
204 Surface: integer; Lines: TStringList; const FileName: String;
205 out Pos: integer): String;
206 var i, k, smin, smax, oldsur: integer;
207 Key, Val, SurStr, PosStr, SakuraName: String;
208 Blocks, Sur2Pos: TStringList;
211 Sur2Pos := TStringList.Create;
212 Blocks := TStringList.Create;
215 SplitBlocks(Lines, Blocks);
216 for i := 0 to Blocks.Count-1 do
218 ParseKeyVal(Blocks[i], Key, Val);
219 if Key = 'sakura' then
222 Ghost2File.Values[SakuraName] := FileName; //
\8e\9f\82©
\82ç
\82Ì
\83V
\83\87\81[
\83g
\83J
\83b
\83g
223 if SakuraName <> Ghost then //
\95Ê
\83S
\81[
\83X
\83g
\82Ì
\92è
\8b`
\83t
\83@
\83C
\83\8b\82È
\82Ì
\82Å
\83p
\83X
225 end else if Key = 'surfacefile' then
228 end else if (Key = 'surface') or (Length(Key) = 0) then
230 //
\83T
\81[
\83t
\83B
\83X
231 if System.Pos(':', Blocks[i]) <= 0 then
233 SurStr := Copy(Blocks[i], 1, System.Pos(':', Blocks[i])-1);
234 PosStr := Copy(Blocks[i], System.Pos(':', Blocks[i])+1, High(integer));
236 if System.Pos('-', SurStr) > 0 then
238 smin := StrToInt(Copy(SurStr, 1, System.Pos('-', SurStr)-1));
239 smax := StrToInt(Copy(SurStr, System.Pos('-', SurStr)+1, High(integer)));
242 smin := StrToInt(SurStr);
245 for k := smin to smax do
249 Sur2Pos.Values[IntToStr(k)] := IntToStr(k);
251 end else if PosStr = '-2' then
253 Sur2Pos.Values[IntToStr(k)] := '' //
\92è
\8b`
\89ð
\8f\9c
254 end else if PosStr = '+' then
257 Sur2Pos.Values[IntToStr(k)] := IntToStr(oldsur);
258 end else if StrToInt(PosStr) >= 0 then
260 Sur2Pos.Values[IntToStr(k)] := PosStr;
261 oldsur := StrToInt(PosStr);
269 // ShowMessage(SakuraName + #13#10 + Sur2Pos.Text);
270 if SakuraName <> Ghost then //sakura=??
\82Ì
\8ew
\92è
\82ª
\94²
\82¯
\82Ä
\82¢
\82é
\92è
\8b`
\83t
\83@
\83C
\83\8b\82Ì
\8fê
\8d\87
274 if Sur2Pos.Values[IntToStr(Surface)] <> '' then
275 Pos := StrToInt(Sur2Pos.Values[IntToStr(Surface)])
285 function LoadDefinitionFile(Ghost: String;
286 Surface: integer; FileName: String; out Pos: integer): String;
287 var Lines: TStringList;
289 Lines := TStringList.Create;
290 Lines.LoadFromFile(FileName);
292 if System.Pos('SVG3', Lines[0]) > 0 then
293 Result := LoadDefinitionFileVer3(Ghost, Surface, Lines, FileName, Pos)
295 Result := LoadDefinitionFileVer2(Ghost, Surface, Lines, FileName, Pos);
301 function FetchBmpFileAndPosition(Ghost: String;
302 Surface: integer; out Pos: integer): String;
303 var Ghosts, AGhost: TStringList;
305 Dir, DefFileName, BmpFileName: String;
308 if Ghost2File.Values[Ghost] <> '' then //
\82·
\82Å
\82É
\82»
\82Ì
\83S
\81[
\83X
\83g
\82É
\82Â
\82¢
\82Ä
\92²
\8d¸
\8dÏ
\82Ý
310 DefFileName := Ghost2File.Values[Ghost];
311 if DefFileName = '*' then //
\82»
\82Ì
\83S
\81[
\83X
\83g
\82Í
\92m
\82ç
\82È
\82¢
\81A
\82Æ
\8bL
\89¯
\82µ
\82Ä
\82¢
\82é
314 end else //
\82»
\82Ì
\83S
\81[
\83X
\83g
\82ð
\92m
\82Á
\82Ä
\82¢
\82é
316 BmpFileName := LoadDefinitionFile(Ghost, Surface,
318 if BmpFileName <> '' then
320 Result := ExtractFilePath(DefFileName) + BmpFileName;
327 //
\83S
\81[
\83X
\83g
\82ª
\8c©
\82Â
\82©
\82ç
\82È
\82©
\82Á
\82½
\8c\8b\89Ê
\82ð
\8bL
\89¯
\81B
328 //
\8c©
\82Â
\82©
\82Á
\82½
\8fê
\8d\87\82É
\82Í
\83t
\83@
\83C
\83\8b\96¼
\82Å
\8fã
\8f\91\82«
\82³
\82ê
\82é
330 Ghost2File.Values[Ghost] := '*';
332 //
\93à
\95\94\8aÖ
\90\94\81Bghost.txt
\82ð
\93Ç
\82Ý
\8d\9e\82Þ
\81B
333 Dir := ExtractFilePath(GhostFile);
334 Ghosts := TStringList.Create;
336 Ghosts.LoadFromFile(GhostFile);
337 AGhost := TStringList.Create;
339 for i := 0 to Ghosts.Count-1 do
341 AGhost.CommaText := Ghosts[i];
342 if AGhost[0] <> 'GHOST' then
344 DefFileName := Dir + AGhost[3];
345 //
\92è
\8b`
\83t
\83@
\83C
\83\8b\82ð
\93Ç
\82Ý
\8d\9e\82Þ
346 BmpFileName := LoadDefinitionFile(Ghost, Surface,
348 if BmpFileName <> '' then
350 Result := ExtractFilePath(DefFileName) + BmpFileName;
363 // 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
364 // H
\82Å
\8ew
\92è
\82³
\82ê
\82Ä
\82¢
\82é
\83r
\83b
\83g
\83}
\83b
\83v
\82É
\8f\91\82«
\8fo
\82·
\82±
\82Æ
\81B
365 function GetImage(Ghost: PChar; Surface: integer; H: HBITMAP): integer; cdecl;
368 Position, x, y, nCol: integer;
371 BmpFile := FetchBmpFileAndPosition(Ghost, Surface, Position);
372 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¢
377 Bmp := TBitmap.Create;
380 if PicFileName <> BmpFile then
383 Pic.LoadFromFile(BmpFile);
384 PicFileName := BmpFile;
388 Pic := TPicture.Create;
393 nCol := Pic.Width div SurfaceWidth;
394 x := SurfaceWidth * (Position mod nCol);
395 y := SurfaceHeight * (Position div nCol);
396 Bmp.Canvas.Draw(-x, -y, Pic.Graphic);
407 //
\83C
\83\81\81[
\83W
\82Ì
\91å
\82«
\82³
\82ð
\95Ô
\82·
\81B
408 //
\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
409 //
\82»
\82ê
\82È
\82ç
\92P
\8f\83\82É
\92è
\90\94\82ð
\95Ô
\82µ
\82Ä
\8d·
\82µ
\8ex
\82¦
\82È
\82¢
\81B
410 //
\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
411 function GetImageSize(Ghost: PChar; Surface: integer;
412 var w, h: integer): integer; cdecl;
420 // DLL
\8cÅ
\97L
\82Ì
\90Ý
\92è
\82ð
\8ds
\82¤
\81B
422 procedure Configure; cdecl;
423 var OpenDialog: TOpenDialog;
427 ShowMessage('Specify SSTP Viewer''s ghost file.');
428 OpenDialog := TOpenDialog.Create(nil);
430 OpenDialog.Filter := 'Ghost Definition File(ghost.txt)|ghost.txt|' +
431 'All Files(*.*)|*.*';
432 OpenDialog.FileName := GhostFile;
433 if OpenDialog.Execute then
435 GhostFile := OpenDialog.FileName;
436 Ini := TIniFile.Create(MyPath + ConfigFile);
438 Ini.WriteString('SVG', 'GhostFile', GhostFile);
449 ShowMessage(E.Message);