mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-11-10 21:05:12 +01:00
commit
5454ba36db
@ -135,6 +135,7 @@ Genesis Plus GX 1.7.5 (xx/xx/xxxx) (Eke-Eke)
|
||||
* added configurable FPS display & toggleable fast-forward key combo
|
||||
(HOME + MINUS with Wii controllers or R TRIGGER + START with Gamecube controller)
|
||||
* added 50hz progressive mode (576p) support for emulation
|
||||
* added WiiU GamePad Controller support on vWii (Fix94)
|
||||
* reduced SRAM files size
|
||||
* improved A/V Sync: when VSYNC is enabled, audio resampler output rate is now adjusted (+/-0,1 %)
|
||||
to always keep audio & video synchronized and input lag is reduced by one frame.
|
||||
|
158
LICENSE.txt
158
LICENSE.txt
@ -74,7 +74,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
LIBCHDR is distributed under following licenses:
|
||||
LIBCHDR is distributed with code under following licenses:
|
||||
|
||||
|
||||
MAME CHD interface
|
||||
@ -166,11 +166,35 @@ original LZMA SDK code, either in source code form or as a compiled binary, for
|
||||
any purpose, commercial or non-commercial, and by any means.
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
NTSC FILTER LIBRARY
|
||||
-------------------
|
||||
|
||||
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 */
|
||||
|
||||
|
||||
NTSC Filter and Blip Buffer libraries are distributed under the
|
||||
terms of the GNU Lesser General Public License (LGPL)
|
||||
BLIP BUFFER LIBRARY
|
||||
-------------------
|
||||
|
||||
Copyright (C) 2003-2009 Shay Green. 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 module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
@ -679,7 +703,111 @@ That's all there is to it!
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
Gamecube & Wii ports are linked with LIBASND library and includes code distributed under
|
||||
Gamecube & Wii ports are linked with LIBOGC library which is distributed under
|
||||
the following license:
|
||||
|
||||
Copyright (C) 2004 - 2009
|
||||
Michael Wiedenbauer (shagkur)
|
||||
Dave Murphy (WinterMute)
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
Gamecube & Wii ports are linked with LIBFAT library which is distributed under
|
||||
the following license:
|
||||
|
||||
Copyright (c) 2006 - 2012
|
||||
Michael "Chishm" Chisholm
|
||||
Dave "WinterMute" Murphy
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
Gamecube & Wii ports are linked with LIBPNG library which is distributed under
|
||||
the following license:
|
||||
|
||||
Copyright (c) 1998-2010 Glenn Randers-Pehrson
|
||||
(Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
(Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
|
||||
The PNG Reference Library is supplied "AS IS". The Contributing Authors
|
||||
and Group 42, Inc. disclaim all warranties, expressed or implied,
|
||||
including, without limitation, the warranties of merchantability and of
|
||||
fitness for any purpose. The Contributing Authors and Group 42, Inc.
|
||||
assume no liability for direct, indirect, incidental, special, exemplary,
|
||||
or consequential damages, which may result from the use of the PNG
|
||||
Reference Library, even if advised of the possibility of such damage.
|
||||
|
||||
There is no warranty against interference with your enjoyment of the
|
||||
|
||||
library or against infringement. There is no warranty that our
|
||||
|
||||
efforts or the library will fulfill any of your particular purposes
|
||||
|
||||
or needs. This library is provided with all faults, and the entire
|
||||
|
||||
risk of satisfactory quality, performance, accuracy, and effort is with
|
||||
|
||||
the user.
|
||||
|
||||
Permission is hereby granted to use, copy, modify, and distribute this
|
||||
source code, or portions hereof, for any purpose, without fee, subject
|
||||
to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented.
|
||||
|
||||
2. Altered versions must be plainly marked as such and
|
||||
must not be misrepresented as being the original source.
|
||||
|
||||
3. This Copyright notice may not be removed or altered from
|
||||
any source or altered source distribution.
|
||||
|
||||
The Contributing Authors and Group 42, Inc. specifically permit, without
|
||||
fee, and encourage the use of this source code as a component to
|
||||
supporting the PNG file format in commercial products. If you use this
|
||||
source code in a product, acknowledgment is not required but would be
|
||||
appreciated.
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
Gamecube & Wii ports are linked with LIBASND library which is distributed under
|
||||
the following license:
|
||||
|
||||
Copyright (c) 2008 Hermes <www.entuwii.net>
|
||||
@ -709,5 +837,25 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
Wii port is linked with WiiDRC library which is distributed under
|
||||
the following license:
|
||||
|
||||
Copyright (c) 2017 FIX94
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
@ -440,9 +440,8 @@ LIBRETRO_CFLAGS += $(BPP_DEFINES) \
|
||||
$(ENDIANNESS_DEFINES) \
|
||||
$(PLATFORM_DEFINES) \
|
||||
-D__LIBRETRO__ \
|
||||
-DM68K_ALLOW_OVERCLOCK \
|
||||
-DZ80_ALLOW_OVERCLOCK \
|
||||
-DCYCLE_SHIFT=10
|
||||
-DM68K_OVERCLOCK_SHIFT=20 \
|
||||
-DZ80_OVERCLOCK_SHIFT=20
|
||||
|
||||
ifneq (,$(findstring msvc,$(platform)))
|
||||
LIBRETRO_CFLAGS += -DINLINE="static _inline"
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 3.4 MiB After Width: | Height: | Size: 3.4 MiB |
@ -268,7 +268,7 @@ typedef struct
|
||||
|
||||
uint address_space; /* Current FC code */
|
||||
|
||||
#ifdef M68K_ALLOW_OVERCLOCK
|
||||
#ifdef M68K_OVERCLOCK_SHIFT
|
||||
int cycle_ratio;
|
||||
#endif
|
||||
|
||||
|
@ -319,8 +319,8 @@ void m68k_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef M68K_ALLOW_OVERCLOCK
|
||||
m68k.cycle_ratio = 1 << CYCLE_SHIFT;
|
||||
#ifdef M68K_OVERCLOCK_SHIFT
|
||||
m68k.cycle_ratio = 1 << M68K_OVERCLOCK_SHIFT;
|
||||
#endif
|
||||
|
||||
#if M68K_EMULATE_INT_ACK == OPT_ON
|
||||
|
@ -514,8 +514,8 @@
|
||||
|
||||
/* ---------------------------- Cycle Counting ---------------------------- */
|
||||
|
||||
#ifdef M68K_ALLOW_OVERCLOCK
|
||||
#define USE_CYCLES(A) m68ki_cpu.cycles += ((A) * m68ki_cpu.cycle_ratio) >> CYCLE_SHIFT
|
||||
#ifdef M68K_OVERCLOCK_SHIFT
|
||||
#define USE_CYCLES(A) m68ki_cpu.cycles += ((A) * m68ki_cpu.cycle_ratio) >> M68K_OVERCLOCK_SHIFT
|
||||
#else
|
||||
#define USE_CYCLES(A) m68ki_cpu.cycles += (A)
|
||||
#endif
|
||||
|
@ -284,8 +284,8 @@ void s68k_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef M68K_ALLOW_OVERCLOCK
|
||||
s68k.cycle_ratio = 1 << CYCLE_SHIFT;
|
||||
#ifdef M68K_OVERCLOCK_SHIFT
|
||||
s68k.cycle_ratio = 1 << M68K_OVERCLOCK_SHIFT;
|
||||
#endif
|
||||
|
||||
#if M68K_EMULATE_INT_ACK == OPT_ON
|
||||
|
@ -89,8 +89,8 @@ void YM3438_Update(int *buffer, int length)
|
||||
ym3438_sample[1] += ym3438_accm[j][1];
|
||||
}
|
||||
}
|
||||
*buffer++ = ym3438_sample[0] * 8;
|
||||
*buffer++ = ym3438_sample[1] * 8;
|
||||
*buffer++ = ym3438_sample[0] * 11;
|
||||
*buffer++ = ym3438_sample[1] * 11;
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,7 +130,7 @@ void sound_init( void )
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
/* YM2612 */
|
||||
#ifdef HAVE_YM3438_CORE
|
||||
#ifdef HAVE_YM3438_CORE
|
||||
if (config.ym3438)
|
||||
{
|
||||
/* Nuked OPN2 */
|
||||
@ -146,7 +146,7 @@ void sound_init( void )
|
||||
fm_cycles_ratio = 6 * 7;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
/* MAME */
|
||||
YM2612Init();
|
||||
@ -276,7 +276,7 @@ int sound_context_save(uint8 *state)
|
||||
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
#ifdef HAVE_YM3438_CORE
|
||||
#ifdef HAVE_YM3438_CORE
|
||||
save_param(&config.ym3438, sizeof(config.ym3438));
|
||||
if (config.ym3438)
|
||||
{
|
||||
@ -290,9 +290,9 @@ int sound_context_save(uint8 *state)
|
||||
bufferptr += YM2612SaveContext(state + sizeof(config.ym3438));
|
||||
YM2612Config(config.dac_bits);
|
||||
}
|
||||
#else
|
||||
#else
|
||||
bufferptr = YM2612SaveContext(state);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -309,11 +309,11 @@ int sound_context_save(uint8 *state)
|
||||
int sound_context_load(uint8 *state)
|
||||
{
|
||||
int bufferptr = 0;
|
||||
uint8 config_ym3438;
|
||||
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
#ifdef HAVE_YM3438_CORE
|
||||
#ifdef HAVE_YM3438_CORE
|
||||
uint8 config_ym3438;
|
||||
load_param(&config_ym3438, sizeof(config_ym3438));
|
||||
if (config_ym3438)
|
||||
{
|
||||
@ -324,13 +324,13 @@ int sound_context_load(uint8 *state)
|
||||
}
|
||||
else
|
||||
{
|
||||
bufferptr += YM2612LoadContext(state + sizeof(config_ym3438));
|
||||
YM2612Config(config.dac_bits);
|
||||
bufferptr += YM2612LoadContext(state + sizeof(config_ym3438));
|
||||
YM2612Config(config.dac_bits);
|
||||
}
|
||||
#else
|
||||
#else
|
||||
bufferptr = YM2612LoadContext(state);
|
||||
YM2612Config(config.dac_bits);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -24,6 +24,10 @@
|
||||
/*
|
||||
** CHANGELOG:
|
||||
**
|
||||
** 26-09-2017 Eke-Eke (Genesis Plus GX):
|
||||
** - fixed EG counter loopback behavior (verified on YM3438 die)
|
||||
** - reverted changes to EG rates 2-7 increment values
|
||||
**
|
||||
** 09-04-2017 Eke-Eke (Genesis Plus GX):
|
||||
** - fixed LFO PM implementation: block & keyscale code should not be modified by LFO (verified on YM2612 die)
|
||||
** - fixed Timer B overflow handling
|
||||
@ -240,12 +244,11 @@ O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
|
||||
|
||||
/* rates 00-11 */
|
||||
/*
|
||||
O( 0),O( 1),O( 2),O( 3),
|
||||
O( 0),O( 1),O( 2),O( 3),
|
||||
O( 0),O( 1)
|
||||
*/
|
||||
O(18),O(18),O( 0),O( 0),
|
||||
O( 0),O( 0),O( 2),O( 2), /* Nemesis's tests */
|
||||
|
||||
O(18),O(18), /* from Nemesis's tests on real YM2612 hardware */
|
||||
O( 2),O( 3),
|
||||
O( 0),O( 1),O( 2),O( 3),
|
||||
O( 0),O( 1),O( 2),O( 3),
|
||||
O( 0),O( 1),O( 2),O( 3),
|
||||
O( 0),O( 1),O( 2),O( 3),
|
||||
@ -1282,7 +1285,7 @@ INLINE void update_ssg_eg_channels(FM_CH *CH)
|
||||
|
||||
INLINE void update_phase_lfo_slot(FM_SLOT *SLOT, UINT32 pm, UINT8 kc, UINT32 fc)
|
||||
{
|
||||
INT32 lfo_fn_offset = lfo_pm_table[(((fc & 0x7f0) >> 4) << 8) + pm];
|
||||
INT32 lfo_fn_offset = lfo_pm_table[((fc & 0x7f0) << 4) + pm];
|
||||
|
||||
if (lfo_fn_offset) /* LFO phase modulation active */
|
||||
{
|
||||
@ -1293,7 +1296,7 @@ INLINE void update_phase_lfo_slot(FM_SLOT *SLOT, UINT32 pm, UINT8 kc, UINT32 fc)
|
||||
fc = ((fc << 1) + lfo_fn_offset) & 0xfff;
|
||||
|
||||
/* (frequency) phase increment counter (17-bit) */
|
||||
fc = (((fc << 5) >> (7 - blk)) + SLOT->DT[kc]) & DT_MASK;
|
||||
fc = (((fc << blk) >> 2) + SLOT->DT[kc]) & DT_MASK;
|
||||
|
||||
/* update phase */
|
||||
SLOT->phase += ((fc * SLOT->mul) >> 1);
|
||||
@ -1308,7 +1311,7 @@ INLINE void update_phase_lfo_channel(FM_CH *CH)
|
||||
{
|
||||
UINT32 fc = CH->block_fnum;
|
||||
|
||||
INT32 lfo_fn_offset = lfo_pm_table[(((fc & 0x7f0) >> 4) << 8) + CH->pms + ym2612.OPN.LFO_PM];
|
||||
INT32 lfo_fn_offset = lfo_pm_table[((fc & 0x7f0) << 4) + CH->pms + ym2612.OPN.LFO_PM];
|
||||
|
||||
if (lfo_fn_offset) /* LFO phase modulation active */
|
||||
{
|
||||
@ -1322,7 +1325,7 @@ INLINE void update_phase_lfo_channel(FM_CH *CH)
|
||||
fc = ((fc << 1) + lfo_fn_offset) & 0xfff;
|
||||
|
||||
/* (frequency) phase increment counter (17-bit) */
|
||||
fc = (fc << 5) >> (7 - blk);
|
||||
fc = (fc << blk) >> 2;
|
||||
|
||||
/* apply DETUNE & MUL operator specific values */
|
||||
finc = (fc + CH->SLOT[SLOT1].DT[kc]) & DT_MASK;
|
||||
@ -1696,7 +1699,7 @@ INLINE void OPNWriteReg(int r, int v)
|
||||
/* keyscale code */
|
||||
CH->kcode = (blk<<2) | opn_fktable[fn >> 7];
|
||||
/* phase increment counter */
|
||||
CH->fc = (fn << 6) >> (7 - blk);
|
||||
CH->fc = (fn<<blk)>>1;
|
||||
|
||||
/* store fnum in clear form for LFO PM calculations */
|
||||
CH->block_fnum = (blk<<11) | fn;
|
||||
@ -1715,7 +1718,7 @@ INLINE void OPNWriteReg(int r, int v)
|
||||
/* keyscale code */
|
||||
ym2612.OPN.SL3.kcode[c]= (blk<<2) | opn_fktable[fn >> 7];
|
||||
/* phase increment counter */
|
||||
ym2612.OPN.SL3.fc[c] = (fn << 6) >> (7 - blk);
|
||||
ym2612.OPN.SL3.fc[c] = (fn<<blk)>>1;
|
||||
ym2612.OPN.SL3.block_fnum[c] = (blk<<11) | fn;
|
||||
ym2612.CH[2].SLOT[SLOT1].Incr=-1;
|
||||
}
|
||||
@ -2017,7 +2020,7 @@ void YM2612Update(int *buffer, int length)
|
||||
refresh_fc_eg_chan(&ym2612.CH[5]);
|
||||
|
||||
/* buffering */
|
||||
for(i=0; i < length ; i++)
|
||||
for(i=0; i<length ; i++)
|
||||
{
|
||||
/* clear outputs */
|
||||
out_fm[0] = 0;
|
||||
@ -2045,14 +2048,21 @@ void YM2612Update(int *buffer, int length)
|
||||
/* advance LFO */
|
||||
advance_lfo();
|
||||
|
||||
/* advance envelope generator */
|
||||
ym2612.OPN.eg_timer ++;
|
||||
|
||||
/* EG is updated every 3 samples */
|
||||
ym2612.OPN.eg_timer++;
|
||||
if (ym2612.OPN.eg_timer >= 3)
|
||||
{
|
||||
/* reset EG timer */
|
||||
ym2612.OPN.eg_timer = 0;
|
||||
|
||||
/* increment EG counter */
|
||||
ym2612.OPN.eg_cnt++;
|
||||
|
||||
/* EG counter is 12-bit only and zero value is skipped (verified on real hardware) */
|
||||
if (ym2612.OPN.eg_cnt == 4096)
|
||||
ym2612.OPN.eg_cnt = 1;
|
||||
|
||||
/* advance envelope generator */
|
||||
advance_eg_channels(&ym2612.CH[0], ym2612.OPN.eg_cnt);
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
#ifdef HAVE_YM3438_CORE
|
||||
/*
|
||||
* Copyright (C) 2017 Alexey Khokholov (Nuke.YKT)
|
||||
*
|
||||
@ -39,7 +40,7 @@
|
||||
* OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
|
||||
* OPL2 ROMs.
|
||||
*
|
||||
* version: 1.0.2
|
||||
* version: 1.0.7
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@ -232,6 +233,8 @@ static const Bit32u fm_algorithm[4][6][8] = {
|
||||
}
|
||||
};
|
||||
|
||||
static Bit32u chip_type = ym3438_type_discrete;
|
||||
|
||||
void OPN2_DoIO(ym3438_t *chip)
|
||||
{
|
||||
/* Write signal check */
|
||||
@ -488,9 +491,9 @@ void OPN2_PhaseCalcIncrement(ym3438_t *chip)
|
||||
lfo_l ^= 0x0f;
|
||||
}
|
||||
fm = (fnum_h >> pg_lfo_sh1[pms][lfo_l]) + (fnum_h >> pg_lfo_sh2[pms][lfo_l]);
|
||||
if (lfo_l > 5)
|
||||
if (pms > 5)
|
||||
{
|
||||
fm <<= 7 - lfo_l;
|
||||
fm <<= pms - 5;
|
||||
}
|
||||
fm >>= 2;
|
||||
if (lfo & 0x10)
|
||||
@ -506,7 +509,7 @@ void OPN2_PhaseCalcIncrement(ym3438_t *chip)
|
||||
basefreq = (fnum << chip->pg_block) >> 2;
|
||||
|
||||
/* Apply detune */
|
||||
if (dt & 0x03)
|
||||
if (dt_l)
|
||||
{
|
||||
if (kcode > 0x1c)
|
||||
{
|
||||
@ -514,7 +517,7 @@ void OPN2_PhaseCalcIncrement(ym3438_t *chip)
|
||||
}
|
||||
block = kcode >> 2;
|
||||
note = kcode & 0x03;
|
||||
sum = block + 1 + ((dt_l == 3) | (dt_l & 0x02) | ((dt_l != 0) << 3));
|
||||
sum = block + 9 + ((dt_l == 3) | (dt_l & 0x02));
|
||||
sum_h = sum >> 1;
|
||||
sum_l = sum & 0x01;
|
||||
detune = pg_detune[(sum_l << 2) | note] >> (9 - sum_h);
|
||||
@ -554,11 +557,11 @@ void OPN2_PhaseGenerate(ym3438_t *chip)
|
||||
void OPN2_EnvelopeSSGEG(ym3438_t *chip)
|
||||
{
|
||||
Bit32u slot = chip->slot;
|
||||
Bit8u direction = 0;
|
||||
chip->eg_ssg_pgrst_latch[slot] = 0;
|
||||
chip->eg_ssg_repeat_latch[slot] = 0;
|
||||
chip->eg_ssg_hold_up_latch[slot] = 0;
|
||||
chip->eg_ssg_inv[slot] = 0;
|
||||
Bit8u direction = 0;
|
||||
if (chip->ssg_eg[slot] & 0x08)
|
||||
{
|
||||
direction = chip->eg_ssg_dir[slot];
|
||||
@ -651,7 +654,7 @@ void OPN2_EnvelopeADSR(ym3438_t *chip)
|
||||
{
|
||||
nextlevel = 0;
|
||||
}
|
||||
else if (chip->eg_state[slot] == eg_num_attack && level != 0 && chip->eg_inc)
|
||||
else if (chip->eg_state[slot] == eg_num_attack && level != 0 && chip->eg_inc && nkon)
|
||||
{
|
||||
inc = (~level << chip->eg_inc) >> 5;
|
||||
}
|
||||
@ -665,13 +668,13 @@ void OPN2_EnvelopeADSR(ym3438_t *chip)
|
||||
{
|
||||
nextstate = eg_num_decay;
|
||||
}
|
||||
else if(chip->eg_inc && !chip->eg_ratemax)
|
||||
else if(chip->eg_inc && !chip->eg_ratemax && nkon)
|
||||
{
|
||||
inc = (~level << chip->eg_inc) >> 5;
|
||||
}
|
||||
break;
|
||||
case eg_num_decay:
|
||||
if (!eg_off && (level >> 5) == chip->eg_sl[1])
|
||||
if ((level >> 5) == chip->eg_sl[1])
|
||||
{
|
||||
nextstate = eg_num_sustain;
|
||||
}
|
||||
@ -724,7 +727,6 @@ void OPN2_EnvelopeADSR(ym3438_t *chip)
|
||||
|
||||
void OPN2_EnvelopePrepare(ym3438_t *chip)
|
||||
{
|
||||
Bit8u reg_rate;
|
||||
Bit8u rate;
|
||||
Bit8u sum;
|
||||
Bit8u inc = 0;
|
||||
@ -739,28 +741,24 @@ void OPN2_EnvelopePrepare(ym3438_t *chip)
|
||||
rate = 0x3f;
|
||||
}
|
||||
|
||||
sum = (rate >> 2) + chip->eg_shift_lock;
|
||||
sum = ((rate >> 2) + chip->eg_shift_lock) & 0x0f;
|
||||
if (chip->eg_rate != 0 && chip->eg_quotient == 2)
|
||||
{
|
||||
if (rate < 48)
|
||||
{
|
||||
if ((sum & 0x0c) == 0x0c)
|
||||
switch (sum)
|
||||
{
|
||||
if ((sum & 0x03) == 0)
|
||||
{
|
||||
inc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sum & 0x01)
|
||||
{
|
||||
inc |= (rate >> 1) & 0x01;
|
||||
}
|
||||
if (sum & 0x02)
|
||||
{
|
||||
inc |= rate & 0x01;
|
||||
}
|
||||
}
|
||||
case 12:
|
||||
inc = 1;
|
||||
break;
|
||||
case 13:
|
||||
inc = (rate >> 1) & 0x01;
|
||||
break;
|
||||
case 14:
|
||||
inc = rate & 0x01;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -785,29 +783,28 @@ void OPN2_EnvelopePrepare(ym3438_t *chip)
|
||||
switch (rate_sel)
|
||||
{
|
||||
case eg_num_attack:
|
||||
reg_rate = chip->ar[slot];
|
||||
chip->eg_rate = chip->ar[slot];
|
||||
break;
|
||||
case eg_num_decay:
|
||||
reg_rate = chip->dr[slot];
|
||||
chip->eg_rate = chip->dr[slot];
|
||||
break;
|
||||
case eg_num_sustain:
|
||||
reg_rate = chip->sr[slot];
|
||||
chip->eg_rate = chip->sr[slot];
|
||||
break;
|
||||
case eg_num_release:
|
||||
reg_rate = (chip->rr[slot] << 1) | 0x01;
|
||||
chip->eg_rate = (chip->rr[slot] << 1) | 0x01;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
chip->eg_rate = reg_rate;
|
||||
chip->eg_ksv = chip->pg_kcode >> (chip->ks[slot] ^ 0x03);
|
||||
if (chip->am[slot])
|
||||
{
|
||||
chip->eg_am_shift = chip->ams[chip->channel];
|
||||
chip->eg_lfo_am = chip->lfo_am >> eg_am_shift[chip->ams[chip->channel]];
|
||||
}
|
||||
else
|
||||
{
|
||||
chip->eg_am_shift = 0;
|
||||
chip->eg_lfo_am = 0;
|
||||
}
|
||||
/* Delay TL & SL value */
|
||||
chip->eg_tl[1] = chip->eg_tl[0];
|
||||
@ -835,7 +832,7 @@ void OPN2_EnvelopeGenerate(ym3438_t *chip)
|
||||
level &= 0x3ff;
|
||||
|
||||
/* Apply AM LFO */
|
||||
level += chip->lfo_am >> eg_am_shift[chip->eg_am_shift];
|
||||
level += chip->eg_lfo_am;
|
||||
|
||||
/* Apply TL */
|
||||
if (!(chip->mode_csm && chip->channel == 2 + 1))
|
||||
@ -966,13 +963,15 @@ void OPN2_ChOutput(ym3438_t *chip)
|
||||
Bit32u channel = chip->channel;
|
||||
Bit32u test_dac = chip->mode_test_2c[5];
|
||||
Bit16s out;
|
||||
Bit16s sign;
|
||||
Bit32u out_en;
|
||||
chip->ch_read = chip->ch_lock;
|
||||
if (chip->slot < 12)
|
||||
{
|
||||
/* Ch 4,5,6 */
|
||||
channel++;
|
||||
}
|
||||
if ((chip->cycles & 3) == 0)
|
||||
if ((cycles & 3) == 0)
|
||||
{
|
||||
if (!test_dac)
|
||||
{
|
||||
@ -983,7 +982,7 @@ void OPN2_ChOutput(ym3438_t *chip)
|
||||
chip->ch_lock_r = chip->pan_r[channel];
|
||||
}
|
||||
/* Ch 6 */
|
||||
if (((chip->cycles >> 2) == 1 && chip->dacen) || test_dac)
|
||||
if (((cycles >> 2) == 1 && chip->dacen) || test_dac)
|
||||
{
|
||||
out = (Bit16s)chip->dacdata ^ 0x100;
|
||||
out <<= 7;
|
||||
@ -995,13 +994,53 @@ void OPN2_ChOutput(ym3438_t *chip)
|
||||
}
|
||||
chip->mol = 0;
|
||||
chip->mor = 0;
|
||||
if (chip->ch_lock_l)
|
||||
|
||||
if (chip_type == ym3438_type_ym2612)
|
||||
{
|
||||
chip->mol = out;
|
||||
out_en = ((cycles & 3) == 3) || test_dac;
|
||||
/* YM2612 DAC emulation(not verified) */
|
||||
sign = out >> 8;
|
||||
if (out >= 0)
|
||||
{
|
||||
out++;
|
||||
sign++;
|
||||
}
|
||||
if (chip->ch_lock_l && out_en)
|
||||
{
|
||||
chip->mol = out;
|
||||
}
|
||||
else
|
||||
{
|
||||
chip->mol = sign;
|
||||
}
|
||||
if (chip->ch_lock_r && out_en)
|
||||
{
|
||||
chip->mor = out;
|
||||
}
|
||||
else
|
||||
{
|
||||
chip->mor = sign;
|
||||
}
|
||||
/* Amplify signal */
|
||||
chip->mol *= 3;
|
||||
chip->mor *= 3;
|
||||
}
|
||||
if (chip->ch_lock_r)
|
||||
else
|
||||
{
|
||||
chip->mor = out;
|
||||
out_en = ((cycles & 3) != 0) || test_dac;
|
||||
/* Discrete YM3438 seems has the ladder effect too */
|
||||
if (out >= 0 && chip_type == ym3438_type_discrete)
|
||||
{
|
||||
out++;
|
||||
}
|
||||
if (chip->ch_lock_l && out_en)
|
||||
{
|
||||
chip->mol = out;
|
||||
}
|
||||
if (chip->ch_lock_r && out_en)
|
||||
{
|
||||
chip->mor = out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1179,6 +1218,11 @@ void OPN2_Reset(ym3438_t *chip)
|
||||
}
|
||||
}
|
||||
|
||||
void OPN2_SetChipType(Bit32u type)
|
||||
{
|
||||
chip_type = type;
|
||||
}
|
||||
|
||||
void OPN2_Clock(ym3438_t *chip, Bit32u *buffer)
|
||||
{
|
||||
chip->lfo_inc = chip->mode_test_21[1];
|
||||
@ -1350,7 +1394,7 @@ Bit32u OPN2_ReadIRQPin(ym3438_t *chip)
|
||||
|
||||
Bit8u OPN2_Read(ym3438_t *chip, Bit32u port)
|
||||
{
|
||||
if ((port & 3) == 0)
|
||||
if ((port & 3) == 0 || chip_type == ym3438_type_asic)
|
||||
{
|
||||
if (chip->mode_test_21[6])
|
||||
{
|
||||
@ -1382,3 +1426,4 @@ Bit8u OPN2_Read(ym3438_t *chip, Bit32u port)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_YM3438_CORE */
|
||||
|
@ -39,12 +39,18 @@
|
||||
* OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
|
||||
* OPL2 ROMs.
|
||||
*
|
||||
* version: 1.0.2
|
||||
* version: 1.0.7
|
||||
*/
|
||||
|
||||
#ifndef YM3438_H
|
||||
#define YM3438_H
|
||||
|
||||
enum {
|
||||
ym3438_type_discrete = 0, /* Discrete YM3438 (Teradrive) */
|
||||
ym3438_type_asic = 1, /* ASIC YM3438 (MD1 VA7, MD2, MD3, etc) */
|
||||
ym3438_type_ym2612 = 2 /* YM2612 (MD1, MD2 VA2) */
|
||||
};
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uintptr_t Bitu;
|
||||
@ -60,148 +66,149 @@ typedef int8_t Bit8s;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Bit32u cycles;
|
||||
Bit32u slot;
|
||||
Bit32u channel;
|
||||
Bit16s mol, mor;
|
||||
/* IO */
|
||||
Bit16u write_data;
|
||||
Bit8u write_a;
|
||||
Bit8u write_d;
|
||||
Bit8u write_a_en;
|
||||
Bit8u write_d_en;
|
||||
Bit8u write_busy;
|
||||
Bit8u write_busy_cnt;
|
||||
Bit8u write_fm_address;
|
||||
Bit8u write_fm_data;
|
||||
Bit8u write_fm_mode_a;
|
||||
Bit16u address;
|
||||
Bit8u data;
|
||||
Bit8u pin_test_in;
|
||||
Bit8u pin_irq;
|
||||
Bit8u busy;
|
||||
/* LFO */
|
||||
Bit8u lfo_en;
|
||||
Bit8u lfo_freq;
|
||||
Bit8u lfo_pm;
|
||||
Bit8u lfo_am;
|
||||
Bit8u lfo_cnt;
|
||||
Bit8u lfo_inc;
|
||||
Bit8u lfo_quotient;
|
||||
/* Phase generator */
|
||||
Bit16u pg_fnum;
|
||||
Bit8u pg_block;
|
||||
Bit8u pg_kcode;
|
||||
Bit32u pg_inc[24];
|
||||
Bit32u pg_phase[24];
|
||||
Bit8u pg_reset[24];
|
||||
Bit32u pg_read;
|
||||
/* Envelope generator */
|
||||
Bit8u eg_cycle;
|
||||
Bit8u eg_cycle_stop;
|
||||
Bit8u eg_shift;
|
||||
Bit8u eg_shift_lock;
|
||||
Bit8u eg_timer_low_lock;
|
||||
Bit16u eg_timer;
|
||||
Bit8u eg_timer_inc;
|
||||
Bit16u eg_quotient;
|
||||
Bit8u eg_custom_timer;
|
||||
Bit8u eg_rate;
|
||||
Bit8u eg_ksv;
|
||||
Bit8u eg_inc;
|
||||
Bit8u eg_ratemax;
|
||||
Bit8u eg_sl[2];
|
||||
Bit8u eg_am_shift;
|
||||
Bit8u eg_tl[2];
|
||||
Bit8u eg_state[24];
|
||||
Bit16u eg_level[24];
|
||||
Bit16u eg_out[24];
|
||||
Bit8u eg_kon[24];
|
||||
Bit8u eg_kon_csm[24];
|
||||
Bit8u eg_kon_latch[24];
|
||||
Bit8u eg_csm_mode[24];
|
||||
Bit8u eg_ssg_enable[24];
|
||||
Bit8u eg_ssg_pgrst_latch[24];
|
||||
Bit8u eg_ssg_repeat_latch[24];
|
||||
Bit8u eg_ssg_hold_up_latch[24];
|
||||
Bit8u eg_ssg_dir[24];
|
||||
Bit8u eg_ssg_inv[24];
|
||||
Bit32u eg_read[2];
|
||||
Bit8u eg_read_inc;
|
||||
/* FM */
|
||||
Bit16s fm_op1[6][2];
|
||||
Bit16s fm_op2[6];
|
||||
Bit16s fm_out[24];
|
||||
Bit16u fm_mod[24];
|
||||
/* Channel */
|
||||
Bit16s ch_acc[6];
|
||||
Bit16s ch_out[6];
|
||||
Bit16s ch_lock;
|
||||
Bit8u ch_lock_l;
|
||||
Bit8u ch_lock_r;
|
||||
Bit16s ch_read;
|
||||
/* Timer */
|
||||
Bit16u timer_a_cnt;
|
||||
Bit16u timer_a_reg;
|
||||
Bit8u timer_a_load_lock;
|
||||
Bit8u timer_a_load;
|
||||
Bit8u timer_a_enable;
|
||||
Bit8u timer_a_reset;
|
||||
Bit8u timer_a_load_latch;
|
||||
Bit8u timer_a_overflow_flag;
|
||||
Bit8u timer_a_overflow;
|
||||
|
||||
Bit16u timer_b_cnt;
|
||||
Bit8u timer_b_subcnt;
|
||||
Bit16u timer_b_reg;
|
||||
Bit8u timer_b_load_lock;
|
||||
Bit8u timer_b_load;
|
||||
Bit8u timer_b_enable;
|
||||
Bit8u timer_b_reset;
|
||||
Bit8u timer_b_load_latch;
|
||||
Bit8u timer_b_overflow_flag;
|
||||
Bit8u timer_b_overflow;
|
||||
|
||||
/* Register set */
|
||||
Bit8u mode_test_21[8];
|
||||
Bit8u mode_test_2c[8];
|
||||
Bit8u mode_ch3;
|
||||
Bit8u mode_kon_channel;
|
||||
Bit8u mode_kon_operator[4];
|
||||
Bit8u mode_kon[24];
|
||||
Bit8u mode_csm;
|
||||
Bit8u mode_kon_csm;
|
||||
Bit8u dacen;
|
||||
Bit16s dacdata;
|
||||
|
||||
Bit8u ks[24];
|
||||
Bit8u ar[24];
|
||||
Bit8u sr[24];
|
||||
Bit8u dt[24];
|
||||
Bit8u multi[24];
|
||||
Bit8u sl[24];
|
||||
Bit8u rr[24];
|
||||
Bit8u dr[24];
|
||||
Bit8u am[24];
|
||||
Bit8u tl[24];
|
||||
Bit8u ssg_eg[24];
|
||||
|
||||
Bit16u fnum[6];
|
||||
Bit8u block[6];
|
||||
Bit8u kcode[6];
|
||||
Bit16u fnum_3ch[6];
|
||||
Bit8u block_3ch[6];
|
||||
Bit8u kcode_3ch[6];
|
||||
Bit8u reg_a4;
|
||||
Bit8u reg_ac;
|
||||
Bit8u connect[6];
|
||||
Bit8u fb[6];
|
||||
Bit8u pan_l[6], pan_r[6];
|
||||
Bit8u ams[6];
|
||||
Bit8u pms[6];
|
||||
Bit32u cycles;
|
||||
Bit32u slot;
|
||||
Bit32u channel;
|
||||
Bit16s mol, mor;
|
||||
/* IO */
|
||||
Bit16u write_data;
|
||||
Bit8u write_a;
|
||||
Bit8u write_d;
|
||||
Bit8u write_a_en;
|
||||
Bit8u write_d_en;
|
||||
Bit8u write_busy;
|
||||
Bit8u write_busy_cnt;
|
||||
Bit8u write_fm_address;
|
||||
Bit8u write_fm_data;
|
||||
Bit8u write_fm_mode_a;
|
||||
Bit16u address;
|
||||
Bit8u data;
|
||||
Bit8u pin_test_in;
|
||||
Bit8u pin_irq;
|
||||
Bit8u busy;
|
||||
/* LFO */
|
||||
Bit8u lfo_en;
|
||||
Bit8u lfo_freq;
|
||||
Bit8u lfo_pm;
|
||||
Bit8u lfo_am;
|
||||
Bit8u lfo_cnt;
|
||||
Bit8u lfo_inc;
|
||||
Bit8u lfo_quotient;
|
||||
/* Phase generator */
|
||||
Bit16u pg_fnum;
|
||||
Bit8u pg_block;
|
||||
Bit8u pg_kcode;
|
||||
Bit32u pg_inc[24];
|
||||
Bit32u pg_phase[24];
|
||||
Bit8u pg_reset[24];
|
||||
Bit32u pg_read;
|
||||
/* Envelope generator */
|
||||
Bit8u eg_cycle;
|
||||
Bit8u eg_cycle_stop;
|
||||
Bit8u eg_shift;
|
||||
Bit8u eg_shift_lock;
|
||||
Bit8u eg_timer_low_lock;
|
||||
Bit16u eg_timer;
|
||||
Bit8u eg_timer_inc;
|
||||
Bit16u eg_quotient;
|
||||
Bit8u eg_custom_timer;
|
||||
Bit8u eg_rate;
|
||||
Bit8u eg_ksv;
|
||||
Bit8u eg_inc;
|
||||
Bit8u eg_ratemax;
|
||||
Bit8u eg_sl[2];
|
||||
Bit8u eg_lfo_am;
|
||||
Bit8u eg_tl[2];
|
||||
Bit8u eg_state[24];
|
||||
Bit16u eg_level[24];
|
||||
Bit16u eg_out[24];
|
||||
Bit8u eg_kon[24];
|
||||
Bit8u eg_kon_csm[24];
|
||||
Bit8u eg_kon_latch[24];
|
||||
Bit8u eg_csm_mode[24];
|
||||
Bit8u eg_ssg_enable[24];
|
||||
Bit8u eg_ssg_pgrst_latch[24];
|
||||
Bit8u eg_ssg_repeat_latch[24];
|
||||
Bit8u eg_ssg_hold_up_latch[24];
|
||||
Bit8u eg_ssg_dir[24];
|
||||
Bit8u eg_ssg_inv[24];
|
||||
Bit32u eg_read[2];
|
||||
Bit8u eg_read_inc;
|
||||
/* FM */
|
||||
Bit16s fm_op1[6][2];
|
||||
Bit16s fm_op2[6];
|
||||
Bit16s fm_out[24];
|
||||
Bit16u fm_mod[24];
|
||||
/* Channel */
|
||||
Bit16s ch_acc[6];
|
||||
Bit16s ch_out[6];
|
||||
Bit16s ch_lock;
|
||||
Bit8u ch_lock_l;
|
||||
Bit8u ch_lock_r;
|
||||
Bit16s ch_read;
|
||||
/* Timer */
|
||||
Bit16u timer_a_cnt;
|
||||
Bit16u timer_a_reg;
|
||||
Bit8u timer_a_load_lock;
|
||||
Bit8u timer_a_load;
|
||||
Bit8u timer_a_enable;
|
||||
Bit8u timer_a_reset;
|
||||
Bit8u timer_a_load_latch;
|
||||
Bit8u timer_a_overflow_flag;
|
||||
Bit8u timer_a_overflow;
|
||||
|
||||
Bit16u timer_b_cnt;
|
||||
Bit8u timer_b_subcnt;
|
||||
Bit16u timer_b_reg;
|
||||
Bit8u timer_b_load_lock;
|
||||
Bit8u timer_b_load;
|
||||
Bit8u timer_b_enable;
|
||||
Bit8u timer_b_reset;
|
||||
Bit8u timer_b_load_latch;
|
||||
Bit8u timer_b_overflow_flag;
|
||||
Bit8u timer_b_overflow;
|
||||
|
||||
/* Register set */
|
||||
Bit8u mode_test_21[8];
|
||||
Bit8u mode_test_2c[8];
|
||||
Bit8u mode_ch3;
|
||||
Bit8u mode_kon_channel;
|
||||
Bit8u mode_kon_operator[4];
|
||||
Bit8u mode_kon[24];
|
||||
Bit8u mode_csm;
|
||||
Bit8u mode_kon_csm;
|
||||
Bit8u dacen;
|
||||
Bit16s dacdata;
|
||||
|
||||
Bit8u ks[24];
|
||||
Bit8u ar[24];
|
||||
Bit8u sr[24];
|
||||
Bit8u dt[24];
|
||||
Bit8u multi[24];
|
||||
Bit8u sl[24];
|
||||
Bit8u rr[24];
|
||||
Bit8u dr[24];
|
||||
Bit8u am[24];
|
||||
Bit8u tl[24];
|
||||
Bit8u ssg_eg[24];
|
||||
|
||||
Bit16u fnum[6];
|
||||
Bit8u block[6];
|
||||
Bit8u kcode[6];
|
||||
Bit16u fnum_3ch[6];
|
||||
Bit8u block_3ch[6];
|
||||
Bit8u kcode_3ch[6];
|
||||
Bit8u reg_a4;
|
||||
Bit8u reg_ac;
|
||||
Bit8u connect[6];
|
||||
Bit8u fb[6];
|
||||
Bit8u pan_l[6], pan_r[6];
|
||||
Bit8u ams[6];
|
||||
Bit8u pms[6];
|
||||
} ym3438_t;
|
||||
|
||||
void OPN2_Reset(ym3438_t *chip);
|
||||
void OPN2_SetChipType(Bit32u type);
|
||||
void OPN2_Clock(ym3438_t *chip, Bit32u *buffer);
|
||||
void OPN2_Write(ym3438_t *chip, Bit32u port, Bit8u data);
|
||||
void OPN2_SetTestPin(ym3438_t *chip, Bit32u value);
|
||||
|
@ -201,18 +201,15 @@
|
||||
#define IFF2 Z80.iff2
|
||||
#define HALT Z80.halt
|
||||
|
||||
#ifdef Z80_ALLOW_OVERCLOCK
|
||||
#define USE_CYCLES(A) Z80.cycles += ((A) * z80_cycle_ratio) >> CYCLE_SHIFT
|
||||
#ifdef Z80_OVERCLOCK_SHIFT
|
||||
#define USE_CYCLES(A) Z80.cycles += ((A) * z80_cycle_ratio) >> Z80_OVERCLOCK_SHIFT
|
||||
UINT32 z80_cycle_ratio;
|
||||
#else
|
||||
#define USE_CYCLES(A) Z80.cycles += (A)
|
||||
#endif
|
||||
|
||||
Z80_Regs Z80;
|
||||
|
||||
#ifdef Z80_ALLOW_OVERCLOCK
|
||||
UINT32 z80_cycle_ratio;
|
||||
#endif
|
||||
|
||||
unsigned char *z80_readmap[64];
|
||||
unsigned char *z80_writemap[64];
|
||||
|
||||
@ -3368,8 +3365,8 @@ void z80_init(const void *config, int (*irqcallback)(int))
|
||||
memset(&Z80, 0, sizeof(Z80));
|
||||
Z80.daisy = config;
|
||||
Z80.irq_callback = irqcallback;
|
||||
#ifdef Z80_ALLOW_OVERCLOCK
|
||||
z80_cycle_ratio = 1 << CYCLE_SHIFT;
|
||||
#ifdef Z80_OVERCLOCK_SHIFT
|
||||
z80_cycle_ratio = 1 << Z80_OVERCLOCK_SHIFT;
|
||||
#endif
|
||||
|
||||
/* Clear registers values (NB: should be random on real hardware ?) */
|
||||
|
@ -51,7 +51,7 @@ typedef struct
|
||||
|
||||
extern Z80_Regs Z80;
|
||||
|
||||
#ifdef Z80_ALLOW_OVERCLOCK
|
||||
#ifdef Z80_OVERCLOCK_SHIFT
|
||||
extern UINT32 z80_cycle_ratio;
|
||||
#endif
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Genesis Plus GX configuration file support
|
||||
*
|
||||
* Copyright Eke-Eke (2007-2016)
|
||||
* Copyright Eke-Eke (2007-2017)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@ -97,7 +97,7 @@ typedef struct
|
||||
t_input_config input[MAX_INPUTS];
|
||||
uint16 pad_keymap[4][MAX_KEYS+1];
|
||||
#ifdef HW_RVL
|
||||
uint32 wpad_keymap[4*3][MAX_KEYS];
|
||||
uint32 wpad_keymap[4*3+1][MAX_KEYS];
|
||||
uint8 autosleep;
|
||||
int32 calx;
|
||||
int32 caly;
|
||||
|
@ -47,6 +47,7 @@
|
||||
|
||||
#ifdef HW_RVL
|
||||
#include <ogc/usbmouse.h>
|
||||
#include "wiidrc.h"
|
||||
#endif
|
||||
|
||||
#include <ogc/lwp_threads.h>
|
||||
@ -122,6 +123,7 @@ extern const u8 ctrl_gamecube_png[];
|
||||
extern const u8 ctrl_classic_png[];
|
||||
extern const u8 ctrl_nunchuk_png[];
|
||||
extern const u8 ctrl_wiimote_png[];
|
||||
extern const u8 ctrl_wiiu_png[];
|
||||
#endif
|
||||
|
||||
/* Generic images */
|
||||
@ -2350,13 +2352,14 @@ static void ctrlmenu(void)
|
||||
|
||||
/* Player Configuration device items */
|
||||
#ifdef HW_RVL
|
||||
gui_item items_device[5] =
|
||||
gui_item items_device[6] =
|
||||
{
|
||||
{NULL,ctrl_option_off_png ,"Input\nDevice","Select Input Controller",534,244,24,24},
|
||||
{NULL,ctrl_gamecube_png ,"Input\nDevice","Select Input Controller",530,246,36,24},
|
||||
{NULL,ctrl_wiimote_png ,"Input\nDevice","Select Input Controller",526,250,40,12},
|
||||
{NULL,ctrl_nunchuk_png ,"Input\nDevice","Select Input Controller",532,242,32,32},
|
||||
{NULL,ctrl_classic_png ,"Input\nDevice","Select Input Controller",526,242,40,32},
|
||||
{NULL,ctrl_wiiu_png ,"Input\nDevice","Select Input Controller",526,246,40,24},
|
||||
};
|
||||
#else
|
||||
gui_item items_device[2] =
|
||||
@ -2392,6 +2395,10 @@ static void ctrlmenu(void)
|
||||
items_device[2].texture = gxTextureOpenPNG(items_device[2].data,0);
|
||||
items_device[3].texture = gxTextureOpenPNG(items_device[3].data,0);
|
||||
items_device[4].texture = gxTextureOpenPNG(items_device[4].data,0);
|
||||
if (WiiDRC_Inited())
|
||||
{
|
||||
items_device[5].texture = gxTextureOpenPNG(items_device[5].data,0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* restore current menu elements */
|
||||
@ -2920,6 +2927,18 @@ static void ctrlmenu(void)
|
||||
}
|
||||
|
||||
if (config.input[player].port >= 4)
|
||||
{
|
||||
/* test WiiU gamepad */
|
||||
config.input[player].device = 4;
|
||||
config.input[player].port = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* autodetect WiiU gamepad */
|
||||
if (config.input[player].device == 4)
|
||||
{
|
||||
/* support for only one gamepad */
|
||||
if (!WiiDRC_Inited() || !WiiDRC_Connected() || (config.input[player].port >= 1))
|
||||
{
|
||||
/* no input controller left */
|
||||
config.input[player].device = -1;
|
||||
@ -3087,6 +3106,10 @@ static void ctrlmenu(void)
|
||||
gxTextureClose(&items_device[2].texture);
|
||||
gxTextureClose(&items_device[3].texture);
|
||||
gxTextureClose(&items_device[4].texture);
|
||||
if (WiiDRC_Inited())
|
||||
{
|
||||
gxTextureClose(&items_device[5].texture);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -3664,13 +3687,14 @@ static void showcredits(void)
|
||||
FONT_writeCenter("libfat by Chism", 18, 0, 640, 1046 - offset, (GXColor)WHITE);
|
||||
FONT_writeCenter("wiiuse by Michael Laforest (Para)", 18, 0, 640, 1064 - offset, (GXColor)WHITE);
|
||||
FONT_writeCenter("asndlib & OGG player by Francisco Muñoz (Hermes)", 18, 0, 640, 1082 - offset, (GXColor)WHITE);
|
||||
FONT_writeCenter("libpng by their respective authors", 18, 0, 640, 1100 - offset, (GXColor)WHITE);
|
||||
FONT_writeCenter("devkitPPC by Wintermute", 18, 0, 640, 1118 - offset, (GXColor)WHITE);
|
||||
FONT_writeCenter("libwiidrc by Fix94", 18, 0, 640, 1100 - offset, (GXColor)WHITE);
|
||||
FONT_writeCenter("libpng by their respective authors", 18, 0, 640, 1118 - offset, (GXColor)WHITE);
|
||||
FONT_writeCenter("devkitPPC by Wintermute", 18, 0, 640, 1136 - offset, (GXColor)WHITE);
|
||||
|
||||
FONT_writeCenter("Special thanks to ...", 20, 0, 640, 1158 - offset, (GXColor)LIGHT_GREEN);
|
||||
FONT_writeCenter("Softdev, Tmbinc, Costis, Emukiddid, Team Twiizer", 18, 0, 640, 1194 - offset, (GXColor)WHITE);
|
||||
FONT_writeCenter("Brakken & former Tehskeen members for their support", 18, 0, 640, 1212 - offset, (GXColor)WHITE);
|
||||
FONT_writeCenter("Anca, my wife, for her patience & various ideas", 18, 0, 640, 1230 - offset, (GXColor)WHITE);
|
||||
FONT_writeCenter("Special thanks to ...", 20, 0, 640, 1176 - offset, (GXColor)LIGHT_GREEN);
|
||||
FONT_writeCenter("Softdev, Tmbinc, Costis, Emukiddid, Team Twiizer", 18, 0, 640, 1212 - offset, (GXColor)WHITE);
|
||||
FONT_writeCenter("Brakken & former Tehskeen members for their support", 18, 0, 640, 1230 - offset, (GXColor)WHITE);
|
||||
FONT_writeCenter("Anca, my wife, for her patience & various ideas", 18, 0, 640, 1248 - offset, (GXColor)WHITE);
|
||||
|
||||
gxSetScreen();
|
||||
p = m_input.keys;
|
||||
|
322
gx/gx_input.c
322
gx/gx_input.c
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Genesis Plus GX input support
|
||||
*
|
||||
* Copyright Eke-Eke (2007-2015)
|
||||
* Copyright Eke-Eke (2007-2017)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
@ -40,10 +40,12 @@
|
||||
#include "shared.h"
|
||||
#include "font.h"
|
||||
#include "gui.h"
|
||||
#include "menu.h"
|
||||
#include "cheats.h"
|
||||
|
||||
#ifdef HW_RVL
|
||||
#include <ogc/usbmouse.h>
|
||||
#include "wiidrc.h"
|
||||
#endif
|
||||
|
||||
/* Analog sticks sensitivity */
|
||||
@ -77,11 +79,12 @@
|
||||
#define PAD_RIGHT 3
|
||||
|
||||
/* default directions mapping */
|
||||
static u32 wpad_dirmap[3][4] =
|
||||
static u32 wpad_dirmap[4][4] =
|
||||
{
|
||||
{WPAD_BUTTON_RIGHT, WPAD_BUTTON_LEFT, WPAD_BUTTON_UP, WPAD_BUTTON_DOWN}, /* WIIMOTE */
|
||||
{WPAD_BUTTON_UP, WPAD_BUTTON_DOWN, WPAD_BUTTON_LEFT, WPAD_BUTTON_RIGHT}, /* WIIMOTE + NUNCHUK */
|
||||
{WPAD_CLASSIC_BUTTON_UP, WPAD_CLASSIC_BUTTON_DOWN, WPAD_CLASSIC_BUTTON_LEFT, WPAD_CLASSIC_BUTTON_RIGHT} /* CLASSIC */
|
||||
{WPAD_BUTTON_RIGHT, WPAD_BUTTON_LEFT, WPAD_BUTTON_UP, WPAD_BUTTON_DOWN}, /* WIIMOTE */
|
||||
{WPAD_BUTTON_UP, WPAD_BUTTON_DOWN, WPAD_BUTTON_LEFT, WPAD_BUTTON_RIGHT}, /* WIIMOTE + NUNCHUK */
|
||||
{WPAD_CLASSIC_BUTTON_UP, WPAD_CLASSIC_BUTTON_DOWN, WPAD_CLASSIC_BUTTON_LEFT, WPAD_CLASSIC_BUTTON_RIGHT}, /* CLASSIC */
|
||||
{WIIDRC_BUTTON_UP, WIIDRC_BUTTON_DOWN, WIIDRC_BUTTON_LEFT, WIIDRC_BUTTON_RIGHT} /* WIIU GAMEPAD */
|
||||
};
|
||||
|
||||
#define WPAD_BUTTONS_HELD (WPAD_BUTTON_UP | WPAD_BUTTON_DOWN | WPAD_BUTTON_LEFT | WPAD_BUTTON_RIGHT | \
|
||||
@ -89,6 +92,10 @@ static u32 wpad_dirmap[3][4] =
|
||||
WPAD_CLASSIC_BUTTON_UP | WPAD_CLASSIC_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_LEFT | WPAD_CLASSIC_BUTTON_RIGHT | \
|
||||
WPAD_CLASSIC_BUTTON_FULL_L | WPAD_CLASSIC_BUTTON_FULL_R | WPAD_CLASSIC_BUTTON_A)
|
||||
|
||||
#define WIIU_BUTTONS_HELD (WIIDRC_BUTTON_UP | WIIDRC_BUTTON_DOWN | WIIDRC_BUTTON_LEFT | WIIDRC_BUTTON_RIGHT | \
|
||||
WIIDRC_BUTTON_MINUS | WIIDRC_BUTTON_PLUS | WIIDRC_BUTTON_A | \
|
||||
WIIDRC_BUTTON_L | WIIDRC_BUTTON_ZL | WIIDRC_BUTTON_R | WIIDRC_BUTTON_ZR)
|
||||
|
||||
#endif
|
||||
|
||||
#define PAD_BUTTONS_HELD (PAD_BUTTON_UP | PAD_BUTTON_DOWN | PAD_BUTTON_LEFT | PAD_BUTTON_RIGHT | \
|
||||
@ -444,7 +451,7 @@ static void pad_update(s8 chan, u8 i)
|
||||
{
|
||||
/* Calculate angle (in degree) */
|
||||
ang = 90.0 - (atan((float)y / (float)x) * 180.0 / M_PI);
|
||||
if (x < 0) ang += 180.0;
|
||||
if (x < 0) ang += 180.0;
|
||||
|
||||
/* 8 bottom sensors = 8 areas */
|
||||
if ((ang > 22.5) && (ang <= 67.5)) input.pad[i] |= INPUT_ACTIVATOR_2L;
|
||||
@ -465,7 +472,7 @@ static void pad_update(s8 chan, u8 i)
|
||||
{
|
||||
/* Calculate angle (in degree) */
|
||||
ang = 90.0 - (atan((float)y / (float)x) * 180.0 / M_PI);
|
||||
if (x < 0) ang += 180.0;
|
||||
if (x < 0) ang += 180.0;
|
||||
|
||||
/* 8 top sensors = 8 areas */
|
||||
if ((ang > 22.5) && (ang <= 67.5)) input.pad[i] |= INPUT_ACTIVATOR_2U;
|
||||
@ -523,7 +530,7 @@ static int wpad_StickX(WPADData *data, u8 right)
|
||||
/* adjust against center position */
|
||||
pos -= center;
|
||||
|
||||
/* return interpolated range [-128;127] */
|
||||
/* return interpolated range [-128;127] */
|
||||
if (pos > 0)
|
||||
{
|
||||
return (int)(127.0 * ((float)pos / (float)(max - center)));
|
||||
@ -572,7 +579,7 @@ static int wpad_StickY(WPADData *data, u8 right)
|
||||
/* adjust against center position */
|
||||
pos -= center;
|
||||
|
||||
/* return interpolated range [-128;127] */
|
||||
/* return interpolated range [-128;127] */
|
||||
if (pos > 0)
|
||||
{
|
||||
return (int)(127.0 * ((float)pos / (float)(max - center)));
|
||||
@ -595,13 +602,25 @@ static void wpad_config(u8 exp, int chan, int first_key, int last_key)
|
||||
inputs_disabled = 1;
|
||||
|
||||
/* Check if device is connected */
|
||||
WPAD_Probe(chan, &p);
|
||||
if (exp <= WPAD_EXP_CLASSIC)
|
||||
{
|
||||
WPAD_Probe(chan, &p);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (WiiDRC_Inited() && WiiDRC_Connected())
|
||||
{
|
||||
p = exp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Device not detected */
|
||||
if (((exp > WPAD_EXP_NONE) && (p != exp)) || (p == 255))
|
||||
{
|
||||
/* device not detected */
|
||||
if (exp == WPAD_EXP_NONE) sprintf(msg, "WIIMOTE #%d is not connected !", chan+1);
|
||||
if (exp == WPAD_EXP_NUNCHUK) sprintf(msg, "NUNCHUK #%d is not connected !", chan+1);
|
||||
if (exp == WPAD_EXP_CLASSIC) sprintf(msg, "CLASSIC #%d is not connected !", chan+1);
|
||||
if (exp == WPAD_EXP_NONE) sprintf(msg, "WIIMOTE #%d is not connected !", chan+1);
|
||||
else if (exp == WPAD_EXP_NUNCHUK) sprintf(msg, "NUNCHUK #%d is not connected !", chan+1);
|
||||
else if (exp == WPAD_EXP_CLASSIC) sprintf(msg, "CLASSIC #%d is not connected !", chan+1);
|
||||
else sprintf(msg, "WIIU GAMEPAD is not connected !");
|
||||
GUI_WaitPrompt("Error",msg);
|
||||
|
||||
/* re-enable background PAD scanning and exit */
|
||||
@ -616,10 +635,21 @@ static void wpad_config(u8 exp, int chan, int first_key, int last_key)
|
||||
if (strcmp(keyname[first_key], "N.A"))
|
||||
{
|
||||
/* remove any pending buttons */
|
||||
while (WPAD_ButtonsHeld(chan))
|
||||
if (exp <= WPAD_EXP_CLASSIC)
|
||||
{
|
||||
VIDEO_WaitVSync();
|
||||
WPAD_ScanPads();
|
||||
while (WPAD_ButtonsHeld(chan))
|
||||
{
|
||||
VIDEO_WaitVSync();
|
||||
WPAD_ScanPads();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (WiiDRC_ButtonsHeld())
|
||||
{
|
||||
VIDEO_WaitVSync();
|
||||
WiiDRC_ScanPads();
|
||||
}
|
||||
}
|
||||
|
||||
/* configurable button */
|
||||
@ -631,8 +661,16 @@ static void wpad_config(u8 exp, int chan, int first_key, int last_key)
|
||||
while (!p)
|
||||
{
|
||||
VIDEO_WaitVSync();
|
||||
WPAD_ScanPads();
|
||||
p = WPAD_ButtonsDown(chan);
|
||||
if (exp <= WPAD_EXP_CLASSIC)
|
||||
{
|
||||
WPAD_ScanPads();
|
||||
p = WPAD_ButtonsDown(chan);
|
||||
}
|
||||
else
|
||||
{
|
||||
WiiDRC_ScanPads();
|
||||
p = WiiDRC_ButtonsDown();
|
||||
}
|
||||
}
|
||||
|
||||
/* detect pressed key */
|
||||
@ -683,9 +721,20 @@ static void wpad_config(u8 exp, int chan, int first_key, int last_key)
|
||||
break;
|
||||
}
|
||||
|
||||
/* WiiU GamePad Controller */
|
||||
default:
|
||||
{
|
||||
first_key = MAX_KEYS;
|
||||
if (p & WIIDRC_BUTTON_A) p = WIIDRC_BUTTON_A;
|
||||
else if (p & WIIDRC_BUTTON_B) p = WIIDRC_BUTTON_B;
|
||||
else if (p & WIIDRC_BUTTON_X) p = WIIDRC_BUTTON_X;
|
||||
else if (p & WIIDRC_BUTTON_Y) p = WIIDRC_BUTTON_Y;
|
||||
else if (p & WIIDRC_BUTTON_ZL) p = WIIDRC_BUTTON_ZL;
|
||||
else if (p & WIIDRC_BUTTON_ZR) p = WIIDRC_BUTTON_ZR;
|
||||
else if (p & WIIDRC_BUTTON_PLUS) p = WIIDRC_BUTTON_PLUS;
|
||||
else if (p & WIIDRC_BUTTON_MINUS) p = WIIDRC_BUTTON_MINUS;
|
||||
else if (p & WIIDRC_BUTTON_L) p = WIIDRC_BUTTON_L;
|
||||
else if (p & WIIDRC_BUTTON_R) p = WIIDRC_BUTTON_R;
|
||||
else first_key = MAX_KEYS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -693,17 +742,28 @@ static void wpad_config(u8 exp, int chan, int first_key, int last_key)
|
||||
/* update key mapping */
|
||||
if (first_key < MAX_KEYS)
|
||||
{
|
||||
config.wpad_keymap[exp + (chan * 3)][first_key] = p;
|
||||
config.wpad_keymap[4*exp + chan][first_key] = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (first_key++ < last_key);
|
||||
|
||||
/* remove any pending buttons */
|
||||
while (WPAD_ButtonsHeld(chan))
|
||||
if (exp <= WPAD_EXP_CLASSIC)
|
||||
{
|
||||
VIDEO_WaitVSync();
|
||||
WPAD_ScanPads();
|
||||
while (WPAD_ButtonsHeld(chan))
|
||||
{
|
||||
VIDEO_WaitVSync();
|
||||
WPAD_ScanPads();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (WiiDRC_ButtonsHeld())
|
||||
{
|
||||
VIDEO_WaitVSync();
|
||||
WiiDRC_ScanPads();
|
||||
}
|
||||
}
|
||||
|
||||
/* re-enable background PAD scanning and exit */
|
||||
@ -715,21 +775,59 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
|
||||
/* WPAD data */
|
||||
WPADData *data = WPAD_Data(chan);
|
||||
|
||||
/* WPAD status */
|
||||
/* Button status */
|
||||
u32 p = data->btns_h;
|
||||
|
||||
/* Analog sticks */
|
||||
s8 x = 0;
|
||||
s8 y = 0;
|
||||
s16 x = 0;
|
||||
s16 y = 0;
|
||||
|
||||
if (exp != WPAD_EXP_NONE)
|
||||
/* WiiU GamePad Controller support */
|
||||
if (exp > WPAD_EXP_CLASSIC)
|
||||
{
|
||||
WiiDRC_ScanPads();
|
||||
if (WiiDRC_ShutdownRequested())
|
||||
{
|
||||
Shutdown = ConfigRequested = 1;
|
||||
reload = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
p = WiiDRC_ButtonsHeld();
|
||||
|
||||
/* Default Wii controller menu keys */
|
||||
if (WiiDRC_ButtonsDown() & WIIDRC_BUTTON_HOME)
|
||||
{
|
||||
/* Default fast-forward key combo */
|
||||
if (p & WIIDRC_BUTTON_MINUS)
|
||||
{
|
||||
audioSync ^= AUDIO_WAIT;
|
||||
videoSync = (audioSync && config.vsync && (gc_pal != vdp_pal)) ? VIDEO_WAIT : 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Return to emulator settings */
|
||||
ConfigRequested = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Left Analog Stick */
|
||||
x = (WiiDRC_lStickX() * 128) / 75;
|
||||
y = (WiiDRC_lStickY() * 128) / 75;
|
||||
if (x > 127) x = 127;
|
||||
else if (x < -128) x = -128;
|
||||
if (y > 127) y = 127;
|
||||
else if (y < -128) y = -128;
|
||||
}
|
||||
else if (exp != WPAD_EXP_NONE)
|
||||
{
|
||||
/* Left Analog Stick */
|
||||
x = wpad_StickX(data,0);
|
||||
y = wpad_StickY(data,0);
|
||||
}
|
||||
|
||||
/* Retrieve current key mapping */
|
||||
u32 *wpad_keymap = config.wpad_keymap[exp + (chan * 3)];
|
||||
u32 *wpad_keymap = config.wpad_keymap[4*exp + chan];
|
||||
|
||||
/* Emulated device */
|
||||
switch (input.dev[i])
|
||||
@ -772,11 +870,24 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
|
||||
input.analog[i][1] = y ? (127 - y) : 128;
|
||||
|
||||
/* Right Stick analog position [0-255] */
|
||||
if (exp == WPAD_EXP_CLASSIC)
|
||||
if (exp >= WPAD_EXP_CLASSIC)
|
||||
{
|
||||
/* Classic Controller right stick */
|
||||
x = wpad_StickX(data,1);
|
||||
y = wpad_StickY(data,1);
|
||||
if (exp > WPAD_EXP_CLASSIC)
|
||||
{
|
||||
/* WiiU GamePad Controller right stick */
|
||||
x = (WiiDRC_rStickX() * 128) / 75;
|
||||
y = (WiiDRC_rStickY() * 128) / 75;
|
||||
if (x > 127) x = 127;
|
||||
else if (x < -128) x = -128;
|
||||
if (y > 127) y = 127;
|
||||
else if (y < -128) y = -128;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Classic Controller right stick */
|
||||
x = wpad_StickX(data,1);
|
||||
y = wpad_StickY(data,1);
|
||||
}
|
||||
|
||||
/* Emulated stick is unidirectional but can be rotated */
|
||||
if (abs(x) > abs(y))
|
||||
@ -867,7 +978,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
|
||||
case DEVICE_LIGHTGUN:
|
||||
{
|
||||
/* Gun screen position (x,y) */
|
||||
if (exp != WPAD_EXP_CLASSIC)
|
||||
if (exp < WPAD_EXP_CLASSIC)
|
||||
{
|
||||
/* Wiimote IR */
|
||||
struct ir_t ir;
|
||||
@ -888,7 +999,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Classic Controller analog stick */
|
||||
/* Left analog stick */
|
||||
input.analog[i][0] += x / ANALOG_SENSITIVITY;
|
||||
input.analog[i][1] -= y / ANALOG_SENSITIVITY;
|
||||
|
||||
@ -927,7 +1038,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
|
||||
if (event.button & 2) input.pad[i] |= INPUT_MOUSE_CENTER;
|
||||
if (event.button & 4) input.pad[i] |= INPUT_MOUSE_LEFT;
|
||||
}
|
||||
else if (exp != WPAD_EXP_CLASSIC)
|
||||
else if (exp == WPAD_EXP_NONE)
|
||||
{
|
||||
/* Wiimote IR (buggy) */
|
||||
struct ir_t ir;
|
||||
@ -942,7 +1053,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Classic Controller analog stick position (-127;+127) -> (-255;+255) */
|
||||
/* Left analog stick position (-127;+127) -> (-255;+255) */
|
||||
input.analog[i][0] = (x / ANALOG_SENSITIVITY) * 2;
|
||||
input.analog[i][1] = (y / ANALOG_SENSITIVITY) * 2;
|
||||
}
|
||||
@ -971,7 +1082,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
|
||||
else if (p & PAD_BUTTON_RIGHT) input.pad[i] |= INPUT_RIGHT;
|
||||
|
||||
/* PEN screen position (x,y) */
|
||||
if (exp != WPAD_EXP_CLASSIC)
|
||||
if (exp < WPAD_EXP_CLASSIC)
|
||||
{
|
||||
/* Wiimote IR */
|
||||
struct ir_t ir;
|
||||
@ -984,7 +1095,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Classic Controller analog stick */
|
||||
/* Left analog stick */
|
||||
input.analog[0][0] += x / ANALOG_SENSITIVITY;
|
||||
input.analog[0][1] -= y / ANALOG_SENSITIVITY;
|
||||
|
||||
@ -1008,7 +1119,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
|
||||
case DEVICE_TEREBI:
|
||||
{
|
||||
/* PEN screen position (x,y) */
|
||||
if (exp != WPAD_EXP_CLASSIC)
|
||||
if (exp < WPAD_EXP_CLASSIC)
|
||||
{
|
||||
/* Wiimote IR */
|
||||
struct ir_t ir;
|
||||
@ -1021,7 +1132,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Classic Controller analog stick */
|
||||
/* Left analog stick */
|
||||
input.analog[0][0] += x / ANALOG_SENSITIVITY;
|
||||
input.analog[0][1] -= y / ANALOG_SENSITIVITY;
|
||||
|
||||
@ -1041,7 +1152,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
|
||||
case DEVICE_GRAPHIC_BOARD:
|
||||
{
|
||||
/* PEN screen position (x,y) */
|
||||
if (exp != WPAD_EXP_CLASSIC)
|
||||
if (exp < WPAD_EXP_CLASSIC)
|
||||
{
|
||||
/* Wiimote IR */
|
||||
struct ir_t ir;
|
||||
@ -1054,7 +1165,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Classic Controller analog stick */
|
||||
/* Left analog stick */
|
||||
input.analog[0][0] += x / ANALOG_SENSITIVITY;
|
||||
input.analog[0][1] -= y / ANALOG_SENSITIVITY;
|
||||
|
||||
@ -1130,6 +1241,7 @@ void gx_input_Init(void)
|
||||
WPAD_Init();
|
||||
WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR);
|
||||
WPAD_SetVRes(WPAD_CHAN_ALL,640,480);
|
||||
WiiDRC_Init();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1195,6 +1307,15 @@ int gx_input_FindDevices(void)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: /* WiiU GamePad Controller */
|
||||
{
|
||||
if (WiiDRC_Inited() && WiiDRC_Connected())
|
||||
{
|
||||
found++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
@ -1236,34 +1357,44 @@ void gx_input_SetDefault(void)
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
/* Wiimote (horizontal) */
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONA] = WPAD_BUTTON_A;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONB] = WPAD_BUTTON_1;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONC] = WPAD_BUTTON_2;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_START] = WPAD_BUTTON_PLUS;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONX] = 0;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONY] = 0;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONZ] = 0;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_MODE] = 0;
|
||||
config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONA] = WPAD_BUTTON_A;
|
||||
config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONB] = WPAD_BUTTON_1;
|
||||
config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONC] = WPAD_BUTTON_2;
|
||||
config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_START] = WPAD_BUTTON_PLUS;
|
||||
config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONX] = 0;
|
||||
config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONY] = 0;
|
||||
config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONZ] = 0;
|
||||
config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_MODE] = 0;
|
||||
|
||||
/* Wiimote + Nunchuk */
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONA] = WPAD_NUNCHUK_BUTTON_Z;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONB] = WPAD_BUTTON_B;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONC] = WPAD_BUTTON_A;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_START] = WPAD_BUTTON_PLUS;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONX] = WPAD_NUNCHUK_BUTTON_C;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONY] = WPAD_BUTTON_1;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONZ] = WPAD_BUTTON_2;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_MODE] = WPAD_BUTTON_MINUS;
|
||||
config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_BUTTONA] = WPAD_NUNCHUK_BUTTON_Z;
|
||||
config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_BUTTONB] = WPAD_BUTTON_B;
|
||||
config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_BUTTONC] = WPAD_BUTTON_A;
|
||||
config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_START] = WPAD_BUTTON_PLUS;
|
||||
config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_BUTTONX] = WPAD_NUNCHUK_BUTTON_C;
|
||||
config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_BUTTONY] = WPAD_BUTTON_1;
|
||||
config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_BUTTONZ] = WPAD_BUTTON_2;
|
||||
config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_MODE] = WPAD_BUTTON_MINUS;
|
||||
|
||||
/* Classic Controller */
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONA] = WPAD_CLASSIC_BUTTON_Y;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONB] = WPAD_CLASSIC_BUTTON_B;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONC] = WPAD_CLASSIC_BUTTON_A;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_START] = WPAD_CLASSIC_BUTTON_PLUS;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONX] = WPAD_CLASSIC_BUTTON_ZL;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONY] = WPAD_CLASSIC_BUTTON_ZR;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONZ] = WPAD_CLASSIC_BUTTON_X;
|
||||
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_MODE] = WPAD_CLASSIC_BUTTON_MINUS;
|
||||
config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_BUTTONA] = WPAD_CLASSIC_BUTTON_Y;
|
||||
config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_BUTTONB] = WPAD_CLASSIC_BUTTON_B;
|
||||
config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_BUTTONC] = WPAD_CLASSIC_BUTTON_A;
|
||||
config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_START] = WPAD_CLASSIC_BUTTON_PLUS;
|
||||
config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_BUTTONX] = WPAD_CLASSIC_BUTTON_ZL;
|
||||
config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_BUTTONY] = WPAD_CLASSIC_BUTTON_ZR;
|
||||
config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_BUTTONZ] = WPAD_CLASSIC_BUTTON_X;
|
||||
config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_MODE] = WPAD_CLASSIC_BUTTON_MINUS;
|
||||
|
||||
/* WiiU GamePad Controller */
|
||||
config.wpad_keymap[4*3][KEY_BUTTONA] = WIIDRC_BUTTON_Y;
|
||||
config.wpad_keymap[4*3][KEY_BUTTONB] = WIIDRC_BUTTON_B;
|
||||
config.wpad_keymap[4*3][KEY_BUTTONC] = WIIDRC_BUTTON_A;
|
||||
config.wpad_keymap[4*3][KEY_START] = WIIDRC_BUTTON_PLUS;
|
||||
config.wpad_keymap[4*3][KEY_BUTTONX] = WIIDRC_BUTTON_L;
|
||||
config.wpad_keymap[4*3][KEY_BUTTONY] = WIIDRC_BUTTON_R;
|
||||
config.wpad_keymap[4*3][KEY_BUTTONZ] = WIIDRC_BUTTON_X;
|
||||
config.wpad_keymap[4*3][KEY_MODE] = WIIDRC_BUTTON_MINUS;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1276,8 +1407,20 @@ void gx_input_SetDefault(void)
|
||||
}
|
||||
|
||||
#ifdef HW_RVL
|
||||
/* autodetect connected WiiU Gamepad Controller */
|
||||
if (WiiDRC_Inited() && WiiDRC_Connected())
|
||||
{
|
||||
config.input[0].device = 4;
|
||||
config.input[0].port = 0;
|
||||
i = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
|
||||
/* autodetect connected Wii Controllers */
|
||||
for (i=0; i<4; i++)
|
||||
while (i++ < 4)
|
||||
{
|
||||
exp = 255;
|
||||
WPAD_Probe(i, &exp);
|
||||
@ -1596,12 +1739,35 @@ void gx_input_UpdateMenu(void)
|
||||
else if (x < -ANALOG_SENSITIVITY) hp |= PAD_BUTTON_LEFT;
|
||||
else if (y > ANALOG_SENSITIVITY) hp |= PAD_BUTTON_UP;
|
||||
else if (y < -ANALOG_SENSITIVITY) hp |= PAD_BUTTON_DOWN;
|
||||
|
||||
/* WiiU GamePad status */
|
||||
u32 pwu = 0;
|
||||
u32 hwu = 0;
|
||||
if (WiiDRC_Inited())
|
||||
{
|
||||
WiiDRC_ScanPads();
|
||||
if (WiiDRC_ShutdownRequested())
|
||||
{
|
||||
Shutdown = ConfigRequested = 1;
|
||||
reload = 0;
|
||||
return;
|
||||
}
|
||||
pwu = WiiDRC_ButtonsDown();
|
||||
hwu = WiiDRC_ButtonsHeld() & WIIU_BUTTONS_HELD;
|
||||
x = WiiDRC_lStickX();
|
||||
y = WiiDRC_lStickY();
|
||||
if (x > ANALOG_SENSITIVITY) hp |= PAD_BUTTON_RIGHT;
|
||||
else if (x < -ANALOG_SENSITIVITY) hp |= PAD_BUTTON_LEFT;
|
||||
else if (y > ANALOG_SENSITIVITY) hp |= PAD_BUTTON_UP;
|
||||
else if (y < -ANALOG_SENSITIVITY) hp |= PAD_BUTTON_DOWN;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* check if any direction/selection key is being held or just being pressed/released */
|
||||
#ifdef HW_RVL
|
||||
if (pp||pw) held_cnt = 0;
|
||||
else if (hp||hw) held_cnt++;
|
||||
if (pp||pw||pwu) held_cnt = 0;
|
||||
else if (hp||hw||hwu) held_cnt++;
|
||||
else held_cnt = 0;
|
||||
#else
|
||||
if (pp) held_cnt = 0;
|
||||
@ -1616,6 +1782,7 @@ void gx_input_UpdateMenu(void)
|
||||
pp |= hp;
|
||||
#ifdef HW_RVL
|
||||
pw |= hw;
|
||||
pwu |= hwu;
|
||||
#endif
|
||||
|
||||
/* delay until next triggering (adjusts direction/selection update speed) */
|
||||
@ -1651,7 +1818,20 @@ void gx_input_UpdateMenu(void)
|
||||
if (pw & (WPAD_BUTTON_1|WPAD_BUTTON_B|WPAD_CLASSIC_BUTTON_B)) pp |= PAD_BUTTON_B;
|
||||
if (pw & (WPAD_BUTTON_HOME|WPAD_CLASSIC_BUTTON_HOME)) pp |= PAD_TRIGGER_Z;
|
||||
if (pw & (WPAD_BUTTON_PLUS|WPAD_CLASSIC_BUTTON_PLUS|WPAD_CLASSIC_BUTTON_FULL_L)) pp |= PAD_TRIGGER_L;
|
||||
if (pw & (WPAD_BUTTON_MINUS|WPAD_CLASSIC_BUTTON_MINUS|WPAD_CLASSIC_BUTTON_FULL_L)) pp |= PAD_TRIGGER_R;
|
||||
if (pw & (WPAD_BUTTON_MINUS|WPAD_CLASSIC_BUTTON_MINUS|WPAD_CLASSIC_BUTTON_FULL_R)) pp |= PAD_TRIGGER_R;
|
||||
|
||||
/* WiiU GamePad direction keys */
|
||||
if (pwu & WIIDRC_BUTTON_UP) pp |= PAD_BUTTON_UP;
|
||||
else if (pwu & WIIDRC_BUTTON_DOWN) pp |= PAD_BUTTON_DOWN;
|
||||
else if (pwu & WIIDRC_BUTTON_LEFT) pp |= PAD_BUTTON_LEFT;
|
||||
else if (pwu & WIIDRC_BUTTON_RIGHT) pp |= PAD_BUTTON_RIGHT;
|
||||
|
||||
/* WiiU GamePad button keys */
|
||||
if (pwu & WIIDRC_BUTTON_A) pp |= PAD_BUTTON_A;
|
||||
if (pwu & WIIDRC_BUTTON_B) pp |= PAD_BUTTON_B;
|
||||
if (pwu & WIIDRC_BUTTON_HOME) pp |= PAD_TRIGGER_Z;
|
||||
if (pwu & (WIIDRC_BUTTON_PLUS|WIIDRC_BUTTON_L|WIIDRC_BUTTON_ZL)) pp |= PAD_TRIGGER_L;
|
||||
if (pwu & (WIIDRC_BUTTON_MINUS|WIIDRC_BUTTON_R|WIIDRC_BUTTON_ZR)) pp |= PAD_TRIGGER_R;
|
||||
#endif
|
||||
|
||||
/* Update menu inputs */
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Genesis Plus GX input support
|
||||
*
|
||||
* Copyright Eke-Eke (2007-2015)
|
||||
* Copyright Eke-Eke (2007-2017)
|
||||
*
|
||||
* Redistribution and use of this code or any derivative works are permitted
|
||||
* provided that the following conditions are met:
|
||||
|
BIN
gx/images/ctrl_wiiu.png
Normal file
BIN
gx/images/ctrl_wiiu.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
@ -54,12 +54,6 @@
|
||||
#include <xtl.h>
|
||||
#endif
|
||||
|
||||
#if defined(M68K_ALLOW_OVERCLOCK) || defined(Z80_ALLOW_OVERCLOCK)
|
||||
#define HAVE_OVERCLOCK
|
||||
/* Overclocking frame delay (hack) */
|
||||
#define OVERCLOCK_FRAME_DELAY 100
|
||||
#endif
|
||||
|
||||
#define RETRO_DEVICE_MDPAD_3B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 0)
|
||||
#define RETRO_DEVICE_MDPAD_6B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 1)
|
||||
#define RETRO_DEVICE_MSPAD_2B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 2)
|
||||
@ -82,6 +76,25 @@
|
||||
#include "sms_ntsc.h"
|
||||
#include <streams/file_stream.h>
|
||||
|
||||
#define STATIC_ASSERT(name, test) typedef struct { int assert_[(test)?1:-1]; } assert_ ## name ## _
|
||||
#define M68K_MAX_CYCLES 1107
|
||||
#define Z80_MAX_CYCLES 345
|
||||
#define OVERCLOCK_FRAME_DELAY 100
|
||||
|
||||
#ifdef M68K_OVERCLOCK_SHIFT
|
||||
#define HAVE_OVERCLOCK
|
||||
STATIC_ASSERT(m68k_overflow,
|
||||
M68K_MAX_CYCLES <= UINT_MAX >> (M68K_OVERCLOCK_SHIFT + 1));
|
||||
#endif
|
||||
|
||||
#ifdef Z80_OVERCLOCK_SHIFT
|
||||
#ifndef HAVE_OVERCLOCK
|
||||
#define HAVE_OVERCLOCK
|
||||
#endif
|
||||
STATIC_ASSERT(z80_overflow,
|
||||
Z80_MAX_CYCLES <= UINT_MAX >> (Z80_OVERCLOCK_SHIFT + 1));
|
||||
#endif
|
||||
|
||||
sms_ntsc_t *sms_ntsc;
|
||||
md_ntsc_t *md_ntsc;
|
||||
|
||||
@ -541,7 +554,7 @@ static void config_default(void)
|
||||
config.lock_on = 0;
|
||||
config.lcd = 0; /* 0.8 fixed point */
|
||||
#ifdef HAVE_OVERCLOCK
|
||||
config.overclock = 0;
|
||||
config.overclock = 100;
|
||||
#endif
|
||||
config.no_sprite_limit = 0;
|
||||
|
||||
@ -812,6 +825,31 @@ static bool update_viewport(void)
|
||||
return ((ow != vwidth) || (oh != vheight) || (oar != vaspect_ratio));
|
||||
}
|
||||
|
||||
#ifdef HAVE_OVERCLOCK
|
||||
static void update_overclock(void)
|
||||
{
|
||||
#ifdef M68K_OVERCLOCK_SHIFT
|
||||
m68k.cycle_ratio = 1 << M68K_OVERCLOCK_SHIFT;
|
||||
#endif
|
||||
#ifdef Z80_OVERCLOCK_SHIFT
|
||||
z80_cycle_ratio = 1 << Z80_OVERCLOCK_SHIFT;
|
||||
#endif
|
||||
if (overclock_delay == 0)
|
||||
{
|
||||
/* Cycle ratios multiply per-instruction cycle counts, so use
|
||||
reciprocals */
|
||||
#ifdef M68K_OVERCLOCK_SHIFT
|
||||
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
m68k.cycle_ratio = (100 << M68K_OVERCLOCK_SHIFT) / config.overclock;
|
||||
#endif
|
||||
#ifdef Z80_OVERCLOCK_SHIFT
|
||||
if ((system_hw & SYSTEM_PBC) != SYSTEM_MD)
|
||||
z80_cycle_ratio = (100 << Z80_OVERCLOCK_SHIFT) / config.overclock;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void check_variables(void)
|
||||
{
|
||||
unsigned orig_value;
|
||||
@ -1124,12 +1162,25 @@ static void check_variables(void)
|
||||
environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var);
|
||||
{
|
||||
orig_value = config.ym3438;
|
||||
if (!strcmp(var.value, "nuked opn2"))
|
||||
if (!strcmp(var.value, "nuked (ym2612)"))
|
||||
{
|
||||
OPN2_SetChipType(ym3438_type_ym2612);
|
||||
config.ym3438 = 1;
|
||||
}
|
||||
else if (!strcmp(var.value, "nuked (asic ym3438)"))
|
||||
{
|
||||
OPN2_SetChipType(ym3438_type_asic);
|
||||
config.ym3438 = 2;
|
||||
}
|
||||
else if (!strcmp(var.value, "nuked (discrete ym3438)"))
|
||||
{
|
||||
OPN2_SetChipType(ym3438_type_discrete);
|
||||
config.ym3438 = 3;
|
||||
}
|
||||
else
|
||||
config.ym3438 = 0;
|
||||
|
||||
if (orig_value != config.ym3438)
|
||||
if (orig_value == 0 && config.ym3438 > 0 || orig_value > 0 && config.ym3438 == 0)
|
||||
{
|
||||
sound_init();
|
||||
sound_reset();
|
||||
@ -1258,17 +1309,19 @@ static void check_variables(void)
|
||||
var.key = "genesis_plus_gx_overclock";
|
||||
environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var);
|
||||
{
|
||||
/* Cycle ratios multiply cycle count, so use reciprocal */
|
||||
if (strcmp(var.value, "100%") == 0)
|
||||
config.overclock = (100 << CYCLE_SHIFT)/100;
|
||||
config.overclock = 100;
|
||||
else if (strcmp(var.value, "125%") == 0)
|
||||
config.overclock = (100 << CYCLE_SHIFT)/125;
|
||||
config.overclock = 125;
|
||||
else if (strcmp(var.value, "150%") == 0)
|
||||
config.overclock = (100 << CYCLE_SHIFT)/150;
|
||||
config.overclock = 150;
|
||||
else if (strcmp(var.value, "175%") == 0)
|
||||
config.overclock = (100 << CYCLE_SHIFT)/175;
|
||||
config.overclock = 175;
|
||||
else if (strcmp(var.value, "200%") == 0)
|
||||
config.overclock = (100 << CYCLE_SHIFT)/200;
|
||||
config.overclock = 200;
|
||||
|
||||
if (system_hw)
|
||||
update_overclock();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1704,11 +1757,11 @@ void retro_set_environment(retro_environment_t cb)
|
||||
{ "genesis_plus_gx_ym2413", "Master System FM; auto|disabled|enabled" },
|
||||
{ "genesis_plus_gx_dac_bits", "YM2612 DAC quantization; disabled|enabled" },
|
||||
#ifdef HAVE_YM3438_CORE
|
||||
{ "genesis_plus_gx_ym3438", "YM2612/YM3438 core; mame|nuked opn2" },
|
||||
{ "genesis_plus_gx_ym3438", "YM2612/YM3438 core; mame|nuked (ym2612)|nuked (asic ym3438)|nuked (discrete ym3438)" },
|
||||
#endif
|
||||
|
||||
{ "genesis_plus_gx_sound_output", "Sound output; stereo|mono" },
|
||||
{ "genesis_plus_gx_audio_filter", "Audio filter; disabled|low-pass" },
|
||||
{ "genesis_plus_gx_sound_output", "Sound output; stereo|mono" },
|
||||
{ "genesis_plus_gx_lowpass_range", "Low-pass filter %; 60|65|70|75|80|85|90|95|5|10|15|20|25|30|35|40|45|50|55"},
|
||||
|
||||
#if HAVE_EQ
|
||||
@ -2074,6 +2127,7 @@ bool retro_unserialize(const void *data, size_t size)
|
||||
|
||||
#ifdef HAVE_OVERCLOCK
|
||||
overclock_delay = OVERCLOCK_FRAME_DELAY;
|
||||
update_overclock();
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
@ -2240,9 +2294,6 @@ bool retro_load_game(const struct retro_game_info *info)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_OVERCLOCK
|
||||
overclock_delay = OVERCLOCK_FRAME_DELAY;
|
||||
#endif
|
||||
audio_init(SOUND_FREQUENCY, 0);
|
||||
system_init();
|
||||
system_reset();
|
||||
@ -2253,6 +2304,11 @@ bool retro_load_game(const struct retro_game_info *info)
|
||||
|
||||
update_viewport();
|
||||
|
||||
#ifdef HAVE_OVERCLOCK
|
||||
overclock_delay = OVERCLOCK_FRAME_DELAY;
|
||||
update_overclock();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2360,6 +2416,7 @@ void retro_reset(void)
|
||||
{
|
||||
#ifdef HAVE_OVERCLOCK
|
||||
overclock_delay = OVERCLOCK_FRAME_DELAY;
|
||||
update_overclock();
|
||||
#endif
|
||||
gen_reset(0);
|
||||
}
|
||||
@ -2371,38 +2428,20 @@ void retro_run(void)
|
||||
|
||||
#ifdef HAVE_OVERCLOCK
|
||||
/* update overclock delay */
|
||||
if (overclock_delay)
|
||||
overclock_delay--;
|
||||
if (overclock_delay && --overclock_delay == 0)
|
||||
update_overclock();
|
||||
#endif
|
||||
|
||||
if (system_hw == SYSTEM_MCD)
|
||||
{
|
||||
#ifdef M68K_ALLOW_OVERCLOCK
|
||||
if (overclock_delay == 0)
|
||||
m68k.cycle_ratio = config.overclock;
|
||||
else
|
||||
m68k.cycle_ratio = 1 << CYCLE_SHIFT;
|
||||
#endif
|
||||
system_frame_scd(0);
|
||||
}
|
||||
else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
|
||||
{
|
||||
#ifdef M68K_ALLOW_OVERCLOCK
|
||||
if (overclock_delay == 0)
|
||||
m68k.cycle_ratio = config.overclock;
|
||||
else
|
||||
m68k.cycle_ratio = 1 << CYCLE_SHIFT;
|
||||
#endif
|
||||
system_frame_gen(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef Z80_ALLOW_OVERCLOCK
|
||||
if (overclock_delay == 0)
|
||||
z80_cycle_ratio = config.overclock;
|
||||
else
|
||||
z80_cycle_ratio = 1 << CYCLE_SHIFT;
|
||||
#endif
|
||||
system_frame_sms(0);
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ typedef unsigned char bool;
|
||||
#define MODE5_MAX_SPRITES_PER_LINE (config.no_sprite_limit ? MAX_SPRITES_PER_LINE : (bitmap.viewport.w >> 4))
|
||||
#define MODE5_MAX_SPRITE_PIXELS (config.no_sprite_limit ? MAX_SPRITES_PER_LINE * 32 : max_sprite_pixels)
|
||||
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
int8 device;
|
||||
uint8 port;
|
||||
|
Loading…
Reference in New Issue
Block a user