Introduce F1 menu to reconfigure key bindings at runtime
This commit is contained in:
		
							parent
							
								
									af145c3a01
								
							
						
					
					
						commit
						dd73db2e9d
					
				
					 17 changed files with 1837 additions and 136 deletions
				
			
		| 
						 | 
					@ -135,6 +135,8 @@ set(MAIN_HEADERS
 | 
				
			||||||
	src/gl-util.h
 | 
						src/gl-util.h
 | 
				
			||||||
	src/util.h
 | 
						src/util.h
 | 
				
			||||||
	src/config.h
 | 
						src/config.h
 | 
				
			||||||
 | 
						src/settingsmenu.h
 | 
				
			||||||
 | 
						src/keybindings.h
 | 
				
			||||||
	src/tileatlas.h
 | 
						src/tileatlas.h
 | 
				
			||||||
	src/sharedstate.h
 | 
						src/sharedstate.h
 | 
				
			||||||
	src/al-util.h
 | 
						src/al-util.h
 | 
				
			||||||
| 
						 | 
					@ -180,6 +182,8 @@ set(MAIN_SOURCE
 | 
				
			||||||
	src/debuglogger.cpp
 | 
						src/debuglogger.cpp
 | 
				
			||||||
	src/etc.cpp
 | 
						src/etc.cpp
 | 
				
			||||||
	src/config.cpp
 | 
						src/config.cpp
 | 
				
			||||||
 | 
						src/settingsmenu.cpp
 | 
				
			||||||
 | 
						src/keybindings.cpp
 | 
				
			||||||
	src/tileatlas.cpp
 | 
						src/tileatlas.cpp
 | 
				
			||||||
	src/sharedstate.cpp
 | 
						src/sharedstate.cpp
 | 
				
			||||||
	src/gl-fun.cpp
 | 
						src/gl-fun.cpp
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,6 +111,19 @@
 | 
				
			||||||
# allowSymlinks=false
 | 
					# allowSymlinks=false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Organisation / company and application / game
 | 
				
			||||||
 | 
					# name to build the directory path where mkxp
 | 
				
			||||||
 | 
					# will store game specific data (eg. key bindings).
 | 
				
			||||||
 | 
					# If not specified, mkxp will save to a common
 | 
				
			||||||
 | 
					# directory shared by all games. Note that these
 | 
				
			||||||
 | 
					# are TWO individual config entries, and both need
 | 
				
			||||||
 | 
					# to be defined for this to take effect.
 | 
				
			||||||
 | 
					# (default: none)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# dataPathOrg=mycompany
 | 
				
			||||||
 | 
					# dataPathApp=mygame
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Set the game window icon to 'path/to/icon.png'
 | 
					# Set the game window icon to 'path/to/icon.png'
 | 
				
			||||||
# (default: none)
 | 
					# (default: none)
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								mkxp.pro
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								mkxp.pro
									
										
									
									
									
								
							| 
						 | 
					@ -114,6 +114,8 @@ HEADERS += \
 | 
				
			||||||
	src/gl-util.h \
 | 
						src/gl-util.h \
 | 
				
			||||||
	src/util.h \
 | 
						src/util.h \
 | 
				
			||||||
	src/config.h \
 | 
						src/config.h \
 | 
				
			||||||
 | 
						src/settingsmenu.h \
 | 
				
			||||||
 | 
						src/keybindings.h \
 | 
				
			||||||
	src/tileatlas.h \
 | 
						src/tileatlas.h \
 | 
				
			||||||
	src/sharedstate.h \
 | 
						src/sharedstate.h \
 | 
				
			||||||
	src/al-util.h \
 | 
						src/al-util.h \
 | 
				
			||||||
| 
						 | 
					@ -158,6 +160,8 @@ SOURCES += \
 | 
				
			||||||
	src/debuglogger.cpp \
 | 
						src/debuglogger.cpp \
 | 
				
			||||||
	src/etc.cpp \
 | 
						src/etc.cpp \
 | 
				
			||||||
	src/config.cpp \
 | 
						src/config.cpp \
 | 
				
			||||||
 | 
						src/settingsmenu.cpp \
 | 
				
			||||||
 | 
						src/keybindings.cpp \
 | 
				
			||||||
	src/tileatlas.cpp \
 | 
						src/tileatlas.cpp \
 | 
				
			||||||
	src/sharedstate.cpp \
 | 
						src/sharedstate.cpp \
 | 
				
			||||||
	src/gl-fun.cpp \
 | 
						src/gl-fun.cpp \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,8 @@
 | 
				
			||||||
#include <boost/program_options/parsers.hpp>
 | 
					#include <boost/program_options/parsers.hpp>
 | 
				
			||||||
#include <boost/program_options/variables_map.hpp>
 | 
					#include <boost/program_options/variables_map.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <SDL_filesystem.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <fstream>
 | 
					#include <fstream>
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -118,6 +120,15 @@ static bool validUtf8(const char *string)
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static std::string prefPath(const char *org, const char *app)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char *path = SDL_GetPrefPath(org, app);
 | 
				
			||||||
 | 
						std::string str(path);
 | 
				
			||||||
 | 
						SDL_free(path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return str;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef std::vector<std::string> StringVec;
 | 
					typedef std::vector<std::string> StringVec;
 | 
				
			||||||
namespace po = boost::program_options;
 | 
					namespace po = boost::program_options;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -167,6 +178,8 @@ void Config::read(int argc, char *argv[])
 | 
				
			||||||
	PO_DESC(anyAltToggleFS, bool) \
 | 
						PO_DESC(anyAltToggleFS, bool) \
 | 
				
			||||||
	PO_DESC(enableReset, bool) \
 | 
						PO_DESC(enableReset, bool) \
 | 
				
			||||||
	PO_DESC(allowSymlinks, bool) \
 | 
						PO_DESC(allowSymlinks, bool) \
 | 
				
			||||||
 | 
						PO_DESC(dataPathOrg, std::string) \
 | 
				
			||||||
 | 
						PO_DESC(dataPathApp, std::string) \
 | 
				
			||||||
	PO_DESC(iconPath, std::string) \
 | 
						PO_DESC(iconPath, std::string) \
 | 
				
			||||||
	PO_DESC(titleLanguage, std::string) \
 | 
						PO_DESC(titleLanguage, std::string) \
 | 
				
			||||||
	PO_DESC(midi.soundFont, std::string) \
 | 
						PO_DESC(midi.soundFont, std::string) \
 | 
				
			||||||
| 
						 | 
					@ -243,6 +256,11 @@ void Config::read(int argc, char *argv[])
 | 
				
			||||||
	rgssVersion = clamp(rgssVersion, 0, 3);
 | 
						rgssVersion = clamp(rgssVersion, 0, 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SE.sourceCount = clamp(SE.sourceCount, 1, 64);
 | 
						SE.sourceCount = clamp(SE.sourceCount, 1, 64);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!dataPathOrg.empty() && !dataPathApp.empty())
 | 
				
			||||||
 | 
							customDataPath = prefPath(dataPathOrg.c_str(), dataPathApp.c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						commonDataPath = prefPath(".", "mkxp");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static std::string baseName(const std::string &path)
 | 
					static std::string baseName(const std::string &path)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,6 +51,9 @@ struct Config
 | 
				
			||||||
	bool allowSymlinks;
 | 
						bool allowSymlinks;
 | 
				
			||||||
	bool pathCache;
 | 
						bool pathCache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string dataPathOrg;
 | 
				
			||||||
 | 
						std::string dataPathApp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::string iconPath;
 | 
						std::string iconPath;
 | 
				
			||||||
	std::string titleLanguage;
 | 
						std::string titleLanguage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,6 +85,10 @@ struct Config
 | 
				
			||||||
		std::string title;
 | 
							std::string title;
 | 
				
			||||||
	} game;
 | 
						} game;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Internal */
 | 
				
			||||||
 | 
						std::string customDataPath;
 | 
				
			||||||
 | 
						std::string commonDataPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Config();
 | 
						Config();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void read(int argc, char *argv[]);
 | 
						void read(int argc, char *argv[]);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "sharedstate.h"
 | 
					#include "sharedstate.h"
 | 
				
			||||||
#include "graphics.h"
 | 
					#include "graphics.h"
 | 
				
			||||||
 | 
					#include "settingsmenu.h"
 | 
				
			||||||
#include "debugwriter.h"
 | 
					#include "debugwriter.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
| 
						 | 
					@ -37,7 +38,7 @@ bool EventThread::keyStates[] = { false };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EventThread::JoyState EventThread::joyState =
 | 
					EventThread::JoyState EventThread::joyState =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	0, 0, { false }
 | 
						{ 0 }, { false }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EventThread::MouseState EventThread::mouseState =
 | 
					EventThread::MouseState EventThread::mouseState =
 | 
				
			||||||
| 
						 | 
					@ -108,6 +109,8 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool resetting = false;
 | 
						bool resetting = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SettingsMenu *sMenu = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (true)
 | 
						while (true)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (!SDL_WaitEvent(&event))
 | 
							if (!SDL_WaitEvent(&event))
 | 
				
			||||||
| 
						 | 
					@ -116,6 +119,19 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (sMenu && sMenu->onEvent(event))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (sMenu->destroyReq())
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									delete sMenu;
 | 
				
			||||||
 | 
									sMenu = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									updateCursorState(cursorInWindow && windowFocused);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		switch (event.type)
 | 
							switch (event.type)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
		case SDL_WINDOWEVENT :
 | 
							case SDL_WINDOWEVENT :
 | 
				
			||||||
| 
						 | 
					@ -129,14 +145,14 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
				
			||||||
			case SDL_WINDOWEVENT_ENTER :
 | 
								case SDL_WINDOWEVENT_ENTER :
 | 
				
			||||||
				cursorInWindow = true;
 | 
									cursorInWindow = true;
 | 
				
			||||||
				mouseState.inWindow = true;
 | 
									mouseState.inWindow = true;
 | 
				
			||||||
				updateCursorState(cursorInWindow && windowFocused);
 | 
									updateCursorState(cursorInWindow && windowFocused && !sMenu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case SDL_WINDOWEVENT_LEAVE :
 | 
								case SDL_WINDOWEVENT_LEAVE :
 | 
				
			||||||
				cursorInWindow = false;
 | 
									cursorInWindow = false;
 | 
				
			||||||
				mouseState.inWindow = false;
 | 
									mouseState.inWindow = false;
 | 
				
			||||||
				updateCursorState(cursorInWindow && windowFocused);
 | 
									updateCursorState(cursorInWindow && windowFocused && !sMenu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -147,13 +163,13 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case SDL_WINDOWEVENT_FOCUS_GAINED :
 | 
								case SDL_WINDOWEVENT_FOCUS_GAINED :
 | 
				
			||||||
				windowFocused = true;
 | 
									windowFocused = true;
 | 
				
			||||||
				updateCursorState(cursorInWindow && windowFocused);
 | 
									updateCursorState(cursorInWindow && windowFocused && !sMenu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case SDL_WINDOWEVENT_FOCUS_LOST :
 | 
								case SDL_WINDOWEVENT_FOCUS_LOST :
 | 
				
			||||||
				windowFocused = false;
 | 
									windowFocused = false;
 | 
				
			||||||
				updateCursorState(cursorInWindow && windowFocused);
 | 
									updateCursorState(cursorInWindow && windowFocused && !sMenu);
 | 
				
			||||||
				resetInputStates();
 | 
									resetInputStates();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
| 
						 | 
					@ -181,6 +197,17 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (event.key.keysym.scancode == SDL_SCANCODE_F1)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (!sMenu)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										sMenu = new SettingsMenu(rtData);
 | 
				
			||||||
 | 
										updateCursorState(false);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									sMenu->raise();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (event.key.keysym.scancode == SDL_SCANCODE_F2)
 | 
								if (event.key.keysym.scancode == SDL_SCANCODE_F2)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				if (!fps.displaying)
 | 
									if (!fps.displaying)
 | 
				
			||||||
| 
						 | 
					@ -248,11 +275,7 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case SDL_JOYAXISMOTION :
 | 
							case SDL_JOYAXISMOTION :
 | 
				
			||||||
			if (event.jaxis.axis == 0)
 | 
								joyState.axis[event.jaxis.axis] = event.jaxis.value;
 | 
				
			||||||
				joyState.xAxis = event.jaxis.value;
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
				joyState.yAxis = event.jaxis.value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case SDL_JOYDEVICEADDED :
 | 
							case SDL_JOYDEVICEADDED :
 | 
				
			||||||
| 
						 | 
					@ -333,6 +356,8 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (SDL_JoystickGetAttached(js))
 | 
						if (SDL_JoystickGetAttached(js))
 | 
				
			||||||
		SDL_JoystickClose(js);
 | 
							SDL_JoystickClose(js);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						delete sMenu;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void EventThread::cleanup()
 | 
					void EventThread::cleanup()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,7 @@
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
#include "etc-internal.h"
 | 
					#include "etc-internal.h"
 | 
				
			||||||
#include "sdl-util.h"
 | 
					#include "sdl-util.h"
 | 
				
			||||||
 | 
					#include "keybindings.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <SDL_scancode.h>
 | 
					#include <SDL_scancode.h>
 | 
				
			||||||
#include <SDL_joystick.h>
 | 
					#include <SDL_joystick.h>
 | 
				
			||||||
| 
						 | 
					@ -45,10 +46,8 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct JoyState
 | 
						struct JoyState
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		int xAxis;
 | 
							int axis[256];
 | 
				
			||||||
		int yAxis;
 | 
							bool buttons[256];
 | 
				
			||||||
 | 
					 | 
				
			||||||
		bool buttons[16];
 | 
					 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static JoyState joyState;
 | 
						static JoyState joyState;
 | 
				
			||||||
| 
						 | 
					@ -155,6 +154,55 @@ struct WindowSizeNotify
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct BindingNotify
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						BindingNotify()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							mut = SDL_CreateMutex();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						~BindingNotify()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SDL_DestroyMutex(mut);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool poll(BDescVec &out) const
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (!changed)
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							SDL_LockMutex(mut);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							out = data;
 | 
				
			||||||
 | 
							changed.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							SDL_UnlockMutex(mut);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void get(BDescVec &out) const
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SDL_LockMutex(mut);
 | 
				
			||||||
 | 
							out = data;
 | 
				
			||||||
 | 
							SDL_UnlockMutex(mut);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void post(const BDescVec &d)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SDL_LockMutex(mut);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							changed.set();
 | 
				
			||||||
 | 
							data = d;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							SDL_UnlockMutex(mut);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						SDL_mutex *mut;
 | 
				
			||||||
 | 
						BDescVec data;
 | 
				
			||||||
 | 
						mutable AtomicFlag changed;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct RGSSThreadData
 | 
					struct RGSSThreadData
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* Main thread sets this to request RGSS thread to terminate */
 | 
						/* Main thread sets this to request RGSS thread to terminate */
 | 
				
			||||||
| 
						 | 
					@ -171,6 +219,7 @@ struct RGSSThreadData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	EventThread *ethread;
 | 
						EventThread *ethread;
 | 
				
			||||||
	WindowSizeNotify windowSizeMsg;
 | 
						WindowSizeNotify windowSizeMsg;
 | 
				
			||||||
 | 
						BindingNotify bindingUpdateMsg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const char *argv0;
 | 
						const char *argv0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -195,6 +195,13 @@ bool SharedFontState::fontPresent(std::string family)
 | 
				
			||||||
	return !(set.regular.empty() && set.other.empty());
 | 
						return !(set.regular.empty() && set.other.empty());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_TTF_Font *SharedFontState::openBundled(int size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						SDL_RWops *ops = openBundledFont();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return TTF_OpenFontRW(ops, 1, size);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct FontPrivate
 | 
					struct FontPrivate
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,6 +49,8 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool fontPresent(std::string family);
 | 
						bool fontPresent(std::string family);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static _TTF_Font *openBundled(int size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	SharedFontStatePrivate *p;
 | 
						SharedFontStatePrivate *p;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										225
									
								
								src/input.cpp
									
										
									
									
									
								
							
							
						
						
									
										225
									
								
								src/input.cpp
									
										
									
									
									
								
							| 
						 | 
					@ -22,6 +22,7 @@
 | 
				
			||||||
#include "input.h"
 | 
					#include "input.h"
 | 
				
			||||||
#include "sharedstate.h"
 | 
					#include "sharedstate.h"
 | 
				
			||||||
#include "eventthread.h"
 | 
					#include "eventthread.h"
 | 
				
			||||||
 | 
					#include "keybindings.h"
 | 
				
			||||||
#include "exception.h"
 | 
					#include "exception.h"
 | 
				
			||||||
#include "util.h"
 | 
					#include "util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,6 +31,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BUTTON_CODE_COUNT 24
 | 
					#define BUTTON_CODE_COUNT 24
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,12 +54,6 @@ struct KbBindingData
 | 
				
			||||||
	Input::ButtonCode target;
 | 
						Input::ButtonCode target;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct JsBindingData
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int source;
 | 
					 | 
				
			||||||
	Input::ButtonCode target;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct Binding
 | 
					struct Binding
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	Binding(Input::ButtonCode target = Input::None)
 | 
						Binding(Input::ButtonCode target = Input::None)
 | 
				
			||||||
| 
						 | 
					@ -82,6 +78,15 @@ struct KbBinding : public Binding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool sourceActive() const
 | 
						bool sourceActive() const
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							/* Special case aliases */
 | 
				
			||||||
 | 
							if (source == SDL_SCANCODE_LSHIFT)
 | 
				
			||||||
 | 
								return EventThread::keyStates[source]
 | 
				
			||||||
 | 
								    || EventThread::keyStates[SDL_SCANCODE_RSHIFT];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (source == SDL_SCANCODE_RETURN)
 | 
				
			||||||
 | 
								return EventThread::keyStates[source]
 | 
				
			||||||
 | 
								    || EventThread::keyStates[SDL_SCANCODE_KP_ENTER];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return EventThread::keyStates[source];
 | 
							return EventThread::keyStates[source];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,11 +105,6 @@ struct JsButtonBinding : public Binding
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	JsButtonBinding() {}
 | 
						JsButtonBinding() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	JsButtonBinding(const JsBindingData &data)
 | 
					 | 
				
			||||||
		: Binding(data.target),
 | 
					 | 
				
			||||||
		  source(data.source)
 | 
					 | 
				
			||||||
	{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool sourceActive() const
 | 
						bool sourceActive() const
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return EventThread::joyState.buttons[source];
 | 
							return EventThread::joyState.buttons[source];
 | 
				
			||||||
| 
						 | 
					@ -115,7 +115,7 @@ struct JsButtonBinding : public Binding
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int source;
 | 
						uint8_t source;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Joystick axis binding */
 | 
					/* Joystick axis binding */
 | 
				
			||||||
| 
						 | 
					@ -123,17 +123,22 @@ struct JsAxisBinding : public Binding
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	JsAxisBinding() {}
 | 
						JsAxisBinding() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	JsAxisBinding(int *source,
 | 
						JsAxisBinding(uint8_t source,
 | 
				
			||||||
	              int compareValue,
 | 
						              AxisDir dir,
 | 
				
			||||||
	              Input::ButtonCode target)
 | 
						              Input::ButtonCode target)
 | 
				
			||||||
	    : Binding(target),
 | 
						    : Binding(target),
 | 
				
			||||||
	      source(source),
 | 
						      source(source),
 | 
				
			||||||
	      compareValue(compareValue)
 | 
						      dir(dir)
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool sourceActive() const
 | 
						bool sourceActive() const
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return (*source == compareValue);
 | 
							int val = EventThread::joyState.axis[source];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (dir == Negative)
 | 
				
			||||||
 | 
								return val < -JAXIS_THRESHOLD;
 | 
				
			||||||
 | 
							else /* dir == Positive */
 | 
				
			||||||
 | 
								return val > JAXIS_THRESHOLD;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool sourceRepeatable() const
 | 
						bool sourceRepeatable() const
 | 
				
			||||||
| 
						 | 
					@ -141,8 +146,8 @@ struct JsAxisBinding : public Binding
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int *source;
 | 
						uint8_t source;
 | 
				
			||||||
	int compareValue;
 | 
						AxisDir dir;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Mouse button binding */
 | 
					/* Mouse button binding */
 | 
				
			||||||
| 
						 | 
					@ -172,10 +177,6 @@ struct MsBinding : public Binding
 | 
				
			||||||
/* Not rebindable */
 | 
					/* Not rebindable */
 | 
				
			||||||
static const KbBindingData staticKbBindings[] =
 | 
					static const KbBindingData staticKbBindings[] =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	{ SDL_SCANCODE_LEFT,   Input::Left  },
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_RIGHT,  Input::Right },
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_UP,     Input::Up    },
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_DOWN,   Input::Down  },
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_LSHIFT, Input::Shift },
 | 
						{ SDL_SCANCODE_LSHIFT, Input::Shift },
 | 
				
			||||||
	{ SDL_SCANCODE_RSHIFT, Input::Shift },
 | 
						{ SDL_SCANCODE_RSHIFT, Input::Shift },
 | 
				
			||||||
	{ SDL_SCANCODE_LCTRL,  Input::Ctrl  },
 | 
						{ SDL_SCANCODE_LCTRL,  Input::Ctrl  },
 | 
				
			||||||
| 
						 | 
					@ -191,61 +192,6 @@ static const KbBindingData staticKbBindings[] =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static elementsN(staticKbBindings);
 | 
					static elementsN(staticKbBindings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Rebindable */
 | 
					 | 
				
			||||||
static const KbBindingData defaultKbBindings[] =
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_SPACE,    Input::C    },
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_RETURN,   Input::C    },
 | 
					 | 
				
			||||||
    { SDL_SCANCODE_KP_ENTER, Input::C    }, /* Treated as alias of RETURN */
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_ESCAPE,   Input::B    },
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_KP_0,     Input::B    },
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_LSHIFT,   Input::A    },
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_RSHIFT,   Input::A    },
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_X,        Input::B    },
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_B,        Input::None },
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_D,        Input::Z    },
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_Q,        Input::L    },
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_W,        Input::R    },
 | 
					 | 
				
			||||||
    { SDL_SCANCODE_V,        Input::None },
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_A,        Input::X    },
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_S,        Input::Y    }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* RGSS1 */
 | 
					 | 
				
			||||||
