]> Shamusworld >> Repos - virtualjaguar/commitdiff
Minor tweaks to Makefiles, added command line switches for most options.
authorShamus Hammons <jlhamm@acm.org>
Thu, 24 May 2012 19:08:14 +0000 (19:08 +0000)
committerShamus Hammons <jlhamm@acm.org>
Thu, 24 May 2012 19:08:14 +0000 (19:08 +0000)
17 files changed:
Makefile
jaguarcore.mak
res/help.html
src/dac.cpp
src/dac.h
src/dsp.cpp
src/file.cpp
src/file.h
src/gui/app.cpp
src/gui/filepicker.cpp
src/gui/filethread.cpp
src/gui/mainwin.cpp
src/gui/mainwin.h
src/jaguar.cpp
src/log.cpp
src/m68000/Makefile
src/virtualjaguar.cpp

index 03de51b29060be8e895b29bb94b3bb1f718f9ab0..4dfadf4b2321e3e8e3f7f7782a71e8bddd747d1c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,20 @@ ifeq "$(findstring Darwin,$(OSTYPE))" "Darwin"
 QMAKE_EXTRA := -spec macx-g++
 endif
 
+# Eh?
+CFLAGS ?= ""
+CPPFLAGS ?= ""
+CXXFLAGS ?= ""
+LDFLAGS ?= ""
+
+QMAKE_EXTRA += "QMAKE_CFLAGS_RELEASE=$(CFLAGS)"
+QMAKE_EXTRA += "QMAKE_CXXFLAGS_RELEASE=$(CXXFLAGS)"
+QMAKE_EXTRA += "QMAKE_LFLAGS_RELEASE=$(LDFLAGS)"
+
+QMAKE_EXTRA += "QMAKE_CFLAGS_DEBUG=$(CFLAGS)"
+QMAKE_EXTRA += "QMAKE_CXXFLAGS_DEBUG=$(CXXFLAGS)"
+QMAKE_EXTRA += "QMAKE_LFLAGS_DEBUG=$(LDFLAGS)"
+
 
 all: prepare virtualjaguar
        @echo -e "\033[01;33m***\033[00;32m Success!\033[00m"
@@ -26,10 +40,10 @@ obj:
 
 prepare: obj
        @echo -e "\033[01;33m***\033[00;32m Preparing to compile Virtual Jaguar...\033[00m"
-#      @echo "#define VJ_RELEASE_VERSION \"v2.0.3\"" > src/version.h
+#      @echo "#define VJ_RELEASE_VERSION \"v2.1.0\"" > src/version.h
 #      @echo "#define VJ_RELEASE_SUBVERSION \"Final\"" >> src/version.h
        @echo "#define VJ_RELEASE_VERSION \"SVN `svn info | grep -i revision`\"" > src/version.h
-       @echo "#define VJ_RELEASE_SUBVERSION \"2.0.3 Prerelease\"" >> src/version.h
+       @echo "#define VJ_RELEASE_SUBVERSION \"2.1.0 Prerelease\"" >> src/version.h
 
 virtualjaguar: sources libs makefile-qt
        @echo -e "\033[01;33m***\033[00;32m Making Virtual Jaguar GUI...\033[00m"
@@ -45,7 +59,8 @@ libs: obj/libm68k.a obj/libjaguarcore.a
 
 obj/libm68k.a: src/m68000/Makefile sources
        @echo -e "\033[01;33m***\033[00;32m Making Customized UAE 68K Core...\033[00m"
-       @$(MAKE) -C src/m68000
+#      @$(MAKE) -C src/m68000
+       @$(MAKE) -C src/m68000 CFLAGS="$(CFLAGS)"
        @cp src/m68000/obj/libm68k.a obj/
 
 obj/libmusashi.a: musashi.mak sources
@@ -54,7 +69,8 @@ obj/libmusashi.a: musashi.mak sources
 
 obj/libjaguarcore.a: jaguarcore.mak sources
        @echo -e "\033[01;33m***\033[00;32m Making Virtual Jaguar core...\033[00m"
-       $(MAKE) -f jaguarcore.mak
+#      $(MAKE) -f jaguarcore.mak
+       $(MAKE) -f jaguarcore.mak CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)"
 
 sources: src/*.h src/*.cpp src/*.c src/m68000/*.c src/m68000/*.h
 
index 16e0b1edaa8baf9494017db42095f30faae5966f..1bcafe0e1baec2b0737fcc46d5a3839dc852a263 100644 (file)
 
 OSTYPE := $(shell uname -a)
 
-ifeq "$(findstring Msys,$(OSTYPE))" "Msys"                     # Win32
+# Win32
+ifeq "$(findstring Msys,$(OSTYPE))" "Msys"
 
 SYSTYPE    := __GCCWIN32__
 SDLLIBTYPE := --libs
 
-else ifeq "$(findstring Darwin,$(OSTYPE))" "Darwin"    # Should catch both 'darwin' and 'darwin7.0'
+# Apple. Should catch both 'darwin' and 'darwin7.0'
+else ifeq "$(findstring Darwin,$(OSTYPE))" "Darwin"
 
 SYSTYPE    := __GCCUNIX__ -D__THINK_STUPID__
 SDLLIBTYPE := --static-libs
 
-else ifeq "$(findstring Linux,$(OSTYPE))" "Linux"              # Linux
+# Linux
+else ifeq "$(findstring Linux,$(OSTYPE))" "Linux"
 
 SYSTYPE    := __GCCUNIX__
 SDLLIBTYPE := --libs
 
-else                                                                                   # ???
+# ??? Throw error, unknown OS
+else
 
 $(error OS TYPE UNDETECTED)
 
@@ -41,14 +45,20 @@ HAVECDIO :=
 CDIOLIB  :=
 endif
 
-CC      := gcc
-LD      := gcc
-AR      := ar
-ARFLAGS := -rs
+CC       := gcc
+LD       := gcc
+AR       := ar
+ARFLAGS  := -rs
 
 # Note that we use optimization level 2 instead of 3--3 doesn't seem to gain much over 2
-CFLAGS  := -MMD -O2 -ffast-math -fomit-frame-pointer `sdl-config --cflags` -D$(SYSTYPE)
-CXXFLAGS  := -MMD -O2 -ffast-math -fomit-frame-pointer `sdl-config --cflags` -D$(SYSTYPE)
+#CFLAGS  := -MMD -O2 -ffast-math -fomit-frame-pointer `sdl-config --cflags` -D$(SYSTYPE)
+#CXXFLAGS  := -MMD -O2 -ffast-math -fomit-frame-pointer `sdl-config --cflags` -D$(SYSTYPE)
+CFLAGS ?= -O2 -ffast-math -fomit-frame-pointer
+CXXFLAGS ?= -O2 -ffast-math -fomit-frame-pointer
+
+SDL_CFLAGS = `sdl-config --cflags`
+DEFINES = -D$(SYSTYPE)
+GCC_DEPS = "-MMD"
 
 INCS := -I./src
 
@@ -101,10 +111,12 @@ obj/libjaguarcore.a: $(OBJS)
 
 obj/%.o: src/%.c
        @echo -e "\033[01;33m***\033[00;32m Compiling $<...\033[00m"
-       @$(CC) $(CFLAGS) $(INCS) -c $< -o $@
+#      @$(CC) $(CFLAGS) $(INCS) -c $< -o $@
+       @$(CC) $(GCC_DEPS) $(CFLAGS) $(SDL_CFLAGS) $(DEFINES) $(INCS) -c $< -o $@
 
 obj/%.o: src/%.cpp
        @echo -e "\033[01;33m***\033[00;32m Compiling $<...\033[00m"
-       @$(CC) $(CXXFLAGS) $(INCS) -c $< -o $@
+#      @$(CC) $(CXXFLAGS) $(INCS) -c $< -o $@
+       @$(CC) $(GCC_DEPS) $(CXXFLAGS) $(SDL_CFLAGS) $(DEFINES) $(INCS) -c $< -o $@
 
 -include obj/*.d
index 7a6fc00c45e221d53500f40751e17d3de3bbe9b6..86daf516aeaf2b29b71f2bb4b64b00d50f17cbc8 100644 (file)
 
 <p>Trademarks used in <i>Virtual Jaguar</i> and/or this documentation are the property of their respective owners. The user(s) of <i>Virtual Jaguar</i> assumes all risk associated with using the software; the authors are not responsible for anything the user(s) does with said software or what happens to the user(s) as a result of using this software.</p>
 
-<p><i>Virtual Jaguar</i> is Free (as in Libre) software and is licensed under the GPL version 3. You should have recieved a copy of the license with this software; if you did not, you may view a copy at <a href="http://www.gnu.org/licenses">http://www.gnu.org/licenses</a>. A copy of the source code is available at <a href="http://icculus.org/virtualjaguar">http://icculus.org/virtualjaguar</a>.</p>
+<p><i>Virtual Jaguar</i> is Free (as in Libre) software and is licensed under the GPL version 3. You should have received a copy of the license with this software; if you did not, you may view a copy at <a href="http://www.gnu.org/licenses">http://www.gnu.org/licenses</a>. A copy of the source code is available at <a href="http://icculus.org/virtualjaguar">http://icculus.org/virtualjaguar</a>.</p>
 
 <p><i>Downfall</i> is &copy; 2011 <b>Reboot</b>, All Rights Reserved. Distribution of <i>Downfall</i> with <i>Virtual Jaguar</i> has been graciously authorized by <b>Reboot</b>, and may not be distributed as part of any other package.</p>
 
index be6c3aed9e314853a679c13ba1ddc6720fcf2047..d005518eb8870ea6d5e5060fd273d712a5c2f67b 100644 (file)
@@ -11,6 +11,7 @@
 // Who  When        What
 // ---  ----------  -------------------------------------------------------------
 // JLH  01/16/2010  Created this log ;-)
+// JLH  04/30/2012  Changed SDL audio handler to run JERRY
 //
 
 // Need to set up defaults that the BIOS sets for the SSI here in DACInit()... !!! FIX !!!
 //       that is the current spinlock implementation. Since the DSP is a separate
 //       entity, could we get away with running it in the sound IRQ?
 
-// ALSO: It may be a good idea to physically separate the left and right buffers
-//       to prevent things like the DSP filling only one side and such. Do such
-//       mono modes exist on the Jag? Seems to according to Super Burnout.
-
 // After testing on a real Jaguar, it seems clear that the I2S interrupt drives
 // the audio subsystem. So while you can drive the audio at a *slower* rate than
 // set by SCLK, you can't drive it any *faster*. Also note, that if the I2S
 
 // Global variables
 
+// These are defined in memory.h/cpp
 //uint16 lrxd, rrxd;                                                   // I2S ports (into Jaguar)
 
 // Local variables
 
-static uint32 LeftFIFOHeadPtr, LeftFIFOTailPtr, RightFIFOHeadPtr, RightFIFOTailPtr;
 static SDL_AudioSpec desired;
 static bool SDLSoundInitialized;
-
-// We can get away with using native endian here because we can tell SDL to use the native
-// endian when looking at the sample buffer, i.e., no need to worry about it.
-
-static uint16 DACBuffer[BUFFER_SIZE];
 static uint8 SCLKFrequencyDivider = 19;                        // Default is roughly 22 KHz (20774 Hz in NTSC mode)
 /*static*/ uint16 serialMode = 0;
 
 // Private function prototypes
 
 void SDLSoundCallback(void * userdata, Uint8 * buffer, int length);
