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 * added configurable FPS display & toggleable fast-forward key combo
(HOME + MINUS with Wii controllers or R TRIGGER + START with Gamecube controller) (HOME + MINUS with Wii controllers or R TRIGGER + START with Gamecube controller)
* added 50hz progressive mode (576p) support for emulation * added 50hz progressive mode (576p) support for emulation
* added WiiU GamePad Controller support on vWii (Fix94)
* reduced SRAM files size * reduced SRAM files size
* improved A/V Sync: when VSYNC is enabled, audio resampler output rate is now adjusted (+/-0,1 %) * 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. 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 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. 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 BLIP BUFFER LIBRARY
terms of the GNU Lesser General Public License (LGPL) -------------------
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 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: the following license:
Copyright (c) 2008 Hermes <www.entuwii.net> 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) \ $(ENDIANNESS_DEFINES) \
$(PLATFORM_DEFINES) \ $(PLATFORM_DEFINES) \
-D__LIBRETRO__ \ -D__LIBRETRO__ \
-DM68K_ALLOW_OVERCLOCK \ -DM68K_OVERCLOCK_SHIFT=20 \
-DZ80_ALLOW_OVERCLOCK \ -DZ80_OVERCLOCK_SHIFT=20
-DCYCLE_SHIFT=10
ifneq (,$(findstring msvc,$(platform))) ifneq (,$(findstring msvc,$(platform)))
LIBRETRO_CFLAGS += -DINLINE="static _inline" 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 */ uint address_space; /* Current FC code */
#ifdef M68K_ALLOW_OVERCLOCK #ifdef M68K_OVERCLOCK_SHIFT
int cycle_ratio; int cycle_ratio;
#endif #endif

View File

@ -319,8 +319,8 @@ void m68k_init(void)
} }
#endif #endif
#ifdef M68K_ALLOW_OVERCLOCK #ifdef M68K_OVERCLOCK_SHIFT
m68k.cycle_ratio = 1 << CYCLE_SHIFT; m68k.cycle_ratio = 1 << M68K_OVERCLOCK_SHIFT;
#endif #endif
#if M68K_EMULATE_INT_ACK == OPT_ON #if M68K_EMULATE_INT_ACK == OPT_ON

View File

@ -514,8 +514,8 @@
/* ---------------------------- Cycle Counting ---------------------------- */ /* ---------------------------- Cycle Counting ---------------------------- */
#ifdef M68K_ALLOW_OVERCLOCK #ifdef M68K_OVERCLOCK_SHIFT
#define USE_CYCLES(A) m68ki_cpu.cycles += ((A) * m68ki_cpu.cycle_ratio) >> CYCLE_SHIFT #define USE_CYCLES(A) m68ki_cpu.cycles += ((A) * m68ki_cpu.cycle_ratio) >> M68K_OVERCLOCK_SHIFT
#else #else
#define USE_CYCLES(A) m68ki_cpu.cycles += (A) #define USE_CYCLES(A) m68ki_cpu.cycles += (A)
#endif #endif

View File

