X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fgui%2Fmainwin.cpp;h=4f9dcce2e8576ea89525adf5ea984197a09e571d;hb=f45b4acc547ca85d9af9efa37d8caa68c20a42e6;hp=5aae995359e54042e37fbbd32b7fa735dd0be80a;hpb=7611a21d2b36def66216598617d647acfc657e3e;p=virtualjaguar diff --git a/src/gui/mainwin.cpp b/src/gui/mainwin.cpp index 5aae995..4f9dcce 100644 --- a/src/gui/mainwin.cpp +++ b/src/gui/mainwin.cpp @@ -32,6 +32,25 @@ #include "settings.h" #include "filepicker.h" +#include "jaguar.h" +#include "video.h" +#include "tom.h" +#include "log.h" +#include "file.h" + +// Uncomment this to use built-in BIOS/CD-ROM BIOS +// You'll need a copy of jagboot.h & jagcd.h for this to work...! +//#define USE_BUILT_IN_BIOS + +// Uncomment this for an official Virtual Jaguar release +//#define VJ_RELEASE_VERSION "2.0.0" +#warning !!! FIX !!! Figure out how to use this in GUI.CPP as well! + +#ifdef USE_BUILT_IN_BIOS +#include "jagboot.h" +#include "jagcd.h" +#endif + // The way BSNES controls things is by setting a timer with a zero // timeout, sleeping if not emulating anything. Seems there has to be a // better way. @@ -44,7 +63,7 @@ // 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() +MainWin::MainWin(): showUntunedTankCircuit(true) { videoWidget = new GLWidget(this); setCentralWidget(videoWidget); @@ -92,12 +111,12 @@ MainWin::MainWin() tvTypeActs = new QActionGroup(this); ntscAct = new QAction(QIcon(":/res/generic.png"), tr("NTSC"), tvTypeActs); - ntscAct->setStatusTip(tr("Sets OpenGL rendering to GL_NEAREST")); + ntscAct->setStatusTip(tr("Sets Jaguar to NTSC mode")); ntscAct->setCheckable(true); connect(ntscAct, SIGNAL(triggered()), this, SLOT(SetNTSC())); palAct = new QAction(QIcon(":/res/generic.png"), tr("PAL"), tvTypeActs); - palAct->setStatusTip(tr("Sets OpenGL rendering to GL_NEAREST")); + palAct->setStatusTip(tr("Sets Jaguar to PAL mode")); palAct->setCheckable(true); connect(palAct, SIGNAL(triggered()), this, SLOT(SetPAL())); @@ -110,10 +129,13 @@ MainWin::MainWin() aboutAct->setStatusTip(tr("Blatant self-promotion")); connect(aboutAct, SIGNAL(triggered()), this, SLOT(ShowAboutWin())); - filePickAct = new QAction(QIcon(":/res/generic.png"), tr("Insert Cartridge..."), this); + filePickAct = new QAction(QIcon(":/res/generic.png"), tr("&Insert Cartridge..."), this); filePickAct->setStatusTip(tr("Insert a cartridge into Virtual Jaguar")); connect(filePickAct, SIGNAL(triggered()), this, SLOT(InsertCart())); + // Misc. connections... + connect(filePickWin, SIGNAL(RequestLoad(QString)), this, SLOT(LoadSoftware(QString))); + // Create menus & toolbars fileMenu = menuBar()->addMenu(tr("&File")); @@ -121,22 +143,26 @@ MainWin::MainWin() fileMenu->addAction(powerAct); fileMenu->addAction(quitAppAct); - fileMenu = menuBar()->addMenu(tr("&Help")); - fileMenu->addAction(aboutAct); + helpMenu = menuBar()->addMenu(tr("&Help")); + helpMenu->addAction(aboutAct); - QToolBar * toolbar = addToolBar(tr("Stuff")); + toolbar = addToolBar(tr("Stuff")); toolbar->addAction(powerAct); + toolbar->addAction(filePickAct); + toolbar->addSeparator(); toolbar->addAction(x1Act); toolbar->addAction(x2Act); toolbar->addAction(x3Act); + toolbar->addSeparator(); toolbar->addAction(ntscAct); toolbar->addAction(palAct); + toolbar->addSeparator(); toolbar->addAction(blurAct); // Create status bar statusBar()->showMessage(tr("Ready")); - // Set toolbar button based on setting read in (sync the UI)... + // Set toolbar buttons/menus based on settings read in (sync the UI)... blurAct->setChecked(vjs.glFilter); x1Act->setChecked(zoomLevel == 1); x2Act->setChecked(zoomLevel == 2); @@ -152,6 +178,54 @@ MainWin::MainWin() timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(Timer())); timer->start(20); + + // NOTE: Keyboards/joysticks will *not* work until SDL is brought back in, or + // the key handling is improved in Qt... + // Wait a minute... it seems they already are... So why no keyboard love? + +#ifdef VJ_RELEASE_VERSION + WriteLog("Virtual Jaguar %s (Last full build was on %s %s)\n", VJ_RELEASE_VERSION, __DATE__, __TIME__); +#else + WriteLog("Virtual Jaguar SVN %s (Last full build was on %s %s)\n", __DATE__, __DATE__, __TIME__); +#endif + WriteLog("Initializing jaguar subsystem...\n"); + JaguarInit(); + + // Get the BIOS ROM +#ifdef USE_BUILT_IN_BIOS + WriteLog("VJ: Using built in BIOS/CD BIOS...\n"); + memcpy(jaguarBootROM, jagBootROM, 0x20000); + memcpy(jaguarCDBootROM, jagCDROM, 0x40000); + BIOSLoaded = CDBIOSLoaded = true; +#else +// What would be nice here would be a way to check if the BIOS was loaded so that we +// could disable the pushbutton on the Misc Options menu... !!! FIX !!! [DONE here, but needs to be fixed in GUI as well!] +WriteLog("About to attempt to load BIOSes...\n"); +#if 1 +//This is short-circuiting the file finding thread... ??? WHY ??? + BIOSLoaded = (JaguarLoadROM(jaguarBootROM, vjs.jagBootPath) == 0x20000 ? true : false); +#else + BIOSLoaded = false; +#endif + WriteLog("VJ: BIOS is %savailable...\n", (BIOSLoaded ? "" : "not ")); + CDBIOSLoaded = (JaguarLoadROM(jaguarCDBootROM, vjs.CDBootPath) == 0x40000 ? true : false); + WriteLog("VJ: CD BIOS is %savailable...\n", (CDBIOSLoaded ? "" : "not ")); +#endif + + SET32(jaguarMainRAM, 0, 0x00200000); // Set top of stack... + +//Let's try this... +// JaguarLoadFile("./software/Rayman (World).j64"); +// JaguarLoadFile("./software/I-War (World).j64"); +// JaguarLoadFile("./software/Alien vs Predator (World).j64"); +//no JaguarLoadFile("./software/battlesphere.bin"); +// JaguarLoadFile("./software/Battle Sphere Gold (World).j64"); +// JaguarLoadFile("./software/Rayman (USA, Europe).zip"); +//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(); } void MainWin::closeEvent(QCloseEvent * event) @@ -164,34 +238,173 @@ void MainWin::Open(void) { } +// +// Here's the main emulator loop +// void MainWin::Timer(void) { if (!running) return; - // Random hash & trash - // We try to simulate an untuned tank circuit here... :-) - for(uint32_t x=0; xrasterWidth; x++) + if (showUntunedTankCircuit) { - for(uint32_t y=0; yrasterHeight; y++) + // Random hash & trash + // We try to simulate an untuned tank circuit here... :-) + for(uint32_t x=0; xrasterWidth; x++) { - videoWidget->buffer[(y * videoWidget->textureWidth) + x] = (rand() & 0xFF) << 8 | (rand() & 0xFF) << 16 | (rand() & 0xFF) << 24;// | (rand() & 0xFF);//0x000000FF; -// buffer[(y * textureWidth) + x] = x*y; + for(uint32_t y=0; yrasterHeight; y++) + { + videoWidget->buffer[(y * videoWidget->textureWidth) + x] = (rand() & 0xFF) << 8 | (rand() & 0xFF) << 16 | (rand() & 0xFF) << 24;// | (rand() & 0xFF);//0x000000FF; + // buffer[(y * textureWidth) + x] = x*y; + } } } + else + { + // Otherwise, run the Jaguar simulation + JaguarExecuteNew(); +// memcpy(videoWidget->buffer, backbuffer, videoWidget->rasterHeight * videoWidget->rasterWidth); + memcpy(videoWidget->buffer, backbuffer, videoWidget->rasterHeight * videoWidget->textureWidth * sizeof(uint32_t)); +// memcpy(surface->pixels, backbuffer, TOMGetVideoModeWidth() * TOMGetVideoModeHeight() * 4); + } videoWidget->updateGL(); } +#if 0 +Window * RunEmu(void) +{ +// extern uint32 * backbuffer; + uint32 * overlayPixels = (uint32 *)sdlemuGetOverlayPixels(); + memset(overlayPixels, 0x00, 640 * 480 * 4); // Clear out overlay... + +//This is crappy... !!! FIX !!! +// extern bool finished, showGUI; + + sdlemuDisableOverlay(); + +// uint32 nFrame = 0, nFrameskip = 0; + uint32 totalFrames = 0; + finished = false; + bool showMessage = true; + uint32 showMsgFrames = 120; + uint8 transparency = 0xFF; + // Pass a message to the "joystick" code to debounce the ESC key... + debounceRunKey = true; + + uint32 cartType = 4; + if (jaguarRomSize == 0x200000) + cartType = 0; + else if (jaguarRomSize == 0x400000) + cartType = 1; + else if (jaguarMainRomCRC32 == 0x687068D5) + cartType = 2; + else if (jaguarMainRomCRC32 == 0x55A0669C) + cartType = 3; + + const char * cartTypeName[5] = { "2M Cartridge", "4M Cartridge", "CD BIOS", "CD Dev BIOS", "Homebrew" }; + uint32 elapsedTicks = SDL_GetTicks(), frameCount = 0, framesPerSecond = 0; + + while (!finished) + { + // Set up new backbuffer with new pixels and data + JaguarExecuteNew(); + totalFrames++; +//WriteLog("Frame #%u...\n", totalFrames); +//extern bool doDSPDis; +//if (totalFrames == 373) +// doDSPDis = true; + +//Problem: Need to do this *only* when the state changes from visible to not... +//Also, need to clear out the GUI when not on (when showMessage is active...) +if (showGUI || showMessage) + sdlemuEnableOverlay(); +else + sdlemuDisableOverlay(); + +//Add in a new function for clearing patches of screen (ClearOverlayRect) + +// Also: Take frame rate into account when calculating fade time... + + // Some QnD GUI stuff here... + if (showGUI) + { + FillScreenRectangle(overlayPixels, 8, 1*FONT_HEIGHT, 128, 4*FONT_HEIGHT, 0x00000000); + extern uint32 gpu_pc, dsp_pc; + DrawString(overlayPixels, 8, 1*FONT_HEIGHT, false, "GPU PC: %08X", gpu_pc); + DrawString(overlayPixels, 8, 2*FONT_HEIGHT, false, "DSP PC: %08X", dsp_pc); + DrawString(overlayPixels, 8, 4*FONT_HEIGHT, false, "%u FPS", framesPerSecond); + } + + if (showMessage) + { + DrawString2(overlayPixels, 8, 24*FONT_HEIGHT, 0x007F63FF, transparency, "Running..."); + DrawString2(overlayPixels, 8, 26*FONT_HEIGHT, 0x001FFF3F, transparency, "%s, run address: %06X", cartTypeName[cartType], jaguarRunAddress); + DrawString2(overlayPixels, 8, 27*FONT_HEIGHT, 0x001FFF3F, transparency, "CRC: %08X", jaguarMainRomCRC32); + + if (showMsgFrames == 0) + { + transparency--; + + if (transparency == 0) +{ + showMessage = false; +/*extern bool doGPUDis; +doGPUDis = true;//*/ +} + + } + else + showMsgFrames--; + } + + frameCount++; + + if (SDL_GetTicks() - elapsedTicks > 250) + elapsedTicks += 250, framesPerSecond = frameCount * 4, frameCount = 0; + } + + // Save the background for the GUI... + // In this case, we squash the color to monochrome, then force it to blue + green... + for(uint32 i=0; i> 16) & 0xFF, g = (pixel >> 8) & 0xFF, r = pixel & 0xFF; + pixel = ((r + g + b) / 3) & 0x00FF; + backbuffer[i] = 0xFF000000 | (pixel << 16) | (pixel << 8); + } + + sdlemuEnableOverlay(); + + return NULL; +} +#endif + void MainWin::ToggleRunState(void) { running = !running; if (!running) { +#if 0 for(uint32_t x=0; xrasterWidth; x++) for(uint32_t y=0; yrasterHeight; y++) videoWidget->buffer[(y * videoWidget->textureWidth) + x] = 0x00000000; +#else +// for(uint32_t i=0; itextureWidth * 256; i++) + { + uint32_t pixel = backbuffer[i]; +// uint8_t b = (pixel >> 16) & 0xFF, g = (pixel >> 8) & 0xFF, r = pixel & 0xFF; + uint8_t r = (pixel >> 24) & 0xFF, g = (pixel >> 16) & 0xFF, b = (pixel >> 8) & 0xFF; + pixel = ((r + g + b) / 3) & 0x00FF; +// backbuffer[i] = 0xFF000000 | (pixel << 16) | (pixel << 8); + backbuffer[i] = 0x000000FF | (pixel << 16) | (pixel << 8); + } + +// memcpy(videoWidget->buffer, backbuffer, videoWidget->rasterHeight * videoWidget->rasterWidth); + memcpy(videoWidget->buffer, backbuffer, videoWidget->rasterHeight * videoWidget->textureWidth * sizeof(uint32_t)); +#endif videoWidget->updateGL(); } @@ -242,6 +455,19 @@ void MainWin::InsertCart(void) filePickWin->show(); } +void MainWin::LoadSoftware(QString file) +{ + running = false; // Prevent bad things(TM) from happening... + SET32(jaguarMainRAM, 0, 0x00200000); // Set top of stack... + showUntunedTankCircuit = (JaguarLoadFile(file.toAscii().data()) ? false : true); +//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::ResizeMainWindow(void) { videoWidget->setFixedSize(zoomLevel * 320, zoomLevel * (vjs.hardwareTypeNTSC ? 240 : 256)); @@ -276,9 +502,15 @@ void MainWin::ReadSettings(void) vjs.useOpenGL = settings.value("useOpenGL", true).toBool(); vjs.glFilter = settings.value("glFilterType", 0).toInt(); vjs.renderType = settings.value("renderType", 0).toInt(); - - // Hardcoded, !!! FIX !!! - strcpy(vjs.ROMPath, "./roms"); + strcpy(vjs.jagBootPath, settings.value("JagBootROM", "./bios/[BIOS] Atari Jaguar (USA, Europe).zip").toString().toAscii().data()); + strcpy(vjs.CDBootPath, settings.value("CDBootROM", "./bios/jagcd.rom").toString().toAscii().data()); + strcpy(vjs.EEPROMPath, settings.value("EEPROMs", "./eeproms").toString().toAscii().data()); + strcpy(vjs.ROMPath, settings.value("ROMs", "./software").toString().toAscii().data()); +WriteLog("MainWin: Paths\n"); +WriteLog(" jagBootPath = \"%s\"\n", vjs.jagBootPath); +WriteLog(" CDBootPath = \"%s\"\n", vjs.CDBootPath); +WriteLog(" EEPROMPath = \"%s\"\n", vjs.EEPROMPath); +WriteLog(" ROMPath = \"%s\"\n", vjs.ROMPath); } void MainWin::WriteSettings(void) @@ -300,6 +532,10 @@ void MainWin::WriteSettings(void) settings.setValue("useOpenGL", vjs.useOpenGL); settings.setValue("glFilterType", vjs.glFilter); settings.setValue("renderType", vjs.renderType); + settings.setValue("JagBootROM", vjs.jagBootPath); + settings.setValue("CDBootROM", vjs.CDBootPath); + settings.setValue("EEPROMs", vjs.EEPROMPath); + settings.setValue("ROMs", vjs.ROMPath); } // Here's how Byuu does it...