-void SDLSoundCallbackNew(void * userdata, Uint8 * buffer, int length);
 void DSPSampleCallback(void);
 
 
@@ -112,31 +103,19 @@ void DACInit(void)
                return;
        }
 
-#ifdef NEW_DAC_CODE
        desired.freq = DAC_AUDIO_RATE;
        desired.format = AUDIO_S16SYS;
        desired.channels = 2;
-       desired.samples = 2048;
-       desired.callback = SDLSoundCallbackNew;
-#else
-//     memory_malloc_secure((void **)&DACBuffer, BUFFER_SIZE * sizeof(uint16), "DAC buffer");
-//     DACBuffer = (uint16 *)memory_malloc(BUFFER_SIZE * sizeof(uint16), "DAC buffer");
-
-       desired.freq = GetCalculatedFrequency();                // SDL will do conversion on the fly, if it can't get the exact rate. Nice!
-       desired.format = AUDIO_S16SYS;                                  // This uses the native endian (for portability)...
-       desired.channels = 2;
-//     desired.samples = 4096;                                                 // Let's try a 4K buffer (can always go lower)
-       desired.samples = 2048;                                                 // Let's try a 2K buffer (can always go lower)
+       desired.samples = 2048;                                         // 2K buffer = audio delay of 42.67 ms (@ 48 KHz)
        desired.callback = SDLSoundCallback;
-#endif
 
-       if (SDL_OpenAudio(&desired, NULL) < 0)                  // NULL means SDL guarantees what we want
+       if (SDL_OpenAudio(&desired, NULL) < 0)          // NULL means SDL guarantees what we want
                WriteLog("DAC: Failed to initialize SDL sound...\n");
        else
        {
                SDLSoundInitialized = true;
                DACReset();
-               SDL_PauseAudio(false);                                          // Start playback!
+               SDL_PauseAudio(false);                                  // Start playback!
                WriteLog("DAC: Successfully initialized. Sample rate: %u\n", desired.freq);
        }
 
@@ -153,7 +132,7 @@ void DACInit(void)
 //
 void DACReset(void)
 {
-       LeftFIFOHeadPtr = LeftFIFOTailPtr = 0, RightFIFOHeadPtr = RightFIFOTailPtr = 1;
+//     LeftFIFOHeadPtr = LeftFIFOTailPtr = 0, RightFIFOHeadPtr = RightFIFOTailPtr = 1;
        ltxd = lrxd = desired.silence;
 }
 
@@ -169,7 +148,6 @@ void DACDone(void)
                SDL_CloseAudio();
        }
 
-//     memory_free(DACBuffer);
        WriteLog("DAC: Done.\n");
 }
 
@@ -189,12 +167,11 @@ void DACDone(void)
 // Note: The samples are packed in the buffer in 16 bit left/16 bit right pairs.
 //       Also, length is the length of the buffer in BYTES
 //
-//static double timePerSample = 0;
 static Uint8 * sampleBuffer;
 static int bufferIndex = 0;
 static int numberOfSamples = 0;
 static bool bufferDone = false;
-void SDLSoundCallbackNew(void * userdata, Uint8 * buffer, int length)
+void SDLSoundCallback(void * userdata, Uint8 * buffer, int length)
 {
        // 1st, check to see if the DSP is running. If not, fill the buffer with L/RXTD and exit.
 
@@ -218,29 +195,6 @@ void SDLSoundCallbackNew(void * userdata, Uint8 * buffer, int length)
 
        // Now, run the DSP for that length of time for each sample we need to make
 
-#if 0
-       for(int i=0; i<(length/2); i+=2)
-       {
-//This stuff is from the old Jaguar execute loop. New stuff is timer based...
-//which means we need to figure that crap out, and how to make it work here.
-//Seems like we need two separate timing queues. Tho not sure how to make that work here...
-//Maybe like the "frameDone" in JaguarExecuteNew() in jaguar.cpp?
-//             JERRYExecPIT(cyclesPerSample);
-//             JERRYI2SExec(cyclesPerSample);
-//             BUTCHExec(cyclesPerSample);
-
-               if (vjs.DSPEnabled)
-               {
-                       if (vjs.usePipelinedDSP)
-                               DSPExecP2(cyclesPerSample);
-                       else
-                               DSPExec(cyclesPerSample);
-               }
-
-               ((uint16_t *)buffer)[i + 0] = ltxd;
-               ((uint16_t *)buffer)[i + 1] = rtxd;
-       }
-#else
        bufferIndex = 0;
        sampleBuffer = buffer;
        numberOfSamples = length / 2;
@@ -264,10 +218,6 @@ void SDLSoundCallbackNew(void * userdata, Uint8 * buffer, int length)
                HandleNextEvent(EVENT_JERRY);
        }
        while (!bufferDone);
-
-       // We do this to prevent problems with trying to write past the end of the buffer...
-//     RemoveCallback(DSPSampleCallback);
-#endif
 }
 
 
@@ -285,98 +235,9 @@ void DSPSampleCallback(void)
 
        SetCallbackTime(DSPSampleCallback, 1000000.0 / (double)DAC_AUDIO_RATE, EVENT_JERRY);
 }
