]> Shamusworld >> Repos - virtualjaguar/commitdiff
Video rendering now has correct timing per frame, in both NTSC and PAL mode.
authorShamus Hammons <jlhamm@acm.org>
Thu, 17 Nov 2011 16:30:31 +0000 (16:30 +0000)
committerShamus Hammons <jlhamm@acm.org>
Thu, 17 Nov 2011 16:30:31 +0000 (16:30 +0000)
src/event.h
src/gui/mainwin.cpp
src/gui/mainwin.h
src/jaguar.cpp
src/tom.cpp

index 35f84468240984c090f50ea230e2dea3878a3267..9014dfb4e3f6f72df8e0395fea0841292c4d96ef 100644 (file)
@@ -9,11 +9,11 @@
 
 #include "types.h"
 
-// Note that these are NTSC timings:
+#define RISC_CYCLE_IN_USEC        0.03760684198
+#define M68K_CYCLE_IN_USEC        (RISC_CYCLE_IN_USEC * 2)
 
-#define RISC_CYCLE_IN_USEC     0.03760684198
-#define M68K_CYCLE_IN_USEC     (RISC_CYCLE_IN_USEC * 2)
-#define HORIZ_PERIOD_IN_USEC   63.5555
+#define HORIZ_PERIOD_IN_USEC_NTSC 63.555555555
+#define HORIZ_PERIOD_IN_USEC_PAL  64.0
 
 #define USEC_TO_RISC_CYCLES(u) (uint32)(((u) / RISC_CYCLE_IN_USEC) + 0.5)
 #define USEC_TO_M68K_CYCLES(u) (uint32)(((u) / M68K_CYCLE_IN_USEC) + 0.5)
index 7abc8c75509405412af2f2e2f8b606c159aeee30..af1dab100837dae93376b6338a0c671ccb288e2a 100644 (file)
@@ -185,6 +185,10 @@ MainWin::MainWin(): running(true), powerButtonOn(false), showUntunedTankCircuit(
        useCDAct->setCheckable(true);
        connect(useCDAct, SIGNAL(triggered()), this, SLOT(ToggleCDUsage()));
 
+       frameAdvanceAct = new QAction(QIcon(":/res/generic.png"), tr("&Frame Advance"), this);
+       frameAdvanceAct->setShortcut(QKeySequence(tr("F7")));
+       connect(frameAdvanceAct, SIGNAL(triggered()), this, SLOT(FrameAdvance()));
+
        // Misc. connections...
        connect(filePickWin, SIGNAL(RequestLoad(QString)), this, SLOT(LoadSoftware(QString)));
        connect(filePickWin, SIGNAL(FilePickerHiding()), this, SLOT(Unpause()));
@@ -194,6 +198,7 @@ MainWin::MainWin(): running(true), powerButtonOn(false), showUntunedTankCircuit(
        fileMenu = menuBar()->addMenu(tr("&Jaguar"));
        fileMenu->addAction(powerAct);
        fileMenu->addAction(pauseAct);
+       fileMenu->addAction(frameAdvanceAct);
        fileMenu->addAction(filePickAct);
        fileMenu->addAction(useCDAct);
        fileMenu->addAction(configAct);
@@ -640,6 +645,14 @@ void MainWin::ToggleCDUsage(void)
 #endif
 }
 
+void MainWin::FrameAdvance(void)
+{
+//printf("Frame Advance...\n");
+       // Execute 1 frame, then exit (only useful in Pause mode)
+       JaguarExecuteNew();
+       videoWidget->updateGL();
+}
+
 void MainWin::ResizeMainWindow(void)
 {
        videoWidget->setFixedSize(zoomLevel * 320, zoomLevel * (vjs.hardwareTypeNTSC ? 240 : 256));
index c69c4780d2c14178f5f0d32926bed96060bcfa9a..30d9eb2b3183a01ebdb7d7a6cb66be94c8a2933c 100644 (file)
@@ -48,6 +48,7 @@ class MainWin: public QMainWindow
                void Unpause(void);
                void LoadSoftware(QString);
                void ToggleCDUsage(void);
+               void FrameAdvance(void);
 
        private:
                void HandleKeys(QKeyEvent *, bool);
@@ -92,6 +93,7 @@ class MainWin: public QMainWindow
                QAction * filePickAct;
                QAction * configAct;
                QAction * useCDAct;
+               QAction * frameAdvanceAct;
                
                QIcon powerGreen;
                QIcon powerRed;
index 75ece207b3049f11eca14c83261fb4a0ca715f4c..0cd84112cace49ef9b8aba93d3df11951e05278a 100644 (file)
@@ -1814,8 +1814,8 @@ void JaguarDone(void)
        JaguarDasm(0x802000, 6000);
        WriteLog("\n");//*/
 #endif
-/*     WriteLog("\n\nM68000 disassembly at $802000...\n");
-       JaguarDasm(0x802000, 10000);
+/*     WriteLog("\n\nM68000 disassembly at $4000...\n");
+       JaguarDasm(0x4000, 10000);
        WriteLog("\n");//*/
 }
 
@@ -1843,6 +1843,8 @@ void JaguarExecute(uint32 * backbuffer, bool render)
 //seem to indicate the refresh rate is *half* the above...
 //     uint16 refreshRate = (vjs.hardwareTypeNTSC ? 30 : 25);
        // Should these be hardwired or read from VP? Yes, from VP!
+       // Err, actually, they should be hardwired, and hardwired to a set # of
+       // lines as well...
        uint32 M68KCyclesPerScanline = m68kClockRate / (vp * refreshRate);
        uint32 RISCCyclesPerScanline = m68kClockRate / (vp * refreshRate);
 
@@ -1951,15 +1953,68 @@ void JaguarExecuteNew(void)
        while (!frameDone);
 }
 
