]> Shamusworld >> Repos - virtualjaguar/commitdiff
UI cleanups, added RAM randomization for main RAM & GPU local RAM.
authorShamus Hammons <jlhamm@acm.org>
Sun, 24 Feb 2013 22:33:45 +0000 (16:33 -0600)
committerShamus Hammons <jlhamm@acm.org>
Sun, 24 Feb 2013 22:33:45 +0000 (16:33 -0600)
res/test-pattern.jpg [new file with mode: 0644]
src/dsp.cpp
src/gpu.cpp
src/gui/gamepad.cpp
src/gui/glwidget.cpp
src/gui/glwidget.h
src/gui/mainwin.cpp
src/gui/mainwin.h
src/jaguar.cpp

diff --git a/res/test-pattern.jpg b/res/test-pattern.jpg
new file mode 100644 (file)
index 0000000..e559cce
Binary files /dev/null and b/res/test-pattern.jpg differ
index 6e6902c3e2bf0221c86c787fb684ade650773afa..53a7d0889f9c6fbd76f6b208d1c4b6a591b8b0d4 100644 (file)
@@ -18,7 +18,6 @@
 
 #include <SDL.h>                                                               // Used only for SDL_GetTicks...
 #include <stdlib.h>
-#include <time.h>
 #include "dac.h"
 #include "gpu.h"
 #include "jagdasm.h"
@@ -1279,7 +1278,6 @@ void DSPInit(void)
 
        dsp_build_branch_condition_table();
        DSPReset();
-       srand(time(NULL));                                                      // For randomizing local RAM
 }
 
 void DSPReset(void)
@@ -1306,12 +1304,10 @@ void DSPReset(void)
        IMASKCleared = false;
        FlushDSPPipeline();
        dsp_reset_stats();
-//     memset(dsp_ram_8, 0xFF, 0x2000);
+
        // Contents of local RAM are quasi-stable; we simulate this by randomizing RAM contents
        for(uint32_t i=0; i<8192; i+=4)
-       {
                *((uint32_t *)(&dsp_ram_8[i])) = rand();
-       }
 }
 
 void DSPDumpDisassembly(void)
index b83051cab3ddf478d4446de6cfe0f5e6bd88d107..1f1bef9351cbe14eb6ab5ba18a1c94d00d5fa7e8 100644 (file)
@@ -1044,6 +1044,10 @@ void GPUReset(void)
        gpu_in_exec = 0;
 //not needed   GPUInterruptPending = false;
        GPUResetStats();
+
+       // Contents of local RAM are quasi-stable; we simulate this by randomizing RAM contents
+       for(uint32_t i=0; i<4096; i+=4)
+               *((uint32_t *)(&gpu_ram_8[i])) = rand();
 }
 
 uint32_t GPUReadPC(void)
index 84307f8ea612e996d9ebcad2a58293efae2e7e23..62a6d7a9bef851d932aba79f87c305fc3a2aa36b 100644 (file)
@@ -95,10 +95,10 @@ bool Gamepad::GetState(int joystickID, int buttonID)
 
                if (axis[joystickID][axisNum] != 0)
                {
-                       if (axis[joystickID][axisNum] > 0 && (direction == 0))
+                       if (axis[joystickID][axisNum] > 16000 && (direction == 0))
                                return true;
 
-                       if (axis[joystickID][axisNum] < 0 && (direction == 1))
+                       if (axis[joystickID][axisNum] < -16000 && (direction == 1))
                                return true;
                }
        }
index af51f47ed3c8c093a6b6b41d85cde92732ceec0c..058f9e0f150b5b07977f338a9d9449a2b11fe7de 100644 (file)
@@ -25,7 +25,7 @@
 
 
 GLWidget::GLWidget(QWidget * parent/*= 0*/): QGLWidget(parent), texture(0),
