#warning "!!! FIX !!! Should have sanity checking for ROM size to prevent buffer overflow!"
uint32 romSize = 0;
-WriteLog("JaguarLoadROM: Attempting to load file '%s'...", path);
+ WriteLog("JaguarLoadROM: Attempting to load file '%s'...", path);
char * ext = strrchr(path, '.');
-if (ext == NULL)
- WriteLog("FAILED!\n");
-else
- WriteLog("Succeeded in finding extension (%s)!\n", ext);
- if (ext != NULL)
+ // No filename extension == YUO FAIL IT (it is loading the file).
+ // This is naive, but it works. But should probably come up with something a little
+ // more robust, to prevent problems with dopes trying to exploit this.
+ if (ext == NULL)
{
- WriteLog("VJ: Loading \"%s\"...", path);
-
- if (strcasecmp(ext, ".zip") == 0)
- {
- // Handle ZIP file loading here...
- WriteLog("(ZIPped)...");
+ WriteLog("FAILED!\n");
+ return 0;
+ }
- if (load_zipped_file(0, 0, path, NULL, &rom, &romSize) == -1)
- {
- WriteLog("Failed!\n");
- return 0;
- }
- }
- else
- {
-/* FILE * fp = fopen(path, "rb");
+ WriteLog("Succeeded in finding extension (%s)!\n", ext);
+ WriteLog("VJ: Loading \"%s\"...", path);
- if (fp == NULL)
- {
- WriteLog("Failed!\n");
- return 0;
- }
+ if (strcasecmp(ext, ".zip") == 0)
+ {
+ // Handle ZIP file loading here...
+ WriteLog("(ZIPped)...");
- fseek(fp, 0, SEEK_END);
- romSize = ftell(fp);
- fseek(fp, 0, SEEK_SET);
- fread(rom, 1, romSize, fp);
- fclose(fp);*/
+ uint8_t * buffer = NULL;
+ romSize = GetFileFromZIP(path, FT_SOFTWARE, buffer);
- // Handle gzipped files transparently [Adam Green]...
+ if (romSize == 0)
+ {
+ WriteLog("Failed!\n");
+ return 0;
+ }
- gzFile fp = gzopen(path, "rb");
+ memcpy(rom, buffer, romSize);
+ delete[] buffer;
+ }
+ else
+ {
+ // Handle gzipped files transparently [Adam Green]...
- if (fp == NULL)
- {
- WriteLog("Failed!\n");
- return 0;
- }
+ gzFile fp = gzopen(path, "rb");
- romSize = gzfilelength(fp);
- gzseek(fp, 0, SEEK_SET);
- gzread(fp, rom, romSize);
- gzclose(fp);
+ if (fp == NULL)
+ {
+ WriteLog("Failed!\n");
+ return 0;
}
- WriteLog("OK (%i bytes)\n", romSize);
+ romSize = gzfilelength(fp);
+ gzseek(fp, 0, SEEK_SET);
+ gzread(fp, rom, romSize);
+ gzclose(fp);
}
+ WriteLog("OK (%i bytes)\n", romSize);
+
return romSize;
}
char * ext = strrchr(path, '.'); // Get the file's extension for non-cartridge checking
//NOTE: Should fix JaguarLoadROM() to replace .zip with what's *in* the zip (.abs, .j64, etc.)
+#warning "!!! Need more robust file type checking in JaguarLoadROM() !!!"
if (strcasecmp(ext, ".rom") == 0)
{
// File extension ".ROM": Alpine image that loads/runs at $802000
//
// Get file from .ZIP
// Returns the size of the file inside the .ZIP file that we're looking at
+// NOTE: If the thing we're looking for is found, it allocates it in the passed in buffer.
+// Which means we have to deallocate it later.
//
uint32 GetFileFromZIP(const char * zipFile, FileType type, uint8 * &buffer)
{
+// NOTE: We could easily check for this by discarding anything that's larger than the RAM/ROM
+// size of the Jaguar console.
#warning "!!! FIX !!! Should have sanity checking for ROM size to prevent buffer overflow!"
const char ftStrings[5][32] = { "Software", "EEPROM", "Label", "Box Art", "Controller Overlay" };
ZIP * zip = openzip(0, 0, zipFile);
zipent * ze = &zip->ent;
bool found = false;
+ // Here we simply rely on the file extension to tell the truth, but we know
+ // that extensions lie like sons-a-bitches. So this is naive, we need to do
+ // something a little more robust to keep bad things from happening here.
+#warning "!!! Checking for image by extension can be fooled !!!"
if ((type == FT_LABEL) && (CheckExtension(ze->name, ".png") || CheckExtension(ze->name, ".jpg") || CheckExtension(ze->name, ".gif")))
{
found = true;
if (found)
{
WriteLog("FILE: Uncompressing...");
+// Insert file size sanity check here...
buffer = new uint8[ze->uncompressed_size];
if (readuncompresszip(zip, ze, (char *)buffer) == 0)
{
WriteLog("success! (%u bytes)\n", ze->uncompressed_size);
+ closezip(zip);
return ze->uncompressed_size;
}
else
{
WriteLog("FAILED!\n");
delete[] buffer;
+ buffer = NULL;
+ closezip(zip);
return 0;
}
}
data->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
dataLayout->addWidget(data);
- insertCart = new QPushButton(QIcon(":/res/generic.png"), "", this);
+//#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);
connect(insertCart, SIGNAL(clicked()), this, SLOT(LoadButtonPressed()));
}
+QString FilePickerWindow::GetSelectedPrettyName(void)
+{
+ return prettyFilename;
+}
+
//
// 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.
//currentFile = s;
//373x172 is label size...
+//365x168 now...
if (!label.isNull())
{
/*
//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(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));
}
// redraw regardless.
QImage cart(":/res/cart-blank.png");
QPainter painter(&cart);
- painter.drawPixmap(23, 87, QPixmap::fromImage(QImage(":/res/label-blank.png")));
+// painter.drawPixmap(23, 87, QPixmap::fromImage(QImage(":/res/label-blank.png")));
+ painter.drawPixmap(27, 89, QPixmap::fromImage(QImage(":/res/label-blank.png")));
painter.end();
cartImage->setPixmap(QPixmap::fromImage(cart));
}
//1048576
//2097152
//4194304
+ prettyFilename = romList[i].name;
title->setText(QString("<h2>%1</h2>").arg(romList[i].name));
//Kludge for now, we'll have to fix this later...
QString fileType = QString(romList[i].flags & FF_ROM ? "%1MB Cartridge" : "%1*** UNKNOWN ***")
public:
FilePickerWindow(QWidget * parent = 0);
+ QString GetSelectedPrettyName(void);
public slots:
void AddFileToList(unsigned long index);
private:
QString currentFile;
+ QString prettyFilename;
QListWidget * fileList2;
FileThread * fileThread;
FileListModel * model;
uint32 crc = crc32_calcCheckSum(buffer, size);
uint32 index = FindCRCIndexInFileList(crc);
// These two are NOT interchangeable!
+//Hm, confusing. It looks like in file.cpp it uses operater new() to create the buffer...
// delete[] buffer;
free(buffer);
QImage label;
bool success = label.loadFromData(buffer, size);
img = new QImage();
- *img = label.scaled(373, 172, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+// *img = label.scaled(373, 172, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ *img = label.scaled(365, 168, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
//printf("FT: Label %s: %ux%u.\n", (success ? "succeeded" : "did not succeed"), img->width(), img->height());
// These two are NOT interchangeable!
+//Hm, confusing. It looks like in file.cpp it uses operater new() to create the buffer...
// delete[] buffer;
free(buffer);
}
// We'll make the VJ core modular so that it doesn't matter what GUI is in
// use, we can drop it in anywhere and use it as-is.
-MainWin::MainWin(): showUntunedTankCircuit(true)
+MainWin::MainWin(): running(false), powerButtonOn(false), showUntunedTankCircuit(true),
+ cartridgeLoaded(false)
{
videoWidget = new GLWidget(this);
setCentralWidget(videoWidget);
- setWindowIcon(QIcon(":/res/vj.xpm"));
+ setWindowIcon(QIcon(":/res/vj-icon.png"));
setWindowTitle("Virtual Jaguar v2.0.0");
ReadSettings();
setUnifiedTitleAndToolBarOnMac(true);
+#warning "!!! Save/Restore window location for FilePickerWindow !!!"
aboutWin = new AboutWindow(this);
filePickWin = new FilePickerWindow(this);
connect(quitAppAct, SIGNAL(triggered()), this, SLOT(close()));
powerAct = new QAction(QIcon(":/res/power.png"), tr("&Power"), this);
- powerAct->setStatusTip(tr("Toggle running state"));
+ powerAct->setStatusTip(tr("Powers Jaguar on/off"));
powerAct->setCheckable(true);
- connect(powerAct, SIGNAL(triggered()), this, SLOT(ToggleRunState()));
+ powerAct->setChecked(false);
+ powerAct->setDisabled(true);
+ connect(powerAct, SIGNAL(triggered()), this, SLOT(TogglePowerState()));
+
+ pauseAct = new QAction(QIcon(":/res/pause.png"), tr("Pause"), this);
+ pauseAct->setStatusTip(tr("Toggles the running state"));
+ pauseAct->setCheckable(true);
+ pauseAct->setDisabled(true);
+ connect(pauseAct, SIGNAL(triggered()), this, SLOT(ToggleRunState()));
zoomActs = new QActionGroup(this);
aboutAct->setStatusTip(tr("Blatant self-promotion"));
connect(aboutAct, SIGNAL(triggered()), this, SLOT(ShowAboutWin()));
- filePickAct = new QAction(QIcon(":/res/generic.png"), tr("&Insert Cartridge..."), this);
+#warning "!!! Set up a decent keyboard shortcut for Insert Cartridge !!!"
+ filePickAct = new QAction(QIcon(":/res/software.png"), tr("&Insert Cartridge..."), this);
filePickAct->setStatusTip(tr("Insert a cartridge into Virtual Jaguar"));
connect(filePickAct, SIGNAL(triggered()), this, SLOT(InsertCart()));
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(filePickAct);
fileMenu->addAction(powerAct);
+ fileMenu->addAction(pauseAct);
fileMenu->addAction(quitAppAct);
helpMenu = menuBar()->addMenu(tr("&Help"));
toolbar = addToolBar(tr("Stuff"));
toolbar->addAction(powerAct);
+ toolbar->addAction(pauseAct);
toolbar->addAction(filePickAct);
toolbar->addSeparator();
toolbar->addAction(x1Act);
}
#endif
+void MainWin::TogglePowerState(void)
+{
+ powerButtonOn = !powerButtonOn;
+
+ if (!powerButtonOn)
+ {
+ pauseAct->setChecked(false);
+ pauseAct->setDisabled(true);
+ showUntunedTankCircuit = true;
+ running = true;
+ }
+ else
+ {
+ showUntunedTankCircuit = (cartridgeLoaded ? false : true);
+ pauseAct->setDisabled(!cartridgeLoaded);
+//This is crappy!!! !!! FIX !!!
+//Is this even needed any more? Hmm. Maybe. Dunno.
+//Seems like it is... But then again, maybe not. Have to test it to see.
+ WriteLog("GUI: Resetting Jaguar...\n");
+ JaguarReset();
+ running = true;
+ }
+}
+
void MainWin::ToggleRunState(void)
{
running = !running;
{
running = false; // Prevent bad things(TM) from happening...
SET32(jaguarMainRAM, 0, 0x00200000); // Set top of stack...
- showUntunedTankCircuit = (JaguarLoadFile(file.toAscii().data()) ? false : true);
+ cartridgeLoaded = (JaguarLoadFile(file.toAscii().data()) ? true : false);
+
+#if 0
+ showUntunedTankCircuit = !cartridgeLoaded;
//This is crappy!!! !!! FIX !!!
//Is this even needed any more? Hmm. Maybe. Dunno.
//Seems like it is... But then again, maybe not. Have to test it to see.
WriteLog("GUI: Resetting Jaguar...\n");
JaguarReset();
running = true;
+#else
+ powerAct->setDisabled(false);
+ powerAct->setChecked(true);
+ powerButtonOn = false;
+ TogglePowerState();
+#endif
+
+ QString newTitle = QString("Virtual Jaguar 2.0.0 - Now playing: %1")
+ .arg(filePickWin->GetSelectedPrettyName());
+ setWindowTitle(newTitle);
}
void MainWin::ResizeMainWindow(void)
private slots:
void Open(void);
void Timer(void);
+ void TogglePowerState(void);
void ToggleRunState(void);
void SetZoom100(void);
void SetZoom200(void);
QTimer * timer;
bool running;
int zoomLevel;
+ bool powerButtonOn;
bool showUntunedTankCircuit;
+ bool cartridgeLoaded;
QMenu * fileMenu;
QMenu * helpMenu;
QAction * quitAppAct;
QAction * powerAct;
+ QAction * pauseAct;
QAction * x1Act;
QAction * x2Act;
QAction * x3Act;
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
- <file>../../res/vj.xpm</file>
+ <file>../../res/vj-icon.png</file>
<file>../../res/power.png</file>
+ <file>../../res/pause.png</file>
<file>../../res/zoom100.png</file>
<file>../../res/zoom200.png</file>
<file>../../res/zoom300.png</file>
<file>../../res/cart-blank.png</file>
<file>../../res/label-blank.png</file>
<file>../../res/vj_title_small.png</file>
- <file>../../res/labels/rayman.jpg</file>
+ <file>../../res/controller.png</file>
+ <file>../../res/insert.png</file>
+ <file>../../res/software.png</file>
+ <file>../../res/upper-left.png</file>
+ <file>../../res/upper-right.png</file>
</qresource>
</RCC>