-#if 0
-       frameDone = false;
-
-       do
-       {
-               double timeToNextEvent = GetTimeToNextEvent();
-//WriteLog("JEN: Time to next event (%u) is %f usec (%u RISC cycles)...\n", nextEvent, timeToNextEvent, USEC_TO_RISC_CYCLES(timeToNextEvent));
-
-               m68k_execute(USEC_TO_M68K_CYCLES(timeToNextEvent));
-
-               if (vjs.GPUEnabled)
-                       GPUExec(USEC_TO_RISC_CYCLES(timeToNextEvent));
-
-#ifndef NEW_DAC_CODE
-               if (vjs.DSPEnabled)
-               {
-                       if (vjs.usePipelinedDSP)
-                               DSPExecP2(USEC_TO_RISC_CYCLES(timeToNextEvent));        // Pipelined DSP execution (3 stage)...
-                       else
-                               DSPExec(USEC_TO_RISC_CYCLES(timeToNextEvent));          // Ordinary non-pipelined DSP
-               }
-#endif
-
-               HandleNextEvent();
-       }
-       while (!frameDone);
-#endif
-
-
-//
-// SDL callback routine to fill audio buffer
-//
-// Note: The samples are packed in the buffer in 16 bit left/16 bit right pairs.
-//       Also, length is the length of the buffer in BYTES
-//
-void SDLSoundCallback(void * userdata, Uint8 * buffer, int length)
-{
-       // Clear the buffer to silence, in case the DAC buffer is empty (or short)
-//This causes choppy sound... Ick.
-       memset(buffer, desired.silence, length);
-//WriteLog("DAC: Inside callback...\n");
-       if (LeftFIFOHeadPtr != LeftFIFOTailPtr)
-       {
-//WriteLog("DAC: About to write some data!\n");
-               int numLeftSamplesReady
-                       = (LeftFIFOTailPtr + (LeftFIFOTailPtr < LeftFIFOHeadPtr ? BUFFER_SIZE : 0))
-                               - LeftFIFOHeadPtr;
-               int numRightSamplesReady
-                       = (RightFIFOTailPtr + (RightFIFOTailPtr < RightFIFOHeadPtr ? BUFFER_SIZE : 0))
-                               - RightFIFOHeadPtr;
-//This waits for the slower side to catch up. If writing only one side, then this
-//causes the buffer not to drain...
-               int numSamplesReady
-                       = (numLeftSamplesReady < numRightSamplesReady
-                               ? numLeftSamplesReady : numRightSamplesReady);//Hmm. * 2;
-
-//Kludge, until I can figure out WTF is going on WRT Super Burnout.
-if (numLeftSamplesReady == 0 || numRightSamplesReady == 0)
-       numSamplesReady = numLeftSamplesReady + numRightSamplesReady;
-
-//The numbers look good--it's just that the DSP can't get enough samples in the DAC buffer!
-//WriteLog("DAC: Left/RightFIFOHeadPtr: %u/%u, Left/RightFIFOTailPtr: %u/%u\n", LeftFIFOHeadPtr, RightFIFOHeadPtr, LeftFIFOTailPtr, RightFIFOTailPtr);
-//WriteLog("     numLeft/RightSamplesReady: %i/%i, numSamplesReady: %i, length of buffer: %i\n", numLeftSamplesReady, numRightSamplesReady, numSamplesReady, length);
-
-/*             if (numSamplesReady > length)
-                       numSamplesReady = length;//*/
-               if (numSamplesReady > length / 2)       // length / 2 because we're comparing 16-bit lengths
-                       numSamplesReady = length / 2;
-//else
-//     WriteLog("     Not enough samples to fill the buffer (short by %u L/R samples)...\n", (length / 2) - numSamplesReady);
-//WriteLog("DAC: %u samples ready.\n", numSamplesReady);
-
-               // Actually, it's a bit more involved than this, but this is the general idea:
-//             memcpy(buffer, DACBuffer, length);
-               for(int i=0; i<numSamplesReady; i++)
-                       ((uint16 *)buffer)[i] = DACBuffer[(LeftFIFOHeadPtr + i) % BUFFER_SIZE];
-                       // Could also use (as long as BUFFER_SIZE is a multiple of 2):
-//                     buffer[i] = DACBuffer[(LeftFIFOHeadPtr + i) & (BUFFER_SIZE - 1)];
-
-               LeftFIFOHeadPtr = (LeftFIFOHeadPtr + numSamplesReady) % BUFFER_SIZE;
-               RightFIFOHeadPtr = (RightFIFOHeadPtr + numSamplesReady) % BUFFER_SIZE;
-               // Could also use (as long as BUFFER_SIZE is a multiple of 2):
-//             LeftFIFOHeadPtr = (LeftFIFOHeadPtr + numSamplesReady) & (BUFFER_SIZE - 1);
-//             RightFIFOHeadPtr = (RightFIFOHeadPtr + numSamplesReady) & (BUFFER_SIZE - 1);
-//WriteLog("  -> Left/RightFIFOHeadPtr: %04X/%04X, Left/RightFIFOTailPtr: %04X/%04X\n", LeftFIFOHeadPtr, RightFIFOHeadPtr, LeftFIFOTailPtr, RightFIFOTailPtr);
-       }
-//Hmm. Seems that the SDL buffer isn't being starved by the DAC buffer...
-//     else
-//             WriteLog("DAC: Silence...!\n");
-}
 
 
+#if 0
 //
 // Calculate the frequency of SCLK * 32 using the divider
 //
@@ -388,48 +249,7 @@ int GetCalculatedFrequency(void)
        // 16 bits of left data + 16 bits of right data = 32 bits, 1 SCLK = 1 bit transferred).
        return systemClockFrequency / (32 * (2 * (SCLKFrequencyDivider + 1)));
 }
-
-
-static int oldFreq = 0;
-
-void DACSetNewFrequency(int freq)
-{
-#ifdef NEW_DAC_CODE
-#else
-       if (freq == oldFreq)
-               return;
-
-       oldFreq = freq;
-
-       // Should do some sanity checking on the frequency...
-
-       if (SDLSoundInitialized)
-               SDL_CloseAudio();
-
-       desired.freq = freq;// SDL will do conversion on the fly, if it can't get the exact rate. Nice!
-       WriteLog("DAC: Changing sample rate to %u Hz!\n", desired.freq);
-
-       if (SDLSoundInitialized)
-       {
-               if (SDL_OpenAudio(&desired, NULL) < 0)  // NULL means SDL guarantees what we want
-               {
-// This is bad, Bad, BAD !!! DON'T ABORT BECAUSE WE DIDN'T GET OUR FREQ! !!! FIX !!!
-#warning !!! FIX !!! Aborting because of SDL audio problem is bad!
-                       WriteLog("DAC: Failed to initialize SDL sound: %s.\nDesired freq: %u\nShutting down!\n", SDL_GetError(), desired.freq);
-//                                             LogDone();
-//                                             exit(1);
-#warning "Reimplement GUICrashGracefully!"
-//                                             GUICrashGracefully("Failed to initialize SDL sound!");
-                       return;
-               }
-       }
-
-       DACReset();
-
-       if (SDLSoundInitialized)
-               SDL_PauseAudio(false);                  // Start playback!
 #endif
-}
 
 
 //
