Merge pull request #112 from ekeeke/master

Sync with upstream
This commit is contained in:
hizzlekizzle 2017-10-10 08:33:23 -05:00 committed by GitHub
commit 5454ba36db
21 changed files with 806 additions and 356 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -268,7 +268,7 @@ typedef struct
uint address_space; /* Current FC code */
#ifdef M68K_ALLOW_OVERCLOCK
#ifdef M68K_OVERCLOCK_SHIFT
int cycle_ratio;
#endif

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
{

View File

@ -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);
}

View File

@ -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 */

View File

@ -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);

View File

@ -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 ?) */

View File

@ -51,7 +51,7 @@ typedef struct
extern Z80_Regs Z80;
#ifdef Z80_ALLOW_OVERCLOCK
#ifdef Z80_OVERCLOCK_SHIFT
extern UINT32 z80_cycle_ratio;
#endif

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -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);
}

View File

@ -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;