2006-07-18 02:53:36 +00:00
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file :
* Copyright ( C ) 2002 Xodnizel
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
// For commctrl.h below
# define _WIN32_IE 0x0300
# include "common.h"
# include <dinput.h>
# include <windows.h>
# include <commctrl.h>
# include "input.h"
# include "keyboard.h"
# include "joystick.h"
2006-07-18 06:35:48 +00:00
# include "../../fceu.h" //mbg merge 7/17/06 added
2006-07-18 02:53:36 +00:00
# include "keyscan.h"
LPDIRECTINPUT7 lpDI = 0 ;
/* UsrInputType[] is user-specified. InputType[] is current
( game loading can override user settings )
*/
int UsrInputType [ 3 ] = { SI_GAMEPAD , SI_GAMEPAD , SIFC_NONE } ;
int InputType [ 3 ] = { 0 , 0 , 0 } ;
int cspec = 0 ;
int gametype = 0 ;
int InitDInput ( void )
{
HRESULT ddrval ;
2006-07-18 06:35:48 +00:00
//mbg merge 7/17/06 changed:
//ddrval=DirectInputCreateEx(fceu_hInstance,DIRECTINPUT_VERSION,&IID_IDirectInput7,(LPVOID *)&lpDI,0);
ddrval = DirectInputCreateEx ( fceu_hInstance , DIRECTINPUT_VERSION , IID_IDirectInput7 , ( LPVOID * ) & lpDI , 0 ) ;
2006-07-18 02:53:36 +00:00
if ( ddrval ! = DI_OK )
{
FCEUD_PrintError ( " DirectInput: Error creating DirectInput object. " ) ;
return 0 ;
}
return 1 ;
}
static uint32 MouseData [ 3 ] ;
static int screenmode = 0 ;
void InputScreenChanged ( int fs )
{
int x ;
if ( GI )
{
for ( x = 0 ; x < 2 ; x + + )
if ( InputType [ x ] = = SI_ZAPPER )
FCEUI_SetInput ( x , SI_ZAPPER , MouseData , fs ) ;
if ( InputType [ 2 ] = = SIFC_SHADOW )
FCEUI_SetInputFC ( SIFC_SHADOW , MouseData , fs ) ;
}
screenmode = fs ;
}
/* Necessary for proper GUI functioning(configuring when a game isn't loaded). */
void InputUserActiveFix ( void )
{
int x ;
for ( x = 0 ; x < 3 ; x + + ) InputType [ x ] = UsrInputType [ x ] ;
}
void ParseGIInput ( FCEUGI * gi )
{
InputType [ 0 ] = UsrInputType [ 0 ] ;
InputType [ 1 ] = UsrInputType [ 1 ] ;
InputType [ 2 ] = UsrInputType [ 2 ] ;
if ( gi )
{
if ( gi - > input [ 0 ] > = 0 )
InputType [ 0 ] = gi - > input [ 0 ] ;
if ( gi - > input [ 1 ] > = 0 )
InputType [ 1 ] = gi - > input [ 1 ] ;
if ( gi - > inputfc > = 0 )
InputType [ 2 ] = gi - > inputfc ;
cspec = gi - > cspecial ;
gametype = gi - > type ;
InitOtherInput ( ) ;
}
else cspec = gametype = 0 ;
}
static uint8 QuizKingData = 0 ;
static uint8 HyperShotData = 0 ;
static uint32 MahjongData = 0 ;
static uint32 FTrainerData = 0 ;
static uint8 TopRiderData = 0 ;
static uint8 BWorldData [ 1 + 13 + 1 ] ;
static void UpdateFKB ( void ) ;
static void UpdateSuborKB ( void ) ;
void UpdateGamepad ( void ) ;
static void UpdateQuizKing ( void ) ;
static void UpdateHyperShot ( void ) ;
static void UpdateMahjong ( void ) ;
static void UpdateFTrainer ( void ) ;
static void UpdateTopRider ( void ) ;
static uint32 JSreturn = 0 ;
int NoWaiting = 0 ;
# include "keyscan.h"
static unsigned char * keys = 0 ;
static unsigned char * keys_nr = 0 ;
static int DIPS = 0 ;
static uint8 keyonce [ MKK_COUNT ] ;
//#define KEY(__a) keys_nr[MKK(__a)]
static int _keyonly ( int a )
{
if ( keys_nr [ a ] )
{
if ( ! keyonce [ a ] )
{
keyonce [ a ] = 1 ;
return ( 1 ) ;
}
}
else
keyonce [ a ] = 0 ;
return ( 0 ) ;
}
int cidisabled = 0 ;
# define MK(x) {{BUTTC_KEYBOARD},{0},{MKK(x)},1}
# define MC(x) {{BUTTC_KEYBOARD},{0},{x},1}
# define MK2(x1,x2) {{BUTTC_KEYBOARD},{0},{MKK(x1),MKK(x2)},2}
# define MKZ() {{0},{0},{0},0}
# define GPZ() {MKZ(), MKZ(), MKZ(), MKZ()}
ButtConfig GamePadConfig [ 4 ] [ 10 ] = {
/* Gamepad 1 */
{
MK ( LEFTALT ) , MK ( LEFTCONTROL ) , MK ( TAB ) , MK ( ENTER ) , MK ( BL_CURSORUP ) ,
MK ( BL_CURSORDOWN ) , MK ( BL_CURSORLEFT ) , MK ( BL_CURSORRIGHT )
} ,
/* Gamepad 2 */
GPZ ( ) ,
/* Gamepad 3 */
GPZ ( ) ,
/* Gamepad 4 */
GPZ ( )
} ;
extern int rapidAlternator ; // for auto-fire / autofire
int DesynchAutoFire = 0 ; // A and B not at same time
uint32 JSAutoHeld = 0 , JSAutoHeldAffected = 0 ; // for auto-hold
uint8 autoHoldOn = 0 , autoHoldReset = 0 , autoHoldRefire = 0 ; // for auto-hold
void SetAutoFireDesynch ( int DesynchOn )
{
if ( DesynchOn )
{
DesynchAutoFire = 1 ;
}
else
{
DesynchAutoFire = 0 ;
}
}
int GetAutoFireDesynch ( )
{
return DesynchAutoFire ;
}
2006-07-18 06:35:48 +00:00
int DTestButton ( ButtConfig * bc )
{
uint32 x ; //mbg merge 7/17/06 changed to uint
for ( x = 0 ; x < bc - > NumC ; x + + )
{
if ( bc - > ButtType [ x ] = = BUTTC_KEYBOARD )
{
if ( keys_nr [ bc - > ButtonNum [ x ] ] )
{
return ( 1 ) ;
}
}
}
if ( DTestButtonJoy ( bc ) ) return ( 1 ) ;
return ( 0 ) ;
}
2006-07-18 02:53:36 +00:00
void UpdateGamepad ( )
{
if ( FCEUI_IsMovieActive ( ) < 0 )
return ;
uint32 JS = 0 ;
int x ;
int wg ;
if ( FCEUI_IsMovieActive ( ) > 0 )
AutoFire ( ) ;
for ( wg = 0 ; wg < 4 ; wg + + )
{
for ( x = 0 ; x < 8 ; x + + )
if ( DTestButton ( & GamePadConfig [ wg ] [ x ] ) )
JS | = ( 1 < < x ) < < ( wg < < 3 ) ;
// if(rapidAlternator)
for ( x = 0 ; x < 2 ; x + + )
if ( DTestButton ( & GamePadConfig [ wg ] [ 8 + x ] ) )
JS | = ( ( 1 < < x ) < < ( wg < < 3 ) ) * ( rapidAlternator ^ ( x * DesynchAutoFire ) ) ;
}
if ( autoHoldOn )
{
if ( autoHoldRefire )
{
autoHoldRefire - - ;
if ( ! autoHoldRefire )
JSAutoHeldAffected = 0 ;
}
for ( wg = 0 ; wg < 4 ; wg + + )
for ( x = 0 ; x < 8 ; x + + )
if ( DTestButton ( & GamePadConfig [ wg ] [ x ] ) )
{
if ( ! autoHoldRefire | | ! ( JSAutoHeldAffected & ( 1 < < x ) < < ( wg < < 3 ) ) )
{
JSAutoHeld ^ = ( 1 < < x ) < < ( wg < < 3 ) ;
JSAutoHeldAffected | = ( 1 < < x ) < < ( wg < < 3 ) ;
autoHoldRefire = 192 ;
}
}
char inputstr [ 32 ] ;
{
uint32 c = JSAutoHeld ;
sprintf ( inputstr , " %c%c%c%c%c%c%c%c %c%c%c%c%c%c%c%c " ,
( c & 0x40 ) ? ' < ' : ' ' , ( c & 0x10 ) ? ' ^ ' : ' ' , ( c & 0x80 ) ? ' > ' : ' ' , ( c & 0x20 ) ? ' v ' : ' ' ,
( c & 0x01 ) ? ' A ' : ' ' , ( c & 0x02 ) ? ' B ' : ' ' , ( c & 0x08 ) ? ' S ' : ' ' , ( c & 0x04 ) ? ' s ' : ' ' ,
( c & 0x4000 ) ? ' < ' : ' ' , ( c & 0x1000 ) ? ' ^ ' : ' ' , ( c & 0x8000 ) ? ' > ' : ' ' , ( c & 0x2000 ) ? ' v ' : ' ' ,
( c & 0x0100 ) ? ' A ' : ' ' , ( c & 0x0200 ) ? ' B ' : ' ' , ( c & 0x0800 ) ? ' S ' : ' ' , ( c & 0x0400 ) ? ' s ' : ' ' ) ;
if ( ! ( c & 0xff00 ) )
inputstr [ 8 ] = ' \0 ' ;
}
FCEU_DispMessage ( " Held: %s " , inputstr ) ;
}
else
{
JSAutoHeldAffected = 0 ;
autoHoldRefire = 0 ;
}
if ( autoHoldReset )
{
FCEU_DispMessage ( " Held: " ) ;
JSAutoHeld = 0 ;
JSAutoHeldAffected = 0 ;
autoHoldRefire = 0 ;
}
// apply auto-hold
if ( JSAutoHeld )
JS ^ = JSAutoHeld ;
JSreturn = JS ;
}
ButtConfig powerpadsc [ 2 ] [ 12 ] = {
{
MK ( O ) , MK ( P ) , MK ( BRACKET_LEFT ) ,
MK ( BRACKET_RIGHT ) ,
MK ( K ) , MK ( L ) , MK ( SEMICOLON ) ,
MK ( APOSTROPHE ) ,
MK ( M ) , MK ( COMMA ) , MK ( PERIOD ) , MK ( SLASH )
} ,
{
MK ( O ) , MK ( P ) , MK ( BRACKET_LEFT ) ,
MK ( BRACKET_RIGHT ) , MK ( K ) , MK ( L ) , MK ( SEMICOLON ) ,
MK ( APOSTROPHE ) ,
MK ( M ) , MK ( COMMA ) , MK ( PERIOD ) , MK ( SLASH )
}
} ;
static uint32 powerpadbuf [ 2 ] ;
static uint32 UpdatePPadData ( int w )
{
uint32 r = 0 ;
ButtConfig * ppadtsc = powerpadsc [ w ] ;
int x ;
for ( x = 0 ; x < 12 ; x + + )
if ( DTestButton ( & ppadtsc [ x ] ) ) r | = 1 < < x ;
return r ;
}
static uint8 fkbkeys [ 0x48 ] ;
static uint8 suborkbkeys [ 0x60 ] ;
2006-07-18 06:35:48 +00:00
void KeyboardUpdateState ( void ) ; //mbg merge 7/17/06 yech had to add this
void GetMouseData ( uint32 * md ) ; //mbg merge 7/17/06 yech had to add this
2006-07-18 02:53:36 +00:00
void FCEUD_UpdateInput ( )
{
int x ;
int t = 0 ;
KeyboardUpdateState ( ) ;
UpdateJoysticks ( ) ;
//UpdatePhysicalInput();
//KeyboardCommands();
FCEUI_HandleEmuCommands ( FCEUD_TestCommandState ) ;
{
for ( x = 0 ; x < 2 ; x + + )
switch ( InputType [ x ] )
{
case SI_GAMEPAD : t | = 1 ; break ;
case SI_ARKANOID : t | = 2 ; break ;
case SI_ZAPPER : t | = 2 ; break ;
case SI_POWERPADA :
case SI_POWERPADB : powerpadbuf [ x ] = UpdatePPadData ( x ) ; break ;
}
switch ( InputType [ 2 ] )
{
case SIFC_ARKANOID : t | = 2 ; break ;
case SIFC_SHADOW : t | = 2 ; break ;
case SIFC_FKB : if ( cidisabled ) UpdateFKB ( ) ; break ;
case SIFC_SUBORKB : if ( cidisabled ) UpdateSuborKB ( ) ; break ;
case SIFC_HYPERSHOT : UpdateHyperShot ( ) ; break ;
case SIFC_MAHJONG : UpdateMahjong ( ) ; break ;
case SIFC_QUIZKING : UpdateQuizKing ( ) ; break ;
case SIFC_FTRAINERB :
case SIFC_FTRAINERA : UpdateFTrainer ( ) ; break ;
case SIFC_TOPRIDER : UpdateTopRider ( ) ; break ;
case SIFC_OEKAKIDS : t | = 2 ; break ;
}
if ( t & 1 )
UpdateGamepad ( ) ;
if ( t & 2 )
GetMouseData ( MouseData ) ;
}
}
void InitOtherInput ( void )
{
void * InputDPtr ;
int t ;
int x ;
int attrib ;
for ( t = 0 , x = 0 ; x < 2 ; x + + )
{
attrib = 0 ;
InputDPtr = 0 ;
switch ( InputType [ x ] )
{
case SI_POWERPADA :
case SI_POWERPADB : InputDPtr = & powerpadbuf [ x ] ; break ;
case SI_GAMEPAD : InputDPtr = & JSreturn ; break ;
case SI_ARKANOID : InputDPtr = MouseData ; t | = 1 ; break ;
case SI_ZAPPER : InputDPtr = MouseData ;
t | = 1 ;
attrib = screenmode ;
break ;
}
FCEUI_SetInput ( x , InputType [ x ] , InputDPtr , attrib ) ;
}
attrib = 0 ;
InputDPtr = 0 ;
switch ( InputType [ 2 ] )
{
case SIFC_SHADOW : InputDPtr = MouseData ; t | = 1 ; attrib = screenmode ; break ;
case SIFC_OEKAKIDS : InputDPtr = MouseData ; t | = 1 ; attrib = screenmode ; break ;
case SIFC_ARKANOID : InputDPtr = MouseData ; t | = 1 ; break ;
case SIFC_FKB : InputDPtr = fkbkeys ; break ;
case SIFC_SUBORKB : InputDPtr = suborkbkeys ; break ;
case SIFC_HYPERSHOT : InputDPtr = & HyperShotData ; break ;
case SIFC_MAHJONG : InputDPtr = & MahjongData ; break ;
case SIFC_QUIZKING : InputDPtr = & QuizKingData ; break ;
case SIFC_TOPRIDER : InputDPtr = & TopRiderData ; break ;
case SIFC_BWORLD : InputDPtr = BWorldData ; break ;
case SIFC_FTRAINERA :
case SIFC_FTRAINERB : InputDPtr = & FTrainerData ; break ;
}
FCEUI_SetInputFC ( InputType [ 2 ] , InputDPtr , attrib ) ;
FCEUI_DisableFourScore ( eoptions & EO_NOFOURSCORE ) ;
}
ButtConfig fkbmap [ 0x48 ] =
{
MK ( F1 ) , MK ( F2 ) , MK ( F3 ) , MK ( F4 ) , MK ( F5 ) , MK ( F6 ) , MK ( F7 ) , MK ( F8 ) ,
MK ( 1 ) , MK ( 2 ) , MK ( 3 ) , MK ( 4 ) , MK ( 5 ) , MK ( 6 ) , MK ( 7 ) , MK ( 8 ) , MK ( 9 ) , MK ( 0 ) ,
MK ( MINUS ) , MK ( EQUAL ) , MK ( BACKSLASH ) , MK ( BACKSPACE ) ,
MK ( ESCAPE ) , MK ( Q ) , MK ( W ) , MK ( E ) , MK ( R ) , MK ( T ) , MK ( Y ) , MK ( U ) , MK ( I ) , MK ( O ) ,
MK ( P ) , MK ( GRAVE ) , MK ( BRACKET_LEFT ) , MK ( ENTER ) ,
MK ( LEFTCONTROL ) , MK ( A ) , MK ( S ) , MK ( D ) , MK ( F ) , MK ( G ) , MK ( H ) , MK ( J ) , MK ( K ) ,
MK ( L ) , MK ( SEMICOLON ) , MK ( APOSTROPHE ) , MK ( BRACKET_RIGHT ) , MK ( INSERT ) ,
MK ( LEFTSHIFT ) , MK ( Z ) , MK ( X ) , MK ( C ) , MK ( V ) , MK ( B ) , MK ( N ) , MK ( M ) , MK ( COMMA ) ,
MK ( PERIOD ) , MK ( SLASH ) , MK ( RIGHTALT ) , MK ( RIGHTSHIFT ) , MK ( LEFTALT ) , MK ( SPACE ) ,
MK ( BL_DELETE ) ,
MK ( BL_END ) ,
MK ( BL_PAGEDOWN ) ,
MK ( BL_CURSORUP ) , MK ( BL_CURSORLEFT ) , MK ( BL_CURSORRIGHT ) , MK ( BL_CURSORDOWN )
} ;
ButtConfig suborkbmap [ 0x60 ] =
{
MC ( 0x01 ) , MC ( 0x3b ) , MC ( 0x3c ) , MC ( 0x3d ) , MC ( 0x3e ) , MC ( 0x3f ) , MC ( 0x40 ) , MC ( 0x41 ) , MC ( 0x42 ) , MC ( 0x43 ) ,
MC ( 0x44 ) , MC ( 0x57 ) , MC ( 0x58 ) , MC ( 0x45 ) , MC ( 0x29 ) , MC ( 0x02 ) , MC ( 0x03 ) , MC ( 0x04 ) , MC ( 0x05 ) , MC ( 0x06 ) ,
MC ( 0x07 ) , MC ( 0x08 ) , MC ( 0x09 ) , MC ( 0x0a ) , MC ( 0x0b ) , MC ( 0x0c ) , MC ( 0x0d ) , MC ( 0x0e ) , MC ( 0xd2 ) , MC ( 0xc7 ) ,
MC ( 0xc9 ) , MC ( 0xc5 ) , MC ( 0xb5 ) , MC ( 0x37 ) , MC ( 0x4a ) , MC ( 0x0f ) , MC ( 0x10 ) , MC ( 0x11 ) , MC ( 0x12 ) , MC ( 0x13 ) ,
MC ( 0x14 ) , MC ( 0x15 ) , MC ( 0x16 ) , MC ( 0x17 ) , MC ( 0x18 ) , MC ( 0x19 ) , MC ( 0x1a ) , MC ( 0x1b ) , MC ( 0x1c ) , MC ( 0xd3 ) ,
MC ( 0xca ) , MC ( 0xd1 ) , MC ( 0x47 ) , MC ( 0x48 ) , MC ( 0x49 ) , MC ( 0x4e ) , MC ( 0x3a ) , MC ( 0x1e ) , MC ( 0x1f ) , MC ( 0x20 ) ,
MC ( 0x21 ) , MC ( 0x22 ) , MC ( 0x23 ) , MC ( 0x24 ) , MC ( 0x25 ) , MC ( 0x26 ) , MC ( 0x27 ) , MC ( 0x28 ) , MC ( 0x4b ) , MC ( 0x4c ) ,
MC ( 0x4d ) , MC ( 0x2a ) , MC ( 0x2c ) , MC ( 0x2d ) , MC ( 0x2e ) , MC ( 0x2f ) , MC ( 0x30 ) , MC ( 0x31 ) , MC ( 0x32 ) , MC ( 0x33 ) ,
MC ( 0x34 ) , MC ( 0x35 ) , MC ( 0x2b ) , MC ( 0xc8 ) , MC ( 0x4f ) , MC ( 0x50 ) , MC ( 0x51 ) , MC ( 0x1d ) , MC ( 0x38 ) , MC ( 0x39 ) ,
MC ( 0xcb ) , MC ( 0xd0 ) , MC ( 0xcd ) , MC ( 0x52 ) , MC ( 0x53 )
} ;
static void UpdateFKB ( void )
{
int x ;
for ( x = 0 ; x < 0x48 ; x + + )
{
fkbkeys [ x ] = 0 ;
if ( DTestButton ( & fkbmap [ x ] ) )
fkbkeys [ x ] = 1 ;
}
}
static void UpdateSuborKB ( void )
{
int x ;
for ( x = 0 ; x < 0x60 ; x + + )
{
suborkbkeys [ x ] = 0 ;
if ( DTestButton ( & suborkbmap [ x ] ) )
suborkbkeys [ x ] = 1 ;
}
}
static ButtConfig HyperShotButtons [ 4 ] =
{
MK ( Q ) , MK ( W ) , MK ( E ) , MK ( R )
} ;
static void UpdateHyperShot ( void )
{
int x ;
HyperShotData = 0 ;
for ( x = 0 ; x < 0x4 ; x + + )
{
if ( DTestButton ( & HyperShotButtons [ x ] ) )
HyperShotData | = 1 < < x ;
}
}
static ButtConfig MahjongButtons [ 21 ] =
{
MK ( Q ) , MK ( W ) , MK ( E ) , MK ( R ) , MK ( T ) ,
MK ( A ) , MK ( S ) , MK ( D ) , MK ( F ) , MK ( G ) , MK ( H ) , MK ( J ) , MK ( K ) , MK ( L ) ,
MK ( Z ) , MK ( X ) , MK ( C ) , MK ( V ) , MK ( B ) , MK ( N ) , MK ( M )
} ;
static void UpdateMahjong ( void )
{
int x ;
MahjongData = 0 ;
for ( x = 0 ; x < 21 ; x + + )
{
if ( DTestButton ( & MahjongButtons [ x ] ) )
MahjongData | = 1 < < x ;
}
}
ButtConfig QuizKingButtons [ 6 ] =
{
MK ( Q ) , MK ( W ) , MK ( E ) , MK ( R ) , MK ( T ) , MK ( Y )
} ;
static void UpdateQuizKing ( void )
{
int x ;
QuizKingData = 0 ;
for ( x = 0 ; x < 6 ; x + + )
{
if ( DTestButton ( & QuizKingButtons [ x ] ) )
QuizKingData | = 1 < < x ;
}
}
ButtConfig TopRiderButtons [ 8 ] =
{
MK ( Q ) , MK ( W ) , MK ( E ) , MK ( R ) , MK ( T ) , MK ( Y ) , MK ( U ) , MK ( I )
} ;
static void UpdateTopRider ( void )
{
int x ;
TopRiderData = 0 ;
for ( x = 0 ; x < 8 ; x + + )
if ( DTestButton ( & TopRiderButtons [ x ] ) )
TopRiderData | = 1 < < x ;
}
ButtConfig FTrainerButtons [ 12 ] =
{
MK ( O ) , MK ( P ) , MK ( BRACKET_LEFT ) ,
MK ( BRACKET_RIGHT ) , MK ( K ) , MK ( L ) , MK ( SEMICOLON ) ,
MK ( APOSTROPHE ) ,
MK ( M ) , MK ( COMMA ) , MK ( PERIOD ) , MK ( SLASH )
} ;
static void UpdateFTrainer ( void )
{
int x ;
FTrainerData = 0 ;
for ( x = 0 ; x < 12 ; x + + )
{
if ( DTestButton ( & FTrainerButtons [ x ] ) )
FTrainerData | = 1 < < x ;
}
}
int DWaitButton ( HWND hParent , const uint8 * text , ButtConfig * bc ) ;
int DWaitSimpleButton ( HWND hParent , const uint8 * text ) ;
CFGSTRUCT InputConfig [ ] = {
ACA ( UsrInputType ) ,
AC ( powerpadsc ) ,
AC ( QuizKingButtons ) ,
AC ( FTrainerButtons ) ,
AC ( HyperShotButtons ) ,
AC ( MahjongButtons ) ,
AC ( GamePadConfig ) ,
AC ( fkbmap ) ,
AC ( suborkbmap ) ,
ENDCFGSTRUCT
} ;
void InitInputStuff ( void )
{
int x , y ;
KeyboardInitialize ( ) ;
InitJoysticks ( hAppWnd ) ;
for ( x = 0 ; x < 4 ; x + + )
for ( y = 0 ; y < 10 ; y + + )
JoyClearBC ( & GamePadConfig [ x ] [ y ] ) ;
for ( x = 0 ; x < 2 ; x + + )
for ( y = 0 ; y < 12 ; y + + )
JoyClearBC ( & powerpadsc [ x ] [ y ] ) ;
for ( x = 0 ; x < 0x48 ; x + + )
JoyClearBC ( & fkbmap [ x ] ) ;
for ( x = 0 ; x < 0x60 ; x + + )
JoyClearBC ( & suborkbmap [ x ] ) ;
for ( x = 0 ; x < 6 ; x + + )
JoyClearBC ( & QuizKingButtons [ x ] ) ;
for ( x = 0 ; x < 12 ; x + + )
JoyClearBC ( & FTrainerButtons [ x ] ) ;
for ( x = 0 ; x < 21 ; x + + )
JoyClearBC ( & MahjongButtons [ x ] ) ;
for ( x = 0 ; x < 4 ; x + + )
JoyClearBC ( & HyperShotButtons [ x ] ) ;
}
static void FCExp ( char * text )
{
static char * fccortab [ 12 ] = { " none " , " arkanoid " , " shadow " , " 4player " , " fkb " , " suborkb " ,
" hypershot " , " mahjong " , " quizking " , " ftrainera " , " ftrainerb " , " oekakids " } ;
static int fccortabi [ 12 ] = { SIFC_NONE , SIFC_ARKANOID , SIFC_SHADOW ,
SIFC_4PLAYER , SIFC_FKB , SIFC_SUBORKB , SIFC_HYPERSHOT , SIFC_MAHJONG , SIFC_QUIZKING ,
SIFC_FTRAINERA , SIFC_FTRAINERB , SIFC_OEKAKIDS } ;
int y ;
for ( y = 0 ; y < 12 ; y + + )
if ( ! strcmp ( fccortab [ y ] , text ) )
UsrInputType [ 2 ] = fccortabi [ y ] ;
}
static char * cortab [ 6 ] = { " none " , " gamepad " , " zapper " , " powerpada " , " powerpadb " , " arkanoid " } ;
static int cortabi [ 6 ] = { SI_NONE , SI_GAMEPAD ,
SI_ZAPPER , SI_POWERPADA , SI_POWERPADB , SI_ARKANOID } ;
static void Input1 ( char * text )
{
int y ;
for ( y = 0 ; y < 6 ; y + + )
if ( ! strcmp ( cortab [ y ] , text ) )
UsrInputType [ 0 ] = cortabi [ y ] ;
}
static void Input2 ( char * text )
{
int y ;
for ( y = 0 ; y < 6 ; y + + )
if ( ! strcmp ( cortab [ y ] , text ) )
UsrInputType [ 1 ] = cortabi [ y ] ;
}
ARGPSTRUCT InputArgs [ ] = {
{ " -fcexp " , 0 , ( void * ) FCExp , 0x2000 } ,
{ " -input1 " , 0 , ( void * ) Input1 , 0x2000 } ,
{ " -input2 " , 0 , ( void * ) Input2 , 0x2000 } ,
{ 0 , 0 , 0 , 0 }
} ;
static char * MakeButtString ( ButtConfig * bc )
{
2006-07-18 06:35:48 +00:00
uint32 x ; //mbg merge 7/17/06 changed to uint
2006-07-18 02:53:36 +00:00
char tmpstr [ 512 ] ;
char * astr ;
tmpstr [ 0 ] = 0 ;
for ( x = 0 ; x < bc - > NumC ; x + + )
{
if ( x ) strcat ( tmpstr , " , " ) ;
if ( bc - > ButtType [ x ] = = BUTTC_KEYBOARD )
{
strcat ( tmpstr , " KB: " ) ;
if ( ! GetKeyNameText ( bc - > ButtonNum [ x ] < < 16 , tmpstr + strlen ( tmpstr ) , 16 ) )
{
switch ( bc - > ButtonNum [ x ] )
{
case 200 : strcpy ( tmpstr + strlen ( tmpstr ) , " Up Arrow " ) ; break ;
case 203 : strcpy ( tmpstr + strlen ( tmpstr ) , " Left Arrow " ) ; break ;
case 205 : strcpy ( tmpstr + strlen ( tmpstr ) , " Right Arrow " ) ; break ;
case 208 : strcpy ( tmpstr + strlen ( tmpstr ) , " Down Arrow " ) ; break ;
default : sprintf ( tmpstr + strlen ( tmpstr ) , " %03d " , bc - > ButtonNum [ x ] ) ; break ;
}
}
}
else if ( bc - > ButtType [ x ] = = BUTTC_JOYSTICK )
{
strcat ( tmpstr , " JS " ) ;
sprintf ( tmpstr + strlen ( tmpstr ) , " %d " , bc - > DeviceNum [ x ] ) ;
if ( bc - > ButtonNum [ x ] & 0x8000 )
{
char * asel [ 3 ] = { " x " , " y " , " z " } ;
sprintf ( tmpstr + strlen ( tmpstr ) , " axis %s%s " , asel [ bc - > ButtonNum [ x ] & 3 ] , ( bc - > ButtonNum [ x ] & 0x4000 ) ? " - " : " + " ) ;
}
else if ( bc - > ButtonNum [ x ] & 0x2000 )
{
sprintf ( tmpstr + strlen ( tmpstr ) , " hat %d:%d " , ( bc - > ButtonNum [ x ] > > 4 ) & 3 ,
bc - > ButtonNum [ x ] & 3 ) ;
}
else
{
sprintf ( tmpstr + strlen ( tmpstr ) , " button %d " , bc - > ButtonNum [ x ] & 127 ) ;
}
}
}
2006-07-18 06:35:48 +00:00
astr = ( char * ) malloc ( strlen ( tmpstr ) + 1 ) ; //mbg merge 7/17/06 added cast
2006-07-18 02:53:36 +00:00
strcpy ( astr , tmpstr ) ;
return ( astr ) ;
}
static int DWBStarted ;
static ButtConfig * DWBButtons ;
static const uint8 * DWBText ;
static HWND die ;
static BOOL CALLBACK DWBCallB ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
switch ( uMsg ) {
case WM_DESTROY :
die = NULL ;
return ( 0 ) ;
case WM_TIMER :
{
uint8 devicenum ;
uint16 buttonnum ;
GUID guid ;
if ( DoJoyWaitTest ( & guid , & devicenum , & buttonnum ) )
{
ButtConfig * bc = DWBButtons ;
char * nstr ;
int wc ;
if ( DWBStarted )
{
ButtConfig * bc = DWBButtons ;
bc - > NumC = 0 ;
DWBStarted = 0 ;
}
wc = bc - > NumC ;
//FCEU_printf("%d: %d\n",devicenum,buttonnum);
bc - > ButtType [ wc ] = BUTTC_JOYSTICK ;
bc - > DeviceNum [ wc ] = devicenum ;
bc - > ButtonNum [ wc ] = buttonnum ;
bc - > DeviceInstance [ wc ] = guid ;
/* Stop config if the user pushes the same button twice in a row. */
if ( wc & & bc - > ButtType [ wc ] = = bc - > ButtType [ wc - 1 ] & & bc - > DeviceNum [ wc ] = = bc - > DeviceNum [ wc - 1 ] & &
bc - > ButtonNum [ wc ] = = bc - > ButtonNum [ wc - 1 ] )
goto gornk ;
bc - > NumC + + ;
/* Stop config if we reached our maximum button limit. */
if ( bc - > NumC > = MAXBUTTCONFIG )
goto gornk ;
nstr = MakeButtString ( bc ) ;
SetDlgItemText ( hwndDlg , 100 , nstr ) ;
free ( nstr ) ;
}
}
break ;
case WM_USER + 666 :
//SetFocus(GetDlgItem(hwndDlg,100));
if ( DWBStarted )
{
char * nstr ;
ButtConfig * bc = DWBButtons ;
bc - > NumC = 0 ;
DWBStarted = 0 ;
nstr = MakeButtString ( bc ) ;
SetDlgItemText ( hwndDlg , 100 , nstr ) ;
free ( nstr ) ;
}
{
ButtConfig * bc = DWBButtons ;
int wc = bc - > NumC ;
char * nstr ;
bc - > ButtType [ wc ] = BUTTC_KEYBOARD ;
bc - > DeviceNum [ wc ] = 0 ;
bc - > ButtonNum [ wc ] = lParam & 255 ;
/* Stop config if the user pushes the same button twice in a row. */
if ( wc & & bc - > ButtType [ wc ] = = bc - > ButtType [ wc - 1 ] & & bc - > DeviceNum [ wc ] = = bc - > DeviceNum [ wc - 1 ] & &
bc - > ButtonNum [ wc ] = = bc - > ButtonNum [ wc - 1 ] )
goto gornk ;
bc - > NumC + + ;
/* Stop config if we reached our maximum button limit. */
if ( bc - > NumC > = MAXBUTTCONFIG )
goto gornk ;
nstr = MakeButtString ( bc ) ;
SetDlgItemText ( hwndDlg , 100 , nstr ) ;
free ( nstr ) ;
}
break ;
case WM_INITDIALOG :
2006-07-18 06:35:48 +00:00
SetWindowText ( hwndDlg , ( char * ) DWBText ) ; //mbg merge 7/17/06 added cast
2006-07-18 02:53:36 +00:00
BeginJoyWait ( hwndDlg ) ;
SetTimer ( hwndDlg , 666 , 25 , 0 ) ; /* Every 25ms.*/
{
char * nstr = MakeButtString ( DWBButtons ) ;
SetDlgItemText ( hwndDlg , 100 , nstr ) ;
free ( nstr ) ;
}
break ;
case WM_CLOSE :
case WM_QUIT : goto gornk ;
case WM_COMMAND :
switch ( wParam & 0xFFFF )
{
case 200 :
{
ButtConfig * bc = DWBButtons ;
char * nstr ;
bc - > NumC = 0 ;
nstr = MakeButtString ( bc ) ;
SetDlgItemText ( hwndDlg , 100 , nstr ) ;
free ( nstr ) ;
}
break ;
case 201 :
gornk :
KillTimer ( hwndDlg , 666 ) ;
EndJoyWait ( hAppWnd ) ;
SetForegroundWindow ( GetParent ( hwndDlg ) ) ;
DestroyWindow ( hwndDlg ) ;
break ;
}
}
return 0 ;
}
int DWaitButton ( HWND hParent , const uint8 * text , ButtConfig * bc )
{
DWBText = text ;
DWBButtons = bc ;
DWBStarted = 1 ;
die = CreateDialog ( fceu_hInstance , " DWBDIALOG " , hParent , DWBCallB ) ;
EnableWindow ( hParent , 0 ) ;
ShowWindow ( die , 1 ) ;
while ( die )
{
MSG msg ;
while ( PeekMessage ( & msg , 0 , 0 , 0 , PM_NOREMOVE ) )
{
if ( GetMessage ( & msg , 0 , 0 , 0 ) > 0 )
{
if ( msg . message = = WM_KEYDOWN | | msg . message = = WM_SYSKEYDOWN )
{
LPARAM tmpo ;
tmpo = ( ( msg . lParam > > 16 ) & 0x7F ) | ( ( msg . lParam > > 17 ) & 0x80 ) ;
PostMessage ( die , WM_USER + 666 , 0 , tmpo ) ;
continue ;
}
if ( msg . message = = WM_SYSCOMMAND ) continue ;
if ( ! IsDialogMessage ( die , & msg ) )
{
TranslateMessage ( & msg ) ;
DispatchMessage ( & msg ) ;
}
}
}
Sleep ( 10 ) ;
}
EnableWindow ( hParent , 1 ) ;
2006-07-18 06:35:48 +00:00
return 0 ; //mbg merge TODO 7/17/06 - had to add this return value--is it right?
2006-07-18 02:53:36 +00:00
}
int DWaitSimpleButton ( HWND hParent , const uint8 * text )
{
DWBStarted = 1 ;
int ret = 0 ;
die = CreateDialog ( fceu_hInstance , " DWBDIALOGSIMPLE " , hParent , NULL ) ;
2006-07-18 06:35:48 +00:00
SetWindowText ( die , ( char * ) text ) ; //mbg merge 7/17/06 added cast
2006-07-18 02:53:36 +00:00
EnableWindow ( hParent , 0 ) ;
ShowWindow ( die , 1 ) ;
while ( die )
{
MSG msg ;
while ( PeekMessage ( & msg , 0 , 0 , 0 , PM_NOREMOVE ) )
{
if ( GetMessage ( & msg , 0 , 0 , 0 ) > 0 )
{
if ( msg . message = = WM_KEYDOWN | | msg . message = = WM_SYSKEYDOWN )
{
LPARAM tmpo ;
tmpo = ( ( msg . lParam > > 16 ) & 0x7F ) | ( ( msg . lParam > > 17 ) & 0x80 ) ;
ret = tmpo ;
goto done ;
}
if ( msg . message = = WM_SYSCOMMAND ) continue ;
if ( ! IsDialogMessage ( die , & msg ) )
{
TranslateMessage ( & msg ) ;
DispatchMessage ( & msg ) ;
}
}
}
Sleep ( 10 ) ;
}
done :
EndDialog ( die , 0 ) ;
EnableWindow ( hParent , 1 ) ;
if ( ret = = 1 ) // convert Esc to nothing (why is it 1 and not VK_ESCAPE?)
ret = 0 ;
return ret ;
}
static ButtConfig * DoTBButtons = 0 ;
static const char * DoTBTitle = 0 ;
static int DoTBMax = 0 ;
static int DoTBType = 0 , DoTBPort = 0 ;
static BOOL CALLBACK DoTBCallB ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
switch ( uMsg ) {
case WM_INITDIALOG :
if ( DoTBType = = SI_GAMEPAD )
{
char buf [ 32 ] ;
sprintf ( buf , " Virtual Gamepad %d " , DoTBPort + 1 ) ;
SetDlgItemText ( hwndDlg , 100 , buf ) ;
sprintf ( buf , " Virtual Gamepad %d " , DoTBPort + 3 ) ;
SetDlgItemText ( hwndDlg , 101 , buf ) ;
CheckDlgButton ( hwndDlg , 400 , ( eoptions & EO_NOFOURSCORE ) ? BST_CHECKED : BST_UNCHECKED ) ;
}
SetWindowText ( hwndDlg , DoTBTitle ) ;
break ;
case WM_CLOSE :
case WM_QUIT : goto gornk ;
case WM_COMMAND :
{
int b ;
b = wParam & 0xFFFF ;
if ( b > = 300 & & b < ( 300 + DoTBMax ) )
{
char btext [ 128 ] ;
btext [ 0 ] = 0 ;
GetDlgItemText ( hwndDlg , b , btext , 128 ) ;
2006-07-18 06:35:48 +00:00
DWaitButton ( hwndDlg , ( uint8 * ) btext , & DoTBButtons [ b - 300 ] ) ; //mbg merge 7/17/06 added cast
2006-07-18 02:53:36 +00:00
}
else switch ( wParam & 0xFFFF )
{
case 1 :
gornk :
if ( DoTBType = = SI_GAMEPAD )
{
eoptions & = ~ EO_NOFOURSCORE ;
if ( IsDlgButtonChecked ( hwndDlg , 400 ) = = BST_CHECKED )
eoptions | = EO_NOFOURSCORE ;
}
EndDialog ( hwndDlg , 0 ) ;
break ;
}
}
}
return 0 ;
}
2006-07-18 06:35:48 +00:00
static void DoTBConfig ( HWND hParent , const char * text , char * _template , ButtConfig * buttons , int max )
2006-07-18 02:53:36 +00:00
{
DoTBTitle = text ;
DoTBButtons = buttons ;
DoTBMax = max ;
2006-07-18 06:35:48 +00:00
DialogBox ( fceu_hInstance , _template , hParent , DoTBCallB ) ;
2006-07-18 02:53:36 +00:00
}
static BOOL CALLBACK InputConCallB ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
static const char * strn [ 6 ] = { " <none> " , " Gamepad " , " Zapper " , " Power Pad A " , " Power Pad B " , " Arkanoid Paddle " } ;
static const char * strf [ 14 ] =
{ " <none> " , " Arkanoid Paddle " , " Hyper Shot gun " , " 4-Player Adapter " ,
" Family Keyboard " , " Subor Keyboard " , " HyperShot Pads " , " Mahjong " , " Quiz King Buzzers " ,
" Family Trainer A " , " Family Trainer B " , " Oeka Kids Tablet " , " Barcode World " ,
" Top Rider " } ;
static const int haven [ 6 ] = { 0 , 1 , 0 , 1 , 1 , 0 } ;
static const int havef [ 14 ] = { 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 } ;
int x ;
switch ( uMsg ) {
case WM_INITDIALOG :
2006-07-19 05:57:00 +00:00
SetDlgItemText ( hwndDlg , 65488 , " Select the device you want to be enabled on input ports 1 and 2, and the Famicom expansion port. You may configure the device listed above each drop-down list by pressing \" Configure \" , if applicable. The device currently being emulated on the each port is listed above the drop down list; loading certain games will override your settings, but only temporarily. If you select a device to be on the emulated Famicom Expansion Port, you should probably have emulated gamepads on the emulated NES-style input ports. " ) ;
2006-07-18 02:53:36 +00:00
for ( x = 0 ; x < 2 ; x + + )
{
int y ;
for ( y = 0 ; y < 6 ; y + + )
SendDlgItemMessage ( hwndDlg , 104 + x , CB_ADDSTRING , 0 , ( LPARAM ) ( LPSTR ) strn [ y ] ) ;
SendDlgItemMessage ( hwndDlg , 104 + x , CB_SETCURSEL , UsrInputType [ x ] , ( LPARAM ) ( LPSTR ) 0 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , 106 + x ) , haven [ InputType [ x ] ] ) ;
SetDlgItemText ( hwndDlg , 200 + x , ( LPTSTR ) strn [ InputType [ x ] ] ) ;
}
{
int y ;
for ( y = 0 ; y < 13 ; y + + )
SendDlgItemMessage ( hwndDlg , 110 , CB_ADDSTRING , 0 , ( LPARAM ) ( LPSTR ) strf [ y ] ) ;
SendDlgItemMessage ( hwndDlg , 110 , CB_SETCURSEL , UsrInputType [ 2 ] , ( LPARAM ) ( LPSTR ) 0 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , 111 ) , havef [ InputType [ 2 ] ] ) ;
SetDlgItemText ( hwndDlg , 202 , ( LPTSTR ) strf [ InputType [ 2 ] ] ) ;
}
extern int autoHoldKey , autoHoldClearKey ;
char btext [ 128 ] ;
if ( autoHoldKey )
{
if ( ! GetKeyNameText ( autoHoldKey < < 16 , btext , 128 ) )
sprintf ( btext , " KB: %d " , autoHoldKey ) ;
}
else
sprintf ( btext , " not assigned " ) ;
SetDlgItemText ( hwndDlg , 115 , btext ) ;
if ( autoHoldClearKey )
{
if ( ! GetKeyNameText ( autoHoldClearKey < < 16 , btext , 128 ) )
sprintf ( btext , " KB: %d " , autoHoldClearKey ) ;
}
else
sprintf ( btext , " not assigned " ) ;
SetDlgItemText ( hwndDlg , 116 , btext ) ;
break ;
case WM_CLOSE :
case WM_QUIT : goto gornk ;
case WM_COMMAND :
if ( HIWORD ( wParam ) = = CBN_SELENDOK )
{
switch ( LOWORD ( wParam ) )
{
case 104 :
case 105 : UsrInputType [ LOWORD ( wParam ) - 104 ] = InputType [ LOWORD ( wParam ) - 104 ] = SendDlgItemMessage ( hwndDlg , LOWORD ( wParam ) , CB_GETCURSEL , 0 , ( LPARAM ) ( LPSTR ) 0 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , LOWORD ( wParam ) + 2 ) , haven [ InputType [ LOWORD ( wParam ) - 104 ] ] ) ;
SetDlgItemText ( hwndDlg , 200 + LOWORD ( wParam ) - 104 , ( LPTSTR ) strn [ InputType [ LOWORD ( wParam ) - 104 ] ] ) ;
break ;
case 110 : UsrInputType [ 2 ] = InputType [ 2 ] = SendDlgItemMessage ( hwndDlg , 110 , CB_GETCURSEL , 0 , ( LPARAM ) ( LPSTR ) 0 ) ;
EnableWindow ( GetDlgItem ( hwndDlg , 111 ) , havef [ InputType [ 2 ] ] ) ;
SetDlgItemText ( hwndDlg , 202 , ( LPTSTR ) strf [ InputType [ 2 ] ] ) ;
break ;
}
}
if ( ! ( wParam > > 16 ) )
switch ( wParam & 0xFFFF )
{
case 111 :
{
const char * text = strf [ InputType [ 2 ] ] ;
DoTBType = DoTBPort = 0 ;
switch ( InputType [ 2 ] )
{
case SIFC_FTRAINERA :
case SIFC_FTRAINERB : DoTBConfig ( hwndDlg , text , " POWERPADDIALOG " , FTrainerButtons , 12 ) ; break ;
case SIFC_FKB : DoTBConfig ( hwndDlg , text , " FKBDIALOG " , fkbmap , 0x48 ) ; break ;
case SIFC_SUBORKB : DoTBConfig ( hwndDlg , text , " SUBORKBDIALOG " , suborkbmap , 0x60 ) ; break ;
case SIFC_QUIZKING : DoTBConfig ( hwndDlg , text , " QUIZKINGDIALOG " , QuizKingButtons , 6 ) ; break ;
}
}
break ;
case 107 :
case 106 :
{
int which = ( wParam & 0xFFFF ) - 106 ;
const char * text = strn [ InputType [ which ] ] ;
DoTBType = DoTBPort = 0 ;
switch ( InputType [ which ] )
{
case SI_GAMEPAD :
{
ButtConfig tmp [ 10 + 10 ] ;
memcpy ( tmp , GamePadConfig [ which ] , 10 * sizeof ( ButtConfig ) ) ;
memcpy ( & tmp [ 10 ] , GamePadConfig [ which + 2 ] , 10 * sizeof ( ButtConfig ) ) ;
DoTBType = SI_GAMEPAD ;
DoTBPort = which ;
DoTBConfig ( hwndDlg , text , " GAMEPADDIALOG " , tmp , 10 + 10 ) ;
memcpy ( GamePadConfig [ which ] , tmp , 10 * sizeof ( ButtConfig ) ) ;
memcpy ( GamePadConfig [ which + 2 ] , & tmp [ 10 ] , 10 * sizeof ( ButtConfig ) ) ;
}
break ;
case SI_POWERPADA :
case SI_POWERPADB :
DoTBConfig ( hwndDlg , text , " POWERPADDIALOG " , powerpadsc [ which ] , 12 ) ;
break ;
}
}
break ;
case 112 : // auto-hold button
{
char btext [ 128 ] ;
btext [ 0 ] = 0 ;
GetDlgItemText ( hwndDlg , 112 , btext , 128 ) ;
2006-07-18 06:35:48 +00:00
int button = DWaitSimpleButton ( hwndDlg , ( uint8 * ) btext ) ; //mbg merge 7/17/06
2006-07-18 02:53:36 +00:00
if ( button )
{
if ( ! GetKeyNameText ( button < < 16 , btext , 128 ) )
sprintf ( btext , " KB: %d " , button ) ;
}
else
sprintf ( btext , " not assigned " ) ;
extern int autoHoldKey ;
autoHoldKey = button ;
SetDlgItemText ( hwndDlg , 115 , btext ) ;
}
break ;
case 114 : // auto-hold clear button
{
char btext [ 128 ] ;
btext [ 0 ] = 0 ;
GetDlgItemText ( hwndDlg , 114 , btext , 128 ) ;
2006-07-18 06:35:48 +00:00
int button = DWaitSimpleButton ( hwndDlg , ( uint8 * ) btext ) ; //mbg merge 7/17/06 added cast
2006-07-18 02:53:36 +00:00
if ( button )
{
if ( ! GetKeyNameText ( button < < 16 , btext , 128 ) )
sprintf ( btext , " KB: %d " , button ) ;
}
else
sprintf ( btext , " not assigned " ) ;
extern int autoHoldClearKey ;
autoHoldClearKey = button ;
SetDlgItemText ( hwndDlg , 116 , btext ) ;
}
break ;
case 1 :
gornk :
EndDialog ( hwndDlg , 0 ) ;
break ;
}
}
return 0 ;
}
void ConfigInput ( HWND hParent )
{
DialogBox ( fceu_hInstance , " INPUTCONFIG " , hParent , InputConCallB ) ;
if ( GI )
InitOtherInput ( ) ;
}
void DestroyInput ( void )
{
if ( lpDI )
{
KillJoysticks ( ) ;
KeyboardClose ( ) ;
IDirectInput7_Release ( lpDI ) ;
}
}
# define CMD_KEY_MASK 0xff
# define CMD_KEY_LSHIFT (1<<16)
# define CMD_KEY_RSHIFT (1<<17)
# define CMD_KEY_SHIFT (CMD_KEY_LSHIFT|CMD_KEY_RSHIFT)
# define CMD_KEY_LCTRL (1<<18)
# define CMD_KEY_RCTRL (1<<19)
# define CMD_KEY_CTRL (CMD_KEY_LCTRL|CMD_KEY_RCTRL)
# define CMD_KEY_LALT (1<<20)
# define CMD_KEY_RALT (1<<21)
# define CMD_KEY_ALT (CMD_KEY_LALT|CMD_KEY_RALT)
int FCEUD_CommandMapping [ EMUCMD_MAX ] ;
CFGSTRUCT HotkeyConfig [ ] = {
AC ( FCEUD_CommandMapping ) ,
ENDCFGSTRUCT
} ;
static struct
{
int cmd ;
int key ;
} DefaultCommandMapping [ ] =
{
{ EMUCMD_RESET , SCAN_R | CMD_KEY_CTRL , } ,
{ EMUCMD_PAUSE , SCAN_PAUSE , } ,
{ EMUCMD_FRAME_ADVANCE , SCAN_BACKSLASH , } ,
{ EMUCMD_SCREENSHOT , SCAN_F12 } ,
{ EMUCMD_HIDE_MENU_TOGGLE , SCAN_ESCAPE } ,
{ EMUCMD_SPEED_SLOWER , SCAN_MINUS , } ,
{ EMUCMD_SPEED_FASTER , SCAN_EQUAL , } ,
{ EMUCMD_SPEED_TURBO , SCAN_TAB , } ,
{ EMUCMD_SAVE_SLOT_0 , SCAN_0 , } ,
{ EMUCMD_SAVE_SLOT_1 , SCAN_1 , } ,
{ EMUCMD_SAVE_SLOT_2 , SCAN_2 , } ,
{ EMUCMD_SAVE_SLOT_3 , SCAN_3 , } ,
{ EMUCMD_SAVE_SLOT_4 , SCAN_4 , } ,
{ EMUCMD_SAVE_SLOT_5 , SCAN_5 , } ,
{ EMUCMD_SAVE_SLOT_6 , SCAN_6 , } ,
{ EMUCMD_SAVE_SLOT_7 , SCAN_7 , } ,
{ EMUCMD_SAVE_SLOT_8 , SCAN_8 , } ,
{ EMUCMD_SAVE_SLOT_9 , SCAN_9 , } ,
{ EMUCMD_SAVE_STATE , SCAN_F5 | CMD_KEY_CTRL , } ,
{ EMUCMD_LOAD_STATE , SCAN_F7 | CMD_KEY_CTRL , } ,
{ EMUCMD_SAVE_STATE_SLOT_0 , SCAN_F10 | CMD_KEY_SHIFT , } ,
{ EMUCMD_SAVE_STATE_SLOT_1 , SCAN_F1 | CMD_KEY_SHIFT , } ,
{ EMUCMD_SAVE_STATE_SLOT_2 , SCAN_F2 | CMD_KEY_SHIFT , } ,
{ EMUCMD_SAVE_STATE_SLOT_3 , SCAN_F3 | CMD_KEY_SHIFT , } ,
{ EMUCMD_SAVE_STATE_SLOT_4 , SCAN_F4 | CMD_KEY_SHIFT , } ,
{ EMUCMD_SAVE_STATE_SLOT_5 , SCAN_F5 | CMD_KEY_SHIFT , } ,
{ EMUCMD_SAVE_STATE_SLOT_6 , SCAN_F6 | CMD_KEY_SHIFT , } ,
{ EMUCMD_SAVE_STATE_SLOT_7 , SCAN_F7 | CMD_KEY_SHIFT , } ,
{ EMUCMD_SAVE_STATE_SLOT_8 , SCAN_F8 | CMD_KEY_SHIFT , } ,
{ EMUCMD_SAVE_STATE_SLOT_9 , SCAN_F9 | CMD_KEY_SHIFT , } ,
{ EMUCMD_LOAD_STATE_SLOT_0 , SCAN_F10 , } ,
{ EMUCMD_LOAD_STATE_SLOT_1 , SCAN_F1 , } ,
{ EMUCMD_LOAD_STATE_SLOT_2 , SCAN_F2 , } ,
{ EMUCMD_LOAD_STATE_SLOT_3 , SCAN_F3 , } ,
{ EMUCMD_LOAD_STATE_SLOT_4 , SCAN_F4 , } ,
{ EMUCMD_LOAD_STATE_SLOT_5 , SCAN_F5 , } ,
{ EMUCMD_LOAD_STATE_SLOT_6 , SCAN_F6 , } ,
{ EMUCMD_LOAD_STATE_SLOT_7 , SCAN_F7 , } ,
{ EMUCMD_LOAD_STATE_SLOT_8 , SCAN_F8 , } ,
{ EMUCMD_LOAD_STATE_SLOT_9 , SCAN_F9 , } ,
/* { EMUCMD_MOVIE_SLOT_0, SCAN_0 | CMD_KEY_ALT, },
{ EMUCMD_MOVIE_SLOT_1 , SCAN_1 | CMD_KEY_ALT , } ,
{ EMUCMD_MOVIE_SLOT_2 , SCAN_2 | CMD_KEY_ALT , } ,
{ EMUCMD_MOVIE_SLOT_3 , SCAN_3 | CMD_KEY_ALT , } ,
{ EMUCMD_MOVIE_SLOT_4 , SCAN_4 | CMD_KEY_ALT , } ,
{ EMUCMD_MOVIE_SLOT_5 , SCAN_5 | CMD_KEY_ALT , } ,
{ EMUCMD_MOVIE_SLOT_6 , SCAN_6 | CMD_KEY_ALT , } ,
{ EMUCMD_MOVIE_SLOT_7 , SCAN_7 | CMD_KEY_ALT , } ,
{ EMUCMD_MOVIE_SLOT_8 , SCAN_8 | CMD_KEY_ALT , } ,
{ EMUCMD_MOVIE_SLOT_9 , SCAN_9 | CMD_KEY_ALT , } ,
{ EMUCMD_MOVIE_RECORD , SCAN_F5 | CMD_KEY_ALT , } ,
{ EMUCMD_MOVIE_REPLAY , SCAN_F7 | CMD_KEY_ALT , } , */
{ EMUCMD_MOVIE_FRAME_DISPLAY_TOGGLE , SCAN_PERIOD , } ,
{ EMUCMD_FDS_EJECT_INSERT , SCAN_F8 | CMD_KEY_CTRL , } ,
{ EMUCMD_FDS_SIDE_SELECT , SCAN_F6 | CMD_KEY_CTRL , } ,
{ EMUCMD_MOVIE_INPUT_DISPLAY_TOGGLE , SCAN_COMMA , } ,
{ EMUCMD_MOVIE_READONLY_TOGGLE , SCAN_8 | CMD_KEY_SHIFT , } ,
{ EMUCMD_MISC_REWIND , SCAN_R , } ,
} ;
# define NUM_DEFAULT_MAPPINGS (sizeof(DefaultCommandMapping) / sizeof(DefaultCommandMapping[0]))
void ApplyDefaultCommandMapping ( void )
{
int i ;
memset ( FCEUD_CommandMapping , 0 , sizeof ( FCEUD_CommandMapping ) ) ;
for ( i = 0 ; i < NUM_DEFAULT_MAPPINGS ; + + i )
FCEUD_CommandMapping [ DefaultCommandMapping [ i ] . cmd ] = DefaultCommandMapping [ i ] . key ;
}
int FCEUD_TestCommandState ( int c )
{
int cmd = FCEUD_CommandMapping [ c ] ;
int cmdmask = cmd & CMD_KEY_MASK ;
// allow certain commands be affected by key repeat
if ( c = = EMUCMD_FRAME_ADVANCE /*
| | c = = EMUCMD_SOUND_VOLUME_UP
| | c = = EMUCMD_SOUND_VOLUME_DOWN
| | c = = EMUCMD_SPEED_SLOWER
| | c = = EMUCMD_SPEED_FASTER */ )
{
keys = GetKeyboard ( ) ;
/* if((cmdmask & CMD_KEY_LALT) == CMD_KEY_LALT
| | ( cmdmask & CMD_KEY_RALT ) = = CMD_KEY_RALT
| | ( cmdmask & CMD_KEY_LALT ) = = CMD_KEY_LALT
| | ( cmdmask & CMD_KEY_LCTRL ) = = CMD_KEY_LCTRL
| | ( cmdmask & CMD_KEY_RCTRL ) = = CMD_KEY_RCTRL
| | ( cmdmask & CMD_KEY_LSHIFT ) = = CMD_KEY_LSHIFT
| | ( cmdmask & CMD_KEY_RSHIFT ) = = CMD_KEY_RSHIFT ) */
keys_nr = GetKeyboard ( ) ;
// else
// keys_nr=GetKeyboard_nr();
}
else if ( c ! = EMUCMD_SPEED_TURBO ) // TODO: this should be made more general by detecting if the command has an "off" function, but right now Turbo is the only command that has it
{
keys = GetKeyboard_jd ( ) ;
keys_nr = GetKeyboard_nr ( ) ;
}
else
{
keys = GetKeyboard_nr ( ) ;
keys_nr = GetKeyboard_nr ( ) ;
}
/* test CTRL, SHIFT, ALT */
if ( cmd & CMD_KEY_ALT )
{
int ctlstate = ( cmd & CMD_KEY_LALT ) ? keys_nr [ SCAN_LEFTALT ] : 0 ;
ctlstate | = ( cmd & CMD_KEY_RALT ) ? keys_nr [ SCAN_RIGHTALT ] : 0 ;
if ( ! ctlstate )
return 0 ;
}
else if ( ( cmdmask ! = SCAN_LEFTALT & & keys_nr [ SCAN_LEFTALT ] ) | | ( cmdmask ! = SCAN_RIGHTALT & & keys_nr [ SCAN_RIGHTALT ] ) )
return 0 ;
if ( cmd & CMD_KEY_CTRL )
{
int ctlstate = ( cmd & CMD_KEY_LCTRL ) ? keys_nr [ SCAN_LEFTCONTROL ] : 0 ;
ctlstate | = ( cmd & CMD_KEY_RCTRL ) ? keys_nr [ SCAN_RIGHTCONTROL ] : 0 ;
if ( ! ctlstate )
return 0 ;
}
else if ( ( cmdmask ! = SCAN_LEFTCONTROL & & keys_nr [ SCAN_LEFTCONTROL ] ) | | ( cmdmask ! = SCAN_RIGHTCONTROL & & keys_nr [ SCAN_RIGHTCONTROL ] ) )
return 0 ;
if ( cmd & CMD_KEY_SHIFT )
{
int ctlstate = ( cmd & CMD_KEY_LSHIFT ) ? keys_nr [ SCAN_LEFTSHIFT ] : 0 ;
ctlstate | = ( cmd & CMD_KEY_RSHIFT ) ? keys_nr [ SCAN_RIGHTSHIFT ] : 0 ;
if ( ! ctlstate )
return 0 ;
}
else if ( ( cmdmask ! = SCAN_LEFTSHIFT & & keys_nr [ SCAN_LEFTSHIFT ] ) | | ( cmdmask ! = SCAN_RIGHTSHIFT & & keys_nr [ SCAN_RIGHTSHIFT ] ) )
return 0 ;
return keys [ cmdmask ] ? 1 : 0 ;
}
static const char * ScanNames [ 256 ] =
{
/* 0x00-0x0f */ 0 , " Escape " , " 1 " , " 2 " , " 3 " , " 4 " , " 5 " , " 6 " , " 7 " , " 8 " , " 9 " , " 0 " , " Minus " , " Equals " , " Backspace " , " Tab " ,
/* 0x10-0x1f */ " Q " , " W " , " E " , " R " , " T " , " Y " , " U " , " I " , " O " , " P " , " [ " , " ] " , " Enter " , " Left Ctrl " , " A " , " S " ,
/* 0x20-0x2f */ " D " , " F " , " G " , " H " , " J " , " K " , " L " , " Semicolon " , " Apostrophe " , " Grave " , " Left Shift " , " Backslash " , " Z " , " X " , " C " , " V " ,
/* 0x30-0x3f */ " B " , " N " , " M " , " Comma " , " Period " , " Slash " , " Right Shift " , " Numpad * " , " Left Alt " , " Space " , " Caps Lock " , " F1 " , " F2 " , " F3 " , " F4 " , " F5 " ,
/* 0x40-0x4f */ " F6 " , " F7 " , " F8 " , " F9 " , " F10 " , " NumLock " , " ScrollLock " , " Numpad 7 " , " Numpad 8 " , " Numpad 9 " , " Numpad Minus " , " Numpad 4 " , " Numpad 5 " , " Numpad 6 " , " Numpad Plus " , " Numpad 1 " ,
/* 0x50-0x5f */ " Numpad 2 " , " Numpad 3 " , " Numpad 0 " , " Numpad Period " , 0 , 0 , " Backslash " , " F11 " , " F12 " , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
/* 0x60-0x6f */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
/* 0x70-0x7f */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
/* 0x80-0x8f */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
/* 0x90-0x9f */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , " Numpad Enter " , " Right Ctrl " , 0 , 0 ,
/* 0xa0-0xaf */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
/* 0xb0-0xbf */ 0 , 0 , 0 , 0 , 0 , " Numpad Divide " , 0 , " PrintScrn " , " Right Alt " , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
/* 0xc0-0xcf */ 0 , 0 , 0 , 0 , 0 , " Pause " , 0 , " Home " , " Up Arrow " , " PgUp " , 0 , " Left Arrow " , 0 , " Right Arrow " , 0 , " End " ,
/* 0xd0-0xdf */ " Down Arrow " , " PgDn " , " Ins " , " Del " , 0 , 0 , 0 , 0 , 0 , 0 , 0 , " Left Win " , " Right Win " , " AppMenu " , 0 , 0 ,
/* 0xe0-0xef */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
/* 0xf0-0xff */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
} ;
static const char * GetKeyName ( int code )
{
static char name [ 16 ] ;
code & = 0xff ;
if ( ScanNames [ code ] )
return ScanNames [ code ] ;
sprintf ( name , " Key 0x%.2x " , code ) ;
return name ;
}
static char * GetKeyComboName ( int c )
{
static char text [ 80 ] ;
text [ 0 ] = ' \0 ' ;
if ( ! c )
return text ;
if ( ( c & CMD_KEY_CTRL ) = = CMD_KEY_CTRL ) strcat ( text , " Ctrl + " ) ;
else if ( ( c & CMD_KEY_CTRL ) = = CMD_KEY_LCTRL ) strcat ( text , " Left Ctrl + " ) ;
else if ( ( c & CMD_KEY_CTRL ) = = CMD_KEY_RCTRL ) strcat ( text , " Right Ctrl + " ) ;
if ( ( c & CMD_KEY_ALT ) = = CMD_KEY_ALT ) strcat ( text , " Alt + " ) ;
else if ( ( c & CMD_KEY_ALT ) = = CMD_KEY_LALT ) strcat ( text , " Left Alt + " ) ;
else if ( ( c & CMD_KEY_ALT ) = = CMD_KEY_RALT ) strcat ( text , " Right Alt + " ) ;
if ( ( c & CMD_KEY_SHIFT ) = = CMD_KEY_SHIFT ) strcat ( text , " Shift + " ) ;
else if ( ( c & CMD_KEY_SHIFT ) = = CMD_KEY_LSHIFT ) strcat ( text , " Left Shift + " ) ;
else if ( ( c & CMD_KEY_SHIFT ) = = CMD_KEY_RSHIFT ) strcat ( text , " Right Shift + " ) ;
strcat ( text , GetKeyName ( c & CMD_KEY_MASK ) ) ;
return text ;
}
struct INPUTDLGTHREADARGS
{
HANDLE hThreadExit ;
HWND hwndDlg ;
} ;
static DWORD WINAPI NewInputDialogThread ( LPVOID lpvArg )
{
struct INPUTDLGTHREADARGS * args = ( struct INPUTDLGTHREADARGS * ) lpvArg ;
while ( args - > hThreadExit )
{
if ( WaitForSingleObject ( args - > hThreadExit , 20 ) = = WAIT_OBJECT_0 )
break ;
// Poke our owner dialog periodically.
PostMessage ( args - > hwndDlg , WM_USER , 0 , 0 ) ;
}
return 0 ;
}
static int GetKeyPressed ( )
{
int key = 0 ;
int i ;
keys_nr = GetKeyboard_nr ( ) ;
for ( i = 0 ; i < 256 & & ! key ; + + i )
{
if ( _keyonly ( i ) )
key = i ;
}
return key ;
}
static int NothingPressed ( )
{
int i ;
keys_nr = GetKeyboard_nr ( ) ;
for ( i = 0 ; i < 256 ; + + i )
{
if ( keys_nr [ i ] )
return 0 ;
}
return 1 ;
}
static int GetKeyMeta ( int key )
{
int meta = key & ( ~ CMD_KEY_MASK ) ;
switch ( key & CMD_KEY_MASK )
{
case SCAN_LEFTCONTROL :
case SCAN_RIGHTCONTROL : return CMD_KEY_CTRL | meta ;
case SCAN_LEFTALT :
case SCAN_RIGHTALT : return CMD_KEY_ALT | meta ;
case SCAN_LEFTSHIFT :
case SCAN_RIGHTSHIFT : return CMD_KEY_SHIFT | meta ;
default :
break ;
}
return meta ;
}
static void ClearExtraMeta ( int * key )
{
switch ( ( * key ) & 0xff )
{
case SCAN_LEFTCONTROL :
case SCAN_RIGHTCONTROL : * key & = ~ ( CMD_KEY_CTRL ) ; break ;
case SCAN_LEFTALT :
case SCAN_RIGHTALT : * key & = ~ ( CMD_KEY_ALT ) ; break ;
case SCAN_LEFTSHIFT :
case SCAN_RIGHTSHIFT : * key & = ~ ( CMD_KEY_SHIFT ) ; break ;
default :
break ;
}
}
static BOOL CALLBACK ChangeInputDialogProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
static HANDLE hThread = NULL ;
static DWORD dwThreadId = 0 ;
static struct INPUTDLGTHREADARGS threadargs ;
static int key = 0 ;
switch ( uMsg )
{
case WM_INITDIALOG :
{
// Start the message thread.
threadargs . hThreadExit = CreateEvent ( NULL , TRUE , FALSE , NULL ) ;
threadargs . hwndDlg = hwndDlg ;
hThread = CreateThread ( NULL , 0 , NewInputDialogThread , ( LPVOID ) & threadargs , 0 , & dwThreadId ) ;
key = 0 ;
memset ( keyonce , 0 , sizeof ( keyonce ) ) ;
KeyboardSetBackgroundAccess ( 1 ) ;
SetFocus ( GetDlgItem ( hwndDlg , 100 ) ) ;
}
return FALSE ;
case WM_COMMAND :
if ( LOWORD ( wParam ) = = 202 & & HIWORD ( wParam ) = = BN_CLICKED )
{
key = 0 ;
PostMessage ( hwndDlg , WM_USER + 1 , 0 , 0 ) ; // Send quit message.
}
else if ( LOWORD ( wParam ) = = 200 & & HIWORD ( wParam ) = = BN_CLICKED )
{
key = - 1 ;
PostMessage ( hwndDlg , WM_USER + 1 , 0 , 0 ) ; // Send quit message.
}
break ;
case WM_USER :
{
// Our thread sent us a timer signal.
int newkey ;
int meta = GetKeyMeta ( key ) ;
KeyboardUpdateState ( ) ;
if ( ( newkey = GetKeyPressed ( ) ) ! = 0 )
{
key = newkey | meta ;
ClearExtraMeta ( & key ) ;
SetDlgItemText ( hwndDlg , 100 , GetKeyComboName ( key ) ) ;
}
else if ( NothingPressed ( ) & & key )
PostMessage ( hwndDlg , WM_USER + 1 , 0 , 0 ) ; // Send quit message.
}
break ;
case WM_USER + 1 :
{
// Done with keyboard.
KeyboardSetBackgroundAccess ( 0 ) ;
// Kill the thread.
SetEvent ( threadargs . hThreadExit ) ;
WaitForSingleObject ( hThread , INFINITE ) ;
CloseHandle ( hThread ) ;
CloseHandle ( threadargs . hThreadExit ) ;
// End the dialog.
EndDialog ( hwndDlg , key ) ;
return TRUE ;
}
default :
break ;
}
return FALSE ;
}
static int * ConflictTable = 0 ;
static int ShouldDisplayMapping ( int mapn , int filter )
{
2006-07-18 06:35:48 +00:00
//mbg merge 7/17/06 changed to if..elseif
if ( filter = = 0 ) /* No filter */
return 1 ;
else if ( filter < = EMUCMDTYPE_MAX ) /* Filter by type */
return ( FCEUI_CommandTable [ mapn ] . type = = filter - 1 ) ;
else if ( filter = = EMUCMDTYPE_MAX + 1 ) /* Assigned */
return FCEUD_CommandMapping [ mapn ] ;
else if ( filter = = EMUCMDTYPE_MAX + 2 ) /* Unassigned */
return ! ( FCEUD_CommandMapping [ mapn ] ) ;
else if ( filter = = EMUCMDTYPE_MAX + 3 ) /* Conflicts */
return ConflictTable [ mapn ] ;
else
return 0 ;
2006-07-18 02:53:36 +00:00
}
static void PopulateMappingDisplay ( HWND hwndDlg )
{
LVITEM lvi ;
int i ;
int idx ;
HWND hwndListView = GetDlgItem ( hwndDlg , 1003 ) ;
int num = SendMessage ( hwndListView , LVM_GETITEMCOUNT , 0 , 0 ) ;
int filter = ( int ) SendDlgItemMessage ( hwndDlg , 300 , CB_GETCURSEL , 0 , 0 ) ;
// Delete everything in the current display.
for ( i = num ; i > 0 ; - - i )
SendMessage ( hwndListView , LVM_DELETEITEM , ( WPARAM ) i - 1 , 0 ) ;
// Get the filter type.
ConflictTable = 0 ;
if ( filter = = EMUCMDTYPE_MAX + 3 )
{
// Set up the conflict table.
ConflictTable = ( int * ) malloc ( sizeof ( int ) * EMUCMD_MAX ) ;
memset ( ConflictTable , 0 , sizeof ( int ) * EMUCMD_MAX ) ;
for ( i = 0 ; i < EMUCMD_MAX - 1 ; + + i )
{
int j ;
for ( j = i + 1 ; j < EMUCMD_MAX ; + + j )
{
if ( FCEUD_CommandMapping [ i ] & &
FCEUD_CommandMapping [ i ] = = FCEUD_CommandMapping [ j ] )
{
ConflictTable [ i ] = 1 ;
ConflictTable [ j ] = 1 ;
}
}
}
}
// Populate display.
for ( i = 0 , idx = 0 ; i < EMUCMD_MAX ; + + i )
{
if ( ShouldDisplayMapping ( i , filter ) )
{
memset ( & lvi , 0 , sizeof ( lvi ) ) ;
lvi . mask = LVIF_TEXT | LVIF_PARAM ;
lvi . iItem = idx ;
lvi . iSubItem = 0 ;
lvi . pszText = ( char * ) FCEUI_CommandTypeNames [ FCEUI_CommandTable [ i ] . type ] ;
lvi . lParam = ( LPARAM ) i ;
SendMessage ( hwndListView , LVM_INSERTITEM , ( WPARAM ) 0 , ( LPARAM ) & lvi ) ;
memset ( & lvi , 0 , sizeof ( lvi ) ) ;
lvi . mask = LVIF_TEXT ;
lvi . iItem = idx ;
lvi . iSubItem = 1 ;
lvi . pszText = FCEUI_CommandTable [ i ] . name ;
SendMessage ( hwndListView , LVM_SETITEM , ( WPARAM ) 0 , ( LPARAM ) & lvi ) ;
memset ( & lvi , 0 , sizeof ( lvi ) ) ;
lvi . mask = LVIF_TEXT ;
lvi . iItem = idx ;
lvi . iSubItem = 2 ;
lvi . pszText = GetKeyComboName ( FCEUD_CommandMapping [ i ] ) ;
SendMessage ( hwndListView , LVM_SETITEM , ( WPARAM ) 0 , ( LPARAM ) & lvi ) ;
idx + + ;
}
}
if ( ConflictTable )
free ( ConflictTable ) ;
}
static BOOL CALLBACK MapInputDialogProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
switch ( uMsg )
{
case WM_INITDIALOG :
{
HWND hwndListView = GetDlgItem ( hwndDlg , 1003 ) ;
LVCOLUMN lv ;
2006-07-18 06:35:48 +00:00
//LVITEM lvi; //mbg merge 7/17/06 removed
2006-07-18 02:53:36 +00:00
int i ;
// Set full row select.
SendMessage ( hwndListView , LVM_SETEXTENDEDLISTVIEWSTYLE , LVS_EX_FULLROWSELECT , LVS_EX_FULLROWSELECT ) ;
// Init ListView columns.
memset ( & lv , 0 , sizeof ( lv ) ) ;
lv . mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH ;
lv . fmt = LVCFMT_LEFT ;
lv . pszText = " Type " ;
lv . cx = 40 ;
SendMessage ( hwndListView , LVM_INSERTCOLUMN , ( WPARAM ) 0 , ( LPARAM ) & lv ) ;
memset ( & lv , 0 , sizeof ( lv ) ) ;
lv . mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH ;
lv . fmt = LVCFMT_LEFT ;
lv . pszText = " Command " ;
lv . cx = 180 ;
SendMessage ( hwndListView , LVM_INSERTCOLUMN , ( WPARAM ) 1 , ( LPARAM ) & lv ) ;
memset ( & lv , 0 , sizeof ( lv ) ) ;
lv . mask = LVCF_FMT | LVCF_TEXT ;
lv . fmt = LVCFMT_LEFT ;
lv . pszText = " Input " ;
SendMessage ( hwndListView , LVM_INSERTCOLUMN , ( WPARAM ) 2 , ( LPARAM ) & lv ) ;
// Populate the filter combobox.
SendDlgItemMessage ( hwndDlg , 300 , CB_INSERTSTRING , 0 , ( LPARAM ) " None " ) ;
for ( i = 0 ; i < EMUCMDTYPE_MAX ; + + i )
SendDlgItemMessage ( hwndDlg , 300 , CB_INSERTSTRING , i + 1 , ( LPARAM ) FCEUI_CommandTypeNames [ i ] ) ;
SendDlgItemMessage ( hwndDlg , 300 , CB_INSERTSTRING , + + i , ( LPARAM ) " Assigned " ) ;
SendDlgItemMessage ( hwndDlg , 300 , CB_INSERTSTRING , + + i , ( LPARAM ) " Unassigned " ) ;
SendDlgItemMessage ( hwndDlg , 300 , CB_INSERTSTRING , + + i , ( LPARAM ) " Conflicts " ) ;
SendDlgItemMessage ( hwndDlg , 300 , CB_SETCURSEL , 0 , 0 ) ; // Default filter is "none".
// Now populate the mapping display.
PopulateMappingDisplay ( hwndDlg ) ;
// Autosize last column.
SendMessage ( hwndListView , LVM_SETCOLUMNWIDTH , ( WPARAM ) 2 , MAKELPARAM ( LVSCW_AUTOSIZE_USEHEADER , 0 ) ) ;
}
return FALSE ;
case WM_COMMAND :
if ( HIWORD ( wParam ) = = CBN_SELCHANGE )
{
PopulateMappingDisplay ( hwndDlg ) ;
break ;
}
switch ( LOWORD ( wParam ) )
{
case IDOK :
EndDialog ( hwndDlg , 1 ) ;
return TRUE ;
case IDCANCEL :
EndDialog ( hwndDlg , 0 ) ;
return TRUE ;
case 200 :
ApplyDefaultCommandMapping ( ) ;
PopulateMappingDisplay ( hwndDlg ) ;
return TRUE ;
default :
break ;
}
break ;
case WM_NOTIFY :
switch ( LOWORD ( wParam ) )
{
case 1003 :
if ( lParam )
{
HWND hwndListView = GetDlgItem ( hwndDlg , 1003 ) ;
NMHDR * pnm = ( NMHDR * ) lParam ;
if ( pnm - > code = = LVN_ITEMACTIVATE )
{
int nSel = SendMessage ( hwndListView , LVM_GETNEXTITEM , ( WPARAM ) - 1 , LVNI_SELECTED ) ;
if ( nSel ! = - 1 )
{
int nCmd ;
int nRet ;
LVITEM lvi ;
// Get the corresponding input
memset ( & lvi , 0 , sizeof ( lvi ) ) ;
lvi . mask = LVIF_PARAM ;
lvi . iItem = nSel ;
lvi . iSubItem = 0 ;
SendMessage ( hwndListView , LVM_GETITEM , 0 , ( LPARAM ) & lvi ) ;
nCmd = lvi . lParam ;
nRet = DialogBox ( fceu_hInstance , " NEWINPUT " , hwndListView , ChangeInputDialogProc ) ;
if ( nRet )
{
// nRet will be -1 when the user selects "clear".
FCEUD_CommandMapping [ nCmd ] = ( nRet < 0 ) ? 0 : nRet ;
memset ( & lvi , 0 , sizeof ( lvi ) ) ;
lvi . mask = LVIF_TEXT ;
lvi . iItem = nSel ;
lvi . iSubItem = 2 ;
lvi . pszText = GetKeyComboName ( FCEUD_CommandMapping [ nCmd ] ) ;
SendMessage ( hwndListView , LVM_SETITEM , ( WPARAM ) 0 , ( LPARAM ) & lvi ) ;
}
}
}
return TRUE ;
}
break ;
default :
break ;
}
break ;
default :
break ;
}
return FALSE ;
}
void MapInput ( void )
{
// Make a backup of the current mappings, in case the user changes their mind.
int * backupmapping = ( int * ) malloc ( sizeof ( FCEUD_CommandMapping ) ) ;
memcpy ( backupmapping , FCEUD_CommandMapping , sizeof ( FCEUD_CommandMapping ) ) ;
if ( ! DialogBox ( fceu_hInstance , " MAPINPUT " , hAppWnd , MapInputDialogProc ) )
memcpy ( FCEUD_CommandMapping , backupmapping , sizeof ( FCEUD_CommandMapping ) ) ;
free ( backupmapping ) ;
}
void FCEUD_TurboOn ( void )
{
NoWaiting | = 1 ;
}
void FCEUD_TurboOff ( void )
{
NoWaiting & = ~ 1 ;
}