├── TUITool ├── TUITool.exe ├── TUITool.ico ├── TUITool.res ├── romnames.db ├── sqlite3.dll ├── libeay32.dll ├── ssleay32.dll ├── tool ├── gamelist.sh └── gamelist.js ├── TUITool.lpr ├── README.md ├── TUITool.lpi ├── i18n ├── TUITool.pot ├── i18n.po └── i18n.en.po ├── mainform.lrj ├── TUITool.lps ├── mainform.lfm └── mainform.pas /TUITool: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryusatgat/trimuitool/HEAD/TUITool -------------------------------------------------------------------------------- /TUITool.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryusatgat/trimuitool/HEAD/TUITool.exe -------------------------------------------------------------------------------- /TUITool.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryusatgat/trimuitool/HEAD/TUITool.ico -------------------------------------------------------------------------------- /TUITool.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryusatgat/trimuitool/HEAD/TUITool.res -------------------------------------------------------------------------------- /romnames.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryusatgat/trimuitool/HEAD/romnames.db -------------------------------------------------------------------------------- /sqlite3.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryusatgat/trimuitool/HEAD/sqlite3.dll -------------------------------------------------------------------------------- /libeay32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryusatgat/trimuitool/HEAD/libeay32.dll -------------------------------------------------------------------------------- /ssleay32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryusatgat/trimuitool/HEAD/ssleay32.dll -------------------------------------------------------------------------------- /tool/gamelist.sh: -------------------------------------------------------------------------------- 1 | #for i in `ls */gamelist.xml` 2 | #do 3 | # echo processing $i ... 4 | # node gamelist.js $i 5 | #done 6 | 7 | for i in `ls */gamelist_en.xml` 8 | do 9 | echo processing $i ... 10 | node gamelist.js $i 1 11 | done 12 | -------------------------------------------------------------------------------- /TUITool.lpr: -------------------------------------------------------------------------------- 1 | program TUITool; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | uses 6 | {$IFDEF UNIX} 7 | cthreads, 8 | {$ENDIF} 9 | {$IFDEF HASAMIGA} 10 | athreads, 11 | {$ENDIF} 12 | Interfaces, // this includes the LCL widgetset 13 | Forms, memdslaz, lazcontrols, MainForm 14 | { you can add units after this }; 15 | 16 | {$R *.res} 17 | 18 | begin 19 | RequireDerivedFormResource:=True; 20 | Application.Title:='TrimUI Tool'; 21 | Application.Scaled:=True; 22 | Application.Initialize; 23 | Application.CreateForm(TFormMain, FormMain); 24 | Application.Run; 25 | end. 26 | 27 | -------------------------------------------------------------------------------- /tool/gamelist.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const xml2js = require('xml2js'); 4 | const sqlite3 = require('sqlite3').verbose(); 5 | 6 | const parser = new xml2js.Parser(); 7 | const db = new sqlite3.Database('./romnames.db'); 8 | 9 | if (process.argv.length == 4) { 10 | db.serialize(function() { 11 | const stmt = db.prepare('UPDATE romnames SET name = ? WHERE system = ? AND shortname = ?'); 12 | fs.readFile(process.argv[2], function(err, data) { 13 | parser.parseString(data, function(err, result) { 14 | for (const game of result.gameList.game) { 15 | stmt.run(game.name[0], path.dirname(process.argv[2]), path.parse(game.path[0]).filename); 16 | } 17 | stmt.finalize(); 18 | db.close(); 19 | }); 20 | }); 21 | }); 22 | } else if (process.argv.length == 3) { 23 | db.run('CREATE TABLE IF NOT EXISTS romnames(system varchar2, shortname varchar2, name varchar2, ename varchar2)'); 24 | 25 | db.serialize(function() { 26 | const stmt = db.prepare('INSERT INTO romnames(system, shortname, name, ename) VALUES (?, ?, ?, ?)'); 27 | fs.readFile(process.argv[2], function(err, data) { 28 | parser.parseString(data, function(err, result) { 29 | for (const game of result.gameList.game) { 30 | stmt.run(path.dirname(process.argv[2]), path.parse(game.path[0]).filename, game.name[0], path.parse(game.path[0])).filename; 31 | } 32 | stmt.finalize(); 33 | db.close(); 34 | }); 35 | }); 36 | }); 37 | } 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TrimUI Smart Pro Tool 2 | 3 | ![image](https://github.com/user-attachments/assets/f2ece30c-c5ff-495c-9813-f6fb26bd4aac) 4 | 5 | 6 | ## Getting ready to use 7 | 1. Turn off the TSP main unit completely. (Setting > System > Power off). 8 | 2. Remove the SD card from the unit and connect it to the PC. (The drive must be recognized) 9 | 3. Run the TRIMUI.exe file to bring up the screen. (The reference position will be set automatically) 10 | 4. If the reference position is not set automatically, press the ... button to select the SD card drive. 11 | 5. When the emulators are listed, they are ready for normal use. Please select the emulator you want to work with. 12 | 13 | ## To add a rom 14 | 1. Select the location where you want to add the rom. (Folder in the bottom left corner, no need to select a subfolder) 15 | 2. Right-click and select Add Rom or select Add Rom from the File menu. 16 | 3. Select the rom you want to add and click the Open button to add it to the list. 17 | 4. If you want to add all the roms that exist in the current emulator's rom folder, click the Regenerate Cache button. (If the Rom shortened filename is checked, it will automatically import the full name) 18 | 19 | ## Image Scraping 20 | 1. To scrape a screenshot, select the rom name from the list and click the Scrape button. 21 | 2. If "shortname" is checked in the details, only one will be scraped, and if it is unchecked, four will be scraped. (Rom shortened filename is an arcade filename, so don't uncheck it, and if you want to scrape more, enter a search term to search in the scrape search term and scrape it to get 4 images unconditionally) 22 | - Emulators with Rom shortened filename checked will get images from adb.arcadeitalia.net, and other emulators will get images from yahoo.com. You may get strange images, so choose the one you like the most. If you don't like all of them, please enter another search term in the scrape search box and press the scrape button. 23 | 3. Additionally, you can click on the scraped images to replace them with your own. 24 | 4. You can search and download your own images in a web browser and drag the files to TRIMUI Tool to add them. 25 | 5. Scrape All Emulators from the Scraper menu will scrape all the roms present in the rom (except if the images already exist), press ESC if you want to cancel the scraping. 26 | 27 | ## Rename Rom 28 | 1. Select a specific Rom from the Rom list and click it once again with the mouse or press F2 after selecting it to rename it. 29 | 2. You can also rename it in Korean and the changes will be saved to the SD card immediately. (The filename will not be changed.) 30 | 3. If you want to change the file name, please change the file name of the rom in Explorer and then click Generate cache.​ 31 | 32 | ## Create a subfolder 33 | 1. Right-click on the folder icon in the bottom left corner and click New folder. 34 | 2. Enter a name for the folder and click OK. 35 | 3. You can drag a rom from the parent folder to the folder (the rom from the physical SD card will be moved to the folder). 36 | 37 | ## Managing gamelist.xml 38 | 1. Clicking "Create a game list using gamelist.xml" from the XML menu will generate a list from the contents of gamelist.xml. (It will also recognize folder tags and save subfolder information.) 39 | 2. Clicking "Generate gamelist.xml" from the XML menu will save the contents of the current list as a gamelist.xml file and specify the gamelist entries in the details. 40 | 41 | ## TIP. What is "Generate cache"? 42 | 1. TSP stock OS creates and uses cache files of sqlite3 DB internally. Because of this, simply copying a rom file to an SD card will not be recognized. 43 | 2. TRIMUI Tool manages file lists and images by modifying this cache. 44 | 3. Therefore, if you click Refresh Roms in the TSP internal menu, the changed rom name will be changed to the original filename. 45 | 4. Please do not use the Refresh Roms function on TSP when managing the list with TRIMUI Tool. 46 | -------------------------------------------------------------------------------- /TUITool.lpi: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | <Scaled Value="True"/> 10 | <ResourceType Value="res"/> 11 | <UseXPManifest Value="True"/> 12 | <XPManifest> 13 | <DpiAware Value="True"/> 14 | <AnsiUTF8 Value="True"/> 15 | </XPManifest> 16 | <Icon Value="0"/> 17 | <Resources Count="2"> 18 | <Resource_0 FileName="i18n\i18n.en.po" Type="RCDATA" ResourceName="I18N.EN"/> 19 | <Resource_1 FileName="i18n\i18n.po" Type="RCDATA" ResourceName="I18N.KO"/> 20 | </Resources> 21 | </General> 22 | <i18n> 23 | <EnableI18N Value="True"/> 24 | <OutDir Value="i18n"/> 25 | </i18n> 26 | <BuildModes> 27 | <Item Name="Default" Default="True"/> 28 | <Item Name="Debug"> 29 | <CompilerOptions> 30 | <Version Value="11"/> 31 | <PathDelim Value="\"/> 32 | <Target> 33 | <Filename Value="TUITool"/> 34 | </Target> 35 | <SearchPaths> 36 | <IncludeFiles Value="$(ProjOutDir)"/> 37 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 38 | </SearchPaths> 39 | <Parsing> 40 | <SyntaxOptions> 41 | <IncludeAssertionCode Value="True"/> 42 | </SyntaxOptions> 43 | </Parsing> 44 | <CodeGeneration> 45 | <Checks> 46 | <IOChecks Value="True"/> 47 | <RangeChecks Value="True"/> 48 | <OverflowChecks Value="True"/> 49 | <StackChecks Value="True"/> 50 | </Checks> 51 | <VerifyObjMethodCallValidity Value="True"/> 52 | </CodeGeneration> 53 | <Linking> 54 | <Debugging> 55 | <DebugInfoType Value="dsDwarf3"/> 56 | <UseHeaptrc Value="True"/> 57 | <TrashVariables Value="True"/> 58 | <UseExternalDbgSyms Value="True"/> 59 | </Debugging> 60 | <Options> 61 | <Win32> 62 | <GraphicApplication Value="True"/> 63 | </Win32> 64 | </Options> 65 | </Linking> 66 | </CompilerOptions> 67 | </Item> 68 | <Item Name="Release"> 69 | <CompilerOptions> 70 | <Version Value="11"/> 71 | <PathDelim Value="\"/> 72 | <Target> 73 | <Filename Value="TUITool"/> 74 | </Target> 75 | <SearchPaths> 76 | <IncludeFiles Value="$(ProjOutDir)"/> 77 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 78 | </SearchPaths> 79 | <CodeGeneration> 80 | <SmartLinkUnit Value="True"/> 81 | <Optimizations> 82 | <OptimizationLevel Value="3"/> 83 | </Optimizations> 84 | </CodeGeneration> 85 | <Linking> 86 | <Debugging> 87 | <GenerateDebugInfo Value="False"/> 88 | <RunWithoutDebug Value="True"/> 89 | </Debugging> 90 | <LinkSmart Value="True"/> 91 | <Options> 92 | <Win32> 93 | <GraphicApplication Value="True"/> 94 | </Win32> 95 | </Options> 96 | </Linking> 97 | </CompilerOptions> 98 | </Item> 99 | </BuildModes> 100 | <PublishOptions> 101 | <Version Value="2"/> 102 | <UseFileFilters Value="True"/> 103 | </PublishOptions> 104 | <RunParams> 105 | <FormatVersion Value="2"/> 106 | </RunParams> 107 | <RequiredPackages> 108 | <Item> 109 | <PackageName Value="LazControls"/> 110 | </Item> 111 | <Item> 112 | <PackageName Value="LazControlDsgn"/> 113 | </Item> 114 | <Item> 115 | <PackageName Value="MemDSLaz"/> 116 | </Item> 117 | <Item> 118 | <PackageName Value="SQLDBLaz"/> 119 | </Item> 120 | <Item> 121 | <PackageName Value="DBFLaz"/> 122 | </Item> 123 | <Item> 124 | <PackageName Value="FCL"/> 125 | </Item> 126 | <Item> 127 | <PackageName Value="LCL"/> 128 | </Item> 129 | </RequiredPackages> 130 | <Units> 131 | <Unit> 132 | <Filename Value="TUITool.lpr"/> 133 | <IsPartOfProject Value="True"/> 134 | </Unit> 135 | <Unit> 136 | <Filename Value="mainform.pas"/> 137 | <IsPartOfProject Value="True"/> 138 | <ComponentName Value="FormMain"/> 139 | <HasResources Value="True"/> 140 | <ResourceBaseClass Value="Form"/> 141 | <UnitName Value="MainForm"/> 142 | </Unit> 143 | </Units> 144 | </ProjectOptions> 145 | <CompilerOptions> 146 | <Version Value="11"/> 147 | <PathDelim Value="\"/> 148 | <Target> 149 | <Filename Value="TUITool"/> 150 | </Target> 151 | <SearchPaths> 152 | <IncludeFiles Value="$(ProjOutDir)"/> 153 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 154 | </SearchPaths> 155 | <Linking> 156 | <Debugging> 157 | <DebugInfoType Value="dsDwarf3"/> 158 | </Debugging> 159 | <Options> 160 | <Win32> 161 | <GraphicApplication Value="True"/> 162 | </Win32> 163 | </Options> 164 | </Linking> 165 | </CompilerOptions> 166 | <Debugging> 167 | <Exceptions> 168 | <Item> 169 | <Name Value="EAbort"/> 170 | </Item> 171 | <Item> 172 | <Name Value="ECodetoolError"/> 173 | </Item> 174 | <Item> 175 | <Name Value="EFOpenError"/> 176 | </Item> 177 | </Exceptions> 178 | </Debugging> 179 | </CONFIG> 180 | -------------------------------------------------------------------------------- /i18n/TUITool.pot: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "Content-Type: text/plain; charset=UTF-8" 3 | 4 | #: mainform.i18n_added 5 | msgid "추가되었습니다" 6 | msgstr "" 7 | 8 | #: mainform.i18n_canceledscrape 9 | msgid "스크랩이 취소되었습니다" 10 | msgstr "" 11 | 12 | #: mainform.i18n_confirm 13 | msgid "확인" 14 | msgstr "" 15 | 16 | #: mainform.i18n_created 17 | msgid "생성되었습니다" 18 | msgstr "" 19 | 20 | #: mainform.i18n_deleteconfirm 21 | msgid "롬 파일을 삭제합니다. 계속 하시겠습니까?" 22 | msgstr "" 23 | 24 | #: mainform.i18n_deleted 25 | msgid "삭제되었습니다" 26 | msgstr "" 27 | 28 | #: mainform.i18n_deletedirconfirm 29 | msgid "폴더를 삭제합니다. 계속 하시겠습니까?" 30 | msgstr "" 31 | 32 | #: mainform.i18n_direxists 33 | msgid "폴더가 존재합니다" 34 | msgstr "" 35 | 36 | #: mainform.i18n_dirnotfound 37 | msgid "폴더를 찾을 수 없습니다" 38 | msgstr "" 39 | 40 | #: mainform.i18n_donescrape 41 | msgid "스크랩이 완료되었습니다" 42 | msgstr "" 43 | 44 | #: mainform.i18n_erroroccured 45 | msgid "오류가 발생하였습니다" 46 | msgstr "" 47 | 48 | #: mainform.i18n_fileexists 49 | msgid "파일이 존재합니다" 50 | msgstr "" 51 | 52 | #: mainform.i18n_filenotfound 53 | msgid "파일을 찾을 수 없습니다" 54 | msgstr "" 55 | 56 | #: mainform.i18n_gamelistconfirm 57 | msgid "캐시로부터 gamelist.xml 파일을 새로 생성합니다. 계속 하시겠습니까?" 58 | msgstr "" 59 | 60 | #: mainform.i18n_gencache 61 | msgid "캐시를 생성하고 있습니다..." 62 | msgstr "" 63 | 64 | #: mainform.i18n_inputdirname 65 | msgid "폴더명을 입력하세요" 66 | msgstr "" 67 | 68 | #: mainform.i18n_makedir 69 | msgid "폴더생성" 70 | msgstr "" 71 | 72 | #: mainform.i18n_noselemul 73 | msgid "선택된 에뮬레이터가 없습니다" 74 | msgstr "" 75 | 76 | #: mainform.i18n_processing 77 | msgid "처리중입니다" 78 | msgstr "" 79 | 80 | #: mainform.i18n_recacheconfirm 81 | msgid "캐시 파일을 재생성합니다. 계속 하시겠습니까?" 82 | msgstr "" 83 | 84 | #: mainform.i18n_romfrom 85 | msgid "롬 한글정보 출처: 텐타클팀(http://cafe.naver.com/raspigamer)" 86 | msgstr "" 87 | 88 | #: mainform.i18n_romnotselected 89 | msgid "롬을 먼저 선택해주세요" 90 | msgstr "" 91 | 92 | #: mainform.i18n_saved 93 | msgid "저장되었습니다" 94 | msgstr "" 95 | 96 | #: mainform.i18n_scrapestarted 97 | msgid " 스크랩이 시작되었습니다" 98 | msgstr "" 99 | 100 | #: tformmain.acabout.caption 101 | msgid "TrimUI 정보(&A)" 102 | msgstr "" 103 | 104 | #: tformmain.acaddrom.caption 105 | msgid "롬추가(&N)" 106 | msgstr "" 107 | 108 | #: tformmain.acbuildgamelist.caption 109 | msgid "&Gamelist.xml 생성" 110 | msgstr "" 111 | 112 | #: tformmain.accancelscrape.caption 113 | msgid "스크랩 취소(&C)" 114 | msgstr "" 115 | 116 | #: tformmain.acchangeimage.caption 117 | msgid "이미지 변경(&I)" 118 | msgstr "" 119 | 120 | #: tformmain.acdelete.caption 121 | msgid "삭제(&D)" 122 | msgstr "" 123 | 124 | #: tformmain.acdetectbasepath.caption 125 | msgid "기준위치 자동인식" 126 | msgstr "" 127 | 128 | #: tformmain.acexit.caption 129 | msgid "종료(&X)" 130 | msgstr "" 131 | 132 | #: tformmain.acgeneratecache.caption 133 | msgid "캐시 재생성(&C)" 134 | msgstr "" 135 | 136 | #: tformmain.acgithub.caption 137 | msgid "&Github" 138 | msgstr "" 139 | 140 | #: tformmain.acmkdir.caption 141 | msgid "폴더 생성(&F)" 142 | msgstr "" 143 | 144 | #: tformmain.acopenbasepath.caption 145 | msgid "기준위치 열기" 146 | msgstr "" 147 | 148 | #: tformmain.acopenimagepos.caption 149 | msgid "이미지 위치 열기(&O)" 150 | msgstr "" 151 | 152 | #: tformmain.acrefresh.caption 153 | msgid "새로 고침" 154 | msgstr "" 155 | 156 | #: tformmain.acrename.caption 157 | msgid "이름 바꾸기(&R)" 158 | msgstr "" 159 | 160 | #: tformmain.acrescrapeall.caption 161 | msgid "모두 스크랩(&A)" 162 | msgstr "" 163 | 164 | #: tformmain.acrmdir.caption 165 | msgid "폴더 삭제(&D)" 166 | msgstr "" 167 | 168 | #: tformmain.acsaveemuinfo.caption 169 | msgid "상세정보 저장(&V)" 170 | msgstr "" 171 | 172 | #: tformmain.acscrape.caption 173 | msgctxt "tformmain.acscrape.caption" 174 | msgid "스크랩(&S)" 175 | msgstr "" 176 | 177 | #: tformmain.acscrapemissing.caption 178 | msgid "누락 항목 스크랩(&M)" 179 | msgstr "" 180 | 181 | #: tformmain.btautodetect.caption 182 | msgid "!" 183 | msgstr "" 184 | 185 | #: tformmain.btopen.caption 186 | msgid "..." 187 | msgstr "" 188 | 189 | #: tformmain.btrefresh.caption 190 | msgid "⟳" 191 | msgstr "" 192 | 193 | #: tformmain.caption 194 | msgid "TrimUI Tool v0.9" 195 | msgstr "" 196 | 197 | #: tformmain.ckhidebios.caption 198 | msgid "바이오스숨기기" 199 | msgstr "" 200 | 201 | #: tformmain.ckshortname.caption 202 | msgid "롬 단축파일명" 203 | msgstr "" 204 | 205 | #: tformmain.ckuseswap.caption 206 | msgid "스왑 사용" 207 | msgstr "" 208 | 209 | #: tformmain.edsearch.hint 210 | msgid "스크래핑 시 해당 키워드를 통해 검색합니다" 211 | msgstr "" 212 | 213 | #: tformmain.groupbox1.caption 214 | msgid "상세정보" 215 | msgstr "" 216 | 217 | #: tformmain.label1.caption 218 | msgid "기준위치" 219 | msgstr "" 220 | 221 | #: tformmain.label2.caption 222 | msgid "에뮬레이터" 223 | msgstr "" 224 | 225 | #: tformmain.label3.caption 226 | msgid "스크랩검색어" 227 | msgstr "" 228 | 229 | #: tformmain.label4.caption 230 | msgid "레이블" 231 | msgstr "" 232 | 233 | #: tformmain.label5.caption 234 | msgid "롬 경로" 235 | msgstr "" 236 | 237 | #: tformmain.label6.caption 238 | msgctxt "tformmain.label6.caption" 239 | msgid "이미지 경로" 240 | msgstr "" 241 | 242 | #: tformmain.label7.caption 243 | msgid "확장자 목록" 244 | msgstr "" 245 | 246 | #: tformmain.label8.caption 247 | msgid "gamelist" 248 | msgstr "" 249 | 250 | #: tformmain.label9.caption 251 | msgid "아이콘" 252 | msgstr "" 253 | 254 | #: tformmain.listview.columns[0].caption 255 | msgid "롬이름" 256 | msgstr "" 257 | 258 | #: tformmain.listview.columns[1].caption 259 | msgctxt "tformmain.listview.columns[1].caption" 260 | msgid "이미지 경로" 261 | msgstr "" 262 | 263 | #: tformmain.listview.columns[2].caption 264 | msgid "롬파일명" 265 | msgstr "" 266 | 267 | #: tformmain.listview.columns[3].caption 268 | msgid "롬경로" 269 | msgstr "" 270 | 271 | #: tformmain.menuitem20.caption 272 | msgid "TrimUI Tool 정보(&A)" 273 | msgstr "" 274 | 275 | #: tformmain.menuitem23.caption 276 | msgid "언어(Language)" 277 | msgstr "" 278 | 279 | #: tformmain.menuitem4.caption 280 | msgid "파일(&F)" 281 | msgstr "" 282 | 283 | #: tformmain.menuitem5.caption 284 | msgid "도움말(&H)" 285 | msgstr "" 286 | 287 | #: tformmain.menuitem9.caption 288 | msgctxt "tformmain.menuitem9.caption" 289 | msgid "스크랩(&S)" 290 | msgstr "" 291 | 292 | #: tformmain.mnlangeng.caption 293 | msgid "&English(영어)" 294 | msgstr "" 295 | 296 | #: tformmain.mnlangeng.hint 297 | msgid "EN" 298 | msgstr "" 299 | 300 | #: tformmain.mnlangkor.caption 301 | msgid "한국어(&Korean)" 302 | msgstr "" 303 | 304 | #: tformmain.mnlangkor.hint 305 | msgid "KO" 306 | msgstr "" 307 | 308 | -------------------------------------------------------------------------------- /i18n/i18n.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: \n" 4 | "POT-Creation-Date: \n" 5 | "PO-Revision-Date: \n" 6 | "Last-Translator: \n" 7 | "Language-Team: \n" 8 | "Language: ko\n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "X-Generator: Poedit 3.4.4\n" 13 | 14 | #: mainform.i18n_added 15 | msgid "추가되었습니다" 16 | msgstr "추가되었습니다" 17 | 18 | #: mainform.i18n_canceledscrape 19 | msgid "스크랩이 취소되었습니다" 20 | msgstr "스크랩이 취소되었습니다" 21 | 22 | #: mainform.i18n_confirm 23 | msgid "확인" 24 | msgstr "확인" 25 | 26 | #: mainform.i18n_created 27 | msgid "생성되었습니다" 28 | msgstr "생성되었습니다" 29 | 30 | #: mainform.i18n_deleteconfirm 31 | msgid "롬 파일을 삭제합니다. 계속 하시겠습니까?" 32 | msgstr "롬 파일을 삭제합니다. 계속 하시겠습니까?" 33 | 34 | #: mainform.i18n_deleted 35 | msgid "삭제되었습니다" 36 | msgstr "삭제되었습니다" 37 | 38 | #: mainform.i18n_deletedirconfirm 39 | msgid "폴더를 삭제합니다. 계속 하시겠습니까?" 40 | msgstr "롬 파일을 삭제합니다. 계속 하시겠습니까?" 41 | 42 | #: mainform.i18n_direxists 43 | msgid "폴더가 존재합니다" 44 | msgstr "파일이 존재합니다" 45 | 46 | #: mainform.i18n_dirnotfound 47 | msgid "폴더를 찾을 수 없습니다" 48 | msgstr "디렉터리를 찾을 수 없습니다" 49 | 50 | #: mainform.i18n_donescrape 51 | msgid "스크랩이 완료되었습니다" 52 | msgstr "스크랩이 완료되었습니다" 53 | 54 | #: mainform.i18n_erroroccured 55 | msgid "오류가 발생하였습니다" 56 | msgstr "오류가 발생하였습니다" 57 | 58 | #: mainform.i18n_fileexists 59 | msgid "파일이 존재합니다" 60 | msgstr "파일이 존재합니다" 61 | 62 | #: mainform.i18n_filenotfound 63 | msgid "파일을 찾을 수 없습니다" 64 | msgstr "파일을 찾을 수 없습니다" 65 | 66 | #: mainform.i18n_gamelistconfirm 67 | msgid "캐시로부터 gamelist.xml 파일을 새로 생성합니다. 계속 하시겠습니까?" 68 | msgstr "캐시로부터 gamelist.xml 파일을 새로 생성합니다. 계속 하시겠습니까?" 69 | 70 | #: mainform.i18n_gencache 71 | msgid "캐시를 생성하고 있습니다..." 72 | msgstr "캐시를 생성하고 있습니다..." 73 | 74 | #: mainform.i18n_inputdirname 75 | msgid "폴더명을 입력하세요" 76 | msgstr "폴더명을 입력하세요" 77 | 78 | #: mainform.i18n_makedir 79 | msgid "폴더생성" 80 | msgstr "폴더생성" 81 | 82 | #: mainform.i18n_noselemul 83 | msgid "선택된 에뮬레이터가 없습니다" 84 | msgstr "선택된 에뮬레이터가 없습니다" 85 | 86 | #: mainform.i18n_processing 87 | msgid "처리중입니다" 88 | msgstr "처리중입니다" 89 | 90 | #: mainform.i18n_recacheconfirm 91 | msgid "캐시 파일을 재생성합니다. 계속 하시겠습니까?" 92 | msgstr "캐시 파일을 재생성합니다. 계속 하시겠습니까?" 93 | 94 | #: mainform.i18n_romfrom 95 | msgid "롬 한글정보 출처: 텐타클팀(http://cafe.naver.com/raspigamer)" 96 | msgstr "롬 한글정보 출처: 텐타클팀(http://cafe.naver.com/raspigamer)" 97 | 98 | #: mainform.i18n_romnotselected 99 | msgid "롬을 먼저 선택해주세요" 100 | msgstr "롬을 먼저 선택해주세요" 101 | 102 | #: mainform.i18n_saved 103 | msgid "저장되었습니다" 104 | msgstr "저장되었습니다" 105 | 106 | #: mainform.i18n_scrapestarted 107 | msgid " 스크랩이 시작되었습니다" 108 | msgstr " 스크랩이 시작되었습니다" 109 | 110 | #: tformmain.acabout.caption 111 | msgid "TrimUI 정보(&A)" 112 | msgstr "TrimUI 정보(&A)" 113 | 114 | #: tformmain.acaddrom.caption 115 | msgid "롬추가(&N)" 116 | msgstr "롬추가(&N)" 117 | 118 | #: tformmain.acbuildgamelist.caption 119 | msgid "&Gamelist.xml 생성" 120 | msgstr "&Gamelist.xml 생성" 121 | 122 | #: tformmain.accancelscrape.caption 123 | msgid "스크랩 취소(&C)" 124 | msgstr "스크랩 취소(&C)" 125 | 126 | #: tformmain.acchangeimage.caption 127 | msgid "이미지 변경(&I)" 128 | msgstr "이미지 변경(&I)" 129 | 130 | #: tformmain.acdelete.caption 131 | msgid "삭제(&D)" 132 | msgstr "삭제(&D)" 133 | 134 | #: tformmain.acdetectbasepath.caption 135 | msgid "기준위치 자동인식" 136 | msgstr "기준위치 자동인식" 137 | 138 | #: tformmain.acexit.caption 139 | msgid "종료(&X)" 140 | msgstr "종료(&X)" 141 | 142 | #: tformmain.acgeneratecache.caption 143 | msgid "캐시 재생성(&C)" 144 | msgstr "캐시 재생성(&C)" 145 | 146 | #: tformmain.acgithub.caption 147 | msgid "&Github" 148 | msgstr "&Github" 149 | 150 | #: tformmain.acmkdir.caption 151 | msgid "폴더 생성(&F)" 152 | msgstr "폴더 생성(&F)" 153 | 154 | #: tformmain.acopenbasepath.caption 155 | msgid "기준위치 열기" 156 | msgstr "기준위치 열기" 157 | 158 | #: tformmain.acopenimagepos.caption 159 | msgid "이미지 위치 열기(&O)" 160 | msgstr "이미지 위치 열기(&O)" 161 | 162 | #: tformmain.acrefresh.caption 163 | msgid "새로 고침" 164 | msgstr "새로 고침" 165 | 166 | #: tformmain.acrename.caption 167 | msgid "이름 바꾸기(&R)" 168 | msgstr "이름 바꾸기(&R)" 169 | 170 | #: tformmain.acrescrapeall.caption 171 | msgid "모두 스크랩(&A)" 172 | msgstr "모두 스크랩(&A)" 173 | 174 | #: tformmain.acrmdir.caption 175 | msgid "폴더 삭제(&D)" 176 | msgstr "폴더 삭제(&D)" 177 | 178 | #: tformmain.acsaveemuinfo.caption 179 | msgid "상세정보 저장(&V)" 180 | msgstr "상세정보 저장(&V)" 181 | 182 | #: tformmain.acscrape.caption 183 | msgctxt "tformmain.acscrape.caption" 184 | msgid "스크랩(&S)" 185 | msgstr "스크랩(&S)" 186 | 187 | #: tformmain.acscrapemissing.caption 188 | msgid "누락 항목 스크랩(&M)" 189 | msgstr "누락 항목 스크랩(&M)" 190 | 191 | #: tformmain.btautodetect.caption 192 | msgid "!" 193 | msgstr "!" 194 | 195 | #: tformmain.btopen.caption 196 | msgid "..." 197 | msgstr "..." 198 | 199 | #: tformmain.btrefresh.caption 200 | msgid "⟳" 201 | msgstr "⟳" 202 | 203 | #: tformmain.caption 204 | msgid "TrimUI Tool v0.9" 205 | msgstr "TrimUI Tool v0.9" 206 | 207 | #: tformmain.ckhidebios.caption 208 | msgid "바이오스숨기기" 209 | msgstr "바이오스숨기기" 210 | 211 | #: tformmain.ckshortname.caption 212 | msgid "롬 단축파일명" 213 | msgstr "롬 단축파일명" 214 | 215 | #: tformmain.ckuseswap.caption 216 | msgid "스왑 사용" 217 | msgstr "스왑 사용" 218 | 219 | #: tformmain.edsearch.hint 220 | msgid "스크래핑 시 해당 키워드를 통해 검색합니다" 221 | msgstr "스크래핑 시 해당 키워드를 통해 검색합니다" 222 | 223 | #: tformmain.groupbox1.caption 224 | msgid "상세정보" 225 | msgstr "상세정보" 226 | 227 | #: tformmain.label1.caption 228 | msgid "기준위치" 229 | msgstr "기준위치" 230 | 231 | #: tformmain.label2.caption 232 | msgid "에뮬레이터" 233 | msgstr "에뮬레이터" 234 | 235 | #: tformmain.label3.caption 236 | msgid "스크랩검색어" 237 | msgstr "스크랩검색어" 238 | 239 | #: tformmain.label4.caption 240 | msgid "레이블" 241 | msgstr "레이블" 242 | 243 | #: tformmain.label5.caption 244 | msgid "롬 경로" 245 | msgstr "롬 경로" 246 | 247 | #: tformmain.label6.caption 248 | msgctxt "tformmain.label6.caption" 249 | msgid "이미지 경로" 250 | msgstr "이미지 경로" 251 | 252 | #: tformmain.label7.caption 253 | msgid "확장자 목록" 254 | msgstr "확장자 목록" 255 | 256 | #: tformmain.label8.caption 257 | msgid "gamelist" 258 | msgstr "gamelist" 259 | 260 | #: tformmain.label9.caption 261 | msgid "아이콘" 262 | msgstr "아이콘" 263 | 264 | #: tformmain.listview.columns[0].caption 265 | msgid "롬이름" 266 | msgstr "롬이름" 267 | 268 | #: tformmain.listview.columns[1].caption 269 | msgctxt "tformmain.listview.columns[1].caption" 270 | msgid "이미지 경로" 271 | msgstr "이미지 경로" 272 | 273 | #: tformmain.listview.columns[2].caption 274 | msgid "롬파일명" 275 | msgstr "롬파일명" 276 | 277 | #: tformmain.listview.columns[3].caption 278 | msgid "롬경로" 279 | msgstr "롬경로" 280 | 281 | #: tformmain.menuitem20.caption 282 | msgid "TrimUI Tool 정보(&A)" 283 | msgstr "TrimUI Tool 정보(&A)" 284 | 285 | #: tformmain.menuitem23.caption 286 | msgid "언어(Language)" 287 | msgstr "언어(Language)" 288 | 289 | #: tformmain.menuitem4.caption 290 | msgid "파일(&F)" 291 | msgstr "파일(&F)" 292 | 293 | #: tformmain.menuitem5.caption 294 | msgid "도움말(&H)" 295 | msgstr "도움말(&H)" 296 | 297 | #: tformmain.menuitem9.caption 298 | msgctxt "tformmain.menuitem9.caption" 299 | msgid "스크랩(&S)" 300 | msgstr "스크랩(&S)" 301 | 302 | #: tformmain.mnlangeng.caption 303 | msgid "&English(영어)" 304 | msgstr "&English(영어)" 305 | 306 | #: tformmain.mnlangeng.hint 307 | msgid "EN" 308 | msgstr "" 309 | 310 | #: tformmain.mnlangkor.caption 311 | msgid "한국어(&Korean)" 312 | msgstr "한국어(&Korean)" 313 | 314 | #: tformmain.mnlangkor.hint 315 | msgid "KO" 316 | msgstr "KO" 317 | 318 | #~ msgid "en" 319 | #~ msgstr "en" 320 | -------------------------------------------------------------------------------- /i18n/i18n.en.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: \n" 4 | "POT-Creation-Date: \n" 5 | "PO-Revision-Date: 2024-07-07 11:45+0900\n" 6 | "Last-Translator: \n" 7 | "Language-Team: \n" 8 | "Language: en\n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "X-Generator: Poedit 3.4.4\n" 13 | "X-Poedit-Basepath: .\n" 14 | 15 | #: mainform.i18n_added 16 | msgid "추가되었습니다" 17 | msgstr "Added" 18 | 19 | #: mainform.i18n_canceledscrape 20 | msgid "스크랩이 취소되었습니다" 21 | msgstr "Canceled scraping" 22 | 23 | #: mainform.i18n_confirm 24 | msgid "확인" 25 | msgstr "Confirm" 26 | 27 | #: mainform.i18n_created 28 | msgid "생성되었습니다" 29 | msgstr "Generated" 30 | 31 | #: mainform.i18n_deleteconfirm 32 | msgid "롬 파일을 삭제합니다. 계속 하시겠습니까?" 33 | msgstr "Delete the ROM file. Do you want to continue?" 34 | 35 | #: mainform.i18n_deleted 36 | msgid "삭제되었습니다" 37 | msgstr "Deleted" 38 | 39 | #: mainform.i18n_deletedirconfirm 40 | msgid "폴더를 삭제합니다. 계속 하시겠습니까?" 41 | msgstr "Delete the folder. Do you want to continue?" 42 | 43 | #: mainform.i18n_direxists 44 | msgid "폴더가 존재합니다" 45 | msgstr "Folder exists" 46 | 47 | #: mainform.i18n_dirnotfound 48 | msgid "폴더를 찾을 수 없습니다" 49 | msgstr "Folder not found" 50 | 51 | #: mainform.i18n_donescrape 52 | msgid "스크랩이 완료되었습니다" 53 | msgstr "Scraping is complete" 54 | 55 | #: mainform.i18n_erroroccured 56 | msgid "오류가 발생하였습니다" 57 | msgstr "An error occurred" 58 | 59 | #: mainform.i18n_fileexists 60 | msgid "파일이 존재합니다" 61 | msgstr "File exists" 62 | 63 | #: mainform.i18n_filenotfound 64 | msgid "파일을 찾을 수 없습니다" 65 | msgstr "File not found" 66 | 67 | #: mainform.i18n_gamelistconfirm 68 | msgid "" 69 | "캐시로부터 gamelist.xml 파일을 새로 생성합니다. 계속 하시겠습니까?" 70 | msgstr "" 71 | "Create a new gamelist.xml file from the cache. Do you want to continue?" 72 | 73 | #: mainform.i18n_gencache 74 | msgid "캐시를 생성하고 있습니다..." 75 | msgstr "Creating a cache..." 76 | 77 | #: mainform.i18n_inputdirname 78 | msgid "폴더명을 입력하세요" 79 | msgstr "Enter the folder name" 80 | 81 | #: mainform.i18n_makedir 82 | msgid "폴더생성" 83 | msgstr "New folder" 84 | 85 | #: mainform.i18n_noselemul 86 | msgid "선택된 에뮬레이터가 없습니다" 87 | msgstr "There is no emulator selected" 88 | 89 | #: mainform.i18n_processing 90 | msgid "처리중입니다" 91 | msgstr "Processing" 92 | 93 | #: mainform.i18n_recacheconfirm 94 | msgid "캐시 파일을 재생성합니다. 계속 하시겠습니까?" 95 | msgstr "Regenerate cache file. Do you want to continue?" 96 | 97 | #: mainform.i18n_romfrom 98 | msgid "롬 한글정보 출처: 텐타클팀(http://cafe.naver.com/raspigamer)" 99 | msgstr "" 100 | "Source of ROM Korean information: Tentacle Team (http://cafe.naver.com/" 101 | "raspigamer)" 102 | 103 | #: mainform.i18n_romnotselected 104 | msgid "롬을 먼저 선택해주세요" 105 | msgstr "Please select the ROM first" 106 | 107 | #: mainform.i18n_saved 108 | msgid "저장되었습니다" 109 | msgstr "Saved" 110 | 111 | #: mainform.i18n_scrapestarted 112 | msgid " 스크랩이 시작되었습니다" 113 | msgstr " The scraping has begun" 114 | 115 | #: tformmain.acabout.caption 116 | msgid "TrimUI 정보(&A)" 117 | msgstr "About TUI Tool" 118 | 119 | #: tformmain.acaddrom.caption 120 | msgid "롬추가(&N)" 121 | msgstr "Add rom" 122 | 123 | #: tformmain.acbuildgamelist.caption 124 | msgid "&Gamelist.xml 생성" 125 | msgstr "&Generate Gamelist.xml" 126 | 127 | #: tformmain.accancelscrape.caption 128 | msgid "스크랩 취소(&C)" 129 | msgstr "&Cancel scraping" 130 | 131 | #: tformmain.acchangeimage.caption 132 | msgid "이미지 변경(&I)" 133 | msgstr "Change &Image" 134 | 135 | #: tformmain.acdelete.caption 136 | msgid "삭제(&D)" 137 | msgstr "&Delete" 138 | 139 | #: tformmain.acdetectbasepath.caption 140 | msgid "기준위치 자동인식" 141 | msgstr "Detect" 142 | 143 | #: tformmain.acexit.caption 144 | msgid "종료(&X)" 145 | msgstr "E&xit" 146 | 147 | #: tformmain.acgeneratecache.caption 148 | msgid "캐시 재생성(&C)" 149 | msgstr "Generate &cache" 150 | 151 | #: tformmain.acgithub.caption 152 | msgid "&Github" 153 | msgstr "&Github" 154 | 155 | #: tformmain.acmkdir.caption 156 | msgid "폴더 생성(&F)" 157 | msgstr "&New folder" 158 | 159 | #: tformmain.acopenbasepath.caption 160 | msgid "기준위치 열기" 161 | msgstr "Open" 162 | 163 | #: tformmain.acopenimagepos.caption 164 | msgid "이미지 위치 열기(&O)" 165 | msgstr "&Open Image Folder" 166 | 167 | #: tformmain.acrefresh.caption 168 | msgid "새로 고침" 169 | msgstr "Refresh" 170 | 171 | #: tformmain.acrename.caption 172 | msgid "이름 바꾸기(&R)" 173 | msgstr "&Rename" 174 | 175 | #: tformmain.acrescrapeall.caption 176 | msgid "모두 스크랩(&A)" 177 | msgstr "Scrape &all" 178 | 179 | #: tformmain.acrmdir.caption 180 | msgid "폴더 삭제(&D)" 181 | msgstr "&Delete folder" 182 | 183 | #: tformmain.acsaveemuinfo.caption 184 | msgid "상세정보 저장(&V)" 185 | msgstr "Sa&ve details" 186 | 187 | #: tformmain.acscrape.caption 188 | msgctxt "tformmain.acscrape.caption" 189 | msgid "스크랩(&S)" 190 | msgstr "&Scrape" 191 | 192 | #: tformmain.acscrapemissing.caption 193 | msgid "누락 항목 스크랩(&M)" 194 | msgstr "Scrape &missing" 195 | 196 | #: tformmain.btautodetect.caption 197 | msgid "!" 198 | msgstr "!" 199 | 200 | #: tformmain.btopen.caption 201 | msgid "..." 202 | msgstr "..." 203 | 204 | #: tformmain.btrefresh.caption 205 | msgid "⟳" 206 | msgstr "⟳" 207 | 208 | #: tformmain.caption 209 | msgid "TrimUI Tool v0.9" 210 | msgstr "TrimUI Tool v0.9" 211 | 212 | #: tformmain.ckhidebios.caption 213 | msgid "바이오스숨기기" 214 | msgstr "Hide bios" 215 | 216 | #: tformmain.ckshortname.caption 217 | msgid "롬 단축파일명" 218 | msgstr "Shortname" 219 | 220 | #: tformmain.ckuseswap.caption 221 | msgid "스왑 사용" 222 | msgstr "Use swap" 223 | 224 | #: tformmain.edsearch.hint 225 | msgid "스크래핑 시 해당 키워드를 통해 검색합니다" 226 | msgstr "Search with keyword when scraping" 227 | 228 | #: tformmain.groupbox1.caption 229 | msgid "상세정보" 230 | msgstr "Details" 231 | 232 | #: tformmain.label1.caption 233 | msgid "기준위치" 234 | msgstr "Base path" 235 | 236 | #: tformmain.label2.caption 237 | msgid "에뮬레이터" 238 | msgstr "Emulator" 239 | 240 | #: tformmain.label3.caption 241 | msgid "스크랩검색어" 242 | msgstr "Search word" 243 | 244 | #: tformmain.label4.caption 245 | msgid "레이블" 246 | msgstr "Label" 247 | 248 | #: tformmain.label5.caption 249 | msgid "롬 경로" 250 | msgstr "Rom path" 251 | 252 | #: tformmain.label6.caption 253 | msgctxt "tformmain.label6.caption" 254 | msgid "이미지 경로" 255 | msgstr "Image path" 256 | 257 | #: tformmain.label7.caption 258 | msgid "확장자 목록" 259 | msgstr "Extensions" 260 | 261 | #: tformmain.label8.caption 262 | msgid "gamelist" 263 | msgstr "gamelist" 264 | 265 | #: tformmain.label9.caption 266 | msgid "아이콘" 267 | msgstr "Icon" 268 | 269 | #: tformmain.listview.columns[0].caption 270 | msgid "롬이름" 271 | msgstr "Rom name" 272 | 273 | #: tformmain.listview.columns[1].caption 274 | msgctxt "tformmain.listview.columns[1].caption" 275 | msgid "이미지 경로" 276 | msgstr "Image path" 277 | 278 | #: tformmain.listview.columns[2].caption 279 | msgid "롬파일명" 280 | msgstr "Rom filename" 281 | 282 | #: tformmain.listview.columns[3].caption 283 | msgid "롬경로" 284 | msgstr "Rom path" 285 | 286 | #: tformmain.menuitem20.caption 287 | msgid "TrimUI Tool 정보(&A)" 288 | msgstr "About TUI Tool" 289 | 290 | #: tformmain.menuitem23.caption 291 | msgid "언어(Language)" 292 | msgstr "&Language" 293 | 294 | #: tformmain.menuitem4.caption 295 | msgid "파일(&F)" 296 | msgstr "&File" 297 | 298 | #: tformmain.menuitem5.caption 299 | msgid "도움말(&H)" 300 | msgstr "&Help" 301 | 302 | #: tformmain.menuitem9.caption 303 | msgctxt "tformmain.menuitem9.caption" 304 | msgid "스크랩(&S)" 305 | msgstr "&Scrape" 306 | 307 | #: tformmain.mnlangeng.caption 308 | msgid "&English(영어)" 309 | msgstr "&English" 310 | 311 | #: tformmain.mnlangeng.hint 312 | msgid "EN" 313 | msgstr "" 314 | 315 | #: tformmain.mnlangkor.caption 316 | msgid "한국어(&Korean)" 317 | msgstr "&Korean" 318 | 319 | #: tformmain.mnlangkor.hint 320 | msgid "KO" 321 | msgstr "" 322 | -------------------------------------------------------------------------------- /mainform.lrj: -------------------------------------------------------------------------------- 1 | {"version":1,"strings":[ 2 | {"hash":127367094,"name":"tformmain.caption","sourcebytes":[84,114,105,109,85,73,32,84,111,111,108,32,118,48,46,57,54],"value":"TrimUI Tool v0.96"}, 3 | {"hash":142165976,"name":"tformmain.ckforcepng.caption","sourcebytes":[234,176,149,236,160,156,32,112,110,103,32,235,179,128,237,153,152],"value":"\uAC15\uC81C png \uBCC0\uD658"}, 4 | {"hash":38331112,"name":"tformmain.label1.caption","sourcebytes":[234,184,176,236,164,128,236,156,132,236,185,152],"value":"\uAE30\uC900\uC704\uCE58"}, 5 | {"hash":12558,"name":"tformmain.btopen.caption","sourcebytes":[46,46,46],"value":"..."}, 6 | {"hash":60579,"name":"tformmain.btrefresh.caption","sourcebytes":[226,159,179],"value":"\u27F3"}, 7 | {"hash":172119648,"name":"tformmain.label2.caption","sourcebytes":[236,151,144,235,174,172,235,160,136,236,157,180,237,132,176],"value":"\uC5D0\uBBAC\uB808\uC774\uD130"}, 8 | {"hash":157693556,"name":"tformmain.label3.caption","sourcebytes":[236,138,164,237,129,172,235,158,169,234,178,128,236,131,137,236,150,180],"value":"\uC2A4\uD06C\uB7A9\uAC80\uC0C9\uC5B4"}, 9 | {"hash":147718036,"name":"tformmain.edsearch.hint","sourcebytes":[236,138,164,237,129,172,235,158,152,237,149,145,32,236,139,156,32,237,149,180,235,139,185,32,237,130,164,236,155,140,235,147,156,235,165,188,32,237,134,181,237,149,180,32,234,178,128,236,131,137,237,149,169,235,139,136,235,139,164],"value":"\uC2A4\uD06C\uB798\uD551 \uC2DC \uD574\uB2F9 \uD0A4\uC6CC\uB4DC\uB97C \uD1B5\uD574 \uAC80\uC0C9\uD569\uB2C8\uB2E4"}, 10 | {"hash":33,"name":"tformmain.btautodetect.caption","sourcebytes":[33],"value":"!"}, 11 | {"hash":170279908,"name":"tformmain.groupbox1.caption","sourcebytes":[236,131,129,236,132,184,236,160,149,235,179,180],"value":"\uC0C1\uC138\uC815\uBCF4"}, 12 | {"hash":124380292,"name":"tformmain.label4.caption","sourcebytes":[235,160,136,236,157,180,235,184,148],"value":"\uB808\uC774\uBE14"}, 13 | {"hash":257162828,"name":"tformmain.label5.caption","sourcebytes":[235,161,172,32,234,178,189,235,161,156],"value":"\uB86C \uACBD\uB85C"}, 14 | {"hash":166249404,"name":"tformmain.label6.caption","sourcebytes":[236,157,180,235,175,184,236,167,128,32,234,178,189,235,161,156],"value":"\uC774\uBBF8\uC9C0 \uACBD\uB85C"}, 15 | {"hash":262899493,"name":"tformmain.ckshortname.caption","sourcebytes":[235,161,172,32,235,139,168,236,182,149,237,140,140,236,157,188,235,170,133],"value":"\uB86C \uB2E8\uCD95\uD30C\uC77C\uBA85"}, 16 | {"hash":92095984,"name":"tformmain.ckhidebios.caption","sourcebytes":[235,176,148,236,157,180,236,152,164,236,138,164,236,136,168,234,184,176,234,184,176],"value":"\uBC14\uC774\uC624\uC2A4\uC228\uAE30\uAE30"}, 17 | {"hash":165302733,"name":"tformmain.label7.caption","sourcebytes":[237,153,149,236,158,165,236,158,144,32,235,170,169,235,161,157],"value":"\uD655\uC7A5\uC790 \uBAA9\uB85D"}, 18 | {"hash":138163828,"name":"tformmain.label8.caption","sourcebytes":[103,97,109,101,108,105,115,116],"value":"gamelist"}, 19 | {"hash":203479177,"name":"tformmain.ckuseswap.caption","sourcebytes":[236,138,164,236,153,145,32,236,130,172,236,154,169],"value":"\uC2A4\uC651 \uC0AC\uC6A9"}, 20 | {"hash":57271176,"name":"tformmain.label9.caption","sourcebytes":[236,149,132,236,157,180,236,189,152],"value":"\uC544\uC774\uCF58"}, 21 | {"hash":191488036,"name":"tformmain.listview.columns[0].caption","sourcebytes":[235,161,172,236,157,180,235,166,132],"value":"\uB86C\uC774\uB984"}, 22 | {"hash":166249404,"name":"tformmain.listview.columns[1].caption","sourcebytes":[236,157,180,235,175,184,236,167,128,32,234,178,189,235,161,156],"value":"\uC774\uBBF8\uC9C0 \uACBD\uB85C"}, 23 | {"hash":102048885,"name":"tformmain.listview.columns[2].caption","sourcebytes":[235,161,172,237,140,140,236,157,188,235,170,133],"value":"\uB86C\uD30C\uC77C\uBA85"}, 24 | {"hash":190730348,"name":"tformmain.listview.columns[3].caption","sourcebytes":[235,161,172,234,178,189,235,161,156],"value":"\uB86C\uACBD\uB85C"}, 25 | {"hash":52791353,"name":"tformmain.acscrape.caption","sourcebytes":[236,138,164,237,129,172,235,158,152,237,149,145,40,38,83,41],"value":"\uC2A4\uD06C\uB798\uD551(&S)"}, 26 | {"hash":160947737,"name":"tformmain.acrescrapeall.caption","sourcebytes":[235,170,168,235,145,144,32,236,138,164,237,129,172,235,158,152,237,149,145,40,38,65,41],"value":"\uBAA8\uB450 \uC2A4\uD06C\uB798\uD551(&A)"}, 27 | {"hash":119690809,"name":"tformmain.acscrapemissing.caption","sourcebytes":[235,136,132,235,157,189,32,237,149,173,235,170,169,32,236,138,164,237,129,172,235,158,152,237,149,145,40,38,77,41],"value":"\uB204\uB77D \uD56D\uBAA9 \uC2A4\uD06C\uB798\uD551(&M)"}, 28 | {"hash":193620297,"name":"tformmain.acrename.caption","sourcebytes":[236,157,180,235,166,132,32,235,176,148,234,190,184,234,184,176,40,38,82,41],"value":"\uC774\uB984 \uBC14\uAFB8\uAE30(&R)"}, 29 | {"hash":110225321,"name":"tformmain.acdelete.caption","sourcebytes":[236,130,173,236,160,156,40,38,68,41],"value":"\uC0AD\uC81C(&D)"}, 30 | {"hash":112456249,"name":"tformmain.accancelscrape.caption","sourcebytes":[236,138,164,237,129,172,235,158,152,237,149,145,32,236,183,168,236,134,140,40,38,67,41],"value":"\uC2A4\uD06C\uB798\uD551 \uCDE8\uC18C(&C)"}, 31 | {"hash":63339337,"name":"tformmain.acchangeimage.caption","sourcebytes":[236,157,180,235,175,184,236,167,128,32,235,179,128,234,178,189,40,38,73,41],"value":"\uC774\uBBF8\uC9C0 \uBCC0\uACBD(&I)"}, 32 | {"hash":117446921,"name":"tformmain.acopenimagepos.caption","sourcebytes":[236,157,180,235,175,184,236,167,128,32,236,156,132,236,185,152,32,236,151,180,234,184,176,40,38,79,41],"value":"\uC774\uBBF8\uC9C0 \uC704\uCE58 \uC5F4\uAE30(&O)"}, 33 | {"hash":206219113,"name":"tformmain.acsaveemuinfo.caption","sourcebytes":[236,131,129,236,132,184,236,160,149,235,179,180,32,236,160,128,236,158,165,40,38,86,41],"value":"\uC0C1\uC138\uC815\uBCF4 \uC800\uC7A5(&V)"}, 34 | {"hash":180066001,"name":"tformmain.acbuildgamelist.caption","sourcebytes":[38,103,97,109,101,108,105,115,116,46,120,109,108,32,236,131,157,236,132,177],"value":"&gamelist.xml \uC0DD\uC131"}, 35 | {"hash":194694696,"name":"tformmain.acrefresh.caption","sourcebytes":[236,131,136,235,161,156,32,234,179,160,236,185,168],"value":"\uC0C8\uB85C \uACE0\uCE68"}, 36 | {"hash":230869853,"name":"tformmain.acdetectbasepath.caption","sourcebytes":[234,184,176,236,164,128,236,156,132,236,185,152,32,236,158,144,235,143,153,236,157,184,236,139,157],"value":"\uAE30\uC900\uC704\uCE58 \uC790\uB3D9\uC778\uC2DD"}, 37 | {"hash":200088752,"name":"tformmain.acopenbasepath.caption","sourcebytes":[234,184,176,236,164,128,236,156,132,236,185,152,32,236,151,180,234,184,176],"value":"\uAE30\uC900\uC704\uCE58 \uC5F4\uAE30"}, 38 | {"hash":95535337,"name":"tformmain.acexit.caption","sourcebytes":[236,162,133,235,163,140,40,38,88,41],"value":"\uC885\uB8CC(&X)"}, 39 | {"hash":56861833,"name":"tformmain.acgeneratecache.caption","sourcebytes":[236,186,144,236,139,156,32,236,158,172,236,131,157,236,132,177,40,38,67,41],"value":"\uCE90\uC2DC \uC7AC\uC0DD\uC131(&C)"}, 40 | {"hash":251678745,"name":"tformmain.acabout.caption","sourcebytes":[84,114,105,109,85,73,32,236,160,149,235,179,180,40,38,65,41],"value":"TrimUI \uC815\uBCF4(&A)"}, 41 | {"hash":4795369,"name":"tformmain.acaddrom.caption","sourcebytes":[235,161,172,236,182,148,234,176,128,40,38,78,41],"value":"\uB86C\uCD94\uAC00(&N)"}, 42 | {"hash":40479625,"name":"tformmain.acmkdir.caption","sourcebytes":[237,143,180,235,141,148,32,236,131,157,236,132,177,40,38,70,41],"value":"\uD3F4\uB354 \uC0DD\uC131(&F)"}, 43 | {"hash":182497170,"name":"tformmain.acgithub.caption","sourcebytes":[38,71,105,116,104,117,98],"value":"&Github"}, 44 | {"hash":306025,"name":"tformmain.acrmdir.caption","sourcebytes":[237,143,180,235,141,148,32,236,130,173,236,160,156,40,38,68,41],"value":"\uD3F4\uB354 \uC0AD\uC81C(&D)"}, 45 | {"hash":73351257,"name":"tformmain.acscanext.caption","sourcebytes":[237,153,149,236,158,165,236,158,144,32,236,138,164,236,186,148,40,38,69,41],"value":"\uD655\uC7A5\uC790 \uC2A4\uCE94(&E)"}, 46 | {"hash":8648729,"name":"tformmain.acscrapetotal.caption","sourcebytes":[236,160,132,236,178,180,32,236,151,144,235,174,172,235,160,136,236,157,180,237,132,176,32,236,138,164,237,129,172,235,158,152,237,149,145,40,38,84,41],"value":"\uC804\uCCB4 \uC5D0\uBBAC\uB808\uC774\uD130 \uC2A4\uD06C\uB798\uD551(&T)"}, 47 | {"hash":229835009,"name":"tformmain.accachefromxml.caption","sourcebytes":[103,97,109,101,108,105,115,116,46,120,109,108,32,236,157,132,32,236,157,180,236,154,169,237,149,180,236,132,156,32,234,178,140,236,158,132,32,235,170,169,235,161,157,32,236,131,157,236,132,177],"value":"gamelist.xml \uC744 \uC774\uC6A9\uD574\uC11C \uAC8C\uC784 \uBAA9\uB85D \uC0DD\uC131"}, 48 | {"hash":109170489,"name":"tformmain.mnfile.caption","sourcebytes":[237,140,140,236,157,188,40,38,70,41],"value":"\uD30C\uC77C(&F)"}, 49 | {"hash":21530681,"name":"tformmain.mnscrape.caption","sourcebytes":[236,138,164,237,129,172,235,158,152,237,141,188,40,38,83,41],"value":"\uC2A4\uD06C\uB798\uD37C(&S)"}, 50 | {"hash":179484,"name":"tformmain.mnxml.caption","sourcebytes":[38,88,77,76],"value":"&XML"}, 51 | {"hash":49466729,"name":"tformmain.mnlanguage.caption","sourcebytes":[236,150,184,236,150,180,40,76,97,110,103,117,97,103,101,41],"value":"\uC5B8\uC5B4(Language)"}, 52 | {"hash":86404281,"name":"tformmain.mnlangkor.caption","sourcebytes":[237,149,156,234,181,173,236,150,180,40,38,75,111,114,101,97,110,41],"value":"\uD55C\uAD6D\uC5B4(&Korean)"}, 53 | {"hash":1279,"name":"tformmain.mnlangkor.hint","sourcebytes":[75,79],"value":"KO"}, 54 | {"hash":205420121,"name":"tformmain.mnlangeng.caption","sourcebytes":[38,69,110,103,108,105,115,104,40,236,152,129,236,150,180,41],"value":"&English(\uC601\uC5B4)"}, 55 | {"hash":1182,"name":"tformmain.mnlangeng.hint","sourcebytes":[69,78],"value":"EN"}, 56 | {"hash":42060169,"name":"tformmain.mnhelp.caption","sourcebytes":[235,143,132,236,155,128,235,167,144,40,38,72,41],"value":"\uB3C4\uC6C0\uB9D0(&H)"}, 57 | {"hash":26682457,"name":"tformmain.menuitem20.caption","sourcebytes":[84,114,105,109,85,73,32,84,111,111,108,32,236,160,149,235,179,180,40,38,65,41],"value":"TrimUI Tool \uC815\uBCF4(&A)"} 58 | ]} 59 | -------------------------------------------------------------------------------- /TUITool.lps: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <ProjectSession> 4 | <PathDelim Value="\"/> 5 | <Version Value="12"/> 6 | <BuildModes Active="Release"/> 7 | <Units> 8 | <Unit> 9 | <Filename Value="TUITool.lpr"/> 10 | <IsPartOfProject Value="True"/> 11 | <EditorIndex Value="-1"/> 12 | <CursorPos X="95" Y="26"/> 13 | <UsageCount Value="222"/> 14 | </Unit> 15 | <Unit> 16 | <Filename Value="mainform.pas"/> 17 | <IsPartOfProject Value="True"/> 18 | <ComponentName Value="FormMain"/> 19 | <HasResources Value="True"/> 20 | <ResourceBaseClass Value="Form"/> 21 | <UnitName Value="MainForm"/> 22 | <IsVisibleTab Value="True"/> 23 | <TopLine Value="22"/> 24 | <CursorPos X="33" Y="28"/> 25 | <UsageCount Value="222"/> 26 | <Bookmarks Count="2"> 27 | <Item0 X="10" Y="1447" ID="2"/> 28 | <Item1 X="11" Y="554" ID="1"/> 29 | </Bookmarks> 30 | <Loaded Value="True"/> 31 | <LoadedDesigner Value="True"/> 32 | </Unit> 33 | <Unit> 34 | <Filename Value="D:\lazarus\fpc\3.2.2\source\rtl\objpas\classes\classesh.inc"/> 35 | <EditorIndex Value="-1"/> 36 | <TopLine Value="1870"/> 37 | <CursorPos X="3" Y="1889"/> 38 | <UsageCount Value="16"/> 39 | </Unit> 40 | <Unit> 41 | <Filename Value="D:\lazarus\fpc\3.2.2\source\rtl\win\wininc\struct.inc"/> 42 | <EditorIndex Value="-1"/> 43 | <TopLine Value="1516"/> 44 | <CursorPos X="6" Y="1526"/> 45 | <UsageCount Value="16"/> 46 | </Unit> 47 | <Unit> 48 | <Filename Value="D:\lazarus\lcl\include\customform.inc"/> 49 | <EditorIndex Value="-1"/> 50 | <TopLine Value="906"/> 51 | <CursorPos Y="923"/> 52 | <UsageCount Value="16"/> 53 | </Unit> 54 | <Unit> 55 | <Filename Value="D:\lazarus\lcl\include\wincontrol.inc"/> 56 | <EditorIndex Value="-1"/> 57 | <TopLine Value="7416"/> 58 | <CursorPos Y="7433"/> 59 | <UsageCount Value="16"/> 60 | </Unit> 61 | <Unit> 62 | <Filename Value="D:\lazarus\fpc\3.2.2\source\rtl\win\messages.pp"/> 63 | <UnitName Value="Messages"/> 64 | <EditorIndex Value="-1"/> 65 | <UsageCount Value="16"/> 66 | </Unit> 67 | <Unit> 68 | <Filename Value="D:\lazarus\fpc\3.2.2\source\rtl\win\wininc\messages.inc"/> 69 | <EditorIndex Value="-1"/> 70 | <TopLine Value="1361"/> 71 | <CursorPos X="24" Y="1380"/> 72 | <UsageCount Value="16"/> 73 | </Unit> 74 | <Unit> 75 | <Filename Value="D:\lazarus\fpc\3.2.2\source\packages\fcl-process\src\simpleipc.pp"/> 76 | <EditorIndex Value="-1"/> 77 | <TopLine Value="110"/> 78 | <CursorPos X="41" Y="146"/> 79 | <UsageCount Value="129"/> 80 | </Unit> 81 | <Unit> 82 | <Filename Value="D:\lazarus\fpc\3.2.2\source\packages\fcl-xml\src\xmlwrite.pp"/> 83 | <UnitName Value="XMLWrite"/> 84 | <EditorIndex Value="-1"/> 85 | <TopLine Value="98"/> 86 | <CursorPos X="11" Y="115"/> 87 | <UsageCount Value="10"/> 88 | </Unit> 89 | <Unit> 90 | <Filename Value="D:\lazarus\fpc\3.2.2\source\packages\fcl-db\src\base\db.pas"/> 91 | <UnitName Value="DB"/> 92 | <EditorIndex Value="-1"/> 93 | <TopLine Value="1674"/> 94 | <CursorPos X="14" Y="1691"/> 95 | <UsageCount Value="17"/> 96 | </Unit> 97 | <Unit> 98 | <Filename Value="D:\lazarus\fpc\3.2.2\source\packages\fcl-db\src\base\dataset.inc"/> 99 | <EditorIndex Value="-1"/> 100 | <TopLine Value="1775"/> 101 | <CursorPos X="3" Y="1779"/> 102 | <UsageCount Value="10"/> 103 | </Unit> 104 | <Unit> 105 | <Filename Value="D:\lazarus\fpc\3.2.2\source\packages\fcl-db\src\memds\memds.pp"/> 106 | <EditorIndex Value="-1"/> 107 | <TopLine Value="1170"/> 108 | <CursorPos X="4" Y="1204"/> 109 | <UsageCount Value="10"/> 110 | </Unit> 111 | <Unit> 112 | <Filename Value="D:\lazarus\fpc\3.2.2\source\packages\fcl-db\src\base\bufdataset.pas"/> 113 | <UnitName Value="BufDataset"/> 114 | <EditorIndex Value="-1"/> 115 | <TopLine Value="622"/> 116 | <CursorPos X="14" Y="637"/> 117 | <UsageCount Value="3"/> 118 | </Unit> 119 | <Unit> 120 | <Filename Value="D:\lazarus\lcl\include\picture.inc"/> 121 | <EditorIndex Value="-1"/> 122 | <TopLine Value="596"/> 123 | <CursorPos Y="614"/> 124 | <UsageCount Value="88"/> 125 | </Unit> 126 | <Unit> 127 | <Filename Value="..\..\Delphi\ToolUI\FormMain.pas"/> 128 | <HasResources Value="True"/> 129 | <EditorIndex Value="-1"/> 130 | <TopLine Value="797"/> 131 | <CursorPos X="5" Y="804"/> 132 | <UsageCount Value="29"/> 133 | </Unit> 134 | <Unit> 135 | <Filename Value="D:\Games\trimui\Roms\CPS1\gamelist.xml"/> 136 | <EditorIndex Value="-1"/> 137 | <CursorPos X="40" Y="39"/> 138 | <UsageCount Value="29"/> 139 | <DefaultSyntaxHighlighter Value="XML"/> 140 | </Unit> 141 | <Unit> 142 | <Filename Value="D:\lazarus\fpc\3.2.2\source\rtl\objpas\sysutils\sysutilh.inc"/> 143 | <EditorIndex Value="-1"/> 144 | <TopLine Value="308"/> 145 | <CursorPos X="13" Y="330"/> 146 | <UsageCount Value="29"/> 147 | </Unit> 148 | <Unit> 149 | <Filename Value="D:\lazarus\fpc\3.2.2\source\rtl\objpas\sysutils\sysutils.inc"/> 150 | <EditorIndex Value="-1"/> 151 | <TopLine Value="154"/> 152 | <CursorPos X="36" Y="163"/> 153 | <UsageCount Value="29"/> 154 | </Unit> 155 | <Unit> 156 | <Filename Value="D:\lazarus\lcl\include\customaction.inc"/> 157 | <EditorIndex Value="-1"/> 158 | <TopLine Value="219"/> 159 | <CursorPos Y="244"/> 160 | <UsageCount Value="23"/> 161 | </Unit> 162 | <Unit> 163 | <Filename Value="D:\lazarus\fpc\3.2.2\source\rtl\win\sysutils.pp"/> 164 | <UnitName Value="SysUtils"/> 165 | <EditorIndex Value="-1"/> 166 | <UsageCount Value="23"/> 167 | </Unit> 168 | <Unit> 169 | <Filename Value="D:\lazarus\lcl\lcltranslator.pas"/> 170 | <UnitName Value="LCLTranslator"/> 171 | <EditorIndex Value="-1"/> 172 | <TopLine Value="328"/> 173 | <CursorPos Y="361"/> 174 | <UsageCount Value="72"/> 175 | </Unit> 176 | <Unit> 177 | <Filename Value="D:\lazarus\lcl\comctrls.pp"/> 178 | <UnitName Value="ComCtrls"/> 179 | <EditorIndex Value="-1"/> 180 | <TopLine Value="3135"/> 181 | <CursorPos X="14" Y="3151"/> 182 | <UsageCount Value="184"/> 183 | </Unit> 184 | <Unit> 185 | <Filename Value="D:\lazarus\lcl\include\treeview.inc"/> 186 | <EditorIndex Value="-1"/> 187 | <TopLine Value="796"/> 188 | <CursorPos Y="812"/> 189 | <UsageCount Value="99"/> 190 | </Unit> 191 | <Unit> 192 | <Filename Value="D:\lazarus\lcl\customtimer.pas"/> 193 | <UnitName Value="CustomTimer"/> 194 | <EditorIndex Value="-1"/> 195 | <TopLine Value="137"/> 196 | <CursorPos Y="155"/> 197 | <UsageCount Value="99"/> 198 | </Unit> 199 | <Unit> 200 | <Filename Value="D:\lazarus\lcl\interfaces\win32\win32callback.inc"/> 201 | <EditorIndex Value="-1"/> 202 | <TopLine Value="2954"/> 203 | <CursorPos Y="2979"/> 204 | <UsageCount Value="99"/> 205 | </Unit> 206 | <Unit> 207 | <Filename Value="D:\lazarus\lcl\interfaces\win32\win32object.inc"/> 208 | <EditorIndex Value="-1"/> 209 | <TopLine Value="389"/> 210 | <CursorPos X="19" Y="415"/> 211 | <UsageCount Value="99"/> 212 | </Unit> 213 | <Unit> 214 | <Filename Value="D:\lazarus\fpc\3.2.2\source\rtl\objpas\sysutils\diskh.inc"/> 215 | <EditorIndex Value="-1"/> 216 | <CursorPos X="2"/> 217 | <UsageCount Value="178"/> 218 | </Unit> 219 | <Unit> 220 | <Filename Value="D:\Games\trimui\Roms\SFC\gamelist.xml"/> 221 | <EditorIndex Value="-1"/> 222 | <TopLine Value="3709"/> 223 | <CursorPos X="39" Y="3725"/> 224 | <UsageCount Value="8"/> 225 | <DefaultSyntaxHighlighter Value="XML"/> 226 | </Unit> 227 | <Unit> 228 | <Filename Value="..\TUITool_old\mainform.pas"/> 229 | <UnitName Value="MainForm"/> 230 | <EditorIndex Value="-1"/> 231 | <TopLine Value="207"/> 232 | <CursorPos X="23" Y="234"/> 233 | <UsageCount Value="9"/> 234 | </Unit> 235 | <Unit> 236 | <Filename Value="D:\lazarus\fpc\3.2.2\source\packages\fcl-xml\src\xmlread.pp"/> 237 | <UnitName Value="XMLRead"/> 238 | <EditorIndex Value="-1"/> 239 | <CursorPos X="51" Y="16"/> 240 | <UsageCount Value="9"/> 241 | </Unit> 242 | <Unit> 243 | <Filename Value="E:\Roms\GBA\gamelist.xml"/> 244 | <EditorIndex Value="-1"/> 245 | <TopLine Value="202"/> 246 | <CursorPos X="11" Y="207"/> 247 | <UsageCount Value="13"/> 248 | <DefaultSyntaxHighlighter Value="XML"/> 249 | </Unit> 250 | </Units> 251 | <JumpHistory HistoryIndex="29"> 252 | <Position> 253 | <Filename Value="mainform.pas"/> 254 | <Caret Line="1529" TopLine="1521"/> 255 | </Position> 256 | <Position> 257 | <Filename Value="mainform.pas"/> 258 | <Caret Line="1534" Column="20" TopLine="1521"/> 259 | </Position> 260 | <Position> 261 | <Filename Value="mainform.pas"/> 262 | </Position> 263 | <Position> 264 | <Filename Value="mainform.pas"/> 265 | <Caret Line="65" Column="19" TopLine="39"/> 266 | </Position> 267 | <Position> 268 | <Filename Value="mainform.pas"/> 269 | <Caret Line="195" Column="29" TopLine="170"/> 270 | </Position> 271 | <Position> 272 | <Filename Value="mainform.pas"/> 273 | <Caret Line="259" Column="30" TopLine="234"/> 274 | </Position> 275 | <Position> 276 | <Filename Value="mainform.pas"/> 277 | <Caret Line="2327" Column="45" TopLine="2313"/> 278 | </Position> 279 | <Position> 280 | <Filename Value="mainform.pas"/> 281 | <Caret Line="1442" Column="50" TopLine="1425"/> 282 | </Position> 283 | <Position> 284 | <Filename Value="mainform.pas"/> 285 | <Caret Line="2303" Column="14" TopLine="2286"/> 286 | </Position> 287 | <Position> 288 | <Filename Value="mainform.pas"/> 289 | </Position> 290 | <Position> 291 | <Filename Value="mainform.pas"/> 292 | <Caret Line="2303" Column="14" TopLine="2277"/> 293 | </Position> 294 | <Position> 295 | <Filename Value="mainform.pas"/> 296 | <Caret Line="2334" Column="55" TopLine="2323"/> 297 | </Position> 298 | <Position> 299 | <Filename Value="mainform.pas"/> 300 | <Caret Line="1529" TopLine="1523"/> 301 | </Position> 302 | <Position> 303 | <Filename Value="mainform.pas"/> 304 | <Caret Line="260" TopLine="260"/> 305 | </Position> 306 | <Position> 307 | <Filename Value="mainform.pas"/> 308 | <Caret Line="280" Column="12" TopLine="258"/> 309 | </Position> 310 | <Position> 311 | <Filename Value="mainform.pas"/> 312 | <Caret Line="296" Column="4" TopLine="270"/> 313 | </Position> 314 | <Position> 315 | <Filename Value="mainform.pas"/> 316 | <Caret Line="559" Column="11" TopLine="539"/> 317 | </Position> 318 | <Position> 319 | <Filename Value="mainform.pas"/> 320 | <Caret Line="1085" Column="35" TopLine="981"/> 321 | </Position> 322 | <Position> 323 | <Filename Value="mainform.pas"/> 324 | <Caret Line="1448" Column="56" TopLine="1423"/> 325 | </Position> 326 | <Position> 327 | <Filename Value="mainform.pas"/> 328 | <Caret Line="1451" Column="22" TopLine="1426"/> 329 | </Position> 330 | <Position> 331 | <Filename Value="mainform.pas"/> 332 | <Caret Line="259" Column="15" TopLine="245"/> 333 | </Position> 334 | <Position> 335 | <Filename Value="mainform.pas"/> 336 | <Caret Line="2352" Column="5" TopLine="2328"/> 337 | </Position> 338 | <Position> 339 | <Filename Value="mainform.pas"/> 340 | <Caret Line="2346" Column="23" TopLine="2329"/> 341 | </Position> 342 | <Position> 343 | <Filename Value="mainform.pas"/> 344 | <Caret Line="1317" Column="34" TopLine="1312"/> 345 | </Position> 346 | <Position> 347 | <Filename Value="mainform.pas"/> 348 | <Caret Line="558" Column="11" TopLine="539"/> 349 | </Position> 350 | <Position> 351 | <Filename Value="mainform.pas"/> 352 | <Caret Line="1060" Column="13" TopLine="1039"/> 353 | </Position> 354 | <Position> 355 | <Filename Value="mainform.pas"/> 356 | <Caret Line="1069" Column="35" TopLine="1061"/> 357 | </Position> 358 | <Position> 359 | <Filename Value="mainform.pas"/> 360 | <Caret Line="259" Column="15" TopLine="245"/> 361 | </Position> 362 | <Position> 363 | <Filename Value="mainform.pas"/> 364 | <Caret Line="2350" Column="42" TopLine="2320"/> 365 | </Position> 366 | <Position> 367 | <Filename Value="mainform.pas"/> 368 | <Caret Line="2370" Column="23" TopLine="2363"/> 369 | </Position> 370 | </JumpHistory> 371 | <RunParams> 372 | <FormatVersion Value="2"/> 373 | <Modes ActiveMode="default"> 374 | <Mode Name="default"> 375 | <local> 376 | <CommandLineParams Value="--lang en"/> 377 | </local> 378 | </Mode> 379 | </Modes> 380 | </RunParams> 381 | <HistoryLists> 382 | <List Name="LaunchingApplication" Type="File" Count="1"> 383 | <Item1 Value="C:\WINDOWS\system32\cmd.exe /C ${TargetCmdLine}"/> 384 | </List> 385 | <List Name="CommandLineParameters" Count="1"> 386 | <Item1 Value="--lang EN"/> 387 | </List> 388 | </HistoryLists> 389 | </ProjectSession> 390 | <Debugging> 391 | <Watches> 392 | <Item> 393 | <Expression Value="Msg"/> 394 | </Item> 395 | <Item> 396 | <Expression Value="Msg.DataStruct^"/> 397 | </Item> 398 | <Item> 399 | <Expression Value="Msg.DataStruct^.lpData"/> 400 | </Item> 401 | </Watches> 402 | </Debugging> 403 | </CONFIG> 404 | -------------------------------------------------------------------------------- /mainform.lfm: -------------------------------------------------------------------------------- 1 | object FormMain: TFormMain 2 | Left = 993 3 | Height = 673 4 | Top = 141 5 | Width = 918 6 | AllowDropFiles = True 7 | Caption = 'TrimUI Tool v0.96' 8 | ClientHeight = 673 9 | ClientWidth = 918 10 | Menu = MainMenu 11 | OnClose = FormClose 12 | OnCreate = FormCreate 13 | OnDestroy = FormDestroy 14 | OnDropFiles = FormDropFiles 15 | OnShow = FormShow 16 | LCLVersion = '3.4.0.0' 17 | object pnImage: TPanel 18 | Left = 692 19 | Height = 573 20 | Top = 0 21 | Width = 226 22 | Align = alRight 23 | BevelOuter = bvNone 24 | ClientHeight = 573 25 | ClientWidth = 226 26 | TabOrder = 1 27 | object Image: TImage 28 | Left = 13 29 | Height = 290 30 | Top = 38 31 | Width = 200 32 | Center = True 33 | ParentShowHint = False 34 | PopupMenu = pmImage 35 | Proportional = True 36 | ShowHint = True 37 | end 38 | object NoImage: TImage 39 | Left = 27 40 | Height = 171 41 | Top = 98 42 | Width = 172 43 | Picture.Data = { 44 | 1754506F727461626C654E6574776F726B47726170686963D016000089504E47 45 | 0D0A1A0A0000000D49484452000000AC000000AB0806000000FB347760000000 46 | 017352474200AECE1CE90000000467414D410000B18F0BFC6105000000097048 47 | 597300000EC300000EC301C76FA8640000166549444154785EED9D3FACDEB615 48 | C5B314488106F0D0C153E10219820E41462F453D1A28827A343A65F4566FF152 49 | 78ABC774CB98A5C01B3D66F418204B468F1E337AF4F8F5FCDE93623DBE4B8A94 50 | 7845EAFB7480637F4F7F288A3ABCBCBC24A54F4E07F2F1F6EDE9F4E6CDE9F4F2 51 | E56D3E7E7C3A3D7A34CF172F6E9FF7FAF5E9F4D34F43E20772700836C4FBF737 52 | A2FCE1878F62FCEA2B95948ACA930F1E7C14F577DFDDE4E1D75F874C1D18A192 53 | BA707CF8703AFDF8E38D501E3EBC2BA4D6FCE28BD3E9D9B3D3E9EAEA10B0A012 54 | B9408CCD3A16CD1249CFC4DA3F7F7EE34ED01A5C1854021702ACE837DF9C4EF7 55 | EEDD15C19EF9E4C98DFB424B7101D01D9F317EF9E5A639BD7FFFEE833E377EFA 56 | E9E9F4F4E98DE53D63E84ECF0CEFDEDD34F7F87ED683BD045241A9A8671881D0 57 | DD9D09102A4DBEF5002F99F8E9F8EC6702DDD1CE41B38F1F673DAC831F8970F1 58 | E3770EDDC94E710875198932ECD8CFD51DEC0C8C361D425D4F84BB438BAB9CEF 59 | 04C41C09EE5B857F7039A9FC3B1A90508E770046792E2134D58A84C45EBDDA45 60 | 2C57B9ED1834FF8CE55B857CB03E090576EE2628971D829A4EF34FCDB70AF6A0 61 | 2F3B761394BBCE8055DD6276D4C13419C2EED0DA2A671D8131F1731BEBDF3B69 62 | E93AF26D95A30E40811CA354FD9269978C247600E5A6311800B8E471FFBD9096 63 | 8F684D6328270DC1CCFAA363B52F32A9A6A18BA01C34C23108B05F126A6C245A 64 | 5DBD01F6EEAF329184B9A7E362423A8BCC884A91F1FBF178EE9F34F6DCC12492 65 | D360C583AEBC21A8957B1A0818D7537DFFFD8DE83C629394096923FA5ED795C5 66 | 886837EE8CE9AA1B81DAD8FBC360E52AD60FF1B40C9C23622C326BB77A8F4953 67 | 66C4CE3782AEB801A885BD163C731410C686855E0C2A0F1DD45EA329B836447B 68 | 3680AEE60CC44A2DB46EB41529602CE91E273453B1A8603D96E906A2D5951C81 69 | 1BD09365C5429DD30A532A5C4F4BD511AD734BA5AB380151F4E2B35269CE7935 70 | 299DB65E848BE577EC88E90A0EE8251AC0433CF365CFB7C02AD91E5663D09239 71 | 85BC94BA035AC759E9485D92504360715B77D068D51C5C2FA55C197408AC1BD8 72 | 8AC4321B04B4BB04AB085A0E4E388C8829D58A20F462657C0BD2FCF71C9A6A05 73 | 42628CCA5965B605696D2B42295602FE538B892C5C939EFF813470135A85C22A 74 | 3E1FA5560134C1AD0AE33FFF19327160163CA7169D328C4AA5D64FA95540EB90 75 | CA6161CBD0625A2706AD42DF4229AD04B38FAC0C6ECD43B4656831711EEBBE12 76 | 4A6505F08BAC8CB5E28C687FD1437AA33C87FC75C144979FE4B387E97C58D023 77 | E69CD7AF5FABDEBF3C3D7BF64C8DD5A36B7EA3CE0ADBAEAEAE16A59B052CDED6 78 | 833B58F715500A0BC143EEF1E51609D122844F744CC8873CB4423C501317A6F3 79 | AE6084E7AD7CBAA7EABD8769C4C8B154B8EAA0326C39C8832BB2E235A04A6121 80 | 7A18518931528B638285DF33E7B5004B058BB5C49286E7E692735D2CEE96833D 81 | 2B061574F60230E9C2CA484FC4B70E9012ECA7AAF925AEC112C1BE57138C350F 82 | CF2B25F7415AD5B1E5B2A585AE81CE2C0435A3D779992103D1A6040B1FD33466 83 | A254B058C5AF6459C27342DEBB77EF9AD6BE2911BE8BA5DDAA138D6BB0A0EFA0 84 | 330BC1709F95815E3911ED9C60E10F99D18652C1D2890A8F1F4945A173353D9F 85 | DF6C4BE5F939C3E01ED8CA3D6004AE103AAB00D488ADE3773538883647B0F7D5 86 | 91CC710D4A044B14203C76648EE838C63A17BA74C4C0561DB1376F860BE64167 87 | 14A0E78ED61C255A4BB05FC8BD09B7D1239F43896063AE4049478F109795C693 88 | 0AB14D13B81B2A2F5DC497851D309D91893D74B466F8C81019CD2E1DAE70FB8F 89 | 33CB6772051BB3AE88B804F8AB587F2B2D42642EA063B7457FA5A003A6A33341 90 | 015B17DB111F89E1C346B096F5421CA94E4DAE6063BE2B422EC5777AB0565A6C 91 | 770395C17B8A22F1FC4C2BABA33340E15A17DA192DC1D2C98AF5E08979C6902B 92 | 58EBB8250315807C8669412A852BB678FE99954E4766E00CAC2B8C0916D07909 93 | F741865C2DE40896CE5B780C5CD3BBB7AE8B1FEE0EEF89F999565647CEC0BB76 94 | 91D1FFFED7DE579929C182172F5EDCD98F182CD72047B0B14AB0A609B73A8EB8 95 | 2FEEA00CBCE71D64948B8E9A817726470B8670ACFD15690AF61FFFB8B9BE8030 96 | ADA801420E912358AC73780C5CE2BF8E88F9C49B80FBF30C6B6658591D950031 97 | 3E2BE15A0CC347CEA235052B4E07179885151E4314218C77E60816EB1D1E03B9 98 | C652C4C25B9B012BC8F5BC3863657544029E71577A9E5680DE51B451C1C28915 99 | B526A78461A81CC1C6425A442696C2B2B054A8CD8005F4ECD3CC58591D1181B7 100 | 754DD52427D126050B87DE36AE8125C8570C4B0FC811AC65ADE1349D52583E2C 101 | 79D914B871BAAE1B79FE11686F049EBDC2C05A99C00A55F69766050B07D15AFE 102 | 27966C0CD2E7083616254885CBE6605D17116F0ECA49D77661E27EB4D7002619 103 | D36C255683B93E1CA34D15459B25583888D6720D4671E4081658A353A5A35C23 104 | 621500BF7673E0CE553628B7689425D01E039EA1ACD2B1EF8AA2CD162C946899 105 | 736A098ECE9435D0600996B1FEF038B8C48F8D4D825913755805CF56385209B5 106 | C78067672BE86D67A192688B040B255AE61484E720622BFC650936D6F19A1BFA 107 | 0D8175B5E63C94A653159E5636E2976B4F00CF4CAC99595441B4C58285126D6A 108 | 2EEB94966081658D21E9E6880D4BCF9C592B0DD7790439F0B4B2C628A3B606F0 109 | 8CB32DB1AE53AC14ED22C18AEFFFF94FD3350819136CCCCA427CE2D472173A79 110 | 963587F8D1CDACEB084F03A70A1D425B0378C5D8167634EE608568970A165EFD 111 | ED6FFAEFEEF953C6040B52561AE1B19FF9B1E39271425FCCCB8D2D97C13D5833 112 | 0051155E5696E71C54486D9D8002B74EACC19A1D8385A25D2358F8F4CF7FD67F 113 | 77D31899122C9630E61A2CE1740E4473785AD94037DA3281D72853C4815E8505 114 | A25D2BD85FC5FBBFFFBD7EDE4D07A6040B106DCC17CD2596B559542005AF8E3A 115 | D67B026D99009FC13A692DBDE28485A25D2B58C8F1611A23E7043B82B869CECA 116 | D890F8BBDDB80121A844CA637506AEA4B64C8025B44E5ACBCC07B90805A2AD21 117 | 58F8580CD381B9820574B4F053631DAA91585462B95D5AD529F035D53155A6EB 118 | 73D229D55F03286CEBE0B5DC62D87045476C158D5EEC1220743A5A74BAB0BE90 119 | F82FDB7605AFCED7A4B2EAAF015EFEEB569D8356A2653974EBD0522FF09A3035 120 | F163F5D7000FFF15016DF93011ADF782398B87683F422E8E59466B38F163F5D7 121 | 000FFF750B772004B5FC106D3B78B905831FAB5F8297FFEA151D98C321DA76F0 122 | 8A160C7EAC7E095E1769D9693844DB065842AB5CD67298F4AE5F027F5807ADE1 123 | D6FEAB8543B46DE031BC3FACFFD32FC1A3C3D5C27FB57088767B78F8B143C74B 124 | BF048FA5DCADFC570B8768B785878B498B2DE897E0F1300931F58443B4DB81C9 125 | 305659ACE5DBB712AC63E2DDE110ED76F02867596EDE2B69EF5CC3C17C778943 126 | B4DBC0C3CD7CF54A82F5586110CCB0E90E8768FDE1D191579AAC11B677AEE182 127 | 77D76F8E43B4BEF008953E7A24C17AD48421C8DB3D5A8996E632B18EEB2CE011 128 | 2970136C4FCB37E6D04AB4B84DE72C5A269A5BF7BD862A33BEEA60EF5CC33D09 129 | 163097C26BF27A8AE72C5A8FF9297A46ACBBB077AE61620E01AFAD1C57868E4C 130 | 7D54C23A7ECA35B895D6D5D5E9CDFDFBA737CA3F7C37BD9F02BE15C734A664BB 131 | 75FC5AD1B24E8CC9DE4CFAE63DB62CA319C9DF6CE7DD05E1EB422DCC95758A77 132 | 565B9C8B6029C87019084B9C63B08E9F92C25A021E8E95DEC897A27E14F38168 133 | A5C776FDB0B940B4DC77E98246DEAD90FAA4D35C59A748C5B8053A96DA5E9B2C 134 | 8A3777AC62A236D7166CEADC14521F6B834B048B25B5D21AF993A81F3633454B 135 | 455B232C184355C1026DAF4D1FC186CDC304B505CB22BDD2B79F70FCDC9B5C5E 136 | 2EE8883D13ADB446B25F3FE29C116DEC9B62A58C611F82F558E9B8A16061E94B 137 | 2552AF0E1AF9F25FFF2AEA887D10EF89565A23D9CF71FA23CE886859616BA519 138 | 928A4899A52A640CD505EB600C776761B130E19A7E8E2941F80A4CEB5DAFD70F 139 | 80FBC82C9F2B314CC35A56FE5AD48F3403D1CE5530DE638B4F6B7D2397CE109D 140 | 32CA78B4CE31943E9B5938840B7D049BE8F5AF152CB4DEB99AFB4E00EBB59556 141 | 7ABF598C4CD186EF2AF854B45EBAF144D48F790EA22582127303B0A2252FD6E0 142 | 5D08A9EFDB5617ACCEAF4D3ECB67EE5845E72881D53C9A4D9281F0DCF1456CD3 143 | 6DF0567A33A2E51546E1F958576B3B427E2FEA8F794AB44FFEFE77FDBC9B0EE5 144 | 927AEBE112EC43B0CAA4B563159D056B85A4105E0EC237ADD09C12EA996E8377 145 | 2A4042B4AFC4F0FCEF45F6596EC1B86F8EBF88E1B9108B5BF296995C54152CF9 146 | D3F955892B783D19C3DAB98689D7A1D7106CEC4D80733159EBAB2E6CB3AE615A 147 | EC8868BF10C3F3B1AEEC439CE1BE8722FBE6F8420CCF855E2F31EE5EB02A7B72 148 | 64EF5CC344AFBD8660B12E3CB470FB5CE1861FD9C0DA826CC18240B49615C4AA 149 | B20F5A6E01CC1949FB4A0CCF1BF3EC81AA822516AFF3ABD24DB0090B504BB056 150 | E789BF633159B687D105FC595024583011EDF3E03C1836F9965B303730819F1B 151 | 9E039F7EFDF59089FAA82A588F8501E4EFFA0B80D6CE354C7C87AA966081D5BB 152 | 8FC56409BA87C78E61A062C1029DFBE1CB2F4FF783F3E0E80E8CB4DC82E450AD 153 | 18F35FAF073486FB0F513217C0AAD85639E490F3EE806884F65525F9BB9EBB6A 154 | ED5C43220F11D414AC159F340B4F08C7DDF97B84758D59C10AAFFFF7BF3BE74D 155 | DD819131B72035541B1BE625DE7B6DDD0DD15AF711A3D5692B397F4AB3CC3D96 156 | 7A63A05C26DA620522B00A65A9608135A2133E0C2C6978CCF43B59D63572046B 157 | 59F85804C0720B5243B5B117272364FD30455B223877C17A74E6E50D7C721DE4 158 | B776AE6524466815CA1AC132852EDC1F8A2D8CBDE2CB4E9B44EB1A7382B57C68 159 | 18BA03232DB7203554CB8858783CBC35521688B64470EE82F518F2C7ADBB4EDC 160 | DAB996911118AB50D6089691A0707F18930D875EC36FBD5AD79813AC15A578F4 161 | 873FD86521C6DC82D8506DCC2520E6AB1F1F39116D89E072054BF890B248F14E 162 | BF0163A573AB93F8FBF5053CDEE9191902AC2D58F0503E73780C1D0BC0FFE1BE 163 | 7038738960AD6B3EF8D39FAE454BF36F9151AEF09CD8502D61AFF05868BA1186 164 | 7B3082B2B2D2C9156CEAD94441F9EADCEA54ABA87F05F962E6016B18B9510FC1 165 | 52C3C363701540187BC562842815AC65D5973235546BCDFE6290827D7718116D 166 | 13C112D6D4B95539C49FF54BF0086D05CDF2080FC1E28F86FEE428CCD01DB046 167 | 894A056BF9CD6B18EBA8617DADE3A333BE0CD13611AC8701244D41BF047ACCD6 168 | 416B59A15072040B48233C2E8CBD22EA31F63A45A960E7267F973236546B75D4 169 | 20B1DFE8BCDA40B44D044B9448E756E5D062EA97E0318C068D20BE97602D5F35 170 | B4AE84A12C9408D6FABA37C4F5E09C5BFCF6DBD34B899B51AD91D14F2689FA71 171 | 8B88D21A98808CB0E987CD89683717AC97968630A47E0DF0A815C6CD7A0916CC 172 | 7DF32AF6ADAB12C15A33BBB0B851D063C63DD17190D5B3E1F9303654FB9D681D 173 | 0FB1CCD1D5B883683717AC87FF0A87FCEAD7000FBF83420BE029D8D432124415 174 | 9B67902B58E69F5AB1D7304C76078168ADD95DA9A1DA982F0BE9B431AB0BF7E1 175 | B7410591A1DD1FFEF8C7D3E3BFFEF5D6F12373059B13D61A793D3FD763C060A2 176 | 23FD35C0AB660CE1A5119E82B546B446B24A36865CC15AD1083886D092988816 177 | 6B6AA5131BAAC535B0666EAD61AE604BF8EEE79F7DBE9536D187FE1AE0E57B04 178 | 62F4142C88ADD56762480CB982B58E63D42C1B885669C4DC82D4502DA1AF98FF 179 | BB842E82FDF7BFCDBCAFE6A42FA4BF26F0F063A97133C3A035056B4D88B162AF 180 | 53E408966B86C7C0621F8FB250A5B2DC829C55B558E7B9D5B92932E0414B5173 181 | B6D6C8777FF98B99E7D59C3C6FFD3581871F0B2735C45BB03C8830EC3437433F 182 | 47B0FC1D1E03891A1443797CF9F9E7667A39AB6A11353E2BA367561A211138D6 183 | FBED679FDDB4A411AC16ACA81F7519F483B465022F3F56057120C06069CDF22A 184 | 249DAD1FC53174C64C2FB69911045AD1846817C3EB0B888131D39609BCFC5898 185 | B08A178B8AA22D626DD1721F84F6AC6BAD6510CBD796005E174EF4D22F1AE720 186 | 5AAF9619062393DA12C0635E01A4F3650C8B1E10F62C5A4FEB4A9904D0D6005E 187 | 13BAE16165E3D8AB683DADEB6455C8086D35E0F136187858D934F6285A2FEB4A 188 | 9E288F00DA63C063C5E3C8C3CAA6B127D17AAC071C1919EED61E0358418F2136 189 | 7858D979EC41B4E471323FA23A23C3DDDA1381D720022C1D1DBA44F42E5A4FDF 190 | D5983435427B23F034F73067C2C8A5A3956869055323789E2D3034E6718CD0DE 191 | 08282C2F871AD29C708D036950469EAD5D8C29D1F2610FEB9C1A9C7119754402 192 | 9E661F92FE813CE0465965E8494BB4FC6D1D5B8B339D721D9180B7959DA94D07 193 | 02B4162D7AF07825C0C80C3DE8A819785BD963624C195A8AD66B82CBC88C90A7 194 | 8E9A81B795850927FB808116A2FDDDEFECEDB598D9DAEAC80C785B5918592078 195 | 208216A2F564644573081D99812DAC2CF1BF630A6219CE49B49903163A32135B 196 | 5859E63050390EE4E31C449BF8FE6D081D9D0984E43914379240F98132EC59B4 197 | 8591229D510046A7AC8BD6260FE04019F62ADAC258BCCE2884E728C79447E4A0 198 | 1C7B13ED82D14E9D5508CC3766DCCA406D263E337920823D8976C17C129DB500 199 | 5B74C04616361907843D88B6A0A33585CE5C80AD3A60238F49DFE5E859B4851D 200 | AD2974F6426CD5011B498D3C425E65A01F6095656BAE70F574F60A6C5D20CC3B 201 | E0FD5407F2D19B683347B462500A2B8188AC8C79115764617372B1E845B4AC24 202 | 58697094CA4A9001326265D08B0CE3C626171FB0D15AB4F8ADBC426025945205 203 | F0999BAD425D53D2193BFCDA7CB4146DF0CAA1A5504A95B065A86B4AE61F1C93 204 | 66E641C56E1539E0BA95A0D42AA2C5DA23888B307C4AFE8001A66E7ACFB68B91 205 | 150A155B41A5581193D7A23721D78E7C32F42281CFD862D5ED482A49E5D64FA9 206 | 56468B4E58489AA04B8E2460D178A95F8B7EC5C89297721440293B805AD5AA09 207 | 1A4981E1575F5AA78CCE4DEBB2A7A238457194BA13A85D88C6BAA12D491EE81D 208 | 9FF380039592CAD9BA651BE9B8DC49A93B82E1DB96CDD294089766F29C5C8551 209 | A8AD2DEA94CE33EC74056778BFF26809999760BC7B7437A063C9DBFD7A68C1A6 210 | A4257386AEB201F0AB7AB1B453F2C079F07B882CD02F4010BD34FB2137102BD0 211 | 9536024E786F16614A84C0C8192D422FFE2E2E154268192ACCE18613ED75B50D 212 | D14B472C878CA0E1F352D1B6123002650084D8698F2D5248F2B8B16BA5AB6E0C 213 | 9AB65E9BB5147938CC4CC3FFC5EA61891158A9983967B49CB823A4B9974A3C25 214 | 796E300149576E001E72EFCDDC1A321CE9F59D881E88581D060572A0AB3702A2 215 | 6D35F7E0E07252191B4E36520E1A039FCD2A9883FD1177A8718754B9E8008495 216 | F6E8D75E0AF1DF2BCD675D0BE5A6131C2E429FC405A8B052A01694A3CE404C6F 217 | 0F219D4B20518CCE260F29571D821EE83947117A2773133A1DBA56EE3A061DB2 218 | 3DC628F74C46FB1A77AC52500E3B07B3ABE89D5A857BB01E891B378AAD964039 219 | DD09181DF2FC82C9A592E6BF9308400E94E31D810EC0E126D463E7CDBF05E57A 220 | 87A090198B3F845B4E2230AC796B385AB506BA831DE3106E3E112A1675E72B2E 221 | 7427670084DBDB52915E48653EA3A541BAA333023E2E030F47E7ECA60CF0F777 222 | E6A3CE417776A6603811CB724973146861189DDA41786A297497178071D1DE39 223 | BA0CF8A6C4A91D9756F704DDF18581074BE763CF43BFB41AF4F4899F9E59933F 224 | 07DDFD058387CD9839D6B767BF9796012B8A40771A8EAA0595C681DF404F1A01 225 | 132A63AD550B11234EAE4D2B4007B2A3A97D3D4025746016746258708790698A 226 | 11145CB26E8B4A309ECFFC5FD2A49230F47C6006A7D3FF0176F1E564B5BA5487 227 | 0000000049454E44AE426082 228 | } 229 | Visible = False 230 | end 231 | object Image1: TImage 232 | Cursor = crHandPoint 233 | Left = 13 234 | Height = 114 235 | Top = 334 236 | Width = 96 237 | Center = True 238 | OnClick = Image1Click 239 | ParentShowHint = False 240 | PopupMenu = pmImage 241 | Proportional = True 242 | ShowHint = True 243 | end 244 | object Image2: TImage 245 | Cursor = crHandPoint 246 | Left = 117 247 | Height = 114 248 | Top = 334 249 | Width = 96 250 | Center = True 251 | OnClick = Image1Click 252 | ParentShowHint = False 253 | PopupMenu = pmImage 254 | Proportional = True 255 | ShowHint = True 256 | end 257 | object Image3: TImage 258 | Cursor = crHandPoint 259 | Left = 13 260 | Height = 114 261 | Top = 454 262 | Width = 96 263 | Center = True 264 | OnClick = Image1Click 265 | ParentShowHint = False 266 | PopupMenu = pmImage 267 | Proportional = True 268 | ShowHint = True 269 | end 270 | object Image4: TImage 271 | Cursor = crHandPoint 272 | Left = 117 273 | Height = 114 274 | Top = 454 275 | Width = 96 276 | Center = True 277 | OnClick = Image1Click 278 | ParentShowHint = False 279 | PopupMenu = pmImage 280 | Proportional = True 281 | ShowHint = True 282 | end 283 | object ckForcePng: TCheckBox 284 | Left = 13 285 | Height = 24 286 | Top = 8 287 | Width = 200 288 | AutoSize = False 289 | Caption = '강제 png 변환' 290 | Checked = True 291 | State = cbChecked 292 | TabOrder = 0 293 | end 294 | end 295 | object Panel3: TPanel 296 | Left = 0 297 | Height = 573 298 | Top = 0 299 | Width = 692 300 | Align = alClient 301 | ClientHeight = 573 302 | ClientWidth = 692 303 | TabOrder = 0 304 | object Panel4: TPanel 305 | Left = 1 306 | Height = 264 307 | Top = 1 308 | Width = 690 309 | Align = alTop 310 | BevelOuter = bvNone 311 | ClientHeight = 264 312 | ClientWidth = 690 313 | TabOrder = 0 314 | object Label1: TLabel 315 | Left = 12 316 | Height = 18 317 | Top = 17 318 | Width = 72 319 | Alignment = taRightJustify 320 | AutoSize = False 321 | Caption = '기준위치' 322 | end 323 | object edBasePath: TEdit 324 | Left = 88 325 | Height = 23 326 | Top = 12 327 | Width = 200 328 | TabOrder = 0 329 | end 330 | object btOpen: TButton 331 | Left = 314 332 | Height = 25 333 | Top = 12 334 | Width = 26 335 | Action = acOpenBasePath 336 | Caption = '...' 337 | Font.Color = clWindowText 338 | Font.Height = -16 339 | Font.Name = '맑은 고딕' 340 | ParentFont = False 341 | ParentShowHint = False 342 | ShowHint = True 343 | TabOrder = 2 344 | OnClick = btOpenClick 345 | end 346 | object btRefresh: TButton 347 | Left = 339 348 | Height = 25 349 | Top = 12 350 | Width = 26 351 | Action = acRefresh 352 | Caption = '⟳' 353 | Font.Color = clWindowText 354 | Font.Height = -16 355 | Font.Name = '맑은 고딕' 356 | ParentFont = False 357 | ParentShowHint = False 358 | ShowHint = True 359 | TabOrder = 3 360 | end 361 | object Label2: TLabel 362 | Left = 399 363 | Height = 18 364 | Top = 17 365 | Width = 76 366 | Alignment = taRightJustify 367 | AutoSize = False 368 | Caption = '에뮬레이터' 369 | end 370 | object cboEmulator: TComboBox 371 | Left = 480 372 | Height = 23 373 | Top = 12 374 | Width = 136 375 | ItemHeight = 15 376 | Style = csDropDownList 377 | TabOrder = 4 378 | OnChange = cboEmulatorChange 379 | end 380 | object Label3: TLabel 381 | Left = 43 382 | Height = 12 383 | Top = 230 384 | Width = 72 385 | Alignment = taRightJustify 386 | Caption = '스크랩검색어' 387 | end 388 | object edSearch: TEdit 389 | Left = 120 390 | Height = 23 391 | Hint = '스크래핑 시 해당 키워드를 통해 검색합니다' 392 | Top = 225 393 | Width = 112 394 | ParentShowHint = False 395 | ShowHint = True 396 | TabOrder = 5 397 | OnKeyPress = edSearchKeyPress 398 | end 399 | object btScrape: TButton 400 | Left = 239 401 | Height = 34 402 | Top = 224 403 | Width = 76 404 | Action = acScrape 405 | TabOrder = 6 406 | end 407 | object btAutoDetect: TButton 408 | Left = 289 409 | Height = 25 410 | Top = 12 411 | Width = 26 412 | Action = acDetectBasePath 413 | Caption = '!' 414 | Font.Color = clWindowText 415 | Font.Height = -16 416 | Font.Name = '맑은 고딕' 417 | ParentFont = False 418 | ParentShowHint = False 419 | ShowHint = True 420 | TabOrder = 1 421 | end 422 | object GroupBox1: TGroupBox 423 | Left = 24 424 | Height = 171 425 | Top = 48 426 | Width = 608 427 | Caption = '상세정보' 428 | ClientHeight = 154 429 | ClientWidth = 604 430 | TabOrder = 7 431 | object Label4: TLabel 432 | Left = 16 433 | Height = 18 434 | Top = 4 435 | Width = 72 436 | Alignment = taRightJustify 437 | AutoSize = False 438 | Caption = '레이블' 439 | end 440 | object Label5: TLabel 441 | Left = 8 442 | Height = 18 443 | Top = 45 444 | Width = 80 445 | Alignment = taRightJustify 446 | AutoSize = False 447 | Caption = '롬 경로' 448 | end 449 | object Label6: TLabel 450 | Left = 303 451 | Height = 18 452 | Top = 44 453 | Width = 88 454 | Alignment = taRightJustify 455 | AutoSize = False 456 | Caption = '이미지 경로' 457 | end 458 | object ckShortname: TCheckBox 459 | Left = 115 460 | Height = 19 461 | Top = 116 462 | Width = 94 463 | Caption = '롬 단축파일명' 464 | TabOrder = 7 465 | end 466 | object edImagePath: TEdit 467 | Left = 400 468 | Height = 23 469 | Top = 38 470 | Width = 193 471 | TabOrder = 3 472 | end 473 | object edRomPath: TEdit 474 | Left = 96 475 | Height = 23 476 | Top = 38 477 | Width = 193 478 | TabOrder = 2 479 | end 480 | object edLabel: TEdit 481 | Left = 96 482 | Height = 23 483 | Top = -2 484 | Width = 193 485 | DoubleBuffered = True 486 | ParentDoubleBuffered = False 487 | TabOrder = 0 488 | end 489 | object ckHideBios: TCheckBox 490 | Left = 219 491 | Height = 19 492 | Top = 116 493 | Width = 102 494 | Caption = '바이오스숨기기' 495 | TabOrder = 8 496 | end 497 | object edGamelist: TEdit 498 | Left = 400 499 | Height = 23 500 | Top = 78 501 | Width = 193 502 | TabOrder = 5 503 | end 504 | object Label7: TLabel 505 | Left = 8 506 | Height = 18 507 | Top = 82 508 | Width = 80 509 | Alignment = taRightJustify 510 | AutoSize = False 511 | Caption = '확장자 목록' 512 | end 513 | object Label8: TLabel 514 | Left = 312 515 | Height = 18 516 | Top = 82 517 | Width = 79 518 | Alignment = taRightJustify 519 | AutoSize = False 520 | Caption = 'gamelist' 521 | end 522 | object edExtList: TEdit 523 | Left = 96 524 | Height = 23 525 | Top = 78 526 | Width = 193 527 | TabOrder = 4 528 | end 529 | object ckUseSwap: TCheckBox 530 | Left = 16 531 | Height = 19 532 | Top = 116 533 | Width = 70 534 | Caption = '스왑 사용' 535 | TabOrder = 6 536 | end 537 | object Label9: TLabel 538 | Left = 312 539 | Height = 18 540 | Top = 4 541 | Width = 79 542 | Alignment = taRightJustify 543 | AutoSize = False 544 | Caption = '아이콘' 545 | end 546 | object edIcon: TEdit 547 | Left = 400 548 | Height = 23 549 | Top = -2 550 | Width = 193 551 | TabOrder = 1 552 | end 553 | object btSaveEmuInfo: TButton 554 | Left = 470 555 | Height = 34 556 | Top = 109 557 | Width = 123 558 | Action = acSaveEmuInfo 559 | TabOrder = 9 560 | end 561 | object btScanExt: TButton 562 | Left = 328 563 | Height = 34 564 | Top = 109 565 | Width = 136 566 | Action = acScanExt 567 | TabOrder = 10 568 | end 569 | end 570 | object btGenerateCache: TButton 571 | Left = 477 572 | Height = 34 573 | Top = 224 574 | Width = 139 575 | Action = acGenerateCache 576 | ParentShowHint = False 577 | ShowHint = True 578 | TabOrder = 8 579 | end 580 | end 581 | object Panel1: TPanel 582 | Left = 1 583 | Height = 307 584 | Top = 265 585 | Width = 690 586 | Align = alClient 587 | ClientHeight = 307 588 | ClientWidth = 690 589 | TabOrder = 1 590 | object TreeView: TTreeView 591 | Left = 1 592 | Height = 305 593 | Top = 1 594 | Width = 137 595 | Align = alLeft 596 | AutoExpand = True 597 | Images = ImageList 598 | PopupMenu = pmDir 599 | RowSelect = True 600 | TabOrder = 0 601 | OnChange = TreeViewChange 602 | OnDragDrop = TreeViewDragDrop 603 | OnDragOver = TreeViewDragOver 604 | OnEdited = TreeViewEdited 605 | Options = [tvoAutoExpand, tvoAutoItemHeight, tvoHideSelection, tvoKeepCollapsedNodes, tvoRowSelect, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw] 606 | end 607 | object ListView: TListView 608 | Left = 143 609 | Height = 305 610 | Top = 1 611 | Width = 546 612 | Align = alClient 613 | AutoSortIndicator = True 614 | BorderStyle = bsNone 615 | Columns = < 616 | item 617 | Caption = '롬이름' 618 | Width = 200 619 | end 620 | item 621 | Caption = '이미지 경로' 622 | Visible = False 623 | Width = 1 624 | end 625 | item 626 | Caption = '롬파일명' 627 | Width = 100 628 | end 629 | item 630 | Caption = '롬경로' 631 | Width = 377 632 | end> 633 | DragMode = dmAutomatic 634 | GridLines = True 635 | HideSelection = False 636 | MultiSelect = True 637 | ParentFont = False 638 | PopupMenu = pmPopup 639 | RowSelect = True 640 | SmallImages = ImageList 641 | SortColumn = 0 642 | SortType = stText 643 | TabOrder = 1 644 | ViewStyle = vsReport 645 | OnCustomDrawItem = ListViewCustomDrawItem 646 | OnEdited = ListViewEdited 647 | OnSelectItem = ListViewSelectItem 648 | end 649 | object Splitter1: TSplitter 650 | Left = 138 651 | Height = 305 652 | Top = 1 653 | Width = 5 654 | end 655 | end 656 | end 657 | object mmLog: TMemo 658 | Left = 0 659 | Height = 80 660 | Top = 573 661 | Width = 918 662 | Align = alBottom 663 | Color = clBlack 664 | Font.Color = clLime 665 | ParentFont = False 666 | ReadOnly = True 667 | ScrollBars = ssAutoBoth 668 | TabOrder = 2 669 | end 670 | object pbInfo: TProgressBar 671 | Left = 0 672 | Height = 20 673 | Top = 653 674 | Width = 918 675 | Align = alBottom 676 | ParentShowHint = False 677 | ShowHint = True 678 | TabOrder = 3 679 | Visible = False 680 | BarShowText = True 681 | end 682 | object ActionList: TActionList 683 | Left = 108 684 | Top = 363 685 | object acScrape: TAction 686 | Caption = '스크래핑(&S)' 687 | OnExecute = acScrapeExecute 688 | end 689 | object acRescrapeAll: TAction 690 | Caption = '모두 스크래핑(&A)' 691 | Visible = False 692 | end 693 | object acScrapeMissing: TAction 694 | Caption = '누락 항목 스크래핑(&M)' 695 | OnExecute = acScrapeMissingExecute 696 | end 697 | object acRename: TAction 698 | Caption = '이름 바꾸기(&R)' 699 | OnExecute = acRenameExecute 700 | ShortCut = 113 701 | end 702 | object acDelete: TAction 703 | Caption = '삭제(&D)' 704 | OnExecute = acDeleteExecute 705 | ShortCut = 32814 706 | end 707 | object acCancelScrape: TAction 708 | Caption = '스크래핑 취소(&C)' 709 | OnExecute = acCancelScrapeExecute 710 | ShortCut = 27 711 | end 712 | object acChangeImage: TAction 713 | Caption = '이미지 변경(&I)' 714 | OnExecute = acChangeImageExecute 715 | end 716 | object acOpenImagePos: TAction 717 | Caption = '이미지 위치 열기(&O)' 718 | OnExecute = acOpenImagePosExecute 719 | end 720 | object acSaveEmuInfo: TAction 721 | Caption = '상세정보 저장(&V)' 722 | OnExecute = acSaveEmuInfoExecute 723 | end 724 | object acBuildGamelist: TAction 725 | Caption = '&gamelist.xml 생성' 726 | OnExecute = acBuildGamelistExecute 727 | end 728 | object acRefresh: TAction 729 | Caption = '새로 고침' 730 | OnExecute = acRefreshExecute 731 | ShortCut = 116 732 | end 733 | object acDetectBasePath: TAction 734 | Caption = '기준위치 자동인식' 735 | OnExecute = acDetectBasePathExecute 736 | end 737 | object acOpenBasePath: TAction 738 | Caption = '기준위치 열기' 739 | OnExecute = acOpenBasePathExecute 740 | ShortCut = 16463 741 | end 742 | object acExit: TAction 743 | Caption = '종료(&X)' 744 | OnExecute = acExitExecute 745 | end 746 | object acGenerateCache: TAction 747 | Caption = '캐시 재생성(&C)' 748 | OnExecute = acGenerateCacheExecute 749 | end 750 | object acAbout: TAction 751 | Caption = 'TrimUI 정보(&A)' 752 | OnExecute = acAboutExecute 753 | end 754 | object acAddRom: TAction 755 | Caption = '롬추가(&N)' 756 | OnExecute = acAddRomExecute 757 | end 758 | object acMkDir: TAction 759 | Caption = '폴더 생성(&F)' 760 | OnExecute = acMkDirExecute 761 | end 762 | object acGithub: TAction 763 | Caption = '&Github' 764 | OnExecute = acGithubExecute 765 | end 766 | object acRmDir: TAction 767 | Caption = '폴더 삭제(&D)' 768 | OnExecute = acRmDirExecute 769 | end 770 | object acScanExt: TAction 771 | Caption = '확장자 스캔(&E)' 772 | OnExecute = acScanExtExecute 773 | end 774 | object acScrapeTotal: TAction 775 | Caption = '전체 에뮬레이터 스크래핑(&T)' 776 | OnExecute = acScrapeTotalExecute 777 | end 778 | object acCacheFromXml: TAction 779 | Caption = 'gamelist.xml 을 이용해서 게임 목록 생성' 780 | OnExecute = acCacheFromXmlExecute 781 | end 782 | end 783 | object pmPopup: TPopupMenu 784 | Left = 220 785 | Top = 363 786 | object pmScrape: TMenuItem 787 | Action = acScrape 788 | end 789 | object Scrapemissing1: TMenuItem 790 | Action = acScrapeMissing 791 | end 792 | object RescrapeAll1: TMenuItem 793 | Action = acRescrapeAll 794 | end 795 | object MenuItem32: TMenuItem 796 | Action = acScrapeTotal 797 | end 798 | object Separator4: TMenuItem 799 | Caption = '-' 800 | end 801 | object MenuItem22: TMenuItem 802 | Action = acAddRom 803 | end 804 | object Rename1: TMenuItem 805 | Action = acRename 806 | end 807 | object MenuItem1: TMenuItem 808 | Action = acChangeImage 809 | end 810 | object Delete1: TMenuItem 811 | Action = acDelete 812 | end 813 | object N1: TMenuItem 814 | Caption = '-' 815 | end 816 | object C1: TMenuItem 817 | Action = acCancelScrape 818 | end 819 | end 820 | object SQLite3Connection: TSQLite3Connection 821 | Connected = False 822 | LoginPrompt = False 823 | KeepConnection = False 824 | Transaction = SQLTransaction 825 | CharSet = 'utf8' 826 | AlwaysUseBigint = False 827 | Left = 220 828 | Top = 304 829 | end 830 | object SQLQuery: TSQLQuery 831 | FieldDefs = <> 832 | Database = SQLite3Connection 833 | Transaction = SQLTransaction 834 | SQL.Strings = ( 835 | '' 836 | ) 837 | Options = [sqoAutoCommit] 838 | Params = <> 839 | Macros = <> 840 | Left = 220 841 | Top = 427 842 | end 843 | object SQLTransaction: TSQLTransaction 844 | Active = False 845 | Database = SQLite3Connection 846 | Left = 109 847 | Top = 427 848 | end 849 | object SQLite3Name: TSQLite3Connection 850 | Connected = False 851 | LoginPrompt = False 852 | KeepConnection = False 853 | Transaction = SQLTransactionName 854 | CharSet = 'utf8' 855 | OpenFlags = [sofReadWrite] 856 | AlwaysUseBigint = False 857 | Left = 109 858 | Top = 304 859 | end 860 | object SQLName: TSQLQuery 861 | FieldDefs = <> 862 | Database = SQLite3Name 863 | Transaction = SQLTransactionName 864 | SQL.Strings = ( 865 | '' 866 | ) 867 | Options = [sqoAutoCommit] 868 | Params = <> 869 | Macros = <> 870 | Left = 168 871 | Top = 427 872 | end 873 | object SQLTransactionName: TSQLTransaction 874 | Active = False 875 | Database = SQLite3Name 876 | Left = 64 877 | Top = 427 878 | end 879 | object pmImage: TPopupMenu 880 | Left = 256 881 | Top = 363 882 | object MenuItem2: TMenuItem 883 | Action = acChangeImage 884 | end 885 | object MenuItem3: TMenuItem 886 | Action = acOpenImagePos 887 | end 888 | end 889 | object MainMenu: TMainMenu 890 | Left = 45 891 | Top = 363 892 | object mnFile: TMenuItem 893 | Caption = '파일(&F)' 894 | object MenuItem7: TMenuItem 895 | Action = acDetectBasePath 896 | end 897 | object MenuItem6: TMenuItem 898 | Action = acOpenBasePath 899 | end 900 | object MenuItem19: TMenuItem 901 | Action = acRefresh 902 | end 903 | object Separator2: TMenuItem 904 | Caption = '-' 905 | end 906 | object MenuItem21: TMenuItem 907 | Action = acAddRom 908 | end 909 | object MenuItem26: TMenuItem 910 | Action = acMkDir 911 | end 912 | object MenuItem30: TMenuItem 913 | Action = acRmDir 914 | end 915 | object MenuItem12: TMenuItem 916 | Action = acSaveEmuInfo 917 | end 918 | object MenuItem13: TMenuItem 919 | Action = acRename 920 | end 921 | object MenuItem15: TMenuItem 922 | Action = acGenerateCache 923 | end 924 | object Separator1: TMenuItem 925 | Caption = '-' 926 | end 927 | object MenuItem8: TMenuItem 928 | Action = acExit 929 | end 930 | end 931 | object mnScrape: TMenuItem 932 | Caption = '스크래퍼(&S)' 933 | object MenuItem10: TMenuItem 934 | Action = acScrape 935 | end 936 | object MenuItem11: TMenuItem 937 | Action = acScrapeMissing 938 | end 939 | object MenuItem31: TMenuItem 940 | Action = acScrapeTotal 941 | end 942 | object MenuItem16: TMenuItem 943 | Action = acCancelScrape 944 | end 945 | object Separator3: TMenuItem 946 | Caption = '-' 947 | end 948 | object MenuItem17: TMenuItem 949 | Action = acChangeImage 950 | end 951 | object MenuItem18: TMenuItem 952 | Action = acOpenImagePos 953 | end 954 | end 955 | object mnXML: TMenuItem 956 | Caption = '&XML' 957 | object MenuItem4: TMenuItem 958 | Action = acCacheFromXml 959 | end 960 | object MenuItem5: TMenuItem 961 | Action = acBuildGamelist 962 | end 963 | end 964 | object mnLanguage: TMenuItem 965 | Caption = '언어(Language)' 966 | object mnLangKor: TMenuItem 967 | Caption = '한국어(&Korean)' 968 | Checked = True 969 | GroupIndex = 1 970 | Hint = 'KO' 971 | OnClick = mnLangKorClick 972 | end 973 | object mnLangEng: TMenuItem 974 | Caption = '&English(영어)' 975 | GroupIndex = 1 976 | Hint = 'EN' 977 | OnClick = mnLangKorClick 978 | end 979 | end 980 | object mnHelp: TMenuItem 981 | Caption = '도움말(&H)' 982 | object MenuItem20: TMenuItem 983 | Action = acAbout 984 | Caption = 'TrimUI Tool 정보(&A)' 985 | end 986 | object MenuItem28: TMenuItem 987 | Action = acGithub 988 | end 989 | end 990 | end 991 | object ImageList: TImageList 992 | Left = 328 993 | Top = 304 994 | Bitmap = { 995 | 4C7A060000001000000010000000DD0400000000000078DAED985F6CD35514C7 996 | 6F3ADD984EC714980F688428236A4974119EFDF360221A338D18D107B7325F84 997 | 80F26062A2461F30445F244CE1417D80487F5D496420FFD99F32B6C41253DA6E 998 | CB9658C75AB4125666BBA66BBB1ECFF7F6F7EB7EFCF66BD73F23406293937B7F 999 | E79CCFBDE79C7B7FF7B6252241B750FC0EF1994F1109165225015DB1BCF457C4 1000 | 03B9F1B8CFBA886EBC4222FDCA8D5D1BA7427EB6C858CD64F63688FF7FBE323E 1001 | 52C1FA47E816BFBF77E8FB1FD1AF4139EBB698BCBB4BDC53E63E08A31DB28B17 1002 | B9ED2B25068D91E3D8C5973E87F8A2A41C54468DC3C56BF6428935908CCA4751 1003 | 836259B55E51B5A57273CFBD8365E6AEF1E5E68EBE5711E972DEFB52EA7533C5 1004 | EA8AEF6AEA8DA51EEF8911047DE88AE5D7B27FEFF50CB9A324057DAB6B3AA98D 1005 | 5748D6F64E47D16A6CA9A28D53219F2926D63C52095B94ACEB8B51C7789486A7 1006 | A7C817BB4A43B108EDF9738AAC7DC5B1BFFD1BA5DD6127ADF7D9C87A71133D35 1007 | F01A7D3ABA970623930B8EB1773CCB367B5BC9EADE44C1449856773F470F9FDC 1008 | 401F5FDA4DDF06220579C4BCDE6F936CD3858D383369E5890DD478C44A2B9C6B 1009 | C8733D5C9047BEEB2EBE25E7D57FC663135477B0917E9FBC5C90F773AD90EFEA 1010 | EEE7E5BCF834385649F6DE1F1BC813F98BD6F464F7A079FE53B256C817316BF3 1011 | 56FF5047DBFA77D29E3F26930BBC1FB5FF24AE793FF1ED4A20DFBA038D54F753 1012 | 036D776D4F84E3610FEC45BC63B55713D7BEB912FF3B188806C2A15828C8ECD7 1013 | AC5F7233CE0345115510DD5917C86733FD3EA088763E5BF79BDE95AC87BD103F 1014 | F28BB88F9990EF907856CFFB3BC5D3DCBFE25644FD3CEE7361C1B86307C4FDEA 1015 | 99DCC6E7F3A0AF53BC22CF5BB47671DE6B17ADB0C34FC6C19CC623368C0F76F8 1016 | A068667B9CC5C5BAE368591F1F3A249E811D7E32478D57E592229A59DFEFCDB2 1017 | 6F1BBE276D869ED97EF815A8DFABB85FCC6CCCF77B1D62A3C97D1430DC2FC7F3 1018 | DC5B270C7E81793E6AAD4A99FF86FC956CFE5CEB770CECBB5C9B69D3FC0DF547 1019 | 9DE1CBB5388F5CC0E0396FFD0DEBCF369BDF2E06102BF264E6655F760DDB4CD7 1020 | BFD2FDB788FBBFD2F70F2204355455CDBC61B1A43EB458923BD067DDD222B815 1021 | 96AAE4FEAABB92296E492FAAEE7BF6596ECA56CF3C595D930AD62C49CEDAB6A4 1022 | E9D8AF191A1B2329478F65083AD8D86702BEC679C1363E944A9F399BA150884C 1023 | E5F4990CC1478E216899C6735CFB3036ECF0EBEE9E3F86A63B792A43D535C959 1024 | 66BE53E75E8ADCB6B4A7A5FDECB98CCCB7FDFD748E451F3AD8F0FC5E6B1AF548 1025 | 325B2FEBCC36E46BF447ABEF6BF6AEA3D939986DE135DA89FEE8E88DF16EDD96 1026 | CED55E8B4D13F84A9B25F5911413FE83AD733CE60E06E76C23231A2FF7C6EBA5 1027 | C67FA46B2E7EAD7E6DB6F2EA57C1FA75E8F6CF72EC09EC8D53A7F3EF1FB0D9FD 1028 | 93BCCCCC8326FB770263B7B6A5658EA829047DC40C5B969D7922CFFBB30CFB0A 1029 | B999BC3FD07518E7CD334E7D766F2477A86BD4A2D5EA76930AFEFBA0C5FEFF06 1030 | 67E30545D4F2DDF326DA85CE4A238FDF647C471CF63BC561D63BF5BFD1F8DC7E 1031 | 045288E7FBA685EFCF4EE9EF149D7856D9C778DC0108FA85E6C7BCFAF9877F16 1032 | 8FCADF9BCCE9FB46DEE3142B3D8A58A5CF9F9F9B8C736AB1A0D578F73E71373F 1033 | F7707F50F3D5FB99DC71D2965B4387F84A7EE79A635ECAC7EAC7D0ED01C5A03F 1034 | 578835D64FFFFFD19DB277174BFE03F97B604E 1035 | } 1036 | end 1037 | object pmDir: TPopupMenu 1038 | Left = 160 1039 | Top = 368 1040 | object MenuItem24: TMenuItem 1041 | Action = acAddRom 1042 | end 1043 | object MenuItem25: TMenuItem 1044 | Action = acMkDir 1045 | end 1046 | object MenuItem29: TMenuItem 1047 | Action = acRmDir 1048 | end 1049 | object MenuItem27: TMenuItem 1050 | Action = acRename 1051 | end 1052 | end 1053 | end 1054 | -------------------------------------------------------------------------------- /mainform.pas: -------------------------------------------------------------------------------- 1 | unit MainForm; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | interface 6 | 7 | uses 8 | Classes, SysUtils, DB, dbf, SQLite3Conn, SQLDB, Forms, Controls, Graphics, 9 | Dialogs, ExtCtrls, ComCtrls, StdCtrls, ActnList, Menus, DBGrids, Buttons, 10 | fpjson, jsonparser, jsonConf, openssl, opensslsockets, fphttpclient, DOM, 11 | XMLRead, XMLWrite, xmltextreader, simpleipc, LazFileUtils, LCLTranslator, 12 | RegExpr, httpprotocol, LCLType, process, dynlibs, fileutil, Translations, 13 | LResources, ShellCtrls, StrUtils, lclintf; 14 | 15 | const 16 | BASE_PATH = '/mnt/SDCARD'; 17 | 18 | type 19 | TEmuConfig = record 20 | Caption: String; 21 | Icon: String; 22 | System: String; 23 | EmuPath: String; 24 | RomPath: String; 25 | ImgPath: String; 26 | CachePath: String; 27 | Shortname: Boolean; 28 | UseSwap: Boolean; 29 | HideBios: Boolean; 30 | Gamelist: String; 31 | ExtList: String; 32 | end; 33 | 34 | PScrapeInfo = ^TScrapeInfo; 35 | TScrapeInfo = record 36 | System, Key, ImagePath, SearchStr, Gamelist, ImageBase, EmuPath: String; 37 | IsShortname, IsForce, ForcePng: Boolean; 38 | end; 39 | 40 | { TQueueThread } 41 | 42 | TQueueThread = class(TThread) 43 | private 44 | HttpClient: TFPHttpClient; 45 | Image: TImage; 46 | class var BasePath: String; 47 | class var IPCClient: TSimpleIPCClient; 48 | class var ScrapeList: TList; 49 | class var Count, TotalCount: Integer; 50 | public 51 | constructor Create(CreateSuspended: boolean); 52 | destructor Destroy; override; 53 | procedure Execute; override; 54 | class procedure SetBasePath(Path: String); static; 55 | class procedure CancelScrape; static; 56 | class procedure Put(ScrapeInfo: TScrapeInfo); static; 57 | function Get(var ScrapeInfo: TScrapeInfo): Boolean; 58 | procedure Scrape(ScrapeInfo: TScrapeInfo; IsArcade: Boolean); 59 | class procedure WriteLog(Log: String); static; 60 | end; 61 | 62 | { TFormMain } 63 | 64 | TFormMain = class(TForm) 65 | acCacheFromXml: TAction; 66 | acCancelScrape: TAction; 67 | acDelete: TAction; 68 | acRename: TAction; 69 | acRescrapeAll: TAction; 70 | acScrape: TAction; 71 | acScrapeMissing: TAction; 72 | acChangeImage: TAction; 73 | acOpenImagePos: TAction; 74 | acSaveEmuInfo: TAction; 75 | acBuildGamelist: TAction; 76 | acRefresh: TAction; 77 | acDetectBasePath: TAction; 78 | acOpenBasePath: TAction; 79 | acExit: TAction; 80 | acGenerateCache: TAction; 81 | acAbout: TAction; 82 | acAddRom: TAction; 83 | acMkDir: TAction; 84 | acGithub: TAction; 85 | acRmDir: TAction; 86 | acScanExt: TAction; 87 | acScrapeTotal: TAction; 88 | ActionList: TActionList; 89 | btGenerateCache: TButton; 90 | btOpen: TButton; 91 | btAutoDetect: TButton; 92 | btRefresh: TButton; 93 | btScanExt: TButton; 94 | btScrape: TButton; 95 | btSaveEmuInfo: TButton; 96 | C1: TMenuItem; 97 | cboEmulator: TComboBox; 98 | ckForcePng: TCheckBox; 99 | ckHideBios: TCheckBox; 100 | ckShortname: TCheckBox; 101 | ckUseSwap: TCheckBox; 102 | Delete1: TMenuItem; 103 | edBasePath: TEdit; 104 | edLabel: TEdit; 105 | edRomPath: TEdit; 106 | edImagePath: TEdit; 107 | edExtList: TEdit; 108 | edGamelist: TEdit; 109 | edIcon: TEdit; 110 | edSearch: TEdit; 111 | GroupBox1: TGroupBox; 112 | Image: TImage; 113 | Image1: TImage; 114 | Image2: TImage; 115 | Image3: TImage; 116 | Image4: TImage; 117 | ImageList: TImageList; 118 | Label1: TLabel; 119 | Label2: TLabel; 120 | Label3: TLabel; 121 | Label4: TLabel; 122 | Label5: TLabel; 123 | Label6: TLabel; 124 | Label7: TLabel; 125 | Label8: TLabel; 126 | Label9: TLabel; 127 | ListView: TListView; 128 | MainMenu: TMainMenu; 129 | MenuItem1: TMenuItem; 130 | MenuItem10: TMenuItem; 131 | MenuItem11: TMenuItem; 132 | MenuItem12: TMenuItem; 133 | MenuItem13: TMenuItem; 134 | MenuItem15: TMenuItem; 135 | MenuItem16: TMenuItem; 136 | MenuItem17: TMenuItem; 137 | MenuItem18: TMenuItem; 138 | MenuItem19: TMenuItem; 139 | MenuItem20: TMenuItem; 140 | MenuItem21: TMenuItem; 141 | MenuItem22: TMenuItem; 142 | MenuItem4: TMenuItem; 143 | MenuItem5: TMenuItem; 144 | mnLanguage: TMenuItem; 145 | MenuItem24: TMenuItem; 146 | MenuItem25: TMenuItem; 147 | MenuItem26: TMenuItem; 148 | MenuItem27: TMenuItem; 149 | MenuItem28: TMenuItem; 150 | MenuItem29: TMenuItem; 151 | MenuItem30: TMenuItem; 152 | MenuItem31: TMenuItem; 153 | MenuItem32: TMenuItem; 154 | mnXML: TMenuItem; 155 | mnLangKor: TMenuItem; 156 | mnLangEng: TMenuItem; 157 | Panel1: TPanel; 158 | pmDir: TPopupMenu; 159 | pbInfo: TProgressBar; 160 | Separator4: TMenuItem; 161 | Separator3: TMenuItem; 162 | Separator2: TMenuItem; 163 | MenuItem2: TMenuItem; 164 | MenuItem3: TMenuItem; 165 | mnFile: TMenuItem; 166 | mnHelp: TMenuItem; 167 | MenuItem6: TMenuItem; 168 | MenuItem7: TMenuItem; 169 | MenuItem8: TMenuItem; 170 | mnScrape: TMenuItem; 171 | Separator1: TMenuItem; 172 | mmLog: TMemo; 173 | N1: TMenuItem; 174 | NoImage: TImage; 175 | pnImage: TPanel; 176 | Panel3: TPanel; 177 | Panel4: TPanel; 178 | pmScrape: TMenuItem; 179 | pmPopup: TPopupMenu; 180 | pmImage: TPopupMenu; 181 | Rename1: TMenuItem; 182 | RescrapeAll1: TMenuItem; 183 | Scrapemissing1: TMenuItem; 184 | Splitter1: TSplitter; 185 | SQLite3Connection: TSQLite3Connection; 186 | SQLite3Name: TSQLite3Connection; 187 | SQLQuery: TSQLQuery; 188 | SQLName: TSQLQuery; 189 | SQLTransaction: TSQLTransaction; 190 | SQLTransactionName: TSQLTransaction; 191 | TreeView: TTreeView; 192 | procedure acAboutExecute(Sender: TObject); 193 | procedure acAddRomExecute(Sender: TObject); 194 | procedure acBuildGamelistExecute(Sender: TObject); 195 | procedure acCacheFromXmlExecute(Sender: TObject); 196 | procedure acCancelScrapeExecute(Sender: TObject); 197 | procedure acChangeImageExecute(Sender: TObject); 198 | procedure acDeleteExecute(Sender: TObject); 199 | procedure acDetectBasePathExecute(Sender: TObject); 200 | procedure acExitExecute(Sender: TObject); 201 | procedure acGenerateCacheExecute(Sender: TObject); 202 | procedure acGithubExecute(Sender: TObject); 203 | procedure acMkDirExecute(Sender: TObject); 204 | procedure acOpenBasePathExecute(Sender: TObject); 205 | procedure acOpenImagePosExecute(Sender: TObject); 206 | procedure acRefreshExecute(Sender: TObject); 207 | procedure acRenameExecute(Sender: TObject); 208 | procedure acRmDirExecute(Sender: TObject); 209 | procedure acSaveEmuInfoExecute(Sender: TObject); 210 | procedure acScanExtExecute(Sender: TObject); 211 | procedure acScrapeExecute(Sender: TObject); 212 | procedure acScrapeMissingExecute(Sender: TObject); 213 | procedure acScrapeTotalExecute(Sender: TObject); 214 | procedure btOpenClick(Sender: TObject); 215 | procedure cboEmulatorChange(Sender: TObject); 216 | procedure edSearchKeyPress(Sender: TObject; var Key: char); 217 | procedure FormClose(Sender: TObject; var {%H-}CloseAction: TCloseAction); 218 | procedure FormCreate(Sender: TObject); 219 | procedure FormDestroy(Sender: TObject); 220 | procedure FormDropFiles(Sender: TObject; const FileNames: array of string); 221 | procedure FormShow(Sender: TObject); 222 | procedure Image1Click(Sender: TObject); 223 | procedure ListViewCustomDrawItem(Sender: TCustomListView; Item: TListItem; 224 | {%H-}State: TCustomDrawState; var {%H-}DefaultDraw: Boolean); 225 | procedure ListViewEdited(Sender: TObject; Item: TListItem; 226 | var AValue: string); 227 | procedure ListViewSelectItem(Sender: TObject; Item: TListItem; 228 | Selected: Boolean); 229 | procedure mnLangKorClick(Sender: TObject); 230 | procedure TreeViewChange(Sender: TObject; Node: TTreeNode); 231 | procedure TreeViewDragDrop(Sender, Source: TObject; X, Y: Integer); 232 | procedure TreeViewDragOver(Sender, Source: TObject; {%H-}X, {%H-}Y: Integer; 233 | {%H-}State: TDragState; var Accept: Boolean); 234 | procedure TreeViewEdited(Sender: TObject; Node: TTreeNode; var S: string); 235 | private 236 | procedure AppIdle(Sender: TObject; var {%H-}Done: Boolean); 237 | public 238 | IPCServer: TSimpleIPCServer; 239 | EmuConfig: TEmuConfig; 240 | QueueThread: TQueueThread; 241 | procedure IPCServerMessage(Sender: TObject); 242 | procedure LoadEmus(BasePath: String); 243 | procedure WriteLog(Log: String); 244 | function LoadEmuConfig(System: String): Boolean; 245 | function LoadEmuInfo(System: String): Boolean; 246 | function SaveEmuConfig(System: String): Boolean; 247 | procedure BuildCache(IsDelete: Boolean=False); 248 | procedure GetSubDir; 249 | procedure GetEmuList(SubDir: String='.'); 250 | function RenameTitle(Key, Tobe: String): Boolean; 251 | function RenameSubDir(Asis, Tobe: String): Boolean; 252 | function DeleteSubDir: Boolean; 253 | function InsertCache(Filename: String; SubDir: String=''): String; 254 | function UpdateCache(Key, Column, Value: String): Boolean; 255 | function DeleteCache(Key: String): Boolean; 256 | function ExecCacheSQL(Query: String; Args: Array of const): Boolean; 257 | function GetFullTitle(Title, DefaultTitle: String): String; 258 | function UpdateRomName(Key, Value: String): Boolean; 259 | procedure GenCacheFromXml(Gamelist: String); 260 | procedure ReadSettings; 261 | procedure WriteSettings; 262 | end; 263 | 264 | var 265 | FormMain: TFormMain; 266 | SystemMap: TStringList; 267 | 268 | resourcestring 269 | I18N_SCRAPESTARTED = ' 스크래핑이 시작되었습니다'; 270 | I18N_ROMFROM = '롬 한글정보 출처: 텐타클팀(http://cafe.naver.com/raspigamer)'; 271 | I18N_FILENOTFOUND = '파일을 찾을 수 없습니다'; 272 | I18N_DIRNOTFOUND = '폴더를 찾을 수 없습니다'; 273 | I18N_CANCELEDSCRAPE = '스크래핑이 취소되었습니다'; 274 | I18N_CACHEFROMXML = 'gamelist.xml 파일정보로부터 캐시파일을 새로 생성합니다. 계속 하시겠습니까?'; 275 | I18N_GENCACHE = '캐시를 생성하고 있습니다...'; 276 | I18N_ERROROCCURED = '오류가 발생하였습니다'; 277 | I18N_FILEEXISTS = '파일이 존재합니다'; 278 | I18N_DIREXISTS = '폴더가 존재합니다'; 279 | I18N_NOSELEMUL = '선택된 에뮬레이터가 없습니다'; 280 | I18N_DONESCRAPE = '스크래핑이 완료되었습니다'; 281 | I18N_ROMNOTSELECTED = '롬을 먼저 선택해주세요'; 282 | I18N_SAVED = '저장되었습니다'; 283 | I18N_CREATED = '생성되었습니다'; 284 | I18N_PROCESSING = '처리중입니다'; 285 | I18N_DELETED = '삭제되었습니다'; 286 | I18N_CONFIRM = '확인'; 287 | I18N_ADDED = '추가되었습니다'; 288 | I18N_RECACHECONFIRM = '캐시 파일을 재생성합니다. 계속 하시겠습니까?'; 289 | I18N_DELETECONFIRM = '롬 파일을 삭제합니다. 계속 하시겠습니까?'; 290 | I18N_DELETEDIRCONFIRM = '폴더를 삭제합니다. 계속 하시겠습니까?'; 291 | I18N_GAMELISTCONFIRM = '캐시로부터 gamelist.xml 파일을 새로 생성합니다. 계속 하시겠습니까?'; 292 | I18N_MAKEDIR = '폴더생성'; 293 | I18N_INPUTDIRNAME = '폴더명을 입력하세요'; 294 | I18N_ADDEDEXT = '확장자가 추가되었습니다'; 295 | I18N_SCRAPEALLCONFIRM = '에뮬레이터 전체 영역에 대해 누락 항목을 스크래핑합니다. 계속하시겠습니까?'; 296 | I18N_DONE = '완료되었습니다'; 297 | 298 | implementation 299 | 300 | {$R *.lfm} 301 | 302 | uses 303 | IniFiles; 304 | 305 | var 306 | CriticalSection: TRTLCriticalSection; 307 | 308 | function Translate(const Language: String): boolean; 309 | var 310 | Res: TResourceStream; 311 | PoStringStream: TStringStream; 312 | PoFile: TPOFile; 313 | LocalTranslator: TPOTranslator; 314 | i: Integer; 315 | begin 316 | Res := TResourceStream.Create(HInstance, 'I18N.' + Language, RT_RCDATA); 317 | PoStringStream := TStringStream.Create(''); 318 | try 319 | Res.SaveToStream(PoStringStream) 320 | finally 321 | Res.Free; 322 | end; 323 | 324 | PoFile := TPOFile.Create(False); 325 | try 326 | PoFile.ReadPOText(PoStringStream.DataString); 327 | Result := TranslateResourceStrings(PoFile); 328 | 329 | LocalTranslator := TPOTranslator.Create(PoFile); 330 | 331 | if Assigned(LRSTranslator) then 332 | LRSTranslator.Free; 333 | LRSTranslator := LocalTranslator; 334 | 335 | for i := 0 to Pred(Screen.CustomFormCount) do 336 | LocalTranslator.UpdateTranslation(Screen.CustomForms[i]); 337 | for i := 0 to Pred(Screen.DataModuleCount) do 338 | LocalTranslator.UpdateTranslation(Screen.DataModules[i]); 339 | finally 340 | if Assigned(PoStringStream) then 341 | PoStringStream.Free; 342 | end; 343 | end; 344 | 345 | function SaveImage(Image: TImage; var ImagePath: String; ForcePng: Boolean): Boolean; 346 | var 347 | PngImage: TPortableNetworkGraphic; 348 | begin 349 | if Image.Picture.Graphic.Classname = 'TPortableNetworkGraphic' then 350 | begin 351 | if ExtractFileExt(ImagePath) <> '.png' then 352 | ImagePath := ExtractFileNameWithoutExt(ImagePath) + '.png' 353 | end else if Image.Picture.Graphic.Classname = 'TJpegImage' then 354 | begin 355 | if ForcePng then 356 | begin 357 | PngImage := TPortableNetworkGraphic.Create; 358 | try 359 | PngImage.Assign(Image.Picture.Bitmap); 360 | ImagePath := ExtractFileNameWithoutExt(ImagePath) + '.png'; 361 | Image.Picture.Bitmap.LoadFromRawImage(PngImage.RawImage, False); 362 | finally 363 | if Assigned(PngImage) then 364 | PngImage.Free; 365 | end; 366 | end else if ExtractFileExt(ImagePath) <> '.jpg' then 367 | ImagePath := ExtractFileNameWithoutExt(ImagePath) + '.jpg' 368 | end else begin 369 | Result := False; 370 | exit; 371 | end; 372 | 373 | if FileExists(ImagePath) then 374 | SysUtils.DeleteFile(ImagePath); 375 | Image.Picture.SaveToFile(ImagePath); 376 | 377 | Result := True; 378 | end; 379 | 380 | function Win2Lin(BasePath, WinPath: String): String; 381 | begin 382 | {$IFDEF Linux} 383 | Result := StringReplace(WinPath, BasePath, BASE_PATH, [rfReplaceAll]); 384 | {$ELSE} 385 | Result := StringReplace( 386 | StringReplace(WinPath, BasePath, BASE_PATH, []), '\', '/', [rfReplaceAll]); 387 | {$ENDIF} 388 | end; 389 | 390 | function Lin2Win(BasePath, LinPath: String): String; 391 | begin 392 | {$IFDEF Linux} 393 | Result := ExpandFileName(StringReplace(LinPath, BASE_PATH, BasePath, [rfReplaceAll])); 394 | {$ELSE} 395 | Result := ExpandFileName(StringReplace( 396 | StringReplace(LinPath, BASE_PATH, BasePath, []), '/', '\', [rfReplaceAll])); 397 | {$ENDIF} 398 | end; 399 | 400 | { TQueueThread } 401 | 402 | constructor TQueueThread.Create(CreateSuspended : boolean); 403 | begin 404 | inherited Create(CreateSuspended); 405 | Image := TImage.Create(nil); 406 | 407 | EnterCriticalSection(CriticalSection); 408 | try 409 | HttpClient := TFPHTTPClient.Create(nil); 410 | if not Assigned(ScrapeList) then 411 | ScrapeList := TList.Create; 412 | if not Assigned(IPCClient) then 413 | begin 414 | IPCClient := TSimpleIPCClient.Create(nil); 415 | IPCClient.ServerID := 'WriteLog'; 416 | end; 417 | 418 | Count := 0; 419 | TotalCount := 0; 420 | finally 421 | LeaveCriticalSection(CriticalSection); 422 | end; 423 | end; 424 | 425 | destructor TQueueThread.Destroy; 426 | var 427 | i: Integer; 428 | begin 429 | EnterCriticalSection(CriticalSection); 430 | try 431 | for i:=0 to ScrapeList.Count-1 do 432 | Dispose(PScrapeInfo(ScrapeList.Items[i])); 433 | 434 | if Assigned(ScrapeList) then 435 | FreeAndNil(ScrapeList); 436 | if Assigned(IPCClient) then 437 | FreeAndNil(IPCClient); 438 | finally 439 | LeaveCriticalSection(CriticalSection); 440 | end; 441 | 442 | HttpClient.Free; 443 | Image.Free; 444 | inherited Destroy; 445 | end; 446 | 447 | procedure TQueueThread.Execute; 448 | var 449 | ScrapeInfo: TScrapeInfo; 450 | begin 451 | ScrapeInfo.System := ''; 452 | ScrapeInfo.SearchStr := ''; 453 | ScrapeInfo.Key := ''; 454 | ScrapeInfo.ImagePath := ''; 455 | ScrapeInfo.IsShortname := False; 456 | ScrapeInfo.IsForce := False; 457 | ScrapeInfo.Gamelist := ''; 458 | ScrapeInfo.ImageBase := ''; 459 | ScrapeInfo.EmuPath := ''; 460 | ScrapeInfo.ForcePng := True; 461 | 462 | while not Terminated do 463 | begin 464 | while Get(ScrapeInfo) do 465 | begin 466 | WriteLog(ScrapeInfo.SearchStr + I18N_SCRAPESTARTED); 467 | if ScrapeInfo.IsShortname then 468 | Scrape(ScrapeInfo, True) 469 | else 470 | Scrape(ScrapeInfo, False); 471 | end; 472 | Sleep(1000); 473 | end; 474 | end; 475 | 476 | class procedure TQueueThread.SetBasePath(Path: String); static; 477 | begin 478 | BasePath := Path; 479 | end; 480 | 481 | class procedure TQueueThread.CancelScrape; static; 482 | var 483 | i: Integer; 484 | begin 485 | if ScrapeList.Count > 0 then 486 | WriteLog(I18N_CANCELEDSCRAPE + ' - ' + IntToStr(ScrapeList.Count)); 487 | EnterCriticalSection(CriticalSection); 488 | 489 | try 490 | for i:=0 to ScrapeList.Count-1 do 491 | Dispose(PScrapeInfo(ScrapeList.Items[i])); 492 | ScrapeList.Clear; 493 | finally 494 | LeaveCriticalSection(CriticalSection); 495 | end; 496 | end; 497 | 498 | class procedure TQueueThread.Put(ScrapeInfo: TScrapeInfo); static; 499 | var 500 | Info: PScrapeInfo; 501 | begin 502 | EnterCriticalSection(CriticalSection); 503 | try 504 | Count += 1; 505 | TotalCount += 1; 506 | New(Info); 507 | Info^ := ScrapeInfo; 508 | ScrapeList.Add(Info); 509 | finally 510 | LeaveCriticalSection(CriticalSection); 511 | end; 512 | end; 513 | 514 | function TQueueThread.Get(var ScrapeInfo: TScrapeInfo): Boolean; 515 | begin 516 | EnterCriticalSection(CriticalSection); 517 | try 518 | if ScrapeList.Count > 0 then 519 | begin 520 | ScrapeInfo := PScrapeInfo(ScrapeList[0])^; 521 | Dispose(PScrapeInfo(ScrapeList[0])); 522 | ScrapeList.Delete(0); 523 | Result := True; 524 | end else 525 | Result := False; 526 | finally 527 | LeaveCriticalSection(CriticalSection); 528 | end; 529 | end; 530 | 531 | procedure TQueueThread.Scrape(ScrapeInfo: TScrapeInfo; IsArcade: Boolean); 532 | var 533 | JsonStr, ImageUrl: String; 534 | JData : TJSONData; 535 | Stream: TStream; 536 | SysStr: String; 537 | Contents: String; 538 | RegEx: TRegExpr; 539 | ImageCount: Integer; 540 | i: Integer; 541 | function GetText(Title: String): String; 542 | var 543 | i: Integer; 544 | begin 545 | for i:=1 to Length(Title) do 546 | if Title[i] in ['(', '['] then 547 | begin 548 | Result := Copy(Title, 1, i-1); 549 | exit; 550 | end; 551 | Result := Title; 552 | end; 553 | begin 554 | if Copy(ScrapeInfo.ImageBase, 1, 1) = '/' then 555 | ScrapeInfo.ImagePath := Lin2Win(BasePath, ScrapeInfo.ImageBase + '/' + ScrapeInfo.Key) 556 | else 557 | ScrapeInfo.ImagePath := Lin2Win(BasePath, ScrapeInfo.EmuPath + '/' + ScrapeInfo.ImageBase + '/' + ScrapeInfo.Key); 558 | 559 | if not DirectoryExists(ExtractFileDir(ScrapeInfo.ImagePath)) then 560 | MkDir(ExtractFileDir(ScrapeInfo.ImagePath)); 561 | if FileExists(ScrapeInfo.ImagePath) and not ScrapeInfo.IsForce then 562 | begin 563 | WriteLog(ScrapeInfo.ImagePath + ' - ' + I18N_FILEEXISTS); 564 | exit; 565 | end; 566 | 567 | EnterCriticalSection(CriticalSection); 568 | try 569 | Count -= 1; 570 | finally 571 | LeaveCriticalSection(CriticalSection); 572 | end; 573 | ImageCount := 0; 574 | Stream := TMemoryStream.Create; 575 | 576 | try 577 | try 578 | if IsArcade then 579 | begin 580 | with HttpClient do 581 | begin 582 | JsonStr := Get('http://adb.arcadeitalia.net/service_scraper.php?ajax=query_mame&game_name=' + ScrapeInfo.SearchStr); 583 | 584 | JData := GetJSON(JsonStr); 585 | 586 | if not Assigned(JData) then 587 | begin 588 | WriteLog('No data found error - ' + ScrapeInfo.SearchStr); 589 | exit; 590 | end; 591 | 592 | ImageUrl := TJsonObject(JData).FindPath('result[0].url_image_ingame').AsString; 593 | Get(ImageUrl, Stream); 594 | Stream.Seek(0, soFromBeginning); 595 | Image.Picture.LoadFromStream(Stream); 596 | 597 | if not SaveImage(Image, ScrapeInfo.ImagePath, ScrapeInfo.ForcePng) then 598 | begin 599 | WriteLog('Scraping ' + ScrapeInfo.System + ' - ' + Image.Picture.Graphic.Classname + '--> File format error'); 600 | exit; 601 | end; 602 | end; 603 | end else 604 | begin 605 | SysStr := ScrapeInfo.System; 606 | if SystemMap.Values[ScrapeInfo.System] <> '' then 607 | SysStr := SystemMap.Values[ScrapeInfo.System]; 608 | try 609 | EnterCriticalSection(CriticalSection); 610 | try 611 | Contents := HttpClient.Get('https://images.search.yahoo.com/search/images?p=' + 612 | HTTPEncode(StringReplace('screenshot+gamefabrique+'+GetText(ScrapeInfo.SearchStr)+'+'+SysStr, ' ', '+', [rfReplaceAll]))); 613 | finally 614 | LeaveCriticalSection(CriticalSection); 615 | end; 616 | except 617 | on E :Exception do 618 | begin 619 | WriteLog(HttpClient.ResponseStatusText + ' - ' + E.Message); 620 | exit; 621 | end; 622 | end; 623 | 624 | RegEx := TRegExpr.Create('img data-src=''(https://tse\d\.mm\.bing\.net.*?)'' alt='); 625 | 626 | try 627 | if RegEx.Exec(Contents) then 628 | begin 629 | ImageUrl := RegEx.Match[1]; 630 | HttpClient.Get(ImageUrl, Stream); 631 | 632 | Stream.Seek(0, soFromBeginning); 633 | Image.Picture.LoadFromStream(Stream); 634 | 635 | if not SaveImage(Image, ScrapeInfo.ImagePath, ScrapeInfo.ForcePng) then 636 | begin 637 | WriteLog('Scraping ' + ScrapeInfo.System + ' - ' + Image.Picture.Graphic.Classname + '--> File format error'); 638 | exit; 639 | end; 640 | 641 | if ScrapeList.Count = 0 then 642 | begin 643 | for i:=1 to 4 do 644 | begin 645 | if RegEx.ExecNext then 646 | begin 647 | ImageUrl := RegEx.Match[1]; 648 | JsonStr := ExtractFilePath(Application.ExeName) + DirectorySeparator + 'Image' + IntToStr(i) + '.jpg'; 649 | HttpClient.Get(ImageUrl, JsonStr); 650 | Inc(ImageCount); 651 | end else break; 652 | end; 653 | end; 654 | end; 655 | finally 656 | RegEx.Free; 657 | end; 658 | end; 659 | 660 | WriteLog('@' + ScrapeInfo.ImagePath + '|' + ScrapeInfo.ImageBase + '|' + ScrapeInfo.Key + '|' + IntToStr(ImageCount) + '|' + 661 | IntToStr(Count) + '|' + IntToStr(TotalCount)); 662 | except 663 | on E :Exception do 664 | WriteLog(ScrapeInfo.SearchStr + I18N_ERROROCCURED + ' - ' + E.Message); 665 | end; 666 | finally 667 | Stream.Free; 668 | EnterCriticalSection(CriticalSection); 669 | try 670 | if Count = 0 then 671 | TotalCount := 0; 672 | finally 673 | LeaveCriticalSection(CriticalSection); 674 | end; 675 | end; 676 | end; 677 | 678 | class procedure TQueueThread.WriteLog(Log: String); static; 679 | begin 680 | if not IPCClient.ServerRunning then 681 | exit; 682 | IPCClient.Active := True; 683 | try 684 | IPCClient.SendStringMessage(Log); 685 | finally 686 | IPCClient.Active := False; 687 | end; 688 | end; 689 | 690 | { TFormMain } 691 | 692 | procedure TFormMain.btOpenClick(Sender: TObject); 693 | begin 694 | 695 | end; 696 | 697 | procedure TFormMain.acScrapeExecute(Sender: TObject); 698 | var 699 | i: Integer; 700 | Filename: String; 701 | ScrapeInfo: TScrapeInfo; 702 | begin 703 | if ListView.Selected = nil then 704 | begin 705 | ShowMessage(I18N_ROMNOTSELECTED); 706 | exit; 707 | end; 708 | 709 | ScrapeInfo.Gamelist := EmuConfig.Gamelist; 710 | ScrapeInfo.System := EmuConfig.System; 711 | ScrapeInfo.IsShortname := (EmuConfig.Shortname)and(edSearch.Text = ''); 712 | ScrapeInfo.IsForce := True; 713 | ScrapeInfo.ImageBase := edImagePath.Text; 714 | ScrapeInfo.ForcePng := ckForcePng.Checked; 715 | ScrapeInfo.EmuPath := EmuConfig.EmuPath; 716 | TQueueThread.SetBasePath(edBasePath.Text); 717 | 718 | for i:= 0 to ListView.Items.Count-1 do 719 | begin 720 | if ListView.Items[i].Selected then 721 | begin 722 | if (edSearch.Text <> '') and (ListView.SelCount=1) then 723 | ScrapeInfo.SearchStr := edSearch.Text 724 | else 725 | ScrapeInfo.SearchStr := ListView.Items[i].SubItems[1]; 726 | ScrapeInfo.Key := ListView.Items[i].SubItems[1]; 727 | Filename := ExtractFilename(Lin2Win(edBasePath.Text, ListView.Items[i].SubItems[2])); 728 | ScrapeInfo.ImagePath := EmuConfig.ImgPath + DirectorySeparator + ExtractFileNameWithoutExt(Filename); 729 | 730 | TQueueThread.Put(ScrapeInfo); 731 | end; 732 | end; 733 | end; 734 | 735 | procedure TFormMain.acScrapeMissingExecute(Sender: TObject); 736 | var 737 | ScrapeInfo: TScrapeInfo; 738 | Filename: String; 739 | i: Integer; 740 | begin 741 | ScrapeInfo.Gamelist := EmuConfig.Gamelist; 742 | ScrapeInfo.System := EmuConfig.System; 743 | ScrapeInfo.IsShortname := EmuConfig.Shortname; 744 | ScrapeInfo.IsForce := True; 745 | ScrapeInfo.ImageBase := edImagePath.Text; 746 | ScrapeInfo.ForcePng := ckForcePng.Checked; 747 | ScrapeInfo.EmuPath := EmuConfig.EmuPath; 748 | TQueueThread.SetBasePath(edBasePath.Text); 749 | 750 | for i:=0 to ListView.Items.Count-1 do 751 | begin 752 | if FileExists(Lin2Win(edBasePath.Text, ListView.Items[i].SubItems[0])) then 753 | continue; 754 | ScrapeInfo.SearchStr := ListView.Items[i].SubItems[1]; 755 | ScrapeInfo.Key := ListView.Items[i].SubItems[1]; 756 | Filename := ExtractFilename(Lin2Win(edBasePath.Text, ListView.Items[i].SubItems[2])); 757 | ScrapeInfo.ImagePath := EmuConfig.ImgPath + DirectorySeparator + ExtractFileNameWithoutExt(Filename); 758 | TQueueThread.Put(ScrapeInfo); 759 | end; 760 | end; 761 | 762 | procedure TFormMain.acScrapeTotalExecute(Sender: TObject); 763 | var 764 | ScrapeInfo: TScrapeInfo; 765 | Filename: String; 766 | EmuPath, Shortname, ImagePath, Path: String; 767 | SearchRec: TSearchRec; 768 | Count: Integer; 769 | begin 770 | Count := 0; 771 | EmuPath := edBasePath.Text + DirectorySeparator + 'Emus'; 772 | 773 | if not DirectoryExists(EmuPath) then 774 | begin 775 | WriteLog(EmuPath + ' - ' + I18N_DIRNOTFOUND); 776 | exit; 777 | end; 778 | 779 | if Application.MessageBox(PChar(I18N_SCRAPEALLCONFIRM), 780 | PChar(I18N_CONFIRM), MB_ICONQUESTION + MB_YESNO) <> IDYES then 781 | exit; 782 | 783 | cboEmulator.Enabled := False; 784 | WriteLog(I18N_SCRAPESTARTED); 785 | 786 | try 787 | if FindFirst(EmuPath + DirectorySeparator + '*', faDirectory, SearchRec) = 0 then 788 | begin 789 | repeat 790 | if Copy(SearchRec.Name, 1, 1) <> '.' then 791 | begin 792 | if not FileExists(EmuPath + DirectorySeparator + SearchRec.Name + DirectorySeparator + 'config.json') then 793 | WriteLog(EmuPath + DirectorySeparator + SearchRec.Name + DirectorySeparator + 'config.json - ' + I18N_FILENOTFOUND) 794 | else begin 795 | if LoadEmuConfig(SearchRec.Name) then 796 | begin 797 | if not DirectoryExists(EmuConfig.RomPath) then 798 | WriteLog(EmuConfig.RomPath + ' - ' + I18N_FILENOTFOUND) 799 | else begin 800 | WriteLog(I18N_PROCESSING + ' - ' + SearchRec.Name); 801 | Application.ProcessMessages; 802 | SQLite3Connection.DatabaseName := EmuConfig.CachePath; 803 | if not SQLite3Connection.Connected then 804 | SQLite3Connection.Connected := True; 805 | try 806 | ScrapeInfo.Gamelist := EmuConfig.Gamelist; 807 | ScrapeInfo.System := EmuConfig.System; 808 | ScrapeInfo.IsShortname := EmuConfig.Shortname; 809 | ScrapeInfo.IsForce := True; 810 | ScrapeInfo.ImageBase := edImagePath.Text; 811 | ScrapeInfo.ForcePng := ckForcePng.Checked; 812 | ScrapeInfo.EmuPath := EmuConfig.EmuPath; 813 | TQueueThread.SetBasePath(edBasePath.Text); 814 | 815 | SQLQuery.SQL.Text := Format('SELECT id, disp, path, imgpath, pinyin, opinyin FROM %s_roms WHERE type = 0', [EmuConfig.System]); 816 | 817 | try 818 | SQLQuery.Active := True; 819 | SQLQuery.First; 820 | 821 | while not SQLQuery.EOF do 822 | begin 823 | Shortname := SQLQuery.FieldByName('opinyin').AsString; 824 | ImagePath := SQLQuery.FieldByName('imgpath').AsString; 825 | Path := SQLQuery.FieldByName('path').AsString; 826 | 827 | if not FileExists(Lin2Win(edBasePath.Text, ImagePath)) then 828 | begin 829 | ScrapeInfo.SearchStr := Shortname; 830 | ScrapeInfo.Key := Shortname; 831 | Filename := ExtractFilename(Lin2Win(edBasePath.Text, Path)); 832 | ScrapeInfo.ImagePath := EmuConfig.ImgPath + DirectorySeparator + ExtractFileNameWithoutExt(Filename); 833 | TQueueThread.Put(ScrapeInfo); 834 | Inc(Count); 835 | end; 836 | 837 | SQLQuery.Next; 838 | end; 839 | except 840 | on E :Exception do 841 | begin 842 | WriteLog(I18N_ERROROCCURED + ' - ' + EmuConfig.System + '_roms - ' + E.Message); 843 | end; 844 | end; 845 | finally 846 | SQLite3Connection.Connected := False; 847 | end; 848 | end; 849 | end; 850 | end; 851 | end; 852 | Application.ProcessMessages; 853 | until FindNext(SearchRec) <> 0; 854 | 855 | SysUtils.FindClose(SearchRec); 856 | end; 857 | finally 858 | LoadEmuConfig(cboEmulator.Text); 859 | cboEmulator.Enabled := True; 860 | end; 861 | 862 | WriteLog(I18N_DONE + ' - ' + IntToStr(Count)); 863 | end; 864 | 865 | procedure TFormMain.acRenameExecute(Sender: TObject); 866 | begin 867 | if (ActiveControl is TTreeView) and Assigned(TTreeView(ActiveControl).Selected) and (TTreeView(ActiveControl).Selected.Level <> 0) then 868 | TTreeView(ActiveControl).Selected.EditText 869 | else if (ActiveControl is TListView) and Assigned(TListView(ActiveControl).Selected) then 870 | TListView(ActiveControl).Selected.EditCaption; 871 | end; 872 | 873 | procedure TFormMain.acRmDirExecute(Sender: TObject); 874 | begin 875 | DeleteSubDir; 876 | end; 877 | 878 | procedure TFormMain.acSaveEmuInfoExecute(Sender: TObject); 879 | var 880 | EmuPath: String; 881 | JConfig: TJSONConfig; 882 | begin 883 | if cboEmulator.Items.Count = 0 then 884 | exit; 885 | 886 | EmuPath := edBasePath.Text + DirectorySeparator + 'Emus' + DirectorySeparator + EmuConfig.System + DirectorySeparator + 'config.json'; 887 | 888 | if not FileExists(EmuPath) then 889 | begin 890 | WriteLog(EmuPath + ' - ' + I18N_FILENOTFOUND); 891 | exit; 892 | end; 893 | JConfig := TJSONConfig.Create(nil); 894 | try 895 | try 896 | JConfig.Formatted := True; 897 | JConfig.Filename := EmuPath; 898 | 899 | JConfig.SetValue('/label', edLabel.Text); 900 | JConfig.SetValue('/icon', edIcon.Text); 901 | JConfig.SetValue('/rompath' , edRomPath.Text); 902 | if edGamelist.Text <> '' then 903 | JConfig.SetValue('/gamelist', edGamelist.Text) 904 | else 905 | JConfig.DeleteValue('/gamelist'); 906 | JConfig.SetValue('/imgpath' , edImagePath.Text); 907 | 908 | JConfig.SetValue('/shortname', Ord(ckShortname.Checked)); 909 | JConfig.SetValue('/hidebios', Ord(ckHideBios.Checked)); 910 | JConfig.SetValue('/useswap', Ord(ckUseSwap.Checked)); 911 | JConfig.SetValue('/extlist', edExtList.Text); 912 | except 913 | on E: Exception do 914 | WriteLog(EmuConfig.System + ' - config.json : ' + E.Message); 915 | end; 916 | finally 917 | WriteLog(I18N_SAVED + ' - ' + EmuPath); 918 | JConfig.Free; 919 | end; 920 | 921 | end; 922 | 923 | procedure TFormMain.acScanExtExecute(Sender: TObject); 924 | const 925 | SkipExt: array [0..10] of String = 926 | ('', 'bak', 'db', 'xml', 'txt', 'state', 'jpg', 'jpeg', 'png', 'gif', 'sh'); 927 | var 928 | ExtList: String; 929 | 930 | procedure ScanExt(SubDir: String; Level: Integer; var ExtList: String); 931 | var 932 | Info: TSearchRec; 933 | Ext: String; 934 | ExtArray: TStringArray; 935 | begin 936 | if FindFirst(EmuConfig.RomPath + DirectorySeparator + SubDir + DirectorySeparator + '*' , faAnyFile, Info) = 0 then 937 | begin 938 | repeat 939 | repeat 940 | if Copy(Info.Name, 1, 1) = '.' then 941 | break; 942 | 943 | if (Level = 0) and ((Info.Attr and faDirectory) = faDirectory) then 944 | begin 945 | ScanExt(Info.Name, 1, ExtList); 946 | break; 947 | end; 948 | 949 | ExtArray := SplitString(ExtList, '|'); 950 | Ext := Copy(ExtractFileExt(Utf8String(Info.Name)), 2); 951 | 952 | if not {%H-}MatchStr(Ext, ExtArray) and not {%H-}MatchStr(LowerCase(Ext), SkipExt) then 953 | begin 954 | if ExtList = '' then 955 | ExtList := Ext 956 | else 957 | ExtList := ExtList + '|' + Ext; 958 | 959 | WriteLog(I18N_ADDEDEXT + ' - ' + Ext); 960 | end; 961 | until True; 962 | until FindNext(Info) <> 0; 963 | 964 | FindClose(Info); 965 | end; 966 | end; 967 | begin 968 | ExtList := edExtList.Text; 969 | ScanExt('.', 0, ExtList); 970 | if ExtList <> edExtList.Text then 971 | begin 972 | edExtList.Text := ExtList; 973 | btSaveEmuInfo.Click; 974 | end; 975 | end; 976 | 977 | procedure TFormMain.acCancelScrapeExecute(Sender: TObject); 978 | begin 979 | TQueueThread.CancelScrape; 980 | pbInfo.Visible := False; 981 | end; 982 | 983 | procedure TFormMain.acBuildGamelistExecute(Sender: TObject); 984 | var 985 | Xml: TXMLDocument; 986 | RootNode, Node, ChildNode: TDOMNode; 987 | begin 988 | if cboEmulator.Items.Count = 0 then 989 | begin 990 | ShowMessage(I18N_NOSELEMUL); 991 | exit; 992 | end; 993 | 994 | if not FileExists(EmuConfig.CachePath) then 995 | btGenerateCache.Click; 996 | 997 | if Application.MessageBox(PChar(I18N_GAMELISTCONFIRM), 998 | PChar(I18N_CONFIRM), MB_ICONQUESTION + MB_YESNO) <> IDYES then 999 | exit; 1000 | 1001 | SQLite3Connection.DatabaseName := EmuConfig.CachePath; 1002 | 1003 | if not SQLite3Connection.Connected then 1004 | SQLite3Connection.Connected := True; 1005 | 1006 | Xml := TXMLDocument.Create; 1007 | 1008 | try 1009 | SQLQuery.SQL.Text := Format('SELECT disp, path, imgpath, type, pinyin, opinyin FROM %s_roms', [EmuConfig.System]); 1010 | try 1011 | SQLQuery.Active := True; 1012 | except 1013 | on E :Exception do 1014 | begin 1015 | WriteLog(I18N_ERROROCCURED + ' - ' + EmuConfig.System + '_roms - ' + E.Message); 1016 | exit; 1017 | end; 1018 | end; 1019 | 1020 | RootNode := Xml.CreateElement('gameList'); 1021 | Xml.AppendChild(RootNode); 1022 | 1023 | SQLQuery.First; 1024 | 1025 | while not SQLQuery.EOF do 1026 | begin 1027 | if SQLQuery.FieldByName('type').AsInteger = 0 then 1028 | Node := Xml.CreateElement('game') 1029 | else 1030 | Node := Xml.CreateElement('folder'); 1031 | RootNode.AppendChild(Node); 1032 | 1033 | ChildNode := Xml.CreateElement('name'); 1034 | ChildNode.TextContent := SQLQuery.FieldByName('disp').AsUnicodeString; 1035 | Node.AppendChild(ChildNode); 1036 | 1037 | ChildNode := Xml.CreateElement('image'); 1038 | ChildNode.TextContent := SQLQuery.FieldByName('imgpath').AsUnicodeString; 1039 | Node.AppendChild(ChildNode); 1040 | 1041 | if SQLQuery.FieldByName('type').AsInteger = 0 then 1042 | begin 1043 | ChildNode := Xml.CreateElement('path'); 1044 | // ChildNode.TextContent := UnicodeString(StringReplace(SQLQuery.FieldByName('path').AsString, EmuConfig.EmuPath + '/', '', [])); 1045 | ChildNode.TextContent := SQLQuery.FieldByName('path').AsUnicodeString; 1046 | Node.AppendChild(ChildNode); 1047 | end; 1048 | 1049 | SQLQuery.Next; 1050 | end; 1051 | 1052 | if (Trim(EmuConfig.Gamelist) = '') or (Trim(edGamelist.Text) = '') then 1053 | begin 1054 | edGamelist.Text := edRomPath.Text + '/gamelist.xml'; 1055 | acSaveEmuInfo.Execute; 1056 | 1057 | EmuConfig.Gamelist := Lin2Win(edBasePath.Text, edGamelist.Text); 1058 | end; 1059 | 1060 | WriteXMLFile(Xml, EmuConfig.Gamelist); 1061 | WriteLog(EmuConfig.Gamelist + ' - ' + I18N_CREATED); 1062 | finally 1063 | if Xml <> nil then 1064 | Xml.Free; 1065 | SQLite3Connection.Connected := False; 1066 | end; 1067 | end; 1068 | 1069 | procedure TFormMain.acCacheFromXmlExecute(Sender: TObject); 1070 | begin 1071 | with TOpenDialog.Create(Self) do 1072 | try 1073 | Filter := 'gamelist file|*.xml'; 1074 | 1075 | if not Execute then 1076 | exit; 1077 | 1078 | GenCacheFromXml(FileName); 1079 | finally 1080 | Free; 1081 | end; 1082 | end; 1083 | 1084 | procedure TFormMain.acAboutExecute(Sender: TObject); 1085 | begin 1086 | ShowMessage('Author: ryusatgat (https://www.ryugod.com)'); 1087 | end; 1088 | 1089 | procedure TFormMain.acAddRomExecute(Sender: TObject); 1090 | var 1091 | Ext: String; 1092 | Filenames: array of String; 1093 | i: Integer; 1094 | begin 1095 | if cboEmulator.Items.Count = 0 then 1096 | begin 1097 | ShowMessage(I18N_NOSELEMUL); 1098 | exit; 1099 | end; 1100 | 1101 | Filenames := []; 1102 | Ext := '*.' + StringReplace(edExtList.Text, '|', ';*.', [rfReplaceAll]); 1103 | with TOpenDialog.Create(Self) do 1104 | try 1105 | Options := Options + [ofAllowMultiSelect]; 1106 | Filter := 'Rom file|' + Ext; 1107 | 1108 | if Execute then 1109 | begin 1110 | SetLength(Filenames, Files.Count); 1111 | for i:=0 to Files.Count-1 Do 1112 | Filenames[i] := Files[i]; 1113 | FormDropFiles(Self, Filenames); 1114 | end; 1115 | finally 1116 | Free; 1117 | end; 1118 | end; 1119 | 1120 | procedure TFormMain.acChangeImageExecute(Sender: TObject); 1121 | var 1122 | Key, ImageFile, WinFilename, Ext: String; 1123 | begin 1124 | if ListView.Selected = nil then 1125 | begin 1126 | ShowMessage(I18N_ROMNOTSELECTED); 1127 | exit; 1128 | end; 1129 | 1130 | with TOpenDialog.Create(Self) do 1131 | try 1132 | Filter := 'Image file|*.png;*.jpg;*.jpeg'; 1133 | if Execute then 1134 | begin 1135 | Image.Picture.LoadFromFile(FileName); 1136 | Ext := ExtractFileExt(FileName); 1137 | 1138 | Key := ListView.Selected.SubItems[1]; 1139 | if Copy(edImagePath.Text, 1, 1) = '/' then 1140 | ImageFile := edImagePath.Text + '/' + ExtractFileNameWithoutExt(ExtractFilename(FileName)) + Ext 1141 | else 1142 | ImageFile := EmuConfig.EmuPath + '/' + edImagePath.Text + '/' + ExtractFileNameWithoutExt(ExtractFilename(FileName)) + Ext; 1143 | WinFilename := Lin2Win(edBasePath.Text, ImageFile); 1144 | SaveImage(Image, WinFilename, ckForcePng.Checked); 1145 | 1146 | ListView.Selected.SubItems[0] := ImageFile; 1147 | UpdateCache(Key, 'imgpath', ImageFile); 1148 | end; 1149 | finally 1150 | Free; 1151 | end; 1152 | end; 1153 | 1154 | procedure TFormMain.acDeleteExecute(Sender: TObject); 1155 | var 1156 | i: Integer; 1157 | Key: String; 1158 | ImgPath, RomPath: String; 1159 | begin 1160 | if ListView.Selected = nil then 1161 | exit; 1162 | if Application.MessageBox(PChar(I18N_DELETECONFIRM), 1163 | PChar(I18N_CONFIRM), MB_ICONQUESTION + MB_YESNO) <> IDYES then 1164 | exit; 1165 | 1166 | for i:=ListView.Items.Count-1 downto 0 do 1167 | if ListView.Items[i].Selected then 1168 | begin 1169 | Key := ListView.Items[i].SubItems[1]; 1170 | ImgPath := Lin2Win(edBasePath.Text, ListView.Items[i].SubItems[0]); 1171 | RomPath := Lin2Win(edBasePath.Text, ListView.Items[i].SubItems[2]); 1172 | if FileExists(ImgPath) then 1173 | begin 1174 | SysUtils.DeleteFile(ImgPath); 1175 | WriteLog(I18N_DELETED + ' - ' + ImgPath); 1176 | end; 1177 | if FileExists(RomPath) then 1178 | begin 1179 | SysUtils.DeleteFile(RomPath); 1180 | WriteLog(I18N_DELETED + ' - ' + RomPath); 1181 | end; 1182 | ListView.Items.Delete(i); 1183 | DeleteCache(Key); 1184 | end; 1185 | end; 1186 | 1187 | procedure TFormMain.acDetectBasePathExecute(Sender: TObject); 1188 | var 1189 | Drv: String; 1190 | Path: String; 1191 | {$IFDEF linux} 1192 | i: Integer; 1193 | List: TStringList; 1194 | {$ENDIF} 1195 | begin 1196 | {$IFDEF linux} 1197 | RunCommand('/bin/bash', ['-c', 'grep vfat /proc/mounts'], Drv); 1198 | List := TStringList.Create; 1199 | try 1200 | List.Delimiter := LineEnding; 1201 | List.DelimitedText := Drv; 1202 | for i:=0 to List.Count-1 do 1203 | begin 1204 | if Copy(List.Strings[i], 1, 6) = '/media' then 1205 | begin 1206 | Path := List.Strings[i]; 1207 | if DirectoryExists(Path + '/Emus') then 1208 | begin 1209 | edBasePath.Text := Path; 1210 | btRefresh.Click; 1211 | break; 1212 | end; 1213 | end; 1214 | end; 1215 | finally 1216 | List.Free; 1217 | end; 1218 | {$ELSE} 1219 | for Drv in 'DEFGHIJK' do 1220 | begin 1221 | Path := Drv + ':\'; 1222 | 1223 | if DirectoryExists(Path + '\Emus') then 1224 | begin 1225 | edBasePath.Text := Path; 1226 | btRefresh.Click; 1227 | break; 1228 | end; 1229 | end; 1230 | {$ENDIF} 1231 | end; 1232 | 1233 | procedure TFormMain.acExitExecute(Sender: TObject); 1234 | begin 1235 | Close; 1236 | end; 1237 | 1238 | procedure TFormMain.acGenerateCacheExecute(Sender: TObject); 1239 | begin 1240 | if Application.MessageBox(PChar(I18N_RECACHECONFIRM), 1241 | PChar(I18N_CONFIRM), MB_ICONQUESTION + MB_YESNO) <> IDYES then 1242 | exit; 1243 | 1244 | BuildCache(True); 1245 | cboEmulatorChange(cboEmulator); 1246 | end; 1247 | 1248 | procedure TFormMain.acGithubExecute(Sender: TObject); 1249 | begin 1250 | openURL('https://github.com/ryusatgat/trimuitool'); 1251 | end; 1252 | 1253 | procedure TFormMain.acMkDirExecute(Sender: TObject); 1254 | var 1255 | Dir, Path: String; 1256 | begin 1257 | if cboEmulator.Items.Count = 0 then 1258 | begin 1259 | ShowMessage(I18N_NOSELEMUL); 1260 | exit; 1261 | end; 1262 | Dir := ''; 1263 | if not InputQuery(I18N_MAKEDIR, I18N_INPUTDIRNAME, Dir) then 1264 | exit; 1265 | Path := Lin2Win(edBasePath.Text, EmuConfig.EmuPath + '/' + edRomPath.Text + '/' + Dir); 1266 | 1267 | if DirectoryExists(Path) then 1268 | begin 1269 | ShowMessage(I18N_DIREXISTS); 1270 | exit 1271 | end; 1272 | 1273 | if not CreateDir(Path) then 1274 | begin 1275 | WriteLog(Path); 1276 | ShowMessage(I18N_ERROROCCURED); 1277 | exit; 1278 | end; 1279 | 1280 | Path := EmuConfig.EmuPath + '/' + edRomPath.Text + '/' + Dir; 1281 | ExecCacheSQL('INSERT INTO %s_roms (disp, path, imgpath, type, ppath, pinyin, cpinyin, opinyin) VALUES (%s, %s, %s, 1, ''.'', '''', '''', '''')', 1282 | [EmuConfig.System, QuotedStr(Dir), QuotedStr(Path), QuotedStr(Path), QuotedStr(Dir)]); 1283 | 1284 | btRefresh.Click; 1285 | end; 1286 | 1287 | procedure TFormMain.acOpenBasePathExecute(Sender: TObject); 1288 | begin 1289 | with TSelectDirectoryDialog.Create(nil) do 1290 | try 1291 | if Execute then 1292 | begin 1293 | edBasePath.Text := FileName; 1294 | btRefresh.Click; 1295 | end; 1296 | finally 1297 | Free; 1298 | end; 1299 | end; 1300 | 1301 | procedure TFormMain.acOpenImagePosExecute(Sender: TObject); 1302 | var 1303 | OStr: String; 1304 | begin 1305 | {$IFDEF Linux} 1306 | if Image.Hint <> '' then 1307 | RunCommand('open', [Image.Hint], OStr); 1308 | {$ELSE} 1309 | RunCommand('explorer.exe', ['/select,"' + Image.Hint + '"'], OStr); 1310 | {$ENDIF} 1311 | end; 1312 | 1313 | procedure TFormMain.acRefreshExecute(Sender: TObject); 1314 | begin 1315 | LoadEmus(edBasePath.Text); 1316 | cboEmulatorChange(cboEmulator); 1317 | end; 1318 | 1319 | procedure TFormMain.cboEmulatorChange(Sender: TObject); 1320 | begin 1321 | if cboEmulator.Items.Count = 0 then 1322 | exit; 1323 | 1324 | LoadEmuConfig(cboEmulator.Text); 1325 | LoadEmuInfo(cboEmulator.Text); 1326 | 1327 | if not FileExists(EmuConfig.CachePath) then 1328 | BuildCache; 1329 | GetSubDir; 1330 | end; 1331 | 1332 | procedure TFormMain.edSearchKeyPress(Sender: TObject; var Key: char); 1333 | begin 1334 | if Key = #13 then 1335 | btScrape.Click; 1336 | end; 1337 | 1338 | procedure TFormMain.FormClose(Sender: TObject; var CloseAction: TCloseAction); 1339 | begin 1340 | WriteSettings; 1341 | TQueueThread.CancelScrape; 1342 | end; 1343 | 1344 | procedure TFormMain.FormCreate(Sender: TObject); 1345 | begin 1346 | InitCriticalSection(CriticalSection); 1347 | IPCServer := TSimpleIPCServer.Create(nil); 1348 | {$ifdef linux} 1349 | Application.OnIdle := @AppIdle; 1350 | {$endif} 1351 | IPCServer.ServerID := 'WriteLog'; 1352 | IPCServer.OnMessageQueued := @IPCServerMessage; 1353 | IPCServer.Global := True; 1354 | IPCServer.StartServer; 1355 | 1356 | SystemMap := TStringList.Create; 1357 | 1358 | SystemMap.Add('DC=Sega Dreamcast'); 1359 | SystemMap.Add('FC=nes'); 1360 | SystemMap.Add('FDS=Famicom Disk System'); 1361 | SystemMap.Add('ARCADE=arcade'); 1362 | SystemMap.Add('FBNEO=arcade'); 1363 | SystemMap.Add('CPS1=arcade'); 1364 | SystemMap.Add('CPS2=arcade'); 1365 | SystemMap.Add('CPS3=arcade'); 1366 | SystemMap.Add('GB=gb'); 1367 | SystemMap.Add('GBA=gba'); 1368 | SystemMap.Add('GBC=gbc'); 1369 | SystemMap.Add('GG=Sega Game Gear'); 1370 | SystemMap.Add('GW=Nintendo Game & Watch'); 1371 | SystemMap.Add('LYNX=Atari Lynx'); 1372 | SystemMap.Add('MAME=arcade'); 1373 | SystemMap.Add('MAME2003PLUS=arcade'); 1374 | SystemMap.Add('MAME2010=arcade'); 1375 | SystemMap.Add('MD=megadrive'); 1376 | SystemMap.Add('MS=mastersystem'); 1377 | SystemMap.Add('N64=Nintendo 64'); 1378 | SystemMap.Add('NAOMI=Sega NAOMI'); 1379 | SystemMap.Add('NGP=ngp'); 1380 | SystemMap.Add('NEOGEO=arcade'); 1381 | SystemMap.Add('OPERA=3DO'); 1382 | SystemMap.Add('PCE=pcengine'); 1383 | SystemMap.Add('PCECD=pcengine'); 1384 | SystemMap.Add('PGM=PolyGame Master'); 1385 | SystemMap.Add('PS=Sony Playstation'); 1386 | SystemMap.Add('PSP=Sony PSP'); 1387 | SystemMap.Add('PSPMINIS=Sony PSP Minis'); 1388 | SystemMap.Add('SATURN=Sega Saturn'); 1389 | SystemMap.Add('SCD=Sega CD'); 1390 | SystemMap.Add('SEGA32X=sega32x'); 1391 | SystemMap.Add('SFC=snes'); 1392 | SystemMap.Add('SFX=SuperGrafx'); 1393 | SystemMap.Add('SG1000=Sega SG-1000'); 1394 | SystemMap.Add('SGB=Super Game Boy'); 1395 | SystemMap.Add('VB=Nintendo Virtual Boy'); 1396 | SystemMap.Add('DOS=DOSBOX'); 1397 | SystemMap.Add('WS=wonderswan'); 1398 | 1399 | QueueThread := TQueueThread.Create(False); 1400 | end; 1401 | 1402 | procedure TFormMain.FormDestroy(Sender: TObject); 1403 | begin 1404 | SQLName.Close; 1405 | SQLite3Name.Connected := False; 1406 | 1407 | TQueueThread.CancelScrape; 1408 | QueueThread.Terminate; 1409 | QueueThread.WaitFor; 1410 | QueueThread.Free; 1411 | IPCServer.StopServer; 1412 | IPCServer.Free; 1413 | SystemMap.Free; 1414 | 1415 | DoneCriticalSection(CriticalSection); 1416 | end; 1417 | 1418 | procedure TFormMain.FormDropFiles(Sender: TObject; 1419 | const FileNames: array of string); 1420 | var 1421 | Key, ImageFile, Ext, Filename, Fullname: String; 1422 | Path, SubDir: String; 1423 | i: Integer; 1424 | begin 1425 | if cboEmulator.Items.Count = 0 then 1426 | exit; 1427 | 1428 | for i:=0 to Length(FileNames)-1 do 1429 | begin 1430 | Ext := ExtractFileExt(FileNames[i]); 1431 | if Pos(Copy(Ext, 2), EmuConfig.ExtList) > 0 then 1432 | begin 1433 | SubDir := TreeView.Selected.Text; 1434 | Filename := ExtractFileNameWithoutExt(ExtractFileName(Filenames[i])); 1435 | Fullname := InsertCache(ExtractFileName(Filenames[i]), SubDir); 1436 | if Fullname = '' then 1437 | exit; 1438 | Path := EmuConfig.RomPath; 1439 | Path := StringReplace(Path, '..' + DirectorySeparator + '..', edBasePath.Text, [rfReplaceAll]); 1440 | if Assigned(TreeView.Selected) and (TreeView.Selected.Level > 0) then 1441 | Path := Path + DirectorySeparator + SubDir; 1442 | Path := Path + DirectorySeparator + Filename + Ext; 1443 | CopyFile(Filenames[i], Path); 1444 | WriteLog(Filenames[i] + ' --> ' + Path); 1445 | GetEmuList(TreeView.Selected.Text); 1446 | end else if Ext = '.xml' then 1447 | begin 1448 | if Application.MessageBox(PChar(I18N_CACHEFROMXML), 1449 | PChar(I18N_CONFIRM), MB_ICONQUESTION + MB_YESNO) <> IDYES then 1450 | exit; 1451 | GenCacheFromXml(FileNames[0]); 1452 | exit; 1453 | end else begin 1454 | if ListView.Selected = nil then 1455 | begin 1456 | ShowMessage(I18N_ROMNOTSELECTED); 1457 | exit; 1458 | end; 1459 | 1460 | case Ext of 1461 | '.jpg','.jpeg','.png': 1462 | else 1463 | exit; 1464 | end; 1465 | Ext := ExtractFileExt(FileNames[0]); 1466 | Image.Picture.LoadFromFile(FileNames[0]); 1467 | Key := ListView.Selected.SubItems[1]; 1468 | 1469 | Filename := ExtractFilename(FileNames[0]); 1470 | if Copy(edImagePath.Text, 1, 1) = '/' then 1471 | ImageFile := edImagePath.Text + '/' + ExtractFileNameWithoutExt(Filename) + Ext 1472 | else 1473 | ImageFile := EmuConfig.EmuPath + '/' + edImagePath.Text + '/' + ExtractFileNameWithoutExt(FileName) + Ext; 1474 | 1475 | Filename := Lin2Win(edBasePath.Text, ImageFile); 1476 | SaveImage(Image, Filename, ckForcePng.Checked); 1477 | ListView.Selected.SubItems[0] := ImageFile; 1478 | UpdateCache(Key, 'imgpath', ImageFile); 1479 | exit; 1480 | end; 1481 | end; 1482 | end; 1483 | 1484 | procedure TFormMain.FormShow(Sender: TObject); 1485 | var 1486 | DbPath: String; 1487 | begin 1488 | WriteLog(I18N_ROMFROM); 1489 | 1490 | DbPath := ExtractFileDir(Application.ExeName) + DirectorySeparator + 'romnames.db'; 1491 | if not FileExists(DbPath) then 1492 | WriteLog('romnames.db - ' + I18N_FILENOTFOUND) 1493 | else 1494 | SQLite3Name.DatabaseName := DbPath; 1495 | 1496 | btAutoDetect.Click; 1497 | ReadSettings; 1498 | end; 1499 | 1500 | procedure TFormMain.Image1Click(Sender: TObject); 1501 | var 1502 | Picture: TPicture; 1503 | begin 1504 | Picture := TPicture.Create; 1505 | try 1506 | if Assigned(TImage(Sender).Picture) then 1507 | begin 1508 | Picture.Assign(Image.Picture); 1509 | Image.Picture.Assign(TImage(Sender).Picture); 1510 | TImage(Sender).Picture.Assign(Picture); 1511 | 1512 | if Image.Hint <> '' then 1513 | begin 1514 | Image.Picture.SaveToFile(Image.Hint); 1515 | WriteLog(I18N_SAVED + ' - ' + Image.Hint); 1516 | end; 1517 | end; 1518 | finally 1519 | if Assigned(Picture) then 1520 | Picture.Free; 1521 | end; 1522 | end; 1523 | 1524 | procedure TFormMain.ListViewCustomDrawItem(Sender: TCustomListView; 1525 | Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean); 1526 | begin 1527 | if not FileExists(Lin2Win(edBasePath.Text, Item.SubItems[2])) then 1528 | begin 1529 | TListView(Sender).Canvas.Brush.Color := $00FF80FF; 1530 | Item.ImageIndex := 4; 1531 | end else if not FileExists(Lin2Win(edBasePath.Text, Item.SubItems[0])) then 1532 | begin 1533 | TListView(Sender).Canvas.Brush.Color := $0080FFFF; 1534 | Item.ImageIndex := 5; 1535 | end else 1536 | Item.ImageIndex := 3; 1537 | end; 1538 | 1539 | procedure TFormMain.ListViewEdited(Sender: TObject; Item: TListItem; 1540 | var AValue: string); 1541 | begin 1542 | if not RenameTitle(Item.SubItems[1], AValue) then 1543 | AValue := Item.Caption; 1544 | end; 1545 | 1546 | procedure TFormMain.ListViewSelectItem(Sender: TObject; Item: TListItem; 1547 | Selected: Boolean); 1548 | var 1549 | ImagePath: String; 1550 | begin 1551 | if not Selected then 1552 | begin 1553 | acScrape.Enabled := False; 1554 | exit; 1555 | end; 1556 | ImagePath := Lin2Win(edBasePath.Text, Item.SubItems[0]); 1557 | acScrape.Enabled := True; 1558 | Image.Hint := ImagePath; 1559 | 1560 | if FileExists(ImagePath) then 1561 | Image.Picture.LoadFromFile(ImagePath) 1562 | else 1563 | Image.Picture.Assign(NoImage.Picture); 1564 | end; 1565 | 1566 | procedure TFormMain.mnLangKorClick(Sender: TObject); 1567 | begin 1568 | mnLangKor.Checked := False; 1569 | mnLangEng.Checked := False; 1570 | TMenuItem(Sender).Checked := True; 1571 | Translate(TMenuItem(Sender).Hint); 1572 | end; 1573 | 1574 | procedure TFormMain.TreeViewChange(Sender: TObject; Node: TTreeNode); 1575 | begin 1576 | if not Assigned(Node) then 1577 | exit; 1578 | if Node.Level = 0 then 1579 | TreeView.ReadOnly := True 1580 | else 1581 | TreeView.ReadOnly := False; 1582 | GetEmuList(Node.Text); 1583 | end; 1584 | 1585 | procedure TFormMain.TreeViewDragDrop(Sender, Source: TObject; X, Y: Integer); 1586 | var 1587 | i: Integer; 1588 | Node: TTreeNode; 1589 | OldPath, Path, PPath, Filename, Shortname: String; 1590 | begin 1591 | if Source is TListView then 1592 | begin 1593 | if not Assigned(TListView(Source).Selected) then 1594 | exit; 1595 | 1596 | Node := TTreeView(Sender).GetNodeAt(X, Y); 1597 | 1598 | if Assigned(Node) and not Node.Selected then 1599 | begin 1600 | Node.ImageIndex := 0; 1601 | for i:=ListView.Items.Count-1 downto 0 do 1602 | begin 1603 | if not ListView.Items[i].Selected then 1604 | continue; 1605 | Filename := ExtractFileName(Lin2Win(edBasePath.Text, ListView.Items[i].SubItems[2])); 1606 | Shortname := ListView.Items[i].SubItems[1]; 1607 | OldPath := ListView.Items[i].SubItems[2]; 1608 | Path := EmuConfig.EmuPath + '/' + edRomPath.Text; 1609 | if Node.Level = 0 then 1610 | PPath := '.' 1611 | else begin 1612 | PPath := Node.Text; 1613 | Path := Path + '/' + PPath; 1614 | end; 1615 | Path := Path + '/' + Filename; 1616 | 1617 | WriteLog(OldPath + ' --> ' + Path); 1618 | RenameFile(Lin2Win(edBasePath.Text, OldPath), Lin2Win(edBasePath.Text, Path)); 1619 | 1620 | ExecCacheSQL('UPDATE %s_roms SET path = %s, ppath = %s WHERE opinyin = %s', 1621 | [EmuConfig.System, QuotedStr(Path), QuotedStr(PPath), QuotedStr(Shortname)]); 1622 | 1623 | ListView.BeginUpdate; 1624 | try 1625 | ListView.Items[i].Delete; 1626 | finally 1627 | ListView.EndUpdate; 1628 | end; 1629 | end; 1630 | end; 1631 | end; 1632 | end; 1633 | 1634 | procedure TFormMain.TreeViewDragOver(Sender, Source: TObject; X, Y: Integer; 1635 | State: TDragState; var Accept: Boolean); 1636 | var 1637 | i: Integer; 1638 | Node: TTreeNode; 1639 | begin 1640 | Accept := Source is TListView; 1641 | if Accept then 1642 | begin 1643 | Node := TTreeView(Sender).GetNodeAt(X, Y); 1644 | 1645 | for i:=0 to TTreeView(Sender).Items.Count-1 do 1646 | begin 1647 | if not TTreeView(Sender).Items[i].Selected then 1648 | TTreeView(Sender).Items[i].ImageIndex := 0; 1649 | end; 1650 | if Assigned(Node) and not Node.Selected then 1651 | begin 1652 | Node.ImageIndex := 2; 1653 | end; 1654 | end; 1655 | end; 1656 | 1657 | procedure TFormMain.TreeViewEdited(Sender: TObject; Node: TTreeNode; 1658 | var S: string); 1659 | begin 1660 | if not RenameSubDir(Node.Text, S) then 1661 | S := Node.Text 1662 | else 1663 | GetEmuList(S); 1664 | end; 1665 | 1666 | procedure TFormMain.AppIdle(Sender: TObject; var Done: Boolean); 1667 | begin 1668 | IPCServer.PeekMessage(1, True); 1669 | end; 1670 | 1671 | procedure TFormMain.IPCServerMessage(Sender: TObject); 1672 | var 1673 | ImageFile, Key: String; 1674 | StrArr: TStringArray; 1675 | i, ImageCount: Integer; 1676 | Count, TotalCount: Integer; 1677 | ImagePath, ImageBase: String; 1678 | begin 1679 | IPCServer.ReadMessage; 1680 | if (Copy(IPCServer.StringMessage, 1, 1) = '@') then 1681 | begin 1682 | try 1683 | StrArr := Copy(IPCServer.StringMessage, 2).Split('|'); 1684 | ImageFile := StrArr[0]; 1685 | ImageBase := Strarr[1]; 1686 | Key := StrArr[2]; 1687 | ImageCount := StrToInt(StrArr[3]); 1688 | Count := StrToInt(StrArr[4]); 1689 | TotalCount := StrToInt(StrArr[5]); 1690 | 1691 | if ImageCount > 0 then 1692 | begin 1693 | Image1.Picture.Clear; 1694 | Image2.Picture.Clear; 1695 | Image3.Picture.Clear; 1696 | Image4.Picture.Clear; 1697 | end; 1698 | 1699 | pbInfo.Visible := TotalCount-Count > 0; 1700 | pbInfo.Max := TotalCount; 1701 | pbInfo.Position := TotalCount - Count; 1702 | pbInfo.Caption := Format('%d / %d', [TotalCount-Count, TotalCount]); 1703 | pbInfo.Hint := pbInfo.Caption; 1704 | 1705 | EnterCriticalSection(CriticalSection); 1706 | try 1707 | for i:=1 to ImageCount do 1708 | begin 1709 | ImagePath := ExtractFilePath(Application.ExeName) + DirectorySeparator + 'Image' + IntToStr(i) + '.jpg'; 1710 | case i of 1711 | 1: Image1.Picture.LoadFromFile(ImagePath); 1712 | 2: Image2.Picture.LoadFromFile(ImagePath); 1713 | 3: Image3.Picture.LoadFromFile(ImagePath); 1714 | 4: Image4.Picture.LoadFromFile(ImagePath); 1715 | end; 1716 | end; 1717 | finally 1718 | LeaveCriticalSection(CriticalSection); 1719 | end; 1720 | except 1721 | on E :Exception do 1722 | begin 1723 | WriteLog(E.Message); 1724 | exit; 1725 | end; 1726 | end; 1727 | 1728 | EnterCriticalSection(CriticalSection); 1729 | try 1730 | if FileExists(ImageFile) then 1731 | begin 1732 | Image.Picture.LoadFromFile(ImageFile); 1733 | Image.Hint := ImageFile; 1734 | 1735 | for i:=0 to ListView.Items.Count-1 do 1736 | if ListView.Items[i].SubItems[1] = Key then 1737 | begin 1738 | if Copy(edImagePath.Text, 1, 1) = '/' then 1739 | ImageFile := ImageBase + '/' + ExtractFileName(ImageFile) 1740 | else 1741 | ImageFile := EmuConfig.EmuPath + '/' + ImageBase + '/' + ExtractFileName(ImageFile); 1742 | 1743 | ListView.Items[i].SubItems[0] := ImageFile; 1744 | UpdateCache(Key, 'imgpath', ImageFile); 1745 | break; 1746 | end; 1747 | end; 1748 | finally 1749 | LeaveCriticalSection(CriticalSection); 1750 | end; 1751 | 1752 | WriteLog(Key + ' (' + pbInfo.Caption + ') - ' + I18N_DONESCRAPE); 1753 | end else 1754 | WriteLog(IPCServer.StringMessage); 1755 | end; 1756 | 1757 | procedure TFormMain.LoadEmus(BasePath: String); 1758 | var 1759 | SearchRec: TSearchRec; 1760 | EmuPath: String; 1761 | begin 1762 | EmuPath := BasePath + DirectorySeparator + 'Emus'; 1763 | 1764 | if not DirectoryExists(EmuPath) then 1765 | begin 1766 | WriteLog(EmuPath + ' - ' + I18N_DIRNOTFOUND); 1767 | exit; 1768 | end; 1769 | 1770 | if cboEmulator.ItemIndex >= 0 then 1771 | cboEmulator.Tag := cboEmulator.ItemIndex; 1772 | cboEmulator.Clear; 1773 | 1774 | if FindFirst(EmuPath + DirectorySeparator + '*', faDirectory, SearchRec) = 0 then 1775 | begin 1776 | repeat 1777 | if Copy(SearchRec.Name, 1, 1) <> '.' then 1778 | begin 1779 | if not FileExists(EmuPath + DirectorySeparator + SearchRec.Name + DirectorySeparator + 'config.json') then 1780 | WriteLog(EmuPath + DirectorySeparator + SearchRec.Name + DirectorySeparator + 'config.json - ' + I18N_FILENOTFOUND) 1781 | else begin 1782 | if LoadEmuConfig(SearchRec.Name) then 1783 | begin 1784 | if not DirectoryExists(EmuConfig.RomPath) then 1785 | WriteLog(EmuConfig.RomPath + ' - ' + I18N_FILENOTFOUND) 1786 | else 1787 | cboEmulator.Items.AddStrings(SearchRec.Name); 1788 | end; 1789 | end; 1790 | end; 1791 | Application.ProcessMessages; 1792 | until FindNext(SearchRec) <> 0; 1793 | 1794 | SysUtils.FindClose(SearchRec); 1795 | end; 1796 | 1797 | if cboEmulator.Items.Count > 0 then 1798 | begin 1799 | btGenerateCache.Enabled := True; 1800 | if cboEmulator.Items.Count > cboEmulator.Tag then 1801 | cboEmulator.ItemIndex := cboEmulator.Tag 1802 | else 1803 | cboEmulator.ItemIndex := 0; 1804 | end else 1805 | btGenerateCache.Enabled := False; 1806 | end; 1807 | 1808 | procedure TFormMain.WriteLog(Log: String); 1809 | begin 1810 | mmLog.Lines.Add(Format('[%s] %s', [TimeToStr(Now), Log])); 1811 | mmLog.CaretPos := Point(0, mmLog.Lines.Count-1); 1812 | end; 1813 | 1814 | function TFormMain.LoadEmuConfig(System: String): Boolean; 1815 | var 1816 | EmuPath: String; 1817 | JConfig: TJSONConfig; 1818 | begin 1819 | EmuPath := edBasePath.Text + DirectorySeparator + 'Emus' + DirectorySeparator + System; 1820 | SetCurrentDir(EmuPath); 1821 | EmuPath := EmuPath + DirectorySeparator + 'config.json'; 1822 | 1823 | if not FileExists(EmuPath) then 1824 | begin 1825 | WriteLog(EmuPath + ' - ' + I18N_FILENOTFOUND); 1826 | Result := False; 1827 | exit; 1828 | end; 1829 | JConfig := TJSONConfig.Create(nil); 1830 | try 1831 | try 1832 | JConfig.Filename := EmuPath; 1833 | 1834 | EmuConfig.RomPath := Lin2Win(edBasePath.Text, String(JConfig.GetValue('/rompath' , '../../Roms/' + System))); 1835 | EmuConfig.System := ExtractFileNameOnly(EmuConfig.RomPath); 1836 | EmuConfig.EmuPath := BASE_PATH + '/Emus/' + System; 1837 | EmuConfig.Caption:= String(JConfig.GetValue('/label', '')); 1838 | EmuConfig.Icon := String(JConfig.GetValue('/icon', '')); 1839 | EmuConfig.CachePath := EmuConfig.RomPath + DirectorySeparator + EmuConfig.System + '_cache7.db'; 1840 | EmuConfig.Gamelist := Lin2Win(edBasePath.Text, String(JConfig.GetValue('/gamelist', ''))); 1841 | EmuConfig.ImgPath := Lin2Win(edBasePath.Text, String(JConfig.GetValue('/imgpath' , '../Imgs/' + System))); 1842 | if Copy(EmuConfig.ImgPath, 1, 5) = '..' + DirectorySeparator + '..' then 1843 | EmuConfig.ImgPath := StringReplace(EmuConfig.ImgPath, '..' + DirectorySeparator + '..', edBasePath.Text, [rfReplaceAll]); 1844 | EmuConfig.Shortname := JConfig.GetValue('/shortname', 0) = 1; 1845 | EmuConfig.HideBios := JConfig.GetValue('/hidebios', 0) = 1; 1846 | EmuConfig.UseSwap := JConfig.GetValue('/useswap', 0) = 1; 1847 | EmuConfig.ExtList:= String(JConfig.GetValue('/extlist', 'zip')); 1848 | except 1849 | on E: Exception do 1850 | begin 1851 | WriteLog(EmuConfig.System + ' - config.json : ' + E.Message); 1852 | Result := False; 1853 | exit; 1854 | end; 1855 | end; 1856 | 1857 | finally 1858 | JConfig.Free; 1859 | end; 1860 | Result := True; 1861 | end; 1862 | 1863 | function TFormMain.LoadEmuInfo(System: String): Boolean; 1864 | var 1865 | EmuPath: String; 1866 | JConfig: TJSONConfig; 1867 | begin 1868 | EmuPath := edBasePath.Text + DirectorySeparator + 'Emus' + DirectorySeparator + System + DirectorySeparator + 'config.json'; 1869 | 1870 | if not FileExists(EmuPath) then 1871 | begin 1872 | WriteLog(EmuPath + ' - ' + I18N_FILENOTFOUND); 1873 | Result := False; 1874 | exit; 1875 | end; 1876 | JConfig := TJSONConfig.Create(nil); 1877 | try 1878 | JConfig.Filename := EmuPath; 1879 | 1880 | edLabel.Text := String(JConfig.GetValue('/label', '')); 1881 | edIcon.Text := String(JConfig.GetValue('/icon', '')); 1882 | edRomPath.Text := String(JConfig.GetValue('/rompath' , '../../Roms/' + System)); 1883 | edGamelist.Text := String(JConfig.GetValue('/gamelist', '')); 1884 | edImagePath.Text := String(JConfig.GetValue('/imgpath' , '../Imgs/' + System)); 1885 | ckShortname.Checked := JConfig.GetValue('/shortname', 0) = 1; 1886 | ckHideBios.Checked := JConfig.GetValue('/hidebios', 0) = 1; 1887 | ckUseSwap.Checked := JConfig.GetValue('/useswap', 0) = 1; 1888 | edExtList.Text := String(JConfig.GetValue('/extlist', 'zip')); 1889 | finally 1890 | JConfig.Free; 1891 | end; 1892 | Result := True; 1893 | end; 1894 | 1895 | function TFormMain.SaveEmuConfig(System: String): Boolean; 1896 | var 1897 | EmuPath: String; 1898 | begin 1899 | EmuPath := edBasePath.Text + DirectorySeparator + 'Emus' + DirectorySeparator + System + DirectorySeparator + 'config.json'; 1900 | 1901 | if not FileExists(EmuPath) then 1902 | begin 1903 | WriteLog(EmuPath + ' - ' + I18N_FILENOTFOUND); 1904 | Result := False; 1905 | exit; 1906 | end; 1907 | 1908 | Result := True; 1909 | end; 1910 | 1911 | procedure TFormMain.BuildCache(IsDelete: Boolean=False); 1912 | var 1913 | Count, AddedCount: Integer; 1914 | ExtList: TStringArray; 1915 | Path: String; 1916 | 1917 | procedure FindUpdate(SubDir: String; Level: Integer); 1918 | var 1919 | Info: TSearchRec; 1920 | Path, ImgPath, Shortname, Fullname: String; 1921 | begin 1922 | if FindFirst(EmuConfig.RomPath + DirectorySeparator + SubDir + DirectorySeparator + '*' , faAnyFile, Info) = 0 then 1923 | begin 1924 | repeat 1925 | repeat 1926 | if Copy(Info.Name, 1, 1) = '.' then 1927 | break; 1928 | if (Level = 0) and ((Info.Attr and faDirectory) = faDirectory) then 1929 | begin 1930 | FindUpdate(Info.Name, 1); 1931 | break; 1932 | end; 1933 | 1934 | if (Info.Attr and faDirectory) = faDirectory then 1935 | break; 1936 | ExtList := SplitString(EmuConfig.ExtList, '|'); 1937 | if {%H-}MatchStr(Copy(ExtractFileExt(Info.Name), 2), ExtList) then 1938 | begin 1939 | Shortname := ExtractFileNameWithoutExt(ExtractFileName(UTF8String(Info.Name))); 1940 | FullName := GetFullTitle(Shortname, Shortname); 1941 | SQLQuery.SQL.Text := Format('UPDATE %s_roms SET disp = %s WHERE opinyin = %s', [EmuConfig.System, QuotedStr(FullName), QuotedStr(Shortname)]); 1942 | SQLQuery.ExecSQL; 1943 | if SQLQuery.RowsAffected = 0 then 1944 | begin 1945 | Inc(AddedCount); 1946 | Path := EmuConfig.EmuPath + '/' + edRomPath.Text + '/'; 1947 | if SubDir = '' then 1948 | SubDir := '.' 1949 | else 1950 | Path := Path + SubDir + '/'; 1951 | Path := Path + Shortname + ExtractFileExt(Utf8String(Info.Name)); 1952 | if Copy(edImagePath.Text, 1, 1) = '/' then 1953 | ImgPath := edImagePath.Text + '/' + Shortname 1954 | else 1955 | ImgPath := EmuConfig.EmuPath + '/' + edImagePath.Text + '/' + Shortname; 1956 | if FileExists(Lin2Win(edBasePath.Text, ImgPath + '.jpg')) then 1957 | ImgPath := ImgPath + '.jpg' 1958 | else 1959 | ImgPath := ImgPath + '.png'; 1960 | 1961 | SQLQuery.SQL.Text := Format('INSERT INTO %s_roms (disp, path, imgpath, type, ppath, pinyin, cpinyin, opinyin) VALUES (%s, %s, %s, 0, %s, %s, %s, %s)', 1962 | [EmuConfig.System, QuotedStr(Fullname), QuotedStr(Path), QuotedStr(ImgPath), QuotedStr(SubDir), QuotedStr(Fullname), QuotedStr(Fullname), QuotedStr(Shortname)]); 1963 | SQLQuery.ExecSQL; 1964 | end; 1965 | end; 1966 | 1967 | Inc(Count); 1968 | 1969 | if Count mod 100 = 0 then 1970 | begin 1971 | WriteLog(I18N_PROCESSING + '... ' + IntToStr(Count)); 1972 | Application.ProcessMessages; 1973 | end; 1974 | until True; 1975 | until FindNext(Info) <> 0; 1976 | 1977 | FindClose(Info); 1978 | end; 1979 | end; 1980 | 1981 | begin 1982 | if IsDelete and FileExists(EmuConfig.CachePath) then 1983 | DeleteFile(EmuConfig.CachePath); 1984 | 1985 | SQLite3Connection.DatabaseName := EmuConfig.CachePath; 1986 | if not SQLite3Connection.Connected then 1987 | SQLite3Connection.Connected := True; 1988 | 1989 | WriteLog(EmuConfig.System + ' - ' + I18N_GENCACHE); 1990 | Count := 0; 1991 | AddedCount := 0; 1992 | try 1993 | SQLQuery.SQL.Text := 1994 | Format('CREATE TABLE IF NOT EXISTS %s_roms (id INTEGER NOT NULL, disp TEXT NOT NULL, path TEXT NOT NULL, imgpath TEXT NOT NULL, type INTEGER NULL, ppath TEXT NOT NULL, pinyin TEXT NOT NULL, cpinyin TEXT NOT NULL, opinyin TEXT NOT NULL, PRIMARY KEY (id))', 1995 | [EmuConfig.System]); 1996 | 1997 | SQLQuery.ExecSQL; 1998 | 1999 | if IsDelete then 2000 | begin 2001 | SQLQuery.SQL.Text := Format('DELETE FROM %s_roms', [EmuConfig.System]); 2002 | SQLQuery.ExecSQL; 2003 | end; 2004 | FindUpdate('', 0); 2005 | 2006 | Path := EmuConfig.EmuPath + '/' + edRomPath.Text + '/'; 2007 | SQLQuery.SQL.Text := Format('INSERT INTO %s_roms (disp, path, imgpath, type, ppath, pinyin, cpinyin, opinyin) SELECT DISTINCT ppath, %s||ppath, %s||ppath, 1, ''.'', '''', '''', '''' FROM %s_roms WHERE ppath <> ''.'' AND ppath NOT IN (SELECT disp FROM %s_roms WHERE type = 1)', 2008 | [EmuConfig.System, QuotedStr(Path), QuotedStr(Path), EmuConfig.System, EmuConfig.System]); 2009 | SQLQuery.ExecSQL; 2010 | finally 2011 | SQLite3Connection.Connected := False; 2012 | WriteLog(IntToStr(AddedCount) + ' - ' + I18N_ADDED); 2013 | end; 2014 | end; 2015 | 2016 | procedure TFormMain.GetSubDir; 2017 | var 2018 | RootNode: TTreeNode; 2019 | Info: TSearchRec; 2020 | begin 2021 | TreeView.BeginUpdate; 2022 | TreeView.Items.Clear; 2023 | try 2024 | RootNode := TreeView.Items.Add(nil, EmuConfig.System); 2025 | RootNode.ImageIndex := 0; 2026 | RootNode.SelectedIndex := 1; 2027 | 2028 | if FindFirst(EmuConfig.RomPath + DirectorySeparator + '*' , faDirectory, Info) = 0 then 2029 | begin 2030 | repeat 2031 | if (Copy(Info.Name, 1, 1) <> '.')and((Info.Attr and faDirectory) = faDirectory) then 2032 | with TreeView.Items.AddChild(RootNode, Info.Name) do 2033 | begin 2034 | ImageIndex := 0; 2035 | SelectedIndex := 1; 2036 | end; 2037 | until FindNext(Info) <> 0; 2038 | end; 2039 | 2040 | FindClose(Info); 2041 | finally 2042 | TreeView.EndUpdate; 2043 | TreeView.TopItem.Selected := True; 2044 | end; 2045 | end; 2046 | 2047 | procedure TFormMain.GetEmuList(SubDir: String='.'); 2048 | var 2049 | Title, Shortname: String; 2050 | begin 2051 | if not Assigned(TreeView.Selected) or (TreeView.Selected.Level = 0) then 2052 | SubDir := '.'; 2053 | ListView.Items.Clear; 2054 | SQLite3Connection.DatabaseName := EmuConfig.CachePath; 2055 | if not SQLite3Connection.Connected then 2056 | SQLite3Connection.Connected := True; 2057 | 2058 | ListView.BeginUpdate; 2059 | try 2060 | SQLQuery.SQL.Text := Format('SELECT id, disp, path, imgpath, pinyin, opinyin FROM %s_roms WHERE ppath = %s AND type = 0', [EmuConfig.System, QuotedStr(SubDir)]); 2061 | try 2062 | SQLQuery.Active := True; 2063 | except 2064 | on E :Exception do 2065 | begin 2066 | WriteLog(I18N_ERROROCCURED + ' - ' + EmuConfig.System + '_roms - ' + E.Message); 2067 | exit; 2068 | end; 2069 | end; 2070 | SQLQuery.First; 2071 | 2072 | while not SQLQuery.EOF do 2073 | begin 2074 | with ListView.Items.Add do 2075 | begin 2076 | ImageIndex := 3; 2077 | Shortname := SQLQuery.FieldByName('opinyin').AsString; 2078 | Title := SQLQuery.FieldByName('disp').AsString; 2079 | Caption := Title; 2080 | SubItems.Add(SQLQuery.FieldByName('imgpath').AsString); 2081 | SubItems.Add(Shortname); 2082 | SubItems.Add(SQLQuery.FieldByName('path').AsString); 2083 | end; 2084 | 2085 | SQLQuery.Next; 2086 | end; 2087 | finally 2088 | ListView.EndUpdate; 2089 | SQLite3Connection.Connected := False; 2090 | end; 2091 | end; 2092 | 2093 | function TFormMain.RenameTitle(Key, Tobe: String): Boolean; 2094 | begin 2095 | Result := False; 2096 | if (Key = Tobe) or (Tobe = '') then 2097 | exit; 2098 | 2099 | Result := UpdateCache(Key, 'disp', Tobe); 2100 | if Result then 2101 | Result := UpdateRomName(Key, Tobe); 2102 | end; 2103 | 2104 | function TFormMain.RenameSubDir(Asis, Tobe: String): Boolean; 2105 | var 2106 | TobePath, AsisPath: String; 2107 | begin 2108 | if (Asis = Tobe) or (Tobe = '') then 2109 | begin 2110 | Result := False; 2111 | exit; 2112 | end; 2113 | 2114 | AsisPath := '/' + edRomPath.Text + '/' + Asis + '/'; 2115 | TobePath := '/' + edRomPath.Text + '/' + Tobe + '/'; 2116 | 2117 | RenameFile(Lin2Win(edBasePath.Text, AsisPath), Lin2Win(edBasePath.Text, TobePath)); 2118 | Result := ExecCacheSQL('UPDATE %s_roms SET path = REPLACE(path, %s, %s), ppath = %s WHERE ppath = %s', 2119 | [EmuConfig.System, QuotedStr(AsIsPath), QuotedStr(TobePath), QuotedStr(Tobe), QuotedStr(Asis)]); 2120 | if Result then 2121 | Result := ExecCacheSQL('UPDATE %s_roms SET disp = %s WHERE disp = %s AND type = 1', 2122 | [EmuConfig.System, QuotedStr(Tobe), QuotedStr(Asis)]); 2123 | end; 2124 | 2125 | function TFormMain.DeleteSubDir: Boolean; 2126 | var 2127 | Dir: String; 2128 | begin 2129 | Result := False; 2130 | if Application.MessageBox(PChar(I18N_DELETEDIRCONFIRM), 2131 | PChar(I18N_CONFIRM), MB_ICONQUESTION + MB_YESNO) <> IDYES then 2132 | exit; 2133 | if Assigned(TreeView.Selected) then 2134 | begin 2135 | if TreeView.Selected.Level = 0 then 2136 | exit; 2137 | 2138 | Dir := Lin2Win(edBasePath.Text, EmuConfig.EmuPath + '/' + edRomPath.Text + '/' + TreeView.Selected.Text); 2139 | 2140 | if not DirectoryExists(Dir) then 2141 | WriteLog(I18N_DIRNOTFOUND + ' - ' + Dir) 2142 | else if not DeleteDirectory(Dir, False) then 2143 | begin 2144 | WriteLog(I18N_ERROROCCURED + ' - ' + Dir); 2145 | exit; 2146 | end; 2147 | end; 2148 | 2149 | Result := ExecCacheSQL('DELETE FROM %s_roms WHERE ppath = %s AND type = 0', [EmuConfig.System, QuotedStr(TreeView.Selected.Text)]); 2150 | if Result then 2151 | Result := ExecCacheSQL('DELETE FROM %s_roms WHERE disp = %s AND type = 1', [EmuConfig.System, QuotedStr(TreeView.Selected.Text)]); 2152 | 2153 | if Result then 2154 | begin 2155 | TreeView.Selected.Delete; 2156 | TreeView.TopItem.Selected := True; 2157 | end; 2158 | end; 2159 | 2160 | function TFormMain.ExecCacheSQL(Query: String; Args: array of const): Boolean; 2161 | begin 2162 | Result := False; 2163 | if (Query = '') then 2164 | exit; 2165 | 2166 | if not SQLite3Connection.Connected then 2167 | SQLite3Connection.Connected := True; 2168 | try 2169 | SQLQuery.SQL.Text := Format(Query, Args); 2170 | try 2171 | SQLQuery.ExecSQL; 2172 | except 2173 | on E :Exception do 2174 | begin 2175 | WriteLog(I18N_ERROROCCURED + ' - ' + E.Message); 2176 | exit; 2177 | end; 2178 | end; 2179 | Result := True; 2180 | finally 2181 | SQLite3Connection.Connected := False; 2182 | end; 2183 | end; 2184 | 2185 | function TFormMain.InsertCache(Filename: String; SubDir: String=''): String; 2186 | var 2187 | Path, ImgPath, Shortname, Fullname: String; 2188 | begin 2189 | SQLite3Connection.DatabaseName := EmuConfig.CachePath; 2190 | if not SQLite3Connection.Connected then 2191 | SQLite3Connection.Connected := True; 2192 | 2193 | WriteLog(EmuConfig.System + ' - ' + I18N_GENCACHE); 2194 | 2195 | if not Assigned(TreeView.Selected) or (TreeView.Selected.Level = 0) then 2196 | SubDir := ''; 2197 | 2198 | try 2199 | SQLQuery.SQL.Text := 2200 | Format('CREATE TABLE IF NOT EXISTS %s_roms (id INTEGER NOT NULL, disp TEXT NOT NULL, path TEXT NOT NULL, imgpath TEXT NOT NULL, type INTEGER NULL, ppath TEXT NOT NULL, pinyin TEXT NOT NULL, cpinyin TEXT NOT NULL, opinyin TEXT NOT NULL, PRIMARY KEY (id))', 2201 | [EmuConfig.System]); 2202 | SQLQuery.ExecSQL; 2203 | 2204 | Shortname := ExtractFileNameWithoutExt(ExtractFilename(Filename)); 2205 | Fullname := GetFullTitle(Shortname, Shortname); 2206 | Result := Fullname; 2207 | Path := EmuConfig.EmuPath + '/' + edRomPath.Text; 2208 | if SubDir = '' then 2209 | SubDir := '.' 2210 | else 2211 | Path := Path + '/' + SubDir; 2212 | Path := Path + '/' + Filename; 2213 | SQLQuery.SQL.Text := Format('UPDATE %s_roms SET disp = %s, path = %s WHERE opinyin = %s', [EmuConfig.System, QuotedStr(FullName), QuotedStr(Path), QuotedStr(Shortname)]); 2214 | SQLQuery.ExecSQL; 2215 | if SQLQuery.RowsAffected = 0 then 2216 | begin 2217 | if Copy(edImagePath.Text, 1, 1) = '/' then 2218 | ImgPath := edImagePath.Text + '/' + ExtractFileNameWithoutExt(FileName) + '.png' 2219 | else 2220 | ImgPath := EmuConfig.EmuPath + '/' + edImagePath.Text + '/' + Shortname + '.png'; 2221 | SQLQuery.SQL.Text := Format('INSERT INTO %s_roms (disp, path, imgpath, type, ppath, pinyin, cpinyin, opinyin) VALUES (%s, %s, %s, 0, %s, %s, %s, %s)', 2222 | [EmuConfig.System, QuotedStr(Fullname), QuotedStr(Path), QuotedStr(ImgPath), QuotedStr(SubDir), QuotedStr(Fullname), QuotedStr(Fullname), QuotedStr(Shortname)]); 2223 | SQLQuery.ExecSQL; 2224 | end; 2225 | finally 2226 | SQLite3Connection.Connected := False; 2227 | WriteLog(Filename + ' - ' + I18N_ADDED); 2228 | end; 2229 | end; 2230 | 2231 | function TFormMain.UpdateCache(Key, Column, Value: String): Boolean; 2232 | begin 2233 | Result := ExecCacheSQL('UPDATE %s_roms SET %s = %s WHERE opinyin = %s', 2234 | [EmuConfig.System, Column, QuotedStr(Value), QuotedStr(Key)]); 2235 | end; 2236 | 2237 | function TFormMain.DeleteCache(Key: String): Boolean; 2238 | begin 2239 | Result := ExecCacheSQL('DELETE FROM %s_roms WHERE opinyin = %s', [EmuConfig.System, QuotedStr(Key)]); 2240 | end; 2241 | 2242 | function TFormMain.GetFullTitle(Title, DefaultTitle: String): String; 2243 | var 2244 | ColName: String; 2245 | begin 2246 | if mnLangKor.Checked then 2247 | ColName := 'name' 2248 | else 2249 | ColName := 'ename'; 2250 | if not SQLite3Name.Connected then 2251 | begin 2252 | SQLite3Name.Connected := True; 2253 | end; 2254 | SQLName.SQL.Text := Format('SELECT name, ename FROM romnames WHERE system = %s AND shortname = %s', 2255 | [QuotedStr(SystemMap.Values[EmuConfig.System]), QuotedStr(Title)]); 2256 | SQLName.Open; 2257 | 2258 | try 2259 | SQLName.First; 2260 | if SQLName.Eof then 2261 | Result := DefaultTitle 2262 | else 2263 | Result := SQLName.FieldByName(ColName).AsString; 2264 | finally 2265 | SQLName.Close; 2266 | end; 2267 | end; 2268 | 2269 | function TFormMain.UpdateRomName(Key, Value: String): Boolean; 2270 | begin 2271 | SQLName.SQL.Text := Format('UPDATE romnames SET name = %s WHERE system = %s AND shortname = %s', [QuotedStr(Value), QuotedStr(SystemMap.Values[EmuConfig.System]), QuotedStr(Key)]); 2272 | try 2273 | SQLName.ExecSQL; 2274 | except 2275 | on E :Exception do 2276 | begin 2277 | WriteLog(I18N_ERROROCCURED + ' - ' + Value + ' - ' + E.Message); 2278 | Result := False; 2279 | exit; 2280 | end; 2281 | end; 2282 | Result := True; 2283 | end; 2284 | 2285 | procedure TFormMain.GenCacheFromXml(Gamelist: String); 2286 | var 2287 | RootNode, Node, ChildNode: TDOMNode; 2288 | Xml: TXMLDocument; 2289 | disp, path, imgpath, ppath, yin: String; 2290 | tp: Integer; 2291 | i: Integer; 2292 | begin 2293 | SQLite3Connection.DatabaseName := EmuConfig.CachePath; 2294 | if not ExecCacheSQL('DELETE FROM %s_roms', [EmuConfig.System]) then 2295 | begin 2296 | WriteLog(I18N_ERROROCCURED + ' - ' + 'DELETE FROM clause'); 2297 | exit; 2298 | end; 2299 | 2300 | ReadXMLFile(Xml, gamelist); 2301 | try 2302 | RootNode := Xml.FindNode('gameList'); 2303 | if RootNode = nil then 2304 | begin 2305 | WriteLog('gameList tag not found - ' + gamelist); 2306 | exit; 2307 | end; 2308 | 2309 | pbInfo.Max := RootNode.GetChildNodes.Count; 2310 | pbInfo.Visible := True; 2311 | imgpath := ''; 2312 | for i:= 0 to RootNode.GetChildNodes.Count-1 do 2313 | begin 2314 | tp := Ord(RootNode.GetChildNodes.Item[i].NodeName = 'folder'); 2315 | Node := RootNode.GetChildNodes.Item[i]; 2316 | ChildNode := Node.FindNode('name'); 2317 | disp := AnsiString(ChildNode.TextContent); 2318 | ChildNode := Node.FindNode('image'); 2319 | imgpath := AnsiString(ChildNode.TextContent); 2320 | 2321 | if tp = 0 then 2322 | begin 2323 | ChildNode := Node.FindNode('path'); 2324 | path := AnsiString(ChildNode.TextContent); 2325 | 2326 | ppath := ExtractFileNameOnly(ExtractFileDir(path)); 2327 | if (EmuConfig.System = ppath) or (ppath= '') or (ppath = '.') or (ppath = '/.') then 2328 | ppath := '.'; 2329 | 2330 | yin := disp; 2331 | end else 2332 | begin 2333 | path := edRomPath.Text; 2334 | ppath := '.'; 2335 | yin := ''; 2336 | end; 2337 | 2338 | if not ExecCacheSQL('INSERT INTO %s_roms (disp, path, imgpath, type, ppath, pinyin, cpinyin, opinyin) VALUES (%s, %s, %s, %d, %s, %s, %s, %s)', 2339 | [EmuConfig.System, QuotedStr(disp), QuotedStr(path), QuotedStr(imgpath), tp, QuotedStr(ppath), QuotedStr(yin), QuotedStr(yin), QuotedStr(yin)]) then 2340 | begin 2341 | WriteLog(I18N_ERROROCCURED + ' - ' + 'INSERT INTO clause - ' + disp); 2342 | exit; 2343 | end; 2344 | 2345 | pbInfo.Position := i+1; 2346 | if pbInfo.Position mod 10 = 0 then 2347 | Application.ProcessMessages; 2348 | end; 2349 | 2350 | WriteLog(I18N_DONE + ' - ' + Gamelist); 2351 | cboEmulatorChange(cboEmulator); 2352 | finally 2353 | Xml.Free; 2354 | end; 2355 | end; 2356 | 2357 | procedure TFormMain.ReadSettings; 2358 | var 2359 | IniFile, Lang: String; 2360 | begin 2361 | IniFile := ExtractFilePath(Application.ExeName) + 2362 | ExtractFileNameOnly(Application.ExeName) + '.ini'; 2363 | with TIniFile.Create(IniFile) do 2364 | try 2365 | Lang := ReadString('Main', 'Lang', 'EN'); 2366 | if Lang = 'EN' then 2367 | mnLangEng.Click; 2368 | finally 2369 | Free; 2370 | end; 2371 | end; 2372 | 2373 | procedure TFormMain.WriteSettings; 2374 | var 2375 | IniFile, Lang: String; 2376 | begin 2377 | IniFile := ExtractFilePath(Application.ExeName) + 2378 | ExtractFileNameOnly(Application.ExeName) + '.ini'; 2379 | 2380 | if mnLangKor.Checked then 2381 | Lang := 'KO' 2382 | else 2383 | Lang := 'EN'; 2384 | with TIniFile.Create(IniFile) do 2385 | try 2386 | WriteString('Main', 'Lang', Lang); 2387 | finally 2388 | Free; 2389 | end; 2390 | end; 2391 | 2392 | 2393 | end. 2394 | --------------------------------------------------------------------------------