static const KbBindingData defaultKbBindings1[] =
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_Z,        Input::A    },
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_C,        Input::C    },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* RGSS2 and higher */
 | 
					 | 
				
			||||||
static const KbBindingData defaultKbBindings2[] =
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_Z,        Input::C    },
 | 
					 | 
				
			||||||
	{ SDL_SCANCODE_C,        Input::None },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static elementsN(defaultKbBindings);
 | 
					 | 
				
			||||||
static elementsN(defaultKbBindings1);
 | 
					 | 
				
			||||||
static elementsN(defaultKbBindings2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Rebindable */
 | 
					 | 
				
			||||||
static const JsBindingData defaultJsBindings[] =
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	{ 0, Input::A    },
 | 
					 | 
				
			||||||
	{ 1, Input::B    },
 | 
					 | 
				
			||||||
	{ 2, Input::C    },
 | 
					 | 
				
			||||||
	{ 3, Input::X    },
 | 
					 | 
				
			||||||
	{ 4, Input::Y    },
 | 
					 | 
				
			||||||
	{ 5, Input::Z    },
 | 
					 | 
				
			||||||
	{ 6, Input::L    },
 | 
					 | 
				
			||||||
	{ 7, Input::R    },
 | 
					 | 
				
			||||||
	{ 8, Input::None },
 | 
					 | 
				
			||||||
	{ 9, Input::None }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static elementsN(defaultJsBindings);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Maps ButtonCode enum values to indices
 | 
					/* Maps ButtonCode enum values to indices
 | 
				
			||||||
 * in the button state array */
 | 
					 * in the button state array */
 | 
				
			||||||
static const int mapToIndex[] =
 | 
					static const int mapToIndex[] =
 | 
				
			||||||
| 
						 | 
					@ -292,6 +238,7 @@ static const Input::ButtonCode otherDirs[4][3] =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct InputPrivate
 | 
					struct InputPrivate
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						std::vector<KbBinding> kbStatBindings;
 | 
				
			||||||
	std::vector<KbBinding> kbBindings;
 | 
						std::vector<KbBinding> kbBindings;
 | 
				
			||||||
	std::vector<JsAxisBinding> jsABindings;
 | 
						std::vector<JsAxisBinding> jsABindings;
 | 
				
			||||||
	std::vector<JsButtonBinding> jsBBindings;
 | 
						std::vector<JsButtonBinding> jsBBindings;
 | 
				
			||||||
| 
						 | 
					@ -320,12 +267,14 @@ struct InputPrivate
 | 
				
			||||||
	} dir8Data;
 | 
						} dir8Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	InputPrivate()
 | 
						InputPrivate(const RGSSThreadData &rtData)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		initKbBindings();
 | 
							initStaticKbBindings();
 | 
				
			||||||
		initJsBindings();
 | 
					 | 
				
			||||||
		initMsBindings();
 | 
							initMsBindings();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Main thread should have these posted by now */
 | 
				
			||||||
 | 
							checkBindingChange(rtData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		states    = stateArray;
 | 
							states    = stateArray;
 | 
				
			||||||
		statesOld = stateArray + BUTTON_CODE_COUNT;
 | 
							statesOld = stateArray + BUTTON_CODE_COUNT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -378,51 +327,90 @@ struct InputPrivate
 | 
				
			||||||
		memset(states, 0, size);
 | 
							memset(states, 0, size);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void initKbBindings()
 | 
						void checkBindingChange(const RGSSThreadData &rtData)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		kbBindings.clear();
 | 
							BDescVec d;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (size_t i = 0; i < staticKbBindingsN; ++i)
 | 
							if (!rtData.bindingUpdateMsg.poll(d))
 | 
				
			||||||
			kbBindings.push_back(KbBinding(staticKbBindings[i]));
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (size_t i = 0; i < defaultKbBindingsN; ++i)
 | 
							applyBindingDesc(d);
 | 
				
			||||||
			kbBindings.push_back(KbBinding(defaultKbBindings[i]));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (rgssVer == 1)
 | 
					 | 
				
			||||||
			for (size_t i = 0; i < defaultKbBindings1N; ++i)
 | 
					 | 
				
			||||||
				kbBindings.push_back(KbBinding(defaultKbBindings1[i]));
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			for (size_t i = 0; i < defaultKbBindings2N; ++i)
 | 
					 | 
				
			||||||
				kbBindings.push_back(KbBinding(defaultKbBindings2[i]));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* Add to binging array */
 | 
					 | 
				
			||||||
		for (size_t i = 0; i < kbBindings.size(); ++i)
 | 
					 | 
				
			||||||
			bindings.push_back(&kbBindings[i]);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void initJsBindings()
 | 
						template<class B>
 | 
				
			||||||
 | 
						void appendBindings(std::vector<B> &bind)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* Create axis bindings */
 | 
							for (size_t i = 0; i < bind.size(); ++i)
 | 
				
			||||||
		jsABindings.resize(4);
 | 
								bindings.push_back(&bind[i]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		size_t i = 0;
 | 
						void applyBindingDesc(const BDescVec &d)
 | 
				
			||||||
		jsABindings[i++] = JsAxisBinding(&EventThread::joyState.xAxis,  0x7FFF, Input::Right);
 | 
						{
 | 
				
			||||||
		jsABindings[i++] = JsAxisBinding(&EventThread::joyState.xAxis, -0x8000, Input::Left);
 | 
							kbBindings.clear();
 | 
				
			||||||
		jsABindings[i++] = JsAxisBinding(&EventThread::joyState.yAxis,  0x7FFF, Input::Down);
 | 
							jsABindings.clear();
 | 
				
			||||||
		jsABindings[i++] = JsAxisBinding(&EventThread::joyState.yAxis, -0x8000, Input::Up);
 | 
							jsBBindings.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Create button bindings */
 | 
							for (size_t i = 0; i < d.size(); ++i)
 | 
				
			||||||
		jsBBindings.resize(defaultJsBindingsN);
 | 
							{
 | 
				
			||||||
 | 
								const BindingDesc &desc = d[i];
 | 
				
			||||||
 | 
								const SourceDesc &src = desc.src;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (size_t i = 0; i < defaultJsBindingsN; ++i)
 | 
								if (desc.target == Input::None)
 | 
				
			||||||
			jsBBindings[i] = JsButtonBinding(defaultJsBindings[i]);
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Add to binging array */
 | 
								switch (desc.src.type)
 | 
				
			||||||
		for (size_t i = 0; i < jsABindings.size(); ++i)
 | 
								{
 | 
				
			||||||
			bindings.push_back(&jsABindings[i]);
 | 
								case Invalid :
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case Key :
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									KbBinding bind;
 | 
				
			||||||
 | 
									bind.source = src.d.scan;
 | 
				
			||||||
 | 
									bind.target = desc.target;
 | 
				
			||||||
 | 
									kbBindings.push_back(bind);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (size_t i = 0; i < jsBBindings.size(); ++i)
 | 
									break;
 | 
				
			||||||
			bindings.push_back(&jsBBindings[i]);
 | 
								}
 | 
				
			||||||
 | 
								case JAxis :
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									JsAxisBinding bind;
 | 
				
			||||||
 | 
									bind.source = src.d.ja.axis;
 | 
				
			||||||
 | 
									bind.dir = src.d.ja.dir;
 | 
				
			||||||
 | 
									bind.target = desc.target;
 | 
				
			||||||
 | 
									jsABindings.push_back(bind);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								case JButton :
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									JsButtonBinding bind;
 | 
				
			||||||
 | 
									bind.source = src.d.jb;
 | 
				
			||||||
 | 
									bind.target = desc.target;
 | 
				
			||||||
 | 
									jsBBindings.push_back(bind);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								default :
 | 
				
			||||||
 | 
									assert(!"unreachable");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bindings.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							appendBindings(kbStatBindings);
 | 
				
			||||||
 | 
							appendBindings(msBindings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							appendBindings(kbBindings);
 | 
				
			||||||
 | 
							appendBindings(jsABindings);
 | 
				
			||||||
 | 
							appendBindings(jsBBindings);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void initStaticKbBindings()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							kbStatBindings.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (size_t i = 0; i < staticKbBindingsN; ++i)
 | 
				
			||||||
 | 
								kbStatBindings.push_back(KbBinding(staticKbBindings[i]));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void initMsBindings()
 | 
						void initMsBindings()
 | 
				
			||||||
| 
						 | 
					@ -433,10 +421,6 @@ struct InputPrivate
 | 
				
			||||||
		msBindings[i++] = MsBinding(SDL_BUTTON_LEFT,   Input::MouseLeft);
 | 
							msBindings[i++] = MsBinding(SDL_BUTTON_LEFT,   Input::MouseLeft);
 | 
				
			||||||
		msBindings[i++] = MsBinding(SDL_BUTTON_MIDDLE, Input::MouseMiddle);
 | 
							msBindings[i++] = MsBinding(SDL_BUTTON_MIDDLE, Input::MouseMiddle);
 | 
				
			||||||
		msBindings[i++] = MsBinding(SDL_BUTTON_RIGHT,  Input::MouseRight);
 | 
							msBindings[i++] = MsBinding(SDL_BUTTON_RIGHT,  Input::MouseRight);
 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* Add to binding array */
 | 
					 | 
				
			||||||
		for (size_t i = 0; i < msBindings.size(); ++i)
 | 
					 | 
				
			||||||
			bindings.push_back(&msBindings[i]);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void pollBindings(Input::ButtonCode &repeatCand)
 | 
						void pollBindings(Input::ButtonCode &repeatCand)
 | 
				
			||||||
| 
						 | 
					@ -564,14 +548,15 @@ struct InputPrivate
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Input::Input()
 | 
					Input::Input(const RGSSThreadData &rtData)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	p = new InputPrivate;
 | 
						p = new InputPrivate(rtData);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Input::update()
 | 
					void Input::update()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	shState->checkShutdown();
 | 
						shState->checkShutdown();
 | 
				
			||||||
 | 
						p->checkBindingChange(shState->rtData());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->swapBuffers();
 | 
						p->swapBuffers();
 | 
				
			||||||
	p->clearBuffer();
 | 
						p->clearBuffer();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,7 @@
 | 
				
			||||||
#define INPUT_H
 | 
					#define INPUT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct InputPrivate;
 | 
					struct InputPrivate;
 | 
				
			||||||
 | 
					struct RGSSThreadData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Input
 | 
					class Input
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -59,7 +60,7 @@ public:
 | 
				
			||||||
	int mouseY();
 | 
						int mouseY();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	Input();
 | 
						Input(const RGSSThreadData &rtData);
 | 
				
			||||||
	~Input();
 | 
						~Input();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	friend struct SharedStatePrivate;
 | 
						friend struct SharedStatePrivate;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										311
									
								
								src/keybindings.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										311
									
								
								src/keybindings.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,311 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					** keybindings.cpp
 | 
				
			||||||
 | 
					**
 | 
				
			||||||
 | 
					** This file is part of mkxp.
 | 
				
			||||||
 | 
					**
 | 
				
			||||||
 | 
					** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
 | 
				
			||||||
 | 
					**
 | 
				
			||||||
 | 
					** mkxp 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.
 | 
				
			||||||
 | 
					**
 | 
				
			||||||
 | 
					** mkxp 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 mkxp.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "keybindings.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#include "util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct KbBindingData
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						SDL_Scancode source;
 | 
				
			||||||
 | 
						Input::ButtonCode target;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void add(BDescVec &d) const
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SourceDesc src;
 | 
				
			||||||
 | 
							src.type = Key;
 | 
				
			||||||
 | 
							src.d.scan = source;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							BindingDesc desc;
 | 
				
			||||||
 | 
							desc.src = src;
 | 
				
			||||||
 | 
							desc.target = target;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							d.push_back(desc);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct JsBindingData
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int source;
 | 
				
			||||||
 | 
						Input::ButtonCode target;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void add(BDescVec &d) const
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SourceDesc src;
 | 
				
			||||||
 | 
							src.type = JButton;
 | 
				
			||||||
 | 
							src.d.jb = source;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							BindingDesc desc;
 | 
				
			||||||
 | 
							desc.src = src;
 | 
				
			||||||
 | 
							desc.target = target;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							d.push_back(desc);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Common */
 | 
				
			||||||
 | 
					static const KbBindingData defaultKbBindings[] =
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_LEFT,   Input::Left  },
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_RIGHT,  Input::Right },
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_UP,     Input::Up    },
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_DOWN,   Input::Down  },
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_SPACE,  Input::C     },
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_RETURN, Input::C     },
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_ESCAPE, Input::B     },
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_KP_0,   Input::B     },
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_LSHIFT, Input::A     },
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_X,      Input::B     },
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_D,      Input::Z     },
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_Q,      Input::L     },
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_W,      Input::R     },
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_A,      Input::X     },
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_S,      Input::Y     }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* RGSS1 */
 | 
				
			||||||
 | 
					static const KbBindingData defaultKbBindings1[] =
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_Z,      Input::A     },
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_C,      Input::C     },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* RGSS2 and higher */
 | 
				
			||||||
 | 
					static const KbBindingData defaultKbBindings2[] =
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						{ SDL_SCANCODE_Z,      Input::C     }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static elementsN(defaultKbBindings);
 | 
				
			||||||
 | 
					static elementsN(defaultKbBindings1);
 | 
				
			||||||
 | 
					static elementsN(defaultKbBindings2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const JsBindingData defaultJsBindings[] =
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						{ 0, Input::A },
 | 
				
			||||||
 | 
						{ 1, Input::B },
 | 
				
			||||||
 | 
						{ 2, Input::C },
 | 
				
			||||||
 | 
						{ 3, Input::X },
 | 
				
			||||||
 | 
						{ 4, Input::Y },
 | 
				
			||||||
 | 
						{ 5, Input::Z },
 | 
				
			||||||
 | 
						{ 6, Input::L },
 | 
				
			||||||
 | 
						{ 7, Input::R }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static elementsN(defaultJsBindings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void addAxisBinding(BDescVec &d, uint8_t axis, AxisDir dir, Input::ButtonCode target)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						SourceDesc src;
 | 
				
			||||||
 | 
						src.type = JAxis;
 | 
				
			||||||
 | 
						src.d.ja.axis = axis;
 | 
				
			||||||
 | 
						src.d.ja.dir = dir;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BindingDesc desc;
 | 
				
			||||||
 | 
						desc.src = src;
 | 
				
			||||||
 | 
						desc.target = target;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						d.push_back(desc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BDescVec genDefaultBindings(const Config &conf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						BDescVec d;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (size_t i = 0; i < defaultKbBindingsN; ++i)
 | 
				
			||||||
 | 
							defaultKbBindings[i].add(d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (conf.rgssVersion == 1)
 | 
				
			||||||
 | 
							for (size_t i = 0; i < defaultKbBindings1N; ++i)
 | 
				
			||||||
 | 
								defaultKbBindings1[i].add(d);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							for (size_t i = 0; i < defaultKbBindings2N; ++i)
 | 
				
			||||||
 | 
								defaultKbBindings2[i].add(d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (size_t i = 0; i < defaultJsBindingsN; ++i)
 | 
				
			||||||
 | 
							defaultJsBindings[i].add(d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						addAxisBinding(d, 0, Negative, Input::Left );
 | 
				
			||||||
 | 
						addAxisBinding(d, 0, Positive, Input::Right);
 | 
				
			||||||
 | 
						addAxisBinding(d, 1, Negative, Input::Up   );
 | 
				
			||||||
 | 
						addAxisBinding(d, 1, Positive, Input::Down );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return d;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FORMAT_VER 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Header
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t formVer;
 | 
				
			||||||
 | 
						uint32_t rgssVer;
 | 
				
			||||||
 | 
						uint32_t count;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void buildPath(const std::string &dir, uint32_t rgssVersion,
 | 
				
			||||||
 | 
					                      char *out, size_t outSize)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						snprintf(out, outSize, "%s/keybindings.mkxp%u", dir.c_str(), rgssVersion);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool writeBindings(const BDescVec &d, const std::string &dir,
 | 
				
			||||||
 | 
					                          uint32_t rgssVersion)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (dir.empty())
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char path[1024];
 | 
				
			||||||
 | 
						buildPath(dir, rgssVersion, path, sizeof(path));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FILE *f = fopen(path, "w");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!f)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Header hd;
 | 
				
			||||||
 | 
						hd.formVer = FORMAT_VER;
 | 
				
			||||||
 | 
						hd.rgssVer = rgssVersion;
 | 
				
			||||||
 | 
						hd.count = d.size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (fwrite(&hd, sizeof(hd), 1, f) < 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fclose(f);
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (fwrite(&d[0], sizeof(d[0]), hd.count, f) < hd.count)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fclose(f);
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fclose(f);
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void storeBindings(const BDescVec &d, const Config &conf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (writeBindings(d, conf.customDataPath, conf.rgssVersion))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeBindings(d, conf.commonDataPath, conf.rgssVersion);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define READ(ptr, size, n, f) if (fread(ptr, size, n, f) < n) return false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool verifyDesc(const BindingDesc &desc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const Input::ButtonCode codes[] =
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						    Input::None,
 | 
				
			||||||
 | 
						    Input::Down, Input::Left, Input::Right, Input::Up,
 | 
				
			||||||
 | 
						    Input::A, Input::B, Input::C,
 | 
				
			||||||
 | 
						    Input::X, Input::Y, Input::Z,
 | 
				
			||||||
 | 
						    Input::L, Input::R,
 | 
				
			||||||
 | 
						    Input::Shift, Input::Ctrl, Input::Alt,
 | 
				
			||||||
 | 
						    Input::F5, Input::F6, Input::F7, Input::F8, Input::F9
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						elementsN(codes);
 | 
				
			||||||
 | 
						size_t i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < codesN; ++i)
 | 
				
			||||||
 | 
							if (desc.target == codes[i])
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (i == codesN)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const SourceDesc &src = desc.src;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (src.type)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						case Invalid:
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						case Key:
 | 
				
			||||||
 | 
							return src.d.scan < SDL_NUM_SCANCODES;
 | 
				
			||||||
 | 
						case JButton:
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						case JAxis:
 | 
				
			||||||
 | 
							return src.d.ja.dir == Negative || src.d.ja.dir == Positive;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool readBindings(BDescVec &out, const std::string &dir,
 | 
				
			||||||
 | 
					                         uint32_t rgssVersion)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (dir.empty())
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char path[1024];
 | 
				
			||||||
 | 
						buildPath(dir, rgssVersion, path, sizeof(path));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FILE *f = fopen(path, "r");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!f)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Header hd;
 | 
				
			||||||
 | 
						if (fread(&hd, sizeof(hd), 1, f) < 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fclose(f);
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (hd.formVer != FORMAT_VER)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						if (hd.rgssVer != rgssVersion)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						/* Arbitrary max value */
 | 
				
			||||||
 | 
						if (hd.count > 1024)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						out.resize(hd.count);
 | 
				
			||||||
 | 
						if (fread(&out[0], sizeof(out[0]), hd.count, f) < hd.count)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fclose(f);
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (size_t i = 0; i < hd.count; ++i)
 | 
				
			||||||
 | 
							if (!verifyDesc(out[i]))
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BDescVec loadBindings(const Config &conf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						BDescVec d;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (readBindings(d, conf.customDataPath, conf.rgssVersion))
 | 
				
			||||||
 | 
							return d;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (readBindings(d, conf.commonDataPath, conf.rgssVersion))
 | 
				
			||||||
 | 
							return d;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return genDefaultBindings(conf);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										108
									
								
								src/keybindings.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								src/keybindings.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,108 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					** keybindings.h
 | 
				
			||||||
 | 
					**
 | 
				
			||||||
 | 
					** This file is part of mkxp.
 | 
				
			||||||
 | 
					**
 | 
				
			||||||
 | 
					** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
 | 
				
			||||||
 | 
					**
 | 
				
			||||||
 | 
					** mkxp 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.
 | 
				
			||||||
 | 
					**
 | 
				
			||||||
 | 
					** mkxp 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 mkxp.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef KEYBINDINGS_H
 | 
				
			||||||
 | 
					#define KEYBINDINGS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "input.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <SDL_scancode.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum AxisDir
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Negative,
 | 
				
			||||||
 | 
						Positive
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum SourceType
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Invalid,
 | 
				
			||||||
 | 
						Key,
 | 
				
			||||||
 | 
						JButton,
 | 
				
			||||||
 | 
						JAxis
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct SourceDesc
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						SourceType type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						union Data
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/* Keyboard scancode */
 | 
				
			||||||
 | 
							SDL_Scancode scan;
 | 
				
			||||||
 | 
							/* Joystick button index */
 | 
				
			||||||
 | 
							uint8_t jb;
 | 
				
			||||||
 | 
							struct
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* Joystick axis index */
 | 
				
			||||||
 | 
								uint8_t axis;
 | 
				
			||||||
 | 
								/* Joystick axis direction */
 | 
				
			||||||
 | 
								AxisDir dir;
 | 
				
			||||||
 | 
							} ja;
 | 
				
			||||||
 | 
						} d;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool operator==(const SourceDesc &o) const
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (type != o.type)
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch (type)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							case Invalid:
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							case Key:
 | 
				
			||||||
 | 
								return d.scan == o.d.scan;
 | 
				
			||||||
 | 
							case JButton:
 | 
				
			||||||
 | 
								return d.jb == o.d.jb;
 | 
				
			||||||
 | 
							case JAxis:
 | 
				
			||||||
 | 
								return (d.ja.axis == o.d.ja.axis) && (d.ja.dir == o.d.ja.dir);
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								assert(!"unreachable");
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool operator!=(const SourceDesc &o) const
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return !(*this == o);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define JAXIS_THRESHOLD 0x4000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct BindingDesc
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						SourceDesc src;
 | 
				
			||||||
 | 
						Input::ButtonCode target;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef std::vector<BindingDesc> BDescVec;
 | 
				
			||||||
 | 
					struct Config;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BDescVec genDefaultBindings(const Config &conf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void storeBindings(const BDescVec &d, const Config &conf);
 | 
				
			||||||
 | 
					BDescVec loadBindings(const Config &conf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // KEYBINDINGS_H
 | 
				
			||||||
							
								
								
									
										10
									
								
								src/main.cpp
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								src/main.cpp
									
										
									
									
									
								
							| 
						 | 
					@ -238,7 +238,7 @@ int main(int argc, char *argv[])
 | 
				
			||||||
	SDL_SetHint("SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS", "0");
 | 
						SDL_SetHint("SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS", "0");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SDL_Window *win;
 | 
						SDL_Window *win;
 | 
				
			||||||
	Uint32 winFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
 | 
						Uint32 winFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_INPUT_FOCUS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (conf.winResizable)
 | 
						if (conf.winResizable)
 | 
				
			||||||
		winFlags |= SDL_WINDOW_RESIZABLE;
 | 
							winFlags |= SDL_WINDOW_RESIZABLE;
 | 
				
			||||||
| 
						 | 
					@ -268,6 +268,9 @@ int main(int argc, char *argv[])
 | 
				
			||||||
	EventThread eventThread;
 | 
						EventThread eventThread;
 | 
				
			||||||
	RGSSThreadData rtData(&eventThread, argv[0], win, conf);
 | 
						RGSSThreadData rtData(&eventThread, argv[0], win, conf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Load and post key bindings */
 | 
				
			||||||
 | 
						rtData.bindingUpdateMsg.post(loadBindings(conf));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Start RGSS thread */
 | 
						/* Start RGSS thread */
 | 
				
			||||||
	SDL_Thread *rgssThread =
 | 
						SDL_Thread *rgssThread =
 | 
				
			||||||
	        SDL_CreateThread(rgssThreadFun, "rgss", &rtData);
 | 
						        SDL_CreateThread(rgssThreadFun, "rgss", &rtData);
 | 
				
			||||||
| 
						 | 
					@ -310,6 +313,11 @@ int main(int argc, char *argv[])
 | 
				
			||||||
	/* Clean up any remainin events */
 | 
						/* Clean up any remainin events */
 | 
				
			||||||
	eventThread.cleanup();
 | 
						eventThread.cleanup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Store key bindings */
 | 
				
			||||||
 | 
						BDescVec keyBinds;
 | 
				
			||||||
 | 
						rtData.bindingUpdateMsg.get(keyBinds);
 | 
				
			||||||
 | 
						storeBindings(keyBinds, rtData.config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Debug() << "Shutting down.";
 | 
						Debug() << "Shutting down.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SDL_DestroyWindow(win);
 | 
						SDL_DestroyWindow(win);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1112
									
								
								src/settingsmenu.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1112
									
								
								src/settingsmenu.cpp
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										46
									
								
								src/settingsmenu.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/settingsmenu.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,46 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					** settingsmenu.h
 | 
				
			||||||
 | 
					**
 | 
				
			||||||
 | 
					** This file is part of mkxp.
 | 
				
			||||||
 | 
					**
 | 
				
			||||||
 | 
					** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
 | 
				
			||||||
 | 
					**
 | 
				
			||||||
 | 
					** mkxp 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.
 | 
				
			||||||
 | 
					**
 | 
				
			||||||
 | 
					** mkxp 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 mkxp.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef SETTINGSMENU_H
 | 
				
			||||||
 | 
					#define SETTINGSMENU_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct SettingsMenuPrivate;
 | 
				
			||||||
 | 
					struct RGSSThreadData;
 | 
				
			||||||
 | 
					union SDL_Event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SettingsMenu
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						SettingsMenu(RGSSThreadData &rtData);
 | 
				
			||||||
 | 
						~SettingsMenu();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Returns true if the event was consumed */
 | 
				
			||||||
 | 
						bool onEvent(const SDL_Event &event);
 | 
				
			||||||
 | 
						void raise();
 | 
				
			||||||
 | 
						bool destroyReq() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						SettingsMenuPrivate *p;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // SETTINGSMENU_H
 | 
				
			||||||
| 
						 | 
					@ -106,6 +106,7 @@ struct SharedStatePrivate
 | 
				
			||||||
	      config(threadData->config),
 | 
						      config(threadData->config),
 | 
				
			||||||
	      midiState(threadData->config),
 | 
						      midiState(threadData->config),
 | 
				
			||||||
	      graphics(threadData),
 | 
						      graphics(threadData),
 | 
				
			||||||
 | 
						      input(*threadData),
 | 
				
			||||||
	      audio(threadData->config),
 | 
						      audio(threadData->config),
 | 
				
			||||||
	      fontState(threadData->config),
 | 
						      fontState(threadData->config),
 | 
				
			||||||
	      stampCounter(0)
 | 
						      stampCounter(0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue