]> Shamusworld >> Repos - virtualjaguar/blob - src/gui/filethread.cpp
Various improvements to the GUI, including Power and Pause buttons, Load
[virtualjaguar] / src / gui / filethread.cpp
1 //
2 // filethread.cpp - File discovery thread
3 //
4 // by James L. Hammons
5 // (C) 2010 Underground Software
6 //
7 // JLH = James L. Hammons <jlhamm@acm.org>
8 //
9 // Who  When        What
10 // ---  ----------  -------------------------------------------------------------
11 // JLH  01/28/2010  Created this file
12 // JLH  02/16/2010  Moved RomIdentifier stuff to its own file
13 // JLH  03/02/2010  Added .ZIP file fishing
14 //
15
16 #include "filethread.h"
17
18 #include <QtGui>
19 #include "crc32.h"
20 #include "file.h"
21 #include "filedb.h"
22 #include "settings.h"
23
24 FileThread::FileThread(QObject * parent/*= 0*/): QThread(parent), abort(false)
25 {
26 }
27
28 FileThread::~FileThread()
29 {
30         mutex.lock();
31         abort = true;
32         condition.wakeOne();
33         mutex.unlock();
34
35         wait();
36 }
37
38 void FileThread::Go(void)
39 {
40         QMutexLocker locker(&mutex);
41         start();
42 }
43
44 /*
45 Our strategy here is like so:
46 Look at the files in the directory pointed to by ROMPath.
47 For each file in the directory, take the CRC32 of it and compare it to the CRC
48 in the romList[]. If there's a match, put it in a list and note it's index value
49 in romList for future reference.
50
51 When constructing the list, use the index to pull up an image of the cart and
52 put that in the list. User picks from a graphical image of the cart.
53
54 Ideally, the label will go into the archive along with the ROM image, but that's
55 for the future...
56 Maybe box art, screenshots will go as well...
57 */
58
59 //
60 // Here's the thread's actual execution path...
61 //
62 void FileThread::run(void)
63 {
64         QDir romDir(vjs.ROMPath);
65 //      QDir romDir("../virtualjaguar/roms/rarities/");
66         QFileInfoList list = romDir.entryInfoList();
67
68 /*
69 Another thing we'll probably have to do here is check for compressed files and
70 decompress/fish around in them to find what we need. :-P
71 */
72
73         for(int i=0; i<list.size(); i++)
74         {
75                 if (abort)
76 #if 1
77 {
78 printf("FileThread: Aborting!!!\n");
79 #endif
80                         return;
81 #if 1
82 }
83 #endif
84
85                 QFileInfo fileInfo = list.at(i);
86
87                 // ZIP files are special: They contain more than just the software now... ;-)
88                 // So now we fish around inside them to pull out the stuff we want.
89                 // Probably also need more stringent error checking as well... :-O
90                 if (fileInfo.suffix().compare("zip", Qt::CaseInsensitive) == 0)
91                 {
92                         uint8 * buffer = NULL;
93                         uint32 size = GetFileFromZIP(fileInfo.canonicalFilePath().toAscii(), FT_SOFTWARE, buffer);
94
95                         if (size > 0)
96                         {
97                                 uint32_t fileSize = size;
98 //printf("FileThread: About to calc checksum on file with size %u... (buffer=%08X)\n", size, buffer);
99                                 uint32 crc = crc32_calcCheckSum(buffer, size);
100                                 uint32 index = FindCRCIndexInFileList(crc);
101 // These two are NOT interchangeable!
102 //Hm, confusing. It looks like in file.cpp it uses operater new() to create the buffer...
103 //                              delete[] buffer;
104                                 free(buffer);
105
106 // Mebbe we should pass a index AND a QImage here???
107 /*
108 Let's think about this... What *do* we need to send out?
109 we need the filename for sure. image file if it exists.
110 do we need the index? I think we're only using it to pull the label from the subdir...
111 we might need it if we want to pull ROM flags from the fileDB...
112 */
113                                 if (index != 0xFFFFFFFF && !(romList[index].flags & FF_BIOS))
114                                 {
115 //Here's a little problem. When we create the image here and pass it off to FilePicker,
116 //we can clobber this image before we have a chance to copy it out in the FilePicker function
117 //because we can be back here before FilePicker can respond.
118 //So we need to fix this so that this does not happen. :-/
119 //And now it is. :-)
120 /*
121 So I guess we can create an image on the heap and pass *that* to FilePicker. But then, would
122 it be worthwhile to just pass the pointer into the FileListModel instead of a copy of an object?
123 Maybe. We'd do like so:
124 QImage * imageCopy = new QImage();
125 */
126                                         QImage * img = NULL;
127                                         size = GetFileFromZIP(fileInfo.canonicalFilePath().toAscii(), FT_LABEL, buffer);
128 //printf("FT: Label size = %u bytes.\n", size);
129
130                                         if (size > 0)
131                                         {
132 //#warning "!!!"
133 //Not sure if this will work properly... Seems to.
134                                                 QImage label;
135                                                 bool success = label.loadFromData(buffer, size);
136                                                 img = new QImage();
137 //                                              *img = label.scaled(373, 172, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
138                                                 *img = label.scaled(365, 168, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
139 //printf("FT: Label %s: %ux%u.\n", (success ? "succeeded" : "did not succeed"), img->width(), img->height());
140 // These two are NOT interchangeable!
141 //Hm, confusing. It looks like in file.cpp it uses operater new() to create the buffer...
142 //                                              delete[] buffer;
143                                                 free(buffer);
144                                         }
145 //printf("FileThread: Attempted to load image. Size: %u x %u...\n", img.width(), img.height());
146
147 //                                      emit FoundAFile(index);
148                                         emit FoundAFile2(index, fileInfo.canonicalFilePath(), img, fileSize);
149                                 }
150                         }
151                 }
152                 else
153                 {
154                         QFile file(romDir.filePath(fileInfo.fileName()));
155
156                         if (file.open(QIODevice::ReadOnly))
157                         {
158                                 uint8 * buffer = new uint8[fileInfo.size()];
159                                 file.read((char *)buffer, fileInfo.size());
160                                 file.close();
161                                 uint32 crc = crc32_calcCheckSum(buffer, fileInfo.size());
162                                 uint32 index = FindCRCIndexInFileList(crc);
163                                 delete[] buffer;
164
165 // Mebbe we should pass a index AND a QImage here???
166                                 if (index != 0xFFFFFFFF && !(romList[index].flags & FF_BIOS))
167 //                                      emit FoundAFile(index);
168                                         emit FoundAFile2(index, fileInfo.canonicalFilePath(), 0, fileInfo.size());
169                         }
170                 }
171         }
172 }
173
174 //
175 // Find a CRC in the ROM list (simple brute force algorithm).
176 // If it's there, return the index, otherwise return $FFFFFFFF
177 //
178 uint32 FileThread::FindCRCIndexInFileList(uint32 crc)
179 {
180         for(int i=0; romList[i].crc32!=0xFFFFFFFF; i++)
181         {
182                 if (romList[i].crc32 == crc)
183                         return i;
184         }
185
186         return 0xFFFFFFFF;
187 }
188