@@ -447,188 +267,18 @@ void DACWriteWord(uint32 offset, uint16 data, uint32 who/*= UNKNOWN*/)
 {
        if (offset == LTXD + 2)
        {
-               if (!SDLSoundInitialized)
-                       return;
-
-#ifdef NEW_DAC_CODE
                ltxd = data;
-#else
-               // Spin until buffer has been drained (for too fast processors!)...
-//Small problem--if Head == 0 and Tail == buffer end, then this will fail... !!! FIX !!!
-//[DONE]
-               // Also, we're taking advantage of the fact that the buffer is a multiple of two
-               // in this check...
-uint32 spin = 0;
-               while (((LeftFIFOTailPtr + 2) & (BUFFER_SIZE - 1)) == LeftFIFOHeadPtr)//;
-               {
-spin++;
-//if ((spin & 0x0FFFFFFF) == 0)
-//     WriteLog("Tail=%X, Head=%X, BUFFER_SIZE-1=%X\n", RightFIFOTailPtr, RightFIFOHeadPtr, BUFFER_SIZE - 1);
-
-if (spin == 0xFFFF0000)
-{
-uint32 ltail = LeftFIFOTailPtr, lhead = LeftFIFOHeadPtr;
-WriteLog("Tail=%X, Head=%X", ltail, lhead);
-
-       WriteLog("\nStuck in left DAC spinlock! Aborting!\n");
-       WriteLog("LTail=%X, LHead=%X, BUFFER_SIZE-1=%X\n", LeftFIFOTailPtr, LeftFIFOHeadPtr, BUFFER_SIZE - 1);
-       WriteLog("RTail=%X, RHead=%X, BUFFER_SIZE-1=%X\n", RightFIFOTailPtr, RightFIFOHeadPtr, BUFFER_SIZE - 1);
-       WriteLog("From while: Tail=%X, Head=%X", (LeftFIFOTailPtr + 2) & (BUFFER_SIZE - 1), LeftFIFOHeadPtr);
-//     LogDone();
-//     exit(0);
-#warning "Reimplement GUICrashGracefully!"
-//     GUICrashGracefully("Stuck in left DAC spinlock!");
-       return;
-}
-               }//*/
-
-               SDL_LockAudio();                                                        // Is it necessary to do this? Mebbe.
-               // We use a circular buffer 'cause it's easy. Note that the callback function
-               // takes care of dumping audio to the soundcard...! Also note that we're writing
-               // the samples in the buffer in an interleaved L/R format.
-               LeftFIFOTailPtr = (LeftFIFOTailPtr + 2) % BUFFER_SIZE;
-               DACBuffer[LeftFIFOTailPtr] = data;
-               SDL_UnlockAudio();
-#endif
        }
        else if (offset == RTXD + 2)
        {
-               if (!SDLSoundInitialized)
-                       return;
-/*
-Here's what's happening now:
-
-Stuck in right DAC spinlock!
-Aborting!
-
-Tail=681, Head=681, BUFFER_SIZE-1=FFFF
-From while: Tail=683, Head=681
-
-????? What the FUCK ?????
-
-& when I uncomment the lines below spin++; it *doesn't* lock here... WTF?????
-
-I think it was missing parentheses causing the fuckup... Seems to work now...
-
-Except for Super Burnout now...! Aarrrgggghhhhh!
-
-Tail=AC, Head=AE
-Stuck in left DAC spinlock! Aborting!
-Tail=AC, Head=AE, BUFFER_SIZE-1=FFFF
-From while: Tail=AE, Head=AE
-
-So it's *really* stuck here in the left FIFO. Figure out why!!!
-
-Prolly 'cause it doesn't set the sample rate right away--betcha it works with the BIOS...
-It gets farther, but then locks here (weird!):
-
-Tail=2564, Head=2566
-Stuck in left DAC spinlock! Aborting!
-Tail=2564, Head=2566, BUFFER_SIZE-1=FFFF
-From while: Tail=2566, Head=2566
-
-Weird--recompile with more WriteLog() entries and it *doesn't* lock...
-Yeah, because there was no DSP running. Duh!
-
-Tail=AC, Head=AE
-Stuck in left DAC spinlock! Aborting!
-LTail=AC, LHead=AE, BUFFER_SIZE-1=FFFF
-RTail=AF, RHead=AF, BUFFER_SIZE-1=FFFF
-From while: Tail=AE, Head=AE
-
-Odd: The right FIFO is empty, but the left FIFO is full!
-And this is what is causing the lockup--the DAC callback waits for the side with
-less samples ready and in this case it's the right channel (that never fills up)
-that it's waiting for...!
-
-Okay, with the kludge in place for the right channel not being filled, we select
-a track and then it locks here:
-
-Tail=60D8, Head=60DA
-Stuck in left DAC spinlock! Aborting!
-LTail=60D8, LHead=60D8, BUFFER_SIZE-1=FFFF
-RTail=DB, RHead=60D9, BUFFER_SIZE-1=FFFF
-From while: Tail=60DA, Head=60D8
-*/
-#ifdef NEW_DAC_CODE
                rtxd = data;
-#else
-#warning Spinlock problem--!!! FIX !!!
-#warning Odd: The right FIFO is empty, but the left FIFO is full!
-               // Spin until buffer has been drained (for too fast processors!)...
-uint32 spin = 0;
-               while (((RightFIFOTailPtr + 2) & (BUFFER_SIZE - 1)) == RightFIFOHeadPtr)//;
-               {
-spin++;
-//if ((spin & 0x0FFFFFFF) == 0)
-//     WriteLog("Tail=%X, Head=%X, BUFFER_SIZE-1=%X\n", RightFIFOTailPtr, RightFIFOHeadPtr, BUFFER_SIZE - 1);
-
-if (spin == 0xFFFF0000)
-{
-uint32 rtail = RightFIFOTailPtr, rhead = RightFIFOHeadPtr;
-WriteLog("Tail=%X, Head=%X", rtail, rhead);
-
-       WriteLog("\nStuck in right DAC spinlock! Aborting!\n");
-       WriteLog("LTail=%X, LHead=%X, BUFFER_SIZE-1=%X\n", LeftFIFOTailPtr, LeftFIFOHeadPtr, BUFFER_SIZE - 1);
-       WriteLog("RTail=%X, RHead=%X, BUFFER_SIZE-1=%X\n", RightFIFOTailPtr, RightFIFOHeadPtr, BUFFER_SIZE - 1);
-       WriteLog("From while: Tail=%X, Head=%X", (RightFIFOTailPtr + 2) & (BUFFER_SIZE - 1), RightFIFOHeadPtr);
-//     LogDone();
-//     exit(0);
-#warning "Reimplement GUICrashGracefully!"
-//     GUICrashGracefully("Stuck in right DAC spinlock!");
-       return;
-}
-               }//*/
-
-               SDL_LockAudio();
-               RightFIFOTailPtr = (RightFIFOTailPtr + 2) % BUFFER_SIZE;
-               DACBuffer[RightFIFOTailPtr] = data;
-               SDL_UnlockAudio();
-/*#ifdef DEBUG_DAC
-               else
-                       WriteLog("DAC: Ran into FIFO's right tail pointer!\n");
-#endif*/
-#endif
        }
        else if (offset == SCLK + 2)                                    // Sample rate
        {
                WriteLog("DAC: Writing %u to SCLK...\n", data);
+
                if ((uint8)data != SCLKFrequencyDivider)
-               {
                        SCLKFrequencyDivider = (uint8)data;
-#ifdef NEW_DAC_CODE
-#else
-//Of course a better way would be to query the hardware to find the upper limit...
-                       if (data > 7)   // Anything less than 8 is too high!
-                       {
-                               if (SDLSoundInitialized)
-                                       SDL_CloseAudio();
-
-                               desired.freq = GetCalculatedFrequency();// SDL will do conversion on the fly, if it can't get the exact rate. Nice!
-                               WriteLog("DAC: Changing sample rate to %u Hz!\n", desired.freq);
-
-                               if (SDLSoundInitialized)
-                               {
-                                       if (SDL_OpenAudio(&desired, NULL) < 0)  // NULL means SDL guarantees what we want
-                                       {
-// This is bad, Bad, BAD !!! DON'T ABORT BECAUSE WE DIDN'T GET OUR FREQ! !!! FIX !!!
-#warning !!! FIX !!! Aborting because of SDL audio problem is bad!
-                                               WriteLog("DAC: Failed to initialize SDL sound: %s.\nDesired freq: %u\nShutting down!\n", SDL_GetError(), desired.freq);
-//                                             LogDone();
-//                                             exit(1);
-#warning "Reimplement GUICrashGracefully!"
-//                                             GUICrashGracefully("Failed to initialize SDL sound!");
-                                               return;
-                                       }
-                               }
-
-                               DACReset();
-
-                               if (SDLSoundInitialized)
-                                       SDL_PauseAudio(false);                  // Start playback!
-                       }
-#endif
-               }
        }
        else if (offset == SMODE + 2)
        {
index ef30549a237436128fa1c4a15ea5c009d1249e98..d0c57202a47db98df3b1e06d3dc7efbf5c7ed21f 100644 (file)
--- a/src/dac.h
+++ b/src/dac.h
@@ -5,17 +5,12 @@
 #ifndef __DAC_H__
 #define __DAC_H__
 
-//this is here, because we have to compensate in more than just dac.cpp...
-#define NEW_DAC_CODE                                                   // New code paths!
-
-//#include "types.h"
 #include "memory.h"
 
 void DACInit(void);
 void DACReset(void);
 void DACDone(void);
-int GetCalculatedFrequency(void);
-void DACSetNewFrequency(int);
+//int GetCalculatedFrequency(void);
 
 // DAC memory access
 
@@ -24,8 +19,4 @@ void DACWriteWord(uint32 offset, uint16 data, uint32 who = UNKNOWN);
 uint8 DACReadByte(uint32 offset, uint32 who = UNKNOWN);
 uint16 DACReadWord(uint32 offset, uint32 who = UNKNOWN);
 
-// Global variables
-
-//extern uint16 lrxd, rrxd;                                                    // I2S ports (into Jaguar)
-
 #endif // __DAC_H__
index d321d47b27339f3acb825685296f4dba8d17c7bd..4704aa303ef2c65144eefdb1ac27bccee801886d 100644 (file)
@@ -814,6 +814,9 @@ SET32(ram2, offset, data);
 // IRQs on J_INT ($F10020), you don't have to run an I2S interrupt on the DSP. Also,
 // It seems that it's only stable for values of SCLK <= 9.
 
+// All of the preceeding is moot now; we run the DSP in the host audio IRQ. This means
+// that we don't actually need this stuff anymore. :-D
+#if 0
                        if (data & INT_ENA1) // I2S interrupt
                        {
                                int freq = GetCalculatedFrequency();
@@ -828,6 +831,7 @@ SET32(ram2, offset, data);
 //                             WriteLog("DSP: Setting audio freqency to %u Hz...\n", freq);
                                DACSetNewFrequency(freq);
                        }
+#endif
 
 /*                     if (IMASKCleared)                                               // If IMASK was cleared,
 #ifdef DSP_DEBUG_IRQ
index acf90d6f64bff6b61e106258b288b959d9822039..691f3a2a985c1f5d4f6360d32b7eeaba7feb9bdf 100644 (file)
@@ -125,7 +125,7 @@ bool JaguarLoadFile(char * path)
 //       directory, copy the one from the ZIP file, if it exists.
        EepromInit();
        jaguarRunAddress = 0x802000;                                    // For non-BIOS runs, this is true
-       int fileType = ParseFileType(buffer[0], buffer[1], jaguarROMSize);
+       int fileType = ParseFileType(buffer, jaguarROMSize);
        jaguarCartInserted = false;
 
        if (fileType == JST_ROM)
@@ -171,13 +171,71 @@ bool JaguarLoadFile(char * path)
                jaguarRunAddress = runAddress;
                return true;
        }
+       // NB: This is *wrong*
+       /*
+       Basically, if there is no "JAG" at position $1C, then the long there is the load/start
+       address in LITTLE ENDIAN.
+       If "JAG" is present, the the next character ("R" or "L") determines the size of the
+       JagServer command (2 bytes vs. 4). Following that are the commands themselves;
+       typically it will either be 2 (load) or 3 (load & run). Command headers go like so:
+       2:
+       Load address (long)
+       Length (long)
+       payload
+       3:
+       Load address (long)
+       Length (long)
+       Run address (long)
+       payload
+       5: (Reset)
+       [command only]
+       7: (Run at address)
+       Run address (long)
+       [no payload]
+       9: (Clear memory)
+       Start address (long)
+       End address (long)
+       [no payload]
+       10: (Poll for commands)
+       [command only]
+       12: (Load & run user program)
+       filname, terminated with NULL
+       [no payload]
+       $FFFF: (Halt)
+       [no payload]
+       */
        else if (fileType == JST_JAGSERVER)
        {
-               uint32 loadAddress = GET32(buffer, 0x22), runAddress = GET32(buffer, 0x2A);
-               WriteLog("FILE: Setting up homebrew (Jag Server)... Run address: %08X, length: %08X\n", runAddress, jaguarROMSize - 0x2E);
-               memcpy(jagMemSpace + loadAddress, buffer + 0x2E, jaguarROMSize - 0x2E);
+               // This kind of shiaut should be in the detection code below...
+               // (and now it is! :-)
+//             if (buffer[0x1C] == 'J' && buffer[0x1D] == 'A' && buffer[0x1E] == 'G')
+//             {
+                       // Still need to do some checking here for type 2 vs. type 3. This assumes 3
+                       // Also, JAGR vs. JAGL (word command size vs. long command size)
+                       uint32 loadAddress = GET32(buffer, 0x22), runAddress = GET32(buffer, 0x2A);
+                       WriteLog("FILE: Setting up homebrew (Jag Server)... Run address: $%X, length: $%X\n", runAddress, jaguarROMSize - 0x2E);
+                       memcpy(jagMemSpace + loadAddress, buffer + 0x2E, jaguarROMSize - 0x2E);
+                       delete[] buffer;
+                       jaguarRunAddress = runAddress;
+                       return true;
+//             }
+//             else // Special WTFOMGBBQ type here...
+//             {
+//                     uint32_t loadAddress = (buffer[0x1F] << 24) | (buffer[0x1E] << 16) | (buffer[0x1D] << 8) | buffer[0x1C];
+//                     WriteLog("FILE: Setting up homebrew (GEMDOS WTFOMGBBQ type)... Run address: $%X, length: $%X\n", loadAddress, jaguarROMSize - 0x20);
+//                     memcpy(jagMemSpace + loadAddress, buffer + 0x20, jaguarROMSize - 0x20);
+//                     delete[] buffer;
+//                     jaguarRunAddress = loadAddress;
+//                     return true;
+//             }
+       }
+       else if (fileType == JST_WTFOMGBBQ)
+       {
+               uint32_t loadAddress = (buffer[0x1F] << 24) | (buffer[0x1E] << 16) | (buffer[0x1D] << 8) | buffer[0x1C];
+               WriteLog("FILE: Setting up homebrew (GEMDOS WTFOMGBBQ type)... Run address: $%X, length: $%X\n", loadAddress, jaguarROMSize - 0x20);
+               memcpy(jagMemSpace + loadAddress, buffer + 0x20, jaguarROMSize - 0x20);
                delete[] buffer;
-               jaguarRunAddress = runAddress;
+               jaguarRunAddress = loadAddress;
                return true;
        }
 
@@ -352,21 +410,26 @@ uint32 GetFileFromZIP(const char * zipFile, FileType type, uint8 * &buffer)
 //
 // Parse the file type based upon file size and/or headers.
 //
-uint32 ParseFileType(uint8 header1, uint8 header2, uint32 size)
+uint32 ParseFileType(uint8_t * buffer, uint32 size)
 {
        // Check headers first...
 
        // ABS/COFF type 1
-       if (header1 == 0x60 && header2 == 0x1B)
+       if (buffer[0] == 0x60 && buffer[1] == 0x1B)
                return JST_ABS_TYPE1;
 
        // ABS/COFF type 2
-       if (header1 == 0x01 && header2 == 0x50)
+       if (buffer[0] == 0x01 && buffer[1] == 0x50)
                return JST_ABS_TYPE2;
 
-       // Jag Server
-       if (header1 == 0x60 && header2 == 0x1A)
-               return JST_JAGSERVER;
+       // Jag Server & other old shite
+       if (buffer[0] == 0x60 && buffer[1] == 0x1A)
+       {
+               if (buffer[0x1C] == 'J' && buffer[0x1D] == 'A' && buffer[0x1E] == 'G')
+                       return JST_JAGSERVER;
+               else
+                       return JST_WTFOMGBBQ;
+       }
 
        // And if that fails, try file sizes...
 
index a7342fc16a8f96e5e72852953d21d7ca87ef2709..b9855bcc5135d4cd94710ae5faaababdea71c944 100644 (file)
@@ -15,13 +15,13 @@ extern "C" {
 
 enum FileType { FT_SOFTWARE=0, FT_EEPROM, FT_LABEL, FT_BOXART, FT_OVERLAY };
 // JST = Jaguar Software Type
-enum { JST_NONE = 0, JST_ROM, JST_ALPINE, JST_ABS_TYPE1, JST_ABS_TYPE2, JST_JAGSERVER };
+enum { JST_NONE = 0, JST_ROM, JST_ALPINE, JST_ABS_TYPE1, JST_ABS_TYPE2, JST_JAGSERVER, JST_WTFOMGBBQ };
 
 uint32 JaguarLoadROM(uint8 * &rom, char * path);
 bool JaguarLoadFile(char * path);
 bool AlpineLoadFile(char * path);
 uint32 GetFileFromZIP(const char * zipFile, FileType type, uint8 * &buffer);
-uint32 ParseFileType(uint8 header1, uint8 header2, uint32 size);
+uint32 ParseFileType(uint8_t * buffer, uint32 size);
 bool HasUniversalHeader(uint8 * rom, uint32 romSize);
 
 #ifdef __cplusplus
index 7a905a9c76c9940870b0658328eb5126291c089e..10df86c646bd811afacaad00532b4afcac63c7d5 100644 (file)
@@ -11,6 +11,7 @@
 // JLH  12/23/2009  Created this file
 // JLH  01/21/2011  Added SDL initialization
 // JLH  06/26/2011  Added fix to keep SDL from hijacking main() on win32
+// JLH  05/24/2012  Added option switches
 //
 
 #include "app.h"
 #include "mainwin.h"
 #include "settings.h"
 #include "types.h"
+#include "version.h"
+
 
-#ifdef __GCCWIN32__
 // Apparently on win32, SDL is hijacking main from Qt. So let's do this:
+#ifdef __GCCWIN32__
 #undef main
 #endif
 
+// Function prototypes...
+static bool ParseCommandLine(int argc, char * argv[]);
+static void ParseOptions(int argc, char * argv[]);
+
+
 //hm. :-/
 // This is stuff we pass into the mainWindow...
 bool noUntunedTankPlease = false;
 bool loadAndGo = false;
+bool useLogfile = true;
 QString filename;
 
 // Here's the main application loop--short and simple...
@@ -41,55 +50,25 @@ int main(int argc, char * argv[])
        // This is stuff we pass into the mainWindow...
 //     noUntunedTankPlease = false;
 
-       if (argc > 1)
-       {
-               if ((strcmp(argv[1], "--help") == 0) || (strcmp(argv[1], "-h") == 0)
-                       || (strcmp(argv[1], "-?") == 0))
-               {
-                       printf("Virtual Jaguar 2.0.0 help\n");
-                       printf("\n");
-                       printf("Command line interface is mostly non-functional ATM, but may return if\n"
-                               "there is enough demand for it. :-)\n");
-                       return 0;
-               }
-
-               if (strcmp(argv[1], "--yarrr") == 0)
-               {
-                       printf("\n");
-                       printf("Shiver me timbers!\n");
-                       printf("\n");
-                       return 0;
-               }
-
-               if ((strcmp(argv[1], "--alpine") == 0) || (strcmp(argv[1], "-a") == 0))
-               {
-                       printf("Alpine Mode enabled.\n");
-                       vjs.hardwareTypeAlpine = true;
-               }
-
-               if (strcmp(argv[1], "--please-dont-kill-my-computer") == 0)
-               {
-                       noUntunedTankPlease = true;
-               }
-
-               // Check for filename
-               if (argv[1][0] != '-')
-               {
-                       loadAndGo = true;
-                       filename = argv[1];
-               }
-       }
+       // Check for options that must be in place be constructing the App object
+       if (!ParseCommandLine(argc, argv))
+               return 0;
 
        Q_INIT_RESOURCE(virtualjaguar); // This must the same name as the exe filename
 //or is it the .qrc filename???
        // This is so we can pass this stuff using signal/slot mechanism...
+//this is left here to remind me not to try doing this again :-P
 //ick  int id = qRegisterMetaType<uint32>();
 
-       bool success = (bool)LogInit("virtualjaguar.log");      // Init logfile
        int retVal = -1;                                                        // Default is failure
 
-       if (!success)
-               printf("Failed to open virtualjaguar.log for writing!\n");
+       if (useLogfile)
+       {
+               bool success = (bool)LogInit("./virtualjaguar.log");    // Init logfile
+
+               if (!success)
+                       printf("Failed to open virtualjaguar.log for writing!\n");
+       }
 
        // Set up SDL library
        if (SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_AUDIO) < 0)
@@ -111,11 +90,207 @@ int main(int argc, char * argv[])
        return retVal;
 }
 
-// Main app constructor--we stick globally accessible stuff here...
-
+//
+// Main app constructor--we stick globally accessible stuff here... (?)
+//
 App::App(int argc, char * argv[]): QApplication(argc, argv)
 {
-       mainWindow = new MainWin(filename);
+       bool loadAndGo = !filename.isEmpty();
+
+       mainWindow = new MainWin(loadAndGo);
        mainWindow->plzDontKillMyComputer = noUntunedTankPlease;
+       ParseOptions(argc, argv);                                       // Override defaults with command line (if any)
+       mainWindow->SyncUI();
+
+       if (loadAndGo)
+               mainWindow->LoadFile(filename);
+
        mainWindow->show();
 }
+
+
+//
+// Here we parse out stuff that needs to be looked at *before* we construct the 
+// App object.
+//
+bool ParseCommandLine(int argc, char * argv[])
+{
+       for(int i=1; i<argc; i++)
+       {
+               if ((strcmp(argv[i], "--help") == 0) || (strcmp(argv[i], "-h") == 0)
+                       || (strcmp(argv[i], "-?") == 0))
+               {
+                       printf(
+                               "Virtual Jaguar " VJ_RELEASE_VERSION " (" VJ_RELEASE_SUBVERSION ")\n"
+                               "Based upon Virtual Jaguar core v1.0.0 by David Raingeard.\n"
+                               "Written by Niels Wagenaar (Linux/WIN32), Carwin Jones (BeOS),\n"
+                               "James Hammons (Linux/WIN32) and Adam Green (MacOS)\n"
+                               "Contact: http://sdlemu.ngemu.com/ | sdlemu@ngemu.com\n"
+                               "\n"
+                               "Usage:\n"
+                               "   virtualjaguar [<filename>] [switches]\n"
+                               "\n"
+                               "   Option            Description\n"
+                               "   ----------------  -----------------------------------\n"
+                               "   <filename>        Name of file to autoload\n"
+                               "   --alpine      -a  Put Virtual Jaguar into Alpine mode\n"
+                               "   --pal         -p  PAL mode\n"
+                               "   --ntsc        -n  NTSC mode\n"
+                               "   --bios        -b  Boot using Jagaur BIOS\n"
+                               "   --no-bios         Do not use Jaguar BIOS\n"
+                               "   --gpu         -g  Enable GPU\n"
+                               "   --no-gpu          Disable GPU\n"
+                               "   --dsp         -d  Enable DSP\n"
+                               "   --no-dsp          Disable DSP\n"
+                               "   --fullscreen  -f  Start in full screen mode\n"
+                               "   --blur        -B  Enable GL bilinear filter\n"
+                               "   --no-blur         Disable GL bilinear filtering\n"
+                               "   --log         -l  Create and use log file\n"
+                               "   --no-log          Do not use log file\n"
+                               "   --help        -h  Show this message\n"
+                               "\n"
+                               "Invoking Virtual Jagaur with no filename will cause it to boot up\n"
+                               "with the VJ GUI.\n"
+                               "\n");
+                       return false;
+               }
+
+               if (strcmp(argv[i], "--yarrr") == 0)
+               {
+                       printf("\n");
+                       printf("Shiver me timbers!\n");
+                       printf("\n");
+                       return false;
+               }
+
+               if ((strcmp(argv[i], "--alpine") == 0) || (strcmp(argv[i], "-a") == 0))
+               {
+                       printf("Alpine Mode enabled.\n");
+                       vjs.hardwareTypeAlpine = true;
+               }
+
+               if (strcmp(argv[i], "--please-dont-kill-my-computer") == 0)
+               {
+                       noUntunedTankPlease = true;
+               }
+
+               if ((strcmp(argv[i], "--log") == 0) || (strcmp(argv[i], "-l") == 0))
+               {
+                       useLogfile = true;
+               }
+
+               if (strcmp(argv[i], "--no-log") == 0)
+               {
+                       useLogfile = false;
+               }
+
+               // Check for filename
+               if (argv[i][0] != '-')
+               {
+                       loadAndGo = true;
+                       filename = argv[i];
+               }
+       }
+
+       return true;
+}
+
+
+//
+// This is to override settings loaded from the config file.
+// Note that settings set here will become the new defaults!
+//
+void ParseOptions(int argc, char * argv[])
+{
+       for(int i=1; i<argc; i++)
+       {
+               if ((strcmp(argv[i], "--pal") == 0) || (strcmp(argv[i], "-p") == 0))
+               {
+                       vjs.hardwareTypeNTSC = false;
+               }
+
+               if ((strcmp(argv[i], "--ntsc") == 0) || (strcmp(argv[i], "-n") == 0))
+               {
+                       vjs.hardwareTypeNTSC = true;
+               }
+
+               if ((strcmp(argv[i], "--bios") == 0) || (strcmp(argv[i], "-b") == 0))
+               {
+                       vjs.useJaguarBIOS = true;
+               }
+
+               if (strcmp(argv[i], "--no-bios") == 0)
+               {
+                       vjs.useJaguarBIOS = false;
+               }
+
+               if ((strcmp(argv[i], "--gpu") == 0) || (strcmp(argv[i], "-g") == 0))
+               {
+                       vjs.GPUEnabled = true;
+               }
+
+               if (strcmp(argv[i], "--no-gpu") == 0)
+               {
+                       vjs.GPUEnabled = false;
+               }
+
+               if ((strcmp(argv[i], "--dsp") == 0) || (strcmp(argv[i], "-d") == 0))
+               {
+                       vjs.DSPEnabled = true;
+                       vjs.audioEnabled = true;
+               }
+
+               if (strcmp(argv[i], "--no-dsp") == 0)
+               {
+                       vjs.DSPEnabled = false;
+                       vjs.audioEnabled = false;
+               }
+
+               if ((strcmp(argv[i], "--fullscreen") == 0) || (strcmp(argv[i], "-f") == 0))
+               {
+                       vjs.fullscreen = true;
+               }
+
+               if ((strcmp(argv[i], "--blur") == 0) || (strcmp(argv[i], "-B") == 0))
+               {
+                       vjs.glFilter = 1;
+               }
+
+               if (strcmp(argv[i], "--no-blur") == 0)
+               {
+                       vjs.glFilter = 0;
+               }
+       }
+}
+
+#if 0
+       bool useJoystick;
+       int32 joyport;                                                          // Joystick port
+       bool hardwareTypeNTSC;                                          // Set to false for PAL
+       bool useJaguarBIOS;
+       bool GPUEnabled;
+       bool DSPEnabled;
+       bool usePipelinedDSP;
+       bool fullscreen;
+       bool useOpenGL;
+       uint32 glFilter;
+       bool hardwareTypeAlpine;
+       bool audioEnabled;
+       uint32 frameSkip;
+       uint32 renderType;
+       bool allowWritesToROM;
+
+       // Keybindings in order of U, D, L, R, C, B, A, Op, Pa, 0-9, #, *
+
+       uint32 p1KeyBindings[21];
+       uint32 p2KeyBindings[21];
+
+       // Paths
+
+       char ROMPath[MAX_PATH];
+       char jagBootPath[MAX_PATH];
+       char CDBootPath[MAX_PATH];
+       char EEPROMPath[MAX_PATH];
+       char alpineROMPath[MAX_PATH];
+       char absROMPath[MAX_PATH];
+#endif
index 67eb5fd75804f4737613ad3c91b570706cd3c5c8..06c3a3da4c88b2b11f136ffd05242901b3398709 100644 (file)
@@ -375,7 +375,7 @@ void FilePickerWindow::UpdateSelection(const QModelIndex & current, const QModel
                                cart = QImage(":/res/alpine-file.png");
                }
                else if (haveUnknown && (fileType == JST_ABS_TYPE1 || fileType == JST_ABS_TYPE2
-                       || fileType == JST_JAGSERVER))
+                       || fileType == JST_JAGSERVER) || fileType == JST_WTFOMGBBQ)
                {
                        cart = QImage(":/res/homebrew-file.png");
                }