@ -284,8 +284,8 @@ void s68k_init(void)
} }
#endif #endif
#ifdef M68K_ALLOW_OVERCLOCK #ifdef M68K_OVERCLOCK_SHIFT
s68k.cycle_ratio = 1 << CYCLE_SHIFT; s68k.cycle_ratio = 1 << M68K_OVERCLOCK_SHIFT;
#endif #endif
#if M68K_EMULATE_INT_ACK == OPT_ON #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]; ym3438_sample[1] += ym3438_accm[j][1];
} }
} }
*buffer++ = ym3438_sample[0] * 8; *buffer++ = ym3438_sample[0] * 11;
*buffer++ = ym3438_sample[1] * 8; *buffer++ = ym3438_sample[1] * 11;
} }
} }
@ -130,7 +130,7 @@ void sound_init( void )
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
{ {
/* YM2612 */ /* YM2612 */
#ifdef HAVE_YM3438_CORE #ifdef HAVE_YM3438_CORE
if (config.ym3438) if (config.ym3438)
{ {
/* Nuked OPN2 */ /* Nuked OPN2 */
@ -146,7 +146,7 @@ void sound_init( void )
fm_cycles_ratio = 6 * 7; fm_cycles_ratio = 6 * 7;
} }
else else
#endif #endif
{ {
/* MAME */ /* MAME */
YM2612Init(); YM2612Init();
@ -276,7 +276,7 @@ int sound_context_save(uint8 *state)
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
{ {
#ifdef HAVE_YM3438_CORE #ifdef HAVE_YM3438_CORE
save_param(&config.ym3438, sizeof(config.ym3438)); save_param(&config.ym3438, sizeof(config.ym3438));
if (config.ym3438) if (config.ym3438)
{ {
@ -290,9 +290,9 @@ int sound_context_save(uint8 *state)
bufferptr += YM2612SaveContext(state + sizeof(config.ym3438)); bufferptr += YM2612SaveContext(state + sizeof(config.ym3438));
YM2612Config(config.dac_bits); YM2612Config(config.dac_bits);
} }
#else #else
bufferptr = YM2612SaveContext(state); bufferptr = YM2612SaveContext(state);
#endif #endif
} }
else else
{ {
@ -309,11 +309,11 @@ int sound_context_save(uint8 *state)
int sound_context_load(uint8 *state) int sound_context_load(uint8 *state)
{ {
int bufferptr = 0; int bufferptr = 0;
uint8 config_ym3438;
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) 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)); load_param(&config_ym3438, sizeof(config_ym3438));
if (config_ym3438) if (config_ym3438)
{ {
@ -327,10 +327,10 @@ int sound_context_load(uint8 *state)
bufferptr += YM2612LoadContext(state + sizeof(config_ym3438)); bufferptr += YM2612LoadContext(state + sizeof(config_ym3438));
YM2612Config(config.dac_bits); YM2612Config(config.dac_bits);
} }
#else #else
bufferptr = YM2612LoadContext(state); bufferptr = YM2612LoadContext(state);
YM2612Config(config.dac_bits); YM2612Config(config.dac_bits);
#endif #endif
} }
else else
{ {

View File

@ -24,6 +24,10 @@
/* /*
** CHANGELOG: ** 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): ** 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 LFO PM implementation: block & keyscale code should not be modified by LFO (verified on YM2612 die)
** - fixed Timer B overflow handling ** - 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 */ /* rates 00-11 */
/* /*
O( 0),O( 1),O( 2),O( 3), O( 0),O( 1)
O( 0),O( 1),O( 2),O( 3),
*/ */
O(18),O(18),O( 0),O( 0), O(18),O(18), /* from Nemesis's tests on real YM2612 hardware */
O( 0),O( 0),O( 2),O( 2), /* Nemesis's tests */ 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), 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) 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 */ 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; fc = ((fc << 1) + lfo_fn_offset) & 0xfff;
/* (frequency) phase increment counter (17-bit) */ /* (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 */ /* update phase */
SLOT->phase += ((fc * SLOT->mul) >> 1); SLOT->phase += ((fc * SLOT->mul) >> 1);
@ -1308,7 +1311,7 @@ INLINE void update_phase_lfo_channel(FM_CH *CH)
{ {
UINT32 fc = CH->block_fnum; 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 */ 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; fc = ((fc << 1) + lfo_fn_offset) & 0xfff;
/* (frequency) phase increment counter (17-bit) */ /* (frequency) phase increment counter (17-bit) */
fc = (fc << 5) >> (7 - blk); fc = (fc << blk) >> 2;
/* apply DETUNE & MUL operator specific values */ /* apply DETUNE & MUL operator specific values */
finc = (fc + CH->SLOT[SLOT1].DT[kc]) & DT_MASK; finc = (fc + CH->SLOT[SLOT1].DT[kc]) & DT_MASK;
@ -1696,7 +1699,7 @@ INLINE void OPNWriteReg(int r, int v)
/* keyscale code */ /* keyscale code */
CH->kcode = (blk<<2) | opn_fktable[fn >> 7]; CH->kcode = (blk<<2) | opn_fktable[fn >> 7];
/* phase increment counter */ /* phase increment counter */
CH->fc = (fn << 6) >> (7 - blk); CH->fc = (fn<<blk)>>1;
/* store fnum in clear form for LFO PM calculations */ /* store fnum in clear form for LFO PM calculations */
CH->block_fnum = (blk<<11) | fn; CH->block_fnum = (blk<<11) | fn;
@ -1715,7 +1718,7 @@ INLINE void OPNWriteReg(int r, int v)
/* keyscale code */ /* keyscale code */
ym2612.OPN.SL3.kcode[c]= (blk<<2) | opn_fktable[fn >> 7]; ym2612.OPN.SL3.kcode[c]= (blk<<2) | opn_fktable[fn >> 7];
/* phase increment counter */ /* 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.OPN.SL3.block_fnum[c] = (blk<<11) | fn;
ym2612.CH[2].SLOT[SLOT1].Incr=-1; ym2612.CH[2].SLOT[SLOT1].Incr=-1;
} }
@ -2017,7 +2020,7 @@ void YM2612Update(int *buffer, int length)
refresh_fc_eg_chan(&ym2612.CH[5]); refresh_fc_eg_chan(&ym2612.CH[5]);
/* buffering */ /* buffering */
for(i=0; i < length ; i++) for(i=0; i<length ; i++)
{ {
/* clear outputs */ /* clear outputs */
out_fm[0] = 0; out_fm[0] = 0;
@ -2045,14 +2048,21 @@ void YM2612Update(int *buffer, int length)
/* advance LFO */ /* advance LFO */
advance_lfo(); advance_lfo();
/* advance envelope generator */
ym2612.OPN.eg_timer ++;
/* EG is updated every 3 samples */ /* EG is updated every 3 samples */
ym2612.OPN.eg_timer++;
if (ym2612.OPN.eg_timer >= 3) if (ym2612.OPN.eg_timer >= 3)
{ {
/* reset EG timer */
ym2612.OPN.eg_timer = 0; ym2612.OPN.eg_timer = 0;
/* increment EG counter */
ym2612.OPN.eg_cnt++; 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); 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) * Copyright (C) 2017 Alexey Khokholov (Nuke.YKT)
* *
@ -39,7 +40,7 @@
* OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): * OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
* OPL2 ROMs. * OPL2 ROMs.
* *
* version: 1.0.2 * version: 1.0.7
*/ */
#include <string.h> #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) void OPN2_DoIO(ym3438_t *chip)
{ {
/* Write signal check */ /* Write signal check */
@ -488,9 +491,9 @@ void OPN2_PhaseCalcIncrement(ym3438_t *chip)
lfo_l ^= 0x0f; lfo_l ^= 0x0f;
} }
fm = (fnum_h >> pg_lfo_sh1[pms][lfo_l]) + (fnum_h >> pg_lfo_sh2[pms][lfo_l]); 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; fm >>= 2;
if (lfo & 0x10) if (lfo & 0x10)
@ -506,7 +509,7 @@ void OPN2_PhaseCalcIncrement(ym3438_t *chip)
basefreq = (fnum << chip->pg_block) >> 2; basefreq = (fnum << chip->pg_block) >> 2;
/* Apply detune */ /* Apply detune */
if (dt & 0x03) if (dt_l)
{ {
if (kcode > 0x1c) if (kcode > 0x1c)
{ {
@ -514,7 +517,7 @@ void OPN2_PhaseCalcIncrement(ym3438_t *chip)
} }
block = kcode >> 2; block = kcode >> 2;
note = kcode & 0x03; 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_h = sum >> 1;
sum_l = sum & 0x01; sum_l = sum & 0x01;
detune = pg_detune[(sum_l << 2) | note] >> (9 - sum_h); 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) void OPN2_EnvelopeSSGEG(ym3438_t *chip)
{ {
Bit32u slot = chip->slot; Bit32u slot = chip->slot;
Bit8u direction = 0;
chip->eg_ssg_pgrst_latch[slot] = 0; chip->eg_ssg_pgrst_latch[slot] = 0;
chip->eg_ssg_repeat_latch[slot] = 0; chip->eg_ssg_repeat_latch[slot] = 0;
chip->eg_ssg_hold_up_latch[slot] = 0; chip->eg_ssg_hold_up_latch[slot] = 0;
chip->eg_ssg_inv[slot] = 0; chip->eg_ssg_inv[slot] = 0;
Bit8u direction = 0;
if (chip->ssg_eg[slot] & 0x08) if (chip->ssg_eg[slot] & 0x08)
{ {
direction = chip->eg_ssg_dir[slot]; direction = chip->eg_ssg_dir[slot];
@ -651,7 +654,7 @@ void OPN2_EnvelopeADSR(ym3438_t *chip)
{ {
nextlevel = 0; 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; inc = (~level << chip->eg_inc) >> 5;
} }
@ -665,13 +668,13 @@ void OPN2_EnvelopeADSR(ym3438_t *chip)
{ {
nextstate = eg_num_decay; 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; inc = (~level << chip->eg_inc) >> 5;
} }
break; break;
case eg_num_decay: case eg_num_decay:
if (!eg_off && (level >> 5) == chip->eg_sl[1]) if ((level >> 5) == chip->eg_sl[1])
{ {
nextstate = eg_num_sustain; nextstate = eg_num_sustain;
} }
@ -724,7 +727,6 @@ void OPN2_EnvelopeADSR(ym3438_t *chip)
void OPN2_EnvelopePrepare(ym3438_t *chip) void OPN2_EnvelopePrepare(ym3438_t *chip)
{ {
Bit8u reg_rate;
Bit8u rate; Bit8u rate;
Bit8u sum; Bit8u sum;
Bit8u inc = 0; Bit8u inc = 0;
@ -739,28 +741,24 @@ void OPN2_EnvelopePrepare(ym3438_t *chip)
rate = 0x3f; 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 (chip->eg_rate != 0 && chip->eg_quotient == 2)
{ {
if (rate < 48) if (rate < 48)
{ {
if ((sum & 0x0c) == 0x0c) switch (sum)
{
if ((sum & 0x03) == 0)
{ {
case 12:
inc = 1; inc = 1;
} break;
else case 13:
{ inc = (rate >> 1) & 0x01;
if (sum & 0x01) break;
{ case 14:
inc |= (rate >> 1) & 0x01; inc = rate & 0x01;
} break;
if (sum & 0x02) default:
{ break;
inc |= rate & 0x01;
}
}
} }
} }
else else
@ -785,29 +783,28 @@ void OPN2_EnvelopePrepare(ym3438_t *chip)
switch (rate_sel) switch (rate_sel)
{ {
case eg_num_attack: case eg_num_attack:
reg_rate = chip->ar[slot]; chip->eg_rate = chip->ar[slot];
break; break;
case eg_num_decay: case eg_num_decay:
reg_rate = chip->dr[slot]; chip->eg_rate = chip->dr[slot];
break; break;
case eg_num_sustain: case eg_num_sustain:
reg_rate = chip->sr[slot]; chip->eg_rate = chip->sr[slot];
break; break;
case eg_num_release: case eg_num_release:
reg_rate = (chip->rr[slot] << 1) | 0x01; chip->eg_rate = (chip->rr[slot] << 1) | 0x01;
break; break;
default: default:
break; break;
} }
chip->eg_rate = reg_rate;
chip->eg_ksv = chip->pg_kcode >> (chip->ks[slot] ^ 0x03); chip->eg_ksv = chip->pg_kcode >> (chip->ks[slot] ^ 0x03);
if (chip->am[slot]) 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 else
{ {
chip->eg_am_shift = 0; chip->eg_lfo_am = 0;
} }
/* Delay TL & SL value */ /* Delay TL & SL value */
chip->eg_tl[1] = chip->eg_tl[0]; chip->eg_tl[1] = chip->eg_tl[0];
@ -835,7 +832,7 @@ void OPN2_EnvelopeGenerate(ym3438_t *chip)
level &= 0x3ff; level &= 0x3ff;
/* Apply AM LFO */ /* Apply AM LFO */
level += chip->lfo_am >> eg_am_shift[chip->eg_am_shift]; level += chip->eg_lfo_am;
/* Apply TL */ /* Apply TL */
if (!(chip->mode_csm && chip->channel == 2 + 1)) if (!(chip->mode_csm && chip->channel == 2 + 1))
@ -966,13 +963,15 @@ void OPN2_ChOutput(ym3438_t *chip)
Bit32u channel = chip->channel; Bit32u channel = chip->channel;
Bit32u test_dac = chip->mode_test_2c[5]; Bit32u test_dac = chip->mode_test_2c[5];
Bit16s out; Bit16s out;
Bit16s sign;
Bit32u out_en;
chip->ch_read = chip->ch_lock; chip->ch_read = chip->ch_lock;
if (chip->slot < 12) if (chip->slot < 12)
{ {
/* Ch 4,5,6 */ /* Ch 4,5,6 */
channel++; channel++;
} }
if ((chip->cycles & 3) == 0) if ((cycles & 3) == 0)
{ {
if (!test_dac) if (!test_dac)
{ {
@ -983,7 +982,7 @@ void OPN2_ChOutput(ym3438_t *chip)
chip->ch_lock_r = chip->pan_r[channel]; chip->ch_lock_r = chip->pan_r[channel];
} }
/* Ch 6 */ /* 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 = (Bit16s)chip->dacdata ^ 0x100;
out <<= 7; out <<= 7;
@ -995,14 +994,54 @@ void OPN2_ChOutput(ym3438_t *chip)
} }
chip->mol = 0; chip->mol = 0;
chip->mor = 0; chip->mor = 0;
if (chip->ch_lock_l)
if (chip_type == ym3438_type_ym2612)
{
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; chip->mol = out;
} }
if (chip->ch_lock_r) else
{
chip->mol = sign;
}
if (chip->ch_lock_r && out_en)
{ {
chip->mor = out; chip->mor = out;
} }
else
{
chip->mor = sign;
}
/* Amplify signal */
chip->mol *= 3;
chip->mor *= 3;
}
else
{
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;
}
}
} }
void OPN2_FMGenerate(ym3438_t *chip) void OPN2_FMGenerate(ym3438_t *chip)
@ -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) void OPN2_Clock(ym3438_t *chip, Bit32u *buffer)
{ {
chip->lfo_inc = chip->mode_test_21[1]; 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) 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]) if (chip->mode_test_21[6])
{ {
@ -1382,3 +1426,4 @@ Bit8u OPN2_Read(ym3438_t *chip, Bit32u port)
} }
return 0; return 0;
} }
#endif /* HAVE_YM3438_CORE */

View File

@ -39,12 +39,18 @@
* OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): * OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
* OPL2 ROMs. * OPL2 ROMs.
* *
* version: 1.0.2 * version: 1.0.7
*/ */
#ifndef YM3438_H #ifndef YM3438_H
#define 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> #include <stdint.h>
typedef uintptr_t Bitu; typedef uintptr_t Bitu;
@ -111,7 +117,7 @@ typedef struct
Bit8u eg_inc; Bit8u eg_inc;
Bit8u eg_ratemax; Bit8u eg_ratemax;
Bit8u eg_sl[2]; Bit8u eg_sl[2];
Bit8u eg_am_shift; Bit8u eg_lfo_am;
Bit8u eg_tl[2]; Bit8u eg_tl[2];
Bit8u eg_state[24]; Bit8u eg_state[24];
Bit16u eg_level[24]; Bit16u eg_level[24];
@ -202,6 +208,7 @@ typedef struct
} ym3438_t; } ym3438_t;
void OPN2_Reset(ym3438_t *chip); void OPN2_Reset(ym3438_t *chip);
void OPN2_SetChipType(Bit32u type);
void OPN2_Clock(ym3438_t *chip, Bit32u *buffer); void OPN2_Clock(ym3438_t *chip, Bit32u *buffer);
void OPN2_Write(ym3438_t *chip, Bit32u port, Bit8u data); void OPN2_Write(ym3438_t *chip, Bit32u port, Bit8u data);
void OPN2_SetTestPin(ym3438_t *chip, Bit32u value); void OPN2_SetTestPin(ym3438_t *chip, Bit32u value);

View File

@ -201,18 +201,15 @@
#define IFF2 Z80.iff2 #define IFF2 Z80.iff2
#define HALT Z80.halt #define HALT Z80.halt
#ifdef Z80_ALLOW_OVERCLOCK #ifdef Z80_OVERCLOCK_SHIFT
#define USE_CYCLES(A) Z80.cycles += ((A) * z80_cycle_ratio) >> CYCLE_SHIFT #define USE_CYCLES(A) Z80.cycles += ((A) * z80_cycle_ratio) >> Z80_OVERCLOCK_SHIFT
UINT32 z80_cycle_ratio;
#else #else
#define USE_CYCLES(A) Z80.cycles += (A) #define USE_CYCLES(A) Z80.cycles += (A)
#endif #endif
Z80_Regs Z80; Z80_Regs Z80;
#ifdef Z80_ALLOW_OVERCLOCK
UINT32 z80_cycle_ratio;
#endif
unsigned char *z80_readmap[64]; unsigned char *z80_readmap[64];
unsigned char *z80_writemap[64]; unsigned char *z80_writemap[64];
@ -3368,8 +3365,8 @@ void z80_init(const void *config, int (*irqcallback)(int))
memset(&Z80, 0, sizeof(Z80)); memset(&Z80, 0, sizeof(Z80));
Z80.daisy = config; Z80.daisy = config;
Z80.irq_callback = irqcallback; Z80.irq_callback = irqcallback;
#ifdef Z80_ALLOW_OVERCLOCK #ifdef Z80_OVERCLOCK_SHIFT
z80_cycle_ratio = 1 << CYCLE_SHIFT; z80_cycle_ratio = 1 << Z80_OVERCLOCK_SHIFT;
#endif #endif
/* Clear registers values (NB: should be random on real hardware ?) */ /* Clear registers values (NB: should be random on real hardware ?) */

View File

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

View File

@ -3,7 +3,7 @@
* *
* Genesis Plus GX configuration file support * 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 * Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met: * provided that the following conditions are met:
@ -97,7 +97,7 @@ typedef struct
t_input_config input[MAX_INPUTS]; t_input_config input[MAX_INPUTS];
uint16 pad_keymap[4][MAX_KEYS+1]; uint16 pad_keymap[4][MAX_KEYS+1];
#ifdef HW_RVL #ifdef HW_RVL
uint32 wpad_keymap[4*3][MAX_KEYS]; uint32 wpad_keymap[4*3+1][MAX_KEYS];
uint8 autosleep; uint8 autosleep;
int32 calx; int32 calx;
int32 caly; int32 caly;

View File

@ -47,6 +47,7 @@
#ifdef HW_RVL #ifdef HW_RVL
#include <ogc/usbmouse.h> #include <ogc/usbmouse.h>
#include "wiidrc.h"
#endif #endif
#include <ogc/lwp_threads.h> #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_classic_png[];
extern const u8 ctrl_nunchuk_png[]; extern const u8 ctrl_nunchuk_png[];
extern const u8 ctrl_wiimote_png[]; extern const u8 ctrl_wiimote_png[];
extern const u8 ctrl_wiiu_png[];
#endif #endif
/* Generic images */ /* Generic images */
@ -2350,13 +2352,14 @@ static void ctrlmenu(void)
/* Player Configuration device items */ /* Player Configuration device items */
#ifdef HW_RVL #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_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_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_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_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_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 #else
gui_item items_device[2] = 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[2].texture = gxTextureOpenPNG(items_device[2].data,0);
items_device[3].texture = gxTextureOpenPNG(items_device[3].data,0); items_device[3].texture = gxTextureOpenPNG(items_device[3].data,0);
items_device[4].texture = gxTextureOpenPNG(items_device[4].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 #endif
/* restore current menu elements */ /* restore current menu elements */
@ -2920,6 +2927,18 @@ static void ctrlmenu(void)
} }
if (config.input[player].port >= 4) 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 */ /* no input controller left */
config.input[player].device = -1; config.input[player].device = -1;
@ -3087,6 +3106,10 @@ static void ctrlmenu(void)
gxTextureClose(&items_device[2].texture); gxTextureClose(&items_device[2].texture);
gxTextureClose(&items_device[3].texture); gxTextureClose(&items_device[3].texture);
gxTextureClose(&items_device[4].texture); gxTextureClose(&items_device[4].texture);
if (WiiDRC_Inited())
{
gxTextureClose(&items_device[5].texture);
}
#endif #endif
} }
@ -3664,13 +3687,14 @@ static void showcredits(void)
FONT_writeCenter("libfat by Chism", 18, 0, 640, 1046 - offset, (GXColor)WHITE); 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("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("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("libwiidrc by Fix94", 18, 0, 640, 1100 - offset, (GXColor)WHITE);
FONT_writeCenter("devkitPPC by Wintermute", 18, 0, 640, 1118 - 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("Special thanks to ...", 20, 0, 640, 1176 - offset, (GXColor)LIGHT_GREEN);
FONT_writeCenter("Softdev, Tmbinc, Costis, Emukiddid, Team Twiizer", 18, 0, 640, 1194 - offset, (GXColor)WHITE); 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, 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, 1230 - offset, (GXColor)WHITE); FONT_writeCenter("Anca, my wife, for her patience & various ideas", 18, 0, 640, 1248 - offset, (GXColor)WHITE);
gxSetScreen(); gxSetScreen();
p = m_input.keys; p = m_input.keys;

View File

@ -3,7 +3,7 @@
* *
* Genesis Plus GX input support * 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 * Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met: * provided that the following conditions are met:
@ -40,10 +40,12 @@
#include "shared.h" #include "shared.h"
#include "font.h" #include "font.h"
#include "gui.h" #include "gui.h"
#include "menu.h"
#include "cheats.h" #include "cheats.h"
#ifdef HW_RVL #ifdef HW_RVL
#include <ogc/usbmouse.h> #include <ogc/usbmouse.h>
#include "wiidrc.h"
#endif #endif
/* Analog sticks sensitivity */ /* Analog sticks sensitivity */
@ -77,11 +79,12 @@
#define PAD_RIGHT 3 #define PAD_RIGHT 3
/* default directions mapping */ /* 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_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_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_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 | \ #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_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) 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 #endif
#define PAD_BUTTONS_HELD (PAD_BUTTON_UP | PAD_BUTTON_DOWN | PAD_BUTTON_LEFT | PAD_BUTTON_RIGHT | \ #define PAD_BUTTONS_HELD (PAD_BUTTON_UP | PAD_BUTTON_DOWN | PAD_BUTTON_LEFT | PAD_BUTTON_RIGHT | \
@ -595,13 +602,25 @@ static void wpad_config(u8 exp, int chan, int first_key, int last_key)
inputs_disabled = 1; inputs_disabled = 1;
/* Check if device is connected */ /* Check if device is connected */
if (exp <= WPAD_EXP_CLASSIC)
{
WPAD_Probe(chan, &p); WPAD_Probe(chan, &p);
}
else
{
if (WiiDRC_Inited() && WiiDRC_Connected())
{
p = exp;
}
}
/* Device not detected */
if (((exp > WPAD_EXP_NONE) && (p != exp)) || (p == 255)) 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_NONE) sprintf(msg, "WIIMOTE #%d is not connected !", chan+1);
if (exp == WPAD_EXP_NUNCHUK) sprintf(msg, "NUNCHUK #%d is not connected !", chan+1); else 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); 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); GUI_WaitPrompt("Error",msg);
/* re-enable background PAD scanning and exit */ /* re-enable background PAD scanning and exit */
@ -616,11 +635,22 @@ static void wpad_config(u8 exp, int chan, int first_key, int last_key)
if (strcmp(keyname[first_key], "N.A")) if (strcmp(keyname[first_key], "N.A"))
{ {
/* remove any pending buttons */ /* remove any pending buttons */
if (exp <= WPAD_EXP_CLASSIC)
{
while (WPAD_ButtonsHeld(chan)) while (WPAD_ButtonsHeld(chan))
{ {
VIDEO_WaitVSync(); VIDEO_WaitVSync();
WPAD_ScanPads(); WPAD_ScanPads();
} }
}
else
{
while (WiiDRC_ButtonsHeld())
{
VIDEO_WaitVSync();
WiiDRC_ScanPads();
}
}
/* configurable button */ /* configurable button */
sprintf(msg,"Press key for %s\n(HOME to return)",keyname[first_key]); sprintf(msg,"Press key for %s\n(HOME to return)",keyname[first_key]);
@ -631,9 +661,17 @@ static void wpad_config(u8 exp, int chan, int first_key, int last_key)
while (!p) while (!p)
{ {
VIDEO_WaitVSync(); VIDEO_WaitVSync();
if (exp <= WPAD_EXP_CLASSIC)
{
WPAD_ScanPads(); WPAD_ScanPads();
p = WPAD_ButtonsDown(chan); p = WPAD_ButtonsDown(chan);
} }
else
{
WiiDRC_ScanPads();
p = WiiDRC_ButtonsDown();
}
}
/* detect pressed key */ /* detect pressed key */
switch (exp) switch (exp)
@ -683,9 +721,20 @@ static void wpad_config(u8 exp, int chan, int first_key, int last_key)
break; break;
} }
/* WiiU GamePad Controller */
default: 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; break;
} }
} }
@ -693,18 +742,29 @@ static void wpad_config(u8 exp, int chan, int first_key, int last_key)
/* update key mapping */ /* update key mapping */
if (first_key < MAX_KEYS) 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); while (first_key++ < last_key);
/* remove any pending buttons */ /* remove any pending buttons */
if (exp <= WPAD_EXP_CLASSIC)
{
while (WPAD_ButtonsHeld(chan)) while (WPAD_ButtonsHeld(chan))
{ {
VIDEO_WaitVSync(); VIDEO_WaitVSync();
WPAD_ScanPads(); WPAD_ScanPads();
} }
}
else
{
while (WiiDRC_ButtonsHeld())
{
VIDEO_WaitVSync();
WiiDRC_ScanPads();
}
}
/* re-enable background PAD scanning and exit */ /* re-enable background PAD scanning and exit */
inputs_disabled = 0; inputs_disabled = 0;
@ -715,21 +775,59 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
/* WPAD data */ /* WPAD data */
WPADData *data = WPAD_Data(chan); WPADData *data = WPAD_Data(chan);
/* WPAD status */ /* Button status */
u32 p = data->btns_h; u32 p = data->btns_h;
/* Analog sticks */ /* Analog sticks */
s8 x = 0; s16 x = 0;
s8 y = 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); x = wpad_StickX(data,0);
y = wpad_StickY(data,0); y = wpad_StickY(data,0);
} }
/* Retrieve current key mapping */ /* Retrieve current key mapping */
u32 *wpad_keymap = config.wpad_keymap[exp + (chan * 3)]; u32 *wpad_keymap = config.wpad_keymap[4*exp + chan];
/* Emulated device */ /* Emulated device */
switch (input.dev[i]) 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; input.analog[i][1] = y ? (127 - y) : 128;
/* Right Stick analog position [0-255] */ /* Right Stick analog position [0-255] */
if (exp == WPAD_EXP_CLASSIC) if (exp >= WPAD_EXP_CLASSIC)
{
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 */ /* Classic Controller right stick */
x = wpad_StickX(data,1); x = wpad_StickX(data,1);
y = wpad_StickY(data,1); y = wpad_StickY(data,1);
}
/* Emulated stick is unidirectional but can be rotated */ /* Emulated stick is unidirectional but can be rotated */
if (abs(x) > abs(y)) if (abs(x) > abs(y))
@ -867,7 +978,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
case DEVICE_LIGHTGUN: case DEVICE_LIGHTGUN:
{ {
/* Gun screen position (x,y) */ /* Gun screen position (x,y) */
if (exp != WPAD_EXP_CLASSIC) if (exp < WPAD_EXP_CLASSIC)
{ {
/* Wiimote IR */ /* Wiimote IR */
struct ir_t ir; struct ir_t ir;
@ -888,7 +999,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
} }
else else
{ {
/* Classic Controller analog stick */ /* Left analog stick */
input.analog[i][0] += x / ANALOG_SENSITIVITY; input.analog[i][0] += x / ANALOG_SENSITIVITY;
input.analog[i][1] -= y / 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 & 2) input.pad[i] |= INPUT_MOUSE_CENTER;
if (event.button & 4) input.pad[i] |= INPUT_MOUSE_LEFT; 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) */ /* Wiimote IR (buggy) */
struct ir_t ir; struct ir_t ir;
@ -942,7 +1053,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
} }
else 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][0] = (x / ANALOG_SENSITIVITY) * 2;
input.analog[i][1] = (y / 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; else if (p & PAD_BUTTON_RIGHT) input.pad[i] |= INPUT_RIGHT;
/* PEN screen position (x,y) */ /* PEN screen position (x,y) */
if (exp != WPAD_EXP_CLASSIC) if (exp < WPAD_EXP_CLASSIC)
{ {
/* Wiimote IR */ /* Wiimote IR */
struct ir_t ir; struct ir_t ir;
@ -984,7 +1095,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
} }
else else
{ {
/* Classic Controller analog stick */ /* Left analog stick */
input.analog[0][0] += x / ANALOG_SENSITIVITY; input.analog[0][0] += x / ANALOG_SENSITIVITY;
input.analog[0][1] -= y / 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: case DEVICE_TEREBI:
{ {
/* PEN screen position (x,y) */ /* PEN screen position (x,y) */
if (exp != WPAD_EXP_CLASSIC) if (exp < WPAD_EXP_CLASSIC)
{ {
/* Wiimote IR */ /* Wiimote IR */
struct ir_t ir; struct ir_t ir;
@ -1021,7 +1132,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
} }
else else
{ {
/* Classic Controller analog stick */ /* Left analog stick */
input.analog[0][0] += x / ANALOG_SENSITIVITY; input.analog[0][0] += x / ANALOG_SENSITIVITY;
input.analog[0][1] -= y / 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: case DEVICE_GRAPHIC_BOARD:
{ {
/* PEN screen position (x,y) */ /* PEN screen position (x,y) */
if (exp != WPAD_EXP_CLASSIC) if (exp < WPAD_EXP_CLASSIC)
{ {
/* Wiimote IR */ /* Wiimote IR */
struct ir_t ir; struct ir_t ir;
@ -1054,7 +1165,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp)
} }
else else
{ {
/* Classic Controller analog stick */ /* Left analog stick */
input.analog[0][0] += x / ANALOG_SENSITIVITY; input.analog[0][0] += x / ANALOG_SENSITIVITY;
input.analog[0][1] -= y / ANALOG_SENSITIVITY; input.analog[0][1] -= y / ANALOG_SENSITIVITY;
@ -1130,6 +1241,7 @@ void gx_input_Init(void)
WPAD_Init(); WPAD_Init();
WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR); WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR);
WPAD_SetVRes(WPAD_CHAN_ALL,640,480); WPAD_SetVRes(WPAD_CHAN_ALL,640,480);
WiiDRC_Init();
#endif #endif
} }
@ -1195,6 +1307,15 @@ int gx_input_FindDevices(void)
} }
break; break;
} }
case 4: /* WiiU GamePad Controller */
{
if (WiiDRC_Inited() && WiiDRC_Connected())
{
found++;
}
break;
}
#endif #endif
default: default:
@ -1236,34 +1357,44 @@ void gx_input_SetDefault(void)
for (i=0; i<4; i++) for (i=0; i<4; i++)
{ {
/* Wiimote (horizontal) */ /* Wiimote (horizontal) */
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONA] = WPAD_BUTTON_A; config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONA] = WPAD_BUTTON_A;
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONB] = WPAD_BUTTON_1; config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONB] = WPAD_BUTTON_1;
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONC] = WPAD_BUTTON_2; config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONC] = WPAD_BUTTON_2;
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_START] = WPAD_BUTTON_PLUS; config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_START] = WPAD_BUTTON_PLUS;
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONX] = 0; config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONX] = 0;
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONY] = 0; config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONY] = 0;
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONZ] = 0; config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONZ] = 0;
config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_MODE] = 0; config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_MODE] = 0;
/* Wiimote + Nunchuk */ /* Wiimote + Nunchuk */
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONA] = WPAD_NUNCHUK_BUTTON_Z; config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_BUTTONA] = WPAD_NUNCHUK_BUTTON_Z;
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONB] = WPAD_BUTTON_B; config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_BUTTONB] = WPAD_BUTTON_B;
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONC] = WPAD_BUTTON_A; config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_BUTTONC] = WPAD_BUTTON_A;
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_START] = WPAD_BUTTON_PLUS; config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_START] = WPAD_BUTTON_PLUS;
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONX] = WPAD_NUNCHUK_BUTTON_C; config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_BUTTONX] = WPAD_NUNCHUK_BUTTON_C;
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONY] = WPAD_BUTTON_1; config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_BUTTONY] = WPAD_BUTTON_1;
config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONZ] = WPAD_BUTTON_2; config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][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_MODE] = WPAD_BUTTON_MINUS;
/* Classic Controller */ /* Classic Controller */
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONA] = WPAD_CLASSIC_BUTTON_Y; config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_BUTTONA] = WPAD_CLASSIC_BUTTON_Y;
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONB] = WPAD_CLASSIC_BUTTON_B; config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_BUTTONB] = WPAD_CLASSIC_BUTTON_B;
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONC] = WPAD_CLASSIC_BUTTON_A; config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_BUTTONC] = WPAD_CLASSIC_BUTTON_A;
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_START] = WPAD_CLASSIC_BUTTON_PLUS; config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_START] = WPAD_CLASSIC_BUTTON_PLUS;
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONX] = WPAD_CLASSIC_BUTTON_ZL; config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_BUTTONX] = WPAD_CLASSIC_BUTTON_ZL;
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONY] = WPAD_CLASSIC_BUTTON_ZR; config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_BUTTONY] = WPAD_CLASSIC_BUTTON_ZR;
config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONZ] = WPAD_CLASSIC_BUTTON_X; config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][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_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 #endif
@ -1276,8 +1407,20 @@ void gx_input_SetDefault(void)
} }
#ifdef HW_RVL #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 */ /* autodetect connected Wii Controllers */
for (i=0; i<4; i++) while (i++ < 4)
{ {
exp = 255; exp = 255;
WPAD_Probe(i, &exp); WPAD_Probe(i, &exp);
@ -1596,12 +1739,35 @@ void gx_input_UpdateMenu(void)
else if (x < -ANALOG_SENSITIVITY) hp |= PAD_BUTTON_LEFT; 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_UP;
else if (y < -ANALOG_SENSITIVITY) hp |= PAD_BUTTON_DOWN; 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 #endif
/* check if any direction/selection key is being held or just being pressed/released */ /* check if any direction/selection key is being held or just being pressed/released */
#ifdef HW_RVL #ifdef HW_RVL
if (pp||pw) held_cnt = 0; if (pp||pw||pwu) held_cnt = 0;
else if (hp||hw) held_cnt++; else if (hp||hw||hwu) held_cnt++;
else held_cnt = 0; else held_cnt = 0;
#else #else
if (pp) held_cnt = 0; if (pp) held_cnt = 0;
@ -1616,6 +1782,7 @@ void gx_input_UpdateMenu(void)
pp |= hp; pp |= hp;
#ifdef HW_RVL #ifdef HW_RVL
pw |= hw; pw |= hw;
pwu |= hwu;
#endif #endif
/* delay until next triggering (adjusts direction/selection update speed) */ /* 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_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_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_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 #endif
/* Update menu inputs */ /* Update menu inputs */

View File

@ -3,7 +3,7 @@
* *
* Genesis Plus GX input support * 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 * Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met: * 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> #include <xtl.h>
#endif #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_3B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 0)
#define RETRO_DEVICE_MDPAD_6B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 1) #define RETRO_DEVICE_MDPAD_6B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 1)
#define RETRO_DEVICE_MSPAD_2B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 2) #define RETRO_DEVICE_MSPAD_2B RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 2)
@ -82,6 +76,25 @@
#include "sms_ntsc.h" #include "sms_ntsc.h"
#include <streams/file_stream.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; sms_ntsc_t *sms_ntsc;
md_ntsc_t *md_ntsc; md_ntsc_t *md_ntsc;
@ -541,7 +554,7 @@ static void config_default(void)
config.lock_on = 0; config.lock_on = 0;
config.lcd = 0; /* 0.8 fixed point */ config.lcd = 0; /* 0.8 fixed point */
#ifdef HAVE_OVERCLOCK #ifdef HAVE_OVERCLOCK
config.overclock = 0; config.overclock = 100;
#endif #endif
config.no_sprite_limit = 0; config.no_sprite_limit = 0;
@ -812,6 +825,31 @@ static bool update_viewport(void)
return ((ow != vwidth) || (oh != vheight) || (oar != vaspect_ratio)); 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) static void check_variables(void)
{ {
unsigned orig_value; unsigned orig_value;
@ -1124,12 +1162,25 @@ static void check_variables(void)
environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var);
{ {
orig_value = config.ym3438; orig_value = config.ym3438;
if (!strcmp(var.value, "nuked opn2")) if (!strcmp(var.value, "nuked (ym2612)"))
{
OPN2_SetChipType(ym3438_type_ym2612);
config.ym3438 = 1; 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 else
config.ym3438 = 0; config.ym3438 = 0;
if (orig_value != config.ym3438) if (orig_value == 0 && config.ym3438 > 0 || orig_value > 0 && config.ym3438 == 0)
{ {
sound_init(); sound_init();
sound_reset(); sound_reset();
@ -1258,17 +1309,19 @@ static void check_variables(void)
var.key = "genesis_plus_gx_overclock"; var.key = "genesis_plus_gx_overclock";
environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var); environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var);
{ {
/* Cycle ratios multiply cycle count, so use reciprocal */
if (strcmp(var.value, "100%") == 0) if (strcmp(var.value, "100%") == 0)
config.overclock = (100 << CYCLE_SHIFT)/100; config.overclock = 100;
else if (strcmp(var.value, "125%") == 0) else if (strcmp(var.value, "125%") == 0)
config.overclock = (100 << CYCLE_SHIFT)/125; config.overclock = 125;
else if (strcmp(var.value, "150%") == 0) else if (strcmp(var.value, "150%") == 0)
config.overclock = (100 << CYCLE_SHIFT)/150; config.overclock = 150;
else if (strcmp(var.value, "175%") == 0) else if (strcmp(var.value, "175%") == 0)
config.overclock = (100 << CYCLE_SHIFT)/175; config.overclock = 175;
else if (strcmp(var.value, "200%") == 0) else if (strcmp(var.value, "200%") == 0)
config.overclock = (100 << CYCLE_SHIFT)/200; config.overclock = 200;
if (system_hw)
update_overclock();
} }
#endif #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_ym2413", "Master System FM; auto|disabled|enabled" },
{ "genesis_plus_gx_dac_bits", "YM2612 DAC quantization; disabled|enabled" }, { "genesis_plus_gx_dac_bits", "YM2612 DAC quantization; disabled|enabled" },
#ifdef HAVE_YM3438_CORE #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 #endif
{ "genesis_plus_gx_audio_filter", "Audio filter; disabled|low-pass" },
{ "genesis_plus_gx_sound_output", "Sound output; stereo|mono" }, { "genesis_plus_gx_sound_output", "Sound output; stereo|mono" },
{ "genesis_plus_gx_audio_filter", "Audio filter; disabled|low-pass" },
{ "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"}, { "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 #if HAVE_EQ
@ -2074,6 +2127,7 @@ bool retro_unserialize(const void *data, size_t size)
#ifdef HAVE_OVERCLOCK #ifdef HAVE_OVERCLOCK
overclock_delay = OVERCLOCK_FRAME_DELAY; overclock_delay = OVERCLOCK_FRAME_DELAY;
update_overclock();
#endif #endif
return TRUE; 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); audio_init(SOUND_FREQUENCY, 0);
system_init(); system_init();
system_reset(); system_reset();
@ -2253,6 +2304,11 @@ bool retro_load_game(const struct retro_game_info *info)
update_viewport(); update_viewport();
#ifdef HAVE_OVERCLOCK
overclock_delay = OVERCLOCK_FRAME_DELAY;
update_overclock();
#endif
return true; return true;
} }
@ -2360,6 +2416,7 @@ void retro_reset(void)
{ {
#ifdef HAVE_OVERCLOCK #ifdef HAVE_OVERCLOCK
overclock_delay = OVERCLOCK_FRAME_DELAY; overclock_delay = OVERCLOCK_FRAME_DELAY;
update_overclock();
#endif #endif
gen_reset(0); gen_reset(0);
} }
@ -2371,38 +2428,20 @@ void retro_run(void)
#ifdef HAVE_OVERCLOCK #ifdef HAVE_OVERCLOCK
/* update overclock delay */ /* update overclock delay */
if (overclock_delay) if (overclock_delay && --overclock_delay == 0)
overclock_delay--; update_overclock();
#endif #endif
if (system_hw == SYSTEM_MCD) 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); system_frame_scd(0);
} }
else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) 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); system_frame_gen(0);
} }
else 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); system_frame_sms(0);
} }