diff -NaHudr snes9x-1.42-src/resource.h bisq-1.42/resource.h --- snes9x-1.42-src/resource.h 2003-12-04 19:03:08.000000000 +0200 +++ bisq-1.42/resource.h 2004-05-12 23:28:47.000000000 +0300 @@ -319,13 +319,16 @@ #define IDM_GFX_PACKS 40108 #define IDM_JUSTIFIER 40109 #define ID_SCREENSHOT 40110 +#define ID_FILE_MOVIE_PLAY 40113 +#define ID_FILE_MOVIE_STOP 40114 +#define ID_FILE_MOVIE_RECORD 40115 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 134 -#define _APS_NEXT_COMMAND_VALUE 40113 +#define _APS_NEXT_COMMAND_VALUE 40116 #define _APS_NEXT_CONTROL_VALUE 1161 #define _APS_NEXT_SYMED_VALUE 101 #endif diff -NaHudr snes9x-1.42-src/snes9x/Makefile.in bisq-1.42/snes9x/Makefile.in --- snes9x-1.42-src/snes9x/Makefile.in 2004-02-23 22:07:32.000000000 +0200 +++ bisq-1.42/snes9x/Makefile.in 2004-05-15 18:56:18.000000000 +0300 @@ -85,6 +85,7 @@ cpu.o sa1.o debug.o sdd1.o tile.o srtc.o \ gfx.o memmap.o snaporig.o clip.o dsp1.o \ ppu.o dma.o snes9x.o snapshot.o screenshot.o \ + movie.o \ cheats.o cheats2.o data.o unix/unix.o unix/config.o globals.o \ $(SPC7110OBJ) $(OBC1OBJ) $(SETAOBJ) $(KREEDOBJ) $(SDD1OBJ) diff -NaHudr snes9x-1.42-src/snes9x/movie.cpp bisq-1.42/snes9x/movie.cpp --- snes9x-1.42-src/snes9x/movie.cpp 1970-01-01 02:00:00.000000000 +0200 +++ bisq-1.42/snes9x/movie.cpp 2004-05-16 17:55:49.000000000 +0300 @@ -0,0 +1,563 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2003 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2002 - 2003 Matthew Kendora and + Brad Jorsch (anomie@users.sourceforge.net) + + + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and + Nach (n-a-c-h@users.sourceforge.net) + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2003 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman (jweidman@slip.net), + neviksti (neviksti@hotmail.com), and + Kris Bleakley (stinkfish@bigpond.com) + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2003 zsKnight, pagefault (pagefault@zsnes.com) + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar and Gary Henderson. + + Movie recording + rerecording C++ code + (c) Copyright 2004 Bisqwit (http://iki.fi/bisqwit/) + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ + +#include + +#include "snapshot.h" +#include "cpuexec.h" +#include "display.h" + +#include "movie.h" + + +/************* + +Movie file format: + + $000 signature + $004 flags + $00 word1 (joymask + mode * $20) + $04 word2 + $08 word3 + $010 rerecord count + $014 block: movie name (block is 32-bits:length + data) + $xxx if mode=FROM_RESET, block:sram + if mode=FROM_STATE, block:savestate + $xxx input. 32 bits per controller per frame. + +****/ + +static const char MovieTempFileName[] = "s9xmovie.tmp"; +static class Movie +{ + static const uint32 MOVIE_SIGNATURE = 0x1A564D53; // SMV^Z + + enum { MOVIE_NO=0, MOVIE_PLAY=1, MOVIE_RECORD=2 } state; + unsigned mode; /* FROM_x */ + + unsigned frameno; + uint32 joymask; + uint32 rerecordcount; + +private: + class IO + { + FILE* fp; + bool error; + private: + uint32 GetInt(unsigned bytes) + { + if(bytes > 4 || bytes <= 0) { error=true; return ~0; } + if(!fp) return 0; + unsigned char Buf[4] = { 0,0,0,0 }; + Get((char*)Buf, bytes); + if(error) return ~0; + + return Buf[0] | (Buf[1]<<8) | (Buf[2]<<16) | (Buf[3]<<24); + } + void PutInt(uint32 val, unsigned bytes) + { + if(bytes <= 0) return; + if(bytes > 4) { error=true; return; } + if(!fp) return; + unsigned char Buf[4]; + Buf[0] = (val & 255); + Buf[1] = (val >> 8) & 255; + Buf[2] = (val >> 16) & 255; + Buf[3] = (val >> 24) & 255; + Put((const char*)Buf, bytes); + } + + public: + uint32 Get32() { return GetInt(4); } + void Put32(uint32 val) { PutInt(val, 4); } + + uint16 Get16() { return GetInt(2); } + void Put16(uint16 val) { PutInt(val, 2); } + + uint8 Get8() { return GetInt(1); } + void Put8(uint8 val) { PutInt(val, 1); } + + void Put(const char* buf, unsigned size) + { + if(fwrite(buf, 1, size, fp) != size) + { + error = true; + perror("fwrite"); + } + fflush(fp); + } + void Get(char* buf, unsigned size) + { + if(fread(buf, 1, size, fp) != size) + { + error = true; + perror("fread"); + } + fflush(fp); + } + + void Rewind() { rewind(fp); } + void Skip(unsigned size) { fseek(fp, size, SEEK_CUR); } + + void PutBlock(const char*buf, unsigned size) { Put32(size); Put(buf, size); } + void PutBlock(const std::vector& buf) { PutBlock(&buf[0], buf.size()); } + + void GetBlock(std::vector& buf) + { + buf.resize(Get32()); Get(&buf[0], buf.size()); + } + void SkipBlock() { Skip(Get32()); } + + bool Ok() const { return !error; } + + IO(): fp(NULL), error(false) + { + } + ~IO() + { + Close(); + } + + void Create(const char* filename) + { + Close(); + fp = fopen(filename, "wb+"); if(fp) return; + perror(filename); error = true; + } + void Open(const char* filename) + { + Close(); + fp = fopen(filename, "rb+"); if(fp) return; + fp = fopen(filename, "rb"); if(fp) return; + perror(filename); error = true; + } + void Close() + { + if(fp) + { + fclose(fp); + fp = NULL; + error = false; + } + } + } file; + +private: + void LoadJoy(uint32& keys) + { + uint32 tmp = file.Get32(); + if(file.Ok()) keys = tmp; + } + void SaveJoy(uint32 keys) + { + file.Put32(keys); + } + +private: + bool JoyEnabled(int i) const + { + return joymask & (1 << i); + } + + unsigned GetControllerCount() const + { + unsigned result=0; + for(int i=0; i<5; ++i) if(JoyEnabled(i)) ++result; + return result; + } + +private: + void GetFlags() + { + uint32 word1 = file.Get32(); + uint32 word2 = file.Get32(); + uint32 word3 = file.Get32(); + joymask = (word1 >> 0) & 0x1F; + mode = (word1 >> 5) & 0x03; + word2=word2; //ignore + word3=word3; //ignore + } + void PutFlags() + { + uint32 word1 = 0; + uint32 word2 = 0; + uint32 word3 = 0; + word1 |= (joymask & 0x1F) << 0; + word1 |= (mode & 0x03) << 5; + file.Put32(word1); + file.Put32(word2); + file.Put32(word3); + } + +private: + void SavePoweronState() + { + switch(mode) + { + case FROM_RESET: + { + // Reset and take SRM immediately + S9xReset(); + Memory.SaveSRAM(MovieTempFileName); + + // Embed it in the movie + FILE *embed = fopen(MovieTempFileName, "rb"); + if(!embed) { perror(MovieTempFileName); return; } + fseek(embed, 0, SEEK_END); + + std::vector buf(ftell(embed)); + + rewind(embed); + fread(&buf[0], 1, buf.size(), embed); + fclose(embed); + + fprintf(stderr, "Writing %u bytes of SRAM\n", buf.size()); + file.PutBlock(buf); + break; + } + case FROM_STATE: + { + // Create a snapshot + S9xFreezeGame(MovieTempFileName); + // Load it - a safe tiny measure against desync + S9xUnfreezeGame(MovieTempFileName); + + std::vector buf; + STREAM embed = NULL; + if(S9xOpenSnapshotFile(MovieTempFileName, TRUE, &embed) == SUCCESS) + { + for(;;) + { + char tmp[4096]; + int n = READ_STREAM(tmp, sizeof tmp, embed); + if(n <= 0) break; + buf.insert(buf.end(), tmp, tmp+n); + } + S9xCloseSnapshotFile(embed); + } + + fprintf(stderr, "Writing %u bytes of snapshot\n", buf.size()); + fflush(stderr); + file.PutBlock(buf); + break; + } + case FROM_LUCK: + break; + } + } + void LoadPoweronState() + { + switch(mode) + { + case FROM_RESET: + { + std::vector buf; + file.GetBlock(buf); + + fprintf(stderr, "Loaded %u bytes of SRAM\n", buf.size()); + + FILE *embed = fopen(MovieTempFileName, "wb"); + if(!embed) { perror(MovieTempFileName); return; } + fwrite(&buf[0], 1, buf.size(), embed); + fclose(embed); + + // Load the SRM and reset + Memory.LoadSRAM(MovieTempFileName); + S9xReset(); + break; + } + case FROM_STATE: + { + std::vector buf; + file.GetBlock(buf); + + fprintf(stderr, "Loaded %u bytes of snapshot\n", buf.size()); + + STREAM embed = NULL; + if(S9xOpenSnapshotFile(MovieTempFileName, FALSE, &embed) == SUCCESS) + { + WRITE_STREAM(&buf[0], buf.size(), embed); + S9xCloseSnapshotFile(embed); + } + + // Load the snapshot + S9xUnfreezeGame(MovieTempFileName); + break; + } + case FROM_LUCK: + break; + } + } + void SkipPoweronState() + { + switch(mode) + { + case FROM_RESET: + { + file.SkipBlock(); /* Skip SRAM */ + break; + } + case FROM_STATE: + { + file.SkipBlock(); /* Skip S96 */ + break; + } + case FROM_LUCK: + break; + } + } + +public: + Movie(): state(MOVIE_NO), mode(FROM_STATE), frameno(0), joymask(0) + { + for(int i=0; i<5; ++i) EnableJoy(i); + } + ~Movie() + { + Stop(); + } + void StartRecording(const char* filename) + { + Stop(); + file.Create(filename); + if(!file.Ok()) return; + + /* Don't set state here yet - otherwise snapshot loading + * will issue a call to ResumeRecording() and that's not + * good. + */ + + rerecordcount = 0; + + file.Put32(MOVIE_SIGNATURE); + PutFlags(); + file.Put32(rerecordcount); + + char buf[256] = "Put movie name here"; + file.PutBlock(buf, sizeof buf); + + if(!file.Ok()) + { + Stop(); + return; + } + + SavePoweronState(); + + /* Finally set state */ + state = MOVIE_RECORD; + frameno = 0; + S9xMessage(S9X_INFO,S9X_HEADER_WARNING, "Movie recording"); + } + void StartPlayback(const char* filename) + { + Stop(); + file.Open(filename); + if(!file.Ok()) return; + + uint32 sig = file.Get32(); + GetFlags(); + rerecordcount = file.Get32(); + + if(sig != MOVIE_SIGNATURE) + { + S9xMessage(S9X_ERROR,S9X_HEADER_WARNING, "Invalid movie format"); + } + + char Buf[256]; + sprintf(Buf, "Rerecorded %u times", rerecordcount); + S9xMessage(S9X_INFO,S9X_HEADER_WARNING, Buf); + + file.SkipBlock(); /* Skip filler */ + + LoadPoweronState(); + + if(!file.Ok()) return; + + state = MOVIE_PLAY; + S9xMessage(S9X_INFO,S9X_HEADER_WARNING, "Movie replay."); + } + void ResumeRecording(unsigned framenumber) + { + if(state == MOVIE_NO) return; + + frameno = framenumber; + + file.Rewind(); + file.Get32(); // ignore sig + GetFlags(); + file.Put32(++rerecordcount); // increase rerecord counter + + file.SkipBlock(); /* Skip filler */ + SkipPoweronState(); + + /* Skip n frames */ + file.Skip(frameno * 2 * GetControllerCount()); + + state = MOVIE_RECORD; + + char Buf[64]; + sprintf(Buf, "Movie rerecording #%u", rerecordcount); + S9xMessage(S9X_INFO,S9X_HEADER_WARNING, Buf); + } + unsigned GetFrameno() const { return frameno; } + void Stop() + { + if(state == MOVIE_NO) return; /* Already closed */ + + file.Close(); + + S9xMessage(S9X_INFO,S9X_HEADER_WARNING, "Movie stop."); + state = MOVIE_NO; + } + +public: + void EnableJoy(int i) { if(state == MOVIE_NO) joymask |= (1 << i); } + void DisableJoy(int i) { if(state == MOVIE_NO) joymask &= ~(1 << i); } + void SetPowerOnMode(unsigned newmode) { if(state == MOVIE_NO) mode = newmode; } + +public: + /* For S9xUpdateJoypads() */ + void Update() + { + switch(state) + { + case MOVIE_PLAY: // Load Frame + { + //fprintf(stderr,"Load frame %u (joymask=%X)\n",frameno,joymask); + for(int i=0; i<5; ++i) + if(JoyEnabled(i)) + { + LoadJoy(IPPU.Joypads[i]); + if(!file.Ok()) { Stop(); break; } + } + break; + } + case MOVIE_RECORD: + { + //fprintf(stderr,"Write frame %u (joymask=%X)\n",frameno,joymask); + for(int i=0; i<5; ++i) + if(JoyEnabled(i)) + { + SaveJoy(IPPU.Joypads[i]); + if(!file.Ok()) { Stop(); break; } + } + break; + } + case MOVIE_NO: + return; + } + ++frameno; + } +} Movie; + +/* External interface functions */ +unsigned S9xMovieGetFrameCounter() +{ + return Movie.GetFrameno(); +} +void S9xMovieSetFrameCounter(unsigned n) +{ + Movie.ResumeRecording(n); +} +void S9xMovieStop() +{ + Movie.Stop(); +} +void S9xMovieRecord(const char *filename) +{ + Movie.StartRecording(filename); +} +void S9xMoviePlay(const char *filename) +{ + Movie.StartPlayback(filename); +} +void S9xMovieTick() +{ + Movie.Update(); +} +void S9xMovieSetJoy(int i, bool8 enabled) +{ + if(enabled) + Movie.EnableJoy(i); + else + Movie.DisableJoy(i); +} +void S9xMovieSetMode(unsigned newmode) +{ + Movie.SetPowerOnMode(newmode); +} diff -NaHudr snes9x-1.42-src/snes9x/movie.h bisq-1.42/snes9x/movie.h --- snes9x-1.42-src/snes9x/movie.h 1970-01-01 02:00:00.000000000 +0200 +++ bisq-1.42/snes9x/movie.h 2004-05-16 17:32:20.000000000 +0300 @@ -0,0 +1,22 @@ +#ifndef bqtS9xMovieH +#define bqtS9xMovieH + +enum { FROM_RESET=0, FROM_STATE=1, FROM_LUCK=2 }; /* movie startup mode */ + +/* Movie setup */ +void S9xMovieSetJoy(int i, bool8 enabled); +void S9xMovieSetMode(unsigned newmode); /* one of the startup modes */ + +/* Movie control */ +void S9xMovieStop(); +void S9xMovieRecord(const char *filename); +void S9xMoviePlay(const char *filename); + +/* Utilities */ +unsigned S9xMovieGetFrameCounter(); + +/* Internal functions */ +void S9xMovieSetFrameCounter(unsigned); +void S9xMovieTick(); + +#endif diff -NaHudr snes9x-1.42-src/snes9x/ppu.cpp bisq-1.42/snes9x/ppu.cpp --- snes9x-1.42-src/snes9x/ppu.cpp 2003-12-04 19:03:08.000000000 +0200 +++ bisq-1.42/snes9x/ppu.cpp 2004-05-15 18:58:03.000000000 +0300 @@ -88,6 +88,8 @@ #include "srtc.h" #include "spc7110.h" +#include "movie.h" + #ifndef ZSNES_FX #include "fxemu.h" #include "fxinst.h" @@ -3012,6 +3014,12 @@ for (i = 0; i < 5; i++) { IPPU.Joypads [i] = S9xReadJoypad (i); + } + + S9xMovieTick(); + + for (i = 0; i < 5; i++) + { if (IPPU.Joypads [i] & SNES_LEFT_MASK) IPPU.Joypads [i] &= ~SNES_RIGHT_MASK; if (IPPU.Joypads [i] & SNES_UP_MASK) diff -NaHudr snes9x-1.42-src/snes9x/snapshot.cpp bisq-1.42/snes9x/snapshot.cpp --- snes9x-1.42-src/snes9x/snapshot.cpp 2003-12-04 19:03:08.000000000 +0200 +++ bisq-1.42/snes9x/snapshot.cpp 2004-05-15 18:59:25.000000000 +0300 @@ -100,6 +100,8 @@ #include "sdd1.h" #include "spc7110.h" +#include "movie.h" + extern uint8 *SRAM; #ifdef ZSNES_FX @@ -145,6 +147,11 @@ {OFFSET (FastROMSpeed), 4, INT_V} }; +static uint32 MovieFrame=0; +static FreezeData SnapMovie [] = { + {0, 4, INT_V} +}; + #undef OFFSET #define OFFSET(f) Offset(f,struct SRegisters *) @@ -599,7 +606,7 @@ FreezeStruct (stream, "REG", &Registers, SnapRegisters, COUNT (SnapRegisters)); FreezeStruct (stream, "PPU", &PPU, SnapPPU, COUNT (SnapPPU)); FreezeStruct (stream, "DMA", DMA, SnapDMA, COUNT (SnapDMA)); - + // RAM and VRAM FreezeBlock (stream, "VRA", Memory.VRAM, 0x10000); FreezeBlock (stream, "RAM", Memory.RAM, 0x20000); @@ -633,6 +640,9 @@ FreezeStruct (stream, "RTC", &rtc_f9, SnapS7RTC, COUNT (SnapS7RTC)); } + MovieFrame = S9xMovieGetFrameCounter(); + FreezeStruct (stream, "MOV", &MovieFrame, SnapMovie, COUNT(SnapMovie)); + S9xSetSoundMute (FALSE); #ifdef ZSNES_FX if (Settings.SuperFX) @@ -690,6 +700,7 @@ if ((result = UnfreezeStruct (stream, "DMA", DMA, SnapDMA, COUNT (SnapDMA))) != SUCCESS) return (result); + if ((result = UnfreezeBlock (stream, "VRA", Memory.VRAM, 0x10000)) != SUCCESS) return (result); if ((result = UnfreezeBlock (stream, "RAM", Memory.RAM, 0x20000)) != SUCCESS) @@ -752,6 +763,12 @@ if(Settings.SPC7110RTC) return result; } + + if (UnfreezeStruct (stream, "MOV", &MovieFrame, SnapMovie, COUNT(SnapMovie)) == SUCCESS) + { + S9xMovieSetFrameCounter(MovieFrame); + } + S9xFixSoundAfterSnapshotLoad (); if(!Memory.FillRAM[0x4213]){ diff -NaHudr snes9x-1.42-src/snes9x/unix/x11.cpp bisq-1.42/snes9x/unix/x11.cpp --- snes9x-1.42-src/snes9x/unix/x11.cpp 2003-12-04 19:03:08.000000000 +0200 +++ bisq-1.42/snes9x/unix/x11.cpp 2004-05-15 19:25:21.000000000 +0300 @@ -907,6 +907,69 @@ #endif } +#include "movie.h" +static const char *S9xChooseMovieFilename(bool8 read_only) +{ + char def [PATH_MAX + 1]; + char title [PATH_MAX + 1]; + char drive [_MAX_DRIVE + 1]; + char dir [_MAX_DIR + 1]; + char ext [_MAX_EXT + 1]; + + _splitpath (Memory.ROMFilename, drive, dir, def, ext); + strcat (def, ".smv"); + sprintf (title, "Choose movie %s filename", read_only ? "playback" : "record"); + const char *filename; + + S9xSetSoundMute (TRUE); + filename = S9xSelectFilename (def, S9xGetSnapshotDirectory (), "smv", title); + S9xSetSoundMute (FALSE); + return (filename); +} +static int QuickSaveNumber=0; +static void SelectQuickSaveNumber(int n) +{ + QuickSaveNumber = n; + + char Buf[256]; + sprintf(Buf, "Slot %d selected", n); + S9xMessage(0,0,Buf); +} +static void LoadQuickSaveNumber() +{ + char def [PATH_MAX + 1]; + char title [PATH_MAX + 1]; + char drive [_MAX_DRIVE + 1]; + char dir [_MAX_DIR + 1]; + char ext [_MAX_EXT + 1]; + + _splitpath (Memory.ROMFilename, drive, dir, def, ext); + sprintf(strchr(def,0), ".%03d", QuickSaveNumber); + + S9xUnfreezeGame(def); + + char Buf[256]; + sprintf(Buf, "Load %d", QuickSaveNumber); + S9xMessage(0,0,Buf); +} +static void SaveQuickSaveNumber() +{ + char def [PATH_MAX + 1]; + char title [PATH_MAX + 1]; + char drive [_MAX_DRIVE + 1]; + char dir [_MAX_DIR + 1]; + char ext [_MAX_EXT + 1]; + + _splitpath (Memory.ROMFilename, drive, dir, def, ext); + sprintf(strchr(def,0), ".%03d", QuickSaveNumber); + + S9xFreezeGame(def); + + char Buf[256]; + sprintf(Buf, "Save %d", QuickSaveNumber); + S9xMessage(0,0,Buf); +} + void S9xProcessEvents (bool8 block) { #ifdef USE_AIDO @@ -944,6 +1007,50 @@ int key; switch (key = XKeycodeToKeysym (GUI.display, event.xkey.keycode, 0)) { + case XK_t: + { + if (event.type == KeyPress) + { + S9xMovieStop(); + S9xMovieSetMode(FROM_RESET); + S9xMovieRecord(S9xChooseMovieFilename (FALSE)); + } + break; + } + case XK_y: + { + if (event.type == KeyPress) + { + S9xMoviePlay(S9xChooseMovieFilename (TRUE)); + } + break; + } + case XK_u: + { + if (event.type == KeyPress)S9xMovieStop (); + break; + } + case XK_s: { if(event.type == KeyPress) SaveQuickSaveNumber(); break; } + case XK_f: { if(event.type == KeyPress) LoadQuickSaveNumber(); break; } + + case XK_Right: byte2 = 1; break; + case XK_Left: byte2 = 2; break; + case XK_Down: byte2 = 4; break; + case XK_Up: byte2 = 8; break; + + case XK_p: byte2 = 16; break; // Start + case XK_h: byte2 = 32; break; // Select + + case XK_w: byte1 = 128; break; // A + case XK_d: byte2 = 128; break; // B + case XK_a: byte1 = 64; break; // X + case XK_x: byte2 = 64; break; // Y + case XK_z: byte1 = 32; break; // TL + case XK_c: byte1 = 16; break; // TR + + + +#if 0 case XK_k: case XK_Right: byte2 = 1; break; case XK_h: @@ -969,7 +1076,7 @@ case XK_t: case XK_d: byte1 = 128; break; // A - case XK_y: +e case XK_y: case XK_c: byte2 = 128; break; // B case XK_m: @@ -987,6 +1094,8 @@ case XK_b: case XK_w: case XK_z: byte1 = 16; break; // TR +#endif + case XK_KP_4: byte4 = 1; break; case XK_KP_6: byte4 = 2; break; @@ -1023,6 +1132,7 @@ case XK_0: if (event.type == KeyPress) { + if(event.xkey.state & Mod1Mask) { SelectQuickSaveNumber(0); break; } Settings.DisableHDMA = !Settings.DisableHDMA; S9xDisplayStateChange ("HDMA emulation", !Settings.DisableHDMA); } @@ -1030,6 +1140,7 @@ case XK_1: if (event.type == KeyPress) { + if(event.xkey.state & Mod1Mask) { SelectQuickSaveNumber(1); break; } PPU.BG_Forced ^= 1; S9xDisplayStateChange ("BG#0", !(PPU.BG_Forced & 1)); } @@ -1037,6 +1148,7 @@ case XK_2: if (event.type == KeyPress) { + if(event.xkey.state & Mod1Mask) { SelectQuickSaveNumber(2); break; } PPU.BG_Forced ^= 2; S9xDisplayStateChange ("BG#1", !(PPU.BG_Forced & 2)); } @@ -1044,6 +1156,7 @@ case XK_3: if (event.type == KeyPress) { + if(event.xkey.state & Mod1Mask) { SelectQuickSaveNumber(3); break; } PPU.BG_Forced ^= 4; S9xDisplayStateChange ("BG#2", !(PPU.BG_Forced & 4)); } @@ -1051,6 +1164,7 @@ case XK_4: if (event.type == KeyPress) { + if(event.xkey.state & Mod1Mask) { SelectQuickSaveNumber(4); break; } PPU.BG_Forced ^= 8; S9xDisplayStateChange ("BG#3", !(PPU.BG_Forced & 8)); } @@ -1058,6 +1172,7 @@ case XK_5: if (event.type == KeyPress) { + if(event.xkey.state & Mod1Mask) { SelectQuickSaveNumber(5); break; } PPU.BG_Forced ^= 16; S9xDisplayStateChange ("Sprites", !(PPU.BG_Forced & 16)); } @@ -1065,6 +1180,7 @@ case XK_6: if (event.type == KeyPress) { + if(event.xkey.state & Mod1Mask) { SelectQuickSaveNumber(6); break; } #ifdef USE_OPENGL if (Settings.OpenGLEnable && (event.xkey.state & ShiftMask)) @@ -1080,6 +1196,7 @@ case XK_7: if (event.type == KeyPress) { + if(event.xkey.state & Mod1Mask) { SelectQuickSaveNumber(7); break; } static char *controllers [] = { "Multiplayer 5 on #0", "Joypad on #0", "Mouse on #1", "Mouse on #0", "Superscope on #1" @@ -1092,6 +1209,7 @@ case XK_8: if (event.type == KeyPress) { + if(event.xkey.state & Mod1Mask) { SelectQuickSaveNumber(8); break; } Settings.BGLayering = !Settings.BGLayering; S9xDisplayStateChange ("Background layering hack", Settings.BGLayering); @@ -1100,6 +1218,7 @@ case XK_9: if (event.type == KeyPress) { + if(event.xkey.state & Mod1Mask) { SelectQuickSaveNumber(9); break; } if (event.xkey.state & ShiftMask) { Settings.Mode7Interpolate ^= TRUE; @@ -2417,6 +2536,7 @@ void S9xGraphicsMode () { + Settings.InterpolatedSound = 1; #ifdef USE_AIDO if (Settings.AIDOShmId) return; @@ -2455,6 +2575,7 @@ } #endif XAutoRepeatOff (GUI.display); + } void S9xParseDisplayArg (char **argv, int &ind, int) diff -NaHudr snes9x-1.42-src/snes9x.rc bisq-1.42/snes9x.rc --- snes9x-1.42-src/snes9x.rc 2003-12-04 19:03:08.000000000 +0200 +++ bisq-1.42/snes9x.rc 2004-05-12 23:30:01.000000000 +0300 @@ -1093,6 +1093,16 @@ MENUITEM "Save SPC&7110 log", IDM_LOG_7110, GRAYED MENUITEM "ROM Information...", IDM_ROM_INFO, GRAYED MENUITEM SEPARATOR + POPUP "Movie" + BEGIN + MENUITEM "Play...", ID_FILE_MOVIE_PLAY + , GRAYED + MENUITEM "Stop", ID_FILE_MOVIE_STOP + , GRAYED + MENUITEM "Record...", ID_FILE_MOVIE_RECORD + , GRAYED + END + MENUITEM SEPARATOR MENUITEM "&Reset Game", ID_FILE_RESET, GRAYED MENUITEM "&Pause\tPause", ID_FILE_PAUSE, GRAYED MENUITEM "E&xit\tAlt+F4", ID_FILE_EXIT diff -NaHudr snes9x-1.42-src/wsnes9x.cpp bisq-1.42/wsnes9x.cpp --- snes9x-1.42-src/wsnes9x.cpp 2003-12-04 19:03:08.000000000 +0200 +++ bisq-1.42/wsnes9x.cpp 2004-05-12 23:36:28.000000000 +0300 @@ -790,6 +790,54 @@ case WM_COMMAND: switch (wParam & 0xffff) { + case ID_FILE_MOVIE_STOP: + S9xMovieStop(); + break; + case ID_FILE_MOVIE_PLAY: + if(!Settings.StopEmulation) + { + OPENFILENAME ofn; + char szFileName[MAX_PATH]; + + szFileName[0] = '\0'; + + ZeroMemory( (LPVOID)&ofn, sizeof(OPENFILENAME) ); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hWnd; + ofn.lpstrFilter = "Snes9x Movie File\0*.smv\0All files\0*.*\0\0"; + ofn.lpstrFile = szFileName; + ofn.lpstrDefExt = "smv"; + ofn.nMaxFile = MAX_PATH; + if(GetOpenFileName( &ofn )) + { + S9xMoviePlay(szFileName); + } + } + break; + case ID_FILE_MOVIE_RECORD: + if(!Settings.StopEmulation) + { + OPENFILENAME ofn; + char szFileName[MAX_PATH]; + + szFileName[0] = '\0'; + + ZeroMemory( (LPVOID)&ofn, sizeof(OPENFILENAME) ); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hWnd; + ofn.lpstrFilter = "Snes9x Movie File\0*.smv\0All files\0*.*\0\0"; + ofn.lpstrFile = szFileName; + ofn.lpstrDefExt = "smv"; + ofn.nMaxFile = MAX_PATH; + ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT /*| OFN_EXPLORER*/; + if(GetSaveFileName( &ofn )) + { + S9xMovieRecord(szFileName); + } + } + break; + + case ID_SCREENSHOT: Settings.TakeScreenshot=true; break; @@ -2943,6 +2991,13 @@ SetMenuItemInfo (GUI.hMenu, ID_DEBUG_TRACE_DSP1, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_DEBUG_FRAME_ADVANCE, FALSE, &mii); SetMenuItemInfo (GUI.hMenu, ID_DEBUG_SNES_STATUS, FALSE, &mii); + + mii.fState = MFS_ENABLED; + SetMenuItemInfo (GUI.hMenu, ID_FILE_MOVIE_PLAY, FALSE, &mii); + SetMenuItemInfo (GUI.hMenu, ID_FILE_MOVIE_RECORD, FALSE, &mii); + + mii.fState = MFS_ENABLED; + SetMenuItemInfo (GUI.hMenu, ID_FILE_MOVIE_STOP, FALSE, &mii); } #define HUGGLE StretchBlt