index bde97eddab985324e251aef1ffdca97477580fa9..e3404989f686dd712e1bf478dd3b4d85a5186b07 100644 (file)
@@ -125,7 +125,7 @@ void FileThread::HandleFile(QFileInfo fileInfo)
        }
 
        // Try to divine the file type by size & header
-       int fileType = ParseFileType(buffer[0], buffer[1], fileSize);
+       int fileType = ParseFileType(buffer, fileSize);
 
        // Check for Alpine ROM w/Universal Header
        bool foundUniversalHeader = HasUniversalHeader(buffer, fileSize);
index 7a026c7b31eee3b5eb23a8750244f7e2c30ad0bf..e7a6ba8c7d505d18177331f07de3b7263c6aea44 100644 (file)
 #include "jagstub2bios.h"
 #include "joystick.h"
 
-#ifdef __GCCWIN32__
+// According to SebRmv, this header isn't seen on Arch Linux either... :-/
+//#ifdef __GCCWIN32__
 // Apparently on win32, usleep() is not pulled in by the usual suspects.
 #include <unistd.h>
-#endif
+//#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
 // 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(QString filenameToRun): running(true), powerButtonOn(false),
+//MainWin::MainWin(QString filenameToRun): running(true), powerButtonOn(false),
+MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false),
        showUntunedTankCircuit(true), cartridgeLoaded(false), CDActive(false),
        //, alpineLoadSuccessful(false),
