]> Shamusworld >> Repos - virtualjaguar/blobdiff - src/gui/filepicker.cpp
2.0.2 release.
[virtualjaguar] / src / gui / filepicker.cpp
index e8a44d1bad7ea9d88d32fb99bd71fa06170afdff..eeec7f4937448dbf613d0ded7376c0cbb7dc1978 100644 (file)
@@ -9,89 +9,19 @@
 // Who  When        What
 // ---  ----------  -------------------------------------------------------------
 // JLH  01/22/2010  Created this file
+// JLH  02/06/2010  Modified to use Qt model/view framework
+// JLH  03/08/2010  Added large cart view and info text
 //
 
 #include "filepicker.h"
 
-#include "crc32.h"
+#include "file.h"
+#include "filedb.h"
 #include "filelistmodel.h"
 #include "filethread.h"
-#include "settings.h"
-#include "types.h"
-
-struct RomIdentifier
-{
-       const uint32 crc32;
-       const char name[128];
-       const char file[128];
-};
-
-RomIdentifier romList2[] = {
-       { 0x0509C85E, "Raiden (World)", "" },
-       { 0x08F15576, "Iron Soldier (World) (v1.04)", "" },
-       { 0x0957A072, "Kasumi Ninja (World)", "" },
-       { 0x0AC83D77, "NBA Jam T.E. (World)", "" },
-       { 0x0EC5369D, "Evolution - Dino Dudes (World)", "" },
-       { 0x0F6A1C2C, "Ultra Vortek (World)", "" },
-       { 0x14915F20, "White Men Can't Jump (World)", "" },
-       { 0x1660F070, "Power Drive Rally (World)", "" },
-       { 0x1E451446, "Trevor McFur in the Crescent Galaxy (World)", "" },
-       { 0x27594C6A, "Defender 2000 (World)", "" },
-       { 0x2E17D5DA, "Bubsy in Fractured Furry Tales (World)", "" },
-       { 0x348E6449, "Double Dragon V - The Shadow Falls (World)", "" },
-       { 0x3615AF6A, "Fever Pitch Soccer (World) (En,Fr,De,Es,It)", "" },
-       { 0x38A130ED, "Troy Aikman NFL Football (World)", "" },
-       { 0x3C044941, "Skyhammer (World)", "" },
-       { 0x42A13EC5, "Soccer Kid (World)", "" },
-       { 0x47EBC158, "Theme Park (World)", "" },
-       { 0x4899628F, "Hover Strike (World)", "" },
-       { 0x53DF6440, "Space War 2000 (World)", "" },
-       { 0x55A0669C, "[BIOS] Atari Jaguar Developer CD (World)", "" },
-       { 0x58272540, "Syndicate (World)", "" },
-       { 0x5A101212, "Sensible Soccer - International Edition (World)", "" },
-       { 0x5B6BB205, "Ruiner Pinball (World)", "" },
-       { 0x5CFF14AB, "Pinball Fantasies (World)", "" },
-       { 0x5E2CDBC0, "Doom (World)", "" },
-       { 0x61C7EEC0, "Zero 5 (World)", "" },
-       { 0x67F9AB3A, "Battle Sphere Gold (World)", "" },
-       { 0x687068D5, "[BIOS] Atari Jaguar CD (World)", "" },
-       { 0x6B2B95AD, "Tempest 2000 (World)", "" },
-       { 0x6EB774EB, "Worms (World)", "" },
-       { 0x6F8B2547, "Super Burnout (World)", "" },
-       { 0x817A2273, "Pitfall - The Mayan Adventure (World)", "" },
-       { 0x8975F48B, "Zool 2 (World)", "" },
-       { 0x8D15DBC6, "[BIOS] Atari Jaguar Stubulator '94 (World)", "" },
-       { 0x8FEA5AB0, "Dragon - The Bruce Lee Story (World)", "" },
-       { 0x97EB4651, "I-War (World)", "" },
-       { 0xA27823D8, "Ultra Vortek (World) (v0.94) (Beta)", "" },
-       { 0xA56D0798, "Protector - Special Edition (World)", "" },
-       { 0xA9F8A00E, "Rayman (World)", "" },
-       { 0xB14C4753, "Fight for Life (World)", "" },
-       { 0xBCB1A4BF, "Brutal Sports Football (World)", "" },
-       { 0xBDA405C6, "Cannon Fodder (World)", "" },
-       { 0xBDE67498, "Cybermorph (World) (Rev 1)", "" },
-       { 0xC5562581, "Zoop! (World)", "" },
-       { 0xC654681B, "Total Carnage (World)", "" },
-       { 0xC6C7BA62, "Fight for Life (World) (Alt)", "" },
-       { 0xC9608717, "Val d'Isere Skiing and Snowboarding (World)", "" },
-       { 0xCBFD822A, "Air Cars (World)", "" },
-       { 0xCD5BF827, "Attack of the Mutant Penguins (World)", "" },
-       { 0xD6C19E34, "Iron Soldier 2 (World)", "" },
-       { 0xDA9C4162, "Missile Command 3D (World)", "" },
-       { 0xDC187F82, "Alien vs Predator (World)", "" },
-       { 0xDE55DCC7, "Flashback - The Quest for Identity (World) (En,Fr)", "" },
-       { 0xE28756DE, "Atari Karts (World)", "" },
-       { 0xE60277BB, "[BIOS] Atari Jaguar Stubulator '93 (World)", "" },
-       { 0xE91BD644, "Wolfenstein 3D (World)", "" },
-       { 0xEC22F572, "SuperCross 3D (World)", "" },
-       { 0xECF854E7, "Cybermorph (World) (Rev 2)", "" },
-       { 0xEEE8D61D, "Club Drive (World)", "" },
-       { 0xF0360DB3, "Hyper Force (World)", "" },
-       { 0xFA7775AE, "Checkered Flag (World)", "" },
-       { 0xFAE31DD0, "Flip Out! (World)", "" },
-       { 0xFB731AAA, "[BIOS] Atari Jaguar (World)", "" },
-       { 0xFFFFFFFF, "***END***", "" }
-};
+#include "imagedelegate.h"
+//#include "settings.h"
+//#include "types.h"
 
 /*
 Our strategy here is like so:
@@ -106,83 +36,454 @@ put that in the list. User picks from a graphical image of the cart.
 Ideally, the label will go into the archive along with the ROM image, but that's
 for the future...
 Maybe box art, screenshots will go as well...
+
+I'm thinking compatibility info should be displayed as well... Just to stop the
+inevitable stupid questions from people too lazy to do basic research for themselves.
+
+
+Data strategy:
+
+- Should keep a QImage of the blank cart with blank label
+- Should keep a QImage of the blank cart? (For overpainting the ROMs label)
+- Should we have a special Alpine image? Floppy image (for COF/ABS)?
+
+- Need some way of keeping track of cart size and compatibility info
+  [compat info needs to be BAD DUMP or % of what works]
+- Need to properly scale the thumbnails images in the list
 */
 
