source refactor, merge/modify more changes from Carl Kenner

This commit is contained in:
dborth 2009-03-04 07:01:04 +00:00
parent ea97d00742
commit bf304d5b82
33 changed files with 2448 additions and 164 deletions

View File

@ -18,9 +18,10 @@ include $(DEVKITPPC)/gamecube_rules
TARGET := vbagx_gc
TARGETDIR := executables
BUILD := build_gc
SOURCES := source/vba source/vba/apu source/vba/common \
source/vba/gb source/vba/gba \
source/ngc source/sz source/unzip
SOURCES := source/ngc/images source/ngc/sounds source/ngc/fonts \
source/ngc/gui source/ngc source/sz source/unzip \
source/vba source/vba/apu source/vba/common \
source/vba/gb source/vba/gba
INCLUDES := source/vba source/ngc source/unzip
#---------------------------------------------------------------------------------
@ -31,14 +32,16 @@ CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \
-DNGC -DUSE_VM -DWORDS_BIGENDIAN \
-DC_CORE -D__ppc__ -D__POWERPC__ -DFINAL_VERSION \
-DSDL -DNO_PNG -DHAVE_ZUTIL_H \
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ \
-fomit-frame-pointer -fno-exceptions \
-Wno-unused-parameter -Wno-strict-aliasing
CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with
#---------------------------------------------------------------------------------
LIBS := -lmxml -lbba -ltinysmb -lfat -lz -logc -lm -lfreetype
LIBS := -lpngu -lpng -lmxml -lbba -ltinysmb -lfat -lz -logc -lm -lfreetype
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
@ -67,7 +70,8 @@ CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
TTFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ttf)))
PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
@ -80,7 +84,8 @@ endif
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
$(sFILES:.s=.o) $(SFILES:.S=.o)
$(TTFFILES:.ttf=.ttf.o) \
$(PNGFILES:.png=.png.o)
#---------------------------------------------------------------------------------
# build a list of include paths
@ -131,10 +136,13 @@ $(OUTPUT).dol: $(OUTPUT).elf
$(OUTPUT).elf: $(OFILES)
#---------------------------------------------------------------------------------
# This rule links in binary data with the .jpg extension
#---------------------------------------------------------------------------------
%.jpg.o : %.jpg
# This rule links in binary data with .ttf and .png extensions
#---------------------------------------------------------------------------------
%.ttf.o : %.ttf
@echo $(notdir $<)
$(bin2o)
%.png.o : %.png
@echo $(notdir $<)
$(bin2o)

View File

@ -18,9 +18,10 @@ include $(DEVKITPPC)/wii_rules
TARGET := vbagx_wii
TARGETDIR := executables
BUILD := build_wii
SOURCES := source/vba source/vba/apu source/vba/common \
source/vba/gb source/vba/gba \
source/ngc source/sz source/unzip
SOURCES := source/ngc/images source/ngc/sounds source/ngc/fonts \
source/ngc/gui source/ngc source/sz source/unzip \
source/vba source/vba/apu source/vba/common \
source/vba/gb source/vba/gba
INCLUDES := source/vba source/ngc source/unzip
#---------------------------------------------------------------------------------
@ -28,17 +29,19 @@ INCLUDES := source/vba source/ngc source/unzip
#---------------------------------------------------------------------------------
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \
-DNGC -DWII_DVD -DWORDS_BIGENDIAN \
-DNGC -DWORDS_BIGENDIAN \
-DC_CORE -D__ppc__ -D__POWERPC__ -DFINAL_VERSION \
-DSDL -DNO_PNG -DHAVE_ZUTIL_H \
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ
-D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ \
-fomit-frame-pointer -fno-exceptions \
-Wno-unused-parameter -Wno-strict-aliasing
CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with
#---------------------------------------------------------------------------------
LIBS := -ldi -lmxml -lfat -lwiiuse -lz -lbte -logc -lm -lfreetype -ltinysmb
LIBS := -ldi -lpngu -lpng -lmxml -lfat -lwiiuse -lz -lbte -logc -lm -lfreetype -ltinysmb
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
@ -67,7 +70,8 @@ CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
TTFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ttf)))
PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
@ -80,7 +84,8 @@ endif
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
$(sFILES:.s=.o) $(SFILES:.S=.o)
$(TTFFILES:.ttf=.ttf.o) \
$(PNGFILES:.png=.png.o)
#---------------------------------------------------------------------------------
# build a list of include paths
@ -131,10 +136,13 @@ $(OUTPUT).dol: $(OUTPUT).elf
$(OUTPUT).elf: $(OFILES)
#---------------------------------------------------------------------------------
# This rule links in binary data with the .jpg extension
#---------------------------------------------------------------------------------
%.jpg.o : %.jpg
# This rule links in binary data with .ttf and .png extensions
#---------------------------------------------------------------------------------
%.ttf.o : %.ttf
@echo $(notdir $<)
$(bin2o)
%.png.o : %.png
@echo $(notdir $<)
$(bin2o)

View File

@ -1,7 +1,7 @@
¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤
- Visual Boy Advance GX -
Version 1.0.7
Version 1.0.8
http://code.google.com/p/vba-wii
(Under GPL License)
@ -12,7 +12,8 @@ With it you can play GBA/Game Boy Color/Game Boy games on your Wii/GameCube.
-=[ Features ]=-
* Wiimote, Nunchuk, Classic, and Gamecube controller support
* Wiimote, Nunchuk, Classic, Gamecube controller, Keyboard, and Mouse support
* Optional special Wii controls built-in for some games
* SRAM and State saving
* IPS/UPS/PPF patch support
* Custom controller configurations
@ -158,7 +159,7 @@ on these topics is the tehskeen forums: http://www.tehskeen.com/forums/
-=[ Credits ]=-
Visual Boy Advance GX Tantric
Visual Boy Advance GX Tantric, Carl Kenner
GameCube/Wii Port Improvements emukidid
Original GameCube Port SoftDev
Visual Boy Advance 1.7.2 Forgotten

View File

