Posts for Fabianx

Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
nitsuja wrote:
Those who've played it know that normally this game relies heavily on trial-and-error (try something, die, restart, try something else, die restart, try something else, finally survive, then die 10 seconds later, restart...) which I found very annoying when I first tried to beat it on console, but luckily that process doesn't have to be watched in a rerecorded movie of its completion.
I'm sorry, at least with my detsound patch (very similar to Bisqwits) the game did run some times faster. I have resynced half of the movie, but every 3000 frames I had to make a correction. And having tried to resync it, I can say: Yes, its an incredible hard game. cu Fabian
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
MovieWatcher wrote:
I can't see it... Maybe it's due to a difference between the SNES9X for Mac and Windows. I don't have "<No sound>" as playback rate, but tried with both disabling sound in general, and any combination I could possibly have chosen. I really hope this get published, though, since it is a real classic. (btw. Was it just the european version that was called another world?)
Under UNIX you need to use: snes9x -r 0 perhaps you have a similar setting. cu Fabian
Post subject: Deterministc sound proposal
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
Hi, here is a deterministic sound proposal for all architectures:
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/cpuexec.cpp snes9x-1.43-dev-src/snes9x/cpuexec.cpp
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/cpuexec.cpp      2005-01-22 02:19:03.000000000 +0100
+++ snes9x-1.43-dev-src/snes9x/cpuexec.cpp      2005-01-23 03:25:15.000000000 +0100
@@ -95,6 +95,7 @@
 #include "debug.h"
 #include "snapshot.h"
 #include "gfx.h"
+#include "soundux.h"
 #include "missing.h"
 #include "apu.h"
 #include "dma.h"