-       pauseForFileSelector(false), loadAndGo(false), plzDontKillMyComputer(false)
+//     pauseForFileSelector(false), loadAndGo(false), plzDontKillMyComputer(false)
+       pauseForFileSelector(false), loadAndGo(autoRun), plzDontKillMyComputer(false)
 {
+       for(int i=0; i<8; i++)
+               keyHeld[i] = false;
+
        videoWidget = new GLWidget(this);
        setCentralWidget(videoWidget);
        setWindowIcon(QIcon(":/res/vj-icon.png"));
@@ -230,16 +236,6 @@ MainWin::MainWin(QString filenameToRun): running(true), powerButtonOn(false),
 
        ReadSettings();
 
-       // Set toolbar buttons/menus based on settings read in (sync the UI)...
-       blurAct->setChecked(vjs.glFilter);
-       x1Act->setChecked(zoomLevel == 1);
-       x2Act->setChecked(zoomLevel == 2);
-       x3Act->setChecked(zoomLevel == 3);
-//     running = powerAct->isChecked();
-       ntscAct->setChecked(vjs.hardwareTypeNTSC);
-       palAct->setChecked(!vjs.hardwareTypeNTSC);
-       powerAct->setIcon(vjs.hardwareTypeNTSC ? powerRed : powerGreen);
-
        // Do this in case original size isn't correct (mostly for the first-run case)
        ResizeMainWindow();
 
@@ -263,13 +259,14 @@ MainWin::MainWin(QString filenameToRun): running(true), powerButtonOn(false),
        memcpy(jagMemSpace + 0xE00000, jaguarBootROM, 0x20000); // Use the stock BIOS
 
        // Check for filename passed in on the command line...
-       if (!filenameToRun.isEmpty())
+//     if (!filenameToRun.isEmpty())
+       if (autoRun)
        {
-               loadAndGo = true;
+//             loadAndGo = true;
                // Attempt to load/run the file the user passed in...
-               LoadSoftware(filenameToRun);
-//             memcpy(jagMemSpace + 0xE00000, jaguarBootROM, 0x20000); // Use the stock BIOS
-               // Prevent the scanner from running...
+//             LoadSoftware(filenameToRun);
+////           memcpy(jagMemSpace + 0xE00000, jaguarBootROM, 0x20000); // Use the stock BIOS
+               // Prevent the file scanner from running...
                return;
        }
 
@@ -302,13 +299,37 @@ MainWin::MainWin(QString filenameToRun): running(true), powerButtonOn(false),
        filePickWin->ScanSoftwareFolder(allowUnknownSoftware);
 }
 