@ -24,7 +24,7 @@
* and for displaying the name of said button
***************************************************************************/
CtrlrMap ctrlr_def[4] = {
CtrlrMap ctrlr_def[5] = {
// Nunchuk btn def
{
CTRLR_NUNCHUK,
@ -112,6 +112,147 @@ CtrlrMap ctrlr_def[4] = {
{0, ""},
{0, ""}
}
},
// Keyboard btn def, see http://www.usb.org/developers/devclass_docs/Hut1_12.pdf
{
CTRLR_KEYBOARD,
150,
{
{4, "A"},
{5, "B"},
{6, "C"},
{7, "D"},
{8, "E"},
{9, "F"},
{10, "G"},
{11, "H"},
{12, "I"},
{13, "J"},
{14, "K"},
{15, "L"},
{16, "M"},
{17, "N"},
{18, "O"},
{19, "P"},
{20, "Q"},
{21, "R"},
{22, "S"},
{23, "T"},
{24, "U"},
{25, "V"},
{26, "W"},
{27, "X"},
{28, "Y"},
{29, "Z"},
{30, "1"},
{31, "2"},
{32, "3"},
{33, "4"},
{34, "5"},
{35, "6"},
{36, "7"},
{37, "8"},
{38, "9"},
{39, "0"},
{40, "ENTER"},
{41, "ESC"},
{42, "BKSP"},
{43, "TAB"},
{44, "SPACE"},
{45, "-"},
{46, "="},
{47, "["},
{48, "]"},
{49, "\\"},
{50, "#"},
{51, ";"},
{52, "'"},
{53, "`"},
{54, ","},
{55, "."},
{56, "/"},
{57, "CAPLK"},
{58, "F1"},
{59, "F2"},
{60, "F3"},
{61, "F4"},
{62, "F5"},
{63, "F6"},
{64, "F7"},
{65, "F8"},
{66, "F9"},
{67, "F10"},
{68, "F11"},
{69, "F12"},
{70, "PRTSC"},
{71, "SCRLK"},
{72, "PAUSE"},
{73, "INS"},
{74, "HOME"},
{75, "PGUP"},
{76, "DEL"},
{77, "END"},
{78, "PGDN"},
{79, "RIGHT"},
{80, "LEFT"},
{81, "DOWN"},
{82, "UP"},
{83, "NUMLK"},
{84, "NP/"},
{85, "NP*"},
{86, "NP-"},
{87, "NP+"},
{88, "NPENT"},
{89, "NP1"},
{90, "NP2"},
{91, "NP3"},
{92, "NP4"},
{93, "NP5"},
{94, "NP6"},
{95, "NP7"},
{96, "NP8"},
{97, "NP9"},
{98, "NP0"},
{99, "NP."},
{100, "\\|"},
{101, "APP"},
{102, "POWER"},
{103, "NP="},
{104, "F13"},
{105, "F14"},
{106, "F15"},
{107, "F16"},
{108, "F17"},
{109, "F18"},
{110, "F19"},
{111, "F20"},
{112, "F21"},
{113, "F22"},
{114, "F23"},
{115, "F24"},
{127, "MUTE"},
{128, "VOL+"},
{129, "VOL-"},
{144, "HANGL"},
{145, "HANJA"},
{146, "KATA"},
{147, "HIRA"},
{224, "LCTRL"},
{225, "LSHFT"},
{226, "LALT"},
{227, "LWIN"},
{228, "RCTRL"},
{229, "RSHFT"},
{230, "RALT"},
{231, "RWIN"},
{232, "MOUSEL"},
{233, "MOUSER"},
{234, "MOUSEM"},
}
}
};

View File

@ -17,6 +17,7 @@ enum {
CTRLR_CLASSIC,
CTRLR_GCPAD,
CTRLR_WIIMOTE,
CTRLR_KEYBOARD,
CTRLR_SNES = 7 // give some other value for the snes padmap
};
@ -28,11 +29,11 @@ typedef struct _btn_map {
typedef struct _ctrlr_map {
u16 type; // controller type
int num_btns; // number of buttons on the controller
BtnMap map[15]; // controller button map
BtnMap map[150]; // controller button map
} CtrlrMap;
// externs:
extern CtrlrMap ctrlr_def[4];
extern CtrlrMap ctrlr_def[5];
#endif

43
source/ngc/filelist.h Normal file
View File

@ -0,0 +1,43 @@
/****************************************************************************
* Visual Boy Advance GX
*
* Tantric March 2009
*
* filelist.h
*
* Contains a list of all of the files in the images/ folder
***************************************************************************/
#ifndef _FILELIST_H_
#define _FILELIST_H_
#include <gccore.h>
extern const u8 font_ttf[];
extern const u32 font_ttf_size;
extern const u8 player1_point_png[];
extern const u32 player1_point_png_size;
extern const u8 player2_point_png[];
extern const u32 player2_point_png_size;
extern const u8 player3_point_png[];
extern const u32 player3_point_png_size;
extern const u8 player4_point_png[];
extern const u32 player4_point_png_size;
extern const u8 player1_grab_png[];
extern const u32 player1_grab_png_size;
extern const u8 player2_grab_png[];
extern const u32 player2_grab_png_size;
extern const u8 player3_grab_png[];
extern const u32 player3_grab_png_size;
extern const u8 player4_grab_png[];
extern const u32 player4_grab_png_size;
#endif

View File

@ -34,6 +34,7 @@ extern "C" {
#include "dvd.h"
#include "networkop.h"
#include "gcunzip.h"
#include "wiiusbsupport.h"
BROWSERINFO browser;
BROWSERENTRY * browserList = NULL; // list of files/folders in browser
@ -342,11 +343,11 @@ int FileSelector (int method)
#endif
/*** Check for exit combo ***/
if ( (gc_sx < -70) || (wm_sx < -70) || (wp & WPAD_BUTTON_HOME) || (wp & WPAD_CLASSIC_BUTTON_HOME) )
if ( (gc_sx < -70) || (wm_sx < -70) || (wp & WPAD_BUTTON_HOME) || (wp & WPAD_CLASSIC_BUTTON_HOME) || DownUsbKeys[KB_ESC])
return 0;
/*** Check buttons, perform actions ***/
if ( (p & PAD_BUTTON_A) || selectit || (wp & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)) )
if ( (p & PAD_BUTTON_A) || selectit || (wp & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)) || DownUsbKeys[KB_ENTER] )
{
if ( selectit )
selectit = 0;
@ -434,7 +435,7 @@ int FileSelector (int method)
}
redraw = 1;
} // End of A
if ( (p & PAD_BUTTON_B) || (wp & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B)) )
if ( (p & PAD_BUTTON_B) || (wp & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B) || DownUsbKeys[KB_BKSP]))
{
while ( (PAD_ButtonsDown(0) & PAD_BUTTON_B)
#ifdef HW_RVL

View File

@ -1,12 +0,0 @@
# Fonts
.rodata
.globl fontface
.balign 32
fontface:
.incbin "../source/ngc/ttf/font.ttf"
.globl fontsize
fontsize: .long 28736

229
source/ngc/gui/gui.h Normal file
View File

@ -0,0 +1,229 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* Tantric February 2009
*
* gui.h
*
* GUI class definitions
***************************************************************************/
#ifndef GUI_H
#define GUI_H
#include <gccore.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <math.h>
#include <wiiuse/wpad.h>
#include <mp3player.h>
#include "pngu/pngu.h"
#include "FreeTypeGX.h"
#include "vba.h"
#include "video.h"
#include "filelist.h"
#include "fileop.h"
#include "menu.h"
#include "input.h"
#define PI 3.14159265f
#define PADCAL 50
#define SCROLL_INITIAL_DELAY 20
#define SCROLL_LOOP_DELAY 3
#define SAVELISTSIZE 6
typedef void (*UpdateCallback)(void * e);
typedef struct _paddata {
u16 btns_d;
u16 btns_u;
u16 btns_h;
s8 stickX;
s8 stickY;
s8 substickX;
s8 substickY;
u8 triggerL;
u8 triggerR;
} PADData;
enum
{
ALIGN_LEFT,
ALIGN_RIGHT,
ALIGN_CENTRE,
ALIGN_TOP,
ALIGN_BOTTOM,
ALIGN_MIDDLE
};
enum
{
STATE_DEFAULT,
STATE_SELECTED,
STATE_CLICKED,
STATE_DISABLED
};
enum
{
TRIGGER_SIMPLE,
TRIGGER_BUTTON_ONLY,
TRIGGER_BUTTON_ONLY_IN_FOCUS
};
#define EFFECT_SLIDE_TOP 1
#define EFFECT_SLIDE_BOTTOM 2
#define EFFECT_SLIDE_RIGHT 4
#define EFFECT_SLIDE_LEFT 8
#define EFFECT_SLIDE_IN 16
#define EFFECT_SLIDE_OUT 32
#define EFFECT_FADE 64
#define EFFECT_SCALE 128
#define EFFECT_COLOR_TRANSITION 256
enum
{
ON_CLICK,
ON_OVER
};
class GuiSound
{
public:
GuiSound(const u8 * s, int l);
~GuiSound();
void Play();
protected:
const u8 * sound;
s32 length;
};
class GuiTrigger
{
public:
GuiTrigger();
~GuiTrigger();
void SetSimpleTrigger(s32 ch, u32 wiibtns, u16 gcbtns);
void SetButtonOnlyTrigger(s32 ch, u32 wiibtns, u16 gcbtns);
void SetButtonOnlyInFocusTrigger(s32 ch, u32 wiibtns, u16 gcbtns);
s8 WPAD_Stick(u8 right, int axis);
bool Left();
bool Right();
bool Up();
bool Down();
u8 type;
s32 chan;
WPADData wpad;
PADData pad;
};
class GuiElement
{
public:
GuiElement();
~GuiElement();
void SetParent(GuiElement * e);
int GetLeft();
int GetTop();
int GetWidth();
int GetHeight();
void SetSize(int w, int h);
bool IsVisible();
bool IsSelectable();
bool IsClickable();
void SetSelectable(bool s);
void SetClickable(bool c);
int GetState();
void SetVisible(bool v);
void SetAlpha(int a);
int GetAlpha();
void SetScale(float s);
float GetScale();
void SetTrigger(GuiTrigger * t);
void SetTrigger(u8 i, GuiTrigger * t);
void SetEffect(int e, int a, int t=0);
void SetEffectOnOver(int e, int a, int t=0);
void SetEffectGrow();
int GetEffect();
bool IsInside(int x, int y);
void SetPosition(int x, int y);
void UpdateEffects();
void SetUpdateCallback(UpdateCallback u);
int IsFocused();
virtual void SetFocus(int f);
virtual void SetState(int s);
virtual void ResetState();
virtual int GetSelected();
virtual void SetAlignment(int hor, int vert);
virtual void Update(GuiTrigger * t);
virtual void Draw();
protected:
bool visible;
int focus; // -1 = cannot focus, 0 = not focused, 1 = focused
int width;
int height;
int xoffset;
int yoffset;
int xoffsetDyn;
int yoffsetDyn;
int alpha;
f32 scale;
int alphaDyn;
f32 scaleDyn;
int effects;
int effectAmount;
int effectTarget;
int effectsOver;
int effectAmountOver;
int effectTargetOver;
int alignmentHor; // LEFT, RIGHT, CENTRE
int alignmentVert; // TOP, BOTTOM, MIDDLE
int state; // DEFAULT, SELECTED, CLICKED, DISABLED
bool selectable; // is SELECTED a valid state?
bool clickable; // is CLICKED a valid state?
GuiTrigger * trigger[2];
GuiElement * parentElement;
UpdateCallback updateCB;
};
class GuiImageData
{
public:
GuiImageData(const u8 * i);
~GuiImageData();
u8 * GetImage();
int GetWidth();
int GetHeight();
protected:
u8 * data;
int height;
int width;
};
class GuiImage : public GuiElement
{
public:
GuiImage(GuiImageData * img);
GuiImage(u8 * img, int w, int h);
GuiImage(int w, int h, GXColor c);
~GuiImage();
void SetAngle(float a);
void SetTile(int t);
void Draw();
u8 * GetImage();
void SetImage(GuiImageData * img);
void SetImage(u8 * img, int w, int h);
GXColor GetPixel(int x, int y);
void SetPixel(int x, int y, GXColor color);
void Stripe(int s);
protected:
u8 * image;
f32 imageangle;
int tile;
};
#endif

View File

@ -0,0 +1,484 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* Tantric February 2009
*
* gui_element.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
/**
* Constructor for the Object class.
*/
GuiElement::GuiElement()
{
xoffset = 0;
yoffset = 0;
width = 0;
height = 0;
alpha = 255;
scale = 1;
state = STATE_DEFAULT;
trigger[0] = NULL;
trigger[1] = NULL;
parentElement = NULL;
selectable = false;
clickable = false;
visible = true;
focus = -1; // cannot be focused
updateCB = NULL;
yoffsetDyn = 0;
xoffsetDyn = 0;
alphaDyn = -1;
scaleDyn = 1;
effects = 0;
effectAmount = 0;
effectTarget = 0;
effectsOver = 0;
effectAmountOver = 0;
effectTargetOver = 0;
// default alignment - align to top left
alignmentVert = ALIGN_TOP;
alignmentHor = ALIGN_LEFT;
}
/**
* Destructor for the GuiElement class.
*/
GuiElement::~GuiElement()
{
}
void GuiElement::SetParent(GuiElement * e)
{
parentElement = e;
}
/**
* Get the left position of the GuiElement.
* @see SetLeft()
* @return Left position in pixel.
*/
int GuiElement::GetLeft()
{
int x = 0;
int pWidth = 0;
int pLeft = 0;
if(parentElement)
{
pWidth = parentElement->GetWidth();
pLeft = parentElement->GetLeft();
}
if(effects & (EFFECT_SLIDE_IN | EFFECT_SLIDE_OUT))
pLeft += xoffsetDyn;
switch(alignmentHor)
{
case ALIGN_LEFT:
x = pLeft;
break;
case ALIGN_CENTRE:
x = pLeft + (pWidth/2) - (width/2);
break;
case ALIGN_RIGHT:
x = pLeft + pWidth - width;
break;
}
return x + xoffset;
}
/**
* Get the top position of the GuiElement.
* @see SetTop()
* @return Top position in pixel.
*/
int GuiElement::GetTop()
{
int y = 0;
int pHeight = 0;
int pTop = 0;
if(parentElement)
{
pHeight = parentElement->GetHeight();
pTop = parentElement->GetTop();
}
if(effects & (EFFECT_SLIDE_IN | EFFECT_SLIDE_OUT))
pTop += yoffsetDyn;
switch(alignmentVert)
{
case ALIGN_TOP:
y = pTop;
break;
case ALIGN_MIDDLE:
y = pTop + (pHeight/2) - (height/2);
break;
case ALIGN_BOTTOM:
y = pTop + pHeight - height;
break;
}
return y + yoffset;
}
/**
* Get the width of the GuiElement.
* @see SetWidth()
* @return Width of the GuiElement.
*/
int GuiElement::GetWidth()
{
return width;
}
/**
* Get the height of the GuiElement.
* @see SetHeight()
* @return Height of the GuiElement.
*/
int GuiElement::GetHeight()
{
return height;
}
/**
* Set the width and height of the GuiElement.
* @param[in] Width Width in pixel.
* @param[in] Height Height in pixel.
* @see SetWidth()
* @see SetHeight()
*/
void GuiElement::SetSize(int w, int h)
{
width = w;
height = h;
}
/**
* Get visible.
* @see SetVisible()
* @return true if visible, false otherwise.
*/
bool GuiElement::IsVisible()
{
return visible;
}
/**
* Set visible.
* @param[in] Visible Set to true to show GuiElement.
* @see IsVisible()
*/
void GuiElement::SetVisible(bool v)
{
visible = v;
}
void GuiElement::SetAlpha(int a)
{
alpha = a;
}
int GuiElement::GetAlpha()
{
int a;
if(alphaDyn >= 0)
a = alphaDyn;
else
a = alpha;
if(parentElement)
a *= parentElement->GetAlpha()/255.0;
return a;
}
void GuiElement::SetScale(float s)
{
scale = s;
}
float GuiElement::GetScale()
{
float s = scale * scaleDyn;
if(parentElement)
s *= parentElement->GetScale();
return s;
}
int GuiElement::GetState()
{
return state;
}
void GuiElement::SetState(int s)
{
state = s;
}
void GuiElement::ResetState()
{
if(state != STATE_DISABLED)
state = STATE_DEFAULT;
}
void GuiElement::SetClickable(bool c)
{
clickable = c;
}
void GuiElement::SetSelectable(bool s)
{
selectable = s;
}
bool GuiElement::IsSelectable()
{
if(state == STATE_DISABLED || state == STATE_CLICKED)
return false;
else
return selectable;
}
bool GuiElement::IsClickable()
{
if(state == STATE_DISABLED || state == STATE_CLICKED)
return false;
else
return clickable;
}
void GuiElement::SetFocus(int f)
{
focus = f;
}
int GuiElement::IsFocused()
{
return focus;
}
void GuiElement::SetTrigger(GuiTrigger * t)
{
if(!trigger[0])
trigger[0] = t;
else if(!trigger[1])
trigger[1] = t;
else // both were assigned, so we'll just overwrite the first one
trigger[0] = t;
}
void GuiElement::SetTrigger(u8 i, GuiTrigger * t)
{
trigger[i] = t;
}
int GuiElement::GetEffect()
{
return effects;
}
void GuiElement::SetEffect(int eff, int amount, int target)
{
if(eff & EFFECT_SLIDE_IN)
{
// these calculations overcompensate a little
if(eff & EFFECT_SLIDE_TOP)
yoffsetDyn = -screenheight;
else if(eff & EFFECT_SLIDE_LEFT)
xoffsetDyn = -screenwidth;
else if(eff & EFFECT_SLIDE_BOTTOM)
yoffsetDyn = screenheight;
else if(eff & EFFECT_SLIDE_RIGHT)
xoffsetDyn = screenwidth;
}
if(eff & EFFECT_FADE && amount > 0)
{
alphaDyn = 0;
}
else if(eff & EFFECT_FADE && amount < 0)
{
alphaDyn = alpha;
}
effects |= eff;
effectAmount = amount;
effectTarget = target;
}
void GuiElement::SetEffectOnOver(int eff, int amount, int target)
{
effectsOver |= eff;
effectAmountOver = amount;
effectTargetOver = target;
}
void GuiElement::SetEffectGrow()
{
SetEffectOnOver(EFFECT_SCALE, 4, 110);
}
void GuiElement::UpdateEffects()
{
if(effects & (EFFECT_SLIDE_IN | EFFECT_SLIDE_OUT))
{
if(effects & EFFECT_SLIDE_IN)
{
if(effects & EFFECT_SLIDE_LEFT)
{
xoffsetDyn += effectAmount;
if(xoffsetDyn >= 0)
{
xoffsetDyn = 0;
effects = 0;
}
}
else if(effects & EFFECT_SLIDE_RIGHT)
{
xoffsetDyn -= effectAmount;
if(xoffsetDyn <= 0)
{
xoffsetDyn = 0;
effects = 0;
}
}
else if(effects & EFFECT_SLIDE_TOP)
{
yoffsetDyn += effectAmount;
if(yoffsetDyn >= 0)
{
yoffsetDyn = 0;
effects = 0;
}
}
else if(effects & EFFECT_SLIDE_BOTTOM)
{
yoffsetDyn -= effectAmount;
if(yoffsetDyn <= 0)
{
yoffsetDyn = 0;
effects = 0;
}
}
}
else
{
if(effects & EFFECT_SLIDE_LEFT)
{
xoffsetDyn -= effectAmount;
if(xoffsetDyn <= -screenwidth)
effects = 0; // shut off effect
}
else if(effects & EFFECT_SLIDE_RIGHT)
{
xoffsetDyn += effectAmount;
if(xoffsetDyn >= screenwidth)
effects = 0; // shut off effect
}
else if(effects & EFFECT_SLIDE_TOP)
{
yoffsetDyn -= effectAmount;
if(yoffsetDyn <= -screenheight)
effects = 0; // shut off effect
}
else if(effects & EFFECT_SLIDE_BOTTOM)
{
yoffsetDyn += effectAmount;
if(yoffsetDyn >= screenheight)
effects = 0; // shut off effect
}
}
}
if(effects & EFFECT_FADE)
{
alphaDyn += effectAmount;
if(effectAmount < 0 && alphaDyn <= 0)
{
alphaDyn = 0;
effects = 0; // shut off effect
}
else if(effectAmount > 0 && alphaDyn >= alpha)
{
alphaDyn = alpha;
effects = 0; // shut off effect
}
}
if(effects & EFFECT_SCALE)
{
scaleDyn += effectAmount/100.0;
if((effectAmount < 0 && scaleDyn <= effectTarget/100.0)
|| (effectAmount > 0 && scaleDyn >= effectTarget/100.0))
{
scaleDyn = effectTarget/100.0;
effects = 0; // shut off effect
}
}
}
void GuiElement::Update(GuiTrigger * t)
{
if(updateCB)
updateCB(this);
}
void GuiElement::SetUpdateCallback(UpdateCallback u)
{
updateCB = u;
}
void GuiElement::SetPosition(int xoff, int yoff)
{
xoffset = xoff;
yoffset = yoff;
}
void GuiElement::SetAlignment(int hor, int vert)
{
alignmentHor = hor;
alignmentVert = vert;
}
int GuiElement::GetSelected()
{
return -1;
}
/**
* Draw an element on screen.
*/
void GuiElement::Draw()
{
}
/**
* Check if a position is inside the GuiElement.
* @param[in] x X position in pixel.
* @param[in] y Y position in pixel.
*/
bool GuiElement::IsInside(int x, int y)
{
if(x > this->GetLeft() && x < (this->GetLeft()+width)
&& y > this->GetTop() && y < (this->GetTop()+height))
return true;
return false;
}

View File

@ -0,0 +1,65 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* Tantric February 2009
*
* gui_imagedata.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
/**
* Constructor for the GuiImageData class.
*/
GuiImageData::GuiImageData(const u8 * img)
{
if(img == NULL)
{
data = NULL;
width = 0;
height = 0;
}
else
{
PNGUPROP imgProp;
IMGCTX ctx;
ctx = PNGU_SelectImageFromBuffer(img);
PNGU_GetImageProperties (ctx, &imgProp);
width = imgProp.imgWidth;
height = imgProp.imgHeight;
data = (u8 *)memalign (32, imgProp.imgWidth * imgProp.imgHeight * 4);
PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, data, 255);
PNGU_ReleaseImageContext (ctx);
DCFlushRange (data, imgProp.imgWidth * imgProp.imgHeight * 4);
}
}
/**
* Destructor for the GuiImageData class.
*/
GuiImageData::~GuiImageData()
{
if(data)
{
free(data);
data = NULL;
}
}
u8 * GuiImageData::GetImage()
{
return data;
}
int GuiImageData::GetWidth()
{
return width;
}
int GuiImageData::GetHeight()
{
return height;
}

View File

@ -0,0 +1,232 @@
/****************************************************************************
* Snes9x 1.51 Nintendo Wii/Gamecube Port
*
* Tantric February 2009
*
* gui_trigger.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
static int scrollDelay = 0;
/**
* Constructor for the GuiTrigger class.
*/
GuiTrigger::GuiTrigger()
{
chan = -1;
memset(&wpad, 0, sizeof(WPADData));
memset(&pad, 0, sizeof(PADData));
}
/**
* Destructor for the GuiTrigger class.
*/
GuiTrigger::~GuiTrigger()
{
}
/**
* Sets a simple trigger. Requires:
* - Element is selected
* - Trigger button is pressed
*/
void GuiTrigger::SetSimpleTrigger(s32 ch, u32 wiibtns, u16 gcbtns)
{
type = TRIGGER_SIMPLE;
chan = ch;
wpad.btns_d = wiibtns;
pad.btns_d = gcbtns;
}
/**
* Sets a button trigger. Requires:
* - Trigger button is pressed
*/
void GuiTrigger::SetButtonOnlyTrigger(s32 ch, u32 wiibtns, u16 gcbtns)
{
type = TRIGGER_BUTTON_ONLY;
chan = ch;
wpad.btns_d = wiibtns;
pad.btns_d = gcbtns;
}
/**
* Sets a button trigger. Requires:
* - Trigger button is pressed
* - Parent window is in focus
*/
void GuiTrigger::SetButtonOnlyInFocusTrigger(s32 ch, u32 wiibtns, u16 gcbtns)
{
type = TRIGGER_BUTTON_ONLY_IN_FOCUS;
chan = ch;
wpad.btns_d = wiibtns;
pad.btns_d = gcbtns;
}
/****************************************************************************
* WPAD_Stick
*
* Get X/Y value from Wii Joystick (classic, nunchuk) input
***************************************************************************/
s8 GuiTrigger::WPAD_Stick(u8 right, int axis)
{
float mag = 0.0;
float ang = 0.0;
switch (wpad.exp.type)
{
case WPAD_EXP_NUNCHUK:
case WPAD_EXP_GUITARHERO3:
if (right == 0)
{
mag = wpad.exp.nunchuk.js.mag;
ang = wpad.exp.nunchuk.js.ang;
}
break;
case WPAD_EXP_CLASSIC:
if (right == 0)
{
mag = wpad.exp.classic.ljs.mag;
ang = wpad.exp.classic.ljs.ang;
}
else
{
mag = wpad.exp.classic.rjs.mag;
ang = wpad.exp.classic.rjs.ang;
}
break;
default:
break;
}
/* calculate x/y value (angle need to be converted into radian) */
if (mag > 1.0) mag = 1.0;
else if (mag < -1.0) mag = -1.0;
double val;
if(axis == 0) // x-axis
val = mag * sin((PI * ang)/180.0f);
else // y-axis
val = mag * cos((PI * ang)/180.0f);
return (s8)(val * 128.0f);
}
bool GuiTrigger::Left()
{
u32 wiibtn = GCSettings.WiimoteOrientation ? WPAD_BUTTON_UP : WPAD_BUTTON_LEFT;
if((wpad.btns_d | wpad.btns_h) & (wiibtn | WPAD_CLASSIC_BUTTON_LEFT)
|| pad.btns_d & PAD_BUTTON_LEFT
|| pad.stickX < -PADCAL
|| WPAD_Stick(0,0) < -PADCAL)
{
if(wpad.btns_d & (wiibtn | WPAD_CLASSIC_BUTTON_LEFT)
|| pad.btns_d & PAD_BUTTON_LEFT)
{
scrollDelay = SCROLL_INITIAL_DELAY; // reset scroll delay.
return true;
}
else if(scrollDelay == 0)
{
scrollDelay = SCROLL_LOOP_DELAY;
return true;
}
else
{
scrollDelay--;
}
}
return false;
}
bool GuiTrigger::Right()
{
u32 wiibtn = GCSettings.WiimoteOrientation ? WPAD_BUTTON_DOWN : WPAD_BUTTON_RIGHT;
if((wpad.btns_d | wpad.btns_h) & (wiibtn | WPAD_CLASSIC_BUTTON_RIGHT)
|| pad.btns_d & PAD_BUTTON_RIGHT
|| pad.stickX > PADCAL
|| WPAD_Stick(0,0) > PADCAL)
{
if(wpad.btns_d & (wiibtn | WPAD_CLASSIC_BUTTON_RIGHT)
|| pad.btns_d & PAD_BUTTON_RIGHT)
{
scrollDelay = SCROLL_INITIAL_DELAY; // reset scroll delay.
return true;
}
else if(scrollDelay == 0)
{
scrollDelay = SCROLL_LOOP_DELAY;
return true;
}
else
{
scrollDelay--;
}
}
return false;
}
bool GuiTrigger::Up()
{
u32 wiibtn = GCSettings.WiimoteOrientation ? WPAD_BUTTON_RIGHT : WPAD_BUTTON_UP;
if((wpad.btns_d | wpad.btns_h) & (wiibtn | WPAD_CLASSIC_BUTTON_UP)
|| pad.btns_d & PAD_BUTTON_UP
|| pad.stickY > PADCAL
|| WPAD_Stick(0,1) > PADCAL)
{
if(wpad.btns_d & (wiibtn | WPAD_CLASSIC_BUTTON_UP)
|| pad.btns_d & PAD_BUTTON_UP)
{
scrollDelay = SCROLL_INITIAL_DELAY; // reset scroll delay.
return true;
}
else if(scrollDelay == 0)
{
scrollDelay = SCROLL_LOOP_DELAY;
return true;
}
else
{
scrollDelay--;
}
}
return false;
}
bool GuiTrigger::Down()
{
u32 wiibtn = GCSettings.WiimoteOrientation ? WPAD_BUTTON_LEFT : WPAD_BUTTON_DOWN;
if((wpad.btns_d | wpad.btns_h) & (wiibtn | WPAD_CLASSIC_BUTTON_DOWN)
|| (pad.btns_d | pad.btns_h) & PAD_BUTTON_DOWN
|| pad.stickY < -PADCAL
|| WPAD_Stick(0,1) < -PADCAL)
{
if(wpad.btns_d & (wiibtn | WPAD_CLASSIC_BUTTON_DOWN)
|| pad.btns_d & PAD_BUTTON_DOWN)
{
scrollDelay = SCROLL_INITIAL_DELAY; // reset scroll delay.
return true;
}
else if(scrollDelay == 0)
{
scrollDelay = SCROLL_LOOP_DELAY;
return true;
}
else
{
scrollDelay--;
}
}
return false;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -22,26 +22,22 @@
#include "audio.h"
#include "video.h"
#include "input.h"
#include "gameinput.h"
#include "vbasupport.h"
#include "wiiusbsupport.h"
#include "gba/GBA.h"
#include "gba/bios.h"
#include "gba/GBAinline.h"
#define VBA_BUTTON_A 1
#define VBA_BUTTON_B 2
#define VBA_BUTTON_SELECT 4
#define VBA_BUTTON_START 8
#define VBA_RIGHT 16
#define VBA_LEFT 32
#define VBA_UP 64
#define VBA_DOWN 128
#define VBA_BUTTON_R 256
#define VBA_BUTTON_L 512
#define VBA_SPEED 1024
#define VBA_CAPTURE 2048
int rumbleRequest[4] = {0,0,0,0};
static int rumbleCount[4] = {0,0,0,0};
unsigned int vbapadmap[10]; // VBA controller buttons
unsigned int gcpadmap[10]; // Gamecube controller Padmap
unsigned int wmpadmap[10]; // Wiimote Padmap
unsigned int ccpadmap[10]; // Classic Controller Padmap
unsigned int ncpadmap[10]; // Nunchuk + wiimote Padmap
unsigned int kbpadmap[10]; // Keyboard Padmap
void ResetControls()
{
@ -112,6 +108,57 @@ void ResetControls()
ncpadmap[i++] = WPAD_BUTTON_RIGHT;
ncpadmap[i++] = WPAD_BUTTON_2;
ncpadmap[i++] = WPAD_BUTTON_1;
/*** Keyboard map ***/
i=0;
kbpadmap[i++] = KB_X; // VBA stupidly has B on the right instead of left
kbpadmap[i++] = KB_Z;
kbpadmap[i++] = KB_BKSP;
kbpadmap[i++] = KB_ENTER;
kbpadmap[i++] = KB_UP;
kbpadmap[i++] = KB_DOWN;
kbpadmap[i++] = KB_LEFT;
kbpadmap[i++] = KB_RIGHT;
kbpadmap[i++] = KB_A;
kbpadmap[i++] = KB_S;
}
/****************************************************************************
* ShutoffRumble
***************************************************************************/
void ShutoffRumble()
{
#ifdef HW_RVL
for(int i=0;i<4;i++)
{
WPAD_Rumble(i, 0);
}
#endif
}
/****************************************************************************
* DoRumble
***************************************************************************/
void DoRumble(int i)
{
if(rumbleRequest[i] && rumbleCount[i] < 3)
{
WPAD_Rumble(i, 1); // rumble on
rumbleCount[i]++;
}
else if(rumbleRequest[i])
{
rumbleCount[i] = 12;
rumbleRequest[i] = 0;
}
else
{
if(rumbleCount[i])
rumbleCount[i]--;
WPAD_Rumble(i, 0); // rumble off
}
}
/****************************************************************************
@ -167,33 +214,17 @@ s8 WPAD_Stick(u8 chan, u8 right, int axis)
return (s8)(val * 128.0f);
}
/****************************************************************************
* DecodeJoy
*
* Reads the changes (buttons pressed, etc) from a controller and reports
* these changes to VBA
****************************************************************************/
static u32 DecodeJoy(unsigned short pad)
u32 StandardMovement(unsigned short pad)
{
u32 J = 0;
signed char pad_x = PAD_StickX (pad);
signed char pad_y = PAD_StickY (pad);
signed char gc_px = PAD_SubStickX (0);
u32 jp = PAD_ButtonsHeld (pad);
u32 J = 0;
#ifdef HW_RVL
signed char wm_ax = WPAD_Stick ((u8)pad, 0, 0);
signed char wm_ay = WPAD_Stick ((u8)pad, 0, 1);
u32 wp = WPAD_ButtonsHeld (pad);
signed char wm_sx = WPAD_Stick (0,1,0); // CC right joystick
u32 exp_type;
if ( WPAD_Probe(pad, &exp_type) != 0 ) exp_type = WPAD_EXP_NONE;
#endif
/***
Gamecube Joystick input
Gamecube Joystick input, same as normal
***/
// Is XY inside the "zone"?
if (pad_x * pad_x + pad_y * pad_y > PADCAL * PADCAL)
@ -265,6 +296,335 @@ static u32 DecodeJoy(unsigned short pad)
}
}
}
// Turbo feature, keyboard or gamecube only
if(DownUsbKeys[KB_SPACE])
J |= VBA_SPEED;
// Capture feature
if(DownUsbKeys[KB_PRTSC] | DownUsbKeys[KB_F12])
J |= VBA_CAPTURE;
#endif
return J;
}
u32 StandardDPad(unsigned short pad)
{
u32 J = 0;
u32 jp = PAD_ButtonsHeld(pad);
#ifdef HW_RVL
u32 exp_type;
if ( WPAD_Probe(pad, &exp_type) != 0 )
exp_type = WPAD_EXP_NONE;
u32 wp = WPAD_ButtonsHeld(pad);
if (wp & WPAD_BUTTON_RIGHT)
J |= VBA_RIGHT;
if (wp & WPAD_BUTTON_LEFT)
J |= VBA_LEFT;
if (wp & WPAD_BUTTON_UP)
J |= VBA_UP;
if (wp & WPAD_BUTTON_DOWN)
J |= VBA_DOWN;
if (exp_type == WPAD_EXP_CLASSIC)
{
if (wp & WPAD_CLASSIC_BUTTON_UP)
J |= VBA_UP;
if (wp & WPAD_CLASSIC_BUTTON_DOWN)
J |= VBA_DOWN;
if (wp & WPAD_CLASSIC_BUTTON_LEFT)
J |= VBA_LEFT;
if (wp & WPAD_CLASSIC_BUTTON_RIGHT)
J |= VBA_RIGHT;
}
#endif
if (jp & PAD_BUTTON_UP)
J |= VBA_UP;
if (jp & PAD_BUTTON_DOWN)
J |= VBA_DOWN;
if (jp & PAD_BUTTON_LEFT)
J |= VBA_LEFT;
if (jp & PAD_BUTTON_RIGHT)
J |= VBA_RIGHT;
return J;
}
u32 StandardSideways(unsigned short pad)
{
u32 J = 0;
#ifdef HW_RVL
u32 wp = WPAD_ButtonsHeld(pad);
if (wp & WPAD_BUTTON_RIGHT)
J |= VBA_UP;
if (wp & WPAD_BUTTON_LEFT)
J |= VBA_DOWN;
if (wp & WPAD_BUTTON_UP)
J |= VBA_LEFT;
if (wp & WPAD_BUTTON_DOWN)
J |= VBA_RIGHT;
if (wp & WPAD_BUTTON_PLUS)
J |= VBA_BUTTON_START;
if (wp & WPAD_BUTTON_MINUS)
J |= VBA_BUTTON_SELECT;
if (wp & WPAD_BUTTON_1)
J |= VBA_BUTTON_B;
if (wp & WPAD_BUTTON_2)
J |= VBA_BUTTON_A;
if (cartridgeType == 2)
{
if (wp & WPAD_BUTTON_A)
J |= VBA_BUTTON_R;
if (wp & WPAD_BUTTON_B)
J |= VBA_BUTTON_L;
}
else
{
if (wp & WPAD_BUTTON_B || wp & WPAD_BUTTON_A)
J |= VBA_SPEED;
}
#endif
return J;
}
u32 StandardClassic(unsigned short pad)
{
u32 J = 0;
#ifdef HW_RVL
u32 wp = WPAD_ButtonsHeld(pad);
if (wp & WPAD_CLASSIC_BUTTON_RIGHT)
J |= VBA_RIGHT;
if (wp & WPAD_CLASSIC_BUTTON_LEFT)
J |= VBA_LEFT;
if (wp & WPAD_CLASSIC_BUTTON_UP)
J |= VBA_UP;
if (wp & WPAD_CLASSIC_BUTTON_DOWN)
J |= VBA_DOWN;
if (wp & WPAD_CLASSIC_BUTTON_PLUS)
J |= VBA_BUTTON_START;
if (wp & WPAD_CLASSIC_BUTTON_MINUS)
J |= VBA_BUTTON_SELECT;
if (wp & WPAD_CLASSIC_BUTTON_FULL_L || wp & WPAD_CLASSIC_BUTTON_ZL)
J |= VBA_BUTTON_L;
if (wp & WPAD_CLASSIC_BUTTON_FULL_R || wp & WPAD_CLASSIC_BUTTON_ZR)
J |= VBA_BUTTON_R;
if (wp & WPAD_CLASSIC_BUTTON_A)
J |= VBA_BUTTON_A;
if (wp & WPAD_CLASSIC_BUTTON_B)
J |= VBA_BUTTON_B;
if (wp & WPAD_CLASSIC_BUTTON_Y || wp & WPAD_CLASSIC_BUTTON_X)
J |= VBA_SPEED;
#endif
return J;
}
u32 StandardGamecube(unsigned short pad)
{
u32 J = 0;
u32 jp = PAD_ButtonsHeld(pad);
if (jp & PAD_BUTTON_UP)
J |= VBA_UP;
if (jp & PAD_BUTTON_DOWN)
J |= VBA_DOWN;
if (jp & PAD_BUTTON_LEFT)
J |= VBA_LEFT;
if (jp & PAD_BUTTON_RIGHT)
J |= VBA_RIGHT;
if (jp & PAD_BUTTON_A)
J |= VBA_BUTTON_A;
if (jp & PAD_BUTTON_B)
J |= VBA_BUTTON_B;
if (jp & PAD_BUTTON_START)
J |= VBA_BUTTON_START;
if (jp & PAD_BUTTON_X)
J |= VBA_BUTTON_SELECT;
if (jp & PAD_TRIGGER_L)
J |= VBA_BUTTON_L;
if (jp & PAD_TRIGGER_R)
J |= VBA_BUTTON_R;
if (jp & PAD_TRIGGER_Z || jp & PAD_BUTTON_Y)
J |= VBA_SPEED;
return J;
}
u32 StandardKeyboard(unsigned short pad)
{
u32 J = 0;
#ifdef HW_RVL
if (DownUsbKeys[KB_UP])
J |= VBA_UP;
if (DownUsbKeys[KB_DOWN])
J |= VBA_DOWN;
if (DownUsbKeys[KB_LEFT])
J |= VBA_LEFT;
if (DownUsbKeys[KB_RIGHT])
J |= VBA_RIGHT;
if (DownUsbKeys[KB_SPACE])
J |= VBA_SPEED;
if (DownUsbKeys[KB_F12] || DownUsbKeys[KB_PRTSC])
J |= VBA_CAPTURE;
if (DownUsbKeys[KB_X])
J |= VBA_BUTTON_A;
if (DownUsbKeys[KB_Z])
J |= VBA_BUTTON_B;
if (DownUsbKeys[KB_A])
J |= VBA_BUTTON_L;
if (DownUsbKeys[KB_S])
J |= VBA_BUTTON_R;
if (DownUsbKeys[KB_ENTER])
J |= VBA_BUTTON_START;
if (DownUsbKeys[KB_BKSP])
J |= VBA_BUTTON_SELECT;
#endif
return J;
}
/****************************************************************************
* DecodeJoy
*
* Reads the STATE (not changes) from a controller and reports
* this STATE (not changes) to VBA
****************************************************************************/
static u32 DecodeJoy(unsigned short pad)
{
TiltScreen = false;
#ifdef HW_RVL
WPADData * wp = WPAD_Data(pad);
CursorX = wp->ir.x;
CursorY = wp->ir.y;
CursorValid = wp->ir.valid;
// check for games that should have special Wii controls (uses wiimote + nunchuk)
if (GCSettings.WiiControls && wp->exp.type == WPAD_EXP_NUNCHUK)
{
switch (RomIdCode & 0xFFFFFF)
{
// Zelda
case ZELDA1:
return Zelda1Input(pad);
case ZELDA2:
return Zelda2Input(pad);
case ALINKTOTHEPAST:
return ALinkToThePastInput(pad);
case LINKSAWAKENING:
return LinksAwakeningInput(pad);
case ORACLEOFAGES:
case ORACLEOFSEASONS:
return OracleOfAgesInput(pad);
case MINISHCAP:
return MinishCapInput(pad);
// Metroid
case METROID0:
return MetroidZeroInput(pad);
// TMNT
case TMNT:
return TMNTInput(pad);
// Medal Of Honor
case MOHUNDERGROUND:
return MohUndergroundInput(pad);
case MOHINFILTRATOR:
return MohInfiltratorInput(pad);
// Harry Potter
case HARRYPOTTER1GBC:
return HarryPotter1GBCInput(pad);
case HARRYPOTTER2GBC:
return HarryPotter2GBCInput(pad);
case HARRYPOTTER1:
return HarryPotter1Input(pad);
case HARRYPOTTER2:
return HarryPotter2Input(pad);
case HARRYPOTTER3:
return HarryPotter3Input(pad);
case HARRYPOTTER4:
return HarryPotter4Input(pad);
case HARRYPOTTER5:
return HarryPotter5Input(pad);
// Mario
case MARIO1CLASSIC:
case MARIO2CLASSIC:
return Mario1ClassicInput(pad);
case MARIO1DX:
return Mario1DXInput(pad);
case MARIO2ADV:
return Mario2Input(pad);
case MARIO3ADV:
return Mario3Input(pad);
case MARIOWORLD:
return MarioWorldInput(pad);
case YOSHIISLAND:
return YoshiIslandInput(pad);
case MARIOLAND1:
return MarioLand1Input(pad);
case MARIOLAND2:
return MarioLand2Input(pad);
case YOSHIUG:
return UniversalGravitationInput(pad);
// Mario Kart
case MARIOKART:
return MarioKartInput(pad);
// Lego Star Wars
case LSW1:
return LegoStarWars1Input(pad);
case LSW2:
return LegoStarWars2Input(pad);
// Mortal Kombat
case MK1:
return MK1Input(pad);
case MK2:
case MK3:
case MK4:
return MK4Input(pad);
case MKA:
return MKAInput(pad);
case MKDA:
case MKTE:
return MKTEInput(pad);
// WarioWare
case TWISTED: //CAKTODO move this somewhere not depended on WiiControls setting
return TwistedInput(pad);
// Kirby
case KIRBYTNT:
case KIRBYTNTJ:
return KirbyTntInput(pad);
// Boktai
case BOKTAI1:
return BoktaiInput(pad);
case BOKTAI2:
case BOKTAI3:
return Boktai2Input(pad);
}
}
else
{
ShutoffRumble();
}
#endif
// the function result, J, is a combination of flags for all the VBA buttons that are down
u32 J = StandardMovement(pad);
signed char gc_px = PAD_SubStickX(0);
u32 jp = PAD_ButtonsHeld(pad);
#ifdef HW_RVL
signed char wm_sx = WPAD_Stick (0,1,0); // CC right joystick
#endif
// Turbo feature
@ -272,7 +632,7 @@ static u32 DecodeJoy(unsigned short pad)
(gc_px > 70)
#ifdef HW_RVL
|| (wm_sx > 70)
|| ((wp & WPAD_BUTTON_A) && (wp & WPAD_BUTTON_B))
|| ((wp->btns_h & WPAD_BUTTON_A) && (wp->btns_h & WPAD_BUTTON_B))
#endif
)
J |= VBA_SPEED;
@ -284,9 +644,10 @@ static u32 DecodeJoy(unsigned short pad)
{
if ((jp & gcpadmap[i]) // gamecube controller
#ifdef HW_RVL
|| ( (exp_type == WPAD_EXP_NONE) && (wp & wmpadmap[i]) ) // wiimote
|| ( (exp_type == WPAD_EXP_CLASSIC) && (wp & ccpadmap[i]) ) // classic controller
|| ( (exp_type == WPAD_EXP_NUNCHUK) && (wp & ncpadmap[i]) ) // nunchuk + wiimote
|| ( (wp->exp.type == WPAD_EXP_NONE) && (wp->btns_h & wmpadmap[i]) ) // wiimote
|| ( (wp->exp.type == WPAD_EXP_CLASSIC) && (wp->btns_h & ccpadmap[i]) ) // classic controller
|| ( (wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & ncpadmap[i]) ) // nunchuk + wiimote
|| ( (DownUsbKeys[kbpadmap[i]]) ) // keyboard
#endif
)
J |= vbapadmap[i];
@ -327,6 +688,7 @@ u32 GetJoy(int pad)
#ifdef HW_RVL
|| (wm_pb & WPAD_BUTTON_HOME)
|| (wm_pb & WPAD_CLASSIC_BUTTON_HOME)
|| (DownUsbKeys[KB_ESC])
#endif
)
{

View File

@ -17,14 +17,31 @@
#define PADCAL 50
#define MAXJP 10
#define VBA_BUTTON_A 1
#define VBA_BUTTON_B 2
#define VBA_BUTTON_SELECT 4
#define VBA_BUTTON_START 8
#define VBA_RIGHT 16
#define VBA_LEFT 32
#define VBA_UP 64
#define VBA_DOWN 128
#define VBA_BUTTON_R 256
#define VBA_BUTTON_L 512
#define VBA_SPEED 1024
#define VBA_CAPTURE 2048
extern int rumbleRequest[4];
extern unsigned int gcpadmap[];
extern unsigned int wmpadmap[];
extern unsigned int ccpadmap[];
extern unsigned int ncpadmap[];
extern unsigned int kbpadmap[];
void ResetControls();
void ShutoffRumble();
void DoRumble(int i);
s8 WPAD_Stick(u8 chan,u8 right, int axis);
u32 GetJoy(int which);
#endif

View File

@ -36,6 +36,7 @@ extern "C" {
#include "menudraw.h"
#include "input.h"
#include "vbaconfig.h"
#include "wiiusbsupport.h"
extern "C"
{
@ -140,6 +141,12 @@ PreferencesMenu ()
sprintf (prefmenu[6], "Verify MC Saves %s", GCSettings.VerifySaves == true ? " ON" : "OFF");
#endif
// disable Widescreen correction in Wii mode - determined automatically
#ifdef HW_RVL
if(GCSettings.scaling == 3)
GCSettings.scaling = 0;
#endif
// correct load/save methods out of bounds
if(GCSettings.LoadMethod > 4)
GCSettings.LoadMethod = 0;
@ -190,8 +197,14 @@ PreferencesMenu ()
if (GCSettings.render == 2)
sprintf (prefmenu[8], "Video Rendering Unfiltered");
sprintf (prefmenu[9], "Video Scaling %s",
GCSettings.widescreen == true ? "16:9 Correction" : "Default");
if (GCSettings.scaling == 0)
sprintf (prefmenu[9], "Video Scaling Maintain Aspect Ratio");
else if (GCSettings.scaling == 1)
sprintf (prefmenu[9], "Video Scaling Partial Stretch");
else if (GCSettings.scaling == 2)
sprintf (prefmenu[9], "Video Scaling Stretch to Fit");
else if (GCSettings.scaling == 3)
sprintf (prefmenu[9], "Video Scaling 16:9 Correction");
ret = RunMenu (prefmenu, prefmenuCount, "Preferences", 16);
@ -240,7 +253,9 @@ PreferencesMenu ()
break;
case 9:
GCSettings.widescreen ^= 1;
GCSettings.scaling++;
if (GCSettings.scaling > 3)
GCSettings.scaling = 0;
break;
case 10:
@ -266,13 +281,14 @@ PreferencesMenu ()
static int
GameMenu ()
{
int gamemenuCount = 8;
int gamemenuCount = 9;
char gamemenu[][50] = {
"Return to Game",
"Reset Game",
"Load SRAM", "Save SRAM",
"Load Game Snapshot", "Save Game Snapshot",
"Reset Zoom",
"Weather: 100% sun",
"Back to Main Menu"
};
@ -303,6 +319,12 @@ GameMenu ()
if(!GCSettings.Zoom)
gamemenu[6][0] = '\0';
// Weather menu if a game with Boktai solar sensor
if ((RomIdCode & 0xFF)=='U')
sprintf(gamemenu[7], "Weather: %d%% sun", SunBars*10);
else
gamemenu[7][0] = '\0';
ret = RunMenu (gamemenu, gamemenuCount, "Game Menu");
switch (ret)
@ -338,8 +360,13 @@ GameMenu ()
quit = retval = 1;
break;
case 7: // Weather
SunBars++;
if (SunBars>10) SunBars=0;
break;
case -1: // Button B
case 7: // Return to previous menu
case 8: // Return to previous menu
retval = 0;
quit = 1;
break;
@ -365,10 +392,11 @@ GetInput (u16 ctrlr_type)
while( PAD_ButtonsHeld(0)
#ifdef HW_RVL
| WPAD_ButtonsHeld(0)
| AnyKeyDown()
#endif
) VIDEO_WaitVSync(); // button 'debounce'
while (pressed == 0)
while (pressed == 0 && !AnyKeyDown())
{
VIDEO_WaitVSync();
// get input based on controller type
@ -380,13 +408,28 @@ GetInput (u16 ctrlr_type)
#ifdef HW_RVL
else
{
// also needed for keyboard read, to prevent infinite wait when no keyboard
pressed = WPAD_ButtonsHeld (0);
}
#endif
/*** check for exit sequence (c-stick left OR home button) ***/
if ( (gc_px < -70) || (pressed & WPAD_BUTTON_HOME) || (pressed & WPAD_CLASSIC_BUTTON_HOME))
return 0;
if (DownUsbKeys[KB_ESC]) return 0;
if (ctrlr_type == CTRLR_KEYBOARD)
pressed = 0;
} // end while
if (DownUsbKeys[KB_ESC]) return 0;
if (!pressed) {
for (int i=4; i<=231; i++) {
if (DownUsbKeys[i]) {
while (DownUsbKeys[i]) {
VIDEO_WaitVSync();
}
return i;
}
}
}
while( pressed == (PAD_ButtonsHeld(0)
#ifdef HW_RVL
| WPAD_ButtonsHeld(0)
@ -404,7 +447,7 @@ GetButtonMap(u16 ctrlr_type, char* btn_name)
"Remapping ",
"Press Any Button",
"on the",
" ", // identify controller
" ", // identify controller (must be at least 8 spaces for "keyboard")
" ",
"Press C-Left or",
"Home to exit"
@ -417,17 +460,19 @@ GetButtonMap(u16 ctrlr_type, char* btn_name)
switch (ctrlr_type) {
case CTRLR_NUNCHUK:
strncpy (cfg_text[3], "NUNCHUK", 7);
strncpy (cfg_text[3], "NUNCHUK", 8); // 8 spaces in "identify controller" above
break;
case CTRLR_CLASSIC:
strncpy (cfg_text[3], "CLASSIC", 7);
strncpy (cfg_text[3], "CLASSIC", 8);
break;
case CTRLR_GCPAD:
strncpy (cfg_text[3], "GC PAD", 7);
strncpy (cfg_text[3], "GC PAD", 8);
break;
case CTRLR_WIIMOTE:
strncpy (cfg_text[3], "WIIMOTE", 7);
strncpy (cfg_text[3], "WIIMOTE", 8);
break;
case CTRLR_KEYBOARD:
strncpy (cfg_text[3], "KEYBOARD", 8);
};
/*** note which button we are remapping ***/
@ -490,6 +535,10 @@ ConfigureButtons (u16 ctrlr_type)
sprintf(menu_title, "VBA - WIIMOTE");
currentpadmap = wmpadmap;
break;
case CTRLR_KEYBOARD:
sprintf(menu_title, "VBA - KEYBOARD");
currentpadmap = kbpadmap;
break;
};
while (quit == 0)
@ -553,12 +602,14 @@ ConfigureButtons (u16 ctrlr_type)
void
ConfigureControllers ()
{
int ctlrmenucount = 6;
int ctlrmenucount = 8;
char ctlrmenu[][50] = {
"Match Wii Game",
"Nunchuk",
"Classic Controller",
"Wiimote",
"Gamecube Pad",
"Keyboard",
"Save Preferences",
"Go Back"
};
@ -568,49 +619,62 @@ ConfigureControllers ()
int oldmenu = menu;
menu = 0;
// disable unavailable controller options if in GC mode
#ifndef HW_RVL
ctlrmenu[0][0] = 0;
ctlrmenu[1][0] = 0;
ctlrmenu[2][0] = 0;
ctlrmenu[3][0] = 0;
ctlrmenu[5][0] = 0;
#endif
while (quit == 0)
{
sprintf (ctlrmenu[0], "Match Wii Game: %s",
GCSettings.WiiControls == true ? " ON" : "OFF");
/*** Controller Config Menu ***/
ret = RunMenu (ctlrmenu, ctlrmenucount, "Configure Controllers");
switch (ret)
{
case 0:
GCSettings.WiiControls ^= 1;
break;
case 1:
/*** Configure Nunchuk ***/
ConfigureButtons (CTRLR_NUNCHUK);
break;
case 1:
case 2:
/*** Configure Classic ***/
ConfigureButtons (CTRLR_CLASSIC);
break;
case 2:
case 3:
/*** Configure Wiimote ***/
ConfigureButtons (CTRLR_WIIMOTE);
break;
case 3:
case 4:
/*** Configure GC Pad ***/
ConfigureButtons (CTRLR_GCPAD);
break;
case 4:
case 5:
/*** Configure Keyboard ***/
ConfigureButtons (CTRLR_KEYBOARD);
break;
case 6:
/*** Save Preferences Now ***/
SavePrefs(NOTSILENT);
break;
case -1: /*** Button B ***/
case 5:
case 7:
/*** Return ***/
quit = 1;
break;

View File

@ -26,6 +26,8 @@
#include "dvd.h"
#include "input.h"
#include "networkop.h"
#include "wiiusbsupport.h"
#include "filelist.h"
/*** Globals ***/
static FT_Library ftlibrary;
@ -33,8 +35,6 @@ static FT_Face face;
static FT_GlyphSlot slot;
static unsigned int fonthi, fontlo;
extern char fontface[]; /*** From fontface.s ***/
extern int fontsize; /*** From fontface.s ***/
extern int screenheight;
extern unsigned int *xfb[2];
extern int whichfb;
@ -57,7 +57,7 @@ FT_Init ()
return 1;
err =
FT_New_Memory_Face (ftlibrary, (FT_Byte *) fontface, fontsize, 0, &face);
FT_New_Memory_Face (ftlibrary, (FT_Byte *) font_ttf, font_ttf_size, 0, &face);
if (err)
return 1;
@ -238,7 +238,7 @@ Credits ()
DrawText (-1, ypos += 18, "Official Site: http://code.google.com/p/vba-wii/");
DrawText (90, ypos += 36, "Visual Boy Advance GX");
DrawText (380, ypos, "Tantric");
DrawText (380, ypos, "Tantric, Carl Kenner");
DrawText (90, ypos += 18, "GameCube/Wii Port Improvements");
DrawText (380, ypos, "emukidid");
DrawText (90, ypos += 18, "Original GameCube Port");
@ -304,8 +304,12 @@ void
WaitButtonA ()
{
#ifdef HW_RVL
while ( (PAD_ButtonsDown (0) & PAD_BUTTON_A) || (WPAD_ButtonsDown(0) & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)) ) VIDEO_WaitVSync();
while (!(PAD_ButtonsDown (0) & PAD_BUTTON_A) && !(WPAD_ButtonsDown(0) & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)) ) VIDEO_WaitVSync();
while ( (PAD_ButtonsDown (0) & PAD_BUTTON_A)
|| (WPAD_ButtonsDown(0) & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A))
|| (DownUsbKeys[KB_ENTER])) VIDEO_WaitVSync();
while (!(PAD_ButtonsDown (0) & PAD_BUTTON_A)
&& !(WPAD_ButtonsDown(0) & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A))
&& !(DownUsbKeys[KB_ENTER])) VIDEO_WaitVSync();
#else
while ( PAD_ButtonsDown (0) & PAD_BUTTON_A ) VIDEO_WaitVSync();
while (!(PAD_ButtonsDown (0) & PAD_BUTTON_A) ) VIDEO_WaitVSync();
@ -324,15 +328,20 @@ WaitButtonAB ()
while ( (PAD_ButtonsDown (0) & (PAD_BUTTON_A | PAD_BUTTON_B))
|| (WPAD_ButtonsDown(0) & (WPAD_BUTTON_A | WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_A | WPAD_CLASSIC_BUTTON_B))
|| (DownUsbKeys[KB_ENTER]) || (DownUsbKeys[KB_ESC])
) VIDEO_WaitVSync();
while ( TRUE )
{
gc_btns = PAD_ButtonsDown (0);
wm_btns = WPAD_ButtonsDown (0);
if ( (gc_btns & PAD_BUTTON_A) || (wm_btns & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)) )
if ( (gc_btns & PAD_BUTTON_A) || (wm_btns & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A))
|| (DownUsbKeys[KB_ENTER])
)
return 1;
else if ( (gc_btns & PAD_BUTTON_B) || (wm_btns & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B)) )
else if ( (gc_btns & PAD_BUTTON_B) || (wm_btns & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B))
|| (DownUsbKeys[KB_ESC])
)
return 0;
}
#else
@ -558,26 +567,44 @@ RunMenu (char items[][50], int maxitems, const char *title, int fontsize, int x)
VIDEO_WaitVSync(); // slow things down a bit so we don't overread the pads
/*** Look for up ***/
if ( (p & PAD_BUTTON_UP) || (wp & (WPAD_BUTTON_UP | WPAD_CLASSIC_BUTTON_UP)) || (gc_ay > PADCAL) || (wm_ay > PADCAL) )
if ( (p & PAD_BUTTON_UP) || (wp & (WPAD_BUTTON_UP | WPAD_CLASSIC_BUTTON_UP)) ||
(gc_ay > PADCAL) || (wm_ay > PADCAL)
#ifdef HW_RVL
|| DownUsbKeys[KB_UP]
#endif
)
{
redraw = 1;
menu = FindMenuItem(&items[0], maxitems, menu, -1);
}
/*** Look for down ***/
if ( (p & PAD_BUTTON_DOWN) || (wp & (WPAD_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_DOWN)) || (gc_ay < -PADCAL) || (wm_ay < -PADCAL) )
if ( (p & PAD_BUTTON_DOWN) || (wp & (WPAD_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_DOWN)) ||
(gc_ay < -PADCAL) || (wm_ay < -PADCAL)
#ifdef HW_RVL
|| DownUsbKeys[KB_DOWN]
#endif
)
{
redraw = 1;
menu = FindMenuItem(&items[0], maxitems, menu, +1);
}
if ((p & PAD_BUTTON_A) || (wp & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A)))
if ((p & PAD_BUTTON_A) || (wp & (WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A))
#ifdef HW_RVL
|| DownUsbKeys[KB_ENTER]
#endif
)
{
quit = 1;
ret = menu;
}
if ((p & PAD_BUTTON_B) || (wp & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B)))
if ((p & PAD_BUTTON_B) || (wp & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B))
#ifdef HW_RVL
|| DownUsbKeys[KB_ESC]
#endif
)
{
quit = -1;
ret = -1;
@ -588,6 +615,7 @@ RunMenu (char items[][50], int maxitems, const char *title, int fontsize, int x)
while ( (PAD_ButtonsDown(0) & PAD_BUTTON_B)
#ifdef HW_RVL
|| (WPAD_ButtonsDown(0) & (WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B))
|| DownUsbKeys[KB_ESC]
#endif
)
{

View File

@ -156,16 +156,18 @@ preparePrefsData (int method)
createXMLSetting("Zoom", "Zoom On/Off", toStr(GCSettings.Zoom));
createXMLSetting("ZoomLevel", "Zoom Level", FtoStr(GCSettings.ZoomLevel));
createXMLSetting("render", "Video Filtering", toStr(GCSettings.render));
createXMLSetting("widescreen", "Aspect Ratio Correction", toStr(GCSettings.widescreen));
createXMLSetting("scaling", "Aspect Ratio Correction", toStr(GCSettings.scaling));
createXMLSetting("xshift", "Horizontal Video Shift", toStr(GCSettings.xshift));
createXMLSetting("yshift", "Vertical Video Shift", toStr(GCSettings.yshift));
createXMLSection("Controller", "Controller Settings");
createXMLSetting("WiiControls", "Match Wii Game", toStr(GCSettings.WiiControls));
createXMLController(gcpadmap, "gcpadmap", "GameCube Pad");
createXMLController(wmpadmap, "wmpadmap", "Wiimote");
createXMLController(ccpadmap, "ccpadmap", "Classic Controller");
createXMLController(ncpadmap, "ncpadmap", "Nunchuk");
createXMLController(kbpadmap, "kbpadmap", "Keyboard");
int datasize = mxmlSaveString(xml, (char *)savebuffer, SAVEBUFFERSIZE, XMLSaveCallback);
@ -283,8 +285,8 @@ decodePrefsData (int method)
verMinor >= 0 && verMinor <= 9 &&
verPoint >= 0 && verPoint <= 9))
result = false;
else if(verPoint < 4 && verMajor == 1) // less than version 1.0.4
result = false; // reset settings
else if(verPoint < 8 && verMajor == 1) // less than version 1.0.8
result = false; // reset settings (sorry, should update settings instead)
else if(verMajor > curMajor || verMinor > curMinor || verPoint > curPoint) // some future version
result = false; // reset settings
else
@ -317,16 +319,18 @@ decodePrefsData (int method)
loadXMLSetting(&GCSettings.Zoom, "Zoom");
loadXMLSetting(&GCSettings.ZoomLevel, "ZoomLevel");
loadXMLSetting(&GCSettings.render, "render");
loadXMLSetting(&GCSettings.widescreen, "widescreen");
loadXMLSetting(&GCSettings.scaling, "scaling");
loadXMLSetting(&GCSettings.xshift, "xshift");
loadXMLSetting(&GCSettings.yshift, "yshift");
// Controller Settings
loadXMLSetting(&GCSettings.WiiControls, "WiiControls");
loadXMLController(gcpadmap, "gcpadmap");
loadXMLController(wmpadmap, "wmpadmap");
loadXMLController(ccpadmap, "ccpadmap");
loadXMLController(ncpadmap, "ncpadmap");
loadXMLController(kbpadmap, "kbpadmap");
}
mxmlDelete(xml);
}