-//FilePickerWindow::FilePickerWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog)//could use Window as well...
-FilePickerWindow::FilePickerWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Window)
+//could use Window as well...
+//FilePickerWindow::FilePickerWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog)
+FilePickerWindow::FilePickerWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Window),
+       currentFile("")
 {
-       setWindowTitle("Insert Cartridge...");
+       setWindowTitle(tr("Insert Cartridge..."));
 
-#if 1
-       fileList2 = new QListWidget(this);
-//     addWidget(fileList);
+//is there any reason why this must be cast as a QAbstractListModel? No
+//Also, need to think about data structure for the model...
+       model = new FileListModel;
+       fileList = new QListView;
+       fileList->setModel(model);
+//     fileList->setItemDelegate(new ImageDelegate(this));
+       fileList->setItemDelegate(new ImageDelegate());
+#if 0
+       //nope.
+//     fileList->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+//     fileList->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
+//small problem with this is that it doesn't take scrollbar into account...
+QSize sbSize = fileList->verticalScrollBar()->minimumSizeHint();
+printf("VSB minimumSizeHint: %u, %u\n", sbSize.width(), sbSize.height());
+QSize sbSize2 = fileList->verticalScrollBar()->sizeHint();
+printf("VSB sizeHint: %u, %u\n", sbSize2.width(), sbSize2.height());
+QRect sbRect = fileList->verticalScrollBar()->normalGeometry();
+printf("VSB normalGeometry: %u, %u\n", sbRect.width(), sbRect.height());
+QSize sbSize3 = fileList->verticalScrollBar()->size();
+printf("VSB size: %u, %u\n", sbSize3.width(), sbSize3.height());
+//     int sbWidth = fileList->verticalScrollBar()->width();
+       int sbWidth = fileList->verticalScrollBar()->size().width();
+       fileList->setFixedWidth((488/4) + 4 + sbWidth);//ick
+#else
+       // This sets it to the "too large size" as the minimum!
+       QScrollBar * vsb = new QScrollBar(Qt::Vertical, this);
+       int sbWidth = vsb->size().width();
+//     printf("VSB size width: %u\n", sbWidth);
+       int sbWidth2 = vsb->sizeHint().width();
+//     printf("VSB sizeHint width: %u\n", sbWidth2);
+       int sbWidth3 = vsb->minimumSize().width();
+//     printf("VSB minimum width: %u\n", sbWidth3);
+       int sbWidth4 = vsb->frameSize().width();
+//     printf("VSB frame width: %u\n", sbWidth4);
+       delete vsb;
+
+//     fileList->setFixedWidth((488/4) + 4);
+       int sbWidth5 = fileList->frameWidth();
+//     printf("List frame width: %u, (diff=%d)\n", sbWidth5, sbWidth5 - ((488/4) + 4));
+       int sbWidth6 = fileList->sizeHint().width();
+//     printf("List sizeHint width: %u\n", sbWidth6);
+       int sbWidth7 = fileList->minimumSize().width();
+//     printf("List minimum width: %u\n", sbWidth7);
+       int sbWidth8 = fileList->minimumSizeHint().width();
+//     printf("List minimum hint width: %u\n", sbWidth8);
+////   fileList->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
+////   fileList->verticalScrollBar()->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
+       // (488/4) + 4 is the width of the object in the filelistmodel. Dunno why the QListView
+       // isn't picking that up. :-(
+       // 488/4 + 4 = 126
+       // 126 + 17 + 4 = 147 <-- correct width
+       fileList->setFixedWidth((488/4) + 4 + sbWidth2 + sbWidth5 + 1);//ick
+//     fileList->setFixedWidth((488/4) + 4 + 17 + 4);//sbWidth);//ick
 
-       QVBoxLayout * layout = new QVBoxLayout();
-//     layout->setSizeConstraint(QLayout::SetFixedSize);
+//     fileList->setSpacing(4);
+       fileList->setUniformItemSizes(true);
+#endif
+
+//     QVBoxLayout * layout = new QVBoxLayout;
+       QHBoxLayout * layout = new QHBoxLayout;
        setLayout(layout);
+       layout->addWidget(fileList);
 
-       layout->addWidget(fileList2);
+       // Weird note: This layout has to be added *before* putting anything into it...
+       QVBoxLayout * vLayout = new QVBoxLayout;
+       layout->addLayout(vLayout);
 
-//     PopulateList();
-       fileThread = new FileThread(this);
+       cartImage = new QLabel;
+       QImage cartImg(":/res/cart-blank.png");
+       QPainter painter(&cartImg);
+       painter.drawPixmap(23, 87, QPixmap(":/res/label-blank.png"));
+       painter.end();
+       cartImage->setPixmap(QPixmap::fromImage(cartImg));
+       cartImage->setMargin(4);
+       vLayout->addWidget(cartImage);
 
-       /*bool b =*/ connect(fileThread, SIGNAL(FoundAFile(unsigned long)), this, SLOT(AddFileToList(unsigned long)));
-//printf("FilePickerWindow: Connection to FileThread %s...\n", (b ? "succeeded" : "failed"));
+       title = new QLabel(QString(tr("<h2>...</h2>")));
+       title->setMargin(6);
+       title->setAlignment(Qt::AlignCenter);
+       vLayout->addWidget(title);
 
-       fileThread->Go(fileList2);
-#else
-QStringList numbers;
-numbers << "One" << "Two" << "Three" << "Four" << "Five";
+#if 1
+       QHBoxLayout * dataLayout = new QHBoxLayout;
+       vLayout->addLayout(dataLayout);
 
-QAbstractItemModel * model = new StringListModel(numbers);
-QListView * view = new QListView;
-view->setModel(model);
+       QLabel * labels = new QLabel(QString(tr(
+               "<b>Type: </b><br>"
+               "<b>CRC32: </b><br>"
+               "<b>Compatibility: </b><br>"
+               "<b>Notes:</b>"
+       )));
+       labels->setAlignment(Qt::AlignRight);
+       labels->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
+       dataLayout->addWidget(labels);
+       data = new QLabel(QString(tr(
+               "?MB Cartridge<br>"
+               "00000000<br>"
+               "?<br>"
+               "?"
+       )));
+       data->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+       dataLayout->addWidget(data);
 
+//#warning "!!! Icon size for pushbutton is tiny !!!"
+       insertCart = new QPushButton(this);
+       insertCart->setIconSize(QSize(40, 40));
+       insertCart->setIcon(QIcon(":/res/insert.png"));
+       insertCart->setDefault(true);                           // We want this button to be the default
+       insertCart->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
+       dataLayout->addWidget(insertCart);
+#else
+       QLabel * text2 = new QLabel(QString(tr(
+               "<table>"
+               "<tr><td align='right'><b>Type: </b></td><td>4MB Cartridge</td></tr>"
+               "<tr><td align='right'><b>CRC32: </b></td><td>FEDCBA98</td></tr>"
+               "<tr><td align='right'><b>Compatibility: </b></td><td>DOES NOT WORK</td></tr>"
+               "<tr><td align='right'><b>Notes: </b></td><td>Universal Header detected; Requires DSP</td></tr>"
+               "</table>"
+       )));
+       vLayout->addWidget(text2);
 #endif
+
+       fileThread = new FileThread(this);
+//     connect(fileThread, SIGNAL(FoundAFile(unsigned long)), this, SLOT(AddFileToList(unsigned long)));
+//     connect(fileThread, SIGNAL(FoundAFile2(unsigned long, QString, QImage *, unsigned long)), this, SLOT(AddFileToList2(unsigned long, QString, QImage *, unsigned long)));
+       connect(fileThread, SIGNAL(FoundAFile3(unsigned long, QString, QImage *,
+               unsigned long, bool, unsigned long, unsigned long)), this,
+               SLOT(AddFileToList3(unsigned long, QString, QImage *, unsigned long,
+               bool, unsigned long, unsigned long)));
+
+// Let's defer this to the main window, so we can have some control over when this is done.
+//     fileThread->Go();
+/*
+New sizes: 373x172 (label), 420x340 (cart)
+*/
+
+//     QItemSelectionModel * ism = fileList->selectionModel();
+//     connect(ism, SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(UpdateSelection(const QModelIndex &, const QModelIndex &)));
+       connect(fileList->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(UpdateSelection(const QModelIndex &, const QModelIndex &)));
+
+       connect(insertCart, SIGNAL(clicked()), this, SLOT(LoadButtonPressed()));
+
+       connect(fileList, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(CatchDoubleClick(const QModelIndex &)));
+
+//     connect(fileList, SIGNAL(doubleClicked()), this, SLOT(LoadButtonPressed()));
+// This returns:
+// Object::connect: No such signal QListView::QAbstractItemView::doubleClicked() in src/gui/filepicker.cpp:203
 }
 