+
+void MainWin::LoadFile(QString file)
+{
+       LoadSoftware(file);
+}
+
+
+void MainWin::SyncUI(void)
+{
+       // Set toolbar buttons/menus based on settings read in (sync the UI)...
+       blurAct->setChecked(vjs.glFilter);
+       x1Act->setChecked(zoomLevel == 1);
+       x2Act->setChecked(zoomLevel == 2);
+       x3Act->setChecked(zoomLevel == 3);
+//     running = powerAct->isChecked();
+       ntscAct->setChecked(vjs.hardwareTypeNTSC);
+       palAct->setChecked(!vjs.hardwareTypeNTSC);
+       powerAct->setIcon(vjs.hardwareTypeNTSC ? powerRed : powerGreen);
+}
+
+
 void MainWin::closeEvent(QCloseEvent * event)
 {
        JaguarDone();
-       WriteSettings();
+// This should only be done by the config dialog
+//     WriteSettings();
+       WriteUISettings();
        event->accept(); // ignore() if can't close for some reason
 }
 
+
 void MainWin::keyPressEvent(QKeyEvent * e)
 {
        // We ignore the Alt key for now, since it causes problems with the GUI
@@ -321,6 +342,7 @@ void MainWin::keyPressEvent(QKeyEvent * e)
        HandleKeys(e, true);
 }
 
+
 void MainWin::keyReleaseEvent(QKeyEvent * e)
 {
        // We ignore the Alt key for now, since it causes problems with the GUI
@@ -333,12 +355,18 @@ void MainWin::keyReleaseEvent(QKeyEvent * e)
        HandleKeys(e, false);
 }
 
+
 void MainWin::HandleKeys(QKeyEvent * e, bool state)
 {
+       enum { P1LEFT = 0, P1RIGHT, P1UP, P1DOWN, P2LEFT, P2RIGHT, P2UP, P2DOWN };
        // We kill bad key combos here, before they can get to the emulator...
        // This also kills the illegal instruction problem that cropped up in Rayman!
        // May want to do this by killing the old one instead of ignoring the new one...
        // Seems to work better that way...
+
+// The problem with this approach is that it causes bad results because it doesn't do
+// any checking of previous states. Need to come up with something better because this
+// causes problems where the keyboard acts as if it were unresponsive. :-P
 #if 0
        if ((e->key() == vjs.p1KeyBindings[BUTTON_L] && joypad_0_buttons[BUTTON_R])
                || (e->key() == vjs.p1KeyBindings[BUTTON_R] && joypad_0_buttons[BUTTON_L])
@@ -346,6 +374,7 @@ void MainWin::HandleKeys(QKeyEvent * e, bool state)
                || (e->key() == vjs.p1KeyBindings[BUTTON_D] && joypad_0_buttons[BUTTON_U]))
                return;
 #else
+#if 0
        if (e->key() == (int)vjs.p1KeyBindings[BUTTON_L] && joypad_0_buttons[BUTTON_R])
                joypad_0_buttons[BUTTON_R] = 0;
        if (e->key() == (int)vjs.p1KeyBindings[BUTTON_R] && joypad_0_buttons[BUTTON_L])
@@ -363,6 +392,33 @@ void MainWin::HandleKeys(QKeyEvent * e, bool state)
                joypad_1_buttons[BUTTON_D] = 0;
        if (e->key() == (int)vjs.p2KeyBindings[BUTTON_D] && joypad_1_buttons[BUTTON_U])
                joypad_1_buttons[BUTTON_U] = 0;
+#else
+//hrm, this still has sticky state problems... Ugh!
+       // First, settle key states...
+       if (e->key() == (int)vjs.p1KeyBindings[BUTTON_L])
+               keyHeld[P1LEFT] = state;
+       else if (e->key() == (int)vjs.p1KeyBindings[BUTTON_R])
+               keyHeld[P1RIGHT] = state;
+       else if (e->key() == (int)vjs.p1KeyBindings[BUTTON_U])
+               keyHeld[P1UP] = state;
+       else if (e->key() == (int)vjs.p1KeyBindings[BUTTON_D])
+               keyHeld[P1DOWN] = state;
+       else if (e->key() == (int)vjs.p2KeyBindings[BUTTON_L])
+               keyHeld[P2LEFT] = state;
+       else if (e->key() == (int)vjs.p2KeyBindings[BUTTON_R])
+               keyHeld[P2RIGHT] = state;
+       else if (e->key() == (int)vjs.p2KeyBindings[BUTTON_U])
+               keyHeld[P2UP] = state;
+       else if (e->key() == (int)vjs.p2KeyBindings[BUTTON_D])
+               keyHeld[P2DOWN] = state;
+
+       // Next, check for conflicts and bail out if there are any...
+       if ((keyHeld[P1LEFT] && keyHeld[P1RIGHT])
+               || (keyHeld[P1UP] && keyHeld[P1DOWN])
+               || (keyHeld[P2LEFT] && keyHeld[P2RIGHT])
+               || (keyHeld[P2UP] && keyHeld[P2DOWN]))
+               return;
+#endif
 #endif
 
        // No bad combos exist, let's stuff the emulator key buffers...!
@@ -380,10 +436,12 @@ void MainWin::HandleKeys(QKeyEvent * e, bool state)
        }
 }
 
+
 void MainWin::Open(void)
 {
 }
 
+
 void MainWin::Configure(void)
 {
        // Call the configuration dialog and update settings
@@ -450,6 +508,7 @@ void MainWin::Configure(void)
        WriteSettings();
 }
 
+
 //
 // Here's the main emulator loop
 //
@@ -484,6 +543,7 @@ void MainWin::Timer(void)
        videoWidget->updateGL();
 }
 
+
 void MainWin::TogglePowerState(void)
 {
        powerButtonOn = !powerButtonOn;
@@ -528,6 +588,7 @@ void MainWin::TogglePowerState(void)
        }
 }
 
+
 void MainWin::ToggleRunState(void)
 {
        running = !running;
@@ -546,55 +607,67 @@ void MainWin::ToggleRunState(void)
        }
 }
 
+
 void MainWin::SetZoom100(void)
 {
        zoomLevel = 1;
        ResizeMainWindow();
 }
 
+
 void MainWin::SetZoom200(void)
 {
        zoomLevel = 2;
        ResizeMainWindow();
 }
 
+
 void MainWin::SetZoom300(void)
 {
        zoomLevel = 3;
        ResizeMainWindow();
 }
 
+
 void MainWin::SetNTSC(void)
 {
        powerAct->setIcon(powerRed);
        timer->setInterval(16);
        vjs.hardwareTypeNTSC = true;
        ResizeMainWindow();
+       WriteSettings();
 }
 
+
 void MainWin::SetPAL(void)
 {
        powerAct->setIcon(powerGreen);
        timer->setInterval(20);
        vjs.hardwareTypeNTSC = false;
        ResizeMainWindow();
+       WriteSettings();
 }
 
+
 void MainWin::ToggleBlur(void)
 {
        vjs.glFilter = !vjs.glFilter;
+       WriteSettings();
 }
 
+
 void MainWin::ShowAboutWin(void)
 {
        aboutWin->show();
 }
 
+
 void MainWin::ShowHelpWin(void)
 {
        helpWin->show();
 }
 
+
 void MainWin::InsertCart(void)
 {
        // If the emulator is running, we pause it here and unpause it later
@@ -608,6 +681,7 @@ void MainWin::InsertCart(void)
        filePickWin->show();
 }
 
+
 void MainWin::Unpause(void)
 {
        // Here we unpause the emulator if it was paused when we went into the file selector
@@ -621,6 +695,7 @@ void MainWin::Unpause(void)
        }
 }
 