View File

@ -36,6 +36,7 @@ extern "C" {
#include "input.h"
#include "video.h"
#include "vbaconfig.h"
#include "wiiusbsupport.h"
extern bool ROMLoaded;
extern int emulating;
@ -50,6 +51,10 @@ char appPath[1024];
static void ExitCleanup()
{
#ifdef HW_RVL
ShutoffRumble();
StopWiiKeyboard();
#endif
LWP_SuspendThread (devicethread);
UnmountAllFAT();
CloseShare();
@ -223,6 +228,8 @@ int main(int argc, char *argv[])
if(argc > 0 && argv[0] != NULL)
CreateAppPath(argv[0]);
StartWiiKeyboardMouse();
int selectedMenu = -1;
// Load preferences
@ -264,6 +271,7 @@ int main(int argc, char *argv[])
if(ConfigRequested)
{
ShutoffRumble();
StopAudio();
ResetVideo_Menu (); // change to menu video mode

View File

@ -11,7 +11,7 @@
#define _VBAGX_H_
#define APPNAME "Visual Boy Advance GX"
#define APPVERSION "1.0.7"
#define APPVERSION "1.0.8"
#define PREF_FILE_NAME "settings.xml"
#define NOTSILENT 0
@ -53,11 +53,13 @@ struct SGCSettings{
int Zoom; // 0 - off, 1 - on
float ZoomLevel; // zoom amount
int widescreen;
int scaling; // 0 - default, 1 - partial stretch, 2 - stretch to fit, 3 - widescreen correction
int render; // 0 - original, 1 - filtered, 2 - unfiltered
int VerifySaves;
int xshift; // video output shift
int yshift;
int WiiControls; // Match Wii Game
int WiimoteOrientation;
};
void ExitToLoader();

View File

@ -41,11 +41,14 @@ DefaultSettings ()
GCSettings.smbpwd[19] = 0;
GCSettings.smbshare[19] = 0;
GCSettings.WiimoteOrientation = 0;
GCSettings.VerifySaves = 0;
GCSettings.Zoom = 0; // zooming default off
GCSettings.ZoomLevel = 1.0; // zoom level
GCSettings.render = 1; // Filtered
GCSettings.widescreen = 0; // no aspect ratio correction
GCSettings.scaling = 1; // partial stretch
GCSettings.WiiControls = true; // Match Wii Game
GCSettings.xshift = 0; // video shift
GCSettings.yshift = 0;

View File

@ -20,8 +20,15 @@
#include "images/bg.h"
#include "vba.h"
#include "menudraw.h"
#include "gui/gui.h"
s32 CursorX, CursorY;
bool CursorVisible;
bool CursorValid;
bool TiltScreen = false;
float TiltAngle = 0;
u32 FrameTimer = 0;
GuiImageData * pointer1;
/*** External 2D Video ***/
/*** 2D Video Globals ***/
@ -30,6 +37,7 @@ unsigned int *xfb[2]; // Framebuffers
int whichfb = 0; // Frame buffer toggle
int screenheight;
int screenwidth;
/*** 3D GX ***/
#define DEFAULT_FIFO_SIZE ( 256 * 1024 )
@ -143,12 +151,29 @@ copy_to_xfb (u32 arg)
void
clearscreen ()
{
int colour = COLOR_BLACK;
// PAL is 640x576 NOT 640x480!
// Fill the bottom of the screen with the background's top? left corner
int colour = bg[0];
whichfb ^= 1;
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], colour);
if (vmode->xfbHeight==480)
{
memcpy (xfb[whichfb], &bg, 1280 * 480);
}
else if (vmode->xfbHeight<480)
{
memcpy (xfb[whichfb], &bg, 1280 * vmode->xfbHeight);
}
else
{
memcpy (xfb[whichfb], &bg, 1280 * 240);
for (int i=0; i<vmode->xfbHeight-480; i++)
memcpy (((char *)xfb[whichfb])+1280*(240+i), ((char *)&bg)+1280 * 240, 1280 * 1);
memcpy (((char *)xfb[whichfb])+1280*(vmode->xfbHeight-240), ((char *)&bg)+1280 * 240, 1280 * 240);
}
}
void
showscreen ()
@ -197,7 +222,16 @@ static void draw_square(Mtx v)
Mtx m; // model matrix.
Mtx mv; // modelview matrix.
if (TiltScreen)
{
guMtxRotDeg(m, 'z', -TiltAngle);
guMtxScaleApply(m, m, 0.8, 0.8, 1);
}
else
{
guMtxIdentity(m);
}
guMtxTransApply(m, m, 0, 0, -100);
guMtxConcat(v, m, mv);
@ -210,6 +244,36 @@ static void draw_square(Mtx v)
GX_End();
}
void Menu_DrawImg(f32 xpos, f32 ypos, u16 width, u16 height, u8 data[], f32 degrees, f32 scaleX, f32 scaleY, u8 alpha);
static void draw_cursor(Mtx v)
{
if (!CursorVisible)
return;
/*
#ifdef HW_RVL
WPADData *wp = WPAD_Data(0);
if(wp->ir.valid)
Menu_DrawImg(wp->ir.x-48, wp->ir.y-48, 96, 96, pointer1->GetImage(), wp->ir.angle, 1, 1, 255);
#endif
*/
Mtx m; // model matrix.
guMtxIdentity(m);
guMtxScaleApply(m, m, 0.05f, 0.05f, 0.06f);
guMtxTransApply(m, m, CursorX-320, 240-CursorY, -100);
GX_LoadPosMtxImm(m, GX_PNMTX0);
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
draw_vert(0, 0, 0.0, 0.0);
draw_vert(1, 0, 1.0, 0.0);
draw_vert(2, 0, 1.0, 1.0);
draw_vert(3, 0, 0.0, 1.0);
GX_End();
}
/****************************************************************************
* StartGX
****************************************************************************/
@ -245,6 +309,8 @@ static void GX_Start()
GX_CopyDisp (xfb[whichfb], GX_TRUE); // reset xfb
GX_Flush();
pointer1 = new GuiImageData(player1_point_png);
}
/****************************************************************************
@ -309,6 +375,7 @@ void InitialiseVideo ()
VIDEO_Configure(vmode);
screenheight = vmode->xfbHeight;
screenwidth = vmode->fbWidth;
xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
xfb[1] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
@ -345,21 +412,50 @@ static void UpdateScaling()
int xscale;
int yscale;
// keep correct aspect ratio
// and use entire screen
if(vwidth == 240) // GBA
{
xscale = 320;
yscale = 213;
}
else // GB
{
xscale = 256;
yscale = 230;
}
float TvAspectRatio;
float GameboyAspectRatio;
float MaxStretchRatio = 1.6f;
if (GCSettings.widescreen)
xscale = (3*xscale)/4;
if (GCSettings.scaling == 1)
MaxStretchRatio = 1.3f;
else if (GCSettings.scaling == 2)
MaxStretchRatio = 1.6f;
else
MaxStretchRatio = 1.0f;
#ifdef HW_RVL
if (CONF_GetAspectRatio() == CONF_ASPECT_16_9)
TvAspectRatio = 16.0f/9.0f;
else
TvAspectRatio = 4.0f/3.0f;
#else
if (GCSettings.scaling == 3)
TvAspectRatio = 16.0f/9.0f;
else
TvAspectRatio = 4.0f/3.0f;
#endif
if (vwidth == 240) // GBA
GameboyAspectRatio = 240.0f/160.0f; // assumes square pixels on GB Advance
else // GB or GBC
GameboyAspectRatio = 160.0f/144.0f; // assumes square pixels on GB Colour
if (TvAspectRatio>GameboyAspectRatio)
{
yscale = 240; // half of TV resolution 640x480
float StretchRatio = TvAspectRatio/GameboyAspectRatio;
if (StretchRatio > MaxStretchRatio)
StretchRatio = MaxStretchRatio;
xscale = 240.0f*GameboyAspectRatio*StretchRatio * ((4.0f/3.0f)/TvAspectRatio);
}
else
{
xscale = 320; // half of TV resolution 640x480
float StretchRatio = GameboyAspectRatio/TvAspectRatio;
if (StretchRatio > MaxStretchRatio)
StretchRatio = MaxStretchRatio;
yscale = 320.0f/GameboyAspectRatio*StretchRatio / ((4.0f/3.0f)/TvAspectRatio);
}
// change zoom
xscale *= GCSettings.ZoomLevel;
@ -556,8 +652,8 @@ void GX_Render(int width, int height, u8 * buffer, int pitch)
GX_SetNumChans(1);
GX_LoadTexObj(&texobj, GX_TEXMAP0);
// render textured quad
draw_square(view);
draw_square(view); // render textured quad
draw_cursor(view); // render cursor
GX_DrawDone();
GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
@ -597,3 +693,52 @@ zoom_reset ()
GCSettings.ZoomLevel = 1.0;
updateScaling = 1; // update video
}
void Menu_DrawImg(f32 xpos, f32 ypos, u16 width, u16 height, u8 data[], f32 degrees, f32 scaleX, f32 scaleY, u8 alpha)
{
if(data == NULL)
return;
GXTexObj texObj;
GX_InitTexObj(&texObj, data, width,height, GX_TF_RGBA8,GX_CLAMP, GX_CLAMP,GX_FALSE);
GX_LoadTexObj(&texObj, GX_TEXMAP0);
GX_SetTevOp (GX_TEVSTAGE0, GX_MODULATE);
GX_SetVtxDesc (GX_VA_TEX0, GX_DIRECT);
Mtx m,m1,m2, mv;
width *=.5;
height*=.5;
guMtxIdentity (m1);
guMtxScaleApply(m1,m1,scaleX,scaleY,1.0);
Vector axis = (Vector) {0 , 0, 1 };
guMtxRotAxisDeg (m2, &axis, degrees);
guMtxConcat(m2,m1,m);
guMtxTransApply(m,m, xpos+width,ypos+height,0);
guMtxConcat (view, m, mv);
GX_LoadPosMtxImm (mv, GX_PNMTX0);
GX_Begin(GX_QUADS, GX_VTXFMT0,4);
GX_Position3f32(-width, -height, 0);
GX_Color4u8(0xFF,0xFF,0xFF,alpha);
GX_TexCoord2f32(0, 0);
GX_Position3f32(width, -height, 0);
GX_Color4u8(0xFF,0xFF,0xFF,alpha);
GX_TexCoord2f32(1, 0);
GX_Position3f32(width, height, 0);
GX_Color4u8(0xFF,0xFF,0xFF,alpha);
GX_TexCoord2f32(1, 1);
GX_Position3f32(-width, height, 0);
GX_Color4u8(0xFF,0xFF,0xFF,alpha);
GX_TexCoord2f32(0, 1);
GX_End();
GX_LoadPosMtxImm (view, GX_PNMTX0);
GX_SetTevOp (GX_TEVSTAGE0, GX_PASSCLR);
GX_SetVtxDesc (GX_VA_TEX0, GX_NONE);
}

View File

@ -11,11 +11,10 @@
* These are pretty standard functions to setup and use GX scaling.
***************************************************************************/
#ifndef __GXHDR__
#define __GXHDR__
#ifndef __VIDEOGX_H__
#define __VIDEOGX_H__
void InitialiseVideo ();
void GX_Start();
void GX_Render_Init(int width, int height);
void GX_Render(int width, int height, u8 * buffer, int pitch);
void clearscreen ();
@ -25,4 +24,12 @@ void zoom_reset ();
void ResetVideo_Menu ();
void ResetVideo_Emu ();
extern int screenheight;
extern int screenwidth;
extern s32 CursorX, CursorY;
extern bool CursorVisible;
extern bool CursorValid;
extern bool TiltScreen;
extern float TiltAngle;
#endif

View File

@ -0,0 +1,370 @@
/****************************************************************************
* Visual Boy Advance GX
*
* Carl Kenner February 2009
*
* wiiusbsupport.cpp
*
* Wii USB Keyboard and USB Mouse support
***************************************************************************/
#include <gccore.h>
#include <ogcsys.h>
#include <ogc/ipc.h>
#include <wiiuse/wpad.h>
#include <cstdio>
#include <string>
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
#include "wiiusbsupport.h"
#ifdef HW_RVL
#define USB_CLASS_HID 0x03
#define USB_SUBCLASS_BOOT 0x01
#define USB_PROTOCOL_KEYBOARD 0x01
#define USB_PROTOCOL_MOUSE 0x02
static int mouse_vid = 0;
static int mouse_pid = 0;
#define DEVLIST_MAXSIZE 0x08
#define USB_REQ_GETPROTOCOL 0x03
#define USB_REQ_SETPROTOCOL 0x0B
#define USB_REQ_GETREPORT 0x01
#define USB_REQ_SETREPORT 0x09
#define USB_REPTYPE_INPUT 0x01
#define USB_REPTYPE_OUTPUT 0x02
#define USB_REPTYPE_FEATURE 0x03
#define USB_REQTYPE_GET 0xA1
#define USB_REQTYPE_SET 0x21
static u8 mouseconfiguration = 0;
static u32 mouseinterface = 0;
static u32 mousealtInterface = 0;
u8 DownUsbKeys[256];
u8 DownUsbShiftKeys = 0;
s32 MouseDirectInputX = 0;
s32 MouseDirectInputY = 0;
static bool KeyboardStarted=false, MouseStarted=false;
static s32 KeyboardHandle=0, MouseHandle=0;
typedef struct
{
u32 message;
u32 id; // direction
u8 modifiers;
u8 unknown;
u8 keys[6];
u8 pad[16];
}TKeyData;
static TKeyData KeyData ATTRIBUTE_ALIGN(32);
static signed char *MouseData = NULL;
static u8 OldKeys[6];
static u8 OldShiftKeys;
static bool StopKeyboard = true;
void KeyPress(u8 key)
{
DownUsbKeys[key] = 1;
}
void KeyRelease(u8 key)
{
DownUsbKeys[key] = 0;
}
bool AnyKeyDown()
{
int i;
for (i=4; i<=231;i++)
{
if (DownUsbKeys[i]) return true;
}
return false;
}
s32 KeyboardCallback(int ret,void * none)
{
if (KeyboardHandle<0 || KeyData.message==0x7fffffff)
return 0;
if(KeyData.message==0)
{
// keyboard connected!
}
else if(KeyData.message==1)
{
// keyboard disconnected!
}
else if(KeyData.message==2)
{
// key event
DownUsbShiftKeys = KeyData.modifiers;
u8 p = DownUsbShiftKeys & (~OldShiftKeys);
if (p & 0x01) KeyPress(KB_LCTRL);
if (p & 0x02) KeyPress(KB_LSHIFT);
if (p & 0x04) KeyPress(KB_LALT);
if (p & 0x08) KeyPress(KB_LWIN);
if (p & 0x10) KeyPress(KB_RCTRL);
if (p & 0x20) KeyPress(KB_RSHIFT);
if (p & 0x40) KeyPress(KB_RALT);
if (p & 0x80) KeyPress(KB_RWIN);
p = OldShiftKeys & (~DownUsbShiftKeys);
if (p & 0x01) KeyRelease(KB_LCTRL);
if (p & 0x02) KeyRelease(KB_LSHIFT);
if (p & 0x04) KeyRelease(KB_LALT);
if (p & 0x08) KeyRelease(KB_LWIN);
if (p & 0x10) KeyRelease(KB_RCTRL);
if (p & 0x20) KeyRelease(KB_RSHIFT);
if (p & 0x40) KeyRelease(KB_RALT);
if (p & 0x80) KeyRelease(KB_RWIN);
// check each key to see if is in the list of old keys, if not it was pressed
for (int i=0; i<6; i++)
{
if (KeyData.keys[i]==1)
{
break; // too many keys held down at once, so no key data except modifiers
}
else if (KeyData.keys[i])
{
bool found = false;
for (int old=0; old<6; old++)
{
if (OldKeys[old]==KeyData.keys[i])
{
found = true;
break;
}
}
if (!found) KeyPress(KeyData.keys[i]);
}
}
// check each old key to see if is in the list of keys, if not it was released
for (int old=0; old<6; old++)
{
if (OldKeys[old])
{
bool found = false;
for (int i=0; i<6; i++)
{
if (OldKeys[old]==KeyData.keys[i])
{
found = true;
break;
}
}
if (!found) KeyRelease(OldKeys[old]);
}
}
// Update old keys, unless too many keys were held down
if (KeyData.keys[0]!=1)
memcpy(OldKeys, KeyData.keys, 6);
}
// no keyboard message
KeyData.message=0x7fffffff;
// Request another keyboard message when one is ready
if (!StopKeyboard)
IOS_IoctlAsync(KeyboardHandle,1,(void *) &KeyData, 16,(void *) &KeyData, 16, KeyboardCallback, NULL);
return 0;
}
void StartWiiKeyboardMouse()
{
memset(DownUsbKeys, 0, sizeof(DownUsbKeys));
if (!KeyboardStarted)
{
USB_Initialize();
StartWiiMouse();
KeyboardHandle=IOS_Open("/dev/usb/kbd", 1);
if (KeyboardHandle<0)
{
// Error!
}
//sleep(2);
KeyData.message=0x7fffffff;
StopKeyboard = false;
if(KeyboardHandle>=0)
IOS_IoctlAsync(KeyboardHandle,1,(void *) &KeyData, 16,(void *) &KeyData, 16, KeyboardCallback, NULL);
KeyboardStarted = true;
}
else
{
if(KeyboardHandle>=0)
IOS_IoctlAsync(KeyboardHandle,1,(void *) &KeyData, 16,(void *) &KeyData, 16, KeyboardCallback, NULL);
}
}
void StopWiiKeyboard()
{
StopKeyboard = true;
IOS_Close(KeyboardHandle);
}
s32 MouseCallback(s32 result, void *usrdata)
{
if (result>0)
{
u8 button = MouseData[0];
int deltax = (s8)MouseData[1];
int deltay = (s8)MouseData[2];
MouseDirectInputX += deltax;
MouseDirectInputY += deltay;
DownUsbKeys[KB_MOUSEL] = (button & 1);
DownUsbKeys[KB_MOUSER] = (button & 2);
DownUsbKeys[KB_MOUSEM] = (button & 4);
USB_ReadIntrMsgAsync(MouseHandle, 0x81, 4, MouseData, MouseCallback, 0);
}
else
{
MouseStarted=0;
MouseHandle=0;
}
return 0;
}
static int wii_find_mouse()
{
s32 fd=0;
static u8 *buffer = 0;
if (!buffer)
{
buffer = (u8*)memalign(32, DEVLIST_MAXSIZE << 3);
}
if(buffer == NULL)
{
return -1;
}
memset(buffer, 0, DEVLIST_MAXSIZE << 3);
u8 dummy;
u16 vid,pid;
if (USB_GetDeviceList("/dev/usb/oh0", buffer, DEVLIST_MAXSIZE, 0, &dummy) < 0)
{
free(buffer);
buffer =0;
return -2;
}
u8 mouseep;
u32 mouseep_size;
int i;
for(i = 0; i < DEVLIST_MAXSIZE; i++)
{
memcpy(&vid, (buffer + (i << 3) + 4), 2);
memcpy(&pid, (buffer + (i << 3) + 6), 2);
if ((vid==0)&&(pid==0))
continue;
fd =0;
int err = USB_OpenDevice("oh0",vid,pid,&fd);
if (err<0)
{
continue;
}
else
{
// error!
}
u32 iConf, iInterface;
usb_devdesc udd;
usb_configurationdesc *ucd;
usb_interfacedesc *uid;
usb_endpointdesc *ued;
USB_GetDescriptors(fd, &udd);
for(iConf = 0; iConf < udd.bNumConfigurations; iConf++)
{
ucd = &udd.configurations[iConf];
for(iInterface = 0; iInterface < ucd->bNumInterfaces; iInterface++)
{
uid = &ucd->interfaces[iInterface];
if ( (uid->bInterfaceClass == USB_CLASS_HID) && (uid->bInterfaceSubClass == USB_SUBCLASS_BOOT) &&
(uid->bInterfaceProtocol== USB_PROTOCOL_MOUSE))
{
int iEp;
for(iEp = 0; iEp < uid->bNumEndpoints; iEp++)
{
ued = &uid->endpoints[iEp];
mouse_vid = vid;
mouse_pid = pid;
mouseep = ued->bEndpointAddress;
mouseep_size = ued->wMaxPacketSize;
mouseconfiguration = ucd->bConfigurationValue;
mouseinterface = uid->bInterfaceNumber;
mousealtInterface = uid->bAlternateSetting;
}
break;
}
}
}
USB_FreeDescriptors(&udd);
USB_CloseDevice(&fd);
}
if (mouse_pid!=0 || mouse_vid!=0) return 0;
return -1;
}
void StartWiiMouse()
{
if (!MouseStarted)
{
if (wii_find_mouse()!=0) return;
if (USB_OpenDevice("oh0", mouse_vid, mouse_pid, &MouseHandle)<0)
{
return;
}
if (!MouseData)
{
MouseData = (signed char*)memalign(32, 20);
}
//set boot protocol
USB_WriteCtrlMsg(MouseHandle,USB_REQTYPE_SET,USB_REQ_SETPROTOCOL,0,0,0,0);
USB_ReadIntrMsgAsync(MouseHandle, 0x81, 4, MouseData, MouseCallback, 0);
MouseStarted=true;
}
}
#else // GameCube stub
u8 DownUsbKeys[256];
bool AnyKeyDown()
{
return false;
}
void StartWiiKeyboardMouse()
{
memset(DownUsbKeys, 0, sizeof(DownUsbKeys));
}
#endif