+/*
+BIG NOTE: NEED TO FIX THIS TO RUN ON ABSOLUTE TIMINGS BASED ON SCANLINES,
+          *NOT* ON THE VERTICAL PERIOD!!!
+
+<Zerosquare> scanlines are 64 µs in PAL
+<Zerosquare> and 63.5555... µs in NTSC
+
+Also: 625 lines per frame in PAL, 525 in NTSC
+
+So... can use
+#define RISC_CYCLE_IN_USEC        0.03760684198
+#define M68K_CYCLE_IN_USEC        (RISC_CYCLE_IN_USEC * 2)
+
+#define HORIZ_PERIOD_IN_USEC_NTSC 63.555555555
+#define HORIZ_PERIOD_IN_USEC_PAL  64.0
+
+#define USEC_TO_RISC_CYCLES(u) (uint32)(((u) / RISC_CYCLE_IN_USEC) + 0.5)
+#define USEC_TO_M68K_CYCLES(u) (uint32)(((u) / M68K_CYCLE_IN_USEC) + 0.5)
+
+to figure cycles per half-line...
+
+USEC_TO_RISC_CYCLES(HORIZ_PERIOD_IN_USEC_NTSC) / 2
+USEC_TO_M68K_CYCLES(HORIZ_PERIOD_IN_USEC_NTSC) / 2
+USEC_TO_RISC_CYCLES(HORIZ_PERIOD_IN_USEC_PAL) / 2
+USEC_TO_M68K_CYCLES(HORIZ_PERIOD_IN_USEC_PAL) / 2
+
+// Full lines here, divide by two for half-lines...
+which gives the following: 1690, 845 (NTSC), 1702, 851 (PAL)
+So, for a full frame, that would yield:
+887250 (NTSC), 1063750 (PAL)
+one second:
+26617500 (NTSC), 26593750 (PAL)
+
+Which is off a little bit for NTSC...
+#define M68K_CLOCK_RATE_PAL            13296950
+#define M68K_CLOCK_RATE_NTSC   13295453
+#define RISC_CLOCK_RATE_PAL            26593900
+#define RISC_CLOCK_RATE_NTSC   26590906
+
+*/
+
+#define USE_CORRECT_PAL_TIMINGS
 void ScanlineCallback(void)
 {
+//OK, this is hardwired to run in NTSC, and for who knows how long.
+//Need to fix this so that it does a half-line in the correct amount of time
+//and number of lines, depending on which mode we're in. [FIXED]
        uint16 vc = TOMReadWord(0xF00006, JAGUAR);
        uint16 vp = TOMReadWord(0xF0003E, JAGUAR) + 1;
        uint16 vi = TOMReadWord(0xF0004E, JAGUAR);
 //     uint16 vbb = TOMReadWord(0xF00040, JAGUAR);
        vc++;
 
+#ifdef USE_CORRECT_PAL_TIMINGS
+       // Each # of lines is for a full frame == 1/30s (NTSC), 1/25s (PAL).
+       // So we cut the number of half-lines in a frame in half. :-P
+       uint16 numHalfLines = ((vjs.hardwareTypeNTSC ? 525 : 625) * 2) / 2;
+
+       if (vc >= numHalfLines)
+#else
        if (vc >= vp)
+#endif
                vc = 0;
 
 //WriteLog("SLC: Currently on line %u (VP=%u)...\n", vc, vp);
@@ -1986,8 +2041,12 @@ void ScanlineCallback(void)
                frameDone = true;
        }//*/
 
+#ifdef USE_CORRECT_PAL_TIMINGS
+       SetCallbackTime(ScanlineCallback, (vjs.hardwareTypeNTSC ? 31.777777777 : 32.0));
+#else
 //     SetCallbackTime(ScanlineCallback, 63.5555);
        SetCallbackTime(ScanlineCallback, 31.77775);
+#endif
 }
 
 // This isn't currently used, but maybe it should be...
index 08832a8ce3ccb3b3ed9c304c26cd5ca3e54df7a9..82062bd1a7517baba30c081d2236687375f2af5c 100644 (file)
@@ -780,10 +780,18 @@ void TOMExecScanline(uint16 scanline, bool render)
 // to do a scanline render in the non-display area... [DONE]
 //this seems to cause a regression in certain games, like rayman
 //which means I have to dig thru the asic nets to see what's wrong...
+/*
+No, the OP doesn't start until VDB, that much is certain. The thing is, VDB is the
+HALF line that the OP starts on--which means that it needs to start at VDB / 2!!!
+
+Hrm, doesn't seem to be enough, though it should be... still sticks for 20 frames.
+*/
 #if 1
 // 16 isn't enough, and neither is 32 for raptgun. 32 fucks up Rayman
+//     if (scanline >= ((uint16)GET16(tomRam8, VDB) / 2) && scanline < ((uint16)GET16(tomRam8, VDE) / 2))
        if (scanline >= (uint16)GET16(tomRam8, VDB) && scanline < (uint16)GET16(tomRam8, VDE))
-//     if (scanline >= ((uint16)GET16(tomRam8, VDB) - 32) && scanline < (uint16)GET16(tomRam8, VDE))
+//     if (scanline >= ((uint16)GET16(tomRam8, VDB) - 16) && scanline < (uint16)GET16(tomRam8, VDE))
+//     if (scanline >= 20 && scanline < (uint16)GET16(tomRam8, VDE))
        {
                if (render)
                {