+
 void MainWin::LoadSoftware(QString file)
 {
        running = false;                                                        // Prevent bad things(TM) from happening...
@@ -648,6 +723,7 @@ void MainWin::LoadSoftware(QString file)
        }
 }
 
+
 void MainWin::ToggleCDUsage(void)
 {
        CDActive = !CDActive;
@@ -670,6 +746,7 @@ void MainWin::ToggleCDUsage(void)
 #endif
 }
 
+
 void MainWin::FrameAdvance(void)
 {
 //printf("Frame Advance...\n");
@@ -678,6 +755,7 @@ void MainWin::FrameAdvance(void)
        videoWidget->updateGL();
 }
 
+
 void MainWin::ResizeMainWindow(void)
 {
        videoWidget->setFixedSize(zoomLevel * 320, zoomLevel * (vjs.hardwareTypeNTSC ? 240 : 256));
@@ -691,6 +769,7 @@ void MainWin::ResizeMainWindow(void)
        }
 }
 
+
 #warning "!!! Need to check the window geometry to see if the positions are legal !!!"
 // i.e., someone could drag it to another screen, close it, then disconnect that screen
 void MainWin::ReadSettings(void)
@@ -781,6 +860,7 @@ WriteLog("Pipelined DSP = %s\n", (vjs.usePipelinedDSP ? "ON" : "off"));
        vjs.p2KeyBindings[BUTTON_s] = settings.value("p2k_star", Qt::Key_Asterisk).toInt();
 }
 
+
 void MainWin::WriteSettings(void)
 {
        QSettings settings("Underground Software", "Virtual Jaguar");
@@ -856,3 +936,14 @@ void MainWin::WriteSettings(void)
        settings.setValue("p2k_pound", vjs.p2KeyBindings[BUTTON_d]);
        settings.setValue("p2k_star", vjs.p2KeyBindings[BUTTON_s]);
 }
+
+
+void MainWin::WriteUISettings(void)
+{
+       QSettings settings("Underground Software", "Virtual Jaguar");
+       settings.setValue("pos", pos());
+       settings.setValue("size", size());
+       settings.setValue("cartLoadPos", filePickWin->pos());
+
+       settings.setValue("zoom", zoomLevel);
+}
index d9d0447bad4dcc0d35d4770e195cb4c7e625712f..ece5324664ed8e08037c6a3e7fb987f80879ddce 100644 (file)
@@ -23,7 +23,10 @@ class MainWin: public QMainWindow
        Q_OBJECT
 
        public:
-               MainWin(QString);
+//             MainWin(QString);
+               MainWin(bool);
+               void LoadFile(QString);
+               void SyncUI(void);
 
        protected:
                void closeEvent(QCloseEvent *);
@@ -55,6 +58,7 @@ class MainWin: public QMainWindow
                void ResizeMainWindow(void);
                void ReadSettings(void);
                void WriteSettings(void);
+               void WriteUISettings(void);
 
 //     public:
                GLWidget * videoWidget;
@@ -72,6 +76,7 @@ class MainWin: public QMainWindow
 //             bool alpineLoadSuccessful;
                bool pauseForFileSelector;
                bool loadAndGo;
+               bool keyHeld[8];
        public:
                bool plzDontKillMyComputer;
        private:
index a943768cfd1cad35a19952e8248906e44d5bf5a3..de5b5a888f8714e74effa72a11fad457844aaad0 100644 (file)
@@ -1900,8 +1900,8 @@ void JaguarDone(void)
        JaguarDasm(0x802000, 6000);
        WriteLog("\n");//*/
 #endif
-/*     WriteLog("\n\nM68000 disassembly at $4000...\n");
-       JaguarDasm(0x4000, 10000);
+/*     WriteLog("\n\nM68000 disassembly at $6004...\n");
+       JaguarDasm(0x6004, 10000);
        WriteLog("\n");//*/
 //     WriteLog("\n\nM68000 disassembly at $802000...\n");
 //     JaguarDasm(0x802000, 0x1000);
@@ -1951,16 +1951,6 @@ void JaguarExecuteNew(void)
                if (vjs.GPUEnabled)
                        GPUExec(USEC_TO_RISC_CYCLES(timeToNextEvent));
 
-#ifndef NEW_DAC_CODE
-               if (vjs.DSPEnabled)
-               {
-                       if (vjs.usePipelinedDSP)
-                               DSPExecP2(USEC_TO_RISC_CYCLES(timeToNextEvent));        // Pipelined DSP execution (3 stage)...
-                       else
-                               DSPExec(USEC_TO_RISC_CYCLES(timeToNextEvent));          // Ordinary non-pipelined DSP
-               }
-#endif
-
                HandleNextEvent();
        }
        while (!frameDone);
index d21ea682a8582654038966b86800161fb985454c..2782c930160ad1e8b3a042981ff90d8d8bf0d7b0 100644 (file)
@@ -29,7 +29,7 @@ static uint32 logSize = 0;
 
 int LogInit(const char * path)
 {
-       log_stream = fopen(path, "wrt");
+       log_stream = fopen(path, "w");
 
        if (log_stream == NULL)
                return 0;
@@ -67,12 +67,11 @@ void WriteLog(const char * text, ...)
 
        if (logSize > MAX_LOG_SIZE)
        {
+               // Instead of dumping out, we just close the file and ignore any more output.
                fflush(log_stream);
                fclose(log_stream);
-               // Instead of dumping out, we just close the file and ignore any more output.
                log_stream = NULL;
-//             exit(1);
-       }//*/
+       }
 
        va_end(arg);
        fflush(log_stream);                                     // Make sure that text is written!
index fd771ae22457767e605f90de604b96dc74276935..eac45ba7e25885ac18a9c4e22c8395b8153f77d3 100644 (file)
@@ -13,7 +13,9 @@ AR      := ar
 ARFLAGS := -rs
 
 # Note that we use optimization level 2 instead of 3--3 doesn't seem to gain much over 2
-CFLAGS  := -MMD -O2 -ffast-math -fomit-frame-pointer -g
+#CFLAGS  := -MMD -O2 -ffast-math -fomit-frame-pointer -g
+CFLAGS  ?= -O2 -ffast-math -fomit-frame-pointer -g
+GCC_DEPS = -MMD
 
 INCS    := -I. -I./obj `sdl-config --cflags`
 
@@ -26,8 +28,6 @@ OBJS = \
        obj/m68kinterface.o \
        obj/m68kdasm.o
 
-#      obj/newcpu.o \
-
 # Targets for convenience sake, not "real" targets
 .PHONY: clean
 
@@ -45,11 +45,13 @@ obj:
 
 obj/%.o: %.c
        @echo -e "\033[01;33m***\033[00;32m Compiling $<...\033[00m"
-       @$(CC) $(CFLAGS) $(INCS) -c $< -o $@
+#      @$(CC) $(CFLAGS) $(INCS) -c $< -o $@
+       @$(CC) $(GCC_DEPS) $(CFLAGS) $(INCS) -c $< -o $@
 
 obj/%.o: obj/%.c
        @echo -e "\033[01;33m***\033[00;32m Compiling $<...\033[00m"
-       @$(CC) $(CFLAGS) $(INCS) -c $< -o $@
+#      @$(CC) $(CFLAGS) $(INCS) -c $< -o $@
+       @$(CC) $(GCC_DEPS) $(CFLAGS) $(INCS) -c $< -o $@
 
 # Generated code
 
@@ -60,7 +62,8 @@ obj/cpustbl.c: obj/gencpu
 
 obj/gencpu: obj/cpudefs.c
        @echo -e "\033[01;33m***\033[00;32m Generating gencpu...\033[00m"
-       @$(CC) $(CFLAGS) gencpu.c readcpu.c obj/cpudefs.c -o obj/gencpu -I. -I./obj
+#      @$(CC) $(CFLAGS) gencpu.c readcpu.c obj/cpudefs.c -o obj/gencpu -I. -I./obj
+       @$(CC) $(GCC_DEPS) $(CFLAGS) gencpu.c readcpu.c obj/cpudefs.c -o obj/gencpu -I. -I./obj
 
 obj/cpudefs.c: obj/build68k
        @echo -e "\033[01;33m***\033[00;32m Generating cpudefs.c...\033[00m"
@@ -68,7 +71,8 @@ obj/cpudefs.c: obj/build68k
 
 obj/build68k: build68k.c
        @echo -e "\033[01;33m***\033[00;32m Compiling build68k.c...\033[00m"
-       @$(CC) $(CFLAGS) build68k.c -o obj/build68k
+#      @$(CC) $(CFLAGS) build68k.c -o obj/build68k
+       @$(CC) $(GCC_DEPS) $(CFLAGS) build68k.c -o obj/build68k
 
 clean:
        @echo -ne "\033[01;33m***\033[00;32m Cleaning out the garbage...\033[00m"
index 8700c35beed6dd1e19e351e48a7891723ed1f5d9..95e81c3869611c757f196534df587ccd9495ab5e 100644 (file)
@@ -146,7 +146,7 @@ int main_old(int argc, char * argv[])
                        printf("  -ntsc           : Force VJ to NTSC mode                     \n");
                        printf("\nInvoking Virtual Jagaur with no ROM file will cause it to boot up\n");
                        printf("with the VJ GUI.\n");
-                       return 1;
+                       return 1;
                }
     }