-// Need a slot here to pickup stuff from the thread...
+void FilePickerWindow::keyPressEvent(QKeyEvent * e)
+{
+       if (e->key() == Qt::Key_Escape)
+       {
+               hide();
+               emit(FilePickerHiding());
+       }
+       else if (e->key() == Qt::Key_Return)
+               LoadButtonPressed();
+}
 
+void FilePickerWindow::CatchDoubleClick(const QModelIndex &)
+{
+       LoadButtonPressed();
+}
+
+QString FilePickerWindow::GetSelectedPrettyName(void)
+{
+       return prettyFilename;
+}
+
+void FilePickerWindow::ScanSoftwareFolder(bool allow/*= false*/)
+{
+       // "allow" is whether or not to allow scanning for unknown software.
+       model->ClearData();
+       fileThread->Go(allow);
+}
+
+//
+// This slot gets called by the FileThread's run() function when it finds a
+// match in the filesystem to a ROM on our CRC list.
+//
 void FilePickerWindow::AddFileToList(unsigned long index)
 {
-       printf("--> Found CRC: %08X...\n", (uint32)index);
+printf("FilePickerWindow: Found match [%s]...\n", romList[index].name);
+       // NOTE: The model *ignores* what you send it, so this is crap. !!! FIX !!! [DONE, somewhat]
+//     model->AddData(QIcon(":/res/generic.png"));
+//     model->AddData(index);
 }
 