-       textureWidth(0), textureHeight(0), buffer(0), rasterWidth(340), rasterHeight(240),
+       textureWidth(0), textureHeight(0), buffer(0), rasterWidth(326), rasterHeight(240),
        offset(0)
 {
        // Screen pitch has to be the texture width (in 32-bit pixels)...
@@ -53,13 +53,15 @@ void GLWidget::initializeGL()
        glEnable(GL_DITHER);
        glEnable(GL_TEXTURE_2D);
        glClearColor(0.0, 0.0, 0.0, 0.0);
+
+       CreateTextures();
 }
 
 
 void GLWidget::paintGL()
 {
-//kludge
-rasterHeight = (vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL);
+//kludge [NO MORE!]
+//rasterHeight = (vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL);
 
        // If we're in fullscreen mode, we take the value of the screen width as
        // set by MainWin, since it may be wider than what our aspect ratio allows.
@@ -113,34 +115,31 @@ rasterHeight = (vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCRE
 
 void GLWidget::resizeGL(int width, int height)
 {
-       if (width > textureWidth || height > textureHeight)
-       {
-               // Seems that power of 2 sizes are still mandatory...
-               textureWidth  = 1024;
-               textureHeight = 512;
-#if 0
-printf("Resizing: new texture width/height = %i x %i\n", textureWidth, textureHeight);
-printf("Resizing: new raster width/height = %i x %i\n", rasterWidth, rasterHeight);
-#endif
+//kludge [No, this is where it belongs!]
+       rasterHeight = (vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL);
 
-               if (buffer)
-               {
-                       delete[] buffer;
-                       glDeleteTextures(1, &texture);
-               }
-
-               buffer = new uint32_t[textureWidth * textureHeight];
-               JaguarSetScreenBuffer(buffer);
-
-//???
-memset(buffer, 0xFF, textureWidth * textureHeight * sizeof(uint32_t));
-               glGenTextures(1, &texture);
-               glBindTexture(GL_TEXTURE_2D, texture);
-               glPixelStorei(GL_UNPACK_ROW_LENGTH, textureWidth);
-               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-               glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, NULL);
-       }
+       return;
+}
+
+
+// At some point, we'll have to create more than one texture to handle
+// cases like Doom. Or have another go at TV type rendering; it will
+// require a 2048x512 texture though. (Note that 512 is the correct height for
+// interlaced screens; we won't have to change much here to support it.)
+void GLWidget::CreateTextures(void)
+{
+       // Seems that power of 2 sizes are still mandatory...
+       textureWidth  = 1024;
+       textureHeight = 512;
+       buffer = new uint32_t[textureWidth * textureHeight];
+       JaguarSetScreenBuffer(buffer);
+
+       glGenTextures(1, &texture);
+       glBindTexture(GL_TEXTURE_2D, texture);
+       glPixelStorei(GL_UNPACK_ROW_LENGTH, textureWidth);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, NULL);
 }
 
 
index 1b000797efe9aa146608b30c07e835ecbb5e42e4..1e8e113bb65a51d673171fc7fac3c95f85895601 100644 (file)
@@ -24,11 +24,13 @@ class GLWidget: public QGLWidget
 //             void clicked();
 
        protected:
-               void initializeGL();
-               void paintGL();
+               void initializeGL(void);
+               void paintGL(void);
                void resizeGL(int width, int height);
 
-//     private:
+       private:
+               void CreateTextures(void);
+
        public:
                GLuint texture;
                int textureWidth, textureHeight;
index 0e19488f9eeed77ee44423c24be5a07ded56de65..0fde969e6541e8d4539f232496b72d41bcb8d5e8 100644 (file)
@@ -52,7 +52,6 @@
 
 #include "dac.h"
 #include "jaguar.h"
-#include "tom.h"
 #include "log.h"
 #include "file.h"
 #include "jagbios.h"
@@ -204,6 +203,7 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false),
 
        frameAdvanceAct = new QAction(QIcon(":/res/frame-advance.png"), tr("&Frame Advance"), this);
        frameAdvanceAct->setShortcut(QKeySequence(tr("F7")));
+       frameAdvanceAct->setDisabled(true);
        connect(frameAdvanceAct, SIGNAL(triggered()), this, SLOT(FrameAdvance()));
 
        fullScreenAct = new QAction(QIcon(":/res/fullscreen.png"), tr("F&ull Screen"), this);
@@ -246,7 +246,7 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false),
        fileMenu = menuBar()->addMenu(tr("&Jaguar"));
        fileMenu->addAction(powerAct);
        fileMenu->addAction(pauseAct);
-       fileMenu->addAction(frameAdvanceAct);
+//     fileMenu->addAction(frameAdvanceAct);
        fileMenu->addAction(filePickAct);
        fileMenu->addAction(useCDAct);
        fileMenu->addAction(configAct);
@@ -269,6 +269,7 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false),
        toolbar = addToolBar(tr("Stuff"));
        toolbar->addAction(powerAct);
        toolbar->addAction(pauseAct);
+       toolbar->addAction(frameAdvanceAct);
        toolbar->addAction(filePickAct);
        toolbar->addAction(useCDAct);
        toolbar->addSeparator();
@@ -300,6 +301,21 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false),
        // Do this in case original size isn't correct (mostly for the first-run case)
        ResizeMainWindow();
 
