mirror of https://github.com/snes9xgit/snes9x.git
Initial 1.52 import
This commit is contained in:
commit
d1666860e0
|
@ -0,0 +1,276 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _65C816_H_
|
||||
#define _65C816_H_
|
||||
|
||||
#define Carry 1
|
||||
#define Zero 2
|
||||
#define IRQ 4
|
||||
#define Decimal 8
|
||||
#define IndexFlag 16
|
||||
#define MemoryFlag 32
|
||||
#define Overflow 64
|
||||
#define Negative 128
|
||||
#define Emulation 256
|
||||
|
||||
#define SetCarry() (ICPU._Carry = 1)
|
||||
#define ClearCarry() (ICPU._Carry = 0)
|
||||
#define SetZero() (ICPU._Zero = 0)
|
||||
#define ClearZero() (ICPU._Zero = 1)
|
||||
#define SetIRQ() (Registers.PL |= IRQ)
|
||||
#define ClearIRQ() (Registers.PL &= ~IRQ)
|
||||
#define SetDecimal() (Registers.PL |= Decimal)
|
||||
#define ClearDecimal() (Registers.PL &= ~Decimal)
|
||||
#define SetIndex() (Registers.PL |= IndexFlag)
|
||||
#define ClearIndex() (Registers.PL &= ~IndexFlag)
|
||||
#define SetMemory() (Registers.PL |= MemoryFlag)
|
||||
#define ClearMemory() (Registers.PL &= ~MemoryFlag)
|
||||
#define SetOverflow() (ICPU._Overflow = 1)
|
||||
#define ClearOverflow() (ICPU._Overflow = 0)
|
||||
#define SetNegative() (ICPU._Negative = 0x80)
|
||||
#define ClearNegative() (ICPU._Negative = 0)
|
||||
|
||||
#define CheckCarry() (ICPU._Carry)
|
||||
#define CheckZero() (ICPU._Zero == 0)
|
||||
#define CheckIRQ() (Registers.PL & IRQ)
|
||||
#define CheckDecimal() (Registers.PL & Decimal)
|
||||
#define CheckIndex() (Registers.PL & IndexFlag)
|
||||
#define CheckMemory() (Registers.PL & MemoryFlag)
|
||||
#define CheckOverflow() (ICPU._Overflow)
|
||||
#define CheckNegative() (ICPU._Negative & 0x80)
|
||||
#define CheckEmulation() (Registers.P.W & Emulation)
|
||||
|
||||
#define SetFlags(f) (Registers.P.W |= (f))
|
||||
#define ClearFlags(f) (Registers.P.W &= ~(f))
|
||||
#define CheckFlag(f) (Registers.PL & (f))
|
||||
|
||||
typedef union
|
||||
{
|
||||
#ifdef LSB_FIRST
|
||||
struct { uint8 l, h; } B;
|
||||
#else
|
||||
struct { uint8 h, l; } B;
|
||||
#endif
|
||||
uint16 W;
|
||||
} pair;
|
||||
|
||||
typedef union
|
||||
{
|
||||
#ifdef LSB_FIRST
|
||||
struct { uint8 xPCl, xPCh, xPB, z; } B;
|
||||
struct { uint16 xPC, d; } W;
|
||||
#else
|
||||
struct { uint8 z, xPB, xPCh, xPCl; } B;
|
||||
struct { uint16 d, xPC; } W;
|
||||
#endif
|
||||
uint32 xPBPC;
|
||||
} PC_t;
|
||||
|
||||
struct SRegisters
|
||||
{
|
||||
uint8 DB;
|
||||
pair P;
|
||||
pair A;
|
||||
pair D;
|
||||
pair S;
|
||||
pair X;
|
||||
pair Y;
|
||||
PC_t PC;
|
||||
};
|
||||
|
||||
#define AL A.B.l
|
||||
#define AH A.B.h
|
||||
#define XL X.B.l
|
||||
#define XH X.B.h
|
||||
#define YL Y.B.l
|
||||
#define YH Y.B.h
|
||||
#define SL S.B.l
|
||||
#define SH S.B.h
|
||||
#define DL D.B.l
|
||||
#define DH D.B.h
|
||||
#define PL P.B.l
|
||||
#define PH P.B.h
|
||||
#define PBPC PC.xPBPC
|
||||
#define PCw PC.W.xPC
|
||||
#define PCh PC.B.xPCh
|
||||
#define PCl PC.B.xPCl
|
||||
#define PB PC.B.xPB
|
||||
|
||||
extern struct SRegisters Registers;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,564 @@
|
|||
// Core SPC emulation: CPU, timers, SMP registers, memory
|
||||
|
||||
// snes_spc 0.9.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "SNES_SPC.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Copyright (C) 2004-2007 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
#define RAM (m.ram.ram)
|
||||
#define REGS (m.smp_regs [0])
|
||||
#define REGS_IN (m.smp_regs [1])
|
||||
|
||||
// (n ? n : 256)
|
||||
#define IF_0_THEN_256( n ) ((uint8_t) ((n) - 1) + 1)
|
||||
|
||||
// Note: SPC_MORE_ACCURACY exists mainly so I can run my validation tests, which
|
||||
// do crazy echo buffer accesses.
|
||||
#ifndef SPC_MORE_ACCURACY
|
||||
#define SPC_MORE_ACCURACY 0
|
||||
#endif
|
||||
|
||||
#ifdef BLARGG_ENABLE_OPTIMIZER
|
||||
#include BLARGG_ENABLE_OPTIMIZER
|
||||
#endif
|
||||
|
||||
|
||||
//// Timers
|
||||
|
||||
#if SPC_DISABLE_TEMPO
|
||||
#define TIMER_DIV( t, n ) ((n) >> t->prescaler)
|
||||
#define TIMER_MUL( t, n ) ((n) << t->prescaler)
|
||||
#else
|
||||
#define TIMER_DIV( t, n ) ((n) / t->prescaler)
|
||||
#define TIMER_MUL( t, n ) ((n) * t->prescaler)
|
||||
#endif
|
||||
|
||||
SNES_SPC::Timer* SNES_SPC::run_timer_( Timer* t, rel_time_t time )
|
||||
{
|
||||
int elapsed = TIMER_DIV( t, time - t->next_time ) + 1;
|
||||
t->next_time += TIMER_MUL( t, elapsed );
|
||||
|
||||
if ( t->enabled )
|
||||
{
|
||||
int remain = IF_0_THEN_256( t->period - t->divider );
|
||||
int divider = t->divider + elapsed;
|
||||
int over = elapsed - remain;
|
||||
if ( over >= 0 )
|
||||
{
|
||||
int n = over / t->period;
|
||||
t->counter = (t->counter + 1 + n) & 0x0F;
|
||||
divider = over - n * t->period;
|
||||
}
|
||||
t->divider = (uint8_t) divider;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
inline SNES_SPC::Timer* SNES_SPC::run_timer( Timer* t, rel_time_t time )
|
||||
{
|
||||
if ( time >= t->next_time )
|
||||
t = run_timer_( t, time );
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
//// ROM
|
||||
|
||||
void SNES_SPC::enable_rom( int enable )
|
||||
{
|
||||
if ( m.rom_enabled != enable )
|
||||
{
|
||||
m.rom_enabled = enable;
|
||||
if ( enable )
|
||||
memcpy( m.hi_ram, &RAM [rom_addr], sizeof m.hi_ram );
|
||||
memcpy( &RAM [rom_addr], (enable ? m.rom : m.hi_ram), rom_size );
|
||||
// TODO: ROM can still get overwritten when DSP writes to echo buffer
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// DSP
|
||||
|
||||
#if SPC_LESS_ACCURATE
|
||||
int const max_reg_time = 29;
|
||||
|
||||
signed char const SNES_SPC::reg_times_ [256] =
|
||||
{
|
||||
-1, 0,-11,-10,-15,-11, -2, -2, 4, 3, 14, 14, 26, 26, 14, 22,
|
||||
2, 3, 0, 1,-12, 0, 1, 1, 7, 6, 14, 14, 27, 14, 14, 23,
|
||||
5, 6, 3, 4, -1, 3, 4, 4, 10, 9, 14, 14, 26, -5, 14, 23,
|
||||
8, 9, 6, 7, 2, 6, 7, 7, 13, 12, 14, 14, 27, -4, 14, 24,
|
||||
11, 12, 9, 10, 5, 9, 10, 10, 16, 15, 14, 14, -2, -4, 14, 24,
|
||||
14, 15, 12, 13, 8, 12, 13, 13, 19, 18, 14, 14, -2,-36, 14, 24,
|
||||
17, 18, 15, 16, 11, 15, 16, 16, 22, 21, 14, 14, 28, -3, 14, 25,
|
||||
20, 21, 18, 19, 14, 18, 19, 19, 25, 24, 14, 14, 14, 29, 14, 25,
|
||||
|
||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
||||
};
|
||||
|
||||
#define RUN_DSP( time, offset ) \
|
||||
int count = (time) - (offset) - m.dsp_time;\
|
||||
if ( count >= 0 )\
|
||||
{\
|
||||
int clock_count = (count & ~(clocks_per_sample - 1)) + clocks_per_sample;\
|
||||
m.dsp_time += clock_count;\
|
||||
dsp.run( clock_count );\
|
||||
}
|
||||
#else
|
||||
#define RUN_DSP( time, offset ) \
|
||||
{\
|
||||
int count = (time) - m.dsp_time;\
|
||||
if ( !SPC_MORE_ACCURACY || count )\
|
||||
{\
|
||||
assert( count > 0 );\
|
||||
m.dsp_time = (time);\
|
||||
dsp.run( count );\
|
||||
}\
|
||||
}
|
||||
#endif
|
||||
|
||||
int SNES_SPC::dsp_read( rel_time_t time )
|
||||
{
|
||||
RUN_DSP( time, reg_times [REGS [r_dspaddr] & 0x7F] );
|
||||
|
||||
int result = dsp.read( REGS [r_dspaddr] & 0x7F );
|
||||
|
||||
#ifdef SPC_DSP_READ_HOOK
|
||||
SPC_DSP_READ_HOOK( spc_time + time, (REGS [r_dspaddr] & 0x7F), result );
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void SNES_SPC::dsp_write( int data, rel_time_t time )
|
||||
{
|
||||
RUN_DSP( time, reg_times [REGS [r_dspaddr]] )
|
||||
#if SPC_LESS_ACCURATE
|
||||
else if ( m.dsp_time == skipping_time )
|
||||
{
|
||||
int r = REGS [r_dspaddr];
|
||||
if ( r == SPC_DSP::r_kon )
|
||||
m.skipped_kon |= data & ~dsp.read( SPC_DSP::r_koff );
|
||||
|
||||
if ( r == SPC_DSP::r_koff )
|
||||
{
|
||||
m.skipped_koff |= data;
|
||||
m.skipped_kon &= ~data;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SPC_DSP_WRITE_HOOK
|
||||
SPC_DSP_WRITE_HOOK( m.spc_time + time, REGS [r_dspaddr], (uint8_t) data );
|
||||
#endif
|
||||
|
||||
if ( REGS [r_dspaddr] <= 0x7F )
|
||||
dsp.write( REGS [r_dspaddr], data );
|
||||
else if ( !SPC_MORE_ACCURACY )
|
||||
dprintf( "SPC wrote to DSP register > $7F\n" );
|
||||
}
|
||||
|
||||
|
||||
//// Memory access extras
|
||||
|
||||
#if SPC_MORE_ACCURACY
|
||||
#define MEM_ACCESS( time, addr ) \
|
||||
{\
|
||||
if ( time >= m.dsp_time )\
|
||||
{\
|
||||
RUN_DSP( time, max_reg_time );\
|
||||
}\
|
||||
}
|
||||
#elif !defined (NDEBUG)
|
||||
// Debug-only check for read/write within echo buffer, since this might result in
|
||||
// inaccurate emulation due to the DSP not being caught up to the present.
|
||||
|
||||
bool SNES_SPC::check_echo_access( int addr )
|
||||
{
|
||||
if ( !(dsp.read( SPC_DSP::r_flg ) & 0x20) )
|
||||
{
|
||||
int start = 0x100 * dsp.read( SPC_DSP::r_esa );
|
||||
int size = 0x800 * (dsp.read( SPC_DSP::r_edl ) & 0x0F);
|
||||
int end = start + (size ? size : 4);
|
||||
if ( start <= addr && addr < end )
|
||||
{
|
||||
if ( !m.echo_accessed )
|
||||
{
|
||||
m.echo_accessed = 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#define MEM_ACCESS( time, addr ) check( !check_echo_access( (uint16_t) addr ) );
|
||||
#else
|
||||
#define MEM_ACCESS( time, addr )
|
||||
#endif
|
||||
|
||||
|
||||
//// CPU write
|
||||
|
||||
#if SPC_MORE_ACCURACY
|
||||
static unsigned char const glitch_probs [3] [256] =
|
||||
{
|
||||
0xC3,0x92,0x5B,0x1C,0xD1,0x92,0x5B,0x1C,0xDB,0x9C,0x72,0x18,0xCD,0x5C,0x38,0x0B,
|
||||
0xE1,0x9C,0x74,0x17,0xCF,0x75,0x45,0x0C,0xCF,0x6E,0x4A,0x0D,0xA3,0x3A,0x1D,0x08,
|
||||
0xDB,0xA0,0x82,0x19,0xD9,0x73,0x3C,0x0E,0xCB,0x76,0x52,0x0B,0xA5,0x46,0x1D,0x09,
|
||||
0xDA,0x74,0x55,0x0F,0xA2,0x3F,0x21,0x05,0x9A,0x40,0x20,0x07,0x63,0x1E,0x10,0x01,
|
||||
0xDF,0xA9,0x85,0x1D,0xD3,0x84,0x4B,0x0E,0xCF,0x6F,0x49,0x0F,0xB3,0x48,0x1E,0x05,
|
||||
0xD8,0x77,0x52,0x12,0xB7,0x49,0x23,0x06,0xAA,0x45,0x28,0x07,0x7D,0x28,0x0F,0x07,
|
||||
0xCC,0x7B,0x4A,0x0E,0xB2,0x4F,0x24,0x07,0xAD,0x43,0x2C,0x06,0x86,0x29,0x11,0x07,
|
||||
0xAE,0x48,0x1F,0x0A,0x76,0x21,0x19,0x05,0x76,0x21,0x14,0x05,0x44,0x11,0x0B,0x01,
|
||||
0xE7,0xAD,0x96,0x23,0xDC,0x86,0x59,0x0E,0xDC,0x7C,0x5F,0x15,0xBB,0x53,0x2E,0x09,
|
||||
0xD6,0x7C,0x4A,0x16,0xBB,0x4A,0x25,0x08,0xB3,0x4F,0x28,0x0B,0x8E,0x23,0x15,0x08,
|
||||
0xCF,0x7F,0x57,0x11,0xB5,0x4A,0x23,0x0A,0xAA,0x42,0x28,0x05,0x7D,0x22,0x12,0x03,
|
||||
0xA6,0x49,0x28,0x09,0x82,0x2B,0x0D,0x04,0x7A,0x20,0x0F,0x04,0x3D,0x0F,0x09,0x03,
|
||||
0xD1,0x7C,0x4C,0x0F,0xAF,0x4E,0x21,0x09,0xA8,0x46,0x2A,0x07,0x85,0x1F,0x0E,0x07,
|
||||
0xA6,0x3F,0x26,0x07,0x7C,0x24,0x14,0x07,0x78,0x22,0x16,0x04,0x46,0x12,0x0A,0x02,
|
||||
0xA6,0x41,0x2C,0x0A,0x7E,0x28,0x11,0x05,0x73,0x1B,0x14,0x05,0x3D,0x11,0x0A,0x02,
|
||||
0x70,0x22,0x17,0x05,0x48,0x13,0x08,0x03,0x3C,0x07,0x0D,0x07,0x26,0x07,0x06,0x01,
|
||||
|
||||
0xE0,0x9F,0xDA,0x7C,0x4F,0x18,0x28,0x0D,0xE9,0x9F,0xDA,0x7C,0x4F,0x18,0x1F,0x07,
|
||||
0xE6,0x97,0xD8,0x72,0x64,0x13,0x26,0x09,0xDC,0x67,0xA9,0x38,0x21,0x07,0x15,0x06,
|
||||
0xE9,0x91,0xD2,0x6B,0x63,0x14,0x2B,0x0E,0xD6,0x61,0xB7,0x41,0x2B,0x0E,0x10,0x09,
|
||||
0xCF,0x59,0xB0,0x2F,0x35,0x08,0x0F,0x07,0xB6,0x30,0x7A,0x21,0x17,0x07,0x09,0x03,
|
||||
0xE7,0xA3,0xE5,0x6B,0x65,0x1F,0x34,0x09,0xD8,0x6B,0xBE,0x45,0x27,0x07,0x10,0x07,
|
||||
0xDA,0x54,0xB1,0x39,0x2E,0x0E,0x17,0x08,0xA9,0x3C,0x86,0x22,0x16,0x06,0x07,0x03,
|
||||
0xD4,0x51,0xBC,0x3D,0x38,0x0A,0x13,0x06,0xB2,0x37,0x79,0x1C,0x17,0x05,0x0E,0x06,
|
||||
0xA7,0x31,0x74,0x1C,0x11,0x06,0x0C,0x02,0x6D,0x1A,0x38,0x10,0x0B,0x05,0x06,0x03,
|
||||
0xEB,0x9A,0xE1,0x7A,0x6F,0x13,0x34,0x0E,0xE6,0x75,0xC5,0x45,0x3E,0x0B,0x1A,0x05,
|
||||
0xD8,0x63,0xC1,0x40,0x3C,0x1B,0x19,0x06,0xB3,0x42,0x83,0x29,0x18,0x0A,0x08,0x04,
|
||||
0xD4,0x58,0xBA,0x43,0x3F,0x0A,0x1F,0x09,0xB1,0x33,0x8A,0x1F,0x1F,0x06,0x0D,0x05,
|
||||
0xAF,0x3C,0x7A,0x1F,0x16,0x08,0x0A,0x01,0x72,0x1B,0x52,0x0D,0x0B,0x09,0x06,0x01,
|
||||
0xCF,0x63,0xB7,0x47,0x40,0x10,0x14,0x06,0xC0,0x41,0x96,0x20,0x1C,0x09,0x10,0x05,
|
||||
0xA6,0x35,0x82,0x1A,0x20,0x0C,0x0E,0x04,0x80,0x1F,0x53,0x0F,0x0B,0x02,0x06,0x01,
|
||||
0xA6,0x31,0x81,0x1B,0x1D,0x01,0x08,0x08,0x7B,0x20,0x4D,0x19,0x0E,0x05,0x07,0x03,
|
||||
0x6B,0x17,0x49,0x07,0x0E,0x03,0x0A,0x05,0x37,0x0B,0x1F,0x06,0x04,0x02,0x07,0x01,
|
||||
|
||||
0xF0,0xD6,0xED,0xAD,0xEC,0xB1,0xEB,0x79,0xAC,0x22,0x47,0x1E,0x6E,0x1B,0x32,0x0A,
|
||||
0xF0,0xD6,0xEA,0xA4,0xED,0xC4,0xDE,0x82,0x98,0x1F,0x50,0x13,0x52,0x15,0x2A,0x0A,
|
||||
0xF1,0xD1,0xEB,0xA2,0xEB,0xB7,0xD8,0x69,0xA2,0x1F,0x5B,0x18,0x55,0x18,0x2C,0x0A,
|
||||
0xED,0xB5,0xDE,0x7E,0xE6,0x85,0xD3,0x59,0x59,0x0F,0x2C,0x09,0x24,0x07,0x15,0x09,
|
||||
0xF1,0xD6,0xEA,0xA0,0xEC,0xBB,0xDA,0x77,0xA9,0x23,0x58,0x14,0x5D,0x12,0x2F,0x09,
|
||||
0xF1,0xC1,0xE3,0x86,0xE4,0x87,0xD2,0x4E,0x68,0x15,0x26,0x0B,0x27,0x09,0x15,0x02,
|
||||
0xEE,0xA6,0xE0,0x5C,0xE0,0x77,0xC3,0x41,0x67,0x1B,0x3C,0x07,0x2A,0x06,0x19,0x07,
|
||||
0xE4,0x75,0xC6,0x43,0xCC,0x50,0x95,0x23,0x35,0x09,0x14,0x04,0x15,0x05,0x0B,0x04,
|
||||
0xEE,0xD6,0xED,0xAD,0xEC,0xB1,0xEB,0x79,0xAC,0x22,0x56,0x14,0x5A,0x12,0x26,0x0A,
|
||||
0xEE,0xBB,0xE7,0x7E,0xE9,0x8D,0xCB,0x49,0x67,0x11,0x34,0x07,0x2B,0x0B,0x14,0x07,
|
||||
0xED,0xA7,0xE5,0x76,0xE3,0x7E,0xC4,0x4B,0x77,0x14,0x34,0x08,0x27,0x07,0x14,0x04,
|
||||
0xE7,0x8B,0xD2,0x4C,0xCA,0x56,0x9E,0x31,0x36,0x0C,0x11,0x07,0x14,0x04,0x0A,0x02,
|
||||
0xF0,0x9B,0xEA,0x6F,0xE5,0x81,0xC4,0x43,0x74,0x10,0x30,0x0B,0x2D,0x08,0x1B,0x06,
|
||||
0xE6,0x83,0xCA,0x48,0xD9,0x56,0xA7,0x23,0x3B,0x09,0x12,0x09,0x15,0x07,0x0A,0x03,
|
||||
0xE5,0x5F,0xCB,0x3C,0xCF,0x48,0x91,0x22,0x31,0x0A,0x17,0x08,0x15,0x04,0x0D,0x02,
|
||||
0xD1,0x43,0x91,0x20,0xA9,0x2D,0x54,0x12,0x17,0x07,0x09,0x02,0x0C,0x04,0x05,0x03,
|
||||
};
|
||||
#endif
|
||||
|
||||
// divided into multiple functions to keep rarely-used functionality separate
|
||||
// so often-used functionality can be optimized better by compiler
|
||||
|
||||
// If write isn't preceded by read, data has this added to it
|
||||
int const no_read_before_write = 0x2000;
|
||||
|
||||
void SNES_SPC::cpu_write_smp_reg_( int data, rel_time_t time, int addr )
|
||||
{
|
||||
switch ( addr )
|
||||
{
|
||||
case r_t0target:
|
||||
case r_t1target:
|
||||
case r_t2target: {
|
||||
Timer* t = &m.timers [addr - r_t0target];
|
||||
int period = IF_0_THEN_256( data );
|
||||
if ( t->period != period )
|
||||
{
|
||||
t = run_timer( t, time );
|
||||
#if SPC_MORE_ACCURACY
|
||||
// Insane behavior when target is written just after counter is
|
||||
// clocked and counter matches new period and new period isn't 1, 2, 4, or 8
|
||||
if ( t->divider == (period & 0xFF) &&
|
||||
t->next_time == time + TIMER_MUL( t, 1 ) &&
|
||||
((period - 1) | ~0x0F) & period )
|
||||
{
|
||||
//dprintf( "SPC pathological timer target write\n" );
|
||||
|
||||
// If the period is 3, 5, or 9, there's a probability this behavior won't occur,
|
||||
// based on the previous period
|
||||
int prob = 0xFF;
|
||||
int old_period = t->period & 0xFF;
|
||||
if ( period == 3 ) prob = glitch_probs [0] [old_period];
|
||||
if ( period == 5 ) prob = glitch_probs [1] [old_period];
|
||||
if ( period == 9 ) prob = glitch_probs [2] [old_period];
|
||||
|
||||
// The glitch suppresses incrementing of one of the counter bits, based on
|
||||
// the lowest set bit in the new period
|
||||
int b = 1;
|
||||
while ( !(period & b) )
|
||||
b <<= 1;
|
||||
|
||||
if ( (rand() >> 4 & 0xFF) <= prob )
|
||||
t->divider = (t->divider - b) & 0xFF;
|
||||
}
|
||||
#endif
|
||||
t->period = period;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case r_t0out:
|
||||
case r_t1out:
|
||||
case r_t2out:
|
||||
if ( !SPC_MORE_ACCURACY )
|
||||
dprintf( "SPC wrote to counter %d\n", (int) addr - r_t0out );
|
||||
|
||||
if ( data < no_read_before_write / 2 )
|
||||
run_timer( &m.timers [addr - r_t0out], time - 1 )->counter = 0;
|
||||
break;
|
||||
|
||||
// Registers that act like RAM
|
||||
case 0x8:
|
||||
case 0x9:
|
||||
REGS_IN [addr] = (uint8_t) data;
|
||||
break;
|
||||
|
||||
case r_test:
|
||||
if ( (uint8_t) data != 0x0A )
|
||||
dprintf( "SPC wrote to test register\n" );
|
||||
break;
|
||||
|
||||
case r_control:
|
||||
// port clears
|
||||
if ( data & 0x10 )
|
||||
{
|
||||
REGS_IN [r_cpuio0] = 0;
|
||||
REGS_IN [r_cpuio1] = 0;
|
||||
}
|
||||
if ( data & 0x20 )
|
||||
{
|
||||
REGS_IN [r_cpuio2] = 0;
|
||||
REGS_IN [r_cpuio3] = 0;
|
||||
}
|
||||
|
||||
// timers
|
||||
{
|
||||
for ( int i = 0; i < timer_count; i++ )
|
||||
{
|
||||
Timer* t = &m.timers [i];
|
||||
int enabled = data >> i & 1;
|
||||
if ( t->enabled != enabled )
|
||||
{
|
||||
t = run_timer( t, time );
|
||||
t->enabled = enabled;
|
||||
if ( enabled )
|
||||
{
|
||||
t->divider = 0;
|
||||
t->counter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
enable_rom( data & 0x80 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SNES_SPC::cpu_write_smp_reg( int data, rel_time_t time, int addr )
|
||||
{
|
||||
if ( addr == r_dspdata ) // 99%
|
||||
dsp_write( data, time );
|
||||
else
|
||||
cpu_write_smp_reg_( data, time, addr );
|
||||
}
|
||||
|
||||
void SNES_SPC::cpu_write_high( int data, int i, rel_time_t time )
|
||||
{
|
||||
if ( i < rom_size )
|
||||
{
|
||||
m.hi_ram [i] = (uint8_t) data;
|
||||
if ( m.rom_enabled )
|
||||
RAM [i + rom_addr] = m.rom [i]; // restore overwritten ROM
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( *(&(RAM [0]) + i + rom_addr) == (uint8_t) data );
|
||||
*(&(RAM [0]) + i + rom_addr) = cpu_pad_fill; // restore overwritten padding
|
||||
cpu_write( data, i + rom_addr - 0x10000, time );
|
||||
}
|
||||
}
|
||||
|
||||
int const bits_in_int = CHAR_BIT * sizeof (int);
|
||||
|
||||
void SNES_SPC::cpu_write( int data, int addr, rel_time_t time )
|
||||
{
|
||||
MEM_ACCESS( time, addr )
|
||||
|
||||
// RAM
|
||||
RAM [addr] = (uint8_t) data;
|
||||
int reg = addr - 0xF0;
|
||||
if ( reg >= 0 ) // 64%
|
||||
{
|
||||
// $F0-$FF
|
||||
if ( reg < reg_count ) // 87%
|
||||
{
|
||||
REGS [reg] = (uint8_t) data;
|
||||
|
||||
// Ports
|
||||
#ifdef SPC_PORT_WRITE_HOOK
|
||||
if ( (unsigned) (reg - r_cpuio0) < port_count )
|
||||
SPC_PORT_WRITE_HOOK( m.spc_time + time, (reg - r_cpuio0),
|
||||
(uint8_t) data, ®S [r_cpuio0] );
|
||||
#endif
|
||||
|
||||
// Registers other than $F2 and $F4-$F7
|
||||
//if ( reg != 2 && reg != 4 && reg != 5 && reg != 6 && reg != 7 )
|
||||
// TODO: this is a bit on the fragile side
|
||||
if ( ((~0x2F00 << (bits_in_int - 16)) << reg) < 0 ) // 36%
|
||||
cpu_write_smp_reg( data, time, reg );
|
||||
}
|
||||
// High mem/address wrap-around
|
||||
else
|
||||
{
|
||||
reg -= rom_addr - 0xF0;
|
||||
if ( reg >= 0 ) // 1% in IPL ROM area or address wrapped around
|
||||
cpu_write_high( data, reg, time );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// CPU read
|
||||
|
||||
inline int SNES_SPC::cpu_read_smp_reg( int reg, rel_time_t time )
|
||||
{
|
||||
int result = REGS_IN [reg];
|
||||
reg -= r_dspaddr;
|
||||
// DSP addr and data
|
||||
if ( (unsigned) reg <= 1 ) // 4% 0xF2 and 0xF3
|
||||
{
|
||||
result = REGS [r_dspaddr];
|
||||
if ( (unsigned) reg == 1 )
|
||||
result = dsp_read( time ); // 0xF3
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int SNES_SPC::cpu_read( int addr, rel_time_t time )
|
||||
{
|
||||
MEM_ACCESS( time, addr )
|
||||
|
||||
// RAM
|
||||
int result = RAM [addr];
|
||||
int reg = addr - 0xF0;
|
||||
if ( reg >= 0 ) // 40%
|
||||
{
|
||||
reg -= 0x10;
|
||||
if ( (unsigned) reg >= 0xFF00 ) // 21%
|
||||
{
|
||||
reg += 0x10 - r_t0out;
|
||||
|
||||
// Timers
|
||||
if ( (unsigned) reg < timer_count ) // 90%
|
||||
{
|
||||
Timer* t = &m.timers [reg];
|
||||
if ( time >= t->next_time )
|
||||
t = run_timer_( t, time );
|
||||
result = t->counter;
|
||||
t->counter = 0;
|
||||
}
|
||||
// Other registers
|
||||
else if ( reg < 0 ) // 10%
|
||||
{
|
||||
result = cpu_read_smp_reg( reg + r_t0out, time );
|
||||
}
|
||||
else // 1%
|
||||
{
|
||||
assert( reg + (r_t0out + 0xF0 - 0x10000) < 0x100 );
|
||||
result = cpu_read( reg + (r_t0out + 0xF0 - 0x10000), time );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//// Run
|
||||
|
||||
// Prefix and suffix for CPU emulator function
|
||||
#define SPC_CPU_RUN_FUNC \
|
||||
BOOST::uint8_t* SNES_SPC::run_until_( time_t end_time )\
|
||||
{\
|
||||
rel_time_t rel_time = m.spc_time - end_time;\
|
||||
assert( rel_time <= 0 );\
|
||||
m.spc_time = end_time;\
|
||||
m.dsp_time += rel_time;\
|
||||
m.timers [0].next_time += rel_time;\
|
||||
m.timers [1].next_time += rel_time;\
|
||||
m.timers [2].next_time += rel_time;
|
||||
|
||||
#define SPC_CPU_RUN_FUNC_END \
|
||||
m.spc_time += rel_time;\
|
||||
m.dsp_time -= rel_time;\
|
||||
m.timers [0].next_time -= rel_time;\
|
||||
m.timers [1].next_time -= rel_time;\
|
||||
m.timers [2].next_time -= rel_time;\
|
||||
assert( m.spc_time <= end_time );\
|
||||
return ®S [r_cpuio0];\
|
||||
}
|
||||
|
||||
int const cpu_lag_max = 12 - 1; // DIV YA,X takes 12 clocks
|
||||
|
||||
void SNES_SPC::end_frame( time_t end_time )
|
||||
{
|
||||
// Catch CPU up to as close to end as possible. If final instruction
|
||||
// would exceed end, does NOT execute it and leaves m.spc_time < end.
|
||||
if ( end_time > m.spc_time )
|
||||
run_until_( end_time );
|
||||
|
||||
m.spc_time -= end_time;
|
||||
m.extra_clocks += end_time;
|
||||
|
||||
// Greatest number of clocks early that emulation can stop early due to
|
||||
// not being able to execute current instruction without going over
|
||||
// allowed time.
|
||||
assert( -cpu_lag_max <= m.spc_time && m.spc_time <= 0 );
|
||||
|
||||
// Catch timers up to CPU
|
||||
for ( int i = 0; i < timer_count; i++ )
|
||||
run_timer( &m.timers [i], 0 );
|
||||
|
||||
// Catch DSP up to CPU
|
||||
if ( m.dsp_time < 0 )
|
||||
{
|
||||
RUN_DSP( 0, max_reg_time );
|
||||
}
|
||||
|
||||
// Save any extra samples beyond what should be generated
|
||||
if ( m.buf_begin )
|
||||
save_extra();
|
||||
}
|
||||
|
||||
// Inclusion here allows static memory access functions and better optimization
|
||||
#include "SPC_CPU.h"
|
|
@ -0,0 +1,288 @@
|
|||
// SNES SPC-700 APU emulator
|
||||
|
||||
// snes_spc 0.9.0
|
||||
#ifndef SNES_SPC_H
|
||||
#define SNES_SPC_H
|
||||
|
||||
#include "SPC_DSP.h"
|
||||
#include "blargg_endian.h"
|
||||
|
||||
struct SNES_SPC {
|
||||
public:
|
||||
typedef BOOST::uint8_t uint8_t;
|
||||
|
||||
// Must be called once before using
|
||||
blargg_err_t init();
|
||||
|
||||
// Sample pairs generated per second
|
||||
enum { sample_rate = 32000 };
|
||||
|
||||
// Emulator use
|
||||
|
||||
// Sets IPL ROM data. Library does not include ROM data. Most SPC music files
|
||||
// don't need ROM, but a full emulator must provide this.
|
||||
enum { rom_size = 0x40 };
|
||||
void init_rom( uint8_t const rom [rom_size] );
|
||||
|
||||
// Sets destination for output samples
|
||||
typedef short sample_t;
|
||||
void set_output( sample_t* out, int out_size );
|
||||
|
||||
// Number of samples written to output since last set
|
||||
int sample_count() const;
|
||||
|
||||
// Resets SPC to power-on state. This resets your output buffer, so you must
|
||||
// call set_output() after this.
|
||||
void reset();
|
||||
|
||||
// Emulates pressing reset switch on SNES. This resets your output buffer, so
|
||||
// you must call set_output() after this.
|
||||
void soft_reset();
|
||||
|
||||
// 1024000 SPC clocks per second, sample pair every 32 clocks
|
||||
typedef int time_t;
|
||||
enum { clock_rate = 1024000 };
|
||||
enum { clocks_per_sample = 32 };
|
||||
|
||||
// Emulated port read/write at specified time
|
||||
enum { port_count = 4 };
|
||||
int read_port ( time_t, int port );
|
||||
void write_port( time_t, int port, int data );
|
||||
|
||||
// Runs SPC to end_time and starts a new time frame at 0
|
||||
void end_frame( time_t end_time );
|
||||
|
||||
// Sound control
|
||||
|
||||
// Mutes voices corresponding to non-zero bits in mask (issues repeated KOFF events).
|
||||
// Reduces emulation accuracy.
|
||||
enum { voice_count = 8 };
|
||||
void mute_voices( int mask );
|
||||
|
||||
// If true, prevents channels and global volumes from being phase-negated.
|
||||
// Only supported by fast DSP.
|
||||
void disable_surround( bool disable = true );
|
||||
|
||||
// Sets tempo, where tempo_unit = normal, tempo_unit / 2 = half speed, etc.
|
||||
enum { tempo_unit = 0x100 };
|
||||
void set_tempo( int );
|
||||
|
||||
// SPC music files
|
||||
|
||||
// Loads SPC data into emulator
|
||||
enum { spc_min_file_size = 0x10180 };
|
||||
enum { spc_file_size = 0x10200 };
|
||||
blargg_err_t load_spc( void const* in, long size );
|
||||
|
||||
// Clears echo region. Useful after loading an SPC as many have garbage in echo.
|
||||
void clear_echo();
|
||||
|
||||
// Plays for count samples and write samples to out. Discards samples if out
|
||||
// is NULL. Count must be a multiple of 2 since output is stereo.
|
||||
blargg_err_t play( int count, sample_t* out );
|
||||
|
||||
// Skips count samples. Several times faster than play() when using fast DSP.
|
||||
blargg_err_t skip( int count );
|
||||
|
||||
// State save/load (only available with accurate DSP)
|
||||
|
||||
#if !SPC_NO_COPY_STATE_FUNCS
|
||||
// Saves/loads state
|
||||
enum { state_size = 68 * 1024L }; // maximum space needed when saving
|
||||
typedef SPC_DSP::copy_func_t copy_func_t;
|
||||
void copy_state( unsigned char** io, copy_func_t );
|
||||
|
||||
// Writes minimal header to spc_out
|
||||
static void init_header( void* spc_out );
|
||||
|
||||
// Saves emulator state as SPC file data. Writes spc_file_size bytes to spc_out.
|
||||
// Does not set up SPC header; use init_header() for that.
|
||||
void save_spc( void* spc_out );
|
||||
|
||||
// Returns true if new key-on events occurred since last check. Useful for
|
||||
// trimming silence while saving an SPC.
|
||||
bool check_kon();
|
||||
#endif
|
||||
|
||||
//// Snes9x Accessor
|
||||
|
||||
void dsp_set_spc_snapshot_callback( void (*callback) (void) );
|
||||
void dsp_dump_spc_snapshot( void );
|
||||
void dsp_set_stereo_switch( int );
|
||||
uint8_t dsp_reg_value( int, int );
|
||||
int dsp_envx_value( int );
|
||||
|
||||
public:
|
||||
BLARGG_DISABLE_NOTHROW
|
||||
|
||||
typedef BOOST::uint16_t uint16_t;
|
||||
|
||||
// Time relative to m_spc_time. Speeds up code a bit by eliminating need to
|
||||
// constantly add m_spc_time to time from CPU. CPU uses time that ends at
|
||||
// 0 to eliminate reloading end time every instruction. It pays off.
|
||||
typedef int rel_time_t;
|
||||
|
||||
struct Timer
|
||||
{
|
||||
rel_time_t next_time; // time of next event
|
||||
int prescaler;
|
||||
int period;
|
||||
int divider;
|
||||
int enabled;
|
||||
int counter;
|
||||
};
|
||||
enum { reg_count = 0x10 };
|
||||
enum { timer_count = 3 };
|
||||
enum { extra_size = SPC_DSP::extra_size };
|
||||
|
||||
enum { signature_size = 35 };
|
||||
|
||||
private:
|
||||
SPC_DSP dsp;
|
||||
|
||||
#if SPC_LESS_ACCURATE
|
||||
static signed char const reg_times_ [256];
|
||||
signed char reg_times [256];
|
||||
#endif
|
||||
|
||||
struct state_t
|
||||
{
|
||||
Timer timers [timer_count];
|
||||
|
||||
uint8_t smp_regs [2] [reg_count];
|
||||
|
||||
struct
|
||||
{
|
||||
int pc;
|
||||
int a;
|
||||
int x;
|
||||
int y;
|
||||
int psw;
|
||||
int sp;
|
||||
} cpu_regs;
|
||||
|
||||
rel_time_t dsp_time;
|
||||
time_t spc_time;
|
||||
bool echo_accessed;
|
||||
|
||||
int tempo;
|
||||
int skipped_kon;
|
||||
int skipped_koff;
|
||||
const char* cpu_error;
|
||||
|
||||
int extra_clocks;
|
||||
sample_t* buf_begin;
|
||||
sample_t const* buf_end;
|
||||
sample_t* extra_pos;
|
||||
sample_t extra_buf [extra_size];
|
||||
|
||||
int rom_enabled;
|
||||
uint8_t rom [rom_size];
|
||||
uint8_t hi_ram [rom_size];
|
||||
|
||||
unsigned char cycle_table [256];
|
||||
|
||||
struct
|
||||
{
|
||||
// padding to neutralize address overflow
|
||||
union {
|
||||
uint8_t padding1 [0x100];
|
||||
uint16_t align; // makes compiler align data for 16-bit access
|
||||
} padding1 [1];
|
||||
uint8_t ram [0x10000];
|
||||
uint8_t padding2 [0x100];
|
||||
} ram;
|
||||
};
|
||||
state_t m;
|
||||
|
||||
enum { rom_addr = 0xFFC0 };
|
||||
|
||||
enum { skipping_time = 127 };
|
||||
|
||||
// Value that padding should be filled with
|
||||
enum { cpu_pad_fill = 0xFF };
|
||||
|
||||
enum {
|
||||
r_test = 0x0, r_control = 0x1,
|
||||
r_dspaddr = 0x2, r_dspdata = 0x3,
|
||||
r_cpuio0 = 0x4, r_cpuio1 = 0x5,
|
||||
r_cpuio2 = 0x6, r_cpuio3 = 0x7,
|
||||
r_f8 = 0x8, r_f9 = 0x9,
|
||||
r_t0target = 0xA, r_t1target = 0xB, r_t2target = 0xC,
|
||||
r_t0out = 0xD, r_t1out = 0xE, r_t2out = 0xF
|
||||
};
|
||||
|
||||
void timers_loaded();
|
||||
void enable_rom( int enable );
|
||||
void reset_buf();
|
||||
void save_extra();
|
||||
void load_regs( uint8_t const in [reg_count] );
|
||||
void ram_loaded();
|
||||
void regs_loaded();
|
||||
void reset_time_regs();
|
||||
void reset_common( int timer_counter_init );
|
||||
|
||||
Timer* run_timer_ ( Timer* t, rel_time_t );
|
||||
Timer* run_timer ( Timer* t, rel_time_t );
|
||||
int dsp_read ( rel_time_t );
|
||||
void dsp_write ( int data, rel_time_t );
|
||||
void cpu_write_smp_reg_( int data, rel_time_t, int addr );
|
||||
void cpu_write_smp_reg ( int data, rel_time_t, int addr );
|
||||
void cpu_write_high ( int data, int i, rel_time_t );
|
||||
void cpu_write ( int data, int addr, rel_time_t );
|
||||
int cpu_read_smp_reg ( int i, rel_time_t );
|
||||
int cpu_read ( int addr, rel_time_t );
|
||||
unsigned CPU_mem_bit ( uint8_t const* pc, rel_time_t );
|
||||
|
||||
bool check_echo_access ( int addr );
|
||||
uint8_t* run_until_( time_t end_time );
|
||||
|
||||
struct spc_file_t
|
||||
{
|
||||
char signature [signature_size];
|
||||
uint8_t has_id666;
|
||||
uint8_t version;
|
||||
uint8_t pcl, pch;
|
||||
uint8_t a;
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
uint8_t psw;
|
||||
uint8_t sp;
|
||||
char text [212];
|
||||
uint8_t ram [0x10000];
|
||||
uint8_t dsp [128];
|
||||
uint8_t unused [0x40];
|
||||
uint8_t ipl_rom [0x40];
|
||||
};
|
||||
|
||||
static char const signature [signature_size + 1];
|
||||
|
||||
void save_regs( uint8_t out [reg_count] );
|
||||
};
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
inline int SNES_SPC::sample_count() const { return (m.extra_clocks >> 5) * 2; }
|
||||
|
||||
inline int SNES_SPC::read_port( time_t t, int port )
|
||||
{
|
||||
assert( (unsigned) port < port_count );
|
||||
return run_until_( t ) [port];
|
||||
}
|
||||
|
||||
inline void SNES_SPC::write_port( time_t t, int port, int data )
|
||||
{
|
||||
assert( (unsigned) port < port_count );
|
||||
run_until_( t ) [0x10 + port] = data;
|
||||
m.ram.ram [0xF4 + port] = data;
|
||||
}
|
||||
|
||||
inline void SNES_SPC::mute_voices( int mask ) { dsp.mute_voices( mask ); }
|
||||
|
||||
inline void SNES_SPC::disable_surround( bool disable ) { dsp.disable_surround( disable ); }
|
||||
|
||||
#if !SPC_NO_COPY_STATE_FUNCS
|
||||
inline bool SNES_SPC::check_kon() { return dsp.check_kon(); }
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,413 @@
|
|||
// SPC emulation support: init, sample buffering, reset, SPC loading
|
||||
|
||||
// snes_spc 0.9.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "SNES_SPC.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Copyright (C) 2004-2007 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
#define RAM (m.ram.ram)
|
||||
#define REGS (m.smp_regs [0])
|
||||
#define REGS_IN (m.smp_regs [1])
|
||||
|
||||
// (n ? n : 256)
|
||||
#define IF_0_THEN_256( n ) ((uint8_t) ((n) - 1) + 1)
|
||||
|
||||
|
||||
//// Init
|
||||
|
||||
blargg_err_t SNES_SPC::init()
|
||||
{
|
||||
memset( &m, 0, sizeof m );
|
||||
dsp.init( RAM );
|
||||
|
||||
m.tempo = tempo_unit;
|
||||
|
||||
// Most SPC music doesn't need ROM, and almost all the rest only rely
|
||||
// on these two bytes
|
||||
m.rom [0x3E] = 0xFF;
|
||||
m.rom [0x3F] = 0xC0;
|
||||
|
||||
static unsigned char const cycle_table [128] =
|
||||
{// 01 23 45 67 89 AB CD EF
|
||||
0x28,0x47,0x34,0x36,0x26,0x54,0x54,0x68, // 0
|
||||
0x48,0x47,0x45,0x56,0x55,0x65,0x22,0x46, // 1
|
||||
0x28,0x47,0x34,0x36,0x26,0x54,0x54,0x74, // 2
|
||||
0x48,0x47,0x45,0x56,0x55,0x65,0x22,0x38, // 3
|
||||
0x28,0x47,0x34,0x36,0x26,0x44,0x54,0x66, // 4
|
||||
0x48,0x47,0x45,0x56,0x55,0x45,0x22,0x43, // 5
|
||||
0x28,0x47,0x34,0x36,0x26,0x44,0x54,0x75, // 6
|
||||
0x48,0x47,0x45,0x56,0x55,0x55,0x22,0x36, // 7
|
||||
0x28,0x47,0x34,0x36,0x26,0x54,0x52,0x45, // 8
|
||||
0x48,0x47,0x45,0x56,0x55,0x55,0x22,0xC5, // 9
|
||||
0x38,0x47,0x34,0x36,0x26,0x44,0x52,0x44, // A
|
||||
0x48,0x47,0x45,0x56,0x55,0x55,0x22,0x34, // B
|
||||
0x38,0x47,0x45,0x47,0x25,0x64,0x52,0x49, // C
|
||||
0x48,0x47,0x56,0x67,0x45,0x55,0x22,0x83, // D
|
||||
0x28,0x47,0x34,0x36,0x24,0x53,0x43,0x40, // E
|
||||
0x48,0x47,0x45,0x56,0x34,0x54,0x22,0x60, // F
|
||||
};
|
||||
|
||||
// unpack cycle table
|
||||
for ( int i = 0; i < 128; i++ )
|
||||
{
|
||||
int n = cycle_table [i];
|
||||
m.cycle_table [i * 2 + 0] = n >> 4;
|
||||
m.cycle_table [i * 2 + 1] = n & 0x0F;
|
||||
}
|
||||
|
||||
#if SPC_LESS_ACCURATE
|
||||
memcpy( reg_times, reg_times_, sizeof reg_times );
|
||||
#endif
|
||||
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SNES_SPC::init_rom( uint8_t const in [rom_size] )
|
||||
{
|
||||
memcpy( m.rom, in, sizeof m.rom );
|
||||
}
|
||||
|
||||
void SNES_SPC::set_tempo( int t )
|
||||
{
|
||||
m.tempo = t;
|
||||
int const timer2_shift = 4; // 64 kHz
|
||||
int const other_shift = 3; // 8 kHz
|
||||
|
||||
#if SPC_DISABLE_TEMPO
|
||||
m.timers [2].prescaler = timer2_shift;
|
||||
m.timers [1].prescaler = timer2_shift + other_shift;
|
||||
m.timers [0].prescaler = timer2_shift + other_shift;
|
||||
#else
|
||||
if ( !t )
|
||||
t = 1;
|
||||
int const timer2_rate = 1 << timer2_shift;
|
||||
int rate = (timer2_rate * tempo_unit + (t >> 1)) / t;
|
||||
if ( rate < timer2_rate / 4 )
|
||||
rate = timer2_rate / 4; // max 4x tempo
|
||||
m.timers [2].prescaler = rate;
|
||||
m.timers [1].prescaler = rate << other_shift;
|
||||
m.timers [0].prescaler = rate << other_shift;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Timer registers have been loaded. Applies these to the timers. Does not
|
||||
// reset timer prescalers or dividers.
|
||||
void SNES_SPC::timers_loaded()
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < timer_count; i++ )
|
||||
{
|
||||
Timer* t = &m.timers [i];
|
||||
t->period = IF_0_THEN_256( REGS [r_t0target + i] );
|
||||
t->enabled = REGS [r_control] >> i & 1;
|
||||
t->counter = REGS_IN [r_t0out + i] & 0x0F;
|
||||
}
|
||||
|
||||
set_tempo( m.tempo );
|
||||
}
|
||||
|
||||
// Loads registers from unified 16-byte format
|
||||
void SNES_SPC::load_regs( uint8_t const in [reg_count] )
|
||||
{
|
||||
memcpy( REGS, in, reg_count );
|
||||
memcpy( REGS_IN, REGS, reg_count );
|
||||
|
||||
// These always read back as 0
|
||||
REGS_IN [r_test ] = 0;
|
||||
REGS_IN [r_control ] = 0;
|
||||
REGS_IN [r_t0target] = 0;
|
||||
REGS_IN [r_t1target] = 0;
|
||||
REGS_IN [r_t2target] = 0;
|
||||
}
|
||||
|
||||
// RAM was just loaded from SPC, with $F0-$FF containing SMP registers
|
||||
// and timer counts. Copies these to proper registers.
|
||||
void SNES_SPC::ram_loaded()
|
||||
{
|
||||
m.rom_enabled = 0;
|
||||
load_regs( &RAM [0xF0] );
|
||||
|
||||
// Put STOP instruction around memory to catch PC underflow/overflow
|
||||
memset( m.ram.padding1, cpu_pad_fill, sizeof m.ram.padding1 );
|
||||
memset( m.ram.padding2, cpu_pad_fill, sizeof m.ram.padding2 );
|
||||
}
|
||||
|
||||
// Registers were just loaded. Applies these new values.
|
||||
void SNES_SPC::regs_loaded()
|
||||
{
|
||||
enable_rom( REGS [r_control] & 0x80 );
|
||||
timers_loaded();
|
||||
}
|
||||
|
||||
void SNES_SPC::reset_time_regs()
|
||||
{
|
||||
m.cpu_error = 0;
|
||||
m.echo_accessed = 0;
|
||||
m.spc_time = 0;
|
||||
m.dsp_time = 0;
|
||||
#if SPC_LESS_ACCURATE
|
||||
m.dsp_time = clocks_per_sample + 1;
|
||||
#endif
|
||||
|
||||
for ( int i = 0; i < timer_count; i++ )
|
||||
{
|
||||
Timer* t = &m.timers [i];
|
||||
t->next_time = 1;
|
||||
t->divider = 0;
|
||||
}
|
||||
|
||||
regs_loaded();
|
||||
|
||||
m.extra_clocks = 0;
|
||||
reset_buf();
|
||||
}
|
||||
|
||||
void SNES_SPC::reset_common( int timer_counter_init )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < timer_count; i++ )
|
||||
REGS_IN [r_t0out + i] = timer_counter_init;
|
||||
|
||||
// Run IPL ROM
|
||||
memset( &m.cpu_regs, 0, sizeof m.cpu_regs );
|
||||
m.cpu_regs.pc = rom_addr;
|
||||
|
||||
REGS [r_test ] = 0x0A;
|
||||
REGS [r_control] = 0xB0; // ROM enabled, clear ports
|
||||
for ( i = 0; i < port_count; i++ )
|
||||
REGS_IN [r_cpuio0 + i] = 0;
|
||||
|
||||
reset_time_regs();
|
||||
}
|
||||
|
||||
void SNES_SPC::soft_reset()
|
||||
{
|
||||
reset_common( 0 );
|
||||
dsp.soft_reset();
|
||||
}
|
||||
|
||||
void SNES_SPC::reset()
|
||||
{
|
||||
m.cpu_regs.pc = 0xFFC0;
|
||||
m.cpu_regs.a = 0x00;
|
||||
m.cpu_regs.x = 0x00;
|
||||
m.cpu_regs.y = 0x00;
|
||||
m.cpu_regs.psw = 0x02;
|
||||
m.cpu_regs.sp = 0xEF;
|
||||
memset( RAM, 0x00, 0x10000 );
|
||||
ram_loaded();
|
||||
reset_common( 0x0F );
|
||||
dsp.reset();
|
||||
}
|
||||
|
||||
char const SNES_SPC::signature [signature_size + 1] =
|
||||
"SNES-SPC700 Sound File Data v0.30\x1A\x1A";
|
||||
|
||||
blargg_err_t SNES_SPC::load_spc( void const* data, long size )
|
||||
{
|
||||
spc_file_t const* const spc = (spc_file_t const*) data;
|
||||
|
||||
// be sure compiler didn't insert any padding into fle_t
|
||||
assert( sizeof (spc_file_t) == spc_min_file_size + 0x80 );
|
||||
|
||||
// Check signature and file size
|
||||
if ( size < signature_size || memcmp( spc, signature, 27 ) )
|
||||
return "Not an SPC file";
|
||||
|
||||
if ( size < spc_min_file_size )
|
||||
return "Corrupt SPC file";
|
||||
|
||||
// CPU registers
|
||||
m.cpu_regs.pc = spc->pch * 0x100 + spc->pcl;
|
||||
m.cpu_regs.a = spc->a;
|
||||
m.cpu_regs.x = spc->x;
|
||||
m.cpu_regs.y = spc->y;
|
||||
m.cpu_regs.psw = spc->psw;
|
||||
m.cpu_regs.sp = spc->sp;
|
||||
|
||||
// RAM and registers
|
||||
memcpy( RAM, spc->ram, 0x10000 );
|
||||
ram_loaded();
|
||||
|
||||
// DSP registers
|
||||
dsp.load( spc->dsp );
|
||||
|
||||
reset_time_regs();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SNES_SPC::clear_echo()
|
||||
{
|
||||
if ( !(dsp.read( SPC_DSP::r_flg ) & 0x20) )
|
||||
{
|
||||
int addr = 0x100 * dsp.read( SPC_DSP::r_esa );
|
||||
int end = addr + 0x800 * (dsp.read( SPC_DSP::r_edl ) & 0x0F);
|
||||
if ( end > 0x10000 )
|
||||
end = 0x10000;
|
||||
memset( &RAM [addr], 0xFF, end - addr );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// Sample output
|
||||
|
||||
void SNES_SPC::reset_buf()
|
||||
{
|
||||
// Start with half extra buffer of silence
|
||||
sample_t* out = m.extra_buf;
|
||||
while ( out < &m.extra_buf [extra_size / 2] )
|
||||
*out++ = 0;
|
||||
|
||||
m.extra_pos = out;
|
||||
m.buf_begin = 0;
|
||||
|
||||
dsp.set_output( 0, 0 );
|
||||
}
|
||||
|
||||
void SNES_SPC::set_output( sample_t* out, int size )
|
||||
{
|
||||
require( (size & 1) == 0 ); // size must be even
|
||||
|
||||
m.extra_clocks &= clocks_per_sample - 1;
|
||||
if ( out )
|
||||
{
|
||||
sample_t const* out_end = out + size;
|
||||
m.buf_begin = out;
|
||||
m.buf_end = out_end;
|
||||
|
||||
// Copy extra to output
|
||||
sample_t const* in = m.extra_buf;
|
||||
while ( in < m.extra_pos && out < out_end )
|
||||
*out++ = *in++;
|
||||
|
||||
// Handle output being full already
|
||||
if ( out >= out_end )
|
||||
{
|
||||
// Have DSP write to remaining extra space
|
||||
out = dsp.extra();
|
||||
out_end = &dsp.extra() [extra_size];
|
||||
|
||||
// Copy any remaining extra samples as if DSP wrote them
|
||||
while ( in < m.extra_pos )
|
||||
*out++ = *in++;
|
||||
assert( out <= out_end );
|
||||
}
|
||||
|
||||
dsp.set_output( out, out_end - out );
|
||||
}
|
||||
else
|
||||
{
|
||||
reset_buf();
|
||||
}
|
||||
}
|
||||
|
||||
void SNES_SPC::save_extra()
|
||||
{
|
||||
// Get end pointers
|
||||
sample_t const* main_end = m.buf_end; // end of data written to buf
|
||||
sample_t const* dsp_end = dsp.out_pos(); // end of data written to dsp.extra()
|
||||
if ( m.buf_begin <= dsp_end && dsp_end <= main_end )
|
||||
{
|
||||
main_end = dsp_end;
|
||||
dsp_end = dsp.extra(); // nothing in DSP's extra
|
||||
}
|
||||
|
||||
// Copy any extra samples at these ends into extra_buf
|
||||
sample_t* out = m.extra_buf;
|
||||
sample_t const* in;
|
||||
for ( in = m.buf_begin + sample_count(); in < main_end; in++ )
|
||||
*out++ = *in;
|
||||
for ( in = dsp.extra(); in < dsp_end ; in++ )
|
||||
*out++ = *in;
|
||||
|
||||
m.extra_pos = out;
|
||||
assert( out <= &m.extra_buf [extra_size] );
|
||||
}
|
||||
|
||||
blargg_err_t SNES_SPC::play( int count, sample_t* out )
|
||||
{
|
||||
require( (count & 1) == 0 ); // must be even
|
||||
if ( count )
|
||||
{
|
||||
set_output( out, count );
|
||||
end_frame( count * (clocks_per_sample / 2) );
|
||||
}
|
||||
|
||||
const char* err = m.cpu_error;
|
||||
m.cpu_error = 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
blargg_err_t SNES_SPC::skip( int count )
|
||||
{
|
||||
#if SPC_LESS_ACCURATE
|
||||
if ( count > 2 * sample_rate * 2 )
|
||||
{
|
||||
set_output( 0, 0 );
|
||||
|
||||
// Skip a multiple of 4 samples
|
||||
time_t end = count;
|
||||
count = (count & 3) + 1 * sample_rate * 2;
|
||||
end = (end - count) * (clocks_per_sample / 2);
|
||||
|
||||
m.skipped_kon = 0;
|
||||
m.skipped_koff = 0;
|
||||
|
||||
// Preserve DSP and timer synchronization
|
||||
// TODO: verify that this really preserves it
|
||||
int old_dsp_time = m.dsp_time + m.spc_time;
|
||||
m.dsp_time = end - m.spc_time + skipping_time;
|
||||
end_frame( end );
|
||||
m.dsp_time = m.dsp_time - skipping_time + old_dsp_time;
|
||||
|
||||
dsp.write( SPC_DSP::r_koff, m.skipped_koff & ~m.skipped_kon );
|
||||
dsp.write( SPC_DSP::r_kon , m.skipped_kon );
|
||||
clear_echo();
|
||||
}
|
||||
#endif
|
||||
|
||||
return play( count, 0 );
|
||||
}
|
||||
|
||||
//// Snes9x Accessor
|
||||
|
||||
void SNES_SPC::dsp_set_spc_snapshot_callback( void (*callback) (void) )
|
||||
{
|
||||
dsp.set_spc_snapshot_callback( callback );
|
||||
}
|
||||
|
||||
void SNES_SPC::dsp_dump_spc_snapshot( void )
|
||||
{
|
||||
dsp.dump_spc_snapshot();
|
||||
}
|
||||
|
||||
void SNES_SPC::dsp_set_stereo_switch( int value )
|
||||
{
|
||||
dsp.set_stereo_switch( value );
|
||||
}
|
||||
|
||||
SNES_SPC::uint8_t SNES_SPC::dsp_reg_value( int ch, int addr )
|
||||
{
|
||||
return dsp.reg_value( ch, addr );
|
||||
}
|
||||
|
||||
int SNES_SPC::dsp_envx_value( int ch )
|
||||
{
|
||||
return dsp.envx_value( ch );
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
// SPC emulation state save/load: copy_state(), save_spc()
|
||||
// Separate file to avoid linking in unless needed
|
||||
|
||||
// snes_spc 0.9.0. http://www.slack.net/‾ant/
|
||||
|
||||
#include "SNES_SPC.h"
|
||||
|
||||
#if !SPC_NO_COPY_STATE_FUNCS
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Copyright (C) 2004-2007 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "blargg_source.h"
|
||||
|
||||
#define RAM (m.ram.ram)
|
||||
#define REGS (m.smp_regs [0])
|
||||
#define REGS_IN (m.smp_regs [1])
|
||||
|
||||
void SNES_SPC::save_regs( uint8_t out [reg_count] )
|
||||
{
|
||||
// Use current timer counter values
|
||||
for ( int i = 0; i < timer_count; i++ )
|
||||
out [r_t0out + i] = m.timers [i].counter;
|
||||
|
||||
// Last written values
|
||||
memcpy( out, REGS, r_t0out );
|
||||
}
|
||||
|
||||
void SNES_SPC::init_header( void* spc_out )
|
||||
{
|
||||
spc_file_t* const spc = (spc_file_t*) spc_out;
|
||||
|
||||
spc->has_id666 = 26; // has none
|
||||
spc->version = 30;
|
||||
memcpy( spc, signature, sizeof spc->signature );
|
||||
memset( spc->text, 0, sizeof spc->text );
|
||||
}
|
||||
|
||||
void SNES_SPC::save_spc( void* spc_out )
|
||||
{
|
||||
spc_file_t* const spc = (spc_file_t*) spc_out;
|
||||
|
||||
// CPU
|
||||
spc->pcl = (uint8_t) (m.cpu_regs.pc >> 0);
|
||||
spc->pch = (uint8_t) (m.cpu_regs.pc >> 8);
|
||||
spc->a = m.cpu_regs.a;
|
||||
spc->x = m.cpu_regs.x;
|
||||
spc->y = m.cpu_regs.y;
|
||||
spc->psw = m.cpu_regs.psw;
|
||||
spc->sp = m.cpu_regs.sp;
|
||||
|
||||
// RAM, ROM
|
||||
memcpy( spc->ram, RAM, sizeof spc->ram );
|
||||
if ( m.rom_enabled )
|
||||
memcpy( spc->ram + rom_addr, m.hi_ram, sizeof m.hi_ram );
|
||||
memset( spc->unused, 0, sizeof spc->unused );
|
||||
memcpy( spc->ipl_rom, m.rom, sizeof spc->ipl_rom );
|
||||
|
||||
// SMP registers
|
||||
save_regs( &spc->ram [0xF0] );
|
||||
int i;
|
||||
for ( i = 0; i < port_count; i++ )
|
||||
spc->ram [0xF0 + r_cpuio0 + i] = REGS_IN [r_cpuio0 + i];
|
||||
|
||||
// DSP registers
|
||||
for ( i = 0; i < SPC_DSP::register_count; i++ )
|
||||
spc->dsp [i] = dsp.read( i );
|
||||
}
|
||||
|
||||
#undef IF_0_THEN_256
|
||||
#define IF_0_THEN_256( n ) ((uint8_t) ((n) - 1) + 1)
|
||||
void SNES_SPC::copy_state( unsigned char** io, copy_func_t copy )
|
||||
{
|
||||
SPC_State_Copier copier( io, copy );
|
||||
|
||||
// Make state data more readable by putting 64K RAM, 16 SMP registers,
|
||||
// then DSP (with its 128 registers) first
|
||||
|
||||
// RAM
|
||||
enable_rom( 0 ); // will get re-enabled if necessary in regs_loaded() below
|
||||
copier.copy( RAM, 0x10000 );
|
||||
|
||||
{
|
||||
// SMP registers
|
||||
uint8_t regs [reg_count];
|
||||
uint8_t regs_in [reg_count];
|
||||
|
||||
memcpy( regs, REGS, reg_count );
|
||||
memcpy( regs_in, REGS_IN, reg_count );
|
||||
|
||||
copier.copy( regs, sizeof regs );
|
||||
copier.copy( regs_in, sizeof regs_in );
|
||||
|
||||
memcpy( REGS, regs, reg_count);
|
||||
memcpy( REGS_IN, regs_in, reg_count );
|
||||
|
||||
enable_rom( REGS [r_control] & 0x80 );
|
||||
}
|
||||
|
||||
// CPU registers
|
||||
SPC_COPY( uint16_t, m.cpu_regs.pc );
|
||||
SPC_COPY( uint8_t, m.cpu_regs.a );
|
||||
SPC_COPY( uint8_t, m.cpu_regs.x );
|
||||
SPC_COPY( uint8_t, m.cpu_regs.y );
|
||||
SPC_COPY( uint8_t, m.cpu_regs.psw );
|
||||
SPC_COPY( uint8_t, m.cpu_regs.sp );
|
||||
copier.extra();
|
||||
|
||||
SPC_COPY( int16_t, m.spc_time );
|
||||
SPC_COPY( int16_t, m.dsp_time );
|
||||
|
||||
// DSP
|
||||
dsp.copy_state( io, copy );
|
||||
|
||||
// Timers
|
||||
for ( int i = 0; i < timer_count; i++ )
|
||||
{
|
||||
Timer* t = &m.timers [i];
|
||||
t->period = IF_0_THEN_256( REGS [r_t0target + i] );
|
||||
t->enabled = REGS [r_control] >> i & 1;
|
||||
SPC_COPY( int16_t, t->next_time );
|
||||
SPC_COPY( uint8_t, t->divider );
|
||||
SPC_COPY( uint8_t, t->counter );
|
||||
copier.extra();
|
||||
}
|
||||
|
||||
set_tempo( m.tempo );
|
||||
|
||||
copier.extra();
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,317 @@
|
|||
// Highly accurate SNES SPC-700 DSP emulator
|
||||
|
||||
// snes_spc 0.9.0
|
||||
#ifndef SPC_DSP_H
|
||||
#define SPC_DSP_H
|
||||
|
||||
#include "blargg_common.h"
|
||||
|
||||
extern "C" { typedef void (*dsp_copy_func_t)( unsigned char** io, void* state, size_t ); }
|
||||
|
||||
class SPC_DSP {
|
||||
public:
|
||||
typedef BOOST::uint8_t uint8_t;
|
||||
|
||||
// Setup
|
||||
|
||||
// Initializes DSP and has it use the 64K RAM provided
|
||||
void init( void* ram_64k );
|
||||
|
||||
// Sets destination for output samples. If out is NULL or out_size is 0,
|
||||
// doesn't generate any.
|
||||
typedef short sample_t;
|
||||
void set_output( sample_t* out, int out_size );
|
||||
|
||||
// Number of samples written to output since it was last set, always
|
||||
// a multiple of 2. Undefined if more samples were generated than
|
||||
// output buffer could hold.
|
||||
int sample_count() const;
|
||||
|
||||
// Emulation
|
||||
|
||||
// Resets DSP to power-on state
|
||||
void reset();
|
||||
|
||||
// Emulates pressing reset switch on SNES
|
||||
void soft_reset();
|
||||
|
||||
// Reads/writes DSP registers. For accuracy, you must first call run()
|
||||
// to catch the DSP up to present.
|
||||
int read ( int addr ) const;
|
||||
void write( int addr, int data );
|
||||
|
||||
// Runs DSP for specified number of clocks (~1024000 per second). Every 32 clocks
|
||||
// a pair of samples is be generated.
|
||||
void run( int clock_count );
|
||||
|
||||
// Sound control
|
||||
|
||||
// Mutes voices corresponding to non-zero bits in mask (issues repeated KOFF events).
|
||||
// Reduces emulation accuracy.
|
||||
enum { voice_count = 8 };
|
||||
void mute_voices( int mask );
|
||||
|
||||
// State
|
||||
|
||||
// Resets DSP and uses supplied values to initialize registers
|
||||
enum { register_count = 128 };
|
||||
void load( uint8_t const regs [register_count] );
|
||||
|
||||
// Saves/loads exact emulator state
|
||||
enum { state_size = 640 }; // maximum space needed when saving
|
||||
typedef dsp_copy_func_t copy_func_t;
|
||||
void copy_state( unsigned char** io, copy_func_t );
|
||||
|
||||
// Returns non-zero if new key-on events occurred since last call
|
||||
bool check_kon();
|
||||
|
||||
// Snes9x Accessor
|
||||
|
||||
int stereo_switch;
|
||||
int take_spc_snapshot;
|
||||
void (*spc_snapshot_callback) (void);
|
||||
|
||||
void set_spc_snapshot_callback( void (*callback) (void) );
|
||||
void dump_spc_snapshot( void );
|
||||
void set_stereo_switch( int );
|
||||
uint8_t reg_value( int, int );
|
||||
int envx_value( int );
|
||||
|
||||
// DSP register addresses
|
||||
|
||||
// Global registers
|
||||
enum {
|
||||
r_mvoll = 0x0C, r_mvolr = 0x1C,
|
||||
r_evoll = 0x2C, r_evolr = 0x3C,
|
||||
r_kon = 0x4C, r_koff = 0x5C,
|
||||
r_flg = 0x6C, r_endx = 0x7C,
|
||||
r_efb = 0x0D, r_pmon = 0x2D,
|
||||
r_non = 0x3D, r_eon = 0x4D,
|
||||
r_dir = 0x5D, r_esa = 0x6D,
|
||||
r_edl = 0x7D,
|
||||
r_fir = 0x0F // 8 coefficients at 0x0F, 0x1F ... 0x7F
|
||||
};
|
||||
|
||||
// Voice registers
|
||||
enum {
|
||||
v_voll = 0x00, v_volr = 0x01,
|
||||
v_pitchl = 0x02, v_pitchh = 0x03,
|
||||
v_srcn = 0x04, v_adsr0 = 0x05,
|
||||
v_adsr1 = 0x06, v_gain = 0x07,
|
||||
v_envx = 0x08, v_outx = 0x09
|
||||
};
|
||||
|
||||
public:
|
||||
enum { extra_size = 16 };
|
||||
sample_t* extra() { return m.extra; }
|
||||
sample_t const* out_pos() const { return m.out; }
|
||||
void disable_surround( bool ) { } // not supported
|
||||
public:
|
||||
BLARGG_DISABLE_NOTHROW
|
||||
|
||||
typedef BOOST::int8_t int8_t;
|
||||
typedef BOOST::int16_t int16_t;
|
||||
|
||||
enum { echo_hist_size = 8 };
|
||||
|
||||
enum env_mode_t { env_release, env_attack, env_decay, env_sustain };
|
||||
enum { brr_buf_size = 12 };
|
||||
struct voice_t
|
||||
{
|
||||
int buf [brr_buf_size*2];// decoded samples (twice the size to simplify wrap handling)
|
||||
int buf_pos; // place in buffer where next samples will be decoded
|
||||
int interp_pos; // relative fractional position in sample (0x1000 = 1.0)
|
||||
int brr_addr; // address of current BRR block
|
||||
int brr_offset; // current decoding offset in BRR block
|
||||
uint8_t* regs; // pointer to voice's DSP registers
|
||||
int vbit; // bitmask for voice: 0x01 for voice 0, 0x02 for voice 1, etc.
|
||||
int kon_delay; // KON delay/current setup phase
|
||||
env_mode_t env_mode;
|
||||
int env; // current envelope level
|
||||
int hidden_env; // used by GAIN mode 7, very obscure quirk
|
||||
uint8_t t_envx_out;
|
||||
int voice_number;
|
||||
};
|
||||
private:
|
||||
enum { brr_block_size = 9 };
|
||||
|
||||
struct state_t
|
||||
{
|
||||
uint8_t regs [register_count];
|
||||
|
||||
// Echo history keeps most recent 8 samples (twice the size to simplify wrap handling)
|
||||
int echo_hist [echo_hist_size * 2] [2];
|
||||
int (*echo_hist_pos) [2]; // &echo_hist [0 to 7]
|
||||
|
||||
int every_other_sample; // toggles every sample
|
||||
int kon; // KON value when last checked
|
||||
int noise;
|
||||
int counter;
|
||||
int echo_offset; // offset from ESA in echo buffer
|
||||
int echo_length; // number of bytes that echo_offset will stop at
|
||||
int phase; // next clock cycle to run (0-31)
|
||||
bool kon_check; // set when a new KON occurs
|
||||
|
||||
// Hidden registers also written to when main register is written to
|
||||
int new_kon;
|
||||
uint8_t endx_buf;
|
||||
uint8_t envx_buf;
|
||||
uint8_t outx_buf;
|
||||
|
||||
// Temporary state between clocks
|
||||
|
||||
// read once per sample
|
||||
int t_pmon;
|
||||
int t_non;
|
||||
int t_eon;
|
||||
int t_dir;
|
||||
int t_koff;
|
||||
|
||||
// read a few clocks ahead then used
|
||||
int t_brr_next_addr;
|
||||
int t_adsr0;
|
||||
int t_brr_header;
|
||||
int t_brr_byte;
|
||||
int t_srcn;
|
||||
int t_esa;
|
||||
int t_echo_enabled;
|
||||
|
||||
// internal state that is recalculated every sample
|
||||
int t_dir_addr;
|
||||
int t_pitch;
|
||||
int t_output;
|
||||
int t_looped;
|
||||
int t_echo_ptr;
|
||||
|
||||
// left/right sums
|
||||
int t_main_out [2];
|
||||
int t_echo_out [2];
|
||||
int t_echo_in [2];
|
||||
|
||||
voice_t voices [voice_count];
|
||||
|
||||
// non-emulation state
|
||||
uint8_t* ram; // 64K shared RAM between DSP and SMP
|
||||
int mute_mask;
|
||||
sample_t* out;
|
||||
sample_t* out_end;
|
||||
sample_t* out_begin;
|
||||
sample_t extra [extra_size];
|
||||
};
|
||||
state_t m;
|
||||
|
||||
void init_counter();
|
||||
void run_counters();
|
||||
unsigned read_counter( int rate );
|
||||
|
||||
int interpolate( voice_t const* v );
|
||||
void run_envelope( voice_t* const v );
|
||||
void decode_brr( voice_t* v );
|
||||
|
||||
void misc_27();
|
||||
void misc_28();
|
||||
void misc_29();
|
||||
void misc_30();
|
||||
|
||||
void voice_output( voice_t const* v, int ch );
|
||||
void voice_V1( voice_t* const );
|
||||
void voice_V2( voice_t* const );
|
||||
void voice_V3( voice_t* const );
|
||||
void voice_V3a( voice_t* const );
|
||||
void voice_V3b( voice_t* const );
|
||||
void voice_V3c( voice_t* const );
|
||||
void voice_V4( voice_t* const );
|
||||
void voice_V5( voice_t* const );
|
||||
void voice_V6( voice_t* const );
|
||||
void voice_V7( voice_t* const );
|
||||
void voice_V8( voice_t* const );
|
||||
void voice_V9( voice_t* const );
|
||||
void voice_V7_V4_V1( voice_t* const );
|
||||
void voice_V8_V5_V2( voice_t* const );
|
||||
void voice_V9_V6_V3( voice_t* const );
|
||||
|
||||
void echo_read( int ch );
|
||||
int echo_output( int ch );
|
||||
void echo_write( int ch );
|
||||
void echo_22();
|
||||
void echo_23();
|
||||
void echo_24();
|
||||
void echo_25();
|
||||
void echo_26();
|
||||
void echo_27();
|
||||
void echo_28();
|
||||
void echo_29();
|
||||
void echo_30();
|
||||
|
||||
void soft_reset_common();
|
||||
};
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
inline int SPC_DSP::sample_count() const { return m.out - m.out_begin; }
|
||||
|
||||
inline int SPC_DSP::read( int addr ) const
|
||||
{
|
||||
assert( (unsigned) addr < register_count );
|
||||
return m.regs [addr];
|
||||
}
|
||||
|
||||
inline void SPC_DSP::write( int addr, int data )
|
||||
{
|
||||
assert( (unsigned) addr < register_count );
|
||||
|
||||
m.regs [addr] = (uint8_t) data;
|
||||
switch ( addr & 0x0F )
|
||||
{
|
||||
case v_envx:
|
||||
m.envx_buf = (uint8_t) data;
|
||||
break;
|
||||
|
||||
case v_outx:
|
||||
m.outx_buf = (uint8_t) data;
|
||||
break;
|
||||
|
||||
case 0x0C:
|
||||
if ( addr == r_kon )
|
||||
m.new_kon = (uint8_t) data;
|
||||
|
||||
if ( addr == r_endx ) // always cleared, regardless of data written
|
||||
{
|
||||
m.endx_buf = 0;
|
||||
m.regs [r_endx] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline void SPC_DSP::mute_voices( int mask ) { m.mute_mask = mask; }
|
||||
|
||||
inline bool SPC_DSP::check_kon()
|
||||
{
|
||||
bool old = m.kon_check;
|
||||
m.kon_check = 0;
|
||||
return old;
|
||||
}
|
||||
|
||||
#if !SPC_NO_COPY_STATE_FUNCS
|
||||
|
||||
class SPC_State_Copier {
|
||||
SPC_DSP::copy_func_t func;
|
||||
unsigned char** buf;
|
||||
public:
|
||||
SPC_State_Copier( unsigned char** p, SPC_DSP::copy_func_t f ) { func = f; buf = p; }
|
||||
void copy( void* state, size_t size );
|
||||
int copy_int( int state, int size );
|
||||
void skip( int count );
|
||||
void extra();
|
||||
};
|
||||
|
||||
#define SPC_COPY( type, state )\
|
||||
{\
|
||||
state = (BOOST::type) copier.copy_int( state, sizeof (BOOST::type) );\
|
||||
assert( (BOOST::type) state == state );\
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,68 @@
|
|||
// snes_spc 0.9.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "SPC_Filter.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Copyright (C) 2007 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
void SPC_Filter::clear() { memset( ch, 0, sizeof ch ); }
|
||||
|
||||
SPC_Filter::SPC_Filter()
|
||||
{
|
||||
gain = gain_unit;
|
||||
bass = bass_norm;
|
||||
clear();
|
||||
}
|
||||
|
||||
void SPC_Filter::run( short* io, int count )
|
||||
{
|
||||
require( (count & 1) == 0 ); // must be even
|
||||
|
||||
int const gain = this->gain;
|
||||
int const bass = this->bass;
|
||||
chan_t* c = &ch [2];
|
||||
do
|
||||
{
|
||||
// cache in registers
|
||||
int sum = (--c)->sum;
|
||||
int pp1 = c->pp1;
|
||||
int p1 = c->p1;
|
||||
|
||||
for ( int i = 0; i < count; i += 2 )
|
||||
{
|
||||
// Low-pass filter (two point FIR with coeffs 0.25, 0.75)
|
||||
int f = io [i] + p1;
|
||||
p1 = io [i] * 3;
|
||||
|
||||
// High-pass filter ("leaky integrator")
|
||||
int delta = f - pp1;
|
||||
pp1 = f;
|
||||
int s = sum >> (gain_bits + 2);
|
||||
sum += (delta * gain) - (sum >> bass);
|
||||
|
||||
// Clamp to 16 bits
|
||||
if ( (short) s != s )
|
||||
s = (s >> 31) ^ 0x7FFF;
|
||||
|
||||
io [i] = (short) s;
|
||||
}
|
||||
|
||||
c->p1 = p1;
|
||||
c->pp1 = pp1;
|
||||
c->sum = sum;
|
||||
++io;
|
||||
}
|
||||
while ( c != ch );
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
// Simple low-pass and high-pass filter to better match sound output of a SNES
|
||||
|
||||
// snes_spc 0.9.0
|
||||
#ifndef SPC_FILTER_H
|
||||
#define SPC_FILTER_H
|
||||
|
||||
#include "blargg_common.h"
|
||||
|
||||
struct SPC_Filter {
|
||||
public:
|
||||
|
||||
// Filters count samples of stereo sound in place. Count must be a multiple of 2.
|
||||
typedef short sample_t;
|
||||
void run( sample_t* io, int count );
|
||||
|
||||
// Optional features
|
||||
|
||||
// Clears filter to silence
|
||||
void clear();
|
||||
|
||||
// Sets gain (volume), where gain_unit is normal. Gains greater than gain_unit
|
||||
// are fine, since output is clamped to 16-bit sample range.
|
||||
enum { gain_unit = 0x100 };
|
||||
void set_gain( int gain );
|
||||
|
||||
// Sets amount of bass (logarithmic scale)
|
||||
enum { bass_none = 0 };
|
||||
enum { bass_norm = 8 }; // normal amount
|
||||
enum { bass_max = 31 };
|
||||
void set_bass( int bass );
|
||||
|
||||
public:
|
||||
SPC_Filter();
|
||||
BLARGG_DISABLE_NOTHROW
|
||||
private:
|
||||
enum { gain_bits = 8 };
|
||||
int gain;
|
||||
int bass;
|
||||
struct chan_t { int p1, pp1, sum; };
|
||||
chan_t ch [2];
|
||||
};
|
||||
|
||||
inline void SPC_Filter::set_gain( int g ) { gain = g; }
|
||||
|
||||
inline void SPC_Filter::set_bass( int b ) { bass = b; }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,654 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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 <math.h>
|
||||
#include "snes9x.h"
|
||||
#include "apu.h"
|
||||
#include "snapshot.h"
|
||||
#include "display.h"
|
||||
#include "resampler.h"
|
||||
|
||||
#define APU_DEFAULT_INPUT_RATE 32000
|
||||
#define APU_MINIMUM_SAMPLE_COUNT 512
|
||||
#define APU_MINIMUM_SAMPLE_BLOCK 128
|
||||
#define APU_NUMERATOR_NTSC 5632
|
||||
#define APU_DENOMINATOR_NTSC 118125
|
||||
#define APU_NUMERATOR_PAL 102400
|
||||
#define APU_DENOMINATOR_PAL 2128137
|
||||
|
||||
SNES_SPC *spc_core = NULL;
|
||||
|
||||
static uint8 APUROM[64] =
|
||||
{
|
||||
0xCD, 0xEF, 0xBD, 0xE8, 0x00, 0xC6, 0x1D, 0xD0,
|
||||
0xFC, 0x8F, 0xAA, 0xF4, 0x8F, 0xBB, 0xF5, 0x78,
|
||||
0xCC, 0xF4, 0xD0, 0xFB, 0x2F, 0x19, 0xEB, 0xF4,
|
||||
0xD0, 0xFC, 0x7E, 0xF4, 0xD0, 0x0B, 0xE4, 0xF5,
|
||||
0xCB, 0xF4, 0xD7, 0x00, 0xFC, 0xD0, 0xF3, 0xAB,
|
||||
0x01, 0x10, 0xEF, 0x7E, 0xF4, 0x10, 0xEB, 0xBA,
|
||||
0xF6, 0xDA, 0x00, 0xBA, 0xF4, 0xC4, 0xF4, 0xDD,
|
||||
0x5D, 0xD0, 0xDB, 0x1F, 0x00, 0x00, 0xC0, 0xFF
|
||||
};
|
||||
|
||||
namespace spc
|
||||
{
|
||||
static apu_callback sa_callback = NULL;
|
||||
static void *extra_data = NULL;
|
||||
|
||||
static bool8 sound_in_sync = TRUE;
|
||||
static bool8 sound_enabled = FALSE;
|
||||
|
||||
static int buffer_size;
|
||||
static int lag_master = 0;
|
||||
static int lag = 0;
|
||||
|
||||
static uint8 *landing_buffer = NULL;
|
||||
static uint8 *shrink_buffer = NULL;
|
||||
|
||||
static Resampler *resampler = NULL;
|
||||
|
||||
static int32 reference_time;
|
||||
static uint32 remainder;
|
||||
|
||||
static const int32 timing_hack_numerator = SNES_SPC::tempo_unit;
|
||||
static int32 timing_hack_denominator = SNES_SPC::tempo_unit;
|
||||
}
|
||||
|
||||
static void EightBitize (uint8 *, int);
|
||||
static void DeStereo (uint8 *, int);
|
||||
static void ReverseStereo (uint8 *, int);
|
||||
static void UpdatePlaybackRate (void);
|
||||
static void from_apu_to_state (uint8 **, void *, size_t);
|
||||
static void to_apu_from_state (uint8 **, void *, size_t);
|
||||
static void SPCSnapshotCallback (void);
|
||||
static inline int S9xAPUGetClock (int32);
|
||||
static inline int S9xAPUGetClockRemainder (int32);
|
||||
|
||||
|
||||
static void EightBitize (uint8 *buffer, int sample_count)
|
||||
{
|
||||
uint8 *buf8 = (uint8 *) buffer;
|
||||
int16 *buf16 = (int16 *) buffer;
|
||||
|
||||
for (int i = 0; i < sample_count; i++)
|
||||
buf8[i] = (uint8) ((buf16[i] / 256) + 128);
|
||||
}
|
||||
|
||||
static void DeStereo (uint8 *buffer, int sample_count)
|
||||
{
|
||||
int16 *buf = (int16 *) buffer;
|
||||
int32 s1, s2;
|
||||
|
||||
for (int i = 0; i < sample_count >> 1; i++)
|
||||
{
|
||||
s1 = (int32) buf[2 * i];
|
||||
s2 = (int32) buf[2 * i + 1];
|
||||
buf[i] = (int16) ((s1 + s2) >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void ReverseStereo (uint8 *src_buffer, int sample_count)
|
||||
{
|
||||
int16 *buffer = (int16 *) src_buffer;
|
||||
|
||||
for (int i = 0; i < sample_count; i += 2)
|
||||
{
|
||||
buffer[i + 1] ^= buffer[i];
|
||||
buffer[i] ^= buffer[i + 1];
|
||||
buffer[i + 1] ^= buffer[i];
|
||||
}
|
||||
}
|
||||
|
||||
bool8 S9xMixSamples (uint8 *buffer, int sample_count)
|
||||
{
|
||||
static int shrink_buffer_size = -1;
|
||||
uint8 *dest;
|
||||
|
||||
if (!Settings.SixteenBitSound || !Settings.Stereo)
|
||||
{
|
||||
/* We still need both stereo samples for generating the mono sample */
|
||||
if (!Settings.Stereo)
|
||||
sample_count <<= 1;
|
||||
|
||||
/* We still have to generate 16-bit samples for bit-dropping, too */
|
||||
if (shrink_buffer_size < (sample_count << 1))
|
||||
{
|
||||
delete[] spc::shrink_buffer;
|
||||
spc::shrink_buffer = new uint8[sample_count << 1];
|
||||
shrink_buffer_size = sample_count << 1;
|
||||
}
|
||||
|
||||
dest = spc::shrink_buffer;
|
||||
}
|
||||
else
|
||||
dest = buffer;
|
||||
|
||||
if (Settings.Mute)
|
||||
{
|
||||
memset(dest, 0, sample_count << 1);
|
||||
spc::resampler->clear();
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (spc::resampler->avail() >= (sample_count + spc::lag))
|
||||
{
|
||||
spc::resampler->read((short *) dest, sample_count);
|
||||
if (spc::lag == spc::lag_master)
|
||||
spc::lag = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(buffer, (Settings.SixteenBitSound ? 0 : 128), (sample_count << (Settings.SixteenBitSound ? 1 : 0)) >> (Settings.Stereo ? 0 : 1));
|
||||
if (spc::lag == 0)
|
||||
spc::lag = spc::lag_master;
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings.ReverseStereo && Settings.Stereo)
|
||||
ReverseStereo(dest, sample_count);
|
||||
|
||||
if (!Settings.Stereo || !Settings.SixteenBitSound)
|
||||
{
|
||||
if (!Settings.Stereo)
|
||||
{
|
||||
DeStereo(dest, sample_count);
|
||||
sample_count >>= 1;
|
||||
}
|
||||
|
||||
if (!Settings.SixteenBitSound)
|
||||
EightBitize(dest, sample_count);
|
||||
|
||||
memcpy(buffer, dest, (sample_count << (Settings.SixteenBitSound ? 1 : 0)));
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
int S9xGetSampleCount (void)
|
||||
{
|
||||
return (spc::resampler->avail() >> (Settings.Stereo ? 0 : 1));
|
||||
}
|
||||
|
||||
void S9xFinalizeSamples (void)
|
||||
{
|
||||
if (!Settings.Mute)
|
||||
{
|
||||
if (!spc::resampler->push((short *) spc::landing_buffer, spc_core->sample_count()))
|
||||
{
|
||||
/* We weren't able to process the entire buffer. Potential overrun. */
|
||||
spc::sound_in_sync = FALSE;
|
||||
|
||||
if (Settings.SoundSync && !Settings.TurboMode)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Settings.SoundSync || Settings.TurboMode || Settings.Mute)
|
||||
spc::sound_in_sync = TRUE;
|
||||
else
|
||||
if (spc::resampler->space_empty() >= spc::resampler->space_filled())
|
||||
spc::sound_in_sync = TRUE;
|
||||
else
|
||||
spc::sound_in_sync = FALSE;
|
||||
|
||||
spc_core->set_output((SNES_SPC::sample_t *) spc::landing_buffer, spc::buffer_size >> 1);
|
||||
}
|
||||
|
||||
void S9xLandSamples (void)
|
||||
{
|
||||
if (spc::sa_callback != NULL)
|
||||
spc::sa_callback(spc::extra_data);
|
||||
else
|
||||
S9xFinalizeSamples();
|
||||
}
|
||||
|
||||
void S9xClearSamples (void)
|
||||
{
|
||||
spc::resampler->clear();
|
||||
spc::lag = spc::lag_master;
|
||||
}
|
||||
|
||||
bool8 S9xSyncSound (void)
|
||||
{
|
||||
if (!Settings.SoundSync || spc::sound_in_sync)
|
||||
return (TRUE);
|
||||
|
||||
S9xLandSamples();
|
||||
|
||||
return (spc::sound_in_sync);
|
||||
}
|
||||
|
||||
void S9xSetSamplesAvailableCallback (apu_callback callback, void *data)
|
||||
{
|
||||
spc::sa_callback = callback;
|
||||
spc::extra_data = data;
|
||||
}
|
||||
|
||||
static void UpdatePlaybackRate (void)
|
||||
{
|
||||
if (Settings.SoundInputRate == 0)
|
||||
Settings.SoundInputRate = APU_DEFAULT_INPUT_RATE;
|
||||
|
||||
double time_ratio = (double) Settings.SoundInputRate * spc::timing_hack_numerator / (Settings.SoundPlaybackRate * spc::timing_hack_denominator);
|
||||
spc::resampler->time_ratio(time_ratio);
|
||||
}
|
||||
|
||||
bool8 S9xInitSound (int buffer_ms, int lag_ms)
|
||||
{
|
||||
// buffer_ms : buffer size given in millisecond
|
||||
// lag_ms : allowable time-lag given in millisecond
|
||||
|
||||
int sample_count = buffer_ms * 32000 / 1000;
|
||||
int lag_sample_count = lag_ms * 32000 / 1000;
|
||||
|
||||
spc::lag_master = lag_sample_count;
|
||||
if (Settings.Stereo)
|
||||
spc::lag_master <<= 1;
|
||||
spc::lag = spc::lag_master;
|
||||
|
||||
if (sample_count < APU_MINIMUM_SAMPLE_COUNT)
|
||||
sample_count = APU_MINIMUM_SAMPLE_COUNT;
|
||||
|
||||
spc::buffer_size = sample_count;
|
||||
if (Settings.Stereo)
|
||||
spc::buffer_size <<= 1;
|
||||
if (Settings.SixteenBitSound)
|
||||
spc::buffer_size <<= 1;
|
||||
|
||||
printf("Sound buffer size: %d (%d samples)\n", spc::buffer_size, sample_count);
|
||||
|
||||
if (spc::landing_buffer)
|
||||
delete[] spc::landing_buffer;
|
||||
spc::landing_buffer = new uint8[spc::buffer_size * 2];
|
||||
if (!spc::landing_buffer)
|
||||
return (FALSE);
|
||||
|
||||
/* The resampler and spc unit use samples (16-bit short) as
|
||||
arguments. Use 2x in the resampler for buffer leveling with SoundSync */
|
||||
if (!spc::resampler)
|
||||
{
|
||||
spc::resampler = new Resampler(spc::buffer_size >> (Settings.SoundSync ? 0 : 1));
|
||||
if (!spc::resampler)
|
||||
{
|
||||
delete[] spc::landing_buffer;
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
spc::resampler->resize(spc::buffer_size >> (Settings.SoundSync ? 0 : 1));
|
||||
|
||||
spc_core->set_output((SNES_SPC::sample_t *) spc::landing_buffer, spc::buffer_size >> 1);
|
||||
|
||||
UpdatePlaybackRate();
|
||||
|
||||
spc::sound_enabled = S9xOpenSoundDevice();
|
||||
|
||||
return (spc::sound_enabled);
|
||||
}
|
||||
|
||||
void S9xSetSoundControl (uint8 voice_switch)
|
||||
{
|
||||
spc_core->dsp_set_stereo_switch(voice_switch << 8 | voice_switch);
|
||||
}
|
||||
|
||||
void S9xSetSoundMute (bool8 mute)
|
||||
{
|
||||
Settings.Mute = mute;
|
||||
if (!spc::sound_enabled)
|
||||
Settings.Mute = TRUE;
|
||||
}
|
||||
|
||||
void S9xDumpSPCSnapshot (void)
|
||||
{
|
||||
spc_core->dsp_dump_spc_snapshot();
|
||||
}
|
||||
|
||||
static void SPCSnapshotCallback (void)
|
||||
{
|
||||
S9xSPCDump(S9xGetFilenameInc((".spc"), SPC_DIR));
|
||||
printf("Dumped key-on triggered spc snapshot.\n");
|
||||
}
|
||||
|
||||
bool8 S9xInitAPU (void)
|
||||
{
|
||||
spc_core = new SNES_SPC;
|
||||
if (!spc_core)
|
||||
return (FALSE);
|
||||
|
||||
spc_core->init();
|
||||
spc_core->init_rom(APUROM);
|
||||
|
||||
spc_core->dsp_set_spc_snapshot_callback(SPCSnapshotCallback);
|
||||
|
||||
spc::landing_buffer = NULL;
|
||||
spc::shrink_buffer = NULL;
|
||||
spc::resampler = NULL;
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
void S9xDeinitAPU (void)
|
||||
{
|
||||
if (spc_core)
|
||||
{
|
||||
delete spc_core;
|
||||
spc_core = NULL;
|
||||
}
|
||||
|
||||
if (spc::resampler)
|
||||
{
|
||||
delete spc::resampler;
|
||||
spc::resampler = NULL;
|
||||
}
|
||||
|
||||
if (spc::landing_buffer)
|
||||
{
|
||||
delete[] spc::landing_buffer;
|
||||
spc::landing_buffer = NULL;
|
||||
}
|
||||
|
||||
if (spc::shrink_buffer)
|
||||
{
|
||||
delete[] spc::shrink_buffer;
|
||||
spc::shrink_buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int S9xAPUGetClock (int32 cpucycles)
|
||||
{
|
||||
if (Settings.PAL)
|
||||
return ((int) floor(((double) APU_NUMERATOR_PAL * spc::timing_hack_numerator * (cpucycles - spc::reference_time) + spc::remainder) /
|
||||
((double) APU_DENOMINATOR_PAL * spc::timing_hack_denominator)));
|
||||
else
|
||||
return (APU_NUMERATOR_NTSC * spc::timing_hack_numerator * (cpucycles - spc::reference_time) + spc::remainder) /
|
||||
(APU_DENOMINATOR_NTSC * spc::timing_hack_denominator);
|
||||
}
|
||||
|
||||
static inline int S9xAPUGetClockRemainder (int32 cpucycles)
|
||||
{
|
||||
if (Settings.PAL)
|
||||
return ((int) fmod (((double) APU_NUMERATOR_PAL * spc::timing_hack_numerator * (cpucycles - spc::reference_time) + spc::remainder),
|
||||
((double) APU_DENOMINATOR_PAL * spc::timing_hack_denominator)));
|
||||
else
|
||||
return (APU_NUMERATOR_NTSC * spc::timing_hack_numerator * (cpucycles - spc::reference_time) + spc::remainder) %
|
||||
(APU_DENOMINATOR_NTSC * spc::timing_hack_denominator);
|
||||
}
|
||||
|
||||
uint8 S9xAPUReadPort (int port)
|
||||
{
|
||||
return ((uint8) spc_core->read_port(S9xAPUGetClock(CPU.Cycles), port));
|
||||
}
|
||||
|
||||
void S9xAPUWritePort (int port, uint8 byte)
|
||||
{
|
||||
spc_core->write_port(S9xAPUGetClock(CPU.Cycles), port, byte);
|
||||
}
|
||||
|
||||
void S9xAPUSetReferenceTime (int32 cpucycles)
|
||||
{
|
||||
spc::reference_time = cpucycles;
|
||||
}
|
||||
|
||||
void S9xAPUExecute (void)
|
||||
{
|
||||
/* Accumulate partial APU cycles */
|
||||
spc_core->end_frame(S9xAPUGetClock(CPU.Cycles));
|
||||
|
||||
spc::remainder = S9xAPUGetClockRemainder(CPU.Cycles);
|
||||
|
||||
S9xAPUSetReferenceTime(CPU.Cycles);
|
||||
}
|
||||
|
||||
void S9xAPUEndScanline (void)
|
||||
{
|
||||
S9xAPUExecute();
|
||||
|
||||
if (spc_core->sample_count() >= APU_MINIMUM_SAMPLE_BLOCK || !spc::sound_in_sync)
|
||||
S9xLandSamples();
|
||||
}
|
||||
|
||||
void S9xAPUTimingSetSpeedup (int ticks)
|
||||
{
|
||||
if (ticks != 0)
|
||||
printf("APU speedup hack: %d\n", ticks);
|
||||
|
||||
spc_core->set_tempo(SNES_SPC::tempo_unit - ticks);
|
||||
|
||||
spc::timing_hack_denominator = SNES_SPC::tempo_unit - ticks;
|
||||
|
||||
UpdatePlaybackRate();
|
||||
}
|
||||
|
||||
void S9xResetAPU (void)
|
||||
{
|
||||
spc::reference_time = 0;
|
||||
spc::remainder = 0;
|
||||
spc_core->reset();
|
||||
spc_core->set_output((SNES_SPC::sample_t *) spc::landing_buffer, spc::buffer_size >> 1);
|
||||
|
||||
spc::resampler->clear();
|
||||
}
|
||||
|
||||
void S9xSoftResetAPU (void)
|
||||
{
|
||||
spc::reference_time = 0;
|
||||
spc::remainder = 0;
|
||||
spc_core->soft_reset();
|
||||
spc_core->set_output((SNES_SPC::sample_t *) spc::landing_buffer, spc::buffer_size >> 1);
|
||||
|
||||
spc::resampler->clear();
|
||||
}
|
||||
|
||||
static void from_apu_to_state (uint8 **buf, void *var, size_t size)
|
||||
{
|
||||
memcpy(*buf, var, size);
|
||||
*buf += size;
|
||||
}
|
||||
|
||||
static void to_apu_from_state (uint8 **buf, void *var, size_t size)
|
||||
{
|
||||
memcpy(var, *buf, size);
|
||||
*buf += size;
|
||||
}
|
||||
|
||||
void S9xAPUSaveState (uint8 *block)
|
||||
{
|
||||
uint8 *ptr = block;
|
||||
|
||||
spc_core->copy_state(&ptr, from_apu_to_state);
|
||||
|
||||
SET_LE32(ptr, spc::reference_time);
|
||||
ptr += sizeof(int32);
|
||||
SET_LE32(ptr, spc::remainder);
|
||||
}
|
||||
|
||||
void S9xAPULoadState (uint8 *block)
|
||||
{
|
||||
uint8 *ptr = block;
|
||||
|
||||
S9xResetAPU();
|
||||
|
||||
spc_core->copy_state(&ptr, to_apu_from_state);
|
||||
|
||||
spc::reference_time = GET_LE32(ptr);
|
||||
ptr += sizeof(int32);
|
||||
spc::remainder = GET_LE32(ptr);
|
||||
}
|
|
@ -0,0 +1,217 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _APU_H_
|
||||
#define _APU_H_
|
||||
|
||||
#include "snes9x.h"
|
||||
#include "SNES_SPC.h"
|
||||
|
||||
typedef void (*apu_callback) (void *);
|
||||
|
||||
#define SPC_SAVE_STATE_BLOCK_SIZE (SNES_SPC::state_size + 8)
|
||||
|
||||
bool8 S9xInitAPU (void);
|
||||
void S9xDeinitAPU (void);
|
||||
void S9xResetAPU (void);
|
||||
void S9xSoftResetAPU (void);
|
||||
uint8 S9xAPUReadPort (int);
|
||||
void S9xAPUWritePort (int, uint8);
|
||||
void S9xAPUExecute (void);
|
||||
void S9xAPUEndScanline (void);
|
||||
void S9xAPUSetReferenceTime (int32);
|
||||
void S9xAPUTimingSetSpeedup (int);
|
||||
void S9xAPULoadState (uint8 *);
|
||||
void S9xAPUSaveState (uint8 *);
|
||||
void S9xDumpSPCSnapshot (void);
|
||||
|
||||
bool8 S9xInitSound (int, int);
|
||||
bool8 S9xOpenSoundDevice (void);
|
||||
|
||||
bool8 S9xSyncSound (void);
|
||||
int S9xGetSampleCount (void);
|
||||
void S9xSetSoundControl (uint8);
|
||||
void S9xSetSoundMute (bool8);
|
||||
void S9xLandSamples (void);
|
||||
void S9xFinalizeSamples (void);
|
||||
void S9xClearSamples (void);
|
||||
bool8 S9xMixSamples (uint8 *, int);
|
||||
void S9xSetSamplesAvailableCallback (apu_callback, void *);
|
||||
|
||||
extern SNES_SPC *spc_core;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,186 @@
|
|||
// Sets up common environment for Shay Green's libraries.
|
||||
// To change configuration options, modify blargg_config.h, not this file.
|
||||
|
||||
// snes_spc 0.9.0
|
||||
#ifndef BLARGG_COMMON_H
|
||||
#define BLARGG_COMMON_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#undef BLARGG_COMMON_H
|
||||
// allow blargg_config.h to #include blargg_common.h
|
||||
#include "blargg_config.h"
|
||||
#ifndef BLARGG_COMMON_H
|
||||
#define BLARGG_COMMON_H
|
||||
|
||||
// BLARGG_RESTRICT: equivalent to restrict, where supported
|
||||
#if defined (__GNUC__) || _MSC_VER >= 1100
|
||||
#define BLARGG_RESTRICT __restrict
|
||||
#else
|
||||
#define BLARGG_RESTRICT
|
||||
#endif
|
||||
|
||||
// STATIC_CAST(T,expr): Used in place of static_cast<T> (expr)
|
||||
#ifndef STATIC_CAST
|
||||
#define STATIC_CAST(T,expr) ((T) (expr))
|
||||
#endif
|
||||
|
||||
// blargg_err_t (0 on success, otherwise error string)
|
||||
#ifndef blargg_err_t
|
||||
typedef const char* blargg_err_t;
|
||||
#endif
|
||||
|
||||
// blargg_vector - very lightweight vector of POD types (no constructor/destructor)
|
||||
template<class T>
|
||||
class blargg_vector {
|
||||
T* begin_;
|
||||
size_t size_;
|
||||
public:
|
||||
blargg_vector() : begin_( 0 ), size_( 0 ) { }
|
||||
~blargg_vector() { free( begin_ ); }
|
||||
size_t size() const { return size_; }
|
||||
T* begin() const { return begin_; }
|
||||
T* end() const { return begin_ + size_; }
|
||||
blargg_err_t resize( size_t n )
|
||||
{
|
||||
// TODO: blargg_common.cpp to hold this as an outline function, ugh
|
||||
void* p = realloc( begin_, n * sizeof (T) );
|
||||
if ( p )
|
||||
begin_ = (T*) p;
|
||||
else if ( n > size_ ) // realloc failure only a problem if expanding
|
||||
return "Out of memory";
|
||||
size_ = n;
|
||||
return 0;
|
||||
}
|
||||
void clear() { void* p = begin_; begin_ = 0; size_ = 0; free( p ); }
|
||||
T& operator [] ( size_t n ) const
|
||||
{
|
||||
assert( n <= size_ ); // <= to allow past-the-end value
|
||||
return begin_ [n];
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef BLARGG_DISABLE_NOTHROW
|
||||
// throw spec mandatory in ISO C++ if operator new can return NULL
|
||||
#if __cplusplus >= 199711 || defined (__GNUC__)
|
||||
#define BLARGG_THROWS( spec ) throw spec
|
||||
#else
|
||||
#define BLARGG_THROWS( spec )
|
||||
#endif
|
||||
#define BLARGG_DISABLE_NOTHROW \
|
||||
void* operator new ( size_t s ) BLARGG_THROWS(()) { return malloc( s ); }\
|
||||
void operator delete ( void* p ) { free( p ); }
|
||||
#define BLARGG_NEW new
|
||||
#else
|
||||
#include <new>
|
||||
#define BLARGG_NEW new (std::nothrow)
|
||||
#endif
|
||||
|
||||
// BLARGG_4CHAR('a','b','c','d') = 'abcd' (four character integer constant)
|
||||
#define BLARGG_4CHAR( a, b, c, d ) \
|
||||
((a&0xFF)*0x1000000L + (b&0xFF)*0x10000L + (c&0xFF)*0x100L + (d&0xFF))
|
||||
|
||||
// BOOST_STATIC_ASSERT( expr ): Generates compile error if expr is 0.
|
||||
#ifndef BOOST_STATIC_ASSERT
|
||||
#ifdef _MSC_VER
|
||||
// MSVC6 (_MSC_VER < 1300) fails for use of __LINE__ when /Zl is specified
|
||||
#define BOOST_STATIC_ASSERT( expr ) \
|
||||
void blargg_failed_( int (*arg) [2 / (int) !!(expr) - 1] )
|
||||
#else
|
||||
// Some other compilers fail when declaring same function multiple times in class,
|
||||
// so differentiate them by line
|
||||
#define BOOST_STATIC_ASSERT( expr ) \
|
||||
void blargg_failed_( int (*arg) [2 / !!(expr) - 1] [__LINE__] )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// BLARGG_COMPILER_HAS_BOOL: If 0, provides bool support for old compiler. If 1,
|
||||
// compiler is assumed to support bool. If undefined, availability is determined.
|
||||
#ifndef BLARGG_COMPILER_HAS_BOOL
|
||||
#if defined (__MWERKS__)
|
||||
#if !__option(bool)
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
#elif defined (_MSC_VER)
|
||||
#if _MSC_VER < 1100
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
#elif defined (__GNUC__)
|
||||
// supports bool
|
||||
#elif __cplusplus < 199711
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
#endif
|
||||
#if defined (BLARGG_COMPILER_HAS_BOOL) && !BLARGG_COMPILER_HAS_BOOL
|
||||
// If you get errors here, modify your blargg_config.h file
|
||||
typedef int bool;
|
||||
const bool true = 1;
|
||||
const bool false = 0;
|
||||
#endif
|
||||
|
||||
// blargg_long/blargg_ulong = at least 32 bits, int if it's big enough
|
||||
|
||||
#if INT_MAX < 0x7FFFFFFF || LONG_MAX == 0x7FFFFFFF
|
||||
typedef long blargg_long;
|
||||
#else
|
||||
typedef int blargg_long;
|
||||
#endif
|
||||
|
||||
#if UINT_MAX < 0xFFFFFFFF || ULONG_MAX == 0xFFFFFFFF
|
||||
typedef unsigned long blargg_ulong;
|
||||
#else
|
||||
typedef unsigned blargg_ulong;
|
||||
#endif
|
||||
|
||||
// BOOST::int8_t etc.
|
||||
|
||||
// HAVE_STDINT_H: If defined, use <stdint.h> for int8_t etc.
|
||||
#if defined (HAVE_STDINT_H)
|
||||
#include <stdint.h>
|
||||
#define BOOST
|
||||
|
||||
// HAVE_INTTYPES_H: If defined, use <stdint.h> for int8_t etc.
|
||||
#elif defined (HAVE_INTTYPES_H)
|
||||
#include <inttypes.h>
|
||||
#define BOOST
|
||||
|
||||
#else
|
||||
struct BOOST
|
||||
{
|
||||
#if UCHAR_MAX == 0xFF && SCHAR_MAX == 0x7F
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
#else
|
||||
// No suitable 8-bit type available
|
||||
typedef struct see_blargg_common_h int8_t;
|
||||
typedef struct see_blargg_common_h uint8_t;
|
||||
#endif
|
||||
|
||||
#if USHRT_MAX == 0xFFFF
|
||||
typedef short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
#else
|
||||
// No suitable 16-bit type available
|
||||
typedef struct see_blargg_common_h int16_t;
|
||||
typedef struct see_blargg_common_h uint16_t;
|
||||
#endif
|
||||
|
||||
#if ULONG_MAX == 0xFFFFFFFF
|
||||
typedef long int32_t;
|
||||
typedef unsigned long uint32_t;
|
||||
#elif UINT_MAX == 0xFFFFFFFF
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
// No suitable 32-bit type available
|
||||
typedef struct see_blargg_common_h int32_t;
|
||||
typedef struct see_blargg_common_h uint32_t;
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,24 @@
|
|||
// snes_spc 0.9.0 user configuration file. Don't replace when updating library.
|
||||
|
||||
// snes_spc 0.9.0
|
||||
#ifndef BLARGG_CONFIG_H
|
||||
#define BLARGG_CONFIG_H
|
||||
|
||||
// Uncomment to disable debugging checks
|
||||
//#define NDEBUG 1
|
||||
|
||||
// Uncomment to enable platform-specific (and possibly non-portable) optimizations
|
||||
//#define BLARGG_NONPORTABLE 1
|
||||
|
||||
// Uncomment if automatic byte-order determination doesn't work
|
||||
//#define BLARGG_BIG_ENDIAN 1
|
||||
|
||||
// Uncomment if you get errors in the bool section of blargg_common.h
|
||||
//#define BLARGG_COMPILER_HAS_BOOL 1
|
||||
|
||||
// Use standard config.h if present
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,185 @@
|
|||
// CPU Byte Order Utilities
|
||||
|
||||
// snes_spc 0.9.0
|
||||
#ifndef BLARGG_ENDIAN
|
||||
#define BLARGG_ENDIAN
|
||||
|
||||
#include "blargg_common.h"
|
||||
|
||||
// BLARGG_CPU_CISC: Defined if CPU has very few general-purpose registers (< 16)
|
||||
#if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \
|
||||
defined (__x86_64__) || defined (__ia64__) || defined (__i386__)
|
||||
#define BLARGG_CPU_X86 1
|
||||
#define BLARGG_CPU_CISC 1
|
||||
#endif
|
||||
|
||||
#if defined (__powerpc__) || defined (__ppc__) || defined (__POWERPC__) || defined (__powerc)
|
||||
#define BLARGG_CPU_POWERPC 1
|
||||
#define BLARGG_CPU_RISC 1
|
||||
#endif
|
||||
|
||||
// BLARGG_BIG_ENDIAN, BLARGG_LITTLE_ENDIAN: Determined automatically, otherwise only
|
||||
// one may be #defined to 1. Only needed if something actually depends on byte order.
|
||||
#if !defined (BLARGG_BIG_ENDIAN) && !defined (BLARGG_LITTLE_ENDIAN)
|
||||
#ifdef __GLIBC__
|
||||
// GCC handles this for us
|
||||
#include <endian.h>
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define BLARGG_LITTLE_ENDIAN 1
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define BLARGG_BIG_ENDIAN 1
|
||||
#endif
|
||||
#else
|
||||
|
||||
#if defined (LSB_FIRST) || defined (__LITTLE_ENDIAN__) || BLARGG_CPU_X86 || \
|
||||
(defined (LITTLE_ENDIAN) && LITTLE_ENDIAN+0 != 1234)
|
||||
#define BLARGG_LITTLE_ENDIAN 1
|
||||
#endif
|
||||
|
||||
#if defined (MSB_FIRST) || defined (__BIG_ENDIAN__) || defined (WORDS_BIGENDIAN) || \
|
||||
defined (__sparc__) || BLARGG_CPU_POWERPC || \
|
||||
(defined (BIG_ENDIAN) && BIG_ENDIAN+0 != 4321)
|
||||
#define BLARGG_BIG_ENDIAN 1
|
||||
#elif !defined (__mips__)
|
||||
// No endian specified; assume little-endian, since it's most common
|
||||
#define BLARGG_LITTLE_ENDIAN 1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if BLARGG_LITTLE_ENDIAN && BLARGG_BIG_ENDIAN
|
||||
#undef BLARGG_LITTLE_ENDIAN
|
||||
#undef BLARGG_BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
inline void blargg_verify_byte_order()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
#if BLARGG_BIG_ENDIAN
|
||||
volatile int i = 1;
|
||||
assert( *(volatile char*) &i == 0 );
|
||||
#elif BLARGG_LITTLE_ENDIAN
|
||||
volatile int i = 1;
|
||||
assert( *(volatile char*) &i != 0 );
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
inline unsigned get_le16( void const* p )
|
||||
{
|
||||
return (unsigned) ((unsigned char const*) p) [1] << 8 |
|
||||
(unsigned) ((unsigned char const*) p) [0];
|
||||
}
|
||||
|
||||
inline unsigned get_be16( void const* p )
|
||||
{
|
||||
return (unsigned) ((unsigned char const*) p) [0] << 8 |
|
||||
(unsigned) ((unsigned char const*) p) [1];
|
||||
}
|
||||
|
||||
inline blargg_ulong get_le32( void const* p )
|
||||
{
|
||||
return (blargg_ulong) ((unsigned char const*) p) [3] << 24 |
|
||||
(blargg_ulong) ((unsigned char const*) p) [2] << 16 |
|
||||
(blargg_ulong) ((unsigned char const*) p) [1] << 8 |
|
||||
(blargg_ulong) ((unsigned char const*) p) [0];
|
||||
}
|
||||
|
||||
inline blargg_ulong get_be32( void const* p )
|
||||
{
|
||||
return (blargg_ulong) ((unsigned char const*) p) [0] << 24 |
|
||||
(blargg_ulong) ((unsigned char const*) p) [1] << 16 |
|
||||
(blargg_ulong) ((unsigned char const*) p) [2] << 8 |
|
||||
(blargg_ulong) ((unsigned char const*) p) [3];
|
||||
}
|
||||
|
||||
inline void set_le16( void* p, unsigned n )
|
||||
{
|
||||
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
|
||||
((unsigned char*) p) [0] = (unsigned char) n;
|
||||
}
|
||||
|
||||
inline void set_be16( void* p, unsigned n )
|
||||
{
|
||||
((unsigned char*) p) [0] = (unsigned char) (n >> 8);
|
||||
((unsigned char*) p) [1] = (unsigned char) n;
|
||||
}
|
||||
|
||||
inline void set_le32( void* p, blargg_ulong n )
|
||||
{
|
||||
((unsigned char*) p) [0] = (unsigned char) n;
|
||||
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
|
||||
((unsigned char*) p) [2] = (unsigned char) (n >> 16);
|
||||
((unsigned char*) p) [3] = (unsigned char) (n >> 24);
|
||||
}
|
||||
|
||||
inline void set_be32( void* p, blargg_ulong n )
|
||||
{
|
||||
((unsigned char*) p) [3] = (unsigned char) n;
|
||||
((unsigned char*) p) [2] = (unsigned char) (n >> 8);
|
||||
((unsigned char*) p) [1] = (unsigned char) (n >> 16);
|
||||
((unsigned char*) p) [0] = (unsigned char) (n >> 24);
|
||||
}
|
||||
|
||||
#if BLARGG_NONPORTABLE
|
||||
// Optimized implementation if byte order is known
|
||||
#if BLARGG_LITTLE_ENDIAN
|
||||
#define GET_LE16( addr ) (*(BOOST::uint16_t*) (addr))
|
||||
#define GET_LE32( addr ) (*(BOOST::uint32_t*) (addr))
|
||||
#define SET_LE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
|
||||
#define SET_LE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
|
||||
#elif BLARGG_BIG_ENDIAN
|
||||
#define GET_BE16( addr ) (*(BOOST::uint16_t*) (addr))
|
||||
#define GET_BE32( addr ) (*(BOOST::uint32_t*) (addr))
|
||||
#define SET_BE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
|
||||
#define SET_BE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
|
||||
|
||||
#if BLARGG_CPU_POWERPC
|
||||
// PowerPC has special byte-reversed instructions
|
||||
#if defined (__MWERKS__)
|
||||
#define GET_LE16( addr ) (__lhbrx( addr, 0 ))
|
||||
#define GET_LE32( addr ) (__lwbrx( addr, 0 ))
|
||||
#define SET_LE16( addr, in ) (__sthbrx( in, addr, 0 ))
|
||||
#define SET_LE32( addr, in ) (__stwbrx( in, addr, 0 ))
|
||||
#elif defined (__GNUC__)
|
||||
#define GET_LE16( addr ) ({unsigned ppc_lhbrx_; asm( "lhbrx %0,0,%1" : "=r" (ppc_lhbrx_) : "r" (addr), "0" (ppc_lhbrx_) ); ppc_lhbrx_;})
|
||||
#define GET_LE32( addr ) ({unsigned ppc_lwbrx_; asm( "lwbrx %0,0,%1" : "=r" (ppc_lwbrx_) : "r" (addr), "0" (ppc_lwbrx_) ); ppc_lwbrx_;})
|
||||
#define SET_LE16( addr, in ) ({asm( "sthbrx %0,0,%1" : : "r" (in), "r" (addr) );})
|
||||
#define SET_LE32( addr, in ) ({asm( "stwbrx %0,0,%1" : : "r" (in), "r" (addr) );})
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef GET_LE16
|
||||
#define GET_LE16( addr ) get_le16( addr )
|
||||
#define SET_LE16( addr, data ) set_le16( addr, data )
|
||||
#endif
|
||||
|
||||
#ifndef GET_LE32
|
||||
#define GET_LE32( addr ) get_le32( addr )
|
||||
#define SET_LE32( addr, data ) set_le32( addr, data )
|
||||
#endif
|
||||
|
||||
#ifndef GET_BE16
|
||||
#define GET_BE16( addr ) get_be16( addr )
|
||||
#define SET_BE16( addr, data ) set_be16( addr, data )
|
||||
#endif
|
||||
|
||||
#ifndef GET_BE32
|
||||
#define GET_BE32( addr ) get_be32( addr )
|
||||
#define SET_BE32( addr, data ) set_be32( addr, data )
|
||||
#endif
|
||||
|
||||
// auto-selecting versions
|
||||
|
||||
inline void set_le( BOOST::uint16_t* p, unsigned n ) { SET_LE16( p, n ); }
|
||||
inline void set_le( BOOST::uint32_t* p, blargg_ulong n ) { SET_LE32( p, n ); }
|
||||
inline void set_be( BOOST::uint16_t* p, unsigned n ) { SET_BE16( p, n ); }
|
||||
inline void set_be( BOOST::uint32_t* p, blargg_ulong n ) { SET_BE32( p, n ); }
|
||||
inline unsigned get_le( BOOST::uint16_t* p ) { return GET_LE16( p ); }
|
||||
inline blargg_ulong get_le( BOOST::uint32_t* p ) { return GET_LE32( p ); }
|
||||
inline unsigned get_be( BOOST::uint16_t* p ) { return GET_BE16( p ); }
|
||||
inline blargg_ulong get_be( BOOST::uint32_t* p ) { return GET_BE32( p ); }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,100 @@
|
|||
/* Included at the beginning of library source files, after all other #include lines.
|
||||
Sets up helpful macros and services used in my source code. They don't need
|
||||
module an annoying module prefix on their names since they are defined after
|
||||
all other #include lines. */
|
||||
|
||||
// snes_spc 0.9.0
|
||||
#ifndef BLARGG_SOURCE_H
|
||||
#define BLARGG_SOURCE_H
|
||||
|
||||
// If debugging is enabled, abort program if expr is false. Meant for checking
|
||||
// internal state and consistency. A failed assertion indicates a bug in the module.
|
||||
// void assert( bool expr );
|
||||
#include <assert.h>
|
||||
|
||||
// If debugging is enabled and expr is false, abort program. Meant for checking
|
||||
// caller-supplied parameters and operations that are outside the control of the
|
||||
// module. A failed requirement indicates a bug outside the module.
|
||||
// void require( bool expr );
|
||||
#undef require
|
||||
#define require( expr ) assert( expr )
|
||||
|
||||
// Like printf() except output goes to debug log file. Might be defined to do
|
||||
// nothing (not even evaluate its arguments).
|
||||
// void dprintf( const char* format, ... );
|
||||
static inline void blargg_dprintf_( const char*, ... ) { }
|
||||
#undef dprintf
|
||||
#define dprintf (1) ? (void) 0 : blargg_dprintf_
|
||||
|
||||
// If enabled, evaluate expr and if false, make debug log entry with source file
|
||||
// and line. Meant for finding situations that should be examined further, but that
|
||||
// don't indicate a problem. In all cases, execution continues normally.
|
||||
#undef check
|
||||
#define check( expr ) ((void) 0)
|
||||
|
||||
// If expr yields error string, return it from current function, otherwise continue.
|
||||
#undef RETURN_ERR
|
||||
#define RETURN_ERR( expr ) do { \
|
||||
blargg_err_t blargg_return_err_ = (expr); \
|
||||
if ( blargg_return_err_ ) return blargg_return_err_; \
|
||||
} while ( 0 )
|
||||
|
||||
// If ptr is 0, return out of memory error string.
|
||||
#undef CHECK_ALLOC
|
||||
#define CHECK_ALLOC( ptr ) do { if ( (ptr) == 0 ) return "Out of memory"; } while ( 0 )
|
||||
|
||||
// Avoid any macros which evaluate their arguments multiple times
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
#define DEF_MIN_MAX( type ) \
|
||||
static inline type min( type x, type y ) { if ( x < y ) return x; return y; }\
|
||||
static inline type max( type x, type y ) { if ( y < x ) return x; return y; }
|
||||
|
||||
DEF_MIN_MAX( int )
|
||||
DEF_MIN_MAX( unsigned )
|
||||
DEF_MIN_MAX( long )
|
||||
DEF_MIN_MAX( unsigned long )
|
||||
DEF_MIN_MAX( float )
|
||||
DEF_MIN_MAX( double )
|
||||
|
||||
#undef DEF_MIN_MAX
|
||||
|
||||
/*
|
||||
// using const references generates crappy code, and I am currenly only using these
|
||||
// for built-in types, so they take arguments by value
|
||||
|
||||
// TODO: remove
|
||||
inline int min( int x, int y )
|
||||
template<class T>
|
||||
inline T min( T x, T y )
|
||||
{
|
||||
if ( x < y )
|
||||
return x;
|
||||
return y;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T max( T x, T y )
|
||||
{
|
||||
if ( x < y )
|
||||
return y;
|
||||
return x;
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO: good idea? bad idea?
|
||||
#undef byte
|
||||
#define byte byte_
|
||||
typedef unsigned char byte;
|
||||
|
||||
// deprecated
|
||||
#define BLARGG_CHECK_ALLOC CHECK_ALLOC
|
||||
#define BLARGG_RETURN_ERR RETURN_ERR
|
||||
|
||||
// BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of dprintf and check
|
||||
#ifdef BLARGG_SOURCE_BEGIN
|
||||
#include BLARGG_SOURCE_BEGIN
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,504 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
/* Simple resampler based on bsnes's ruby audio library */
|
||||
|
||||
#ifndef __RESAMPLER_H
|
||||
#define __RESAMPLER_H
|
||||
|
||||
#include "ring_buffer.h"
|
||||
|
||||
#undef MIN
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
#undef CLAMP
|
||||
#undef short_clamp
|
||||
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
|
||||
#define short_clamp(n) ((short) CLAMP((n), -32768, 32767))
|
||||
|
||||
class Resampler : public ring_buffer
|
||||
{
|
||||
protected:
|
||||
|
||||
double r_step;
|
||||
double r_frac;
|
||||
int r_left[4], r_right[4];
|
||||
|
||||
double
|
||||
hermite (double mu1, double a, double b, double c, double d)
|
||||
{
|
||||
const double tension = 0.0; //-1 = low, 0 = normal, 1 = high
|
||||
const double bias = 0.0; //-1 = left, 0 = even, 1 = right
|
||||
|
||||
double mu2, mu3, m0, m1, a0, a1, a2, a3;
|
||||
|
||||
mu2 = mu1 * mu1;
|
||||
mu3 = mu2 * mu1;
|
||||
|
||||
m0 = (b - a) * (1 + bias) * (1 - tension) / 2;
|
||||
m0 += (c - b) * (1 - bias) * (1 - tension) / 2;
|
||||
m1 = (c - b) * (1 + bias) * (1 - tension) / 2;
|
||||
m1 += (d - c) * (1 - bias) * (1 - tension) / 2;
|
||||
|
||||
a0 = +2 * mu3 - 3 * mu2 + 1;
|
||||
a1 = mu3 - 2 * mu2 + mu1;
|
||||
a2 = mu3 - mu2;
|
||||
a3 = -2 * mu3 + 3 * mu2;
|
||||
|
||||
return (a0 * b) + (a1 * m0) + (a2 * m1) + (a3 * c);
|
||||
}
|
||||
|
||||
public:
|
||||
Resampler (int num_samples) : ring_buffer (num_samples << 1)
|
||||
{
|
||||
r_frac = 0.0;
|
||||
}
|
||||
|
||||
~Resampler ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
time_ratio (double ratio)
|
||||
{
|
||||
r_step = ratio;
|
||||
clear ();
|
||||
}
|
||||
|
||||
void
|
||||
clear (void)
|
||||
{
|
||||
ring_buffer::clear ();
|
||||
r_frac = 0;
|
||||
r_left [0] = r_left [1] = r_left [2] = r_left [3] = 0;
|
||||
r_right[0] = r_right[1] = r_right[2] = r_right[3] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
read (short *data, int num_samples)
|
||||
{
|
||||
int i_position = start >> 1;
|
||||
short *internal_buffer = (short *) buffer;
|
||||
int o_position = 0;
|
||||
int consumed = 0;
|
||||
|
||||
while (o_position < num_samples && consumed < buffer_size)
|
||||
{
|
||||
int s_left = internal_buffer[i_position];
|
||||
int s_right = internal_buffer[i_position + 1];
|
||||
const double margin_of_error = 1.0e-10;
|
||||
|
||||
if (fabs(r_step - 1.0) < margin_of_error)
|
||||
{
|
||||
data[o_position] = (short) s_left;
|
||||
data[o_position + 1] = (short) s_right;
|
||||
|
||||
o_position += 2;
|
||||
i_position = (i_position + 2) % (buffer_size >> 1);
|
||||
consumed += 2;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
r_left [0] = r_left [1];
|
||||
r_left [1] = r_left [2];
|
||||
r_left [2] = r_left [3];
|
||||
r_left [3] = s_left;
|
||||
|
||||
r_right[0] = r_right[1];
|
||||
r_right[1] = r_right[2];
|
||||
r_right[2] = r_right[3];
|
||||
r_right[3] = s_right;
|
||||
|
||||
while (r_frac <= 1.0 && o_position < num_samples)
|
||||
{
|
||||
data[o_position] = short_clamp (hermite (r_frac, r_left [0], r_left [1], r_left [2], r_left [3]));
|
||||
data[o_position + 1] = short_clamp (hermite (r_frac, r_right[0], r_right[1], r_right[2], r_right[3]));
|
||||
|
||||
o_position += 2;
|
||||
|
||||
r_frac += r_step;
|
||||
}
|
||||
|
||||
if (r_frac > 1.0)
|
||||
{
|
||||
r_frac -= 1.0;
|
||||
i_position = (i_position + 2) % (buffer_size >> 1);
|
||||
consumed += 2;
|
||||
}
|
||||
}
|
||||
|
||||
size -= consumed << 1;
|
||||
start = (start + (consumed << 1)) % buffer_size;
|
||||
}
|
||||
|
||||
bool
|
||||
push (short *src, int num_samples)
|
||||
{
|
||||
if (max_write () < num_samples)
|
||||
return false;
|
||||
|
||||
ring_buffer::push ((unsigned char *) src, num_samples << 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
max_write (void)
|
||||
{
|
||||
return space_empty () >> 1;
|
||||
}
|
||||
|
||||
void
|
||||
resize (int num_samples)
|
||||
{
|
||||
ring_buffer::resize (num_samples << 1);
|
||||
}
|
||||
|
||||
int
|
||||
avail (void)
|
||||
{
|
||||
return (int) floor (((size >> 2) - r_frac) / r_step) * 2;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* __RESAMPLER_H */
|
|
@ -0,0 +1,111 @@
|
|||
/* Simple byte-based ring buffer. Licensed under public domain (C) BearOso. */
|
||||
|
||||
#ifndef __RING_BUFFER_H
|
||||
#define __RING_BUFFER_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#undef MIN
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
class ring_buffer
|
||||
{
|
||||
protected:
|
||||
int size;
|
||||
int buffer_size;
|
||||
int start;
|
||||
unsigned char *buffer;
|
||||
|
||||
public:
|
||||
ring_buffer (int buffer_size)
|
||||
{
|
||||
this->buffer_size = buffer_size;
|
||||
buffer = new unsigned char[this->buffer_size];
|
||||
memset (buffer, 0, this->buffer_size);
|
||||
|
||||
size = 0;
|
||||
start = 0;
|
||||
}
|
||||
|
||||
~ring_buffer (void)
|
||||
{
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
bool
|
||||
push (unsigned char *src, int bytes)
|
||||
{
|
||||
if (space_empty () < bytes)
|
||||
return false;
|
||||
|
||||
int end = (start + size) % buffer_size;
|
||||
int first_write_size = MIN (bytes, buffer_size - end);
|
||||
|
||||
memcpy (buffer + end, src, first_write_size);
|
||||
|
||||
if (bytes > first_write_size)
|
||||
memcpy (buffer, src + first_write_size, bytes - first_write_size);
|
||||
|
||||
size += bytes;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
pull (unsigned char *dst, int bytes)
|
||||
{
|
||||
if (space_filled () < bytes)
|
||||
return false;
|
||||
|
||||
memcpy (dst, buffer + start, MIN (bytes, buffer_size - start));
|
||||
|
||||
if (bytes > (buffer_size - start))
|
||||
memcpy (dst + (buffer_size - start), buffer, bytes - (buffer_size - start));
|
||||
|
||||
start = (start + bytes) % buffer_size;
|
||||
size -= bytes;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline int
|
||||
space_empty (void)
|
||||
{
|
||||
return buffer_size - size;
|
||||
}
|
||||
|
||||
inline int
|
||||
space_filled (void)
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
clear (void)
|
||||
{
|
||||
start = 0;
|
||||
size = 0;
|
||||
memset (buffer, 0, buffer_size);
|
||||
}
|
||||
|
||||
void
|
||||
resize (int size)
|
||||
{
|
||||
delete[] buffer;
|
||||
buffer_size = size;
|
||||
buffer = new unsigned char[buffer_size];
|
||||
memset (buffer, 0, this->buffer_size);
|
||||
|
||||
size = 0;
|
||||
start = 0;
|
||||
}
|
||||
|
||||
inline void
|
||||
cache_silence (void)
|
||||
{
|
||||
clear ();
|
||||
size = buffer_size;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,211 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _BSX_H_
|
||||
#define _BSX_H_
|
||||
|
||||
struct SBSX
|
||||
{
|
||||
bool8 dirty; // Changed register values
|
||||
bool8 dirty2; // Changed register values
|
||||
bool8 bootup; // Start in bios mapping
|
||||
bool8 flash_enable; // Flash state
|
||||
bool8 write_enable; // ROM write protection
|
||||
bool8 read_enable; // Allow card vendor reading
|
||||
uint32 flash_command; // Flash command
|
||||
uint32 old_write; // Previous flash write address
|
||||
uint32 new_write; // Current flash write address
|
||||
uint8 out_index;
|
||||
uint8 output[32];
|
||||
uint8 PPU[32];
|
||||
uint8 MMC[16];
|
||||
uint8 prevMMC[16];
|
||||
uint8 test2192[32];
|
||||
};
|
||||
|
||||
extern struct SBSX BSX;
|
||||
|
||||
uint8 S9xGetBSX (uint32);
|
||||
void S9xSetBSX (uint8, uint32);
|
||||
uint8 S9xGetBSXPPU (uint16);
|
||||
void S9xSetBSXPPU (uint8, uint16);
|
||||
uint8 * S9xGetBasePointerBSX (uint32);
|
||||
void S9xInitBSX (void);
|
||||
void S9xResetBSX (void);
|
||||
void S9xBSXPostLoadState (void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,341 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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 <math.h>
|
||||
#include "snes9x.h"
|
||||
#include "memmap.h"
|
||||
|
||||
#define C4_PI 3.14159265
|
||||
|
||||
int16 C4WFXVal;
|
||||
int16 C4WFYVal;
|
||||
int16 C4WFZVal;
|
||||
int16 C4WFX2Val;
|
||||
int16 C4WFY2Val;
|
||||
int16 C4WFDist;
|
||||
int16 C4WFScale;
|
||||
int16 C41FXVal;
|
||||
int16 C41FYVal;
|
||||
int16 C41FAngleRes;
|
||||
int16 C41FDist;
|
||||
int16 C41FDistVal;
|
||||
|
||||
static double tanval;
|
||||
static double c4x, c4y, c4z;
|
||||
static double c4x2, c4y2, c4z2;
|
||||
|
||||
|
||||
void C4TransfWireFrame (void)
|
||||
{
|
||||
c4x = (double) C4WFXVal;
|
||||
c4y = (double) C4WFYVal;
|
||||
c4z = (double) C4WFZVal - 0x95;
|
||||
|
||||
// Rotate X
|
||||
tanval = -(double) C4WFX2Val * C4_PI * 2 / 128;
|
||||
c4y2 = c4y * cos(tanval) - c4z * sin(tanval);
|
||||
c4z2 = c4y * sin(tanval) + c4z * cos(tanval);
|
||||
|
||||
// Rotate Y
|
||||
tanval = -(double) C4WFY2Val * C4_PI * 2 / 128;
|
||||
c4x2 = c4x * cos(tanval) + c4z2 * sin(tanval);
|
||||
c4z = c4x * -sin(tanval) + c4z2 * cos(tanval);
|
||||
|
||||
// Rotate Z
|
||||
tanval = -(double) C4WFDist * C4_PI * 2 / 128;
|
||||
c4x = c4x2 * cos(tanval) - c4y2 * sin(tanval);
|
||||
c4y = c4x2 * sin(tanval) + c4y2 * cos(tanval);
|
||||
|
||||
// Scale
|
||||
C4WFXVal = (int16) (c4x * (double) C4WFScale / (0x90 * (c4z + 0x95)) * 0x95);
|
||||
C4WFYVal = (int16) (c4y * (double) C4WFScale / (0x90 * (c4z + 0x95)) * 0x95);
|
||||
}
|
||||
|
||||
void C4TransfWireFrame2 (void)
|
||||
{
|
||||
c4x = (double) C4WFXVal;
|
||||
c4y = (double) C4WFYVal;
|
||||
c4z = (double) C4WFZVal;
|
||||
|
||||
// Rotate X
|
||||
tanval = -(double) C4WFX2Val * C4_PI * 2 / 128;
|
||||
c4y2 = c4y * cos(tanval) - c4z * sin(tanval);
|
||||
c4z2 = c4y * sin(tanval) + c4z * cos(tanval);
|
||||
|
||||
// Rotate Y
|
||||
tanval = -(double) C4WFY2Val * C4_PI * 2 / 128;
|
||||
c4x2 = c4x * cos(tanval) + c4z2 * sin(tanval);
|
||||
c4z = c4x * -sin(tanval) + c4z2 * cos(tanval);
|
||||
|
||||
// Rotate Z
|
||||
tanval = -(double) C4WFDist * C4_PI * 2 / 128;
|
||||
c4x = c4x2 * cos(tanval) - c4y2 * sin(tanval);
|
||||
c4y = c4x2 * sin(tanval) + c4y2 * cos(tanval);
|
||||
|
||||
// Scale
|
||||
C4WFXVal = (int16) (c4x * (double) C4WFScale / 0x100);
|
||||
C4WFYVal = (int16) (c4y * (double) C4WFScale / 0x100);
|
||||
}
|
||||
|
||||
void C4CalcWireFrame (void)
|
||||
{
|
||||
C4WFXVal = C4WFX2Val - C4WFXVal;
|
||||
C4WFYVal = C4WFY2Val - C4WFYVal;
|
||||
|
||||
if (abs(C4WFXVal) > abs(C4WFYVal))
|
||||
{
|
||||
C4WFDist = abs(C4WFXVal) + 1;
|
||||
C4WFYVal = (int16) (256 * (double) C4WFYVal / abs(C4WFXVal));
|
||||
if (C4WFXVal < 0)
|
||||
C4WFXVal = -256;
|
||||
else
|
||||
C4WFXVal = 256;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (C4WFYVal != 0)
|
||||
{
|
||||
C4WFDist = abs(C4WFYVal) + 1;
|
||||
C4WFXVal = (int16) (256 * (double) C4WFXVal / abs(C4WFYVal));
|
||||
if (C4WFYVal < 0)
|
||||
C4WFYVal = -256;
|
||||
else
|
||||
C4WFYVal = 256;
|
||||
}
|
||||
else
|
||||
C4WFDist = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void C4Op1F (void)
|
||||
{
|
||||
if (C41FXVal == 0)
|
||||
{
|
||||
if (C41FYVal > 0)
|
||||
C41FAngleRes = 0x80;
|
||||
else
|
||||
C41FAngleRes = 0x180;
|
||||
}
|
||||
else
|
||||
{
|
||||
tanval = (double) C41FYVal / C41FXVal;
|
||||
C41FAngleRes = (int16) (atan(tanval) / (C4_PI * 2) * 512);
|
||||
C41FAngleRes = C41FAngleRes;
|
||||
if (C41FXVal< 0)
|
||||
C41FAngleRes += 0x100;
|
||||
C41FAngleRes &= 0x1FF;
|
||||
}
|
||||
}
|
||||
|
||||
void C4Op15 (void)
|
||||
{
|
||||
tanval = sqrt((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal);
|
||||
C41FDist = (int16) tanval;
|
||||
}
|
||||
|
||||
void C4Op0D (void)
|
||||
{
|
||||
tanval = sqrt((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal);
|
||||
tanval = C41FDistVal / tanval;
|
||||
C41FYVal = (int16) (C41FYVal * tanval * 0.99);
|
||||
C41FXVal = (int16) (C41FXVal * tanval * 0.98);
|
||||
}
|
||||
|
||||
uint8 * S9xGetBasePointerC4 (uint16 Address)
|
||||
{
|
||||
if (Address >= 0x7f40 && Address <= 0x7f5e)
|
||||
return (NULL);
|
||||
return (Memory.C4RAM - 0x6000);
|
||||
}
|
||||
|
||||
uint8 * S9xGetMemPointerC4 (uint16 Address)
|
||||
{
|
||||
if (Address >= 0x7f40 && Address <= 0x7f5e)
|
||||
return (NULL);
|
||||
return (Memory.C4RAM - 0x6000 + (Address & 0xffff));
|
||||
}
|
||||
|
||||
#ifdef ZSNES_C4
|
||||
START_EXTERN_C
|
||||
|
||||
void C4LoaDMem (char *C4RAM)
|
||||
{
|
||||
memmove(C4RAM + (READ_WORD(C4RAM + 0x1f45) & 0x1fff), C4GetMemPointer(READ_3WORD(C4RAM + 0x1f40)), READ_WORD(C4RAM + 0x1f43));
|
||||
}
|
||||
|
||||
END_EXTERN_C
|
||||
#endif
|
|
@ -0,0 +1,224 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _C4_H_
|
||||
#define _C4_H_
|
||||
|
||||
#ifdef ZSNES_C4
|
||||
START_EXTERN_C
|
||||
#endif
|
||||
|
||||
extern int16 C4WFXVal;
|
||||
extern int16 C4WFYVal;
|
||||
extern int16 C4WFZVal;
|
||||
extern int16 C4WFX2Val;
|
||||
extern int16 C4WFY2Val;
|
||||
extern int16 C4WFDist;
|
||||
extern int16 C4WFScale;
|
||||
extern int16 C41FXVal;
|
||||
extern int16 C41FYVal;
|
||||
extern int16 C41FAngleRes;
|
||||
extern int16 C41FDist;
|
||||
extern int16 C41FDistVal;
|
||||
|
||||
#ifdef ZSNES_C4
|
||||
extern uint8 *C4Ram;
|
||||
#endif
|
||||
|
||||
void C4TransfWireFrame (void);
|
||||
void C4TransfWireFrame2 (void);
|
||||
void C4CalcWireFrame (void);
|
||||
void C4Op0D (void);
|
||||
void C4Op15 (void);
|
||||
void C4Op1F (void);
|
||||
void S9xInitC4 (void);
|
||||
void S9xSetC4 (uint8, uint16);
|
||||
uint8 S9xGetC4 (uint16);
|
||||
|
||||
#ifdef ZSNES_C4
|
||||
END_EXTERN_C
|
||||
#endif
|
||||
|
||||
uint8 * S9xGetBasePointerC4 (uint16);
|
||||
uint8 * S9xGetMemPointerC4 (uint16);
|
||||
|
||||
static inline uint8 * C4GetMemPointer (uint32 Address)
|
||||
{
|
||||
return (Memory.ROM + ((Address & 0xff0000) >> 1) + (Address & 0x7fff));
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,578 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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 <ctype.h>
|
||||
#include "snes9x.h"
|
||||
#include "memmap.h"
|
||||
#include "cheats.h"
|
||||
|
||||
#define WRAM_BITS ALL_BITS
|
||||
#define SRAM_BITS ALL_BITS + (0x20000 >> 5)
|
||||
#define IRAM_BITS ALL_BITS + (0x30000 >> 5)
|
||||
|
||||
#define BIT_CLEAR(a, v) (a)[(v) >> 5] &= ~(1 << ((v) & 31))
|
||||
|
||||
#define TEST_BIT(a, v) ((a)[(v) >> 5] & (1 << ((v) & 31)))
|
||||
|
||||
#define _S9XCHTC(c, a, b) \
|
||||
((c) == S9X_LESS_THAN ? (a) < (b) : \
|
||||
(c) == S9X_GREATER_THAN ? (a) > (b) : \
|
||||
(c) == S9X_LESS_THAN_OR_EQUAL ? (a) <= (b) : \
|
||||
(c) == S9X_GREATER_THAN_OR_EQUAL ? (a) >= (b) : \
|
||||
(c) == S9X_EQUAL ? (a) == (b) : \
|
||||
(a) != (b))
|
||||
|
||||
#define _S9XCHTD(s, m, o) \
|
||||
((s) == S9X_8_BITS ? ((uint8) (*((m) + (o)))) : \
|
||||
(s) == S9X_16_BITS ? ((uint16) (*((m) + (o)) + (*((m) + (o) + 1) << 8))) : \
|
||||
(s) == S9X_24_BITS ? ((uint32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16))) : \
|
||||
((uint32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16) + (*((m) + (o) + 3) << 24))))
|
||||
|
||||
#define _S9XCHTDS(s, m, o) \
|
||||
((s) == S9X_8_BITS ? ((int8) (*((m) + (o)))) : \
|
||||
(s) == S9X_16_BITS ? ((int16) (*((m) + (o)) + (*((m) + (o) + 1) << 8))) : \
|
||||
(s) == S9X_24_BITS ? (((int32) ((*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16)) << 8)) >> 8): \
|
||||
((int32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16) + (*((m) + (o) + 3) << 24))))
|
||||
|
||||
static bool8 S9xAllHex (const char *, int);
|
||||
|
||||
|
||||
static bool8 S9xAllHex (const char *code, int len)
|
||||
{
|
||||
for (int i = 0; i < len; i++)
|
||||
if ((code[i] < '0' || code[i] > '9') && (code[i] < 'a' || code[i] > 'f') && (code[i] < 'A' || code[i] > 'F'))
|
||||
return (FALSE);
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
const char * S9xProActionReplayToRaw (const char *code, uint32 &address, uint8 &byte)
|
||||
{
|
||||
uint32 data = 0;
|
||||
|
||||
if (strlen(code) != 8 || !S9xAllHex(code, 8) || sscanf(code, "%x", &data) != 1)
|
||||
return ("Invalid Pro Action Replay code - should be 8 hex digits in length.");
|
||||
|
||||
address = data >> 8;
|
||||
byte = (uint8) data;
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
const char * S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram, uint8 &num_bytes, uint8 bytes[3])
|
||||
{
|
||||
char tmp[15];
|
||||
int i;
|
||||
|
||||
if (strlen(code) != 14)
|
||||
return ("Invalid Gold Finger code - should be 14 hex digits in length.");
|
||||
|
||||
strncpy(tmp, code, 5);
|
||||
tmp[5] = 0;
|
||||
if (sscanf(tmp, "%x", &address) != 1)
|
||||
return ("Invalid Gold Finger code.");
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
unsigned int byte;
|
||||
|
||||
strncpy(tmp, code + 5 + i * 2, 2);
|
||||
tmp[2] = 0;
|
||||
if (sscanf(tmp, "%x", &byte) != 1)
|
||||
break;
|
||||
bytes[i] = (uint8) byte;
|
||||
}
|
||||
|
||||
num_bytes = i;
|
||||
sram = code[13] == '1';
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
const char * S9xGameGenieToRaw (const char *code, uint32 &address, uint8 &byte)
|
||||
{
|
||||
char new_code[12];
|
||||
|
||||
if (strlen(code) != 9 || *(code + 4) != '-' || !S9xAllHex(code, 4) || !S9xAllHex(code + 5, 4))
|
||||
return ("Invalid Game Genie(tm) code - should be 'xxxx-xxxx'.");
|
||||
|
||||
strcpy(new_code, "0x");
|
||||
strncpy(new_code + 2, code, 4);
|
||||
strcpy(new_code + 6, code + 5);
|
||||
|
||||
static const char *real_hex = "0123456789ABCDEF";
|
||||
static const char *genie_hex = "DF4709156BC8A23E";
|
||||
|
||||
for (int i = 2; i < 10; i++)
|
||||
{
|
||||
if (islower(new_code[i]))
|
||||
new_code[i] = toupper(new_code[i]);
|
||||
|
||||
int j;
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
if (new_code[i] == genie_hex[j])
|
||||
{
|
||||
new_code[i] = real_hex[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == 16)
|
||||
return ("Invalid hex-character in Game Genie(tm) code.");
|
||||
}
|
||||
|
||||
uint32 data = 0;
|
||||
sscanf(new_code, "%x", &data);
|
||||
byte = (uint8) (data >> 24);
|
||||
address = data & 0xffffff;
|
||||
address = ((address & 0x003c00) << 10) +
|
||||
((address & 0x00003c) << 14) +
|
||||
((address & 0xf00000) >> 8) +
|
||||
((address & 0x000003) << 10) +
|
||||
((address & 0x00c000) >> 6) +
|
||||
((address & 0x0f0000) >> 12) +
|
||||
((address & 0x0003c0) >> 6);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void S9xStartCheatSearch (SCheatData *d)
|
||||
{
|
||||
memmove(d->CWRAM, d->RAM, 0x20000);
|
||||
memmove(d->CSRAM, d->SRAM, 0x10000);
|
||||
memmove(d->CIRAM, &d->FillRAM[0x3000], 0x2000);
|
||||
memset((char *) d->ALL_BITS, 0xff, 0x32000 >> 3);
|
||||
}
|
||||
|
||||
void S9xSearchForChange (SCheatData *d, S9xCheatComparisonType cmp, S9xCheatDataSize size, bool8 is_signed, bool8 update)
|
||||
{
|
||||
int l, i;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case S9X_8_BITS: l = 0; break;
|
||||
case S9X_16_BITS: l = 1; break;
|
||||
case S9X_24_BITS: l = 2; break;
|
||||
default:
|
||||
case S9X_32_BITS: l = 3; break;
|
||||
}
|
||||
|
||||
if (is_signed)
|
||||
{
|
||||
for (i = 0; i < 0x20000 - l; i++)
|
||||
{
|
||||
if (TEST_BIT(d->WRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTDS(size, d->RAM, i), _S9XCHTDS(size, d->CWRAM, i)))
|
||||
{
|
||||
if (update)
|
||||
d->CWRAM[i] = d->RAM[i];
|
||||
}
|
||||
else
|
||||
BIT_CLEAR(d->WRAM_BITS, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x10000 - l; i++)
|
||||
{
|
||||
if (TEST_BIT(d->SRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTDS(size, d->SRAM, i), _S9XCHTDS(size, d->CSRAM, i)))
|
||||
{
|
||||
if (update)
|
||||
d->CSRAM[i] = d->SRAM[i];
|
||||
}
|
||||
else
|
||||
BIT_CLEAR(d->SRAM_BITS, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x2000 - l; i++)
|
||||
{
|
||||
if (TEST_BIT(d->IRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTDS(size, d->FillRAM + 0x3000, i), _S9XCHTDS(size, d->CIRAM, i)))
|
||||
{
|
||||
if (update)
|
||||
d->CIRAM[i] = d->FillRAM[i + 0x3000];
|
||||
}
|
||||
else
|
||||
BIT_CLEAR(d->IRAM_BITS, i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 0x20000 - l; i++)
|
||||
{
|
||||
if (TEST_BIT(d->WRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTD(size, d->RAM, i), _S9XCHTD(size, d->CWRAM, i)))
|
||||
{
|
||||
if (update)
|
||||
d->CWRAM[i] = d->RAM[i];
|
||||
}
|
||||
else
|
||||
BIT_CLEAR(d->WRAM_BITS, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x10000 - l; i++)
|
||||
{
|
||||
if (TEST_BIT(d->SRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTD(size, d->SRAM, i), _S9XCHTD(size, d->CSRAM, i)))
|
||||
{
|
||||
if (update)
|
||||
d->CSRAM[i] = d->SRAM[i];
|
||||
}
|
||||
else
|
||||
BIT_CLEAR(d->SRAM_BITS, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x2000 - l; i++)
|
||||
{
|
||||
if (TEST_BIT(d->IRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTD(size, d->FillRAM + 0x3000, i), _S9XCHTD(size, d->CIRAM, i)))
|
||||
{
|
||||
if (update)
|
||||
d->CIRAM[i] = d->FillRAM[i + 0x3000];
|
||||
}
|
||||
else
|
||||
BIT_CLEAR(d->IRAM_BITS, i);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0x20000 - l; i < 0x20000; i++)
|
||||
BIT_CLEAR(d->WRAM_BITS, i);
|
||||
|
||||
for (i = 0x10000 - l; i < 0x10000; i++)
|
||||
BIT_CLEAR(d->SRAM_BITS, i);
|
||||
}
|
||||
|
||||
void S9xSearchForValue (SCheatData *d, S9xCheatComparisonType cmp, S9xCheatDataSize size, uint32 value, bool8 is_signed, bool8 update)
|
||||
{
|
||||
int l, i;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case S9X_8_BITS: l = 0; break;
|
||||
case S9X_16_BITS: l = 1; break;
|
||||
case S9X_24_BITS: l = 2; break;
|
||||
default:
|
||||
case S9X_32_BITS: l = 3; break;
|
||||
}
|
||||
|
||||
if (is_signed)
|
||||
{
|
||||
for (i = 0; i < 0x20000 - l; i++)
|
||||
{
|
||||
if (TEST_BIT(d->WRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTDS(size, d->RAM, i), (int32) value))
|
||||
{
|
||||
if (update)
|
||||
d->CWRAM[i] = d->RAM[i];
|
||||
}
|
||||
else
|
||||
BIT_CLEAR(d->WRAM_BITS, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x10000 - l; i++)
|
||||
{
|
||||
if (TEST_BIT(d->SRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTDS(size, d->SRAM, i), (int32) value))
|
||||
{
|
||||
if (update)
|
||||
d->CSRAM[i] = d->SRAM[i];
|
||||
}
|
||||
else
|
||||
BIT_CLEAR(d->SRAM_BITS, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x2000 - l; i++)
|
||||
{
|
||||
if (TEST_BIT(d->IRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTDS(size, d->FillRAM + 0x3000, i), (int32) value))
|
||||
{
|
||||
if (update)
|
||||
d->CIRAM[i] = d->FillRAM[i + 0x3000];
|
||||
}
|
||||
else
|
||||
BIT_CLEAR(d->IRAM_BITS, i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 0x20000 - l; i++)
|
||||
{
|
||||
if (TEST_BIT(d->WRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTD(size, d->RAM, i), value))
|
||||
{
|
||||
if (update)
|
||||
d->CWRAM[i] = d->RAM[i];
|
||||
}
|
||||
else
|
||||
BIT_CLEAR(d->WRAM_BITS, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x10000 - l; i++)
|
||||
{
|
||||
if (TEST_BIT(d->SRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTD(size, d->SRAM, i), value))
|
||||
{
|
||||
if (update)
|
||||
d->CSRAM[i] = d->SRAM[i];
|
||||
}
|
||||
else
|
||||
BIT_CLEAR(d->SRAM_BITS, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x2000 - l; i++)
|
||||
{
|
||||
if (TEST_BIT(d->IRAM_BITS, i) && _S9XCHTC(cmp, _S9XCHTD(size, d->FillRAM + 0x3000, i), value))
|
||||
{
|
||||
if (update)
|
||||
d->CIRAM[i] = d->FillRAM[i + 0x3000];
|
||||
}
|
||||
else
|
||||
BIT_CLEAR(d->IRAM_BITS, i);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0x20000 - l; i < 0x20000; i++)
|
||||
BIT_CLEAR(d->WRAM_BITS, i);
|
||||
|
||||
for (i = 0x10000 - l; i < 0x10000; i++)
|
||||
BIT_CLEAR(d->SRAM_BITS, i);
|
||||
}
|
||||
|
||||
void S9xSearchForAddress (SCheatData *d, S9xCheatComparisonType cmp, S9xCheatDataSize size, uint32 value, bool8 update)
|
||||
{
|
||||
int l, i;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case S9X_8_BITS: l = 0; break;
|
||||
case S9X_16_BITS: l = 1; break;
|
||||
case S9X_24_BITS: l = 2; break;
|
||||
default:
|
||||
case S9X_32_BITS: l = 3; break;
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x20000 - l; i++)
|
||||
{
|
||||
if (TEST_BIT(d->WRAM_BITS, i) && _S9XCHTC(cmp, i, (int32) value))
|
||||
{
|
||||
if (update)
|
||||
d->CWRAM[i] = d->RAM[i];
|
||||
}
|
||||
else
|
||||
BIT_CLEAR(d->WRAM_BITS, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x10000 - l; i++)
|
||||
{
|
||||
if (TEST_BIT(d->SRAM_BITS, i) && _S9XCHTC(cmp, i + 0x20000, (int32) value))
|
||||
{
|
||||
if (update)
|
||||
d->CSRAM[i] = d->SRAM[i];
|
||||
}
|
||||
else
|
||||
BIT_CLEAR(d->SRAM_BITS, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x2000 - l; i++)
|
||||
{
|
||||
if (TEST_BIT(d->IRAM_BITS, i) && _S9XCHTC(cmp, i + 0x30000, (int32) value))
|
||||
{
|
||||
if (update)
|
||||
d->CIRAM[i] = d->FillRAM[i + 0x3000];
|
||||
}
|
||||
else
|
||||
BIT_CLEAR(d->IRAM_BITS, i);
|
||||
}
|
||||
|
||||
for (i = 0x20000 - l; i < 0x20000; i++)
|
||||
BIT_CLEAR(d->WRAM_BITS, i);
|
||||
|
||||
for (i = 0x10000 - l; i < 0x10000; i++)
|
||||
BIT_CLEAR(d->SRAM_BITS, i);
|
||||
}
|
||||
|
||||
void S9xOutputCheatSearchResults (SCheatData *d)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 0x20000; i++)
|
||||
{
|
||||
if (TEST_BIT(d->WRAM_BITS, i))
|
||||
printf("WRAM: %05x: %02x\n", i, d->RAM[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x10000; i++)
|
||||
{
|
||||
if (TEST_BIT(d->SRAM_BITS, i))
|
||||
printf("SRAM: %04x: %02x\n", i, d->SRAM[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x2000; i++)
|
||||
{
|
||||
if (TEST_BIT(d->IRAM_BITS, i))
|
||||
printf("IRAM: %05x: %02x\n", i, d->FillRAM[i + 0x3000]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,262 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _CHEATS_H_
|
||||
#define _CHEATS_H_
|
||||
|
||||
#define MAX_CHEATS 150
|
||||
|
||||
struct SCheat
|
||||
{
|
||||
uint32 address;
|
||||
uint8 byte;
|
||||
uint8 saved_byte;
|
||||
bool8 enabled;
|
||||
bool8 saved;
|
||||
char name[22];
|
||||
};
|
||||
|
||||
struct SCheatData
|
||||
{
|
||||
struct SCheat c[MAX_CHEATS];
|
||||
uint32 num_cheats;
|
||||
uint8 CWRAM[0x20000];
|
||||
uint8 CSRAM[0x10000];
|
||||
uint8 CIRAM[0x2000];
|
||||
uint8 *RAM;
|
||||
uint8 *FillRAM;
|
||||
uint8 *SRAM;
|
||||
uint32 ALL_BITS[0x32000 >> 5];
|
||||
uint8 CWatchRAM[0x32000];
|
||||
};
|
||||
|
||||
struct Watch
|
||||
{
|
||||
bool on;
|
||||
int size;
|
||||
int format;
|
||||
uint32 address;
|
||||
char buf[12];
|
||||
char desc[32];
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
S9X_LESS_THAN,
|
||||
S9X_GREATER_THAN,
|
||||
S9X_LESS_THAN_OR_EQUAL,
|
||||
S9X_GREATER_THAN_OR_EQUAL,
|
||||
S9X_EQUAL,
|
||||
S9X_NOT_EQUAL
|
||||
} S9xCheatComparisonType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
S9X_8_BITS,
|
||||
S9X_16_BITS,
|
||||
S9X_24_BITS,
|
||||
S9X_32_BITS
|
||||
} S9xCheatDataSize;
|
||||
|
||||
extern SCheatData Cheat;
|
||||
extern Watch watches[16];
|
||||
|
||||
void S9xApplyCheat (uint32);
|
||||
void S9xApplyCheats (void);
|
||||
void S9xRemoveCheat (uint32);
|
||||
void S9xRemoveCheats (void);
|
||||
void S9xDeleteCheat (uint32);
|
||||
void S9xDeleteCheats (void);
|
||||
void S9xEnableCheat (uint32);
|
||||
void S9xDisableCheat (uint32);
|
||||
void S9xAddCheat (bool8, bool8, uint32, uint8);
|
||||
void S9xInitCheatData (void);
|
||||
void S9xInitWatchedAddress (void);
|
||||
bool8 S9xLoadCheatFile (const char *);
|
||||
bool8 S9xSaveCheatFile (const char *);
|
||||
|
||||
void S9xStartCheatSearch (SCheatData *);
|
||||
void S9xSearchForChange (SCheatData *, S9xCheatComparisonType, S9xCheatDataSize, bool8, bool8);
|
||||
void S9xSearchForValue (SCheatData *, S9xCheatComparisonType, S9xCheatDataSize, uint32, bool8, bool8);
|
||||
void S9xSearchForAddress (SCheatData *, S9xCheatComparisonType, S9xCheatDataSize, uint32, bool8);
|
||||
void S9xOutputCheatSearchResults (SCheatData *);
|
||||
|
||||
const char * S9xGameGenieToRaw (const char *, uint32 &, uint8 &);
|
||||
const char * S9xProActionReplayToRaw (const char *, uint32 &, uint8 &);
|
||||
const char * S9xGoldFingerToRaw (const char *, uint32 &, bool8 &, uint8 &, uint8 bytes[3]);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,406 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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 "snes9x.h"
|
||||
#include "memmap.h"
|
||||
#include "cheats.h"
|
||||
|
||||
static uint8 S9xGetByteFree (uint32);
|
||||
static void S9xSetByteFree (uint8, uint32);
|
||||
|
||||
|
||||
static uint8 S9xGetByteFree (uint32 address)
|
||||
{
|
||||
uint32 Cycles = CPU.Cycles;
|
||||
uint32 WaitAddress = CPU.WaitAddress;
|
||||
uint8 byte;
|
||||
|
||||
byte = S9xGetByte(address);
|
||||
|
||||
CPU.WaitAddress = WaitAddress;
|
||||
CPU.Cycles = Cycles;
|
||||
|
||||
return (byte);
|
||||
}
|
||||
|
||||
static void S9xSetByteFree (uint8 byte, uint32 address)
|
||||
{
|
||||
uint32 Cycles = CPU.Cycles;
|
||||
uint32 WaitAddress = CPU.WaitAddress;
|
||||
|
||||
S9xSetByte(byte, address);
|
||||
|
||||
CPU.WaitAddress = WaitAddress;
|
||||
CPU.Cycles = Cycles;
|
||||
}
|
||||
|
||||
void S9xInitWatchedAddress (void)
|
||||
{
|
||||
for (unsigned int i = 0; i < sizeof(watches) / sizeof(watches[0]); i++)
|
||||
watches[i].on = false;
|
||||
|
||||
}
|
||||
|
||||
void S9xInitCheatData (void)
|
||||
{
|
||||
Cheat.RAM = Memory.RAM;
|
||||
Cheat.SRAM = Memory.SRAM;
|
||||
Cheat.FillRAM = Memory.FillRAM;
|
||||
}
|
||||
|
||||
void S9xAddCheat (bool8 enable, bool8 save_current_value, uint32 address, uint8 byte)
|
||||
{
|
||||
if (Cheat.num_cheats < sizeof(Cheat.c) / sizeof(Cheat.c[0]))
|
||||
{
|
||||
Cheat.c[Cheat.num_cheats].address = address;
|
||||
Cheat.c[Cheat.num_cheats].byte = byte;
|
||||
Cheat.c[Cheat.num_cheats].enabled = enable;
|
||||
|
||||
if (save_current_value)
|
||||
{
|
||||
Cheat.c[Cheat.num_cheats].saved_byte = S9xGetByteFree(address);
|
||||
Cheat.c[Cheat.num_cheats].saved = TRUE;
|
||||
}
|
||||
|
||||
Cheat.num_cheats++;
|
||||
}
|
||||
}
|
||||
|
||||
void S9xDeleteCheat (uint32 which1)
|
||||
{
|
||||
if (which1 < Cheat.num_cheats)
|
||||
{
|
||||
if (Cheat.c[which1].enabled)
|
||||
S9xRemoveCheat(which1);
|
||||
|
||||
memmove(&Cheat.c[which1], &Cheat.c[which1 + 1], sizeof(Cheat.c[0]) * (Cheat.num_cheats - which1 - 1));
|
||||
|
||||
Cheat.num_cheats--;
|
||||
}
|
||||
}
|
||||
|
||||
void S9xDeleteCheats (void)
|
||||
{
|
||||
S9xRemoveCheats();
|
||||
Cheat.num_cheats = 0;
|
||||
}
|
||||
|
||||
void S9xRemoveCheat (uint32 which1)
|
||||
{
|
||||
if (Cheat.c[which1].saved)
|
||||
{
|
||||
uint32 address = Cheat.c[which1].address;
|
||||
|
||||
int block = (address & 0xffffff) >> MEMMAP_SHIFT;
|
||||
uint8 *ptr = Memory.Map[block];
|
||||
|
||||
if (ptr >= (uint8 *) CMemory::MAP_LAST)
|
||||
*(ptr + (address & 0xffff)) = Cheat.c[which1].saved_byte;
|
||||
else
|
||||
S9xSetByteFree(Cheat.c[which1].saved_byte, address);
|
||||
}
|
||||
}
|
||||
|
||||
void S9xRemoveCheats (void)
|
||||
{
|
||||
for (uint32 i = 0; i < Cheat.num_cheats; i++)
|
||||
if (Cheat.c[i].enabled)
|
||||
S9xRemoveCheat(i);
|
||||
}
|
||||
|
||||
void S9xEnableCheat (uint32 which1)
|
||||
{
|
||||
if (which1 < Cheat.num_cheats && !Cheat.c[which1].enabled)
|
||||
{
|
||||
Cheat.c[which1].enabled = TRUE;
|
||||
S9xApplyCheat(which1);
|
||||
}
|
||||
}
|
||||
|
||||
void S9xDisableCheat (uint32 which1)
|
||||
{
|
||||
if (which1 < Cheat.num_cheats && Cheat.c[which1].enabled)
|
||||
{
|
||||
S9xRemoveCheat(which1);
|
||||
Cheat.c[which1].enabled = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void S9xApplyCheat (uint32 which1)
|
||||
{
|
||||
uint32 address = Cheat.c[which1].address;
|
||||
|
||||
if (!Cheat.c[which1].saved)
|
||||
{
|
||||
Cheat.c[which1].saved_byte = S9xGetByteFree(address);
|
||||
Cheat.c[which1].saved = TRUE;
|
||||
}
|
||||
|
||||
int block = (address & 0xffffff) >> MEMMAP_SHIFT;
|
||||
uint8 *ptr = Memory.Map[block];
|
||||
|
||||
if (ptr >= (uint8 *) CMemory::MAP_LAST)
|
||||
*(ptr + (address & 0xffff)) = Cheat.c[which1].byte;
|
||||
else
|
||||
S9xSetByteFree(Cheat.c[which1].byte, address);
|
||||
}
|
||||
|
||||
void S9xApplyCheats (void)
|
||||
{
|
||||
if (Settings.ApplyCheats)
|
||||
{
|
||||
for (uint32 i = 0; i < Cheat.num_cheats; i++)
|
||||
if (Cheat.c[i].enabled)
|
||||
S9xApplyCheat(i);
|
||||
}
|
||||
}
|
||||
|
||||
bool8 S9xLoadCheatFile (const char *filename)
|
||||
{
|
||||
FILE *fs;
|
||||
uint8 data[28];
|
||||
|
||||
Cheat.num_cheats = 0;
|
||||
|
||||
fs = fopen(filename, "rb");
|
||||
if (!fs)
|
||||
return (FALSE);
|
||||
|
||||
while (fread((void *) data, 1, 28, fs) == 28)
|
||||
{
|
||||
Cheat.c[Cheat.num_cheats].enabled = (data[0] & 4) == 0;
|
||||
Cheat.c[Cheat.num_cheats].byte = data[1];
|
||||
Cheat.c[Cheat.num_cheats].address = data[2] | (data[3] << 8) | (data[4] << 16);
|
||||
Cheat.c[Cheat.num_cheats].saved_byte = data[5];
|
||||
Cheat.c[Cheat.num_cheats].saved = (data[0] & 8) != 0;
|
||||
memmove(Cheat.c[Cheat.num_cheats].name, &data[8], 20);
|
||||
Cheat.c[Cheat.num_cheats++].name[20] = 0;
|
||||
}
|
||||
|
||||
fclose(fs);
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
bool8 S9xSaveCheatFile (const char *filename)
|
||||
{
|
||||
if (Cheat.num_cheats == 0)
|
||||
{
|
||||
remove(filename);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
FILE *fs;
|
||||
uint8 data[28];
|
||||
|
||||
fs = fopen(filename, "wb");
|
||||
if (!fs)
|
||||
return (FALSE);
|
||||
|
||||
for (uint32 i = 0; i < Cheat.num_cheats; i++)
|
||||
{
|
||||
ZeroMemory(data, 28);
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
data[6] = 254;
|
||||
data[7] = 252;
|
||||
}
|
||||
|
||||
if (!Cheat.c[i].enabled)
|
||||
data[0] |= 4;
|
||||
|
||||
if (Cheat.c[i].saved)
|
||||
data[0] |= 8;
|
||||
|
||||
data[1] = Cheat.c[i].byte;
|
||||
data[2] = (uint8) (Cheat.c[i].address >> 0);
|
||||
data[3] = (uint8) (Cheat.c[i].address >> 8);
|
||||
data[4] = (uint8) (Cheat.c[i].address >> 16);
|
||||
data[5] = Cheat.c[i].saved_byte;
|
||||
|
||||
memmove(&data[8], Cheat.c[i].name, 19);
|
||||
|
||||
if (fwrite(data, 28, 1, fs) != 1)
|
||||
{
|
||||
fclose(fs);
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return (fclose(fs) == 0);
|
||||
}
|
|
@ -0,0 +1,405 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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 "snes9x.h"
|
||||
#include "memmap.h"
|
||||
|
||||
static uint8 region_map[6][6] =
|
||||
{
|
||||
{ 0, 0x01, 0x03, 0x07, 0x0f, 0x1f },
|
||||
{ 0, 0, 0x02, 0x06, 0x0e, 0x1e },
|
||||
{ 0, 0, 0, 0x04, 0x0c, 0x1c },
|
||||
{ 0, 0, 0, 0, 0x08, 0x18 },
|
||||
{ 0, 0, 0, 0, 0, 0x10 }
|
||||
};
|
||||
|
||||
static inline uint8 CalcWindowMask (int, uint8, uint8);
|
||||
static inline void StoreWindowRegions (uint8, struct ClipData *, int, int16 *, uint8 *, bool8, bool8 s = FALSE);
|
||||
|
||||
|
||||
static inline uint8 CalcWindowMask (int i, uint8 W1, uint8 W2)
|
||||
{
|
||||
if (!PPU.ClipWindow1Enable[i])
|
||||
{
|
||||
if (!PPU.ClipWindow2Enable[i])
|
||||
return (0);
|
||||
else
|
||||
{
|
||||
if (!PPU.ClipWindow2Inside[i])
|
||||
return (~W2);
|
||||
return (W2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!PPU.ClipWindow2Enable[i])
|
||||
{
|
||||
if (!PPU.ClipWindow1Inside[i])
|
||||
return (~W1);
|
||||
return (W1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!PPU.ClipWindow1Inside[i])
|
||||
W1 = ~W1;
|
||||
if (!PPU.ClipWindow2Inside[i])
|
||||
W2 = ~W2;
|
||||
|
||||
switch (PPU.ClipWindowOverlapLogic[i])
|
||||
{
|
||||
case 0: // OR
|
||||
return (W1 | W2);
|
||||
|
||||
case 1: // AND
|
||||
return (W1 & W2);
|
||||
|
||||
case 2: // XOR
|
||||
return (W1 ^ W2);
|
||||
|
||||
case 3: // XNOR
|
||||
return (~(W1 ^ W2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Never get here
|
||||
return (0);
|
||||
}
|
||||
|
||||
static inline void StoreWindowRegions (uint8 Mask, struct ClipData *Clip, int n_regions, int16 *windows, uint8 *drawing_modes, bool8 sub, bool8 StoreMode0)
|
||||
{
|
||||
int ct = 0;
|
||||
|
||||
for (int j = 0; j < n_regions; j++)
|
||||
{
|
||||
int DrawMode = drawing_modes[j];
|
||||
if (sub)
|
||||
DrawMode |= 1;
|
||||
if (Mask & (1 << j))
|
||||
DrawMode = 0;
|
||||
|
||||
if (!StoreMode0 && !DrawMode)
|
||||
continue;
|
||||
|
||||
if (ct > 0 && Clip->Right[ct - 1] == windows[j] && Clip->DrawMode[ct - 1] == DrawMode)
|
||||
Clip->Right[ct - 1] = windows[j + 1]; // This region borders with and has the same drawing mode as the previous region: merge them.
|
||||
else
|
||||
{
|
||||
// Add a new region to the BG
|
||||
Clip->Left[ct] = windows[j];
|
||||
Clip->Right[ct] = windows[j + 1];
|
||||
Clip->DrawMode[ct] = DrawMode;
|
||||
ct++;
|
||||
}
|
||||
}
|
||||
|
||||
Clip->Count = ct;
|
||||
}
|
||||
|
||||
void S9xComputeClipWindows (void)
|
||||
{
|
||||
int16 windows[6] = { 0, 256, 256, 256, 256, 256 };
|
||||
uint8 drawing_modes[5] = { 0, 0, 0, 0, 0 };
|
||||
int n_regions = 1;
|
||||
int i, j;
|
||||
|
||||
// Calculate window regions. We have at most 5 regions, because we have 6 control points
|
||||
// (screen edges, window 1 left & right, and window 2 left & right).
|
||||
|
||||
if (PPU.Window1Left <= PPU.Window1Right)
|
||||
{
|
||||
if (PPU.Window1Left > 0)
|
||||
{
|
||||
windows[2] = 256;
|
||||
windows[1] = PPU.Window1Left;
|
||||
n_regions = 2;
|
||||
}
|
||||
|
||||
if (PPU.Window1Right < 255)
|
||||
{
|
||||
windows[n_regions + 1] = 256;
|
||||
windows[n_regions] = PPU.Window1Right + 1;
|
||||
n_regions++;
|
||||
}
|
||||
}
|
||||
|
||||
if (PPU.Window2Left <= PPU.Window2Right)
|
||||
{
|
||||
for (i = 0; i <= n_regions; i++)
|
||||
{
|
||||
if (PPU.Window2Left == windows[i])
|
||||
break;
|
||||
|
||||
if (PPU.Window2Left < windows[i])
|
||||
{
|
||||
for (j = n_regions; j >= i; j--)
|
||||
windows[j + 1] = windows[j];
|
||||
|
||||
windows[i] = PPU.Window2Left;
|
||||
n_regions++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (; i <= n_regions; i++)
|
||||
{
|
||||
if (PPU.Window2Right + 1 == windows[i])
|
||||
break;
|
||||
|
||||
if (PPU.Window2Right + 1 < windows[i])
|
||||
{
|
||||
for (j = n_regions; j >= i; j--)
|
||||
windows[j + 1] = windows[j];
|
||||
|
||||
windows[i] = PPU.Window2Right + 1;
|
||||
n_regions++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get a bitmap of which regions correspond to each window.
|
||||
|
||||
uint8 W1, W2;
|
||||
|
||||
if (PPU.Window1Left <= PPU.Window1Right)
|
||||
{
|
||||
for (i = 0; windows[i] != PPU.Window1Left; i++) ;
|
||||
for (j = i; windows[j] != PPU.Window1Right + 1; j++) ;
|
||||
W1 = region_map[i][j];
|
||||
}
|
||||
else
|
||||
W1 = 0;
|
||||
|
||||
if (PPU.Window2Left <= PPU.Window2Right)
|
||||
{
|
||||
for (i = 0; windows[i] != PPU.Window2Left; i++) ;
|
||||
for (j = i; windows[j] != PPU.Window2Right + 1; j++) ;
|
||||
W2 = region_map[i][j];
|
||||
}
|
||||
else
|
||||
W2 = 0;
|
||||
|
||||
// Color Window affects the drawing mode for each region.
|
||||
// Modes are: 3=Draw as normal, 2=clip color (math only), 1=no math (draw only), 0=nothing.
|
||||
|
||||
uint8 CW_color = 0, CW_math = 0;
|
||||
uint8 CW = CalcWindowMask(5, W1, W2);
|
||||
|
||||
switch (Memory.FillRAM[0x2130] & 0xc0)
|
||||
{
|
||||
case 0x00: CW_color = 0; break;
|
||||
case 0x40: CW_color = ~CW; break;
|
||||
case 0x80: CW_color = CW; break;
|
||||
case 0xc0: CW_color = 0xff; break;
|
||||
}
|
||||
|
||||
switch (Memory.FillRAM[0x2130] & 0x30)
|
||||
{
|
||||
case 0x00: CW_math = 0; break;
|
||||
case 0x10: CW_math = ~CW; break;
|
||||
case 0x20: CW_math = CW; break;
|
||||
case 0x30: CW_math = 0xff; break;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_regions; i++)
|
||||
{
|
||||
if (!(CW_color & (1 << i)))
|
||||
drawing_modes[i] |= 1;
|
||||
if (!(CW_math & (1 << i)))
|
||||
drawing_modes[i] |= 2;
|
||||
}
|
||||
|
||||
// Store backdrop clip window (draw everywhere color window allows)
|
||||
|
||||
StoreWindowRegions(0, &IPPU.Clip[0][5], n_regions, windows, drawing_modes, FALSE, TRUE);
|
||||
StoreWindowRegions(0, &IPPU.Clip[1][5], n_regions, windows, drawing_modes, TRUE, TRUE);
|
||||
|
||||
// Store per-BG and OBJ clip windows
|
||||
|
||||
for (j = 0; j < 5; j++)
|
||||
{
|
||||
uint8 W = Settings.DisableGraphicWindows ? 0 : CalcWindowMask(j, W1, W2);
|
||||
for (int sub = 0; sub < 2; sub++)
|
||||
{
|
||||
if (Memory.FillRAM[sub + 0x212e] & (1 << j))
|
||||
StoreWindowRegions(W, &IPPU.Clip[sub][j], n_regions, windows, drawing_modes, sub);
|
||||
else
|
||||
StoreWindowRegions(0, &IPPU.Clip[sub][j], n_regions, windows, drawing_modes, sub);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,653 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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 <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include "conffile.h"
|
||||
|
||||
#ifdef __WIN32__
|
||||
#define snprintf _snprintf // needs ANSI compliant name
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(a,b) ((a) > (b)? (a) : (b))
|
||||
# define MIN(a,b) ((a) < (b)? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define SORT_SECTIONS_BY_SIZE // output
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool ConfigFile::defaultAutoAdd = false;
|
||||
bool ConfigFile::niceAlignment = false;
|
||||
bool ConfigFile::showComments = true;
|
||||
bool ConfigFile::alphaSort = true;
|
||||
bool ConfigFile::timeSort = false;
|
||||
static ConfigFile* curConfigFile = NULL; // for section_then_key_less
|
||||
|
||||
ConfigFile::ConfigFile(void) {
|
||||
Clear();
|
||||
}
|
||||
|
||||
void ConfigFile::Clear(void){
|
||||
data.clear();
|
||||
linectr = 0;
|
||||
}
|
||||
|
||||
bool ConfigFile::LoadFile(const char *filename){
|
||||
STREAM s;
|
||||
bool ret=false;
|
||||
const char *n, *n2;
|
||||
|
||||
if((s=OPEN_STREAM(filename, "r"))){
|
||||
n=filename;
|
||||
n2=strrchr(n, '/'); if(n2!=NULL) n=n2+1;
|
||||
n2=strrchr(n, '\\'); if(n2!=NULL) n=n2+1;
|
||||
LoadFile(new fReader(s), n);
|
||||
CLOSE_STREAM(s);
|
||||
ret = true;
|
||||
} else {
|
||||
fprintf(stderr, "Couldn't open conffile ");
|
||||
perror(filename);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void ConfigFile::LoadFile(Reader *r, const char *name){
|
||||
curConfigFile = this;
|
||||
string l, key, val;
|
||||
string section;
|
||||
string comment;
|
||||
int i, line, line2;
|
||||
bool eof;
|
||||
|
||||
line=line2=0;
|
||||
section.clear();
|
||||
do {
|
||||
line=line2++;
|
||||
l=r->getline(eof);
|
||||
ConfigEntry::trim(l);
|
||||
if(l.size()==0) continue;
|
||||
|
||||
if(l[0]=='#' || l[0]==';'){
|
||||
// comment
|
||||
continue;
|
||||
}
|
||||
|
||||
if(l[0]=='['){
|
||||
if(*l.rbegin()!=']'){
|
||||
if(name) fprintf(stderr, "%s:", name);
|
||||
fprintf(stderr, "[%d]: Ignoring invalid section header\n", line);
|
||||
continue;
|
||||
}
|
||||
section.assign(l, 1, l.size()-2);
|
||||
continue;
|
||||
}
|
||||
|
||||
while(*l.rbegin()=='\\'){
|
||||
l.erase(l.size()-1);
|
||||
line2++;
|
||||
val=r->getline(eof);
|
||||
if(eof){
|
||||
fprintf(stderr, "Unexpected EOF reading config file");
|
||||
if(name) fprintf(stderr, " '%s'", name);
|
||||
fprintf(stderr, "\n");
|
||||
return;
|
||||
}
|
||||
ConfigEntry::trim(val);
|
||||
l+=val;
|
||||
}
|
||||
i=l.find('=');
|
||||
if(i<0){
|
||||
if(name) fprintf(stderr, "%s:", name);
|
||||
fprintf(stderr, "[%d]: Ignoring invalid entry\n", line);
|
||||
continue;
|
||||
}
|
||||
key=l.substr(0,i); ConfigEntry::trim(key);
|
||||
val=l.substr(i+1); comment = ConfigEntry::trimCommented(val);
|
||||
if(val[0]=='"' && *val.rbegin()=='"') val=val.substr(1, val.size()-2);
|
||||
|
||||
ConfigEntry e(line, section, key, val);
|
||||
e.comment = comment;
|
||||
data.erase(e);
|
||||
data.insert(e);
|
||||
} while(!eof);
|
||||
curConfigFile = NULL;
|
||||
}
|
||||
|
||||
bool ConfigFile::SaveTo(const char *filename){
|
||||
string section;
|
||||
FILE *fp;
|
||||
|
||||
if((fp=fopen(filename, "w"))==NULL){
|
||||
fprintf(stderr, "Couldn't write conffile ");
|
||||
perror(filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
curConfigFile = this;
|
||||
section.clear();
|
||||
set<ConfigEntry, ConfigEntry::line_less> tmp;
|
||||
fprintf(fp, "# Config file output by snes9x\n");
|
||||
time_t t=time(NULL);
|
||||
fprintf(fp, "# %s", ctime(&t));
|
||||
|
||||
#ifdef SORT_SECTIONS_BY_SIZE
|
||||
std::set<ConfigEntry, ConfigEntry::section_then_key_less> data2;
|
||||
for(set<ConfigEntry, ConfigEntry::key_less>::iterator k=data.begin(); k!=data.end(); k++){
|
||||
ConfigEntry e (k->line, k->section, k->key, k->val); e.comment = k->comment;
|
||||
data2.insert(e);
|
||||
}
|
||||
#else
|
||||
#define data2 data
|
||||
#define section_then_key_less key_less
|
||||
#endif
|
||||
|
||||
for(set<ConfigEntry, ConfigEntry::section_then_key_less>::iterator j=data2.begin(); ; j++){
|
||||
if(j==data2.end() || j->section!=section){
|
||||
if(!tmp.empty()){
|
||||
fprintf(fp, "\n[%s]\n", section.c_str());
|
||||
unsigned int maxKeyLen=0, maxValLen=0; int maxLeftDiv=0; int maxRightDiv=-1;
|
||||
if(niceAlignment){
|
||||
for(set<ConfigEntry, ConfigEntry::line_less>::iterator i=tmp.begin(); i!=tmp.end(); i++){
|
||||
int len3 = i->key.find_last_of(':');
|
||||
maxRightDiv = MAX(maxRightDiv, len3);
|
||||
len3 = i->key.length() - len3;
|
||||
maxLeftDiv = MAX(maxLeftDiv, len3);
|
||||
maxKeyLen = MAX(maxKeyLen, i->key.length()+3);
|
||||
if(showComments){
|
||||
string o=i->val; ConfigEntry::trim(o);
|
||||
unsigned int len = o.length();
|
||||
for(signed int j=len-1;j>=0;j--) if(o.at(j)=='#') len++;
|
||||
if(o!=i->val) len+=2;
|
||||
maxValLen = MAX(maxValLen, len);
|
||||
}
|
||||
}
|
||||
if(maxValLen>48) maxValLen=48; // limit spacing
|
||||
}
|
||||
|
||||
for(set<ConfigEntry, ConfigEntry::line_less>::iterator i=tmp.begin(); i!=tmp.end(); i++){
|
||||
string o=i->val; ConfigEntry::trim(o);
|
||||
if(o!=i->val) o="\""+i->val+"\"";
|
||||
int off=0, len3=0;
|
||||
for(;;){
|
||||
int k=o.find('#',off);
|
||||
if(k>=0){
|
||||
o.insert(k,1,'#'); // re-double any comment characters
|
||||
off=k+2;
|
||||
if(off<(int)o.length()) continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(niceAlignment){
|
||||
len3=i->key.find_last_of(':');
|
||||
int len3sub=0;
|
||||
if(len3 < maxRightDiv){
|
||||
for(int j=len3;j<maxRightDiv;j++) fputc(' ',fp);
|
||||
len3sub=maxRightDiv-len3;
|
||||
len3 = maxRightDiv;
|
||||
}
|
||||
len3+=maxLeftDiv-i->key.length();
|
||||
for(unsigned int j=i->key.length()+len3+3;j<maxKeyLen;j++) fputc(' ',fp);
|
||||
fprintf(fp, "%s", i->key.c_str());
|
||||
for(int j=0;j<len3-len3sub;j++) fputc(' ',fp);
|
||||
fprintf(fp, " = %s", o.c_str());
|
||||
} else
|
||||
fprintf(fp, "%s = %s", i->key.c_str(), o.c_str());
|
||||
|
||||
if(showComments && !i->comment.empty()){
|
||||
if(niceAlignment) for(unsigned int j=o.length();j<maxValLen;j++) fputc(' ',fp);
|
||||
fprintf(fp, " # %s", i->comment.c_str());
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
}
|
||||
if(j==data2.end()) break;
|
||||
section=j->section;
|
||||
tmp.clear();
|
||||
}
|
||||
tmp.insert(*j);
|
||||
}
|
||||
curConfigFile = NULL;
|
||||
|
||||
#undef data2
|
||||
#undef section_then_key_less
|
||||
|
||||
if(ferror(fp))
|
||||
{
|
||||
fp = fp;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************/
|
||||
|
||||
string ConfigFile::Get(const char *key){
|
||||
set<ConfigEntry, ConfigEntry::key_less>::iterator i;
|
||||
i=data.find(ConfigEntry(key));
|
||||
i->used=true;
|
||||
return i->val;
|
||||
}
|
||||
bool ConfigFile::Has(const char *key){
|
||||
return data.find(ConfigEntry(key))!=data.end();
|
||||
}
|
||||
|
||||
// exists and isn't completely empty (any side-effects are intentional)
|
||||
bool ConfigFile::Exists(const char *key){
|
||||
const char* val = GetString(key, NULL);
|
||||
return val && *val;
|
||||
}
|
||||
|
||||
|
||||
string ConfigFile::GetString(const char *key, string def){
|
||||
if(!Exists(key))
|
||||
return def;
|
||||
return Get(key);
|
||||
}
|
||||
|
||||
char *ConfigFile::GetString(const char *key, char *out, uint32 outlen){
|
||||
if(!Exists(key)) return NULL;
|
||||
ZeroMemory(out, outlen);
|
||||
string o=Get(key);
|
||||
if(outlen>0){
|
||||
outlen--;
|
||||
if(o.size()<outlen) outlen=o.size();
|
||||
memcpy(out, o.data(), outlen);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
const char *ConfigFile::GetString(const char *key, const char *def){
|
||||
set<ConfigEntry, ConfigEntry::key_less>::iterator i;
|
||||
i=data.find(ConfigEntry(key));
|
||||
if(i==data.end())
|
||||
{
|
||||
if(defaultAutoAdd) SetString(key,""); //SetString(key, def?def:"");
|
||||
return def;
|
||||
}
|
||||
i->used=true;
|
||||
// This should be OK, until this key gets removed
|
||||
const std::string &iVal = i->val;
|
||||
return iVal.c_str();
|
||||
}
|
||||
|
||||
char *ConfigFile::GetStringDup(const char *key, const char *def){
|
||||
const char *c=GetString(key, def);
|
||||
if(c==NULL) return NULL;
|
||||
return strdup(c);
|
||||
}
|
||||
|
||||
bool ConfigFile::SetString(const char *key, string val, const char *comment){
|
||||
set<ConfigEntry, ConfigEntry::key_less>::iterator i;
|
||||
bool ret=false;
|
||||
|
||||
ConfigEntry e(key, val);
|
||||
if(comment && *comment) e.comment = comment;
|
||||
e.used=true;
|
||||
|
||||
i=data.find(e);
|
||||
if(i!=data.end()){
|
||||
e.line=i->line;
|
||||
data.erase(e);
|
||||
ret=true;
|
||||
}
|
||||
if((i==data.end() && (!alphaSort || timeSort)) || (!alphaSort && timeSort))
|
||||
e.line = linectr++;
|
||||
|
||||
data.insert(e);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32 ConfigFile::GetInt(const char *key, int32 def, bool *bad){
|
||||
if(bad) *bad=false;
|
||||
if(!Exists(key))
|
||||
return def;
|
||||
char *c;
|
||||
int32 i;
|
||||
string o=Get(key);
|
||||
i=strtol(o.c_str(), &c, 10);
|
||||
if(c!=NULL && *c!='\0'){
|
||||
i=def;
|
||||
if(bad) *bad=true;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
bool ConfigFile::SetInt(const char *key, int32 val, const char *comment){
|
||||
char buf[20];
|
||||
snprintf(buf, sizeof(buf), "%d", (int)val);
|
||||
return SetString(key, buf, comment);
|
||||
}
|
||||
|
||||
uint32 ConfigFile::GetUInt(const char *key, uint32 def, int base, bool *bad){
|
||||
if(bad) *bad=false;
|
||||
if(!Exists(key))
|
||||
return def;
|
||||
if(base!=8 && base!=10 && base!=16) base=0;
|
||||
char *c;
|
||||
uint32 i;
|
||||
string o=Get(key);
|
||||
i=strtol(o.c_str(), &c, base);
|
||||
if(c!=NULL && *c!='\0'){
|
||||
i=def;
|
||||
if(bad) *bad=true;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
bool ConfigFile::SetUInt(const char *key, uint32 val, int base, const char *comment){
|
||||
char buf[20];
|
||||
switch(base){
|
||||
case 10:
|
||||
default:
|
||||
snprintf(buf, sizeof(buf), "%u", (unsigned int)val);
|
||||
break;
|
||||
case 8:
|
||||
snprintf(buf, sizeof(buf), "%#o", (unsigned int)val);
|
||||
break;
|
||||
case 16:
|
||||
snprintf(buf, sizeof(buf), "%#x", (unsigned int)val);
|
||||
break;
|
||||
}
|
||||
return SetString(key, buf, comment);
|
||||
}
|
||||
|
||||
bool ConfigFile::GetBool(const char *key, bool def, bool *bad){
|
||||
if(bad) *bad=false;
|
||||
if(!Exists(key))
|
||||
return def;
|
||||
string o=Get(key);
|
||||
const char *c=o.c_str();
|
||||
if(!strcasecmp(c, "true") || !strcasecmp(c, "1") || !strcasecmp(c, "yes") || !strcasecmp(c, "on")) return true;
|
||||
if(!strcasecmp(c, "false") || !strcasecmp(c, "0") || !strcasecmp(c, "no") || !strcasecmp(c, "off")) return false;
|
||||
if(bad) *bad=true;
|
||||
return def;
|
||||
}
|
||||
|
||||
bool ConfigFile::SetBool(const char *key, bool val, const char *true_val, const char *false_val, const char *comment){
|
||||
return SetString(key, val?true_val:false_val, comment);
|
||||
}
|
||||
|
||||
const char* ConfigFile::GetComment(const char *key)
|
||||
{
|
||||
set<ConfigEntry, ConfigEntry::key_less>::iterator i;
|
||||
i=data.find(ConfigEntry(key));
|
||||
if(i==data.end())
|
||||
return NULL;
|
||||
|
||||
// This should be OK, until this key gets removed
|
||||
const std::string &iCom = i->comment;
|
||||
return iCom.c_str();
|
||||
}
|
||||
|
||||
bool ConfigFile::DeleteKey(const char *key){
|
||||
return (data.erase(ConfigEntry(key))>0);
|
||||
}
|
||||
|
||||
/***********************************************/
|
||||
|
||||
bool ConfigFile::DeleteSection(const char *section){
|
||||
set<ConfigEntry, ConfigEntry::key_less>::iterator s, e;
|
||||
|
||||
for(s=data.begin(); s!=data.end() && s->section!=section; s++) ;
|
||||
if(s==data.end()) return false;
|
||||
for(e=s; e!=data.end() && e->section==section; e++) ;
|
||||
data.erase(s, e);
|
||||
return true;
|
||||
}
|
||||
|
||||
ConfigFile::secvec_t ConfigFile::GetSection(const char *section){
|
||||
secvec_t v;
|
||||
set<ConfigEntry, ConfigEntry::key_less>::iterator i;
|
||||
|
||||
v.clear();
|
||||
for(i=data.begin(); i!=data.end(); i++){
|
||||
if(i->section!=section) continue;
|
||||
v.push_back(std::pair<string,string>(i->key, i->val));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
int ConfigFile::GetSectionSize(const char *section){
|
||||
int count=0;
|
||||
const unsigned int seclen=strlen(section);
|
||||
set<ConfigEntry, ConfigEntry::key_less>::iterator i;
|
||||
for(i=data.begin(); i!=data.end(); i++)
|
||||
if(i->section==section || !strncasecmp(section,i->section.c_str(),MIN(seclen,i->section.size()))) count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
// Clears all key-value pairs that didn't receive a "Get" or "Exists" command
|
||||
void ConfigFile::ClearUnused()
|
||||
{
|
||||
set<ConfigEntry, ConfigEntry::key_less>::iterator i;
|
||||
again:
|
||||
for(i=data.begin(); i!=data.end(); i++){
|
||||
if(!i->used){
|
||||
data.erase(i);
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigFile::ClearLines()
|
||||
{
|
||||
set<ConfigEntry, ConfigEntry::key_less>::iterator i;
|
||||
for(i=data.begin(); i!=data.end(); i++){
|
||||
*(const_cast<int*>(&i->line)) = -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool ConfigFile::ConfigEntry::section_then_key_less::operator()(const ConfigEntry &a, const ConfigEntry &b) {
|
||||
if(curConfigFile && a.section!=b.section){
|
||||
const int sva = curConfigFile->GetSectionSize(a.section.c_str());
|
||||
const int svb = curConfigFile->GetSectionSize(b.section.c_str());
|
||||
if(sva<svb) return true;
|
||||
if(sva>svb) return false;
|
||||
return a.section<b.section;
|
||||
}
|
||||
return a.key<b.key;
|
||||
}
|
||||
|
||||
|
||||
void ConfigFile::SetDefaultAutoAdd(bool autoAdd)
|
||||
{
|
||||
defaultAutoAdd = autoAdd;
|
||||
}
|
||||
void ConfigFile::SetNiceAlignment(bool align)
|
||||
{
|
||||
niceAlignment = align;
|
||||
}
|
||||
void ConfigFile::SetShowComments(bool show)
|
||||
{
|
||||
showComments = show;
|
||||
}
|
||||
void ConfigFile::SetAlphaSort(bool sort)
|
||||
{
|
||||
alphaSort = sort;
|
||||
}
|
||||
void ConfigFile::SetTimeSort(bool sort)
|
||||
{
|
||||
timeSort = sort;
|
||||
}
|
|
@ -0,0 +1,404 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _CONFIG_H_
|
||||
#define _CONFIG_H_
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#ifdef UNZIP_SUPPORT
|
||||
#include "unzip/unzip.h"
|
||||
#endif
|
||||
#include "snes9x.h"
|
||||
#include "reader.h"
|
||||
|
||||
class ConfigFile {
|
||||
public:
|
||||
ConfigFile(void);
|
||||
|
||||
void Clear(void);
|
||||
|
||||
// return false on failure
|
||||
bool LoadFile(const char *filename);
|
||||
void LoadFile(Reader *r, const char *name=NULL);
|
||||
|
||||
// return false if key does not exist or is empty
|
||||
bool Exists(const char *key);
|
||||
|
||||
// return the value / default
|
||||
std::string GetString(const char *key, std::string def);
|
||||
char *GetString(const char *key, char *out, uint32 outlen); // return NULL if it doesn't exist, out not affected
|
||||
const char *GetString(const char *key, const char *def=NULL); // NOTE: returned pointer becomes invalid when key is deleted/modified, or the ConfigFile is Clear()ed or deleted.
|
||||
char *GetStringDup(const char *key, const char *def=NULL); // Much like "strdup(GetString(key, def))"
|
||||
int32 GetInt(const char *key, int32 def=-1, bool *bad=NULL);
|
||||
uint32 GetUInt(const char *key, uint32 def=0, int base=0, bool *bad=NULL); // base = 0, 8, 10, or 16
|
||||
bool GetBool(const char *key, bool def=false, bool *bad=NULL);
|
||||
const char* GetComment(const char *key); // NOTE: returned pointer becomes invalid when key is deleted/modified, or the ConfigFile is Clear()ed or deleted.
|
||||
|
||||
// return true if the key existed prior to setting
|
||||
bool SetString(const char *key, std::string val, const char *comment="");
|
||||
bool SetInt(const char *key, int32 val, const char *comment="");
|
||||
bool SetUInt(const char *key, uint32 val, int base=10, const char *comment=""); // base = 8, 10, or 16
|
||||
bool SetBool(const char *key, bool val, const char *true_val="TRUE", const char *false_val="FALSE", const char *comment="");
|
||||
bool DeleteKey(const char *key);
|
||||
|
||||
// Operation on entire sections
|
||||
bool DeleteSection(const char *section);
|
||||
typedef std::vector<std::pair<std::string,std::string> > secvec_t;
|
||||
secvec_t GetSection(const char *section);
|
||||
int GetSectionSize(const char *section);
|
||||
|
||||
// Clears all key-value pairs that didn't receive a Set command, or a Get command with autoAdd on
|
||||
void ClearUnused(void);
|
||||
|
||||
// Clears all stored line numbers
|
||||
void ClearLines(void);
|
||||
|
||||
bool SaveTo(const char *filename);
|
||||
|
||||
static void SetDefaultAutoAdd(bool autoAdd);
|
||||
static void SetNiceAlignment(bool align);
|
||||
static void SetShowComments(bool show);
|
||||
static void SetAlphaSort(bool sort);
|
||||
static void SetTimeSort(bool sort);
|
||||
|
||||
private:
|
||||
std::string Get(const char *key);
|
||||
bool Has(const char *key);
|
||||
|
||||
class ConfigEntry {
|
||||
protected:
|
||||
int line;
|
||||
std::string section;
|
||||
std::string key;
|
||||
std::string val;
|
||||
std::string comment;
|
||||
mutable bool used;
|
||||
|
||||
struct section_then_key_less {
|
||||
bool operator()(const ConfigEntry &a, const ConfigEntry &b);
|
||||
};
|
||||
|
||||
struct key_less {
|
||||
bool operator()(const ConfigEntry &a, const ConfigEntry &b) const{
|
||||
if(a.section!=b.section) return a.section<b.section;
|
||||
return a.key<b.key;
|
||||
}
|
||||
};
|
||||
|
||||
struct line_less {
|
||||
bool operator()(const ConfigEntry &a, const ConfigEntry &b){
|
||||
if(a.line==b.line) return (b.val.empty() && !a.val.empty()) || a.key<b.key;
|
||||
if(b.line<0) return true;
|
||||
if(a.line<0) return false;
|
||||
return a.line<b.line;
|
||||
}
|
||||
};
|
||||
|
||||
static void trim(std::string &s){
|
||||
int i;
|
||||
i=s.find_first_not_of(" \f\n\r\t\v");
|
||||
if(i==-1){
|
||||
s.clear();
|
||||
return;
|
||||
}
|
||||
if(i>0) s.erase(0, i); // erase leading whitespace
|
||||
i=s.find_last_not_of(" \f\n\r\t\v");
|
||||
if(i!=-1) s.erase(i+1); // erase trailing whitespace
|
||||
return;
|
||||
}
|
||||
|
||||
// trims comments and leading/trailing whitespace from s, and returns any trimmed comments
|
||||
// make sure not to call this more than once on the same string
|
||||
static std::string trimCommented(std::string &s){
|
||||
std::string cmt;
|
||||
int i;
|
||||
i=s.find_first_not_of(" \f\n\r\t\v");
|
||||
if(i==-1){
|
||||
s.clear();
|
||||
return cmt;
|
||||
}
|
||||
if(i>0) s.erase(0, i); // erase leading whitespace
|
||||
int off=0;
|
||||
for(;;){
|
||||
i=s.find('#',off); // find trailing comment
|
||||
if(i>=0)
|
||||
{
|
||||
if((int)s.length()>i+1 && s.at(i+1) == '#') {
|
||||
s.erase(i,1); // ignore ## and change to #
|
||||
off = i+1;
|
||||
continue;
|
||||
} else {
|
||||
int j=s.find_first_not_of(" \f\n\r\t\v",i+1);
|
||||
if(j!=-1) cmt = s.substr(j); // store
|
||||
s.erase(i); // erase trailing comment
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
i=s.find_last_not_of(" \f\n\r\t\v");
|
||||
if(i!=-1) s.erase(i+1); // erase trailing whitespace
|
||||
return cmt;
|
||||
}
|
||||
|
||||
public:
|
||||
ConfigEntry(int l, const std::string &s, const std::string &k, const std::string &v) :
|
||||
line(l), section(s), key(k), val(v) {
|
||||
trim(section);
|
||||
trim(key);
|
||||
used=false;
|
||||
}
|
||||
|
||||
void parse_key(const std::string &k){
|
||||
int i=k.find("::");
|
||||
if(i==-1){
|
||||
section="Uncategorized"; key=k;
|
||||
} else {
|
||||
section=k.substr(0,i); key=k.substr(i+2);
|
||||
}
|
||||
trim(section);
|
||||
trim(key);
|
||||
used=false;
|
||||
}
|
||||
|
||||
ConfigEntry(const std::string k){
|
||||
parse_key(k);
|
||||
}
|
||||
|
||||
ConfigEntry(const std::string k, const std::string &v) : line(-1), val(v) {
|
||||
parse_key(k);
|
||||
}
|
||||
|
||||
friend class ConfigFile;
|
||||
friend struct key_less;
|
||||
friend struct line_less;
|
||||
};
|
||||
std::set<ConfigEntry, ConfigEntry::key_less> data;
|
||||
int linectr;
|
||||
static bool defaultAutoAdd;
|
||||
static bool niceAlignment;
|
||||
static bool showComments;
|
||||
static bool alphaSort;
|
||||
static bool timeSort;
|
||||
};
|
||||
|
||||
/* Config file format:
|
||||
*
|
||||
* Comments are any lines whose first non-whitespace character is ';' or '#'.
|
||||
* Note that comments can also follow a value, on the same line.
|
||||
* To intentionally have a '#' character in the value, use ##
|
||||
*
|
||||
* All parameters fall into sections. To name a section, the first
|
||||
* non-whitespace character on the line will be '[', and the last will be ']'.
|
||||
*
|
||||
* Parameters are simple key=value pairs. Whitespace around the '=', and at the
|
||||
* beginning or end of the line is ignored. Key names may not contain '=' nor
|
||||
* begin with '[', however values can. If the last character of the value is
|
||||
* '\', the next line (sans leading/trailing whitespace) is considered part of
|
||||
* the value as well. Programmatically, the key "K" in section "S" is referred
|
||||
* to as "S::K", much like C++ namespaces. For example:
|
||||
* [Section1]
|
||||
* # this is a comment
|
||||
* foo = bar \
|
||||
* baz\
|
||||
* quux \
|
||||
* ## this is not a comment! # this IS a comment
|
||||
* means the value of "Section1::foo" is "bar bazquux # this is not a comment!"
|
||||
*
|
||||
* Parameters may be of several types:
|
||||
* String - Bare characters. If the first and last characters are both '"',
|
||||
* they are removed (so just double them if you really want quotes
|
||||
* there)
|
||||
* Int - A decimal number from -2147483648 to 2147483647
|
||||
* UInt - A number in decimal, hex, or octal from 0 to 4294967295 (or
|
||||
* 0xffffffff, or 037777777777)
|
||||
* Bool - true/false, 0/1, on/off, yes/no
|
||||
*
|
||||
* Of course, the actual accepted values for a parameter may be further
|
||||
* restricted ;)
|
||||
*/
|
||||
|
||||
|
||||
/* You must write this for your port */
|
||||
void S9xParsePortConfig(ConfigFile &, int pass);
|
||||
|
||||
/* This may or may not be useful to you */
|
||||
const char *S9xParseDisplayConfig(ConfigFile &, int pass);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,453 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _CONTROLS_H_
|
||||
#define _CONTROLS_H_
|
||||
|
||||
#define S9xNoMapping 0
|
||||
#define S9xButtonJoypad 1
|
||||
#define S9xButtonMouse 2
|
||||
#define S9xButtonSuperscope 3
|
||||
#define S9xButtonJustifier 4
|
||||
#define S9xButtonCommand 5
|
||||
#define S9xButtonMulti 6
|
||||
#define S9xAxisJoypad 7
|
||||
#define S9xPointer 8
|
||||
|
||||
#define S9xButtonPseudopointer 254
|
||||
#define S9xAxisPseudopointer 253
|
||||
#define S9xAxisPseudobuttons 252
|
||||
|
||||
// These are automatically kicked out to the S9xHandlePortCommand function.
|
||||
// If your port wants to define port-specific commands or whatever, use these values for the s9xcommand_t type field.
|
||||
|
||||
#define S9xButtonPort 251
|
||||
#define S9xAxisPort 250
|
||||
#define S9xPointerPort 249
|
||||
|
||||
#define S9xBadMapping 255
|
||||
#define InvalidControlID ((uint32) -1)
|
||||
|
||||
// S9xButtonPseudopointer and S9xAxisPseudopointer will report pointer motion using IDs PseudoPointerBase through PseudoPointerBase+7.
|
||||
// S9xAxisPseudopointer command types. S9xAxisPseudobuttons will report buttons with IDs PseudoButtonBase to PseudoButtonBase+255.
|
||||
|
||||
#define PseudoPointerBase (InvalidControlID - 8)
|
||||
#define PseudoButtonBase (PseudoPointerBase - 256)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8 type;
|
||||
uint8 multi_press:2;
|
||||
uint8 button_norpt:1;
|
||||
|
||||
union
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8 idx:3; // Pad number 0-7
|
||||
uint8 toggle:1; // If set, toggle turbo/sticky for the button
|
||||
uint8 turbo:1; // If set, be a 'turbo' button
|
||||
uint8 sticky:1; // If set, toggle button state (on/turbo or off) when pressed and do nothing on release
|
||||
uint16 buttons; // Which buttons to actuate. Use SNES_*_MASK constants from snes9x.h
|
||||
} joypad;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8 idx:1; // Mouse number 0-1
|
||||
uint8 left:1; // buttons
|
||||
uint8 right:1;
|
||||
} mouse;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8 fire:1;
|
||||
uint8 cursor:1;
|
||||
uint8 turbo:1;
|
||||
uint8 pause:1;
|
||||
uint8 aim_offscreen:1; // Pretend we're pointing the gun offscreen (ignore the pointer)
|
||||
} scope;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8 idx:3; // Pseudo-pointer number 0-7
|
||||
uint8 speed_type:2; // 0=variable, 1=slow, 2=med, 3=fast
|
||||
int8 UD:2; // -1=up, 1=down, 0=no vertical motion
|
||||
int8 LR:2; // -1=left, 1=right, 0=no horizontal motion
|
||||
} pointer;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8 idx:1; // Justifier number 0-1
|
||||
uint8 trigger:1; // buttons
|
||||
uint8 start:1;
|
||||
uint8 aim_offscreen:1; // Pretend we're pointing the gun offscreen (ignore the pointer)
|
||||
} justifier;
|
||||
|
||||
int32 multi_idx;
|
||||
uint16 command;
|
||||
} button;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8 idx:3; // Pad number 0-7
|
||||
uint8 invert:1; // 1 = positive is Left/Up/Y/X/L
|
||||
uint8 axis:3; // 0=Left/Right, 1=Up/Down, 2=Y/A, 3=X/B, 4=L/R
|
||||
uint8 threshold; // (threshold+1)/256% deflection is a button press
|
||||
} joypad;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8 idx:3; // Pseudo-pointer number 0-7
|
||||
uint8 speed_type:2; // 0=variable, 1=slow, 2=med, 3=fast
|
||||
uint8 invert:1; // 1 = invert axis, so positive is up/left
|
||||
uint8 HV:1; // 0=horizontal, 1=vertical
|
||||
} pointer;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8 threshold; // (threshold+1)/256% deflection is a button press
|
||||
uint8 negbutton; // Button ID for negative deflection
|
||||
uint8 posbutton; // Button ID for positive deflection
|
||||
} button;
|
||||
} axis;
|
||||
|
||||
struct // Which SNES-pointers to control with this pointer
|
||||
{
|
||||
uint16 aim_mouse0:1;
|
||||
uint16 aim_mouse1:1;
|
||||
uint16 aim_scope:1;
|
||||
uint16 aim_justifier0:1;
|
||||
uint16 aim_justifier1:1;
|
||||
} pointer;
|
||||
|
||||
uint8 port[4];
|
||||
};
|
||||
} s9xcommand_t;
|
||||
|
||||
// Starting out...
|
||||
|
||||
void S9xUnmapAllControls (void);
|
||||
|
||||
// Setting which controllers are plugged in.
|
||||
|
||||
enum controllers
|
||||
{
|
||||
CTL_NONE, // all ids ignored
|
||||
CTL_JOYPAD, // use id1 to specify 0-7
|
||||
CTL_MOUSE, // use id1 to specify 0-1
|
||||
CTL_SUPERSCOPE,
|
||||
CTL_JUSTIFIER, // use id1: 0=one justifier, 1=two justifiers
|
||||
CTL_MP5 // use id1-id4 to specify pad 0-7 (or -1)
|
||||
};
|
||||
|
||||
void S9xSetController (int port, enum controllers controller, int8 id1, int8 id2, int8 id3, int8 id4); // port=0-1
|
||||
void S9xGetController (int port, enum controllers *controller, int8 *id1, int8 *id2, int8 *id3, int8 *id4);
|
||||
void S9xReportControllers (void);
|
||||
|
||||
// Call this when you're done with S9xSetController, or if you change any of the controller Settings.*Master flags.
|
||||
// Returns true if something was disabled.
|
||||
|
||||
bool S9xVerifyControllers (void);
|
||||
|
||||
// Functions for translation s9xcommand_t's into strings, and vice versa.
|
||||
// free() the returned string after you're done with it.
|
||||
|
||||
char * S9xGetCommandName (s9xcommand_t command);
|
||||
s9xcommand_t S9xGetCommandT (const char *name);
|
||||
|
||||
// Returns an array of strings naming all the snes9x commands.
|
||||
// Note that this is only the strings for S9xButtonCommand!
|
||||
// The idea is that this would be used for a pull-down list in a config GUI. DO NOT free() the returned value.
|
||||
|
||||
const char ** S9xGetAllSnes9xCommands (void);
|
||||
|
||||
// Generic mapping functions
|
||||
|
||||
s9xcommand_t S9xGetMapping (uint32 id);
|
||||
void S9xUnmapID (uint32 id);
|
||||
|
||||
// Button mapping functions.
|
||||
// If a button is mapped with poll=TRUE, then S9xPollButton will be called whenever snes9x feels a need for that mapping.
|
||||
// Otherwise, snes9x will assume you will call S9xReportButton() whenever the button state changes.
|
||||
// S9xMapButton() will fail and return FALSE if mapping.type isn't an S9xButton* type.
|
||||
|
||||
bool S9xMapButton (uint32 id, s9xcommand_t mapping, bool poll);
|
||||
void S9xReportButton (uint32 id, bool pressed);
|
||||
|
||||
// Pointer mapping functions.
|
||||
// If a pointer is mapped with poll=TRUE, then S9xPollPointer will be called whenever snes9x feels a need for that mapping.
|
||||
// Otherwise, snes9x will assume you will call S9xReportPointer() whenever the pointer position changes.
|
||||
// S9xMapPointer() will fail and return FALSE if mapping.type isn't an S9xPointer* type.
|
||||
|
||||
// Note that position [0,0] is considered the upper-left corner of the 'screen',
|
||||
// and either [255,223] or [255,239] is the lower-right.
|
||||
// Note that the SNES mouse doesn't aim at a particular point,
|
||||
// so the SNES's idea of where the mouse pointer is will probably differ from your OS's idea.
|
||||
|
||||
bool S9xMapPointer (uint32 id, s9xcommand_t mapping, bool poll);
|
||||
void S9xReportPointer (uint32 id, int16 x, int16 y);
|
||||
|
||||
// Axis mapping functions.
|
||||
// If an axis is mapped with poll=TRUE, then S9xPollAxis will be called whenever snes9x feels a need for that mapping.
|
||||
// Otherwise, snes9x will assume you will call S9xReportAxis() whenever the axis deflection changes.
|
||||
// S9xMapAxis() will fail and return FALSE if mapping.type isn't an S9xAxis* type.
|
||||
|
||||
// Note that value is linear -32767 through 32767 with 0 being no deflection.
|
||||
// If your axis reports differently you should transform the value before passing it to S9xReportAxis().
|
||||
|
||||
bool S9xMapAxis (uint32 id, s9xcommand_t mapping, bool poll);
|
||||
void S9xReportAxis (uint32 id, int16 value);
|
||||
|
||||
// Do whatever the s9xcommand_t says to do.
|
||||
// If cmd.type is a button type, data1 should be TRUE (non-0) or FALSE (0) to indicate whether the 'button' is pressed or released.
|
||||
// If cmd.type is an axis, data1 holds the deflection value.
|
||||
// If cmd.type is a pointer, data1 and data2 are the positions of the pointer.
|
||||
|
||||
void S9xApplyCommand (s9xcommand_t cmd, int16 data1, int16 data2);
|
||||
|
||||
//////////
|
||||
// These functions are called by snes9x into your port, so each port should implement them.
|
||||
|
||||
// If something was mapped with poll=TRUE, these functions will be called when snes9x needs the button/axis/pointer state.
|
||||
// Fill in the reference options as appropriate.
|
||||
|
||||
bool S9xPollButton (uint32 id, bool *pressed);
|
||||
bool S9xPollPointer (uint32 id, int16 *x, int16 *y);
|
||||
bool S9xPollAxis (uint32 id, int16 *value);
|
||||
|
||||
// These are called when snes9x tries to apply a command with a S9x*Port type.
|
||||
// data1 and data2 are filled in like S9xApplyCommand.
|
||||
|
||||
void S9xHandlePortCommand (s9xcommand_t cmd, int16 data1, int16 data2);
|
||||
|
||||
// Called before already-read SNES joypad data is being used by the game if your port defines SNES_JOY_READ_CALLBACKS.
|
||||
|
||||
#ifdef SNES_JOY_READ_CALLBACKS
|
||||
void S9xOnSNESPadRead (void);
|
||||
#endif
|
||||
|
||||
// These are for your use.
|
||||
|
||||
s9xcommand_t S9xGetPortCommandT (const char *name);
|
||||
char * S9xGetPortCommandName (s9xcommand_t command);
|
||||
void S9xSetupDefaultKeymap (void);
|
||||
bool8 S9xMapInput (const char *name, s9xcommand_t *cmd);
|
||||
|
||||
//////////
|
||||
// These functions are called from snes9x into this subsystem. No need to use them from a port.
|
||||
|
||||
// Use when resetting snes9x.
|
||||
|
||||
void S9xControlsReset (void);
|
||||
void S9xControlsSoftReset (void);
|
||||
|
||||
// Use when writing to $4016.
|
||||
|
||||
void S9xSetJoypadLatch (bool latch);
|
||||
|
||||
// Use when reading $4016/7 (JOYSER0 and JOYSER1).
|
||||
|
||||
uint8 S9xReadJOYSERn (int n);
|
||||
|
||||
// End-Of-Frame processing. Sets gun latch variables and tries to draw crosshairs
|
||||
|
||||
void S9xControlEOF (void);
|
||||
|
||||
// Functions and a structure for snapshot.
|
||||
|
||||
struct SControlSnapshot
|
||||
{
|
||||
uint8 ver;
|
||||
uint8 port1_read_idx[2];
|
||||
uint8 dummy1[4]; // for future expansion
|
||||
uint8 port2_read_idx[2];
|
||||
uint8 dummy2[4];
|
||||
uint8 mouse_speed[2];
|
||||
uint8 justifier_select;
|
||||
uint8 dummy3[8];
|
||||
bool8 pad_read, pad_read_last;
|
||||
uint8 internal[60]; // yes, we need to save this!
|
||||
};
|
||||
|
||||
void S9xControlPreSaveState (struct SControlSnapshot *s);
|
||||
void S9xControlPostLoadState (struct SControlSnapshot *s);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,339 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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 "snes9x.h"
|
||||
#include "memmap.h"
|
||||
#include "dma.h"
|
||||
#include "apu/apu.h"
|
||||
#include "fxemu.h"
|
||||
#include "sdd1.h"
|
||||
#include "srtc.h"
|
||||
#include "snapshot.h"
|
||||
#include "cheats.h"
|
||||
#include "logger.h"
|
||||
#ifdef DEBUGGER
|
||||
#include "debug.h"
|
||||
#endif
|
||||
|
||||
static void S9xResetCPU (void);
|
||||
static void S9xSoftResetCPU (void);
|
||||
|
||||
|
||||
static void S9xResetCPU (void)
|
||||
{
|
||||
S9xSoftResetCPU();
|
||||
Registers.SL = 0xff;
|
||||
Registers.P.W = 0;
|
||||
Registers.A.W = 0;
|
||||
Registers.X.W = 0;
|
||||
Registers.Y.W = 0;
|
||||
SetFlags(MemoryFlag | IndexFlag | IRQ | Emulation);
|
||||
ClearFlags(Decimal);
|
||||
}
|
||||
|
||||
static void S9xSoftResetCPU (void)
|
||||
{
|
||||
Registers.PBPC = 0;
|
||||
Registers.PB = 0;
|
||||
Registers.PCw = S9xGetWord(0xfffc);
|
||||
OpenBus = Registers.PCh;
|
||||
Registers.D.W = 0;
|
||||
Registers.DB = 0;
|
||||
Registers.SH = 1;
|
||||
Registers.SL -= 3;
|
||||
Registers.XH = 0;
|
||||
Registers.YH = 0;
|
||||
|
||||
ICPU.ShiftedPB = 0;
|
||||
ICPU.ShiftedDB = 0;
|
||||
SetFlags(MemoryFlag | IndexFlag | IRQ | Emulation);
|
||||
ClearFlags(Decimal);
|
||||
|
||||
CPU.Cycles = 182; // Or 188. This is the cycle count just after the jump to the Reset Vector.
|
||||
CPU.PrevCycles = -1;
|
||||
CPU.V_Counter = 0;
|
||||
CPU.Flags = CPU.Flags & (DEBUG_MODE_FLAG | TRACE_FLAG);
|
||||
CPU.PCBase = NULL;
|
||||
CPU.IRQActive = FALSE;
|
||||
CPU.IRQPending = 0;
|
||||
CPU.MemSpeed = SLOW_ONE_CYCLE;
|
||||
CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2;
|
||||
CPU.FastROMSpeed = SLOW_ONE_CYCLE;
|
||||
CPU.InDMA = FALSE;
|
||||
CPU.InHDMA = FALSE;
|
||||
CPU.InDMAorHDMA = FALSE;
|
||||
CPU.InWRAMDMAorHDMA = FALSE;
|
||||
CPU.HDMARanInDMA = 0;
|
||||
CPU.CurrentDMAorHDMAChannel = -1;
|
||||
CPU.WhichEvent = HC_RENDER_EVENT;
|
||||
CPU.NextEvent = Timings.RenderPos;
|
||||
CPU.WaitingForInterrupt = FALSE;
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
CPU.WaitCounter = 0;
|
||||
CPU.PBPCAtOpcodeStart = 0xffffffff;
|
||||
CPU.AutoSaveTimer = 0;
|
||||
CPU.SRAMModified = FALSE;
|
||||
|
||||
Timings.InterlaceField = FALSE;
|
||||
Timings.H_Max = Timings.H_Max_Master;
|
||||
Timings.V_Max = Timings.V_Max_Master;
|
||||
Timings.NMITriggerPos = 0xffff;
|
||||
if (Model->_5A22 == 2)
|
||||
Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2;
|
||||
else
|
||||
Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v1;
|
||||
|
||||
S9xSetPCBase(Registers.PBPC);
|
||||
|
||||
ICPU.S9xOpcodes = S9xOpcodesE1;
|
||||
ICPU.S9xOpLengths = S9xOpLengthsM1X1;
|
||||
ICPU.CPUExecuting = TRUE;
|
||||
|
||||
S9xUnpackStatus();
|
||||
}
|
||||
|
||||
void S9xReset (void)
|
||||
{
|
||||
S9xResetSaveTimer(FALSE);
|
||||
S9xResetLogger();
|
||||
|
||||
memset(Memory.RAM, 0x55, 0x20000);
|
||||
memset(Memory.VRAM, 0x00, 0x10000);
|
||||
ZeroMemory(Memory.FillRAM, 0x8000);
|
||||
|
||||
if (Settings.BS)
|
||||
S9xResetBSX();
|
||||
|
||||
S9xResetCPU();
|
||||
S9xResetPPU();
|
||||
S9xResetDMA();
|
||||
S9xResetAPU();
|
||||
|
||||
if (Settings.DSP)
|
||||
S9xResetDSP();
|
||||
if (Settings.SuperFX)
|
||||
S9xResetSuperFX();
|
||||
if (Settings.SA1)
|
||||
S9xSA1Init();
|
||||
if (Settings.SDD1)
|
||||
S9xResetSDD1();
|
||||
if (Settings.SPC7110)
|
||||
S9xResetSPC7110();
|
||||
if (Settings.C4)
|
||||
S9xInitC4();
|
||||
if (Settings.OBC1)
|
||||
S9xResetOBC1();
|
||||
if (Settings.SRTC)
|
||||
S9xResetSRTC();
|
||||
|
||||
S9xInitCheatData();
|
||||
}
|
||||
|
||||
void S9xSoftReset (void)
|
||||
{
|
||||
S9xResetSaveTimer(FALSE);
|
||||
|
||||
memset(Memory.VRAM, 0x00, 0x10000);
|
||||
ZeroMemory(Memory.FillRAM, 0x8000);
|
||||
|
||||
if (Settings.BS)
|
||||
S9xResetBSX();
|
||||
|
||||
S9xSoftResetCPU();
|
||||
S9xSoftResetPPU();
|
||||
S9xResetDMA();
|
||||
S9xSoftResetAPU();
|
||||
|
||||
if (Settings.DSP)
|
||||
S9xResetDSP();
|
||||
if (Settings.SuperFX)
|
||||
S9xResetSuperFX();
|
||||
if (Settings.SA1)
|
||||
S9xSA1Init();
|
||||
if (Settings.SDD1)
|
||||
S9xResetSDD1();
|
||||
if (Settings.SPC7110)
|
||||
S9xResetSPC7110();
|
||||
if (Settings.C4)
|
||||
S9xInitC4();
|
||||
if (Settings.OBC1)
|
||||
S9xResetOBC1();
|
||||
if (Settings.SRTC)
|
||||
S9xResetSRTC();
|
||||
|
||||
S9xInitCheatData();
|
||||
}
|
|
@ -0,0 +1,690 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _CPUADDR_H_
|
||||
#define _CPUADDR_H_
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NONE = 0,
|
||||
READ = 1,
|
||||
WRITE = 2,
|
||||
MODIFY = 3,
|
||||
JUMP = 5,
|
||||
JSR = 8
|
||||
} AccessMode;
|
||||
|
||||
static inline uint8 Immediate8Slow (AccessMode a)
|
||||
{
|
||||
uint8 val = S9xGetByte(Registers.PBPC);
|
||||
if (a & READ)
|
||||
OpenBus = val;
|
||||
Registers.PCw++;
|
||||
|
||||
return (val);
|
||||
}
|
||||
|
||||
static inline uint8 Immediate8 (AccessMode a)
|
||||
{
|
||||
uint8 val = CPU.PCBase[Registers.PCw];
|
||||
if (a & READ)
|
||||
OpenBus = val;
|
||||
AddCycles(CPU.MemSpeed);
|
||||
Registers.PCw++;
|
||||
|
||||
return (val);
|
||||
}
|
||||
|
||||
static inline uint16 Immediate16Slow (AccessMode a)
|
||||
{
|
||||
uint16 val = S9xGetWord(Registers.PBPC, WRAP_BANK);
|
||||
if (a & READ)
|
||||
OpenBus = (uint8) (val >> 8);
|
||||
Registers.PCw += 2;
|
||||
|
||||
return (val);
|
||||
}
|
||||
|
||||
static inline uint16 Immediate16 (AccessMode a)
|
||||
{
|
||||
uint16 val = READ_WORD(CPU.PCBase + Registers.PCw);
|
||||
if (a & READ)
|
||||
OpenBus = (uint8) (val >> 8);
|
||||
AddCycles(CPU.MemSpeedx2);
|
||||
Registers.PCw += 2;
|
||||
|
||||
return (val);
|
||||
}
|
||||
|
||||
static inline uint32 RelativeSlow (AccessMode a) // branch $xx
|
||||
{
|
||||
int8 offset = Immediate8Slow(a);
|
||||
|
||||
return ((int16) Registers.PCw + offset) & 0xffff;
|
||||
}
|
||||
|
||||
static inline uint32 Relative (AccessMode a) // branch $xx
|
||||
{
|
||||
int8 offset = Immediate8(a);
|
||||
|
||||
return ((int16) Registers.PCw + offset) & 0xffff;
|
||||
}
|
||||
|
||||
static inline uint32 RelativeLongSlow (AccessMode a) // BRL $xxxx
|
||||
{
|
||||
int16 offset = Immediate16Slow(a);
|
||||
|
||||
return ((int32) Registers.PCw + offset) & 0xffff;
|
||||
}
|
||||
|
||||
static inline uint32 RelativeLong (AccessMode a) // BRL $xxxx
|
||||
{
|
||||
int16 offset = Immediate16(a);
|
||||
|
||||
return ((int32) Registers.PCw + offset) & 0xffff;
|
||||
}
|
||||
|
||||
static inline uint32 AbsoluteIndexedIndirectSlow (AccessMode a) // (a,X)
|
||||
{
|
||||
uint16 addr;
|
||||
|
||||
if (a & JSR)
|
||||
{
|
||||
// JSR (a,X) pushes the old address in the middle of loading the new.
|
||||
// OpenBus needs to be set to account for this.
|
||||
addr = Immediate8Slow(READ);
|
||||
if (a == JSR)
|
||||
OpenBus = Registers.PCl;
|
||||
addr |= Immediate8Slow(READ) << 8;
|
||||
}
|
||||
else
|
||||
addr = Immediate16Slow(READ);
|
||||
|
||||
AddCycles(ONE_CYCLE);
|
||||
addr += Registers.X.W;
|
||||
|
||||
// Address load wraps within the bank
|
||||
uint16 addr2 = S9xGetWord(ICPU.ShiftedPB | addr, WRAP_BANK);
|
||||
OpenBus = addr2 >> 8;
|
||||
|
||||
return (addr2);
|
||||
}
|
||||
|
||||
static inline uint32 AbsoluteIndexedIndirect (AccessMode a) // (a,X)
|
||||
{
|
||||
uint16 addr = Immediate16Slow(READ);
|
||||
addr += Registers.X.W;
|
||||
|
||||
// Address load wraps within the bank
|
||||
uint16 addr2 = S9xGetWord(ICPU.ShiftedPB | addr, WRAP_BANK);
|
||||
OpenBus = addr2 >> 8;
|
||||
|
||||
return (addr2);
|
||||
}
|
||||
|
||||
static inline uint32 AbsoluteIndirectLongSlow (AccessMode a) // [a]
|
||||
{
|
||||
uint16 addr = Immediate16Slow(READ);
|
||||
|
||||
// No info on wrapping, but it doesn't matter anyway due to mirroring
|
||||
uint32 addr2 = S9xGetWord(addr);
|
||||
OpenBus = addr2 >> 8;
|
||||
addr2 |= (OpenBus = S9xGetByte(addr + 2)) << 16;
|
||||
|
||||
return (addr2);
|
||||
}
|
||||
|
||||
static inline uint32 AbsoluteIndirectLong (AccessMode a) // [a]
|
||||
{
|
||||
uint16 addr = Immediate16(READ);
|
||||
|
||||
// No info on wrapping, but it doesn't matter anyway due to mirroring
|
||||
uint32 addr2 = S9xGetWord(addr);
|
||||
OpenBus = addr2 >> 8;
|
||||
addr2 |= (OpenBus = S9xGetByte(addr + 2)) << 16;
|
||||
|
||||
return (addr2);
|
||||
}
|
||||
|
||||
static inline uint32 AbsoluteIndirectSlow (AccessMode a) // (a)
|
||||
{
|
||||
// No info on wrapping, but it doesn't matter anyway due to mirroring
|
||||
uint16 addr2 = S9xGetWord(Immediate16Slow(READ));
|
||||
OpenBus = addr2 >> 8;
|
||||
|
||||
return (addr2);
|
||||
}
|
||||
|
||||
static inline uint32 AbsoluteIndirect (AccessMode a) // (a)
|
||||
{
|
||||
// No info on wrapping, but it doesn't matter anyway due to mirroring
|
||||
uint16 addr2 = S9xGetWord(Immediate16(READ));
|
||||
OpenBus = addr2 >> 8;
|
||||
|
||||
return (addr2);
|
||||
}
|
||||
|
||||
static inline uint32 AbsoluteSlow (AccessMode a) // a
|
||||
{
|
||||
return (ICPU.ShiftedDB | Immediate16Slow(a));
|
||||
}
|
||||
|
||||
static inline uint32 Absolute (AccessMode a) // a
|
||||
{
|
||||
return (ICPU.ShiftedDB | Immediate16(a));
|
||||
}
|
||||
|
||||
static inline uint32 AbsoluteLongSlow (AccessMode a) // l
|
||||
{
|
||||
uint32 addr = Immediate16Slow(READ);
|
||||
|
||||
// JSR l pushes the old bank in the middle of loading the new.
|
||||
// OpenBus needs to be set to account for this.
|
||||
if (a == JSR)
|
||||
OpenBus = Registers.PB;
|
||||
|
||||
addr |= Immediate8Slow(a) << 16;
|
||||
|
||||
return (addr);
|
||||
}
|
||||
|
||||
static inline uint32 AbsoluteLong (AccessMode a) // l
|
||||
{
|
||||
uint32 addr = READ_3WORD(CPU.PCBase + Registers.PCw);
|
||||
AddCycles(CPU.MemSpeedx2 + CPU.MemSpeed);
|
||||
if (a & READ)
|
||||
OpenBus = addr >> 16;
|
||||
Registers.PCw += 3;
|
||||
|
||||
return (addr);
|
||||
}
|
||||
|
||||
static inline uint32 DirectSlow (AccessMode a) // d
|
||||
{
|
||||
uint16 addr = Immediate8Slow(a) + Registers.D.W;
|
||||
if (Registers.DL != 0)
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr);
|
||||
}
|
||||
|
||||
static inline uint32 Direct (AccessMode a) // d
|
||||
{
|
||||
uint16 addr = Immediate8(a) + Registers.D.W;
|
||||
if (Registers.DL != 0)
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndirectSlow (AccessMode a) // (d)
|
||||
{
|
||||
uint32 addr = S9xGetWord(DirectSlow(READ), (!CheckEmulation() || Registers.DL) ? WRAP_BANK : WRAP_PAGE);
|
||||
if (a & READ)
|
||||
OpenBus = (uint8) (addr >> 8);
|
||||
addr |= ICPU.ShiftedDB;
|
||||
|
||||
return (addr);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndirectE0 (AccessMode a) // (d)
|
||||
{
|
||||
uint32 addr = S9xGetWord(Direct(READ));
|
||||
if (a & READ)
|
||||
OpenBus = (uint8) (addr >> 8);
|
||||
addr |= ICPU.ShiftedDB;
|
||||
|
||||
return (addr);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndirectE1 (AccessMode a) // (d)
|
||||
{
|
||||
uint32 addr = S9xGetWord(DirectSlow(READ), Registers.DL ? WRAP_BANK : WRAP_PAGE);
|
||||
if (a & READ)
|
||||
OpenBus = (uint8) (addr >> 8);
|
||||
addr |= ICPU.ShiftedDB;
|
||||
|
||||
return (addr);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndirectIndexedSlow (AccessMode a) // (d),Y
|
||||
{
|
||||
uint32 addr = DirectIndirectSlow(a);
|
||||
if (a & WRITE || !CheckIndex() || (addr & 0xff) + Registers.YL >= 0x100)
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr + Registers.Y.W);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndirectIndexedE0X0 (AccessMode a) // (d),Y
|
||||
{
|
||||
uint32 addr = DirectIndirectE0(a);
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr + Registers.Y.W);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndirectIndexedE0X1 (AccessMode a) // (d),Y
|
||||
{
|
||||
uint32 addr = DirectIndirectE0(a);
|
||||
if (a & WRITE || (addr & 0xff) + Registers.YL >= 0x100)
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr + Registers.Y.W);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndirectIndexedE1 (AccessMode a) // (d),Y
|
||||
{
|
||||
uint32 addr = DirectIndirectE1(a);
|
||||
if (a & WRITE || (addr & 0xff) + Registers.YL >= 0x100)
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr + Registers.Y.W);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndirectLongSlow (AccessMode a) // [d]
|
||||
{
|
||||
uint16 addr = DirectSlow(READ);
|
||||
uint32 addr2 = S9xGetWord(addr);
|
||||
OpenBus = addr2 >> 8;
|
||||
addr2 |= (OpenBus = S9xGetByte(addr + 2)) << 16;
|
||||
|
||||
return (addr2);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndirectLong (AccessMode a) // [d]
|
||||
{
|
||||
uint16 addr = Direct(READ);
|
||||
uint32 addr2 = S9xGetWord(addr);
|
||||
OpenBus = addr2 >> 8;
|
||||
addr2 |= (OpenBus = S9xGetByte(addr + 2)) << 16;
|
||||
|
||||
return (addr2);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndirectIndexedLongSlow (AccessMode a) // [d],Y
|
||||
{
|
||||
return (DirectIndirectLongSlow(a) + Registers.Y.W);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndirectIndexedLong (AccessMode a) // [d],Y
|
||||
{
|
||||
return (DirectIndirectLong(a) + Registers.Y.W);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndexedXSlow (AccessMode a) // d,X
|
||||
{
|
||||
pair addr;
|
||||
addr.W = DirectSlow(a);
|
||||
if (!CheckEmulation() || Registers.DL)
|
||||
addr.W += Registers.X.W;
|
||||
else
|
||||
addr.B.l += Registers.XL;
|
||||
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr.W);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndexedXE0 (AccessMode a) // d,X
|
||||
{
|
||||
uint16 addr = Direct(a) + Registers.X.W;
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndexedXE1 (AccessMode a) // d,X
|
||||
{
|
||||
if (Registers.DL)
|
||||
return (DirectIndexedXE0(a));
|
||||
else
|
||||
{
|
||||
pair addr;
|
||||
addr.W = Direct(a);
|
||||
addr.B.l += Registers.XL;
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr.W);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndexedYSlow (AccessMode a) // d,Y
|
||||
{
|
||||
pair addr;
|
||||
addr.W = DirectSlow(a);
|
||||
if (!CheckEmulation() || Registers.DL)
|
||||
addr.W += Registers.Y.W;
|
||||
else
|
||||
addr.B.l += Registers.YL;
|
||||
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr.W);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndexedYE0 (AccessMode a) // d,Y
|
||||
{
|
||||
uint16 addr = Direct(a) + Registers.Y.W;
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndexedYE1 (AccessMode a) // d,Y
|
||||
{
|
||||
if (Registers.DL)
|
||||
return (DirectIndexedYE0(a));
|
||||
else
|
||||
{
|
||||
pair addr;
|
||||
addr.W = Direct(a);
|
||||
addr.B.l += Registers.YL;
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr.W);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndexedIndirectSlow (AccessMode a) // (d,X)
|
||||
{
|
||||
uint32 addr = S9xGetWord(DirectIndexedXSlow(READ), (!CheckEmulation() || Registers.DL) ? WRAP_BANK : WRAP_PAGE);
|
||||
if (a & READ)
|
||||
OpenBus = (uint8) (addr >> 8);
|
||||
|
||||
return (ICPU.ShiftedDB | addr);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndexedIndirectE0 (AccessMode a) // (d,X)
|
||||
{
|
||||
uint32 addr = S9xGetWord(DirectIndexedXE0(READ));
|
||||
if (a & READ)
|
||||
OpenBus = (uint8) (addr >> 8);
|
||||
|
||||
return (ICPU.ShiftedDB | addr);
|
||||
}
|
||||
|
||||
static inline uint32 DirectIndexedIndirectE1 (AccessMode a) // (d,X)
|
||||
{
|
||||
uint32 addr = S9xGetWord(DirectIndexedXE1(READ), Registers.DL ? WRAP_BANK : WRAP_PAGE);
|
||||
if (a & READ)
|
||||
OpenBus = (uint8) (addr >> 8);
|
||||
|
||||
return (ICPU.ShiftedDB | addr);
|
||||
}
|
||||
|
||||
static inline uint32 AbsoluteIndexedXSlow (AccessMode a) // a,X
|
||||
{
|
||||
uint32 addr = AbsoluteSlow(a);
|
||||
if (a & WRITE || !CheckIndex() || (addr & 0xff) + Registers.XL >= 0x100)
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr + Registers.X.W);
|
||||
}
|
||||
|
||||
static inline uint32 AbsoluteIndexedXX0 (AccessMode a) // a,X
|
||||
{
|
||||
uint32 addr = Absolute(a);
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr + Registers.X.W);
|
||||
}
|
||||
|
||||
static inline uint32 AbsoluteIndexedXX1 (AccessMode a) // a,X
|
||||
{
|
||||
uint32 addr = Absolute(a);
|
||||
if (a & WRITE || (addr & 0xff) + Registers.XL >= 0x100)
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr + Registers.X.W);
|
||||
}
|
||||
|
||||
static inline uint32 AbsoluteIndexedYSlow (AccessMode a) // a,Y
|
||||
{
|
||||
uint32 addr = AbsoluteSlow(a);
|
||||
if (a & WRITE || !CheckIndex() || (addr & 0xff) + Registers.YL >= 0x100)
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr + Registers.Y.W);
|
||||
}
|
||||
|
||||
static inline uint32 AbsoluteIndexedYX0 (AccessMode a) // a,Y
|
||||
{
|
||||
uint32 addr = Absolute(a);
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr + Registers.Y.W);
|
||||
}
|
||||
|
||||
static inline uint32 AbsoluteIndexedYX1 (AccessMode a) // a,Y
|
||||
{
|
||||
uint32 addr = Absolute(a);
|
||||
if (a & WRITE || (addr & 0xff) + Registers.YL >= 0x100)
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr + Registers.Y.W);
|
||||
}
|
||||
|
||||
static inline uint32 AbsoluteLongIndexedXSlow (AccessMode a) // l,X
|
||||
{
|
||||
return (AbsoluteLongSlow(a) + Registers.X.W);
|
||||
}
|
||||
|
||||
static inline uint32 AbsoluteLongIndexedX (AccessMode a) // l,X
|
||||
{
|
||||
return (AbsoluteLong(a) + Registers.X.W);
|
||||
}
|
||||
|
||||
static inline uint32 StackRelativeSlow (AccessMode a) // d,S
|
||||
{
|
||||
uint16 addr = Immediate8Slow(a) + Registers.S.W;
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr);
|
||||
}
|
||||
|
||||
static inline uint32 StackRelative (AccessMode a) // d,S
|
||||
{
|
||||
uint16 addr = Immediate8(a) + Registers.S.W;
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr);
|
||||
}
|
||||
|
||||
static inline uint32 StackRelativeIndirectIndexedSlow (AccessMode a) // (d,S),Y
|
||||
{
|
||||
uint32 addr = S9xGetWord(StackRelativeSlow(READ));
|
||||
if (a & READ)
|
||||
OpenBus = (uint8) (addr >> 8);
|
||||
addr = (addr + Registers.Y.W + ICPU.ShiftedDB) & 0xffffff;
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr);
|
||||
}
|
||||
|
||||
static inline uint32 StackRelativeIndirectIndexed (AccessMode a) // (d,S),Y
|
||||
{
|
||||
uint32 addr = S9xGetWord(StackRelative(READ));
|
||||
if (a & READ)
|
||||
OpenBus = (uint8) (addr >> 8);
|
||||
addr = (addr + Registers.Y.W + ICPU.ShiftedDB) & 0xffffff;
|
||||
AddCycles(ONE_CYCLE);
|
||||
|
||||
return (addr);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,565 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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 "snes9x.h"
|
||||
#include "memmap.h"
|
||||
#include "cpuops.h"
|
||||
#include "dma.h"
|
||||
#include "apu/apu.h"
|
||||
#include "fxemu.h"
|
||||
#include "snapshot.h"
|
||||
#ifdef DEBUGGER
|
||||
#include "debug.h"
|
||||
#include "missing.h"
|
||||
#endif
|
||||
|
||||
|
||||
void S9xMainLoop (void)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (CPU.Flags)
|
||||
{
|
||||
if (CPU.Flags & NMI_FLAG)
|
||||
{
|
||||
if (Timings.NMITriggerPos <= CPU.Cycles)
|
||||
{
|
||||
CPU.Flags &= ~NMI_FLAG;
|
||||
Timings.NMITriggerPos = 0xffff;
|
||||
if (CPU.WaitingForInterrupt)
|
||||
{
|
||||
CPU.WaitingForInterrupt = FALSE;
|
||||
Registers.PCw++;
|
||||
}
|
||||
|
||||
S9xOpcode_NMI();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUGGER
|
||||
if ((CPU.Flags & BREAK_FLAG) && !(CPU.Flags & SINGLE_STEP_FLAG))
|
||||
{
|
||||
for (int Break = 0; Break != 6; Break++)
|
||||
{
|
||||
if (S9xBreakpoint[Break].Enabled &&
|
||||
S9xBreakpoint[Break].Bank == Registers.PB &&
|
||||
S9xBreakpoint[Break].Address == Registers.PCw)
|
||||
{
|
||||
if (S9xBreakpoint[Break].Enabled == 2)
|
||||
S9xBreakpoint[Break].Enabled = TRUE;
|
||||
else
|
||||
CPU.Flags |= DEBUG_MODE_FLAG;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (CPU.Flags & IRQ_FLAG)
|
||||
{
|
||||
if (CPU.IRQPending)
|
||||
// FIXME: In case of IRQ during WRAM refresh
|
||||
CPU.IRQPending--;
|
||||
else
|
||||
{
|
||||
if (CPU.WaitingForInterrupt)
|
||||
{
|
||||
CPU.WaitingForInterrupt = FALSE;
|
||||
Registers.PCw++;
|
||||
}
|
||||
|
||||
if (CPU.IRQActive && !Settings.DisableIRQ)
|
||||
{
|
||||
if (!CheckFlag(IRQ))
|
||||
// in IRQ handler $4211 is supposed to be read, so IRQ_FLAG should be cleared.
|
||||
S9xOpcode_IRQ();
|
||||
}
|
||||
else
|
||||
CPU.Flags &= ~IRQ_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
if (CPU.Flags & SCAN_KEYS_FLAG)
|
||||
break;
|
||||
|
||||
#ifdef DEBUGGER
|
||||
if (CPU.Flags & DEBUG_MODE_FLAG)
|
||||
break;
|
||||
|
||||
if (CPU.Flags & TRACE_FLAG)
|
||||
S9xTrace();
|
||||
|
||||
if (CPU.Flags & SINGLE_STEP_FLAG)
|
||||
{
|
||||
CPU.Flags &= ~SINGLE_STEP_FLAG;
|
||||
CPU.Flags |= DEBUG_MODE_FLAG;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.PBPCAtOpcodeStart = Registers.PBPC;
|
||||
#endif
|
||||
|
||||
register uint8 Op;
|
||||
register struct SOpcodes *Opcodes;
|
||||
|
||||
CPU.PrevCycles = CPU.Cycles;
|
||||
|
||||
if (CPU.PCBase)
|
||||
{
|
||||
Op = CPU.PCBase[Registers.PCw];
|
||||
CPU.Cycles += CPU.MemSpeed;
|
||||
Opcodes = ICPU.S9xOpcodes;
|
||||
}
|
||||
else
|
||||
{
|
||||
Op = S9xGetByte(Registers.PBPC);
|
||||
OpenBus = Op;
|
||||
Opcodes = S9xOpcodesSlow;
|
||||
}
|
||||
|
||||
if ((Registers.PCw & MEMMAP_MASK) + ICPU.S9xOpLengths[Op] >= MEMMAP_BLOCK_SIZE)
|
||||
{
|
||||
uint8 *oldPCBase = CPU.PCBase;
|
||||
|
||||
CPU.PCBase = S9xGetBasePointer(ICPU.ShiftedPB + ((uint16) (Registers.PCw + 4)));
|
||||
if (oldPCBase != CPU.PCBase || (Registers.PCw & ~MEMMAP_MASK) == (0xffff & ~MEMMAP_MASK))
|
||||
Opcodes = S9xOpcodesSlow;
|
||||
}
|
||||
|
||||
Registers.PCw++;
|
||||
(*Opcodes[Op].S9xOpcode)();
|
||||
|
||||
if (SA1.Executing)
|
||||
S9xSA1MainLoop();
|
||||
|
||||
while (CPU.Cycles >= CPU.NextEvent)
|
||||
S9xDoHEventProcessing();
|
||||
}
|
||||
|
||||
S9xPackStatus();
|
||||
|
||||
if (CPU.Flags & SCAN_KEYS_FLAG)
|
||||
{
|
||||
#ifdef DEBUGGER
|
||||
if (!(CPU.Flags & FRAME_ADVANCE_FLAG))
|
||||
#endif
|
||||
S9xSyncSpeed();
|
||||
CPU.Flags &= ~SCAN_KEYS_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
void S9xSetIRQ (uint32 source)
|
||||
{
|
||||
CPU.IRQActive |= source;
|
||||
CPU.IRQPending = Timings.IRQPendCount;
|
||||
CPU.Flags |= IRQ_FLAG;
|
||||
|
||||
if (CPU.WaitingForInterrupt)
|
||||
{
|
||||
// Force IRQ to trigger immediately after WAI -
|
||||
// Final Fantasy Mystic Quest crashes without this.
|
||||
CPU.WaitingForInterrupt = FALSE;
|
||||
Registers.PCw++;
|
||||
}
|
||||
|
||||
#ifdef DEBUGGER
|
||||
S9xTraceMessage("--- /IRQ low");
|
||||
#endif
|
||||
}
|
||||
|
||||
void S9xClearIRQ (uint32 source)
|
||||
{
|
||||
CPU.IRQActive &= ~source;
|
||||
if (!CPU.IRQActive)
|
||||
CPU.Flags &= ~IRQ_FLAG;
|
||||
|
||||
#ifdef DEBUGGER
|
||||
S9xTraceMessage("--- /IRQ high");
|
||||
#endif
|
||||
}
|
||||
|
||||
void S9xDoHEventProcessing (void)
|
||||
{
|
||||
#ifdef DEBUGGER
|
||||
if (Settings.TraceHCEvent)
|
||||
S9xTraceFormattedMessage("--- HC event processing (%02d) expected HC:%04d executed HC:%04d",
|
||||
CPU.WhichEvent, CPU.NextEvent, CPU.Cycles);
|
||||
#endif
|
||||
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitCounter++;
|
||||
#endif
|
||||
|
||||
switch (CPU.WhichEvent)
|
||||
{
|
||||
case HC_HBLANK_START_EVENT:
|
||||
S9xCheckMissingHTimerPosition(Timings.HBlankStart);
|
||||
|
||||
break;
|
||||
|
||||
case HC_HDMA_START_EVENT:
|
||||
if (PPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight)
|
||||
{
|
||||
#ifdef DEBUGGER
|
||||
S9xTraceFormattedMessage("*** HDMA HC:%04d, Channel:%02x", CPU.Cycles, PPU.HDMA);
|
||||
#endif
|
||||
PPU.HDMA = S9xDoHDMA(PPU.HDMA);
|
||||
}
|
||||
|
||||
S9xCheckMissingHTimerPosition(Timings.HDMAStart);
|
||||
|
||||
break;
|
||||
|
||||
case HC_HCOUNTER_MAX_EVENT:
|
||||
#ifndef ZSNES_FX
|
||||
if (Settings.SuperFX)
|
||||
{
|
||||
if (!SuperFX.oneLineDone)
|
||||
S9xSuperFXExec();
|
||||
SuperFX.oneLineDone = FALSE;
|
||||
}
|
||||
#else
|
||||
S9xSuperFXExec();
|
||||
#endif
|
||||
|
||||
S9xAPUEndScanline();
|
||||
CPU.Cycles -= Timings.H_Max;
|
||||
S9xAPUSetReferenceTime(CPU.Cycles);
|
||||
|
||||
if ((Timings.NMITriggerPos != 0xffff) && (Timings.NMITriggerPos >= Timings.H_Max))
|
||||
Timings.NMITriggerPos -= Timings.H_Max;
|
||||
|
||||
CPU.V_Counter++;
|
||||
if (CPU.V_Counter >= Timings.V_Max) // V ranges from 0 to Timings.V_Max - 1
|
||||
{
|
||||
CPU.V_Counter = 0;
|
||||
Timings.InterlaceField ^= 1;
|
||||
|
||||
// From byuu:
|
||||
// [NTSC]
|
||||
// interlace mode has 525 scanlines: 263 on the even frame, and 262 on the odd.
|
||||
// non-interlace mode has 524 scanlines: 262 scanlines on both even and odd frames.
|
||||
// [PAL] <PAL info is unverified on hardware>
|
||||
// interlace mode has 625 scanlines: 313 on the even frame, and 312 on the odd.
|
||||
// non-interlace mode has 624 scanlines: 312 scanlines on both even and odd frames.
|
||||
if (IPPU.Interlace && !Timings.InterlaceField)
|
||||
Timings.V_Max = Timings.V_Max_Master + 1; // 263 (NTSC), 313?(PAL)
|
||||
else
|
||||
Timings.V_Max = Timings.V_Max_Master; // 262 (NTSC), 312?(PAL)
|
||||
|
||||
Memory.FillRAM[0x213F] ^= 0x80;
|
||||
PPU.RangeTimeOver = 0;
|
||||
|
||||
// FIXME: reading $4210 will wait 2 cycles, then perform reading, then wait 4 more cycles.
|
||||
Memory.FillRAM[0x4210] = Model->_5A22;
|
||||
CPU.Flags &= ~NMI_FLAG;
|
||||
Timings.NMITriggerPos = 0xffff;
|
||||
|
||||
ICPU.Frame++;
|
||||
PPU.HVBeamCounterLatched = 0;
|
||||
CPU.Flags |= SCAN_KEYS_FLAG;
|
||||
}
|
||||
|
||||
// From byuu:
|
||||
// In non-interlace mode, there are 341 dots per scanline, and 262 scanlines per frame.
|
||||
// On odd frames, scanline 240 is one dot short.
|
||||
// In interlace mode, there are always 341 dots per scanline. Even frames have 263 scanlines,
|
||||
// and odd frames have 262 scanlines.
|
||||
// Interlace mode scanline 240 on odd frames is not missing a dot.
|
||||
if (CPU.V_Counter == 240 && !IPPU.Interlace && Timings.InterlaceField) // V=240
|
||||
Timings.H_Max = Timings.H_Max_Master - ONE_DOT_CYCLE; // HC=1360
|
||||
else
|
||||
Timings.H_Max = Timings.H_Max_Master; // HC=1364
|
||||
|
||||
if (Model->_5A22 == 2)
|
||||
{
|
||||
if (CPU.V_Counter != 240 || IPPU.Interlace || !Timings.InterlaceField) // V=240
|
||||
{
|
||||
if (Timings.WRAMRefreshPos == SNES_WRAM_REFRESH_HC_v2 - ONE_DOT_CYCLE) // HC=534
|
||||
Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2; // HC=538
|
||||
else
|
||||
Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v2 - ONE_DOT_CYCLE; // HC=534
|
||||
}
|
||||
}
|
||||
else
|
||||
Timings.WRAMRefreshPos = SNES_WRAM_REFRESH_HC_v1;
|
||||
|
||||
S9xCheckMissingHTimerPosition(0);
|
||||
|
||||
if (CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE) // VBlank starts from V=225(240).
|
||||
{
|
||||
S9xEndScreenRefresh();
|
||||
PPU.HDMA = 0;
|
||||
// Bits 7 and 6 of $4212 are computed when read in S9xGetPPU.
|
||||
#ifdef DEBUGGER
|
||||
missing.dma_this_frame = 0;
|
||||
#endif
|
||||
IPPU.MaxBrightness = PPU.Brightness;
|
||||
PPU.ForcedBlanking = (Memory.FillRAM [0x2100] >> 7) & 1;
|
||||
|
||||
if (!PPU.ForcedBlanking)
|
||||
{
|
||||
PPU.OAMAddr = PPU.SavedOAMAddr;
|
||||
|
||||
uint8 tmp = 0;
|
||||
|
||||
if (PPU.OAMPriorityRotation)
|
||||
tmp = (PPU.OAMAddr & 0xFE) >> 1;
|
||||
if ((PPU.OAMFlip & 1) || PPU.FirstSprite != tmp)
|
||||
{
|
||||
PPU.FirstSprite = tmp;
|
||||
IPPU.OBJChanged = TRUE;
|
||||
}
|
||||
|
||||
PPU.OAMFlip = 0;
|
||||
}
|
||||
|
||||
// FIXME: writing to $4210 will wait 6 cycles.
|
||||
Memory.FillRAM[0x4210] = 0x80 | Model->_5A22;
|
||||
if (Memory.FillRAM[0x4200] & 0x80)
|
||||
{
|
||||
// FIXME: triggered at HC=6, checked just before the final CPU cycle,
|
||||
// then, when to call S9xOpcode_NMI()?
|
||||
CPU.Flags |= NMI_FLAG;
|
||||
Timings.NMITriggerPos = 6 + 6;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (CPU.V_Counter == PPU.ScreenHeight + 3) // FIXME: not true
|
||||
{
|
||||
if (Memory.FillRAM[0x4200] & 1)
|
||||
S9xDoAutoJoypad();
|
||||
}
|
||||
|
||||
if (CPU.V_Counter == FIRST_VISIBLE_LINE) // V=1
|
||||
S9xStartScreenRefresh();
|
||||
|
||||
CPU.NextEvent = -1;
|
||||
|
||||
break;
|
||||
|
||||
case HC_HDMA_INIT_EVENT:
|
||||
if (CPU.V_Counter == 0)
|
||||
S9xStartHDMA();
|
||||
|
||||
S9xCheckMissingHTimerPosition(Timings.HDMAInit);
|
||||
|
||||
break;
|
||||
|
||||
case HC_RENDER_EVENT:
|
||||
if (CPU.V_Counter >= FIRST_VISIBLE_LINE && CPU.V_Counter <= PPU.ScreenHeight)
|
||||
RenderLine((uint8) (CPU.V_Counter - FIRST_VISIBLE_LINE));
|
||||
|
||||
S9xCheckMissingHTimerPosition(Timings.RenderPos);
|
||||
|
||||
break;
|
||||
|
||||
case HC_WRAM_REFRESH_EVENT:
|
||||
#ifdef DEBUGGER
|
||||
S9xTraceFormattedMessage("*** WRAM Refresh HC:%04d", CPU.Cycles);
|
||||
#endif
|
||||
S9xCheckMissingHTimerHalt(Timings.WRAMRefreshPos, SNES_WRAM_REFRESH_CYCLES);
|
||||
CPU.Cycles += SNES_WRAM_REFRESH_CYCLES;
|
||||
|
||||
S9xCheckMissingHTimerPosition(Timings.WRAMRefreshPos);
|
||||
|
||||
break;
|
||||
|
||||
case HC_IRQ_1_3_EVENT:
|
||||
case HC_IRQ_3_5_EVENT:
|
||||
case HC_IRQ_5_7_EVENT:
|
||||
case HC_IRQ_7_9_EVENT:
|
||||
case HC_IRQ_9_A_EVENT:
|
||||
case HC_IRQ_A_1_EVENT:
|
||||
if (PPU.HTimerEnabled && (!PPU.VTimerEnabled || (CPU.V_Counter == PPU.VTimerPosition)))
|
||||
S9xSetIRQ(PPU_IRQ_SOURCE);
|
||||
else
|
||||
if (PPU.VTimerEnabled && (CPU.V_Counter == PPU.VTimerPosition))
|
||||
S9xSetIRQ(PPU_IRQ_SOURCE);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
S9xReschedule();
|
||||
|
||||
#ifdef DEBUGGER
|
||||
if (Settings.TraceHCEvent)
|
||||
S9xTraceFormattedMessage("--- HC event rescheduled (%02d) expected HC:%04d", CPU.WhichEvent, CPU.NextEvent);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,353 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _CPUEXEC_H_
|
||||
#define _CPUEXEC_H_
|
||||
|
||||
#include "ppu.h"
|
||||
|
||||
struct SOpcodes
|
||||
{
|
||||
void (*S9xOpcode) (void);
|
||||
};
|
||||
|
||||
struct SICPU
|
||||
{
|
||||
struct SOpcodes *S9xOpcodes;
|
||||
uint8 *S9xOpLengths;
|
||||
uint8 _Carry;
|
||||
uint8 _Zero;
|
||||
uint8 _Negative;
|
||||
uint8 _Overflow;
|
||||
bool8 CPUExecuting;
|
||||
uint32 ShiftedPB;
|
||||
uint32 ShiftedDB;
|
||||
uint32 Frame;
|
||||
uint32 FrameAdvanceCount;
|
||||
};
|
||||
|
||||
extern struct SICPU ICPU;
|
||||
|
||||
extern struct SOpcodes S9xOpcodesE1[256];
|
||||
extern struct SOpcodes S9xOpcodesM1X1[256];
|
||||
extern struct SOpcodes S9xOpcodesM1X0[256];
|
||||
extern struct SOpcodes S9xOpcodesM0X1[256];
|
||||
extern struct SOpcodes S9xOpcodesM0X0[256];
|
||||
extern struct SOpcodes S9xOpcodesSlow[256];
|
||||
extern uint8 S9xOpLengthsM1X1[256];
|
||||
extern uint8 S9xOpLengthsM1X0[256];
|
||||
extern uint8 S9xOpLengthsM0X1[256];
|
||||
extern uint8 S9xOpLengthsM0X0[256];
|
||||
|
||||
void S9xMainLoop (void);
|
||||
void S9xReset (void);
|
||||
void S9xSoftReset (void);
|
||||
void S9xDoHEventProcessing (void);
|
||||
void S9xClearIRQ (uint32);
|
||||
void S9xSetIRQ (uint32);
|
||||
|
||||
static inline void S9xUnpackStatus (void)
|
||||
{
|
||||
ICPU._Zero = (Registers.PL & Zero) == 0;
|
||||
ICPU._Negative = (Registers.PL & Negative);
|
||||
ICPU._Carry = (Registers.PL & Carry);
|
||||
ICPU._Overflow = (Registers.PL & Overflow) >> 6;
|
||||
}
|
||||
|
||||
static inline void S9xPackStatus (void)
|
||||
{
|
||||
Registers.PL &= ~(Zero | Negative | Carry | Overflow);
|
||||
Registers.PL |= ICPU._Carry | ((ICPU._Zero == 0) << 1) | (ICPU._Negative & 0x80) | (ICPU._Overflow << 6);
|
||||
}
|
||||
|
||||
static inline void S9xFixCycles (void)
|
||||
{
|
||||
if (CheckEmulation())
|
||||
{
|
||||
ICPU.S9xOpcodes = S9xOpcodesE1;
|
||||
ICPU.S9xOpLengths = S9xOpLengthsM1X1;
|
||||
}
|
||||
else
|
||||
if (CheckMemory())
|
||||
{
|
||||
if (CheckIndex())
|
||||
{
|
||||
ICPU.S9xOpcodes = S9xOpcodesM1X1;
|
||||
ICPU.S9xOpLengths = S9xOpLengthsM1X1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ICPU.S9xOpcodes = S9xOpcodesM1X0;
|
||||
ICPU.S9xOpLengths = S9xOpLengthsM1X0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CheckIndex())
|
||||
{
|
||||
ICPU.S9xOpcodes = S9xOpcodesM0X1;
|
||||
ICPU.S9xOpLengths = S9xOpLengthsM0X1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ICPU.S9xOpcodes = S9xOpcodesM0X0;
|
||||
ICPU.S9xOpLengths = S9xOpLengthsM0X0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void S9xReschedule (void)
|
||||
{
|
||||
uint8 next = 0;
|
||||
int32 hpos = 0;
|
||||
|
||||
switch (CPU.WhichEvent)
|
||||
{
|
||||
case HC_HBLANK_START_EVENT:
|
||||
case HC_IRQ_1_3_EVENT:
|
||||
next = HC_HDMA_START_EVENT;
|
||||
hpos = Timings.HDMAStart;
|
||||
break;
|
||||
|
||||
case HC_HDMA_START_EVENT:
|
||||
case HC_IRQ_3_5_EVENT:
|
||||
next = HC_HCOUNTER_MAX_EVENT;
|
||||
hpos = Timings.H_Max;
|
||||
break;
|
||||
|
||||
case HC_HCOUNTER_MAX_EVENT:
|
||||
case HC_IRQ_5_7_EVENT:
|
||||
next = HC_HDMA_INIT_EVENT;
|
||||
hpos = Timings.HDMAInit;
|
||||
break;
|
||||
|
||||
case HC_HDMA_INIT_EVENT:
|
||||
case HC_IRQ_7_9_EVENT:
|
||||
next = HC_RENDER_EVENT;
|
||||
hpos = Timings.RenderPos;
|
||||
break;
|
||||
|
||||
case HC_RENDER_EVENT:
|
||||
case HC_IRQ_9_A_EVENT:
|
||||
next = HC_WRAM_REFRESH_EVENT;
|
||||
hpos = Timings.WRAMRefreshPos;
|
||||
break;
|
||||
|
||||
case HC_WRAM_REFRESH_EVENT:
|
||||
case HC_IRQ_A_1_EVENT:
|
||||
next = HC_HBLANK_START_EVENT;
|
||||
hpos = Timings.HBlankStart;
|
||||
break;
|
||||
}
|
||||
|
||||
if (((int32) PPU.HTimerPosition > CPU.NextEvent) && ((int32) PPU.HTimerPosition < hpos))
|
||||
{
|
||||
hpos = (int32) PPU.HTimerPosition;
|
||||
|
||||
switch (next)
|
||||
{
|
||||
case HC_HDMA_START_EVENT:
|
||||
next = HC_IRQ_1_3_EVENT;
|
||||
break;
|
||||
|
||||
case HC_HCOUNTER_MAX_EVENT:
|
||||
next = HC_IRQ_3_5_EVENT;
|
||||
break;
|
||||
|
||||
case HC_HDMA_INIT_EVENT:
|
||||
next = HC_IRQ_5_7_EVENT;
|
||||
break;
|
||||
|
||||
case HC_RENDER_EVENT:
|
||||
next = HC_IRQ_7_9_EVENT;
|
||||
break;
|
||||
|
||||
case HC_WRAM_REFRESH_EVENT:
|
||||
next = HC_IRQ_9_A_EVENT;
|
||||
break;
|
||||
|
||||
case HC_HBLANK_START_EVENT:
|
||||
next = HC_IRQ_A_1_EVENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CPU.NextEvent = hpos;
|
||||
CPU.WhichEvent = next;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,904 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _CPUMACRO_H_
|
||||
#define _CPUMACRO_H_
|
||||
|
||||
#define rOP8(OP, ADDR, WRAP, FUNC) \
|
||||
static void Op##OP (void) \
|
||||
{ \
|
||||
uint8 val = OpenBus = S9xGetByte(ADDR(READ)); \
|
||||
FUNC(val); \
|
||||
}
|
||||
|
||||
#define rOP16(OP, ADDR, WRAP, FUNC) \
|
||||
static void Op##OP (void) \
|
||||
{ \
|
||||
uint16 val = S9xGetWord(ADDR(READ), WRAP); \
|
||||
OpenBus = (uint8) (val >> 8); \
|
||||
FUNC(val); \
|
||||
}
|
||||
|
||||
#define rOPC(OP, COND, ADDR, WRAP, FUNC) \
|
||||
static void Op##OP (void) \
|
||||
{ \
|
||||
if (Check##COND()) \
|
||||
{ \
|
||||
uint8 val = OpenBus = S9xGetByte(ADDR(READ)); \
|
||||
FUNC(val); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
uint16 val = S9xGetWord(ADDR(READ), WRAP); \
|
||||
OpenBus = (uint8) (val >> 8); \
|
||||
FUNC(val); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define rOPM(OP, ADDR, WRAP, FUNC) \
|
||||
rOPC(OP, Memory, ADDR, WRAP, FUNC)
|
||||
|
||||
#define rOPX(OP, ADDR, WRAP, FUNC) \
|
||||
rOPC(OP, Index, ADDR, WRAP, FUNC)
|
||||
|
||||
#define wOP8(OP, ADDR, WRAP, FUNC) \
|
||||
static void Op##OP (void) \
|
||||
{ \
|
||||
FUNC##8(ADDR(WRITE)); \
|
||||
}
|
||||
|
||||
#define wOP16(OP, ADDR, WRAP, FUNC) \
|
||||
static void Op##OP (void) \
|
||||
{ \
|
||||
FUNC##16(ADDR(WRITE), WRAP); \
|
||||
}
|
||||
|
||||
#define wOPC(OP, COND, ADDR, WRAP, FUNC) \
|
||||
static void Op##OP (void) \
|
||||
{ \
|
||||
if (Check##COND()) \
|
||||
FUNC##8(ADDR(WRITE)); \
|
||||
else \
|
||||
FUNC##16(ADDR(WRITE), WRAP); \
|
||||
}
|
||||
|
||||
#define wOPM(OP, ADDR, WRAP, FUNC) \
|
||||
wOPC(OP, Memory, ADDR, WRAP, FUNC)
|
||||
|
||||
#define wOPX(OP, ADDR, WRAP, FUNC) \
|
||||
wOPC(OP, Index, ADDR, WRAP, FUNC)
|
||||
|
||||
#define mOP8(OP, ADDR, WRAP, FUNC) \
|
||||
static void Op##OP (void) \
|
||||
{ \
|
||||
FUNC##8(ADDR(MODIFY)); \
|
||||
}
|
||||
|
||||
#define mOP16(OP, ADDR, WRAP, FUNC) \
|
||||
static void Op##OP (void) \
|
||||
{ \
|
||||
FUNC##16(ADDR(MODIFY), WRAP); \
|
||||
}
|
||||
|
||||
#define mOPC(OP, COND, ADDR, WRAP, FUNC) \
|
||||
static void Op##OP (void) \
|
||||
{ \
|
||||
if (Check##COND()) \
|
||||
FUNC##8(ADDR(MODIFY)); \
|
||||
else \
|
||||
FUNC##16(ADDR(MODIFY), WRAP); \
|
||||
}
|
||||
|
||||
#define mOPM(OP, ADDR, WRAP, FUNC) \
|
||||
mOPC(OP, Memory, ADDR, WRAP, FUNC)
|
||||
|
||||
#define bOP(OP, REL, COND, CHK, E) \
|
||||
static void Op##OP (void) \
|
||||
{ \
|
||||
pair newPC; \
|
||||
newPC.W = REL(JUMP); \
|
||||
if (COND) \
|
||||
{ \
|
||||
AddCycles(ONE_CYCLE); \
|
||||
if (E && Registers.PCh != newPC.B.h) \
|
||||
AddCycles(ONE_CYCLE); \
|
||||
if ((Registers.PCw & ~MEMMAP_MASK) != (newPC.W & ~MEMMAP_MASK)) \
|
||||
S9xSetPCBase(ICPU.ShiftedPB + newPC.W); \
|
||||
else \
|
||||
Registers.PCw = newPC.W; \
|
||||
CPUShutdown(); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
static inline void SetZN (uint16 Work16)
|
||||
{
|
||||
ICPU._Zero = Work16 != 0;
|
||||
ICPU._Negative = (uint8) (Work16 >> 8);
|
||||
}
|
||||
|
||||
static inline void SetZN (uint8 Work8)
|
||||
{
|
||||
ICPU._Zero = Work8;
|
||||
ICPU._Negative = Work8;
|
||||
}
|
||||
|
||||
static inline void ADC (uint16 Work16)
|
||||
{
|
||||
if (CheckDecimal())
|
||||
{
|
||||
uint16 A1 = Registers.A.W & 0x000F;
|
||||
uint16 A2 = Registers.A.W & 0x00F0;
|
||||
uint16 A3 = Registers.A.W & 0x0F00;
|
||||
uint32 A4 = Registers.A.W & 0xF000;
|
||||
uint16 W1 = Work16 & 0x000F;
|
||||
uint16 W2 = Work16 & 0x00F0;
|
||||
uint16 W3 = Work16 & 0x0F00;
|
||||
uint16 W4 = Work16 & 0xF000;
|
||||
|
||||
A1 += W1 + CheckCarry();
|
||||
if (A1 > 0x0009)
|
||||
{
|
||||
A1 -= 0x000A;
|
||||
A1 &= 0x000F;
|
||||
A2 += 0x0010;
|
||||
}
|
||||
|
||||
A2 += W2;
|
||||
if (A2 > 0x0090)
|
||||
{
|
||||
A2 -= 0x00A0;
|
||||
A2 &= 0x00F0;
|
||||
A3 += 0x0100;
|
||||
}
|
||||
|
||||
A3 += W3;
|
||||
if (A3 > 0x0900)
|
||||
{
|
||||
A3 -= 0x0A00;
|
||||
A3 &= 0x0F00;
|
||||
A4 += 0x1000;
|
||||
}
|
||||
|
||||
A4 += W4;
|
||||
if (A4 > 0x9000)
|
||||
{
|
||||
A4 -= 0xA000;
|
||||
A4 &= 0xF000;
|
||||
SetCarry();
|
||||
}
|
||||
else
|
||||
ClearCarry();
|
||||
|
||||
uint16 Ans16 = A4 | A3 | A2 | A1;
|
||||
|
||||
if (~(Registers.A.W ^ Work16) & (Work16 ^ Ans16) & 0x8000)
|
||||
SetOverflow();
|
||||
else
|
||||
ClearOverflow();
|
||||
|
||||
Registers.A.W = Ans16;
|
||||
SetZN(Registers.A.W);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 Ans32 = Registers.A.W + Work16 + CheckCarry();
|
||||
|
||||
ICPU._Carry = Ans32 >= 0x10000;
|
||||
|
||||
if (~(Registers.A.W ^ Work16) & (Work16 ^ (uint16) Ans32) & 0x8000)
|
||||
SetOverflow();
|
||||
else
|
||||
ClearOverflow();
|
||||
|
||||
Registers.A.W = (uint16) Ans32;
|
||||
SetZN(Registers.A.W);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ADC (uint8 Work8)
|
||||
{
|
||||
if (CheckDecimal())
|
||||
{
|
||||
uint8 A1 = Registers.A.W & 0x0F;
|
||||
uint16 A2 = Registers.A.W & 0xF0;
|
||||
uint8 W1 = Work8 & 0x0F;
|
||||
uint8 W2 = Work8 & 0xF0;
|
||||
|
||||
A1 += W1 + CheckCarry();
|
||||
if (A1 > 0x09)
|
||||
{
|
||||
A1 -= 0x0A;
|
||||
A1 &= 0x0F;
|
||||
A2 += 0x10;
|
||||
}
|
||||
|
||||
A2 += W2;
|
||||
if (A2 > 0x90)
|
||||
{
|
||||
A2 -= 0xA0;
|
||||
A2 &= 0xF0;
|
||||
SetCarry();
|
||||
}
|
||||
else
|
||||
ClearCarry();
|
||||
|
||||
uint8 Ans8 = A2 | A1;
|
||||
|
||||
if (~(Registers.AL ^ Work8) & (Work8 ^ Ans8) & 0x80)
|
||||
SetOverflow();
|
||||
else
|
||||
ClearOverflow();
|
||||
|
||||
Registers.AL = Ans8;
|
||||
SetZN(Registers.AL);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16 Ans16 = Registers.AL + Work8 + CheckCarry();
|
||||
|
||||
ICPU._Carry = Ans16 >= 0x100;
|
||||
|
||||
if (~(Registers.AL ^ Work8) & (Work8 ^ (uint8) Ans16) & 0x80)
|
||||
SetOverflow();
|
||||
else
|
||||
ClearOverflow();
|
||||
|
||||
Registers.AL = (uint8) Ans16;
|
||||
SetZN(Registers.AL);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void AND (uint16 Work16)
|
||||
{
|
||||
Registers.A.W &= Work16;
|
||||
SetZN(Registers.A.W);
|
||||
}
|
||||
|
||||
static inline void AND (uint8 Work8)
|
||||
{
|
||||
Registers.AL &= Work8;
|
||||
SetZN(Registers.AL);
|
||||
}
|
||||
|
||||
static inline void ASL16 (uint32 OpAddress, s9xwrap_t w)
|
||||
{
|
||||
uint16 Work16 = S9xGetWord(OpAddress, w);
|
||||
ICPU._Carry = (Work16 & 0x8000) != 0;
|
||||
Work16 <<= 1;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetWord(Work16, OpAddress, w, WRITE_10);
|
||||
OpenBus = Work16 & 0xff;
|
||||
SetZN(Work16);
|
||||
}
|
||||
|
||||
static inline void ASL8 (uint32 OpAddress)
|
||||
{
|
||||
uint8 Work8 = S9xGetByte(OpAddress);
|
||||
ICPU._Carry = (Work8 & 0x80) != 0;
|
||||
Work8 <<= 1;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetByte(Work8, OpAddress);
|
||||
OpenBus = Work8;
|
||||
SetZN(Work8);
|
||||
}
|
||||
|
||||
static inline void BIT (uint16 Work16)
|
||||
{
|
||||
ICPU._Overflow = (Work16 & 0x4000) != 0;
|
||||
ICPU._Negative = (uint8) (Work16 >> 8);
|
||||
ICPU._Zero = (Work16 & Registers.A.W) != 0;
|
||||
}
|
||||
|
||||
static inline void BIT (uint8 Work8)
|
||||
{
|
||||
ICPU._Overflow = (Work8 & 0x40) != 0;
|
||||
ICPU._Negative = Work8;
|
||||
ICPU._Zero = Work8 & Registers.AL;
|
||||
}
|
||||
|
||||
static inline void CMP (uint16 val)
|
||||
{
|
||||
int32 Int32 = (int32) Registers.A.W - (int32) val;
|
||||
ICPU._Carry = Int32 >= 0;
|
||||
SetZN((uint16) Int32);
|
||||
}
|
||||
|
||||
static inline void CMP (uint8 val)
|
||||
{
|
||||
int16 Int16 = (int16) Registers.AL - (int16) val;
|
||||
ICPU._Carry = Int16 >= 0;
|
||||
SetZN((uint8) Int16);
|
||||
}
|
||||
|
||||
static inline void CPX (uint16 val)
|
||||
{
|
||||
int32 Int32 = (int32) Registers.X.W - (int32) val;
|
||||
ICPU._Carry = Int32 >= 0;
|
||||
SetZN((uint16) Int32);
|
||||
}
|
||||
|
||||
static inline void CPX (uint8 val)
|
||||
{
|
||||
int16 Int16 = (int16) Registers.XL - (int16) val;
|
||||
ICPU._Carry = Int16 >= 0;
|
||||
SetZN((uint8) Int16);
|
||||
}
|
||||
|
||||
static inline void CPY (uint16 val)
|
||||
{
|
||||
int32 Int32 = (int32) Registers.Y.W - (int32) val;
|
||||
ICPU._Carry = Int32 >= 0;
|
||||
SetZN((uint16) Int32);
|
||||
}
|
||||
|
||||
static inline void CPY (uint8 val)
|
||||
{
|
||||
int16 Int16 = (int16) Registers.YL - (int16) val;
|
||||
ICPU._Carry = Int16 >= 0;
|
||||
SetZN((uint8) Int16);
|
||||
}
|
||||
|
||||
static inline void DEC16 (uint32 OpAddress, s9xwrap_t w)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
uint16 Work16 = S9xGetWord(OpAddress, w) - 1;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetWord(Work16, OpAddress, w, WRITE_10);
|
||||
OpenBus = Work16 & 0xff;
|
||||
SetZN(Work16);
|
||||
}
|
||||
|
||||
static inline void DEC8 (uint32 OpAddress)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
uint8 Work8 = S9xGetByte(OpAddress) - 1;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetByte(Work8, OpAddress);
|
||||
OpenBus = Work8;
|
||||
SetZN(Work8);
|
||||
}
|
||||
|
||||
static inline void EOR (uint16 val)
|
||||
{
|
||||
Registers.A.W ^= val;
|
||||
SetZN(Registers.A.W);
|
||||
}
|
||||
|
||||
static inline void EOR (uint8 val)
|
||||
{
|
||||
Registers.AL ^= val;
|
||||
SetZN(Registers.AL);
|
||||
}
|
||||
|
||||
static inline void INC16 (uint32 OpAddress, s9xwrap_t w)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
uint16 Work16 = S9xGetWord(OpAddress, w) + 1;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetWord(Work16, OpAddress, w, WRITE_10);
|
||||
OpenBus = Work16 & 0xff;
|
||||
SetZN(Work16);
|
||||
}
|
||||
|
||||
static inline void INC8 (uint32 OpAddress)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
uint8 Work8 = S9xGetByte(OpAddress) + 1;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetByte(Work8, OpAddress);
|
||||
OpenBus = Work8;
|
||||
SetZN(Work8);
|
||||
}
|
||||
|
||||
static inline void LDA (uint16 val)
|
||||
{
|
||||
Registers.A.W = val;
|
||||
SetZN(Registers.A.W);
|
||||
}
|
||||
|
||||
static inline void LDA (uint8 val)
|
||||
{
|
||||
Registers.AL = val;
|
||||
SetZN(Registers.AL);
|
||||
}
|
||||
|
||||
static inline void LDX (uint16 val)
|
||||
{
|
||||
Registers.X.W = val;
|
||||
SetZN(Registers.X.W);
|
||||
}
|
||||
|
||||
static inline void LDX (uint8 val)
|
||||
{
|
||||
Registers.XL = val;
|
||||
SetZN(Registers.XL);
|
||||
}
|
||||
|
||||
static inline void LDY (uint16 val)
|
||||
{
|
||||
Registers.Y.W = val;
|
||||
SetZN(Registers.Y.W);
|
||||
}
|
||||
|
||||
static inline void LDY (uint8 val)
|
||||
{
|
||||
Registers.YL = val;
|
||||
SetZN(Registers.YL);
|
||||
}
|
||||
|
||||
static inline void LSR16 (uint32 OpAddress, s9xwrap_t w)
|
||||
{
|
||||
uint16 Work16 = S9xGetWord(OpAddress, w);
|
||||
ICPU._Carry = Work16 & 1;
|
||||
Work16 >>= 1;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetWord(Work16, OpAddress, w, WRITE_10);
|
||||
OpenBus = Work16 & 0xff;
|
||||
SetZN(Work16);
|
||||
}
|
||||
|
||||
static inline void LSR8 (uint32 OpAddress)
|
||||
{
|
||||
uint8 Work8 = S9xGetByte(OpAddress);
|
||||
ICPU._Carry = Work8 & 1;
|
||||
Work8 >>= 1;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetByte(Work8, OpAddress);
|
||||
OpenBus = Work8;
|
||||
SetZN(Work8);
|
||||
}
|
||||
|
||||
static inline void ORA (uint16 val)
|
||||
{
|
||||
Registers.A.W |= val;
|
||||
SetZN(Registers.A.W);
|
||||
}
|
||||
|
||||
static inline void ORA (uint8 val)
|
||||
{
|
||||
Registers.AL |= val;
|
||||
SetZN(Registers.AL);
|
||||
}
|
||||
|
||||
static inline void ROL16 (uint32 OpAddress, s9xwrap_t w)
|
||||
{
|
||||
uint32 Work32 = (((uint32) S9xGetWord(OpAddress, w)) << 1) | CheckCarry();
|
||||
ICPU._Carry = Work32 >= 0x10000;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetWord((uint16) Work32, OpAddress, w, WRITE_10);
|
||||
OpenBus = Work32 & 0xff;
|
||||
SetZN((uint16) Work32);
|
||||
}
|
||||
|
||||
static inline void ROL8 (uint32 OpAddress)
|
||||
{
|
||||
uint16 Work16 = (((uint16) S9xGetByte(OpAddress)) << 1) | CheckCarry();
|
||||
ICPU._Carry = Work16 >= 0x100;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetByte((uint8) Work16, OpAddress);
|
||||
OpenBus = Work16 & 0xff;
|
||||
SetZN((uint8) Work16);
|
||||
}
|
||||
|
||||
static inline void ROR16 (uint32 OpAddress, s9xwrap_t w)
|
||||
{
|
||||
uint32 Work32 = ((uint32) S9xGetWord(OpAddress, w)) | (((uint32) CheckCarry()) << 16);
|
||||
ICPU._Carry = Work32 & 1;
|
||||
Work32 >>= 1;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetWord((uint16) Work32, OpAddress, w, WRITE_10);
|
||||
OpenBus = Work32 & 0xff;
|
||||
SetZN((uint16) Work32);
|
||||
}
|
||||
|
||||
static inline void ROR8 (uint32 OpAddress)
|
||||
{
|
||||
uint16 Work16 = ((uint16) S9xGetByte(OpAddress)) | (((uint16) CheckCarry()) << 8);
|
||||
ICPU._Carry = Work16 & 1;
|
||||
Work16 >>= 1;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetByte((uint8) Work16, OpAddress);
|
||||
OpenBus = Work16 & 0xff;
|
||||
SetZN((uint8) Work16);
|
||||
}
|
||||
|
||||
static inline void SBC (uint16 Work16)
|
||||
{
|
||||
if (CheckDecimal())
|
||||
{
|
||||
uint16 A1 = Registers.A.W & 0x000F;
|
||||
uint16 A2 = Registers.A.W & 0x00F0;
|
||||
uint16 A3 = Registers.A.W & 0x0F00;
|
||||
uint32 A4 = Registers.A.W & 0xF000;
|
||||
uint16 W1 = Work16 & 0x000F;
|
||||
uint16 W2 = Work16 & 0x00F0;
|
||||
uint16 W3 = Work16 & 0x0F00;
|
||||
uint16 W4 = Work16 & 0xF000;
|
||||
|
||||
A1 -= W1 + !CheckCarry();
|
||||
A2 -= W2;
|
||||
A3 -= W3;
|
||||
A4 -= W4;
|
||||
|
||||
if (A1 > 0x000F)
|
||||
{
|
||||
A1 += 0x000A;
|
||||
A1 &= 0x000F;
|
||||
A2 -= 0x0010;
|
||||
}
|
||||
|
||||
if (A2 > 0x00F0)
|
||||
{
|
||||
A2 += 0x00A0;
|
||||
A2 &= 0x00F0;
|
||||
A3 -= 0x0100;
|
||||
}
|
||||
|
||||
if (A3 > 0x0F00)
|
||||
{
|
||||
A3 += 0x0A00;
|
||||
A3 &= 0x0F00;
|
||||
A4 -= 0x1000;
|
||||
}
|
||||
|
||||
if (A4 > 0xF000)
|
||||
{
|
||||
A4 += 0xA000;
|
||||
A4 &= 0xF000;
|
||||
ClearCarry();
|
||||
}
|
||||
else
|
||||
SetCarry();
|
||||
|
||||
uint16 Ans16 = A4 | A3 | A2 | A1;
|
||||
|
||||
if ((Registers.A.W ^ Work16) & (Registers.A.W ^ Ans16) & 0x8000)
|
||||
SetOverflow();
|
||||
else
|
||||
ClearOverflow();
|
||||
|
||||
Registers.A.W = Ans16;
|
||||
SetZN(Registers.A.W);
|
||||
}
|
||||
else
|
||||
{
|
||||
int32 Int32 = (int32) Registers.A.W - (int32) Work16 + (int32) CheckCarry() - 1;
|
||||
|
||||
ICPU._Carry = Int32 >= 0;
|
||||
|
||||
if ((Registers.A.W ^ Work16) & (Registers.A.W ^ (uint16) Int32) & 0x8000)
|
||||
SetOverflow();
|
||||
else
|
||||
ClearOverflow();
|
||||
|
||||
Registers.A.W = (uint16) Int32;
|
||||
SetZN(Registers.A.W);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SBC (uint8 Work8)
|
||||
{
|
||||
if (CheckDecimal())
|
||||
{
|
||||
uint8 A1 = Registers.A.W & 0x0F;
|
||||
uint16 A2 = Registers.A.W & 0xF0;
|
||||
uint8 W1 = Work8 & 0x0F;
|
||||
uint8 W2 = Work8 & 0xF0;
|
||||
|
||||
A1 -= W1 + !CheckCarry();
|
||||
A2 -= W2;
|
||||
|
||||
if (A1 > 0x0F)
|
||||
{
|
||||
A1 += 0x0A;
|
||||
A1 &= 0x0F;
|
||||
A2 -= 0x10;
|
||||
}
|
||||
|
||||
if (A2 > 0xF0)
|
||||
{
|
||||
A2 += 0xA0;
|
||||
A2 &= 0xF0;
|
||||
ClearCarry();
|
||||
}
|
||||
else
|
||||
SetCarry();
|
||||
|
||||
uint8 Ans8 = A2 | A1;
|
||||
|
||||
if ((Registers.AL ^ Work8) & (Registers.AL ^ Ans8) & 0x80)
|
||||
SetOverflow();
|
||||
else
|
||||
ClearOverflow();
|
||||
|
||||
Registers.AL = Ans8;
|
||||
SetZN(Registers.AL);
|
||||
}
|
||||
else
|
||||
{
|
||||
int16 Int16 = (int16) Registers.AL - (int16) Work8 + (int16) CheckCarry() - 1;
|
||||
|
||||
ICPU._Carry = Int16 >= 0;
|
||||
|
||||
if ((Registers.AL ^ Work8) & (Registers.AL ^ (uint8) Int16) & 0x80)
|
||||
SetOverflow();
|
||||
else
|
||||
ClearOverflow();
|
||||
|
||||
Registers.AL = (uint8) Int16;
|
||||
SetZN(Registers.AL);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void STA16 (uint32 OpAddress, enum s9xwrap_t w)
|
||||
{
|
||||
S9xSetWord(Registers.A.W, OpAddress, w);
|
||||
OpenBus = Registers.AH;
|
||||
}
|
||||
|
||||
static inline void STA8 (uint32 OpAddress)
|
||||
{
|
||||
S9xSetByte(Registers.AL, OpAddress);
|
||||
OpenBus = Registers.AL;
|
||||
}
|
||||
|
||||
static inline void STX16 (uint32 OpAddress, enum s9xwrap_t w)
|
||||
{
|
||||
S9xSetWord(Registers.X.W, OpAddress, w);
|
||||
OpenBus = Registers.XH;
|
||||
}
|
||||
|
||||
static inline void STX8 (uint32 OpAddress)
|
||||
{
|
||||
S9xSetByte(Registers.XL, OpAddress);
|
||||
OpenBus = Registers.XL;
|
||||
}
|
||||
|
||||
static inline void STY16 (uint32 OpAddress, enum s9xwrap_t w)
|
||||
{
|
||||
S9xSetWord(Registers.Y.W, OpAddress, w);
|
||||
OpenBus = Registers.YH;
|
||||
}
|
||||
|
||||
static inline void STY8 (uint32 OpAddress)
|
||||
{
|
||||
S9xSetByte(Registers.YL, OpAddress);
|
||||
OpenBus = Registers.YL;
|
||||
}
|
||||
|
||||
static inline void STZ16 (uint32 OpAddress, enum s9xwrap_t w)
|
||||
{
|
||||
S9xSetWord(0, OpAddress, w);
|
||||
OpenBus = 0;
|
||||
}
|
||||
|
||||
static inline void STZ8 (uint32 OpAddress)
|
||||
{
|
||||
S9xSetByte(0, OpAddress);
|
||||
OpenBus = 0;
|
||||
}
|
||||
|
||||
static inline void TSB16 (uint32 OpAddress, enum s9xwrap_t w)
|
||||
{
|
||||
uint16 Work16 = S9xGetWord(OpAddress, w);
|
||||
ICPU._Zero = (Work16 & Registers.A.W) != 0;
|
||||
Work16 |= Registers.A.W;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetWord(Work16, OpAddress, w, WRITE_10);
|
||||
OpenBus = Work16 & 0xff;
|
||||
}
|
||||
|
||||
static inline void TSB8 (uint32 OpAddress)
|
||||
{
|
||||
uint8 Work8 = S9xGetByte(OpAddress);
|
||||
ICPU._Zero = Work8 & Registers.AL;
|
||||
Work8 |= Registers.AL;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetByte(Work8, OpAddress);
|
||||
OpenBus = Work8;
|
||||
}
|
||||
|
||||
static inline void TRB16 (uint32 OpAddress, enum s9xwrap_t w)
|
||||
{
|
||||
uint16 Work16 = S9xGetWord(OpAddress, w);
|
||||
ICPU._Zero = (Work16 & Registers.A.W) != 0;
|
||||
Work16 &= ~Registers.A.W;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetWord(Work16, OpAddress, w, WRITE_10);
|
||||
OpenBus = Work16 & 0xff;
|
||||
}
|
||||
|
||||
static inline void TRB8 (uint32 OpAddress)
|
||||
{
|
||||
uint8 Work8 = S9xGetByte(OpAddress);
|
||||
ICPU._Zero = Work8 & Registers.AL;
|
||||
Work8 &= ~Registers.AL;
|
||||
AddCycles(ONE_CYCLE);
|
||||
S9xSetByte(Work8, OpAddress);
|
||||
OpenBus = Work8;
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,188 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _CPUOPS_H_
|
||||
#define _CPUOPS_H_
|
||||
|
||||
void S9xOpcode_NMI (void);
|
||||
void S9xOpcode_IRQ (void);
|
||||
|
||||
#define CHECK_FOR_IRQ() \
|
||||
if (CPU.IRQActive && !CheckFlag(IRQ) && !Settings.DisableIRQ) \
|
||||
S9xOpcode_IRQ()
|
||||
|
||||
#endif
|
|
@ -0,0 +1,682 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifdef HAVE_LIBPNG
|
||||
#include <png.h>
|
||||
#endif
|
||||
#include "port.h"
|
||||
#include "crosshairs.h"
|
||||
|
||||
static const char *crosshairs[32] =
|
||||
{
|
||||
"` " // Crosshair 0 (no image)
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" ",
|
||||
|
||||
"` " // Crosshair 1 (the classic small dot)
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" #. "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" ",
|
||||
|
||||
"` " // Crosshair 2 (a standard cross)
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" .#. "
|
||||
" .#. "
|
||||
" ...#... "
|
||||
" ####### "
|
||||
" ...#... "
|
||||
" .#. "
|
||||
" .#. "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" ",
|
||||
|
||||
"` .#. " // Crosshair 3 (a standard cross)
|
||||
" .#. "
|
||||
" .#. "
|
||||
" .#. "
|
||||
" .#. "
|
||||
" .#. "
|
||||
".......#......."
|
||||
"###############"
|
||||
".......#......."
|
||||
" .#. "
|
||||
" .#. "
|
||||
" .#. "
|
||||
" .#. "
|
||||
" .#. "
|
||||
" .#. ",
|
||||
|
||||
"` " // Crosshair 4 (an X)
|
||||
" "
|
||||
" "
|
||||
" . . "
|
||||
" .#. .#. "
|
||||
" .#. .#. "
|
||||
" .#.#. "
|
||||
" .#. "
|
||||
" .#.#. "
|
||||
" .#. .#. "
|
||||
" .#. .#. "
|
||||
" . . "
|
||||
" "
|
||||
" "
|
||||
" ",
|
||||
|
||||
"`. . " // Crosshair 5 (an X)
|
||||
".#. .#."
|
||||
" .#. .#. "
|
||||
" .#. .#. "
|
||||
" .#. .#. "
|
||||
" .#. .#. "
|
||||
" .#.#. "
|
||||
" .#. "
|
||||
" .#.#. "
|
||||
" .#. .#. "
|
||||
" .#. .#. "
|
||||
" .#. .#. "
|
||||
" .#. .#. "
|
||||
".#. .#."
|
||||
" . . ",
|
||||
|
||||
"` " // Crosshair 6 (a combo)
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" #.# "
|
||||
" ...#... "
|
||||
" #.# "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" ",
|
||||
|
||||
"` . " // Crosshair 7 (a combo)
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" #.# "
|
||||
".......#......."
|
||||
" #.# "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" . ",
|
||||
|
||||
"` # " // Crosshair 8 (a diamond cross)
|
||||
" #.# "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
"#......#......#"
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" #.# "
|
||||
" # ",
|
||||
|
||||
"` ### " // Crosshair 9 (a circle cross)
|
||||
" ## . ## "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
"# . #"
|
||||
"#......#......#"
|
||||
"# . #"
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" ## . ## "
|
||||
" ### ",
|
||||
|
||||
"` .#. " // Crosshair 10 (a square cross)
|
||||
" .#. "
|
||||
" .#. "
|
||||
" ....#.... "
|
||||
" .#######. "
|
||||
" .# #. "
|
||||
"....# #...."
|
||||
"##### #####"
|
||||
"....# #...."
|
||||
" .# #. "
|
||||
" .#######. "
|
||||
" ....#.... "
|
||||
" .#. "
|
||||
" .#. "
|
||||
" .#. ",
|
||||
|
||||
"` .#. " // Crosshair 11 (an interrupted cross)
|
||||
" .#. "
|
||||
" .#. "
|
||||
" .#. "
|
||||
" .#. "
|
||||
" "
|
||||
"..... ....."
|
||||
"##### #####"
|
||||
"..... ....."
|
||||
" "
|
||||
" .#. "
|
||||
" .#. "
|
||||
" .#. "
|
||||
" .#. "
|
||||
" .#. ",
|
||||
|
||||
"`. . " // Crosshair 12 (an interrupted X)
|
||||
".#. .#."
|
||||
" .#. .#. "
|
||||
" .#. .#. "
|
||||
" .#. .#. "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" .#. .#. "
|
||||
" .#. .#. "
|
||||
" .#. .#. "
|
||||
".#. .#."
|
||||
" . . ",
|
||||
|
||||
"` . " // Crosshair 13 (an interrupted combo)
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" "
|
||||
" "
|
||||
"..... ....."
|
||||
" "
|
||||
" "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" # . # "
|
||||
" . ",
|
||||
|
||||
"`#### #### " // Crosshair 14
|
||||
"#.... ....#"
|
||||
"#. .#"
|
||||
"#. .#"
|
||||
"#. .#"
|
||||
" # "
|
||||
" # "
|
||||
" ##### "
|
||||
" # "
|
||||
" # "
|
||||
"#. .#"
|
||||
"#. .#"
|
||||
"#. .#"
|
||||
"#.... ....#"
|
||||
" #### #### ",
|
||||
|
||||
"` .# #. " // Crosshair 15
|
||||
" .# #. "
|
||||
" .# #. "
|
||||
"....# #...."
|
||||
"##### #####"
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
"##### #####"
|
||||
"....# #...."
|
||||
" .# #. "
|
||||
" .# #. "
|
||||
" .# #. ",
|
||||
|
||||
"` # " // Crosshair 16
|
||||
" # "
|
||||
" # "
|
||||
" ....#.... "
|
||||
" . # . "
|
||||
" . # . "
|
||||
" . # . "
|
||||
"###############"
|
||||
" . # . "
|
||||
" . # . "
|
||||
" . # . "
|
||||
" ....#.... "
|
||||
" # "
|
||||
" # "
|
||||
" # ",
|
||||
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
|
||||
bool S9xLoadCrosshairFile (int idx, const char *filename)
|
||||
{
|
||||
if (idx < 1 || idx > 31)
|
||||
return (false);
|
||||
|
||||
char *s = (char *) calloc(15 * 15 + 1, sizeof(char));
|
||||
if (s == NULL)
|
||||
{
|
||||
fprintf(stderr, "S9xLoadCrosshairFile: malloc error while reading ");
|
||||
perror(filename);
|
||||
return (false);
|
||||
}
|
||||
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
fprintf(stderr, "S9xLoadCrosshairFile: Couldn't open ");
|
||||
perror(filename);
|
||||
free(s);
|
||||
return (false);
|
||||
}
|
||||
|
||||
size_t l = fread(s, 1, 8, fp);
|
||||
if (l != 8)
|
||||
{
|
||||
fprintf(stderr, "S9xLoadCrosshairFile: File is too short!\n");
|
||||
free(s);
|
||||
fclose(fp);
|
||||
return (false);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBPNG
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
|
||||
if (!png_sig_cmp((png_byte *) s, 0, 8))
|
||||
{
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!png_ptr)
|
||||
{
|
||||
free(s);
|
||||
fclose(fp);
|
||||
return (false);
|
||||
}
|
||||
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr)
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
|
||||
free(s);
|
||||
fclose(fp);
|
||||
return (false);
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, fp);
|
||||
png_set_sig_bytes(png_ptr, 8);
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
png_uint_32 width, height;
|
||||
int bit_depth, color_type;
|
||||
|
||||
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
|
||||
if (color_type != PNG_COLOR_TYPE_PALETTE)
|
||||
{
|
||||
fprintf(stderr, "S9xLoadCrosshairFile: Input PNG is not a palettized image!\n");
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
||||
free(s);
|
||||
fclose(fp);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (bit_depth == 16)
|
||||
png_set_strip_16(png_ptr);
|
||||
|
||||
if (width != 15 || height != 15)
|
||||
{
|
||||
fprintf(stderr, "S9xLoadCrosshairFile: Expecting a 15x15 PNG\n");
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
||||
free(s);
|
||||
fclose(fp);
|
||||
return (false);
|
||||
}
|
||||
|
||||
png_color *pngpal;
|
||||
png_byte *trans;
|
||||
int num_palette = 0, num_trans = 0;
|
||||
int transcol = -1, fgcol = -1, bgcol = -1;
|
||||
|
||||
png_get_PLTE(png_ptr, info_ptr, &pngpal, &num_palette);
|
||||
png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
|
||||
|
||||
if (num_palette != 3 || num_trans != 1)
|
||||
{
|
||||
fprintf(stderr, "S9xLoadCrosshairFile: Expecting a 3-color PNG with 1 trasnparent color\n");
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
||||
free(s);
|
||||
fclose(fp);
|
||||
return (false);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (trans[0] == i)
|
||||
transcol = i;
|
||||
else
|
||||
if (pngpal[i].red == 0 && pngpal[i].green == 0 && pngpal[i].blue == 0)
|
||||
bgcol = i;
|
||||
else
|
||||
if (pngpal[i].red == 255 && pngpal[i].green == 255 && pngpal[i].blue == 255)
|
||||
fgcol = i;
|
||||
}
|
||||
|
||||
if (transcol < 0 || fgcol < 0 || bgcol < 0)
|
||||
{
|
||||
fprintf(stderr, "S9xLoadCrosshairFile: PNG must have 3 colors: white (fg), black (bg), and transparent.\n");
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
||||
free(s);
|
||||
fclose(fp);
|
||||
return (false);
|
||||
}
|
||||
|
||||
png_set_packing(png_ptr);
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
png_byte *row_pointer = new png_byte[png_get_rowbytes(png_ptr, info_ptr)];
|
||||
|
||||
for (int r = 0; r < 15 * 15; r += 15)
|
||||
{
|
||||
png_read_row(png_ptr, row_pointer, NULL);
|
||||
|
||||
for (int i = 0; i < 15; i++)
|
||||
{
|
||||
if (row_pointer[i] == transcol)
|
||||
s[r + i] = ' ';
|
||||
else
|
||||
if (row_pointer[i] == fgcol)
|
||||
s[r + i] = '#';
|
||||
else
|
||||
if (row_pointer[i] == bgcol)
|
||||
s[r + i] = '.';
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "S9xLoadCrosshairFile: WTF? This was supposed to be a 3-color PNG!\n");
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
||||
free(s);
|
||||
fclose(fp);
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s[15 * 15] = 0;
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
l = fread(s + 8, 1, 15 - 8, fp);
|
||||
if (l != 15 - 8)
|
||||
{
|
||||
fprintf(stderr, "S9xLoadCrosshairFile: File is too short!\n");
|
||||
free(s);
|
||||
fclose(fp);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (getc(fp) != '\n')
|
||||
{
|
||||
fprintf(stderr, "S9xLoadCrosshairFile: Invalid file format! (note: PNG support is not available)\n");
|
||||
free(s);
|
||||
fclose(fp);
|
||||
return (false);
|
||||
}
|
||||
|
||||
for (int r = 1; r < 15; r++)
|
||||
{
|
||||
l = fread(s + r * 15, 1, 15, fp);
|
||||
if (l != 15)
|
||||
{
|
||||
fprintf(stderr, "S9xLoadCrosshairFile: File is too short! (note: PNG support is not available)\n");
|
||||
free(s);
|
||||
fclose(fp);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (getc(fp) != '\n')
|
||||
{
|
||||
fprintf(stderr, "S9xLoadCrosshairFile: Invalid file format! (note: PNG support is not available)\n");
|
||||
free(s);
|
||||
fclose(fp);
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 15 * 15; i++)
|
||||
{
|
||||
if (s[i] != ' ' && s[i] != '#' && s[i] != '.')
|
||||
{
|
||||
fprintf(stderr, "S9xLoadCrosshairFile: Invalid file format! (note: PNG support is not available)\n");
|
||||
free(s);
|
||||
fclose(fp);
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (crosshairs[idx] != NULL && crosshairs[idx][0] != '`')
|
||||
free((void *) crosshairs[idx]);
|
||||
crosshairs[idx] = s;
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
const char * S9xGetCrosshair (int idx)
|
||||
{
|
||||
if (idx < 0 || idx > 31)
|
||||
return (NULL);
|
||||
|
||||
return (crosshairs[idx]);
|
||||
}
|
|
@ -0,0 +1,233 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _CROSSHAIRS_H_
|
||||
#define _CROSSHAIRS_H_
|
||||
|
||||
// Read in the specified crosshair file, replacing whatever data might be in that slot.
|
||||
// Available slots are 1-31.
|
||||
// The input file must be a PNG or a text file.
|
||||
// PNG: 15x15 pixels, palettized, with 3 colors (white, black, and transparent).
|
||||
// text: 15 lines of 16 characters (counting the \n), consisting of ' ', '#', or '.'.
|
||||
|
||||
bool S9xLoadCrosshairFile (int idx, const char *filename);
|
||||
|
||||
// Return the specified crosshair. Woo-hoo.
|
||||
// char * to a 225-byte string, with '#' marking foreground, '.' marking background,
|
||||
// and anything else transparent.
|
||||
|
||||
const char * S9xGetCrosshair (int idx);
|
||||
|
||||
// In controls.cpp. Sets the crosshair for the specified device. Defaults are:
|
||||
// cross fgcolor bgcolor
|
||||
// Mouse 1: 1 White Black
|
||||
// Mouse 2: 1 Purple White
|
||||
// Superscope: 2 White Black
|
||||
// Justifier 1: 4 Blue Black
|
||||
// Justifier 2: 4 MagicPink Black
|
||||
//
|
||||
// Available colors are: Trans, Black, 25Grey, 50Grey, 75Grey, White, Red, Orange,
|
||||
// Yellow, Green, Cyan, Sky, Blue, Violet, MagicPink, and Purple.
|
||||
// You may also prefix a 't' (e.g. tBlue) for a 50%-transparent version.
|
||||
// Use idx = -1 or fg/bg = NULL to keep the current setting.
|
||||
|
||||
enum crosscontrols
|
||||
{
|
||||
X_MOUSE1,
|
||||
X_MOUSE2,
|
||||
X_SUPERSCOPE,
|
||||
X_JUSTIFIER1,
|
||||
X_JUSTIFIER2
|
||||
};
|
||||
|
||||
void S9xSetControllerCrosshair (enum crosscontrols ctl, int8 idx, const char *fg, const char *bg);
|
||||
void S9xGetControllerCrosshair (enum crosscontrols ctl, int8 *idx, const char **fg, const char **bg);
|
||||
|
||||
// In gfx.cpp, much like S9xDisplayChar() except it takes the parameters
|
||||
// listed and looks up GFX.Screen.
|
||||
// The 'crosshair' arg is a 15x15 image, with '#' meaning fgcolor,
|
||||
// '.' meaning bgcolor, and anything else meaning transparent.
|
||||
// Color values should be (RGB):
|
||||
// 0 = transparent 4 = 23 23 23 8 = 31 31 0 12 = 0 0 31
|
||||
// 1 = 0 0 0 5 = 31 31 31 9 = 0 31 0 13 = 23 0 31
|
||||
// 2 = 8 8 8 6 = 31 0 0 10 = 0 31 31 14 = 31 0 31
|
||||
// 3 = 16 16 16 7 = 31 16 0 11 = 0 23 31 15 = 31 0 16
|
||||
// 16-31 are 50% transparent versions of 0-15.
|
||||
|
||||
void S9xDrawCrosshair (const char *crosshair, uint8 fgcolor, uint8 bgcolor, int16 x, int16 y);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,200 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifdef DEBUGGER
|
||||
|
||||
#ifndef _DEBUG_H_
|
||||
#define _DEBUG_H_
|
||||
|
||||
struct SBreakPoint
|
||||
{
|
||||
bool8 Enabled;
|
||||
uint8 Bank;
|
||||
uint16 Address;
|
||||
};
|
||||
|
||||
extern struct SBreakPoint S9xBreakpoint[6];
|
||||
|
||||
void S9xDoDebug (void);
|
||||
void S9xTrace (void);
|
||||
void S9xSA1Trace (void);
|
||||
void S9xTraceMessage (const char *);
|
||||
void S9xTraceFormattedMessage (const char *, ...);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,235 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _DISPLAY_H_
|
||||
#define _DISPLAY_H_
|
||||
|
||||
enum s9x_getdirtype
|
||||
{
|
||||
DEFAULT_DIR = 0,
|
||||
HOME_DIR,
|
||||
ROMFILENAME_DIR,
|
||||
ROM_DIR,
|
||||
SRAM_DIR,
|
||||
SNAPSHOT_DIR,
|
||||
SCREENSHOT_DIR,
|
||||
SPC_DIR,
|
||||
CHEAT_DIR,
|
||||
IPS_DIR,
|
||||
BIOS_DIR,
|
||||
LOG_DIR,
|
||||
LAST_DIR
|
||||
};
|
||||
|
||||
void S9xUsage (void);
|
||||
char * S9xParseArgs (char **, int);
|
||||
void S9xLoadConfigFiles (char **, int);
|
||||
void S9xSetInfoString (const char *);
|
||||
|
||||
// Routines the port has to implement even if it doesn't use them
|
||||
|
||||
void S9xPutImage (int, int);
|
||||
void S9xInitDisplay (int, char **);
|
||||
void S9xDeinitDisplay (void);
|
||||
void S9xTextMode (void);
|
||||
void S9xGraphicsMode (void);
|
||||
void S9xSetPalette (void);
|
||||
void S9xToggleSoundChannel (int);
|
||||
bool8 S9xOpenSnapshotFile (const char *, bool8, STREAM *);
|
||||
void S9xCloseSnapshotFile (STREAM);
|
||||
const char * S9xStringInput (const char *);
|
||||
const char * S9xGetDirectory (enum s9x_getdirtype);
|
||||
const char * S9xGetFilename (const char *, enum s9x_getdirtype);
|
||||
const char * S9xGetFilenameInc (const char *, enum s9x_getdirtype);
|
||||
const char * S9xChooseFilename (bool8);
|
||||
const char * S9xBasename (const char *);
|
||||
|
||||
// Routines the port has to implement if it uses command-line
|
||||
|
||||
void S9xExtraUsage (void);
|
||||
void S9xParseArg (char **, int &, int);
|
||||
|
||||
// Routines the port may implement as needed
|
||||
|
||||
void S9xExtraDisplayUsage (void);
|
||||
void S9xParseDisplayArg (char **, int &, int);
|
||||
void S9xSetTitle (const char *);
|
||||
void S9xInitInputDevices (void);
|
||||
void S9xProcessEvents (bool8);
|
||||
const char * S9xSelectFilename (const char *, const char *, const char *, const char *);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,211 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _DMA_H_
|
||||
#define _DMA_H_
|
||||
|
||||
struct SDMA
|
||||
{
|
||||
bool8 ReverseTransfer;
|
||||
bool8 HDMAIndirectAddressing;
|
||||
bool8 UnusedBit43x0;
|
||||
bool8 AAddressFixed;
|
||||
bool8 AAddressDecrement;
|
||||
uint8 TransferMode;
|
||||
uint8 BAddress;
|
||||
uint16 AAddress;
|
||||
uint8 ABank;
|
||||
uint16 DMACount_Or_HDMAIndirectAddress;
|
||||
uint8 IndirectBank;
|
||||
uint16 Address;
|
||||
uint8 Repeat;
|
||||
uint8 LineCount;
|
||||
uint8 UnknownByte;
|
||||
uint8 DoTransfer;
|
||||
};
|
||||
|
||||
#define TransferBytes DMACount_Or_HDMAIndirectAddress
|
||||
#define IndirectAddress DMACount_Or_HDMAIndirectAddress
|
||||
|
||||
extern struct SDMA DMA[8];
|
||||
|
||||
bool8 S9xDoDMA (uint8);
|
||||
void S9xStartHDMA (void);
|
||||
uint8 S9xDoHDMA (uint8);
|
||||
void S9xResetDMA (void);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,68 @@
|
|||
Control input names are completely defined by the individual ports. This
|
||||
document is intended to collect the rules for all ports.
|
||||
|
||||
The various meta-characters in the rules are:
|
||||
# - A number. The range is detemined by the context
|
||||
## - A two-digit number (i.e. with leading zeros)
|
||||
[...] - Something optional
|
||||
(...) - For grouping with |
|
||||
| - "or", choose one of the options.
|
||||
<...> - A named field
|
||||
{...} - A list of possible values. Multiple values may be used, but they
|
||||
must be in the order listed and joined with +-signs.
|
||||
"" - 'ditto', used to indicate the same list as the above line.
|
||||
|
||||
================================================================================
|
||||
Unix
|
||||
================================================================================
|
||||
|
||||
Input names:
|
||||
Jxx:Axis# Axis # on joystick xx. Axis0 may be
|
||||
Up/Down, and Axis1 Left/Right.
|
||||
Jxx:B# Button # on joystick xx.
|
||||
|
||||
Jxx:{M1,M2,M3,M4,M5,M6,M7,M8}+B# Used with the 'JSx Meta#' port
|
||||
Jxx:{M1,M2,M3,M4,M5,M6,M7,M8}+Axis# command.
|
||||
|
||||
Jxx:X+B# Used to 'define' this key for all
|
||||
Jxx:X+Axis# combinations of JS Meta.
|
||||
|
||||
Port-specific Commands:
|
||||
JSx Meta# Used to specify modifier keys (i.e. Shift, Control) to
|
||||
affect the specified joystick. For example, you could
|
||||
map J00:B20 to "JS0 Meta1", then map J00:B0 to "Joypad1
|
||||
A" and J00:M1+B0 to "Joypad1 Turbo A". '#' may range
|
||||
from 1-8.
|
||||
|
||||
Jsx ToggleMeta# Like the above, but toggles the meta-state each time
|
||||
the button is pressed.
|
||||
|
||||
================================================================================
|
||||
Unix/X11
|
||||
================================================================================
|
||||
|
||||
Keyboard Input:
|
||||
|
||||
Note that only one keyboard (K00) is currently supported. If you know how
|
||||
to support multiple keyboards (and can test it!), feel free to fix x11.cpp
|
||||
and delete this note.
|
||||
|
||||
Keyboard modifiers are S=Shift, C=Control, A=Alt, M=Meta. Combine them in
|
||||
order, i.e. all 4 would be "SCAM".
|
||||
|
||||
Kxx:<keyname> Key names are as recognized by XStringToKeysym.
|
||||
Kxx:<mods>+<keyname> Note however that keys are mapped by keycode,
|
||||
so for example on a standard qwerty keyboard
|
||||
"K00:colon" and "K00:semicolon" are identical.
|
||||
|
||||
Pointer Input:
|
||||
|
||||
Note that only one mouse (M00) is currently supported. If you know how to
|
||||
support multiple pointing devices (and can test it!), feel free to fix
|
||||
x11.cpp and delete this note.
|
||||
|
||||
Mxx:Pointer Map the mouse pointer. If someone has a mouse
|
||||
Mxx:Pointer# device with multiple pointers, fix x11.cpp to
|
||||
report that and you can use the second syntax.
|
||||
|
||||
Mxx:B# Mouse buttons.
|
|
@ -0,0 +1,97 @@
|
|||
This lists the available commands, excluding the ones you get back from
|
||||
S9xGetAllSnes9xCommands(). The various meta-characters are:
|
||||
# - A number. The range is detemined by the context
|
||||
## - A two-digit number (i.e. with leading zeros)
|
||||
[...] - Something optional
|
||||
(...) - For grouping with |
|
||||
| - "or", choose one of the options.
|
||||
<...> - A named field
|
||||
{...} - A list of possible values. Multiple values may be used, but they
|
||||
must be in the order listed and joined with +-signs.
|
||||
"" - 'ditto', used to indicate the same list as the above line.
|
||||
|
||||
Speeds are: Var, Slow, Med, and Fast. 'Var' starts slow and speeds up as the
|
||||
button is held.
|
||||
|
||||
Axes are: Left/Right, Right/Left, Up/Down, Down/Up, Y/A, A/Y, X/B, B/X, L/R,
|
||||
and R/L. Negative is listed first (i.e. "Y/A" means negative deflection is
|
||||
towards Y, while "A/Y" means negative deflection is towards A).
|
||||
|
||||
AxisToPointer, ButtonToPointer, and AxisToButtons allow for translating
|
||||
between different input types. There are 8 'pointers' with IDs
|
||||
PseudoPointerBase+0 to PseudoPointerBase+7, and 256 'buttons' with IDs
|
||||
PseudoButtonBase+0 to PseudoButtonBase+255. So for example,
|
||||
"AxisToButtons 0/255 T=50%" would take the axis data, and do
|
||||
S9xReportButton(PseudoButtonBase+0,1) when said axis goes past 50% in the
|
||||
negative direction and S9xReportButton(PseudoButtonBase+255,1) when it goes
|
||||
over 50% deflection in the positive direction. Similarly, it will do
|
||||
S9xReportButton(...,0) when the deflection drops under 50% in either
|
||||
direction. "ButtonToPointer 1u Slow" would move the pointer with ID
|
||||
PseudoPointerBase+0 up one pixel per frame as long as the button is pressed
|
||||
(reporting this change at the end of each frame).
|
||||
|
||||
---------------
|
||||
Button Commands
|
||||
---------------
|
||||
|
||||
Joypad# {Up, Down, Left, Right, A, B, X, Y, L, R, Start, Select}
|
||||
Joypad# Turbo ""
|
||||
Joypad# Sticky ""
|
||||
Joypad# StickyTurbo ""
|
||||
Joypad# ToggleTurbo ""
|
||||
Joypad# ToggleSticky ""
|
||||
Joypad# ToggleStickyTurbo ""
|
||||
|
||||
Mouse# (L|R|LR)
|
||||
|
||||
Superscope AimOffscreen
|
||||
Superscope {Fire, Cursor, ToggleTurbo, Pause}
|
||||
Superscope AimOffscreen ""
|
||||
|
||||
Justifier# AimOffscreen
|
||||
Justifier# {Trigger, Start}
|
||||
Justifier# AimOffscreen ""
|
||||
|
||||
ButtonToPointer #[u|d][l|r] <speed> ; NOTE: "# <speed>" is invalid
|
||||
|
||||
-------------
|
||||
Axis Commands
|
||||
-------------
|
||||
|
||||
Joypad# Axis <axis> T=#% ; T = 0.1 to 100 by tenths
|
||||
AxisToButtons #/# T=#% ; neg then pos, range 0-255, T as above
|
||||
AxisToPointer #(h|v) [-]<speed> ; NOTE: '-' inverts the axis
|
||||
|
||||
----------------
|
||||
Pointer Commands
|
||||
----------------
|
||||
|
||||
Pointer {Mouse1, Mouse2, Superscope, Justifier1, Justifier2}
|
||||
|
||||
------
|
||||
Multis
|
||||
------
|
||||
|
||||
Multis are a type of button command. The basic format of a multi is "{...}",
|
||||
where the '...' consists of 1 or more valid non-multi button command
|
||||
strings. The braces are literal, not metacharacters. Subcommands separated
|
||||
by commas are executed one after the next. Semicolons skip one frame before
|
||||
continuing subcommand execution. Semicolons may be repeated. When the multi
|
||||
button is pressed, each subcommand is 'pressed', and when the multi button
|
||||
is released each subcommand is 'released'.
|
||||
|
||||
There are also press-only multis, defined as "+{...}". These act just like
|
||||
regular multis, with two differences: the multi is only run when you press
|
||||
the button (release isignored), and each subcommand must be prefixed with
|
||||
'+' or '-' to indicate whether the the subcommand should be pressed or
|
||||
released.
|
||||
|
||||
For example: {Joypad1 A,Joypad2 A;Joypad3 A;;;;;QuickSave000}
|
||||
This presses (or releases) A on pads 1 and 2, then waits one frame, then
|
||||
presses A on pad 3, then waits 5 frames, then saves to snapshot 0 (on press
|
||||
only).
|
||||
|
||||
You may access the multi number in the returned s9xcommand_t structure as
|
||||
cmd.button.multi_idx. This may be used to assign the same multi to multiple
|
||||
buttons:
|
||||
MULTI#<num> ; NOTE: that's a literal octothorpe
|
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
|
@ -0,0 +1,504 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
|
@ -0,0 +1,390 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html;charset=iso-8859-1">
|
||||
<meta http-equiv="Content-Style-Type" content="text/css">
|
||||
<meta name="description" content="How to Port Snes9x to a New Platform">
|
||||
<style type="text/css">
|
||||
<!-- ul { list-style-type:none } h2 { margin-top:3em } h3 { margin-top:2em } -->
|
||||
</style>
|
||||
<title>Porting Snes9x</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1 style="text-align:center">How to Port Snes9x to a New Platform</h1>
|
||||
<div style="text-align:right">
|
||||
Version: 1.52<br>
|
||||
(c) Copyright 1998 Gary Henderson
|
||||
</div>
|
||||
<h2>Introduction</h2>
|
||||
<p>
|
||||
This is brief description of the steps to port Snes9x to the new platform. It describes what code you have to write and what functions exist that you can make use of. It also gives some insights as to how Snes9x actually works, although that will be subject of another document yet to be written.
|
||||
</p>
|
||||
<h2>System Requirements</h2>
|
||||
<p>
|
||||
A C++ compiler. For the most part Snes9x really isn't written in C++, it just uses the C++ compiler as a “better C” compiler to get inline functions and so on. GCC is good for compiling Snes9x (<a href="http://gcc.gnu.org/">http://gcc.gnu.org/</a>).
|
||||
</p>
|
||||
<p>
|
||||
A fast CPU. SNES emulation is very compute intensive; two, or sometimes three CPUs to emulate, an 8-channel 16-bit stereo sound digital signal processor with real-time sample decompression, filter and echo effects, two custom graphics processor chips that can produce transparency, scaling, rotation and window effects in 32768 colors, and finally hardware DMA all take their toll on the host CPU.
|
||||
</p>
|
||||
<p>
|
||||
Enough RAM. Snes9x uses 8MB to load SNES ROM images and several MB for emulating sound, graphics, custom chips, and so on.
|
||||
</p>
|
||||
<p>
|
||||
A 16-bit color (two bytes per pixel) or deeper display, at least 512*478 pixels in resolution. Pixel format conversion may be required before you place the rendered SNES screen on to the display.
|
||||
</p>
|
||||
<p>
|
||||
Sound output requires spooling 8-bit or 16-bit, mono or stereo digital sound data to the host sound system. Some ports can use interrupts or callbacks from the sound system to know when more sound data is required, most other ports have to periodically poll the host sound system to see if more data is required; if it is then the sound mixing code is called to fill the sound buffer with SNES sound data, which then can be passed on to the host sound system. Sound data is generated as an array of bytes (<code>uint8</code>) for 8-bit sound or shorts (<code>int16</code>) for 16-bit data. Stereo sound data generates twice as many samples, with each channel's samples interleaved, first left's then right's.
|
||||
</p>
|
||||
<p>
|
||||
For the user to be able to control and play SNES games, some form of input device is required, a joypad or keyboard, for example. The real SNES can have 2 eight-button digital joypads connected to it or 5 joypads when an optional multi-player adaptor is connected, although most games only require a single joypad. Access to all eight buttons and the direction pad, of course, are usually required by most games. Snes9x does emulate the multi-player adaptor hardware, if you were wondering, but its still up to you to provide the emulation of the individual joypads.
|
||||
</p>
|
||||
<p>
|
||||
The real SNES also has a SNES mouse, Super Scope and Justifier (light-gun) available as optional extras. Snes9x can emulate all of these using some form of pointing device, usually the host system's mouse.
|
||||
</p>
|
||||
<p>
|
||||
Some SNES game cartridges contains a small amount of extra RAM and a battery, so ROMs could save a player's progress through a game for games that takes many hours to play from start to finish. Snes9x simulates this S-RAM by saving the contents of the area of memory occupied by the S-RAM into a file then automatically restoring it again the next time the user plays the same game. If the hardware you're porting to doesn't have a storage media available then you could be in trouble.
|
||||
</p>
|
||||
<p>
|
||||
Snes9x also implements freeze-game files which can record the state of the SNES hardware and RAM at a particular point in time and can restore it to that exact state at a later date - the result is that users can save a game at any point, not just at save-game or password points provided by the original game coders. Each freeze file is over 400k in size. To help save disk space, Snes9x can be compiled with zlib (<a href="http://www.zlib.net/">http://www.zlib.net/</a>), which is used to GZIP compress the freeze files, reducing the size to typically below 100k. zlib is also used to load GZIP or ZIP compressed ROM images. Additionally, Snes9x supports JMA archives compressed with NSRT (<a href="http://nsrt.edgeemu.com/">http://nsrt.edgeemu.com/</a>).
|
||||
</p>
|
||||
<h2>Compile-Time Options</h2>
|
||||
<h3><code>DEBUGGER</code></h3>
|
||||
<p>
|
||||
Enables extra code to assist you in debugging SNES ROMs. The debugger has only ever been a quick-hack and user-interface to debugger facilities is virtually non-existent. Most of the debugger information is output via stdout and enabling the debugger slows the whole emulator down slightly. However, the debugger options available are very powerful; you could use it to help get your port working. You probably still want to ship the finished version with the debugger disabled, it will only confuse non-technical users.
|
||||
</p>
|
||||
<h3><code>RIGHTSHIFT_IS_SAR</code></h3>
|
||||
<p>
|
||||
Define this if your compiler uses shift right arithmetic for signed values. For example, GCC and Visual C++ use shift right arithmetic.
|
||||
</p>
|
||||
<h3><code>CPU_SHUTDOWN</code></h3>
|
||||
<p>
|
||||
This is a speed-up hack. When defined and if <code>Settings.ShutdownMaster</code> is <code>true</code>, Snes9x starts watching for when CPU is in a simply loop waiting for a known event to happen - like the end of the current scanline. If Snes9x spots CPU in such a loop, it simply skips the emulation of its instructions until the event happens. It can be a big win with lots of SNES games, but will break a small number of games. In this case, set <code>Settings.ShutdownMaster</code> to <code>false</code> before you load a ROM image. Note that this hack is forcibly disabled in some games. See <code>Memory.ApplyROMFixes</code> function for the list of such games.
|
||||
</p>
|
||||
<h3><code>CORRECT_VRAM_READS</code></h3>
|
||||
<p>
|
||||
You must define this. It allows correct VRAM reads.
|
||||
</p>
|
||||
<h3><code>ZLIB / UNZIP_SUPPORT / JMA_SUPPORT</code></h3>
|
||||
<p>
|
||||
Define these if you want to support GZIP/ZIP/JMA compressed ROM images and GZIP compressed freeze-game files.
|
||||
</p>
|
||||
<h3><code>ZSNES_FX / ZSNES_C4</code></h3>
|
||||
<p>
|
||||
Define these if your CPU is x86 compatible and you're going to use the ZSNES Super FX and C4 assembler codes.
|
||||
</p>
|
||||
<h3><code>USE_OPENGL</code></h3>
|
||||
<p>
|
||||
Define this and set <code>Settings.OpenGLEnable</code> to <code>true</code>, then you'll get the rendered SNES image as one OpenGL texture.
|
||||
</p>
|
||||
<h3>Typical Options Common for Most Platforms</h3>
|
||||
<p><code>
|
||||
ZLIB<br>
|
||||
UNZIP_SUPPORT<br>
|
||||
JMA_SUPPORT<br>
|
||||
CPU_SHUTDOWN<br>
|
||||
RIGHTSHIFT_IS_SAR<br>
|
||||
CORRECT_VRAM_READS
|
||||
</code></p>
|
||||
<h2>Editing port.h</h2>
|
||||
<p>
|
||||
You may need to edit <code>port.h</code> to fit Snes9x to your system.
|
||||
</p>
|
||||
<p>
|
||||
If the byte ordering of your system is least significant byte first, make sure <code>LSB_FIRST</code> is defined, otherwise make sure it's not defined.
|
||||
</p>
|
||||
<p>
|
||||
You'll need to make sure what pixel format your system uses for 16-bit colors (<code>RGB565</code>, <code>RGB555</code>, <code>BGR565</code> or <code>BGR555</code>), and if it's not <code>RGB565</code>, define <code>PIXEL_FORMAT</code> to it so that Snes9x will use it to render the SNES screen. For example, Windows uses <code>RGB565</code>, Mac OS X uses <code>RGB555</code>. If your system supports more than one pixel format, you can define <code>GFX_MULTI_FORMAT</code> and change Snes9x's pixel format dynamically by calling <code>S9xSetRenderPixelFormat</code> function. If your system is 24 or 32-bit only, then don't define anything; instead write a conversion routine that will take a complete rendered 16-bit SNES screen in <code>RGB565</code> format and convert to the format required to be displayed on your system.
|
||||
</p>
|
||||
<p>
|
||||
<code>port.h</code> also typedefs some types; <code>uint8</code> for an unsigned 8-bit quantity, <code>uint16</code> for an unsigned 16-bit quantity, <code>uint32</code> for a 32-bit unsigned quantity and <code>bool8</code> for a <code>true</code>/<code>false</code> type. Signed versions are also typedef'ed.
|
||||
</p>
|
||||
<h2>Controllers Management</h2>
|
||||
<p>
|
||||
Read <code>controls.h</code>, <code>crosshair.h</code>, <code>controls.txt</code> and <code>control-inputs.txt</code> for details. This section is the minimal explanation to get the SNES controls workable.
|
||||
</p>
|
||||
<p>
|
||||
The real SNES allows several different types of devices to be plugged into the game controller ports. The devices Snes9x emulates are a joypad, multi-player adaptor known as the Multi Player 5 or Multi Tap (allowing a further 4 joypads to be plugged in), a 2-button mouse, a light gun known as the Super Scope, and a light gun known as the Justifier.
|
||||
</p>
|
||||
<p>
|
||||
In your initialization code, call <code>S9xUnmapAllControl</code> function.
|
||||
</p>
|
||||
<p>
|
||||
Map any IDs to each SNES controller's buttons and pointers. (ID 249-255 are reserved).
|
||||
</p>
|
||||
<p>
|
||||
Typically, use <code>S9xMapPointer</code> function for the pointer of the SNES mouse, Super Scope and Justifier, <code>S9xMapButton</code> function for other buttons. Set <code>poll</code> to <code>false</code> for the joypad buttons, <code>true</code> for the other buttons and pointers.
|
||||
</p>
|
||||
<p>
|
||||
<code>S9xMapButton(k1P_A_Button, s9xcommand_t cmd = S9xGetCommandT("Joypad1 A"), false);</code>
|
||||
</p>
|
||||
<p>
|
||||
In your main emulation loop, after <code>S9xMainLoop</code> function is called, check your system's keyboard/joypad, and call <code>S9xReportButton</code> function to report the states of the SNES joypad buttons to Snes9x.
|
||||
</p>
|
||||
<p>
|
||||
<code>void MyMainLoop (void)<br>
|
||||
{<br>
|
||||
S9xMainLoop();<br>
|
||||
MyReportButttons();<br>
|
||||
}</code>
|
||||
</p>
|
||||
<p>
|
||||
<code>void MyReportButtons (void)<br>
|
||||
{<br>
|
||||
S9xReportButton(k1P_A_Button, (key_is_pressed ? true : false));<br>
|
||||
}</code>
|
||||
</p>
|
||||
<p>
|
||||
Prepare your <code>S9xPollButton</code> and <code>S9xPollPointer</code> function to reply Snes9x's request for other buttons/cursors states.
|
||||
</p>
|
||||
<p>
|
||||
Call <code>S9xSetController</code> function. It connects each input device to each SNES input port.<br>
|
||||
Here's typical controller settings that is used by the real SNES games:
|
||||
</p>
|
||||
<p>Joypad<br>
|
||||
<code>S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);<br>
|
||||
S9xSetController(1, CTL_JOYPAD, 1, 0, 0, 0);</code>
|
||||
</p>
|
||||
<p>Mouse (port 1)<br>
|
||||
<code>S9xSetController(0, CTL_MOUSE, 0, 0, 0, 0);<br>
|
||||
S9xSetController(1, CTL_JOYPAD, 1, 0, 0, 0);</code>
|
||||
</p>
|
||||
<p>Mouse (port 2)<br>
|
||||
<code>S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);<br>
|
||||
S9xSetController(1, CTL_MOUSE, 1, 0, 0, 0);</code>
|
||||
</p>
|
||||
<p>Super Scope<br>
|
||||
<code>S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);<br>
|
||||
S9xSetController(1, CTL_SUPERSCOPE, 0, 0, 0, 0);</code>
|
||||
</p>
|
||||
<p>Multi Player 5<br>
|
||||
<code>S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);<br>
|
||||
S9xSetController(1, CTL_MP5, 1, 2, 3, 4);</code>
|
||||
</p>
|
||||
<p>Justifier<br>
|
||||
<code>S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);<br>
|
||||
S9xSetController(1, CTL_JUSTIFIER, 0, 0, 0, 0);</code>
|
||||
</p>
|
||||
<p>Justifier (2 players)<br>
|
||||
<code>S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);<br>
|
||||
S9xSetController(1, CTL_JUSTIFIER, 1, 0, 0, 0);</code>
|
||||
</p>
|
||||
<h2>Existing Interface Functions</h2>
|
||||
<h3><code>bool8 Memory.Init (void)</code></h3>
|
||||
<p>
|
||||
Allocates and initializes several major lumps of memory, for example the SNES ROM and RAM arrays, tile cache arrays, etc. Returns <code>false</code> if memory allocation fails.
|
||||
</p>
|
||||
<h3><code>void Memory.Deinit (void)</code></h3>
|
||||
<p>
|
||||
Deallocates the memory allocations made by <code>Memory.Init</code> function.
|
||||
</p>
|
||||
<h3><code>bool8 S9xGraphicsInit (void)</code></h3>
|
||||
<p>
|
||||
Allocates and initializes several lookup tables used to speed up SNES graphics rendering. Call after you have initialized the <code>GFX.Screen</code> and <code>GFX.Pitch</code> values. Returns <code>false</code> if memory allocation fails.
|
||||
</p>
|
||||
<h3><code>void S9xGraphicsDeinit (void)</code></h3>
|
||||
<p>
|
||||
Deallocates the memory allocations made by <code>S9xGraphicsInit</code> function.
|
||||
</p>
|
||||
<h3><code>bool8 S9xInitAPU (void)</code></h3>
|
||||
<p>
|
||||
Allocates and initializes several arrays used by the sound CPU and sound generation code. Returns <code>false</code> if memory allocation fails.
|
||||
</p>
|
||||
<h3><code>void S9xDeinitAPU (void)</code></h3>
|
||||
<p>
|
||||
Deallocates the allocations made by <code>S9xInitAPU</code> function.
|
||||
</p>
|
||||
<h3><code>bool8 S9xInitSound (int buffer_ms, int lag_ms)</code></h3>
|
||||
<p>
|
||||
Allocates memory for mixing and queueing SNES sound data, does more sound code initialization and opens the host system's sound device by calling <code>S9xOpenSoundDevice</code>, a function you must provide. Before calling this function you must set up <code>Settings.SoundSync</code>, <code>Settings.SixteenBitSound</code>, <code>Settings.SoundPlaybackRate</code>, <code>Settings.SoundInputRate</code> (see section below) and <code>Settings.Stereo</code>.<br>
|
||||
<code>buffer_ms</code>, given in milliseconds, is the memory buffer size for queueing sound data. <code>lag_ms</code> is allowable latency between when a sample is queued and when it is pulled in <code>S9xMixSamples</code>. Set <code>lag_ms</code> to zero if you have your own latency handling code in your port.
|
||||
</p>
|
||||
<h3><code>void S9xReset (void)</code></h3>
|
||||
<p>
|
||||
Resets the SNES emulated hardware back to the state it was in at “switch-on” except the S-RAM area is preserved (“hardware reset”). The effect is it resets the current game back to the start. This function is automatically called by <code>Memory.LoadROM</code> function.
|
||||
</p>
|
||||
<h3><code>void S9xSoftReset (void)</code></h3>
|
||||
<p>
|
||||
Similar to <code>S9xReset</code> function, but “software reset” as you press the SNES reset button.
|
||||
</p>
|
||||
<h3><code>bool8 Memory.LoadROM (const char *filepath)</code></h3>
|
||||
<p>
|
||||
Attempts to load the specified ROM image filename into the emulated ROM area. There are many different SNES ROM image formats and the code attempts to auto-detect as many different types as it can and in a vast majority of the cases gets it right.<br>
|
||||
There are several ROM image options in the <code>Settings</code>structure; allow the user to set them before calling <code>Memory.LoadROM</code> function, or make sure they are all reset to default values before each call to <code>Memory.LoadROM</code> function. See <code>Settings.ForceXXX</code> in <code>snes9x.h</code>.
|
||||
</p>
|
||||
<h3><code>bool8 Memory.LoadMultiCart (const char *cartApath, const char *cartBpath)</code></h3>
|
||||
<p>
|
||||
Attempts to load multiple ROM images into the emulated ROM area, for the multiple cartridge systems such as Sufami Turbo, Same Game, etc.
|
||||
</p>
|
||||
<h3><code>bool8 Memory.LoadSRAM (const char *filepath)</code></h3>
|
||||
<p>
|
||||
Call this function to load the associated S-RAM save file (if any). The filename should be based on the ROM image name to allow easy linkage. The current ports change the directory and the filename extension of the ROM filename to derive the S-RAM filename.
|
||||
</p>
|
||||
<h3><code>bool8 Memory.SaveSRAM (const char *filepath)</code></h3>
|
||||
<p>
|
||||
Call this function to save the emulated S-RAM area into a file so it can be restored again the next time the user wants to play the game. Remember to call this when just before the emulator exits or when the user has been playing a game and is about to load another one.
|
||||
</p>
|
||||
<h3><code>void S9xMainLoop (void)</code></h3>
|
||||
<p>
|
||||
The emulator main loop. Call this from your own main loop that calls this function (if a ROM image is loaded and the game is not paused), processes any pending host system events, then goes back around the loop again until the emulator exits. <code>S9xMainLoop</code> function normally returns control to your main loop once every emulated frame, when it reaches the start of scan-line zero. However it may take a few frames when a huge memory transfer is being emulated. The function can return more often if the <code>DEBUGGER</code> compile-time flag is defined and the CPU has hit a break point, or the <code>DEBUG_MODE_FLAG</code> bit is set in <code>CPU.Flags</code> or instruction single-stepping is enabled.
|
||||
</p>
|
||||
<h3><code>void S9xMixSamples (uint8 *buffer, int sample_count)</code></h3>
|
||||
<p>
|
||||
Call this function from your host sound system handling code to fill <code>buffer</code> with ready-mixed SNES sound data. If 16-bit sound mode is chosen, then the buffer will be filled with an array of <code>sample_count</code> <code>int16</code>, otherwise an array of <code>sample_count</code> <code>uint8</code>. If stereo sound generation is selected the buffer is filled with the same number of samples, but in pairs, first a left channel sample followed by the right channel sample.<br>
|
||||
If there are less queued samples than you request by <code>sample_count</code>, the function fills <code>buffer</code> with silent sound data and returns <code>false</code>. To avoid this shortage of queued samples, request larger buffer size when calling <code>S9xInitSound</code>, and handle sound latency safely.
|
||||
</p>
|
||||
<h3><code>int S9xGetSampleCount (void)</code></h3>
|
||||
<p>
|
||||
Returns the number of sound samples available in the buffer for your configured playback settings.
|
||||
</p>
|
||||
<h3><code>void S9xSetSamplesAvailableCallback (void (*) samples_available (void *), void *data)</code></h3>
|
||||
<p>
|
||||
Call this function to set up a callback that is run when sound samples are made available. <code>samples_available</code> is a function you provide that returns <code>void</code> and takes a pointer as an argument. <code>data</code> is a pointer that you may wish to pass to your callback or can be <code>NULL</code>. If you choose to provide a callback, you must call the provided <code>S9xFinalizeSamples</code> function inside it to actually buffer the samples. If you are using a callback-oriented sound API, it is recommended to set up a function that locks a common mutex during the calls to <code>S9xFinalizeSamples</code> and <code>S9xMixSamples</code> to prevent them from running at the same time and corrupting the sound buffer.<br>
|
||||
If you wish to disable a callback you have set up or need to temporarily shut down your sound system, you may pass <code>NULL</code> for both arguments to revert to the built-in version.
|
||||
</p>
|
||||
<h3><code>bool8 S9xSyncSound (void)</code></h3>
|
||||
<p>
|
||||
Call this function to synchronize the sound buffers to the game state. If Snes9x is generating too much sound data, or a buffer-overrun is likely, this function will return <code>false</code>. In this case, you may wish to wait until your host sound system uses the available samples, and <code>S9xSyncSound</code> returns <code>true</code> before continuing to execute <code>S9xMainLoop</code>.
|
||||
</p>
|
||||
<h3><code>bool8 S9xSetSoundMute (bool8 mute)</code></h3>
|
||||
<p>
|
||||
Call with a <code>true</code> parameter to prevent <code>S9xMixSamples</code> function from processing SNES sample data and instead just filling the return buffer with silent sound data. Useful if your sound system is interrupt or callback driven and the game has been paused either directly or indirectly because the user interacting with the emulator's user interface in some way.
|
||||
</p>
|
||||
<h3><code>bool8 S9xFreezeGame (const char *filepath)</code></h3>
|
||||
<p>
|
||||
Call this function to record the current SNES hardware state into a file, the file can be loaded back using <code>S9xUnfreezeGame</code> function at a later date effectively restoring the current game to exact same spot. Call this function while you're processing any pending system events when <code>S9xMainLoop</code> function has returned control to you in your main loop.
|
||||
</p>
|
||||
<h3><code>bool8 S9xUnfreezeGame (const char *filepath)</code></h3>
|
||||
<p>
|
||||
Restore the SNES hardware back to the exactly the state it was in when <code>S9xFreezeGame</code> function was used to generate the file specified. You have to arrange the correct ROM is already loaded using <code>Memory.LoadROM</code> function, an easy way to arrange this is to base freeze-game filenames on the ROM image name. The UNIX/Linux ports load freeze-game files when the user presses a function key, with the names romfilename.000 for F1, romfilename.001 for F2, etc. Games are frozen in the first place when the user presses Shift-function key. You could choose some other scheme.
|
||||
</p>
|
||||
<h3><code>void S9xDumpSPCSnapshot (void)</code></h3>
|
||||
<p>
|
||||
Call this funtion to make a so-called SPC file, a snapshot of SNES sound state. Actual dump occurs at the first key-on event after this function is called.
|
||||
</p>
|
||||
<h3><code>void S9xSetInfoString (const char *string)</code></h3>
|
||||
<p>
|
||||
Call this function if you want to show a message onto the SNES screen.
|
||||
</p>
|
||||
<h3>Other Available Functions</h3>
|
||||
<p>
|
||||
See <code>movie.h</code> and <code>movie.cpp</code> to support the Snes9x movie feature.<br>
|
||||
See <code>cheats.h</code>, <code>cheats.cpp</code> and <code>cheats2.cpp</code> to support the cheat feature.
|
||||
</p>
|
||||
<h2>Interface Functions You Need to Implement</h2>
|
||||
<h3><code>bool8 S9xOpenSnapshotFile (const char *filepath, bool8 read_only, STREAM *file)</code></h3>
|
||||
<p>
|
||||
This function opens a freeze-game file. <code>STREAM</code> is defined as a <code>gzFile</code> if <code>ZLIB</code> is defined else it's defined as <code>FILE *</code>. The <code>read_only</code> parameter is set to <code>true</code> when reading a freeze-game file and <code>false</code> when writing a freeze-game file. Open the file <code>filepath</code> and return its pointer <code>file</code>.
|
||||
</p>
|
||||
<h3><code>void S9xCloseSnapshotFile (STREAM file)</code></h3>
|
||||
<p>
|
||||
This function closes the freeze-game file opened by <code>S9xOpenSnapshotFile</code> function.
|
||||
</p>
|
||||
<h3><code>void S9xExit (void)</code></h3>
|
||||
<p>
|
||||
Called when some fatal error situation arises or when the “q” debugger command is used.
|
||||
</p>
|
||||
<h3><code>bool8 S9xInitUpdate (void)</code></h3>
|
||||
<p>
|
||||
Called just before Snes9x begins to render an SNES screen. Use this function if you should prepare before drawing, otherwise let it empty.
|
||||
</p>
|
||||
<h3><code>bool8 S9xDeinitUpdate (int width, int height)</code></h3>
|
||||
<p>
|
||||
Called once a complete SNES screen has been rendered into the <code>GFX.Screen</code> memory buffer, now is your chance to copy the SNES rendered screen to the host computer's screen memory. The problem is that you have to cope with different sized SNES rendered screens: 256*224, 256*239, 512*224, 512*239, 512*448 and 512*478.
|
||||
</p>
|
||||
|
||||
<h3><code>bool8 S9xContinueUpdate (int width, int height)</code></h3>
|
||||
<p>
|
||||
Similar to <code>S9xDeinitUpdate</code>, but in interlace mode (512*448 or 512*478) only. Called once an even frame has been rendered into the <code>GFX.Screen</code> memory buffer.
|
||||
</p>
|
||||
<h3><code>void S9xMessage (int type, int number, const char *message)</code></h3>
|
||||
<p>
|
||||
When Snes9x wants to display an error, information or warning message, it calls this function. Check in <code>messages.h</code> for the types and individual message numbers that Snes9x currently passes as parameters.<br>
|
||||
The idea is display the message string so the user can see it, but you choose not to display anything at all, or change the message based on the message number or message type.<br>
|
||||
Eventually all debug output will also go via this function, trace information already does.
|
||||
</p>
|
||||
<h3><code>bool8 S9xOpenSoundDevice (void)</code></h3>
|
||||
<p>
|
||||
<code>S9xInitSound</code> function calls this function to actually open the host sound device.
|
||||
</p>
|
||||
<h3><code>const char *S9xGetFilename (const char *extension, enum s9x_getdirtype dirtype)</code></h3>
|
||||
<p>
|
||||
When Snes9x needs to know the name of the cheat/IPS file and so on, this function is called. Check <code>extension</code> and <code>dirtype</code>, and return the appropriate filename. The current ports return the ROM file path with the given extension.
|
||||
</p>
|
||||
<h3><code>const char *S9xGetFilenameInc (const char *extension, enum s9x_getdirtype dirtype)</code></h3>
|
||||
<p>
|
||||
Almost the same as <code>S9xGetFilename</code> function, but used for saving SPC files etc. So you have to take care not to delete the previously saved file, by increasing the number of the filename; romname.000.spc, romname.001.spc, ...
|
||||
</p>
|
||||
<h3><code>const char *S9xGetDirectory (enum s9x_getdirtype dirtype)</code></h3>
|
||||
<p>
|
||||
Called when Snes9x wants to know the directory <code>dirtype</code>.
|
||||
</p>
|
||||
<h3><code>const char *S9xChooseFilename (bool8 read_only)</code></h3>
|
||||
<p>
|
||||
If your port can match Snes9x's built-in <code>LoadFreezeFile</code>/<code>SaveFreezeFile</code> command (see <code>controls.cpp</code>), you may choose to use this function. Otherwise return <code>NULL</code>.
|
||||
</p>
|
||||
<h3><code>const char *S9xChooseMovieFilename (bool8 read_only)</code></h3>
|
||||
<p>
|
||||
If your port can match Snes9x's built-in <code>BeginRecordingMovie</code>/<code>LoadMovie</code> command (see <code>controls.cpp</code>), you may choose to use this function. Otherwise return <code>NULL</code>.
|
||||
</p>
|
||||
<h3><code>const char *S9xBasename (const char *path)</code></h3>
|
||||
<p>
|
||||
Called when Snes9x wants to know the name of the ROM image. Typically, extract the filename from <code>path</code> and return it.
|
||||
</p>
|
||||
<h3><code>void S9xAutoSaveSRAM (void)</code></h3>
|
||||
<p>
|
||||
If <code>Settings.AutoSaveDelay</code> is not zero, Snes9x calls this function when the contents of the S-RAM has been changed. Typically, call <code>Memory.SaveSRAM</code> function from this function.
|
||||
</p>
|
||||
<h3><code>void S9xToggleSoundChannel (int c)</code></h3>
|
||||
<p>
|
||||
If your port can match Snes9x's built-in <code>SoundChannelXXX</code> command (see <code>controls.cpp</code>), you may choose to use this function. Otherwise return <code>NULL</code>. Basically, turn on/off the sound channel <code>c</code> (0-7), and turn on all channels if <code>c</code> is 8.
|
||||
</p>
|
||||
<h3><code>void S9xSetPalette (void)</code></h3>
|
||||
<p>
|
||||
Called when the SNES color palette has changed. Use this function if your system should change its color palette to match the SNES's. Otherwise let it empty.
|
||||
</p>
|
||||
<h3><code>void S9xSyncSpeed (void)</code></h3>
|
||||
<p>
|
||||
Called at the end of <code>S9xMainLoop</code> function, when emulating one frame has been done. You should adjust the frame rate in this function.
|
||||
</p>
|
||||
<h2>Global Variables</h2>
|
||||
<h3><code>uint16 *GFX.Screen</code></h3>
|
||||
<p>
|
||||
A <code>uint16</code> array pointer to (at least) 2*512*478 bytes buffer where Snes9x puts the rendered SNES screen. However, if your port will not support hires mode (<code>Settings.SupportHiRes = false</code>), then a 2*256*239 bytes buffer is allowed. You should allocate the space by yourself. As well you can change the <code>GFX.Screen</code> value after <code>S9xDeinitUpdate</code> function is called so that double-buffering will be easy.
|
||||
</p>
|
||||
<h3><code>uint32 GFX.Pitch</code></h3>
|
||||
<p>
|
||||
Bytes per line (not pixels per line) of the <code>GFX.Screen</code> buffer. Typically set it to 1024. When the SNES screen is 256 pixels width and <code>Settings.OpenGLEnable</code> is <code>false</code>, last half 512 bytes per line are unused. When <code>Settings.OpenGLEnable</code> is <code>true</code>, <code>GFX.Pitch</code> is ignored.
|
||||
</p>
|
||||
<h3>Settings structure</h3>
|
||||
<p>
|
||||
There are various switches in the <code>Settings</code> structure. See <code>snes9x.h</code> for details. At least the settings below are required for good emulation.
|
||||
</p>
|
||||
<p><code>
|
||||
memset(&Settings, 0, sizeof(Settings));<br>
|
||||
Settings.MouseMaster = true;<br>
|
||||
Settings.SuperScopeMaster = true;<br>
|
||||
Settings.JustifierMaster = true;<br>
|
||||
Settings.MultiPlayer5Master = true;<br>
|
||||
Settings.FrameTimePAL = 20000;<br>
|
||||
Settings.FrameTimeNTSC = 16667;<br>
|
||||
Settings.SixteenBitSound = true;<br>
|
||||
Settings.Stereo = true;<br>
|
||||
Settings.SoundPlaybackRate = 32000;<br>
|
||||
Settings.SoundInputRate = 32000;<br>
|
||||
Settings.SupportHiRes = true;<br>
|
||||
Settings.Transparency = true;<br>
|
||||
Settings.AutoDisplayMessages = true;<br>
|
||||
Settings.InitialInfoStringTimeout = 120;<br>
|
||||
Settings.HDMATimingHack = 100;<br>
|
||||
Settings.BlockInvalidVRAMAccessMaster = true;
|
||||
</code></p>
|
||||
<h3><code>Settings.SoundInputRate</code></h3>
|
||||
<p>
|
||||
Adjusts the sound rate through resampling. For every <code>Settings.SoundInputRate</code> samples generated by the SNES, <code>Settings.SoundPlaybackRate</code> samples will be produced.<br>
|
||||
The sound generation rate on a SNES is directly proportional to the video output rate. Displays that synchronize with the vertical refresh but have a slightly lower refresh-rate than the emulated system can experience sound drop-outs. It may be beneficial to provide an option for users to configure <code>Settings.SoundInputRate</code> to suit their own systems. Setting <code>Settings.SoundInputRate</code> to a value that matches the actual output rate (i.e. 31977hz for 59.96hz) or lower will allow the users to eliminate crackling. A range of 31000hz to 33000hz should be inclusive enough for all displays. Use of this setting paired with the <code>S9xSyncSound</code> function can eliminate sound discontinuity.
|
||||
</p>
|
||||
<div style="text-align:right; margin-top:3em">
|
||||
Updated most recently by: 2010/01/09 zones
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,84 @@
|
|||
***** Important notice ********************************************************
|
||||
This document describes the snapshot file format for Snes9x 1.52 and later,
|
||||
not compatible with 1.51.
|
||||
*******************************************************************************
|
||||
|
||||
Snes9x snapshot file format: (may be gzip-compressed)
|
||||
|
||||
Begins with fixed length signature, consisting of a string, ':', a 4-digit
|
||||
decimal version, and a '\n'.
|
||||
|
||||
#!s9xsnp:0006 <-- '\n' after the 6
|
||||
|
||||
Then we have various blocks. The block format is: 3-character block name,
|
||||
':', 6-digit length, ':', then the data. Blocks are written in a defined
|
||||
order. Structs are written packed with their members in a defined order, in
|
||||
big-endian order where applicable.
|
||||
|
||||
NAM:000019:Chrono Trigger.zip
|
||||
|
||||
Currently defined blocks (in order) are:
|
||||
|
||||
Essential parts:
|
||||
NAM - ROM filename, from Memory.ROMFilename. 0-terminated string.
|
||||
CPU - struct SCPUState, CPU internal state variables.
|
||||
REG - struct SRegisters, emulated CPU registers.
|
||||
PPU - struct SPPU, PPU internal variables. Note that IPPU is never saved.
|
||||
DMA - struct SDMA, DMA/HDMA state variables.
|
||||
VRA - Memory.VRAM, 0x10000 bytes.
|
||||
RAM - Memory.RAM, 0x20000 bytes (WRAM).
|
||||
SRA - Memory.SRAM, 0x20000 bytes.
|
||||
FIL - Memory.FillRAM, 0x8000 bytes (register backing store).
|
||||
SND - All of sound emulated registers and state valiables.
|
||||
CTL - struct SControlSnapshot, controller emulation.
|
||||
TIM - struct STimings, variables about timings between emulated events.
|
||||
|
||||
Optional parts:
|
||||
SFX - struct FxRegs_s, Super FX.
|
||||
SA1 - struct SSA1, SA1 internal state variables.
|
||||
SAR - struct SSA1Registers, SA1 emulated registers.
|
||||
DP1 - struct SDSP1, DSP-1.
|
||||
DP2 - struct SDSP2, DSP-2.
|
||||
DP4 - struct SDSP4, DSP-4.
|
||||
CX4 - Memory.C4RAM, 0x2000 bytes.
|
||||
ST0 - struct SST010, ST-010.
|
||||
OBC - struct SOBC1, OBC1 internal state variables.
|
||||
OBM - Memory.OBC1RAM, 0x2000 byts.
|
||||
S71 - struct SSPC7110Snapshot, SPC7110.
|
||||
SRT - struct SSRTCSnapshot, S-RTC internal state variables.
|
||||
CLK - struct SRTCData, S-RTC emulated registers.
|
||||
BSX - struct SBSX, BS-X.
|
||||
SHO - rendered SNES screen.
|
||||
MOV - struct SnapshotMovieInfo.
|
||||
MID - Some block of data the movie subsystem.
|
||||
|
||||
==================
|
||||
|
||||
Without changing the snapshot version number:
|
||||
---------------------------------------------
|
||||
|
||||
Blocks may be safely added at the END of the file, as anything after the last
|
||||
block is ignored. Blocks may not be moved or removed.
|
||||
|
||||
Blocks may not decrease in size. Say you decrease from 10 bytes to 5. Then
|
||||
later you increase back to 8. The only way you could safely do this is if
|
||||
bytes 5-7 still mean the same thing they meant when the block was 10 bytes
|
||||
long.
|
||||
|
||||
Blocks may increase in size as you wish, as long as you can handle old
|
||||
savestates with the old shorter size.
|
||||
|
||||
Struct members may not change in interpretation. New struct members may be
|
||||
added (at the END!) only if you can cope with them being binary-0 in older
|
||||
savestates. Struct members may not be removed or changed in size/type.
|
||||
|
||||
With changing the snapshot version number:
|
||||
------------------------------------------
|
||||
|
||||
Blocks may be added, moved, or removed at will.
|
||||
|
||||
Blocks may decrease in size.
|
||||
|
||||
Struct members may be added, moved, or deleted, and their
|
||||
interpretations/types may be changed. Use the 'debuted_in' and 'deleted_in'
|
||||
fields to indicate when the new member debuted or the old member went away.
|
|
@ -0,0 +1,173 @@
|
|||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
|
@ -0,0 +1,241 @@
|
|||
#-----------------------------------------
|
||||
# snes9x.conf : Snes9x Configuration file
|
||||
#-----------------------------------------
|
||||
|
||||
[ROM]
|
||||
# Filename =
|
||||
LoROM = FALSE
|
||||
HiROM = FALSE
|
||||
PAL = FALSE
|
||||
NTSC = FALSE
|
||||
# Header = TRUE/FALSE to ForceHeader or ForceNoHeader
|
||||
# Interleaved = TRUE/FALSE to ForceInterleaved or ForceNoInterleaved
|
||||
Interleaved2 = FALSE
|
||||
InterleaveGD24 = FALSE
|
||||
Cheat = FALSE
|
||||
Patch = TRUE
|
||||
|
||||
[Sound]
|
||||
Sync = FALSE
|
||||
16BitSound = TRUE
|
||||
Stereo = TRUE
|
||||
ReverseStereo = FALSE
|
||||
Rate = 32000
|
||||
InputRate = 32000
|
||||
Mute = FALSE
|
||||
|
||||
[Display]
|
||||
HiRes = TRUE
|
||||
Transparency = TRUE
|
||||
GraphicWindows = TRUE
|
||||
DisplayFrameRate = FALSE
|
||||
DisplayWatchedAddresses = FALSE
|
||||
DisplayInput = FALSE
|
||||
DisplayFrameCount = FALSE
|
||||
MessagesInImage = TRUE
|
||||
MessageDisplayTime = 120
|
||||
|
||||
[Settings]
|
||||
BSXBootup = FALSE
|
||||
# FrameTime =
|
||||
FrameSkip = Auto
|
||||
TurboMode = FALSE
|
||||
TurboFrameSkip = 15
|
||||
MovieTruncateAtEnd = FALSE
|
||||
MovieNotifyIgnored = FALSE
|
||||
WrongMovieStateProtection = TRUE
|
||||
StretchScreenshots = 1
|
||||
SnapshotScreenshots = TRUE
|
||||
DontSaveOopsSnapshot = FALSE
|
||||
AutoSaveDelay = 0
|
||||
|
||||
[Controls]
|
||||
MouseMaster = TRUE
|
||||
SuperscopeMaster = TRUE
|
||||
JustifierMaster = TRUE
|
||||
MP5Master = TRUE
|
||||
AllowLeftRight = FALSE
|
||||
Port1 = pad1
|
||||
Port2 = none
|
||||
Mouse1Crosshair = 1 White/Black
|
||||
Mouse2Crosshair = 1 White/Black
|
||||
SuperscopeCrosshair = 2 White/Black
|
||||
Justifier1Crosshair = 4 Blue/Black
|
||||
Justifier2Crosshair = 4 MagicPink/Black
|
||||
|
||||
[Hack]
|
||||
EnableGameSpecificHacks = TRUE
|
||||
AllowInvalidVRAMAccess = FALSE
|
||||
SpeedHacks = FALSE
|
||||
DisableIRQ = FALSE
|
||||
DisableHDMA = FALSE
|
||||
HDMATiming = 100
|
||||
|
||||
[Netplay]
|
||||
Enable = FALSE
|
||||
Port = 6096
|
||||
Server = ""
|
||||
|
||||
[DEBUG]
|
||||
Debugger = FALSE
|
||||
Trace = FALSE
|
||||
|
||||
[Unix]
|
||||
# BaseDir = ~/.snes9x
|
||||
# SnapshotFilename =
|
||||
# PlayMovieFilename =
|
||||
# RecordMovieFilename =
|
||||
EnableGamePad = TRUE
|
||||
PadDevice1 = (null)
|
||||
PadDevice2 = (null)
|
||||
PadDevice3 = (null)
|
||||
PadDevice4 = (null)
|
||||
PadDevice5 = (null)
|
||||
PadDevice6 = (null)
|
||||
PadDevice7 = (null)
|
||||
PadDevice8 = (null)
|
||||
ThreadSound = FALSE
|
||||
SoundBufferSize = 100
|
||||
SoundFragmentSize = 2048
|
||||
# SoundDevice =
|
||||
ClearAllControls = FALSE
|
||||
|
||||
[Unix/X11]
|
||||
SetKeyRepeat = TRUE
|
||||
VideoMode = 1
|
||||
|
||||
[Unix/X11 Controls]
|
||||
J00:Axis1 = Joypad1 Axis Up/Down T=50%
|
||||
J00:Axis0 = Joypad1 Axis Left/Right T=50%
|
||||
J00:B1 = Joypad1 A
|
||||
J00:B2 = Joypad1 B
|
||||
J00:B0 = Joypad1 X
|
||||
J00:B3 = Joypad1 Y
|
||||
J00:B6 = Joypad1 L
|
||||
J00:B7 = Joypad1 R
|
||||
J00:B8 = Joypad1 Select
|
||||
J00:B11 = Joypad1 Start
|
||||
K00:u = Joypad1 Up
|
||||
K00:Up = Joypad1 Up
|
||||
K00:j = Joypad1 Down
|
||||
K00:n = Joypad1 Down
|
||||
K00:Down = Joypad1 Down
|
||||
K00:h = Joypad1 Left
|
||||
K00:Left = Joypad1 Left
|
||||
K00:k = Joypad1 Right
|
||||
K00:Right = Joypad1 Right
|
||||
K00:d = Joypad1 A
|
||||
K00:S+d = Joypad1 ToggleTurbo A
|
||||
K00:C+d = Joypad1 ToggleSticky A
|
||||
K00:c = Joypad1 B
|
||||
K00:S+c = Joypad1 ToggleTurbo B
|
||||
K00:C+c = Joypad1 ToggleSticky B
|
||||
K00:s = Joypad1 X
|
||||
K00:S+s = Joypad1 ToggleTurbo X
|
||||
K00:C+s = Joypad1 ToggleSticky X
|
||||
K00:x = Joypad1 Y
|
||||
K00:S+x = Joypad1 ToggleTurbo Y
|
||||
K00:C+x = Joypad1 ToggleSticky Y
|
||||
K00:a = Joypad1 L
|
||||
K00:v = Joypad1 L
|
||||
K00:S+a = Joypad1 ToggleTurbo L
|
||||
K00:S+v = Joypad1 ToggleTurbo L
|
||||
K00:C+a = Joypad1 ToggleSticky L
|
||||
K00:C+v = Joypad1 ToggleSticky L
|
||||
K00:z = Joypad1 R
|
||||
K00:S+z = Joypad1 ToggleTurbo R
|
||||
K00:C+z = Joypad1 ToggleSticky R
|
||||
K00:space = Joypad1 Select
|
||||
K00:Return = Joypad1 Start
|
||||
K00:KP_Up = Joypad2 Up
|
||||
K00:KP_Down = Joypad2 Down
|
||||
K00:KP_Left = Joypad2 Left
|
||||
K00:KP_Right = Joypad2 Right
|
||||
K00:Prior = Joypad2 A
|
||||
K00:Next = Joypad2 B
|
||||
K00:Home = Joypad2 X
|
||||
K00:End = Joypad2 Y
|
||||
K00:Insert = Joypad2 L
|
||||
K00:Delete = Joypad2 R
|
||||
K00:KP_Add = Joypad2 Select
|
||||
K00:KP_Enter = Joypad2 Start
|
||||
K00:Escape = ExitEmu
|
||||
K00:Pause = Pause
|
||||
K00:Scroll_Lock = Pause
|
||||
K00:CS+Escape = Reset
|
||||
K00:S+Escape = SoftReset
|
||||
K00:F12 = SaveFreezeFile
|
||||
K00:A+F3 = SaveFreezeFile
|
||||
K00:C+F3 = SaveFreezeFile
|
||||
K00:F11 = LoadFreezeFile
|
||||
K00:A+F2 = LoadFreezeFile
|
||||
K00:C+F2 = LoadFreezeFile
|
||||
K00:S+F1 = QuickSave000
|
||||
K00:S+F2 = QuickSave001
|
||||
K00:S+F3 = QuickSave002
|
||||
K00:S+F4 = QuickSave003
|
||||
K00:S+F5 = QuickSave004
|
||||
K00:S+F6 = QuickSave005
|
||||
K00:S+F7 = QuickSave006
|
||||
K00:S+F8 = QuickSave007
|
||||
K00:S+F9 = QuickSave008
|
||||
K00:F1 = QuickLoad000
|
||||
K00:F2 = QuickLoad001
|
||||
K00:F3 = QuickLoad002
|
||||
K00:F4 = QuickLoad003
|
||||
K00:F5 = QuickLoad004
|
||||
K00:F6 = QuickLoad005
|
||||
K00:F7 = QuickLoad006
|
||||
K00:F8 = QuickLoad007
|
||||
K00:F9 = QuickLoad008
|
||||
K00:F10 = LoadOopsFile
|
||||
K00:A+F1 = SaveSPC
|
||||
K00:C+F1 = SaveSPC
|
||||
K00:Print = Screenshot
|
||||
K00:S+1 = BeginRecordingMovie
|
||||
K00:S+2 = EndRecordingMovie
|
||||
K00:S+3 = LoadMovie
|
||||
K00:Tab = EmuTurbo
|
||||
K00:S+Tab = ToggleEmuTurbo
|
||||
K00:equal = IncFrameRate
|
||||
K00:minus = DecFrameRate
|
||||
K00:S+equal = IncFrameTime
|
||||
K00:S+minus = DecFrameTime
|
||||
K00:A+equal = IncEmuTurbo
|
||||
K00:A+minus = DecEmuTurbo
|
||||
K00:C+equal = IncTurboSpeed
|
||||
K00:C+minus = DecTurboSpeed
|
||||
K00:6 = SwapJoypads
|
||||
K00:A+F4 = SoundChannel0
|
||||
K00:C+F4 = SoundChannel0
|
||||
K00:A+F5 = SoundChannel1
|
||||
K00:C+F5 = SoundChannel1
|
||||
K00:A+F6 = SoundChannel2
|
||||
K00:C+F6 = SoundChannel2
|
||||
K00:A+F7 = SoundChannel3
|
||||
K00:C+F7 = SoundChannel3
|
||||
K00:A+F8 = SoundChannel4
|
||||
K00:C+F8 = SoundChannel4
|
||||
K00:A+F9 = SoundChannel5
|
||||
K00:C+F9 = SoundChannel5
|
||||
K00:A+F10 = SoundChannel6
|
||||
K00:C+F10 = SoundChannel6
|
||||
K00:A+F11 = SoundChannel7
|
||||
K00:C+F11 = SoundChannel7
|
||||
K00:A+F12 = SoundChannelsOn
|
||||
K00:C+F12 = SoundChannelsOn
|
||||
K00:1 = ToggleBG0
|
||||
K00:2 = ToggleBG1
|
||||
K00:3 = ToggleBG2
|
||||
K00:4 = ToggleBG3
|
||||
K00:5 = ToggleSprites
|
||||
K00:9 = ToggleTransparency
|
||||
K00:BackSpace = ClipWindows
|
||||
K00:0 = ToggleHDMA
|
||||
K00:A+Escape = Debugger
|
||||
M00:Pointer = Pointer Mouse1+Superscope+Justifier1
|
||||
M00:B0 = {Mouse1 L,Superscope Fire,Justifier1 Trigger}
|
||||
M00:B2 = {Mouse1 R,Superscope Cursor,Justifier1 Start}
|
||||
M00:B1 = {Justifier1 AimOffscreen Trigger,Superscope AimOffscreen}
|
||||
K00:grave = Superscope ToggleTurbo
|
||||
K00:slash = Superscope Pause
|
|
@ -0,0 +1,229 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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 "snes9x.h"
|
||||
#include "memmap.h"
|
||||
#ifdef DEBUGGER
|
||||
#include "missing.h"
|
||||
#endif
|
||||
|
||||
uint8 (*GetDSP) (uint16) = NULL;
|
||||
void (*SetDSP) (uint8, uint16) = NULL;
|
||||
|
||||
|
||||
void S9xResetDSP (void)
|
||||
{
|
||||
memset(&DSP1, 0, sizeof(DSP1));
|
||||
DSP1.waiting4command = TRUE;
|
||||
DSP1.first_parameter = TRUE;
|
||||
|
||||
memset(&DSP2, 0, sizeof(DSP2));
|
||||
DSP2.waiting4command = TRUE;
|
||||
|
||||
memset(&DSP3, 0, sizeof(DSP3));
|
||||
DSP3_Reset();
|
||||
|
||||
memset(&DSP4, 0, sizeof(DSP4));
|
||||
DSP4.waiting4command = TRUE;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
|
@ -0,0 +1,618 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _DSP1_H_
|
||||
#define _DSP1_H_
|
||||
|
||||
enum
|
||||
{
|
||||
M_DSP1_LOROM_S,
|
||||
M_DSP1_LOROM_L,
|
||||
M_DSP1_HIROM,
|
||||
M_DSP2_LOROM,
|
||||
M_DSP3_LOROM,
|
||||
M_DSP4_LOROM
|
||||
};
|
||||
|
||||
struct SDSP0
|
||||
{
|
||||
uint32 maptype;
|
||||
uint32 boundary;
|
||||
};
|
||||
|
||||
struct SDSP1
|
||||
{
|
||||
bool8 waiting4command;
|
||||
bool8 first_parameter;
|
||||
uint8 command;
|
||||
uint32 in_count;
|
||||
uint32 in_index;
|
||||
uint32 out_count;
|
||||
uint32 out_index;
|
||||
uint8 parameters[512];
|
||||
uint8 output[512];
|
||||
|
||||
int16 CentreX;
|
||||
int16 CentreY;
|
||||
int16 VOffset;
|
||||
|
||||
int16 VPlane_C;
|
||||
int16 VPlane_E;
|
||||
|
||||
// Azimuth and Zenith angles
|
||||
int16 SinAas;
|
||||
int16 CosAas;
|
||||
int16 SinAzs;
|
||||
int16 CosAzs;
|
||||
|
||||
// Clipped Zenith angle
|
||||
int16 SinAZS;
|
||||
int16 CosAZS;
|
||||
int16 SecAZS_C1;
|
||||
int16 SecAZS_E1;
|
||||
int16 SecAZS_C2;
|
||||
int16 SecAZS_E2;
|
||||
|
||||
int16 Nx;
|
||||
int16 Ny;
|
||||
int16 Nz;
|
||||
int16 Gx;
|
||||
int16 Gy;
|
||||
int16 Gz;
|
||||
int16 C_Les;
|
||||
int16 E_Les;
|
||||
int16 G_Les;
|
||||
|
||||
int16 matrixA[3][3];
|
||||
int16 matrixB[3][3];
|
||||
int16 matrixC[3][3];
|
||||
|
||||
int16 Op00Multiplicand;
|
||||
int16 Op00Multiplier;
|
||||
int16 Op00Result;
|
||||
|
||||
int16 Op20Multiplicand;
|
||||
int16 Op20Multiplier;
|
||||
int16 Op20Result;
|
||||
|
||||
int16 Op10Coefficient;
|
||||
int16 Op10Exponent;
|
||||
int16 Op10CoefficientR;
|
||||
int16 Op10ExponentR;
|
||||
|
||||
int16 Op04Angle;
|
||||
int16 Op04Radius;
|
||||
int16 Op04Sin;
|
||||
int16 Op04Cos;
|
||||
|
||||
int16 Op0CA;
|
||||
int16 Op0CX1;
|
||||
int16 Op0CY1;
|
||||
int16 Op0CX2;
|
||||
int16 Op0CY2;
|
||||
|
||||
int16 Op02FX;
|
||||
int16 Op02FY;
|
||||
int16 Op02FZ;
|
||||
int16 Op02LFE;
|
||||
int16 Op02LES;
|
||||
int16 Op02AAS;
|
||||
int16 Op02AZS;
|
||||
int16 Op02VOF;
|
||||
int16 Op02VVA;
|
||||
int16 Op02CX;
|
||||
int16 Op02CY;
|
||||
|
||||
int16 Op0AVS;
|
||||
int16 Op0AA;
|
||||
int16 Op0AB;
|
||||
int16 Op0AC;
|
||||
int16 Op0AD;
|
||||
|
||||
int16 Op06X;
|
||||
int16 Op06Y;
|
||||
int16 Op06Z;
|
||||
int16 Op06H;
|
||||
int16 Op06V;
|
||||
int16 Op06M;
|
||||
|
||||
int16 Op01m;
|
||||
int16 Op01Zr;
|
||||
int16 Op01Xr;
|
||||
int16 Op01Yr;
|
||||
|
||||
int16 Op11m;
|
||||
int16 Op11Zr;
|
||||
int16 Op11Xr;
|
||||
int16 Op11Yr;
|
||||
|
||||
int16 Op21m;
|
||||
int16 Op21Zr;
|
||||
int16 Op21Xr;
|
||||
int16 Op21Yr;
|
||||
|
||||
int16 Op0DX;
|
||||
int16 Op0DY;
|
||||
int16 Op0DZ;
|
||||
int16 Op0DF;
|
||||
int16 Op0DL;
|
||||
int16 Op0DU;
|
||||
|
||||
int16 Op1DX;
|
||||
int16 Op1DY;
|
||||
int16 Op1DZ;
|
||||
int16 Op1DF;
|
||||
int16 Op1DL;
|
||||
int16 Op1DU;
|
||||
|
||||
int16 Op2DX;
|
||||
int16 Op2DY;
|
||||
int16 Op2DZ;
|
||||
int16 Op2DF;
|
||||
int16 Op2DL;
|
||||
int16 Op2DU;
|
||||
|
||||
int16 Op03F;
|
||||
int16 Op03L;
|
||||
int16 Op03U;
|
||||
int16 Op03X;
|
||||
int16 Op03Y;
|
||||
int16 Op03Z;
|
||||
|
||||
int16 Op13F;
|
||||
int16 Op13L;
|
||||
int16 Op13U;
|
||||
int16 Op13X;
|
||||
int16 Op13Y;
|
||||
int16 Op13Z;
|
||||
|
||||
int16 Op23F;
|
||||
int16 Op23L;
|
||||
int16 Op23U;
|
||||
int16 Op23X;
|
||||
int16 Op23Y;
|
||||
int16 Op23Z;
|
||||
|
||||
int16 Op14Zr;
|
||||
int16 Op14Xr;
|
||||
int16 Op14Yr;
|
||||
int16 Op14U;
|
||||
int16 Op14F;
|
||||
int16 Op14L;
|
||||
int16 Op14Zrr;
|
||||
int16 Op14Xrr;
|
||||
int16 Op14Yrr;
|
||||
|
||||
int16 Op0EH;
|
||||
int16 Op0EV;
|
||||
int16 Op0EX;
|
||||
int16 Op0EY;
|
||||
|
||||
int16 Op0BX;
|
||||
int16 Op0BY;
|
||||
int16 Op0BZ;
|
||||
int16 Op0BS;
|
||||
|
||||
int16 Op1BX;
|
||||
int16 Op1BY;
|
||||
int16 Op1BZ;
|
||||
int16 Op1BS;
|
||||
|
||||
int16 Op2BX;
|
||||
int16 Op2BY;
|
||||
int16 Op2BZ;
|
||||
int16 Op2BS;
|
||||
|
||||
int16 Op28X;
|
||||
int16 Op28Y;
|
||||
int16 Op28Z;
|
||||
int16 Op28R;
|
||||
|
||||
int16 Op1CX;
|
||||
int16 Op1CY;
|
||||
int16 Op1CZ;
|
||||
int16 Op1CXBR;
|
||||
int16 Op1CYBR;
|
||||
int16 Op1CZBR;
|
||||
int16 Op1CXAR;
|
||||
int16 Op1CYAR;
|
||||
int16 Op1CZAR;
|
||||
int16 Op1CX1;
|
||||
int16 Op1CY1;
|
||||
int16 Op1CZ1;
|
||||
int16 Op1CX2;
|
||||
int16 Op1CY2;
|
||||
int16 Op1CZ2;
|
||||
|
||||
uint16 Op0FRamsize;
|
||||
uint16 Op0FPass;
|
||||
|
||||
int16 Op2FUnknown;
|
||||
int16 Op2FSize;
|
||||
|
||||
int16 Op08X;
|
||||
int16 Op08Y;
|
||||
int16 Op08Z;
|
||||
int16 Op08Ll;
|
||||
int16 Op08Lh;
|
||||
|
||||
int16 Op18X;
|
||||
int16 Op18Y;
|
||||
int16 Op18Z;
|
||||
int16 Op18R;
|
||||
int16 Op18D;
|
||||
|
||||
int16 Op38X;
|
||||
int16 Op38Y;
|
||||
int16 Op38Z;
|
||||
int16 Op38R;
|
||||
int16 Op38D;
|
||||
};
|
||||
|
||||
struct SDSP2
|
||||
{
|
||||
bool8 waiting4command;
|
||||
uint8 command;
|
||||
uint32 in_count;
|
||||
uint32 in_index;
|
||||
uint32 out_count;
|
||||
uint32 out_index;
|
||||
uint8 parameters[512];
|
||||
uint8 output[512];
|
||||
|
||||
bool8 Op05HasLen;
|
||||
int32 Op05Len;
|
||||
uint8 Op05Transparent;
|
||||
|
||||
bool8 Op06HasLen;
|
||||
int32 Op06Len;
|
||||
|
||||
uint16 Op09Word1;
|
||||
uint16 Op09Word2;
|
||||
|
||||
bool8 Op0DHasLen;
|
||||
int32 Op0DOutLen;
|
||||
int32 Op0DInLen;
|
||||
};
|
||||
|
||||
struct SDSP3
|
||||
{
|
||||
uint16 DR;
|
||||
uint16 SR;
|
||||
uint16 MemoryIndex;
|
||||
|
||||
int16 WinLo;
|
||||
int16 WinHi;
|
||||
int16 AddLo;
|
||||
int16 AddHi;
|
||||
|
||||
uint16 Codewords;
|
||||
uint16 Outwords;
|
||||
uint16 Symbol;
|
||||
uint16 BitCount;
|
||||
uint16 Index;
|
||||
uint16 Codes[512];
|
||||
uint16 BitsLeft;
|
||||
uint16 ReqBits;
|
||||
uint16 ReqData;
|
||||
uint16 BitCommand;
|
||||
uint8 BaseLength;
|
||||
uint16 BaseCodes;
|
||||
uint16 BaseCode;
|
||||
uint8 CodeLengths[8];
|
||||
uint16 CodeOffsets[8];
|
||||
uint16 LZCode;
|
||||
uint8 LZLength;
|
||||
|
||||
uint16 X;
|
||||
uint16 Y;
|
||||
|
||||
uint8 Bitmap[8];
|
||||
uint8 Bitplane[8];
|
||||
uint16 BMIndex;
|
||||
uint16 BPIndex;
|
||||
uint16 Count;
|
||||
|
||||
int16 op3e_x;
|
||||
int16 op3e_y;
|
||||
|
||||
int16 op1e_terrain[0x2000];
|
||||
int16 op1e_cost[0x2000];
|
||||
int16 op1e_weight[0x2000];
|
||||
|
||||
int16 op1e_cell;
|
||||
int16 op1e_turn;
|
||||
int16 op1e_search;
|
||||
|
||||
int16 op1e_x;
|
||||
int16 op1e_y;
|
||||
|
||||
int16 op1e_min_radius;
|
||||
int16 op1e_max_radius;
|
||||
|
||||
int16 op1e_max_search_radius;
|
||||
int16 op1e_max_path_radius;
|
||||
|
||||
int16 op1e_lcv_radius;
|
||||
int16 op1e_lcv_steps;
|
||||
int16 op1e_lcv_turns;
|
||||
};
|
||||
|
||||
struct SDSP4
|
||||
{
|
||||
bool8 waiting4command;
|
||||
bool8 half_command;
|
||||
uint16 command;
|
||||
uint32 in_count;
|
||||
uint32 in_index;
|
||||
uint32 out_count;
|
||||
uint32 out_index;
|
||||
uint8 parameters[512];
|
||||
uint8 output[512];
|
||||
uint8 byte;
|
||||
uint16 address;
|
||||
|
||||
// op control
|
||||
int8 Logic; // controls op flow
|
||||
|
||||
// projection format
|
||||
int16 lcv; // loop-control variable
|
||||
int16 distance; // z-position into virtual world
|
||||
int16 raster; // current raster line
|
||||
int16 segments; // number of raster lines drawn
|
||||
|
||||
// 1.15.16 or 1.15.0 [sign, integer, fraction]
|
||||
int32 world_x; // line of x-projection in world
|
||||
int32 world_y; // line of y-projection in world
|
||||
int32 world_dx; // projection line x-delta
|
||||
int32 world_dy; // projection line y-delta
|
||||
int16 world_ddx; // x-delta increment
|
||||
int16 world_ddy; // y-delta increment
|
||||
int32 world_xenv; // world x-shaping factor
|
||||
int16 world_yofs; // world y-vertical scroll
|
||||
int16 view_x1; // current viewer-x
|
||||
int16 view_y1; // current viewer-y
|
||||
int16 view_x2; // future viewer-x
|
||||
int16 view_y2; // future viewer-y
|
||||
int16 view_dx; // view x-delta factor
|
||||
int16 view_dy; // view y-delta factor
|
||||
int16 view_xofs1; // current viewer x-vertical scroll
|
||||
int16 view_yofs1; // current viewer y-vertical scroll
|
||||
int16 view_xofs2; // future viewer x-vertical scroll
|
||||
int16 view_yofs2; // future viewer y-vertical scroll
|
||||
int16 view_yofsenv; // y-scroll shaping factor
|
||||
int16 view_turnoff_x; // road turnoff data
|
||||
int16 view_turnoff_dx; // road turnoff delta factor
|
||||
|
||||
// drawing area
|
||||
int16 viewport_cx; // x-center of viewport window
|
||||
int16 viewport_cy; // y-center of render window
|
||||
int16 viewport_left; // x-left of viewport
|
||||
int16 viewport_right; // x-right of viewport
|
||||
int16 viewport_top; // y-top of viewport
|
||||
int16 viewport_bottom; // y-bottom of viewport
|
||||
|
||||
// sprite structure
|
||||
int16 sprite_x; // projected x-pos of sprite
|
||||
int16 sprite_y; // projected y-pos of sprite
|
||||
int16 sprite_attr; // obj attributes
|
||||
bool8 sprite_size; // sprite size: 8x8 or 16x16
|
||||
int16 sprite_clipy; // visible line to clip pixels off
|
||||
int16 sprite_count;
|
||||
|
||||
// generic projection variables designed for two solid polygons + two polygon sides
|
||||
int16 poly_clipLf[2][2]; // left clip boundary
|
||||
int16 poly_clipRt[2][2]; // right clip boundary
|
||||
int16 poly_ptr[2][2]; // HDMA structure pointers
|
||||
int16 poly_raster[2][2]; // current raster line below horizon
|
||||
int16 poly_top[2][2]; // top clip boundary
|
||||
int16 poly_bottom[2][2]; // bottom clip boundary
|
||||
int16 poly_cx[2][2]; // center for left/right points
|
||||
int16 poly_start[2]; // current projection points
|
||||
int16 poly_plane[2]; // previous z-plane distance
|
||||
|
||||
// OAM
|
||||
int16 OAM_attr[16]; // OAM (size, MSB) data
|
||||
int16 OAM_index; // index into OAM table
|
||||
int16 OAM_bits; // offset into OAM table
|
||||
int16 OAM_RowMax; // maximum number of tiles per 8 aligned pixels (row)
|
||||
int16 OAM_Row[32]; // current number of tiles per row
|
||||
};
|
||||
|
||||
extern struct SDSP0 DSP0;
|
||||
extern struct SDSP1 DSP1;
|
||||
extern struct SDSP2 DSP2;
|
||||
extern struct SDSP3 DSP3;
|
||||
extern struct SDSP4 DSP4;
|
||||
|
||||
uint8 S9xGetDSP (uint16);
|
||||
void S9xSetDSP (uint8, uint16);
|
||||
void S9xResetDSP (void);
|
||||
uint8 DSP1GetByte (uint16);
|
||||
void DSP1SetByte (uint8, uint16);
|
||||
uint8 DSP2GetByte (uint16);
|
||||
void DSP2SetByte (uint8, uint16);
|
||||
uint8 DSP3GetByte (uint16);
|
||||
void DSP3SetByte (uint8, uint16);
|
||||
uint8 DSP4GetByte (uint16);
|
||||
void DSP4SetByte (uint8, uint16);
|
||||
void DSP3_Reset (void);
|
||||
|
||||
extern uint8 (*GetDSP) (uint16);
|
||||
extern void (*SetDSP) (uint8, uint16);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,532 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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 "snes9x.h"
|
||||
#include "memmap.h"
|
||||
|
||||
static void DSP2_Op01 (void);
|
||||
static void DSP2_Op03 (void);
|
||||
static void DSP2_Op05 (void);
|
||||
static void DSP2_Op06 (void);
|
||||
static void DSP2_Op09 (void);
|
||||
static void DSP2_Op0D (void);
|
||||
|
||||
|
||||
// convert bitmap to bitplane tile
|
||||
static void DSP2_Op01 (void)
|
||||
{
|
||||
// Op01 size is always 32 bytes input and output
|
||||
// The hardware does strange things if you vary the size
|
||||
|
||||
uint8 c0, c1, c2, c3;
|
||||
uint8 *p1 = DSP2.parameters;
|
||||
uint8 *p2a = DSP2.output;
|
||||
uint8 *p2b = DSP2.output + 16; // halfway
|
||||
|
||||
// Process 8 blocks of 4 bytes each
|
||||
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
c0 = *p1++;
|
||||
c1 = *p1++;
|
||||
c2 = *p1++;
|
||||
c3 = *p1++;
|
||||
|
||||
*p2a++ = (c0 & 0x10) << 3 |
|
||||
(c0 & 0x01) << 6 |
|
||||
(c1 & 0x10) << 1 |
|
||||
(c1 & 0x01) << 4 |
|
||||
(c2 & 0x10) >> 1 |
|
||||
(c2 & 0x01) << 2 |
|
||||
(c3 & 0x10) >> 3 |
|
||||
(c3 & 0x01);
|
||||
|
||||
*p2a++ = (c0 & 0x20) << 2 |
|
||||
(c0 & 0x02) << 5 |
|
||||
(c1 & 0x20) |
|
||||
(c1 & 0x02) << 3 |
|
||||
(c2 & 0x20) >> 2 |
|
||||
(c2 & 0x02) << 1 |
|
||||
(c3 & 0x20) >> 4 |
|
||||
(c3 & 0x02) >> 1;
|
||||
|
||||
*p2b++ = (c0 & 0x40) << 1 |
|
||||
(c0 & 0x04) << 4 |
|
||||
(c1 & 0x40) >> 1 |
|
||||
(c1 & 0x04) << 2 |
|
||||
(c2 & 0x40) >> 3 |
|
||||
(c2 & 0x04) |
|
||||
(c3 & 0x40) >> 5 |
|
||||
(c3 & 0x04) >> 2;
|
||||
|
||||
*p2b++ = (c0 & 0x80) |
|
||||
(c0 & 0x08) << 3 |
|
||||
(c1 & 0x80) >> 2 |
|
||||
(c1 & 0x08) << 1 |
|
||||
(c2 & 0x80) >> 4 |
|
||||
(c2 & 0x08) >> 1 |
|
||||
(c3 & 0x80) >> 6 |
|
||||
(c3 & 0x08) >> 3;
|
||||
}
|
||||
}
|
||||
|
||||
// set transparent color
|
||||
static void DSP2_Op03 (void)
|
||||
{
|
||||
DSP2.Op05Transparent = DSP2.parameters[0];
|
||||
}
|
||||
|
||||
// replace bitmap using transparent color
|
||||
static void DSP2_Op05 (void)
|
||||
{
|
||||
// Overlay bitmap with transparency.
|
||||
// Input:
|
||||
//
|
||||
// Bitmap 1: i[0] <=> i[size-1]
|
||||
// Bitmap 2: i[size] <=> i[2*size-1]
|
||||
//
|
||||
// Output:
|
||||
//
|
||||
// Bitmap 3: o[0] <=> o[size-1]
|
||||
//
|
||||
// Processing:
|
||||
//
|
||||
// Process all 4-bit pixels (nibbles) in the bitmap
|
||||
//
|
||||
// if ( BM2_pixel == transparent_color )
|
||||
// pixelout = BM1_pixel
|
||||
// else
|
||||
// pixelout = BM2_pixel
|
||||
|
||||
// The max size bitmap is limited to 255 because the size parameter is a byte
|
||||
// I think size=0 is an error. The behavior of the chip on size=0 is to
|
||||
// return the last value written to DR if you read DR on Op05 with
|
||||
// size = 0. I don't think it's worth implementing this quirk unless it's
|
||||
// proven necessary.
|
||||
|
||||
uint8 color;
|
||||
uint8 c1, c2;
|
||||
uint8 *p1 = DSP2.parameters;
|
||||
uint8 *p2 = DSP2.parameters + DSP2.Op05Len;
|
||||
uint8 *p3 = DSP2.output;
|
||||
|
||||
color = DSP2.Op05Transparent & 0x0f;
|
||||
|
||||
for (int32 n = 0; n < DSP2.Op05Len; n++)
|
||||
{
|
||||
c1 = *p1++;
|
||||
c2 = *p2++;
|
||||
*p3++ = (((c2 >> 4) == color) ? c1 & 0xf0: c2 & 0xf0) | (((c2 & 0x0f) == color) ? c1 & 0x0f: c2 & 0x0f);
|
||||
}
|
||||
}
|
||||
|
||||
// reverse bitmap
|
||||
static void DSP2_Op06 (void)
|
||||
{
|
||||
// Input:
|
||||
// size
|
||||
// bitmap
|
||||
|
||||
for (int32 i = 0, j = DSP2.Op06Len - 1; i < DSP2.Op06Len; i++, j--)
|
||||
DSP2.output[j] = (DSP2.parameters[i] << 4) | (DSP2.parameters[i] >> 4);
|
||||
}
|
||||
|
||||
// multiply
|
||||
static void DSP2_Op09 (void)
|
||||
{
|
||||
DSP2.Op09Word1 = DSP2.parameters[0] | (DSP2.parameters[1] << 8);
|
||||
DSP2.Op09Word2 = DSP2.parameters[2] | (DSP2.parameters[3] << 8);
|
||||
|
||||
uint32 temp = DSP2.Op09Word1 * DSP2.Op09Word2;
|
||||
DSP2.output[0] = temp & 0xFF;
|
||||
DSP2.output[1] = (temp >> 8) & 0xFF;
|
||||
DSP2.output[2] = (temp >> 16) & 0xFF;
|
||||
DSP2.output[3] = (temp >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
// scale bitmap
|
||||
static void DSP2_Op0D (void)
|
||||
{
|
||||
// Bit accurate hardware algorithm - uses fixed point math
|
||||
// This should match the DSP2 Op0D output exactly
|
||||
// I wouldn't recommend using this unless you're doing hardware debug.
|
||||
// In some situations it has small visual artifacts that
|
||||
// are not readily apparent on a TV screen but show up clearly
|
||||
// on a monitor. Use Overload's scaling instead.
|
||||
// This is for hardware verification testing.
|
||||
//
|
||||
// One note: the HW can do odd byte scaling but since we divide
|
||||
// by two to get the count of bytes this won't work well for
|
||||
// odd byte scaling (in any of the current algorithm implementations).
|
||||
// So far I haven't seen Dungeon Master use it.
|
||||
// If it does we can adjust the parameters and code to work with it
|
||||
|
||||
uint32 multiplier; // Any size int >= 32-bits
|
||||
uint32 pixloc; // match size of multiplier
|
||||
uint8 pixelarray[512];
|
||||
|
||||
if (DSP2.Op0DInLen <= DSP2.Op0DOutLen)
|
||||
multiplier = 0x10000; // In our self defined fixed point 0x10000 == 1
|
||||
else
|
||||
multiplier = (DSP2.Op0DInLen << 17) / ((DSP2.Op0DOutLen << 1) + 1);
|
||||
|
||||
pixloc = 0;
|
||||
|
||||
for (int32 i = 0; i < DSP2.Op0DOutLen * 2; i++)
|
||||
{
|
||||
int32 j = pixloc >> 16;
|
||||
|
||||
if (j & 1)
|
||||
pixelarray[i] = DSP2.parameters[j >> 1] & 0x0f;
|
||||
else
|
||||
pixelarray[i] = (DSP2.parameters[j >> 1] & 0xf0) >> 4;
|
||||
|
||||
pixloc += multiplier;
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < DSP2.Op0DOutLen; i++)
|
||||
DSP2.output[i] = (pixelarray[i << 1] << 4) | pixelarray[(i << 1) + 1];
|
||||
}
|
||||
|
||||
/*
|
||||
static void DSP2_Op0D (void)
|
||||
{
|
||||
// Overload's algorithm - use this unless doing hardware testing
|
||||
|
||||
// One note: the HW can do odd byte scaling but since we divide
|
||||
// by two to get the count of bytes this won't work well for
|
||||
// odd byte scaling (in any of the current algorithm implementations).
|
||||
// So far I haven't seen Dungeon Master use it.
|
||||
// If it does we can adjust the parameters and code to work with it
|
||||
|
||||
int32 pixel_offset;
|
||||
uint8 pixelarray[512];
|
||||
|
||||
for (int32 i = 0; i < DSP2.Op0DOutLen * 2; i++)
|
||||
{
|
||||
pixel_offset = (i * DSP2.Op0DInLen) / DSP2.Op0DOutLen;
|
||||
|
||||
if ((pixel_offset & 1) == 0)
|
||||
pixelarray[i] = DSP2.parameters[pixel_offset >> 1] >> 4;
|
||||
else
|
||||
pixelarray[i] = DSP2.parameters[pixel_offset >> 1] & 0x0f;
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < DSP2.Op0DOutLen; i++)
|
||||
DSP2.output[i] = (pixelarray[i << 1] << 4) | pixelarray[(i << 1) + 1];
|
||||
}
|
||||
*/
|
||||
|
||||
void DSP2SetByte (uint8 byte, uint16 address)
|
||||
{
|
||||
if ((address & 0xf000) == 0x6000 || (address >= 0x8000 && address < 0xc000))
|
||||
{
|
||||
if (DSP2.waiting4command)
|
||||
{
|
||||
DSP2.command = byte;
|
||||
DSP2.in_index = 0;
|
||||
DSP2.waiting4command = FALSE;
|
||||
|
||||
switch (byte)
|
||||
{
|
||||
case 0x01: DSP2.in_count = 32; break;
|
||||
case 0x03: DSP2.in_count = 1; break;
|
||||
case 0x05: DSP2.in_count = 1; break;
|
||||
case 0x06: DSP2.in_count = 1; break;
|
||||
case 0x09: DSP2.in_count = 4; break;
|
||||
case 0x0D: DSP2.in_count = 2; break;
|
||||
default:
|
||||
#ifdef DEBUGGER
|
||||
//printf("Op%02X\n", byte);
|
||||
#endif
|
||||
case 0x0f: DSP2.in_count = 0; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DSP2.parameters[DSP2.in_index] = byte;
|
||||
DSP2.in_index++;
|
||||
}
|
||||
|
||||
if (DSP2.in_count == DSP2.in_index)
|
||||
{
|
||||
DSP2.waiting4command = TRUE;
|
||||
DSP2.out_index = 0;
|
||||
|
||||
switch (DSP2.command)
|
||||
{
|
||||
case 0x01:
|
||||
DSP2.out_count = 32;
|
||||
DSP2_Op01();
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
DSP2_Op03();
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
if (DSP2.Op05HasLen)
|
||||
{
|
||||
DSP2.Op05HasLen = FALSE;
|
||||
DSP2.out_count = DSP2.Op05Len;
|
||||
DSP2_Op05();
|
||||
}
|
||||
else
|
||||
{
|
||||
DSP2.Op05Len = DSP2.parameters[0];
|
||||
DSP2.in_index = 0;
|
||||
DSP2.in_count = 2 * DSP2.Op05Len;
|
||||
DSP2.Op05HasLen = TRUE;
|
||||
if (byte)
|
||||
DSP2.waiting4command = FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
if (DSP2.Op06HasLen)
|
||||
{
|
||||
DSP2.Op06HasLen = FALSE;
|
||||
DSP2.out_count = DSP2.Op06Len;
|
||||
DSP2_Op06();
|
||||
}
|
||||
else
|
||||
{
|
||||
DSP2.Op06Len = DSP2.parameters[0];
|
||||
DSP2.in_index = 0;
|
||||
DSP2.in_count = DSP2.Op06Len;
|
||||
DSP2.Op06HasLen = TRUE;
|
||||
if (byte)
|
||||
DSP2.waiting4command = FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x09:
|
||||
DSP2.out_count = 4;
|
||||
DSP2_Op09();
|
||||
break;
|
||||
|
||||
case 0x0D:
|
||||
if (DSP2.Op0DHasLen)
|
||||
{
|
||||
DSP2.Op0DHasLen = FALSE;
|
||||
DSP2.out_count = DSP2.Op0DOutLen;
|
||||
DSP2_Op0D();
|
||||
}
|
||||
else
|
||||
{
|
||||
DSP2.Op0DInLen = DSP2.parameters[0];
|
||||
DSP2.Op0DOutLen = DSP2.parameters[1];
|
||||
DSP2.in_index = 0;
|
||||
DSP2.in_count = (DSP2.Op0DInLen + 1) >> 1;
|
||||
DSP2.Op0DHasLen = TRUE;
|
||||
if (byte)
|
||||
DSP2.waiting4command = FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x0f:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 DSP2GetByte (uint16 address)
|
||||
{
|
||||
uint8 t;
|
||||
|
||||
if ((address & 0xf000) == 0x6000 || (address >= 0x8000 && address < 0xc000))
|
||||
{
|
||||
if (DSP2.out_count)
|
||||
{
|
||||
t = (uint8) DSP2.output[DSP2.out_index];
|
||||
DSP2.out_index++;
|
||||
if (DSP2.out_count == DSP2.out_index)
|
||||
DSP2.out_count = 0;
|
||||
}
|
||||
else
|
||||
t = 0xff;
|
||||
}
|
||||
else
|
||||
t = 0x80;
|
||||
|
||||
return (t);
|
||||
}
|
|
@ -0,0 +1,654 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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 "snes9x.h"
|
||||
#include "2xsai.h"
|
||||
|
||||
#define ALL_COLOR_MASK (FIRST_COLOR_MASK | SECOND_COLOR_MASK | THIRD_COLOR_MASK)
|
||||
|
||||
#ifdef GFX_MULTI_FORMAT
|
||||
static uint32 colorMask = 0, qcolorMask = 0, lowPixelMask = 0, qlowpixelMask = 0;
|
||||
#else
|
||||
#define colorMask (((~RGB_LOW_BITS_MASK & ALL_COLOR_MASK) << 16) | (~RGB_LOW_BITS_MASK & ALL_COLOR_MASK))
|
||||
#define qcolorMask (((~TWO_LOW_BITS_MASK & ALL_COLOR_MASK) << 16) | (~TWO_LOW_BITS_MASK & ALL_COLOR_MASK))
|
||||
#define lowPixelMask ((RGB_LOW_BITS_MASK << 16) | RGB_LOW_BITS_MASK)
|
||||
#define qlowpixelMask ((TWO_LOW_BITS_MASK << 16) | TWO_LOW_BITS_MASK)
|
||||
#endif
|
||||
|
||||
static inline int GetResult (uint32, uint32, uint32, uint32);
|
||||
static inline int GetResult1 (uint32, uint32, uint32, uint32, uint32);
|
||||
static inline int GetResult2 (uint32, uint32, uint32, uint32, uint32);
|
||||
static inline uint32 INTERPOLATE (uint32, uint32);
|
||||
static inline uint32 Q_INTERPOLATE (uint32, uint32, uint32, uint32);
|
||||
|
||||
|
||||
static inline int GetResult (uint32 A, uint32 B, uint32 C, uint32 D)
|
||||
{
|
||||
int x = 0, y = 0, r = 0;
|
||||
|
||||
if (A == C) x += 1; else if (B == C) y += 1;
|
||||
if (A == D) x += 1; else if (B == D) y += 1;
|
||||
if (x <= 1) r += 1;
|
||||
if (y <= 1) r -= 1;
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
static inline int GetResult1 (uint32 A, uint32 B, uint32 C, uint32 D, uint32 E)
|
||||
{
|
||||
int x = 0, y = 0, r = 0;
|
||||
|
||||
if (A == C) x += 1; else if (B == C) y += 1;
|
||||
if (A == D) x += 1; else if (B == D) y += 1;
|
||||
if (x <= 1) r += 1;
|
||||
if (y <= 1) r -= 1;
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
static inline int GetResult2 (uint32 A, uint32 B, uint32 C, uint32 D, uint32 E)
|
||||
{
|
||||
int x = 0, y = 0, r = 0;
|
||||
|
||||
if (A == C) x += 1; else if (B == C) y += 1;
|
||||
if (A == D) x += 1; else if (B == D) y += 1;
|
||||
if (x <= 1) r -= 1;
|
||||
if (y <= 1) r += 1;
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
static inline uint32 INTERPOLATE (uint32 A, uint32 B)
|
||||
{
|
||||
return (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask));
|
||||
}
|
||||
|
||||
static inline uint32 Q_INTERPOLATE (uint32 A, uint32 B, uint32 C, uint32 D)
|
||||
{
|
||||
uint32 x = ((A & qcolorMask) >> 2) + ((B & qcolorMask) >> 2) + ((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2);
|
||||
uint32 y = (A & qlowpixelMask) + (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask);
|
||||
|
||||
y = (y >> 2) & qlowpixelMask;
|
||||
|
||||
return (x + y);
|
||||
}
|
||||
|
||||
bool8 S9xBlit2xSaIFilterInit (void)
|
||||
{
|
||||
#ifdef GFX_MULTI_FORMAT
|
||||
colorMask = ((~RGB_LOW_BITS_MASK & ALL_COLOR_MASK) << 16) | (~RGB_LOW_BITS_MASK & ALL_COLOR_MASK);
|
||||
qcolorMask = ((~TWO_LOW_BITS_MASK & ALL_COLOR_MASK) << 16) | (~TWO_LOW_BITS_MASK & ALL_COLOR_MASK);
|
||||
lowPixelMask = (RGB_LOW_BITS_MASK << 16) | RGB_LOW_BITS_MASK;
|
||||
qlowpixelMask = (TWO_LOW_BITS_MASK << 16) | TWO_LOW_BITS_MASK;
|
||||
#endif
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
void S9xBlit2xSaIFilterDeinit (void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void SuperEagle (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
uint16 *bP;
|
||||
uint32 *dP;
|
||||
uint32 nextline = srcRowBytes >> 1;
|
||||
|
||||
for (; height; height--)
|
||||
{
|
||||
bP = (uint16 *) srcPtr;
|
||||
dP = (uint32 *) dstPtr;
|
||||
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
uint32 color1, color2, color3, color4, color5, color6;
|
||||
uint32 colorA0, colorA1, colorA2, colorA3, colorB0, colorB1, colorB2, colorB3, colorS1, colorS2;
|
||||
uint32 product1a, product1b, product2a, product2b;
|
||||
|
||||
colorB0 = *(bP - nextline - 1);
|
||||
colorB1 = *(bP - nextline );
|
||||
colorB2 = *(bP - nextline + 1);
|
||||
colorB3 = *(bP - nextline + 2);
|
||||
|
||||
color4 = *(bP - 1);
|
||||
color5 = *(bP );
|
||||
color6 = *(bP + 1);
|
||||
colorS2 = *(bP + 2);
|
||||
|
||||
color1 = *(bP + nextline - 1);
|
||||
color2 = *(bP + nextline );
|
||||
color3 = *(bP + nextline + 1);
|
||||
colorS1 = *(bP + nextline + 2);
|
||||
|
||||
colorA0 = *(bP + nextline + nextline - 1);
|
||||
colorA1 = *(bP + nextline + nextline );
|
||||
colorA2 = *(bP + nextline + nextline + 1);
|
||||
colorA3 = *(bP + nextline + nextline + 2);
|
||||
|
||||
if (color2 == color6 && color5 != color3)
|
||||
{
|
||||
product1b = product2a = color2;
|
||||
if ((color1 == color2 && color6 == colorS2) || (color2 == colorA1 && color6 == colorB2))
|
||||
{
|
||||
product1a = INTERPOLATE(color2, color5);
|
||||
product1a = INTERPOLATE(color2, product1a);
|
||||
product2b = INTERPOLATE(color2, color3);
|
||||
product2b = INTERPOLATE(color2, product2b);
|
||||
}
|
||||
else
|
||||
{
|
||||
product1a = INTERPOLATE(color5, color6);
|
||||
product2b = INTERPOLATE(color2, color3);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (color5 == color3 && color2 != color6)
|
||||
{
|
||||
product2b = product1a = color5;
|
||||
if ((colorB1 == color5 && color3 == colorA2) || (color4 == color5 && color3 == colorS1))
|
||||
{
|
||||
product1b = INTERPOLATE(color5, color6);
|
||||
product1b = INTERPOLATE(color5, product1b);
|
||||
product2a = INTERPOLATE(color5, color2);
|
||||
product2a = INTERPOLATE(color5, product2a);
|
||||
}
|
||||
else
|
||||
{
|
||||
product1b = INTERPOLATE(color5, color6);
|
||||
product2a = INTERPOLATE(color2, color3);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (color5 == color3 && color2 == color6 && color5 != color6)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
r += GetResult(color6, color5, color1, colorA1);
|
||||
r += GetResult(color6, color5, color4, colorB1);
|
||||
r += GetResult(color6, color5, colorA2, colorS1);
|
||||
r += GetResult(color6, color5, colorB2, colorS2);
|
||||
|
||||
if (r > 0)
|
||||
{
|
||||
product1b = product2a = color2;
|
||||
product1a = product2b = INTERPOLATE(color5, color6);
|
||||
}
|
||||
else
|
||||
if (r < 0)
|
||||
{
|
||||
product2b = product1a = color5;
|
||||
product1b = product2a = INTERPOLATE(color5, color6);
|
||||
}
|
||||
else
|
||||
{
|
||||
product2b = product1a = color5;
|
||||
product1b = product2a = color2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((color2 == color5) || (color3 == color6))
|
||||
{
|
||||
product1a = color5;
|
||||
product2a = color2;
|
||||
product1b = color6;
|
||||
product2b = color3;
|
||||
}
|
||||
else
|
||||
{
|
||||
product1b = product1a = INTERPOLATE(color5, color6);
|
||||
product1a = INTERPOLATE(color5, product1a);
|
||||
product1b = INTERPOLATE(color6, product1b);
|
||||
|
||||
product2a = product2b = INTERPOLATE(color2, color3);
|
||||
product2a = INTERPOLATE(color2, product2a);
|
||||
product2b = INTERPOLATE(color3, product2b);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MSB_FIRST
|
||||
product1a = (product1a << 16) | product1b;
|
||||
product2a = (product2a << 16) | product2b;
|
||||
#else
|
||||
product1a = product1a | (product1b << 16);
|
||||
product2a = product2a | (product2b << 16);
|
||||
#endif
|
||||
|
||||
*(dP) = product1a;
|
||||
*(dP + (dstRowBytes >> 2)) = product2a;
|
||||
|
||||
bP++;
|
||||
dP++;
|
||||
}
|
||||
|
||||
dstPtr += dstRowBytes << 1;
|
||||
srcPtr += srcRowBytes;
|
||||
}
|
||||
}
|
||||
|
||||
void _2xSaI (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
uint16 *bP;
|
||||
uint32 *dP;
|
||||
uint32 nextline = srcRowBytes >> 1;
|
||||
|
||||
for (; height; height--)
|
||||
{
|
||||
bP = (uint16 *) srcPtr;
|
||||
dP = (uint32 *) dstPtr;
|
||||
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
uint32 colorA, colorB, colorC, colorD, colorE, colorF, colorG, colorH, colorI, colorJ, colorK, colorL, colorM, colorN, colorO, colorP;
|
||||
uint32 product, product1, product2;
|
||||
|
||||
colorI = *(bP - nextline - 1);
|
||||
colorE = *(bP - nextline );
|
||||
colorF = *(bP - nextline + 1);
|
||||
colorJ = *(bP - nextline + 2);
|
||||
|
||||
colorG = *(bP - 1);
|
||||
colorA = *(bP );
|
||||
colorB = *(bP + 1);
|
||||
colorK = *(bP + 2);
|
||||
|
||||
colorH = *(bP + nextline - 1);
|
||||
colorC = *(bP + nextline );
|
||||
colorD = *(bP + nextline + 1);
|
||||
colorL = *(bP + nextline + 2);
|
||||
|
||||
colorM = *(bP + nextline + nextline - 1);
|
||||
colorN = *(bP + nextline + nextline );
|
||||
colorO = *(bP + nextline + nextline + 1);
|
||||
colorP = *(bP + nextline + nextline + 2);
|
||||
|
||||
if ((colorA == colorD) && (colorB != colorC))
|
||||
{
|
||||
if (((colorA == colorE) && (colorB == colorL)) || ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ)))
|
||||
product = colorA;
|
||||
else
|
||||
product = INTERPOLATE(colorA, colorB);
|
||||
|
||||
if (((colorA == colorG) && (colorC == colorO)) || ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM)))
|
||||
product1 = colorA;
|
||||
else
|
||||
product1 = INTERPOLATE(colorA, colorC);
|
||||
|
||||
product2 = colorA;
|
||||
}
|
||||
else
|
||||
if ((colorB == colorC) && (colorA != colorD))
|
||||
{
|
||||
if (((colorB == colorF) && (colorA == colorH)) || ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI)))
|
||||
product = colorB;
|
||||
else
|
||||
product = INTERPOLATE(colorA, colorB);
|
||||
|
||||
if (((colorC == colorH) && (colorA == colorF)) || ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI)))
|
||||
product1 = colorC;
|
||||
else
|
||||
product1 = INTERPOLATE(colorA, colorC);
|
||||
|
||||
product2 = colorB;
|
||||
}
|
||||
else
|
||||
if ((colorA == colorD) && (colorB == colorC))
|
||||
{
|
||||
if (colorA == colorB)
|
||||
{
|
||||
product = colorA;
|
||||
product1 = colorA;
|
||||
product2 = colorA;
|
||||
}
|
||||
else
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
product1 = INTERPOLATE(colorA, colorC);
|
||||
product = INTERPOLATE(colorA, colorB);
|
||||
|
||||
r += GetResult1(colorA, colorB, colorG, colorE, colorI);
|
||||
r += GetResult2(colorB, colorA, colorK, colorF, colorJ);
|
||||
r += GetResult2(colorB, colorA, colorH, colorN, colorM);
|
||||
r += GetResult1(colorA, colorB, colorL, colorO, colorP);
|
||||
|
||||
if (r > 0)
|
||||
product2 = colorA;
|
||||
else
|
||||
if (r < 0)
|
||||
product2 = colorB;
|
||||
else
|
||||
product2 = Q_INTERPOLATE(colorA, colorB, colorC, colorD);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
product2 = Q_INTERPOLATE(colorA, colorB, colorC, colorD);
|
||||
|
||||
if ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ))
|
||||
product = colorA;
|
||||
else
|
||||
if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))
|
||||
product = colorB;
|
||||
else
|
||||
product = INTERPOLATE(colorA, colorB);
|
||||
|
||||
if ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM))
|
||||
product1 = colorA;
|
||||
else
|
||||
if ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI))
|
||||
product1 = colorC;
|
||||
else
|
||||
product1 = INTERPOLATE(colorA, colorC);
|
||||
}
|
||||
|
||||
#ifdef MSB_FIRST
|
||||
product = (colorA << 16) | product;
|
||||
product1 = (product1 << 16) | product2;
|
||||
#else
|
||||
product = colorA | (product << 16);
|
||||
product1 = product1 | (product2 << 16);
|
||||
#endif
|
||||
|
||||
*(dP) = product;
|
||||
*(dP + (dstRowBytes >> 2)) = product1;
|
||||
|
||||
bP++;
|
||||
dP++;
|
||||
}
|
||||
|
||||
dstPtr += dstRowBytes << 1;
|
||||
srcPtr += srcRowBytes;
|
||||
}
|
||||
}
|
||||
|
||||
void Super2xSaI (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
uint16 *bP;
|
||||
uint32 *dP;
|
||||
uint32 nextline = srcRowBytes >> 1;
|
||||
|
||||
for (; height; height--)
|
||||
{
|
||||
bP = (uint16 *) srcPtr;
|
||||
dP = (uint32 *) dstPtr;
|
||||
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
uint32 color1, color2, color3, color4, color5, color6;
|
||||
uint32 colorA0, colorA1, colorA2, colorA3, colorB0, colorB1, colorB2, colorB3, colorS1, colorS2;
|
||||
uint32 product1a, product1b, product2a, product2b;
|
||||
|
||||
colorB0 = *(bP - nextline - 1);
|
||||
colorB1 = *(bP - nextline );
|
||||
colorB2 = *(bP - nextline + 1);
|
||||
colorB3 = *(bP - nextline + 2);
|
||||
|
||||
color4 = *(bP - 1);
|
||||
color5 = *(bP );
|
||||
color6 = *(bP + 1);
|
||||
colorS2 = *(bP + 2);
|
||||
|
||||
color1 = *(bP + nextline - 1);
|
||||
color2 = *(bP + nextline );
|
||||
color3 = *(bP + nextline + 1);
|
||||
colorS1 = *(bP + nextline + 2);
|
||||
|
||||
colorA0 = *(bP + nextline + nextline - 1);
|
||||
colorA1 = *(bP + nextline + nextline );
|
||||
colorA2 = *(bP + nextline + nextline + 1);
|
||||
colorA3 = *(bP + nextline + nextline + 2);
|
||||
|
||||
if (color2 == color6 && color5 != color3)
|
||||
product2b = product1b = color2;
|
||||
else
|
||||
if (color5 == color3 && color2 != color6)
|
||||
product2b = product1b = color5;
|
||||
else
|
||||
if (color5 == color3 && color2 == color6 && color5 != color6)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
r += GetResult(color6, color5, color1, colorA1);
|
||||
r += GetResult(color6, color5, color4, colorB1);
|
||||
r += GetResult(color6, color5, colorA2, colorS1);
|
||||
r += GetResult(color6, color5, colorB2, colorS2);
|
||||
|
||||
if (r > 0)
|
||||
product2b = product1b = color6;
|
||||
else
|
||||
if (r < 0)
|
||||
product2b = product1b = color5;
|
||||
else
|
||||
product2b = product1b = INTERPOLATE(color5, color6);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
|
||||
product2b = Q_INTERPOLATE(color3, color3, color3, color2);
|
||||
else
|
||||
if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
|
||||
product2b = Q_INTERPOLATE(color2, color2, color2, color3);
|
||||
else
|
||||
product2b = INTERPOLATE(color2, color3);
|
||||
|
||||
if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
|
||||
product1b = Q_INTERPOLATE(color6, color6, color6, color5);
|
||||
else
|
||||
if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
|
||||
product1b = Q_INTERPOLATE(color6, color5, color5, color5);
|
||||
else
|
||||
product1b = INTERPOLATE (color5, color6);
|
||||
}
|
||||
|
||||
if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
|
||||
product2a = INTERPOLATE(color2, color5);
|
||||
else
|
||||
if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
|
||||
product2a = INTERPOLATE(color2, color5);
|
||||
else
|
||||
product2a = color2;
|
||||
|
||||
if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
|
||||
product1a = INTERPOLATE(color2, color5);
|
||||
else
|
||||
if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
|
||||
product1a = INTERPOLATE(color2, color5);
|
||||
else
|
||||
product1a = color5;
|
||||
|
||||
#ifdef MSB_FIRST
|
||||
product1a = (product1a << 16) | product1b;
|
||||
product2a = (product2a << 16) | product2b;
|
||||
#else
|
||||
product1a = product1a | (product1b << 16);
|
||||
product2a = product2a | (product2b << 16);
|
||||
#endif
|
||||
|
||||
*(dP) = product1a;
|
||||
*(dP +(dstRowBytes >> 2)) = product2a;
|
||||
|
||||
bP++;
|
||||
dP++;
|
||||
}
|
||||
|
||||
dstPtr += dstRowBytes << 1;
|
||||
srcPtr += srcRowBytes;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _2xsai_h_
|
||||
#define _2xsai_h_
|
||||
|
||||
bool8 S9xBlit2xSaIFilterInit (void);
|
||||
void S9xBlit2xSaIFilterDeinit (void);
|
||||
void SuperEagle (uint8 *, int, uint8 *, int, int, int);
|
||||
void _2xSaI (uint8 *, int, uint8 *, int, int, int);
|
||||
void Super2xSaI (uint8 *, int, uint8 *, int, int, int);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,638 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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 "snes9x.h"
|
||||
#include "blit.h"
|
||||
|
||||
#define ALL_COLOR_MASK (FIRST_COLOR_MASK | SECOND_COLOR_MASK | THIRD_COLOR_MASK)
|
||||
|
||||
#ifdef GFX_MULTI_FORMAT
|
||||
static uint16 lowPixelMask = 0, qlowPixelMask = 0;
|
||||
static uint32 colorMask = 0;
|
||||
#else
|
||||
#define lowPixelMask (RGB_LOW_BITS_MASK)
|
||||
#define qlowPixelMask ((RGB_HI_BITS_MASK >> 3) | TWO_LOW_BITS_MASK)
|
||||
#define colorMask (((~RGB_HI_BITS_MASK & ALL_COLOR_MASK) << 16) | (~RGB_HI_BITS_MASK & ALL_COLOR_MASK))
|
||||
#endif
|
||||
|
||||
static snes_ntsc_t *ntsc = NULL;
|
||||
static uint8 *XDelta = NULL;
|
||||
|
||||
|
||||
bool8 S9xBlitFilterInit (void)
|
||||
{
|
||||
XDelta = new uint8[SNES_WIDTH * SNES_HEIGHT_EXTENDED * 4];
|
||||
if (!XDelta)
|
||||
return (FALSE);
|
||||
|
||||
S9xBlitClearDelta();
|
||||
|
||||
#ifdef GFX_MULTI_FORMAT
|
||||
lowPixelMask = RGB_LOW_BITS_MASK;
|
||||
qlowPixelMask = (RGB_HI_BITS_MASK >> 3) | TWO_LOW_BITS_MASK;
|
||||
colorMask = ((~RGB_HI_BITS_MASK & ALL_COLOR_MASK) << 16) | (~RGB_HI_BITS_MASK & ALL_COLOR_MASK);
|
||||
#endif
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
void S9xBlitFilterDeinit (void)
|
||||
{
|
||||
if (XDelta)
|
||||
{
|
||||
delete[] XDelta;
|
||||
XDelta = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void S9xBlitClearDelta (void)
|
||||
{
|
||||
uint32 *d = (uint32 *) XDelta;
|
||||
|
||||
for (int y = 0; y < SNES_HEIGHT_EXTENDED; y++)
|
||||
for (int x = 0; x < SNES_WIDTH; x++)
|
||||
*d++ = 0x80008000;
|
||||
}
|
||||
|
||||
bool8 S9xBlitNTSCFilterInit (void)
|
||||
{
|
||||
ntsc = (snes_ntsc_t *) malloc(sizeof(snes_ntsc_t));
|
||||
if (!ntsc)
|
||||
return (FALSE);
|
||||
|
||||
snes_ntsc_init(ntsc, &snes_ntsc_composite);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
void S9xBlitNTSCFilterDeinit (void)
|
||||
{
|
||||
if (ntsc)
|
||||
{
|
||||
free(ntsc);
|
||||
ntsc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void S9xBlitNTSCFilterSet (const snes_ntsc_setup_t *setup)
|
||||
{
|
||||
snes_ntsc_init(ntsc, setup);
|
||||
}
|
||||
|
||||
void S9xBlitPixSmall16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
width <<= 1;
|
||||
|
||||
for (; height; height--)
|
||||
{
|
||||
memcpy(dstPtr, srcPtr, width);
|
||||
srcPtr += srcRowBytes;
|
||||
dstPtr += dstRowBytes;
|
||||
}
|
||||
}
|
||||
|
||||
void S9xBlitPixScaled16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
uint8 *dstPtr2 = dstPtr + dstRowBytes, *deltaPtr = XDelta;
|
||||
dstRowBytes <<= 1;
|
||||
|
||||
for (; height; height--)
|
||||
{
|
||||
uint32 *dP1 = (uint32 *) dstPtr, *dP2 = (uint32 *) dstPtr2, *bP = (uint32 *) srcPtr, *xP = (uint32 *) deltaPtr;
|
||||
uint32 currentPixel, lastPixel, currentPixA, currentPixB, colorA, colorB;
|
||||
|
||||
for (int i = 0; i < (width >> 1); i++)
|
||||
{
|
||||
currentPixel = *bP;
|
||||
lastPixel = *xP;
|
||||
|
||||
if (currentPixel != lastPixel)
|
||||
{
|
||||
#ifdef MSB_FIRST
|
||||
colorA = (currentPixel >> 16) & 0xFFFF;
|
||||
colorB = (currentPixel ) & 0xFFFF;
|
||||
#else
|
||||
colorA = (currentPixel ) & 0xFFFF;
|
||||
colorB = (currentPixel >> 16) & 0xFFFF;
|
||||
#endif
|
||||
|
||||
currentPixA = (colorA << 16) | colorA;
|
||||
currentPixB = (colorB << 16) | colorB;
|
||||
|
||||
dP1[0] = currentPixA;
|
||||
dP1[1] = currentPixB;
|
||||
dP2[0] = currentPixA;
|
||||
dP2[1] = currentPixB;
|
||||
|
||||
*xP = *bP;
|
||||
}
|
||||
|
||||
bP++;
|
||||
xP++;
|
||||
dP1 += 2;
|
||||
dP2 += 2;
|
||||
}
|
||||
|
||||
srcPtr += srcRowBytes;
|
||||
deltaPtr += srcRowBytes;
|
||||
dstPtr += dstRowBytes;
|
||||
dstPtr2 += dstRowBytes;
|
||||
}
|
||||
}
|
||||
|
||||
void S9xBlitPixHiRes16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
width <<= 1;
|
||||
|
||||
for (; height; height--)
|
||||
{
|
||||
memcpy(dstPtr, srcPtr, width);
|
||||
dstPtr += dstRowBytes;
|
||||
memcpy(dstPtr, srcPtr, width);
|
||||
srcPtr += srcRowBytes;
|
||||
dstPtr += dstRowBytes;
|
||||
}
|
||||
}
|
||||
|
||||
void S9xBlitPixScaledTV16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
uint8 *dstPtr2 = dstPtr + dstRowBytes, *deltaPtr = XDelta;
|
||||
dstRowBytes <<= 1;
|
||||
|
||||
for (; height; height--)
|
||||
{
|
||||
uint32 *dP1 = (uint32 *) dstPtr, *dP2 = (uint32 *) dstPtr2, *bP = (uint32 *) srcPtr, *xP = (uint32 *) deltaPtr;
|
||||
uint32 currentPixel, nextPixel, currentDelta, nextDelta, colorA, colorB, product, darkened;
|
||||
|
||||
for (int i = 0; i < (width >> 1) - 1; i++)
|
||||
{
|
||||
currentPixel = *bP;
|
||||
currentDelta = *xP;
|
||||
nextPixel = *(bP + 1);
|
||||
nextDelta = *(xP + 1);
|
||||
|
||||
if ((currentPixel != currentDelta) || (nextPixel != nextDelta))
|
||||
{
|
||||
*xP = *bP;
|
||||
|
||||
#ifdef MSB_FIRST
|
||||
colorA = (currentPixel >> 16) & 0xFFFF;
|
||||
colorB = (currentPixel ) & 0xFFFF;
|
||||
#else
|
||||
colorA = (currentPixel ) & 0xFFFF;
|
||||
colorB = (currentPixel >> 16) & 0xFFFF;
|
||||
#endif
|
||||
|
||||
#ifdef MSB_FIRST
|
||||
*dP1 = product = (colorA << 16) | ((((colorA >> 1) & colorMask) + ((colorB >> 1) & colorMask) + (colorA & colorB & lowPixelMask)) );
|
||||
#else
|
||||
*dP1 = product = (colorA ) | ((((colorA >> 1) & colorMask) + ((colorB >> 1) & colorMask) + (colorA & colorB & lowPixelMask)) << 16);
|
||||
#endif
|
||||
|
||||
darkened = (product = ((product >> 1) & colorMask));
|
||||
darkened += (product = ((product >> 1) & colorMask));
|
||||
darkened += (product >> 1) & colorMask;
|
||||
|
||||
*dP2 = darkened;
|
||||
|
||||
#ifdef MSB_FIRST
|
||||
colorA = (nextPixel >> 16) & 0xFFFF;
|
||||
#else
|
||||
colorA = (nextPixel ) & 0xFFFF;
|
||||
#endif
|
||||
|
||||
#ifdef MSB_FIRST
|
||||
*(dP1 + 1) = product = (colorB << 16) | ((((colorA >> 1) & colorMask) + ((colorB >> 1) & colorMask) + (colorA & colorB & lowPixelMask)) );
|
||||
#else
|
||||
*(dP1 + 1) = product = (colorB ) | ((((colorA >> 1) & colorMask) + ((colorB >> 1) & colorMask) + (colorA & colorB & lowPixelMask)) << 16);
|
||||
#endif
|
||||
|
||||
darkened = (product = ((product >> 1) & colorMask));
|
||||
darkened += (product = ((product >> 1) & colorMask));
|
||||
darkened += (product >> 1) & colorMask;
|
||||
|
||||
*(dP2 + 1) = darkened;
|
||||
}
|
||||
|
||||
bP++;
|
||||
xP++;
|
||||
dP1 += 2;
|
||||
dP2 += 2;
|
||||
}
|
||||
|
||||
// Last 2 Pixels
|
||||
|
||||
currentPixel = *bP;
|
||||
currentDelta = *xP;
|
||||
|
||||
if (currentPixel != currentDelta)
|
||||
{
|
||||
*xP = *bP;
|
||||
|
||||
#ifdef MSB_FIRST
|
||||
colorA = (currentPixel >> 16) & 0xFFFF;
|
||||
colorB = (currentPixel ) & 0xFFFF;
|
||||
#else
|
||||
colorA = (currentPixel ) & 0xFFFF;
|
||||
colorB = (currentPixel >> 16) & 0xFFFF;
|
||||
#endif
|
||||
|
||||
#ifdef MSB_FIRST
|
||||
*dP1 = product = (colorA << 16) | ((((colorA >> 1) & colorMask) + ((colorB >> 1) & colorMask) + (colorA & colorB & lowPixelMask)) );
|
||||
#else
|
||||
*dP1 = product = (colorA ) | ((((colorA >> 1) & colorMask) + ((colorB >> 1) & colorMask) + (colorA & colorB & lowPixelMask)) << 16);
|
||||
#endif
|
||||
|
||||
darkened = (product = ((product >> 1) & colorMask));
|
||||
darkened += (product = ((product >> 1) & colorMask));
|
||||
darkened += (product >> 1) & colorMask;
|
||||
|
||||
*dP2 = darkened;
|
||||
|
||||
*(dP1 + 1) = product = (colorB << 16) | colorB;
|
||||
|
||||
darkened = (product = ((product >> 1) & colorMask));
|
||||
darkened += (product = ((product >> 1) & colorMask));
|
||||
darkened += (product >> 1) & colorMask;
|
||||
|
||||
*(dP2 + 1) = darkened;
|
||||
}
|
||||
|
||||
srcPtr += srcRowBytes;
|
||||
deltaPtr += srcRowBytes;
|
||||
dstPtr += dstRowBytes;
|
||||
dstPtr2 += dstRowBytes;
|
||||
}
|
||||
}
|
||||
|
||||
void S9xBlitPixHiResTV16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
uint8 *dstPtr2 = dstPtr + dstRowBytes;
|
||||
dstRowBytes <<= 1;
|
||||
|
||||
for (; height; height--)
|
||||
{
|
||||
uint32 *dP1 = (uint32 *) dstPtr, *dP2 = (uint32 *) dstPtr2, *bP = (uint32 *) srcPtr;
|
||||
uint32 product, darkened;
|
||||
|
||||
for (int i = 0; i < (width >> 1); i++)
|
||||
{
|
||||
product = *dP1++ = *bP++;
|
||||
darkened = (product = (product >> 1) & colorMask);
|
||||
darkened += (product = (product >> 1) & colorMask);
|
||||
*dP2++ = darkened;
|
||||
}
|
||||
|
||||
srcPtr += srcRowBytes;
|
||||
dstPtr += dstRowBytes;
|
||||
dstPtr2 += dstRowBytes;
|
||||
}
|
||||
}
|
||||
|
||||
void S9xBlitPixHiResMixedTV16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
uint8 *dstPtr2 = dstPtr + dstRowBytes, *srcPtr2 = srcPtr + srcRowBytes;
|
||||
dstRowBytes <<= 1;
|
||||
|
||||
for (; height > 1; height--)
|
||||
{
|
||||
uint16 *dP1 = (uint16 *) dstPtr, *dP2 = (uint16 *) dstPtr2, *bP1 = (uint16 *) srcPtr, *bP2 = (uint16 *) srcPtr2;
|
||||
uint16 prev, next, mixed;
|
||||
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
prev = *bP1++;
|
||||
next = *bP2++;
|
||||
mixed = prev + next + ((prev ^ next) & lowPixelMask);
|
||||
|
||||
*dP1++ = prev;
|
||||
*dP2++ = (mixed >> 1) - (mixed >> 4 & qlowPixelMask);
|
||||
}
|
||||
|
||||
srcPtr += srcRowBytes;
|
||||
srcPtr2 += srcRowBytes;
|
||||
dstPtr += dstRowBytes;
|
||||
dstPtr2 += dstRowBytes;
|
||||
}
|
||||
|
||||
// Last 1 line
|
||||
|
||||
uint16 *dP1 = (uint16 *) dstPtr, *dP2 = (uint16 *) dstPtr2, *bP1 = (uint16 *) srcPtr;
|
||||
uint16 prev, mixed;
|
||||
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
prev = *bP1++;
|
||||
mixed = prev + ((prev ^ 0) & lowPixelMask);
|
||||
|
||||
*dP1++ = prev;
|
||||
*dP2++ = (mixed >> 1) - (mixed >> 4 & qlowPixelMask);
|
||||
}
|
||||
}
|
||||
|
||||
void S9xBlitPixSmooth16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
uint8 *dstPtr2 = dstPtr + dstRowBytes, *deltaPtr = XDelta;
|
||||
uint32 lastLinePix[SNES_WIDTH << 1];
|
||||
uint8 lastLineChg[SNES_WIDTH >> 1];
|
||||
int lineBytes = width << 1;
|
||||
|
||||
dstRowBytes <<= 1;
|
||||
|
||||
memset(lastLinePix, 0, sizeof(lastLinePix));
|
||||
memset(lastLineChg, 0, sizeof(lastLineChg));
|
||||
|
||||
for (; height; height--)
|
||||
{
|
||||
uint32 *dP1 = (uint32 *) dstPtr, *dP2 = (uint32 *) dstPtr2, *bP = (uint32 *) srcPtr, *xP = (uint32 *) deltaPtr;
|
||||
uint32 *lL = lastLinePix;
|
||||
uint8 *lC = lastLineChg;
|
||||
uint32 currentPixel, nextPixel, currentDelta, nextDelta, lastPix, lastChg, thisChg, currentPixA, currentPixB, colorA, colorB, colorC;
|
||||
uint16 savePixel;
|
||||
|
||||
savePixel = *(uint16 *) (srcPtr + lineBytes);
|
||||
*(uint16 *) (srcPtr + lineBytes) = *(uint16 *) (srcPtr + lineBytes - 2);
|
||||
*(uint32 *) (deltaPtr + lineBytes) = *(uint32 *) (srcPtr + lineBytes);
|
||||
|
||||
nextPixel = *bP++;
|
||||
nextDelta = *xP++;
|
||||
|
||||
for (int i = 0; i < (width >> 1); i++)
|
||||
{
|
||||
currentPixel = nextPixel;
|
||||
currentDelta = nextDelta;
|
||||
nextPixel = *bP++;
|
||||
nextDelta = *xP++;
|
||||
lastChg = *lC;
|
||||
thisChg = (nextPixel - nextDelta) | (currentPixel - currentDelta);
|
||||
|
||||
#ifdef MSB_FIRST
|
||||
colorA = (currentPixel >> 16) & 0xFFFF;
|
||||
colorB = (currentPixel ) & 0xFFFF;
|
||||
colorC = (nextPixel >> 16) & 0xFFFF;
|
||||
|
||||
currentPixA = (colorA << 16) | ((((colorA >> 1) & colorMask) + ((colorB >> 1) & colorMask) + (colorA & colorB & lowPixelMask)) );
|
||||
currentPixB = (colorB << 16) | ((((colorC >> 1) & colorMask) + ((colorB >> 1) & colorMask) + (colorC & colorB & lowPixelMask)) );
|
||||
#else
|
||||
colorA = (currentPixel ) & 0xFFFF;
|
||||
colorB = (currentPixel >> 16) & 0xFFFF;
|
||||
colorC = (nextPixel ) & 0xFFFF;
|
||||
|
||||
currentPixA = (colorA ) | ((((colorA >> 1) & colorMask) + ((colorB >> 1) & colorMask) + (colorA & colorB & lowPixelMask)) << 16);
|
||||
currentPixB = (colorB ) | ((((colorC >> 1) & colorMask) + ((colorB >> 1) & colorMask) + (colorC & colorB & lowPixelMask)) << 16);
|
||||
#endif
|
||||
|
||||
if (thisChg | lastChg)
|
||||
{
|
||||
xP[-2] = currentPixel;
|
||||
|
||||
lastPix = lL[0];
|
||||
dP1[0] = ((currentPixA >> 1) & colorMask) + ((lastPix >> 1) & colorMask) + (currentPixA & lastPix & lowPixelMask);
|
||||
dP2[0] = currentPixA;
|
||||
lL[0] = currentPixA;
|
||||
|
||||
lastPix = lL[1];
|
||||
dP1[1] = ((currentPixB >> 1) & colorMask) + ((lastPix >> 1) & colorMask) + (currentPixB & lastPix & lowPixelMask);
|
||||
dP2[1] = currentPixB;
|
||||
lL[1] = currentPixB;
|
||||
|
||||
*lC++ = (thisChg != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
lL[0] = currentPixA;
|
||||
lL[1] = currentPixB;
|
||||
*lC++ = 0;
|
||||
}
|
||||
|
||||
lL += 2;
|
||||
dP2 += 2;
|
||||
dP1 += 2;
|
||||
}
|
||||
|
||||
*(uint16 *) (srcPtr + lineBytes) = savePixel;
|
||||
|
||||
srcPtr += srcRowBytes;
|
||||
deltaPtr += srcRowBytes;
|
||||
dstPtr += dstRowBytes;
|
||||
dstPtr2 += dstRowBytes;
|
||||
}
|
||||
}
|
||||
|
||||
void S9xBlitPixSuper2xSaI16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
Super2xSaI(srcPtr, srcRowBytes, dstPtr, dstRowBytes, width, height);
|
||||
}
|
||||
|
||||
void S9xBlitPix2xSaI16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
_2xSaI(srcPtr, srcRowBytes, dstPtr, dstRowBytes, width, height);
|
||||
}
|
||||
|
||||
void S9xBlitPixSuperEagle16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
SuperEagle(srcPtr, srcRowBytes, dstPtr, dstRowBytes, width, height);
|
||||
}
|
||||
|
||||
void S9xBlitPixEPX16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
EPX_16(srcPtr, srcRowBytes, dstPtr, dstRowBytes, width, height);
|
||||
}
|
||||
|
||||
void S9xBlitPixHQ2x16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
HQ2X_16(srcPtr, srcRowBytes, dstPtr, dstRowBytes, width, height);
|
||||
}
|
||||
|
||||
void S9xBlitPixHQ3x16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
HQ3X_16(srcPtr, srcRowBytes, dstPtr, dstRowBytes, width, height);
|
||||
}
|
||||
|
||||
void S9xBlitPixHQ4x16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
HQ4X_16(srcPtr, srcRowBytes, dstPtr, dstRowBytes, width, height);
|
||||
}
|
||||
|
||||
void S9xBlitPixNTSC16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
snes_ntsc_blit(ntsc, (SNES_NTSC_IN_T const *) srcPtr, srcRowBytes >> 1, 0, width, height, dstPtr, dstRowBytes);
|
||||
}
|
||||
|
||||
void S9xBlitPixHiResNTSC16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
snes_ntsc_blit_hires(ntsc, (SNES_NTSC_IN_T const *) srcPtr, srcRowBytes >> 1, 0, width, height, dstPtr, dstRowBytes);
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _blit_h_
|
||||
#define _blit_h_
|
||||
|
||||
#include "2xsai.h"
|
||||
#include "epx.h"
|
||||
#include "hq2x.h"
|
||||
#include "snes_ntsc.h"
|
||||
|
||||
bool8 S9xBlitFilterInit (void);
|
||||
void S9xBlitFilterDeinit (void);
|
||||
void S9xBlitClearDelta (void);
|
||||
bool8 S9xBlitNTSCFilterInit (void);
|
||||
void S9xBlitNTSCFilterDeinit (void);
|
||||
void S9xBlitNTSCFilterSet (const snes_ntsc_setup_t *);
|
||||
void S9xBlitPixSmall16 (uint8 *, int, uint8 *, int, int, int);
|
||||
void S9xBlitPixScaled16 (uint8 *, int, uint8 *, int, int, int);
|
||||
void S9xBlitPixHiRes16 (uint8 *, int, uint8 *, int, int, int);
|
||||
void S9xBlitPixScaledTV16 (uint8 *, int, uint8 *, int, int, int);
|
||||
void S9xBlitPixHiResTV16 (uint8 *, int, uint8 *, int, int, int);
|
||||
void S9xBlitPixHiResMixedTV16 (uint8 *, int, uint8 *, int, int, int);
|
||||
void S9xBlitPixSmooth16 (uint8 *, int, uint8 *, int, int, int);
|
||||
void S9xBlitPixSuperEagle16 (uint8 *, int, uint8 *, int, int, int);
|
||||
void S9xBlitPix2xSaI16 (uint8 *, int, uint8 *, int, int, int);
|
||||
void S9xBlitPixSuper2xSaI16 (uint8 *, int, uint8 *, int, int, int);
|
||||
void S9xBlitPixEPX16 (uint8 *, int, uint8 *, int, int, int);
|
||||
void S9xBlitPixHQ2x16 (uint8 *, int, uint8 *, int, int, int);
|
||||
void S9xBlitPixHQ3x16 (uint8 *, int, uint8 *, int, int, int);
|
||||
void S9xBlitPixHQ4x16 (uint8 *, int, uint8 *, int, int, int);
|
||||
void S9xBlitPixNTSC16 (uint8 *, int, uint8 *, int, int, int);
|
||||
void S9xBlitPixHiResNTSC16 (uint8 *, int, uint8 *, int, int, int);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,429 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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 "snes9x.h"
|
||||
#include "epx.h"
|
||||
|
||||
|
||||
void EPX_16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
|
||||
{
|
||||
uint16 colorX, colorA, colorB, colorC, colorD;
|
||||
uint16 *sP, *uP, *lP;
|
||||
uint32 *dP1, *dP2;
|
||||
int w;
|
||||
|
||||
height -= 2;
|
||||
|
||||
// D
|
||||
// A X C
|
||||
// B
|
||||
|
||||
// top edge
|
||||
|
||||
sP = (uint16 *) srcPtr;
|
||||
lP = (uint16 *) (srcPtr + srcRowBytes);
|
||||
dP1 = (uint32 *) dstPtr;
|
||||
dP2 = (uint32 *) (dstPtr + dstRowBytes);
|
||||
|
||||
// left edge
|
||||
|
||||
colorX = *sP;
|
||||
colorC = *++sP;
|
||||
colorB = *lP++;
|
||||
|
||||
if ((colorX != colorC) && (colorB != colorX))
|
||||
{
|
||||
#ifdef MSB_FIRST
|
||||
*dP1 = (colorX << 16) + colorX;
|
||||
*dP2 = (colorX << 16) + ((colorB == colorC) ? colorB : colorX);
|
||||
#else
|
||||
*dP1 = colorX + (colorX << 16);
|
||||
*dP2 = colorX + (((colorB == colorC) ? colorB : colorX) << 16);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
*dP1 = *dP2 = (colorX << 16) + colorX;
|
||||
|
||||
dP1++;
|
||||
dP2++;
|
||||
|
||||
//
|
||||
|
||||
for (w = width - 2; w; w--)
|
||||
{
|
||||
colorA = colorX;
|
||||
colorX = colorC;
|
||||
colorC = *++sP;
|
||||
colorB = *lP++;
|
||||
|
||||
if ((colorA != colorC) && (colorB != colorX))
|
||||
{
|
||||
#ifdef MSB_FIRST
|
||||
*dP1 = (colorX << 16) + colorX;
|
||||
*dP2 = (((colorA == colorB) ? colorA : colorX) << 16) + ((colorB == colorC) ? colorB : colorX);
|
||||
#else
|
||||
*dP1 = colorX + (colorX << 16);
|
||||
*dP2 = ((colorA == colorB) ? colorA : colorX) + (((colorB == colorC) ? colorB : colorX) << 16);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
*dP1 = *dP2 = (colorX << 16) + colorX;
|
||||
|
||||
dP1++;
|
||||
dP2++;
|
||||
}
|
||||
|
||||
// right edge
|
||||
|
||||
colorA = colorX;
|
||||
colorX = colorC;
|
||||
colorB = *lP;
|
||||
|
||||
if ((colorA != colorX) && (colorB != colorX))
|
||||
{
|
||||
#ifdef MSB_FIRST
|
||||
*dP1 = (colorX << 16) + colorX;
|
||||
*dP2 = (((colorA == colorB) ? colorA : colorX) << 16) + colorX;
|
||||
#else
|
||||
*dP1 = colorX + (colorX << 16);
|
||||
*dP2 = ((colorA == colorB) ? colorA : colorX) + (colorX << 16);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
*dP1 = *dP2 = (colorX << 16) + colorX;
|
||||
|
||||
srcPtr += srcRowBytes;
|
||||
dstPtr += dstRowBytes << 1;
|
||||
|
||||
//
|
||||
|
||||
for (; height; height--)
|
||||
{
|
||||
sP = (uint16 *) srcPtr;
|
||||
uP = (uint16 *) (srcPtr - srcRowBytes);
|
||||
lP = (uint16 *) (srcPtr + srcRowBytes);
|
||||
dP1 = (uint32 *) dstPtr;
|
||||
dP2 = (uint32 *) (dstPtr + dstRowBytes);
|
||||
|
||||
// left edge
|
||||
|
||||
colorX = *sP;
|
||||
colorC = *++sP;
|
||||
colorB = *lP++;
|
||||
colorD = *uP++;
|
||||
|
||||
if ((colorX != colorC) && (colorB != colorD))
|
||||
{
|
||||
#ifdef MSB_FIRST
|
||||
*dP1 = (colorX << 16) + ((colorC == colorD) ? colorC : colorX);
|
||||
*dP2 = (colorX << 16) + ((colorB == colorC) ? colorB : colorX);
|
||||
#else
|
||||
*dP1 = colorX + (((colorC == colorD) ? colorC : colorX) << 16);
|
||||
*dP2 = colorX + (((colorB == colorC) ? colorB : colorX) << 16);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
*dP1 = *dP2 = (colorX << 16) + colorX;
|
||||
|
||||
dP1++;
|
||||
dP2++;
|
||||
|
||||
//
|
||||
|
||||
for (w = width - 2; w; w--)
|
||||
{
|
||||
colorA = colorX;
|
||||
colorX = colorC;
|
||||
colorC = *++sP;
|
||||
colorB = *lP++;
|
||||
colorD = *uP++;
|
||||
|
||||
if ((colorA != colorC) && (colorB != colorD))
|
||||
{
|
||||
#ifdef MSB_FIRST
|
||||
*dP1 = (((colorD == colorA) ? colorD : colorX) << 16) + ((colorC == colorD) ? colorC : colorX);
|
||||
*dP2 = (((colorA == colorB) ? colorA : colorX) << 16) + ((colorB == colorC) ? colorB : colorX);
|
||||
#else
|
||||
*dP1 = ((colorD == colorA) ? colorD : colorX) + (((colorC == colorD) ? colorC : colorX) << 16);
|
||||
*dP2 = ((colorA == colorB) ? colorA : colorX) + (((colorB == colorC) ? colorB : colorX) << 16);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
*dP1 = *dP2 = (colorX << 16) + colorX;
|
||||
|
||||
dP1++;
|
||||
dP2++;
|
||||
}
|
||||
|
||||
// right edge
|
||||
|
||||
colorA = colorX;
|
||||
colorX = colorC;
|
||||
colorB = *lP;
|
||||
colorD = *uP;
|
||||
|
||||
if ((colorA != colorX) && (colorB != colorD))
|
||||
{
|
||||
#ifdef MSB_FIRST
|
||||
*dP1 = (((colorD == colorA) ? colorD : colorX) << 16) + colorX;
|
||||
*dP2 = (((colorA == colorB) ? colorA : colorX) << 16) + colorX;
|
||||
#else
|
||||
*dP1 = ((colorD == colorA) ? colorD : colorX) + (colorX << 16);
|
||||
*dP2 = ((colorA == colorB) ? colorA : colorX) + (colorX << 16);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
*dP1 = *dP2 = (colorX << 16) + colorX;
|
||||
|
||||
srcPtr += srcRowBytes;
|
||||
dstPtr += dstRowBytes << 1;
|
||||
}
|
||||
|
||||
// bottom edge
|
||||
|
||||
sP = (uint16 *) srcPtr;
|
||||
uP = (uint16 *) (srcPtr - srcRowBytes);
|
||||
dP1 = (uint32 *) dstPtr;
|
||||
dP2 = (uint32 *) (dstPtr + dstRowBytes);
|
||||
|
||||
// left edge
|
||||
|
||||
colorX = *sP;
|
||||
colorC = *++sP;
|
||||
colorD = *uP++;
|
||||
|
||||
if ((colorX != colorC) && (colorX != colorD))
|
||||
{
|
||||
#ifdef MSB_FIRST
|
||||
*dP1 = (colorX << 16) + ((colorC == colorD) ? colorC : colorX);
|
||||
*dP2 = (colorX << 16) + colorX;
|
||||
#else
|
||||
*dP1 = colorX + (((colorC == colorD) ? colorC : colorX) << 16);
|
||||
*dP2 = colorX + (colorX << 16);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
*dP1 = *dP2 = (colorX << 16) + colorX;
|
||||
|
||||
dP1++;
|
||||
dP2++;
|
||||
|
||||
//
|
||||
|
||||
for (w = width - 2; w; w--)
|
||||
{
|
||||
colorA = colorX;
|
||||
colorX = colorC;
|
||||
colorC = *++sP;
|
||||
colorD = *uP++;
|
||||
|
||||
if ((colorA != colorC) && (colorX != colorD))
|
||||
{
|
||||
#ifdef MSB_FIRST
|
||||
*dP1 = (((colorD == colorA) ? colorD : colorX) << 16) + ((colorC == colorD) ? colorC : colorX);
|
||||
*dP2 = (colorX << 16) + colorX;
|
||||
#else
|
||||
*dP1 = ((colorD == colorA) ? colorD : colorX) + (((colorC == colorD) ? colorC : colorX) << 16);
|
||||
*dP2 = colorX + (colorX << 16);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
*dP1 = *dP2 = (colorX << 16) + colorX;
|
||||
|
||||
dP1++;
|
||||
dP2++;
|
||||
}
|
||||
|
||||
// right edge
|
||||
|
||||
colorA = colorX;
|
||||
colorX = colorC;
|
||||
colorD = *uP;
|
||||
|
||||
if ((colorA != colorX) && (colorX != colorD))
|
||||
{
|
||||
#ifdef MSB_FIRST
|
||||
*dP1 = (((colorD == colorA) ? colorD : colorX) << 16) + colorX;
|
||||
*dP2 = (colorX << 16) + colorX;
|
||||
#else
|
||||
*dP1 = ((colorD == colorA) ? colorD : colorX) + (colorX << 16);
|
||||
*dP2 = colorX + (colorX << 16);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
*dP1 = *dP2 = (colorX << 16) + colorX;
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _epx_h_
|
||||
#define _epx_h_
|
||||
|
||||
void EPX_16 (uint8 *, int, uint8 *, int, int, int);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,187 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _hq2x_h_
|
||||
#define _hq2x_h_
|
||||
|
||||
bool8 S9xBlitHQ2xFilterInit (void);
|
||||
void S9xBlitHQ2xFilterDeinit (void);
|
||||
void HQ2X_16 (uint8 *, uint32, uint8 *, uint32, int, int);
|
||||
void HQ3X_16 (uint8 *, uint32, uint8 *, uint32, int, int);
|
||||
void HQ4X_16 (uint8 *, uint32, uint8 *, uint32, int, int);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,504 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
|
@ -0,0 +1,251 @@
|
|||
/* snes_ntsc 0.2.2. http://www.slack.net/~ant/ */
|
||||
|
||||
#include "snes_ntsc.h"
|
||||
|
||||
/* Copyright (C) 2006-2007 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
snes_ntsc_setup_t const snes_ntsc_monochrome = { 0,-1, 0, 0,.2, 0,.2,-.2,-.2,-1, 1, 0, 0 };
|
||||
snes_ntsc_setup_t const snes_ntsc_composite = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 };
|
||||
snes_ntsc_setup_t const snes_ntsc_svideo = { 0, 0, 0, 0,.2, 0,.2, -1, -1, 0, 1, 0, 0 };
|
||||
snes_ntsc_setup_t const snes_ntsc_rgb = { 0, 0, 0, 0,.2, 0,.7, -1, -1,-1, 1, 0, 0 };
|
||||
|
||||
#define alignment_count 3
|
||||
#define burst_count 3
|
||||
#define rescale_in 8
|
||||
#define rescale_out 7
|
||||
|
||||
#define artifacts_mid 1.0f
|
||||
#define fringing_mid 1.0f
|
||||
#define std_decoder_hue 0
|
||||
|
||||
#define rgb_bits 7 /* half normal range to allow for doubled hires pixels */
|
||||
#define gamma_size 32
|
||||
|
||||
#include "snes_ntsc_impl.h"
|
||||
|
||||
/* 3 input pixels -> 8 composite samples */
|
||||
pixel_info_t const snes_ntsc_pixels [alignment_count] = {
|
||||
{ PIXEL_OFFSET( -4, -9 ), { 1, 1, .6667f, 0 } },
|
||||
{ PIXEL_OFFSET( -2, -7 ), { .3333f, 1, 1, .3333f } },
|
||||
{ PIXEL_OFFSET( 0, -5 ), { 0, .6667f, 1, 1 } },
|
||||
};
|
||||
|
||||
static void merge_kernel_fields( snes_ntsc_rgb_t* io )
|
||||
{
|
||||
int n;
|
||||
for ( n = burst_size; n; --n )
|
||||
{
|
||||
snes_ntsc_rgb_t p0 = io [burst_size * 0] + rgb_bias;
|
||||
snes_ntsc_rgb_t p1 = io [burst_size * 1] + rgb_bias;
|
||||
snes_ntsc_rgb_t p2 = io [burst_size * 2] + rgb_bias;
|
||||
/* merge colors without losing precision */
|
||||
io [burst_size * 0] =
|
||||
((p0 + p1 - ((p0 ^ p1) & snes_ntsc_rgb_builder)) >> 1) - rgb_bias;
|
||||
io [burst_size * 1] =
|
||||
((p1 + p2 - ((p1 ^ p2) & snes_ntsc_rgb_builder)) >> 1) - rgb_bias;
|
||||
io [burst_size * 2] =
|
||||
((p2 + p0 - ((p2 ^ p0) & snes_ntsc_rgb_builder)) >> 1) - rgb_bias;
|
||||
++io;
|
||||
}
|
||||
}
|
||||
|
||||
static void correct_errors( snes_ntsc_rgb_t color, snes_ntsc_rgb_t* out )
|
||||
{
|
||||
int n;
|
||||
for ( n = burst_count; n; --n )
|
||||
{
|
||||
unsigned i;
|
||||
for ( i = 0; i < rgb_kernel_size / 2; i++ )
|
||||
{
|
||||
snes_ntsc_rgb_t error = color -
|
||||
out [i ] - out [(i+12)%14+14] - out [(i+10)%14+28] -
|
||||
out [i + 7] - out [i + 5 +14] - out [i + 3 +28];
|
||||
DISTRIBUTE_ERROR( i+3+28, i+5+14, i+7 );
|
||||
}
|
||||
out += alignment_count * rgb_kernel_size;
|
||||
}
|
||||
}
|
||||
|
||||
void snes_ntsc_init( snes_ntsc_t* ntsc, snes_ntsc_setup_t const* setup )
|
||||
{
|
||||
int merge_fields;
|
||||
int entry;
|
||||
init_t impl;
|
||||
if ( !setup )
|
||||
setup = &snes_ntsc_composite;
|
||||
init( &impl, setup );
|
||||
|
||||
merge_fields = setup->merge_fields;
|
||||
if ( setup->artifacts <= -1 && setup->fringing <= -1 )
|
||||
merge_fields = 1;
|
||||
|
||||
for ( entry = 0; entry < snes_ntsc_palette_size; entry++ )
|
||||
{
|
||||
/* Reduce number of significant bits of source color. Clearing the
|
||||
low bits of R and B were least notictable. Modifying green was too
|
||||
noticeable. */
|
||||
int ir = entry >> 8 & 0x1E;
|
||||
int ig = entry >> 4 & 0x1F;
|
||||
int ib = entry << 1 & 0x1E;
|
||||
|
||||
#if SNES_NTSC_BSNES_COLORTBL
|
||||
if ( setup->bsnes_colortbl )
|
||||
{
|
||||
int bgr15 = (ib << 10) | (ig << 5) | ir;
|
||||
unsigned long rgb16 = setup->bsnes_colortbl [bgr15];
|
||||
ir = rgb16 >> 11 & 0x1E;
|
||||
ig = rgb16 >> 6 & 0x1F;
|
||||
ib = rgb16 & 0x1E;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
float rr = impl.to_float [ir];
|
||||
float gg = impl.to_float [ig];
|
||||
float bb = impl.to_float [ib];
|
||||
|
||||
float y, i, q = RGB_TO_YIQ( rr, gg, bb, y, i );
|
||||
|
||||
int r, g, b = YIQ_TO_RGB( y, i, q, impl.to_rgb, int, r, g );
|
||||
snes_ntsc_rgb_t rgb = PACK_RGB( r, g, b );
|
||||
|
||||
snes_ntsc_rgb_t* out = ntsc->table [entry];
|
||||
gen_kernel( &impl, y, i, q, out );
|
||||
if ( merge_fields )
|
||||
merge_kernel_fields( out );
|
||||
correct_errors( rgb, out );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SNES_NTSC_NO_BLITTERS
|
||||
|
||||
void snes_ntsc_blit( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input, long in_row_width,
|
||||
int burst_phase, int in_width, int in_height, void* rgb_out, long out_pitch )
|
||||
{
|
||||
int chunk_count = (in_width - 1) / snes_ntsc_in_chunk;
|
||||
for ( ; in_height; --in_height )
|
||||
{
|
||||
SNES_NTSC_IN_T const* line_in = input;
|
||||
SNES_NTSC_BEGIN_ROW( ntsc, burst_phase,
|
||||
snes_ntsc_black, snes_ntsc_black, SNES_NTSC_ADJ_IN( *line_in ) );
|
||||
snes_ntsc_out_t* restrict line_out = (snes_ntsc_out_t*) rgb_out;
|
||||
int n;
|
||||
++line_in;
|
||||
|
||||
for ( n = chunk_count; n; --n )
|
||||
{
|
||||
/* order of input and output pixels must not be altered */
|
||||
SNES_NTSC_COLOR_IN( 0, SNES_NTSC_ADJ_IN( line_in [0] ) );
|
||||
SNES_NTSC_RGB_OUT( 0, line_out [0], SNES_NTSC_OUT_DEPTH );
|
||||
SNES_NTSC_RGB_OUT( 1, line_out [1], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
SNES_NTSC_COLOR_IN( 1, SNES_NTSC_ADJ_IN( line_in [1] ) );
|
||||
SNES_NTSC_RGB_OUT( 2, line_out [2], SNES_NTSC_OUT_DEPTH );
|
||||
SNES_NTSC_RGB_OUT( 3, line_out [3], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
SNES_NTSC_COLOR_IN( 2, SNES_NTSC_ADJ_IN( line_in [2] ) );
|
||||
SNES_NTSC_RGB_OUT( 4, line_out [4], SNES_NTSC_OUT_DEPTH );
|
||||
SNES_NTSC_RGB_OUT( 5, line_out [5], SNES_NTSC_OUT_DEPTH );
|
||||
SNES_NTSC_RGB_OUT( 6, line_out [6], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
line_in += 3;
|
||||
line_out += 7;
|
||||
}
|
||||
|
||||
/* finish final pixels */
|
||||
SNES_NTSC_COLOR_IN( 0, snes_ntsc_black );
|
||||
SNES_NTSC_RGB_OUT( 0, line_out [0], SNES_NTSC_OUT_DEPTH );
|
||||
SNES_NTSC_RGB_OUT( 1, line_out [1], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
SNES_NTSC_COLOR_IN( 1, snes_ntsc_black );
|
||||
SNES_NTSC_RGB_OUT( 2, line_out [2], SNES_NTSC_OUT_DEPTH );
|
||||
SNES_NTSC_RGB_OUT( 3, line_out [3], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
SNES_NTSC_COLOR_IN( 2, snes_ntsc_black );
|
||||
SNES_NTSC_RGB_OUT( 4, line_out [4], SNES_NTSC_OUT_DEPTH );
|
||||
SNES_NTSC_RGB_OUT( 5, line_out [5], SNES_NTSC_OUT_DEPTH );
|
||||
SNES_NTSC_RGB_OUT( 6, line_out [6], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
burst_phase = (burst_phase + 1) % snes_ntsc_burst_count;
|
||||
input += in_row_width;
|
||||
rgb_out = (char*) rgb_out + out_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
void snes_ntsc_blit_hires( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input, long in_row_width,
|
||||
int burst_phase, int in_width, int in_height, void* rgb_out, long out_pitch )
|
||||
{
|
||||
int chunk_count = (in_width - 2) / (snes_ntsc_in_chunk * 2);
|
||||
for ( ; in_height; --in_height )
|
||||
{
|
||||
SNES_NTSC_IN_T const* line_in = input;
|
||||
SNES_NTSC_HIRES_ROW( ntsc, burst_phase,
|
||||
snes_ntsc_black, snes_ntsc_black, snes_ntsc_black,
|
||||
SNES_NTSC_ADJ_IN( line_in [0] ),
|
||||
SNES_NTSC_ADJ_IN( line_in [1] ) );
|
||||
snes_ntsc_out_t* restrict line_out = (snes_ntsc_out_t*) rgb_out;
|
||||
int n;
|
||||
line_in += 2;
|
||||
|
||||
for ( n = chunk_count; n; --n )
|
||||
{
|
||||
/* twice as many input pixels per chunk */
|
||||
SNES_NTSC_COLOR_IN( 0, SNES_NTSC_ADJ_IN( line_in [0] ) );
|
||||
SNES_NTSC_HIRES_OUT( 0, line_out [0], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
SNES_NTSC_COLOR_IN( 1, SNES_NTSC_ADJ_IN( line_in [1] ) );
|
||||
SNES_NTSC_HIRES_OUT( 1, line_out [1], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
SNES_NTSC_COLOR_IN( 2, SNES_NTSC_ADJ_IN( line_in [2] ) );
|
||||
SNES_NTSC_HIRES_OUT( 2, line_out [2], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
SNES_NTSC_COLOR_IN( 3, SNES_NTSC_ADJ_IN( line_in [3] ) );
|
||||
SNES_NTSC_HIRES_OUT( 3, line_out [3], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
SNES_NTSC_COLOR_IN( 4, SNES_NTSC_ADJ_IN( line_in [4] ) );
|
||||
SNES_NTSC_HIRES_OUT( 4, line_out [4], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
SNES_NTSC_COLOR_IN( 5, SNES_NTSC_ADJ_IN( line_in [5] ) );
|
||||
SNES_NTSC_HIRES_OUT( 5, line_out [5], SNES_NTSC_OUT_DEPTH );
|
||||
SNES_NTSC_HIRES_OUT( 6, line_out [6], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
line_in += 6;
|
||||
line_out += 7;
|
||||
}
|
||||
|
||||
SNES_NTSC_COLOR_IN( 0, snes_ntsc_black );
|
||||
SNES_NTSC_HIRES_OUT( 0, line_out [0], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
SNES_NTSC_COLOR_IN( 1, snes_ntsc_black );
|
||||
SNES_NTSC_HIRES_OUT( 1, line_out [1], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
SNES_NTSC_COLOR_IN( 2, snes_ntsc_black );
|
||||
SNES_NTSC_HIRES_OUT( 2, line_out [2], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
SNES_NTSC_COLOR_IN( 3, snes_ntsc_black );
|
||||
SNES_NTSC_HIRES_OUT( 3, line_out [3], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
SNES_NTSC_COLOR_IN( 4, snes_ntsc_black );
|
||||
SNES_NTSC_HIRES_OUT( 4, line_out [4], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
SNES_NTSC_COLOR_IN( 5, snes_ntsc_black );
|
||||
SNES_NTSC_HIRES_OUT( 5, line_out [5], SNES_NTSC_OUT_DEPTH );
|
||||
SNES_NTSC_HIRES_OUT( 6, line_out [6], SNES_NTSC_OUT_DEPTH );
|
||||
|
||||
burst_phase = (burst_phase + 1) % snes_ntsc_burst_count;
|
||||
input += in_row_width;
|
||||
rgb_out = (char*) rgb_out + out_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,210 @@
|
|||
/* SNES NTSC video filter */
|
||||
|
||||
/* snes_ntsc 0.2.2 */
|
||||
#ifndef SNES_NTSC_H
|
||||
#define SNES_NTSC_H
|
||||
|
||||
#include "snes_ntsc_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Image parameters, ranging from -1.0 to 1.0. Actual internal values shown
|
||||
in parenthesis and should remain fairly stable in future versions. */
|
||||
typedef struct snes_ntsc_setup_t
|
||||
{
|
||||
/* Basic parameters */
|
||||
double hue; /* -1 = -180 degrees +1 = +180 degrees */
|
||||
double saturation; /* -1 = grayscale (0.0) +1 = oversaturated colors (2.0) */
|
||||
double contrast; /* -1 = dark (0.5) +1 = light (1.5) */
|
||||
double brightness; /* -1 = dark (0.5) +1 = light (1.5) */
|
||||
double sharpness; /* edge contrast enhancement/blurring */
|
||||
|
||||
/* Advanced parameters */
|
||||
double gamma; /* -1 = dark (1.5) +1 = light (0.5) */
|
||||
double resolution; /* image resolution */
|
||||
double artifacts; /* artifacts caused by color changes */
|
||||
double fringing; /* color artifacts caused by brightness changes */
|
||||
double bleed; /* color bleed (color resolution reduction) */
|
||||
int merge_fields; /* if 1, merges even and odd fields together to reduce flicker */
|
||||
float const* decoder_matrix; /* optional RGB decoder matrix, 6 elements */
|
||||
|
||||
unsigned long const* bsnes_colortbl; /* undocumented; set to 0 */
|
||||
} snes_ntsc_setup_t;
|
||||
|
||||
/* Video format presets */
|
||||
extern snes_ntsc_setup_t const snes_ntsc_composite; /* color bleeding + artifacts */
|
||||
extern snes_ntsc_setup_t const snes_ntsc_svideo; /* color bleeding only */
|
||||
extern snes_ntsc_setup_t const snes_ntsc_rgb; /* crisp image */
|
||||
extern snes_ntsc_setup_t const snes_ntsc_monochrome;/* desaturated + artifacts */
|
||||
|
||||
/* Initializes and adjusts parameters. Can be called multiple times on the same
|
||||
snes_ntsc_t object. Can pass NULL for either parameter. */
|
||||
typedef struct snes_ntsc_t snes_ntsc_t;
|
||||
void snes_ntsc_init( snes_ntsc_t* ntsc, snes_ntsc_setup_t const* setup );
|
||||
|
||||
/* Filters one or more rows of pixels. Input pixel format is set by SNES_NTSC_IN_FORMAT
|
||||
and output RGB depth is set by SNES_NTSC_OUT_DEPTH. Both default to 16-bit RGB.
|
||||
In_row_width is the number of pixels to get to the next input row. Out_pitch
|
||||
is the number of *bytes* to get to the next output row. */
|
||||
void snes_ntsc_blit( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input,
|
||||
long in_row_width, int burst_phase, int in_width, int in_height,
|
||||
void* rgb_out, long out_pitch );
|
||||
|
||||
void snes_ntsc_blit_hires( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input,
|
||||
long in_row_width, int burst_phase, int in_width, int in_height,
|
||||
void* rgb_out, long out_pitch );
|
||||
|
||||
/* Number of output pixels written by low-res blitter for given input width. Width
|
||||
might be rounded down slightly; use SNES_NTSC_IN_WIDTH() on result to find rounded
|
||||
value. Guaranteed not to round 256 down at all. */
|
||||
#define SNES_NTSC_OUT_WIDTH( in_width ) \
|
||||
((((in_width) - 1) / snes_ntsc_in_chunk + 1) * snes_ntsc_out_chunk)
|
||||
|
||||
/* Number of low-res input pixels that will fit within given output width. Might be
|
||||
rounded down slightly; use SNES_NTSC_OUT_WIDTH() on result to find rounded
|
||||
value. */
|
||||
#define SNES_NTSC_IN_WIDTH( out_width ) \
|
||||
(((out_width) / snes_ntsc_out_chunk - 1) * snes_ntsc_in_chunk + 1)
|
||||
|
||||
|
||||
/* Interface for user-defined custom blitters */
|
||||
|
||||
enum { snes_ntsc_in_chunk = 3 }; /* number of input pixels read per chunk */
|
||||
enum { snes_ntsc_out_chunk = 7 }; /* number of output pixels generated per chunk */
|
||||
enum { snes_ntsc_black = 0 }; /* palette index for black */
|
||||
enum { snes_ntsc_burst_count = 3 }; /* burst phase cycles through 0, 1, and 2 */
|
||||
|
||||
/* Begins outputting row and starts three pixels. First pixel will be cut off a bit.
|
||||
Use snes_ntsc_black for unused pixels. Declares variables, so must be before first
|
||||
statement in a block (unless you're using C++). */
|
||||
#define SNES_NTSC_BEGIN_ROW( ntsc, burst, pixel0, pixel1, pixel2 ) \
|
||||
char const* ktable = \
|
||||
(char const*) (ntsc)->table + burst * (snes_ntsc_burst_size * sizeof (snes_ntsc_rgb_t));\
|
||||
SNES_NTSC_BEGIN_ROW_6_( pixel0, pixel1, pixel2, SNES_NTSC_IN_FORMAT, ktable )
|
||||
|
||||
/* Begins input pixel */
|
||||
#define SNES_NTSC_COLOR_IN( index, color ) \
|
||||
SNES_NTSC_COLOR_IN_( index, color, SNES_NTSC_IN_FORMAT, ktable )
|
||||
|
||||
/* Generates output pixel. Bits can be 24, 16, 15, 14, 32 (treated as 24), or 0:
|
||||
24: RRRRRRRR GGGGGGGG BBBBBBBB (8-8-8 RGB)
|
||||
16: RRRRRGGG GGGBBBBB (5-6-5 RGB)
|
||||
15: RRRRRGG GGGBBBBB (5-5-5 RGB)
|
||||
14: BBBBBGG GGGRRRRR (5-5-5 BGR, native SNES format)
|
||||
0: xxxRRRRR RRRxxGGG GGGGGxxB BBBBBBBx (native internal format; x = junk bits) */
|
||||
#define SNES_NTSC_RGB_OUT( index, rgb_out, bits ) \
|
||||
SNES_NTSC_RGB_OUT_14_( index, rgb_out, bits, 1 )
|
||||
|
||||
/* Hires equivalents */
|
||||
#define SNES_NTSC_HIRES_ROW( ntsc, burst, pixel1, pixel2, pixel3, pixel4, pixel5 ) \
|
||||
char const* ktable = \
|
||||
(char const*) (ntsc)->table + burst * (snes_ntsc_burst_size * sizeof (snes_ntsc_rgb_t));\
|
||||
unsigned const snes_ntsc_pixel1_ = (pixel1);\
|
||||
snes_ntsc_rgb_t const* kernel1 = SNES_NTSC_IN_FORMAT( ktable, snes_ntsc_pixel1_ );\
|
||||
unsigned const snes_ntsc_pixel2_ = (pixel2);\
|
||||
snes_ntsc_rgb_t const* kernel2 = SNES_NTSC_IN_FORMAT( ktable, snes_ntsc_pixel2_ );\
|
||||
unsigned const snes_ntsc_pixel3_ = (pixel3);\
|
||||
snes_ntsc_rgb_t const* kernel3 = SNES_NTSC_IN_FORMAT( ktable, snes_ntsc_pixel3_ );\
|
||||
unsigned const snes_ntsc_pixel4_ = (pixel4);\
|
||||
snes_ntsc_rgb_t const* kernel4 = SNES_NTSC_IN_FORMAT( ktable, snes_ntsc_pixel4_ );\
|
||||
unsigned const snes_ntsc_pixel5_ = (pixel5);\
|
||||
snes_ntsc_rgb_t const* kernel5 = SNES_NTSC_IN_FORMAT( ktable, snes_ntsc_pixel5_ );\
|
||||
snes_ntsc_rgb_t const* kernel0 = kernel1;\
|
||||
snes_ntsc_rgb_t const* kernelx0;\
|
||||
snes_ntsc_rgb_t const* kernelx1 = kernel1;\
|
||||
snes_ntsc_rgb_t const* kernelx2 = kernel1;\
|
||||
snes_ntsc_rgb_t const* kernelx3 = kernel1;\
|
||||
snes_ntsc_rgb_t const* kernelx4 = kernel1;\
|
||||
snes_ntsc_rgb_t const* kernelx5 = kernel1
|
||||
|
||||
#define SNES_NTSC_HIRES_OUT( x, rgb_out, bits ) {\
|
||||
snes_ntsc_rgb_t raw_ =\
|
||||
kernel0 [ x ] + kernel2 [(x+5)%7+14] + kernel4 [(x+3)%7+28] +\
|
||||
kernelx0 [(x+7)%7+7] + kernelx2 [(x+5)%7+21] + kernelx4 [(x+3)%7+35] +\
|
||||
kernel1 [(x+6)%7 ] + kernel3 [(x+4)%7+14] + kernel5 [(x+2)%7+28] +\
|
||||
kernelx1 [(x+6)%7+7] + kernelx3 [(x+4)%7+21] + kernelx5 [(x+2)%7+35];\
|
||||
SNES_NTSC_CLAMP_( raw_, 0 );\
|
||||
SNES_NTSC_RGB_OUT_( rgb_out, (bits), 0 );\
|
||||
}
|
||||
|
||||
|
||||
/* private */
|
||||
enum { snes_ntsc_entry_size = 128 };
|
||||
enum { snes_ntsc_palette_size = 0x2000 };
|
||||
typedef unsigned long snes_ntsc_rgb_t;
|
||||
struct snes_ntsc_t {
|
||||
snes_ntsc_rgb_t table [snes_ntsc_palette_size] [snes_ntsc_entry_size];
|
||||
};
|
||||
enum { snes_ntsc_burst_size = snes_ntsc_entry_size / snes_ntsc_burst_count };
|
||||
|
||||
#define SNES_NTSC_RGB16( ktable, n ) \
|
||||
(snes_ntsc_rgb_t const*) (ktable + ((n & 0x001E) | (n >> 1 & 0x03E0) | (n >> 2 & 0x3C00)) * \
|
||||
(snes_ntsc_entry_size / 2 * sizeof (snes_ntsc_rgb_t)))
|
||||
|
||||
#define SNES_NTSC_RGB15( ktable, n ) \
|
||||
(snes_ntsc_rgb_t const*) (ktable + ((n & 0x001E) | (n >> 0 & 0x03E0) | (n >> 1 & 0x3C00)) * \
|
||||
(snes_ntsc_entry_size / 2 * sizeof (snes_ntsc_rgb_t)))
|
||||
|
||||
#define SNES_NTSC_BGR15( ktable, n ) \
|
||||
(snes_ntsc_rgb_t const*) (ktable + ((n << 9 & 0x3C00) | (n & 0x03E0) | (n >> 10 & 0x001E)) * \
|
||||
(snes_ntsc_entry_size / 2 * sizeof (snes_ntsc_rgb_t)))
|
||||
|
||||
/* common 3->7 ntsc macros */
|
||||
#define SNES_NTSC_BEGIN_ROW_6_( pixel0, pixel1, pixel2, ENTRY, table ) \
|
||||
unsigned const snes_ntsc_pixel0_ = (pixel0);\
|
||||
snes_ntsc_rgb_t const* kernel0 = ENTRY( table, snes_ntsc_pixel0_ );\
|
||||
unsigned const snes_ntsc_pixel1_ = (pixel1);\
|
||||
snes_ntsc_rgb_t const* kernel1 = ENTRY( table, snes_ntsc_pixel1_ );\
|
||||
unsigned const snes_ntsc_pixel2_ = (pixel2);\
|
||||
snes_ntsc_rgb_t const* kernel2 = ENTRY( table, snes_ntsc_pixel2_ );\
|
||||
snes_ntsc_rgb_t const* kernelx0;\
|
||||
snes_ntsc_rgb_t const* kernelx1 = kernel0;\
|
||||
snes_ntsc_rgb_t const* kernelx2 = kernel0
|
||||
|
||||
#define SNES_NTSC_RGB_OUT_14_( x, rgb_out, bits, shift ) {\
|
||||
snes_ntsc_rgb_t raw_ =\
|
||||
kernel0 [x ] + kernel1 [(x+12)%7+14] + kernel2 [(x+10)%7+28] +\
|
||||
kernelx0 [(x+7)%14] + kernelx1 [(x+ 5)%7+21] + kernelx2 [(x+ 3)%7+35];\
|
||||
SNES_NTSC_CLAMP_( raw_, shift );\
|
||||
SNES_NTSC_RGB_OUT_( rgb_out, bits, shift );\
|
||||
}
|
||||
|
||||
/* common ntsc macros */
|
||||
#define snes_ntsc_rgb_builder ((1L << 21) | (1 << 11) | (1 << 1))
|
||||
#define snes_ntsc_clamp_mask (snes_ntsc_rgb_builder * 3 / 2)
|
||||
#define snes_ntsc_clamp_add (snes_ntsc_rgb_builder * 0x101)
|
||||
#define SNES_NTSC_CLAMP_( io, shift ) {\
|
||||
snes_ntsc_rgb_t sub = (io) >> (9-(shift)) & snes_ntsc_clamp_mask;\
|
||||
snes_ntsc_rgb_t clamp = snes_ntsc_clamp_add - sub;\
|
||||
io |= clamp;\
|
||||
clamp -= sub;\
|
||||
io &= clamp;\
|
||||
}
|
||||
|
||||
#define SNES_NTSC_COLOR_IN_( index, color, ENTRY, table ) {\
|
||||
unsigned color_;\
|
||||
kernelx##index = kernel##index;\
|
||||
kernel##index = (color_ = (color), ENTRY( table, color_ ));\
|
||||
}
|
||||
|
||||
/* x is always zero except in snes_ntsc library */
|
||||
#define SNES_NTSC_RGB_OUT_( rgb_out, bits, x ) {\
|
||||
if ( bits == 16 )\
|
||||
rgb_out = (raw_>>(13-x)& 0xF800)|(raw_>>(8-x)&0x07E0)|(raw_>>(4-x)&0x001F);\
|
||||
if ( bits == 24 || bits == 32 )\
|
||||
rgb_out = (raw_>>(5-x)&0xFF0000)|(raw_>>(3-x)&0xFF00)|(raw_>>(1-x)&0xFF);\
|
||||
if ( bits == 15 )\
|
||||
rgb_out = (raw_>>(14-x)& 0x7C00)|(raw_>>(9-x)&0x03E0)|(raw_>>(4-x)&0x001F);\
|
||||
if ( bits == 14 )\
|
||||
rgb_out = (raw_>>(24-x)& 0x001F)|(raw_>>(9-x)&0x03E0)|(raw_<<(6+x)&0x7C00);\
|
||||
if ( bits == 0 )\
|
||||
rgb_out = raw_ << x;\
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,27 @@
|
|||
/* Configure library by modifying this file */
|
||||
|
||||
#ifndef SNES_NTSC_CONFIG_H
|
||||
#define SNES_NTSC_CONFIG_H
|
||||
|
||||
/* Format of source pixels */
|
||||
#define SNES_NTSC_IN_FORMAT SNES_NTSC_RGB15
|
||||
/* #define SNES_NTSC_IN_FORMAT SNES_NTSC_RGB16 */
|
||||
/* #define SNES_NTSC_IN_FORMAT SNES_NTSC_BGR15 */
|
||||
|
||||
/* The following affect the built-in blitter only; a custom blitter can
|
||||
handle things however it wants. */
|
||||
|
||||
/* Bits per pixel of output. Can be 15, 16, 32, or 24 (same as 32). */
|
||||
#define SNES_NTSC_OUT_DEPTH 15
|
||||
|
||||
/* Type of input pixel values */
|
||||
#define SNES_NTSC_IN_T unsigned short
|
||||
|
||||
/* Each raw pixel input value is passed through this. You might want to mask
|
||||
the pixel index if you use the high bits as flags, etc. */
|
||||
#define SNES_NTSC_ADJ_IN( in ) in
|
||||
|
||||
/* For each pixel, this is the basic operation:
|
||||
output_color = SNES_NTSC_ADJ_IN( SNES_NTSC_IN_T ) */
|
||||
|
||||
#endif
|
|
@ -0,0 +1,439 @@
|
|||
/* snes_ntsc 0.2.2. http://www.slack.net/~ant/ */
|
||||
|
||||
/* Common implementation of NTSC filters */
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
/* Copyright (C) 2006 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#define DISABLE_CORRECTION 0
|
||||
|
||||
#undef PI
|
||||
#define PI 3.14159265358979323846f
|
||||
|
||||
#ifndef LUMA_CUTOFF
|
||||
#define LUMA_CUTOFF 0.20
|
||||
#endif
|
||||
#ifndef gamma_size
|
||||
#define gamma_size 1
|
||||
#endif
|
||||
#ifndef rgb_bits
|
||||
#define rgb_bits 8
|
||||
#endif
|
||||
#ifndef artifacts_max
|
||||
#define artifacts_max (artifacts_mid * 1.5f)
|
||||
#endif
|
||||
#ifndef fringing_max
|
||||
#define fringing_max (fringing_mid * 2)
|
||||
#endif
|
||||
#ifndef STD_HUE_CONDITION
|
||||
#define STD_HUE_CONDITION( setup ) 1
|
||||
#endif
|
||||
|
||||
#define ext_decoder_hue (std_decoder_hue + 15)
|
||||
#define rgb_unit (1 << rgb_bits)
|
||||
#define rgb_offset (rgb_unit * 2 + 0.5f)
|
||||
|
||||
enum { burst_size = snes_ntsc_entry_size / burst_count };
|
||||
enum { kernel_half = 16 };
|
||||
enum { kernel_size = kernel_half * 2 + 1 };
|
||||
|
||||
typedef struct init_t
|
||||
{
|
||||
float to_rgb [burst_count * 6];
|
||||
float to_float [gamma_size];
|
||||
float contrast;
|
||||
float brightness;
|
||||
float artifacts;
|
||||
float fringing;
|
||||
float kernel [rescale_out * kernel_size * 2];
|
||||
} init_t;
|
||||
|
||||
#define ROTATE_IQ( i, q, sin_b, cos_b ) {\
|
||||
float t;\
|
||||
t = i * cos_b - q * sin_b;\
|
||||
q = i * sin_b + q * cos_b;\
|
||||
i = t;\
|
||||
}
|
||||
|
||||
static void init_filters( init_t* impl, snes_ntsc_setup_t const* setup )
|
||||
{
|
||||
#if rescale_out > 1
|
||||
float kernels [kernel_size * 2];
|
||||
#else
|
||||
float* const kernels = impl->kernel;
|
||||
#endif
|
||||
|
||||
/* generate luma (y) filter using sinc kernel */
|
||||
{
|
||||
/* sinc with rolloff (dsf) */
|
||||
float const rolloff = 1 + (float) setup->sharpness * (float) 0.032;
|
||||
float const maxh = 32;
|
||||
float const pow_a_n = (float) pow( rolloff, maxh );
|
||||
float sum;
|
||||
int i;
|
||||
/* quadratic mapping to reduce negative (blurring) range */
|
||||
float to_angle = (float) setup->resolution + 1;
|
||||
to_angle = PI / maxh * (float) LUMA_CUTOFF * (to_angle * to_angle + 1);
|
||||
|
||||
kernels [kernel_size * 3 / 2] = maxh; /* default center value */
|
||||
for ( i = 0; i < kernel_half * 2 + 1; i++ )
|
||||
{
|
||||
int x = i - kernel_half;
|
||||
float angle = x * to_angle;
|
||||
/* instability occurs at center point with rolloff very close to 1.0 */
|
||||
if ( x || pow_a_n > (float) 1.056 || pow_a_n < (float) 0.981 )
|
||||
{
|
||||
float rolloff_cos_a = rolloff * (float) cos( angle );
|
||||
float num = 1 - rolloff_cos_a -
|
||||
pow_a_n * (float) cos( maxh * angle ) +
|
||||
pow_a_n * rolloff * (float) cos( (maxh - 1) * angle );
|
||||
float den = 1 - rolloff_cos_a - rolloff_cos_a + rolloff * rolloff;
|
||||
float dsf = num / den;
|
||||
kernels [kernel_size * 3 / 2 - kernel_half + i] = dsf - (float) 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
/* apply blackman window and find sum */
|
||||
sum = 0;
|
||||
for ( i = 0; i < kernel_half * 2 + 1; i++ )
|
||||
{
|
||||
float x = PI * 2 / (kernel_half * 2) * i;
|
||||
float blackman = 0.42f - 0.5f * (float) cos( x ) + 0.08f * (float) cos( x * 2 );
|
||||
sum += (kernels [kernel_size * 3 / 2 - kernel_half + i] *= blackman);
|
||||
}
|
||||
|
||||
/* normalize kernel */
|
||||
sum = 1.0f / sum;
|
||||
for ( i = 0; i < kernel_half * 2 + 1; i++ )
|
||||
{
|
||||
int x = kernel_size * 3 / 2 - kernel_half + i;
|
||||
kernels [x] *= sum;
|
||||
/* assert( kernels [x] == kernels [x] ); catch numerical instability */
|
||||
}
|
||||
}
|
||||
|
||||
/* generate chroma (iq) filter using gaussian kernel */
|
||||
{
|
||||
float const cutoff_factor = -0.03125f;
|
||||
float cutoff = (float) setup->bleed;
|
||||
int i;
|
||||
|
||||
if ( cutoff < 0 )
|
||||
{
|
||||
/* keep extreme value accessible only near upper end of scale (1.0) */
|
||||
cutoff *= cutoff;
|
||||
cutoff *= cutoff;
|
||||
cutoff *= cutoff;
|
||||
cutoff *= -30.0f / 0.65f;
|
||||
}
|
||||
cutoff = cutoff_factor - 0.65f * cutoff_factor * cutoff;
|
||||
|
||||
for ( i = -kernel_half; i <= kernel_half; i++ )
|
||||
kernels [kernel_size / 2 + i] = (float) exp( i * i * cutoff );
|
||||
|
||||
/* normalize even and odd phases separately */
|
||||
for ( i = 0; i < 2; i++ )
|
||||
{
|
||||
float sum = 0;
|
||||
int x;
|
||||
for ( x = i; x < kernel_size; x += 2 )
|
||||
sum += kernels [x];
|
||||
|
||||
sum = 1.0f / sum;
|
||||
for ( x = i; x < kernel_size; x += 2 )
|
||||
{
|
||||
kernels [x] *= sum;
|
||||
/* assert( kernels [x] == kernels [x] ); catch numerical instability */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
printf( "luma:\n" );
|
||||
for ( i = kernel_size; i < kernel_size * 2; i++ )
|
||||
printf( "%f\n", kernels [i] );
|
||||
printf( "chroma:\n" );
|
||||
for ( i = 0; i < kernel_size; i++ )
|
||||
printf( "%f\n", kernels [i] );
|
||||
*/
|
||||
|
||||
/* generate linear rescale kernels */
|
||||
#if rescale_out > 1
|
||||
{
|
||||
float weight = 1.0f;
|
||||
float* out = impl->kernel;
|
||||
int n = rescale_out;
|
||||
do
|
||||
{
|
||||
float remain = 0;
|
||||
int i;
|
||||
weight -= 1.0f / rescale_in;
|
||||
for ( i = 0; i < kernel_size * 2; i++ )
|
||||
{
|
||||
float cur = kernels [i];
|
||||
float m = cur * weight;
|
||||
*out++ = m + remain;
|
||||
remain = cur - m;
|
||||
}
|
||||
}
|
||||
while ( --n );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static float const default_decoder [6] =
|
||||
{ 0.956f, 0.621f, -0.272f, -0.647f, -1.105f, 1.702f };
|
||||
|
||||
static void init( init_t* impl, snes_ntsc_setup_t const* setup )
|
||||
{
|
||||
impl->brightness = (float) setup->brightness * (0.5f * rgb_unit) + rgb_offset;
|
||||
impl->contrast = (float) setup->contrast * (0.5f * rgb_unit) + rgb_unit;
|
||||
#ifdef default_palette_contrast
|
||||
if ( !setup->palette )
|
||||
impl->contrast *= default_palette_contrast;
|
||||
#endif
|
||||
|
||||
impl->artifacts = (float) setup->artifacts;
|
||||
if ( impl->artifacts > 0 )
|
||||
impl->artifacts *= artifacts_max - artifacts_mid;
|
||||
impl->artifacts = impl->artifacts * artifacts_mid + artifacts_mid;
|
||||
|
||||
impl->fringing = (float) setup->fringing;
|
||||
if ( impl->fringing > 0 )
|
||||
impl->fringing *= fringing_max - fringing_mid;
|
||||
impl->fringing = impl->fringing * fringing_mid + fringing_mid;
|
||||
|
||||
init_filters( impl, setup );
|
||||
|
||||
/* generate gamma table */
|
||||
if ( gamma_size > 1 )
|
||||
{
|
||||
float const to_float = 1.0f / (gamma_size - (gamma_size > 1));
|
||||
float const gamma = 1.1333f - (float) setup->gamma * 0.5f;
|
||||
/* match common PC's 2.2 gamma to TV's 2.65 gamma */
|
||||
int i;
|
||||
for ( i = 0; i < gamma_size; i++ )
|
||||
impl->to_float [i] =
|
||||
(float) pow( i * to_float, gamma ) * impl->contrast + impl->brightness;
|
||||
}
|
||||
|
||||
/* setup decoder matricies */
|
||||
{
|
||||
float hue = (float) setup->hue * PI + PI / 180 * ext_decoder_hue;
|
||||
float sat = (float) setup->saturation + 1;
|
||||
float const* decoder = setup->decoder_matrix;
|
||||
if ( !decoder )
|
||||
{
|
||||
decoder = default_decoder;
|
||||
if ( STD_HUE_CONDITION( setup ) )
|
||||
hue += PI / 180 * (std_decoder_hue - ext_decoder_hue);
|
||||
}
|
||||
|
||||
{
|
||||
float s = (float) sin( hue ) * sat;
|
||||
float c = (float) cos( hue ) * sat;
|
||||
float* out = impl->to_rgb;
|
||||
int n;
|
||||
|
||||
n = burst_count;
|
||||
do
|
||||
{
|
||||
float const* in = decoder;
|
||||
int n = 3;
|
||||
do
|
||||
{
|
||||
float i = *in++;
|
||||
float q = *in++;
|
||||
*out++ = i * c - q * s;
|
||||
*out++ = i * s + q * c;
|
||||
}
|
||||
while ( --n );
|
||||
if ( burst_count <= 1 )
|
||||
break;
|
||||
ROTATE_IQ( s, c, 0.866025f, -0.5f ); /* +120 degrees */
|
||||
}
|
||||
while ( --n );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* kernel generation */
|
||||
|
||||
#define RGB_TO_YIQ( r, g, b, y, i ) (\
|
||||
(y = (r) * 0.299f + (g) * 0.587f + (b) * 0.114f),\
|
||||
(i = (r) * 0.596f - (g) * 0.275f - (b) * 0.321f),\
|
||||
((r) * 0.212f - (g) * 0.523f + (b) * 0.311f)\
|
||||
)
|
||||
|
||||
#define YIQ_TO_RGB( y, i, q, to_rgb, type, r, g ) (\
|
||||
r = (type) (y + to_rgb [0] * i + to_rgb [1] * q),\
|
||||
g = (type) (y + to_rgb [2] * i + to_rgb [3] * q),\
|
||||
(type) (y + to_rgb [4] * i + to_rgb [5] * q)\
|
||||
)
|
||||
|
||||
#define PACK_RGB( r, g, b ) ((r) << 21 | (g) << 11 | (b) << 1)
|
||||
|
||||
enum { rgb_kernel_size = burst_size / alignment_count };
|
||||
enum { rgb_bias = rgb_unit * 2 * snes_ntsc_rgb_builder };
|
||||
|
||||
typedef struct pixel_info_t
|
||||
{
|
||||
int offset;
|
||||
float negate;
|
||||
float kernel [4];
|
||||
} pixel_info_t;
|
||||
|
||||
#if rescale_in > 1
|
||||
#define PIXEL_OFFSET_( ntsc, scaled ) \
|
||||
(kernel_size / 2 + ntsc + (scaled != 0) + (rescale_out - scaled) % rescale_out + \
|
||||
(kernel_size * 2 * scaled))
|
||||
|
||||
#define PIXEL_OFFSET( ntsc, scaled ) \
|
||||
PIXEL_OFFSET_( ((ntsc) - (scaled) / rescale_out * rescale_in),\
|
||||
(((scaled) + rescale_out * 10) % rescale_out) ),\
|
||||
(1.0f - (((ntsc) + 100) & 2))
|
||||
#else
|
||||
#define PIXEL_OFFSET( ntsc, scaled ) \
|
||||
(kernel_size / 2 + (ntsc) - (scaled)),\
|
||||
(1.0f - (((ntsc) + 100) & 2))
|
||||
#endif
|
||||
|
||||
extern pixel_info_t const snes_ntsc_pixels [alignment_count];
|
||||
|
||||
/* Generate pixel at all burst phases and column alignments */
|
||||
static void gen_kernel( init_t* impl, float y, float i, float q, snes_ntsc_rgb_t* out )
|
||||
{
|
||||
/* generate for each scanline burst phase */
|
||||
float const* to_rgb = impl->to_rgb;
|
||||
int burst_remain = burst_count;
|
||||
y -= rgb_offset;
|
||||
do
|
||||
{
|
||||
/* Encode yiq into *two* composite signals (to allow control over artifacting).
|
||||
Convolve these with kernels which: filter respective components, apply
|
||||
sharpening, and rescale horizontally. Convert resulting yiq to rgb and pack
|
||||
into integer. Based on algorithm by NewRisingSun. */
|
||||
pixel_info_t const* pixel = snes_ntsc_pixels;
|
||||
int alignment_remain = alignment_count;
|
||||
do
|
||||
{
|
||||
/* negate is -1 when composite starts at odd multiple of 2 */
|
||||
float const yy = y * impl->fringing * pixel->negate;
|
||||
float const ic0 = (i + yy) * pixel->kernel [0];
|
||||
float const qc1 = (q + yy) * pixel->kernel [1];
|
||||
float const ic2 = (i - yy) * pixel->kernel [2];
|
||||
float const qc3 = (q - yy) * pixel->kernel [3];
|
||||
|
||||
float const factor = impl->artifacts * pixel->negate;
|
||||
float const ii = i * factor;
|
||||
float const yc0 = (y + ii) * pixel->kernel [0];
|
||||
float const yc2 = (y - ii) * pixel->kernel [2];
|
||||
|
||||
float const qq = q * factor;
|
||||
float const yc1 = (y + qq) * pixel->kernel [1];
|
||||
float const yc3 = (y - qq) * pixel->kernel [3];
|
||||
|
||||
float const* k = &impl->kernel [pixel->offset];
|
||||
int n;
|
||||
++pixel;
|
||||
for ( n = rgb_kernel_size; n; --n )
|
||||
{
|
||||
float i = k[0]*ic0 + k[2]*ic2;
|
||||
float q = k[1]*qc1 + k[3]*qc3;
|
||||
float y = k[kernel_size+0]*yc0 + k[kernel_size+1]*yc1 +
|
||||
k[kernel_size+2]*yc2 + k[kernel_size+3]*yc3 + rgb_offset;
|
||||
if ( rescale_out <= 1 )
|
||||
k--;
|
||||
else if ( k < &impl->kernel [kernel_size * 2 * (rescale_out - 1)] )
|
||||
k += kernel_size * 2 - 1;
|
||||
else
|
||||
k -= kernel_size * 2 * (rescale_out - 1) + 2;
|
||||
{
|
||||
int r, g, b = YIQ_TO_RGB( y, i, q, to_rgb, int, r, g );
|
||||
*out++ = PACK_RGB( r, g, b ) - rgb_bias;
|
||||
}
|
||||
}
|
||||
}
|
||||
while ( alignment_count > 1 && --alignment_remain );
|
||||
|
||||
if ( burst_count <= 1 )
|
||||
break;
|
||||
|
||||
to_rgb += 6;
|
||||
|
||||
ROTATE_IQ( i, q, -0.866025f, -0.5f ); /* -120 degrees */
|
||||
}
|
||||
while ( --burst_remain );
|
||||
}
|
||||
|
||||
static void correct_errors( snes_ntsc_rgb_t color, snes_ntsc_rgb_t* out );
|
||||
|
||||
#if DISABLE_CORRECTION
|
||||
#define CORRECT_ERROR( a ) { out [i] += rgb_bias; }
|
||||
#define DISTRIBUTE_ERROR( a, b, c ) { out [i] += rgb_bias; }
|
||||
#else
|
||||
#define CORRECT_ERROR( a ) { out [a] += error; }
|
||||
#define DISTRIBUTE_ERROR( a, b, c ) {\
|
||||
snes_ntsc_rgb_t fourth = (error + 2 * snes_ntsc_rgb_builder) >> 2;\
|
||||
fourth &= (rgb_bias >> 1) - snes_ntsc_rgb_builder;\
|
||||
fourth -= rgb_bias >> 2;\
|
||||
out [a] += fourth;\
|
||||
out [b] += fourth;\
|
||||
out [c] += fourth;\
|
||||
out [i] += error - (fourth * 3);\
|
||||
}
|
||||
#endif
|
||||
|
||||
#define RGB_PALETTE_OUT( rgb, out_ )\
|
||||
{\
|
||||
unsigned char* out = (out_);\
|
||||
snes_ntsc_rgb_t clamped = (rgb);\
|
||||
SNES_NTSC_CLAMP_( clamped, (8 - rgb_bits) );\
|
||||
out [0] = (unsigned char) (clamped >> 21);\
|
||||
out [1] = (unsigned char) (clamped >> 11);\
|
||||
out [2] = (unsigned char) (clamped >> 1);\
|
||||
}
|
||||
|
||||
/* blitter related */
|
||||
|
||||
#ifndef restrict
|
||||
#if defined (__GNUC__)
|
||||
#define restrict __restrict__
|
||||
#elif defined (_MSC_VER) && _MSC_VER > 1300
|
||||
#define restrict __restrict
|
||||
#else
|
||||
/* no support for restricted pointers */
|
||||
#define restrict
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#if SNES_NTSC_OUT_DEPTH <= 16
|
||||
#if USHRT_MAX == 0xFFFF
|
||||
typedef unsigned short snes_ntsc_out_t;
|
||||
#else
|
||||
#error "Need 16-bit int type"
|
||||
#endif
|
||||
|
||||
#else
|
||||
#if UINT_MAX == 0xFFFFFFFF
|
||||
typedef unsigned int snes_ntsc_out_t;
|
||||
#elif ULONG_MAX == 0xFFFFFFFF
|
||||
typedef unsigned long snes_ntsc_out_t;
|
||||
#else
|
||||
#error "Need 32-bit int type"
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,325 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _FONT_H_
|
||||
#define _FONT_H_
|
||||
|
||||
static const char *font[] =
|
||||
{
|
||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||
" . . . . .. . . ",
|
||||
" .#. .#.#. . . ... .#. . . .##. .#. .#. . . . . ",
|
||||
" .#. .#.#. .#.#. .###. .#..#. .#. .#. .#. .#. .#.#. .#. .#. ",
|
||||
" .#. .#.#. .#####. .#.#. ..#. .#.#. .#. .#. .#. .#. ..#.. .... .#. ",
|
||||
" .#. . . .#.#. .###. .#.. .#. . .#. .#. .###. .#####. .. .####. .. .#. ",
|
||||
" . .#####. .#.#. .#..#. .#.#. .#. .#. .#. ..#.. .##. .... .##. .#. ",
|
||||
" .#. .#.#. .###. . .#. .#.#. .#. .#. .#.#. .#. .#. .##. . ",
|
||||
" . . . ... . . . . . . . . .#. .. ",
|
||||
" . ",
|
||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||
" . . .. .... . .... .. .... .. .. . ",
|
||||
" .#. .#. .##. .####. .#. .####. .##. .####. .##. .##. .. .. . . .#. ",
|
||||
".#.#. .##. .#..#. ...#. .##. .#... .#.. ...#. .#..#. .#..#. .##. .##. .#. .... .#. .#.#. ",
|
||||
".#.#. .#. . .#. .##. .#.#. .###. .###. .#. .##. .#..#. .##. .##. .#. .####. .#. ..#. ",
|
||||
".#.#. .#. .#. ...#. .####. ...#. .#..#. .#. .#..#. .###. .. .. .#. .... .#. .#. ",
|
||||
".#.#. .#. .#.. .#..#. ..#. .#..#. .#..#. .#. .#..#. ..#. .##. .##. .#. .####. .#. . ",
|
||||
" .#. .###. .####. .##. .#. .##. .##. .#. .##. .##. .##. .#. .#. .... .#. .#. ",
|
||||
" . ... .... .. . .. .. . .. .. .. .#. . . . ",
|
||||
" . ",
|
||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||
" .. .. ... .. ... .... .... .. . . ... . . . . . . . . .. ",
|
||||
" .##. .##. .###. .##. .###. .####. .####. .##. .#..#. .###. .#. .#..#. .#. .#. .#. .#. .#. .##. ",
|
||||
".#..#. .#..#. .#..#. .#..#. .#..#. .#... .#... .#..#. .#..#. .#. .#. .#.#. .#. .##.##. .##..#. .#..#. ",
|
||||
".#.##. .#..#. .###. .#. . .#..#. .###. .###. .#... .####. .#. .#. .##. .#. .#.#.#. .#.#.#. .#..#. ",
|
||||
".#.##. .####. .#..#. .#. . .#..#. .#.. .#.. .#.##. .#..#. .#. . .#. .##. .#. .#...#. .#.#.#. .#..#. ",
|
||||
".#... .#..#. .#..#. .#..#. .#..#. .#... .#. .#..#. .#..#. .#. .#..#. .#.#. .#... .#. .#. .#..##. .#..#. ",
|
||||
" .##. .#..#. .###. .##. .###. .####. .#. .###. .#..#. .###. .##. .#..#. .####. .#. .#. .#. .#. .##. ",
|
||||
" .. . . ... .. ... .... . ... . . ... .. . . .... . . . . .. ",
|
||||
" ",
|
||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||
" ... .. ... .. ... . . . . . . . . . . .... ... ... . ",
|
||||
".###. .##. .###. .##. .###. .#. .#. .#. .#. .#. .#. .#..#. .#.#. .####. .###. . .###. .#. ",
|
||||
".#..#. .#..#. .#..#. .#..#. .#. .#. .#. .#. .#. .#...#. .#..#. .#.#. ...#. .#.. .#. ..#. .#.#. ",
|
||||
".#..#. .#..#. .#..#. .#.. .#. .#. .#. .#. .#. .#.#.#. .##. .#.#. .#. .#. .#. .#. . . ",
|
||||
".###. .#..#. .###. ..#. .#. .#. .#. .#. .#. .#.#.#. .#..#. .#. .#. .#. .#. .#. ",
|
||||
".#.. .##.#. .#.#. .#..#. .#. .#...#. .#.#. .##.##. .#..#. .#. .#... .#.. .#. ..#. .... ",
|
||||
".#. .##. .#..#. .##. .#. .###. .#. .#. .#. .#..#. .#. .####. .###. . .###. .####. ",
|
||||
" . ..#. . . .. . ... . . . . . . .... ... ... .... ",
|
||||
" . ",
|
||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||
" .. . . . . . . . .. ",
|
||||
".##. .#. .#. .#. .#. .#. .#. .#. .##. ",
|
||||
" .#. ... .#.. .. ..#. .. .#.#. ... .#.. .. . .#.. .#. .. .. ... .. ",
|
||||
" .#. .###. .###. .##. .###. .##. .#.. .###. .###. .##. .#. .#.#. .#. .##.##. .###. .##. ",
|
||||
" . .#..#. .#..#. .#.. .#..#. .#.##. .###. .#..#. .#..#. .#. .#. .##. .#. .#.#.#. .#..#. .#..#. ",
|
||||
" .#.##. .#..#. .#.. .#..#. .##.. .#. .##. .#..#. .#. ..#. .#.#. .#. .#...#. .#..#. .#..#. ",
|
||||
" .#.#. .###. .##. .###. .##. .#. .#... .#..#. .###. .#.#. .#..#. .###. .#. .#. .#..#. .##. ",
|
||||
" . . ... .. ... .. . .###. . . ... .#. . . ... . . . . .. ",
|
||||
" ... . ",
|
||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||
" . . . . . . ",
|
||||
" .#. .#. .#. .#. .#.#. ",
|
||||
" ... ... ... ... .#. . . . . . . . . . . .... .#. .#. .#. .#.#. ",
|
||||
".###. .###. .###. .###. .###. .#..#. .#.#. .#...#. .#..#. .#..#. .####. .##. .#. .##. . . ",
|
||||
".#..#. .#..#. .#..#. .##.. .#. .#..#. .#.#. .#.#.#. .##. .#..#. ..#. .#. .#. .#. ",
|
||||
".#..#. .#..#. .#. . ..##. .#.. .#..#. .#.#. .#.#.#. .##. .#.#. .#.. .#. .#. .#. ",
|
||||
".###. .###. .#. .###. .##. .###. .#. .#.#. .#..#. .#. .####. .#. .#. .#. ",
|
||||
".#.. ..#. . ... .. ... . . . . . .#. .... . . . ",
|
||||
" . . . ",
|
||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||
" .. ..... ",
|
||||
" .##. .#####. ... . . . . .. ",
|
||||
" .#. . .. ....#. .###. .#. .#. .#. .#.. .##. . . . ",
|
||||
" .#. .#. .##. .#####. .#. .#. .###. ... .###. .###. .. .#. .#.#.#. ",
|
||||
" . .#. .#. . .##. ....#. .#. .##. .#.#. .###. .#. .##.#. .##. .##. .#.#.#. ",
|
||||
" .#. . .#. .#. .. ...#. .#. .#. ..#. .#. .##. .#.. ..#. .#. ...#. ",
|
||||
" .#.#. .##. .#. .###. .#. .#. .#. .###. .#. .#. .####. .##. .##. ",
|
||||
" .#. .. .#. ... . . . ... . . .... .. .. ",
|
||||
" . . ",
|
||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||
" .... . . ... . . . .... . . . .. . ..... . . . ",
|
||||
" .####. .#. ..#.. .###. ...#. ..#.. ..#.. .####. .#... .... .#.#. .##..#. .#####. .#... .#. .#. ",
|
||||
" .... ...#. .#. .#####. .#. .#####. .#####. .#####. .#..#. .####. .####. .#####. .. .#. ....#. .#####. .#. .#. ",
|
||||
".####. .##. .## .#...#. .#. ...#. ..#.#. ..#.. .# .#. .#..#. ...#. .#.#. .##..#. .#. .#..#. .#..#. ",
|
||||
" .... .#. .#.# . .#. .#. .##. .#..#. .#####. .#. .#. . .#. .#. ..#. .. .#. .#. .#.#. . .#. ",
|
||||
" .#. .#. ..#. ..#.. .#.#. .#..#. ..#.. . .#. .#. ...#. .#. ...#. .#.#. .#... ...#. ",
|
||||
" .#. .#. .##. .#####. .#..#. .#..#. .#. .#. .#. .####. .#. .###. .#. .#. .###. .###. ",
|
||||
" . . .. ..... . . . . . . . .... . ... . . ... ... ",
|
||||
" ",
|
||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||
" .... .. . . . ... . . ... .... . . . ..... . . ",
|
||||
" .####. ..##. .#.#.#. .###. .#. ..#.. .###. .####. ..#.. .#. . . .#. .. .#####. .#. ..#.. ..... ",
|
||||
" .#..#. .###. .#.#.#. ..... .#. .#####. ... ...#. .#####. .#. .#.#. .#..##. ....#. .#.#. .#####. .#####. ",
|
||||
" .####. ..#. .#.#.#. .#####. .##. ..#.. .#.#. ....#. .#. .#.#. .###.. .#. .#..#. ..#.. .#. ",
|
||||
".#...#. .####. . ..#. ..#.. .#.#. .#. .#. .###. .#. .#. .#. .#.. .#. . .#. .#.#.#. .#.#. ",
|
||||
" . .#. ..#. ...#. .#. .#.. ..#. ..... .#.#. .#.#.#. .#. .#. .#. .#.... ..#. .#. .#.#.#. .#. ",
|
||||
" .#. .##. .###. .#. .#. .##. .#####. .#. .#. ..#.. .#. .#. .#. .####. .##. .#. ..#.. .#. ",
|
||||
" . .. ... . . .. ..... . . . . . . .... .. . . . ",
|
||||
" ",
|
||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||
" .. . . ... . .... .... . . . . . ..... . . . . ",
|
||||
" .##. .#. .#. .###. .#... ... .####. .####. .#..#. .#.#. .#. ..... .#####. ....#. .#.#. .#. ",
|
||||
" ..#. .#. . .#. .#. .#.##. .###. ...#. ..... .#..#. .#.#. .#. .#####. .#...#. .###.#. .#.#. .#.#. ",
|
||||
" .##. .#. . .#.#. .#####. .##.#. .#. .###. .#####. .#..#. .#.#. .#. . .#...#. . .#. ....#. . . .#. ",
|
||||
" ..#. .#..#. .##. ..#.. .#.#. ..#. ..#. ....#. . .#. .#.#. .#..#. .#...#. .#. .#. . ",
|
||||
" .##. .####. ..#.#. .#.. .#. ...#. ...#. ..#. ..#. .#.#. .#.#. .#####. ..#. ...#. ",
|
||||
" ..#. ...#. .##. . .###. .#. .#####. .####. .##. .##. .#..##. .##. .#...#. .##. .###. ",
|
||||
" . . .. ... . ..... .... .. ... . .. .. . . .. ... ",
|
||||
" ",
|
||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
//2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678/2345678
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,987 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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 "snes9x.h"
|
||||
#include "memmap.h"
|
||||
#include "fxinst.h"
|
||||
#include "fxemu.h"
|
||||
|
||||
static void FxReset (struct FxInfo_s *);
|
||||
static void fx_readRegisterSpace (void);
|
||||
static void fx_writeRegisterSpace (void);
|
||||
static void fx_updateRamBank (uint8);
|
||||
static void fx_dirtySCBR (void);
|
||||
static bool8 fx_checkStartAddress (void);
|
||||
static uint32 FxEmulate (uint32);
|
||||
static void FxCacheWriteAccess (uint16);
|
||||
static void FxFlushCache (void);
|
||||
|
||||
|
||||
void S9xInitSuperFX (void)
|
||||
{
|
||||
memset((uint8 *) &GSU, 0, sizeof(struct FxRegs_s));
|
||||
}
|
||||
|
||||
void S9xResetSuperFX (void)
|
||||
{
|
||||
// FIXME: Snes9x can't execute CPU and SuperFX at a time. Don't ask me what is 0.417 :P
|
||||
SuperFX.speedPerLine = (uint32) (0.417 * 10.5e6 * ((1.0 / (float) Memory.ROMFramesPerSecond) / ((float) (Timings.V_Max))));
|
||||
SuperFX.oneLineDone = FALSE;
|
||||
SuperFX.vFlags = 0;
|
||||
FxReset(&SuperFX);
|
||||
}
|
||||
|
||||
void S9xSetSuperFX (uint8 byte, uint16 address)
|
||||
{
|
||||
switch (address)
|
||||
{
|
||||
case 0x3030:
|
||||
if ((Memory.FillRAM[0x3030] ^ byte) & FLG_G)
|
||||
{
|
||||
Memory.FillRAM[0x3030] = byte;
|
||||
if (byte & FLG_G)
|
||||
{
|
||||
if (!SuperFX.oneLineDone)
|
||||
{
|
||||
S9xSuperFXExec();
|
||||
SuperFX.oneLineDone = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
FxFlushCache();
|
||||
}
|
||||
else
|
||||
Memory.FillRAM[0x3030] = byte;
|
||||
|
||||
break;
|
||||
|
||||
case 0x3031:
|
||||
Memory.FillRAM[0x3031] = byte;
|
||||
break;
|
||||
|
||||
case 0x3033:
|
||||
Memory.FillRAM[0x3033] = byte;
|
||||
break;
|
||||
|
||||
case 0x3034:
|
||||
Memory.FillRAM[0x3034] = byte & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x3036:
|
||||
Memory.FillRAM[0x3036] = byte & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x3037:
|
||||
Memory.FillRAM[0x3037] = byte;
|
||||
break;
|
||||
|
||||
case 0x3038:
|
||||
Memory.FillRAM[0x3038] = byte;
|
||||
fx_dirtySCBR();
|
||||
break;
|
||||
|
||||
case 0x3039:
|
||||
Memory.FillRAM[0x3039] = byte;
|
||||
break;
|
||||
|
||||
case 0x303a:
|
||||
Memory.FillRAM[0x303a] = byte;
|
||||
break;
|
||||
|
||||
case 0x303b:
|
||||
break;
|
||||
|
||||
case 0x303c:
|
||||
Memory.FillRAM[0x303c] = byte;
|
||||
fx_updateRamBank(byte);
|
||||
break;
|
||||
|
||||
case 0x303f:
|
||||
Memory.FillRAM[0x303f] = byte;
|
||||
break;
|
||||
|
||||
case 0x301f:
|
||||
Memory.FillRAM[0x301f] = byte;
|
||||
Memory.FillRAM[0x3000 + GSU_SFR] |= FLG_G;
|
||||
if (!SuperFX.oneLineDone)
|
||||
{
|
||||
S9xSuperFXExec();
|
||||
SuperFX.oneLineDone = TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
Memory.FillRAM[address] = byte;
|
||||
if (address >= 0x3100)
|
||||
FxCacheWriteAccess(address);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8 S9xGetSuperFX (uint16 address)
|
||||
{
|
||||
uint8 byte;
|
||||
|
||||
byte = Memory.FillRAM[address];
|
||||
#ifdef CPU_SHUTDOWN
|
||||
if (address == 0x3030)
|
||||
CPU.WaitAddress = CPU.PBPCAtOpcodeStart;
|
||||
#endif
|
||||
if (address == 0x3031)
|
||||
{
|
||||
S9xClearIRQ(GSU_IRQ_SOURCE);
|
||||
Memory.FillRAM[0x3031] = byte & 0x7f;
|
||||
}
|
||||
|
||||
return (byte);
|
||||
}
|
||||
|
||||
void S9xSuperFXExec (void)
|
||||
{
|
||||
if ((Memory.FillRAM[0x3000 + GSU_SFR] & FLG_G) && (Memory.FillRAM[0x3000 + GSU_SCMR] & 0x18) == 0x18)
|
||||
{
|
||||
FxEmulate((Memory.FillRAM[0x3000 + GSU_CLSR] & 1) ? SuperFX.speedPerLine * 2 : SuperFX.speedPerLine);
|
||||
|
||||
uint16 GSUStatus = Memory.FillRAM[0x3000 + GSU_SFR] | (Memory.FillRAM[0x3000 + GSU_SFR + 1] << 8);
|
||||
if ((GSUStatus & (FLG_G | FLG_IRQ)) == FLG_IRQ)
|
||||
S9xSetIRQ(GSU_IRQ_SOURCE);
|
||||
}
|
||||
}
|
||||
|
||||
static void FxReset (struct FxInfo_s *psFxInfo)
|
||||
{
|
||||
// Clear all internal variables
|
||||
memset((uint8 *) &GSU, 0, sizeof(struct FxRegs_s));
|
||||
|
||||
// Set default registers
|
||||
GSU.pvSreg = GSU.pvDreg = &R0;
|
||||
|
||||
// Set RAM and ROM pointers
|
||||
GSU.pvRegisters = psFxInfo->pvRegisters;
|
||||
GSU.nRamBanks = psFxInfo->nRamBanks;
|
||||
GSU.pvRam = psFxInfo->pvRam;
|
||||
GSU.nRomBanks = psFxInfo->nRomBanks;
|
||||
GSU.pvRom = psFxInfo->pvRom;
|
||||
GSU.vPrevScreenHeight = ~0;
|
||||
GSU.vPrevMode = ~0;
|
||||
|
||||
// The GSU can't access more than 2mb (16mbits)
|
||||
if (GSU.nRomBanks > 0x20)
|
||||
GSU.nRomBanks = 0x20;
|
||||
|
||||
// Clear FxChip register space
|
||||
memset(GSU.pvRegisters, 0, 0x300);
|
||||
|
||||
// Set FxChip version Number
|
||||
GSU.pvRegisters[0x3b] = 0;
|
||||
|
||||
// Make ROM bank table
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
uint32 b = i & 0x7f;
|
||||
|
||||
if (b >= 0x40)
|
||||
{
|
||||
if (GSU.nRomBanks > 1)
|
||||
b %= GSU.nRomBanks;
|
||||
else
|
||||
b &= 1;
|
||||
|
||||
GSU.apvRomBank[i] = &GSU.pvRom[b << 16];
|
||||
}
|
||||
else
|
||||
{
|
||||
b %= GSU.nRomBanks * 2;
|
||||
GSU.apvRomBank[i] = &GSU.pvRom[(b << 16) + 0x200000];
|
||||
}
|
||||
}
|
||||
|
||||
// Make RAM bank table
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
GSU.apvRamBank[i] = &GSU.pvRam[(i % GSU.nRamBanks) << 16];
|
||||
GSU.apvRomBank[0x70 + i] = GSU.apvRamBank[i];
|
||||
}
|
||||
|
||||
// Start with a nop in the pipe
|
||||
GSU.vPipe = 0x01;
|
||||
|
||||
// Set pointer to GSU cache
|
||||
GSU.pvCache = &GSU.pvRegisters[0x100];
|
||||
|
||||
fx_readRegisterSpace();
|
||||
}
|
||||
|
||||
static void fx_readRegisterSpace (void)
|
||||
{
|
||||
static uint32 avHeight[] = { 128, 160, 192, 256 };
|
||||
static uint32 avMult[] = { 16, 32, 32, 64 };
|
||||
|
||||
uint8 *p;
|
||||
int n;
|
||||
|
||||
GSU.vErrorCode = 0;
|
||||
|
||||
// Update R0-R15
|
||||
p = GSU.pvRegisters;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
GSU.avReg[i] = *p++;
|
||||
GSU.avReg[i] += ((uint32) (*p++)) << 8;
|
||||
}
|
||||
|
||||
// Update other registers
|
||||
p = GSU.pvRegisters;
|
||||
GSU.vStatusReg = (uint32) p[GSU_SFR];
|
||||
GSU.vStatusReg |= ((uint32) p[GSU_SFR + 1]) << 8;
|
||||
GSU.vPrgBankReg = (uint32) p[GSU_PBR];
|
||||
GSU.vRomBankReg = (uint32) p[GSU_ROMBR];
|
||||
GSU.vRamBankReg = ((uint32) p[GSU_RAMBR]) & (FX_RAM_BANKS - 1);
|
||||
GSU.vCacheBaseReg = (uint32) p[GSU_CBR];
|
||||
GSU.vCacheBaseReg |= ((uint32) p[GSU_CBR + 1]) << 8;
|
||||
|
||||
// Update status register variables
|
||||
GSU.vZero = !(GSU.vStatusReg & FLG_Z);
|
||||
GSU.vSign = (GSU.vStatusReg & FLG_S) << 12;
|
||||
GSU.vOverflow = (GSU.vStatusReg & FLG_OV) << 16;
|
||||
GSU.vCarry = (GSU.vStatusReg & FLG_CY) >> 2;
|
||||
|
||||
// Set bank pointers
|
||||
GSU.pvRamBank = GSU.apvRamBank[GSU.vRamBankReg & 0x3];
|
||||
GSU.pvRomBank = GSU.apvRomBank[GSU.vRomBankReg];
|
||||
GSU.pvPrgBank = GSU.apvRomBank[GSU.vPrgBankReg];
|
||||
|
||||
// Set screen pointers
|
||||
GSU.pvScreenBase = &GSU.pvRam[USEX8(p[GSU_SCBR]) << 10];
|
||||
n = (int) (!!(p[GSU_SCMR] & 0x04));
|
||||
n |= ((int) (!!(p[GSU_SCMR] & 0x20))) << 1;
|
||||
GSU.vScreenHeight = GSU.vScreenRealHeight = avHeight[n];
|
||||
GSU.vMode = p[GSU_SCMR] & 0x03;
|
||||
|
||||
if (n == 3)
|
||||
GSU.vScreenSize = (256 / 8) * (256 / 8) * 32;
|
||||
else
|
||||
GSU.vScreenSize = (GSU.vScreenHeight / 8) * (256 / 8) * avMult[GSU.vMode];
|
||||
|
||||
if (GSU.vPlotOptionReg & 0x10) // OBJ Mode (for drawing into sprites)
|
||||
GSU.vScreenHeight = 256;
|
||||
|
||||
if (GSU.pvScreenBase + GSU.vScreenSize > GSU.pvRam + (GSU.nRamBanks * 65536))
|
||||
GSU.pvScreenBase = GSU.pvRam + (GSU.nRamBanks * 65536) - GSU.vScreenSize;
|
||||
|
||||
GSU.pfPlot = fx_PlotTable[GSU.vMode];
|
||||
GSU.pfRpix = fx_PlotTable[GSU.vMode + 5];
|
||||
|
||||
fx_OpcodeTable[0x04c] = GSU.pfPlot;
|
||||
fx_OpcodeTable[0x14c] = GSU.pfRpix;
|
||||
fx_OpcodeTable[0x24c] = GSU.pfPlot;
|
||||
fx_OpcodeTable[0x34c] = GSU.pfRpix;
|
||||
|
||||
fx_computeScreenPointers();
|
||||
|
||||
//fx_backupCache();
|
||||
}
|
||||
|
||||
static void fx_writeRegisterSpace (void)
|
||||
{
|
||||
uint8 *p;
|
||||
|
||||
p = GSU.pvRegisters;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
*p++ = (uint8) GSU.avReg[i];
|
||||
*p++ = (uint8) (GSU.avReg[i] >> 8);
|
||||
}
|
||||
|
||||
// Update status register
|
||||
if (USEX16(GSU.vZero) == 0)
|
||||
SF(Z);
|
||||
else
|
||||
CF(Z);
|
||||
|
||||
if (GSU.vSign & 0x8000)
|
||||
SF(S);
|
||||
else
|
||||
CF(S);
|
||||
|
||||
if (GSU.vOverflow >= 0x8000 || GSU.vOverflow < -0x8000)
|
||||
SF(OV);
|
||||
else
|
||||
CF(OV);
|
||||
|
||||
if (GSU.vCarry)
|
||||
SF(CY);
|
||||
else
|
||||
CF(CY);
|
||||
|
||||
p = GSU.pvRegisters;
|
||||
p[GSU_SFR] = (uint8) GSU.vStatusReg;
|
||||
p[GSU_SFR + 1] = (uint8) (GSU.vStatusReg >> 8);
|
||||
p[GSU_PBR] = (uint8) GSU.vPrgBankReg;
|
||||
p[GSU_ROMBR] = (uint8) GSU.vRomBankReg;
|
||||
p[GSU_RAMBR] = (uint8) GSU.vRamBankReg;
|
||||
p[GSU_CBR] = (uint8) GSU.vCacheBaseReg;
|
||||
p[GSU_CBR + 1] = (uint8) (GSU.vCacheBaseReg >> 8);
|
||||
|
||||
//fx_restoreCache();
|
||||
}
|
||||
|
||||
// Update RamBankReg and RAM Bank pointer
|
||||
static void fx_updateRamBank (uint8 byte)
|
||||
{
|
||||
// Update BankReg and Bank pointer
|
||||
GSU.vRamBankReg = (uint32) byte & (FX_RAM_BANKS - 1);
|
||||
GSU.pvRamBank = GSU.apvRamBank[byte & 0x3];
|
||||
}
|
||||
|
||||
// SCBR write seen. We need to update our cached screen pointers
|
||||
static void fx_dirtySCBR (void)
|
||||
{
|
||||
GSU.vSCBRDirty = TRUE;
|
||||
}
|
||||
|
||||
static bool8 fx_checkStartAddress (void)
|
||||
{
|
||||
// Check if we start inside the cache
|
||||
if (GSU.bCacheActive && R15 >= GSU.vCacheBaseReg && R15 < (GSU.vCacheBaseReg + 512))
|
||||
return (TRUE);
|
||||
|
||||
/*
|
||||
// Check if we're in an unused area
|
||||
if (GSU.vPrgBankReg < 0x40 && R15 < 0x8000)
|
||||
return (FALSE);
|
||||
*/
|
||||
|
||||
if (GSU.vPrgBankReg >= 0x60 && GSU.vPrgBankReg <= 0x6f)
|
||||
return (FALSE);
|
||||
|
||||
if (GSU.vPrgBankReg >= 0x74)
|
||||
return (FALSE);
|
||||
|
||||
// Check if we're in RAM and the RAN flag is not set
|
||||
if (GSU.vPrgBankReg >= 0x70 && GSU.vPrgBankReg <= 0x73 && !(SCMR & (1 << 3)))
|
||||
return (FALSE);
|
||||
|
||||
// If not, we're in ROM, so check if the RON flag is set
|
||||
if (!(SCMR & (1 << 4)))
|
||||
return (FALSE);
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
// Execute until the next stop instruction
|
||||
static uint32 FxEmulate (uint32 nInstructions)
|
||||
{
|
||||
uint32 vCount;
|
||||
|
||||
// Read registers and initialize GSU session
|
||||
fx_readRegisterSpace();
|
||||
|
||||
// Check if the start address is valid
|
||||
if (!fx_checkStartAddress())
|
||||
{
|
||||
CF(G);
|
||||
fx_writeRegisterSpace();
|
||||
/*
|
||||
GSU.vIllegalAddress = (GSU.vPrgBankReg << 24) | R15;
|
||||
return (FX_ERROR_ILLEGAL_ADDRESS);
|
||||
*/
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
// Execute GSU session
|
||||
CF(IRQ);
|
||||
|
||||
/*
|
||||
if (GSU.bBreakPoint)
|
||||
vCount = fx_run_to_breakpoint(nInstructions);
|
||||
else
|
||||
*/
|
||||
vCount = fx_run(nInstructions);
|
||||
|
||||
// Store GSU registers
|
||||
fx_writeRegisterSpace();
|
||||
|
||||
// Check for error code
|
||||
if (GSU.vErrorCode)
|
||||
return (GSU.vErrorCode);
|
||||
else
|
||||
return (vCount);
|
||||
}
|
||||
|
||||
void fx_computeScreenPointers (void)
|
||||
{
|
||||
if (GSU.vMode != GSU.vPrevMode || GSU.vPrevScreenHeight != GSU.vScreenHeight || GSU.vSCBRDirty)
|
||||
{
|
||||
GSU.vSCBRDirty = FALSE;
|
||||
|
||||
// Make a list of pointers to the start of each screen column
|
||||
switch (GSU.vScreenHeight)
|
||||
{
|
||||
case 128:
|
||||
switch (GSU.vMode)
|
||||
{
|
||||
case 0:
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4);
|
||||
GSU.x[i] = i << 8;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5);
|
||||
GSU.x[i] = i << 9;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6);
|
||||
GSU.x[i] = i << 10;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 160:
|
||||
switch (GSU.vMode)
|
||||
{
|
||||
case 0:
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4);
|
||||
GSU.x[i] = (i << 8) + (i << 6);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5);
|
||||
GSU.x[i] = (i << 9) + (i << 7);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6);
|
||||
GSU.x[i] = (i << 10) + (i << 8);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 192:
|
||||
switch (GSU.vMode)
|
||||
{
|
||||
case 0:
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4);
|
||||
GSU.x[i] = (i << 8) + (i << 7);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5);
|
||||
GSU.x[i] = (i << 9) + (i << 8);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6);
|
||||
GSU.x[i] = (i << 10) + (i << 9);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 256:
|
||||
switch (GSU.vMode)
|
||||
{
|
||||
case 0:
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
GSU.apvScreen[i] = GSU.pvScreenBase + ((i & 0x10) << 9) + ((i & 0xf) << 8);
|
||||
GSU.x[i] = ((i & 0x10) << 8) + ((i & 0xf) << 4);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
GSU.apvScreen[i] = GSU.pvScreenBase + ((i & 0x10) << 10) + ((i & 0xf) << 9);
|
||||
GSU.x[i] = ((i & 0x10) << 9) + ((i & 0xf) << 5);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
GSU.apvScreen[i] = GSU.pvScreenBase + ((i & 0x10) << 11) + ((i & 0xf) << 10);
|
||||
GSU.x[i] = ((i & 0x10) << 10) + ((i & 0xf) << 6);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
GSU.vPrevMode = GSU.vMode;
|
||||
GSU.vPrevScreenHeight = GSU.vScreenHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// Write access to the cache
|
||||
static void FxCacheWriteAccess (uint16 vAddress)
|
||||
{
|
||||
/*
|
||||
if (!GSU.bCacheActive)
|
||||
{
|
||||
uint8 v = GSU.pvCache[GSU.pvCache[vAddress & 0x1ff];
|
||||
fx_setCache();
|
||||
GSU.pvCache[GSU.pvCache[vAddress & 0x1ff] = v;
|
||||
}
|
||||
*/
|
||||
|
||||
if ((vAddress & 0x00f) == 0x00f)
|
||||
GSU.vCacheFlags |= 1 << ((vAddress & 0x1f0) >> 4);
|
||||
}
|
||||
|
||||
static void FxFlushCache (void)
|
||||
{
|
||||
GSU.vCacheFlags = 0;
|
||||
GSU.vCacheBaseReg = 0;
|
||||
GSU.bCacheActive = FALSE;
|
||||
//GSU.vPipe = 0x1;
|
||||
}
|
||||
|
||||
void fx_flushCache (void)
|
||||
{
|
||||
//fx_restoreCache();
|
||||
GSU.vCacheFlags = 0;
|
||||
GSU.bCacheActive = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
static void fx_setCache (void)
|
||||
{
|
||||
uint32 c;
|
||||
|
||||
GSU.bCacheActive = TRUE;
|
||||
GSU.pvRegisters[0x3e] &= 0xf0;
|
||||
|
||||
c = (uint32) GSU.pvRegisters[0x3e];
|
||||
c |= ((uint32) GSU.pvRegisters[0x3f]) << 8;
|
||||
if (c == GSU.vCacheBaseReg)
|
||||
return;
|
||||
|
||||
GSU.vCacheBaseReg = c;
|
||||
GSU.vCacheFlags = 0;
|
||||
|
||||
if (c < (0x10000 - 512))
|
||||
{
|
||||
const uint8 *t = &ROM(c);
|
||||
memcpy(GSU.pvCache, t, 512);
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint8 *t1, *t2;
|
||||
uint32 i = 0x10000 - c;
|
||||
|
||||
t1 = &ROM(c);
|
||||
t2 = &ROM(0);
|
||||
memcpy(GSU.pvCache, t1, i);
|
||||
memcpy(&GSU.pvCache[i], t2, 512 - i);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
static void fx_backupCache (void)
|
||||
{
|
||||
uint32 v = GSU.vCacheFlags;
|
||||
uint32 c = USEX16(GSU.vCacheBaseReg);
|
||||
|
||||
if (v)
|
||||
{
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
if (v & 1)
|
||||
{
|
||||
if (c < (0x10000 - 16))
|
||||
{
|
||||
uint8 *t = &GSU.pvPrgBank[c];
|
||||
memcpy(&GSU.avCacheBackup[i << 4], t, 16);
|
||||
memcpy(t, &GSU.pvCache[i << 4], 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8 *t1, *t2;
|
||||
uint32 a = 0x10000 - c;
|
||||
|
||||
t1 = &GSU.pvPrgBank[c];
|
||||
t2 = &GSU.pvPrgBank[0];
|
||||
memcpy(&GSU.avCacheBackup[i << 4], t1, a);
|
||||
memcpy(t1, &GSU.pvCache[i << 4], a);
|
||||
memcpy(&GSU.avCacheBackup[(i << 4) + a], t2, 16 - a);
|
||||
memcpy(t2, &GSU.pvCache[(i << 4) + a], 16 - a);
|
||||
}
|
||||
}
|
||||
|
||||
c = USEX16(c + 16);
|
||||
v >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
static void fx_restoreCache()
|
||||
{
|
||||
uint32 v = GSU.vCacheFlags;
|
||||
uint32 c = USEX16(GSU.vCacheBaseReg);
|
||||
|
||||
if (v)
|
||||
{
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
if (v & 1)
|
||||
{
|
||||
if (c < (0x10000 - 16))
|
||||
{
|
||||
uint8 *t = &GSU.pvPrgBank[c];
|
||||
memcpy(t, &GSU.avCacheBackup[i << 4], 16);
|
||||
memcpy(&GSU.pvCache[i << 4], t, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8 *t1, *t2;
|
||||
uint32 a = 0x10000 - c;
|
||||
|
||||
t1 = &GSU.pvPrgBank[c];
|
||||
t2 = &GSU.pvPrgBank[0];
|
||||
memcpy(t1, &GSU.avCacheBackup[i << 4], a);
|
||||
memcpy(&GSU.pvCache[i << 4], t1, a);
|
||||
memcpy(t2, &GSU.avCacheBackup[(i << 4) + a], 16 - a);
|
||||
memcpy(&GSU.pvCache[(i << 4) + a], t2, 16 - a);
|
||||
}
|
||||
}
|
||||
|
||||
c = USEX16(c + 16);
|
||||
v >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Breakpoints
|
||||
/*
|
||||
static void FxBreakPointSet (uint32 vAddress)
|
||||
{
|
||||
GSU.bBreakPoint = TRUE;
|
||||
GSU.vBreakPoint = USEX16(vAddress);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
static void FxBreakPointClear (void)
|
||||
{
|
||||
GSU.bBreakPoint = FALSE;
|
||||
}
|
||||
*/
|
||||
|
||||
// Step by step execution
|
||||
/*
|
||||
static uint32 FxStepOver (uint32 nInstructions)
|
||||
{
|
||||
uint32 vCount;
|
||||
|
||||
fx_readRegisterSpace();
|
||||
|
||||
if (!fx_checkStartAddress())
|
||||
{
|
||||
CF(G);
|
||||
#if 0
|
||||
GSU.vIllegalAddress = (GSU.vPrgBankReg << 24) | R15;
|
||||
return (FX_ERROR_ILLEGAL_ADDRESS);
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (PIPE >= 0xf0)
|
||||
GSU.vStepPoint = USEX16(R15 + 3);
|
||||
else
|
||||
if ((PIPE >= 0x05 && PIPE <= 0x0f) || (PIPE >= 0xa0 && PIPE <= 0xaf))
|
||||
GSU.vStepPoint = USEX16(R15 + 2);
|
||||
else
|
||||
GSU.vStepPoint = USEX16(R15 + 1);
|
||||
|
||||
vCount = fx_step_over(nInstructions);
|
||||
|
||||
fx_writeRegisterSpace();
|
||||
|
||||
if (GSU.vErrorCode)
|
||||
return (GSU.vErrorCode);
|
||||
else
|
||||
return (vCount);
|
||||
}
|
||||
*/
|
||||
|
||||
// Errors
|
||||
/*
|
||||
static int FxGetErrorCode (void)
|
||||
{
|
||||
return (GSU.vErrorCode);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
static int FxGetIllegalAddress (void)
|
||||
{
|
||||
return (GSU.vIllegalAddress);
|
||||
}
|
||||
*/
|
||||
|
||||
// Access to internal registers
|
||||
/*
|
||||
static uint32 FxGetColorRegister (void)
|
||||
{
|
||||
return (GSU.vColorReg & 0xff);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
static uint32 FxGetPlotOptionRegister (void)
|
||||
{
|
||||
return (GSU.vPlotOptionReg & 0x1f);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
static uint32 FxGetSourceRegisterIndex (void)
|
||||
{
|
||||
return (GSU.pvSreg - GSU.avReg);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
static uint32 FxGetDestinationRegisterIndex (void)
|
||||
{
|
||||
return (GSU.pvDreg - GSU.avReg);
|
||||
}
|
||||
*/
|
||||
|
||||
// Get the byte currently in the pipe
|
||||
/*
|
||||
static uint8 FxPipe (void)
|
||||
{
|
||||
return (GSU.vPipe);
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,236 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _FXEMU_H_
|
||||
#define _FXEMU_H_
|
||||
|
||||
#ifndef ZSNES_FX
|
||||
|
||||
// The FxInfo_s structure, the link between the FxEmulator and the Snes Emulator
|
||||
struct FxInfo_s
|
||||
{
|
||||
uint32 vFlags;
|
||||
uint8 *pvRegisters; // 768 bytes located in the memory at address 0x3000
|
||||
uint32 nRamBanks; // Number of 64kb-banks in GSU-RAM/BackupRAM (banks 0x70-0x73)
|
||||
uint8 *pvRam; // Pointer to GSU-RAM
|
||||
uint32 nRomBanks; // Number of 32kb-banks in Cart-ROM
|
||||
uint8 *pvRom; // Pointer to Cart-ROM
|
||||
uint32 speedPerLine;
|
||||
bool8 oneLineDone;
|
||||
};
|
||||
|
||||
extern struct FxInfo_s SuperFX;
|
||||
|
||||
void S9xInitSuperFX (void);
|
||||
void S9xSetSuperFX (uint8, uint16);
|
||||
uint8 S9xGetSuperFX (uint16);
|
||||
void fx_flushCache (void);
|
||||
void fx_computeScreenPointers (void);
|
||||
uint32 fx_run (uint32);
|
||||
|
||||
#define FX_BREAKPOINT (-1)
|
||||
#define FX_ERROR_ILLEGAL_ADDRESS (-2)
|
||||
|
||||
#else
|
||||
|
||||
#define S9xSetSuperFX S9xSuperFXWriteReg
|
||||
#define S9xGetSuperFX S9xSuperFXReadReg
|
||||
|
||||
START_EXTERN_C
|
||||
extern uint8 *SFXPlotTable;
|
||||
|
||||
void S9xSuperFXWriteReg (uint8, uint32);
|
||||
uint8 S9xSuperFXReadReg (uint32);
|
||||
void S9xSuperFXPreSaveState (void);
|
||||
void S9xSuperFXPostSaveState (void);
|
||||
void S9xSuperFXPostLoadState (void);
|
||||
END_EXTERN_C
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef ZSNES_FX
|
||||
START_EXTERN_C
|
||||
#endif
|
||||
|
||||
void S9xResetSuperFX (void);
|
||||
void S9xSuperFXExec (void);
|
||||
|
||||
#ifdef ZSNES_FX
|
||||
END_EXTERN_C
|
||||
#endif
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,546 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _FXINST_H_
|
||||
#define _FXINST_H_
|
||||
|
||||
#ifndef ZSNES_FX
|
||||
|
||||
/*
|
||||
* FxChip(GSU) register space specification
|
||||
* (Register address space 3000-32ff)
|
||||
*
|
||||
* The 16 generic 16 bit registers:
|
||||
* (Some have a special function in special circumstances)
|
||||
* 3000 - R0 default source/destination register
|
||||
* 3002 - R1 pixel plot X position register
|
||||
* 3004 - R2 pixel plot Y position register
|
||||
* 3006 - R3
|
||||
* 3008 - R4 lower 16 bit result of lmult
|
||||
* 300a - R5
|
||||
* 300c - R6 multiplier for fmult and lmult
|
||||
* 300e - R7 fixed point texel X position for merge
|
||||
* 3010 - R8 fixed point texel Y position for merge
|
||||
* 3012 - R9
|
||||
* 3014 - R10
|
||||
* 3016 - R11 return address set by link
|
||||
* 3018 - R12 loop counter
|
||||
* 301a - R13 loop point address
|
||||
* 301c - R14 rom address for getb, getbh, getbl, getbs
|
||||
* 301e - R15 program counter
|
||||
*
|
||||
* 3020-302f - unused
|
||||
*
|
||||
* Other internal registers
|
||||
* 3030 - SFR status flag register (16bit)
|
||||
* 3032 - unused
|
||||
* 3033 - BRAMR Backup RAM register (8bit)
|
||||
* 3034 - PBR program bank register (8bit)
|
||||
* 3035 - unused
|
||||
* 3036 - ROMBR rom bank register (8bit)
|
||||
* 3037 - CFGR control flags register (8bit)
|
||||
* 3038 - SCBR screen base register (8bit)
|
||||
* 3039 - CLSR clock speed register (8bit)
|
||||
* 303a - SCMR screen mode register (8bit)
|
||||
* 303b - VCR version code register (8bit) (read only)
|
||||
* 303c - RAMBR ram bank register (8bit)
|
||||
* 303d - unused
|
||||
* 303e - CBR cache base register (16bit)
|
||||
*
|
||||
* 3040-30ff - unused
|
||||
*
|
||||
* 3100-32ff - CACHERAM 512 bytes of GSU cache memory
|
||||
*
|
||||
* SFR status flag register bits:
|
||||
* 0 -
|
||||
* 1 Z Zero flag
|
||||
* 2 CY Carry flag
|
||||
* 3 S Sign flag
|
||||
* 4 OV Overflow flag
|
||||
* 5 G Go flag (set to 1 when the GSU is running)
|
||||
* 6 R Set to 1 when reading ROM using R14 address
|
||||
* 7 -
|
||||
* 8 ALT1 Mode set-up flag for the next instruction
|
||||
* 9 ALT2 Mode set-up flag for the next instruction
|
||||
* 10 IL Immediate lower 8-bit flag
|
||||
* 11 IH Immediate higher 8-bit flag
|
||||
* 12 B Set to 1 when the WITH instruction is executed
|
||||
* 13 -
|
||||
* 14 -
|
||||
* 15 IRQ Set to 1 when GSU caused an interrupt
|
||||
* Set to 0 when read by 658c16
|
||||
*
|
||||
* BRAMR = 0, BackupRAM is disabled
|
||||
* BRAMR = 1, BackupRAM is enabled
|
||||
*
|
||||
* CFGR control flags register bits:
|
||||
* 0 -
|
||||
* 1 -
|
||||
* 2 -
|
||||
* 3 -
|
||||
* 4 -
|
||||
* 5 MS0 Multiplier speed, 0=standard, 1=high speed
|
||||
* 6 -
|
||||
* 7 IRQ Set to 1 when GSU interrupt request is masked
|
||||
*
|
||||
* CLSR clock speed register bits:
|
||||
* 0 CLSR clock speed, 0 = 10.7Mhz, 1 = 21.4Mhz
|
||||
*
|
||||
* SCMR screen mode register bits:
|
||||
* 0 MD0 color depth mode bit 0
|
||||
* 1 MD1 color depth mode bit 1
|
||||
* 2 HT0 screen height bit 1
|
||||
* 3 RAN RAM access control
|
||||
* 4 RON ROM access control
|
||||
* 5 HT1 screen height bit 2
|
||||
* 6 -
|
||||
* 7 -
|
||||
*
|
||||
* RON = 0 SNES CPU has ROM access
|
||||
* RON = 1 GSU has ROM access
|
||||
*
|
||||
* RAN = 0 SNES has game pak RAM access
|
||||
* RAN = 1 GSU has game pak RAM access
|
||||
*
|
||||
* HT1 HT0 Screen height mode
|
||||
* 0 0 128 pixels high
|
||||
* 0 1 160 pixels high
|
||||
* 1 0 192 pixels high
|
||||
* 1 1 OBJ mode
|
||||
*
|
||||
* MD1 MD0 Color depth mode
|
||||
* 0 0 4 color mode
|
||||
* 0 1 16 color mode
|
||||
* 1 0 not used
|
||||
* 1 1 256 color mode
|
||||
*
|
||||
* CBR cache base register bits:
|
||||
* 15-4 Specify base address for data to cache from ROM or RAM
|
||||
* 3-0 Are 0 when address is read
|
||||
*
|
||||
* Write access to the program counter (301e) from
|
||||
* the SNES-CPU will start the GSU, and it will not
|
||||
* stop until it reaches a stop instruction.
|
||||
*
|
||||
*/
|
||||
|
||||
// Number of banks in GSU RAM
|
||||
#define FX_RAM_BANKS 4
|
||||
|
||||
// Emulate proper R14 ROM access (slower, but safer)
|
||||
#define FX_DO_ROMBUFFER
|
||||
|
||||
// Address checking (definately slow)
|
||||
//#define FX_ADDRESS_CHECK
|
||||
|
||||
struct FxRegs_s
|
||||
{
|
||||
// FxChip registers
|
||||
uint32 avReg[16]; // 16 Generic registers
|
||||
uint32 vColorReg; // Internal color register
|
||||
uint32 vPlotOptionReg; // Plot option register
|
||||
uint32 vStatusReg; // Status register
|
||||
uint32 vPrgBankReg; // Program bank index register
|
||||
uint32 vRomBankReg; // Rom bank index register
|
||||
uint32 vRamBankReg; // Ram bank index register
|
||||
uint32 vCacheBaseReg; // Cache base address register
|
||||
uint32 vCacheFlags; // Saying what parts of the cache was written to
|
||||
uint32 vLastRamAdr; // Last RAM address accessed
|
||||
uint32 *pvDreg; // Pointer to current destination register
|
||||
uint32 *pvSreg; // Pointer to current source register
|
||||
uint8 vRomBuffer; // Current byte read by R14
|
||||
uint8 vPipe; // Instructionset pipe
|
||||
uint32 vPipeAdr; // The address of where the pipe was read from
|
||||
|
||||
// Status register optimization stuff
|
||||
uint32 vSign; // v & 0x8000
|
||||
uint32 vZero; // v == 0
|
||||
uint32 vCarry; // a value of 1 or 0
|
||||
int32 vOverflow; // (v >= 0x8000 || v < -0x8000)
|
||||
|
||||
// Other emulator variables
|
||||
int32 vErrorCode;
|
||||
uint32 vIllegalAddress;
|
||||
|
||||
uint8 bBreakPoint;
|
||||
uint32 vBreakPoint;
|
||||
uint32 vStepPoint;
|
||||
|
||||
uint8 *pvRegisters; // 768 bytes located in the memory at address 0x3000
|
||||
uint32 nRamBanks; // Number of 64kb-banks in FxRam (Don't confuse it with SNES-Ram!!!)
|
||||
uint8 *pvRam; // Pointer to FxRam
|
||||
uint32 nRomBanks; // Number of 32kb-banks in Cart-ROM
|
||||
uint8 *pvRom; // Pointer to Cart-ROM
|
||||
|
||||
uint32 vMode; // Color depth/mode
|
||||
uint32 vPrevMode; // Previous depth
|
||||
uint8 *pvScreenBase;
|
||||
uint8 *apvScreen[32]; // Pointer to each of the 32 screen colums
|
||||
int32 x[32];
|
||||
uint32 vScreenHeight; // 128, 160, 192 or 256 (could be overriden by cmode)
|
||||
uint32 vScreenRealHeight; // 128, 160, 192 or 256
|
||||
uint32 vPrevScreenHeight;
|
||||
uint32 vScreenSize;
|
||||
void (*pfPlot) (void);
|
||||
void (*pfRpix) (void);
|
||||
|
||||
uint8 *pvRamBank; // Pointer to current RAM-bank
|
||||
uint8 *pvRomBank; // Pointer to current ROM-bank
|
||||
uint8 *pvPrgBank; // Pointer to current program ROM-bank
|
||||
|
||||
uint8 *apvRamBank[FX_RAM_BANKS]; // Ram bank table (max 256kb)
|
||||
uint8 *apvRomBank[256]; // Rom bank table
|
||||
|
||||
uint8 bCacheActive;
|
||||
uint8 *pvCache; // Pointer to the GSU cache
|
||||
uint8 avCacheBackup[512]; // Backup of ROM when the cache has replaced it
|
||||
uint32 vCounter;
|
||||
uint32 vInstCount;
|
||||
uint32 vSCBRDirty; // If SCBR is written, our cached screen pointers need updating
|
||||
|
||||
uint8 *avRegAddr; // To reference avReg in snapshot.cpp
|
||||
};
|
||||
|
||||
extern struct FxRegs_s GSU;
|
||||
|
||||
// GSU registers
|
||||
#define GSU_R0 0x000
|
||||
#define GSU_R1 0x002
|
||||
#define GSU_R2 0x004
|
||||
#define GSU_R3 0x006
|
||||
#define GSU_R4 0x008
|
||||
#define GSU_R5 0x00a
|
||||
#define GSU_R6 0x00c
|
||||
#define GSU_R7 0x00e
|
||||
#define GSU_R8 0x010
|
||||
#define GSU_R9 0x012
|
||||
#define GSU_R10 0x014
|
||||
#define GSU_R11 0x016
|
||||
#define GSU_R12 0x018
|
||||
#define GSU_R13 0x01a
|
||||
#define GSU_R14 0x01c
|
||||
#define GSU_R15 0x01e
|
||||
#define GSU_SFR 0x030
|
||||
#define GSU_BRAMR 0x033
|
||||
#define GSU_PBR 0x034
|
||||
#define GSU_ROMBR 0x036
|
||||
#define GSU_CFGR 0x037
|
||||
#define GSU_SCBR 0x038
|
||||
#define GSU_CLSR 0x039
|
||||
#define GSU_SCMR 0x03a
|
||||
#define GSU_VCR 0x03b
|
||||
#define GSU_RAMBR 0x03c
|
||||
#define GSU_CBR 0x03e
|
||||
#define GSU_CACHERAM 0x100
|
||||
|
||||
// SFR flags
|
||||
#define FLG_Z (1 << 1)
|
||||
#define FLG_CY (1 << 2)
|
||||
#define FLG_S (1 << 3)
|
||||
#define FLG_OV (1 << 4)
|
||||
#define FLG_G (1 << 5)
|
||||
#define FLG_R (1 << 6)
|
||||
#define FLG_ALT1 (1 << 8)
|
||||
#define FLG_ALT2 (1 << 9)
|
||||
#define FLG_IL (1 << 10)
|
||||
#define FLG_IH (1 << 11)
|
||||
#define FLG_B (1 << 12)
|
||||
#define FLG_IRQ (1 << 15)
|
||||
|
||||
// Test flag
|
||||
#define TF(a) (GSU.vStatusReg & FLG_##a)
|
||||
#define CF(a) (GSU.vStatusReg &= ~FLG_##a)
|
||||
#define SF(a) (GSU.vStatusReg |= FLG_##a)
|
||||
|
||||
// Test and set flag if condition, clear if not
|
||||
#define TS(a, b) GSU.vStatusReg = ((GSU.vStatusReg & (~FLG_##a)) | ((!!(##b)) * FLG_##a))
|
||||
|
||||
// Testing ALT1 & ALT2 bits
|
||||
#define ALT0 (!TF(ALT1) && !TF(ALT2))
|
||||
#define ALT1 ( TF(ALT1) && !TF(ALT2))
|
||||
#define ALT2 (!TF(ALT1) && TF(ALT2))
|
||||
#define ALT3 ( TF(ALT1) && TF(ALT2))
|
||||
|
||||
// Sign extend from 8/16 bit to 32 bit
|
||||
#define SEX8(a) ((int32) ((int8) (a)))
|
||||
#define SEX16(a) ((int32) ((int16) (a)))
|
||||
|
||||
// Unsign extend from 8/16 bit to 32 bit
|
||||
#define USEX8(a) ((uint32) ((uint8) (a)))
|
||||
#define USEX16(a) ((uint32) ((uint16) (a)))
|
||||
#define SUSEX16(a) ((int32) ((uint16) (a)))
|
||||
|
||||
// Set/Clr Sign and Zero flag
|
||||
#define TSZ(num) TS(S, ((num) & 0x8000)); TS(Z, (!USEX16(num)))
|
||||
|
||||
// Clear flags
|
||||
#define CLRFLAGS GSU.vStatusReg &= ~(FLG_ALT1 | FLG_ALT2 | FLG_B); GSU.pvDreg = GSU.pvSreg = &R0
|
||||
|
||||
// Read current RAM-Bank
|
||||
#define RAM(adr) GSU.pvRamBank[USEX16(adr)]
|
||||
|
||||
// Read current ROM-Bank
|
||||
#define ROM(idx) GSU.pvRomBank[USEX16(idx)]
|
||||
|
||||
// Access the current value in the pipe
|
||||
#define PIPE GSU.vPipe
|
||||
|
||||
// Access data in the current program bank
|
||||
#define PRGBANK(idx) GSU.pvPrgBank[USEX16(idx)]
|
||||
|
||||
// Update pipe from ROM
|
||||
#if 0
|
||||
#define FETCHPIPE { PIPE = PRGBANK(R15); GSU.vPipeAdr = (GSU.vPrgBankReg << 16) + R15; }
|
||||
#else
|
||||
#define FETCHPIPE { PIPE = PRGBANK(R15); }
|
||||
#endif
|
||||
|
||||
// ABS
|
||||
#define ABS(x) ((x) < 0 ? -(x) : (x))
|
||||
|
||||
// Access source register
|
||||
#define SREG (*GSU.pvSreg)
|
||||
|
||||
// Access destination register
|
||||
#define DREG (*GSU.pvDreg)
|
||||
|
||||
#ifndef FX_DO_ROMBUFFER
|
||||
|
||||
// Don't read R14
|
||||
#define READR14
|
||||
|
||||
// Don't test and/or read R14
|
||||
#define TESTR14
|
||||
|
||||
#else
|
||||
|
||||
// Read R14
|
||||
#define READR14 GSU.vRomBuffer = ROM(R14)
|
||||
|
||||
// Test and/or read R14
|
||||
#define TESTR14 if (GSU.pvDreg == &R14) READR14
|
||||
|
||||
#endif
|
||||
|
||||
// Access to registers
|
||||
#define R0 GSU.avReg[0]
|
||||
#define R1 GSU.avReg[1]
|
||||
#define R2 GSU.avReg[2]
|
||||
#define R3 GSU.avReg[3]
|
||||
#define R4 GSU.avReg[4]
|
||||
#define R5 GSU.avReg[5]
|
||||
#define R6 GSU.avReg[6]
|
||||
#define R7 GSU.avReg[7]
|
||||
#define R8 GSU.avReg[8]
|
||||
#define R9 GSU.avReg[9]
|
||||
#define R10 GSU.avReg[10]
|
||||
#define R11 GSU.avReg[11]
|
||||
#define R12 GSU.avReg[12]
|
||||
#define R13 GSU.avReg[13]
|
||||
#define R14 GSU.avReg[14]
|
||||
#define R15 GSU.avReg[15]
|
||||
#define SFR GSU.vStatusReg
|
||||
#define PBR GSU.vPrgBankReg
|
||||
#define ROMBR GSU.vRomBankReg
|
||||
#define RAMBR GSU.vRamBankReg
|
||||
#define CBR GSU.vCacheBaseReg
|
||||
#define SCBR USEX8(GSU.pvRegisters[GSU_SCBR])
|
||||
#define SCMR USEX8(GSU.pvRegisters[GSU_SCMR])
|
||||
#define COLR GSU.vColorReg
|
||||
#define POR GSU.vPlotOptionReg
|
||||
#define BRAMR USEX8(GSU.pvRegisters[GSU_BRAMR])
|
||||
#define VCR USEX8(GSU.pvRegisters[GSU_VCR])
|
||||
#define CFGR USEX8(GSU.pvRegisters[GSU_CFGR])
|
||||
#define CLSR USEX8(GSU.pvRegisters[GSU_CLSR])
|
||||
|
||||
// Execute instruction from the pipe, and fetch next byte to the pipe
|
||||
#define FX_STEP \
|
||||
{ \
|
||||
uint32 vOpcode = (uint32) PIPE; \
|
||||
FETCHPIPE; \
|
||||
(*fx_OpcodeTable[(GSU.vStatusReg & 0x300) | vOpcode])(); \
|
||||
}
|
||||
|
||||
extern void (*fx_PlotTable[]) (void);
|
||||
extern void (*fx_OpcodeTable[]) (void);
|
||||
|
||||
// Set this define if branches are relative to the instruction in the delay slot (I think they are)
|
||||
#define BRANCH_DELAY_RELATIVE
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,904 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _GETSET_H_
|
||||
#define _GETSET_H_
|
||||
|
||||
#include "cpuexec.h"
|
||||
#include "dsp.h"
|
||||
#include "sa1.h"
|
||||
#include "spc7110.h"
|
||||
#include "c4.h"
|
||||
#include "obc1.h"
|
||||
#include "seta.h"
|
||||
#include "bsx.h"
|
||||
|
||||
extern uint8 OpenBus;
|
||||
|
||||
inline uint8 S9xGetByte (uint32 Address)
|
||||
{
|
||||
int block;
|
||||
uint8 *GetAddress = Memory.Map[block = ((Address & 0xffffff) >> MEMMAP_SHIFT)];
|
||||
|
||||
if (!CPU.InDMAorHDMA)
|
||||
CPU.Cycles += Memory.MemorySpeed[block];
|
||||
|
||||
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
if (Memory.BlockIsRAM[block])
|
||||
CPU.WaitAddress = CPU.PBPCAtOpcodeStart;
|
||||
#endif
|
||||
return (*(GetAddress + (Address & 0xffff)));
|
||||
}
|
||||
|
||||
switch ((pint) GetAddress)
|
||||
{
|
||||
case CMemory::MAP_CPU:
|
||||
return (S9xGetCPU(Address & 0xffff));
|
||||
|
||||
case CMemory::MAP_PPU:
|
||||
if (CPU.InDMAorHDMA && (Address & 0xff00) == 0x2100)
|
||||
return (OpenBus);
|
||||
return (S9xGetPPU(Address & 0xffff));
|
||||
|
||||
case CMemory::MAP_LOROM_SRAM:
|
||||
case CMemory::MAP_SA1RAM:
|
||||
// Address & 0x7fff : offset into bank
|
||||
// Address & 0xff0000 : bank
|
||||
// bank >> 1 | offset : SRAM address, unbound
|
||||
// unbound & SRAMMask : SRAM offset
|
||||
return (*(Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask)));
|
||||
|
||||
case CMemory::MAP_LOROM_SRAM_B:
|
||||
return (*(Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB)));
|
||||
|
||||
case CMemory::MAP_HIROM_SRAM:
|
||||
case CMemory::MAP_RONLY_SRAM:
|
||||
return (*(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask)));
|
||||
|
||||
case CMemory::MAP_BWRAM:
|
||||
return (*(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)));
|
||||
|
||||
case CMemory::MAP_DSP:
|
||||
return (S9xGetDSP(Address & 0xffff));
|
||||
|
||||
case CMemory::MAP_SPC7110_ROM:
|
||||
return (S9xGetSPC7110Byte(Address));
|
||||
|
||||
case CMemory::MAP_SPC7110_DRAM:
|
||||
return (S9xGetSPC7110(0x4800));
|
||||
|
||||
case CMemory::MAP_C4:
|
||||
return (S9xGetC4(Address & 0xffff));
|
||||
|
||||
case CMemory::MAP_OBC_RAM:
|
||||
return (S9xGetOBC1(Address & 0xffff));
|
||||
|
||||
case CMemory::MAP_SETA_DSP:
|
||||
return (S9xGetSetaDSP(Address));
|
||||
|
||||
case CMemory::MAP_SETA_RISC:
|
||||
return (S9xGetST018(Address));
|
||||
|
||||
case CMemory::MAP_BSX:
|
||||
return (S9xGetBSX(Address));
|
||||
|
||||
case CMemory::MAP_NONE:
|
||||
default:
|
||||
return (OpenBus);
|
||||
}
|
||||
}
|
||||
|
||||
inline uint16 S9xGetWord (uint32 Address, enum s9xwrap_t w = WRAP_NONE)
|
||||
{
|
||||
uint32 mask = MEMMAP_MASK & (w == WRAP_PAGE ? 0xff : (w == WRAP_BANK ? 0xffff : 0xffffff));
|
||||
if ((Address & mask) == mask)
|
||||
{
|
||||
PC_t a;
|
||||
|
||||
OpenBus = S9xGetByte(Address);
|
||||
|
||||
switch (w)
|
||||
{
|
||||
case WRAP_PAGE:
|
||||
a.xPBPC = Address;
|
||||
a.B.xPCl++;
|
||||
return (OpenBus | (S9xGetByte(a.xPBPC) << 8));
|
||||
|
||||
case WRAP_BANK:
|
||||
a.xPBPC = Address;
|
||||
a.W.xPC++;
|
||||
return (OpenBus | (S9xGetByte(a.xPBPC) << 8));
|
||||
|
||||
case WRAP_NONE:
|
||||
default:
|
||||
return (OpenBus | (S9xGetByte(Address + 1) << 8));
|
||||
}
|
||||
}
|
||||
|
||||
int block;
|
||||
uint8 *GetAddress = Memory.Map[block = ((Address & 0xffffff) >> MEMMAP_SHIFT)];
|
||||
|
||||
if (!CPU.InDMAorHDMA)
|
||||
CPU.Cycles += (Memory.MemorySpeed[block] << 1);
|
||||
|
||||
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
if (Memory.BlockIsRAM[block])
|
||||
CPU.WaitAddress = CPU.PBPCAtOpcodeStart;
|
||||
#endif
|
||||
return (READ_WORD(GetAddress + (Address & 0xffff)));
|
||||
}
|
||||
|
||||
switch ((pint) GetAddress)
|
||||
{
|
||||
case CMemory::MAP_CPU:
|
||||
return (S9xGetCPU(Address & 0xffff) | (S9xGetCPU((Address + 1) & 0xffff) << 8));
|
||||
|
||||
case CMemory::MAP_PPU:
|
||||
if (CPU.InDMAorHDMA)
|
||||
{
|
||||
OpenBus = S9xGetByte(Address);
|
||||
return (OpenBus | (S9xGetByte(Address + 1) << 8));
|
||||
}
|
||||
|
||||
return (S9xGetPPU(Address & 0xffff) | (S9xGetPPU((Address + 1) & 0xffff) << 8));
|
||||
|
||||
case CMemory::MAP_LOROM_SRAM:
|
||||
case CMemory::MAP_SA1RAM:
|
||||
if (Memory.SRAMMask >= MEMMAP_MASK)
|
||||
return (READ_WORD(Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask)));
|
||||
else
|
||||
return ((*(Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask))) |
|
||||
((*(Memory.SRAM + (((((Address + 1) & 0xff0000) >> 1) | ((Address + 1) & 0x7fff)) & Memory.SRAMMask))) << 8));
|
||||
|
||||
case CMemory::MAP_LOROM_SRAM_B:
|
||||
if (Multi.sramMaskB >= MEMMAP_MASK)
|
||||
return (READ_WORD(Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB)));
|
||||
else
|
||||
return ((*(Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB))) |
|
||||
((*(Multi.sramB + (((((Address + 1) & 0xff0000) >> 1) | ((Address + 1) & 0x7fff)) & Multi.sramMaskB))) << 8));
|
||||
|
||||
case CMemory::MAP_HIROM_SRAM:
|
||||
case CMemory::MAP_RONLY_SRAM:
|
||||
if (Memory.SRAMMask >= MEMMAP_MASK)
|
||||
return (READ_WORD(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask)));
|
||||
else
|
||||
return ((*(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask)) |
|
||||
(*(Memory.SRAM + ((((Address + 1) & 0x7fff) - 0x6000 + (((Address + 1) & 0xf0000) >> 3)) & Memory.SRAMMask)) << 8)));
|
||||
|
||||
case CMemory::MAP_BWRAM:
|
||||
return (READ_WORD(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)));
|
||||
|
||||
case CMemory::MAP_DSP:
|
||||
return (S9xGetDSP(Address & 0xffff) | (S9xGetDSP((Address + 1) & 0xffff) << 8));
|
||||
|
||||
case CMemory::MAP_SPC7110_ROM:
|
||||
return (S9xGetSPC7110Byte(Address) | (S9xGetSPC7110Byte(Address + 1) << 8));
|
||||
|
||||
case CMemory::MAP_SPC7110_DRAM:
|
||||
return (S9xGetSPC7110(0x4800) | (S9xGetSPC7110(0x4800) << 8));
|
||||
|
||||
case CMemory::MAP_C4:
|
||||
return (S9xGetC4(Address & 0xffff) | (S9xGetC4((Address + 1) & 0xffff) << 8));
|
||||
|
||||
case CMemory::MAP_OBC_RAM:
|
||||
return (S9xGetOBC1(Address & 0xffff) | (S9xGetOBC1((Address + 1) & 0xffff) << 8));
|
||||
|
||||
case CMemory::MAP_SETA_DSP:
|
||||
return (S9xGetSetaDSP(Address) | (S9xGetSetaDSP(Address + 1) << 8));
|
||||
|
||||
case CMemory::MAP_SETA_RISC:
|
||||
return (S9xGetST018(Address) | (S9xGetST018(Address + 1) << 8));
|
||||
|
||||
case CMemory::MAP_BSX:
|
||||
return (S9xGetBSX(Address) | (S9xGetBSX(Address + 1) << 8));
|
||||
|
||||
case CMemory::MAP_NONE:
|
||||
default:
|
||||
return (OpenBus | (OpenBus << 8));
|
||||
}
|
||||
}
|
||||
|
||||
inline void S9xSetByte (uint8 Byte, uint32 Address)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
|
||||
int block;
|
||||
uint8 *SetAddress = Memory.WriteMap[block = ((Address & 0xffffff) >> MEMMAP_SHIFT)];
|
||||
|
||||
if (!CPU.InDMAorHDMA)
|
||||
CPU.Cycles += Memory.MemorySpeed[block];
|
||||
|
||||
if (SetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
SetAddress += (Address & 0xffff);
|
||||
*SetAddress = Byte;
|
||||
|
||||
if (Settings.SA1)
|
||||
{
|
||||
if (SetAddress == SA1.WaitByteAddress1 || SetAddress == SA1.WaitByteAddress2)
|
||||
{
|
||||
SA1.Executing = SA1.S9xOpcodes != NULL;
|
||||
SA1.WaitCounter = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
*(SetAddress + (Address & 0xffff)) = Byte;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
switch ((pint) SetAddress)
|
||||
{
|
||||
case CMemory::MAP_CPU:
|
||||
S9xSetCPU(Byte, Address & 0xffff);
|
||||
return;
|
||||
|
||||
case CMemory::MAP_PPU:
|
||||
if (CPU.InDMAorHDMA && (Address & 0xff00) == 0x2100)
|
||||
return;
|
||||
S9xSetPPU(Byte, Address & 0xffff);
|
||||
return;
|
||||
|
||||
case CMemory::MAP_LOROM_SRAM:
|
||||
if (Memory.SRAMMask)
|
||||
{
|
||||
*(Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask)) = Byte;
|
||||
CPU.SRAMModified = TRUE;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case CMemory::MAP_LOROM_SRAM_B:
|
||||
if (Multi.sramMaskB)
|
||||
{
|
||||
*(Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB)) = Byte;
|
||||
CPU.SRAMModified = TRUE;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case CMemory::MAP_HIROM_SRAM:
|
||||
if (Memory.SRAMMask)
|
||||
{
|
||||
*(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask)) = Byte;
|
||||
CPU.SRAMModified = TRUE;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case CMemory::MAP_BWRAM:
|
||||
*(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) = Byte;
|
||||
CPU.SRAMModified = TRUE;
|
||||
return;
|
||||
|
||||
case CMemory::MAP_SA1RAM:
|
||||
*(Memory.SRAM + (Address & 0xffff)) = Byte;
|
||||
SA1.Executing = !SA1.Waiting;
|
||||
return;
|
||||
|
||||
case CMemory::MAP_DSP:
|
||||
S9xSetDSP(Byte, Address & 0xffff);
|
||||
return;
|
||||
|
||||
case CMemory::MAP_C4:
|
||||
S9xSetC4(Byte, Address & 0xffff);
|
||||
return;
|
||||
|
||||
case CMemory::MAP_OBC_RAM:
|
||||
S9xSetOBC1(Byte, Address & 0xffff);
|
||||
return;
|
||||
|
||||
case CMemory::MAP_SETA_DSP:
|
||||
S9xSetSetaDSP(Byte, Address);
|
||||
return;
|
||||
|
||||
case CMemory::MAP_SETA_RISC:
|
||||
S9xSetST018(Byte, Address);
|
||||
return;
|
||||
|
||||
case CMemory::MAP_BSX:
|
||||
S9xSetBSX(Byte, Address);
|
||||
return;
|
||||
|
||||
case CMemory::MAP_NONE:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
inline void S9xSetWord (uint16 Word, uint32 Address, enum s9xwrap_t w = WRAP_NONE, enum s9xwriteorder_t o = WRITE_01)
|
||||
{
|
||||
uint32 mask = MEMMAP_MASK & (w == WRAP_PAGE ? 0xff : (w == WRAP_BANK ? 0xffff : 0xffffff));
|
||||
if ((Address & mask) == mask)
|
||||
{
|
||||
PC_t a;
|
||||
|
||||
if (!o)
|
||||
S9xSetByte((uint8) Word, Address);
|
||||
|
||||
switch (w)
|
||||
{
|
||||
case WRAP_PAGE:
|
||||
a.xPBPC = Address;
|
||||
a.B.xPCl++;
|
||||
S9xSetByte(Word >> 8, a.xPBPC);
|
||||
break;
|
||||
|
||||
case WRAP_BANK:
|
||||
a.xPBPC = Address;
|
||||
a.W.xPC++;
|
||||
S9xSetByte(Word >> 8, a.xPBPC);
|
||||
break;
|
||||
|
||||
case WRAP_NONE:
|
||||
default:
|
||||
S9xSetByte(Word >> 8, Address + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (o)
|
||||
S9xSetByte((uint8) Word, Address);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CPU_SHUTDOWN
|
||||
CPU.WaitAddress = 0xffffffff;
|
||||
#endif
|
||||
|
||||
int block;
|
||||
uint8 *SetAddress = Memory.WriteMap[block = ((Address & 0xffffff) >> MEMMAP_SHIFT)];
|
||||
|
||||
if (!CPU.InDMAorHDMA)
|
||||
CPU.Cycles += (Memory.MemorySpeed[block] << 1);
|
||||
|
||||
if (SetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||
{
|
||||
#ifdef CPU_SHUTDOWN
|
||||
SetAddress += (Address & 0xffff);
|
||||
WRITE_WORD(SetAddress, Word);
|
||||
|
||||
if (Settings.SA1)
|
||||
{
|
||||
if (SetAddress == SA1.WaitByteAddress1 || SetAddress == SA1.WaitByteAddress2)
|
||||
{
|
||||
SA1.Executing = SA1.S9xOpcodes != NULL;
|
||||
SA1.WaitCounter = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
WRITE_WORD(SetAddress + (Address & 0xffff), Word);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
switch ((pint) SetAddress)
|
||||
{
|
||||
case CMemory::MAP_CPU:
|
||||
if (o)
|
||||
{
|
||||
S9xSetCPU(Word >> 8, (Address + 1) & 0xffff);
|
||||
S9xSetCPU((uint8) Word, Address & 0xffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
S9xSetCPU((uint8) Word, Address & 0xffff);
|
||||
S9xSetCPU(Word >> 8, (Address + 1) & 0xffff);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case CMemory::MAP_PPU:
|
||||
if (CPU.InDMAorHDMA)
|
||||
{
|
||||
if ((Address & 0xff00) != 0x2100)
|
||||
S9xSetPPU((uint8) Word, Address & 0xffff);
|
||||
if (((Address + 1) & 0xff00) != 0x2100)
|
||||
S9xSetPPU(Word >> 8, (Address + 1) & 0xffff);
|
||||
return;
|
||||
}
|
||||
|
||||
if (o)
|
||||
{
|
||||
S9xSetPPU(Word >> 8, (Address + 1) & 0xffff);
|
||||
S9xSetPPU((uint8) Word, Address & 0xffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
S9xSetPPU((uint8) Word, Address & 0xffff);
|
||||
S9xSetPPU(Word >> 8, (Address + 1) & 0xffff);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case CMemory::MAP_LOROM_SRAM:
|
||||
if (Memory.SRAMMask)
|
||||
{
|
||||
if (Memory.SRAMMask >= MEMMAP_MASK)
|
||||
WRITE_WORD(Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask), Word);
|
||||
else
|
||||
{
|
||||
*(Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask)) = (uint8) Word;
|
||||
*(Memory.SRAM + (((((Address + 1) & 0xff0000) >> 1) | ((Address + 1) & 0x7fff)) & Memory.SRAMMask)) = Word >> 8;
|
||||
}
|
||||
|
||||
CPU.SRAMModified = TRUE;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case CMemory::MAP_LOROM_SRAM_B:
|
||||
if (Multi.sramMaskB)
|
||||
{
|
||||
if (Multi.sramMaskB >= MEMMAP_MASK)
|
||||
WRITE_WORD(Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB), Word);
|
||||
else
|
||||
{
|
||||
*(Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB)) = (uint8) Word;
|
||||
*(Multi.sramB + (((((Address + 1) & 0xff0000) >> 1) | ((Address + 1) & 0x7fff)) & Multi.sramMaskB)) = Word >> 8;
|
||||
}
|
||||
|
||||
CPU.SRAMModified = TRUE;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case CMemory::MAP_HIROM_SRAM:
|
||||
if (Memory.SRAMMask)
|
||||
{
|
||||
if (Memory.SRAMMask >= MEMMAP_MASK)
|
||||
WRITE_WORD(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask), Word);
|
||||
else
|
||||
{
|
||||
*(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask)) = (uint8) Word;
|
||||
*(Memory.SRAM + ((((Address + 1) & 0x7fff) - 0x6000 + (((Address + 1) & 0xf0000) >> 3)) & Memory.SRAMMask)) = Word >> 8;
|
||||
}
|
||||
|
||||
CPU.SRAMModified = TRUE;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case CMemory::MAP_BWRAM:
|
||||
WRITE_WORD(Memory.BWRAM + ((Address & 0x7fff) - 0x6000), Word);
|
||||
CPU.SRAMModified = TRUE;
|
||||
return;
|
||||
|
||||
case CMemory::MAP_SA1RAM:
|
||||
WRITE_WORD(Memory.SRAM + (Address & 0xffff), Word);
|
||||
SA1.Executing = !SA1.Waiting;
|
||||
return;
|
||||
|
||||
case CMemory::MAP_DSP:
|
||||
if (o)
|
||||
{
|
||||
S9xSetDSP(Word >> 8, (Address + 1) & 0xffff);
|
||||
S9xSetDSP((uint8) Word, Address & 0xffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
S9xSetDSP((uint8) Word, Address & 0xffff);
|
||||
S9xSetDSP(Word >> 8, (Address + 1) & 0xffff);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case CMemory::MAP_C4:
|
||||
if (o)
|
||||
{
|
||||
S9xSetC4(Word >> 8, (Address + 1) & 0xffff);
|
||||
S9xSetC4((uint8) Word, Address & 0xffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
S9xSetC4((uint8) Word, Address & 0xffff);
|
||||
S9xSetC4(Word >> 8, (Address + 1) & 0xffff);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case CMemory::MAP_OBC_RAM:
|
||||
if (o)
|
||||
{
|
||||
S9xSetOBC1(Word >> 8, (Address + 1) & 0xffff);
|
||||
S9xSetOBC1((uint8) Word, Address & 0xffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
S9xSetOBC1((uint8) Word, Address & 0xffff);
|
||||
S9xSetOBC1(Word >> 8, (Address + 1) & 0xffff);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case CMemory::MAP_SETA_DSP:
|
||||
if (o)
|
||||
{
|
||||
S9xSetSetaDSP(Word >> 8, Address + 1);
|
||||
S9xSetSetaDSP((uint8) Word, Address);
|
||||
}
|
||||
else
|
||||
{
|
||||
S9xSetSetaDSP((uint8) Word, Address);
|
||||
S9xSetSetaDSP(Word >> 8, Address + 1);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case CMemory::MAP_SETA_RISC:
|
||||
if (o)
|
||||
{
|
||||
S9xSetST018(Word >> 8, Address + 1);
|
||||
S9xSetST018((uint8) Word, Address);
|
||||
}
|
||||
else
|
||||
{
|
||||
S9xSetST018((uint8) Word, Address);
|
||||
S9xSetST018(Word >> 8, Address + 1);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case CMemory::MAP_BSX:
|
||||
if (o)
|
||||
{
|
||||
S9xSetBSX(Word >> 8, Address + 1);
|
||||
S9xSetBSX((uint8) Word, Address);
|
||||
}
|
||||
else
|
||||
{
|
||||
S9xSetBSX((uint8) Word, Address);
|
||||
S9xSetBSX(Word >> 8, Address + 1);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case CMemory::MAP_NONE:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
inline void S9xSetPCBase (uint32 Address)
|
||||
{
|
||||
Registers.PBPC = Address & 0xffffff;
|
||||
ICPU.ShiftedPB = Address & 0xff0000;
|
||||
|
||||
int block;
|
||||
uint8 *GetAddress = Memory.Map[block = ((Address & 0xffffff) >> MEMMAP_SHIFT)];
|
||||
|
||||
CPU.MemSpeed = Memory.MemorySpeed[block];
|
||||
CPU.MemSpeedx2 = CPU.MemSpeed << 1;
|
||||
|
||||
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||
{
|
||||
CPU.PCBase = GetAddress;
|
||||
return;
|
||||
}
|
||||
|
||||
switch ((pint) GetAddress)
|
||||
{
|
||||
case CMemory::MAP_LOROM_SRAM:
|
||||
if ((Memory.SRAMMask & MEMMAP_MASK) != MEMMAP_MASK)
|
||||
CPU.PCBase = NULL;
|
||||
else
|
||||
CPU.PCBase = Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask) - (Address & 0xffff);
|
||||
return;
|
||||
|
||||
case CMemory::MAP_LOROM_SRAM_B:
|
||||
if ((Multi.sramMaskB & MEMMAP_MASK) != MEMMAP_MASK)
|
||||
CPU.PCBase = NULL;
|
||||
else
|
||||
CPU.PCBase = Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB) - (Address & 0xffff);
|
||||
return;
|
||||
|
||||
case CMemory::MAP_HIROM_SRAM:
|
||||
if ((Memory.SRAMMask & MEMMAP_MASK) != MEMMAP_MASK)
|
||||
CPU.PCBase = NULL;
|
||||
else
|
||||
CPU.PCBase = Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask) - (Address & 0xffff);
|
||||
return;
|
||||
|
||||
case CMemory::MAP_BWRAM:
|
||||
CPU.PCBase = Memory.BWRAM - 0x6000 - (Address & 0x8000);
|
||||
return;
|
||||
|
||||
case CMemory::MAP_SA1RAM:
|
||||
CPU.PCBase = Memory.SRAM;
|
||||
return;
|
||||
|
||||
case CMemory::MAP_SPC7110_ROM:
|
||||
CPU.PCBase = S9xGetBasePointerSPC7110(Address);
|
||||
return;
|
||||
|
||||
case CMemory::MAP_C4:
|
||||
CPU.PCBase = S9xGetBasePointerC4(Address & 0xffff);
|
||||
return;
|
||||
|
||||
case CMemory::MAP_OBC_RAM:
|
||||
CPU.PCBase = S9xGetBasePointerOBC1(Address & 0xffff);
|
||||
return;
|
||||
|
||||
case CMemory::MAP_BSX:
|
||||
CPU.PCBase = S9xGetBasePointerBSX(Address);
|
||||
return;
|
||||
|
||||
case CMemory::MAP_NONE:
|
||||
default:
|
||||
CPU.PCBase = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
inline uint8 * S9xGetBasePointer (uint32 Address)
|
||||
{
|
||||
uint8 *GetAddress = Memory.Map[(Address & 0xffffff) >> MEMMAP_SHIFT];
|
||||
|
||||
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||
return (GetAddress);
|
||||
|
||||
switch ((pint) GetAddress)
|
||||
{
|
||||
case CMemory::MAP_LOROM_SRAM:
|
||||
if ((Memory.SRAMMask & MEMMAP_MASK) != MEMMAP_MASK)
|
||||
return (NULL);
|
||||
return (Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask) - (Address & 0xffff));
|
||||
|
||||
case CMemory::MAP_LOROM_SRAM_B:
|
||||
if ((Multi.sramMaskB & MEMMAP_MASK) != MEMMAP_MASK)
|
||||
return (NULL);
|
||||
return (Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB) - (Address & 0xffff));
|
||||
|
||||
case CMemory::MAP_HIROM_SRAM:
|
||||
if ((Memory.SRAMMask & MEMMAP_MASK) != MEMMAP_MASK)
|
||||
return (NULL);
|
||||
return (Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask) - (Address & 0xffff));
|
||||
|
||||
case CMemory::MAP_BWRAM:
|
||||
return (Memory.BWRAM - 0x6000 - (Address & 0x8000));
|
||||
|
||||
case CMemory::MAP_SA1RAM:
|
||||
return (Memory.SRAM);
|
||||
|
||||
case CMemory::MAP_SPC7110_ROM:
|
||||
return (S9xGetBasePointerSPC7110(Address));
|
||||
|
||||
case CMemory::MAP_C4:
|
||||
return (S9xGetBasePointerC4(Address & 0xffff));
|
||||
|
||||
case CMemory::MAP_OBC_RAM:
|
||||
return (S9xGetBasePointerOBC1(Address & 0xffff));
|
||||
|
||||
case CMemory::MAP_NONE:
|
||||
default:
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
inline uint8 * S9xGetMemPointer (uint32 Address)
|
||||
{
|
||||
uint8 *GetAddress = Memory.Map[(Address & 0xffffff) >> MEMMAP_SHIFT];
|
||||
|
||||
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
|
||||
return (GetAddress + (Address & 0xffff));
|
||||
|
||||
switch ((pint) GetAddress)
|
||||
{
|
||||
case CMemory::MAP_LOROM_SRAM:
|
||||
if ((Memory.SRAMMask & MEMMAP_MASK) != MEMMAP_MASK)
|
||||
return (NULL);
|
||||
return (Memory.SRAM + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Memory.SRAMMask));
|
||||
|
||||
case CMemory::MAP_LOROM_SRAM_B:
|
||||
if ((Multi.sramMaskB & MEMMAP_MASK) != MEMMAP_MASK)
|
||||
return (NULL);
|
||||
return (Multi.sramB + ((((Address & 0xff0000) >> 1) | (Address & 0x7fff)) & Multi.sramMaskB));
|
||||
|
||||
case CMemory::MAP_HIROM_SRAM:
|
||||
if ((Memory.SRAMMask & MEMMAP_MASK) != MEMMAP_MASK)
|
||||
return (NULL);
|
||||
return (Memory.SRAM + (((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask));
|
||||
|
||||
case CMemory::MAP_BWRAM:
|
||||
return (Memory.BWRAM - 0x6000 + (Address & 0x7fff));
|
||||
|
||||
case CMemory::MAP_SA1RAM:
|
||||
return (Memory.SRAM + (Address & 0xffff));
|
||||
|
||||
case CMemory::MAP_SPC7110_ROM:
|
||||
return (S9xGetBasePointerSPC7110(Address) + (Address & 0xffff));
|
||||
|
||||
case CMemory::MAP_C4:
|
||||
return (S9xGetMemPointerC4(Address & 0xffff));
|
||||
|
||||
case CMemory::MAP_OBC_RAM:
|
||||
return (S9xGetMemPointerOBC1(Address & 0xffff));
|
||||
|
||||
case CMemory::MAP_NONE:
|
||||
default:
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,366 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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.
|
||||
***********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _GFX_H_
|
||||
#define _GFX_H_
|
||||
|
||||
struct SGFX
|
||||
{
|
||||
uint16 *Screen;
|
||||
uint16 *SubScreen;
|
||||
uint8 *ZBuffer;
|
||||
uint8 *SubZBuffer;
|
||||
uint32 Pitch;
|
||||
uint32 ScreenSize;
|
||||
uint16 *S;
|
||||
uint8 *DB;
|
||||
uint16 *X2;
|
||||
uint16 *ZERO;
|
||||
uint32 RealPPL; // true PPL of Screen buffer
|
||||
uint32 PPL; // number of pixels on each of Screen buffer
|
||||
uint32 LinesPerTile; // number of lines in 1 tile (4 or 8 due to interlace)
|
||||
uint16 *ScreenColors; // screen colors for rendering main
|
||||
uint16 *RealScreenColors; // screen colors, ignoring color window clipping
|
||||
uint8 Z1; // depth for comparison
|
||||
uint8 Z2; // depth to save
|
||||
uint32 FixedColour;
|
||||
uint8 DoInterlace;
|
||||
uint8 InterlaceFrame;
|
||||
uint32 StartY;
|
||||
uint32 EndY;
|
||||
bool8 ClipColors;
|
||||
uint8 OBJWidths[128];
|
||||
uint8 OBJVisibleTiles[128];
|
||||
|
||||
struct ClipData *Clip;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8 RTOFlags;
|
||||
int16 Tiles;
|
||||
|
||||
struct
|
||||
{
|
||||
int8 Sprite;
|
||||
uint8 Line;
|
||||
} OBJ[32];
|
||||
} OBJLines[SNES_HEIGHT_EXTENDED];
|
||||
|
||||
#ifdef GFX_MULTI_FORMAT
|
||||
uint32 PixelFormat;
|
||||
uint32 (*BuildPixel) (uint32, uint32, uint32);
|
||||
uint32 (*BuildPixel2) (uint32, uint32, uint32);
|
||||
void (*DecomposePixel) (uint32, uint32 &, uint32 &, uint32 &);
|
||||
#endif
|
||||
|
||||
void (*DrawBackdropMath) (uint32, uint32, uint32);
|
||||
void (*DrawBackdropNomath) (uint32, uint32, uint32);
|
||||
void (*DrawTileMath) (uint32, uint32, uint32, uint32);
|
||||
void (*DrawTileNomath) (uint32, uint32, uint32, uint32);
|
||||
void (*DrawClippedTileMath) (uint32, uint32, uint32, uint32, uint32, uint32);
|
||||
void (*DrawClippedTileNomath) (uint32, uint32, uint32, uint32, uint32, uint32);
|
||||
void (*DrawMosaicPixelMath) (uint32, uint32, uint32, uint32, uint32, uint32);
|
||||
void (*DrawMosaicPixelNomath) (uint32, uint32, uint32, uint32, uint32, uint32);
|
||||
void (*DrawMode7BG1Math) (uint32, uint32, int);
|
||||
void (*DrawMode7BG1Nomath) (uint32, uint32, int);
|
||||
void (*DrawMode7BG2Math) (uint32, uint32, int);
|
||||
void (*DrawMode7BG2Nomath) (uint32, uint32, int);
|
||||
|
||||
const char *InfoString;
|
||||
uint32 InfoStringTimeout;
|
||||
char FrameDisplayString[256];
|
||||
};
|
||||
|
||||
struct SBG
|
||||
{
|
||||
uint8 (*ConvertTile) (uint8 *, uint32, uint32);
|
||||
uint8 (*ConvertTileFlip) (uint8 *, uint32, uint32);
|
||||
|
||||
uint32 TileSizeH;
|
||||
uint32 TileSizeV;
|
||||
uint32 OffsetSizeH;
|
||||
uint32 OffsetSizeV;
|
||||
uint32 TileShift;
|
||||
uint32 TileAddress;
|
||||
uint32 NameSelect;
|
||||
uint32 SCBase;
|
||||
|
||||
uint32 StartPalette;
|
||||
uint32 PaletteShift;
|
||||
uint32 PaletteMask;
|
||||
uint8 EnableMath;
|
||||
uint8 InterlaceLine;
|
||||
|
||||
uint8 *Buffer;
|
||||
uint8 *BufferFlip;
|
||||
uint8 *Buffered;
|
||||
uint8 *BufferedFlip;
|
||||
bool8 DirectColourMode;
|
||||
};
|
||||
|
||||
struct SLineData
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint16 VOffset;
|
||||
uint16 HOffset;
|
||||
} BG[4];
|
||||
};
|
||||
|
||||
struct SLineMatrixData
|
||||
{
|
||||
short MatrixA;
|
||||
short MatrixB;
|
||||
short MatrixC;
|
||||
short MatrixD;
|
||||
short CentreX;
|
||||
short CentreY;
|
||||
short M7HOFS;
|
||||
short M7VOFS;
|
||||
};
|
||||
|
||||
extern uint16 BlackColourMap[256];
|
||||
extern uint16 DirectColourMaps[8][256];
|
||||
extern uint8 mul_brightness[16][32];
|
||||
extern struct SBG BG;
|
||||
extern struct SGFX GFX;
|
||||
|
||||
#define H_FLIP 0x4000
|
||||
#define V_FLIP 0x8000
|
||||
#define BLANK_TILE 2
|
||||
|
||||
#define COLOR_ADD1_2(C1, C2) \
|
||||
((((((C1) & RGB_REMOVE_LOW_BITS_MASK) + \
|
||||
((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + \
|
||||
((C1) & (C2) & RGB_LOW_BITS_MASK)) | ALPHA_BITS_MASK)
|
||||
|
||||
#define COLOR_ADD(C1, C2) \
|
||||
(GFX.X2[((((C1) & RGB_REMOVE_LOW_BITS_MASK) + \
|
||||
((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + \
|
||||
((C1) & (C2) & RGB_LOW_BITS_MASK)] | \
|
||||
(((C1) ^ (C2)) & RGB_LOW_BITS_MASK))
|
||||
|
||||
#define COLOR_SUB1_2(C1, C2) \
|
||||
GFX.ZERO[(((C1) | RGB_HI_BITS_MASKx2) - \
|
||||
((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1]
|
||||
|
||||
inline uint16 COLOR_SUB (uint16 C1, uint16 C2)
|
||||
{
|
||||
uint16 mC1, mC2, v = ALPHA_BITS_MASK;
|
||||
|
||||
mC1 = C1 & FIRST_COLOR_MASK;
|
||||
mC2 = C2 & FIRST_COLOR_MASK;
|
||||
if (mC1 > mC2) v += (mC1 - mC2);
|
||||
|
||||
mC1 = C1 & SECOND_COLOR_MASK;
|
||||
mC2 = C2 & SECOND_COLOR_MASK;
|
||||
if (mC1 > mC2) v += (mC1 - mC2);
|
||||
|
||||
mC1 = C1 & THIRD_COLOR_MASK;
|
||||
mC2 = C2 & THIRD_COLOR_MASK;
|
||||
if (mC1 > mC2) v += (mC1 - mC2);
|
||||
|
||||
return (v);
|
||||
}
|
||||
|
||||
void S9xStartScreenRefresh (void);
|
||||
void S9xEndScreenRefresh (void);
|
||||
void S9xUpdateScreen (void);
|
||||
void S9xBuildDirectColourMaps (void);
|
||||
void RenderLine (uint8);
|
||||
void S9xComputeClipWindows (void);
|
||||
void S9xDisplayChar (uint16 *, uint8);
|
||||
// called automatically unless Settings.AutoDisplayMessages is false
|
||||
void S9xDisplayMessages (uint16 *, int, int, int, int);
|
||||
#ifdef GFX_MULTI_FORMAT
|
||||
bool8 S9xSetRenderPixelFormat (int);
|
||||
#endif
|
||||
|
||||
// external port interface which must be implemented or initialised for each port
|
||||
bool8 S9xGraphicsInit (void);
|
||||
void S9xGraphicsDeinit (void);
|
||||
bool8 S9xInitUpdate (void);
|
||||
bool8 S9xDeinitUpdate (int, int);
|
||||
bool8 S9xContinueUpdate (int, int);
|
||||
void S9xReRefresh (void);
|
||||
void S9xSetPalette (void);
|
||||
void S9xSyncSpeed (void);
|
||||
|
||||
// called instead of S9xDisplayString if set to non-NULL
|
||||
extern void (*S9xCustomDisplayString) (const char *, int, int, bool);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,410 @@
|
|||
/***********************************************************************************
|
||||
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
||||
|
||||
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
||||
Jerremy Koot (jkoot@snes9x.com)
|
||||
|
||||
(c) Copyright 2002 - 2004 Matthew Kendora
|
||||
|
||||
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
||||
|
||||
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
||||
|
||||
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
||||
|
||||
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
||||
Kris Bleakley (codeviolation@hotmail.com)
|
||||
|
||||
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
||||
Nach (n-a-c-h@users.sourceforge.net),
|
||||
zones (kasumitokoduck@yahoo.com)
|
||||
|
||||
(c) Copyright 2006 - 2007 nitsuja
|
||||
|
||||
(c) Copyright 2009 - 2010 BearOso,
|
||||
OV2
|
||||
|
||||
|
||||
BS-X C emulator code
|
||||
(c) Copyright 2005 - 2006 Dreamer Nom,
|
||||
zones
|
||||
|
||||
C4 x86 assembler and some C emulation code
|
||||
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
||||
Nach,
|
||||
zsKnight (zsknight@zsnes.com)
|
||||
|
||||
C4 C++ code
|
||||
(c) Copyright 2003 - 2006 Brad Jorsch,
|
||||
Nach
|
||||
|
||||
DSP-1 emulator code
|
||||
(c) Copyright 1998 - 2006 _Demo_,
|
||||
Andreas Naive (andreasnaive@gmail.com),
|
||||
Gary Henderson,
|
||||
Ivar (ivar@snes9x.com),
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
neviksti (neviksti@hotmail.com)
|
||||
|
||||
DSP-2 emulator code
|
||||
(c) Copyright 2003 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
||||
Matthew Kendora,
|
||||
neviksti
|
||||
|
||||
DSP-3 emulator code
|
||||
(c) Copyright 2003 - 2006 John Weidman,
|
||||
Kris Bleakley,
|
||||
Lancer,
|
||||
z80 gaiden
|
||||
|
||||
DSP-4 emulator code
|
||||
(c) Copyright 2004 - 2006 Dreamer Nom,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Nach,
|
||||
z80 gaiden
|
||||
|
||||
OBC1 emulator code
|
||||
(c) Copyright 2001 - 2004 zsKnight,
|
||||
pagefault (pagefault@zsnes.com),
|
||||
Kris Bleakley
|
||||
Ported from x86 assembler to C by sanmaiwashi
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
||||
(c) Copyright 2002 Matthew Kendora with research by
|
||||
zsKnight,
|
||||
John Weidman,
|
||||
Dark Force
|
||||
|
||||
SPC7110 and RTC C++ emulator code used in 1.52+
|
||||
(c) Copyright 2009 byuu,
|
||||
neviksti
|
||||
|
||||
S-DD1 C emulator code
|
||||
(c) Copyright 2003 Brad Jorsch with research by
|
||||
Andreas Naive,
|
||||
John Weidman
|
||||
|
||||
S-RTC C emulator code
|
||||
(c) Copyright 2001 - 2006 byuu,
|
||||
John Weidman
|
||||
|
||||
ST010 C++ emulator code
|
||||
(c) Copyright 2003 Feather,
|
||||
John Weidman,
|
||||
Kris Bleakley,
|
||||
Matthew Kendora
|
||||
|
||||
Super FX x86 assembler emulator code
|
||||
(c) Copyright 1998 - 2003 _Demo_,
|
||||
pagefault,
|
||||
zsKnight
|
||||
|
||||
Super FX C emulator code
|
||||
(c) Copyright 1997 - 1999 Ivar,
|
||||
Gary Henderson,
|
||||
John Weidman
|
||||
|
||||
Sound emulator code used in 1.5-1.51
|
||||
(c) Copyright 1998 - 2003 Brad Martin
|
||||
(c) Copyright 1998 - 2006 Charles Bilyue'
|
||||
|
||||
Sound emulator code used in 1.52+
|
||||
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
||||
|
||||
SH assembler code partly based on x86 assembler code
|
||||
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
||||
|
||||
2xSaI filter
|
||||
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
||||
|
||||
HQ2x, HQ3x, HQ4x filters
|
||||
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
||||
|
||||
NTSC filter
|
||||
(c) Copyright 2006 - 2007 Shay Green
|
||||
|
||||
GTK+ GUI code
|
||||
(c) Copyright 2004 - 2010 BearOso
|
||||
|
||||
Win32 GUI code
|
||||
(c) Copyright 2003 - 2006 blip,
|
||||
funkyass,
|
||||
Matthew Kendora,
|
||||
Nach,
|
||||
nitsuja
|
||||
(c) Copyright 2009 - 2010 OV2
|
||||
|
||||
Mac OS GUI code
|
||||
(c) Copyright 1998 - 2001 John Stiles
|
||||
(c) Copyright 2001 - 2010 zones
|
||||
|
||||
|
||||
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/or 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 or it's derivatives.
|
||||
|
||||
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
||||
seek permission of the copyright holders first. Commercial use includes,
|
||||
but is not limited to, charging money for Snes9x or software derived from
|
||||
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
||||
using Snes9x as a promotion for your commercial product.
|
||||
|
||||
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 "snes9x.h"
|
||||
#include "memmap.h"
|
||||
#include "dma.h"
|
||||
#include "apu/apu.h"
|
||||
#include "fxinst.h"
|
||||
#include "fxemu.h"
|
||||
#include "srtc.h"
|
||||
#include "cheats.h"
|
||||
#ifdef NETPLAY_SUPPORT
|
||||
#include "netplay.h"
|
||||
#endif
|
||||
#ifdef DEBUGGER
|
||||
#include "debug.h"
|
||||
#include "missing.h"
|
||||
#endif
|
||||
|
||||
struct SCPUState CPU;
|
||||
struct SICPU ICPU;
|
||||
struct SRegisters Registers;
|
||||
struct SPPU PPU;
|
||||
struct InternalPPU IPPU;
|
||||
struct SDMA DMA[8];
|
||||
struct STimings Timings;
|
||||
struct SGFX GFX;
|
||||
struct SBG BG;
|
||||
struct SLineData LineData[240];
|
||||
struct SLineMatrixData LineMatrixData[240];
|
||||
struct SDSP0 DSP0;
|
||||
struct SDSP1 DSP1;
|
||||
struct SDSP2 DSP2;
|
||||
struct SDSP3 DSP3;
|
||||
struct SDSP4 DSP4;
|
||||
struct SSA1 SA1;
|
||||
struct SSA1Registers SA1Registers;
|
||||
struct SST010 ST010;
|
||||
struct SST011 ST011;
|
||||
struct SST018 ST018;
|
||||
struct SOBC1 OBC1;
|
||||
struct SSPC7110Snapshot s7snap;
|
||||
struct SSRTCSnapshot srtcsnap;
|
||||
struct SRTCData RTCData;
|
||||
struct SBSX BSX;
|
||||
struct SMulti Multi;
|
||||
struct SSettings Settings;
|
||||
struct SSNESGameFixes SNESGameFixes;
|
||||
#ifdef NETPLAY_SUPPORT
|
||||
struct SNetPlay NetPlay;
|
||||
#endif
|
||||
#ifdef DEBUGGER
|
||||
struct Missing missing;
|
||||
#endif
|
||||
struct SCheatData Cheat;
|
||||
struct Watch watches[16];
|
||||
#ifndef ZSNES_FX
|
||||
struct FxRegs_s GSU;
|
||||
struct FxInfo_s SuperFX;
|
||||
#endif
|
||||
CMemory Memory;
|
||||
|
||||
char String[513];
|
||||
uint8 OpenBus = 0;
|
||||
uint8 *HDMAMemPointers[8];
|
||||
uint16 BlackColourMap[256];
|
||||
uint16 DirectColourMaps[8][256];
|
||||
|
||||
SnesModel M1SNES = { 1, 3, 2 };
|
||||
SnesModel M2SNES = { 2, 4, 3 };
|
||||
SnesModel *Model = &M1SNES;
|
||||
|
||||
#if defined(ZSNES_FX) || defined(ZSNES_C4)
|
||||
uint8 *ROM = NULL;
|
||||
uint8 *SRAM = NULL;
|
||||
uint8 *RegRAM = NULL;
|
||||
#endif
|
||||
#ifdef ZSNES_FX
|
||||
uint8 *SFXPlotTable = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef GFX_MULTI_FORMAT
|
||||
uint32 RED_LOW_BIT_MASK = RED_LOW_BIT_MASK_RGB565;
|
||||
uint32 GREEN_LOW_BIT_MASK = GREEN_LOW_BIT_MASK_RGB565;
|
||||
uint32 BLUE_LOW_BIT_MASK = BLUE_LOW_BIT_MASK_RGB565;
|
||||
uint32 RED_HI_BIT_MASK = RED_HI_BIT_MASK_RGB565;
|
||||
uint32 GREEN_HI_BIT_MASK = GREEN_HI_BIT_MASK_RGB565;
|
||||
uint32 BLUE_HI_BIT_MASK = BLUE_HI_BIT_MASK_RGB565;
|
||||
uint32 MAX_RED = MAX_RED_RGB565;
|
||||
uint32 MAX_GREEN = MAX_GREEN_RGB565;
|
||||
uint32 MAX_BLUE = MAX_BLUE_RGB565;
|
||||
uint32 SPARE_RGB_BIT_MASK = SPARE_RGB_BIT_MASK_RGB565;
|
||||
uint32 GREEN_HI_BIT = (MAX_GREEN_RGB565 + 1) >> 1;
|
||||
uint32 RGB_LOW_BITS_MASK = (RED_LOW_BIT_MASK_RGB565 | GREEN_LOW_BIT_MASK_RGB565 | BLUE_LOW_BIT_MASK_RGB565);
|
||||
uint32 RGB_HI_BITS_MASK = (RED_HI_BIT_MASK_RGB565 | GREEN_HI_BIT_MASK_RGB565 | BLUE_HI_BIT_MASK_RGB565);
|
||||
uint32 RGB_HI_BITS_MASKx2 = (RED_HI_BIT_MASK_RGB565 | GREEN_HI_BIT_MASK_RGB565 | BLUE_HI_BIT_MASK_RGB565) << 1;
|
||||
uint32 RGB_REMOVE_LOW_BITS_MASK = ~RGB_LOW_BITS_MASK;
|
||||
uint32 FIRST_COLOR_MASK = FIRST_COLOR_MASK_RGB565;
|
||||
uint32 SECOND_COLOR_MASK = SECOND_COLOR_MASK_RGB565;
|
||||
uint32 THIRD_COLOR_MASK = THIRD_COLOR_MASK_RGB565;
|
||||
uint32 ALPHA_BITS_MASK = ALPHA_BITS_MASK_RGB565;
|
||||
uint32 FIRST_THIRD_COLOR_MASK = 0;
|
||||
uint32 TWO_LOW_BITS_MASK = 0;
|
||||
uint32 HIGH_BITS_SHIFTED_TWO_MASK = 0;
|
||||
#endif
|
||||
|
||||
uint16 SignExtend[2] =
|
||||
{
|
||||
0x0000,
|
||||
0xff00
|
||||
};
|
||||
|
||||
int HDMA_ModeByteCounts[8] =
|
||||
{
|
||||
1, 2, 2, 4, 4, 4, 2, 4
|
||||
};
|
||||
|
||||
uint8 mul_brightness[16][32] =
|
||||
{
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04 },
|
||||
{ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06 },
|
||||
{ 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04,
|
||||
0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08 },
|
||||
{ 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05,
|
||||
0x05, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a },
|
||||
{ 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06,
|
||||
0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c },
|
||||
{ 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07,
|
||||
0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e },
|
||||
{ 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08,
|
||||
0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x11 },
|
||||
{ 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09,
|
||||
0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x13 },
|
||||
{ 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x05, 0x06, 0x07, 0x07, 0x08, 0x09, 0x09, 0x0a,
|
||||
0x0b, 0x0b, 0x0c, 0x0d, 0x0d, 0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15 },
|
||||
{ 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x04, 0x05, 0x06, 0x07, 0x07, 0x08, 0x09, 0x0a, 0x0a, 0x0b,
|
||||
0x0c, 0x0c, 0x0d, 0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14, 0x15, 0x15, 0x16, 0x17 },
|
||||
{ 0x00, 0x01, 0x02, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0a, 0x0b, 0x0c,
|
||||
0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14, 0x15, 0x16, 0x16, 0x17, 0x18, 0x19 },
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0a, 0x0b, 0x0c, 0x0d,
|
||||
0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x17, 0x18, 0x19, 0x1a, 0x1b },
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
|
||||
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d },
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }
|
||||
};
|
||||
|
||||
uint8 S9xOpLengthsM0X0[256] =
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 0
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 1
|
||||
3, 2, 4, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 2
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 3
|
||||
1, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 4
|
||||
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 4, 3, 3, 4, // 5
|
||||
1, 2, 3, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 6
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 7
|
||||
2, 2, 3, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 8
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 9
|
||||
3, 2, 3, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // A
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // B
|
||||
3, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // C
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // D
|
||||
3, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // E
|
||||
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4 // F
|
||||
};
|
||||
|
||||
uint8 S9xOpLengthsM0X1[256] =
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 0
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 1
|
||||
3, 2, 4, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 2
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 3
|
||||
1, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 4
|
||||
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 4, 3, 3, 4, // 5
|
||||
1, 2, 3, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 6
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 7
|
||||
2, 2, 3, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 8
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 9
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // A
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // B
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // C
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // D
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // E
|
||||
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4 // F
|
||||
};
|
||||
|
||||
uint8 S9xOpLengthsM1X0[256] =
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 0
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 1
|
||||
3, 2, 4, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 2
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 3
|
||||
1, 2, 2, 2, 3, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 4
|
||||
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 4, 3, 3, 4, // 5
|
||||
1, 2, 3, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 6
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 7
|
||||
2, 2, 3, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 8
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 9
|
||||
3, 2, 3, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // A
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // B
|
||||
3, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // C
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // D
|
||||
3, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // E
|
||||
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4 // F
|
||||
};
|
||||
|
||||
uint8 S9xOpLengthsM1X1[256] =
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 0
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 1
|
||||
3, 2, 4, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 2
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 3
|
||||
1, 2, 2, 2, 3, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 4
|
||||
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 4, 3, 3, 4, // 5
|
||||
1, 2, 3, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 6
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 7
|
||||
2, 2, 3, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // 8
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // 9
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // A
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // B
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // C
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4, // D
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 3, 3, 3, 4, // E
|
||||
2, 2, 2, 2, 3, 2, 2, 2, 1, 3, 1, 1, 3, 3, 3, 4 // F
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
Brandon Wright (bearoso@gmail.com)
|
||||
|
||||
Translators:
|
||||
Tukuyomi (fr_FR)
|
||||
Inukaze (es_VE)
|
||||
Tibério Vítor (pt_BR)
|
||||
Milan Kostić (sr@latin)
|
|
@ -0,0 +1,241 @@
|
|||
SUBDIRS = data po
|
||||
|
||||
bin_PROGRAMS = snes9x-gtk
|
||||
snes9x_gtk_LDADD =
|
||||
if DEBUG
|
||||
else
|
||||
snes9x_gtk_CXXFLAGS = -fno-exceptions -fno-rtti
|
||||
endif
|
||||
noinst_LIBRARIES =
|
||||
|
||||
INCLUDES = -I$(top_srcdir) -I.. -DSNES9XLOCALEDIR=\""$(snes9xlocaledir)"\"
|
||||
|
||||
CLEANFILES = \
|
||||
src/gtk_glade.cpp \
|
||||
src/sourcify
|
||||
|
||||
snes9x_gtk_SOURCES = \
|
||||
src/gtk_sound_driver.h \
|
||||
../filter/2xsai.cpp \
|
||||
../filter/2xsai.h \
|
||||
../filter/epx.cpp \
|
||||
../filter/epx.h \
|
||||
../filter/hq2x.cpp \
|
||||
../filter/hq2x.h \
|
||||
src/filter_epx_unsafe.h \
|
||||
src/filter_epx_unsafe.cpp \
|
||||
src/gtk_binding.cpp \
|
||||
src/gtk_binding.h \
|
||||
src/gtk_cheat.cpp \
|
||||
src/gtk_cheat.h \
|
||||
src/gtk_config.cpp \
|
||||
src/gtk_config.h \
|
||||
src/gtk_control.cpp \
|
||||
src/gtk_control.h \
|
||||
src/gtk_display.cpp \
|
||||
src/gtk_display_driver_gtk.cpp \
|
||||
src/gtk_display_driver_gtk.h \
|
||||
src/gtk_display_driver.h \
|
||||
src/gtk_display.h \
|
||||
src/gtk_file.cpp \
|
||||
src/gtk_file.h \
|
||||
src/gtk_glade.cpp \
|
||||
src/gtk_glade_window.cpp \
|
||||
src/gtk_glade_window.h \
|
||||
src/gtk_preferences.cpp \
|
||||
src/gtk_preferences.h \
|
||||
src/gtk_s9xcore.h \
|
||||
src/gtk_s9x.cpp \
|
||||
src/gtk_s9x.h \
|
||||
src/gtk_s9xwindow.cpp \
|
||||
src/gtk_s9xwindow.h \
|
||||
src/gtk_sound.cpp \
|
||||
src/gtk_sound.h \
|
||||
src/gtk_splash.h \
|
||||
src/snes_ntsc_config.h \
|
||||
src/snes_ntsc.h \
|
||||
src/snes_ntsc_impl.h \
|
||||
src/snes_ntsc.c
|
||||
|
||||
if PORTAUDIO
|
||||
snes9x_gtk_SOURCES += \
|
||||
src/gtk_sound_driver_portaudio.cpp \
|
||||
src/gtk_sound_driver_portaudio.h
|
||||
endif
|
||||
|
||||
if PULSEAUDIO
|
||||
snes9x_gtk_SOURCES += \
|
||||
src/gtk_sound_driver_pulse.cpp \
|
||||
src/gtk_sound_driver_pulse.h
|
||||
endif
|
||||
|
||||
if OSS
|
||||
snes9x_gtk_SOURCES += \
|
||||
src/gtk_sound_driver_oss.h \
|
||||
src/gtk_sound_driver_oss.cpp
|
||||
endif
|
||||
|
||||
if SDL
|
||||
snes9x_gtk_SOURCES += \
|
||||
src/gtk_sound_driver_sdl.h \
|
||||
src/gtk_sound_driver_sdl.cpp
|
||||
endif
|
||||
|
||||
if ALSA
|
||||
snes9x_gtk_SOURCES += \
|
||||
src/gtk_sound_driver_alsa.h \
|
||||
src/gtk_sound_driver_alsa.cpp
|
||||
endif
|
||||
|
||||
if ZSNESFX
|
||||
snes9x_gtk_SOURCES += \
|
||||
../i386/fxemu2b.asm \
|
||||
../i386/fxemu2.asm \
|
||||
../i386/fxemu2c.asm \
|
||||
../i386/fxtable.asm \
|
||||
../i386/sfxproc.asm \
|
||||
../i386/zsnes.asm
|
||||
else
|
||||
snes9x_gtk_SOURCES += \
|
||||
../fxinst.cpp \
|
||||
../fxemu.cpp \
|
||||
../fxdbg.cpp
|
||||
endif
|
||||
|
||||
if ZSNESC4
|
||||
snes9x_gtk_SOURCES += \
|
||||
../i386/c4.asm \
|
||||
../i386/zsnesc4.asm \
|
||||
../c4.cpp
|
||||
else
|
||||
snes9x_gtk_SOURCES += \
|
||||
../c4.cpp \
|
||||
../c4emu.cpp
|
||||
endif
|
||||
|
||||
# APU
|
||||
snes9x_gtk_SOURCES += \
|
||||
../apu/apu.cpp \
|
||||
../apu/SNES_SPC.cpp \
|
||||
../apu/SNES_SPC_misc.cpp \
|
||||
../apu/SNES_SPC_state.cpp \
|
||||
../apu/SPC_DSP.cpp \
|
||||
../apu/SPC_Filter.cpp
|
||||
|
||||
# DSP
|
||||
snes9x_gtk_SOURCES += \
|
||||
../dsp.cpp \
|
||||
../dsp1.cpp \
|
||||
../dsp2.cpp \
|
||||
../dsp3.cpp \
|
||||
../dsp4.cpp
|
||||
|
||||
# Base
|
||||
snes9x_gtk_SOURCES += \
|
||||
../spc7110.cpp \
|
||||
../obc1.cpp \
|
||||
../seta.cpp \
|
||||
../seta010.cpp \
|
||||
../seta011.cpp \
|
||||
../seta018.cpp \
|
||||
../controls.cpp \
|
||||
../crosshairs.cpp \
|
||||
../cpu.cpp \
|
||||
../sa1.cpp \
|
||||
../debug.cpp \
|
||||
../sdd1.cpp \
|
||||
../tile.cpp \
|
||||
../srtc.cpp \
|
||||
../gfx.cpp \
|
||||
../memmap.cpp \
|
||||
../clip.cpp \
|
||||
../ppu.cpp \
|
||||
../dma.cpp \
|
||||
../snes9x.cpp \
|
||||
../globals.cpp \
|
||||
../reader.cpp \
|
||||
../conffile.cpp \
|
||||
../bsx.cpp \
|
||||
../logger.cpp \
|
||||
../snapshot.cpp \
|
||||
../screenshot.cpp \
|
||||
../movie.cpp
|
||||
|
||||
# ASMCPU Doesn't exist anymore.
|
||||
snes9x_gtk_SOURCES += \
|
||||
../cpuops.cpp \
|
||||
../cpuexec.cpp \
|
||||
../sa1cpu.cpp
|
||||
|
||||
snes9x_gtk_SOURCES += \
|
||||
../cheats.cpp \
|
||||
../cheats2.cpp
|
||||
|
||||
if SDD1_DECOMP
|
||||
snes9x_gtk_SOURCES += ../sdd1emu.cpp
|
||||
endif
|
||||
|
||||
if NETPLAY
|
||||
snes9x_gtk_SOURCES += \
|
||||
../netplay.cpp \
|
||||
../server.cpp
|
||||
endif
|
||||
|
||||
# Zip support is nonconfigurable.
|
||||
snes9x_gtk_SOURCES += \
|
||||
../loadzip.cpp \
|
||||
../unzip/unzip.c \
|
||||
../unzip/ioapi.c \
|
||||
../unzip/zip.c
|
||||
UNZIPDEFINES=-DUNZIP_SUPPORT
|
||||
|
||||
if JMA
|
||||
snes9x_gtk_LDADD += libjma.a
|
||||
noinst_LIBRARIES += libjma.a
|
||||
libjma_a_SOURCES = \
|
||||
../jma/s9x-jma.cpp \
|
||||
../jma/7zlzma.cpp \
|
||||
../jma/crc32.cpp \
|
||||
../jma/iiostrm.cpp \
|
||||
../jma/inbyte.cpp \
|
||||
../jma/jma.cpp \
|
||||
../jma/lzma.cpp \
|
||||
../jma/lzmadec.cpp \
|
||||
../jma/winout.cpp
|
||||
libjma_a_CPPFLAGS = -fexceptions
|
||||
endif
|
||||
|
||||
if OPENGL
|
||||
snes9x_gtk_SOURCES += \
|
||||
src/gtk_display_driver_opengl.cpp \
|
||||
src/gtk_display_driver_opengl.h
|
||||
endif
|
||||
|
||||
if XV
|
||||
snes9x_gtk_SOURCES += \
|
||||
src/gtk_display_driver_xv.cpp \
|
||||
src/gtk_display_driver_xv.h
|
||||
endif
|
||||
|
||||
if NETPLAY
|
||||
snes9x_gtk_SOURCES += \
|
||||
src/gtk_netplay_dialog.cpp \
|
||||
src/gtk_netplay_dialog.h \
|
||||
src/gtk_netplay.cpp \
|
||||
src/gtk_netplay.h
|
||||
endif
|
||||
|
||||
SUFFIXES = .asm .ASM
|
||||
|
||||
src/sourcify: src/sourcify.c
|
||||
$(CC) src/sourcify.c -o src/sourcify
|
||||
|
||||
src/gtk_glade.cpp: src/sourcify src/snes9x.glade
|
||||
src/sourcify src/snes9x.glade src/gtk_glade.cpp snes9x_glade
|
||||
|
||||
.asm.o:
|
||||
$(NASM) -f elf -DELF $(NASM_FLAGS) -i ./ -i ../ -i ../i386/ -i i386/ -o $@ $*.asm
|
||||
|
||||
.ASM.o:
|
||||
$(NASM) -f elf -DELF $(NASM_FLAGS) -i ./ -i ../ -i ../i386/ -i i386/ $*.ASM -o $@
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh
|
||||
|
||||
glib-gettextize -f -c
|
||||
intltoolize --copy --force --automake
|
||||
aclocal
|
||||
automake --add-missing --copy
|
||||
autoconf
|
||||
|
||||
rm -f intltool-extract.in intltool-merge.in intltool-update.in
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
#! /bin/sh
|
||||
# Wrapper for compilers which do not understand `-c -o'.
|
||||
|
||||
scriptversion=2009-10-06.20; # UTC
|
||||
|
||||
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009 Free Software
|
||||
# Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Wrapper for compilers which do not understand `-c -o'.
|
||||
Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||
arguments, and rename the output as expected.
|
||||
|
||||
If you are trying to build a whole package this is not the
|
||||
right script to run: please start by reading the file `INSTALL'.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "compile $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
ofile=
|
||||
cfile=
|
||||
eat=
|
||||
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as `compile cc -o foo foo.c'.
|
||||
# So we strip `-o arg' only if arg is an object.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.obj)
|
||||
ofile=$2
|
||||
;;
|
||||
*)
|
||||
set x "$@" -o "$2"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*.c)
|
||||
cfile=$1
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if test -z "$ofile" || test -z "$cfile"; then
|
||||
# If no `-o' option was seen then we might have been invoked from a
|
||||
# pattern rule where we don't need one. That is ok -- this is a
|
||||
# normal compilation that the losing compiler can handle. If no
|
||||
# `.c' file was seen then we are probably linking. That is also
|
||||
# ok.
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
# Name of file we expect compiler to create.
|
||||
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
|
||||
|
||||
# Create the lock directory.
|
||||
# Note: use `[/\\:.-]' here to ensure that we don't use the same name
|
||||
# that we are using for the .o file. Also, base the name on the expected
|
||||
# object file name, since that is what matters with a parallel build.
|
||||
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
|
||||
while true; do
|
||||
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
# FIXME: race condition here if user kills between mkdir and trap.
|
||||
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||
|
||||
# Run the compile.
|
||||
"$@"
|
||||
ret=$?
|
||||
|
||||
if test -f "$cofile"; then
|
||||
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
|
||||
elif test -f "${cofile}bj"; then
|
||||
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
|
||||
fi
|
||||
|
||||
rmdir "$lockdir"
|
||||
exit $ret
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,547 @@
|
|||
AC_INIT([snes9x-gtk], 1.52)
|
||||
dnl Set CFLAGS, CXXFLAGS to something
|
||||
dnl before doing AC_PROG_CC, AC_PROG_CXX to avoid default -g
|
||||
CFLAGS="-O2 -Wall -W -pedantic -Wno-unused-parameter -pipe $CFLAGS"
|
||||
CXXFLAGS="$CFLAGS"
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_PROG_RANLIB
|
||||
AC_LANG_CPLUSPLUS
|
||||
|
||||
AC_PROG_INSTALL
|
||||
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||
|
||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
|
||||
|
||||
AM_PROG_CC_C_O
|
||||
IT_PROG_INTLTOOL([0.40.1])
|
||||
GETTEXT_PACKAGE=[snes9x-gtk]
|
||||
AC_SUBST(GETTEXT_PACKAGE)
|
||||
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE")
|
||||
|
||||
AM_GLIB_GNU_GETTEXT
|
||||
|
||||
snes9xlocaledir='${prefix}/${DATADIRNAME}/locale'
|
||||
AC_SUBST(snes9xlocaledir)
|
||||
|
||||
AC_ARG_WITH(debug,
|
||||
[AS_HELP_STRING([--with(out)-debug],
|
||||
[Leave debug information in the final binary (default: without)])],
|
||||
[],
|
||||
[with_debug=no])
|
||||
|
||||
AC_ARG_WITH(opengl,
|
||||
[AS_HELP_STRING([--with(out)-opengl],
|
||||
[Use OpenGL for output (default: with)])],
|
||||
[],
|
||||
[with_opengl=yes])
|
||||
|
||||
AC_ARG_WITH(joystick,
|
||||
[AS_HELP_STRING([--with(out)-joystick],
|
||||
[Enable joystick support if available (default: with)])],
|
||||
[],
|
||||
[with_joystick=yes])
|
||||
|
||||
AC_ARG_WITH(xv,
|
||||
[AS_HELP_STRING([--with(out)-xv],
|
||||
[Enable XVideo output on GTK (default: with)])],
|
||||
[],
|
||||
[with_xv=yes])
|
||||
|
||||
AC_ARG_WITH(xrandr,
|
||||
[AS_HELP_STRING([--with(out)-xrandr],
|
||||
[Enable XRandR support on GTK (default: with)])],
|
||||
[],
|
||||
[with_xrandr=yes])
|
||||
|
||||
AC_ARG_WITH(portaudio,
|
||||
[AS_HELP_STRING([--with(out)-portaudio],
|
||||
[Enable PortAudio sound driver support (default: with)])],
|
||||
[],
|
||||
[with_portaudio=yes])
|
||||
|
||||
AC_ARG_WITH(oss,
|
||||
[AS_HELP_STRING([--with(out)-oss],
|
||||
[Enable OSS sound driver support (default: with)])],
|
||||
[],
|
||||
[with_oss=yes])
|
||||
|
||||
AC_ARG_WITH(alsa,
|
||||
[AS_HELP_STRING([--with(out)-alsa],
|
||||
[Enable ALSA sound driver support (default: with)])],
|
||||
[],
|
||||
[with_alsa=yes])
|
||||
|
||||
AC_ARG_WITH(pulseaudio,
|
||||
[AS_HELP_STRING([--with(out)-pulseaudio],
|
||||
[Enable PulseAudio sound driver support (default: with)])],
|
||||
[],
|
||||
[with_pulseaudio=yes])
|
||||
|
||||
AC_ARG_WITH(assembler,
|
||||
[AS_HELP_STRING([--with(out)-assembler],
|
||||
[Use assembler cores if available (default: with)])],
|
||||
[],
|
||||
[with_assembler=yes])
|
||||
|
||||
AC_ARG_WITH(zsnesc4,
|
||||
[AS_HELP_STRING([--with(out)-zsnesc4],
|
||||
[Use ZSNES C4 core if available (default: same as --with-assembler)])],
|
||||
[],
|
||||
[with_zsnesc4=$with_assembler])
|
||||
|
||||
AC_ARG_WITH(zsnesfx,
|
||||
[AS_HELP_STRING([--with(out)-zsnesfx],
|
||||
[Use ZSNES SuperFX core if available (default: same as --with-assembler)])],
|
||||
[],
|
||||
[with_zsnesfx=$with_assembler])
|
||||
|
||||
AC_ARG_WITH(debugger,
|
||||
[AS_HELP_STRING([--with(out)-debugger],
|
||||
[Enable debugger (default: without)])],
|
||||
[],
|
||||
[with_debugger=no])
|
||||
|
||||
AC_ARG_WITH(sdd1-decomp,
|
||||
[AS_HELP_STRING([--with(out)-sdd1-decomp],
|
||||
[Use SDD1 decompression (default: with)])],
|
||||
[],
|
||||
[with_sdd1_decomp=yes])
|
||||
|
||||
AC_ARG_WITH(netplay,
|
||||
[AS_HELP_STRING([--with(out)-netplay],
|
||||
[Enable netplay support (default: without)])],
|
||||
[],
|
||||
[with_netplay=yes])
|
||||
|
||||
AC_ARG_WITH(jma-decomp,
|
||||
[AS_HELP_STRING([--with(out)-jma-decomp],
|
||||
[Enable JMA archive decompression (default: with)])],
|
||||
[],
|
||||
[with_jma_decomp=yes])
|
||||
|
||||
AC_ARG_WITH(newblend,
|
||||
[AS_HELP_STRING([--with(out)-newblend],
|
||||
[New colour blender (default: with)])],
|
||||
[],
|
||||
[with_newblend=yes])
|
||||
|
||||
AC_ARG_WITH(zlib,
|
||||
[AS_HELP_STRING([--with(out)-zlib],
|
||||
[Support gzip decompression])],
|
||||
[],
|
||||
[with_zlib=yes])
|
||||
|
||||
AC_ARG_WITH(png,
|
||||
[AS_HELP_STRING([--with(out)-screenshot],
|
||||
[Screenshot support through libpng if available (default: with)])],
|
||||
[],
|
||||
[with_screenshot=yes])
|
||||
|
||||
if test yes = "$with_debug" ; then
|
||||
CFLAGS="$CFLAGS -g"
|
||||
else
|
||||
CFLAGS="$CFLAGS -fomit-frame-pointer"
|
||||
fi
|
||||
|
||||
ZSNESFX='#ZSNESFX=yes'
|
||||
ZSNESC4='#ZSNESC4=yes'
|
||||
ASMCPU=''
|
||||
SDD1_DECOMP='#SDD1_DECOMP=yes'
|
||||
JMA='#JMA=yes'
|
||||
SPC700ASM=''
|
||||
I386SPC=''
|
||||
CPUINC=''
|
||||
NETPLAY='#NETPLAY=yes'
|
||||
|
||||
SYSLIBS=''
|
||||
NASM='not_found'
|
||||
|
||||
OPENGL=0
|
||||
|
||||
if test yes = "$with_opengl" ; then
|
||||
OPENGL=yes
|
||||
fi
|
||||
|
||||
GTK=yes
|
||||
snes9x_info_display="GTK"
|
||||
|
||||
PKG_CHECK_MODULES([GTK], [gtk+-2.0 >= 2.10])
|
||||
PKG_CHECK_MODULES([GLIB], [gthread-2.0 >= 2.6 gobject-2.0 >= 2.6])
|
||||
PKG_CHECK_MODULES([GLADE], [libglade-2.0 >= 2.0])
|
||||
PKG_CHECK_MODULES([LIBXML], [libxml-2.0 >= 2.0])
|
||||
|
||||
if test yes = "$with_opengl" ; then
|
||||
|
||||
AC_CHECK_LIB(GL,glGetString,[
|
||||
OPENGL=yes
|
||||
CFLAGS="$CFLAGS -DUSE_OPENGL"
|
||||
LIBS="-lGL"
|
||||
],[
|
||||
OPENGL=0
|
||||
])
|
||||
fi
|
||||
|
||||
GTKJOY=0
|
||||
SDL_CFLAGS=""
|
||||
SDL_LIBS=""
|
||||
if test yes = "$with_joystick"; then
|
||||
PKG_CHECK_MODULES([SDL],[sdl],[
|
||||
GTKJOY=yes
|
||||
CFLAGS="$CFLAGS -DUSE_JOYSTICK"
|
||||
],[
|
||||
AC_CHECK_PROG(SDLCONFIGFOUND,[sdl-config],yes,no)
|
||||
|
||||
if test yes = "$SDLCONFIGFOUND" ; then
|
||||
SDL_CFLAGS="-DUSE_JOYSTICK `sdl-config --cflags`"
|
||||
SDL_LIBS="`sdl-config --libs`"
|
||||
GTKJOY=yes
|
||||
else
|
||||
echo "Cannot find SDL. Disabling joystick support."
|
||||
fi
|
||||
])
|
||||
fi
|
||||
|
||||
XV=0
|
||||
XV_CFLAGS=""
|
||||
XV_LIBS=""
|
||||
if test yes = "$with_xv" ; then
|
||||
PKG_CHECK_MODULES([XV],[xv],[
|
||||
XV=yes
|
||||
CFLAGS="$CFLAGS -DUSE_XV"
|
||||
],[
|
||||
echo "Cannot find libXv. Make sure the X11 development headers are installed."
|
||||
echo "--> Disabling Xv support"
|
||||
])
|
||||
fi
|
||||
|
||||
PORTAUDIO=0
|
||||
PORTAUDIO_CFLAGS=""
|
||||
PORTAUDIO_LIBS=""
|
||||
if test yes = "$with_portaudio" ; then
|
||||
PKG_CHECK_MODULES([PORTAUDIO], [portaudio-2.0 >= 10],[
|
||||
PORTAUDIO=yes
|
||||
CFLAGS="$CFLAGS -DUSE_PORTAUDIO"
|
||||
],[
|
||||
echo "Cannot find PortAudio."
|
||||
echo "--> Disabling PortAudio support"
|
||||
])
|
||||
fi
|
||||
|
||||
OSS=0
|
||||
if test yes = "$with_oss" ; then
|
||||
|
||||
AC_CHECK_HEADER(sys/soundcard.h, [
|
||||
CFLAGS="$CFLAGS -DUSE_OSS"
|
||||
OSS=yes
|
||||
],[
|
||||
echo "Cannot find OSS headers."
|
||||
echo "--> Disabling OSS support"
|
||||
])
|
||||
fi
|
||||
|
||||
ALSA=0
|
||||
ALSA_CFLAGS=""
|
||||
ALSA_LIBS=""
|
||||
if test yes = "$with_alsa" ; then
|
||||
|
||||
PKG_CHECK_MODULES([ALSA], [alsa],[
|
||||
ALSA=yes
|
||||
CFLAGS="$CFLAGS -DUSE_ALSA"
|
||||
],[
|
||||
echo "Cannot find ALSA development support."
|
||||
echo "--> Disabling ALSA"
|
||||
])
|
||||
fi
|
||||
|
||||
PULSEAUDIO=0
|
||||
PULSEAUDIO_CFLAGS=""
|
||||
PULSEAUDIO_LIBS=""
|
||||
if test yes = "$with_pulseaudio" ; then
|
||||
PKG_CHECK_MODULES([PULSEAUDIO], [libpulse-simple],[
|
||||
PULSEAUDIO=yes
|
||||
CFLAGS="$CFLAGS -DUSE_PULSEAUDIO"
|
||||
],[
|
||||
echo "Cannot find PulseAudio library."
|
||||
echo "--> Disabling PulseAudio"
|
||||
])
|
||||
fi
|
||||
|
||||
XRANDR=0
|
||||
XRANDR_CFLAGS=""
|
||||
XRANDR_LIBS=""
|
||||
if test yes = "$with_xrandr" ; then
|
||||
PKG_CHECK_MODULES([XRANDR],[xrandr],[
|
||||
XRANDR=yes
|
||||
CFLAGS="$CFLAGS -DUSE_XRANDR"
|
||||
],[
|
||||
echo "Cannot find libXrandr. Make sure the X11 development headers are installed."
|
||||
echo "--> Disabling Xrandr support."
|
||||
])
|
||||
fi
|
||||
PKG_CHECK_MODULES([LIBPNG],libpng)
|
||||
|
||||
CFLAGS="$CFLAGS $GTK_CFLAGS $GLIB_CFLAGS $GLADE_CFLAGS $LIBXML_CFLAGS $PORTAUDIO_CFLAGS $LIBPNG_CFLAGS $SDL_CFLAGS $XV_CFLAGS $XRANDR_CFLAGS $ALSA_CFLAGS $PULSEAUDIO_CFLAGS"
|
||||
LIBS="$LIBS $GTK_LIBS $GLIB_LIBS $GLADE_LIBS $LIBXML_LIBS $PORTAUDIO_LIBS $LIBPNG_LIBS $SDL_LIBS $XV_LIBS $XRANDR_LIBS $ALSA_LIBS $PULSEAUDIO_LIBS"
|
||||
|
||||
|
||||
AC_MSG_CHECKING(if the CPU is IA32)
|
||||
AC_CACHE_VAL(snes9x_cv_i386_cpu, [
|
||||
AC_TRY_COMPILE([
|
||||
#if (defined (__i386__) || defined (__i486__) ||\
|
||||
defined (__i586__) || defined (__i686__) || defined (__WIN32__) || defined (__DJGPP))
|
||||
/* */
|
||||
#else
|
||||
#error Not i386.
|
||||
#endif
|
||||
], [], snes9x_cv_i386_cpu=yes, snes9x_cv_i386_cpu=no)])
|
||||
|
||||
dnl Enable assembler optimizations if CPU is x86
|
||||
|
||||
NASM="not_found"
|
||||
if test yes = "$with_assembler"; then
|
||||
AC_PATH_PROG(prog_nasm, nasm, no)
|
||||
|
||||
if test "x$ac_cv_path_prog_nasm" = "xno"; then
|
||||
if test yes = "$snes9x_cv_i386_cpu"; then
|
||||
AC_MSG_WARN([No nasm found. Will build without assembler optimizations.])
|
||||
fi
|
||||
else
|
||||
if test yes = "$snes9x_cv_i386_cpu"; then
|
||||
NASM="$ac_cv_path_prog_nasm"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $NASM != "not_found"; then
|
||||
if test yes = "$with_zsnesc4"; then
|
||||
ZSNESC4=yes
|
||||
CFLAGS="$CFLAGS -DZSNES_C4"
|
||||
NASM_FLAGS="$NASM_FLAGS -DZSNES_C4"
|
||||
fi
|
||||
if test yes = "$with_zsnesfx"; then
|
||||
ZSNESFX=yes
|
||||
CFLAGS="$CFLAGS -DZSNES_FX -DEXECUTE_SUPERFX_PER_LINE"
|
||||
NASM_FLAGS="$NASM_FLAGS -DZSNES_FX -DEXECUTE_SUPERFX_PER_LINE"
|
||||
fi
|
||||
CPUINC='-Ii386'
|
||||
fi
|
||||
|
||||
CFLAGS="$CFLAGS -DCORRECT_VRAM_READS"
|
||||
CORRECT_VRAM_READS=1
|
||||
|
||||
if test yes = "$with_debugger"; then
|
||||
CFLAGS="$CFLAGS -DDEBUGGER"
|
||||
fi
|
||||
|
||||
|
||||
dnl Enable SDD1 decompression if requested
|
||||
if test yes = "$with_sdd1_decomp"; then
|
||||
CFLAGS="$CFLAGS -DSDD1_DECOMP"
|
||||
SDD1_DECOMP=yes
|
||||
fi
|
||||
|
||||
dnl Enable Netplay support if requested
|
||||
if test yes = "$with_netplay"; then
|
||||
CFLAGS="$CFLAGS -DNETPLAY_SUPPORT"
|
||||
NETPLAY=yes
|
||||
fi
|
||||
|
||||
dnl Enable jma decompression (nachs own format)
|
||||
if test yes = "$with_jma_decomp"; then
|
||||
CFLAGS="$CFLAGS -DJMA_SUPPORT"
|
||||
JMA=yes
|
||||
fi
|
||||
|
||||
dnl FIXME: There is a third case (OLD) that is missed with this.
|
||||
if test yes = "$with_newblend"; then
|
||||
CFLAGS="$CFLAGS -DNEW_COLOUR_BLENDING"
|
||||
else
|
||||
#OLD_COLOUR_BLENDING hasn't been default for a while
|
||||
# SYSDEFINES="$SYSDEFINES"' -DOLD_COLOUR_BLENDING'
|
||||
:
|
||||
fi
|
||||
|
||||
if test yes = "$with_zlib"; then
|
||||
AC_CHECK_HEADERS(zlib.h)
|
||||
AC_CHECK_LIB(z, gzread, [
|
||||
CFLAGS="$CFLAGS -DZLIB"
|
||||
LIBS="$LIBS -lz"
|
||||
], ,)
|
||||
fi
|
||||
|
||||
if test yes = "$with_screenshot"; then
|
||||
AC_CHECK_LIB(png, png_init_io, [
|
||||
CFLAGS="$CFLAGS -DHAVE_LIBPNG"
|
||||
LIBS="$LIBS -lpng"
|
||||
], , -lz -lm)
|
||||
fi
|
||||
|
||||
dnl Check for functions
|
||||
AC_CHECK_FUNC(mkstemp, [
|
||||
CFLAGS="$CFLAGS -DHAVE_MKSTEMP"
|
||||
])
|
||||
|
||||
dnl Check for headers
|
||||
|
||||
AC_CHECK_HEADER(strings.h, [
|
||||
CFLAGS="$CFLAGS -DHAVE_STRINGS_H"
|
||||
])
|
||||
|
||||
AC_CHECK_HEADER(sys/ioctl.h, [
|
||||
CFLAGS="$CFLAGS -DHAVE_SYS_IOCTL_H"
|
||||
])
|
||||
|
||||
AC_CHECK_HEADER(stdint.h, [
|
||||
CFLAGS="$CFLAGS -DHAVE_STDINT_H"
|
||||
])
|
||||
|
||||
|
||||
dnl Check SAR
|
||||
|
||||
AC_DEFUN([AC_MY_CHECK_SAR],
|
||||
[
|
||||
AC_MSG_CHECKING([if rightshift $1 is arithmetic])
|
||||
AC_CACHE_VAL(ac_cv_my_sar_$1,
|
||||
[
|
||||
AC_TRY_RUN([
|
||||
#include "../port.h"
|
||||
|
||||
int main(void){
|
||||
$1 i;
|
||||
|
||||
i=-1;
|
||||
i>>=1;
|
||||
return(i<0?0:1);
|
||||
}
|
||||
],ac_cv_my_sar_$1=yes,ac_cv_my_sar_$1=no,ac_cv_my_sar_%1=no)
|
||||
])
|
||||
|
||||
if test $ac_cv_my_sar_$1 = no; then
|
||||
AC_MSG_RESULT(no)
|
||||
else
|
||||
CFLAGS="$CFLAGS -DRIGHTSHIFT_$1_IS_SAR"
|
||||
AC_MSG_RESULT(yes)
|
||||
fi
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING(if sizeof(void *) == sizeof(int))
|
||||
AC_TRY_RUN([
|
||||
int main()
|
||||
{
|
||||
return(!(sizeof(void *) == sizeof(int)));
|
||||
}
|
||||
], snes9x_ptr_is_int=yes)
|
||||
if test x$snes9x_ptr_is_int = xyes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
CFLAGS="$CFLAGS -DPTR_NOT_INT"
|
||||
fi
|
||||
|
||||
AC_MY_CHECK_SAR(int8)
|
||||
AC_MY_CHECK_SAR(int16)
|
||||
AC_MY_CHECK_SAR(int32)
|
||||
AC_MY_CHECK_SAR(int64)
|
||||
if test $ac_cv_my_sar_int8 = yes && \
|
||||
test $ac_cv_my_sar_int16 = yes && \
|
||||
test $ac_cv_my_sar_int32 = yes && \
|
||||
test $ac_cv_my_sar_int64 = yes ; then
|
||||
CFLAGS="$CFLAGS -DRIGHTSHIFT_IS_SAR"
|
||||
fi
|
||||
|
||||
CFLAGS="$CFLAGS -DCPU_SHUTDOWN -DSPC700_SHUTDOWN -DNO_INLINE_SET_GET -DUNZIP_SUPPORT -DSPC700_C -I. -I.. -I../unzip"
|
||||
|
||||
CXXFLAGS="$CFLAGS"
|
||||
|
||||
CCASFLAGS="$CFLAGS -I.. -I../i386"
|
||||
|
||||
AM_CONDITIONAL(ZSNESFX, [test yes = "$ZSNESFX"])
|
||||
AM_CONDITIONAL(ZSNESC4, [test yes = "$ZSNESC4"])
|
||||
AM_CONDITIONAL(ASMCPU, [test yes = "$ASMCPU"])
|
||||
AM_CONDITIONAL(SDD1_DECOMP, [test yes = "$SDD1_DECOMP"])
|
||||
AM_CONDITIONAL(NETPLAY, [test yes = "$NETPLAY"])
|
||||
AM_CONDITIONAL(JMA, [test yes = "$JMA"])
|
||||
AM_CONDITIONAL(OPENGL, [test yes = "$OPENGL"])
|
||||
AM_CONDITIONAL(XV, [test yes = "$XV"])
|
||||
AM_CONDITIONAL(PORTAUDIO, [test yes = "$PORTAUDIO"])
|
||||
AM_CONDITIONAL(OSS, [test yes = "$OSS"])
|
||||
AM_CONDITIONAL(DEBUG, [test yes = "$with_debug" ])
|
||||
AM_CONDITIONAL(SDL, [test yes = "$GTKJOY"])
|
||||
AM_CONDITIONAL(ALSA, [test yes = "$ALSA"])
|
||||
AM_CONDITIONAL(PULSEAUDIO, [test yes = "$PULSEAUDIO"])
|
||||
|
||||
AC_SUBST(NASM)
|
||||
AC_SUBST(NASM_FLAGS)
|
||||
|
||||
AC_OUTPUT(Makefile data/Makefile po/Makefile.in)
|
||||
|
||||
echo ""
|
||||
echo "Snes9x will build with support for the following:"
|
||||
echo ""
|
||||
|
||||
if test yes = "$ALSA" ; then
|
||||
echo " ALSA"
|
||||
fi
|
||||
|
||||
if test yes = "$PULSEAUDIO" ; then
|
||||
echo " PulseAudio"
|
||||
fi
|
||||
|
||||
if test yes = "$OPENGL" ; then
|
||||
echo " OpenGL"
|
||||
else
|
||||
if test yes = "$with_opengl" ; then
|
||||
echo "!!! NOT able to use OpenGL support"
|
||||
echo "--- Needs gtkglext and OpenGL libraries and headers"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test yes = "$XV" ; then
|
||||
echo " XVideo"
|
||||
else
|
||||
if test yes = "$with_xv" ; then
|
||||
echo "!!! NOT able to use XVideo support"
|
||||
echo "--- Needs recent X11 libraries and headers"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test yes = "$XRANDR" ; then
|
||||
echo " XRandR"
|
||||
else
|
||||
if test yes = "$with_xrandr" ; then
|
||||
echo "!!! NOT able to use XRandR support"
|
||||
echo "--- Needs recent X11 libraries and headers"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test yes = "$GTKJOY" ; then
|
||||
echo " Joysticks"
|
||||
else
|
||||
if test yes = "$with_joystick" ; then
|
||||
echo "!!! NOT able to use joystick support"
|
||||
echo "--- Needs SDL libraries and headers"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test yes = "$NETPLAY" ; then
|
||||
echo " NetPlay"
|
||||
else
|
||||
if test yes = "$with_netplay" ; then
|
||||
echo "!!! NOT able to build NetPlay support"
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
if ! test yes = "$PORTAUDIO" ; then
|
||||
if ! test yes = "$OSS" ; then
|
||||
if ! test yes = "$SDL"; then
|
||||
if ! test yes = "$ALSA"; then
|
||||
echo "ERROR: No audio driver is selected or available. Snes9x will probably not build."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,24 @@
|
|||
desktopdir = $(datadir)/applications
|
||||
desktop_DATA = snes9x.desktop
|
||||
|
||||
icon16x16dir = $(datadir)/icons/hicolor/16x16/apps
|
||||
icon16x16_DATA = snes9x_16x16.png
|
||||
|
||||
icon24x24dir = $(datadir)/icons/hicolor/24x24/apps
|
||||
icon24x24_DATA = snes9x_24x24.png
|
||||
|
||||
icon32x32dir = $(datadir)/icons/hicolor/32x32/apps
|
||||
icon32x32_DATA = snes9x_32x32.png
|
||||
|
||||
iconscalabledir = $(datadir)/icons/hicolor/scalable/apps
|
||||
iconscalable_DATA = snes9x.svg
|
||||
|
||||
install-data-hook:
|
||||
mv -f $(DESTDIR)$(datadir)/icons/hicolor/16x16/apps/snes9x_16x16.png \
|
||||
$(DESTDIR)$(datadir)/icons/hicolor/16x16/apps/snes9x.png
|
||||
mv -f $(DESTDIR)$(datadir)/icons/hicolor/24x24/apps/snes9x_24x24.png \
|
||||
$(DESTDIR)$(datadir)/icons/hicolor/24x24/apps/snes9x.png
|
||||
mv -f $(DESTDIR)$(datadir)/icons/hicolor/32x32/apps/snes9x_32x32.png \
|
||||
$(DESTDIR)$(datadir)/icons/hicolor/32x32/apps/snes9x.png
|
||||
touch -c $(DESTDIR)$(datadir)/icons/hicolor
|
||||
|
|
@ -0,0 +1,534 @@
|
|||
# Makefile.in generated by automake 1.11.1 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
|
||||
# Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
subdir = data
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
AM_V_GEN = $(am__v_GEN_$(V))
|
||||
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
AM_V_at = $(am__v_at_$(V))
|
||||
am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
|
||||
am__v_at_0 = @
|
||||
SOURCES =
|
||||
DIST_SOURCES =
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__installdirs = "$(DESTDIR)$(desktopdir)" \
|
||||
"$(DESTDIR)$(icon16x16dir)" "$(DESTDIR)$(icon24x24dir)" \
|
||||
"$(DESTDIR)$(icon32x32dir)" "$(DESTDIR)$(iconscalabledir)"
|
||||
DATA = $(desktop_DATA) $(icon16x16_DATA) $(icon24x24_DATA) \
|
||||
$(icon32x32_DATA) $(iconscalable_DATA)
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
ALL_LINGUAS = @ALL_LINGUAS@
|
||||
ALSA_CFLAGS = @ALSA_CFLAGS@
|
||||
ALSA_LIBS = @ALSA_LIBS@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CATALOGS = @CATALOGS@
|
||||
CATOBJEXT = @CATOBJEXT@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DATADIRNAME = @DATADIRNAME@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
|
||||
GLADE_CFLAGS = @GLADE_CFLAGS@
|
||||
GLADE_LIBS = @GLADE_LIBS@
|
||||
GLIB_CFLAGS = @GLIB_CFLAGS@
|
||||
GLIB_LIBS = @GLIB_LIBS@
|
||||
GMOFILES = @GMOFILES@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GREP = @GREP@
|
||||
GTK_CFLAGS = @GTK_CFLAGS@
|
||||
GTK_LIBS = @GTK_LIBS@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
INSTOBJEXT = @INSTOBJEXT@
|
||||
INTLLIBS = @INTLLIBS@
|
||||
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
|
||||
INTLTOOL_MERGE = @INTLTOOL_MERGE@
|
||||
INTLTOOL_PERL = @INTLTOOL_PERL@
|
||||
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBPNG_CFLAGS = @LIBPNG_CFLAGS@
|
||||
LIBPNG_LIBS = @LIBPNG_LIBS@
|
||||
LIBS = @LIBS@
|
||||
LIBXML_CFLAGS = @LIBXML_CFLAGS@
|
||||
LIBXML_LIBS = @LIBXML_LIBS@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
MKINSTALLDIRS = @MKINSTALLDIRS@
|
||||
MSGFMT = @MSGFMT@
|
||||
MSGFMT_OPTS = @MSGFMT_OPTS@
|
||||
MSGMERGE = @MSGMERGE@
|
||||
NASM = @NASM@
|
||||
NASM_FLAGS = @NASM_FLAGS@
|
||||
OBJEXT = @OBJEXT@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PKG_CONFIG = @PKG_CONFIG@
|
||||
POFILES = @POFILES@
|
||||
PORTAUDIO_CFLAGS = @PORTAUDIO_CFLAGS@
|
||||
PORTAUDIO_LIBS = @PORTAUDIO_LIBS@
|
||||
POSUB = @POSUB@
|
||||
PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
|
||||
PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
|
||||
PULSEAUDIO_CFLAGS = @PULSEAUDIO_CFLAGS@
|
||||
PULSEAUDIO_LIBS = @PULSEAUDIO_LIBS@
|
||||
RANLIB = @RANLIB@
|
||||
SDLCONFIGFOUND = @SDLCONFIGFOUND@
|
||||
SDL_CFLAGS = @SDL_CFLAGS@
|
||||
SDL_LIBS = @SDL_LIBS@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
USE_NLS = @USE_NLS@
|
||||
VERSION = @VERSION@
|
||||
XGETTEXT = @XGETTEXT@
|
||||
XRANDR_CFLAGS = @XRANDR_CFLAGS@
|
||||
XRANDR_LIBS = @XRANDR_LIBS@
|
||||
XV_CFLAGS = @XV_CFLAGS@
|
||||
XV_LIBS = @XV_LIBS@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build_alias = @build_alias@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host_alias = @host_alias@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
prog_nasm = @prog_nasm@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
snes9xlocaledir = @snes9xlocaledir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
desktopdir = $(datadir)/applications
|
||||
desktop_DATA = snes9x.desktop
|
||||
icon16x16dir = $(datadir)/icons/hicolor/16x16/apps
|
||||
icon16x16_DATA = snes9x_16x16.png
|
||||
icon24x24dir = $(datadir)/icons/hicolor/24x24/apps
|
||||
icon24x24_DATA = snes9x_24x24.png
|
||||
icon32x32dir = $(datadir)/icons/hicolor/32x32/apps
|
||||
icon32x32_DATA = snes9x_32x32.png
|
||||
iconscalabledir = $(datadir)/icons/hicolor/scalable/apps
|
||||
iconscalable_DATA = snes9x.svg
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign data/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --foreign data/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
install-desktopDATA: $(desktop_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(desktopdir)" || $(MKDIR_P) "$(DESTDIR)$(desktopdir)"
|
||||
@list='$(desktop_DATA)'; test -n "$(desktopdir)" || list=; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(desktopdir)'"; \
|
||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(desktopdir)" || exit $$?; \
|
||||
done
|
||||
|
||||
uninstall-desktopDATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(desktop_DATA)'; test -n "$(desktopdir)" || list=; \
|
||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||
test -n "$$files" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(desktopdir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(desktopdir)" && rm -f $$files
|
||||
install-icon16x16DATA: $(icon16x16_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(icon16x16dir)" || $(MKDIR_P) "$(DESTDIR)$(icon16x16dir)"
|
||||
@list='$(icon16x16_DATA)'; test -n "$(icon16x16dir)" || list=; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(icon16x16dir)'"; \
|
||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(icon16x16dir)" || exit $$?; \
|
||||
done
|
||||
|
||||
uninstall-icon16x16DATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(icon16x16_DATA)'; test -n "$(icon16x16dir)" || list=; \
|
||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||
test -n "$$files" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(icon16x16dir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(icon16x16dir)" && rm -f $$files
|
||||
install-icon24x24DATA: $(icon24x24_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(icon24x24dir)" || $(MKDIR_P) "$(DESTDIR)$(icon24x24dir)"
|
||||
@list='$(icon24x24_DATA)'; test -n "$(icon24x24dir)" || list=; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(icon24x24dir)'"; \
|
||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(icon24x24dir)" || exit $$?; \
|
||||
done
|
||||
|
||||
uninstall-icon24x24DATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(icon24x24_DATA)'; test -n "$(icon24x24dir)" || list=; \
|
||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||
test -n "$$files" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(icon24x24dir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(icon24x24dir)" && rm -f $$files
|
||||
install-icon32x32DATA: $(icon32x32_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(icon32x32dir)" || $(MKDIR_P) "$(DESTDIR)$(icon32x32dir)"
|
||||
@list='$(icon32x32_DATA)'; test -n "$(icon32x32dir)" || list=; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(icon32x32dir)'"; \
|
||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(icon32x32dir)" || exit $$?; \
|
||||
done
|
||||
|
||||
uninstall-icon32x32DATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(icon32x32_DATA)'; test -n "$(icon32x32dir)" || list=; \
|
||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||
test -n "$$files" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(icon32x32dir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(icon32x32dir)" && rm -f $$files
|
||||
install-iconscalableDATA: $(iconscalable_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(iconscalabledir)" || $(MKDIR_P) "$(DESTDIR)$(iconscalabledir)"
|
||||
@list='$(iconscalable_DATA)'; test -n "$(iconscalabledir)" || list=; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(iconscalabledir)'"; \
|
||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(iconscalabledir)" || exit $$?; \
|
||||
done
|
||||
|
||||
uninstall-iconscalableDATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(iconscalable_DATA)'; test -n "$(iconscalabledir)" || list=; \
|
||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||
test -n "$$files" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(iconscalabledir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(iconscalabledir)" && rm -f $$files
|
||||
tags: TAGS
|
||||
TAGS:
|
||||
|
||||
ctags: CTAGS
|
||||
CTAGS:
|
||||
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(DATA)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(desktopdir)" "$(DESTDIR)$(icon16x16dir)" "$(DESTDIR)$(icon24x24dir)" "$(DESTDIR)$(icon32x32dir)" "$(DESTDIR)$(iconscalabledir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-generic
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-desktopDATA install-icon16x16DATA \
|
||||
install-icon24x24DATA install-icon32x32DATA \
|
||||
install-iconscalableDATA
|
||||
@$(NORMAL_INSTALL)
|
||||
$(MAKE) $(AM_MAKEFLAGS) install-data-hook
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-generic
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-desktopDATA uninstall-icon16x16DATA \
|
||||
uninstall-icon24x24DATA uninstall-icon32x32DATA \
|
||||
uninstall-iconscalableDATA
|
||||
|
||||
.MAKE: install-am install-data-am install-strip
|
||||
|
||||
.PHONY: all all-am check check-am clean clean-generic distclean \
|
||||
distclean-generic distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am \
|
||||
install-data-hook install-desktopDATA install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-icon16x16DATA install-icon24x24DATA \
|
||||
install-icon32x32DATA install-iconscalableDATA install-info \
|
||||
install-info-am install-man install-pdf install-pdf-am \
|
||||
install-ps install-ps-am install-strip installcheck \
|
||||
installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
|
||||
pdf-am ps ps-am uninstall uninstall-am uninstall-desktopDATA \
|
||||
uninstall-icon16x16DATA uninstall-icon24x24DATA \
|
||||
uninstall-icon32x32DATA uninstall-iconscalableDATA
|
||||
|
||||
|
||||
install-data-hook:
|
||||
mv -f $(DESTDIR)$(datadir)/icons/hicolor/16x16/apps/snes9x_16x16.png \
|
||||
$(DESTDIR)$(datadir)/icons/hicolor/16x16/apps/snes9x.png
|
||||
mv -f $(DESTDIR)$(datadir)/icons/hicolor/24x24/apps/snes9x_24x24.png \
|
||||
$(DESTDIR)$(datadir)/icons/hicolor/24x24/apps/snes9x.png
|
||||
mv -f $(DESTDIR)$(datadir)/icons/hicolor/32x32/apps/snes9x_32x32.png \
|
||||
$(DESTDIR)$(datadir)/icons/hicolor/32x32/apps/snes9x.png
|
||||
touch -c $(DESTDIR)$(datadir)/icons/hicolor
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
|
@ -0,0 +1,9 @@
|
|||
[Desktop Entry]
|
||||
Name=Snes9x
|
||||
Comment=Super NES Emulator
|
||||
Type=Application
|
||||
Categories=Game;Emulator;
|
||||
MimeType=application/x-snes-rom;
|
||||
Exec=snes9x-gtk %F
|
||||
TryExec=snes9x-gtk
|
||||
Icon=snes9x
|
|
@ -0,0 +1,587 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://web.resource.org/cc/"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="48"
|
||||
height="48"
|
||||
id="svg3697"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.45.1"
|
||||
version="1.0"
|
||||
sodipodi:docbase="/home/bearoso/Desktop/snes9x-1.51-src/gtk"
|
||||
sodipodi:docname="snes9x.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
||||
<defs
|
||||
id="defs3699">
|
||||
<linearGradient
|
||||
id="linearGradient3862">
|
||||
<stop
|
||||
style="stop-color:#483493;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3864" />
|
||||
<stop
|
||||
style="stop-color:#1f1936;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3866" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3856">
|
||||
<stop
|
||||
style="stop-color:#cec6f9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3858" />
|
||||
<stop
|
||||
style="stop-color:#8b71eb;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3860" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3850">
|
||||
<stop
|
||||
id="stop3852"
|
||||
offset="0"
|
||||
style="stop-color:#8b95e6;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3854"
|
||||
offset="1"
|
||||
style="stop-color:#847cdf;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3804">
|
||||
<stop
|
||||
id="stop3806"
|
||||
offset="0"
|
||||
style="stop-color:#464097;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3808"
|
||||
offset="1"
|
||||
style="stop-color:#29293b;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3794">
|
||||
<stop
|
||||
id="stop3796"
|
||||
offset="0"
|
||||
style="stop-color:#eee5fb;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3798"
|
||||
offset="1"
|
||||
style="stop-color:#9f9bc1;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3770">
|
||||
<stop
|
||||
style="stop-color:#aeacc7;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3772" />
|
||||
<stop
|
||||
style="stop-color:#a19ec8;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3774" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3770"
|
||||
id="radialGradient3788"
|
||||
cx="7.119658"
|
||||
cy="3.5299144"
|
||||
fx="7.119658"
|
||||
fy="3.5299144"
|
||||
r="2.5213675"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3794"
|
||||
id="radialGradient3792"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="7.6385846"
|
||||
cy="2.1311038"
|
||||
fx="7.6385846"
|
||||
fy="2.1311038"
|
||||
r="2.5213675"
|
||||
gradientTransform="matrix(1.5905007,-1.0269578e-2,1.0269364e-2,1.5904675,-4.5385807,-1.7383567)" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3804"
|
||||
id="radialGradient3802"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="7.6324792"
|
||||
cy="4.0267229"
|
||||
fx="7.6324792"
|
||||
fy="4.0267229"
|
||||
r="2.5213675"
|
||||
gradientTransform="matrix(2.6871169,2.6177942e-7,-1.751068e-7,1.7949189,-12.876884,-3.6298631)" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3804"
|
||||
id="radialGradient3815"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.6871169,2.6177942e-7,-1.751068e-7,1.7949189,-12.876884,-3.6298631)"
|
||||
cx="7.6324792"
|
||||
cy="4.0267229"
|
||||
fx="7.6324792"
|
||||
fy="4.0267229"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3794"
|
||||
id="radialGradient3817"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.5905007,-1.0269578e-2,1.0269364e-2,1.5904675,-4.5385807,-1.7383567)"
|
||||
cx="7.6385846"
|
||||
cy="2.1311038"
|
||||
fx="7.6385846"
|
||||
fy="2.1311038"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3770"
|
||||
id="radialGradient3819"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="7.119658"
|
||||
cy="3.5299144"
|
||||
fx="7.119658"
|
||||
fy="3.5299144"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3804"
|
||||
id="radialGradient3829"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.6871169,2.6177942e-7,-1.751068e-7,1.7949189,-12.876884,-3.6298631)"
|
||||
cx="7.6324792"
|
||||
cy="4.0267229"
|
||||
fx="7.6324792"
|
||||
fy="4.0267229"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3794"
|
||||
id="radialGradient3831"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.5905007,-1.0269578e-2,1.0269364e-2,1.5904675,-4.5385807,-1.7383567)"
|
||||
cx="7.6385846"
|
||||
cy="2.1311038"
|
||||
fx="7.6385846"
|
||||
fy="2.1311038"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3770"
|
||||
id="radialGradient3833"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="7.119658"
|
||||
cy="3.5299144"
|
||||
fx="7.119658"
|
||||
fy="3.5299144"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3862"
|
||||
id="radialGradient3844"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.6871169,2.6177942e-7,-1.751068e-7,1.7949189,-12.876884,-3.6298631)"
|
||||
cx="7.6324792"
|
||||
cy="4.0267229"
|
||||
fx="7.6324792"
|
||||
fy="4.0267229"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3856"
|
||||
id="radialGradient3846"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.5905007,-1.0269578e-2,1.0269364e-2,1.5904675,-4.5385807,-1.7383567)"
|
||||
cx="7.6385846"
|
||||
cy="2.1311038"
|
||||
fx="7.6385846"
|
||||
fy="2.1311038"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3850"
|
||||
id="radialGradient3848"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="7.119658"
|
||||
cy="3.5299144"
|
||||
fx="7.119658"
|
||||
fy="3.5299144"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3862"
|
||||
id="radialGradient3881"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.6871169,2.6177942e-7,-1.751068e-7,1.7949189,-12.876884,-3.6298631)"
|
||||
cx="7.6324792"
|
||||
cy="4.0267229"
|
||||
fx="7.6324792"
|
||||
fy="4.0267229"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3856"
|
||||
id="radialGradient3883"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.5905007,-1.0269578e-2,1.0269364e-2,1.5904675,-4.5385807,-1.7383567)"
|
||||
cx="7.6385846"
|
||||
cy="2.1311038"
|
||||
fx="7.6385846"
|
||||
fy="2.1311038"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3850"
|
||||
id="radialGradient3885"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="7.119658"
|
||||
cy="3.5299144"
|
||||
fx="7.119658"
|
||||
fy="3.5299144"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3862"
|
||||
id="radialGradient3887"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.6871169,2.6177942e-7,-1.751068e-7,1.7949189,-12.876884,-3.6298631)"
|
||||
cx="7.6324792"
|
||||
cy="4.0267229"
|
||||
fx="7.6324792"
|
||||
fy="4.0267229"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3856"
|
||||
id="radialGradient3889"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.5905007,-1.0269578e-2,1.0269364e-2,1.5904675,-4.5385807,-1.7383567)"
|
||||
cx="7.6385846"
|
||||
cy="2.1311038"
|
||||
fx="7.6385846"
|
||||
fy="2.1311038"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3850"
|
||||
id="radialGradient3891"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="7.119658"
|
||||
cy="3.5299144"
|
||||
fx="7.119658"
|
||||
fy="3.5299144"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3770"
|
||||
id="radialGradient3893"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="7.119658"
|
||||
cy="3.5299144"
|
||||
fx="7.119658"
|
||||
fy="3.5299144"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3794"
|
||||
id="radialGradient3895"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.5905007,-1.0269578e-2,1.0269364e-2,1.5904675,-4.5385807,-1.7383567)"
|
||||
cx="7.6385846"
|
||||
cy="2.1311038"
|
||||
fx="7.6385846"
|
||||
fy="2.1311038"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3804"
|
||||
id="radialGradient3897"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.6871169,2.6177942e-7,-1.751068e-7,1.7949189,-12.876884,-3.6298631)"
|
||||
cx="7.6324792"
|
||||
cy="4.0267229"
|
||||
fx="7.6324792"
|
||||
fy="4.0267229"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3804"
|
||||
id="radialGradient2216"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.6871169,2.6177942e-7,-1.751068e-7,1.7949189,-12.876884,-3.6298631)"
|
||||
cx="7.6324792"
|
||||
cy="4.0267229"
|
||||
fx="7.6324792"
|
||||
fy="4.0267229"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3794"
|
||||
id="radialGradient2218"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.5905007,-1.0269578e-2,1.0269364e-2,1.5904675,-4.5385807,-1.7383567)"
|
||||
cx="7.6385846"
|
||||
cy="2.1311038"
|
||||
fx="7.6385846"
|
||||
fy="2.1311038"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3770"
|
||||
id="radialGradient2220"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="7.119658"
|
||||
cy="3.5299144"
|
||||
fx="7.119658"
|
||||
fy="3.5299144"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3804"
|
||||
id="radialGradient3203"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.6871169,2.6177942e-7,-1.751068e-7,1.7949189,-12.876884,-3.6298631)"
|
||||
cx="7.6324792"
|
||||
cy="4.0267229"
|
||||
fx="7.6324792"
|
||||
fy="4.0267229"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3794"
|
||||
id="radialGradient3205"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.5905007,-1.0269578e-2,1.0269364e-2,1.5904675,-4.5385807,-1.7383567)"
|
||||
cx="7.6385846"
|
||||
cy="2.1311038"
|
||||
fx="7.6385846"
|
||||
fy="2.1311038"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3770"
|
||||
id="radialGradient3207"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="7.119658"
|
||||
cy="3.5299144"
|
||||
fx="7.119658"
|
||||
fy="3.5299144"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3862"
|
||||
id="radialGradient3217"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.6871169,2.6177942e-7,-1.751068e-7,1.7949189,-12.876884,-3.6298631)"
|
||||
cx="7.6324792"
|
||||
cy="4.0267229"
|
||||
fx="7.6324792"
|
||||
fy="4.0267229"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3856"
|
||||
id="radialGradient3219"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.5905007,-1.0269578e-2,1.0269364e-2,1.5904675,-4.5385807,-1.7383567)"
|
||||
cx="7.6385846"
|
||||
cy="2.1311038"
|
||||
fx="7.6385846"
|
||||
fy="2.1311038"
|
||||
r="2.5213675" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3850"
|
||||
id="radialGradient3221"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="7.119658"
|
||||
cy="3.5299144"
|
||||
fx="7.119658"
|
||||
fy="3.5299144"
|
||||
r="2.5213675" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="32"
|
||||
inkscape:cx="25.791945"
|
||||
inkscape:cy="22.945934"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:document-units="px"
|
||||
width="48px"
|
||||
height="48px"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1152"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="25"
|
||||
inkscape:object-paths="false"
|
||||
gridtolerance="50"
|
||||
inkscape:guide-bbox="false"
|
||||
gridempspacing="10"
|
||||
showguides="false" />
|
||||
<metadata
|
||||
id="metadata3702">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<g
|
||||
id="g3185"
|
||||
transform="matrix(0.9850951,0,0,0.9850951,0.4228796,0.5142787)">
|
||||
<path
|
||||
transform="matrix(2.8182772,0,0,2.8182772,2.4234116,-0.8937005)"
|
||||
d="M 10.153846 4.094017 A 2.5213675 2.5213675 0 1 1 5.1111112,4.094017 A 2.5213675 2.5213675 0 1 1 10.153846 4.094017 z"
|
||||
sodipodi:ry="2.5213675"
|
||||
sodipodi:rx="2.5213675"
|
||||
sodipodi:cy="4.094017"
|
||||
sodipodi:cx="7.6324787"
|
||||
id="path3800"
|
||||
style="fill:url(#radialGradient2216);fill-opacity:1;stroke:none"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(2.4675728,0,0,2.4775297,5.1348034,0.5069042)"
|
||||
d="M 10.153846 4.094017 A 2.5213675 2.5213675 0 1 1 5.1111112,4.094017 A 2.5213675 2.5213675 0 1 1 10.153846 4.094017 z"
|
||||
sodipodi:ry="2.5213675"
|
||||
sodipodi:rx="2.5213675"
|
||||
sodipodi:cy="4.094017"
|
||||
sodipodi:cx="7.6324787"
|
||||
id="path3790"
|
||||
style="fill:url(#radialGradient2218);fill-opacity:1;stroke:none"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(1.8688936,0,0,1.8764348,9.6962225,3.0078915)"
|
||||
d="M 10.153846 4.094017 A 2.5213675 2.5213675 0 1 1 5.1111112,4.094017 A 2.5213675 2.5213675 0 1 1 10.153846 4.094017 z"
|
||||
sodipodi:ry="2.5213675"
|
||||
sodipodi:rx="2.5213675"
|
||||
sodipodi:cy="4.094017"
|
||||
sodipodi:cx="7.6324787"
|
||||
id="path3765"
|
||||
style="fill:url(#radialGradient2220);fill-opacity:1;stroke:none"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3190"
|
||||
transform="matrix(0.9846397,0,0,0.9824171,0.2007479,0.5761166)">
|
||||
<path
|
||||
transform="matrix(2.8195807,0,0,2.8195807,15.852927,12.315787)"
|
||||
d="M 10.153846 4.094017 A 2.5213675 2.5213675 0 1 1 5.1111112,4.094017 A 2.5213675 2.5213675 0 1 1 10.153846 4.094017 z"
|
||||
sodipodi:ry="2.5213675"
|
||||
sodipodi:rx="2.5213675"
|
||||
sodipodi:cy="4.094017"
|
||||
sodipodi:cx="7.6324787"
|
||||
id="path3838"
|
||||
style="fill:url(#radialGradient3887);fill-opacity:1;stroke:none"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(2.4675728,0,0,2.4775297,18.554955,13.700977)"
|
||||
d="M 10.153846 4.094017 A 2.5213675 2.5213675 0 1 1 5.1111112,4.094017 A 2.5213675 2.5213675 0 1 1 10.153846 4.094017 z"
|
||||
sodipodi:ry="2.5213675"
|
||||
sodipodi:rx="2.5213675"
|
||||
sodipodi:cy="4.094017"
|
||||
sodipodi:cx="7.6324787"
|
||||
id="path3840"
|
||||
style="fill:url(#radialGradient3889);fill-opacity:1;stroke:none"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(1.8688936,0,0,1.8764348,23.116374,16.201965)"
|
||||
d="M 10.153846 4.094017 A 2.5213675 2.5213675 0 1 1 5.1111112,4.094017 A 2.5213675 2.5213675 0 1 1 10.153846 4.094017 z"
|
||||
sodipodi:ry="2.5213675"
|
||||
sodipodi:rx="2.5213675"
|
||||
sodipodi:cy="4.094017"
|
||||
sodipodi:cx="7.6324787"
|
||||
id="path3842"
|
||||
style="fill:url(#radialGradient3891);fill-opacity:1;stroke:none"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3195"
|
||||
transform="matrix(0.9850952,0,0,0.9850951,-12.577123,13.514279)">
|
||||
<path
|
||||
transform="matrix(2.8182772,0,0,2.8182772,2.4234116,-0.8937005)"
|
||||
d="M 10.153846 4.094017 A 2.5213675 2.5213675 0 1 1 5.1111112,4.094017 A 2.5213675 2.5213675 0 1 1 10.153846 4.094017 z"
|
||||
sodipodi:ry="2.5213675"
|
||||
sodipodi:rx="2.5213675"
|
||||
sodipodi:cy="4.094017"
|
||||
sodipodi:cx="7.6324787"
|
||||
id="path3197"
|
||||
style="fill:url(#radialGradient3203);fill-opacity:1;stroke:none"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(2.4675728,0,0,2.4775297,5.1348034,0.5069042)"
|
||||
d="M 10.153846 4.094017 A 2.5213675 2.5213675 0 1 1 5.1111112,4.094017 A 2.5213675 2.5213675 0 1 1 10.153846 4.094017 z"
|
||||
sodipodi:ry="2.5213675"
|
||||
sodipodi:rx="2.5213675"
|
||||
sodipodi:cy="4.094017"
|
||||
sodipodi:cx="7.6324787"
|
||||
id="path3199"
|
||||
style="fill:url(#radialGradient3205);fill-opacity:1;stroke:none"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(1.8688936,0,0,1.8764348,9.6962225,3.0078915)"
|
||||
d="M 10.153846 4.094017 A 2.5213675 2.5213675 0 1 1 5.1111112,4.094017 A 2.5213675 2.5213675 0 1 1 10.153846 4.094017 z"
|
||||
sodipodi:ry="2.5213675"
|
||||
sodipodi:rx="2.5213675"
|
||||
sodipodi:cy="4.094017"
|
||||
sodipodi:cx="7.6324787"
|
||||
id="path3201"
|
||||
style="fill:url(#radialGradient3207);fill-opacity:1;stroke:none"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3209"
|
||||
transform="matrix(0.9846397,0,0,0.9846397,-12.799251,13.507286)">
|
||||
<path
|
||||
transform="matrix(2.8195807,0,0,2.8195807,15.852927,12.315787)"
|
||||
d="M 10.153846 4.094017 A 2.5213675 2.5213675 0 1 1 5.1111112,4.094017 A 2.5213675 2.5213675 0 1 1 10.153846 4.094017 z"
|
||||
sodipodi:ry="2.5213675"
|
||||
sodipodi:rx="2.5213675"
|
||||
sodipodi:cy="4.094017"
|
||||
sodipodi:cx="7.6324787"
|
||||
id="path3211"
|
||||
style="fill:url(#radialGradient3217);fill-opacity:1;stroke:none"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(2.4675728,0,0,2.4775297,18.554955,13.700977)"
|
||||
d="M 10.153846 4.094017 A 2.5213675 2.5213675 0 1 1 5.1111112,4.094017 A 2.5213675 2.5213675 0 1 1 10.153846 4.094017 z"
|
||||
sodipodi:ry="2.5213675"
|
||||
sodipodi:rx="2.5213675"
|
||||
sodipodi:cy="4.094017"
|
||||
sodipodi:cx="7.6324787"
|
||||
id="path3213"
|
||||
style="fill:url(#radialGradient3219);fill-opacity:1;stroke:none"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(1.8688936,0,0,1.8764348,23.116374,16.201965)"
|
||||
d="M 10.153846 4.094017 A 2.5213675 2.5213675 0 1 1 5.1111112,4.094017 A 2.5213675 2.5213675 0 1 1 10.153846 4.094017 z"
|
||||
sodipodi:ry="2.5213675"
|
||||
sodipodi:rx="2.5213675"
|
||||
sodipodi:cy="4.094017"
|
||||
sodipodi:cx="7.6324787"
|
||||
id="path3215"
|
||||
style="fill:url(#radialGradient3221);fill-opacity:1;stroke:none"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 20 KiB |
Binary file not shown.
After Width: | Height: | Size: 581 B |
Binary file not shown.
After Width: | Height: | Size: 855 B |
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,630 @@
|
|||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2009-04-28.21; # UTC
|
||||
|
||||
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
|
||||
# Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Run PROGRAMS ARGS to compile a file, generating dependencies
|
||||
as side-effects.
|
||||
|
||||
Environment variables:
|
||||
depmode Dependency tracking mode.
|
||||
source Source file read by `PROGRAMS ARGS'.
|
||||
object Object file output by `PROGRAMS ARGS'.
|
||||
DEPDIR directory where to store dependencies.
|
||||
depfile Dependency file to output.
|
||||
tmpdepfile Temporary file to use when outputing dependencies.
|
||||
libtool Whether libtool is used (yes/no).
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "depcomp $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
||||
depfile=${depfile-`echo "$object" |
|
||||
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
||||
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||
|
||||
rm -f "$tmpdepfile"
|
||||
|
||||
# Some modes work just like other modes, but use different flags. We
|
||||
# parameterize here, but still list the modes in the big case below,
|
||||
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||
# here, because this file can only contain one case statement.
|
||||
if test "$depmode" = hp; then
|
||||
# HP compiler uses -M and no extra arg.
|
||||
gccflag=-M
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
if test "$depmode" = dashXmstdout; then
|
||||
# This is just like dashmstdout with a different argument.
|
||||
dashmflag=-xM
|
||||
depmode=dashmstdout
|
||||
fi
|
||||
|
||||
cygpath_u="cygpath -u -f -"
|
||||
if test "$depmode" = msvcmsys; then
|
||||
# This is just like msvisualcpp but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u="sed s,\\\\\\\\,/,g"
|
||||
depmode=msvisualcpp
|
||||
fi
|
||||
|
||||
case "$depmode" in
|
||||
gcc3)
|
||||
## gcc 3 implements dependency tracking that does exactly what
|
||||
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
|
||||
## the command line argument order; so add the flags where they
|
||||
## appear in depend2.am. Note that the slowdown incurred here
|
||||
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
|
||||
*) set fnord "$@" "$arg" ;;
|
||||
esac
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
done
|
||||
"$@"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
mv "$tmpdepfile" "$depfile"
|
||||
;;
|
||||
|
||||
gcc)
|
||||
## There are various ways to get dependency output from gcc. Here's
|
||||
## why we pick this rather obscure method:
|
||||
## - Don't want to use -MD because we'd like the dependencies to end
|
||||
## up in a subdir. Having to rename by hand is ugly.
|
||||
## (We might end up doing this anyway to support other compilers.)
|
||||
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||
## -MM, not -M (despite what the docs say).
|
||||
## - Using -M directly means running the compiler twice (even worse
|
||||
## than renaming).
|
||||
if test -z "$gccflag"; then
|
||||
gccflag=-MD,
|
||||
fi
|
||||
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||
## The second -e expression handles DOS-style file names with drive letters.
|
||||
sed -e 's/^[^:]*: / /' \
|
||||
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||
## This next piece of magic avoids the `deleted header file' problem.
|
||||
## The problem is that when a header file which appears in a .P file
|
||||
## is deleted, the dependency causes make to die (because there is
|
||||
## typically no way to rebuild the header). We avoid this by adding
|
||||
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||
## this for us directly.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" |
|
||||
## Some versions of gcc put a space before the `:'. On the theory
|
||||
## that the space means something, we add a space to the output as
|
||||
## well.
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
sgi)
|
||||
if test "$libtool" = yes; then
|
||||
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||
else
|
||||
"$@" -MDupdate "$tmpdepfile"
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
|
||||
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||
echo "$object : \\" > "$depfile"
|
||||
|
||||
# Clip off the initial element (the dependent). Don't try to be
|
||||
# clever and replace this with sed code, as IRIX sed won't handle
|
||||
# lines with more than a fixed number of characters (4096 in
|
||||
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||
# the IRIX cc adds comments like `#:fec' to the end of the
|
||||
# dependency line.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
|
||||
tr '
|
||||
' ' ' >> "$depfile"
|
||||
echo >> "$depfile"
|
||||
|
||||
# The second pass generates a dummy entry for each header file.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||
>> "$depfile"
|
||||
else
|
||||
# The sourcefile does not contain any dependencies, so just
|
||||
# store a dummy comment line, to avoid errors with the Makefile
|
||||
# "include basename.Plo" scheme.
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
aix)
|
||||
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||
# in a .u file. In older versions, this file always lives in the
|
||||
# current directory. Also, the AIX compiler puts `$object:' at the
|
||||
# start of each line; $object doesn't have directory information.
|
||||
# Version 6 uses the directory in both cases.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$base.u
|
||||
tmpdepfile3=$dir.libs/$base.u
|
||||
"$@" -Wc,-M
|
||||
else
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$dir$base.u
|
||||
tmpdepfile3=$dir$base.u
|
||||
"$@" -M
|
||||
fi
|
||||
stat=$?
|
||||
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
# Each line is of the form `foo.o: dependent.h'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||
# That's a tab and a space in the [].
|
||||
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
# The sourcefile does not contain any dependencies, so just
|
||||
# store a dummy comment line, to avoid errors with the Makefile
|
||||
# "include basename.Plo" scheme.
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
icc)
|
||||
# Intel's C compiler understands `-MD -MF file'. However on
|
||||
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
|
||||
# ICC 7.0 will fill foo.d with something like
|
||||
# foo.o: sub/foo.c
|
||||
# foo.o: sub/foo.h
|
||||
# which is wrong. We want:
|
||||
# sub/foo.o: sub/foo.c
|
||||
# sub/foo.o: sub/foo.h
|
||||
# sub/foo.c:
|
||||
# sub/foo.h:
|
||||
# ICC 7.1 will output
|
||||
# foo.o: sub/foo.c sub/foo.h
|
||||
# and will wrap long lines using \ :
|
||||
# foo.o: sub/foo.c ... \
|
||||
# sub/foo.h ... \
|
||||
# ...
|
||||
|
||||
"$@" -MD -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each line is of the form `foo.o: dependent.h',
|
||||
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
|
||||
sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp2)
|
||||
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
|
||||
# compilers, which have integrated preprocessors. The correct option
|
||||
# to use with these is +Maked; it writes dependencies to a file named
|
||||
# 'foo.d', which lands next to the object file, wherever that
|
||||
# happens to be.
|
||||
# Much of this is similar to the tru64 case; see comments there.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir.libs/$base.d
|
||||
"$@" -Wc,+Maked
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
"$@" +Maked
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||
# Add `dependent.h:' lines.
|
||||
sed -ne '2,${
|
||||
s/^ *//
|
||||
s/ \\*$//
|
||||
s/$/:/
|
||||
p
|
||||
}' "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile" "$tmpdepfile2"
|
||||
;;
|
||||
|
||||
tru64)
|
||||
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
|
||||
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||
# dependencies in `foo.d' instead, so we check for that too.
|
||||
# Subdirectories are respected.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
|
||||
if test "$libtool" = yes; then
|
||||
# With Tru64 cc, shared objects can also be used to make a
|
||||
# static library. This mechanism is used in libtool 1.4 series to
|
||||
# handle both shared and static libraries in a single compilation.
|
||||
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
|
||||
#
|
||||
# With libtool 1.5 this exception was removed, and libtool now
|
||||
# generates 2 separate objects for the 2 libraries. These two
|
||||
# compilations output dependencies in $dir.libs/$base.o.d and
|
||||
# in $dir$base.o.d. We have to check for both files, because
|
||||
# one of the two compilations can be disabled. We should prefer
|
||||
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
||||
# automatically cleaned when .libs/ is deleted, while ignoring
|
||||
# the former would cause a distcleancheck panic.
|
||||
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
|
||||
tmpdepfile2=$dir$base.o.d # libtool 1.5
|
||||
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
|
||||
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
|
||||
"$@" -Wc,-MD
|
||||
else
|
||||
tmpdepfile1=$dir$base.o.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
tmpdepfile3=$dir$base.d
|
||||
tmpdepfile4=$dir$base.d
|
||||
"$@" -MD
|
||||
fi
|
||||
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||
# That's a tab and a space in the [].
|
||||
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
#nosideeffect)
|
||||
# This comment above is used by automake to tell side-effect
|
||||
# dependency tracking mechanisms from slower ones.
|
||||
|
||||
dashmstdout)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout, regardless of -o.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -z "$dashmflag" && dashmflag=-M
|
||||
# Require at least two characters before searching for `:'
|
||||
# in the target name. This is to cope with DOS-style filenames:
|
||||
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
|
||||
"$@" $dashmflag |
|
||||
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
dashXmstdout)
|
||||
# This case only exists to satisfy depend.m4. It is never actually
|
||||
# run, as this mode is specially recognized in the preamble.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
makedepend)
|
||||
"$@" || exit $?
|
||||
# Remove any Libtool call
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
# X makedepend
|
||||
shift
|
||||
cleared=no eat=no
|
||||
for arg
|
||||
do
|
||||
case $cleared in
|
||||
no)
|
||||
set ""; shift
|
||||
cleared=yes ;;
|
||||
esac
|
||||
if test $eat = yes; then
|
||||
eat=no
|
||||
continue
|
||||
fi
|
||||
case "$arg" in
|
||||
-D*|-I*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
# Strip any option that makedepend may not understand. Remove
|
||||
# the object too, otherwise makedepend will parse it as a source file.
|
||||
-arch)
|
||||
eat=yes ;;
|
||||
-*|$object)
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
esac
|
||||
done
|
||||
obj_suffix=`echo "$object" | sed 's/^.*\././'`
|
||||
touch "$tmpdepfile"
|
||||
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
sed '1,2d' "$tmpdepfile" | tr ' ' '
|
||||
' | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||
;;
|
||||
|
||||
cpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
"$@" -E |
|
||||
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
|
||||
sed '$ s: \\$::' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
cat < "$tmpdepfile" >> "$depfile"
|
||||
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvisualcpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||
set fnord "$@"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
"$@" -E 2>/dev/null |
|
||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
|
||||
echo " " >> "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvcmsys)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
none)
|
||||
exec "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown depmode $depmode" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue