OSDN Git Service

Check if ghost file exists on startup
[winbottle/svg-dll.git] / SVG.dpr
1 {
2 SSTP Bottle Surface Preview Plug-In for "SVG"
3 (C)2003 naru, Mikage Sawatari / SSTP Bottle
4 }
5
6 library SVG;
7
8 {$R *.res}
9
10 uses
11   Windows, Classes, SysUtils, Graphics, IniFiles, Dialogs;
12
13 const
14   SurfaceWidth  = 48;
15   SurfaceHeight = 64;
16   ConfigFile = 'SVG.ini';
17
18 var
19   MyPath: String;
20   GhostFile: String;
21   Ghost2File: TStringList;
22
23 // 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
24 // \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ð
25 // \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
26 // 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
27 // \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
28 // \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
29 procedure Load(Path: PChar); cdecl;
30 var Ini: TIniFile;
31 begin
32   MyPath := Path;
33   Ini := TIniFile.Create(MyPath + ConfigFile);
34   try
35     GhostFile := Ini.ReadString('SVG', 'GhostFile', '');
36   finally
37     Ini.Free;
38   end;
39   if not FileExists(GhostFile) then
40     ShowMessage('SVG.dll Warning: Ghost file is not specified');
41   Ghost2File := TStringList.Create;
42 end;
43
44 // DLL\83A\83\93\83\8d\81[\83h\8e\9e\82É\8cÄ\82Î\82ê\82é\81B
45 // \82½\82Ô\82ñ\82â\82é\82±\82Æ\82Í\82È\82¢\81B
46 procedure Unload; cdecl;
47 begin
48   Ghost2File.Free;
49 end;
50
51 // DLL\82Ì\96¼\91O\82¨\82æ\82Ñ\83o\81[\83W\83\87\83\93\82ð\95Ô\82·\81B
52 // 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
53 // NameLen\83o\83C\83g\82ð\92´\82¦\82Ä\82Í\82È\82ç\82È\82¢\81B
54 // version\82É\82Í\82Æ\82è\82 \82¦\82¸1\82ð\95Ô\82·\82±\82Æ\81Bversion\82ÍSSTP Bottle Client\82Æ\82Ì
55 // \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É
56 // \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
57 // CanConfigure\82Í\81AConfigure\82ð\8cÄ\82Î\82ê\82Ä\82â\82é\82±\82Æ\82ª\82 \82é\82©\82Ç\82¤\82©\82ð\95Ô\82·\81B
58 function GetVersion(DLLName: PChar; NameLen: integer;
59   var Version: integer; var CanConfigure: boolean): integer; cdecl;
60 const ThisDLL = 'SVG Surface Loader for Ver. 1.1';
61 begin
62   Version := 1;
63   CanConfigure := true;
64   StrLCopy(DLLName, ThisDLL, NameLen);
65   Result := Length(ThisDLL) + 1;
66 end;
67
68 function LoadDefinitionFile(Ghost: String;
69   Surface: integer; FileName: String; out Pos: integer): String;
70 var Lines, ALine, SurfaceMap: TStringList;
71     i, j, p: integer;
72 begin
73   // \93à\95\94\8aÖ\90\94\81B\83S\81[\83X\83g\92è\8b`\83t\83@\83C\83\8b\82ð\89ð\90Í\82µ\82Ä\81A
74   // \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é
75   Lines := TStringList.Create;
76   try
77     Lines.LoadFromFile(FileName);
78     ALine := TStringList.Create;
79     try
80       ALine.CommaText := Lines[0];
81       if (ALine[0] <> 'GHOST') then
82         Exit;
83       if (ALine[1] <> Ghost) then
84       begin
85         Ghost2File.Values[Ghost] := FileName; // \8e\9f\82©\82ç\82Ì\83V\83\87\81[\83g\83J\83b\83g
86         Exit;
87       end;
88
89       // \96Ú\93I\82Ì\83S\81[\83X\83g\94­\8c©
90
91       SurfaceMap := TStringList.Create;
92       try
93         for i := 1 to Lines.Count-1 do
94         begin
95           SurfaceMap.CommaText := Lines[i];
96           for j := 0 to SurfaceMap.Count-1 do
97           begin
98             try
99               p := System.Pos(':', SurfaceMap[j]);
100               if p = 0 then
101                 Continue;
102               if StrToInt(Copy(SurfaceMap[j], 1, p-1)) = Surface then
103               begin
104                 Pos := StrToInt(Copy(SurfaceMap[j], p+1, High(integer)));
105                 Result := ALine[4]; // BMP\83t\83@\83C\83\8b\96¼
106                 Exit;
107               end;
108             except
109               on EConvertError do; // nothing. \92P\82È\82é\83R\83\81\83\93\83g\8ds\88µ\82¢
110             end;
111           end;
112         end;
113       finally
114         SurfaceMap.Free;
115       end;
116
117       // BASIC\82Ì\8fê\8d\87\82Ì\8f\88\97\9d
118       if AnsiCompareText('BASIC', ALine[3]) = 0 then
119       begin
120         if (Surface >= 0) and (Surface <= 11) then
121         begin
122           Result := ALine[4]; // BMP\83t\83@\83C\83\8b\96¼
123           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é
124           Exit;
125         end;
126       end;
127
128     finally
129       ALine.Free;
130     end;
131   finally
132     Lines.Free;
133   end;
134 end;
135
136 function FetchBmpFileAndPosition(Ghost: String;
137   Surface: integer; out Pos: integer): String;
138 var Ghosts, AGhost: TStringList;
139     i, dum: integer;
140     Dir, DefFileName, BmpFileName: String;
141 begin
142   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é
143   begin
144     DefFileName := Ghost2File.Values[Ghost];
145     BmpFileName := LoadDefinitionFile(Ghost, Surface,
146       DefFileName, dum);
147     if BmpFileName <> '' then
148     begin
149       Result := ExtractFilePath(DefFileName) + BmpFileName;
150       Pos := dum;
151       Exit;
152     end;
153   end;
154
155   // \93à\95\94\8aÖ\90\94\81Bghost.txt\82ð\93Ç\82Ý\8d\9e\82Þ\81B
156   Dir := ExtractFilePath(GhostFile);
157   Ghosts := TStringList.Create;
158   try
159     Ghosts.LoadFromFile(GhostFile);
160     for i := 0 to Ghosts.Count-1 do
161     begin
162       AGhost := TStringList.Create;
163       try
164         AGhost.CommaText := Ghosts[i];
165         if AGhost[0] <> 'GHOST' then
166           Continue;
167         DefFileName := Dir + AGhost[3];
168         // \92è\8b`\83t\83@\83C\83\8b\82ð\93Ç\82Ý\8d\9e\82Þ
169         BmpFileName := LoadDefinitionFile(Ghost, Surface,
170           DefFileName, dum);
171         if BmpFileName <> '' then
172         begin
173           Result := ExtractFilePath(DefFileName) + BmpFileName;
174           Pos := dum;
175           Break;
176         end;
177       finally
178         AGhost.Free;
179       end;
180     end;
181   finally
182     Ghosts.Free;
183   end;
184 end;
185
186 // 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
187 // H\82Å\8ew\92è\82³\82ê\82Ä\82¢\82é\83r\83b\83g\83}\83b\83v\82É\8f\91\82«\8fo\82·\82±\82Æ\81B
188 function GetImage(Ghost: PChar; Surface: integer; H: HBITMAP): integer; cdecl;
189 var Bmp, Bmp2: TBitmap;
190     BmpFile: String;
191     Position, x, y, nCol: integer;
192 begin
193   try
194     BmpFile := FetchBmpFileAndPosition(Ghost, Surface, Position);
195     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¢
196     begin
197       Result := 1;
198       Exit;
199     end;
200   except
201     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¢
202     begin
203       Result := 1;
204       Exit;
205     end;
206   end;
207
208   Bmp := TBitmap.Create;
209   try
210     Bmp.Handle := H;
211     Bmp2 := TBitmap.Create;
212     try
213       Bmp2.LoadFromFile(BmpFile);
214       nCol := Bmp2.Width div SurfaceWidth;
215       x := SurfaceWidth * (Position mod nCol);
216       y := SurfaceHeight * (Position div nCol);
217       Bmp.Canvas.CopyRect(
218         Rect(0, 0, Bmp.Width, Bmp.Height),
219         Bmp2.Canvas,
220         Rect(x, y, x+SurfaceWidth, y+SurfaceHeight)
221       );
222     finally
223       Bmp2.Free;
224     end;
225   finally
226     Bmp.ReleaseHandle;
227     Bmp.Free;
228   end;
229   Result := 0;
230 end;
231
232 // \83C\83\81\81[\83W\82Ì\91å\82«\82³\82ð\95Ô\82·\81B
233 // \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
234 // \82»\82ê\82È\82ç\92P\8f\83\82É\92è\90\94\82ð\95Ô\82µ\82Ä\8d·\82µ\8ex\82¦\82È\82¢\81B
235 // \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
236 function GetImageSize(Ghost: PChar; Surface: integer;
237   var w, h: integer): integer; cdecl;
238 begin
239   w := SurfaceWidth;
240   h := SurfaceHeight;
241   Result := 0;
242 end;
243
244
245 // DLL\8cÅ\97L\82Ì\90Ý\92è\82ð\8ds\82¤\81B
246 //
247 procedure Configure; cdecl;
248 var OpenDialog: TOpenDialog;
249     Ini: TIniFile;
250 begin
251   try
252     ShowMessage('Specify SSTP Viewer''s ghost file.');
253     OpenDialog := TOpenDialog.Create(nil);
254     try
255       OpenDialog.Filter := 'Ghost Definition File(ghost.txt)|ghost.txt|' +
256        'All Files(*.*)|*.*';
257       OpenDialog.FileName := GhostFile;
258       if OpenDialog.Execute then
259       begin
260         GhostFile := OpenDialog.FileName;
261         Ini := TIniFile.Create(MyPath + ConfigFile);
262         try
263           Ini.WriteString('SVG', 'GhostFile', GhostFile);
264         finally
265           Ini.Free;
266         end;
267         Ghost2File.Clear;
268       end;
269     finally
270       OpenDialog.Free;
271     end;
272   except
273     on E: Exception do
274       ShowMessage(E.Message);
275   end;
276 end;
277
278 exports
279   Load,
280   Unload,
281   GetVersion,
282   Configure,
283   GetImage,
284   GetImageSize;
285
286 begin
287
288 end.