+void FilePickerWindow::AddFileToList2(unsigned long index, QString str, QImage * img, unsigned long size)
+{
+if (index != 0xFFFFFFFF)
+       printf("FilePickerWindow(2): Found match [%s]...\n", romList[index].name);
 
-/*
-void FilePickerWindow::PopulateList(void)
+       if (img)
+       {
+               model->AddData(index, str, *img, size);
+//It would be better to pass the pointer into the model though...
+               delete img;
+       }
+       else
+               model->AddData(index, str, QImage(), size);
+}
+
+void FilePickerWindow::AddFileToList3(unsigned long index, QString str, QImage * img, unsigned long size, bool haveUniversalHeader, unsigned long fileType, unsigned long crc)
 {
-       QDir romDir(vjs.ROMPath);
-       QFileInfoList list = romDir.entryInfoList();
+//if (index != 0xFFFFFFFF)
+//     printf("FilePickerWindow(3): Found match [%s]...\n", romList[index].name);
 
-       for(int i=0; i<list.size(); i++)
+       if (img)
        {
-               QFileInfo fileInfo = list.at(i);
-//         std::cout << qPrintable(QString("%1 %2").arg(fileInfo.size(), 10)
-//                                                 .arg(fileInfo.fileName()));
-//         std::cout << std::endl;
-               QFile file(romDir.filePath(fileInfo.fileName()));
-               uint8 * buffer = new uint8[fileInfo.size()];
-
-               if (file.open(QIODevice::ReadOnly))
+               model->AddData(index, str, *img, size, haveUniversalHeader, fileType, crc);
+//It would be better to pass the pointer into the model though...
+               delete img;
+       }
+       else
+               model->AddData(index, str, QImage(), size, haveUniversalHeader, fileType, crc);
+}
+
+void FilePickerWindow::LoadButtonPressed(void)
+{
+       // TODO: Get the text of the current selection, call the MainWin slot for loading
+       emit(RequestLoad(currentFile));
+       hide();
+}
+
+//
+// This slot gets called when the QListView gets clicked on. Updates
+// the cart graphic and accompanying text.
+//
+void FilePickerWindow::UpdateSelection(const QModelIndex & current, const QModelIndex &/*previous*/)
+{
+#if 0
+       QString s = current.model()->data(current, Qt::EditRole).toString();
+       unsigned long i = current.model()->data(current, Qt::DisplayRole).toUInt();
+       QImage label = current.model()->data(current, Qt::DecorationRole).value<QImage>();
+//     printf("FPW: %s\n", s.toAscii().data());
+       unsigned long fileSize = current.model()->data(current, Qt::WhatsThisRole).toUInt();
+#else
+//     QString s = current.model()->data(current, FLM_FILENAME).toString();
+       currentFile = current.model()->data(current, FLM_FILENAME).toString();
+       unsigned long i = current.model()->data(current, FLM_INDEX).toUInt();
+       QImage label = current.model()->data(current, FLM_LABEL).value<QImage>();
+       unsigned long fileSize = current.model()->data(current, FLM_FILESIZE).toUInt();
+       bool haveUniversalHeader = current.model()->data(current, FLM_UNIVERSALHDR).toBool();
+       unsigned long fileType = current.model()->data(current, FLM_FILETYPE).toUInt();
+       uint32 crc = (uint32)current.model()->data(current, FLM_CRC).toUInt();
+//     printf("FPW: %s\n", s.toAscii().data());
+       bool haveUnknown = (i == 0xFFFFFFFF ? true : false);
+#endif
+
+       // Disallow loading completely unknown files, but allow all others.
+       insertCart->setEnabled(haveUnknown && (fileType == JST_NONE) ? false : true);
+//hm.
+//currentFile = s;
+
+//373x172 is label size...
+//365x168 now...
+       if (!label.isNull())
+       {
+/*
+       QImage cartImg(":/res/cart-blank.png");
+       QPainter painter(&cartImg);
+       painter.drawPixmap(23, 87, QPixmap(":/res/label-blank.png"));
+       painter.end();
+       cartSmall = cartImg.scaled(488/4, 395/4, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+*/
+               QImage cart(":/res/cart-blank.png");
+               QPainter painter(&cart);
+//Though this should probably be done when this is loaded, instead of every time here...
+//QImage scaledImg = label.scaled(373, 172, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+//painter.drawPixmap(23, 87, QPixmap::fromImage(scaledImg));
+               // Now, looks like it is...
+//             painter.drawPixmap(23, 87, QPixmap::fromImage(label));
+               painter.drawPixmap(27, 89, QPixmap::fromImage(label));
+//             painter.drawPixmap(23, 87, 373, 172, QPixmap::fromImage(label));
+
+// Well, heck. This should be done to the label *before* we get here.
+               painter.drawPixmap(27, 89, QPixmap::fromImage(QImage(":/res/upper-left.png")));
+               painter.drawPixmap(27+355, 89, QPixmap::fromImage(QImage(":/res/upper-right.png")));
+
+               painter.end();
+               cartImage->setPixmap(QPixmap::fromImage(cart));
+       }
+       else
+       {
+               // We should try to be intelligent with our updates here, and only redraw when
+               // we're going from a selection with a label to a selection without. Now, we
+               // redraw regardless.
+               QImage cart;
+
+// We now have to sources of data for the passed in files:
+// - The file DB
+// - The file type detection
+// This means we have to be mindful of what's passed back by that stuff.
+// We can assume that if it wasn't found in the DB, then the fileType
+// should be valid.
+// The DB takes precedence over the fileType.
+               if ((!haveUnknown && (romList[i].flags & FF_ROM))
+                       || (haveUnknown && (fileType == JST_ROM) && !haveUniversalHeader))
+               {
+                       cart = QImage(":/res/cart-blank.png");
+                       QPainter painter(&cart);
+                       painter.drawPixmap(27, 89, QPixmap::fromImage(QImage(":/res/label-blank.png")));
+                       painter.end();
+               }
+               else if ((!haveUnknown && (romList[i].flags & FF_ALPINE))
+                       || (haveUnknown
+                               && ((fileType == JST_ALPINE) || ((fileType == JST_ROM) && haveUniversalHeader))))
+               {
+                       if (haveUniversalHeader)
+                               cart = QImage(":/res/skunkboard-file.png");
+                       else
+                               cart = QImage(":/res/alpine-file.png");
+               }
+               else if (haveUnknown && (fileType == JST_ABS_TYPE1 || fileType == JST_ABS_TYPE2
+                       || fileType == JST_JAGSERVER))
                {
-                       file.read((char *)buffer, fileInfo.size());
-                       uint32 crc = crc32_calcCheckSum(buffer, fileInfo.size());
-                       file.close();
-//printf("FilePickerWindow: File crc == %08X...\n", crc);
-
-                       for(int j=0; romList2[j].crc32 != 0xFFFFFFFF; j++)
-                       {
-                               if (romList2[j].crc32 == crc)
-                               {
-printf("FilePickerWindow: Found match [%s]...\n", romList2[j].name);
-                                       new QListWidgetItem(QIcon(":/res/generic.png"), romList2[j].name, fileList);
-                                       break;
-                               }
-                       }
+                       cart = QImage(":/res/homebrew-file.png");
                }
+               else
+                       cart = QImage(":/res/unknown-file.png");
+
+               cartImage->setPixmap(QPixmap::fromImage(cart));
+       }
+
+//1048576
+//2097152
+//4194304
+       if (!haveUnknown)
+               prettyFilename = romList[i].name;
+       else
+       {
+               int lastSlashPos = currentFile.lastIndexOf('/');
+               prettyFilename = "\"" + currentFile.mid(lastSlashPos + 1) + "\"";
+       }
 
-               delete[] buffer;
+       title->setText(QString("<h2>%1</h2>").arg(prettyFilename));
+
+//Kludge for now, we'll have to fix this later...
+// So let's fix it now!
+       QString fileTypeString, crcString, notes, compatibility;
+
+#if 0
+       if (!haveUnknown)
+       {
+               if (romList[i].flags & FF_ROM)
+                       fileTypeString = QString(tr("%1MB Cartridge")).arg(fileSize / 1048576);
+               else if (romList[i].flags & FF_ALPINE)
+                       fileTypeString = QString(tr("%1MB Alpine ROM")).arg(fileSize / 1048576);
+               else
+                       fileTypeString = QString(tr("*** UNKNOWN *** (%1 bytes)")).arg(fileSize);
+       }
+#else
+       if ((!haveUnknown && (romList[i].flags & FF_ROM))
+               || (haveUnknown && (fileType == JST_ROM) && !haveUniversalHeader))
+               fileTypeString = QString(tr("%1MB Cartridge")).arg(fileSize / 1048576);
+       else if ((!haveUnknown && (romList[i].flags & FF_ALPINE))
+               || (haveUnknown
+                               && ((fileType == JST_ALPINE) || ((fileType == JST_ROM) && haveUniversalHeader))))
+       {
+               if (haveUniversalHeader)
+                       fileTypeString = QString(tr("%1MB Alpine ROM w/Universal Header"));
+               else
+                       fileTypeString = QString(tr("%1MB Alpine ROM"));
+
+               fileTypeString = fileTypeString.arg((fileSize + 8192) / 1048576);
        }
+       else if (haveUnknown && (fileType == JST_ABS_TYPE1 || fileType == JST_ABS_TYPE2))
+               fileTypeString = QString(tr("ABS/COF Executable (%1 bytes)")).arg(fileSize);
+       else if (haveUnknown && (fileType == JST_JAGSERVER))
+               fileTypeString = QString(tr("Jaguar Server Executable (%1 bytes)")).arg(fileSize);
+       else
+               fileTypeString = QString(tr("*** UNKNOWN *** (%1 bytes)")).arg(fileSize);
+#endif
+
+//     crcString = QString("%1").arg(romList[i].crc32, 8, 16, QChar('0')).toUpper();
+       crcString = QString("%1").arg(crc, 8, 16, QChar('0')).toUpper();
+
+       if (!haveUnknown && (romList[i].flags & FF_NON_WORKING))
+               compatibility = "DOES NOT WORK";
+       else
+               compatibility = "Unknown";
+
+       // This is going to need some formatting love before long...
+       if (!haveUnknown && (romList[i].flags & FF_BAD_DUMP))
+               notes = "<b>BAD DUMP</b>";
+
+//     if (haveUniversalHeader)
+//             notes += " Universal Header detected";
+
+       if (!haveUnknown && (romList[i].flags & FF_REQ_BIOS))
+               notes += " Requires BIOS";
+
+       if (!haveUnknown && (romList[i].flags & FF_REQ_DSP))
+               notes += " Requires DSP";
+
+       if (!haveUnknown && (romList[i].flags & FF_VERIFIED))
+               notes += " <i>(Verified)</i>";
+
+       data->setText(QString("%1<br>%2<br>%3<br>%4")
+               .arg(fileTypeString).arg(crcString).arg(compatibility).arg(notes));
 }
+
+/*
+    Super Duper Awesome Guy (World)
+
+         Type: 4MB Cartridge
+        CRC32: FEDCBA98
+Compatibility: DOES NOT WORK
+        Notes: Universal Header detected; Requires DSP
+
+
+    Stupid Homebrew Game That Sux
+
+         Type: ABS/COF Executable (43853 bytes)
+        CRC32: 76543210
+Compatibility: Unknown
+        Notes: $4000 Load, $4000 Run
+
+
+    Action Hopscotch Plus (Prototype)
+
+         Type: 2MB Alpine ROM
+        CRC32: 44889921
+Compatibility: 80% (or ****)
+        Notes: EEPROM available
 */