+       // Create our test pattern bitmap
+       QImage tempImg(":/res/test-pattern.jpg");
+       QImage tempImgScaled = tempImg.scaled(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT_PAL, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+
+       for(uint32_t y=0; y<VIRTUAL_SCREEN_HEIGHT_PAL; y++)
+       {
+               const QRgb * scanline = (QRgb *)tempImgScaled.constScanLine(y);
+
+               for(uint32_t x=0; x<VIRTUAL_SCREEN_WIDTH; x++)
+               {
+                       uint32_t pixel = (qRed(scanline[x]) << 24) | (qGreen(scanline[x]) << 16) | (qBlue(scanline[x]) << 8) | 0xFF;
+                       testPattern[(y * VIRTUAL_SCREEN_WIDTH) + x] = pixel;
+               }
+       }
+
        // Set up timer based loop for animation...
        timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(Timer()));
@@ -616,8 +632,6 @@ void MainWin::Timer(void)
        if (showUntunedTankCircuit)
        {
                // Some machines can't handle this, so we give them the option to disable it. :-)
-#warning "!!! Add test pattern here for -z option !!!"
-// Actually, should put test pattern in buffer in function below :-P
                if (!plzDontKillMyComputer)
                {
                        // Random hash & trash
@@ -657,10 +671,20 @@ void MainWin::TogglePowerState(void)
                pauseAct->setChecked(false);
                pauseAct->setDisabled(true);
                showUntunedTankCircuit = true;
+               DACPauseAudioThread();
                // This is just in case the ROM we were playing was in a narrow or wide field mode,
                // so the untuned tank sim doesn't look wrong. :-)
-               DACPauseAudioThread();
                TOMReset();
+
+               if (plzDontKillMyComputer)
+               {
+                       // We have to do it line by line, because the texture pitch is not the
+                       // same as the picture buffer's pitch.
+                       for(uint32_t y=0; y<videoWidget->rasterHeight; y++)
+                       {
+                               memcpy(videoWidget->buffer + (y * videoWidget->textureWidth), testPattern + (y * VIRTUAL_SCREEN_WIDTH), VIRTUAL_SCREEN_WIDTH * sizeof(uint32_t));
+                       }
+               }
        }
        else
        {
@@ -696,6 +720,8 @@ void MainWin::ToggleRunState(void)
 
        if (!running)
        {
+               frameAdvanceAct->setDisabled(false);
+
                for(uint32_t i=0; i<(uint32_t)(videoWidget->textureWidth * 256); i++)
                {
                        uint32_t pixel = videoWidget->buffer[i];
@@ -706,6 +732,8 @@ void MainWin::ToggleRunState(void)
 
                videoWidget->updateGL();
        }
+       else
+               frameAdvanceAct->setDisabled(true);
 
        // Pause/unpause any running/non-running threads...
        DACPauseAudioThread(!running);
@@ -846,6 +874,8 @@ void MainWin::FrameAdvance(void)
        // Execute 1 frame, then exit (only useful in Pause mode)
        JaguarExecuteNew();
        videoWidget->updateGL();
+       // Need to execute 1 frames' worth of DSP thread as well :-/
+#warning "!!! Need to execute the DSP thread for 1 frame too !!!"
 }
 
 
@@ -854,7 +884,6 @@ void MainWin::SetFullScreen(bool state/*= true*/)
        if (state)
        {
                mainWinPosition = pos();
-//             mainWinSize = size();
                menuBar()->hide();
                statusBar()->hide();
                x1Act->setDisabled(true);
@@ -865,18 +894,15 @@ void MainWin::SetFullScreen(bool state/*= true*/)
                // screen than screen 0:
                int screenNum = QApplication::desktop()->screenNumber(videoWidget);
                QRect r = QApplication::desktop()->availableGeometry(screenNum);
-//             double targetWidth = 320.0, targetHeight = (vjs.hardwareTypeNTSC ? 240.0 : 256.0);
                double targetWidth = (double)VIRTUAL_SCREEN_WIDTH,
                        targetHeight = (double)(vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL);
                double aspectRatio = targetWidth / targetHeight;
-               // NOTE: Really should check here to see which dimension constrains the other.
-               //       Right now, we assume that height is the constraint.
+               // NOTE: Really should check here to see which dimension constrains the
+               //       other. Right now, we assume that height is the constraint.
                int newWidth = (int)(aspectRatio * (double)r.height());
                videoWidget->offset = (r.width() - newWidth) / 2;
                videoWidget->fullscreen = true;
                videoWidget->outputWidth = newWidth;
-
-//             videoWidget->setFixedSize(newWidth, r.height());
                videoWidget->setFixedSize(r.width(), r.height());
                showFullScreen();
        }
@@ -897,6 +923,8 @@ void MainWin::SetFullScreen(bool state/*= true*/)
 
        // For some reason, this doesn't work: If the emu is paused, toggling from
        // fullscreen to windowed (& vice versa) shows a white screen.
+       // (It was the ResizeGL() function in GLWidget: it was being called too
+       // much, causing the buffer to be deleted, remade & cleared.)
 //     videoWidget->updateGL();
 }
 
@@ -945,9 +973,18 @@ void MainWin::ShowRISCDasmBrowserWin(void)
 
 void MainWin::ResizeMainWindow(void)
 {
-//     videoWidget->setFixedSize(zoomLevel * 320, zoomLevel * (vjs.hardwareTypeNTSC ? 240 : 256));
        videoWidget->setFixedSize(zoomLevel * VIRTUAL_SCREEN_WIDTH,
                zoomLevel * (vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL));
+
+       // Show the test pattern if user requested plzDontKillMyComputer mode
+       if (!powerButtonOn && plzDontKillMyComputer)
+       {
+               for(uint32_t y=0; y<videoWidget->rasterHeight; y++)
+               {
+                       memcpy(videoWidget->buffer + (y * videoWidget->textureWidth), testPattern + (y * VIRTUAL_SCREEN_WIDTH), VIRTUAL_SCREEN_WIDTH * sizeof(uint32_t));
+               }
+       }
+
        show();
 
        for(int i=0; i<2; i++)
index 80cfe935183d1b8f48d93e43bdae9b61cf96d77a..1c7871cba272ff6a5c8b718b9dcec0eee7f1ff8f 100644 (file)
@@ -10,6 +10,7 @@
 
 //Hrm. uh??? I thought this wasn't the way to do this stuff...???
 #include <QtGui>
+#include "tom.h"
 
 // Forward declarations
 class GLWidget;
@@ -136,6 +137,7 @@ class MainWin: public QMainWindow
 
                QIcon powerGreen;
                QIcon powerRed;
+               uint32_t testPattern[VIRTUAL_SCREEN_WIDTH * VIRTUAL_SCREEN_HEIGHT_PAL];
 };
 
 #endif // __MAINWIN_H__
index 72802f518ce117b6895c2e9db4e2c0ff364083d3..e1b95aa4dbdedbf13daef539bd3d4c07cab46fd8 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "jaguar.h"
 
+#include <time.h>
 #include <SDL.h>
 #include "SDL_opengl.h"
 #include "blitter.h"
@@ -1758,12 +1759,19 @@ void JaguarSetScreenPitch(uint32_t pitch)
 //
 void JaguarInit(void)
 {
+       // For randomizing RAM
+       srand(time(NULL));
+
+       // Contents of local RAM are quasi-stable; we simulate this by randomizing RAM contents
+       for(uint32_t i=0; i<0x200000; i+=4)
+               *((uint32_t *)(&jaguarMainRAM[i])) = rand();
+
 #ifdef CPU_DEBUG_MEMORY
        memset(readMem, 0x00, 0x400000);
        memset(writeMemMin, 0xFF, 0x400000);
        memset(writeMemMax, 0x00, 0x400000);
 #endif
-       memset(jaguarMainRAM, 0x00, 0x200000);
+//     memset(jaguarMainRAM, 0x00, 0x200000);
 //     memset(jaguar_mainRom, 0xFF, 0x200000); // & set it to all Fs...
 //     memset(jaguar_mainRom, 0x00, 0x200000); // & set it to all 0s...
 //NOTE: This *doesn't* fix FlipOut...
@@ -1784,11 +1792,16 @@ memset(jaguarMainRAM + 0x804, 0xFF, 4);
        CDROMInit();
 }
 
+
 //New timer based code stuffola...
 void HalflineCallback(void);
 void RenderCallback(void);
 void JaguarReset(void)
 {
+       // Contents of local RAM are quasi-stable; we simulate this by randomizing RAM contents
+       for(uint32_t i=0; i<0x200000; i+=4)
+               *((uint32_t *)(&jaguarMainRAM[i])) = rand();
+
        // New timer base code stuffola...
        InitializeEventList();
 //Need to change this so it uses the single RAM space and load the BIOS
@@ -1816,6 +1829,7 @@ void JaguarReset(void)
        SetCallbackTime(HalflineCallback, (vjs.hardwareTypeNTSC ? 31.777777777 : 32.0));
 }
 
+
 void JaguarDone(void)
 {
 #ifdef CPU_DEBUG_MEMORY