bool8 S9xUnfreezeGame(const char* filename) { if (statef_open(filename, "rb")) { int result; if ((result = Unfreeze()) != SUCCESS) { switch (result) { case WRONG_FORMAT: S9xMessage(S9X_ERROR, S9X_WRONG_FORMAT, "File not in Snes9x freeze format"); S9xReset(); break; case WRONG_VERSION: S9xMessage(S9X_ERROR, S9X_WRONG_VERSION, "Incompatable Snes9x freeze file format version"); S9xReset(); break; default: // should never happen break; } statef_close(); return (FALSE); } statef_close(); return (TRUE); } return (FALSE); }
const char *S9xBasename (const char *f) { const char *p; S9xMessage (0,0,"s9x base name"); if ((p = strrchr (f, '/')) != NULL || (p = strrchr (f, '\\')) != NULL) return (p + 1); return (f); }
uint8 S9xGetDSP (uint16 address) { #ifdef DEBUGGER if (Settings.TraceDSP) { sprintf(String, "DSP read: 0x%04X", address); S9xMessage(S9X_TRACE, S9X_TRACE_DSP1, String); } #endif return ((*GetDSP)(address)); }
void S9xSetDSP(uint8 byte, uint16 address) { #ifdef DEBUGGER missing.unknowndsp_write = address; if (Settings.TraceDSP) { sprintf(String, "DSP write: 0x%04X=0x%02X", address, byte); S9xMessage(S9X_TRACE, S9X_TRACE_DSP1, String); } #endif (*SetDSP)(byte, address); //DSP1SetByte(byte, address); }
void S9xQuickLoadSlot (int slot) { char def[PATH_MAX]; char filename[PATH_MAX]; char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char ext[_MAX_EXT]; if (!gui_config->rom_loaded) return; _splitpath (Memory.ROMFilename, drive, dir, def, ext); snprintf (filename, PATH_MAX, "%s%s%s.%03d", S9xGetDirectory (SNAPSHOT_DIR), SLASH_STR, def, slot); if (file_exists (filename)) S9xFreezeGame (S9xGetFilename (".undo", SNAPSHOT_DIR)); if (S9xUnfreezeGame (filename)) { snprintf (buf, PATH_MAX, "%s.%03d loaded", def, slot); S9xSetInfoString (buf); return; } static const char *digits = "t123456789"; _splitpath (Memory.ROMFilename, drive, dir, def, ext); snprintf (filename, PATH_MAX, "%s%s%s.zs%c", S9xGetDirectory (SNAPSHOT_DIR), SLASH_STR, def, digits[slot]); if (file_exists (filename)) S9xFreezeGame (S9xGetFilename (".undo", SNAPSHOT_DIR)); if (S9xUnfreezeGame (filename)) { snprintf (buf, PATH_MAX, "Loaded ZSNES freeze file %s.zs%c", def, digits [slot]); S9xSetInfoString (buf); return; } S9xMessage (S9X_ERROR, S9X_FREEZE_FILE_NOT_FOUND, "Freeze file not found"); }
bool8 S9xOpenSnapshotFile( const char *fname, bool8 read_only, STREAM *file) { char filename [_MAX_PATH + 1]; char drive [_MAX_DRIVE + 1]; char dir [_MAX_DIR + 1]; char fn [_MAX_FNAME + 1]; char ext [_MAX_EXT + 1]; _splitpath( fname, drive, dir, fn, ext); _makepath( filename, drive, dir, fn, ext[0] == '\0' ? ".000" : ext); if (read_only) { if ((*file = OPEN_STREAM (filename, "rb"))) return (TRUE); } else { if ((*file = OPEN_STREAM (filename, "wb"))) return (TRUE); FILE *fs = fopen (filename, "rb"); if (fs) { sprintf (String, "Freeze file \"%s\" exists but is read only", filename); fclose (fs); S9xMessage (S9X_ERROR, S9X_FREEZE_FILE_NOT_FOUND, String); } else { sprintf (String, "Cannot create freeze file \"%s\". Directory is read-only or does not exist.", filename); S9xMessage (S9X_ERROR, S9X_FREEZE_FILE_NOT_FOUND, String); } } return (FALSE); }
uint8 S9xGetDSP(uint16 address) { uint8 t; #ifdef DEBUGGER if (Settings.TraceDSP) { sprintf(String, "DSP read: 0x%04X", address); S9xMessage(S9X_TRACE, S9X_TRACE_DSP1, String); } #endif t = (*GetDSP)(address); //DSP1GetByte(address); return (t); }
void STOP(char* s) { char buffer[100]; #ifdef DEBUGGER S9xAPUOPrint(buffer, IAPU.PC - IAPU.RAM); #endif sprintf(String, "Sound CPU in unknown state executing %s at %04lX\n%s\n", s, IAPU.PC - IAPU.RAM, buffer); S9xMessage(S9X_ERROR, S9X_APU_STOPPED, String); APU.TimerEnabled[0] = APU.TimerEnabled[1] = APU.TimerEnabled[2] = FALSE; CPU.APU_APUExecuting = FALSE; #ifdef DEBUGGER CPU.Flags |= DEBUG_MODE_FLAG; #else S9xExit(); #endif }
static int S9xGetSDD1Dir(char * packdir) { char dir[_MAX_DIR + 1]; char drive[_MAX_DRIVE + 1]; char name[_MAX_FNAME + 1]; char ext[_MAX_EXT + 1]; PathSplit(S9xGetFilename(FILE_ROM), drive, dir, name, ext); if (strncmp(Memory.ROMName, "Star Ocean", 10) == 0) { PathMake(packdir, drive, dir, "socnsdd1", 0); return 1; } else if(strncmp(Memory.ROMName, "STREET FIGHTER ALPHA2", 21) == 0) { PathMake(packdir, drive, dir, "sfa2sdd1", 0); return 1; } else { S9xMessage(S9X_WARNING, S9X_ROM_INFO, "WARNING: No default SDD1 pack for this ROM"); return 0; } }
bool8 S9xReadSuperScopePosition (int & /* x */, int & /* y */, uint32 & /* buttons */) { S9xMessage (0,0,"read scope"); return (FALSE); }
static int Unfreeze() { // notaz: overflowing the damn Symbian stack again char buffer [16]; char rom_filename [512]; int result; int version; unsigned int len = strlen(SNAPSHOT_MAGIC) + 1 + 4 + 1; if (statef_read(buffer, len) != (int)len) return (WRONG_FORMAT); if (strncmp(buffer, SNAPSHOT_MAGIC, strlen(SNAPSHOT_MAGIC)) != 0) return (WRONG_FORMAT); if ((version = atoi(&buffer [strlen(SNAPSHOT_MAGIC) + 1])) > SNAPSHOT_VERSION) return (WRONG_VERSION); if ((result = UnfreezeBlock("NAM", (uint8*) rom_filename, 512)) != SUCCESS) return (result); if (strcasecmp(rom_filename, Memory.ROMFilename) != 0 && strcasecmp(S9xBasename(rom_filename), S9xBasename(Memory.ROMFilename)) != 0) { S9xMessage(S9X_WARNING, S9X_FREEZE_ROM_NAME, "Current loaded ROM image doesn't match that required by freeze-game file."); } uint32 old_flags = CPU.Flags; #ifdef USE_SA1 uint32 sa1_old_flags = SA1.Flags; #endif S9xReset(); S9xSetSoundMute(TRUE); if ((result = UnfreezeStruct("CPU", &CPU, SnapCPU, COUNT(SnapCPU))) != SUCCESS) return (result); FixROMSpeed(); CPU.Flags |= old_flags & (DEBUG_MODE_FLAG | TRACE_FLAG | SINGLE_STEP_FLAG | FRAME_ADVANCE_FLAG); if ((result = UnfreezeStruct("REG", &Registers, SnapRegisters, COUNT(SnapRegisters))) != SUCCESS) return (result); if ((result = UnfreezeStruct("PPU", &PPU, SnapPPU, COUNT(SnapPPU))) != SUCCESS) return (result); IPPU.ColorsChanged = TRUE; IPPU.OBJChanged = TRUE; CPU.InDMA = FALSE; // Restore colors from PPU unsigned int i; for (i = 0; i < 256; i++) { IPPU.Red[i] = PPU.CGDATA[i] & 0x1f; IPPU.Green[i] = (PPU.CGDATA[i] >> 5) & 0x1f; IPPU.Blue[i] = (PPU.CGDATA[i] >> 10) & 0x1f; } S9xFixColourBrightness(); IPPU.RenderThisFrame = FALSE; if ((result = UnfreezeStruct("DMA", DMA, SnapDMA, COUNT(SnapDMA))) != SUCCESS) return (result); if ((result = UnfreezeBlock("VRA", Memory.VRAM, 0x10000)) != SUCCESS) return (result); if ((result = UnfreezeBlock("RAM", Memory.RAM, 0x20000)) != SUCCESS) return (result); if ((result = UnfreezeBlock("SRA", SRAM, 0x20000)) != SUCCESS) return (result); if ((result = UnfreezeBlock("FIL", Memory.FillRAM, 0x8000)) != SUCCESS) return (result); // Restore graphics shadow registers GFX.r212c_s = Memory.FillRAM[0x212c]; GFX.r212d_s = Memory.FillRAM[0x212d]; GFX.r212e_s = Memory.FillRAM[0x212e]; GFX.r212f_s = Memory.FillRAM[0x212f]; GFX.r2130_s = Memory.FillRAM[0x2130]; GFX.r2131_s = Memory.FillRAM[0x2131]; if (UnfreezeStruct("APU", &APU, SnapAPU, COUNT(SnapAPU)) == SUCCESS) { SAPURegisters spcregs; if ((result = UnfreezeStruct("ARE", &spcregs, SnapAPURegisters, COUNT(SnapAPURegisters))) != SUCCESS) return (result); // reload all SPC700 regs from savestate compatible struct IAPU.P = spcregs.P; IAPU.YA.W = spcregs.YA.W; IAPU.X = spcregs.X; IAPU.S = spcregs.S; IAPU.PC = IAPU.RAM + spcregs.PC; if ((result = UnfreezeBlock("ARA", IAPU.RAM, 0x10000)) != SUCCESS) return (result); if ((result = UnfreezeStruct("SOU", &SoundData, SnapSoundData, COUNT(SnapSoundData))) != SUCCESS) return (result); // notaz: just to be sure int u; for (u = 0; u < 8; u++) { SoundData.channels[u].env_ind_attack &= 0xf; SoundData.channels[u].env_ind_decay &= 0x7; SoundData.channels[u].env_ind_sustain &= 0x1f; } S9xSetSoundMute(FALSE); S9xAPUUnpackStatus(); if (APUCheckDirectPage()) IAPU.DirectPage = IAPU.RAM + 0x100; else IAPU.DirectPage = IAPU.RAM; Settings.APUEnabled = TRUE; /*IAPU.APUExecuting*/CPU.APU_APUExecuting = TRUE; } else { Settings.APUEnabled = FALSE; /*IAPU.APUExecuting*/CPU.APU_APUExecuting = FALSE; S9xSetSoundMute(TRUE); } #ifdef USE_SA1 if ((result = UnfreezeStruct("SA1", &SA1, SnapSA1, COUNT(SnapSA1))) == SUCCESS) { if ((result = UnfreezeStruct("SAR", &SA1Registers, SnapSA1Registers, COUNT(SnapSA1Registers))) != SUCCESS) return (result); S9xFixSA1AfterSnapshotLoad(); SA1.Flags |= sa1_old_flags & (TRACE_FLAG); } #endif S9xFixSoundAfterSnapshotLoad(); ICPU.ShiftedPB = Registers.PB << 16; ICPU.ShiftedDB = Registers.DB << 16; S9xSetPCBase(ICPU.ShiftedPB + Registers.PC); #ifndef ASMCPU S9xUnpackStatus(); // not needed S9xFixCycles(); // also not needed? #endif S9xReschedule(); S9xSRTCPostLoadState(); if (Settings.SDD1) S9xSDD1PostLoadState(); return (SUCCESS); }
static int ReadOrigSnapshot (STREAM snap) { char buffer [_MAX_PATH]; char rom_filename [_MAX_PATH]; int result; int i; int j; int version; int len = strlen (ORIG_SNAPSHOT_MAGIC) + 1 + 4 + 1; if (READ_STREAM (buffer, len, snap) != len) return (WRONG_FORMAT); if (strncmp (buffer, ORIG_SNAPSHOT_MAGIC, strlen (ORIG_SNAPSHOT_MAGIC)) != 0) return (WRONG_FORMAT); if ((version = atoi (&buffer [strlen (SNAPSHOT_MAGIC) + 1])) > ORIG_SNAPSHOT_VERSION) return (WRONG_VERSION); if ((result = ReadBlock ("NAM:", rom_filename, _MAX_PATH, snap)) != SUCCESS) return (result); if ((result = ReadBlock ("HiR:", buffer, 0x41, snap)) != SUCCESS) return (result); if (strcasecmp (rom_filename, Memory.ROMFilename) != 0 && strcasecmp (S9xBasename (rom_filename), S9xBasename (Memory.ROMFilename)) != 0) { S9xMessage (S9X_WARNING, S9X_FREEZE_ROM_NAME, "Current loaded ROM image doesn't match that required by freeze-game file."); } S9xReset (); S9xSetSoundMute (TRUE); if ((result = ReadBlock ("CPU:", &OrigCPU, sizeof (OrigCPU), snap)) != SUCCESS) return (result); OrigCPU.FastROMSpeed = OrigCPU.FastROMSpeed_old; Memory.FixROMSpeed (); if (version == 3) { OrigCPU.Cycles = OrigCPU.Cycles_old; OrigCPU.NextEvent = OrigCPU.NextEvent_old; OrigCPU.V_Counter = OrigCPU.V_Counter_old; OrigCPU.MemSpeed = OrigCPU.MemSpeed_old; OrigCPU.MemSpeedx2 = OrigCPU.MemSpeedx2_old; OrigCPU.FastROMSpeed = OrigCPU.FastROMSpeed_old; } CPU.Flags = OrigCPU.Flags; CPU.BranchSkip = OrigCPU.BranchSkip; CPU.NMIActive = OrigCPU.NMIActive; CPU.IRQActive = OrigCPU.IRQActive; CPU.WaitingForInterrupt = OrigCPU.WaitingForInterrupt; CPU.WhichEvent = OrigCPU.WhichEvent; CPU.Cycles = OrigCPU.Cycles; CPU.NextEvent = OrigCPU.NextEvent; CPU.V_Counter = OrigCPU.V_Counter; CPU.MemSpeed = OrigCPU.MemSpeed; CPU.MemSpeedx2 = OrigCPU.MemSpeedx2; CPU.FastROMSpeed = OrigCPU.FastROMSpeed; if ((result = ReadBlock ("REG:", &OrigRegisters, sizeof (OrigRegisters), snap)) != SUCCESS) return (result); Registers = *(struct SRegisters *) &OrigRegisters; if ((result = ReadBlock ("PPU:", &OrigPPU, sizeof (OrigPPU), snap)) != SUCCESS) return (result); if (version == 2) { OrigPPU.OBJNameSelect = OrigPPU.OBJNameSelect_old << 13; OrigPPU.OBJNameBase <<= 1; OrigPPU.OBJNameSelect <<= 13; } PPU.BGMode = OrigPPU.BGMode; PPU.BG3Priority = OrigPPU.BG3Priority; PPU.Brightness = OrigPPU.Brightness; PPU.VMA.High = OrigPPU.VMA.High; PPU.VMA.Increment = OrigPPU.VMA.Increment; PPU.VMA.Address = OrigPPU.VMA.Address; PPU.VMA.Mask1 = OrigPPU.VMA.Mask1; PPU.VMA.FullGraphicCount = OrigPPU.VMA.FullGraphicCount; PPU.VMA.Shift = OrigPPU.VMA.Shift; for (i = 0; i < 4; i++) { PPU.BG[i].SCBase = OrigPPU.BG[i].SCBase; PPU.BG[i].VOffset = OrigPPU.BG[i].VOffset; PPU.BG[i].HOffset = OrigPPU.BG[i].HOffset; PPU.BG[i].BGSize = OrigPPU.BG[i].BGSize; PPU.BG[i].NameBase = OrigPPU.BG[i].NameBase; PPU.BG[i].SCSize = OrigPPU.BG[i].SCSize; } PPU.CGFLIP = OrigPPU.CGFLIP; for (i = 0; i < 256; i++) PPU.CGDATA [i] = OrigPPU.CGDATA [i]; PPU.FirstSprite = OrigPPU.FirstSprite; for (i = 0; i < 128; i++) { PPU.OBJ[i].HPos = OrigPPU.OBJ [i].HPos; PPU.OBJ[i].VPos = OrigPPU.OBJ [i].VPos; PPU.OBJ[i].Name = OrigPPU.OBJ [i].Name; PPU.OBJ[i].VFlip = OrigPPU.OBJ [i].VFlip; PPU.OBJ[i].HFlip = OrigPPU.OBJ [i].HFlip; PPU.OBJ[i].Priority = OrigPPU.OBJ [i].Priority; PPU.OBJ[i].Palette = OrigPPU.OBJ [i].Palette; PPU.OBJ[i].Size = OrigPPU.OBJ [i].Size; } PPU.OAMPriorityRotation = OrigPPU.OAMPriorityRotation; PPU.OAMAddr = OrigPPU.OAMAddr; PPU.OAMFlip = OrigPPU.OAMFlip; PPU.OAMTileAddress = OrigPPU.OAMTileAddress; PPU.IRQVBeamPos = OrigPPU.IRQVBeamPos; PPU.IRQHBeamPos = OrigPPU.IRQHBeamPos; PPU.VBeamPosLatched = OrigPPU.VBeamPosLatched; PPU.HBeamPosLatched = OrigPPU.HBeamPosLatched; PPU.HBeamFlip = OrigPPU.HBeamFlip; PPU.VBeamFlip = OrigPPU.VBeamFlip; PPU.HVBeamCounterLatched = OrigPPU.HVBeamCounterLatched; PPU.MatrixA = OrigPPU.MatrixA; PPU.MatrixB = OrigPPU.MatrixB; PPU.MatrixC = OrigPPU.MatrixC; PPU.MatrixD = OrigPPU.MatrixD; PPU.CentreX = OrigPPU.CentreX; PPU.CentreY = OrigPPU.CentreY; PPU.Joypad1ButtonReadPos = OrigPPU.Joypad1ButtonReadPos; PPU.Joypad2ButtonReadPos = OrigPPU.Joypad2ButtonReadPos; PPU.Joypad3ButtonReadPos = OrigPPU.Joypad3ButtonReadPos; PPU.CGADD = OrigPPU.CGADD; PPU.FixedColourRed = OrigPPU.FixedColourRed; PPU.FixedColourGreen = OrigPPU.FixedColourGreen; PPU.FixedColourBlue = OrigPPU.FixedColourBlue; PPU.SavedOAMAddr = OrigPPU.SavedOAMAddr; PPU.ScreenHeight = OrigPPU.ScreenHeight; PPU.WRAM = OrigPPU.WRAM; PPU.ForcedBlanking = OrigPPU.ForcedBlanking; PPU.OBJNameSelect = OrigPPU.OBJNameSelect; PPU.OBJSizeSelect = OrigPPU.OBJSizeSelect; PPU.OBJNameBase = OrigPPU.OBJNameBase; PPU.OAMReadFlip = OrigPPU.OAMReadFlip; memmove (PPU.OAMData, OrigPPU.OAMData, sizeof (PPU.OAMData)); PPU.VTimerEnabled = OrigPPU.VTimerEnabled; PPU.HTimerEnabled = OrigPPU.HTimerEnabled; PPU.HTimerPosition = OrigPPU.HTimerPosition; PPU.Mosaic = OrigPPU.Mosaic; memmove (PPU.BGMosaic, OrigPPU.BGMosaic, sizeof (PPU.BGMosaic)); PPU.Mode7HFlip = OrigPPU.Mode7HFlip; PPU.Mode7VFlip = OrigPPU.Mode7VFlip; PPU.Mode7Repeat = OrigPPU.Mode7Repeat; PPU.Window1Left = OrigPPU.Window1Left; PPU.Window1Right = OrigPPU.Window1Right; PPU.Window2Left = OrigPPU.Window2Left; PPU.Window2Right = OrigPPU.Window2Right; for (i = 0; i < 6; i++) { PPU.ClipWindowOverlapLogic [i] = OrigPPU.ClipWindowOverlapLogic [i]; PPU.ClipWindow1Enable [i] = OrigPPU.ClipWindow1Enable [i]; PPU.ClipWindow2Enable [i] = OrigPPU.ClipWindow2Enable [i]; PPU.ClipWindow1Inside [i] = OrigPPU.ClipWindow1Inside [i]; PPU.ClipWindow2Inside [i] = OrigPPU.ClipWindow2Inside [i]; } PPU.CGFLIPRead = OrigPPU.CGFLIPRead; PPU.Need16x8Mulitply = OrigPPU.Need16x8Mulitply; IPPU.ColorsChanged = TRUE; IPPU.OBJChanged = TRUE; S9xFixColourBrightness (); IPPU.RenderThisFrame = FALSE; if ((result = ReadBlock ("DMA:", OrigDMA, sizeof (OrigDMA), snap)) != SUCCESS) return (result); for (i = 0; i < 8; i++) { DMA[i].TransferDirection = OrigDMA[i].TransferDirection; DMA[i].AAddressFixed = OrigDMA[i].AAddressFixed; DMA[i].AAddressDecrement = OrigDMA[i].AAddressDecrement; DMA[i].TransferMode = OrigDMA[i].TransferMode; DMA[i].ABank = OrigDMA[i].ABank; DMA[i].AAddress = OrigDMA[i].AAddress; DMA[i].Address = OrigDMA[i].Address; DMA[i].BAddress = OrigDMA[i].BAddress; DMA[i].TransferBytes = OrigDMA[i].TransferBytes; DMA[i].HDMAIndirectAddressing = OrigDMA[i].HDMAIndirectAddressing; DMA[i].IndirectAddress = OrigDMA[i].IndirectAddress; DMA[i].IndirectBank = OrigDMA[i].IndirectBank; DMA[i].Repeat = OrigDMA[i].Repeat; DMA[i].LineCount = OrigDMA[i].LineCount; DMA[i].FirstLine = OrigDMA[i].FirstLine; } if ((result = ReadBlock ("VRA:", Memory.VRAM, 0x10000, snap)) != SUCCESS) return (result); if ((result = ReadBlock ("RAM:", Memory.RAM, 0x20000, snap)) != SUCCESS) return (result); if ((result = ReadBlock ("SRA:", Memory.SRAM, 0x10000, snap)) != SUCCESS) return (result); if ((result = ReadBlock ("FIL:", Memory.FillRAM, 0x8000, snap)) != SUCCESS) return (result); if (ReadBlock ("APU:", &OrigAPU, sizeof (OrigAPU), snap) == SUCCESS) { APU = *(struct SAPU *) &OrigAPU; if ((result = ReadBlock ("ARE:", &OrigAPURegisters, sizeof (OrigAPURegisters), snap)) != SUCCESS) return (result); APURegisters = *(struct SAPURegisters *) &OrigAPURegisters; if ((result = ReadBlock ("ARA:", IAPU.RAM, 0x10000, snap)) != SUCCESS) return (result); if ((result = ReadBlock ("SOU:", &OrigSoundData, sizeof (SOrigSoundData), snap)) != SUCCESS) return (result); SoundData.master_volume_left = OrigSoundData.master_volume_left; SoundData.master_volume_right = OrigSoundData.master_volume_right; SoundData.echo_volume_left = OrigSoundData.echo_volume_left; SoundData.echo_volume_right = OrigSoundData.echo_volume_right; SoundData.echo_enable = OrigSoundData.echo_enable; SoundData.echo_feedback = OrigSoundData.echo_feedback; SoundData.echo_ptr = OrigSoundData.echo_ptr; SoundData.echo_buffer_size = OrigSoundData.echo_buffer_size; SoundData.echo_write_enabled = OrigSoundData.echo_write_enabled; SoundData.echo_channel_enable = OrigSoundData.echo_channel_enable; SoundData.pitch_mod = OrigSoundData.pitch_mod; for (i = 0; i < 3; i++) SoundData.dummy [i] = OrigSoundData.dummy [i]; for (i = 0; i < NUM_CHANNELS; i++) { SoundData.channels [i].state = OrigSoundData.channels [i].state; SoundData.channels [i].type = OrigSoundData.channels [i].type; SoundData.channels [i].volume_left = OrigSoundData.channels [i].volume_left; SoundData.channels [i].volume_right = OrigSoundData.channels [i].volume_right; SoundData.channels [i].hertz = OrigSoundData.channels [i].frequency; SoundData.channels [i].count = OrigSoundData.channels [i].count; SoundData.channels [i].loop = OrigSoundData.channels [i].loop; SoundData.channels [i].envx = OrigSoundData.channels [i].envx; SoundData.channels [i].left_vol_level = OrigSoundData.channels [i].left_vol_level; SoundData.channels [i].right_vol_level = OrigSoundData.channels [i].right_vol_level; SoundData.channels [i].envx_target = OrigSoundData.channels [i].envx_target; SoundData.channels [i].env_error = OrigSoundData.channels [i].env_error; SoundData.channels [i].erate = OrigSoundData.channels [i].erate; SoundData.channels [i].direction = OrigSoundData.channels [i].direction; SoundData.channels [i].attack_rate = OrigSoundData.channels [i].attack_rate; SoundData.channels [i].decay_rate = OrigSoundData.channels [i].decay_rate; SoundData.channels [i].sustain_rate = OrigSoundData.channels [i].sustain_rate; SoundData.channels [i].release_rate = OrigSoundData.channels [i].release_rate; SoundData.channels [i].sustain_level = OrigSoundData.channels [i].sustain_level; SoundData.channels [i].sample = OrigSoundData.channels [i].sample; for (j = 0; j < 16; j++) SoundData.channels [i].decoded [j] = OrigSoundData.channels [i].decoded [j]; for (j = 0; j < 2; j++) SoundData.channels [i].previous [j] = OrigSoundData.channels [i].previous [j]; SoundData.channels [i].sample_number = OrigSoundData.channels [i].sample_number; SoundData.channels [i].last_block = OrigSoundData.channels [i].last_block; SoundData.channels [i].needs_decode = OrigSoundData.channels [i].needs_decode; SoundData.channels [i].block_pointer = OrigSoundData.channels [i].block_pointer; SoundData.channels [i].sample_pointer = OrigSoundData.channels [i].sample_pointer; SoundData.channels [i].mode = OrigSoundData.channels [i].mode; } S9xSetSoundMute (FALSE); IAPU.PC = IAPU.RAM + APURegisters.PC; S9xAPUUnpackStatus (); if (APUCheckDirectPage ()) IAPU.DirectPage = IAPU.RAM + 0x100; else IAPU.DirectPage = IAPU.RAM; Settings.APUEnabled = TRUE; IAPU.APUExecuting = TRUE; } else { Settings.APUEnabled = FALSE; IAPU.APUExecuting = FALSE; S9xSetSoundMute (TRUE); } S9xFixSoundAfterSnapshotLoad (1); ICPU.ShiftedPB = Registers.PB << 16; ICPU.ShiftedDB = Registers.DB << 16; S9xSetPCBase (ICPU.ShiftedPB + Registers.PC); S9xUnpackStatus (); S9xFixCycles (); S9xReschedule (); return (SUCCESS); }
int S9xMovieOpen (const char* filename, bool8 read_only, uint8 sync_flags, uint8 sync_flags2) { FILE* fd; STREAM stream; int result; int fn; char movie_filename [_MAX_PATH]; #ifdef WIN32 _fullpath(movie_filename, filename, _MAX_PATH); #else strcpy(movie_filename, filename); #endif if(!(fd=fopen(movie_filename, "rb+"))) if(!(fd=fopen(movie_filename, "rb"))) return FILE_NOT_FOUND; else read_only = TRUE; const bool8 wasPaused = Settings.Paused; const uint32 prevFrameTime = Settings.FrameTime; // stop current movie before opening change_state(MOVIE_STATE_NONE); // read header if((result=read_movie_header(fd, &Movie))!=SUCCESS) { fclose(fd); return result; } read_movie_extrarominfo(fd, &Movie); fn=dup(fileno(fd)); fclose(fd); // apparently this lseek is necessary lseek(fn, Movie.SaveStateOffset, SEEK_SET); if(!(stream=REOPEN_STREAM(fn, "rb"))) return FILE_NOT_FOUND; // store previous, before changing to the movie's settings store_previous_settings(); // store default if (sync_flags & MOVIE_SYNC_DATA_EXISTS) { Settings.UseWIPAPUTiming = (sync_flags & MOVIE_SYNC_WIP1TIMING) ? TRUE : FALSE; Settings.SoundEnvelopeHeightReading = (sync_flags & MOVIE_SYNC_VOLUMEENVX) ? TRUE : FALSE; Settings.FakeMuteFix = (sync_flags & MOVIE_SYNC_FAKEMUTE) ? TRUE : FALSE; Settings.UpAndDown = (sync_flags & MOVIE_SYNC_LEFTRIGHT) ? TRUE : FALSE; // doesn't actually affect synchronization Settings.SoundSync = (sync_flags & MOVIE_SYNC_SYNCSOUND) ? TRUE : FALSE; // doesn't seem to affect synchronization Settings.InitFastROMSetting = (sync_flags2 & MOVIE_SYNC2_INIT_FASTROM) ? TRUE : FALSE; //Settings.ShutdownMaster = (sync_flags & MOVIE_SYNC_NOCPUSHUTDOWN) ? FALSE : TRUE; } // set from movie restore_movie_settings(); if(Movie.Opts & MOVIE_OPT_FROM_RESET) { Movie.State = MOVIE_STATE_PLAY; // prevent NSRT controller switching (in S9xPostRomInit) if(!Memory.LoadLastROM()) S9xReset(); Memory.ClearSRAM(false); // in case the SRAM read fails Movie.State = MOVIE_STATE_NONE; // save only SRAM for a from-reset snapshot result=(READ_STREAM(Memory.SRAM, 0x20000, stream) == 0x20000) ? SUCCESS : WRONG_FORMAT; } else { result=S9xUnfreezeFromStream(stream); } CLOSE_STREAM(stream); if(result!=SUCCESS) { return result; } if(!(fd=fopen(movie_filename, "rb+"))) if(!(fd=fopen(movie_filename, "rb"))) return FILE_NOT_FOUND; else read_only = TRUE; if(fseek(fd, Movie.ControllerDataOffset, SEEK_SET)) return WRONG_FORMAT; // read controller data Movie.File=fd; Movie.BytesPerFrame=bytes_per_frame(); Movie.InputBufferPtr=Movie.InputBuffer; uint32 to_read=Movie.BytesPerFrame * (Movie.MaxFrame+1); reserve_buffer_space(to_read); fread(Movie.InputBufferPtr, 1, to_read, fd); // read "baseline" controller data if(Movie.MaxFrame) read_frame_controller_data(); strncpy(Movie.Filename, movie_filename, _MAX_PATH); Movie.Filename[_MAX_PATH-1]='\0'; Movie.CurrentFrame=0; Movie.ReadOnly=read_only; change_state(MOVIE_STATE_PLAY); Settings.Paused = wasPaused; Settings.FrameTime = prevFrameTime; // restore emulation speed Movie.RecordedThisSession = false; S9xUpdateFrameCounter(-1); Movie.RequiresReset = false; S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_REPLAY); return SUCCESS; }
void VideoLogger(void *pixels, int width, int height, int depth, int bytes_per_line) { int fc = S9xMovieGetFrameCounter(); if (fc > 0) framecounter = fc; else framecounter++; if (video) { int i; char *data = (char*)pixels; static int lastwidth = width; // first resolution static int lastheight = height; if (lastwidth != width || lastheight != height) // this is just for informing the encoder that something has changed { printf("Frame %d, resolution changed from %dx%d to %dx%d!\n", fc, lastwidth, lastheight, width, height); lastwidth = width; lastheight = height; } for (i=0; i < height; i++) fwrite(data + i*bytes_per_line, depth, width, video); fflush(video); fflush(audio); drift++; if (maxframes > 0 && __builtin_expect((unsigned)framecounter >= maxframes, 0)) { printf("-maxframes hit\ndrift:%d\n",drift); S9xExit(); } } if (Settings.DisplayPressedKeys==1 || keypressscreen) { uint16 MovieGetJoypad(int i); int buttons = MovieGetJoypad(0); static char buffer[128]; // This string spacing pattern is optimized for the 256 pixel wide screen. sprintf(buffer, "%s %s %s %s %s %s %c%c%c%c%c%c", buttons & SNES_START_MASK ? "Start" : "_____", buttons & SNES_SELECT_MASK ? "Select" : "______", buttons & SNES_UP_MASK ? "Up" : "__", buttons & SNES_DOWN_MASK ? "Down" : "____", buttons & SNES_LEFT_MASK ? "Left" : "____", buttons & SNES_RIGHT_MASK ? "Right" : "_____", buttons & SNES_A_MASK ? 'A':'_', buttons & SNES_B_MASK ? 'B':'_', buttons & SNES_X_MASK ? 'X':'_', buttons & SNES_Y_MASK ? 'Y':'_', buttons & SNES_TL_MASK ? 'L':'_', buttons & SNES_TR_MASK ? 'R':'_' /*framecounter*/); if (Settings.DisplayPressedKeys==1) fprintf(stderr, "%s %d \r", buffer, framecounter); //if (keypressscreen) S9xSetInfoString(buffer); } if (__builtin_expect(messageframe >= 0 && framecounter == messageframe, 0)) { S9xMessage(S9X_INFO, S9X_MOVIE_INFO, message); GFX.InfoStringTimeout = 300; messageframe = -1; } /* if (__builtin_expect(fastforwardpoint >= 0 && framecounter >= fastforwardpoint, 0)) { Settings.FramesToSkip = fastforwarddistance; fastforwardpoint = -1; }*/ }
static void finish_playback (void) { change_state(MOVIE_STATE_FINISHED); S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_END); }
void S9xExtraDisplayUsage (void) { S9xMessage(S9X_INFO, S9X_USAGE, "-fullscreen fullscreen mode (without scaling)"); S9xMessage(S9X_INFO, S9X_USAGE, ""); S9xMessage(S9X_INFO, S9X_USAGE, "-v1 Video mode: Blocky (default)"); S9xMessage(S9X_INFO, S9X_USAGE, "-v2 Video mode: TV"); S9xMessage(S9X_INFO, S9X_USAGE, "-v3 Video mode: Smooth"); S9xMessage(S9X_INFO, S9X_USAGE, "-v4 Video mode: SuperEagle"); S9xMessage(S9X_INFO, S9X_USAGE, "-v5 Video mode: 2xSaI"); S9xMessage(S9X_INFO, S9X_USAGE, "-v6 Video mode: Super2xSaI"); S9xMessage(S9X_INFO, S9X_USAGE, "-v7 Video mode: EPX"); S9xMessage(S9X_INFO, S9X_USAGE, "-v8 Video mode: hq2x"); S9xMessage(S9X_INFO, S9X_USAGE, ""); }
char * S9xParseArgs (char **argv, int argc) { for (int i = 1; i < argc; i++) { if (*argv[i] == '-') { if (!strcasecmp(argv[i], "-help")) S9xUsage(); else // SOUND OPTIONS if (!strcasecmp(argv[i], "-soundsync")) Settings.SoundSync = TRUE; else if (!strcasecmp(argv[i], "-playbackrate")) { if (i + 1 < argc) { Settings.SoundPlaybackRate = atoi(argv[++i]); if (Settings.SoundPlaybackRate < 8192) Settings.SoundPlaybackRate = 8192; } else S9xUsage(); } else if (!strcasecmp(argv[i], "-inputrate")) { if (i + 1 < argc) { Settings.SoundInputRate = atoi(argv[++i]); if (Settings.SoundInputRate < 8192) Settings.SoundInputRate = 8192; } else S9xUsage(); } else if (!strcasecmp(argv[i], "-reversestereo")) Settings.ReverseStereo = TRUE; else if (!strcasecmp(argv[i], "-nostereo")) Settings.Stereo = FALSE; else if (!strcasecmp(argv[i], "-eightbit")) Settings.SixteenBitSound = FALSE; else if (!strcasecmp(argv[i], "-mute")) Settings.Mute = TRUE; else // DISPLAY OPTIONS if (!strcasecmp(argv[i], "-displayframerate")) Settings.DisplayFrameRate = TRUE; else if (!strcasecmp(argv[i], "-displaykeypress")) Settings.DisplayPressedKeys = TRUE; else if (!strcasecmp(argv[i], "-nohires")) Settings.SupportHiRes = FALSE; else if (!strcasecmp(argv[i], "-notransparency")) Settings.Transparency = FALSE; else if (!strcasecmp(argv[i], "-nowindows")) Settings.DisableGraphicWindows = TRUE; else // CONTROLLER OPTIONS if (!strcasecmp(argv[i], "-nomp5")) Settings.MultiPlayer5Master = FALSE; else if (!strcasecmp(argv[i], "-nomouse")) Settings.MouseMaster = FALSE; else if (!strcasecmp(argv[i], "-nosuperscope")) Settings.SuperScopeMaster = FALSE; else if (!strcasecmp(argv[i], "-nojustifier")) Settings.JustifierMaster = FALSE; else if (!strcasecmp(argv[i], "-port1") || !strcasecmp(argv[i], "-port2")) { if (i + 1 < argc) { i++; if (!parse_controller_spec(argv[i - 1][5] - '1', argv[i])) S9xUsage(); } else S9xUsage(); } else // ROM OPTIONS if (!strcasecmp(argv[i], "-hirom")) Settings.ForceHiROM = TRUE; else if (!strcasecmp(argv[i], "-lorom")) Settings.ForceLoROM = TRUE; else if (!strcasecmp(argv[i], "-ntsc")) Settings.ForceNTSC = TRUE; else if (!strcasecmp(argv[i], "-pal")) Settings.ForcePAL = TRUE; else if (!strcasecmp(argv[i], "-nointerleave")) Settings.ForceNotInterleaved = TRUE; else if (!strcasecmp(argv[i], "-interleaved")) Settings.ForceInterleaved = TRUE; else if (!strcasecmp(argv[i], "-interleaved2")) Settings.ForceInterleaved2 = TRUE; else if (!strcasecmp(argv[i], "-interleavedgd24")) Settings.ForceInterleaveGD24 = TRUE; else if (!strcasecmp(argv[i], "-noheader")) Settings.ForceNoHeader = TRUE; else if (!strcasecmp(argv[i], "-header")) Settings.ForceHeader = TRUE; else if (!strcasecmp(argv[i], "-bsxbootup")) Settings.BSXBootup = TRUE; else // PATCH/CHEAT OPTIONS if (!strcasecmp(argv[i], "-nopatch")) Settings.NoPatch = TRUE; else if (!strcasecmp(argv[i], "-cheat")) Settings.ApplyCheats = TRUE; else if (!strcasecmp(argv[i], "-gamegenie")) { if (i + 1 < argc) { uint32 address; uint8 byte; const char *error; if ((error = S9xGameGenieToRaw(argv[++i], address, byte)) == NULL) S9xAddCheat(TRUE, FALSE, address, byte); else S9xMessage(S9X_ERROR, S9X_GAME_GENIE_CODE_ERROR, error); } else S9xUsage(); } else if (!strcasecmp(argv[i], "-actionreplay")) { if (i + 1 < argc) { uint32 address; uint8 byte; const char *error; if ((error = S9xProActionReplayToRaw(argv[++i], address, byte)) == NULL) S9xAddCheat(TRUE, FALSE, address, byte); else S9xMessage(S9X_ERROR, S9X_ACTION_REPLY_CODE_ERROR, error); } else S9xUsage(); } else if (!strcasecmp(argv[i], "-goldfinger")) { if (i + 1 < argc) { uint32 address; uint8 bytes[3]; bool8 sram; uint8 num_bytes; const char *error; if ((error = S9xGoldFingerToRaw(argv[++i], address, sram, num_bytes, bytes)) == NULL) { for (int c = 0; c < num_bytes; c++) S9xAddCheat(TRUE, FALSE, address + c, bytes[c]); } else S9xMessage(S9X_ERROR, S9X_GOLD_FINGER_CODE_ERROR, error); } else S9xUsage(); } else // NETPLAY OPTIONS #ifdef NETPLAY_SUPPORT if (!strcasecmp(argv[i], "-net")) Settings.NetPlay = TRUE; else if (!strcasecmp(argv[i], "-port")) { if (i + 1 < argc) Settings.Port = -atoi(argv[++i]); else S9xUsage(); } else if (!strcasecmp(argv[i], "-server")) { if (i + 1 < argc) { strncpy(Settings.ServerName, argv[++i], 127); Settings.ServerName[127] = 0; } else S9xUsage(); } else #endif // HACKING OR DEBUGGING OPTIONS #ifdef DEBUGGER if (!strcasecmp(argv[i], "-debug")) CPU.Flags |= DEBUG_MODE_FLAG; else if (!strcasecmp(argv[i], "-trace")) { ENSURE_TRACE_OPEN(trace,"trace.log","wb") CPU.Flags |= TRACE_FLAG; } else #endif if (!strcasecmp(argv[i], "-hdmatiming")) { if (i + 1 < argc) { int p = atoi(argv[++i]); if (p > 0 && p < 200) Settings.HDMATimingHack = p; } else S9xUsage(); } else if (!strcasecmp(argv[i], "-invalidvramaccess")) Settings.BlockInvalidVRAMAccessMaster = FALSE; else // OTHER OPTIONS if (!strcasecmp(argv[i], "-frameskip")) { if (i + 1 < argc) Settings.SkipFrames = atoi(argv[++i]) + 1; else S9xUsage(); } else if (!strcasecmp(argv[i], "-frametime")) { if (i + 1 < argc) Settings.FrameTimePAL = Settings.FrameTimeNTSC = atoi(argv[++i]); else S9xUsage(); } else if (!strcasecmp(argv[i], "-upanddown")) Settings.UpAndDown = TRUE; else if (!strcasecmp(argv[i], "-conf")) { if (++i >= argc) S9xUsage(); // Else do nothing, S9xLoadConfigFiles() handled it. } else if (!strcasecmp(argv[i], "-nostdconf")) { // Do nothing, S9xLoadConfigFiles() handled it. } else S9xParseArg(argv, i, argc); } else rom_filename = argv[i]; } S9xVerifyControllers(); return (rom_filename); }
void S9xGenerateSound (void) { S9xMessage (0,0,"generate sound"); return; }
bool8 S9xReadMousePosition (int /* which1 */, int &/* x */, int & /* y */, uint32 & /* buttons */) { S9xMessage (0,0,"read mouse"); return (FALSE); }
const char *S9xGetSnapshotDirectory(void) { S9xMessage (0,0,"get snapshot dir"); return "."; }
char *osd_GetPackDir(void) { S9xMessage (0,0,"get pack dir"); return "."; }
void erk (void) { S9xMessage (0,0, "Erk!"); }
int S9xMovieOpen (const char* filename, bool8 read_only) { FILE* fd; STREAM stream; int result; int fn; if(!(fd=fopen(filename, read_only ? "rb" : "rb+"))) return FILE_NOT_FOUND; // stop current movie before opening change_state(MOVIE_STATE_NONE); // read header if((result=read_movie_header(fd, &Movie))!=SUCCESS) { fclose(fd); return result; } fn=dup(fileno(fd)); fclose(fd); // apparently this lseek is necessary lseek(fn, Movie.SaveStateOffset, SEEK_SET); if(!(stream=REOPEN_STREAM(fn, "rb"))) return FILE_NOT_FOUND; if(Movie.Opts & MOVIE_OPT_FROM_RESET) { S9xReset(); // save only SRAM for a from-reset snapshot result=(READ_STREAM(SRAM, 0x20000, stream) == 0x20000) ? SUCCESS : WRONG_FORMAT; } else { result=S9xUnfreezeFromStream(stream); } CLOSE_STREAM(stream); if(result!=SUCCESS) { return result; } if(!(fd=fopen(filename, read_only ? "rb" : "rb+"))) return FILE_NOT_FOUND; if(fseek(fd, Movie.ControllerDataOffset, SEEK_SET)) return WRONG_FORMAT; // read controller data Movie.File=fd; Movie.BytesPerFrame=bytes_per_frame(); Movie.InputBufferPtr=Movie.InputBuffer; uint32 to_read=Movie.BytesPerFrame * (Movie.MaxFrame+1); reserve_buffer_space(to_read); fread(Movie.InputBufferPtr, 1, to_read, fd); // read "baseline" controller data read_frame_controller_data(); strncpy(Movie.Filename, filename, _MAX_PATH); Movie.Filename[_MAX_PATH-1]='\0'; Movie.CurrentFrame=0; Movie.ReadOnly=read_only; change_state(MOVIE_STATE_PLAY); S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_REPLAY); return SUCCESS; }
const char *S9xGetFilenameInc (const char *e) { S9xMessage (0,0,"get filename inc"); return e; }
void S9xUsage (void) { /* 12345678901234567890123456789012345678901234567890123456789012345678901234567890 */ S9xMessage(S9X_INFO, S9X_USAGE, ""); S9xMessage(S9X_INFO, S9X_USAGE, "Snes9x " VERSION); S9xMessage(S9X_INFO, S9X_USAGE, ""); S9xMessage(S9X_INFO, S9X_USAGE, "usage: snes9x [options] <ROM image filename>"); S9xMessage(S9X_INFO, S9X_USAGE, ""); // SOUND OPTIONS S9xMessage(S9X_INFO, S9X_USAGE, "-soundsync Synchronize sound as far as possible"); S9xMessage(S9X_INFO, S9X_USAGE, "-playbackrate <Hz> Set sound playback rate"); S9xMessage(S9X_INFO, S9X_USAGE, "-inputrate <Hz> Set sound input rate"); S9xMessage(S9X_INFO, S9X_USAGE, "-reversestereo Reverse stereo sound output"); S9xMessage(S9X_INFO, S9X_USAGE, "-nostereo Disable stereo sound output"); S9xMessage(S9X_INFO, S9X_USAGE, "-eightbit Use 8bit sound instead of 16bit"); S9xMessage(S9X_INFO, S9X_USAGE, "-mute Mute sound"); S9xMessage(S9X_INFO, S9X_USAGE, ""); // DISPLAY OPTIONS S9xMessage(S9X_INFO, S9X_USAGE, "-displayframerate Display the frame rate counter"); S9xMessage(S9X_INFO, S9X_USAGE, "-displaykeypress Display input of all controllers and peripherals"); S9xMessage(S9X_INFO, S9X_USAGE, "-nohires (Not recommended) Disable support for hi-res and"); S9xMessage(S9X_INFO, S9X_USAGE, " interlace modes"); S9xMessage(S9X_INFO, S9X_USAGE, "-notransparency (Not recommended) Disable transparency effects"); S9xMessage(S9X_INFO, S9X_USAGE, "-nowindows (Not recommended) Disable graphic window effects"); S9xMessage(S9X_INFO, S9X_USAGE, ""); // CONTROLLER OPTIONS S9xMessage(S9X_INFO, S9X_USAGE, "-nomp5 Disable emulation of the Multiplayer 5 adapter"); S9xMessage(S9X_INFO, S9X_USAGE, "-nomouse Disable emulation of the SNES mouse"); S9xMessage(S9X_INFO, S9X_USAGE, "-nosuperscope Disable emulation of the Superscope"); S9xMessage(S9X_INFO, S9X_USAGE, "-nojustifier Disable emulation of the Konami Justifier"); S9xMessage(S9X_INFO, S9X_USAGE, "-port# <control> Specify which controller to emulate in port 1/2"); S9xMessage(S9X_INFO, S9X_USAGE, " Controllers: none No controller"); S9xMessage(S9X_INFO, S9X_USAGE, " pad# Joypad number 1-8"); S9xMessage(S9X_INFO, S9X_USAGE, " mouse# Mouse number 1-2"); S9xMessage(S9X_INFO, S9X_USAGE, " superscope Superscope (not useful with -port1)"); S9xMessage(S9X_INFO, S9X_USAGE, " justifier Blue Justifier (not useful with -port1)"); S9xMessage(S9X_INFO, S9X_USAGE, " two-justifiers Blue & Pink Justifiers"); S9xMessage(S9X_INFO, S9X_USAGE, " mp5:#### MP5 with the 4 named pads (1-8 or n)"); S9xMessage(S9X_INFO, S9X_USAGE, ""); // ROM OPTIONS S9xMessage(S9X_INFO, S9X_USAGE, "-hirom Force Hi-ROM memory map"); S9xMessage(S9X_INFO, S9X_USAGE, "-lorom Force Lo-ROM memory map"); S9xMessage(S9X_INFO, S9X_USAGE, "-ntsc Force NTSC timing (60 frames/sec)"); S9xMessage(S9X_INFO, S9X_USAGE, "-pal Force PAL timing (50 frames/sec)"); S9xMessage(S9X_INFO, S9X_USAGE, "-nointerleave Assume the ROM image is not in interleaved"); S9xMessage(S9X_INFO, S9X_USAGE, " format"); S9xMessage(S9X_INFO, S9X_USAGE, "-interleaved Assume the ROM image is in interleaved format"); S9xMessage(S9X_INFO, S9X_USAGE, "-interleaved2 Assume the ROM image is in interleaved 2 format"); S9xMessage(S9X_INFO, S9X_USAGE, "-interleavedgd24 Assume the ROM image is in interleaved gd24"); S9xMessage(S9X_INFO, S9X_USAGE, " format"); S9xMessage(S9X_INFO, S9X_USAGE, "-noheader Assume the ROM image doesn't have a header of a"); S9xMessage(S9X_INFO, S9X_USAGE, " copier"); S9xMessage(S9X_INFO, S9X_USAGE, "-header Assume the ROM image has a header of a copier"); S9xMessage(S9X_INFO, S9X_USAGE, "-bsxbootup Boot up BS games from BS-X"); S9xMessage(S9X_INFO, S9X_USAGE, ""); // PATCH/CHEAT OPTIONS S9xMessage(S9X_INFO, S9X_USAGE, "-nopatch Do not apply any available IPS/UPS patches"); S9xMessage(S9X_INFO, S9X_USAGE, "-cheat Apply saved cheats"); S9xMessage(S9X_INFO, S9X_USAGE, "-gamegenie <code> Supply a Game Genie code"); S9xMessage(S9X_INFO, S9X_USAGE, "-actionreplay <code> Supply a Pro-Action Reply code"); S9xMessage(S9X_INFO, S9X_USAGE, "-goldfinger <code> Supply a Gold Finger code"); S9xMessage(S9X_INFO, S9X_USAGE, ""); #ifdef NETPLAY_SUPPORT // NETPLAY OPTIONS S9xMessage(S9X_INFO, S9X_USAGE, "-net Enable netplay"); S9xMessage(S9X_INFO, S9X_USAGE, "-port <num> Use port <num> for netplay (use with -net)"); S9xMessage(S9X_INFO, S9X_USAGE, "-server <string> Use the specified server for netplay"); S9xMessage(S9X_INFO, S9X_USAGE, " (use with -net)"); S9xMessage(S9X_INFO, S9X_USAGE, ""); #endif // HACKING OR DEBUGGING OPTIONS #ifdef DEBUGGER S9xMessage(S9X_INFO, S9X_USAGE, "-debug Set the Debugger flag"); S9xMessage(S9X_INFO, S9X_USAGE, "-trace Begin CPU instruction tracing"); #endif S9xMessage(S9X_INFO, S9X_USAGE, "-hdmatiming <1-199> (Not recommended) Changes HDMA transfer timings"); S9xMessage(S9X_INFO, S9X_USAGE, " event comes"); S9xMessage(S9X_INFO, S9X_USAGE, "-invalidvramaccess (Not recommended) Allow invalid VRAM access"); S9xMessage(S9X_INFO, S9X_USAGE, ""); // OTHER OPTIONS S9xMessage(S9X_INFO, S9X_USAGE, "-frameskip <num> Screen update frame skip rate"); S9xMessage(S9X_INFO, S9X_USAGE, "-frametime <num> Milliseconds per frame for frameskip auto-adjust"); S9xMessage(S9X_INFO, S9X_USAGE, "-upanddown Override protection from pressing left+right or"); S9xMessage(S9X_INFO, S9X_USAGE, " up+down together"); S9xMessage(S9X_INFO, S9X_USAGE, "-conf <filename> Use specified conf file (after standard files)"); S9xMessage(S9X_INFO, S9X_USAGE, "-nostdconf Do not load the standard config files"); S9xMessage(S9X_INFO, S9X_USAGE, ""); S9xExtraUsage(); S9xMessage(S9X_INFO, S9X_USAGE, ""); S9xMessage(S9X_INFO, S9X_USAGE, "ROM image can be compressed with zip, gzip, JMA, or compress."); exit(1); }
void S9xExtraDisplayUsage (void) { /* 12345678901234567890123456789012345678901234567890123456789012345678901234567890 */ S9xMessage(S9X_INFO, S9X_USAGE, "-setrepeat Allow altering keyboard auto-repeat"); S9xMessage(S9X_INFO, S9X_USAGE, ""); S9xMessage(S9X_INFO, S9X_USAGE, "-v1 Video mode: Blocky (default)"); S9xMessage(S9X_INFO, S9X_USAGE, "-v2 Video mode: TV"); S9xMessage(S9X_INFO, S9X_USAGE, "-v3 Video mode: Smooth"); S9xMessage(S9X_INFO, S9X_USAGE, "-v4 Video mode: SuperEagle"); S9xMessage(S9X_INFO, S9X_USAGE, "-v5 Video mode: 2xSaI"); S9xMessage(S9X_INFO, S9X_USAGE, "-v6 Video mode: Super2xSaI"); S9xMessage(S9X_INFO, S9X_USAGE, "-v7 Video mode: EPX"); S9xMessage(S9X_INFO, S9X_USAGE, "-v8 Video mode: hq2x"); S9xMessage(S9X_INFO, S9X_USAGE, ""); }
void NPServerProcessInput (void) { static uint8 header = 0; static uint32 pos = 0; KeyMap myKeys; if (npserver.phasecount == 0) { for (int c = 1; c <= NP_MAX_CLIENTS; c++) if (npplayer[c].ready) sem_wait(sememu[c]); for (uint32 j = 0; j < npserver.phasespan; j++) nprecvpad[0][j] = npcachpad[j]; for (int i = 0; i < npserver.numplayers; i++) { for (uint32 j = 0; j < npserver.phasespan; j++) { npactvpad[i][j] = npsendpad[i][j]; npsendpad[i][j] = nprecvpad[i][j]; } } if (npserver.header & 0x80) { for (int i = 0; i < npserver.numplayers; i++) { npactvpad[i][npserver.phasespan] = 0; npsendpad[i][npserver.phasespan] = 0; } npserver.phasespan++; if (npserver.phasespan > (uint32) Memory.ROMFramesPerSecond) npserver.phasespan = (uint32) Memory.ROMFramesPerSecond; char str[256]; sprintf(str, "delay: %d", npserver.phasespan); S9xMessage(0, 0, str); } else if (npserver.header & 0x40) { npserver.phasespan--; if (npserver.phasespan == 0) npserver.phasespan = 1; char str[256]; sprintf(str, "delay: %d", npserver.phasespan); S9xMessage(0, 0, str); } npserver.header = header; header = 0; pos = 0; } for (int i = 0; i < npserver.numplayers; i++) { controlPad[i] = npactvpad[i][pos]; ControlPadFlagsToS9xReportButtons(i, controlPad[i]); } GetKeys(myKeys); if (ISpKeyIsPressed(kISpEsc) || KeyIsPressed(myKeys, keyCode[kKeyEsc])) { if (s9xthreadrunning) { if (!eventQueued) { PostQueueToSubEventLoop(); eventQueued = true; } } else running = false; return; } uint32 pad = 0; JoypadScanDirection(0, &pad); if (ISpKeyIsPressed(kISp1PR )) pad |= 0x0010; if (ISpKeyIsPressed(kISp1PL )) pad |= 0x0020; if (ISpKeyIsPressed(kISp1PX )) pad |= 0x0040; if (ISpKeyIsPressed(kISp1PA )) pad |= 0x0080; if (ISpKeyIsPressed(kISp1PStart )) pad |= 0x1000; if (ISpKeyIsPressed(kISp1PSelect)) pad |= 0x2000; if (ISpKeyIsPressed(kISp1PY )) pad |= 0x4000; if (ISpKeyIsPressed(kISp1PB )) pad |= 0x8000; if (KeyIsPressed(myKeys, keyCode[k1PR] )) pad |= 0x0010; if (KeyIsPressed(myKeys, keyCode[k1PL] )) pad |= 0x0020; if (KeyIsPressed(myKeys, keyCode[k1PX] )) pad |= 0x0040; if (KeyIsPressed(myKeys, keyCode[k1PA] )) pad |= 0x0080; if (KeyIsPressed(myKeys, keyCode[k1PRight] )) pad |= 0x0100; if (KeyIsPressed(myKeys, keyCode[k1PLeft] )) pad |= 0x0200; if (KeyIsPressed(myKeys, keyCode[k1PDown] )) pad |= 0x0400; if (KeyIsPressed(myKeys, keyCode[k1PUp] )) pad |= 0x0800; if (KeyIsPressed(myKeys, keyCode[k1PStart] )) pad |= 0x1000; if (KeyIsPressed(myKeys, keyCode[k1PSelect])) pad |= 0x2000; if (KeyIsPressed(myKeys, keyCode[k1PY] )) pad |= 0x4000; if (KeyIsPressed(myKeys, keyCode[k1PB] )) pad |= 0x8000; npcachpad[pos] = pad; if (KeyIsPressed(myKeys, keyCode[k2PR])) header |= 0x80; if (KeyIsPressed(myKeys, keyCode[k2PL])) header |= 0x40; if (npserver.phasecount == 0) { npserver.phasecount = npserver.phasespan; for (int c = 1; c <= NP_MAX_CLIENTS; c++) if (npplayer[c].ready) sem_post(sempad[c]); } npserver.phasecount--; pos++; }
//const char* S9xGetFilenameInc (const char* e) const char* S9xGetFilenameInc (const char* inExt, enum s9x_getdirtype dirtype) { S9xMessage (0,0,"get filename inc"); //return e; return inExt; }
int S9xMovieOpen (const char* filename, bool8 read_only) { FILE* fd; STREAM stream; int result; int fn; char movie_filename [_MAX_PATH]; #ifdef __WIN32__ _fullpath(movie_filename, filename, _MAX_PATH); #else strcpy(movie_filename, filename); #endif if(!(fd=fopen(movie_filename, "rb+"))) if(!(fd=fopen(movie_filename, "rb"))) return FILE_NOT_FOUND; else read_only = TRUE; const bool8 wasPaused = Settings.Paused; // stop current movie before opening change_state(MOVIE_STATE_NONE); // read header if((result=read_movie_header(fd, &Movie))!=SUCCESS) { fclose(fd); return result; } read_movie_extrarominfo(fd, &Movie); fn=dup(fileno(fd)); fclose(fd); // apparently this lseek is necessary lseek(fn, Movie.SaveStateOffset, SEEK_SET); if(!(stream=REOPEN_STREAM(fn, "rb"))) return FILE_NOT_FOUND; // store previous, before changing to the movie's settings store_previous_settings(); // set from movie restore_movie_settings(); if(Movie.Opts & MOVIE_OPT_FROM_RESET) { Movie.State = MOVIE_STATE_PLAY; // prevent NSRT controller switching (in S9xPostRomInit) if(!Memory.LoadLastROM()) S9xReset(); Memory.ClearSRAM(false); // in case the SRAM read fails Movie.State = MOVIE_STATE_NONE; S9xMovieResetControls(); // save only SRAM for a from-reset snapshot result=(READ_STREAM(Memory.SRAM, 0x20000, stream) == 0x20000) ? SUCCESS : WRONG_FORMAT; } else { result=S9xUnfreezeFromStream(stream); } CLOSE_STREAM(stream); if(result!=SUCCESS) { return result; } if(!(fd=fopen(movie_filename, "rb+"))) if(!(fd=fopen(movie_filename, "rb"))) return FILE_NOT_FOUND; else read_only = TRUE; if(fseek(fd, Movie.ControllerDataOffset, SEEK_SET)) return WRONG_FORMAT; // read controller data Movie.File=fd; Movie.BytesPerSample=bytes_per_sample(); Movie.InputBufferPtr=Movie.InputBuffer; uint32 to_read=Movie.BytesPerSample * (Movie.MaxSample+1); reserve_buffer_space(to_read); fread(Movie.InputBufferPtr, 1, to_read, fd); // read "baseline" controller data if(Movie.MaxSample && Movie.MaxFrame) read_frame_controller_data(true); strncpy(Movie.Filename, movie_filename, _MAX_PATH); Movie.Filename[_MAX_PATH-1]='\0'; Movie.CurrentFrame=0; Movie.CurrentSample=0; Movie.ReadOnly=read_only; change_state(MOVIE_STATE_PLAY); Settings.Paused = wasPaused; Movie.RecordedThisSession = false; S9xUpdateFrameCounter(-1); S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_REPLAY); return SUCCESS; }
bool8 S9xDoScreenshot (int width, int height) { Settings.TakeScreenshot = FALSE; #ifdef HAVE_LIBPNG FILE *fp; png_structp png_ptr; png_infop info_ptr; png_color_8 sig_bit; int imgwidth, imgheight; const char *fname; fname = S9xGetFilenameInc(".png", SCREENSHOT_DIR); fp = fopen(fname, "wb"); if (!fp) { S9xMessage(S9X_ERROR, 0, "Failed to take screenshot."); return (FALSE); } png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { fclose(fp); remove(fname); S9xMessage(S9X_ERROR, 0, "Failed to take screenshot."); return (FALSE); } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp) NULL); fclose(fp); remove(fname); S9xMessage(S9X_ERROR, 0, "Failed to take screenshot."); return (FALSE); } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); remove(fname); S9xMessage(S9X_ERROR, 0, "Failed to take screenshot."); return (FALSE); } imgwidth = width; imgheight = height; if (Settings.StretchScreenshots == 1) { if (width > SNES_WIDTH && height <= SNES_HEIGHT_EXTENDED) imgheight = height << 1; } else if (Settings.StretchScreenshots == 2) { if (width <= SNES_WIDTH) imgwidth = width << 1; if (height <= SNES_HEIGHT_EXTENDED) imgheight = height << 1; } png_init_io(png_ptr, fp); png_set_IHDR(png_ptr, info_ptr, imgwidth, imgheight, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); sig_bit.red = 5; sig_bit.green = 5; sig_bit.blue = 5; png_set_sBIT(png_ptr, info_ptr, &sig_bit); png_set_shift(png_ptr, &sig_bit); png_write_info(png_ptr, info_ptr); png_set_packing(png_ptr); png_byte *row_pointer = new png_byte[png_get_rowbytes(png_ptr, info_ptr)]; uint16 *screen = GFX.Screen; for (int y = 0; y < height; y++, screen += GFX.RealPPL) { png_byte *rowpix = row_pointer; for (int x = 0; x < width; x++) { uint32 r, g, b; DECOMPOSE_PIXEL(screen[x], r, g, b); *(rowpix++) = r; *(rowpix++) = g; *(rowpix++) = b; if (imgwidth != width) { *(rowpix++) = r; *(rowpix++) = g; *(rowpix++) = b; } } png_write_row(png_ptr, row_pointer); if (imgheight != height) png_write_row(png_ptr, row_pointer); } delete [] row_pointer; png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); fprintf(stderr, "%s saved.\n", fname); const char *base = S9xBasename(fname); sprintf(String, "Saved screenshot %s", base); S9xMessage(S9X_INFO, 0, String); return (TRUE); #else fprintf(stderr, "Screenshot support not available (libpng was not found at build time).\n"); return (FALSE); #endif }