@@ -301,6 +302,8 @@
        {
            // Start of V-blank
            S9xEndScreenRefresh ();
+           if (Settings.SoundDeterministic)
+               S9xMixSamplesPrepare ();
            IPPU.HDMA = 0;
            // Bits 7 and 6 of $4212 are computed when read in S9xGetPPU.
            missing.dma_this_frame = 0;
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/i386/cpuexec.S snes9x-1.43-dev-src/snes9x/i386/cpuexec.S
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/i386/cpuexec.S   2005-01-21 14:55:18.000000000 +0100
+++ snes9x-1.43-dev-src/snes9x/i386/cpuexec.S   2005-01-23 03:19:25.000000000 +0100
@@ -391,6 +391,10 @@
        cmpl %eax,%edx
        jne .L165
        ccall S9xEndScreenRefresh
+       testb $0xff, SoundDeterministic
+       jz .nosounddet
+       ccall S9xMixSamplesPrepare
+.nosounddet:
        movb Brightness,%al
        xorl %ecx,%ecx
        movb %al,MaxBrightness
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/i386/offsets.h snes9x-1.43-dev-src/snes9x/i386/offsets.h
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/i386/offsets.h   2005-01-22 02:13:34.000000000 +0100
+++ snes9x-1.43-dev-src/snes9x/i386/offsets.h   2005-01-23 03:55:07.000000000 +0100
@@ -108,6 +108,7 @@
 #define Paused Settings + 17
 #define PAL Settings + 29
 #define SoundSync Settings + 108
+#define SoundDeterministic Settings + 109
 #define SA1Enabled Settings + 82
 #define SuperFXEnabled Settings + 80
 #define ApuP APURegisters + 0
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/offsets.cpp snes9x-1.43-dev-src/snes9x/offsets.cpp
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/offsets.cpp      2004-07-11 23:50:59.000000000 +0200
+++ snes9x-1.43-dev-src/snes9x/offsets.cpp      2005-01-23 03:55:06.000000000 +0100
@@ -243,6 +243,7 @@
     OFFSET7(Paused,Paused)
     OFFSET7(PAL,PAL)
     OFFSET7(SoundSync,SoundSync)
+    OFFSET7(SoundDeterministic,SoundDeterministic)
     OFFSET7(SA1Enabled,SA1)
     OFFSET7(SuperFXEnabled,SuperFX)

diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/snes9x.cpp snes9x-1.43-dev-src/snes9x/snes9x.cpp
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/snes9x.cpp       2005-01-21 17:01:42.000000000 +0100
+++ snes9x-1.43-dev-src/snes9x/snes9x.cpp       2005-01-22 02:32:50.000000000 +0100
@@ -254,6 +254,12 @@
            {
                Settings.NextAPUEnabled = FALSE;
            }
+           else if (strcasecmp (argv [i], "-ds") == 0 ||
+                    strcasecmp (argv [i], "-detsound") == 0)
+           {
+               Settings.SoundDeterministic = TRUE;
+           }
+
            else if (strcasecmp (argv [i], "-soundskip") == 0 ||
                     strcasecmp (argv [i], "-sk") == 0)
            {
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/snes9x.h snes9x-1.43-dev-src/snes9x/snes9x.h
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/snes9x.h 2005-01-22 02:20:10.000000000 +0100
+++ snes9x-1.43-dev-src/snes9x/snes9x.h 2005-01-22 02:13:32.000000000 +0100
@@ -330,6 +330,7 @@
     bool8  DisableSampleCaching;
     bool8  DisableMasterVolume;
     bool8  SoundSync;
+    bool8  SoundDeterministic;
     bool8  InterpolatedSound;
     bool8  ThreadSound;
     bool8  Mute;
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/soundux.cpp snes9x-1.43-dev-src/snes9x/soundux.cpp
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/soundux.cpp      2005-01-22 01:48:29.000000000 +0100
+++ snes9x-1.43-dev-src/snes9x/soundux.cpp      2005-01-23 14:57:59.000000000 +0100
@@ -1442,6 +1442,102 @@
 extern uint8 int2ulaw (int);
 #endif

+
+uint8 SoundBuffer[SOUND_BUFFER_SIZE];
+int32 play_position=0;
+int32 samples_mixed_so_far=0;
+int32 turbo_on=0;
+
+void S9xMixSamplesPrepare ()
+{
+        static int carry=0;
+       if (!Settings.SoundDeterministic)
+               return;
+
+       // Go back to "sync with soundcard" after turbo mode
+       if (!Settings.TurboMode && turbo_on)
+       {
+        play_position=0;
+        samples_mixed_so_far=0;
+         turbo_on=0;
+       }
+
+       if (Settings.TurboMode)
+          turbo_on=1;
+       /* Where to put the samples to */
+       unsigned byte_offset = play_position +
+                     (so.sixteen_bit ? (samples_mixed_so_far << 1)
+                                     : samples_mixed_so_far);
+       byte_offset &= SOUND_BUFFER_SIZE_MASK; /* wrap */
+
+       /* Number of samples to generate now */
+       carry += so.playback_rate * Settings.FrameTime;
+       int sample_count = carry / 1000000, sample16=1;
+        carry -= sample_count * 1000000;
+       if(so.stereo)       sample_count *= 2;
+
+        if (so.sixteen_bit)
+           sample16=2;
+
+       /* Mix the samples */
+       samples_mixed_so_far += sample_count;
+       for(;;)
+       {
+
+        int I = sample_count;
+        if (byte_offset + I*sample16 > SOUND_BUFFER_SIZE)
+        {
+                I = (SOUND_BUFFER_SIZE - byte_offset) / sample16;
+        }
+        if(I == 0) break;
+
+        S9xMixSamplesR (SoundBuffer+byte_offset, I);
+
+        sample_count-= I;
+        byte_offset += I*sample16;
+        byte_offset &= SOUND_BUFFER_SIZE_MASK; /* wrap */
+    }
+}
+
+void S9xMixSamples (uint8 *buffer, int sample_count)
+{
+    if (samples_mixed_so_far<sample_count)
+           return;
+
+    if (!Settings.SoundDeterministic)
+    {
+        S9xMixSamplesR (buffer, sample_count);
+       return;
+    }
+    unsigned bytes_to_write = sample_count;
+    if(so.sixteen_bit) bytes_to_write <<= 1;
+
+    unsigned byte_offset = play_position, byte_offset_w=0;
+    play_position += bytes_to_write;
+    play_position &= SOUND_BUFFER_SIZE_MASK; /* wrap to beginning */
+
+    /* Copy the samples to the buffer until nothing is left */
+    for(;;)
+    {
+
+        int I = bytes_to_write;
+        if (byte_offset + I > SOUND_BUFFER_SIZE)
+        {
+                I = SOUND_BUFFER_SIZE - byte_offset;
+        }
+        if(I == 0) break;
+
+        memcpy ((char *) buffer + byte_offset_w, (char *) SoundBuffer + byte_offset, I);
+
+        bytes_to_write -= I;
+        byte_offset_w += I;
+        byte_offset += I;
+        byte_offset &= SOUND_BUFFER_SIZE_MASK; /* wrap */
+    }
+    /* All data copied. */
+    samples_mixed_so_far -= sample_count;
+}
+
 // For backwards compatibility with older port specific code
 void S9xMixSamplesO (uint8 *buffer, int sample_count, int byte_offset)
 {
@@ -1451,7 +1547,7 @@
 END_OF_FUNCTION(S9xMixSamplesO);
 #endif

-void S9xMixSamples (uint8 *buffer, int sample_count)
+void S9xMixSamplesR (uint8 *buffer, int sample_count)
 {
     int J;
     int I;
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/soundux.h snes9x-1.43-dev-src/snes9x/soundux.h
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/soundux.h        2004-07-11 23:51:00.000000000 +0200
+++ snes9x-1.43-dev-src/snes9x/soundux.h        2005-01-23 03:36:37.000000000 +0100
@@ -239,7 +239,9 @@
 void S9xFixEnvelope (int channel, uint8 gain, uint8 adsr1, uint8 adsr2);
 void S9xStartSample (int channel);

+EXTERN_C void S9xMixSamplesPrepare (void);
 EXTERN_C void S9xMixSamples (uint8 *buffer, int sample_count);
+EXTERN_C void S9xMixSamplesR (uint8 *buffer, int sample_count);
 EXTERN_C void S9xMixSamplesO (uint8 *buffer, int sample_count, int byte_offset);
 bool8 S9xOpenSoundDevice (int, bool8, int);
 void S9xSetPlaybackRate (uint32 rate);
Tell me what you think of it. cu Fabian PS: And yes this was mostly copied from the unix ringbuffer-version. PPS: Revision 3
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
Bisqwit wrote:
I already have a completely deterministic sound code in my recording patch (assuming threads are not used). http://tasvideos.org/ConvertingSMVToAVIInLinux.html
Yes, this is a _very nice_ solution and I think its even the best one (using NO_BLOCK in a _very_ nice and efficient way), although I think I would put it after PutFrame and not before. Sorry, for not appreciating your work at first bisqwit, but I was a bit shocked that you already had a very good solution for something on what I worked a whole day. Well, at least I learned a lot ;-). But I think we should try to get any of such option into the mainstream code soon, because then we can have timeattacks for some more great games and we even fix the netplay code! ;-) cu Fabian
Post subject: [PATCH/unix] Sound desync bug fix proposal
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
Hi, did I say I wanted to look at this tomorrow again? Well I guess I could not sleep. First the bad news: It seems there is no generic approach for all architectures possible, so each one has to be fixed seperately. (else you would duplicate very much code) But here the good news: With just a very small change its possible to make at least the unix version completely deterministic (by adding a -detsound option, which will be needed for recording as for playing - I think its the best we can do at the moment) I don't have windows, so I can't implement it for the Win version. I propose the following patch, which might loose sound samples (once in a while, see the outcommented printf), but is completely deterministic. I have not heard any glitches though.
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/cpuexec.cpp snes9x-1.43-dev-src/snes9x/cpuexec.cpp
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/cpuexec.cpp      2005-01-22 02:19:03.000000000 +0100
+++ snes9x-1.43-dev-src/snes9x/cpuexec.cpp      2005-01-22 02:27:07.000000000 +0100
@@ -104,6 +104,8 @@

 void S9xMainLoop (void)
 {
+    static int counter=1;
+
     for (;;)
     {
 #ifdef DEBUG_MAXCOUNT
@@ -201,7 +203,10 @@
        if (SA1.Executing)
            S9xSA1MainLoop ();
        DO_HBLANK_CHECK();
+       counter++;
     }
+    printf("Got %8d times through the main for-loop\n", counter);
+    counter=0;
     Registers.PC = CPU.PC - CPU.PCBase;
     S9xPackStatus ();
     APURegisters.PC = IAPU.PC - IAPU.RAM;
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/Makefile snes9x-1.43-dev-src/snes9x/Makefile
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/Makefile 2005-01-22 02:13:43.000000000 +0100
+++ snes9x-1.43-dev-src/snes9x/Makefile 2005-01-22 02:27:17.000000000 +0100
@@ -1,7 +1,7 @@
 # Generated automatically from Makefile.in by configure.
 ZSNESFX=1
 ZSNESC4=1
-ASMCPU=1
+#ASMCPU=1
 #SPC700ASM=1
 NETPLAY=1
 UNZIP=1
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/snes9x.cpp snes9x-1.43-dev-src/snes9x/snes9x.cpp
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/snes9x.cpp       2005-01-21 17:01:42.000000000 +0100
+++ snes9x-1.43-dev-src/snes9x/snes9x.cpp       2005-01-22 02:32:50.000000000 +0100
@@ -254,6 +254,12 @@
            {
                Settings.NextAPUEnabled = FALSE;
            }
+           else if (strcasecmp (argv [i], "-ds") == 0 ||
+                    strcasecmp (argv [i], "-detsound") == 0)
+           {
+               Settings.SoundDeterministic = TRUE;
+           }
+
            else if (strcasecmp (argv [i], "-soundskip") == 0 ||
                     strcasecmp (argv [i], "-sk") == 0)
            {
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/snes9x.h snes9x-1.43-dev-src/snes9x/snes9x.h
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/snes9x.h 2005-01-22 02:20:10.000000000 +0100
+++ snes9x-1.43-dev-src/snes9x/snes9x.h 2005-01-22 02:13:32.000000000 +0100
@@ -330,6 +330,7 @@
     bool8  DisableSampleCaching;
     bool8  DisableMasterVolume;
     bool8  SoundSync;
+    bool8  SoundDeterministic;
     bool8  InterpolatedSound;
     bool8  ThreadSound;
     bool8  Mute;
diff -ur snes9x-1.43-dev-src.fabian-patchset/snes9x/unix/unix.cpp snes9x-1.43-dev-src/snes9x/unix/unix.cpp
--- snes9x-1.43-dev-src.fabian-patchset/snes9x/unix/unix.cpp    2005-01-22 02:22:15.000000000 +0100
+++ snes9x-1.43-dev-src/snes9x/unix/unix.cpp    2005-01-22 02:37:12.000000000 +0100
@@ -392,6 +392,9 @@

 #include "cheats.h"

+static void SoundTrigger();
+static void S9xPrepareMixSamples(void);
+
 int main (int argc, char **argv)
 {
     if (argc < S9xMinCommandLineArgs ())
@@ -641,7 +644,12 @@
            || (CPU.Flags & (DEBUG_MODE_FLAG | SINGLE_STEP_FLAG))
 #endif
            )
-           S9xMainLoop ();
+       {
+          S9xMainLoop ();
+          if (Settings.SoundDeterministic)
+                  S9xPrepareMixSamples();
+       }
+

        if (Settings.Paused
 #ifdef DEBUGGER
@@ -1928,6 +1936,29 @@
     }
 }

+static void S9xPrepareMixSamples()
+{
+       /* Where to put the samples to */
+       unsigned byte_offset = so.play_position +
+                     (so.sixteen_bit ? (so.samples_mixed_so_far << 1)
+                                     : so.samples_mixed_so_far);
+       /* Number of samples to generate now */
+        int sample_count = so.buffer_size;
+
+        if (so.sixteen_bit)
+        {
+           /* to prevent running out of buffer space,
+            * create less samples
+            */
+            sample_count >>= 1;
+        }
+
+       /* Mix the missing samples */
+       S9xMixSamplesO (Buf, sample_count,
+                         byte_offset & SOUND_BUFFER_SIZE_MASK);
+       so.samples_mixed_so_far += sample_count;
+}
+
 void *S9xProcessSound (void *)
 {
     /* Linux and Sun versions */
@@ -2013,8 +2044,9 @@
                      (so.sixteen_bit ? (so.samples_mixed_so_far << 1)
                                      : so.samples_mixed_so_far);
 //printf ("%d:", sample_count - so.samples_mixed_so_far); fflush (stdout);
-       if (Settings.SoundSync == 2)
+       if (Settings.SoundSync == 2 || Settings.SoundDeterministic)
        {
+           //printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Really big BUG!\n");
            /*memset (Buf + (byte_offset & SOUND_BUFFER_SIZE_MASK), 0,
                    sample_count - so.samples_mixed_so_far);*/
        }
Its against my patchset, so it might not apply completely clean, but you should easily get the idea. Also the first two files are for determining deterministic behaviour. I do run: snes9x -detsound [...] > loga1 snes9x -detsound [...] > loga2 And edit the files after I have loaded the movie. They should be exact the same until some offset, where one movie was stopped earlier than the other one. I would have implemented the same for a (blind) windows patch, but windows does not use a ring buffer, but a linear one it seems. TNSe, blip: Perhaps you want to try to implement such a S9xPrepareMixSamples function for windows and run it after S9xMainLoop? cu Fabian PS: I hope that this will finally fix those sound issues.
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
Bag of Magic Food wrote:
It would be nice if we could fix Out Of This World so we wouldn't have to watch a silent movie of it.
Thats what I worked on today, but with not much success :-/. What I can say now is that the APU (Sound-Processor) is acting differently each time if Sound is on in Frame 2317. Argh ... I might know why ... Lets check ... There were some rand() somewhere ... Those could lead to this behaviour ... [edit] Nope, I was wrong. It even has "random" behaviour, when I removed thos rand() calls. But if I remove the write()-Call to the Soundcard it magically starts to be "deterministic". I really don't know what I should think of that ... My only left idea is memory corruption somewhere or some value, which is not reset and such "random". I'll now make a Load-Movie at Beginning function to reduce the "randomness" factor. [edit2] Its getting worse. After re-adding the code using threads or setitimer under unix, I got again "random" behaviour. That really sucks. I will give up on the Sound desync for now as I'm out of ideas at the moment. [edit3] Ok, I now understand at least the "randomness". The problem seems to be (that occurs on all systems) that the sound buffer of the APU is not cleared in constant time intervals, but just when the output buffer of the soundcard gets too small. Of course this will fail to have a deterministic behaviour, which is badly needed for our movies. Solution seems for me to implement another ring buffer and to drop any samples that are "too much" in it. But I'll investigate this further tomorrow. I hope this explanation might help someone. cu Fabian
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
Zurreco wrote:
Bubsy in Claws Encounters of the Furred Kind (U).smc CRC32: 444A52C1 Randomly desynchs at 4 intervals so far.
I can't seem to find the desync. Could you give an example, please? cu Fabian
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
Bag of Magic Food wrote:
Hmm, nice. Do you think this will fix any other games?
This might fix problems, when running the movie gives a slightly different result then loading a save-state and rewinding the movie. But I have not heard of any games with that problem - except for Zelda. I think only time will tell. :-) [edit:] Yes, this might fix many other games as well. I think desyncs happen, because of: - You run the movie - You save a savestate, but its missing information - You load the savestate to re-edit (the console is now in a slightly different state) - You record the movie -> You watch the movie -> it could desync, because the "console-state-change" of course does not happen in the movie. So one might need to check the list in http://nesvideos.stc.cx/viewtopic.php?t=542 again. However I'm still wondering how setting other sound settings can influence some games, but this might be another missing bit of "information". cu Fabian
Post subject: Zelda Desync (hopefully) fixed!
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
Hi, I think I fixed the Zelda Desync. Please test: http://nesvideos.stc.cx/viewtopic.php?t=1680 cu Fabian
Post subject: Zelda Desync (hopefully) fixed!
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
Hi, I spent some hours today of really boring debugging, but it was worth it. For those that are in a hurry ;), here is the patch first:
diff -ur snes9x-1.43-dev-src.old/snes9x/snapshot.cpp snes9x-1.43-dev-src.zelda/snes9x/snapshot.cpp
--- snes9x-1.43-dev-src.old/snes9x/snapshot.cpp 2004-07-11 23:51:00.000000000 +0200
+++ snes9x-1.43-dev-src.zelda/snes9x/snapshot.cpp       2005-01-21 01:57:24.000000000 +0100
@@ -317,7 +317,9 @@
     {OFFSET (BGMosaic), 4, uint8_ARRAY_V},
     {OFFSET (OAMData), 512 + 32, uint8_ARRAY_V},
     {OFFSET (Need16x8Mulitply), 1, INT_V},
-    {OFFSET (MouseSpeed), 2, uint8_ARRAY_V}
+    {OFFSET (MouseSpeed), 2, uint8_ARRAY_V},
+    {OFFSET (OpenBus1), 1, INT_V},
+    {OFFSET (OpenBus2), 1, INT_V}
 };

 #undef OFFSET
It seems Zelda stores some important information about the Sprites in PPU.OpenBus1 and PPU.OpenBus2. Adding those to the list of saved parameters in the snapshot file, seems to solve the desync problems with Zelda. How I did it: After trying _all_ possible Parameters in CPU (that were not yet saved) without much success (and spending hours of frustrating work), I had the right idea. I outcommented the S9xReset() before loading a Snapshot. And then I could notice, that when I loaded a savestate the sprites seemed to move around quite random. So, there must be a variable, that is set, and if you do _not_ reset it, the behaviour is (almost) random. So I did do the same with all functions in S9xReset allowing them to be just called once. (with a static first var, which is set to false after one going through) I found out its in S9xPPUReset, then I used the same trick as above to corner the variable, which makes random behaviour. Finally I found them. So, please test it and finally make a great Zelda-Time Attack! cu Fabian PS: Could someone please forward this to Snes9x authors, if the patch works for you?
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
Very nice upgrade! cu Fabian
Post subject: FYI: My Patchset for snes9x/unix
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
Hi, just for your information: I was quite unsatisfied with the way snes9x does work under unix as I were missing: ShowCurrentFrame, FrameAdvance, skip certain Number of Frames, the possibility to make movies with a savestate included and a key shortcut to make a movie read-only to be able to watch (not edit) a scene more than once (Or like in a big video like super Metroid make some Mark Points ...). I added those and some more options: -dmi / -displaymovieinfo: Shows Movie: Current Frame / Max Frame, but at the position of the FPS counter (which is not as annoying as the normal "status" position) -dpr / -displaypressedkeys: Shows the current pressed keys. A cool way to learn how a "perfect" player is playing and to spot unneeded key presses ;-). Shift+4 = Make new movie with snapshot included Shift+5 = Display Movie Info Shift+6 = Display Pressed Keys Shift+7 or \ = Advance one frame (\ did not work in my tests though :/) Shift+8 = Change R/W status of Movie Shift+9 = Skip a certain number of Frames Display Pressed Keys and Display Movie Info could be easily added to the windows version though I understand that most of you will be quite satisfied with the '.' and status bar solution already implemented. So the only thing interesting for those using windows could be the "Display Pressed Keys" Code, which is rather trivial, but the idea was new ... Blip, Anyone: If you are interested in the Patch-Set get it from: http://studwww.ira.uka.de/~s_franz2/smv/fabian-snes9x.diff cu Fabian
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
VIPer7 wrote:
Fabianx wrote:
As flying is faster than running, I'm afraid you had the possibility to use a shell in Star World 4 ...
You mean the red shell that's lying around there? I doubt I'd be able to fly under the pipe, I'm pretty sure I would have done that otherwise If you mean Star World 5b, well I already am flying with a shell there :P
Well, but the problem is that you are just flying upwards and not with the normal cape, which that glitch is about. And I could imagine that as normal cape flying is the fastest, cape flying with a shell would be equally fastest ... cu Fabian PS: My snes9x hack is making progress. Its very interesting to see that wall jumps in Metroid for example are just very good timed and no magic :-P. And that you in your video are constantly pressing Y. Are you really pressing Y or are you using a trick to have Y automatically held? PPS: It would also apply to the windows version (mostly generic changes in gfx.c), but as I don't have windows I can't compile nor test it.
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
VIPer7 wrote:
I didn't know that site, but I had a look at it and knew most of those things already (it looks like the publisher of the website just published everything that people sent to him, because several things are mentioned twice and more...). Anyway, the things I didn't know were the bonus room in Castle #4 (which unfortunately does not save time...) and the "fly-with-shell" trick. I haven't tried it out yet, but if it doesn't waste any time, I'll try to perform it somewhere.
As flying is faster than running, I'm afraid you had the possibility to use a shell in Star World 4 ... Are you gonna redo that part?
VIPer7 wrote:
Fabianx wrote:
PPS: What would be really cool addition to snes9x would be a graphical controller, which shows which keys are pressed by the movie so one can learn (at 1.2 fps) how to do difficult things ...
Well, there is a way to look which buttons were pressed. You have to open the .smv file with a hex editor, then go to the right position and "read" the numbers that you find there. I made a small tutorial about this, you can find it. Maybe some good programmer here can create a plugin which actually displays the keypresses during the video??
As I'm hacking already on the code (the unix version sucks so far as you seem to have far more possibilities in Windows) ... ... I'll try ... What I have done so far: - Shift+4 gives the possiblity to save movies with Snapshots (It was not possible before) - Shift+5 displays current and total frames of a Movie ... (There was no possibility than hex-editing the movie to look at the current frame number ...) Perhaps I could make Shift+6 display key combinations pressed. Lets see. And I think I need to add frame advance also to the unix code (which was why I looked at the code anyway) *sigh* as there is no binding of \ in the unix keybindings. bisqwit: As you seem to use the unix version, tell me if you are interested in the patch ... cu Fabian
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
VIPer7 wrote:
OmnipotentEntity wrote:
Oh no. Now he's going to start over again.
Now, he won't :P Sorry Fabianx, but if you watch your video at very slow speed (or even better, with frame advance), you'll notice that there is quite a big slowdown; between the frames 3895 and 3915 Mario more or less stands still in the air. And afterwards he also lost the running speed, so there's some more time lost there.
Could _you_ try to do this? Perhaps I missed something, because at least the running speed should be no problem as Mario is again in Cape mode like you can see in one frame (I just resetted that button then) and for the standing still, I might have no longer pressed forward, so he just got upward, but not forward ... As I said it was my first try. cu Fabian
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
VIPer7 wrote:
Fabianx wrote:
I must disagree to the "impossible". I dunno if you can get the needed height, but I managed by starting a flight just after the Chuck and going up and down for some time I passed exactly through the hole.
Hmm, I tried it again, but couldn't reproduce what you said. Either I bump against the pipe, or I hit the green blocks: Could you do it without slowing down at all? If yes, can you please send me a video of it or upload it somewhere?
Well, I was wrong first, but now you gonna redo the level :-P. After lots of testing and even thinking about the walljump I had the right idea, you can fly into the opposite direction. It might even be that this trick allows much higher flying in some levels, but this must be tested out and you are the frame master not me ... Anyway: http://studwww.ira.uka.de/~s_franz2/smv/test-yes-solution-smw.smv Please "scroll" (Tab) a lot forward, because it was my first day with snes9x (I had used only zsnes before) ... Also this video looks quite stupid at the beginning ... Please forgive ;-). I did the "trick" by pressing X (to the already pressed Y) while going up and then releasing X again and pressing forward to put the key into the hole ... Hope it helps you and is at least as fast as your other method, because I think this looks much funnier :-) Btw. Do you know: http://www.gamewinners.com/snes/SMarioWorld.htm ? It has lots of nice hints and glitches and I would love seeing you flying with a shell in one level at least :-). cu Fabian PS: This is soooo cool. I learned so much about flying, what I did not know before. PPS: What would be really cool addition to snes9x would be a graphical controller, which shows which keys are pressed by the movie so one can learn (at 1.2 fps) how to do difficult things ...
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
I think this would be a beautiful example for a time attack, because: - you can manipulate luck - it should not be too long - and it can be very difficult (depending on the players skills ;-) ) Problem about Animaniacs could be: - There are no known glitches (at least I found none) cu Fabian
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
VIPer7 wrote:
So I tried to put in some delay after entering the room, but that didn't change anything, the ghosts still spawned at the exact same point, when they came into sight. Also entering the first door a few frames later didn't change anything, and now I also tried entering the whole level 1 frame later, but still no change. I'm not yet giving up hope and will do some more tries tomorrow, but if I can't manipulate this it would really suck, as I'd lose lots of time :(
Actually Volkov flies not through the holes, but directly through the rings of ghosts. Could you please post a video with the failed attempt to get through? cu Fabian PS: Perhaps someone else has an idea then.
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
Shingen wrote:
I liked it, despite its flaws. Even if it doesn't get published it's worth a watch.
Uhm, I can't find the right ROM ... At least Sim City (E) [!] seems wrong, as that one gives "interesting results" ... EDIT: Sim City (U) [!] is the right one ... To the video itself: This is no timeattack as it is mostly played in normal speed. I think a real timeattack would be able to build in a really fast time and I think that would look very interesting. It was a nice idea and the City looked quite good, but reaction was too slow overall. It was interesting to watch on Turbo though ;-) Thus overall: Voting No cu Fabian
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
I'm voting yes, because: - 8-3 is much more entertaining in this video. - Its also quite nice how those shells commit suicide directly before mario. - Backwards swimming is really cool - Also going under Bowser is really cool though going through the impossible stream of axes is also good. What I'm missing: - In the old video POM is jumping onto a barely seeable platform above the lava, which looks shocking. - Running over the small bricks in 8-1 is not as spectacular as jumping in between ... What I saw in both videos: It seems you are loosing time before the first Warp to level 4 ... I'm sure that you have measured it frame by frame though it looks a big odd. cu Fabian
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
Terimakasih wrote:
Also I think (I might be wrong) there are some stages where you start the Speed-Booster into an open door, but could you not go through the door and open the opposite door to fly even farther? I wondered if you could not shoot the door or at least make a race with your own shoot ;-), which would look pretty cool.
Sorry, I can't understand these meaning... I know all-these-words,but can't translate,sorry.. Would you give me a sample-smv-file or a picture(Jpg,Bmp,Gif,Png)...?
Nevermind. I watched your video again and found out, that I was wrong. You already use the speed booster to the absolute maximum. Thank you for that one :-). Has Smokey seen your new video, yet? I ask, because I watched his video to "compare" routes and playing style and I was quite astonished that Smokey already uses so many tricks. However you hae found some really cool new ones, which he could perhaps use if they are not too difficult to perform. Btw. Have you already measured all rooms frame by frame? I just ask, because I saw in one NES metroid submission, that this could help improving the time even more. What about a 100% run now? ;-) Btw. I don't think anyone from Nintendo has ever though that some"input" would beat the game in 27 minutes. I mean they thought that under 3 hours was really good... cu Fabian
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
"And now, I think "clear time 00:26" is impossibility..." And I think you are damn right. This movie was so absolute perfect. Awesome. Its very very nice how you use the Draygon Glitch to go back again through the metroid area ... What I wondered: There are some stages (at the beginning) where you Run, Jump, run again. Could it be faster to use the mockbal glitch there? (I just ask, I really don't know ...) Also I think (I might be wrong) there are some stages where you start the Speed-Booster into an open door, but could you not go through the door and open the opposite door to fly even farther? I wondered if you could not shoot the door or at least make a race with your own shoot ;-), which would look pretty cool. Another thing: Is it possible in where you fight Ridley to gain enough speed to fly back through the next two rooms? I dunno if anything of that is practicable. That are just ideas. cu Fabian
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
alexpenev wrote:
It's on hold, I'm playing some n64 titles for the mo'. =P
Have fun. I found some "mistakes" in your current video. (but I've just watched teh first two parts) - In the fight with Maxwell, when he gets between you you could have used the "Blade Storm" technique to fight him. Generally its a cool trick to corner an enemy between you and an ally. I think this would also work with Gale Shield or Teleport ... -> Damn, I should have used paper and pencil to write up the mistakes I noted. Sorry, can't remember anymore atm. - Many fights are astonishingly fast (Ifrit or Gnome especially was way cool), but some are just two lengthy for a "perfect" movie. cu Fabian
Experienced Forum User
Joined: 12/17/2004
Posts: 99
Location: Karlsruhe, Germany
VIPer7 wrote:
So, Donut Plains 1 b turned out to be more work than expected. I had a great run, bumping on one super koopa after the other, collecting 1UP in the end and still keeping enough height to get up to the key... but, unfortunately, somehow I just couldn't get up there. The problem: This wall of green !- blocks. It's supposed to be a help to get to the key easier, but it makes the hole between pipe and platform smaller and therefore impossible to pass with a flight.
First of all: Hi, I am new and have read the whole thread, which was very interesting. I must disagree to the "impossible". I dunno if you can get the needed height, but I managed by starting a flight just after the Chuck and going up and down for some time I passed exactly through the hole. So I think it could be possible and if it is you should do it, because flying on top through the level is quite boring imho. It might be that you need to bump some enemies and then need to gain some hight, still making the level more interesting in my opinion. Well otherwise: Keep up the awesome work! cu Fabian