View File

@ -0,0 +1,73 @@
/****************************************************************************
* Visual Boy Advance GX
*
* Carl Kenner Febuary 2009
*
* wiiusbsupport.h
*
* Wii USB Keyboard and USB Mouse support
***************************************************************************/
#ifndef _WIIUSBSUPPORT_H_
#define _WIIUSBSUPPORT_H_
#define KB_A 4
#define KB_B 5
#define KB_C 6
#define KB_D 7
#define KB_E 8
#define KB_F 9
#define KB_Q 20
#define KB_R 21
#define KB_S 22
#define KB_V 25
#define KB_W 26
#define KB_X 27
#define KB_Y 28
#define KB_Z 29
#define KB_ENTER 40
#define KB_ESC 41
#define KB_BKSP 42
#define KB_TAB 43
#define KB_SPACE 44
#define KB_F1 58
#define KB_F2 59
#define KB_F3 60
#define KB_F4 61
#define KB_F5 62
#define KB_F6 63
#define KB_F7 64
#define KB_F8 65
#define KB_F9 66
#define KB_F10 67
#define KB_F11 68
#define KB_F12 69
#define KB_PRTSC 70
#define KB_SCRLK 71
#define KB_PAUSE 72
#define KB_RIGHT 79
#define KB_LEFT 80
#define KB_DOWN 81
#define KB_UP 82
#define KB_LCTRL 224
#define KB_LSHIFT 225
#define KB_LALT 226
#define KB_LWIN 227
#define KB_RCTRL 228
#define KB_RSHIFT 229
#define KB_RALT 230
#define KB_RWIN 231
// CAKTODO
#define KB_MOUSEL 232
#define KB_MOUSER 233
#define KB_MOUSEM 234
void StartWiiKeyboardMouse();
void StopWiiKeyboard();
bool AnyKeyDown();
void StartWiiMouse();
extern u8 DownUsbKeys[256];
extern u8 DownUsbShiftKeys;
#endif