Compare commits
109 Commits
master
...
gtk3-app-r
Author | SHA1 | Date | |
---|---|---|---|
32969c0959 | |||
39af396004 | |||
cc4be1f903 | |||
6ce3016719 | |||
c125083a45 | |||
db325ad44d | |||
1201b8928f | |||
39ad93210c | |||
dcf2481fcf | |||
f45613f715 | |||
46821dd49a | |||
d365f44fec | |||
e46d87257c | |||
a56a97d657 | |||
cc0827c429 | |||
07f6da4c9e | |||
5049f400f0 | |||
863e6de420 | |||
92cc8b6c6e | |||
50326f4058 | |||
dac9d29ab2 | |||
e6aef1ce82 | |||
55a258ad0f | |||
bef38d16d2 | |||
337f396eff | |||
d63560d3c1 | |||
a39937aeb2 | |||
7ce7c8c404 | |||
6a15ff582e | |||
f74b1cd3d9 | |||
825786210a | |||
accaedbdac | |||
7dbd0e18f9 | |||
7e9ebde585 | |||
45e62a2f26 | |||
1d7034fb88 | |||
add54953c6 | |||
6ea36bbc39 | |||
f6838a901c | |||
bdb22e7034 | |||
2887110e99 | |||
116ea7d0d7 | |||
f7beeb9c98 | |||
f46d35528b | |||
65fe7f2f9c | |||
008db16fb5 | |||
b6c949fa82 | |||
8c3154a061 | |||
3fe57f976c | |||
4042b7f38c | |||
4075a13b61 | |||
4ac7c0dd0d | |||
6594edf1bf | |||
89080ef47e | |||
a08e1d1c83 | |||
8780aafe99 | |||
15d949e338 | |||
c00946ea2e | |||
e42d16290d | |||
9b360ef292 | |||
836cb024b5 | |||
b142227577 | |||
5b79094293 | |||
53934aedec | |||
16c040d2d2 | |||
8f9d24c1e8 | |||
b428995126 | |||
a53d7f1e92 | |||
29ce04ff8a | |||
a1b464bd23 | |||
9224b3f2ac | |||
6a9ca41970 | |||
df9189448d | |||
10ac1bd0a5 | |||
e1a1c3efbd | |||
e38b0e40fa | |||
ba82da5f49 | |||
94e1b397ca | |||
36299d124a | |||
bf2dc12fb9 | |||
0b3ad8bcfd | |||
3de0d8fb6a | |||
0270ed336e | |||
cf0bfc6076 | |||
a032722e84 | |||
bf8ac1f00d | |||
517ad73e64 | |||
8e8e576460 | |||
8d0526fd1f | |||
c27e266cda | |||
8ce3b02833 | |||
a83d6eca5b | |||
6c5dfece40 | |||
a243325b8c | |||
023d43e893 | |||
90c0447703 | |||
0d07a389ca | |||
fc81729533 | |||
1f7cd57df8 | |||
3984359008 | |||
959f0cc88e | |||
6e263cd22a | |||
f3f1bf293a | |||
d6a1555290 | |||
f1d0344672 | |||
62bfe0cef9 | |||
6e65945c35 | |||
4d4d272a5c | |||
bba05ac5b9 |
9
.gitignore
vendored
@ -1 +1,10 @@
|
|||||||
build
|
build
|
||||||
|
|
||||||
|
# intermediate source files generated at build time
|
||||||
|
gtk3/sameboy-gtk3-resources.c
|
||||||
|
gtk3/resources/gtk3/
|
||||||
|
gtk3/resources/ui/#*#
|
||||||
|
|
||||||
|
# temporary backup file
|
||||||
|
*.*~
|
||||||
|
|
||||||
|
@ -2426,6 +2426,29 @@ void GB_debugger_add_symbol(GB_gameboy_t *gb, uint16_t bank, uint16_t address, c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GB_debugger_load_symbol_file_from_buffer(GB_gameboy_t *gb, const char *buffer, size_t size)
|
||||||
|
{
|
||||||
|
const char *str_ptr = buffer;
|
||||||
|
unsigned length = 0;
|
||||||
|
|
||||||
|
while (str_ptr && size--) {
|
||||||
|
length++;
|
||||||
|
char c = (char) *str_ptr++;
|
||||||
|
|
||||||
|
if (c == '\n' || size == 0) {
|
||||||
|
const char *line = str_ptr - length--;
|
||||||
|
unsigned bank, address;
|
||||||
|
char symbol[length];
|
||||||
|
|
||||||
|
if (sscanf(line, "%x:%x %s", &bank, &address, symbol) == 3) {
|
||||||
|
GB_debugger_add_symbol(gb, bank, address, symbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
length = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GB_debugger_load_symbol_file(GB_gameboy_t *gb, const char *path)
|
void GB_debugger_load_symbol_file(GB_gameboy_t *gb, const char *path)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(path, "r");
|
FILE *f = fopen(path, "r");
|
||||||
|
@ -35,7 +35,7 @@ void
|
|||||||
#endif
|
#endif
|
||||||
GB_debugger_execute_command(GB_gameboy_t *gb, char *input); /* Destroys input. */
|
GB_debugger_execute_command(GB_gameboy_t *gb, char *input); /* Destroys input. */
|
||||||
char *GB_debugger_complete_substring(GB_gameboy_t *gb, char *input, uintptr_t *context); /* Destroys input, result requires free */
|
char *GB_debugger_complete_substring(GB_gameboy_t *gb, char *input, uintptr_t *context); /* Destroys input, result requires free */
|
||||||
|
void GB_debugger_load_symbol_file_from_buffer(GB_gameboy_t *gb, const char *buffer, size_t size);
|
||||||
void GB_debugger_load_symbol_file(GB_gameboy_t *gb, const char *path);
|
void GB_debugger_load_symbol_file(GB_gameboy_t *gb, const char *path);
|
||||||
const char *GB_debugger_name_for_address(GB_gameboy_t *gb, uint16_t addr);
|
const char *GB_debugger_name_for_address(GB_gameboy_t *gb, uint16_t addr);
|
||||||
bool GB_debugger_evaluate(GB_gameboy_t *gb, const char *string, uint16_t *result, uint16_t *result_bank); /* result_bank is -1 if unused. */
|
bool GB_debugger_evaluate(GB_gameboy_t *gb, const char *string, uint16_t *result, uint16_t *result_bank); /* result_bank is -1 if unused. */
|
||||||
|
75
Makefile
@ -1,5 +1,5 @@
|
|||||||
# Make hacks
|
# Make hacks
|
||||||
.INTERMEDIATE:
|
.INTERMEDIATE: gtk3/sameboy-gtk3-resources.c
|
||||||
|
|
||||||
# Set target, configuration, version and destination folders
|
# Set target, configuration, version and destination folders
|
||||||
|
|
||||||
@ -128,6 +128,33 @@ else
|
|||||||
GL_CFLAGS := $(shell $(PKG_CONFIG) --cflags gl)
|
GL_CFLAGS := $(shell $(PKG_CONFIG) --cflags gl)
|
||||||
GL_LDFLAGS := $(shell $(PKG_CONFIG) --libs gl || echo -lGL)
|
GL_LDFLAGS := $(shell $(PKG_CONFIG) --libs gl || echo -lGL)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq (,$(PKG_CONFIG))
|
||||||
|
ifneq ($(findstring gtk3,$(MAKECMDGOALS)),)
|
||||||
|
$(error The gtk3 target requires pkg-config)
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
GTK_OPTIONS := -DGDK_DISABLE_DEPRECATED=1 -DGTK_DISABLE_DEPRECATED=1 -DG_DISABLE_DEPRECATED=1 -DG_LOG_DOMAIN=\"SameBoy\" -DRESOURCE_PREFIX=\"/io/github/sameboy/\" -DAPP_ID=\"io.github.sameboy\"
|
||||||
|
|
||||||
|
ifeq ($(SDL_AUDIO_DRIVER),sdl)
|
||||||
|
GTK_OPTIONS += -DUSE_SDL_AUDIO
|
||||||
|
endif
|
||||||
|
|
||||||
|
GTK3_CFLAGS := $(shell $(PKG_CONFIG) --cflags gio-2.0 gtk+-3.0 epoxy) $(GTK_OPTIONS)
|
||||||
|
GTK3_LDFLAGS := $(shell $(PKG_CONFIG) --libs gio-2.0 gtk+-3.0 epoxy)
|
||||||
|
|
||||||
|
ifdef LINK_STATIC_SDL
|
||||||
|
GTK3_CFLAGS += $(shell $(PKG_CONFIG) --cflags sdl2)
|
||||||
|
GTK3_LDFLAGS += $(shell $(PKG_CONFIG) --libs --static sdl2 | sed -e 's/-lSDL2//' | sed -e 's/^-L\([^ ]\+\)/\1\/libSDL2.a -L\1/')
|
||||||
|
else
|
||||||
|
GTK3_CFLAGS += $(shell $(PKG_CONFIG) --cflags sdl2)
|
||||||
|
GTK3_LDFLAGS += $(shell $(PKG_CONFIG) --libs sdl2)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# TODO: REMOVE DISABLE UNUSED WARNINGS
|
||||||
|
GTK3_CFLAGS += -Wno-unused
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(PLATFORM),windows32)
|
ifeq ($(PLATFORM),windows32)
|
||||||
CFLAGS += -IWindows -Drandom=rand --target=i386-pc-windows
|
CFLAGS += -IWindows -Drandom=rand --target=i386-pc-windows
|
||||||
LDFLAGS += -lmsvcrt -lcomdlg32 -luser32 -lshell32 -lole32 -lSDL2main -Wl,/MANIFESTFILE:NUL --target=i386-pc-windows
|
LDFLAGS += -lmsvcrt -lcomdlg32 -luser32 -lshell32 -lole32 -lSDL2main -Wl,/MANIFESTFILE:NUL --target=i386-pc-windows
|
||||||
@ -135,6 +162,7 @@ SDL_LDFLAGS := -lSDL2
|
|||||||
GL_LDFLAGS := -lopengl32
|
GL_LDFLAGS := -lopengl32
|
||||||
else
|
else
|
||||||
LDFLAGS += -lc -lm -ldl
|
LDFLAGS += -lc -lm -ldl
|
||||||
|
GTK3_LDFLAGS += -Wl -rdynamic
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(PLATFORM),Darwin)
|
ifeq ($(PLATFORM),Darwin)
|
||||||
@ -189,6 +217,7 @@ endif
|
|||||||
cocoa: $(BIN)/SameBoy.app
|
cocoa: $(BIN)/SameBoy.app
|
||||||
quicklook: $(BIN)/SameBoy.qlgenerator
|
quicklook: $(BIN)/SameBoy.qlgenerator
|
||||||
sdl: $(SDL_TARGET) $(BIN)/SDL/dmg_boot.bin $(BIN)/SDL/cgb_boot.bin $(BIN)/SDL/agb_boot.bin $(BIN)/SDL/sgb_boot.bin $(BIN)/SDL/sgb2_boot.bin $(BIN)/SDL/LICENSE $(BIN)/SDL/registers.sym $(BIN)/SDL/background.bmp $(BIN)/SDL/Shaders
|
sdl: $(SDL_TARGET) $(BIN)/SDL/dmg_boot.bin $(BIN)/SDL/cgb_boot.bin $(BIN)/SDL/agb_boot.bin $(BIN)/SDL/sgb_boot.bin $(BIN)/SDL/sgb2_boot.bin $(BIN)/SDL/LICENSE $(BIN)/SDL/registers.sym $(BIN)/SDL/background.bmp $(BIN)/SDL/Shaders
|
||||||
|
gtk3: $(BIN)/gtk3/sameboy
|
||||||
bootroms: $(BIN)/BootROMs/agb_boot.bin $(BIN)/BootROMs/cgb_boot.bin $(BIN)/BootROMs/dmg_boot.bin $(BIN)/BootROMs/sgb_boot.bin $(BIN)/BootROMs/sgb2_boot.bin
|
bootroms: $(BIN)/BootROMs/agb_boot.bin $(BIN)/BootROMs/cgb_boot.bin $(BIN)/BootROMs/dmg_boot.bin $(BIN)/BootROMs/sgb_boot.bin $(BIN)/BootROMs/sgb2_boot.bin
|
||||||
tester: $(TESTER_TARGET) $(BIN)/tester/dmg_boot.bin $(BIN)/tester/cgb_boot.bin $(BIN)/tester/agb_boot.bin $(BIN)/tester/sgb_boot.bin $(BIN)/tester/sgb2_boot.bin
|
tester: $(TESTER_TARGET) $(BIN)/tester/dmg_boot.bin $(BIN)/tester/cgb_boot.bin $(BIN)/tester/agb_boot.bin $(BIN)/tester/sgb_boot.bin $(BIN)/tester/sgb2_boot.bin
|
||||||
all: cocoa sdl tester libretro
|
all: cocoa sdl tester libretro
|
||||||
@ -197,6 +226,7 @@ all: cocoa sdl tester libretro
|
|||||||
|
|
||||||
CORE_SOURCES := $(shell ls Core/*.c)
|
CORE_SOURCES := $(shell ls Core/*.c)
|
||||||
SDL_SOURCES := $(shell ls SDL/*.c) $(OPEN_DIALOG) SDL/audio/$(SDL_AUDIO_DRIVER).c
|
SDL_SOURCES := $(shell ls SDL/*.c) $(OPEN_DIALOG) SDL/audio/$(SDL_AUDIO_DRIVER).c
|
||||||
|
GTK3_SOURCES := $(shell ls gtk3/*.c gtk3/**/*.c) gtk3/sameboy-gtk3-resources.c SDL/audio/$(SDL_AUDIO_DRIVER).c
|
||||||
TESTER_SOURCES := $(shell ls Tester/*.c)
|
TESTER_SOURCES := $(shell ls Tester/*.c)
|
||||||
|
|
||||||
ifeq ($(PLATFORM),Darwin)
|
ifeq ($(PLATFORM),Darwin)
|
||||||
@ -212,6 +242,7 @@ CORE_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(CORE_SOURCES))
|
|||||||
COCOA_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(COCOA_SOURCES))
|
COCOA_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(COCOA_SOURCES))
|
||||||
QUICKLOOK_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(QUICKLOOK_SOURCES))
|
QUICKLOOK_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(QUICKLOOK_SOURCES))
|
||||||
SDL_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(SDL_SOURCES))
|
SDL_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(SDL_SOURCES))
|
||||||
|
GTK3_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(GTK3_SOURCES))
|
||||||
TESTER_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(TESTER_SOURCES))
|
TESTER_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(TESTER_SOURCES))
|
||||||
|
|
||||||
# Automatic dependency generation
|
# Automatic dependency generation
|
||||||
@ -221,6 +252,9 @@ ifneq ($(filter-out clean bootroms libretro %.bin, $(MAKECMDGOALS)),)
|
|||||||
ifneq ($(filter $(MAKECMDGOALS),sdl),)
|
ifneq ($(filter $(MAKECMDGOALS),sdl),)
|
||||||
-include $(SDL_OBJECTS:.o=.dep)
|
-include $(SDL_OBJECTS:.o=.dep)
|
||||||
endif
|
endif
|
||||||
|
ifneq ($(filter $(MAKECMDGOALS),gtk3),)
|
||||||
|
-include $(GTK3_OBJECTS:.o=.gtk3dep)
|
||||||
|
endif
|
||||||
ifneq ($(filter $(MAKECMDGOALS),tester),)
|
ifneq ($(filter $(MAKECMDGOALS),tester),)
|
||||||
-include $(TESTER_OBJECTS:.o=.dep)
|
-include $(TESTER_OBJECTS:.o=.dep)
|
||||||
endif
|
endif
|
||||||
@ -233,6 +267,16 @@ $(OBJ)/SDL/%.dep: SDL/%
|
|||||||
-@$(MKDIR) -p $(dir $@)
|
-@$(MKDIR) -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) $(SDL_CFLAGS) $(GL_CFLAGS) -MT $(OBJ)/$^.o -M $^ -c -o $@
|
$(CC) $(CFLAGS) $(SDL_CFLAGS) $(GL_CFLAGS) -MT $(OBJ)/$^.o -M $^ -c -o $@
|
||||||
|
|
||||||
|
gtk3/sameboy-gtk3-resources.c: gtk3/sameboy.gresource.xml $(shell glib-compile-resources --sourcedir=gtk3/resources --generate-dependencies gtk3/sameboy.gresource.xml)
|
||||||
|
glib-compile-resources --sourcedir=gtk3/resources --target=$@ --generate-source $<
|
||||||
|
# Resource hack cleanup
|
||||||
|
rm -rf gtk3/resources/gtk3
|
||||||
|
|
||||||
|
# GTK3 requires special CFLAGS
|
||||||
|
$(OBJ)/gtk3/%.gtk3dep: %
|
||||||
|
-@$(MKDIR) -p $(dir $@)
|
||||||
|
$(CC) $(CFLAGS) $(GTK3_CFLAGS) -MT $(OBJ)/$^.o -M $^ -c -o $@
|
||||||
|
|
||||||
$(OBJ)/%.dep: %
|
$(OBJ)/%.dep: %
|
||||||
-@$(MKDIR) -p $(dir $@)
|
-@$(MKDIR) -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) -MT $(OBJ)/$^.o -M $^ -c -o $@
|
$(CC) $(CFLAGS) -MT $(OBJ)/$^.o -M $^ -c -o $@
|
||||||
@ -247,6 +291,11 @@ $(OBJ)/SDL/%.c.o: SDL/%.c
|
|||||||
-@$(MKDIR) -p $(dir $@)
|
-@$(MKDIR) -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) $(FAT_FLAGS) $(SDL_CFLAGS) $(GL_CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) $(FAT_FLAGS) $(SDL_CFLAGS) $(GL_CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
# GTK3 requires special CFLAGS
|
||||||
|
$(OBJ)/gtk3/%.c.o: gtk3/%.c
|
||||||
|
-@$(MKDIR) -p $(dir $@)
|
||||||
|
$(CC) $(CFLAGS) $(GTK3_CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(OBJ)/%.c.o: %.c
|
$(OBJ)/%.c.o: %.c
|
||||||
-@$(MKDIR) -p $(dir $@)
|
-@$(MKDIR) -p $(dir $@)
|
||||||
$(CC) $(CFLAGS) $(FAT_FLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) $(FAT_FLAGS) -c $< -o $@
|
||||||
@ -326,7 +375,7 @@ ifeq ($(CONF), release)
|
|||||||
$(STRIP) $@
|
$(STRIP) $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Windows version builds two, one with a conole and one without it
|
# Windows version builds two, one with a console and one without it
|
||||||
$(BIN)/SDL/sameboy.exe: $(CORE_OBJECTS) $(SDL_OBJECTS) $(OBJ)/Windows/resources.o
|
$(BIN)/SDL/sameboy.exe: $(CORE_OBJECTS) $(SDL_OBJECTS) $(OBJ)/Windows/resources.o
|
||||||
-@$(MKDIR) -p $(dir $@)
|
-@$(MKDIR) -p $(dir $@)
|
||||||
$(CC) $^ -o $@ $(LDFLAGS) $(SDL_LDFLAGS) $(GL_LDFLAGS) -Wl,/subsystem:windows
|
$(CC) $^ -o $@ $(LDFLAGS) $(SDL_LDFLAGS) $(GL_LDFLAGS) -Wl,/subsystem:windows
|
||||||
@ -353,6 +402,15 @@ $(BIN)/SDL/SDL2.dll:
|
|||||||
@$(eval MATCH := $(shell where $$LIB:SDL2.dll))
|
@$(eval MATCH := $(shell where $$LIB:SDL2.dll))
|
||||||
cp "$(MATCH)" $@
|
cp "$(MATCH)" $@
|
||||||
|
|
||||||
|
# GTK3
|
||||||
|
|
||||||
|
$(BIN)/gtk3/sameboy: $(CORE_OBJECTS) $(GTK3_OBJECTS)
|
||||||
|
-@$(MKDIR) -p $(dir $@)
|
||||||
|
$(CC) $^ -o $@ $(LDFLAGS) $(GTK3_LDFLAGS)
|
||||||
|
ifeq ($(CONF), release)
|
||||||
|
strip $@
|
||||||
|
endif
|
||||||
|
|
||||||
# Tester
|
# Tester
|
||||||
|
|
||||||
$(BIN)/tester/sameboy_tester: $(CORE_OBJECTS) $(TESTER_OBJECTS)
|
$(BIN)/tester/sameboy_tester: $(CORE_OBJECTS) $(TESTER_OBJECTS)
|
||||||
@ -394,6 +452,19 @@ $(BIN)/SDL/Shaders: Shaders
|
|||||||
-@$(MKDIR) -p $@
|
-@$(MKDIR) -p $@
|
||||||
cp -rf Shaders/*.fsh $@
|
cp -rf Shaders/*.fsh $@
|
||||||
|
|
||||||
|
# Fugly resource hack
|
||||||
|
gtk3/resources/bootroms/%.bin: $(BOOTROMS_DIR)/%.bin
|
||||||
|
-@$(MKDIR) -p gtk3/resources/gtk3/resources/bootroms/
|
||||||
|
cp -f $< gtk3/resources/$@
|
||||||
|
|
||||||
|
gtk3/resources/Shaders/%.fsh: Shaders/%.fsh
|
||||||
|
-@$(MKDIR) -p gtk3/resources/gtk3/resources/Shaders/
|
||||||
|
cp -rf $< gtk3/resources/$@
|
||||||
|
|
||||||
|
gtk3/resources/Misc/%: Misc/%
|
||||||
|
-@$(MKDIR) -p gtk3/resources/gtk3/resources/Misc/
|
||||||
|
cp -rf $< gtk3/resources/$@
|
||||||
|
|
||||||
# Boot ROMs
|
# Boot ROMs
|
||||||
|
|
||||||
$(OBJ)/%.2bpp: %.png
|
$(OBJ)/%.2bpp: %.png
|
||||||
|
@ -5,12 +5,14 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <Core/gb.h>
|
#include <Core/gb.h>
|
||||||
|
|
||||||
|
unsigned GB_audio_default_sample_rate(void);
|
||||||
bool GB_audio_is_playing(void);
|
bool GB_audio_is_playing(void);
|
||||||
void GB_audio_set_paused(bool paused);
|
void GB_audio_set_paused(bool paused);
|
||||||
void GB_audio_clear_queue(void);
|
void GB_audio_clear_queue(void);
|
||||||
unsigned GB_audio_get_frequency(void);
|
unsigned GB_audio_get_sample_rate(void);
|
||||||
size_t GB_audio_get_queue_length(void);
|
size_t GB_audio_get_queue_length(void);
|
||||||
void GB_audio_queue_sample(GB_sample_t *sample);
|
void GB_audio_queue_sample(GB_sample_t *sample);
|
||||||
void GB_audio_init(void);
|
void GB_audio_init(unsigned sample_rate);
|
||||||
|
void GB_audio_destroy(void);
|
||||||
|
|
||||||
#endif /* sdl_audio_h */
|
#endif /* sdl_audio_h */
|
||||||
|
@ -29,6 +29,11 @@ static SDL_AudioSpec want_aspec, have_aspec;
|
|||||||
static unsigned buffer_pos = 0;
|
static unsigned buffer_pos = 0;
|
||||||
static GB_sample_t audio_buffer[AUDIO_BUFFER_SIZE];
|
static GB_sample_t audio_buffer[AUDIO_BUFFER_SIZE];
|
||||||
|
|
||||||
|
unsigned GB_audio_default_sample_rate(void)
|
||||||
|
{
|
||||||
|
return AUDIO_FREQUENCY;
|
||||||
|
}
|
||||||
|
|
||||||
bool GB_audio_is_playing(void)
|
bool GB_audio_is_playing(void)
|
||||||
{
|
{
|
||||||
return SDL_GetAudioDeviceStatus(device_id) == SDL_AUDIO_PLAYING;
|
return SDL_GetAudioDeviceStatus(device_id) == SDL_AUDIO_PLAYING;
|
||||||
@ -45,7 +50,7 @@ void GB_audio_clear_queue(void)
|
|||||||
SDL_ClearQueuedAudio(device_id);
|
SDL_ClearQueuedAudio(device_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned GB_audio_get_frequency(void)
|
unsigned GB_audio_get_sample_rate(void)
|
||||||
{
|
{
|
||||||
return have_aspec.freq;
|
return have_aspec.freq;
|
||||||
}
|
}
|
||||||
@ -65,11 +70,11 @@ void GB_audio_queue_sample(GB_sample_t *sample)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GB_audio_init(void)
|
void GB_audio_init(unsigned sample_rate)
|
||||||
{
|
{
|
||||||
/* Configure Audio */
|
/* Configure Audio */
|
||||||
memset(&want_aspec, 0, sizeof(want_aspec));
|
memset(&want_aspec, 0, sizeof(want_aspec));
|
||||||
want_aspec.freq = AUDIO_FREQUENCY;
|
want_aspec.freq = sample_rate == 0 ? GB_audio_default_sample_rate() : sample_rate;
|
||||||
want_aspec.format = AUDIO_S16SYS;
|
want_aspec.format = AUDIO_S16SYS;
|
||||||
want_aspec.channels = 2;
|
want_aspec.channels = 2;
|
||||||
want_aspec.samples = 512;
|
want_aspec.samples = 512;
|
||||||
@ -94,3 +99,9 @@ void GB_audio_init(void)
|
|||||||
|
|
||||||
device_id = SDL_OpenAudioDevice(0, 0, &want_aspec, &have_aspec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_SAMPLES_CHANGE);
|
device_id = SDL_OpenAudioDevice(0, 0, &want_aspec, &have_aspec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_SAMPLES_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GB_audio_destroy() {
|
||||||
|
GB_audio_set_paused(true);
|
||||||
|
|
||||||
|
SDL_CloseAudioDevice(device_id);
|
||||||
|
}
|
||||||
|
10
SDL/main.c
@ -389,15 +389,15 @@ static void gb_audio_callback(GB_gameboy_t *gb, GB_sample_t *sample)
|
|||||||
if (turbo_down) {
|
if (turbo_down) {
|
||||||
static unsigned skip = 0;
|
static unsigned skip = 0;
|
||||||
skip++;
|
skip++;
|
||||||
if (skip == GB_audio_get_frequency() / 8) {
|
if (skip == GB_audio_get_sample_rate() / 8) {
|
||||||
skip = 0;
|
skip = 0;
|
||||||
}
|
}
|
||||||
if (skip > GB_audio_get_frequency() / 16) {
|
if (skip > GB_audio_get_sample_rate() / 16) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GB_audio_get_queue_length() / sizeof(*sample) > GB_audio_get_frequency() / 4) {
|
if (GB_audio_get_queue_length() / sizeof(*sample) > GB_audio_get_sample_rate() / 4) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -503,7 +503,7 @@ restart:
|
|||||||
GB_set_rgb_encode_callback(&gb, rgb_encode);
|
GB_set_rgb_encode_callback(&gb, rgb_encode);
|
||||||
GB_set_rumble_callback(&gb, rumble);
|
GB_set_rumble_callback(&gb, rumble);
|
||||||
GB_set_rumble_mode(&gb, configuration.rumble_mode);
|
GB_set_rumble_mode(&gb, configuration.rumble_mode);
|
||||||
GB_set_sample_rate(&gb, GB_audio_get_frequency());
|
GB_set_sample_rate(&gb, GB_audio_get_sample_rate());
|
||||||
GB_set_color_correction_mode(&gb, configuration.color_correction_mode);
|
GB_set_color_correction_mode(&gb, configuration.color_correction_mode);
|
||||||
GB_set_light_temperature(&gb, (configuration.color_temperature - 10.0) / 10.0);
|
GB_set_light_temperature(&gb, (configuration.color_temperature - 10.0) / 10.0);
|
||||||
GB_set_interference_volume(&gb, configuration.interference_volume / 100.0);
|
GB_set_interference_volume(&gb, configuration.interference_volume / 100.0);
|
||||||
@ -703,7 +703,7 @@ int main(int argc, char **argv)
|
|||||||
pixel_format = SDL_AllocFormat(SDL_PIXELFORMAT_ABGR8888);
|
pixel_format = SDL_AllocFormat(SDL_PIXELFORMAT_ABGR8888);
|
||||||
}
|
}
|
||||||
|
|
||||||
GB_audio_init();
|
GB_audio_init(GB_audio_default_sample_rate());
|
||||||
|
|
||||||
SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
|
SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
|
||||||
|
|
||||||
|
80
gtk3/check_menu_radio_group.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#include "check_menu_radio_group.h"
|
||||||
|
|
||||||
|
static void check_menu_item_group_handler(GtkCheckMenuItem *item, CheckMenuItemGroupHandlerData *data) {
|
||||||
|
bool cancel = false;
|
||||||
|
|
||||||
|
if (data->handler) {
|
||||||
|
cancel = data->handler(data->group->parent, GTK_WIDGET(item), (gpointer) data->arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
GValue value = G_VALUE_INIT;
|
||||||
|
g_value_init(&value, G_TYPE_BOOLEAN);
|
||||||
|
|
||||||
|
if (cancel) {
|
||||||
|
g_value_set_boolean(&value, false);
|
||||||
|
g_object_set_property(G_OBJECT(item), "active", &value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (unsigned i = 0; i < data->group->count; i++) {
|
||||||
|
GtkCheckMenuItem *cur = GTK_CHECK_MENU_ITEM(data->group->items[i]);
|
||||||
|
g_value_set_boolean(&value, cur == item);
|
||||||
|
g_object_set_property(G_OBJECT(cur), "active", &value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckMenuItemGroup *check_menu_item_group_new(GtkWidget *parent, char **names, char **args) {
|
||||||
|
unsigned name_count = 0;
|
||||||
|
|
||||||
|
if (names != NULL) {
|
||||||
|
for (char **ptr = names; *ptr != NULL; ptr++, name_count++);
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckMenuItemGroup *group = g_malloc0(sizeof(CheckMenuItemGroup));
|
||||||
|
group->parent = parent;
|
||||||
|
group->count = name_count;
|
||||||
|
group->items = g_malloc0(sizeof(GtkWidget*) * name_count);
|
||||||
|
group->handlers = g_malloc0(sizeof(CheckMenuItemGroupHandlerData*) * name_count);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < name_count; i++) {
|
||||||
|
group->items[i] = gtk_check_menu_item_new_with_label(names[i]);
|
||||||
|
|
||||||
|
group->handlers[i] = g_malloc0(sizeof(CheckMenuItemGroupHandlerData));
|
||||||
|
group->handlers[i]->group = group;
|
||||||
|
group->handlers[i]->arg = args[i];
|
||||||
|
g_signal_connect(group->items[i], "toggled", G_CALLBACK(check_menu_item_group_handler), group->handlers[i]);
|
||||||
|
|
||||||
|
gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(group->items[i]), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_menu_item_group_activate(CheckMenuItemGroup *group, char *arg) {
|
||||||
|
GValue value = G_VALUE_INIT;
|
||||||
|
g_value_init(&value, G_TYPE_BOOLEAN);
|
||||||
|
g_value_set_boolean(&value, false);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < group->count; i++) {
|
||||||
|
GtkCheckMenuItem *cur = GTK_CHECK_MENU_ITEM(group->items[i]);
|
||||||
|
|
||||||
|
if (g_strcmp0(arg, group->handlers[i]->arg) == 0) {
|
||||||
|
gtk_check_menu_item_set_active(cur, true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g_object_set_property(G_OBJECT(cur), "active", &value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_menu_item_group_connect_toggle_signal(CheckMenuItemGroup *group, bool (*handler)(GtkWidget *, GtkWidget *, gpointer)) {
|
||||||
|
for (unsigned i = 0; i < group->count; i++) {
|
||||||
|
group->handlers[i]->handler = handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_menu_item_group_insert_into_menu_shell(CheckMenuItemGroup *group, GtkMenuShell *menu_shell, gint position) {
|
||||||
|
for (unsigned i = 0; i < group->count; i++) {
|
||||||
|
gtk_menu_shell_insert(menu_shell, group->items[i], position + i);
|
||||||
|
}
|
||||||
|
}
|
25
gtk3/check_menu_radio_group.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef check_menu_radio_group_h
|
||||||
|
#define check_menu_radio_group_h
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
typedef struct CheckMenuItemGroupHandlerData {
|
||||||
|
struct CheckMenuItemGroup *group;
|
||||||
|
char *arg;
|
||||||
|
bool (*handler)(GtkWidget *, GtkWidget *, void *);
|
||||||
|
} CheckMenuItemGroupHandlerData;
|
||||||
|
|
||||||
|
typedef struct CheckMenuItemGroup {
|
||||||
|
GtkWidget *parent;
|
||||||
|
unsigned count;
|
||||||
|
GtkWidget **items;
|
||||||
|
CheckMenuItemGroupHandlerData **handlers;
|
||||||
|
} CheckMenuItemGroup;
|
||||||
|
|
||||||
|
CheckMenuItemGroup *check_menu_item_group_new(GtkWidget *parent, char **names, char **args);
|
||||||
|
void check_menu_item_group_activate(CheckMenuItemGroup *group, char *arg);
|
||||||
|
void check_menu_item_group_connect_toggle_signal(CheckMenuItemGroup *group, bool (*handler)(GtkWidget *, GtkWidget *, gpointer));
|
||||||
|
void check_menu_item_group_insert_into_menu_shell(CheckMenuItemGroup *group, GtkMenuShell *menu_shell, gint position);
|
||||||
|
|
||||||
|
#endif
|
543
gtk3/config.c
Normal file
@ -0,0 +1,543 @@
|
|||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#define get_object(id) gtk_builder_get_object(builder, id)
|
||||||
|
#define builder_get(type, id) type(get_object(id))
|
||||||
|
|
||||||
|
gchar* config_file_path;
|
||||||
|
GKeyFile *key_file;
|
||||||
|
|
||||||
|
static void print_config_error(GError *error) {
|
||||||
|
if (error == NULL) return;
|
||||||
|
|
||||||
|
if (!g_error_matches(error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND) && !g_error_matches(error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) {
|
||||||
|
g_warning("Config error: %s", error->message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _print_config(config_t *config, GLogLevelFlags log_level) {
|
||||||
|
#define EXPAND_GROUP(name, members) { \
|
||||||
|
g_log(G_LOG_DOMAIN, log_level, "[%s]", #name); \
|
||||||
|
struct config_ ## name ## _t *group = &config->name; \
|
||||||
|
members \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXPAND_GROUP_MEMBER(member, key_type, default_value) \
|
||||||
|
g_log(G_LOG_DOMAIN, log_level, "%s="FORMAT_FOR_KEY_TYPE(key_type)"", #member, group->member);
|
||||||
|
|
||||||
|
EXPAND_CONFIG
|
||||||
|
#undef EXPAND_GROUP
|
||||||
|
#undef EXPAND_GROUP_MEMBER
|
||||||
|
}
|
||||||
|
|
||||||
|
// Duplicates the input and converts the first character to uppercase
|
||||||
|
gchar* ascii_ucfirst(gchar *str) {
|
||||||
|
gchar *out = g_strdup(str);
|
||||||
|
out[0] = g_ascii_toupper(str[0]);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_config_from_key_file(config_t *config, GKeyFile *key_file) {
|
||||||
|
g_message("Loading config from key file");
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
#define EXPAND_GROUP(name_arg, members) { \
|
||||||
|
struct config_ ## name_arg ## _t *group = &config->name_arg; \
|
||||||
|
g_autofree gchar *group_name = ascii_ucfirst(#name_arg); \
|
||||||
|
members \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXPAND_GROUP_MEMBER(member, key_type, default_value) \
|
||||||
|
group->member = g_key_file_get_##key_type(key_file, group_name, #member, &error); \
|
||||||
|
if (error != NULL) { \
|
||||||
|
group->member = default_value; \
|
||||||
|
print_config_error(error); \
|
||||||
|
g_clear_error(&error); \
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPAND_CONFIG
|
||||||
|
|
||||||
|
if (config->emulation.rewind_duration > 600) {
|
||||||
|
g_warning("Setting Emulation.rewind_duration too high might affect performance.");
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef EXPAND_GROUP
|
||||||
|
#undef EXPAND_GROUP_MEMBER
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_config(config_t *config) {
|
||||||
|
_print_config(config, G_LOG_LEVEL_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void save_config_to_key_file(config_t *config, GKeyFile *key_file) {
|
||||||
|
g_message("Saving config to key file");
|
||||||
|
GError *error = NULL;
|
||||||
|
gchar *group_name;
|
||||||
|
|
||||||
|
#define EXPAND_GROUP(name_arg, members) { \
|
||||||
|
struct config_ ## name_arg ## _t *group = &config->name_arg; \
|
||||||
|
g_autofree gchar *group_name = ascii_ucfirst(#name_arg); \
|
||||||
|
members \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXPAND_GROUP_MEMBER_IF_0(member, key_type, default_value) \
|
||||||
|
g_key_file_set_##key_type(key_file, group_name, #member, group->member);
|
||||||
|
|
||||||
|
#define EXPAND_GROUP_MEMBER_IF_1(member, key_type, default_value) \
|
||||||
|
if (group->member != NULL) { \
|
||||||
|
g_key_file_set_##key_type(key_file, group_name, #member, group->member); \
|
||||||
|
} \
|
||||||
|
else if (g_key_file_has_key(key_file, group_name, #member, &error)) { \
|
||||||
|
if (error != NULL) { \
|
||||||
|
g_warning("%s", error->message); \
|
||||||
|
g_clear_error(&error); \
|
||||||
|
} \
|
||||||
|
g_key_file_remove_key(key_file, group_name, #member, &error); \
|
||||||
|
if (error != NULL) { \
|
||||||
|
g_warning("%s", error->message); \
|
||||||
|
g_clear_error(&error); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXPAND_GROUP_MEMBER_IF_EVAL(y, member, key_type, default_value) EXPAND_GROUP_MEMBER_IF_ ## y(member, key_type, default_value)
|
||||||
|
#define EXPAND_GROUP_MEMBER_IF(member, key_type, is_pointer, default_value) EXPAND_GROUP_MEMBER_IF_EVAL(is_pointer, member, key_type, default_value)
|
||||||
|
#define EXPAND_GROUP_MEMBER(member, key_type, default_value) EXPAND_GROUP_MEMBER_IF(member, key_type, GTYPE_IS_POINTER(key_type), default_value)
|
||||||
|
|
||||||
|
EXPAND_CONFIG
|
||||||
|
|
||||||
|
#undef EXPAND_GROUP
|
||||||
|
#undef EXPAND_GROUP_MEMBER
|
||||||
|
#undef EXPAND_GROUP_MEMBER_IF
|
||||||
|
#undef EXPAND_GROUP_MEMBER_IF_EVAL
|
||||||
|
#undef EXPAND_GROUP_MEMBER_IF_0
|
||||||
|
#undef EXPAND_GROUP_MEMBER_IF_1
|
||||||
|
|
||||||
|
// Save config to disk
|
||||||
|
if (!g_key_file_save_to_file(key_file, config_file_path, &error)) {
|
||||||
|
g_warning ("Failed to save %s: %s", config_file_path, error->message);
|
||||||
|
g_error_free(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_config(GApplication *app, gchar *path, GDateTime **modification_date) {
|
||||||
|
free_config();
|
||||||
|
key_file = g_key_file_new();
|
||||||
|
|
||||||
|
if (path != NULL) {
|
||||||
|
config_file_path = path;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
config_file_path = g_build_filename(g_get_user_config_dir(), CONFIG_FILE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
load_config(app, modification_date);
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_config(GApplication *app, GDateTime **modification_date) {
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_message("Trying to load config from %s", config_file_path);
|
||||||
|
|
||||||
|
g_autoptr(GFile) file = g_file_new_for_path(config_file_path);
|
||||||
|
g_autoptr(GFileInfo) file_info = g_file_query_info(file, "time::*", G_FILE_QUERY_INFO_NONE, NULL, NULL);
|
||||||
|
|
||||||
|
#if GLIB_CHECK_VERSION(2,62,0)
|
||||||
|
*modification_date = g_file_info_get_modification_date_time(file_info);
|
||||||
|
#else
|
||||||
|
GTimeVal tv;
|
||||||
|
g_file_info_get_modification_time(file_info, &tv);
|
||||||
|
*modification_date = g_date_time_new_from_timeval_utc(&tv);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!g_key_file_load_from_file(key_file, config_file_path, G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &error)) {
|
||||||
|
if (error->domain == G_FILE_ERROR) {
|
||||||
|
g_warning("Unable to load %s: %s", config_file_path, error->message);
|
||||||
|
}
|
||||||
|
else if (error->domain == G_KEY_FILE_ERROR) {
|
||||||
|
g_warning("Failed to parse %s: %s", config_file_path, error->message);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_error_free(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
load_config_from_key_file(&config, key_file);
|
||||||
|
_print_config(&config, G_LOG_LEVEL_DEBUG);
|
||||||
|
|
||||||
|
// Update GAction states
|
||||||
|
g_action_group_change_action_state(G_ACTION_GROUP(app), "toggle_mute", g_variant_new_boolean(config.audio.muted));
|
||||||
|
}
|
||||||
|
|
||||||
|
void save_config(GtkWindow *main_window, GDateTime *saved_modification_date) {
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_message("Trying to save config to %s", config_file_path);
|
||||||
|
|
||||||
|
g_autoptr(GFile) file = g_file_new_for_path(config_file_path);
|
||||||
|
g_autoptr(GFileInfo) file_info = g_file_query_info(file, "time::*", G_FILE_QUERY_INFO_NONE, NULL, NULL);
|
||||||
|
|
||||||
|
#if GLIB_CHECK_VERSION(2,62,0)
|
||||||
|
GDateTime *modification_date = g_file_info_get_modification_date_time(file_info);
|
||||||
|
#else
|
||||||
|
GTimeVal tv;
|
||||||
|
g_file_info_get_modification_time(file_info, &tv);
|
||||||
|
GDateTime *modification_date = g_date_time_new_from_timeval_utc(&tv);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!g_date_time_equal(saved_modification_date, modification_date)) {
|
||||||
|
GtkMessageDialog *dialog = GTK_MESSAGE_DIALOG(gtk_message_dialog_new(
|
||||||
|
main_window,
|
||||||
|
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
GTK_MESSAGE_QUESTION,
|
||||||
|
GTK_BUTTONS_YES_NO,
|
||||||
|
"It looks like the configuration has changed on disk. Overwrite?"
|
||||||
|
));
|
||||||
|
|
||||||
|
gtk_window_set_title(GTK_WINDOW(dialog), "SameBoy");
|
||||||
|
|
||||||
|
gint result = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||||
|
|
||||||
|
switch (result) {
|
||||||
|
case GTK_RESPONSE_YES:
|
||||||
|
save_config_to_key_file(&config, key_file);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Action has been canceled
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
save_config_to_key_file(&config, key_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_config(void) {
|
||||||
|
if (key_file != NULL) {
|
||||||
|
g_key_file_free(key_file);
|
||||||
|
key_file = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_boot_rom_selector(GtkBuilder *builder) {
|
||||||
|
GtkComboBoxText *combo_box = builder_get(GTK_COMBO_BOX_TEXT, "boot_rom_selector");
|
||||||
|
gtk_combo_box_text_remove_all(combo_box);
|
||||||
|
gtk_combo_box_text_append(combo_box, "auto", "Use Built-in Boot ROMs");
|
||||||
|
if (config.emulation.boot_rom_path != NULL && !g_str_equal(config.emulation.boot_rom_path, "auto") && !g_str_equal(config.emulation.boot_rom_path, "other")) {
|
||||||
|
gtk_combo_box_text_append(combo_box, config.emulation.boot_rom_path, config.emulation.boot_rom_path);
|
||||||
|
gtk_combo_box_set_active_id(GTK_COMBO_BOX(combo_box), config.emulation.boot_rom_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gtk_combo_box_set_active_id(GTK_COMBO_BOX(combo_box), "auto");
|
||||||
|
}
|
||||||
|
gtk_combo_box_text_append_text(combo_box, "<separator>");
|
||||||
|
gtk_combo_box_text_append(combo_box, "other", "Other");
|
||||||
|
}
|
||||||
|
|
||||||
|
GB_color_correction_mode_t config_get_color_correction_mode(void) {
|
||||||
|
if (config.video.color_correction_id == NULL) goto default_value;
|
||||||
|
|
||||||
|
if (g_strcmp0(config.video.color_correction_id, "disabled") == 0) {
|
||||||
|
return GB_COLOR_CORRECTION_DISABLED;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.video.color_correction_id, "correct_color_curves") == 0) {
|
||||||
|
return GB_COLOR_CORRECTION_CORRECT_CURVES;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.video.color_correction_id, "emulate_hardware") == 0) {
|
||||||
|
return GB_COLOR_CORRECTION_EMULATE_HARDWARE;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.video.color_correction_id, "preserve_brightness") == 0) {
|
||||||
|
return GB_COLOR_CORRECTION_PRESERVE_BRIGHTNESS;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.video.color_correction_id, "reduce_contrast") == 0) {
|
||||||
|
return GB_COLOR_CORRECTION_REDUCE_CONTRAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should not happen
|
||||||
|
g_warning("Unknown color correction mode: %s\nFalling back to “Emulate Hardware”", config.video.color_correction_id);
|
||||||
|
default_value: return GB_COLOR_CORRECTION_EMULATE_HARDWARE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void config_set_color_correction_mode(GB_color_correction_mode_t mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case GB_COLOR_CORRECTION_DISABLED:
|
||||||
|
config.video.color_correction_id = "disabled";
|
||||||
|
break;
|
||||||
|
case GB_COLOR_CORRECTION_CORRECT_CURVES:
|
||||||
|
config.video.color_correction_id = "correct_color_curves";
|
||||||
|
break;
|
||||||
|
case GB_COLOR_CORRECTION_EMULATE_HARDWARE:
|
||||||
|
config.video.color_correction_id = "emulate_hardware";
|
||||||
|
break;
|
||||||
|
case GB_COLOR_CORRECTION_PRESERVE_BRIGHTNESS:
|
||||||
|
config.video.color_correction_id = "preserve_brightness";
|
||||||
|
break;
|
||||||
|
case GB_COLOR_CORRECTION_REDUCE_CONTRAST:
|
||||||
|
config.video.color_correction_id = "reduce_contrast";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GB_frame_blending_mode_t config_get_frame_blending_mode(void) {
|
||||||
|
if (config.video.frame_blending_mode == NULL) goto default_value;
|
||||||
|
|
||||||
|
if (g_strcmp0(config.video.frame_blending_mode, "disabled") == 0) {
|
||||||
|
return GB_FRAME_BLENDING_MODE_DISABLED;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.video.frame_blending_mode, "simple") == 0) {
|
||||||
|
return GB_FRAME_BLENDING_MODE_SIMPLE;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.video.frame_blending_mode, "accurate") == 0) {
|
||||||
|
return GB_FRAME_BLENDING_MODE_ACCURATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should not happen
|
||||||
|
g_warning("Unknown frame blending mode: %s\nFalling back to “Disabled”", config.video.frame_blending_mode);
|
||||||
|
default_value: return GB_FRAME_BLENDING_MODE_DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void config_set_frame_blending_mode(GB_frame_blending_mode_t mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case GB_FRAME_BLENDING_MODE_DISABLED:
|
||||||
|
config.video.frame_blending_mode = "disabled";
|
||||||
|
break;
|
||||||
|
case GB_FRAME_BLENDING_MODE_SIMPLE:
|
||||||
|
config.video.frame_blending_mode = "simple";
|
||||||
|
break;
|
||||||
|
case GB_FRAME_BLENDING_MODE_ACCURATE:
|
||||||
|
case GB_FRAME_BLENDING_MODE_ACCURATE_ODD:
|
||||||
|
config.video.frame_blending_mode = "accurate";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GB_border_mode_t config_get_display_border_mode(void) {
|
||||||
|
if (config.video.display_border_mode == NULL) goto default_value;
|
||||||
|
|
||||||
|
if (g_strcmp0(config.video.display_border_mode, "never") == 0) {
|
||||||
|
return GB_BORDER_NEVER;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.video.display_border_mode, "sgb_only") == 0) {
|
||||||
|
return GB_BORDER_SGB;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.video.display_border_mode, "always") == 0) {
|
||||||
|
return GB_BORDER_ALWAYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should not happen
|
||||||
|
g_warning("Unknown SGB border mode: %s\nFalling back to “Never”", config.video.display_border_mode);
|
||||||
|
default_value: return GB_BORDER_NEVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void config_set_display_border_mode(GB_border_mode_t mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case GB_BORDER_NEVER:
|
||||||
|
config.video.display_border_mode = "never";
|
||||||
|
break;
|
||||||
|
case GB_BORDER_SGB:
|
||||||
|
config.video.display_border_mode = "sgb_only";
|
||||||
|
break;
|
||||||
|
case GB_BORDER_ALWAYS:
|
||||||
|
config.video.display_border_mode = "always";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const GB_palette_t* config_get_monochrome_palette(void) {
|
||||||
|
if (config.video.monochrome_palette_id == NULL) goto default_value;
|
||||||
|
|
||||||
|
if (g_strcmp0(config.video.monochrome_palette_id, "greyscale") == 0) {
|
||||||
|
return &GB_PALETTE_GREY;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.video.monochrome_palette_id, "lime") == 0) {
|
||||||
|
return &GB_PALETTE_DMG;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.video.monochrome_palette_id, "olive") == 0) {
|
||||||
|
return &GB_PALETTE_MGB;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.video.monochrome_palette_id, "teal") == 0) {
|
||||||
|
return &GB_PALETTE_GBL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should not happen
|
||||||
|
g_warning("Unknown monochrome palette: %s\nFalling back to “Greyscale”", config.video.monochrome_palette_id);
|
||||||
|
default_value: return &GB_PALETTE_GREY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void config_set_monochrome_palette(const GB_palette_t *mode) {
|
||||||
|
g_message("%p | %p | %p | %p | %p", mode, &GB_PALETTE_GREY, &GB_PALETTE_DMG, &GB_PALETTE_MGB, &GB_PALETTE_GBL);
|
||||||
|
|
||||||
|
if (mode == &GB_PALETTE_GREY) {
|
||||||
|
config.video.monochrome_palette_id = "greyscale";
|
||||||
|
}
|
||||||
|
else if (mode == &GB_PALETTE_DMG) {
|
||||||
|
config.video.monochrome_palette_id = "lime";
|
||||||
|
}
|
||||||
|
else if (mode == &GB_PALETTE_MGB) {
|
||||||
|
config.video.monochrome_palette_id = "olive";
|
||||||
|
}
|
||||||
|
else if (mode == &GB_PALETTE_GBL) {
|
||||||
|
config.video.monochrome_palette_id = "teal";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GB_highpass_mode_t config_get_highpass_mode(void) {
|
||||||
|
if (config.audio.high_pass_filter_id == NULL) goto default_value;
|
||||||
|
|
||||||
|
if (g_strcmp0(config.audio.high_pass_filter_id, "disabled") == 0) {
|
||||||
|
return GB_HIGHPASS_OFF;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.audio.high_pass_filter_id, "emulate_hardware") == 0) {
|
||||||
|
return GB_HIGHPASS_ACCURATE;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.audio.high_pass_filter_id, "preserve_waveform") == 0) {
|
||||||
|
return GB_HIGHPASS_REMOVE_DC_OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should not happen
|
||||||
|
g_warning("Unknown highpass mode: %s\nFalling back to “Accurate”", config.audio.high_pass_filter_id);
|
||||||
|
default_value: return GB_HIGHPASS_ACCURATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void config_set_highpass_mode(GB_highpass_mode_t mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case GB_HIGHPASS_OFF:
|
||||||
|
config.audio.high_pass_filter_id = "disabled";
|
||||||
|
break;
|
||||||
|
case GB_HIGHPASS_MAX:
|
||||||
|
g_warning("GB_HIGHPASS_MAX is not a valid highpass mode, falling back to “Accurate”.");
|
||||||
|
case GB_HIGHPASS_ACCURATE:
|
||||||
|
config.audio.high_pass_filter_id = "emulate_hardware";
|
||||||
|
break;
|
||||||
|
case GB_HIGHPASS_REMOVE_DC_OFFSET:
|
||||||
|
config.audio.high_pass_filter_id = "preserve_waveform";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const GB_rumble_mode_t config_get_rumble_mode(void) {
|
||||||
|
if (config.controls.rumble_mode == NULL) goto default_value;
|
||||||
|
|
||||||
|
if (g_strcmp0(config.controls.rumble_mode, "never") == 0) {
|
||||||
|
return GB_RUMBLE_DISABLED;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.controls.rumble_mode, "rumble_cartridges") == 0) {
|
||||||
|
return GB_RUMBLE_CARTRIDGE_ONLY;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.controls.rumble_mode, "always") == 0) {
|
||||||
|
return GB_RUMBLE_ALL_GAMES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should not happen
|
||||||
|
g_warning("Unknown rumble mode: %s\nFalling back to “Never”", config.controls.rumble_mode);
|
||||||
|
default_value: return GB_RUMBLE_DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void config_set_rumble_mode(GB_rumble_mode_t mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case GB_RUMBLE_DISABLED:
|
||||||
|
config.controls.rumble_mode = "never";
|
||||||
|
break;
|
||||||
|
case GB_RUMBLE_CARTRIDGE_ONLY:
|
||||||
|
config.controls.rumble_mode = "rumble_cartridges";
|
||||||
|
break;
|
||||||
|
case GB_RUMBLE_ALL_GAMES:
|
||||||
|
config.controls.rumble_mode = "always";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GB_model_t config_get_model(void) {
|
||||||
|
if (g_strcmp0(config.emulation.model, "DMG") == 0) {
|
||||||
|
return config_get_dmg_model();
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.emulation.model, "MGB") == 0) {
|
||||||
|
g_warning("Emulation of MGBs is unsupported, falling back to DMG.");
|
||||||
|
|
||||||
|
return config_get_dmg_model();
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.emulation.model, "AGB") == 0) {
|
||||||
|
return GB_MODEL_AGB;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.emulation.model, "SGB") == 0) {
|
||||||
|
return config_get_sgb_model();
|
||||||
|
}
|
||||||
|
|
||||||
|
return config_get_cgb_model();
|
||||||
|
}
|
||||||
|
|
||||||
|
GB_model_t config_get_model_type(struct CliOptionData *cli_options) {
|
||||||
|
if (cli_options->model != -1) {
|
||||||
|
return cli_options->model;
|
||||||
|
}
|
||||||
|
|
||||||
|
return config_get_model();
|
||||||
|
}
|
||||||
|
|
||||||
|
void config_set_model(GB_model_t model) {
|
||||||
|
switch (model & GB_MODEL_FAMILY_MASK) {
|
||||||
|
case GB_MODEL_DMG_FAMILY:
|
||||||
|
if (model & GB_MODEL_SGB) {
|
||||||
|
config.emulation.model = "SGB";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
config.emulation.model = "DMG";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GB_MODEL_MGB_FAMILY:
|
||||||
|
config.emulation.model = "MGB";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GB_MODEL_CGB_FAMILY:
|
||||||
|
if (model & GB_MODEL_AGB) {
|
||||||
|
config.emulation.model = "AGB";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
config.emulation.model = "CGB";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GB_model_t config_get_dmg_model(void) {
|
||||||
|
if (config.emulation.dmg_revision_name == NULL) goto default_value;
|
||||||
|
|
||||||
|
// TODO: Synchronize with GB_model_t (Core/gb.h)
|
||||||
|
if (g_strcmp0(config.emulation.dmg_revision_name, "DMG_CPU_B") == 0) {
|
||||||
|
return GB_MODEL_DMG_B;
|
||||||
|
}
|
||||||
|
|
||||||
|
default_value: return GB_MODEL_DMG_B;
|
||||||
|
}
|
||||||
|
|
||||||
|
GB_model_t config_get_sgb_model(void) {
|
||||||
|
if (config.emulation.sgb_revision_name == NULL) goto default_value;
|
||||||
|
|
||||||
|
// TODO: Synchronize with GB_model_t (Core/gb.h)
|
||||||
|
if (g_strcmp0(config.emulation.sgb_revision_name, "SGB1_NTSC") == 0) {
|
||||||
|
return GB_MODEL_SGB_NTSC;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.emulation.sgb_revision_name, "SGB1_PAL") == 0) {
|
||||||
|
return GB_MODEL_SGB_PAL;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.emulation.sgb_revision_name, "SGB2") == 0) {
|
||||||
|
return GB_MODEL_SGB2;
|
||||||
|
}
|
||||||
|
|
||||||
|
default_value: return GB_MODEL_SGB2;
|
||||||
|
}
|
||||||
|
|
||||||
|
GB_model_t config_get_cgb_model(void) {
|
||||||
|
if (config.emulation.cgb_revision_name == NULL) goto default_value;
|
||||||
|
|
||||||
|
// TODO: Synchronize with GB_model_t (Core/gb.h)
|
||||||
|
if (g_strcmp0(config.emulation.cgb_revision_name, "CPU_CGB_C") == 0) {
|
||||||
|
return GB_MODEL_CGB_C;
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(config.emulation.cgb_revision_name, "CPU_CGB_E") == 0) {
|
||||||
|
return GB_MODEL_CGB_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
default_value: return GB_MODEL_CGB_E;
|
||||||
|
}
|
113
gtk3/config.h
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
#ifndef config_h
|
||||||
|
#define config_h
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <Core/gb.h>
|
||||||
|
#include "shader.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#define CONFIG_FILE "sameboy-gtk3.ini"
|
||||||
|
|
||||||
|
#define FORMAT_FOR_KEY_TYPE(type) FORMAT_FOR_##type
|
||||||
|
#define FORMAT_FOR_string "%s"
|
||||||
|
#define FORMAT_FOR_integer "%d"
|
||||||
|
#define FORMAT_FOR_boolean "%d"
|
||||||
|
|
||||||
|
#define GTYPE_OF_KEY_TYPE(type) GTYPE_OF_##type
|
||||||
|
#define GTYPE_OF_string gchar *
|
||||||
|
#define GTYPE_OF_integer gint
|
||||||
|
#define GTYPE_OF_boolean gboolean
|
||||||
|
|
||||||
|
#define GTYPE_IS_POINTER(type) GTYPE_IS_POINTER_##type
|
||||||
|
#define GTYPE_IS_POINTER_string 1
|
||||||
|
#define GTYPE_IS_POINTER_integer 0
|
||||||
|
#define GTYPE_IS_POINTER_boolean 0
|
||||||
|
|
||||||
|
// Macro usage:
|
||||||
|
// EXPAND_CONFIG(EXPAND_GROUP(…) EXPAND_GROUP(…) …)
|
||||||
|
// EXPAND_GROUP(group_name, group_members)
|
||||||
|
// EXPAND_GROUP_MEMBER(member_name, key_type, default_value)
|
||||||
|
#define EXPAND_CONFIG \
|
||||||
|
EXPAND_GROUP(emulation, \
|
||||||
|
EXPAND_GROUP_MEMBER(boot_rom_path, string, "auto") /* overrides search location for boot ROMs by name */ \
|
||||||
|
EXPAND_GROUP_MEMBER(rewind_duration, integer, 10) \
|
||||||
|
EXPAND_GROUP_MEMBER(dmg_revision_name, string, "DMG_CPU_B") \
|
||||||
|
EXPAND_GROUP_MEMBER(sgb_revision_name, string, "SGB2") \
|
||||||
|
EXPAND_GROUP_MEMBER(cgb_revision_name, string, "CPU_CGB_E") \
|
||||||
|
EXPAND_GROUP_MEMBER(model, string, "cgb") \
|
||||||
|
) \
|
||||||
|
EXPAND_GROUP(video, \
|
||||||
|
EXPAND_GROUP_MEMBER(shader, string, "NearestNeighbor") \
|
||||||
|
EXPAND_GROUP_MEMBER(color_correction_id, string, "emulate_hardware") \
|
||||||
|
EXPAND_GROUP_MEMBER(light_temperature, integer, 0) \
|
||||||
|
EXPAND_GROUP_MEMBER(frame_blending_mode, string, "disabled") \
|
||||||
|
EXPAND_GROUP_MEMBER(display_border_mode, string, "never") \
|
||||||
|
EXPAND_GROUP_MEMBER(monochrome_palette_id, string, "greyscale") \
|
||||||
|
EXPAND_GROUP_MEMBER(keep_aspect_ratio, boolean, true) \
|
||||||
|
EXPAND_GROUP_MEMBER(use_integer_scaling, boolean, true) \
|
||||||
|
) \
|
||||||
|
EXPAND_GROUP(audio, \
|
||||||
|
EXPAND_GROUP_MEMBER(high_pass_filter_id, string, "emulate_hardware") \
|
||||||
|
EXPAND_GROUP_MEMBER(sample_rate, integer, -1) \
|
||||||
|
EXPAND_GROUP_MEMBER(interference_volume, integer, 0) \
|
||||||
|
EXPAND_GROUP_MEMBER(muted, boolean, false) \
|
||||||
|
) \
|
||||||
|
EXPAND_GROUP(controls, \
|
||||||
|
EXPAND_GROUP_MEMBER(analog_speed_controls, boolean, false) \
|
||||||
|
EXPAND_GROUP_MEMBER(rumble_mode, string, "never") \
|
||||||
|
) \
|
||||||
|
EXPAND_GROUP(window, \
|
||||||
|
\
|
||||||
|
)
|
||||||
|
|
||||||
|
typedef struct config_t {
|
||||||
|
#define EXPAND_GROUP(group_name, members) struct config_ ## group_name ## _t { \
|
||||||
|
members \
|
||||||
|
} group_name;
|
||||||
|
#define EXPAND_GROUP_MEMBER(member, key_type, default_value) GTYPE_OF_KEY_TYPE(key_type) member;
|
||||||
|
|
||||||
|
EXPAND_CONFIG
|
||||||
|
|
||||||
|
#undef EXPAND_GROUP
|
||||||
|
#undef EXPAND_GROUP_MEMBER
|
||||||
|
} config_t;
|
||||||
|
|
||||||
|
config_t config;
|
||||||
|
|
||||||
|
void print_config(config_t *config);
|
||||||
|
void load_config_from_key_file(config_t *config, GKeyFile *key_file);
|
||||||
|
|
||||||
|
void init_config(GApplication *app, gchar *path, GDateTime **modification_date);
|
||||||
|
void load_config(GApplication *app, GDateTime **modification_date);
|
||||||
|
void save_config(GtkWindow *main_window, GDateTime *saved_modification_date);
|
||||||
|
void free_config(void);
|
||||||
|
|
||||||
|
void update_boot_rom_selector(GtkBuilder *builder);
|
||||||
|
|
||||||
|
GB_color_correction_mode_t config_get_color_correction_mode(void);
|
||||||
|
void config_set_color_correction_mode(GB_color_correction_mode_t);
|
||||||
|
|
||||||
|
GB_frame_blending_mode_t config_get_frame_blending_mode(void);
|
||||||
|
void config_set_frame_blending_mode(GB_frame_blending_mode_t);
|
||||||
|
|
||||||
|
GB_border_mode_t config_get_display_border_mode(void);
|
||||||
|
void config_set_display_border_mode(GB_border_mode_t);
|
||||||
|
|
||||||
|
GB_highpass_mode_t config_get_highpass_mode(void);
|
||||||
|
void config_set_highpass_mode(GB_highpass_mode_t);
|
||||||
|
|
||||||
|
const GB_palette_t* config_get_monochrome_palette(void);
|
||||||
|
void config_set_monochrome_palette(const GB_palette_t*);
|
||||||
|
|
||||||
|
const GB_rumble_mode_t config_get_rumble_mode(void);
|
||||||
|
void config_set_rumble_mode(const GB_rumble_mode_t);
|
||||||
|
|
||||||
|
void config_set_model(GB_model_t model);
|
||||||
|
GB_model_t config_get_model(void);
|
||||||
|
GB_model_t config_get_model_type(struct CliOptionData *cli_options);
|
||||||
|
|
||||||
|
GB_model_t config_get_dmg_model(void);
|
||||||
|
GB_model_t config_get_sgb_model(void);
|
||||||
|
GB_model_t config_get_cgb_model(void);
|
||||||
|
|
||||||
|
#endif /* config_h */
|
6
gtk3/main.c
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#define G_LOG_USE_STRUCTURED
|
||||||
|
#include "sameboy_application.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
return g_application_run(G_APPLICATION(sameboy_application_new()), argc, argv);
|
||||||
|
}
|
48
gtk3/resources/css/main.css
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
.vram-viewer-button-bar {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vram-viewer-button-bar button {
|
||||||
|
padding: 2px 4px;
|
||||||
|
min-height: 11px;
|
||||||
|
min-width: 12px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dark theme for the console, based on GNOME Terminal colors */
|
||||||
|
.debug-console,
|
||||||
|
.debug-console entry,
|
||||||
|
.debug-console scrolledwindow,
|
||||||
|
.debug-console textview,
|
||||||
|
.debug-console textview text {
|
||||||
|
background: #2E3436;
|
||||||
|
color: #D3D7CF;
|
||||||
|
font-size: 12px;
|
||||||
|
border-color: #3d4548;
|
||||||
|
}
|
||||||
|
|
||||||
|
.debug-console entry {
|
||||||
|
background: #252a2c;
|
||||||
|
border: none; /* 1px solid #1d2022 */
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.debug-console .border-none {
|
||||||
|
border-top: none;
|
||||||
|
border-left: none;
|
||||||
|
border-bottom: none;
|
||||||
|
border-right: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.debug-console .border-right {
|
||||||
|
border-right: 1px solid #3d4548;
|
||||||
|
}
|
||||||
|
|
||||||
|
.debug-console .border-bottom {
|
||||||
|
border-bottom: 1px solid #3d4548;
|
||||||
|
}
|
||||||
|
|
||||||
|
.monospace {
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
939
gtk3/resources/gamecontrollerdb_d3f1cea1.txt
Normal file
@ -0,0 +1,939 @@
|
|||||||
|
# Game Controller DB for SDL in 2.0.9 format
|
||||||
|
# Source: https://github.com/gabomdq/SDL_GameControllerDB
|
||||||
|
|
||||||
|
# Windows
|
||||||
|
03000000fa2d00000100000000000000,3DRUDDER,leftx:a0,lefty:a1,rightx:a5,righty:a2,platform:Windows,
|
||||||
|
03000000c82d00002038000000000000,8bitdo,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d000011ab000000000000,8BitDo F30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00001038000000000000,8BitDo F30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00000090000000000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00000650000000000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:a4,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000c82d00005106000000000000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00000310000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000c82d00002028000000000000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00008010000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000c82d00000190000000000000,8BitDo N30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00001590000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00006528000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00015900000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00065280000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000022000000090000000000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000203800000900000000000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00000130000000000000,8BitDo SF30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00000060000000000000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00000061000000000000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d000021ab000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000102800000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00003028000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00000030000000000000,8BitDo SN30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00000351000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00001290000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d000020ab000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00004028000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00006228000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00000260000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00000261000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00000031000000000000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000c82d00003032000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows,
|
||||||
|
03000000a00500003232000000000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
030000008f0e00001200000000000000,Acme GA-02,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000fa190000f0ff000000000000,Acteck AGJ-3200,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
030000006f0e00001413000000000000,Afterglow,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000341a00003608000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006f0e00000263000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006f0e00001101000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006f0e00001401000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006f0e00001402000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006f0e00001901000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006f0e00001a01000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000d62000001d57000000000000,Airflo PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000869800002400000000007801,Astro C40 TR,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000d6200000e557000000000000,Batarang,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000c01100001352000000000000,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows,
|
||||||
|
030000006f0e00003201000000000000,Battlefield 4 PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000d62000002a79000000000000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000bc2000006012000000000000,Betop 2126F,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000bc2000000055000000000000,Betop BFM Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000bc2000006312000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000bc2000006321000000000000,BETOP CONTROLLER,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000bc2000006412000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000c01100000555000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000c01100000655000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000790000000700000000000000,Betop Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000808300000300000000000000,Betop Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
030000006b1400000055000000000000,Bigben PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
030000006b1400000103000000000000,Bigben PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
|
||||||
|
0300000066f700000500000000000000,BrutalLegendTest,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000d81d00000b00000000000000,BUFFALO BSGP1601 Series ,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows,
|
||||||
|
03000000e82000006058000000000000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000457500000401000000000000,Cobra,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000005e0400008e02000000000000,Controller (XBOX 360 For Windows),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
030000005e040000a102000000000000,Controller (Xbox 360 Wireless Receiver for Windows),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
030000005e040000ff02000000000000,Controller (Xbox One For Windows) - Wired,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
030000005e040000ea02000000000000,Controller (Xbox One For Windows) - Wireless,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000260900008888000000000000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a4,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000a306000022f6000000000000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000451300000830000000000000,Defender Game Racer X7,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
030000007d0400000840000000000000,Destroyer Tiltpad,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000791d00000103000000000000,Dual Box WII,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000bd12000002e0000000000000,Dual USB Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,
|
||||||
|
030000008f0e00000910000000000000,DualShock 2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows,
|
||||||
|
030000006f0e00003001000000000000,EA SPORTS PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000b80500000410000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,
|
||||||
|
03000000b80500000610000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,
|
||||||
|
03000000120c0000f61c000000000000,Elite,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000008f0e00000f31000000000000,EXEQ,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
|
||||||
|
03000000341a00000108000000000000,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
030000006f0e00008401000000000000,Faceoff Deluxe+ Audio Wired Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006f0e00008001000000000000,Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000852100000201000000000000,FF-GP1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00008500000000000000,Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00008400000000000000,Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00008700000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00008800000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00002700000000000000,FIGHTING STICK V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
78696e70757403000000000000000000,Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000790000002201000000000000,Game Controller for PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
0300000066f700000100000000000000,Game VIB Joystick,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows,
|
||||||
|
03000000260900002625000000000000,Gamecube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000790000004618000000000000,GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000280400000140000000000000,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000ac0500003d03000000000000,GameSir,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000ac0500004d04000000000000,GameSir,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000ffff00000000000000000000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000c01100000140000000000000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006f0e00000102000000007801,GameStop Xbox 360 Wired Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
030000009b2800003200000000000000,GC/N64 to USB v3.4,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,
|
||||||
|
030000009b2800006000000000000000,GC/N64 to USB v3.6,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows,
|
||||||
|
030000008305000009a0000000000000,Genius,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
030000008305000031b0000000000000,Genius Maxfire Blaze 3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000451300000010000000000000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
030000005c1a00003330000000000000,Genius MaxFire Grandias 12V,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000300f00000b01000000000000,GGE909 Recoil Pad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000f0250000c283000000000000,Gioteck,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000f025000021c1000000000000,Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000f0250000c383000000000000,Gioteck VX2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000f0250000c483000000000000,Gioteck VX2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
030000007d0400000540000000000000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000341a00000302000000000000,Hama Scorpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00004900000000000000,Hatsune Miku Sho Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000001008000001e1000000000000,Havit HV-G60,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000d81400000862000000000000,HitBox Edition Cthulhu+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000632500002605000000000000,HJD-X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
030000000d0f00002d00000000000000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00005f00000000000000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00005e00000000000000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00004000000000000000,Hori Fighting Stick Mini 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00005400000000000000,Hori Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00000900000000000000,Hori Pad 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00004d00000000000000,Hori Pad A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00009200000000000000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00001600000000007803,HORI Real Arcade Pro EX-SE (Xbox 360),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
030000000d0f00009c00000000000000,Hori TAC Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f0000c100000000000000,Horipad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00006e00000000000000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00006600000000000000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00005500000000000000,Horipad 4 FPS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f0000ee00000000000000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000250900000017000000000000,HRAP2 on PS/SS/N64 Joypad to USB BOX,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
|
030000008f0e00001330000000000000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000d81d00000f00000000000000,iBUFFALO BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000d81d00001000000000000000,iBUFFALO BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000830500006020000000000000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Windows,
|
||||||
|
03000000b50700001403000000000000,Impact Black,a:b2,b:b3,back:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
|
||||||
|
030000006f0e00002401000000000000,INJUSTICE FightStick PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000ac0500002c02000000000000,IPEGA,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000491900000204000000000000,Ipega PG-9023,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000491900000304000000000000,Ipega PG-9087 - Bluetooth Gamepad,+righty:+a5,-righty:-a4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
030000006e0500000a20000000000000,JC-DUX60 ELECOM MMO Gamepad,a:b2,b:b3,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b14,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b15,righttrigger:b13,rightx:a3,righty:a4,start:b20,x:b0,y:b1,platform:Windows,
|
||||||
|
030000006e0500000520000000000000,JC-P301U,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
|
||||||
|
030000006e0500000320000000000000,JC-U3613M (DInput),a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows,
|
||||||
|
030000006e0500000720000000000000,JC-W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows,
|
||||||
|
030000007e0500000620000000000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Windows,
|
||||||
|
030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Windows,
|
||||||
|
030000007e0500000720000000000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000bd12000003c0000000000000,JY-P70UR,a:b1,b:b0,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b11,righttrigger:b9,rightx:a3,righty:a2,start:b4,x:b3,y:b2,platform:Windows,
|
||||||
|
03000000242f00002d00000000000000,JYS Wireless Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000242f00008a00000000000000,JYS Wireless Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000790000000200000000000000,King PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
030000006d040000d1ca000000000000,Logitech ChillStream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006d040000d2ca000000000000,Logitech Cordless Precision,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006d04000011c2000000000000,Logitech Cordless Wingman,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b2,righttrigger:b7,rightx:a3,righty:a4,x:b4,platform:Windows,
|
||||||
|
030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006d04000018c2000000000000,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006d04000019c2000000000000,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006d0400001ac2000000000000,Logitech Precision Gamepad,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006d0400000ac2000000000000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000380700006652000000000000,Mad Catz C.T.R.L.R,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000380700005032000000000000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000380700005082000000000000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000380700008433000000000000,Mad Catz FightStick TE S+ (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000380700008483000000000000,Mad Catz FightStick TE S+ (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000380700008134000000000000,Mad Catz FightStick TE2+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000380700008184000000000000,Mad Catz FightStick TE2+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000380700006252000000000000,Mad Catz Micro C.T.R.L.R,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000380700008034000000000000,Mad Catz TE2 PS3 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000380700008084000000000000,Mad Catz TE2 PS4 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000380700008532000000000000,Madcatz Arcade Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000380700003888000000000000,Madcatz Arcade Fightstick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000380700001888000000000000,MadCatz SFIV FightStick PS3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000002a0600001024000000000000,Matricom,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows,
|
||||||
|
03000000790000004418000000000000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,back:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b0,leftshoulder:b4,leftstick:b0,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000242f00007300000000000000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,
|
||||||
|
0300000079000000d218000000000000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000d620000010a7000000000000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000008f0e00001030000000000000,Mayflash USB Adapter for original Sega Saturn controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,platform:Windows,
|
||||||
|
0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
|
||||||
|
03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000790000002418000000000000,Mega Drive,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b2,start:b9,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000380700006382000000000000,MLG GamePad PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000c62400002a89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000c62400002b89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000c62400001a89000000000000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000c62400001b89000000000000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000efbe0000edfe000000000000,Monect Virtual Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
|
030000006b140000010c000000000000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000152000000182000000000000,NGDS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000bd12000015d0000000000000,Nintendo Retrolink USB Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
030000000d0500000308000000000000,Nostromo N45,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000550900001472000000000000,NVIDIA Controller v01.04,a:b11,b:b10,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b5,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b4,righttrigger:a5,rightx:a3,righty:a6,start:b3,x:b9,y:b8,platform:Windows,
|
||||||
|
030000004b120000014d000000000000,NYKO AIRFLO,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,rightshoulder:b5,rightstick:a2,righttrigger:b7,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000782300000a10000000000000,Onlive Wireless Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,platform:Windows,
|
||||||
|
03000000d62000006d57000000000000,OPP PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006b14000001a1000000000000,Orange Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000362800000100000000000000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows,
|
||||||
|
03000000120c0000f60e000000000000,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006f0e00000901000000000000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
030000004c050000da0c000000000000,PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000d62000009557000000000000,Pro Elite PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000d62000009f31000000000000,Pro Ex mini PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000d6200000c757000000000000,Pro Ex mini PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000632500002306000000000000,PS Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000e30500009605000000000000,PS to USB convert cable,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000100800000100000000000000,PS1 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
030000008f0e00007530000000000000,PS1 Controller,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b1,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000100800000300000000000000,PS2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000250900008888000000000000,PS2 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000666600006706000000000000,PS2 Controller,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Windows,
|
||||||
|
030000006b1400000303000000000000,PS2 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
030000009d0d00001330000000000000,PS2 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000250900000500000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows,
|
||||||
|
030000004c0500006802000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b10,lefttrigger:a3~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:a4~,rightx:a2,righty:a5,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000632500007505000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000888800000803000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,
|
||||||
|
030000008f0e00001431000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000003807000056a8000000000000,PS3 RF pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000100000008200000000000000,PS360+ v1.66,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:h0.4,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000004c050000a00b000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000004c050000cc09000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000004c050000e60c000000000000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000300f00000011000000000000,QanBa Arcade JoyStick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000300f00001611000000000000,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000222c00000020000000000000,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000300f00001210000000000000,QanBa Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000341a00000104000000000000,QanBa Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,platform:Windows,
|
||||||
|
03000000222c00000223000000000000,Qanba Obsidian Arcade Joystick PS3 Mode,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000222c00000023000000000000,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000321500000204000000000000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000321500000104000000000000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000321500000507000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000321500000707000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000321500000011000000000000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000321500000009000000000000,Razer Serval,+lefty:+a2,-lefty:-a1,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,leftx:a0,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
030000000d0f00001100000000000000,REAL ARCADE PRO.3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00006a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00006b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00008a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00008b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00007000000000000000,REAL ARCADE PRO.4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00002200000000000000,REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00005b00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000000d0f00005c00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000790000001100000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000bd12000013d0000000000000,Retrolink USB SEGA Saturn Classic,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,lefttrigger:b6,rightshoulder:b2,righttrigger:b7,start:b8,x:b3,y:b4,platform:Windows,
|
||||||
|
0300000000f000000300000000000000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,
|
||||||
|
0300000000f00000f100000000000000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,
|
||||||
|
030000006b140000010d000000000000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006b140000020d000000000000,Revolution Pro Controller 2(1/2),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006b140000130d000000000000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006f0e00001e01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006f0e00002801000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006f0e00002f01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000004f04000003d0000000000000,run'n'drive,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000a30600001af5000000000000,Saitek Cyborg,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000a306000023f6000000000000,Saitek Cyborg V.1 Game pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000300f00001201000000000000,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
|
||||||
|
03000000a30600000701000000000000,Saitek P220,a:b2,b:b3,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b5,x:b0,y:b1,platform:Windows,
|
||||||
|
03000000a30600000cff000000000000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b0,y:b1,platform:Windows,
|
||||||
|
03000000a30600000c04000000000000,Saitek P2900,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000300f00001001000000000000,Saitek P480 Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
|
||||||
|
03000000a30600000b04000000000000,Saitek P990,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000a30600002106000000000000,Saitek PS1000,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000a306000020f6000000000000,Saitek PS2700,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000300f00001101000000000000,Saitek Rumble Pad,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
|
||||||
|
03000000730700000401000000000000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows,
|
||||||
|
0300000000050000289b000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000005e0400008e02000000007801,ShanWan PS3/PC Wired GamePad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000341a00000208000000000000,SL-6555-SBK,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000341a00000908000000000000,SL-6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
030000008f0e00000800000000000000,SpeedLink Strike FX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000c01100000591000000000000,Speedlink Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000d11800000094000000000000,Stadia Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b11,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000110100001914000000000000,SteelSeries,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000381000001214000000000000,SteelSeries Free,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000110100003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000381000001814000000000000,SteelSeries Stratus XL,a:b0,b:b1,back:b18,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b19,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000790000001c18000000000000,STK-7024X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000ff1100003133000000000000,SVEN X-PAD,a:b2,b:b3,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a4,start:b5,x:b0,y:b1,platform:Windows,
|
||||||
|
03000000d620000011a7000000000000,Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000457500002211000000000000,SZMY-POWER PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000004f04000007d0000000000000,T Mini Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000004f0400000ab1000000000000,T.16000M,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b10,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000fa1900000706000000000000,Team 5,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000b50700001203000000000000,Techmobility X6-38V,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
|
||||||
|
030000004f04000015b3000000000000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
|
||||||
|
030000004f04000023b3000000000000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000004f0400000ed0000000000000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows,
|
||||||
|
030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
|
||||||
|
03000000666600000488000000000000,TigerGame PS/PS2 Game Controller Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000d62000006000000000000000,Tournament PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000005f140000c501000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000b80500000210000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
030000004f04000087b6000000000000,TWCS Throttle,dpdown:b8,dpleft:b9,dpright:b7,dpup:b6,leftstick:b5,lefttrigger:-a5,leftx:a0,lefty:a1,righttrigger:+a5,platform:Windows,
|
||||||
|
03000000d90400000200000000000000,TwinShock PS2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
030000006e0500001320000000000000,U4113,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000101c0000171c000000000000,uRage Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000300f00000701000000000000,USB 4-Axis 12-Button Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000341a00002308000000000000,USB gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
030000005509000000b4000000000000,USB gamepad,a:b10,b:b11,back:b5,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,guide:b14,leftshoulder:b8,leftstick:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:a5,rightx:a2,righty:a3,start:b4,x:b12,y:b13,platform:Windows,
|
||||||
|
030000006b1400000203000000000000,USB gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000790000000a00000000000000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000f0250000c183000000000000,USB gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000ff1100004133000000000000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000632500002305000000000000,USB Vibration Joystick (BM),a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000790000001a18000000000000,Venom,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
03000000790000001b18000000000000,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006f0e00000302000000000000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
030000006f0e00000702000000000000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
0300000034120000adbe000000000000,vJoy Device,a:b0,b:b1,back:b15,dpdown:b6,dpleft:b7,dpright:b8,dpup:b5,guide:b16,leftshoulder:b9,leftstick:b13,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b14,righttrigger:b12,rightx:+a3,righty:+a4,start:b4,x:b2,y:b3,platform:Windows,
|
||||||
|
030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
030000005e040000ff02000000007801,Xbox One Elite Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
030000005e040000130b000000000000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000341a00000608000000000000,Xeox,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000450c00002043000000000000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000ac0500005b05000000000000,Xiaoji Gamesir-G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
|
||||||
|
03000000172700004431000000000000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000786901006e70000000000000,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
|
||||||
|
03000000790000004f18000000000000,ZD-T Android,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
|
||||||
|
03000000120c0000101e000000000000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
|
||||||
|
|
||||||
|
# Mac OS X
|
||||||
|
030000008f0e00000300000009010000,2In1 USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
|
03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000c82d00000650000001000000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
|
03000000c82d00005106000000010000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000c82d00001590000001000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
030000003512000012ab000001000000,8BitDo NES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000022000000090000001000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000c82d00000190000001000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000102800000900000000000000,8Bitdo SFC30 GamePad Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000c82d00001290000001000000,8BitDo SN30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000c82d00000260000001000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000c82d00000031000001000000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000c82d00001890000001000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a31,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
03000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
|
03000000a00500003232000009010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
|
03000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
03000000c62400001a89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,
|
||||||
|
03000000c62400001b89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
|
03000000d62000002a79000000010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
03000000c01100000140000000010000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000006f0e00000102000000000000,GameStop Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
030000007d0400000540000001010000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000000d0f00002d00000000100000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000000d0f00005f00000000010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000000d0f00005e00000000010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000000d0f00005f00000000000000,HORI Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000000d0f00005e00000000000000,HORI Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000000d0f00004d00000000000000,HORI Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000000d0f00009200000000010000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000000d0f00006e00000000010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000000d0f00006600000000010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000000d0f00006600000000000000,HORIPAD FPS PLUS 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000000d0f0000ee00000000010000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000008f0e00001330000011010000,HuiJia SNES Controller,a:b4,b:b2,back:b16,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b12,rightshoulder:b14,start:b18,x:b6,y:b0,platform:Mac OS X,
|
||||||
|
03000000830500006020000000010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,
|
||||||
|
03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,
|
||||||
|
030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
03000000242f00002d00000007010000,JYS Wireless Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
|
030000006d04000016c2000000020000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000006d04000016c2000000030000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000006d04000016c2000014040000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000006d04000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000006d04000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000006d04000019c2000005030000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000006d0400001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
030000006d04000018c2000000010000,Logitech RumblePad 2 USB,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3~,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000006d04000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
03000000380700005032000000010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
03000000380700005082000000010000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
03000000380700008433000000010000,Mad Catz FightStick TE S+ (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
03000000380700008483000000010000,Mad Catz FightStick TE S+ (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
03000000790000004418000000010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
03000000242f00007300000000020000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
0300000079000000d218000026010000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
|
03000000d620000010a7000003010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X,
|
||||||
|
03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,
|
||||||
|
03000000d8140000cecf000000000000,MC Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000005e0400002700000001010000,Microsoft SideWinder Plug & Play Game Pad,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,leftx:a0,lefty:a1,righttrigger:b5,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
03000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
03000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
|
03000000c62400002b89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
|
03000000632500007505000000020000,NEOGEO mini PAD Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
|
03000000d620000011a7000000020000,Nintendo Switch Core (Plus) Wired Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
030000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
03000000550900001472000025050000,NVIDIA Controller v01.04,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
030000006f0e00000901000002010000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
|
030000004c050000da0c000000010000,Playstation Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
|
03000000d62000006dca000000010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
|
||||||
|
030000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
|
||||||
|
030000004c050000a00b000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
03000000321500000204000000010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
03000000321500000104000000010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
03000000321500000010000000010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
03000000321500000507000001010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
|
03000000321500000011000000010000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
03000000321500000009000000020000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
030000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
0300000032150000030a000000000000,Razer Wildcat,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
03000000790000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
|
03000000790000001100000006010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
|
030000006b140000010d000000010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000006b140000130d000000010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
03000000c6240000fefa000000000000,Rock Candy Gamepad for PS3,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
03000000730700000401000000010000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Mac OS X,
|
||||||
|
03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X,
|
||||||
|
03000000b40400000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X,
|
||||||
|
030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
|
||||||
|
0300000000f00000f100000000000000,SNES RetroPort,a:b2,b:b3,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,rightshoulder:b7,start:b6,x:b0,y:b1,platform:Mac OS X,
|
||||||
|
30000004c050000e60c0000000100000,Sony DualSense,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
03000000d11800000094000000010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
030000005e0400008e02000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
03000000381000002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
03000000110100001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
03000000457500002211000000010000,SZMY-POWER PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X,
|
||||||
|
030000004f0400000ed0000000020000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X,
|
||||||
|
03000000bd12000015d0000000000000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
|
03000000bd12000015d0000000010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
|
03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X,
|
||||||
|
030000006f0e00000302000025040000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
030000006f0e00000702000003060000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
03000000791d00000103000009010000,Wii Classic Controller,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
|
||||||
|
050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X,
|
||||||
|
050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X,
|
||||||
|
030000005e0400008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
03000000c6240000045d000000000000,Xbox 360 Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
030000005e040000050b000003090000,Xbox Elite Wireless Controller Series 2,a:b0,b:b1,back:b31,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b53,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
|
030000005e040000d102000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
030000005e040000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
030000005e040000e302000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
030000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
|
030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
|
030000005e040000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
030000005e040000e002000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
030000005e040000ea02000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
|
||||||
|
030000005e040000fd02000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
|
03000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Mac OS X,
|
||||||
|
03000000120c0000100e000000010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
03000000120c0000101e000000010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||||
|
|
||||||
|
# Linux
|
||||||
|
03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
05000000c82d00001038000000010000,8Bitdo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
05000000c82d00005106000000010000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
03000000c82d00001590000011010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
05000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
03000000c82d00000310000011010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
05000000c82d00008010000000010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
03000000022000000090000011010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
05000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
05000000c82d00002038000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
03000000c82d00000190000011010000,8Bitdo NES30 Pro 8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
05000000c82d00000060000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
05000000c82d00000061000000010000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
03000000c82d000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
030000003512000012ab000010010000,8Bitdo SFC30 GamePad,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux,
|
||||||
|
05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
05000000c82d00003028000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
03000000c82d00000160000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
03000000c82d00001290000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
05000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
05000000c82d00006228000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
03000000c82d00000260000011010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
05000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
05000000202800000900000000010000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
030000005e0400008e02000020010000,8BitDo Wireless Adapter,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000c82d00000031000011010000,8BitDo Wireless Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
05000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
|
||||||
|
05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
05000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
030000006f0e00001302000000010000,Afterglow,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000006f0e00003901000020060000,Afterglow Controller for Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000006f0e00003901000000430000,Afterglow Prismatic Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000006f0e00003901000013020000,Afterglow Prismatic Wired Controller 048-007-NA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000007c1800000006000010010000,Alienware Dual Compatible Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,
|
||||||
|
05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000120c00000500000010010000,AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux,
|
||||||
|
03000000c62400001b89000011010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
03000000d62000002a79000011010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000c21100000791000011010000,Be1 GC101 Controller 1.03 mode,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000c31100000791000011010000,Be1 GC101 GAMEPAD 1.03 mode,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
030000005e0400008e02000003030000,Be1 GC101 Xbox 360 Controller mode,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000ffff0000ffff000000010000,Chinese-made Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
|
||||||
|
03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux,
|
||||||
|
03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000a306000022f6000011010000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000b40400000a01000000010000,CYPRESS USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,
|
||||||
|
03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
030000004f04000004b3000010010000,Dual Power 2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
|
||||||
|
030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000008f0e00000800000010010000,Gasia Co. Ltd PS(R) Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
030000006f0e00001304000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
0300000079000000d418000000010000,GPD Win 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000007d0400000540000000010000,Gravis Eliminator GamePad Pro,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000280400000140000000010000,Gravis GamePad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000008f0e00000610000000010000,GreenAsia Electronics 4Axes 12Keys GamePad ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux,
|
||||||
|
030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000f0250000c383000010010000,GT VX2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
06000000adde0000efbe000002010000,Hidromancer Game Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000c9110000f055000011010000,HJC Game GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000632500002605000010010000,HJD-X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
030000000d0f00000d00000000010000,hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftx:b4,lefty:b5,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux,
|
||||||
|
030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000000d0f0000c100000011010000,HORI CO. LTD. HORIPAD S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000000d0f00006a00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000000d0f00006b00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000000d0f00008500000010010000,HORI Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000000d0f00008600000002010000,Hori Fighting Commander,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
030000000d0f00005f00000011010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000000d0f00005e00000011010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000000d0f0000aa00000011010000,HORI Real Arcade Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
030000000d0f0000d800000072056800,HORI Real Arcade Pro S,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
|
||||||
|
030000000d0f00001600000000010000,Hori Real Arcade Pro.EX-SE (Xbox 360),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
030000000d0f00006e00000011010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000000d0f00006600000011010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000000d0f0000ee00000011010000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000000d0f00006700000001010000,HORIPAD ONE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000008f0e00001330000010010000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000242e00008816000001010000,Hyperkin X91,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
|
||||||
|
050000006964726f69643a636f6e0000,idroid:con,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000b50700001503000010010000,impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
|
||||||
|
03000000d80400008200000003000000,IMS PCU#0 Gamepad Interface,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux,
|
||||||
|
03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux,
|
||||||
|
0500000049190000020400001b010000,Ipega PG-9069 - Bluetooth Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b161,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
03000000632500007505000011010000,Ipega PG-9099 - Bluetooth Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,
|
||||||
|
03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
|
||||||
|
03000000300f00000b01000010010000,Jess Tech GGE909 PC Recoil Pad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux,
|
||||||
|
050000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux,
|
||||||
|
030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
050000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000242f00002d00000011010000,JYS Wireless Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000242f00008a00000011010000,JYS Wireless Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux,
|
||||||
|
030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000006d040000d1ca000000000000,Logitech ChillStream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000006d0400001ec2000019200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000006d0400000ac2000010010000,Logitech Inc. WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux,
|
||||||
|
030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux,
|
||||||
|
05000000380700006652000025010000,Mad Catz C.T.R.L.R ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000380700005032000011010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000380700005082000011010000,Mad Catz FightPad PRO (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000380700008034000011010000,Mad Catz fightstick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000380700008084000011010000,Mad Catz fightstick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000380700008433000011010000,Mad Catz FightStick TE S+ (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000380700008483000011010000,Mad Catz FightStick TE S+ (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000380700003847000090040000,Mad Catz Wired Xbox 360 Controller (SFIV),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000380700001888000010010000,MadCatz PC USB Wired Stick 8818,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000380700003888000010010000,MadCatz PC USB Wired Stick 8838,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000120c00000500000000010000,Manta Dualshock 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000790000004318000010010000,Mayflash GameCube Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000242f00007300000011010000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux,
|
||||||
|
0300000079000000d218000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000d620000010a7000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
0300000025090000e803000001010000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
|
03000000780000000600000010010000,Microntek USB Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
030000005e0400000e00000000010000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,
|
||||||
|
030000005e0400008e02000004010000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e0400008e02000062230000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
050000005e040000050b000003090000,Microsoft X-Box One Elite 2 pad,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
030000005e040000e302000003020000,Microsoft X-Box One Elite pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e040000d102000001010000,Microsoft X-Box One pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e040000dd02000003020000,Microsoft X-Box One pad (Firmware 2015),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e040000d102000003020000,Microsoft X-Box One pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
|
||||||
|
030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
|
||||||
|
030000005e040000000b000008040000,Microsoft Xbox One Elite 2 pad - Wired,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e040000ea02000008040000,Microsoft Xbox One S pad - Wired,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000c62400001a53000000010000,Mini PE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
|
||||||
|
05000000d6200000e589000001000000,Moga 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
|
||||||
|
05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
|
||||||
|
05000000d62000007162000001000000,Moga Pro 2 HID,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000c62400002b89000011010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
05000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
05000000c62400001a89000000010000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
03000000250900006688000000010000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
|
||||||
|
030000006b140000010c000010010000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
060000007e0500000820000000000000,Nintendo Combined Joy-Cons (joycond),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
|
||||||
|
030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux,
|
||||||
|
03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
050000007e0500000920000001800000,Nintendo Switch Pro Controller (joycond),a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
|
||||||
|
030000007e0500000920000011810000,Nintendo Switch Pro Controller Wired (joycond),a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
|
||||||
|
050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
|
05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
030000000d0500000308000010010000,Nostromo n45 Dual Analog Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
|
||||||
|
05000000550900001472000001000000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
19000000010000000100000001010000,odroidgo2_joypad,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux,
|
||||||
|
19000000010000000200000011000000,odroidgo2_joypad_v11,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e0400000202000000010000,Old Xbox pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
|
||||||
|
05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,
|
||||||
|
05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,
|
||||||
|
03000000830500005020000010010000,Padix Co. Ltd. Rockfire PSX/USB Bridge,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000790000001c18000011010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
030000006f0e0000b802000001010000,PDP AFTERGLOW Wired Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000006f0e0000b802000013020000,PDP AFTERGLOW Wired Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000006f0e00008001000011010000,PDP CO. LTD. Faceoff Wired Pro Controller for Nintendo Switch,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000006f0e00003101000000010000,PDP EA Sports Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000006f0e00008701000011010000,PDP Rock Candy Wired Controller for Nintendo Switch,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
030000006f0e00000901000011010000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000006f0e0000a802000023020000,PDP Wired Controller for Xbox One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
030000006f0e00008501000011010000,PDP Wired Fight Pad Pro for Nintendo Switch,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
05000000491900000204000000000000,PG-9118,x:b76,a:b73,b:b74,y:b77,back:b83,start:b84,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b79,lefttrigger:b81,rightshoulder:b80,righttrigger:b82,leftstick:b86,rightstick:b87,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Linux,
|
||||||
|
0500000049190000030400001b010000,PG-9099,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
030000004c050000da0c000011010000,Playstation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000c62400001a58000001010000,PowerA Xbox One Cabled,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000004c0500006802000010010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
|
||||||
|
030000004c0500006802000010810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
|
030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
|
||||||
|
030000004c0500006802000011810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
|
030000006f0e00001402000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000008f0e00000300000010010000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
050000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:a12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:a13,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
|
||||||
|
050000004c0500006802000000800000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
|
050000004c0500006802000000810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
|
05000000504c415953544154494f4e00,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
|
||||||
|
060000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
|
||||||
|
030000004c050000a00b000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000004c050000a00b000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
|
030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000004c050000c405000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
|
030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000004c050000cc09000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000004c050000cc09000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
|
03000000c01100000140000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
050000004c050000c405000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
|
050000004c050000c405000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
|
050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
|
050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
|
030000004c050000e60c000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000300f00001211000011010000,QanBa Arcade JoyStick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux,
|
||||||
|
030000009b2800003200000001010000,Raphnet Technologies GC/N64 to USB v3.4,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
|
||||||
|
030000009b2800006000000001010000,Raphnet Technologies GC/N64 to USB v3.6,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux,
|
||||||
|
030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,
|
||||||
|
030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000008916000000fd000024010000,Razer Onza Tournament Edition,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000321500000204000011010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000321500000104000011010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000321500000810000011010000,Razer Panthera Evo Arcade Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000321500000010000011010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000321500000507000000010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
03000000321500000011000011010000,Razer Raion Fightpad for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000008916000000fe000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000c6240000045d000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000321500000009000011010000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
0300000032150000030a000001010000,Razer Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000790000001100000010010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
0300000081170000990a000001010000,Retronic Adapter,a:b0,leftx:a0,lefty:a1,platform:Linux,
|
||||||
|
0300000000f000000300000000010000,RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,
|
||||||
|
030000006b140000010d000011010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000006b140000130d000011010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000006f0e00001f01000000010000,Rock Candy,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000006f0e00001e01000011010000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000006f0e00004601000001010000,Rock Candy Xbox One Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b0,y:b1,platform:Linux,
|
||||||
|
03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000300f00001201000010010000,Saitek P380,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
|
||||||
|
03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux,
|
||||||
|
03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000a306000020f6000011010000,Saitek PS2700 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000a30600001005000000010000,Saitek Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux,
|
||||||
|
03000000d81d00000e00000010010000,Savior,a:b0,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b9,x:b4,y:b5,platform:Linux,
|
||||||
|
03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,back:b4,dpdown:b2,dpleft:b3,dpright:b1,dpup:b0,leftshoulder:b9,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b8,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b5,x:b13,y:b11,platform:Linux,
|
||||||
|
03000000f025000021c1000010010000,ShanWan Gioteck PS3 Wired Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000632500007505000010010000,SHANWAN PS3/PC Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000bc2000000055000010010000,ShanWan PS3/PC Wired GamePad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
03000000632500002305000010010000,ShanWan USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000341a00000908000010010000,SL-6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
|
||||||
|
030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000d11800000094000011010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
|
||||||
|
03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
|
||||||
|
03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000381000003014000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000381000003114000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
0500000011010000311400001b010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b32,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
05000000110100001914000009010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
03000000ad1b000038f0000090040000,Street Fighter IV FightStick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000003b07000004a1000000010000,Suncom SFX Plus for USB,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Linux,
|
||||||
|
03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
|
||||||
|
0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,
|
||||||
|
03000000457500002211000010010000,SZMY-POWER CO. LTD. GAMEPAD,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
030000008f0e00000d31000010010000,SZMY-POWER CO. LTD. GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
|
||||||
|
030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
|
||||||
|
030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000004f0400000ed0000011010000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000b50700000399000000010000,Thrustmaster Firestorm Digital 2,a:b2,b:b4,back:b11,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b0,righttrigger:b9,start:b1,x:b3,y:b5,platform:Linux,
|
||||||
|
030000004f04000003b3000010010000,Thrustmaster Firestorm Dual Analog 2,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b9,rightx:a2,righty:a3,x:b1,y:b3,platform:Linux,
|
||||||
|
030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux,
|
||||||
|
030000004f04000026b3000002040000,Thrustmaster Gamepad GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000c6240000025b000002020000,Thrustmaster GPX Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000004f04000007d0000000010000,Thrustmaster T Mini Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000004f04000012b3000010010000,Thrustmaster vibrating gamepad,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
|
||||||
|
03000000bd12000015d0000010010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux,
|
||||||
|
030000005e0400008e02000070050000,Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000c01100000591000011010000,Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000790000000600000007010000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
03000000790000001100000000010000,USB Gamepad1,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux,
|
||||||
|
030000006f0e00000302000011010000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
030000006f0e00000702000011010000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
05000000ac0500003232000001000000,VR-BOX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000791d00000103000010010000,Wii Classic Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
050000000d0f0000f600000001000000,Wireless HORIPAD Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e040000a102000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e040000a102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e040000a102000014010000,Xbox 360 Wireless Receiver (XBOX),a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e040000d102000002010000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
050000005e040000fd02000030110000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
030000005e040000ea02000000000000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
030000005e040000ea02000001030000,Xbox One Wireless Controller (Model 1708),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
050000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
050000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
030000005e0400008e02000000010000,xbox360 Wireless EasySMX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000450c00002043000010010000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000ac0500005b05000010010000,Xiaoji Gamesir-G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
|
||||||
|
05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux,
|
||||||
|
03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,
|
||||||
|
xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
|
||||||
|
03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
|
||||||
|
|
||||||
|
# Android
|
||||||
|
05000000c82d000006500000ffff3f00,8BitDo M30 Gamepad,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a4,start:b6,x:b3,y:b2,platform:Android,
|
||||||
|
05000000c82d000051060000ffff3f00,8BitDo M30 Gamepad,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,start:b6,x:b3,y:b2,platform:Android,
|
||||||
|
05000000c82d000015900000ffff3f00,8BitDo N30 Pro 2,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
|
||||||
|
05000000c82d000065280000ffff3f00,8BitDo N30 Pro 2,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b17,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
|
||||||
|
050000000220000000900000ffff3f00,8BitDo NES30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
|
||||||
|
050000002038000009000000ffff3f00,8BitDo NES30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
|
||||||
|
05000000c82d000000600000ffff3f00,8BitDo SF30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
|
||||||
|
05000000c82d000000610000ffff3f00,8BitDo SF30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
|
||||||
|
05000000c82d000012900000ffff3f00,8BitDo SN30 Gamepad,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
|
||||||
|
05000000c82d000062280000ffff3f00,8BitDo SN30 Gamepad,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
|
||||||
|
05000000c82d000001600000ffff3f00,8BitDo SN30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
|
||||||
|
05000000c82d000002600000ffff0f00,8BitDo SN30 Pro+,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b17,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
|
||||||
|
050000002028000009000000ffff3f00,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,platform:Android,
|
||||||
|
050000003512000020ab000000780f00,8BitDo SNES30 Gamepad,a:b21,b:b20,back:b30,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b26,rightshoulder:b27,start:b31,x:b24,y:b23,platform:Android,
|
||||||
|
05000000c82d000018900000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
|
||||||
|
05000000c82d000030320000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
|
||||||
|
05000000bc20000000550000ffff3f00,GameSir G3w,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
05000000d6020000e5890000dfff3f00,GPD XD Plus,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
0500000031366332860c44aadfff0f00,GS Gamepad,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
0500000083050000602000000ffe0000,iBuffalo SNES Controller,a:b1,b:b0,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b15,rightshoulder:b16,start:b10,x:b3,y:b2,platform:Android,
|
||||||
|
64633436313965656664373634323364,Microsoft X-Box 360 pad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,platform:Android,
|
||||||
|
7573622067616d657061642020202020,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,platform:Android,
|
||||||
|
050000007e05000009200000ffff0f00,Nintendo Switch Pro Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b16,x:b17,y:b2,platform:Android,
|
||||||
|
37336435666338653565313731303834,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
61363931656135336130663561616264,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
050000005509000003720000cf7f3f00,NVIDIA Controller v01.01,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
050000005509000010720000ffff3f00,NVIDIA Controller v01.03,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
050000005509000014720000df7f3f00,NVIDIA Controller v01.04,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
050000004c05000068020000dfff3f00,PS3 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
030000004c050000cc09000000006800,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
050000004c050000c4050000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android,
|
||||||
|
050000004c050000c4050000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
050000004c050000cc090000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android,
|
||||||
|
050000004c050000cc090000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
35643031303033326130316330353564,PS4 Controller,a:b1,b:b17,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android,
|
||||||
|
050000004c050000e60c0000fffe3f00,PS5 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,platform:Android,
|
||||||
|
62653861643333663663383332396665,Razer Kishi,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
050000003215000005070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
050000003215000007070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
050000003215000000090000bf7f3f00,Razer Serval,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,platform:Android,
|
||||||
|
32633532643734376632656664383733,Sony DualSense,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android,
|
||||||
|
61303162353165316365336436343139,Sony DualSense,a:b1,b:b19,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a5,start:b18,x:b0,y:b2,platform:Android,
|
||||||
|
05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android,
|
||||||
|
05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Android,
|
||||||
|
050000004f0400000ed00000fffe3f00,ThrustMaster eSwap PRO Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
5477696e20555342204a6f7973746963,Twin USB Joystick,a:b22,b:b21,back:b28,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b26,leftstick:b30,lefttrigger:b24,leftx:a0,lefty:a1,rightshoulder:b27,rightstick:b31,righttrigger:b25,rightx:a3,righty:a2,start:b29,x:b23,y:b20,platform:Android,
|
||||||
|
30306539356238653637313730656134,Wireless HORIPAD Switch Pro Controller,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,leftstick:b15,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b18,x:b19,y:b2,platform:Android,
|
||||||
|
050000005e040000fd020000ff7f3f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
050000005e040000e00200000ffe3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b17,y:b2,platform:Android,
|
||||||
|
050000005e040000fd020000ffff3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
050000005e040000130b0000ffff3f00,Xbox Series Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
65633038363832353634653836396239,Xbox Series Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
050000005e04000091020000ff073f00,Xbox Wireless Controller,a:b0,b:b1,back:b4,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
34356136633366613530316338376136,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,x:b17,y:b2,platform:Android,
|
||||||
|
050000001727000044310000ffff3f00,XiaoMi Game Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a6,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Android,
|
||||||
|
|
||||||
|
# iOS
|
||||||
|
05000000ac0500000100000000006d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,platform:iOS,
|
||||||
|
05000000ac050000010000004f066d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,platform:iOS,
|
||||||
|
05000000ac05000001000000cf076d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,platform:iOS,
|
||||||
|
05000000ac05000001000000df076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
|
||||||
|
05000000ac05000001000000ff076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS,
|
||||||
|
05000000ac0500000200000000006d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,platform:iOS,
|
||||||
|
05000000ac050000020000004f066d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,platform:iOS,
|
||||||
|
4d466947616d65706164010000000000,MFi Extended Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:iOS,
|
||||||
|
4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:iOS,
|
||||||
|
050000004c050000cc090000df070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
|
||||||
|
050000004c050000cc090000ff070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS,
|
||||||
|
050000004c050000cc090000ff870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,touchpad:b11,x:b2,y:b3,platform:iOS,
|
||||||
|
05000000ac0500000300000000006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,platform:iOS,
|
||||||
|
05000000ac0500000300000043006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,platform:iOS,
|
||||||
|
05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS,
|
||||||
|
05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:iOS,
|
||||||
|
050000005e040000050b0000ff070001,Xbox Elite Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS,
|
||||||
|
050000005e040000e0020000df070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:iOS,
|
||||||
|
050000005e040000e0020000ff070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,platform:iOS,
|
BIN
gtk3/resources/pixmaps/CPU.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
gtk3/resources/pixmaps/Display.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
gtk3/resources/pixmaps/Joypad.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
gtk3/resources/pixmaps/Speaker.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
gtk3/resources/pixmaps/logo/logo_128.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
gtk3/resources/pixmaps/logo/logo_16.png
Normal file
After Width: | Height: | Size: 974 B |
BIN
gtk3/resources/pixmaps/logo/logo_256.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
gtk3/resources/pixmaps/logo/logo_32.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
gtk3/resources/pixmaps/logo/logo_48.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
gtk3/resources/pixmaps/logo/logo_64.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
74
gtk3/resources/ui/about_dialog.ui
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015-2021 Lior Halphon
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
Author: Maximilian Mader
|
||||||
|
|
||||||
|
-->
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.22"/>
|
||||||
|
<!-- interface-license-type mit -->
|
||||||
|
<!-- interface-name SameBoy -->
|
||||||
|
<!-- interface-description SameBoy is an open source Game Boy (DMG) and Game Boy Color (CGB) emulator, written in portable C. -->
|
||||||
|
<!-- interface-copyright 2015-2021 Lior Halphon -->
|
||||||
|
<!-- interface-authors Maximilian Mader -->
|
||||||
|
<template class="AboutDialog">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="type_hint">normal</property>
|
||||||
|
<property name="program_name">SameBoy</property>
|
||||||
|
<property name="copyright" translatable="yes">Copyright © 2015-2021 Lior Halphon</property>
|
||||||
|
<property name="website">https://sameboy.github.io</property>
|
||||||
|
<property name="website_label" translatable="yes">sameboy.github.io</property>
|
||||||
|
<property name="authors">Lior Halphon https://github.com/LIJI32
|
||||||
|
|
||||||
|
GTK3 frontend by
|
||||||
|
Maximilian Mader https://github.com/max-m</property>
|
||||||
|
<property name="logo_icon_name"/>
|
||||||
|
<property name="license_type">mit-x11</property>
|
||||||
|
<child internal-child="vbox">
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="spacing">2</property>
|
||||||
|
<child internal-child="action_area">
|
||||||
|
<object class="GtkButtonBox">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="layout_style">end</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child type="titlebar">
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
</template>
|
||||||
|
</interface>
|
202
gtk3/resources/ui/console_window.ui
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015-2021 Lior Halphon
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
Author: Maximilian Mader
|
||||||
|
|
||||||
|
-->
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.22"/>
|
||||||
|
<!-- interface-license-type mit -->
|
||||||
|
<!-- interface-name SameBoy -->
|
||||||
|
<!-- interface-description SameBoy is an open source Game Boy (DMG) and Game Boy Color (CGB) emulator, written in portable C. -->
|
||||||
|
<!-- interface-copyright 2015-2021 Lior Halphon -->
|
||||||
|
<!-- interface-authors Maximilian Mader -->
|
||||||
|
<template class="ConsoleWindow">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="title" translatable="yes">Debug Console</property>
|
||||||
|
<property name="default_width">920</property>
|
||||||
|
<property name="default_height">400</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="shadow_type">in</property>
|
||||||
|
<property name="min_content_width">600</property>
|
||||||
|
<property name="min_content_height">376</property>
|
||||||
|
<property name="max_content_width">600</property>
|
||||||
|
<property name="max_content_height">376</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTextView" id="output">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="editable">False</property>
|
||||||
|
<property name="wrap_mode">word</property>
|
||||||
|
<property name="left_margin">5</property>
|
||||||
|
<property name="right_margin">5</property>
|
||||||
|
<property name="top_margin">5</property>
|
||||||
|
<property name="bottom_margin">5</property>
|
||||||
|
<property name="cursor_visible">False</property>
|
||||||
|
<property name="accepts_tab">False</property>
|
||||||
|
<property name="monospace">True</property>
|
||||||
|
<style>
|
||||||
|
<class name="border-none"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<style>
|
||||||
|
<class name="border-none"/>
|
||||||
|
<class name="border-right"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="width_request">320</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="shadow_type">in</property>
|
||||||
|
<property name="min_content_width">320</property>
|
||||||
|
<property name="min_content_height">80</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTextView" id="sidebar_input">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="wrap_mode">word</property>
|
||||||
|
<property name="left_margin">5</property>
|
||||||
|
<property name="right_margin">5</property>
|
||||||
|
<property name="top_margin">5</property>
|
||||||
|
<property name="bottom_margin">5</property>
|
||||||
|
<property name="accepts_tab">False</property>
|
||||||
|
<property name="monospace">True</property>
|
||||||
|
<style>
|
||||||
|
<class name="border-none"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<style>
|
||||||
|
<class name="border-none"/>
|
||||||
|
<class name="border-bottom"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="shadow_type">in</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTextView" id="sidebar_output">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="editable">False</property>
|
||||||
|
<property name="wrap_mode">word</property>
|
||||||
|
<property name="left_margin">5</property>
|
||||||
|
<property name="right_margin">5</property>
|
||||||
|
<property name="top_margin">5</property>
|
||||||
|
<property name="bottom_margin">5</property>
|
||||||
|
<property name="accepts_tab">False</property>
|
||||||
|
<property name="monospace">True</property>
|
||||||
|
<style>
|
||||||
|
<class name="border-none"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<style>
|
||||||
|
<class name="border-none"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<style>
|
||||||
|
<class name="border-none"/>
|
||||||
|
<class name="border-bottom"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="input">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="margin_top">3</property>
|
||||||
|
<property name="margin_bottom">3</property>
|
||||||
|
<property name="placeholder_text" translatable="yes">Console input</property>
|
||||||
|
<signal name="activate" handler="on_input_enter" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child type="titlebar">
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<style>
|
||||||
|
<class name="debug-console"/>
|
||||||
|
</style>
|
||||||
|
</template>
|
||||||
|
</interface>
|
358
gtk3/resources/ui/main_menu.ui
Normal file
@ -0,0 +1,358 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015-2019 Lior Halphon
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
Author: Maximilian Mader
|
||||||
|
|
||||||
|
-->
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.22"/>
|
||||||
|
<!-- interface-license-type mit -->
|
||||||
|
<!-- interface-name SameBoy -->
|
||||||
|
<!-- interface-description SameBoy is an open source Game Boy (DMG) and Game Boy Color (CGB) emulator, written in portable C. -->
|
||||||
|
<!-- interface-copyright 2015-2021 Lior Halphon -->
|
||||||
|
<!-- interface-authors Maximilian Mader -->
|
||||||
|
<template class="MainMenu">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">_File</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="action_name">app.open</property>
|
||||||
|
<property name="label" translatable="yes">_Open</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">_Recent files</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkRecentChooserMenu">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="filter">recent_files_filter</property>
|
||||||
|
<property name="limit">10</property>
|
||||||
|
<property name="sort_type">mru</property>
|
||||||
|
<signal name="item-activated" handler="on_open_recent_activate" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="action_name">app.close</property>
|
||||||
|
<property name="label" translatable="yes">_Close</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="action_name">app.quit</property>
|
||||||
|
<property name="label" translatable="yes">_Quit</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">_Edit</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="action_name">app.preferences</property>
|
||||||
|
<property name="label" translatable="yes">_Preferences</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">E_mulation</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="action_name">app.reset</property>
|
||||||
|
<property name="label" translatable="yes">_Reset</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCheckMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="action_name">app.pause</property>
|
||||||
|
<property name="label" translatable="yes">Pause</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="action_name">app.save_state</property>
|
||||||
|
<property name="label" translatable="yes">Save State</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="action_name">app.load_state</property>
|
||||||
|
<property name="label" translatable="yes">Load State</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorMenuItem" id="before_model_changer">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCheckMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="action_name">app.toggle_mute</property>
|
||||||
|
<property name="label" translatable="yes">Mute Sound</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">_Link</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu" id="link_menu">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">_Develop</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCheckMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="action_name">app.toggle_developer_mode</property>
|
||||||
|
<property name="label" translatable="yes">Developer Mode</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="action_name">app.show_console</property>
|
||||||
|
<property name="label" translatable="yes">Show Console</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="action_name">app.clear_console</property>
|
||||||
|
<property name="label" translatable="yes">Clear Console</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="action_name">app.break_debugger</property>
|
||||||
|
<property name="label" translatable="yes">Break Debugger</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="action_name">app.open_memory_viewer</property>
|
||||||
|
<property name="label" translatable="yes">Show Memory Viewer</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="action_name">app.open_vram_viewer</property>
|
||||||
|
<property name="label" translatable="yes">Show VRAM Viewer</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="action_name">app.open_gtk_debugger</property>
|
||||||
|
<property name="label" translatable="yes">Show GTK Debugger</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">_Help</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="action_name">app.about</property>
|
||||||
|
<property name="label">_About</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<object class="GtkRecentFilter" id="recent_files_filter">
|
||||||
|
<mime-types>
|
||||||
|
<mime-type>application/x-gameboy-rom</mime-type>
|
||||||
|
<mime-type>application/x-gameboy-color-rom</mime-type>
|
||||||
|
</mime-types>
|
||||||
|
<patterns>
|
||||||
|
<pattern>*.gb</pattern>
|
||||||
|
<pattern>*.gbc</pattern>
|
||||||
|
<pattern>*.isx</pattern>
|
||||||
|
</patterns>
|
||||||
|
<applications>
|
||||||
|
<application>sameboy</application>
|
||||||
|
</applications>
|
||||||
|
</object>
|
||||||
|
</interface>
|
51
gtk3/resources/ui/main_window.ui
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015-2019 Lior Halphon
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
Author: Maximilian Mader
|
||||||
|
|
||||||
|
-->
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.22"/>
|
||||||
|
<!-- interface-license-type mit -->
|
||||||
|
<!-- interface-name SameBoy -->
|
||||||
|
<!-- interface-description SameBoy is an open source Game Boy (DMG) and Game Boy Color (CGB) emulator, written in portable C. -->
|
||||||
|
<!-- interface-copyright 2015-2021 Lior Halphon -->
|
||||||
|
<!-- interface-authors Maximilian Mader -->
|
||||||
|
<template class="MainWindow">
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox" id="container">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="MainMenu" id="main_menu">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</template>
|
||||||
|
</interface>
|
1056
gtk3/resources/ui/preferences_window.ui
Normal file
103
gtk3/resources/ui/printer_window.ui
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015-2019 Lior Halphon
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
Author: Maximilian Mader
|
||||||
|
|
||||||
|
-->
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.22"/>
|
||||||
|
<!-- interface-license-type mit -->
|
||||||
|
<!-- interface-name SameBoy -->
|
||||||
|
<!-- interface-description SameBoy is an open source Game Boy (DMG) and Game Boy Color (CGB) emulator, written in portable C. -->
|
||||||
|
<!-- interface-copyright 2015-2021 Lior Halphon -->
|
||||||
|
<!-- interface-authors Maximilian Mader -->
|
||||||
|
<template class="PrinterWindow">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="resizable">False</property>
|
||||||
|
<property name="default_width">322</property>
|
||||||
|
<property name="default_height">434</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow" id="scrolled_window">
|
||||||
|
<property name="min-content-height">432</property>
|
||||||
|
<property name="max-content-height">432</property>
|
||||||
|
<property name="hexpand">0</property>
|
||||||
|
<property name="vexpand">1</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="shadow_type">in</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkViewport">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="shadow_type">none</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkDrawingArea" id="printer_canvas">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<signal name="draw" handler="on_printer_draw" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child type="titlebar">
|
||||||
|
<object class="GtkHeaderBar">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="title" translatable="yes">Printer</property>
|
||||||
|
<property name="has_subtitle">False</property>
|
||||||
|
<property name="show_close_button">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="printer_save_button">
|
||||||
|
<property name="label">gtk-save</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<signal name="clicked" handler="on_printer_save" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="pack_type">end</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="printer_clear_button">
|
||||||
|
<property name="label">gtk-delete</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<signal name="clicked" handler="on_printer_clear" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="pack_type">end</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</template>
|
||||||
|
</interface>
|
525
gtk3/resources/ui/vram_viewer_window.ui
Normal file
@ -0,0 +1,525 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015-2021 Lior Halphon
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
Author: Maximilian Mader
|
||||||
|
|
||||||
|
-->
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.22"/>
|
||||||
|
<!-- interface-license-type mit -->
|
||||||
|
<!-- interface-name SameBoy -->
|
||||||
|
<!-- interface-description SameBoy is an open source Game Boy (DMG) and Game Boy Color (CGB) emulator, written in portable C. -->
|
||||||
|
<!-- interface-copyright 2015-2021 Lior Halphon -->
|
||||||
|
<!-- interface-authors Maximilian Mader -->
|
||||||
|
<template class="VramViewerWindow">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="title" translatable="yes">VRAM Viewer</property>
|
||||||
|
<property name="resizable">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="margin_top">3</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="spacing">6</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkStackSwitcher">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="margin_start">10</property>
|
||||||
|
<property name="margin_end">10</property>
|
||||||
|
<property name="stack">stack</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkStack" id="stack">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="hhomogeneous">False</property>
|
||||||
|
<property name="vhomogeneous">False</property>
|
||||||
|
<property name="transition_type">slide-left-right</property>
|
||||||
|
<property name="interpolate_size">True</property>
|
||||||
|
<signal name="notify::visible-child" handler="visible_tab_changed" swapped="no"/>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="margin_start">6</property>
|
||||||
|
<property name="margin_end">6</property>
|
||||||
|
<property name="margin_bottom">3</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBoxText" id="tileset_palette_selector">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="active">0</property>
|
||||||
|
<property name="active_id">bg0</property>
|
||||||
|
<items>
|
||||||
|
<item id="bg0" translatable="yes">Background Palette 0</item>
|
||||||
|
<item id="bg1" translatable="yes">Background Palette 1</item>
|
||||||
|
<item id="bg2" translatable="yes">Background Palette 2</item>
|
||||||
|
<item id="bg3" translatable="yes">Background Palette 3</item>
|
||||||
|
<item id="bg4" translatable="yes">Background Palette 4</item>
|
||||||
|
<item id="bg5" translatable="yes">Background Palette 5</item>
|
||||||
|
<item id="bg6" translatable="yes">Background Palette 6</item>
|
||||||
|
<item id="bg7" translatable="yes">Background Palette 7</item>
|
||||||
|
<item translatable="yes"><separator></item>
|
||||||
|
<item id="obj0" translatable="yes">Object Palette 0</item>
|
||||||
|
<item id="obj1" translatable="yes">Object Palette 1</item>
|
||||||
|
<item id="obj2" translatable="yes">Object Palette 2</item>
|
||||||
|
<item id="obj3" translatable="yes">Object Palette 3</item>
|
||||||
|
<item id="obj4" translatable="yes">Object Palette 4</item>
|
||||||
|
<item id="obj5" translatable="yes">Object Palette 5</item>
|
||||||
|
<item id="obj6" translatable="yes">Object Palette 6</item>
|
||||||
|
<item id="obj7" translatable="yes">Object Palette 7</item>
|
||||||
|
</items>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToggleButton" id="tileset_toggle_grid_button">
|
||||||
|
<property name="label" translatable="yes">Grid</property>
|
||||||
|
<property name="width_request">70</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="pack_type">end</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<style>
|
||||||
|
<class name="vram-viewer-button-bar"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkDrawingArea" id="tileset_canvas">
|
||||||
|
<property name="width_request">512</property>
|
||||||
|
<property name="height_request">384</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="app_paintable">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<signal name="draw" handler="draw_tileset_canvas" swapped="no"/>
|
||||||
|
<signal name="motion-notify-event" handler="tileset_canvas_motion" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="name">tileset</property>
|
||||||
|
<property name="title" translatable="yes">Tileset</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="margin_start">6</property>
|
||||||
|
<property name="margin_end">6</property>
|
||||||
|
<property name="spacing">3</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBoxText" id="tilemap_palette_selector">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="active">0</property>
|
||||||
|
<property name="active_id">auto</property>
|
||||||
|
<items>
|
||||||
|
<item id="auto" translatable="yes">Effective Palettes</item>
|
||||||
|
<item translatable="yes"><separator></item>
|
||||||
|
<item id="bg0" translatable="yes">Background Palette 0</item>
|
||||||
|
<item id="bg1" translatable="yes">Background Palette 1</item>
|
||||||
|
<item id="bg2" translatable="yes">Background Palette 2</item>
|
||||||
|
<item id="bg3" translatable="yes">Background Palette 3</item>
|
||||||
|
<item id="bg4" translatable="yes">Background Palette 4</item>
|
||||||
|
<item id="bg5" translatable="yes">Background Palette 5</item>
|
||||||
|
<item id="bg6" translatable="yes">Background Palette 6</item>
|
||||||
|
<item id="bg7" translatable="yes">Background Palette 7</item>
|
||||||
|
<item translatable="yes"><separator></item>
|
||||||
|
<item id="obj0" translatable="yes">Object Palette 0</item>
|
||||||
|
<item id="obj1" translatable="yes">Object Palette 1</item>
|
||||||
|
<item id="obj2" translatable="yes">Object Palette 2</item>
|
||||||
|
<item id="obj3" translatable="yes">Object Palette 3</item>
|
||||||
|
<item id="obj4" translatable="yes">Object Palette 4</item>
|
||||||
|
<item id="obj5" translatable="yes">Object Palette 5</item>
|
||||||
|
<item id="obj6" translatable="yes">Object Palette 6</item>
|
||||||
|
<item id="obj7" translatable="yes">Object Palette 7</item>
|
||||||
|
</items>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBoxText" id="tilemap_tilemap_selector">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="active">0</property>
|
||||||
|
<property name="active_id">auto</property>
|
||||||
|
<items>
|
||||||
|
<item id="auto" translatable="yes">Effective Tilemap</item>
|
||||||
|
<item translatable="yes"><separator></item>
|
||||||
|
<item id="9800" translatable="yes">Tilemap at $9800</item>
|
||||||
|
<item id="9C00" translatable="yes">Tilemap at $9C00</item>
|
||||||
|
</items>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToggleButton" id="tilemap_toggle_grid_button">
|
||||||
|
<property name="label" translatable="yes">Grid</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="margin_start">2</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="pack_type">end</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToggleButton" id="tilemap_toggle_scrolling_button">
|
||||||
|
<property name="label" translatable="yes">Scrolling</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="margin_start">2</property>
|
||||||
|
<property name="margin_end">2</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="pack_type">end</property>
|
||||||
|
<property name="position">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBoxText" id="tilemap_tileset_selector">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="active">0</property>
|
||||||
|
<property name="active_id">auto</property>
|
||||||
|
<items>
|
||||||
|
<item id="auto" translatable="yes">Effective Tileset</item>
|
||||||
|
<item translatable="yes"><separator></item>
|
||||||
|
<item id="8800" translatable="yes">Tileset at $8800</item>
|
||||||
|
<item id="8000" translatable="yes">Tileset at $8000</item>
|
||||||
|
</items>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">4</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<style>
|
||||||
|
<class name="vram-viewer-button-bar"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkDrawingArea" id="tilemap_canvas">
|
||||||
|
<property name="width_request">512</property>
|
||||||
|
<property name="height_request">512</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="app_paintable">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="halign">start</property>
|
||||||
|
<property name="valign">start</property>
|
||||||
|
<property name="hexpand">False</property>
|
||||||
|
<property name="vexpand">False</property>
|
||||||
|
<signal name="draw" handler="draw_tilemap_canvas" swapped="no"/>
|
||||||
|
<signal name="motion-notify-event" handler="tilemap_canvas_motion" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="name">tilemap</property>
|
||||||
|
<property name="title" translatable="yes">Tilemap</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="width_request">512</property>
|
||||||
|
<property name="height_request">512</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="shadow_type">in</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeView" id="sprites">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="headers_clickable">False</property>
|
||||||
|
<property name="enable_search">False</property>
|
||||||
|
<property name="show_expanders">False</property>
|
||||||
|
<child internal-child="selection">
|
||||||
|
<object class="GtkTreeSelection"/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeViewColumn">
|
||||||
|
<property name="min_width">32</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCellRendererPixbuf"/>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="pixbuf">0</attribute>
|
||||||
|
</attributes>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeViewColumn">
|
||||||
|
<property name="title" translatable="yes">X</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCellRendererText"/>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="text">1</attribute>
|
||||||
|
</attributes>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeViewColumn">
|
||||||
|
<property name="title" translatable="yes">Y</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCellRendererText"/>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="text">2</attribute>
|
||||||
|
</attributes>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeViewColumn">
|
||||||
|
<property name="title" translatable="yes">Tile</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCellRendererText"/>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="text">3</attribute>
|
||||||
|
</attributes>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeViewColumn">
|
||||||
|
<property name="title" translatable="yes">Tile Addr.</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCellRendererText"/>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="text">4</attribute>
|
||||||
|
</attributes>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeViewColumn">
|
||||||
|
<property name="title" translatable="yes">OAM Addr.</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCellRendererText"/>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="text">5</attribute>
|
||||||
|
</attributes>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeViewColumn">
|
||||||
|
<property name="title" translatable="yes">Attributes</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCellRendererText"/>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="text">6</attribute>
|
||||||
|
</attributes>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="name">sprites</property>
|
||||||
|
<property name="title" translatable="yes">Sprites</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeView" id="palettes">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="headers_visible">False</property>
|
||||||
|
<property name="headers_clickable">False</property>
|
||||||
|
<property name="enable_search">False</property>
|
||||||
|
<property name="show_expanders">False</property>
|
||||||
|
<style>
|
||||||
|
<class name="monospace"/>
|
||||||
|
</style>
|
||||||
|
<child internal-child="selection">
|
||||||
|
<object class="GtkTreeSelection"/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeViewColumn">
|
||||||
|
<property name="title" translatable="yes">Type</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCellRendererText"/>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="text">0</attribute>
|
||||||
|
</attributes>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeViewColumn">
|
||||||
|
<property name="title" translatable="yes">Color 0</property>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCellRendererText" id="palette_cell_renderer_0"/>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="text">1</attribute>
|
||||||
|
</attributes>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeViewColumn">
|
||||||
|
<property name="title" translatable="yes">Color 1</property>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCellRendererText" id="palette_cell_renderer_1"/>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="text">3</attribute>
|
||||||
|
</attributes>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeViewColumn">
|
||||||
|
<property name="title" translatable="yes">Color 2</property>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCellRendererText" id="palette_cell_renderer_2"/>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="text">5</attribute>
|
||||||
|
</attributes>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeViewColumn">
|
||||||
|
<property name="title" translatable="yes">Color 3</property>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCellRendererText" id="palette_cell_renderer_3"/>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="text">7</attribute>
|
||||||
|
</attributes>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="name">palettes</property>
|
||||||
|
<property name="title" translatable="yes">Palettes</property>
|
||||||
|
<property name="position">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="status">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="margin_bottom">5</property>
|
||||||
|
<property name="justify">center</property>
|
||||||
|
<property name="single_line_mode">True</property>
|
||||||
|
<property name="track_visited_links">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child type="titlebar">
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
</template>
|
||||||
|
</interface>
|
126
gtk3/resources/ui/window.ui
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015-2021 Lior Halphon
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
Author: Maximilian Mader
|
||||||
|
|
||||||
|
-->
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.22"/>
|
||||||
|
<!-- interface-license-type mit -->
|
||||||
|
<!-- interface-name SameBoy -->
|
||||||
|
<!-- interface-description SameBoy is an open source Game Boy (DMG) and Game Boy Color (CGB) emulator, written in portable C. -->
|
||||||
|
<!-- interface-copyright 2015-2021 Lior Halphon -->
|
||||||
|
<!-- interface-authors Maximilian Mader -->
|
||||||
|
<object class="GtkAboutDialog" id="about_dialog">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="type_hint">normal</property>
|
||||||
|
<property name="program_name">SameBoy</property>
|
||||||
|
<property name="copyright" translatable="yes">Copyright © 2015-2021 Lior Halphon</property>
|
||||||
|
<property name="website">https://sameboy.github.io</property>
|
||||||
|
<property name="website_label" translatable="yes">sameboy.github.io</property>
|
||||||
|
<property name="authors">Lior Halphon https://github.com/LIJI32
|
||||||
|
|
||||||
|
GTK3 frontend by
|
||||||
|
Maximilian Mader https://github.com/max-m</property>
|
||||||
|
<property name="logo_icon_name"/>
|
||||||
|
<property name="license_type">mit-x11</property>
|
||||||
|
<child internal-child="vbox">
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="spacing">2</property>
|
||||||
|
<child internal-child="action_area">
|
||||||
|
<object class="GtkButtonBox">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="layout_style">end</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child type="titlebar">
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
|
||||||
|
<object class="GtkWindow" id="memory_viewer">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="title" translatable="yes">Memory Viewer</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Placeholder</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Placeholder</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Placeholder</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child type="titlebar">
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</interface>
|
56
gtk3/sameboy.gresource.xml
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<gresources>
|
||||||
|
<gresource prefix="/io/github/sameboy">
|
||||||
|
<file preprocess="xml-stripblanks" compressed="true">ui/window.ui</file>
|
||||||
|
<file preprocess="xml-stripblanks" compressed="true">ui/about_dialog.ui</file>
|
||||||
|
<file preprocess="xml-stripblanks" compressed="true">ui/main_window.ui</file>
|
||||||
|
<file preprocess="xml-stripblanks" compressed="true">ui/main_menu.ui</file>
|
||||||
|
<file preprocess="xml-stripblanks" compressed="true">ui/console_window.ui</file>
|
||||||
|
<file preprocess="xml-stripblanks" compressed="true">ui/preferences_window.ui</file>
|
||||||
|
<file preprocess="xml-stripblanks" compressed="true">ui/vram_viewer_window.ui</file>
|
||||||
|
<file preprocess="xml-stripblanks" compressed="true">ui/printer_window.ui</file>
|
||||||
|
|
||||||
|
<file compressed="true">css/main.css</file>
|
||||||
|
<file compressed="true" alias="gamecontrollerdb.txt">gamecontrollerdb_d3f1cea1.txt</file>
|
||||||
|
|
||||||
|
<file alias="logo_256.png">pixmaps/logo/logo_256.png</file>
|
||||||
|
<file alias="logo_128.png">pixmaps/logo/logo_128.png</file>
|
||||||
|
<file alias="logo_64.png">pixmaps/logo/logo_64.png</file>
|
||||||
|
<file alias="logo_48.png">pixmaps/logo/logo_48.png</file>
|
||||||
|
<file alias="logo_32.png">pixmaps/logo/logo_32.png</file>
|
||||||
|
<file alias="logo_16.png">pixmaps/logo/logo_16.png</file>
|
||||||
|
|
||||||
|
<!-- Boot ROMs, generated at compile time -->
|
||||||
|
<!-- The file path is a hack to get automatic dependency generation working-->
|
||||||
|
<file compressed="true" alias="bootroms/dmg_boot.bin">gtk3/resources/bootroms/dmg_boot.bin</file>
|
||||||
|
<file compressed="true" alias="bootroms/cgb_boot.bin">gtk3/resources/bootroms/cgb_boot.bin</file>
|
||||||
|
<file compressed="true" alias="bootroms/agb_boot.bin">gtk3/resources/bootroms/agb_boot.bin</file>
|
||||||
|
<file compressed="true" alias="bootroms/sgb_boot.bin">gtk3/resources/bootroms/sgb_boot.bin</file>
|
||||||
|
<file compressed="true" alias="bootroms/sgb2_boot.bin">gtk3/resources/bootroms/sgb2_boot.bin</file>
|
||||||
|
|
||||||
|
<!-- Shaders -->
|
||||||
|
<!-- The file path is a hack to get automatic dependency generation working-->
|
||||||
|
<file compressed="true" alias="Shaders/AAOmniScaleLegacy.fsh">gtk3/resources/Shaders/AAOmniScaleLegacy.fsh</file>
|
||||||
|
<file compressed="true" alias="Shaders/AAScale2x.fsh">gtk3/resources/Shaders/AAScale2x.fsh</file>
|
||||||
|
<file compressed="true" alias="Shaders/AAScale4x.fsh">gtk3/resources/Shaders/AAScale4x.fsh</file>
|
||||||
|
<file compressed="true" alias="Shaders/Bilinear.fsh">gtk3/resources/Shaders/Bilinear.fsh</file>
|
||||||
|
<file compressed="true" alias="Shaders/CRT.fsh">gtk3/resources/Shaders/CRT.fsh</file>
|
||||||
|
<file compressed="true" alias="Shaders/HQ2x.fsh">gtk3/resources/Shaders/HQ2x.fsh</file>
|
||||||
|
<file compressed="true" alias="Shaders/MonoLCD.fsh">gtk3/resources/Shaders/MonoLCD.fsh</file>
|
||||||
|
<file compressed="true" alias="Shaders/LCD.fsh">gtk3/resources/Shaders/LCD.fsh</file>
|
||||||
|
<file compressed="true" alias="Shaders/MasterShader.fsh">gtk3/resources/Shaders/MasterShader.fsh</file>
|
||||||
|
<file compressed="true" alias="Shaders/NearestNeighbor.fsh">gtk3/resources/Shaders/NearestNeighbor.fsh</file>
|
||||||
|
<file compressed="true" alias="Shaders/OmniScale.fsh">gtk3/resources/Shaders/OmniScale.fsh</file>
|
||||||
|
<file compressed="true" alias="Shaders/OmniScaleLegacy.fsh">gtk3/resources/Shaders/OmniScaleLegacy.fsh</file>
|
||||||
|
<file compressed="true" alias="Shaders/Scale2x.fsh">gtk3/resources/Shaders/Scale2x.fsh</file>
|
||||||
|
<file compressed="true" alias="Shaders/Scale4x.fsh">gtk3/resources/Shaders/Scale4x.fsh</file>
|
||||||
|
<file compressed="true" alias="Shaders/SmoothBilinear.fsh">gtk3/resources/Shaders/SmoothBilinear.fsh</file>
|
||||||
|
|
||||||
|
<file compressed="true" alias="Misc/registers.sym">gtk3/resources/Misc/registers.sym</file>
|
||||||
|
|
||||||
|
<file>pixmaps/CPU.png</file>
|
||||||
|
<file>pixmaps/Display.png</file>
|
||||||
|
<file>pixmaps/Joypad.png</file>
|
||||||
|
<file>pixmaps/Speaker.png</file>
|
||||||
|
</gresource>
|
||||||
|
</gresources>
|
396
gtk3/sameboy_application.c
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
#include "sameboy_application.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "widgets/main_window.h"
|
||||||
|
#include "widgets/about_dialog.h"
|
||||||
|
#include "widgets/preferences_window.h"
|
||||||
|
|
||||||
|
#define str(x) #x
|
||||||
|
#define xstr(x) str(x)
|
||||||
|
|
||||||
|
#define action_set_enabled(map, name, value) \
|
||||||
|
g_simple_action_set_enabled( \
|
||||||
|
G_SIMPLE_ACTION( \
|
||||||
|
g_action_map_lookup_action(G_ACTION_MAP(map), name) \
|
||||||
|
), \
|
||||||
|
value \
|
||||||
|
);
|
||||||
|
|
||||||
|
struct _SameBoyApplication {
|
||||||
|
GtkApplication parent;
|
||||||
|
|
||||||
|
struct CliOptionData cli_options;
|
||||||
|
|
||||||
|
const GThread *main_thread;
|
||||||
|
PreferencesWindow *preferences;
|
||||||
|
AboutDialog *about_dialog;
|
||||||
|
|
||||||
|
GDateTime *config_modification_date;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE(SameBoyApplication, sameboy_application, GTK_TYPE_APPLICATION);
|
||||||
|
|
||||||
|
static void sameboy_application_init(SameBoyApplication *app) {
|
||||||
|
g_debug("sameboy_application_init(%p)", app);
|
||||||
|
|
||||||
|
// Define our command line parameters
|
||||||
|
GOptionEntry entries[] = {
|
||||||
|
{ "version", 'v', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, NULL, "Show the application version", NULL },
|
||||||
|
{ "fullscreen", 'f', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &app->cli_options.fullscreen, "Start in fullscreen mode", NULL },
|
||||||
|
{ "bootrom", 'b', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &app->cli_options.boot_rom_path, "Path to the boot ROM to use", "<file path>" },
|
||||||
|
{ "model", 'm', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, NULL, "Override the model type to emulate", "<model type>" },
|
||||||
|
{ "config", 'c', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &app->cli_options.config_path, "Override the path of the configuration file", "<file path>" },
|
||||||
|
{ "no-gl", 's', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &app->cli_options.force_software_renderer, "Do not use OpenGL for rendering", NULL },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Setup our command line information
|
||||||
|
g_application_add_main_option_entries(G_APPLICATION(app), entries);
|
||||||
|
g_application_set_option_context_parameter_string(G_APPLICATION(app), "[FILE…]");
|
||||||
|
g_application_set_option_context_summary(G_APPLICATION(app), "SameBoy is an open source Game Boy (DMG) and Game Boy Color (CGB) emulator.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint sameboy_application_handle_local_options(GApplication *gapp, GVariantDict *options) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(gapp);
|
||||||
|
g_debug("sameboy_application_handle_local_options");
|
||||||
|
|
||||||
|
guint32 count;
|
||||||
|
if (g_variant_dict_lookup(options, "version", "b", &count)) {
|
||||||
|
g_message("SameBoy v" xstr(VERSION));
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle model override
|
||||||
|
GVariant *model_name_var = g_variant_dict_lookup_value(options, "model", G_VARIANT_TYPE_STRING);
|
||||||
|
app->cli_options.model = -1;
|
||||||
|
|
||||||
|
if (model_name_var != NULL) {
|
||||||
|
const gchar *model_name = g_variant_get_string(model_name_var, NULL);
|
||||||
|
|
||||||
|
// TODO: Synchronize with GB_model_t (Core/gb.h)
|
||||||
|
if (g_str_has_prefix(model_name, "DMG")) {
|
||||||
|
if (g_str_has_suffix(model_name, "-B") || g_strcmp0(model_name, "DMG") == 0) {
|
||||||
|
app->cli_options.model = GB_MODEL_DMG_B;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
app->cli_options.model = GB_MODEL_DMG_B;
|
||||||
|
g_warning("Unsupported revision: %s\nFalling back to DMG-B", model_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (g_str_has_prefix(model_name, "SGB")) {
|
||||||
|
if (g_str_has_suffix(model_name, "-NTSC") || g_strcmp0(model_name, "SGB") == 0) {
|
||||||
|
app->cli_options.model = GB_MODEL_SGB;
|
||||||
|
}
|
||||||
|
else if (g_str_has_suffix(model_name, "-PAL")) {
|
||||||
|
app->cli_options.model = GB_MODEL_SGB | GB_MODEL_PAL_BIT;
|
||||||
|
}
|
||||||
|
else if (g_str_has_suffix(model_name, "2")) {
|
||||||
|
app->cli_options.model = GB_MODEL_SGB2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
app->cli_options.model = GB_MODEL_SGB2;
|
||||||
|
g_warning("Unsupported revision: %s\nFalling back to SGB2", model_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (g_str_has_prefix(model_name, "CGB")) {
|
||||||
|
if (g_str_has_suffix(model_name, "-C")) {
|
||||||
|
app->cli_options.model = GB_MODEL_CGB_C;
|
||||||
|
}
|
||||||
|
else if (g_str_has_suffix(model_name, "-E") || g_strcmp0(model_name, "CGB") == 0) {
|
||||||
|
app->cli_options.model = GB_MODEL_CGB_E;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
app->cli_options.model = GB_MODEL_CGB_E;
|
||||||
|
g_warning("Unsupported revision: %s\nFalling back to CGB-E", model_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (g_str_has_prefix(model_name, "AGB")) {
|
||||||
|
app->cli_options.model = GB_MODEL_AGB;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g_warning("Unknown model: %s", model_name);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return G_APPLICATION_CLASS(sameboy_application_parent_class)->handle_local_options(G_APPLICATION(app), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void activate_open(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(user_data);
|
||||||
|
MainWindow *window = SAMEBOY_MAIN_WINDOW(gtk_application_get_active_window(GTK_APPLICATION(app)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void activate_close(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(user_data);
|
||||||
|
MainWindow *window = SAMEBOY_MAIN_WINDOW(gtk_application_get_active_window(GTK_APPLICATION(app)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void activate_reset(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(user_data);
|
||||||
|
MainWindow *window = SAMEBOY_MAIN_WINDOW(gtk_application_get_active_window(GTK_APPLICATION(app)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_pause_changed(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(user_data);
|
||||||
|
MainWindow *window = SAMEBOY_MAIN_WINDOW(gtk_application_get_active_window(GTK_APPLICATION(app)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void activate_show_console(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(user_data);
|
||||||
|
MainWindow *window = SAMEBOY_MAIN_WINDOW(gtk_application_get_active_window(GTK_APPLICATION(app)));
|
||||||
|
main_window_open_console_window(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void activate_open_memory_viewer(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(user_data);
|
||||||
|
MainWindow *window = SAMEBOY_MAIN_WINDOW(gtk_application_get_active_window(GTK_APPLICATION(app)));
|
||||||
|
main_window_open_memory_viewer_window(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void activate_open_vram_viewer(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(user_data);
|
||||||
|
MainWindow *window = SAMEBOY_MAIN_WINDOW(gtk_application_get_active_window(GTK_APPLICATION(app)));
|
||||||
|
main_window_open_vram_viewer_window(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void activate_break_debugger(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(user_data);
|
||||||
|
MainWindow *window = SAMEBOY_MAIN_WINDOW(gtk_application_get_active_window(GTK_APPLICATION(app)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_developer_mode_changed(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(user_data);
|
||||||
|
MainWindow *window = SAMEBOY_MAIN_WINDOW(gtk_application_get_active_window(GTK_APPLICATION(app)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void activate_clear_console(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(user_data);
|
||||||
|
MainWindow *window = SAMEBOY_MAIN_WINDOW(gtk_application_get_active_window(GTK_APPLICATION(app)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void activate_open_gtk_debugger(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
|
||||||
|
gtk_window_set_interactive_debugging(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void activate_quit(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(user_data);
|
||||||
|
MainWindow *window = SAMEBOY_MAIN_WINDOW(gtk_application_get_active_window(GTK_APPLICATION(app)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the global about dialog.
|
||||||
|
*/
|
||||||
|
static void activate_about(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(user_data);
|
||||||
|
gtk_dialog_run(GTK_DIALOG(app->about_dialog));
|
||||||
|
gtk_widget_hide(GTK_WIDGET(app->about_dialog));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the global preferences menu.
|
||||||
|
*/
|
||||||
|
static void activate_preferences(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(user_data);
|
||||||
|
gtk_widget_show_all(GTK_WIDGET(app->preferences));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_mute_changed(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(user_data);
|
||||||
|
MainWindow *window = SAMEBOY_MAIN_WINDOW(gtk_application_get_active_window(GTK_APPLICATION(app)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const GActionEntry file_entries[] = {
|
||||||
|
{ "open", activate_open, NULL, NULL, NULL },
|
||||||
|
{ "close", activate_close, NULL, NULL, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const GActionEntry emulation_entries[] = {
|
||||||
|
{ "reset", activate_reset, NULL, NULL, NULL },
|
||||||
|
{ "pause", NULL, NULL, "false", on_pause_changed },
|
||||||
|
{ "save_state", NULL, NULL, NULL, NULL },
|
||||||
|
{ "load_state", NULL, NULL, NULL, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const GActionEntry developer_entries[] = {
|
||||||
|
{ "show_console", activate_show_console, NULL, NULL, NULL },
|
||||||
|
{ "open_memory_viewer", activate_open_memory_viewer, NULL, NULL, NULL },
|
||||||
|
{ "open_vram_viewer", activate_open_vram_viewer, NULL, NULL, NULL },
|
||||||
|
{ "break_debugger", activate_break_debugger, NULL, NULL, NULL },
|
||||||
|
{ "toggle_developer_mode", NULL, NULL, "false", on_developer_mode_changed },
|
||||||
|
{ "clear_console", activate_clear_console, NULL, NULL, NULL },
|
||||||
|
{ "open_gtk_debugger", activate_open_gtk_debugger, NULL, NULL, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
static GActionEntry app_entries[] = {
|
||||||
|
{ "quit", activate_quit, NULL, NULL, NULL },
|
||||||
|
{ "about", activate_about, NULL, NULL, NULL },
|
||||||
|
{ "preferences", activate_preferences, NULL, NULL, NULL },
|
||||||
|
{ "toggle_mute", NULL, NULL, "false", on_mute_changed },
|
||||||
|
};
|
||||||
|
|
||||||
|
// WHY DO WE NEED SUCH AN UGLY METHOD, GTK?!
|
||||||
|
static void action_entries_set_enabled(SameBoyApplication *app, const GActionEntry *entries, unsigned n_entries, bool value) {
|
||||||
|
// Assumes null-terminated if n_entries == -1
|
||||||
|
for (unsigned i = 0; n_entries == -1 ? entries[i].name != NULL : i < n_entries; i++) {
|
||||||
|
const GActionEntry *entry = &entries[i];
|
||||||
|
if (entry->name == NULL) continue;
|
||||||
|
|
||||||
|
action_set_enabled(app, entry->name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void create_action_groups(SameBoyApplication *app) {
|
||||||
|
g_action_map_add_action_entries(G_ACTION_MAP(app), emulation_entries, G_N_ELEMENTS(emulation_entries), app);
|
||||||
|
g_action_map_add_action_entries(G_ACTION_MAP(app), developer_entries, G_N_ELEMENTS(developer_entries), app);
|
||||||
|
g_action_map_add_action_entries(G_ACTION_MAP(app), app_entries, G_N_ELEMENTS(app_entries), app);
|
||||||
|
g_action_map_add_action_entries(G_ACTION_MAP(app), file_entries, G_N_ELEMENTS(file_entries), app);
|
||||||
|
|
||||||
|
action_set_enabled(app, "close", false);
|
||||||
|
action_entries_set_enabled(app, emulation_entries, G_N_ELEMENTS(emulation_entries), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sameboy_application_startup(GApplication *gapp) {
|
||||||
|
G_APPLICATION_CLASS(sameboy_application_parent_class)->startup(gapp);
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// signal(SIGINT, quit_interrupt);
|
||||||
|
|
||||||
|
g_debug("GTK version %u.%u.%u", gtk_get_major_version(), gtk_get_minor_version(), gtk_get_micro_version());
|
||||||
|
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(gapp);
|
||||||
|
g_debug("sameboy_application_startup");
|
||||||
|
g_debug("config_path: %s", app->cli_options.config_path);
|
||||||
|
g_debug("boot_rom_path: %s", app->cli_options.boot_rom_path);
|
||||||
|
g_debug("fullscreen: %d", app->cli_options.fullscreen);
|
||||||
|
g_debug("model: %d", app->cli_options.model);
|
||||||
|
g_debug("force_software_renderer: %d", app->cli_options.force_software_renderer);
|
||||||
|
|
||||||
|
init_config(G_APPLICATION(app), app->cli_options.config_path, &app->config_modification_date);
|
||||||
|
|
||||||
|
app->preferences = preferences_window_new();
|
||||||
|
app->about_dialog = about_dialog_new();
|
||||||
|
|
||||||
|
gtk_application_add_window(GTK_APPLICATION(gapp), GTK_WINDOW(app->preferences));
|
||||||
|
|
||||||
|
create_action_groups(app);
|
||||||
|
|
||||||
|
#if NDEBUG
|
||||||
|
// Disable when not compiled in debug mode
|
||||||
|
action_set_enabled(app, "open_gtk_debugger", false);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GdkScreen *screen = gdk_screen_get_default();
|
||||||
|
GtkCssProvider *provider = gtk_css_provider_new();
|
||||||
|
gtk_css_provider_load_from_resource(provider, RESOURCE_PREFIX "css/main.css");
|
||||||
|
gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||||
|
|
||||||
|
// Just hide our sub-windows when closing them
|
||||||
|
g_signal_connect(app->preferences, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void open_file(SameBoyApplication *app, GFile *file) {
|
||||||
|
if (file != NULL) {
|
||||||
|
gchar *path = g_file_get_path(file);
|
||||||
|
g_debug("File path: %s", path);
|
||||||
|
g_free(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow *window = main_window_new(SAMEBOY_APPLICATION(app), app->cli_options.force_software_renderer);
|
||||||
|
main_window_setup_menu(window, config.emulation.model);
|
||||||
|
|
||||||
|
// Define a set of window icons
|
||||||
|
GList *icon_list = NULL;
|
||||||
|
static char* icons[] = {
|
||||||
|
RESOURCE_PREFIX "logo_256.png",
|
||||||
|
RESOURCE_PREFIX "logo_128.png",
|
||||||
|
RESOURCE_PREFIX "logo_64.png",
|
||||||
|
RESOURCE_PREFIX "logo_48.png",
|
||||||
|
RESOURCE_PREFIX "logo_32.png",
|
||||||
|
RESOURCE_PREFIX "logo_16.png"
|
||||||
|
};
|
||||||
|
|
||||||
|
GdkPixbuf *icon = gdk_pixbuf_new_from_resource(icons[5], NULL);
|
||||||
|
if (icon) {
|
||||||
|
gtk_window_set_icon(GTK_WINDOW(window), icon);
|
||||||
|
gtk_window_set_default_icon(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create list of GdkPixbufs
|
||||||
|
for (int i = 0; i < (sizeof(icons) / sizeof(const char*)); ++i) {
|
||||||
|
GdkPixbuf *icon = gdk_pixbuf_new_from_resource(icons[i], NULL);
|
||||||
|
if (!icon) continue;
|
||||||
|
|
||||||
|
icon_list = g_list_prepend(icon_list, icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let GTK choose the proper icon
|
||||||
|
gtk_window_set_icon_list(GTK_WINDOW(window), icon_list);
|
||||||
|
gtk_window_set_default_icon_list(icon_list);
|
||||||
|
|
||||||
|
gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(app->about_dialog), gdk_pixbuf_new_from_resource(icons[2], NULL)); // reuse the 64x64 icon
|
||||||
|
gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(app->about_dialog), "v" xstr(VERSION));
|
||||||
|
g_list_free_full(icon_list, g_object_unref);
|
||||||
|
|
||||||
|
if (app->cli_options.fullscreen) {
|
||||||
|
main_window_fullscreen(window, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_window_present(GTK_WINDOW(window));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sameboy_application_activate(GApplication *gapp) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(gapp);
|
||||||
|
g_debug("sameboy_application_activate");
|
||||||
|
|
||||||
|
open_file(app, NULL);
|
||||||
|
|
||||||
|
G_APPLICATION_CLASS(sameboy_application_parent_class)->activate(gapp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sameboy_application_open(GApplication *gapp, GFile **files, int n_files, const char *hint) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(gapp);
|
||||||
|
g_debug("sameboy_application_open(hint = \"%s\")", hint);
|
||||||
|
|
||||||
|
if (n_files >= 1) {
|
||||||
|
if (n_files > 1) {
|
||||||
|
g_warning("More than one file specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
open_file(app, files[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_APPLICATION_CLASS(sameboy_application_parent_class)->open(gapp, files, n_files, hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sameboy_application_shutdown(GApplication *gapp) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(gapp);
|
||||||
|
g_debug("sameboy_application_shutdown");
|
||||||
|
|
||||||
|
G_APPLICATION_CLASS(sameboy_application_parent_class)->shutdown(gapp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sameboy_application_class_init(SameBoyApplicationClass *class) {
|
||||||
|
G_APPLICATION_CLASS(class)->handle_local_options = sameboy_application_handle_local_options;
|
||||||
|
G_APPLICATION_CLASS(class)->startup = sameboy_application_startup;
|
||||||
|
G_APPLICATION_CLASS(class)->activate = sameboy_application_activate;
|
||||||
|
G_APPLICATION_CLASS(class)->open = sameboy_application_open;
|
||||||
|
G_APPLICATION_CLASS(class)->shutdown = sameboy_application_shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
SameBoyApplication *sameboy_application_new(void) {
|
||||||
|
return g_object_new(
|
||||||
|
SAMEBOY_APPLICATION_TYPE,
|
||||||
|
"application-id", APP_ID,
|
||||||
|
// "flags", G_APPLICATION_NON_UNIQUE | G_APPLICATION_HANDLES_OPEN,
|
||||||
|
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sameboy_application_preferences_signal_connect(SameBoyApplication *app, const gchar *detailed_signal, GCallback c_handler, gpointer data) {
|
||||||
|
g_signal_connect(app->preferences, detailed_signal, c_handler, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CliOptionData *sameboy_application_get_cli_options(SameBoyApplication *self) {
|
||||||
|
return &self->cli_options;
|
||||||
|
}
|
20
gtk3/sameboy_application.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef sameboy_application_h
|
||||||
|
#define sameboy_application_h
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <Core/gb.h>
|
||||||
|
|
||||||
|
struct CliOptionData {
|
||||||
|
gchar *config_path;
|
||||||
|
gchar *boot_rom_path;
|
||||||
|
gboolean fullscreen;
|
||||||
|
GB_model_t model;
|
||||||
|
gboolean force_software_renderer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SAMEBOY_APPLICATION_TYPE (sameboy_application_get_type())
|
||||||
|
G_DECLARE_FINAL_TYPE(SameBoyApplication, sameboy_application, SAMEBOY, APPLICATION, GtkApplication)
|
||||||
|
|
||||||
|
SameBoyApplication *sameboy_application_new(void);
|
||||||
|
void sameboy_application_preferences_signal_connect(SameBoyApplication *app, const gchar *detailed_signal, GCallback c_handler, gpointer data);
|
||||||
|
struct CliOptionData *sameboy_application_get_cli_options(SameBoyApplication *self);
|
||||||
|
#endif
|
208
gtk3/shader.c
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
#include "shader.h"
|
||||||
|
|
||||||
|
static const char *vertex_shader = "\n\
|
||||||
|
#version 150 \n\
|
||||||
|
in vec4 aPosition;\n\
|
||||||
|
void main(void) {\n\
|
||||||
|
gl_Position = aPosition;\n\
|
||||||
|
}\n\
|
||||||
|
";
|
||||||
|
|
||||||
|
static GBytes *master_shader_f = NULL;
|
||||||
|
static const gchar *master_shader_code;
|
||||||
|
static gsize master_shader_code_size = 0;
|
||||||
|
|
||||||
|
static GLuint create_shader(const char *source, GLenum type)
|
||||||
|
{
|
||||||
|
// Create the shader object
|
||||||
|
GLuint shader = glCreateShader(type);
|
||||||
|
// Load the shader source
|
||||||
|
glShaderSource(shader, 1, &source, 0);
|
||||||
|
// Compile the shader
|
||||||
|
glCompileShader(shader);
|
||||||
|
// Check for errors
|
||||||
|
GLint status = 0;
|
||||||
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||||
|
if (status == GL_FALSE) {
|
||||||
|
GLchar messages[1024];
|
||||||
|
glGetShaderInfoLog(shader, sizeof(messages), 0, &messages[0]);
|
||||||
|
g_warning("GLSL Shader Error: %s", messages);
|
||||||
|
}
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLuint create_program(const char *vsh, const char *fsh)
|
||||||
|
{
|
||||||
|
// Build shaders
|
||||||
|
GLuint vertex_shader = create_shader(vsh, GL_VERTEX_SHADER);
|
||||||
|
GLuint fragment_shader = create_shader(fsh, GL_FRAGMENT_SHADER);
|
||||||
|
|
||||||
|
// Create program
|
||||||
|
GLuint program = glCreateProgram();
|
||||||
|
|
||||||
|
// Attach shaders
|
||||||
|
glAttachShader(program, vertex_shader);
|
||||||
|
glAttachShader(program, fragment_shader);
|
||||||
|
|
||||||
|
// Link program
|
||||||
|
glLinkProgram(program);
|
||||||
|
// Check for errors
|
||||||
|
GLint status;
|
||||||
|
glGetProgramiv(program, GL_LINK_STATUS, &status);
|
||||||
|
|
||||||
|
if (status == GL_FALSE) {
|
||||||
|
GLchar messages[1024];
|
||||||
|
glGetProgramInfoLog(program, sizeof(messages), 0, &messages[0]);
|
||||||
|
g_warning("GLSL Program Error: %s", messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete shaders
|
||||||
|
glDeleteShader(vertex_shader);
|
||||||
|
glDeleteShader(fragment_shader);
|
||||||
|
|
||||||
|
return program;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool init_shader_with_name(shader_t *shader, const char *name)
|
||||||
|
{
|
||||||
|
if (epoxy_gl_version() < 32) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GError *error = NULL;
|
||||||
|
static char final_shader_code[0x10801] = {0,};
|
||||||
|
static signed long filter_token_location = 0;
|
||||||
|
|
||||||
|
if (!master_shader_code_size) {
|
||||||
|
master_shader_f = g_resources_lookup_data(RESOURCE_PREFIX "Shaders/MasterShader.fsh", G_RESOURCE_LOOKUP_FLAGS_NONE, &error);
|
||||||
|
master_shader_code = g_bytes_get_data(master_shader_f, &master_shader_code_size);
|
||||||
|
|
||||||
|
if (!master_shader_f) {
|
||||||
|
g_warning("Failed to load master shader: %s", error->message);
|
||||||
|
g_error_free(error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
filter_token_location = strstr(master_shader_code, "{filter}") - master_shader_code;
|
||||||
|
|
||||||
|
if (filter_token_location < 0) {
|
||||||
|
g_error_free(error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char shader_path[1024];
|
||||||
|
g_snprintf(shader_path, sizeof(shader_path), RESOURCE_PREFIX "Shaders/%s.fsh", name);
|
||||||
|
|
||||||
|
GBytes *shader_f = g_resources_lookup_data(shader_path, G_RESOURCE_LOOKUP_FLAGS_NONE, &error);
|
||||||
|
if (!shader_f) {
|
||||||
|
g_warning("Failed to load shader \"%s\": %s", shader_path, error->message);
|
||||||
|
g_error_free(error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
gsize shader_code_size;
|
||||||
|
const gchar *shader_code = g_bytes_get_data(shader_f, &shader_code_size);
|
||||||
|
|
||||||
|
memset(final_shader_code, 0, sizeof(final_shader_code));
|
||||||
|
memcpy(final_shader_code, master_shader_code, filter_token_location);
|
||||||
|
strcpy(final_shader_code + filter_token_location, shader_code);
|
||||||
|
strcat(final_shader_code + filter_token_location,
|
||||||
|
master_shader_code + filter_token_location + sizeof("{filter}") - 1);
|
||||||
|
|
||||||
|
g_bytes_unref(shader_f);
|
||||||
|
|
||||||
|
shader->program = create_program(vertex_shader, final_shader_code);
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
shader->position_attribute = glGetAttribLocation(shader->program, "aPosition");
|
||||||
|
// Uniforms
|
||||||
|
shader->resolution_uniform = glGetUniformLocation(shader->program, "output_resolution");
|
||||||
|
shader->origin_uniform = glGetUniformLocation(shader->program, "origin");
|
||||||
|
|
||||||
|
glGenTextures(1, &shader->texture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, shader->texture);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
shader->texture_uniform = glGetUniformLocation(shader->program, "image");
|
||||||
|
|
||||||
|
glGenTextures(1, &shader->previous_texture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, shader->previous_texture);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
shader->previous_texture_uniform = glGetUniformLocation(shader->program, "previous_image");
|
||||||
|
|
||||||
|
shader->blending_mode_uniform = glGetUniformLocation(shader->program, "frame_blending_mode");
|
||||||
|
|
||||||
|
// Program
|
||||||
|
|
||||||
|
glUseProgram(shader->program);
|
||||||
|
|
||||||
|
GLuint vao;
|
||||||
|
glGenVertexArrays(1, &vao);
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
|
||||||
|
GLuint vbo;
|
||||||
|
glGenBuffers(1, &vbo);
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
|
||||||
|
static GLfloat const quad[16] = {
|
||||||
|
-1.f, -1.f, 0, 1,
|
||||||
|
-1.f, +1.f, 0, 1,
|
||||||
|
+1.f, -1.f, 0, 1,
|
||||||
|
+1.f, +1.f, 0, 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW);
|
||||||
|
glEnableVertexAttribArray(shader->position_attribute);
|
||||||
|
glVertexAttribPointer(shader->position_attribute, 4, GL_FLOAT, GL_FALSE, 0, 0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_bitmap_with_shader(shader_t *shader, void *bitmap, void *previous,
|
||||||
|
unsigned source_width, unsigned source_height,
|
||||||
|
unsigned x, unsigned y, unsigned w, unsigned h,
|
||||||
|
GB_frame_blending_mode_t blending_mode)
|
||||||
|
{
|
||||||
|
glUseProgram(shader->program);
|
||||||
|
glUniform2f(shader->origin_uniform, x, y);
|
||||||
|
glUniform2f(shader->resolution_uniform, w, h);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, shader->texture);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, source_width, source_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, bitmap);
|
||||||
|
glUniform1i(shader->texture_uniform, 0);
|
||||||
|
glUniform1i(shader->blending_mode_uniform, previous? blending_mode : GB_FRAME_BLENDING_MODE_DISABLED);
|
||||||
|
if (previous) {
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, shader->previous_texture);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, source_width, source_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, previous);
|
||||||
|
glUniform1i(shader->previous_texture_uniform, 1);
|
||||||
|
}
|
||||||
|
glBindFragDataLocation(shader->program, 0, "frag_color");
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_shader(shader_t *shader)
|
||||||
|
{
|
||||||
|
if (epoxy_gl_version() < 32) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glDeleteProgram(shader->program);
|
||||||
|
glDeleteTextures(1, &shader->texture);
|
||||||
|
glDeleteTextures(1, &shader->previous_texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_master_shader(void) {
|
||||||
|
g_bytes_unref(master_shader_f);
|
||||||
|
master_shader_code_size = 0;
|
||||||
|
}
|
38
gtk3/shader.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef shader_h
|
||||||
|
#define shader_h
|
||||||
|
#include <epoxy/gl.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
typedef struct shader_s {
|
||||||
|
GLuint resolution_uniform;
|
||||||
|
GLuint origin_uniform;
|
||||||
|
GLuint texture_uniform;
|
||||||
|
GLuint previous_texture_uniform;
|
||||||
|
GLuint blending_mode_uniform;
|
||||||
|
|
||||||
|
GLuint position_attribute;
|
||||||
|
GLuint texture;
|
||||||
|
GLuint previous_texture;
|
||||||
|
GLuint program;
|
||||||
|
} shader_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GB_FRAME_BLENDING_MODE_DISABLED,
|
||||||
|
GB_FRAME_BLENDING_MODE_SIMPLE,
|
||||||
|
GB_FRAME_BLENDING_MODE_ACCURATE,
|
||||||
|
GB_FRAME_BLENDING_MODE_ACCURATE_EVEN = GB_FRAME_BLENDING_MODE_ACCURATE,
|
||||||
|
GB_FRAME_BLENDING_MODE_ACCURATE_ODD,
|
||||||
|
} GB_frame_blending_mode_t;
|
||||||
|
|
||||||
|
bool init_shader_with_name(shader_t *shader, const char *name);
|
||||||
|
void render_bitmap_with_shader(shader_t *shader, void *bitmap, void *previous,
|
||||||
|
unsigned source_width, unsigned source_height,
|
||||||
|
unsigned x, unsigned y, unsigned w, unsigned h,
|
||||||
|
GB_frame_blending_mode_t blending_mode);
|
||||||
|
void free_shader(struct shader_s *shader);
|
||||||
|
void free_master_shader(void);
|
||||||
|
|
||||||
|
#endif /* shader_h */
|
116
gtk3/types.h
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
#ifndef types_h
|
||||||
|
#define types_h
|
||||||
|
|
||||||
|
#include "SDL.h"
|
||||||
|
#include "widgets/console_window.h"
|
||||||
|
#include "widgets/main_window.h"
|
||||||
|
#include "widgets/preferences_window.h"
|
||||||
|
#include "widgets/printer_window.h"
|
||||||
|
#include "widgets/vram_viewer_window.h"
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
int16_t x, y;
|
||||||
|
uint16_t width, height;
|
||||||
|
} Rect;
|
||||||
|
|
||||||
|
/*
|
||||||
|
typedef struct GuiData {
|
||||||
|
struct CliOptionData {
|
||||||
|
gchar *config_path;
|
||||||
|
gchar *boot_rom_path;
|
||||||
|
gboolean fullscreen;
|
||||||
|
GB_model_t model;
|
||||||
|
gboolean force_software_renderer;
|
||||||
|
} cli_options;
|
||||||
|
|
||||||
|
GFile *file;
|
||||||
|
gint sample_rate;
|
||||||
|
GDateTime *config_modification_date;
|
||||||
|
|
||||||
|
char *battery_save_path;
|
||||||
|
char *cheats_save_path;
|
||||||
|
|
||||||
|
GB_model_t prev_model;
|
||||||
|
|
||||||
|
const GThread *main_thread;
|
||||||
|
volatile bool running;
|
||||||
|
volatile bool stopping;
|
||||||
|
volatile bool stopped;
|
||||||
|
|
||||||
|
// GTK pointers
|
||||||
|
GtkApplication *main_application;
|
||||||
|
GtkBuilder *builder;
|
||||||
|
MainWindow *main_window;
|
||||||
|
|
||||||
|
ConsoleWindow *console;
|
||||||
|
PreferencesWindow *preferences;
|
||||||
|
VramViewerWindow *vram_viewer;
|
||||||
|
PrinterWindow *printer;
|
||||||
|
GtkWindow *memory_viewer;
|
||||||
|
|
||||||
|
// Audio and video
|
||||||
|
bool audio_initialized;
|
||||||
|
bool border_mode_changed;
|
||||||
|
bool is_fullscreen;
|
||||||
|
unsigned last_screen_width;
|
||||||
|
unsigned last_screen_height;
|
||||||
|
|
||||||
|
// Fast forward / slow motion
|
||||||
|
bool underclock_down;
|
||||||
|
bool rewind_down;
|
||||||
|
bool do_rewind;
|
||||||
|
bool rewind_paused;
|
||||||
|
bool turbo_down;
|
||||||
|
double clock_mutliplier;
|
||||||
|
double analog_clock_multiplier;
|
||||||
|
bool analog_clock_multiplier_valid;
|
||||||
|
|
||||||
|
// Input
|
||||||
|
uint8_t pressed_buttons;
|
||||||
|
struct Controller_t {
|
||||||
|
SDL_GameController *controller;
|
||||||
|
SDL_Haptic *haptic;
|
||||||
|
bool ignore_rumble;
|
||||||
|
} *controllers;
|
||||||
|
unsigned controller_count;
|
||||||
|
struct Controller_t *last_used_controller; // Used for rumble
|
||||||
|
} GuiData;
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
INPUT_UP,
|
||||||
|
INPUT_DOWN,
|
||||||
|
INPUT_LEFT,
|
||||||
|
INPUT_RIGHT,
|
||||||
|
INPUT_A,
|
||||||
|
INPUT_B,
|
||||||
|
INPUT_START,
|
||||||
|
INPUT_SELECT,
|
||||||
|
|
||||||
|
INPUT_TURBO,
|
||||||
|
INPUT_REWIND,
|
||||||
|
INPUT_SLOWDOWN,
|
||||||
|
|
||||||
|
INPUT_FULLSCREEN,
|
||||||
|
} input_names_t;
|
||||||
|
|
||||||
|
static unsigned key_map[] = {
|
||||||
|
[INPUT_UP] = GDK_KEY_w,
|
||||||
|
[INPUT_LEFT] = GDK_KEY_a,
|
||||||
|
[INPUT_DOWN] = GDK_KEY_s,
|
||||||
|
[INPUT_RIGHT] = GDK_KEY_d,
|
||||||
|
|
||||||
|
[INPUT_A] = GDK_KEY_l,
|
||||||
|
[INPUT_B] = GDK_KEY_k,
|
||||||
|
|
||||||
|
[INPUT_START] = GDK_KEY_h,
|
||||||
|
[INPUT_SELECT] = GDK_KEY_g,
|
||||||
|
|
||||||
|
[INPUT_TURBO] = GDK_KEY_space,
|
||||||
|
[INPUT_REWIND] = GDK_KEY_Tab,
|
||||||
|
[INPUT_SLOWDOWN] = GDK_KEY_Shift_L,
|
||||||
|
|
||||||
|
[INPUT_FULLSCREEN] = GDK_KEY_F11,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
173
gtk3/util.c
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
#include "util.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include <epoxy/gl.h>
|
||||||
|
|
||||||
|
// Workaround to figure out if we have proper OpenGL support.
|
||||||
|
// Otherwise the application would crash after our GtkGlArea is realized
|
||||||
|
// and the context it uses is a legacy OpenGL 1.4 context because
|
||||||
|
// GTK3 calls OpenGL 2.0+ functions on it.
|
||||||
|
bool test_gl_support(void) {
|
||||||
|
gboolean result = false;
|
||||||
|
|
||||||
|
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||||
|
g_signal_connect(window, "realize", G_CALLBACK(gl_check_realize), &result);
|
||||||
|
gtk_widget_realize(window);
|
||||||
|
gtk_widget_destroy(window);
|
||||||
|
window = NULL;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The main function for the OpenGL version check workaround
|
||||||
|
void gl_check_realize(GtkWidget *w, gpointer user_data_ptr) {
|
||||||
|
gboolean *result = (gboolean *) user_data_ptr;
|
||||||
|
|
||||||
|
GError *error = NULL;
|
||||||
|
GdkWindow *gdk_window = gtk_widget_get_window(w);
|
||||||
|
GdkGLContext *context = gdk_window_create_gl_context(gdk_window, &error);
|
||||||
|
|
||||||
|
if (error != NULL) {
|
||||||
|
g_warning("Failed to create context: %s", error->message);
|
||||||
|
g_error_free(error);
|
||||||
|
*result = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gdk_gl_context_make_current(context);
|
||||||
|
int version = epoxy_gl_version();
|
||||||
|
|
||||||
|
g_object_run_dispose(G_OBJECT(context));
|
||||||
|
g_object_unref(context);
|
||||||
|
context = NULL;
|
||||||
|
|
||||||
|
gdk_gl_context_clear_current();
|
||||||
|
|
||||||
|
g_debug("OpenGL version: %d", version);
|
||||||
|
|
||||||
|
*result = version >= 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void replace_extension(const char *src, size_t length, char *dest, const char *ext) {
|
||||||
|
memcpy(dest, src, length);
|
||||||
|
dest[length] = 0;
|
||||||
|
|
||||||
|
/* Remove extension */
|
||||||
|
for (size_t i = length; i--;) {
|
||||||
|
if (dest[i] == '/') break;
|
||||||
|
if (dest[i] == '.') {
|
||||||
|
dest[i] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add new extension */
|
||||||
|
strcat(dest, ext);
|
||||||
|
}
|
||||||
|
|
||||||
|
double clamp_double(double min, double max, double value) {
|
||||||
|
if (value < min) return min;
|
||||||
|
if (value > max) return max;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
double max_double(double a, double b) {
|
||||||
|
if (a > b) return a;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
double min_double(double a, double b) {
|
||||||
|
if (a < b) return a;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t convert_color(uint16_t color) {
|
||||||
|
const uint8_t r = ((uint16_t)(color & 0x1F) * 255) / 31;
|
||||||
|
const uint8_t g = ((uint16_t)((color >> 5) & 0x1F) * 255) / 31;
|
||||||
|
const uint8_t b = ((uint16_t)((color >> 10) & 0x1F) * 255) / 31;
|
||||||
|
|
||||||
|
return (r << 16) | (g << 8) | b;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t rgb_encode(GB_gameboy_t *gb, uint8_t r, uint8_t g, uint8_t b) {
|
||||||
|
return 0xFF000000 | (r << 16) | (g << 8) | b;
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *menubar_to_menu(GtkMenuBar *menubar) {
|
||||||
|
GtkWidget *menu = gtk_menu_new();
|
||||||
|
g_autoptr(GList) iter = gtk_container_get_children(GTK_CONTAINER(menubar));
|
||||||
|
|
||||||
|
while (iter) {
|
||||||
|
GtkWidget *item = GTK_WIDGET(iter->data);
|
||||||
|
gtk_widget_reparent(item, menu);
|
||||||
|
iter = iter->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determines if a ComboBox entry should be converted into a separator.
|
||||||
|
// Each element with a text value of `<separator>` will be converted into a separator element.
|
||||||
|
gboolean is_separator(GtkTreeModel *model, GtkTreeIter *iter, gpointer data) {
|
||||||
|
gchar *text = NULL;
|
||||||
|
|
||||||
|
gtk_tree_model_get(model, iter, 0, &text, -1);
|
||||||
|
gboolean result = g_strcmp0("<separator>", text) == 0;
|
||||||
|
g_free(text);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively goes through all children of the given container and sets
|
||||||
|
// our `is_separator` function to all children of type`GtkComboBox`
|
||||||
|
void set_combo_box_row_separator_func(GtkContainer *container) {
|
||||||
|
GList *children = gtk_container_get_children(container);
|
||||||
|
|
||||||
|
for (GList *l = children; l; l = l->next) {
|
||||||
|
if (GTK_IS_COMBO_BOX(l->data)) {
|
||||||
|
gtk_combo_box_set_row_separator_func(GTK_COMBO_BOX(l->data), is_separator, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GTK_IS_CONTAINER(l->data)) {
|
||||||
|
set_combo_box_row_separator_func(GTK_CONTAINER(l->data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free(children);
|
||||||
|
}
|
||||||
|
|
||||||
|
void text_view_scroll_to_bottom(GtkTextView *textview, GtkTextMark *mark) {
|
||||||
|
GtkTextBuffer *buffer = gtk_text_view_get_buffer(textview);
|
||||||
|
GtkTextIter iter;
|
||||||
|
|
||||||
|
gtk_text_buffer_get_end_iter(buffer, &iter);
|
||||||
|
gtk_text_iter_set_line_offset(&iter, 0);
|
||||||
|
|
||||||
|
gtk_text_buffer_move_mark(buffer, mark, &iter);
|
||||||
|
gtk_text_view_scroll_to_mark(textview, mark, 0.0, true, 0.0, 0.10);
|
||||||
|
|
||||||
|
gtk_text_buffer_delete_mark(buffer, mark);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scrolled_window_scroll_to_bottom(GtkScrolledWindow *window) {
|
||||||
|
GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment(window);
|
||||||
|
gtk_adjustment_set_value(adj, gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj));
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar* format_scale_value_pct(GtkScale *scale, gdouble value) {
|
||||||
|
GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(scale));
|
||||||
|
gdouble lower = gtk_adjustment_get_lower(adj);
|
||||||
|
gdouble upper = gtk_adjustment_get_upper(adj);
|
||||||
|
gdouble range = fabs(upper - lower);
|
||||||
|
gdouble pct = ((value + fabs(lower)) / range) * 100.0;
|
||||||
|
return g_strdup_printf ("%.0f%% ", pct);
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar* format_scale_color_temperature(GtkScale *scale, gdouble value) {
|
||||||
|
GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(scale));
|
||||||
|
gdouble lower = gtk_adjustment_get_lower(adj);
|
||||||
|
gdouble upper = gtk_adjustment_get_upper(adj);
|
||||||
|
gdouble range = fabs(upper - lower);
|
||||||
|
gdouble normalized = (value + lower) / range;
|
||||||
|
gdouble kelvin = 12000 + normalized * (12000 - 1000);
|
||||||
|
return g_strdup_printf ("%.0fK ", kelvin);
|
||||||
|
}
|
32
gtk3/util.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef util_h
|
||||||
|
#define util_h
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <Core/gb.h>
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
bool test_gl_support(void);
|
||||||
|
void gl_check_realize(GtkWidget *w, gpointer user_data_ptr);
|
||||||
|
|
||||||
|
void replace_extension(const char *src, size_t length, char *dest, const char *ext);
|
||||||
|
|
||||||
|
double clamp_double(double min, double max, double value);
|
||||||
|
double max_double(double a, double b);
|
||||||
|
double min_double(double a, double b);
|
||||||
|
|
||||||
|
uint32_t convert_color(uint16_t color);
|
||||||
|
uint32_t rgb_encode(GB_gameboy_t *gb, uint8_t r, uint8_t g, uint8_t b);
|
||||||
|
|
||||||
|
GtkWidget *menubar_to_menu(GtkMenuBar *menubar);
|
||||||
|
|
||||||
|
gboolean is_separator(GtkTreeModel *model, GtkTreeIter *iter, gpointer data);
|
||||||
|
void set_combo_box_row_separator_func(GtkContainer *container);
|
||||||
|
|
||||||
|
void text_view_scroll_to_bottom(GtkTextView *textview, GtkTextMark *mark);
|
||||||
|
void scrolled_window_scroll_to_bottom(GtkScrolledWindow *window);
|
||||||
|
|
||||||
|
gchar* format_scale_value_pct(GtkScale *scale, gdouble value);
|
||||||
|
gchar* format_scale_color_temperature(GtkScale *scale, gdouble value);
|
||||||
|
|
||||||
|
#endif
|
19
gtk3/widgets/about_dialog.c
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include "about_dialog.h"
|
||||||
|
|
||||||
|
struct _AboutDialog {
|
||||||
|
GtkMenuBarClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE(AboutDialog, about_dialog, GTK_TYPE_ABOUT_DIALOG);
|
||||||
|
|
||||||
|
static void about_dialog_init(AboutDialog *self) {
|
||||||
|
gtk_widget_init_template(GTK_WIDGET(self));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void about_dialog_class_init(AboutDialogClass *class) {
|
||||||
|
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), RESOURCE_PREFIX "ui/about_dialog.ui");
|
||||||
|
}
|
||||||
|
|
||||||
|
AboutDialog *about_dialog_new() {
|
||||||
|
return g_object_new(ABOUT_DIALOG_TYPE, NULL);
|
||||||
|
}
|
11
gtk3/widgets/about_dialog.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef about_dialog_h
|
||||||
|
#define about_dialog_h
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#define ABOUT_DIALOG_TYPE (about_dialog_get_type())
|
||||||
|
G_DECLARE_FINAL_TYPE(AboutDialog, about_dialog, SAMEBOY, ABOUT_DIALOG, GtkAboutDialog)
|
||||||
|
|
||||||
|
AboutDialog *about_dialog_new();
|
||||||
|
|
||||||
|
#endif
|
530
gtk3/widgets/console_window.c
Normal file
@ -0,0 +1,530 @@
|
|||||||
|
#include "console_window.h"
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
|
struct Selection {
|
||||||
|
gint start;
|
||||||
|
gint end;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _ConsoleWindow {
|
||||||
|
GtkWindowClass parent_class;
|
||||||
|
|
||||||
|
GtkEntry *input;
|
||||||
|
GtkTextView *output;
|
||||||
|
GtkTextView *sidebar_input;
|
||||||
|
GtkTextView *sidebar_output;
|
||||||
|
|
||||||
|
GAsyncQueue *input_queue;
|
||||||
|
GAsyncQueue *output_queue;
|
||||||
|
|
||||||
|
bool should_clear;
|
||||||
|
bool log_to_sidebar;
|
||||||
|
bool clear_sidebar;
|
||||||
|
|
||||||
|
GtkEntryCompletion *command_completion;
|
||||||
|
guint command_history_len;
|
||||||
|
gint command_history_index;
|
||||||
|
|
||||||
|
struct Selection auto_complete_range;
|
||||||
|
uintptr_t auto_complete_context;
|
||||||
|
bool ignore_auto_complete_context_reset;
|
||||||
|
|
||||||
|
bool developer_mode;
|
||||||
|
|
||||||
|
GB_gameboy_t *gb;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE(ConsoleWindow, console_window, GTK_TYPE_WINDOW);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PROP_GB_PTR = 1,
|
||||||
|
|
||||||
|
N_PROPERTIES
|
||||||
|
} ConsoleWindowProperty;
|
||||||
|
|
||||||
|
static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *message;
|
||||||
|
GB_log_attributes attributes;
|
||||||
|
bool sidebar;
|
||||||
|
} AttributedMessage;
|
||||||
|
|
||||||
|
static void console_window_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) {
|
||||||
|
ConsoleWindow *self = (ConsoleWindow *) object;
|
||||||
|
|
||||||
|
switch ((ConsoleWindowProperty) property_id) {
|
||||||
|
case PROP_GB_PTR: self->gb = g_value_get_pointer(value); break;
|
||||||
|
default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void console_window_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) {
|
||||||
|
ConsoleWindow *self = (ConsoleWindow *) object;
|
||||||
|
|
||||||
|
switch ((ConsoleWindowProperty) property_id) {
|
||||||
|
case PROP_GB_PTR: g_value_set_pointer(value, self->gb); break;
|
||||||
|
default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean on_input_key_press(GtkEntry *input, GdkEventKey *event, ConsoleWindow *self) {
|
||||||
|
switch (event->keyval) {
|
||||||
|
case GDK_KEY_Up:
|
||||||
|
if (event->type == GDK_KEY_PRESS) {
|
||||||
|
if (self->command_history_index + 1 == self->command_history_len) {
|
||||||
|
self->command_history_index = self->command_history_len - 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->command_history_index += 1;
|
||||||
|
|
||||||
|
GtkTreeIter iter;
|
||||||
|
GtkTreeModel *model = gtk_entry_completion_get_model(self->command_completion);
|
||||||
|
|
||||||
|
if (!gtk_tree_model_iter_nth_child(model, &iter, NULL, self->command_history_index)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *entry = NULL;
|
||||||
|
gtk_tree_model_get(model, &iter, 0, &entry, -1);
|
||||||
|
gtk_entry_set_text(input, entry);
|
||||||
|
gtk_editable_set_position(GTK_EDITABLE(input), -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GDK_KEY_Down:
|
||||||
|
if (event->type == GDK_KEY_PRESS) {
|
||||||
|
if (self->command_history_index <= 0) {
|
||||||
|
gtk_entry_set_text(input, "");
|
||||||
|
self->command_history_index = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->command_history_index == -1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->command_history_index -= 1;
|
||||||
|
|
||||||
|
GtkTreeIter iter;
|
||||||
|
GtkTreeModel *model = gtk_entry_completion_get_model(self->command_completion);
|
||||||
|
|
||||||
|
if (!gtk_tree_model_iter_nth_child(model, &iter, NULL, self->command_history_index)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *entry = NULL;
|
||||||
|
gtk_tree_model_get(model, &iter, 0, &entry, -1);
|
||||||
|
gtk_entry_set_text(input, entry);
|
||||||
|
gtk_editable_set_position(GTK_EDITABLE(input), -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GDK_KEY_Tab:
|
||||||
|
if (event->type == GDK_KEY_PRESS) {
|
||||||
|
if (self->auto_complete_context == 0) {
|
||||||
|
gint start_pos;
|
||||||
|
gint end_pos;
|
||||||
|
gtk_editable_get_selection_bounds(GTK_EDITABLE(input), &start_pos, &end_pos);
|
||||||
|
|
||||||
|
if (start_pos != end_pos) {
|
||||||
|
self->ignore_auto_complete_context_reset = true;
|
||||||
|
gtk_editable_delete_text(GTK_EDITABLE(input), start_pos, end_pos);
|
||||||
|
self->ignore_auto_complete_context_reset = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->auto_complete_range = (struct Selection){
|
||||||
|
.start = start_pos,
|
||||||
|
.end = start_pos
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *substring = gtk_editable_get_chars(GTK_EDITABLE(input), 0, self->auto_complete_range.start);
|
||||||
|
|
||||||
|
uintptr_t context = self->auto_complete_context;
|
||||||
|
char *completion = GB_debugger_complete_substring(self->gb, substring, &context);
|
||||||
|
g_free(substring);
|
||||||
|
|
||||||
|
if (completion) {
|
||||||
|
self->ignore_auto_complete_context_reset = true;
|
||||||
|
|
||||||
|
gtk_editable_select_region(GTK_EDITABLE(input), self->auto_complete_range.start, self->auto_complete_range.end);
|
||||||
|
gint new_end = self->auto_complete_range.start;
|
||||||
|
gtk_editable_delete_text(GTK_EDITABLE(input), self->auto_complete_range.start, self->auto_complete_range.end);
|
||||||
|
gtk_editable_insert_text(GTK_EDITABLE(input), completion, -1, &new_end);
|
||||||
|
self->auto_complete_range.end = new_end;
|
||||||
|
|
||||||
|
gtk_editable_set_position(GTK_EDITABLE(input), self->auto_complete_range.end);
|
||||||
|
|
||||||
|
self->ignore_auto_complete_context_reset = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g_debug("BEEP (no completion found)");
|
||||||
|
gdk_display_beep(gdk_display_get_default());
|
||||||
|
}
|
||||||
|
|
||||||
|
self->auto_complete_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reset_auto_completion_context(GtkEntry *input, ConsoleWindow *self) {
|
||||||
|
if (self->ignore_auto_complete_context_reset) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->auto_complete_context = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_delete_text(GtkEditable *editable, int start_pos, int end_pos, ConsoleWindow *self) {
|
||||||
|
reset_auto_completion_context(GTK_ENTRY(editable), self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_insert_text(GtkEditable *editable, char*new_text, int new_text_length, gpointer position, ConsoleWindow *self) {
|
||||||
|
reset_auto_completion_context(GTK_ENTRY(editable), self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_move_cursor(GtkEntry *input, GtkMovementStep step, int count, gboolean extend_selection, ConsoleWindow *self) {
|
||||||
|
reset_auto_completion_context(input, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void console_window_init(ConsoleWindow *self) {
|
||||||
|
gtk_widget_init_template(GTK_WIDGET(self));
|
||||||
|
|
||||||
|
GtkTextBuffer *text_buf = gtk_text_view_get_buffer(self->output);
|
||||||
|
GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table(text_buf);
|
||||||
|
|
||||||
|
gtk_text_buffer_create_tag(text_buf, "bold", "weight", PANGO_WEIGHT_BOLD, NULL);
|
||||||
|
gtk_text_buffer_create_tag(text_buf, "underline", "underline", PANGO_UNDERLINE_SINGLE, "underline-set", true, NULL);
|
||||||
|
gtk_text_buffer_create_tag(text_buf, "dashed_underline", "underline", PANGO_UNDERLINE_DOUBLE, "underline-set", true, NULL);
|
||||||
|
|
||||||
|
gtk_text_view_set_buffer(
|
||||||
|
self->sidebar_output,
|
||||||
|
gtk_text_buffer_new(tag_table)
|
||||||
|
);
|
||||||
|
|
||||||
|
gtk_text_buffer_set_text(gtk_text_view_get_buffer(self->sidebar_input), "registers\nbacktrace\n", -1);
|
||||||
|
|
||||||
|
self->input_queue = g_async_queue_new();
|
||||||
|
self->output_queue = g_async_queue_new();
|
||||||
|
self->log_to_sidebar = false;
|
||||||
|
self->clear_sidebar = false;
|
||||||
|
self->command_history_index = -1;
|
||||||
|
|
||||||
|
GtkTreeIter iter;
|
||||||
|
GtkListStore *command_list_store = gtk_list_store_new(1, G_TYPE_STRING);
|
||||||
|
self->command_completion = gtk_entry_completion_new();
|
||||||
|
gtk_entry_completion_set_model(self->command_completion, GTK_TREE_MODEL(command_list_store));
|
||||||
|
gtk_entry_completion_set_text_column(self->command_completion, 0);
|
||||||
|
gtk_entry_completion_set_popup_completion(self->command_completion, false);
|
||||||
|
gtk_entry_completion_set_inline_completion(self->command_completion, false);
|
||||||
|
gtk_entry_set_completion(self->input, self->command_completion);
|
||||||
|
gtk_entry_set_input_hints(self->input, GTK_INPUT_HINT_NO_SPELLCHECK | GTK_INPUT_HINT_NO_EMOJI);
|
||||||
|
|
||||||
|
gtk_widget_add_events(GTK_WIDGET(self), GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
|
||||||
|
|
||||||
|
g_signal_connect(self->input, "key-press-event", G_CALLBACK(on_input_key_press), self);
|
||||||
|
g_signal_connect(self->input, "key-release-event", G_CALLBACK(on_input_key_press), self);
|
||||||
|
g_signal_connect(self->input, "delete-text", G_CALLBACK(on_delete_text), self);
|
||||||
|
g_signal_connect(self->input, "insert-text", G_CALLBACK(on_insert_text), self);
|
||||||
|
g_signal_connect(self->input, "move-cursor", G_CALLBACK(on_move_cursor), self);
|
||||||
|
|
||||||
|
gtk_widget_grab_focus(GTK_WIDGET(self->input));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void console_window_realize(GtkWidget *widget) {
|
||||||
|
ConsoleWindow *self = (ConsoleWindow *)widget;
|
||||||
|
|
||||||
|
GTK_WIDGET_CLASS(console_window_parent_class)->realize(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Takes ownership of message
|
||||||
|
static void log_simple(ConsoleWindow *self, const char *message) {
|
||||||
|
AttributedMessage *attr_msg = g_new(AttributedMessage, 1);
|
||||||
|
attr_msg->message = message;
|
||||||
|
attr_msg->attributes = 0;
|
||||||
|
attr_msg->sidebar = false;
|
||||||
|
|
||||||
|
g_async_queue_push(self->output_queue, attr_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Use command history (arrow key (↑, ↓) events)
|
||||||
|
static void on_input_enter(GtkEntry *input, ConsoleWindow *self) {
|
||||||
|
const gchar *text_ptr = gtk_entry_get_text(input);
|
||||||
|
const gchar *text = NULL;
|
||||||
|
|
||||||
|
GtkTreeModel *model = gtk_entry_completion_get_model(self->command_completion);
|
||||||
|
|
||||||
|
if (g_strcmp0("", text_ptr) == 0) {
|
||||||
|
const char *last = NULL;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
if (gtk_tree_model_get_iter_first(model, &iter)) {
|
||||||
|
gtk_tree_model_get(model, &iter, 0, &last, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last) text = last;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
text = text_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text) {
|
||||||
|
const char *last = NULL;
|
||||||
|
|
||||||
|
GtkTreeIter iter;
|
||||||
|
if (gtk_tree_model_get_iter_first(model, &iter)) {
|
||||||
|
gtk_tree_model_get(model, &iter, 0, &last, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add command to queue unless it was the last command issued
|
||||||
|
if (!last || g_strcmp0(last, text) != 0) {
|
||||||
|
gtk_list_store_prepend(GTK_LIST_STORE(model), &iter);
|
||||||
|
gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, text, -1);
|
||||||
|
self->command_history_len += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_async_queue_push(self->input_queue, (gpointer) g_strdup(text));
|
||||||
|
gtk_entry_set_text(self->input, "");
|
||||||
|
|
||||||
|
self->command_history_index = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_sidebar(ConsoleWindow *self, GB_gameboy_t *gb) {
|
||||||
|
if (!GB_debugger_is_stopped(gb)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkTextBuffer *text_buf = gtk_text_view_get_buffer(self->sidebar_input);
|
||||||
|
gint line_count = gtk_text_buffer_get_line_count(text_buf);
|
||||||
|
|
||||||
|
self->log_to_sidebar = true;
|
||||||
|
self->clear_sidebar = true;
|
||||||
|
|
||||||
|
for (unsigned line = 0; line < line_count; ++line) {
|
||||||
|
GtkTextIter start_iter;
|
||||||
|
GtkTextIter end_iter;
|
||||||
|
gunichar ch;
|
||||||
|
|
||||||
|
gtk_text_buffer_get_iter_at_line(text_buf, &start_iter, line);
|
||||||
|
end_iter = start_iter;
|
||||||
|
|
||||||
|
do {
|
||||||
|
ch = gtk_text_iter_get_char(&end_iter);
|
||||||
|
if (!gtk_text_iter_forward_char(&end_iter)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (ch != '\n');
|
||||||
|
|
||||||
|
gchar *cmd = gtk_text_buffer_get_text(text_buf, &start_iter, &end_iter, false);
|
||||||
|
g_strchug(cmd); // trim leading whitespace
|
||||||
|
g_strchomp(cmd); // trim trailing whitespace
|
||||||
|
|
||||||
|
if (g_strcmp0("", cmd) != 0) {
|
||||||
|
char *duped = g_strdup(cmd);
|
||||||
|
GB_attributed_log(gb, GB_LOG_BOLD, "%s:\n", duped);
|
||||||
|
GB_debugger_execute_command(gb, duped);
|
||||||
|
GB_log(gb, "\n");
|
||||||
|
g_free(duped);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
self->log_to_sidebar = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean console_window_draw(GtkWidget *widget, cairo_t *cr) {
|
||||||
|
ConsoleWindow *self = (ConsoleWindow *)widget;
|
||||||
|
GtkTextBuffer *main_text_buf = gtk_text_view_get_buffer(self->output);
|
||||||
|
GtkTextBuffer *sidebar_text_buf = gtk_text_view_get_buffer(self->sidebar_output);
|
||||||
|
|
||||||
|
if (self->should_clear) {
|
||||||
|
gtk_text_buffer_set_text(main_text_buf, "", -1);
|
||||||
|
gtk_text_buffer_set_text(sidebar_text_buf, "", -1);
|
||||||
|
|
||||||
|
// clear pending log messages
|
||||||
|
while (g_async_queue_try_pop(self->output_queue));
|
||||||
|
|
||||||
|
self->should_clear = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GtkTextIter iter;
|
||||||
|
GtkTextIter start;
|
||||||
|
AttributedMessage *attr_msg = NULL;
|
||||||
|
|
||||||
|
GtkTextIter main_scroll_iter;
|
||||||
|
bool scroll_main = false;
|
||||||
|
|
||||||
|
GtkTextIter sidebar_scroll_iter;
|
||||||
|
bool scroll_sidebar = false;
|
||||||
|
|
||||||
|
if (self->clear_sidebar) {
|
||||||
|
gtk_text_buffer_set_text(sidebar_text_buf, "", -1);
|
||||||
|
self->clear_sidebar = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((attr_msg = g_async_queue_try_pop(self->output_queue))) {
|
||||||
|
GtkTextBuffer *text_buf = attr_msg->sidebar? sidebar_text_buf : main_text_buf;
|
||||||
|
|
||||||
|
gtk_text_buffer_get_end_iter(text_buf, &iter);
|
||||||
|
GtkTextMark *start_mark = gtk_text_buffer_create_mark(text_buf, NULL, &iter, true);
|
||||||
|
|
||||||
|
// give ownership of message to the text buffer
|
||||||
|
gtk_text_buffer_insert(text_buf, &iter, attr_msg->message, -1);
|
||||||
|
gtk_text_buffer_get_iter_at_mark(text_buf, &start, start_mark);
|
||||||
|
|
||||||
|
if (attr_msg->attributes & GB_LOG_BOLD) {
|
||||||
|
gtk_text_buffer_apply_tag_by_name(text_buf, "bold", &start, &iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attr_msg->attributes & GB_LOG_DASHED_UNDERLINE) {
|
||||||
|
gtk_text_buffer_apply_tag_by_name(text_buf, "dashed_underline", &start, &iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attr_msg->attributes & GB_LOG_UNDERLINE) {
|
||||||
|
gtk_text_buffer_apply_tag_by_name(text_buf, "underline", &start, &iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_text_buffer_delete_mark(text_buf, start_mark);
|
||||||
|
|
||||||
|
if (attr_msg->sidebar) {
|
||||||
|
scroll_sidebar = true;
|
||||||
|
sidebar_scroll_iter = iter;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
scroll_main = true;
|
||||||
|
main_scroll_iter = iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(attr_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scroll_main) {
|
||||||
|
text_view_scroll_to_bottom(self->output, gtk_text_buffer_create_mark(main_text_buf, NULL, &main_scroll_iter, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scroll_sidebar) {
|
||||||
|
text_view_scroll_to_bottom(self->sidebar_output, gtk_text_buffer_create_mark(sidebar_text_buf, NULL, &sidebar_scroll_iter, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GTK_WIDGET_CLASS(console_window_parent_class)->draw(widget, cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void console_window_class_init(ConsoleWindowClass *class) {
|
||||||
|
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), RESOURCE_PREFIX "ui/console_window.ui");
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), ConsoleWindow, input);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), ConsoleWindow, output);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), ConsoleWindow, sidebar_input);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), ConsoleWindow, sidebar_output);
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_input_enter);
|
||||||
|
|
||||||
|
GTK_WIDGET_CLASS(class)->realize = console_window_realize;
|
||||||
|
GTK_WIDGET_CLASS(class)->draw = console_window_draw;
|
||||||
|
|
||||||
|
obj_properties[PROP_GB_PTR] = g_param_spec_pointer(
|
||||||
|
"gb", "SameBoy core pointer", "SameBoy Core pointer (GB_gameboy_t)",
|
||||||
|
G_PARAM_CONSTRUCT | G_PARAM_READWRITE
|
||||||
|
);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS(class)->set_property = console_window_set_property;
|
||||||
|
G_OBJECT_CLASS(class)->get_property = console_window_get_property;
|
||||||
|
|
||||||
|
g_object_class_install_properties(G_OBJECT_CLASS(class), N_PROPERTIES, obj_properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsoleWindow *console_window_new(GB_gameboy_t *gb) {
|
||||||
|
return g_object_new(CONSOLE_WINDOW_TYPE, "gb", gb, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function gets called every VBlank while the emulation is running.
|
||||||
|
char *console_window_get_async_input(ConsoleWindow *self, GB_gameboy_t *gb) {
|
||||||
|
self->clear_sidebar = true;
|
||||||
|
|
||||||
|
char *command = (char *)g_async_queue_try_pop(self->input_queue);
|
||||||
|
|
||||||
|
if (command) {
|
||||||
|
gchar *msg = g_strdup_printf("> %s\n", command);
|
||||||
|
log_simple(self, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will only be called if the debugger is in stopped mode (after a breakpoint hit for example),
|
||||||
|
// thus we block the emulation thread until input is available.
|
||||||
|
char *console_window_get_sync_input(ConsoleWindow *self, GB_gameboy_t *gb) {
|
||||||
|
update_sidebar(self, gb);
|
||||||
|
|
||||||
|
char *command = (char *)g_async_queue_pop(self->input_queue);
|
||||||
|
|
||||||
|
if (command) {
|
||||||
|
gchar *msg = g_strdup_printf("> %s\n", command);
|
||||||
|
log_simple(self, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
void console_window_focus(ConsoleWindow *self) {
|
||||||
|
gtk_window_present_with_time(GTK_WINDOW(self), time(NULL));
|
||||||
|
gtk_widget_grab_focus(GTK_WIDGET(self->input));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Queues a message to be logged to the console
|
||||||
|
void console_window_log(ConsoleWindow *self, const char *message, GB_log_attributes attributes) {
|
||||||
|
if (!message || g_str_equal("", message)) return;
|
||||||
|
|
||||||
|
if (self->developer_mode) {
|
||||||
|
console_window_focus(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributedMessage *attr_msg = g_new(AttributedMessage, 1);
|
||||||
|
attr_msg->message = g_strdup(message);
|
||||||
|
attr_msg->attributes = attributes;
|
||||||
|
attr_msg->sidebar = self->log_to_sidebar;
|
||||||
|
|
||||||
|
g_async_queue_push(self->output_queue, attr_msg);
|
||||||
|
|
||||||
|
// mark as dirty
|
||||||
|
gtk_widget_queue_draw(GTK_WIDGET(self));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marks the console as to be cleared on the next redraw
|
||||||
|
void console_window_clear(ConsoleWindow *self) {
|
||||||
|
self->should_clear = true;
|
||||||
|
|
||||||
|
// mark as dirty
|
||||||
|
gtk_widget_queue_draw(GTK_WIDGET(self));
|
||||||
|
}
|
||||||
|
|
||||||
|
void console_window_break_debugger(ConsoleWindow *self, bool forced) {
|
||||||
|
if (!forced && !self->developer_mode) return;
|
||||||
|
|
||||||
|
GB_debugger_break(self->gb);
|
||||||
|
console_window_focus(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hack to avoid deadlocking on queue reads ...
|
||||||
|
void console_window_abort_debugger(ConsoleWindow *self) {
|
||||||
|
g_async_queue_push(self->input_queue, g_strdup("c\0"));
|
||||||
|
g_async_queue_push(self->output_queue, g_strdup("c\0"));
|
||||||
|
console_window_clear(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void console_window_set_developer_mode(ConsoleWindow *self, bool value) {
|
||||||
|
self->developer_mode = value;
|
||||||
|
}
|
20
gtk3/widgets/console_window.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef console_window_h
|
||||||
|
#define console_window_h
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <Core/gb.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define CONSOLE_WINDOW_TYPE (console_window_get_type())
|
||||||
|
G_DECLARE_FINAL_TYPE(ConsoleWindow, console_window, SAMEBOY, CONSOLE_WINDOW, GtkWindow)
|
||||||
|
|
||||||
|
ConsoleWindow *console_window_new(GB_gameboy_t *gb);
|
||||||
|
char *console_window_get_async_input(ConsoleWindow *self, GB_gameboy_t *gb);
|
||||||
|
char *console_window_get_sync_input(ConsoleWindow *self, GB_gameboy_t *gb);
|
||||||
|
void console_window_log(ConsoleWindow *self, const char *message, GB_log_attributes attributes);
|
||||||
|
void console_window_clear(ConsoleWindow *self);
|
||||||
|
void console_window_focus(ConsoleWindow *self);
|
||||||
|
void console_window_break_debugger(ConsoleWindow *self, bool forced);
|
||||||
|
void console_window_abort_debugger(ConsoleWindow *self);
|
||||||
|
void console_window_set_developer_mode(ConsoleWindow *self, bool value);
|
||||||
|
#endif
|
367
gtk3/widgets/gb_screen.c
Normal file
@ -0,0 +1,367 @@
|
|||||||
|
#include "gb_screen.h"
|
||||||
|
#include "../config.h"
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
|
struct _GbScreen {
|
||||||
|
GtkBin parent;
|
||||||
|
|
||||||
|
GtkGLArea *gl_area;
|
||||||
|
|
||||||
|
bool use_gl;
|
||||||
|
shader_t shader;
|
||||||
|
|
||||||
|
uint32_t *image_buffers[3];
|
||||||
|
unsigned char current_buffer;
|
||||||
|
|
||||||
|
unsigned screen_width;
|
||||||
|
unsigned screen_height;
|
||||||
|
|
||||||
|
GB_frame_blending_mode_t blending_mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE(GbScreen, gb_screen, GTK_TYPE_BIN);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PROP_USE_GL = 1,
|
||||||
|
N_PROPERTIES
|
||||||
|
} GbScreenProperty;
|
||||||
|
|
||||||
|
static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
|
||||||
|
|
||||||
|
static void gb_screen_finalize(GObject *object) {
|
||||||
|
GbScreen *self = (GbScreen *) object;
|
||||||
|
|
||||||
|
if (self->image_buffers[0]) g_free(self->image_buffers[0]);
|
||||||
|
if (self->image_buffers[1]) g_free(self->image_buffers[1]);
|
||||||
|
if (self->image_buffers[2]) g_free(self->image_buffers[2]);
|
||||||
|
|
||||||
|
free_shader(&self->shader);
|
||||||
|
free_master_shader();
|
||||||
|
|
||||||
|
G_OBJECT_CLASS(gb_screen_parent_class)->finalize(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gb_screen_get_natural_size(GbScreen *self, gint *natural_width, gint *natural_height, double *scale_x_ptr, double *scale_y_ptr) {
|
||||||
|
int width = gtk_widget_get_allocated_width(GTK_WIDGET(self));
|
||||||
|
int height = gtk_widget_get_allocated_height(GTK_WIDGET(self));
|
||||||
|
|
||||||
|
double scale_x = width / (double)self->screen_width;
|
||||||
|
double scale_y = height / (double)self->screen_height;
|
||||||
|
|
||||||
|
if (config.video.use_integer_scaling) {
|
||||||
|
scale_x = (unsigned)(scale_x);
|
||||||
|
scale_y = (unsigned)(scale_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.video.keep_aspect_ratio) {
|
||||||
|
if (scale_x > scale_y) {
|
||||||
|
scale_x = scale_y;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
scale_y = scale_x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scale_x = max_double(1.0, scale_x);
|
||||||
|
scale_y = max_double(1.0, scale_y);
|
||||||
|
|
||||||
|
if (natural_width) *natural_width = self->screen_width * scale_x;
|
||||||
|
if (natural_height) *natural_height = self->screen_height * scale_y;
|
||||||
|
if (scale_x_ptr) *scale_x_ptr = scale_x;
|
||||||
|
if (scale_y_ptr) *scale_y_ptr = scale_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gb_screen_calculate_viewport(GbScreen *self, Rect *viewport_ptr, gint *scaled_width_ptr, gint *scaled_height_ptr, double *scale_x_ptr, double *scale_y_ptr) {
|
||||||
|
gint scaled_width, scaled_height;
|
||||||
|
double scale_x, scale_y;
|
||||||
|
|
||||||
|
GtkWidget *widget = GTK_WIDGET(self);
|
||||||
|
int width = gtk_widget_get_allocated_width(widget);
|
||||||
|
int height = gtk_widget_get_allocated_height(widget);
|
||||||
|
gb_screen_get_natural_size(self, &scaled_width, &scaled_height, &scale_x, &scale_y);
|
||||||
|
|
||||||
|
if (viewport_ptr) {
|
||||||
|
*viewport_ptr = (Rect){
|
||||||
|
(width - scaled_width) / 2,
|
||||||
|
(height - scaled_height) / 2,
|
||||||
|
scaled_width,
|
||||||
|
scaled_height
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (scaled_width_ptr) *scaled_width_ptr = scaled_width;
|
||||||
|
if (scaled_height_ptr) *scaled_height_ptr = scaled_height;
|
||||||
|
if (scale_x_ptr) *scale_x_ptr = scale_x;
|
||||||
|
if (scale_y_ptr) *scale_y_ptr = scale_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean gb_screen_draw(GtkWidget *widget, cairo_t *cr) {
|
||||||
|
GbScreen *self = (GbScreen *)widget;
|
||||||
|
|
||||||
|
if (!self->use_gl) {
|
||||||
|
int width = gtk_widget_get_allocated_width(widget);
|
||||||
|
int height = gtk_widget_get_allocated_height(widget);
|
||||||
|
|
||||||
|
GtkStyleContext *context = gtk_widget_get_style_context(widget);
|
||||||
|
gtk_render_background(context, cr, 0, 0, width, height);
|
||||||
|
gtk_render_frame(context, cr, 0, 0, width, height);
|
||||||
|
|
||||||
|
Rect viewport;
|
||||||
|
double scale_x, scale_y;
|
||||||
|
gb_screen_calculate_viewport(self, &viewport, NULL, NULL, &scale_x, &scale_y);
|
||||||
|
|
||||||
|
cairo_surface_t *surface = cairo_image_surface_create_for_data(
|
||||||
|
(unsigned char *) gb_screen_get_current_buffer(self),
|
||||||
|
CAIRO_FORMAT_RGB24,
|
||||||
|
self->screen_width,
|
||||||
|
self->screen_height,
|
||||||
|
cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, self->screen_width)
|
||||||
|
);
|
||||||
|
|
||||||
|
cairo_translate(cr, viewport.x, viewport.y);
|
||||||
|
cairo_scale(cr, scale_x, scale_y);
|
||||||
|
cairo_set_source_surface(cr, surface, 0, 0);
|
||||||
|
cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
|
||||||
|
cairo_paint(cr);
|
||||||
|
|
||||||
|
cairo_surface_destroy(surface);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GTK_WIDGET_CLASS(gb_screen_parent_class)->draw(widget, cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gb_screen_get_preferred_width(GtkWidget *widget, gint *minimum_width, gint *natural_width) {
|
||||||
|
GbScreen *self = (GbScreen *)widget;
|
||||||
|
|
||||||
|
*minimum_width = self->screen_width;
|
||||||
|
gb_screen_get_natural_size(self, natural_width, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gb_screen_get_preferred_height(GtkWidget *widget, gint *minimum_height, gint *natural_height) {
|
||||||
|
GbScreen *self = (GbScreen *)widget;
|
||||||
|
|
||||||
|
*minimum_height = self->screen_height;
|
||||||
|
gb_screen_get_natural_size(self, NULL, natural_height, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gb_screen_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) {
|
||||||
|
GbScreen *self = (GbScreen *) object;
|
||||||
|
|
||||||
|
switch ((GbScreenProperty) property_id) {
|
||||||
|
case PROP_USE_GL:
|
||||||
|
self->use_gl = g_value_get_boolean(value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gb_screen_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) {
|
||||||
|
GbScreen *self = (GbScreen *) object;
|
||||||
|
|
||||||
|
switch ((GbScreenProperty) property_id) {
|
||||||
|
case PROP_USE_GL:
|
||||||
|
g_value_set_boolean(value, self->use_gl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gb_screen_gl_area_render(GtkGLArea *gl_area, GdkGLContext *context, GObject *object) {
|
||||||
|
GbScreen *self = (GbScreen *)object;
|
||||||
|
|
||||||
|
Rect viewport;
|
||||||
|
gint scaled_width, scaled_height;
|
||||||
|
gb_screen_calculate_viewport(self, &viewport, &scaled_width, &scaled_height, NULL, NULL);
|
||||||
|
|
||||||
|
glViewport(viewport.x, viewport.y, scaled_width, scaled_height);
|
||||||
|
|
||||||
|
uint32_t *pixels = gb_screen_get_current_buffer(self);
|
||||||
|
uint32_t *previous = gb_screen_get_previous_buffer(self);
|
||||||
|
|
||||||
|
static void *_pixels = NULL;
|
||||||
|
|
||||||
|
if (pixels) {
|
||||||
|
_pixels = pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
glClearColor(0, 0, 0, 1);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
render_bitmap_with_shader(
|
||||||
|
&self->shader, _pixels, previous,
|
||||||
|
self->screen_width, self->screen_height,
|
||||||
|
viewport.x, viewport.y, viewport.width, viewport.height,
|
||||||
|
self->blending_mode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gb_screen_gl_area_realized(GtkWidget *widget, GObject *object) {
|
||||||
|
GbScreen *self = (GbScreen *)object;
|
||||||
|
GtkGLArea *gl_area = GTK_GL_AREA(widget);
|
||||||
|
|
||||||
|
g_debug("GL Context: %p", gtk_gl_area_get_context(self->gl_area));
|
||||||
|
|
||||||
|
gtk_gl_area_make_current(self->gl_area);
|
||||||
|
if (gtk_gl_area_get_error(self->gl_area) != NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *renderer = (char *)glGetString(GL_RENDERER);
|
||||||
|
g_debug("GtkGLArea on %s", renderer ? renderer : "Unknown");
|
||||||
|
|
||||||
|
if (config.video.shader == NULL || (!init_shader_with_name(&self->shader, config.video.shader) && !init_shader_with_name(&self->shader, "NearestNeighbor"))) {
|
||||||
|
GError *error = g_error_new_literal(g_quark_from_string("sameboy-gl-error"), 1, "Failed to initialize shaders");
|
||||||
|
gtk_gl_area_set_error(self->gl_area, error);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g_info("Using OpenGL for rendering");
|
||||||
|
G_OBJECT_CLASS(gb_screen_parent_class)->constructed(object);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (gtk_gl_area_get_error(self->gl_area) != NULL) {
|
||||||
|
g_warning("GtkGLArea: %s", gtk_gl_area_get_error(self->gl_area)->message);
|
||||||
|
}
|
||||||
|
gtk_widget_destroy(GTK_WIDGET(self->gl_area));
|
||||||
|
self->gl_area = NULL;
|
||||||
|
self->use_gl = false;
|
||||||
|
|
||||||
|
g_info("Using Cairo for rendering");
|
||||||
|
G_OBJECT_CLASS(gb_screen_parent_class)->constructed(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gb_screen_constructed(GObject *object) {
|
||||||
|
GbScreen *self = (GbScreen *)object;
|
||||||
|
|
||||||
|
// Very ugly workaround for GtkGlArea!
|
||||||
|
// When a GtkGlArea is realized and it creates a legacy GL 1.4 context
|
||||||
|
// it tries to use GL 2.0 functions to render the window which leads to the application crashing.
|
||||||
|
// So we initialize GTK, create a dummy GtkWindow object, attach a `realize` callback and
|
||||||
|
// in this callback create a GdkGLContext on this window. But instead of running the GTK main loop
|
||||||
|
// we just realize and destroy the dummy window and compare the context’s version in the realize callback.
|
||||||
|
self->use_gl = self->use_gl && test_gl_support();
|
||||||
|
|
||||||
|
if (self->use_gl) {
|
||||||
|
self->gl_area = GTK_GL_AREA(gtk_gl_area_new());
|
||||||
|
g_signal_connect(self->gl_area, "realize", G_CALLBACK(gb_screen_gl_area_realized), object);
|
||||||
|
g_signal_connect(self->gl_area, "render", G_CALLBACK(gb_screen_gl_area_render), object);
|
||||||
|
|
||||||
|
gtk_gl_area_set_required_version(self->gl_area, 3, 2);
|
||||||
|
gtk_gl_area_set_auto_render(self->gl_area, false);
|
||||||
|
gtk_gl_area_set_has_alpha(self->gl_area, false);
|
||||||
|
gtk_gl_area_set_has_depth_buffer(self->gl_area, false);
|
||||||
|
gtk_gl_area_set_has_stencil_buffer(self->gl_area, false);
|
||||||
|
gtk_container_add(GTK_CONTAINER(self), GTK_WIDGET(self->gl_area));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g_info("Using Cairo for rendering");
|
||||||
|
G_OBJECT_CLASS(gb_screen_parent_class)->constructed(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gb_screen_class_init(GbScreenClass *class) {
|
||||||
|
obj_properties[PROP_USE_GL] = g_param_spec_boolean(
|
||||||
|
"use-gl", "Use OpenGL", "Whether to use OpenGL for rendering.",
|
||||||
|
true,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE
|
||||||
|
);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS(class)->finalize = gb_screen_finalize;
|
||||||
|
G_OBJECT_CLASS(class)->set_property = gb_screen_set_property;
|
||||||
|
G_OBJECT_CLASS(class)->get_property = gb_screen_get_property;
|
||||||
|
G_OBJECT_CLASS(class)->constructed = gb_screen_constructed;
|
||||||
|
|
||||||
|
GTK_WIDGET_CLASS(class)->draw = gb_screen_draw;
|
||||||
|
GTK_WIDGET_CLASS(class)->get_preferred_width = gb_screen_get_preferred_width;
|
||||||
|
GTK_WIDGET_CLASS(class)->get_preferred_height = gb_screen_get_preferred_height;
|
||||||
|
|
||||||
|
g_object_class_install_properties(G_OBJECT_CLASS(class), N_PROPERTIES, obj_properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gb_screen_init(GbScreen *self) {
|
||||||
|
gb_screen_set_resolution(self, 160, 144);
|
||||||
|
gb_screen_clear(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
GbScreen *gb_screen_new(bool force_fallback) {
|
||||||
|
return g_object_new(GB_SCREEN_TYPE, "use-gl", !force_fallback, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gb_screen_clear(GbScreen *self) {
|
||||||
|
for (unsigned i = 0; i < 3; i++) {
|
||||||
|
memset(self->image_buffers[i], 0, self->screen_width * self->screen_height * sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gb_screen_uses_fallback(GbScreen *self) {
|
||||||
|
return !self->use_gl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determines how many frame buffers to use
|
||||||
|
static uint8_t number_of_buffers(GbScreen *self) {
|
||||||
|
if (!self->use_gl) return 2;
|
||||||
|
|
||||||
|
bool should_blend = config_get_frame_blending_mode() != GB_FRAME_BLENDING_MODE_DISABLED;
|
||||||
|
|
||||||
|
return should_blend? 3 : 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the buffer that should be used by the Core to render a new frame to
|
||||||
|
uint32_t *gb_screen_get_pixels(GbScreen *self) {
|
||||||
|
return self->image_buffers[(self->current_buffer + 1) % number_of_buffers(self)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the current finished frame
|
||||||
|
uint32_t *gb_screen_get_current_buffer(GbScreen *self) {
|
||||||
|
return self->image_buffers[self->current_buffer];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the previous finished frame
|
||||||
|
uint32_t *gb_screen_get_previous_buffer(GbScreen *self) {
|
||||||
|
return self->image_buffers[(self->current_buffer + 2) % number_of_buffers(self)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cycles the buffers
|
||||||
|
void gb_screen_flip(GbScreen *self) {
|
||||||
|
self->current_buffer = (self->current_buffer + 1) % number_of_buffers(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gb_screen_set_resolution(GbScreen *self, unsigned width, unsigned height) {
|
||||||
|
self->screen_width = width;
|
||||||
|
self->screen_height = height;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < 3; i++) {
|
||||||
|
self->image_buffers[i] = g_realloc_n(
|
||||||
|
self->image_buffers[i],
|
||||||
|
self->screen_width * self->screen_height, sizeof(uint32_t)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_queue_resize(GTK_WIDGET(self));
|
||||||
|
}
|
||||||
|
|
||||||
|
void gb_screen_set_blending_mode(GbScreen *self, GB_frame_blending_mode_t mode) {
|
||||||
|
self->blending_mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gb_screen_set_shader(GbScreen *self, const char *shader_name) {
|
||||||
|
if (!self->use_gl) return;
|
||||||
|
|
||||||
|
free_shader(&self->shader);
|
||||||
|
init_shader_with_name(&self->shader, shader_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gb_screen_queue_render(GbScreen *self) {
|
||||||
|
if (self->use_gl) {
|
||||||
|
gtk_gl_area_queue_render(self->gl_area);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_queue_draw(GTK_WIDGET(self));
|
||||||
|
}
|
26
gtk3/widgets/gb_screen.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef gb_screen_h
|
||||||
|
#define gb_screen_h
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <Core/gb.h>
|
||||||
|
#include "../shader.h"
|
||||||
|
|
||||||
|
#define GB_SCREEN_TYPE (gb_screen_get_type())
|
||||||
|
G_DECLARE_FINAL_TYPE(GbScreen, gb_screen, SAMEBOY, GB_SCREEN, GtkBin)
|
||||||
|
|
||||||
|
GbScreen *gb_screen_new(bool force_fallback);
|
||||||
|
void gb_screen_clear(GbScreen *self);
|
||||||
|
bool gb_screen_uses_fallback(GbScreen *self);
|
||||||
|
|
||||||
|
uint32_t *gb_screen_get_pixels(GbScreen *self);
|
||||||
|
uint32_t *gb_screen_get_current_buffer(GbScreen *self);
|
||||||
|
uint32_t *gb_screen_get_previous_buffer(GbScreen *self);
|
||||||
|
void gb_screen_flip(GbScreen *self);
|
||||||
|
void gb_screen_set_resolution(GbScreen *self, unsigned width, unsigned height);
|
||||||
|
void gb_screen_set_blending_mode(GbScreen *self, GB_frame_blending_mode_t mode);
|
||||||
|
void gb_screen_set_shader(GbScreen *self, const char *shader_name);
|
||||||
|
void gb_screen_queue_render(GbScreen *self);
|
||||||
|
|
||||||
|
#endif
|
91
gtk3/widgets/main_menu.c
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#include "main_menu.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "gb_screen.h"
|
||||||
|
#include "main_window.h"
|
||||||
|
#include "../check_menu_radio_group.h"
|
||||||
|
|
||||||
|
struct _MainMenu {
|
||||||
|
GtkMenuBar parent_instance;
|
||||||
|
GtkMenuBarClass parent_class;
|
||||||
|
|
||||||
|
GtkSeparatorMenuItem *before_model_changer;
|
||||||
|
GtkMenu *link_menu;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE(MainMenu, main_menu, GTK_TYPE_MENU_BAR);
|
||||||
|
|
||||||
|
static void main_menu_init(MainMenu *self) {
|
||||||
|
gtk_widget_init_template(GTK_WIDGET(self));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void main_menu_class_init(MainMenuClass *class) {
|
||||||
|
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), RESOURCE_PREFIX "ui/main_menu.ui");
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), MainMenu, before_model_changer);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), MainMenu, link_menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainMenu *main_menu_new() {
|
||||||
|
return g_object_new(MAIN_MENU_TYPE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create our application’s menu.
|
||||||
|
//
|
||||||
|
// This function tries to stick to the desktop environment’s conventions.
|
||||||
|
// For the GNOME Shell it uses a hamburger menu, otherwise it either lets
|
||||||
|
// the desktop environment shell handle the menu if it signals support for it
|
||||||
|
// or uses a standard menubar inside the menu.
|
||||||
|
void main_menu_setup( MainMenu *self
|
||||||
|
, char *model_string
|
||||||
|
, MainWindow *main_window
|
||||||
|
, bool (*on_change_model)(GtkWidget *, GtkWidget *, gpointer)
|
||||||
|
, bool (*on_change_linked_device)(GtkWidget *, GtkWidget *, gpointer)
|
||||||
|
) {
|
||||||
|
// Creating these items in the UI defintion files was buggy in some desktop
|
||||||
|
// environments and the manual call of `g_signal_connect` was needed anyway
|
||||||
|
// because the UI definition can’t define string arguments for signal handlers.
|
||||||
|
static const char *const model_names[] = {
|
||||||
|
"Game Boy",
|
||||||
|
"Super Game Boy",
|
||||||
|
"Game Boy Color",
|
||||||
|
"Game Boy Advance",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *const model_codes[] = {
|
||||||
|
"DMG",
|
||||||
|
"SGB",
|
||||||
|
"CGB",
|
||||||
|
"GBA",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
// Find the menu item index of the previous sibling of the new menu items
|
||||||
|
GtkContainer *parent = GTK_CONTAINER(gtk_widget_get_parent(GTK_WIDGET(self->before_model_changer)));
|
||||||
|
g_autoptr(GList) list = gtk_container_get_children(parent);
|
||||||
|
gint position = g_list_index(list, self->before_model_changer);
|
||||||
|
|
||||||
|
CheckMenuItemGroup *model_group = check_menu_item_group_new(GTK_WIDGET(main_window), (char **) model_names, (char **) model_codes);
|
||||||
|
check_menu_item_group_insert_into_menu_shell(model_group, GTK_MENU_SHELL(parent), position + 1);
|
||||||
|
check_menu_item_group_connect_toggle_signal(model_group, on_change_model);
|
||||||
|
check_menu_item_group_activate(model_group, model_string);
|
||||||
|
|
||||||
|
static const char *const peripheral_names[] = {
|
||||||
|
"None",
|
||||||
|
"Game Boy Printer",
|
||||||
|
"WorkBoy",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *const peripheral_codes[] = {
|
||||||
|
"NONE",
|
||||||
|
"PRINTER",
|
||||||
|
"WORKBOY",
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
CheckMenuItemGroup *link_group = check_menu_item_group_new(GTK_WIDGET(main_window), (char **) peripheral_names, (char **) peripheral_codes);
|
||||||
|
check_menu_item_group_insert_into_menu_shell(link_group, GTK_MENU_SHELL(self->link_menu), 0);
|
||||||
|
check_menu_item_group_connect_toggle_signal(link_group, on_change_linked_device);
|
||||||
|
check_menu_item_group_activate(link_group, "NONE");
|
||||||
|
}
|
19
gtk3/widgets/main_menu.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef main_menu_h
|
||||||
|
#define main_menu_h
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <Core/gb.h>
|
||||||
|
#include "main_window.h"
|
||||||
|
|
||||||
|
#define MAIN_MENU_TYPE (main_menu_get_type())
|
||||||
|
G_DECLARE_FINAL_TYPE(MainMenu, main_menu, SAMEBOY, MAIN_MENU, GtkMenuBar)
|
||||||
|
|
||||||
|
MainMenu *main_menu_new();
|
||||||
|
void main_menu_setup( MainMenu *self
|
||||||
|
, char *model_string
|
||||||
|
, MainWindow *main_window
|
||||||
|
, bool (*on_change_model)(GtkWidget *, GtkWidget *, gpointer)
|
||||||
|
, bool (*on_change_linked_device)(GtkWidget *, GtkWidget *, gpointer)
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
582
gtk3/widgets/main_window.c
Normal file
@ -0,0 +1,582 @@
|
|||||||
|
#include "main_window.h"
|
||||||
|
#include <Core/gb.h>
|
||||||
|
|
||||||
|
#include "../../SDL/audio/audio.h"
|
||||||
|
#include "../config.h"
|
||||||
|
#include "gb_screen.h"
|
||||||
|
#include "main_menu.h"
|
||||||
|
#include "console_window.h"
|
||||||
|
#include "printer_window.h"
|
||||||
|
#include "preferences_window.h"
|
||||||
|
#include "vram_viewer_window.h"
|
||||||
|
|
||||||
|
struct _MainWindow {
|
||||||
|
GtkApplicationWindowClass parent_class;
|
||||||
|
|
||||||
|
// Child nodes
|
||||||
|
GtkBox *container;
|
||||||
|
GbScreen *screen;
|
||||||
|
MainMenu *main_menu;
|
||||||
|
|
||||||
|
bool force_software_renderer;
|
||||||
|
|
||||||
|
// The local SameBoy core instance
|
||||||
|
GB_gameboy_t *gb;
|
||||||
|
unsigned sample_rate;
|
||||||
|
bool running; // Indicates that the emulation thread is running
|
||||||
|
bool stopping; // Indicates that the emulation thread is about to be stopped
|
||||||
|
|
||||||
|
GFile *file;
|
||||||
|
char *battery_save_path;
|
||||||
|
char *cheats_save_path;
|
||||||
|
|
||||||
|
// Fast forward / slow motion
|
||||||
|
bool underclock_down;
|
||||||
|
bool rewind_down;
|
||||||
|
bool do_rewind;
|
||||||
|
bool rewind_paused;
|
||||||
|
bool turbo_down;
|
||||||
|
double clock_mutliplier;
|
||||||
|
double analog_clock_multiplier;
|
||||||
|
bool analog_clock_multiplier_valid;
|
||||||
|
|
||||||
|
// Local sub-windows
|
||||||
|
ConsoleWindow *console;
|
||||||
|
GtkWindow *memory_viewer; // TODO
|
||||||
|
PrinterWindow *printer;
|
||||||
|
VramViewerWindow *vram_viewer;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE(MainWindow, main_window, GTK_TYPE_APPLICATION_WINDOW);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PROP_FORCE_SOFTWARE_RENDERER = 1,
|
||||||
|
|
||||||
|
N_PROPERTIES
|
||||||
|
} MainWindowProperty;
|
||||||
|
|
||||||
|
static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
|
||||||
|
|
||||||
|
#define perform_atomic(self, block) { \
|
||||||
|
while (!GB_is_inited(self->gb)); \
|
||||||
|
bool was_running = self->running && !GB_debugger_is_stopped(self->gb); \
|
||||||
|
if (was_running) { main_window_stop(self); } \
|
||||||
|
block; \
|
||||||
|
if (was_running) { main_window_start(self); } \
|
||||||
|
}
|
||||||
|
|
||||||
|
static void main_window_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) {
|
||||||
|
MainWindow *self = (MainWindow *) object;
|
||||||
|
|
||||||
|
switch ((MainWindowProperty) property_id) {
|
||||||
|
case PROP_FORCE_SOFTWARE_RENDERER: self->force_software_renderer = g_value_get_boolean(value); break;
|
||||||
|
default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void main_window_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) {
|
||||||
|
MainWindow *self = (MainWindow *) object;
|
||||||
|
|
||||||
|
switch ((MainWindowProperty) property_id) {
|
||||||
|
case PROP_FORCE_SOFTWARE_RENDERER: g_value_set_boolean(value, self->force_software_renderer); break;
|
||||||
|
default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_update_color_correction(PreferencesWindow *pref, const GB_color_correction_mode_t mode, MainWindow *self) {
|
||||||
|
g_debug("on_update_color_correction(%d)", mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_update_video_color_temperature(PreferencesWindow *pref, const gint light_temperature, MainWindow *self) {
|
||||||
|
g_debug("on_update_video_color_temperature(%d)", light_temperature);
|
||||||
|
|
||||||
|
if (GB_is_inited(self->gb)) {
|
||||||
|
// wouldn’t it be nice to use the value set in the GtkAdjustment of the slider instead of 256.0 here?
|
||||||
|
GB_set_light_temperature(self->gb, (double) light_temperature / 256.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_update_monochrome_palette(PreferencesWindow *pref, const GB_palette_t *palette, MainWindow *self) {
|
||||||
|
g_debug(
|
||||||
|
"on_update_monochrome_palette(\n\trgb(%d, %d, %d),\n\trgb(%d, %d, %d),\n\trgb(%d, %d, %d),\n\trgb(%d, %d, %d),\n\trgb(%d, %d, %d)\n)",
|
||||||
|
palette->colors[0].r, palette->colors[0].g, palette->colors[0].b,
|
||||||
|
palette->colors[1].r, palette->colors[1].g, palette->colors[1].b,
|
||||||
|
palette->colors[2].r, palette->colors[2].g, palette->colors[2].b,
|
||||||
|
palette->colors[3].r, palette->colors[3].g, palette->colors[3].b,
|
||||||
|
palette->colors[4].r, palette->colors[4].g, palette->colors[4].b
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_update_highpass(PreferencesWindow *pref, const GB_highpass_mode_t mode, MainWindow *self) {
|
||||||
|
g_debug("on_update_highpass(%d)", mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_update_rewind_duration(PreferencesWindow *pref, const guint rewind_duration, MainWindow *self) {
|
||||||
|
g_debug("on_update_rewind_duration(%d)", rewind_duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_update_rumble_mode(PreferencesWindow *pref, const GB_rumble_mode_t mode, MainWindow *self) {
|
||||||
|
g_debug("on_update_rumble_mode(%d)", mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_update_video_display_border_mode(PreferencesWindow *pref, const gchar *name, MainWindow *self) {
|
||||||
|
g_debug("on_update_video_display_border_mode(%s)", name);
|
||||||
|
// self->border_mode_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_update_video_shader(PreferencesWindow *pref, const gchar *name, MainWindow *self) {
|
||||||
|
g_debug("on_update_video_shader(%s)", name);
|
||||||
|
main_window_set_shader(self, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_update_audio_sample_rate(PreferencesWindow *pref, const guint sample_rate, MainWindow *self) {
|
||||||
|
g_debug("on_update_audio_sample_rate(%d)", sample_rate);
|
||||||
|
|
||||||
|
if (sample_rate == -1) {
|
||||||
|
self->sample_rate = GB_audio_default_sample_rate();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self->sample_rate = sample_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// init_audio();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_update_audio_interference_volume(PreferencesWindow *pref, const guint *interference_volume, MainWindow *self) {
|
||||||
|
g_debug("on_update_audio_interference_volume(%d)", *interference_volume);
|
||||||
|
|
||||||
|
if (GB_is_inited(self->gb)) {
|
||||||
|
// wouldn’t it be nice to use the value set in the GtkAdjustment of the slider instead of 100.0 here?
|
||||||
|
GB_set_interference_volume(self->gb, (double) *interference_volume / 100.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool on_change_model(GtkWidget *parent, GtkWidget *widget, gpointer user_data) {
|
||||||
|
MainWindow *self = SAMEBOY_MAIN_WINDOW(parent);
|
||||||
|
g_debug("on_change_model");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PrinterCallbackData {
|
||||||
|
PrinterWindow *printer_window;
|
||||||
|
uint32_t *image;
|
||||||
|
uint8_t height;
|
||||||
|
uint8_t top_margin;
|
||||||
|
uint8_t bottom_margin;
|
||||||
|
uint8_t exposure;
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean draw_printer_image(struct PrinterCallbackData *data) {
|
||||||
|
printer_window_update(data->printer_window, data->image, data->height, data->top_margin, data->bottom_margin, data->exposure);
|
||||||
|
|
||||||
|
g_free(data->image);
|
||||||
|
g_slice_free(struct PrinterCallbackData, data);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void emu_thread_on_print_image(GB_gameboy_t *gb, uint32_t *image, uint8_t height, uint8_t top_margin, uint8_t bottom_margin, uint8_t exposure) {
|
||||||
|
MainWindow *self = SAMEBOY_MAIN_WINDOW(GB_get_user_data(gb));
|
||||||
|
|
||||||
|
struct PrinterCallbackData *data = g_slice_alloc(sizeof(struct PrinterCallbackData));
|
||||||
|
|
||||||
|
data->printer_window = self->printer;
|
||||||
|
data->image = g_malloc0(160 * height * sizeof(image[0]));
|
||||||
|
memcpy(data->image, image, 160 * height * sizeof(image[0]));
|
||||||
|
|
||||||
|
data->height = height;
|
||||||
|
data->top_margin = top_margin;
|
||||||
|
data->bottom_margin = bottom_margin;
|
||||||
|
data->exposure = exposure;
|
||||||
|
|
||||||
|
// We must make sure to run this function on the GTK thread
|
||||||
|
g_idle_add((GSourceFunc) draw_printer_image, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool on_change_linked_device(GtkWidget *parent, GtkWidget *widget, gpointer user_data) {
|
||||||
|
MainWindow *self = SAMEBOY_MAIN_WINDOW(parent);
|
||||||
|
g_debug("on_change_linked_device");
|
||||||
|
|
||||||
|
GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM(widget);
|
||||||
|
gchar *device_id = (gchar *) user_data;
|
||||||
|
|
||||||
|
if (!gtk_check_menu_item_get_active(check_menu_item)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (!GB_is_inited(self->gb)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
perform_atomic(self, {
|
||||||
|
if (g_strcmp0(device_id, "NONE") == 0) {
|
||||||
|
g_debug("Disconnecting serial device");
|
||||||
|
GB_disconnect_serial(self->gb);
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(device_id, "PRINTER") == 0) {
|
||||||
|
g_debug("Connecting printer");
|
||||||
|
GB_connect_printer(self->gb, emu_thread_on_print_image);
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(device_id, "WORKBOY") == 0) {
|
||||||
|
g_debug("Connecting WorkBoy");
|
||||||
|
|
||||||
|
g_warning("Not yet implemented!")
|
||||||
|
GB_disconnect_serial(self->gb);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void emu_thread_on_load_boot_rom(GB_gameboy_t *gb, GB_boot_rom_t type) {
|
||||||
|
g_debug("on_load_boot_rom(%p, %d)", gb, type);
|
||||||
|
|
||||||
|
MainWindow *self = SAMEBOY_MAIN_WINDOW(GB_get_user_data(gb));
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(gtk_window_get_application(GTK_WINDOW(self)));
|
||||||
|
struct CliOptionData *cli_options = sameboy_application_get_cli_options(app);
|
||||||
|
|
||||||
|
GError *error = NULL;
|
||||||
|
char *boot_rom_path = NULL;
|
||||||
|
GBytes *boot_rom_f = NULL;
|
||||||
|
const guchar *boot_rom_data;
|
||||||
|
gsize boot_rom_size;
|
||||||
|
|
||||||
|
static const char *const names[] = {
|
||||||
|
[GB_BOOT_ROM_DMG0] = "dmg0_boot.bin",
|
||||||
|
[GB_BOOT_ROM_DMG] = "dmg_boot.bin",
|
||||||
|
[GB_BOOT_ROM_MGB] = "mgb_boot.bin",
|
||||||
|
[GB_BOOT_ROM_SGB] = "sgb_boot.bin",
|
||||||
|
[GB_BOOT_ROM_SGB2] = "sgb2_boot.bin",
|
||||||
|
[GB_BOOT_ROM_CGB0] = "cgb0_boot.bin",
|
||||||
|
[GB_BOOT_ROM_CGB] = "cgb_boot.bin",
|
||||||
|
[GB_BOOT_ROM_AGB] = "agb_boot.bin",
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *const boot_rom_name = names[type];
|
||||||
|
|
||||||
|
if (cli_options->boot_rom_path != NULL) {
|
||||||
|
g_message("[CLI override] Trying to load boot ROM from %s", cli_options->boot_rom_path);
|
||||||
|
if (GB_load_boot_rom(gb, cli_options->boot_rom_path)) {
|
||||||
|
g_warning("Falling back to boot ROM from config");
|
||||||
|
goto config_boot_rom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { config_boot_rom:
|
||||||
|
if (config.emulation.boot_rom_path != NULL && g_strcmp0(config.emulation.boot_rom_path, "other") != 0 && g_strcmp0(config.emulation.boot_rom_path, "auto") != 0) {
|
||||||
|
boot_rom_path = g_build_filename(config.emulation.boot_rom_path, boot_rom_name, NULL);
|
||||||
|
g_message("Trying to load boot ROM from %s", boot_rom_path);
|
||||||
|
|
||||||
|
if (GB_load_boot_rom(gb, boot_rom_path)) {
|
||||||
|
g_free(boot_rom_path);
|
||||||
|
g_warning("Falling back to internal boot ROM");
|
||||||
|
goto internal_boot_rom;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(boot_rom_path);
|
||||||
|
}
|
||||||
|
else { internal_boot_rom:
|
||||||
|
boot_rom_path = g_build_filename(RESOURCE_PREFIX "bootroms/", boot_rom_name, NULL);
|
||||||
|
boot_rom_f = g_resources_lookup_data(boot_rom_path, G_RESOURCE_LOOKUP_FLAGS_NONE, &error);
|
||||||
|
|
||||||
|
g_message("Loading internal boot ROM: %s", boot_rom_path);
|
||||||
|
|
||||||
|
if (boot_rom_f == NULL) {
|
||||||
|
g_warning("Failed to load internal boot ROM: %s", boot_rom_path);
|
||||||
|
g_error_free(error);
|
||||||
|
// exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
boot_rom_data = g_bytes_get_data(boot_rom_f, &boot_rom_size);
|
||||||
|
GB_load_boot_rom_from_buffer(gb, boot_rom_data, boot_rom_size);
|
||||||
|
g_bytes_unref(boot_rom_f);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(boot_rom_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void main_window_init_core(MainWindow *self) {
|
||||||
|
if (GB_is_inited(self->gb)) return;
|
||||||
|
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(gtk_window_get_application(GTK_WINDOW(self)));
|
||||||
|
struct CliOptionData *cli_options = sameboy_application_get_cli_options(app);
|
||||||
|
|
||||||
|
GB_init(self->gb, config_get_model_type(cli_options));
|
||||||
|
GB_set_user_data(self->gb, self);
|
||||||
|
|
||||||
|
if (config.audio.sample_rate == -1) {
|
||||||
|
self->sample_rate = GB_audio_default_sample_rate();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self->sample_rate = config.audio.sample_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GB_set_vblank_callback(self->gb, emu_thread_on_vblank);
|
||||||
|
// GB_set_rgb_encode_callback(self->gb, emu_thread_rgb_encode);
|
||||||
|
|
||||||
|
GB_set_pixels_output(self->gb, main_window_get_current_buffer(self));
|
||||||
|
GB_set_color_correction_mode(self->gb, config_get_color_correction_mode());
|
||||||
|
GB_set_light_temperature(self->gb, (double) config.video.light_temperature / 256.0);
|
||||||
|
if (config_get_display_border_mode() <= GB_BORDER_ALWAYS) {
|
||||||
|
GB_set_border_mode(self->gb, config_get_display_border_mode());
|
||||||
|
}
|
||||||
|
|
||||||
|
// GB_apu_set_sample_callback(self->gb, emu_thread_audio_callback);
|
||||||
|
|
||||||
|
GB_set_sample_rate(self->gb, GB_audio_get_sample_rate());
|
||||||
|
GB_set_highpass_filter_mode(self->gb, config_get_highpass_mode());
|
||||||
|
GB_set_interference_volume(self->gb, (double) config.audio.interference_volume / 100.0);
|
||||||
|
|
||||||
|
// GB_set_log_callback(self->gb, emu_thread_console_log);
|
||||||
|
// GB_set_input_callback(self->gb, emu_thread_get_sync_input);
|
||||||
|
// GB_set_async_input_callback(self->gb, emu_thread_get_async_input);
|
||||||
|
|
||||||
|
GB_set_boot_rom_load_callback(self->gb, emu_thread_on_load_boot_rom);
|
||||||
|
// GB_set_update_input_hint_callback(self->gb, emu_thread_handle_events);
|
||||||
|
// GB_set_rumble_callback(self->gb, emu_thread_rumble_callback);
|
||||||
|
|
||||||
|
GB_set_rumble_mode(self->gb, config_get_rumble_mode());
|
||||||
|
GB_set_rewind_length(self->gb, config.emulation.rewind_duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_application_set(MainWindow *self, GObject *object) {
|
||||||
|
SameBoyApplication *app = SAMEBOY_APPLICATION(gtk_window_get_application(GTK_WINDOW(self)));
|
||||||
|
g_debug("on_application_set(%p, %p) => %p", self, object, app);
|
||||||
|
|
||||||
|
sameboy_application_preferences_signal_connect(app, "pref-update::color-correction", G_CALLBACK(on_update_color_correction), self);
|
||||||
|
sameboy_application_preferences_signal_connect(app, "pref-update::video-color-temperature", G_CALLBACK(on_update_video_color_temperature), self);
|
||||||
|
sameboy_application_preferences_signal_connect(app, "pref-update::monochrome-palette", G_CALLBACK(on_update_monochrome_palette), self);
|
||||||
|
sameboy_application_preferences_signal_connect(app, "pref-update::highpass", G_CALLBACK(on_update_highpass), self);
|
||||||
|
sameboy_application_preferences_signal_connect(app, "pref-update::rewind-duration", G_CALLBACK(on_update_rewind_duration), self);
|
||||||
|
sameboy_application_preferences_signal_connect(app, "pref-update::rumble-mode", G_CALLBACK(on_update_rumble_mode), self);
|
||||||
|
sameboy_application_preferences_signal_connect(app, "pref-update::video-display-border-mode", G_CALLBACK(on_update_video_display_border_mode), self);
|
||||||
|
sameboy_application_preferences_signal_connect(app, "pref-update::video-shader", G_CALLBACK(on_update_video_shader), self);
|
||||||
|
sameboy_application_preferences_signal_connect(app, "pref-update::audio-sample-rate", G_CALLBACK(on_update_audio_sample_rate), self);
|
||||||
|
sameboy_application_preferences_signal_connect(app, "pref-update::audio-interference-volume", G_CALLBACK(on_update_audio_interference_volume), self);
|
||||||
|
|
||||||
|
main_window_init_core(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void main_window_constructed(GObject *object) {
|
||||||
|
G_OBJECT_CLASS(main_window_parent_class)->constructed(object);
|
||||||
|
|
||||||
|
MainWindow *self = (MainWindow *) object;
|
||||||
|
|
||||||
|
self->screen = gb_screen_new(self->force_software_renderer);
|
||||||
|
gtk_box_pack_end(GTK_BOX(self->container), GTK_WIDGET(self->screen), true, true, 0);
|
||||||
|
|
||||||
|
g_signal_connect(self, "notify::application", G_CALLBACK(on_application_set), self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void main_window_init(MainWindow *self) {
|
||||||
|
gtk_widget_init_template(GTK_WIDGET(self));
|
||||||
|
|
||||||
|
gtk_window_set_title(GTK_WINDOW(self), "SameBoy");
|
||||||
|
gtk_application_window_set_show_menubar(GTK_APPLICATION_WINDOW(self), false);
|
||||||
|
|
||||||
|
// Connect signal handlers
|
||||||
|
gtk_widget_add_events(GTK_WIDGET(self), GDK_KEY_PRESS_MASK);
|
||||||
|
gtk_widget_add_events(GTK_WIDGET(self), GDK_KEY_RELEASE_MASK);
|
||||||
|
|
||||||
|
GtkAccelGroup *accelGroup = gtk_accel_group_new();
|
||||||
|
gtk_window_add_accel_group(GTK_WINDOW(self), accelGroup);
|
||||||
|
gtk_widget_add_accelerator(GTK_WIDGET(self), "break-debugger-keyboard", accelGroup, GDK_KEY_C, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||||
|
|
||||||
|
self->gb = g_malloc(sizeof(GB_gameboy_t));
|
||||||
|
if (self->gb == NULL) {
|
||||||
|
g_warning("Out of memory!");
|
||||||
|
// TODO: Try to stop gracefully
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
self->console = console_window_new(self->gb);
|
||||||
|
gtk_window_set_attached_to(GTK_WINDOW(self->console), GTK_WIDGET(self));
|
||||||
|
|
||||||
|
self->vram_viewer = vram_viewer_window_new();
|
||||||
|
gtk_window_set_attached_to(GTK_WINDOW(self->vram_viewer), GTK_WIDGET(self));
|
||||||
|
|
||||||
|
self->printer = printer_window_new();
|
||||||
|
gtk_window_set_attached_to(GTK_WINDOW(self->printer), GTK_WIDGET(self));
|
||||||
|
|
||||||
|
// Just hide our sub-windows when closing them
|
||||||
|
g_signal_connect(self->console, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
|
||||||
|
// g_signal_connect(self->memory_viewer, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
|
||||||
|
g_signal_connect(self->printer, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
|
||||||
|
g_signal_connect(self->vram_viewer, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void main_window_class_init(MainWindowClass *class) {
|
||||||
|
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), RESOURCE_PREFIX "ui/main_window.ui");
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), MainWindow, container);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), MainWindow, main_menu);
|
||||||
|
|
||||||
|
g_signal_new(
|
||||||
|
"break-debugger-keyboard", // signal name
|
||||||
|
G_TYPE_FROM_CLASS(class), // itype
|
||||||
|
G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_ACTION, // signal_flags
|
||||||
|
0, // class_offset
|
||||||
|
NULL, // accumulator
|
||||||
|
NULL, // accumulator_data
|
||||||
|
NULL, // c_marshaller,
|
||||||
|
G_TYPE_NONE, // return_type
|
||||||
|
0 // n_params
|
||||||
|
);
|
||||||
|
|
||||||
|
obj_properties[PROP_FORCE_SOFTWARE_RENDERER] = g_param_spec_boolean(
|
||||||
|
"force_software_renderer", "Software Renderer", "Forces the use of software rendering via Cairo",
|
||||||
|
false,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE
|
||||||
|
);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS(class)->set_property = main_window_set_property;
|
||||||
|
G_OBJECT_CLASS(class)->get_property = main_window_get_property;
|
||||||
|
G_OBJECT_CLASS(class)->constructed = main_window_constructed;
|
||||||
|
|
||||||
|
g_object_class_install_properties(G_OBJECT_CLASS(class), N_PROPERTIES, obj_properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow *main_window_new(SameBoyApplication *application, bool force_software_renderer) {
|
||||||
|
g_debug("main_window_new(%p, %d)", application, force_software_renderer);
|
||||||
|
|
||||||
|
return g_object_new(
|
||||||
|
MAIN_WINDOW_TYPE,
|
||||||
|
"application", G_APPLICATION(application),
|
||||||
|
"force_software_renderer", force_software_renderer,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window_fullscreen(MainWindow *self, bool make_fullscreen) {
|
||||||
|
if (make_fullscreen) {
|
||||||
|
gtk_window_fullscreen(GTK_WINDOW(self));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gtk_window_unfullscreen(GTK_WINDOW(self));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window_setup_menu(MainWindow *self, char *model_string) {
|
||||||
|
main_menu_setup(self->main_menu, model_string, self, on_change_model, on_change_linked_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window_open_console_window(MainWindow *self) {
|
||||||
|
gtk_widget_show_all(GTK_WIDGET(self->console));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window_open_memory_viewer_window(MainWindow *self) {
|
||||||
|
g_warning("Not yet implemented!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window_open_vram_viewer_window(MainWindow *self) {
|
||||||
|
gtk_widget_show_all(GTK_WIDGET(self->vram_viewer));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window_open_printer_window(MainWindow *self) {
|
||||||
|
gtk_widget_show_all(GTK_WIDGET(self->printer));
|
||||||
|
}
|
||||||
|
|
||||||
|
// GbScreen wrappers
|
||||||
|
void main_window_clear(MainWindow *self) {
|
||||||
|
return gb_screen_clear(self->screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t *main_window_get_pixels(MainWindow *self) {
|
||||||
|
return gb_screen_get_pixels(self->screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t *main_window_get_current_buffer(MainWindow *self) {
|
||||||
|
return gb_screen_get_current_buffer(self->screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t *main_window_get_previous_buffer(MainWindow *self) {
|
||||||
|
return gb_screen_get_previous_buffer(self->screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window_flip(MainWindow *self) {
|
||||||
|
return gb_screen_flip(self->screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window_set_resolution(MainWindow *self, unsigned width, unsigned height) {
|
||||||
|
return gb_screen_set_resolution(self->screen, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window_set_blending_mode(MainWindow *self, GB_frame_blending_mode_t mode) {
|
||||||
|
return gb_screen_set_blending_mode(self->screen, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window_set_shader(MainWindow *self, const char *shader_name) {
|
||||||
|
return gb_screen_set_shader(self->screen, shader_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window_queue_render(MainWindow *self) {
|
||||||
|
return gb_screen_queue_render(self->screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Core functions
|
||||||
|
static void emulation_thread(MainWindow *self) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void main_window_start_emulation_thread(MainWindow *self) {
|
||||||
|
if (self->running) return;
|
||||||
|
while (self->stopping);
|
||||||
|
|
||||||
|
g_thread_new("EmulationThread", (GThreadFunc)emulation_thread, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window_start(MainWindow *self) {
|
||||||
|
g_debug("main_window_start");
|
||||||
|
self->running = true;
|
||||||
|
|
||||||
|
// TODO: Clear audio queue
|
||||||
|
|
||||||
|
while (self->running) {
|
||||||
|
if (self->rewind_paused) {
|
||||||
|
// handle_events(self->gb);
|
||||||
|
g_usleep(G_USEC_PER_SEC / 8);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (self->do_rewind) {
|
||||||
|
GB_rewind_pop(self->gb);
|
||||||
|
if (self->turbo_down) {
|
||||||
|
GB_rewind_pop(self->gb);
|
||||||
|
}
|
||||||
|
if (!GB_rewind_pop(self->gb)) {
|
||||||
|
self->rewind_paused = true;
|
||||||
|
}
|
||||||
|
self->do_rewind = false;
|
||||||
|
}
|
||||||
|
GB_run(self->gb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->file) {
|
||||||
|
GB_save_battery(self->gb, self->battery_save_path);
|
||||||
|
GB_save_cheats(self->gb, self->cheats_save_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
self->stopping = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window_stop(MainWindow *self) {
|
||||||
|
g_debug("main_window_stop");
|
||||||
|
if (self->running) return;
|
||||||
|
|
||||||
|
// GB_audio_set_paused(true);
|
||||||
|
GB_debugger_set_disabled(self->gb, true);
|
||||||
|
|
||||||
|
self->stopping = true;
|
||||||
|
self->running = false;
|
||||||
|
|
||||||
|
if (GB_debugger_is_stopped(self->gb)) {
|
||||||
|
console_window_abort_debugger(self->console);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (self->stopping);
|
||||||
|
|
||||||
|
GB_debugger_set_disabled(self->gb, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window_reset(MainWindow *self) {
|
||||||
|
g_debug("main_window_reset");
|
||||||
|
}
|
38
gtk3/widgets/main_window.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef main_window_h
|
||||||
|
#define main_window_h
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <Core/gb.h>
|
||||||
|
#include "../sameboy_application.h"
|
||||||
|
#include "../shader.h"
|
||||||
|
|
||||||
|
#define MAIN_WINDOW_TYPE (main_window_get_type())
|
||||||
|
G_DECLARE_FINAL_TYPE(MainWindow, main_window, SAMEBOY, MAIN_WINDOW, GtkApplicationWindow)
|
||||||
|
|
||||||
|
MainWindow *main_window_new(SameBoyApplication *app, bool force_software_renderer);
|
||||||
|
void main_window_setup_menu(MainWindow *self, char *model_string);
|
||||||
|
|
||||||
|
void main_window_fullscreen(MainWindow *self, bool make_fullscreen);
|
||||||
|
void main_window_open_console_window(MainWindow *self);
|
||||||
|
void main_window_open_memory_viewer_window(MainWindow *self);
|
||||||
|
void main_window_open_vram_viewer_window(MainWindow *self);
|
||||||
|
void main_window_open_printer_window(MainWindow *self);
|
||||||
|
|
||||||
|
// GbScreen wrappers
|
||||||
|
void main_window_clear(MainWindow *self);
|
||||||
|
uint32_t *main_window_get_pixels(MainWindow *self);
|
||||||
|
uint32_t *main_window_get_current_buffer(MainWindow *self);
|
||||||
|
uint32_t *main_window_get_previous_buffer(MainWindow *self);
|
||||||
|
void main_window_flip(MainWindow *self);
|
||||||
|
void main_window_set_resolution(MainWindow *self, unsigned width, unsigned height);
|
||||||
|
void main_window_set_blending_mode(MainWindow *self, GB_frame_blending_mode_t mode);
|
||||||
|
void main_window_set_shader(MainWindow *self, const char *shader_name);
|
||||||
|
void main_window_queue_render(MainWindow *self);
|
||||||
|
|
||||||
|
// Core functions
|
||||||
|
void main_window_start(MainWindow *self);
|
||||||
|
void main_window_stop(MainWindow *self);
|
||||||
|
void main_window_reset(MainWindow *self);
|
||||||
|
|
||||||
|
#endif
|
344
gtk3/widgets/preferences_window.c
Normal file
@ -0,0 +1,344 @@
|
|||||||
|
#include "preferences_window.h"
|
||||||
|
#include "../config.h"
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
|
struct _PreferencesWindow {
|
||||||
|
GtkWindowClass parent_class;
|
||||||
|
|
||||||
|
GtkComboBoxText *boot_rom_selector;
|
||||||
|
GtkComboBoxText *rewind_duration_selector;
|
||||||
|
GtkComboBox *dmg_revision_selector;
|
||||||
|
GtkComboBoxText *sgb_revision_selector;
|
||||||
|
GtkComboBox *cgb_revision_selector;
|
||||||
|
GtkComboBoxText *shader_selector;
|
||||||
|
GtkComboBoxText *color_correction_selector;
|
||||||
|
GtkScale *light_temperature_slider;
|
||||||
|
GtkComboBoxText *frame_blending_selector;
|
||||||
|
GtkComboBoxText *monochrome_palette_selector;
|
||||||
|
GtkComboBoxText *display_border_selector;
|
||||||
|
GtkCheckButton *integer_scaling_toggle;
|
||||||
|
GtkCheckButton *aspect_ratio_toggle;
|
||||||
|
GtkComboBoxText *highpass_filter_selector;
|
||||||
|
GtkComboBoxText *sample_rate_selector;
|
||||||
|
GtkScale *interference_volume_slider;
|
||||||
|
GtkCheckButton *analog_speed_controls_toggle;
|
||||||
|
GtkComboBoxText *rumble_mode_selector;
|
||||||
|
GtkButton *configure_joypad_skip;
|
||||||
|
|
||||||
|
GB_gameboy_t *gb;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE(PreferencesWindow, preferences_window, GTK_TYPE_WINDOW);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PREF_UPDATE,
|
||||||
|
N_SIGNALS
|
||||||
|
} PreferencesWindowSignals;
|
||||||
|
|
||||||
|
static guint preferences_signals[N_SIGNALS] = { 0, };
|
||||||
|
|
||||||
|
static void preferences_window_init(PreferencesWindow *self) {
|
||||||
|
gtk_widget_init_template(GTK_WIDGET(self));
|
||||||
|
|
||||||
|
// Add a couple of "snapping points" to the sliders
|
||||||
|
gtk_scale_add_mark(self->light_temperature_slider, 0.0, GTK_POS_BOTTOM, NULL);
|
||||||
|
|
||||||
|
for (unsigned i = 1; i < 10; i++) {
|
||||||
|
gtk_scale_add_mark(self->interference_volume_slider, ((double) i / 10.0) * 100.0, GTK_POS_BOTTOM, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
preferences_window_update_boot_rom_selector(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_boot_rom_location_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
GtkComboBox *box = GTK_COMBO_BOX(w);
|
||||||
|
const gchar *id = gtk_combo_box_get_active_id(box);
|
||||||
|
if (id == NULL) return;
|
||||||
|
|
||||||
|
if (g_strcmp0(id, "other") == 0) {
|
||||||
|
GtkFileChooserNative *native = gtk_file_chooser_native_new("Select Folder", GTK_WINDOW(self), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, "_Select", "_Cancel");
|
||||||
|
gint res = gtk_native_dialog_run(GTK_NATIVE_DIALOG(native));
|
||||||
|
|
||||||
|
if (res == GTK_RESPONSE_ACCEPT) {
|
||||||
|
config.emulation.boot_rom_path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(native));
|
||||||
|
preferences_window_update_boot_rom_selector(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref(native);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
config.emulation.boot_rom_path = (gchar *)id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_cgb_model_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
GtkComboBox *box = GTK_COMBO_BOX(w);
|
||||||
|
config.emulation.cgb_revision_name = (gchar *)gtk_combo_box_get_active_id(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_frame_blending_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
GtkComboBox *box = GTK_COMBO_BOX(w);
|
||||||
|
config.video.frame_blending_mode = (gchar *)gtk_combo_box_get_active_id(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_dmg_model_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
GtkComboBox *box = GTK_COMBO_BOX(w);
|
||||||
|
config.emulation.dmg_revision_name = (gchar *)gtk_combo_box_get_active_id(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_keep_aspect_ratio_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
GtkCheckButton *button = GTK_CHECK_BUTTON(w);
|
||||||
|
gboolean value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
|
||||||
|
config.video.keep_aspect_ratio = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_sgb_model_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
GtkComboBox *box = GTK_COMBO_BOX(w);
|
||||||
|
config.emulation.sgb_revision_name = (gchar *)gtk_combo_box_get_active_id(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_use_integer_scaling_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
GtkCheckButton *button = GTK_CHECK_BUTTON(w);
|
||||||
|
gboolean value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
|
||||||
|
config.video.use_integer_scaling = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_analog_speed_controls_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
GtkCheckButton *button = GTK_CHECK_BUTTON(w);
|
||||||
|
gboolean value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
|
||||||
|
config.controls.analog_speed_controls = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_color_correction_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
GtkComboBox *box = GTK_COMBO_BOX(w);
|
||||||
|
config.video.color_correction_id = (gchar *)gtk_combo_box_get_active_id(box);
|
||||||
|
|
||||||
|
g_signal_emit(
|
||||||
|
self,
|
||||||
|
preferences_signals[PREF_UPDATE],
|
||||||
|
g_quark_from_static_string("color-correction"),
|
||||||
|
config_get_color_correction_mode()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_light_temperature_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
GtkRange *range = GTK_RANGE(w);
|
||||||
|
gdouble value = gtk_range_get_value(range);
|
||||||
|
config.video.light_temperature = (guint32) value;
|
||||||
|
|
||||||
|
g_signal_emit(
|
||||||
|
self,
|
||||||
|
preferences_signals[PREF_UPDATE],
|
||||||
|
g_quark_from_static_string("video-color-temperature"),
|
||||||
|
config.video.light_temperature
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_monochrome_palette_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
GtkComboBox *box = GTK_COMBO_BOX(w);
|
||||||
|
config.video.monochrome_palette_id = (gchar *)gtk_combo_box_get_active_id(box);
|
||||||
|
|
||||||
|
g_signal_emit(
|
||||||
|
self,
|
||||||
|
preferences_signals[PREF_UPDATE],
|
||||||
|
g_quark_from_static_string("monochrome-palette"),
|
||||||
|
config_get_monochrome_palette()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_highpass_filter_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
config.audio.high_pass_filter_id = (gchar *)gtk_combo_box_get_active_id(GTK_COMBO_BOX(w));
|
||||||
|
|
||||||
|
g_signal_emit(
|
||||||
|
self,
|
||||||
|
preferences_signals[PREF_UPDATE],
|
||||||
|
g_quark_from_static_string("highpass"),
|
||||||
|
config_get_highpass_mode()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_rewind_duration_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
GtkComboBox *box = GTK_COMBO_BOX(w);
|
||||||
|
config.emulation.rewind_duration = g_ascii_strtoll(gtk_combo_box_get_active_id(box), NULL, 10);
|
||||||
|
|
||||||
|
g_signal_emit(
|
||||||
|
self,
|
||||||
|
preferences_signals[PREF_UPDATE],
|
||||||
|
g_quark_from_static_string("rewind-duration"),
|
||||||
|
config.emulation.rewind_duration
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_rumble_mode_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
GtkComboBox *box = GTK_COMBO_BOX(w);
|
||||||
|
config.controls.rumble_mode = (gchar *)gtk_combo_box_get_active_id(box);
|
||||||
|
|
||||||
|
g_signal_emit(
|
||||||
|
self,
|
||||||
|
preferences_signals[PREF_UPDATE],
|
||||||
|
g_quark_from_static_string("rumble-mode"),
|
||||||
|
config_get_rumble_mode()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_display_border_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
GtkComboBox *box = GTK_COMBO_BOX(w);
|
||||||
|
config.video.display_border_mode = (gchar *)gtk_combo_box_get_active_id(box);
|
||||||
|
|
||||||
|
g_signal_emit(
|
||||||
|
self,
|
||||||
|
preferences_signals[PREF_UPDATE],
|
||||||
|
g_quark_from_static_string("video-display-border-mode"),
|
||||||
|
config.video.display_border_mode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_graphic_filter_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
GtkComboBox *box = GTK_COMBO_BOX(w);
|
||||||
|
config.video.shader = (gchar *)gtk_combo_box_get_active_id(box);
|
||||||
|
|
||||||
|
g_signal_emit(
|
||||||
|
self,
|
||||||
|
preferences_signals[PREF_UPDATE],
|
||||||
|
g_quark_from_static_string("video-shader"),
|
||||||
|
config.video.shader
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_sample_rate_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
GtkComboBox *box = GTK_COMBO_BOX(w);
|
||||||
|
config.audio.sample_rate = g_ascii_strtoll(gtk_combo_box_get_active_id(box), NULL, 10);
|
||||||
|
|
||||||
|
g_signal_emit(
|
||||||
|
self,
|
||||||
|
preferences_signals[PREF_UPDATE],
|
||||||
|
g_quark_from_static_string("audio-sample-rate"),
|
||||||
|
config.audio.sample_rate
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_interference_volume_changed(GtkWidget *w, PreferencesWindow *self) {
|
||||||
|
GtkRange *range = GTK_RANGE(w);
|
||||||
|
gdouble value = gtk_range_get_value(range);
|
||||||
|
config.audio.interference_volume = (guint32) value;
|
||||||
|
|
||||||
|
g_signal_emit(
|
||||||
|
self,
|
||||||
|
preferences_signals[PREF_UPDATE],
|
||||||
|
g_quark_from_static_string("audio-interference-volume"),
|
||||||
|
&config.audio.interference_volume
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void preferences_window_realize(GtkWidget *widget) {
|
||||||
|
PreferencesWindow *self = (PreferencesWindow *)widget;
|
||||||
|
|
||||||
|
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->rewind_duration_selector), g_strdup_printf("%i", config.emulation.rewind_duration));
|
||||||
|
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->dmg_revision_selector), config.emulation.dmg_revision_name);
|
||||||
|
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->sgb_revision_selector), config.emulation.sgb_revision_name);
|
||||||
|
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->cgb_revision_selector), config.emulation.cgb_revision_name);
|
||||||
|
|
||||||
|
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->shader_selector), config.video.shader);
|
||||||
|
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->color_correction_selector), config.video.color_correction_id);
|
||||||
|
gtk_range_set_value(GTK_RANGE(self->light_temperature_slider), (double) config.video.light_temperature);
|
||||||
|
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->frame_blending_selector), config.video.frame_blending_mode);
|
||||||
|
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->display_border_selector), config.video.display_border_mode);
|
||||||
|
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->monochrome_palette_selector), config.video.monochrome_palette_id);
|
||||||
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->integer_scaling_toggle), config.video.use_integer_scaling);
|
||||||
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->aspect_ratio_toggle), config.video.keep_aspect_ratio);
|
||||||
|
|
||||||
|
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->highpass_filter_selector), config.audio.high_pass_filter_id);
|
||||||
|
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->sample_rate_selector), g_strdup_printf("%i", config.audio.sample_rate));
|
||||||
|
gtk_range_set_value(GTK_RANGE(self->interference_volume_slider), (double) config.audio.interference_volume);
|
||||||
|
|
||||||
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->analog_speed_controls_toggle), config.controls.analog_speed_controls);
|
||||||
|
gtk_combo_box_set_active_id(GTK_COMBO_BOX(self->rumble_mode_selector), config.controls.rumble_mode);
|
||||||
|
|
||||||
|
set_combo_box_row_separator_func(GTK_CONTAINER(self));
|
||||||
|
|
||||||
|
GTK_WIDGET_CLASS(preferences_window_parent_class)->realize(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void preferences_window_class_init(PreferencesWindowClass *class) {
|
||||||
|
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), RESOURCE_PREFIX "ui/preferences_window.ui");
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, boot_rom_selector);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, rewind_duration_selector);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, dmg_revision_selector);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, sgb_revision_selector);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, cgb_revision_selector);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, shader_selector);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, color_correction_selector);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, light_temperature_slider);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, frame_blending_selector);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, monochrome_palette_selector);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, display_border_selector);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, integer_scaling_toggle);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, aspect_ratio_toggle);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, highpass_filter_selector);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, sample_rate_selector);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, interference_volume_slider);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, analog_speed_controls_toggle);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, rumble_mode_selector);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PreferencesWindow, configure_joypad_skip);
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_boot_rom_location_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_rewind_duration_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_dmg_model_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_sgb_model_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_cgb_model_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_graphic_filter_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_color_correction_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_light_temperature_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_frame_blending_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_monochrome_palette_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_display_border_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_use_integer_scaling_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_keep_aspect_ratio_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_highpass_filter_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_sample_rate_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_interference_volume_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_analog_speed_controls_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_rumble_mode_changed);
|
||||||
|
|
||||||
|
// gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), do_refresh_joypad_menu);
|
||||||
|
// gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_default_joypad_changed);
|
||||||
|
// gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), do_configure_joypad);
|
||||||
|
// gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), do_skip_configure_joypad);
|
||||||
|
|
||||||
|
GTK_WIDGET_CLASS(class)->realize = preferences_window_realize;
|
||||||
|
|
||||||
|
preferences_signals[PREF_UPDATE] = g_signal_new(
|
||||||
|
"pref-update", // signal name
|
||||||
|
G_TYPE_FROM_CLASS(G_OBJECT_CLASS(class)), // itype
|
||||||
|
G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED, // signal_flags
|
||||||
|
0, // class_offset
|
||||||
|
NULL, // accumulator
|
||||||
|
NULL, // accumulator_data
|
||||||
|
NULL, // c_marshaller,
|
||||||
|
G_TYPE_NONE, // return_type
|
||||||
|
1, // n_params,
|
||||||
|
G_TYPE_POINTER
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
PreferencesWindow *preferences_window_new(void) {
|
||||||
|
return g_object_new(PREFERENCES_WINDOW_TYPE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void preferences_window_update_boot_rom_selector(PreferencesWindow *self) {
|
||||||
|
GtkComboBoxText *combo_box = self->boot_rom_selector;
|
||||||
|
gtk_combo_box_text_remove_all(combo_box);
|
||||||
|
gtk_combo_box_text_append(combo_box, "auto", "Use Built-in Boot ROMs");
|
||||||
|
|
||||||
|
if (config.emulation.boot_rom_path != NULL && !g_str_equal(config.emulation.boot_rom_path, "auto") && !g_str_equal(config.emulation.boot_rom_path, "other")) {
|
||||||
|
gtk_combo_box_text_append(combo_box, config.emulation.boot_rom_path, config.emulation.boot_rom_path);
|
||||||
|
gtk_combo_box_set_active_id(GTK_COMBO_BOX(combo_box), config.emulation.boot_rom_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gtk_combo_box_set_active_id(GTK_COMBO_BOX(combo_box), "auto");
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_combo_box_text_append_text(combo_box, "<separator>");
|
||||||
|
gtk_combo_box_text_append(combo_box, "other", "Other");
|
||||||
|
}
|
13
gtk3/widgets/preferences_window.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#ifndef preferences_window_h
|
||||||
|
#define preferences_window_h
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <Core/gb.h>
|
||||||
|
|
||||||
|
#define PREFERENCES_WINDOW_TYPE (preferences_window_get_type())
|
||||||
|
G_DECLARE_FINAL_TYPE(PreferencesWindow, preferences_window, SAMEBOY, PREFERENCES_WINDOW, GtkWindow)
|
||||||
|
|
||||||
|
PreferencesWindow *preferences_window_new(void);
|
||||||
|
void preferences_window_update_boot_rom_selector(PreferencesWindow *self);
|
||||||
|
|
||||||
|
#endif
|
215
gtk3/widgets/printer_window.c
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
#include "printer_window.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
|
struct _PrinterWindow {
|
||||||
|
GtkWindowClass parent_class;
|
||||||
|
|
||||||
|
GtkScrolledWindow *scrolled_window;
|
||||||
|
GtkDrawingArea *printer_canvas;
|
||||||
|
GtkButton *printer_save_button;
|
||||||
|
GtkButton *printer_clear_button;
|
||||||
|
|
||||||
|
uint32_t *current_image;
|
||||||
|
size_t current_height;
|
||||||
|
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
GMutex surface_mutex;
|
||||||
|
|
||||||
|
char *suggestion_prefix;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE(PrinterWindow, printer_window, GTK_TYPE_WINDOW);
|
||||||
|
|
||||||
|
static gboolean on_printer_draw(GtkWidget *widget, cairo_t *cr, PrinterWindow *window) {
|
||||||
|
GtkStyleContext *context = gtk_widget_get_style_context(widget);
|
||||||
|
g_mutex_lock(&window->surface_mutex);
|
||||||
|
|
||||||
|
int width = cairo_image_surface_get_width(window->surface);
|
||||||
|
int height = cairo_image_surface_get_height(window->surface);
|
||||||
|
|
||||||
|
gtk_render_background(context, cr, 0, 0, width, height);
|
||||||
|
gtk_render_frame(context, cr, 0, 0, width, height);
|
||||||
|
|
||||||
|
cairo_scale(cr, 2.0, 2.0);
|
||||||
|
cairo_set_source_surface(cr, window->surface, 0, 0);
|
||||||
|
cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
|
||||||
|
cairo_paint(cr);
|
||||||
|
|
||||||
|
g_mutex_unlock(&window->surface_mutex);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_printer_save(GtkWidget *w, PrinterWindow *self) {
|
||||||
|
// This function is defined in `main.c` ...
|
||||||
|
// gpointer perform_atomic(gpointer (*fn)(gpointer args), gpointer args);
|
||||||
|
|
||||||
|
// This is ugly, yup.
|
||||||
|
// bool success = perform_atomic((gpointer)(*printer_window_save), self);
|
||||||
|
// g_debug("File saving status: %d", success);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_printer_clear(GtkWidget *w, PrinterWindow *self) {
|
||||||
|
printer_window_clear(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printer_window_init(PrinterWindow *window) {
|
||||||
|
gtk_widget_init_template(GTK_WIDGET(window));
|
||||||
|
|
||||||
|
set_combo_box_row_separator_func(GTK_CONTAINER(window));
|
||||||
|
|
||||||
|
printer_window_clear(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printer_window_finalize(GObject *object) {
|
||||||
|
PrinterWindow *window = (PrinterWindow *) object;
|
||||||
|
|
||||||
|
g_free(window->current_image);
|
||||||
|
cairo_surface_destroy(window->surface);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS(printer_window_parent_class)->finalize(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printer_window_class_init(PrinterWindowClass *class) {
|
||||||
|
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), RESOURCE_PREFIX "ui/printer_window.ui");
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PrinterWindow, scrolled_window);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PrinterWindow, printer_canvas);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PrinterWindow, printer_save_button);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), PrinterWindow, printer_clear_button);
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_printer_draw);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_printer_save);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_printer_clear);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS(class)->finalize = printer_window_finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrinterWindow *printer_window_new(void) {
|
||||||
|
return g_object_new(PRINTER_WINDOW_TYPE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printer_window_update(PrinterWindow *self, uint32_t *image, uint8_t height, uint8_t top_margin, uint8_t bottom_margin, uint8_t exposure) {
|
||||||
|
g_mutex_lock(&self->surface_mutex);
|
||||||
|
|
||||||
|
size_t current_size = self->current_height * 160;
|
||||||
|
size_t new_height = self->current_height
|
||||||
|
+ top_margin * 8
|
||||||
|
+ height
|
||||||
|
+ bottom_margin * 8;
|
||||||
|
size_t new_size = new_height * 160 * sizeof(uint32_t);
|
||||||
|
uint32_t *new_image = g_malloc(new_size);
|
||||||
|
|
||||||
|
memset(new_image, 0xFF, new_size); // fill with white
|
||||||
|
memcpy(new_image, self->current_image, current_size * sizeof(uint32_t)); // copy old image
|
||||||
|
memcpy(new_image + current_size + (top_margin * 160 * 8), image, height * 160 * sizeof(uint32_t)); // copy new image
|
||||||
|
|
||||||
|
g_free(self->current_image);
|
||||||
|
self->current_image = new_image;
|
||||||
|
self->current_height = new_height;
|
||||||
|
|
||||||
|
self->surface = cairo_image_surface_create_for_data(
|
||||||
|
(unsigned char*)self->current_image,
|
||||||
|
CAIRO_FORMAT_RGB24,
|
||||||
|
160,
|
||||||
|
self->current_height,
|
||||||
|
cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, 160)
|
||||||
|
);
|
||||||
|
|
||||||
|
g_mutex_unlock(&self->surface_mutex);
|
||||||
|
|
||||||
|
gtk_widget_set_size_request(GTK_WIDGET(self->printer_canvas), 160 * 2, self->current_height * 2);
|
||||||
|
gtk_window_present_with_time(GTK_WINDOW(self), time(NULL));
|
||||||
|
|
||||||
|
// queue scrolling, so that it will execute after the size request
|
||||||
|
g_idle_add((GSourceFunc)scrolled_window_scroll_to_bottom, self->scrolled_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printer_window_clear(PrinterWindow *self) {
|
||||||
|
g_mutex_lock(&self->surface_mutex);
|
||||||
|
|
||||||
|
self->surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 160, 0);
|
||||||
|
self->current_image = NULL;
|
||||||
|
self->current_height = 0;
|
||||||
|
|
||||||
|
gtk_widget_set_size_request(GTK_WIDGET(self->printer_canvas), 160 * 2, 0);
|
||||||
|
|
||||||
|
g_mutex_unlock(&self->surface_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool printer_window_save(PrinterWindow *self) {
|
||||||
|
GtkFileChooserNative *native = gtk_file_chooser_native_new("Save Printed Image", GTK_WINDOW(self), GTK_FILE_CHOOSER_ACTION_SAVE, "_Save", "_Cancel");
|
||||||
|
|
||||||
|
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(native), true);
|
||||||
|
gtk_file_chooser_set_create_folders(GTK_FILE_CHOOSER(native), true);
|
||||||
|
|
||||||
|
if (self->suggestion_prefix == NULL) {
|
||||||
|
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(native), "print.png");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GString *suggestion = g_string_new(self->suggestion_prefix);
|
||||||
|
|
||||||
|
#if GLIB_CHECK_VERSION(2,62,0)
|
||||||
|
gchar *date = g_date_time_format_iso8601(g_date_time_new_now_local());
|
||||||
|
#else
|
||||||
|
GTimeVal tv;
|
||||||
|
g_get_current_time(&tv);
|
||||||
|
gchar *date = g_time_val_to_iso8601(&tv);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
g_string_append_printf(suggestion, "_printout_%s.png", date);
|
||||||
|
|
||||||
|
for (gsize i = 0; i < suggestion->len; i++) {
|
||||||
|
if (suggestion->str[i] == ':') {
|
||||||
|
suggestion->str[i] = '-';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *basename = g_path_get_basename(suggestion->str);
|
||||||
|
gchar *dirname = g_path_get_dirname(suggestion->str);
|
||||||
|
|
||||||
|
gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(native), suggestion->str);
|
||||||
|
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(native), basename);
|
||||||
|
|
||||||
|
g_free(dirname);
|
||||||
|
g_free(basename);
|
||||||
|
g_string_free(suggestion, true);
|
||||||
|
g_free(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkFileFilter *filter = gtk_file_filter_new();
|
||||||
|
gtk_file_filter_add_pattern(filter, "*.png");
|
||||||
|
gtk_file_filter_add_mime_type(filter, "image/png");
|
||||||
|
gtk_file_filter_set_name(filter, "PNG");
|
||||||
|
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(native), filter);
|
||||||
|
|
||||||
|
gint res = gtk_native_dialog_run(GTK_NATIVE_DIALOG(native));
|
||||||
|
|
||||||
|
if (res == GTK_RESPONSE_ACCEPT) {
|
||||||
|
const char* path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(native));
|
||||||
|
|
||||||
|
g_mutex_lock(&self->surface_mutex);
|
||||||
|
cairo_status_t status = cairo_surface_write_to_png(self->surface, path);
|
||||||
|
g_mutex_unlock(&self->surface_mutex);
|
||||||
|
|
||||||
|
return status == CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref(native);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printer_window_set_suggestion_prefix(PrinterWindow *self, char* prefix) {
|
||||||
|
if (self->suggestion_prefix != NULL) {
|
||||||
|
g_free(self->suggestion_prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prefix != NULL) {
|
||||||
|
self->suggestion_prefix = g_strdup(prefix);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self->suggestion_prefix = NULL;
|
||||||
|
}
|
||||||
|
}
|
16
gtk3/widgets/printer_window.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef printer_window_h
|
||||||
|
#define printer_window_h
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <Core/gb.h>
|
||||||
|
|
||||||
|
#define PRINTER_WINDOW_TYPE (printer_window_get_type())
|
||||||
|
G_DECLARE_FINAL_TYPE(PrinterWindow, printer_window, SAMEBOY, PRINTER_WINDOW, GtkWindow)
|
||||||
|
|
||||||
|
PrinterWindow *printer_window_new(void);
|
||||||
|
void printer_window_clear(PrinterWindow *self);
|
||||||
|
bool printer_window_save(PrinterWindow *self);
|
||||||
|
void printer_window_update(PrinterWindow *self, uint32_t *image, uint8_t height, uint8_t top_margin, uint8_t bottom_margin, uint8_t exposure);
|
||||||
|
void printer_window_set_suggestion_prefix(PrinterWindow *self, char* prefix);
|
||||||
|
|
||||||
|
#endif
|
638
gtk3/widgets/vram_viewer_window.c
Normal file
@ -0,0 +1,638 @@
|
|||||||
|
#include "vram_viewer_window.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "../types.h"
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
|
#define tileset_buffer_length 256 * 192 * 4
|
||||||
|
#define tilemap_buffer_length 256 * 256 * 4
|
||||||
|
|
||||||
|
struct _VramViewerWindow {
|
||||||
|
GtkWindowClass parent_class;
|
||||||
|
|
||||||
|
GtkStack *stack;
|
||||||
|
GtkComboBoxText *tileset_palette_selector;
|
||||||
|
GtkToggleButton *tileset_toggle_grid_button;
|
||||||
|
GtkDrawingArea *tileset_canvas;
|
||||||
|
GtkComboBoxText *tilemap_palette_selector;
|
||||||
|
GtkComboBoxText *tilemap_tilemap_selector;
|
||||||
|
GtkToggleButton *tilemap_toggle_grid_button;
|
||||||
|
GtkToggleButton *tilemap_toggle_scrolling_button;
|
||||||
|
GtkComboBoxText *tilemap_tileset_selector;
|
||||||
|
GtkDrawingArea *tilemap_canvas;
|
||||||
|
GtkTreeView *sprites;
|
||||||
|
GtkTreeView *palettes;
|
||||||
|
GtkCellRendererText *palette_cell_renderer_0;
|
||||||
|
GtkCellRendererText *palette_cell_renderer_1;
|
||||||
|
GtkCellRendererText *palette_cell_renderer_2;
|
||||||
|
GtkCellRendererText *palette_cell_renderer_3;
|
||||||
|
GtkLabel *status;
|
||||||
|
|
||||||
|
bool is_cgb;
|
||||||
|
uint16_t oam_count;
|
||||||
|
uint8_t oam_height;
|
||||||
|
|
||||||
|
uint8_t palette_data[16][0x40];
|
||||||
|
GB_oam_info_t oam_info[40];
|
||||||
|
|
||||||
|
Rect scroll_rect;
|
||||||
|
|
||||||
|
uint8_t gb_lcdc;
|
||||||
|
uint8_t *gb_vram;
|
||||||
|
|
||||||
|
uint32_t *tileset_buffer;
|
||||||
|
uint32_t *tilemap_buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE(VramViewerWindow, vram_viewer_window, GTK_TYPE_WINDOW);
|
||||||
|
|
||||||
|
static void visible_tab_changed(GObject *stack, GParamSpec *pspec, VramViewerWindow *window) {
|
||||||
|
if (gtk_widget_in_destruction(GTK_WIDGET (stack))) return;
|
||||||
|
|
||||||
|
gtk_label_set_text(window->status, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean draw_tileset_canvas(GtkWidget *widget, cairo_t *cr, VramViewerWindow *window) {
|
||||||
|
GtkStyleContext *context = gtk_widget_get_style_context(widget);
|
||||||
|
int width = gtk_widget_get_allocated_width(widget);
|
||||||
|
int height = gtk_widget_get_allocated_height(widget);
|
||||||
|
|
||||||
|
gtk_render_background(context, cr, 0, 0, width, height);
|
||||||
|
gtk_render_frame(context, cr, 0, 0, width, height);
|
||||||
|
|
||||||
|
cairo_surface_t *surface = cairo_image_surface_create_for_data(
|
||||||
|
(unsigned char *) window->tileset_buffer,
|
||||||
|
CAIRO_FORMAT_RGB24,
|
||||||
|
256,
|
||||||
|
192,
|
||||||
|
cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, 256)
|
||||||
|
);
|
||||||
|
|
||||||
|
cairo_scale(cr, 2.0, 2.0);
|
||||||
|
cairo_set_source_surface(cr, surface, 0, 0);
|
||||||
|
cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
|
||||||
|
cairo_paint(cr);
|
||||||
|
|
||||||
|
if (gtk_toggle_button_get_active(window->tileset_toggle_grid_button)) {
|
||||||
|
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.25);
|
||||||
|
cairo_set_line_width(cr, 1);
|
||||||
|
|
||||||
|
const int divisions_x = 256 / 8;
|
||||||
|
const int divisions_y = 192 / 8;
|
||||||
|
|
||||||
|
for (int i = 0; i < divisions_x; i++) {
|
||||||
|
const int j = 256 * i;
|
||||||
|
|
||||||
|
cairo_move_to(cr, j / divisions_x, 0);
|
||||||
|
cairo_line_to(cr, j / divisions_x, 192);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < divisions_y; i++) {
|
||||||
|
const int j = 192 * i;
|
||||||
|
|
||||||
|
cairo_move_to(cr, 0, j / divisions_y);
|
||||||
|
cairo_line_to(cr, 256, j / divisions_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_stroke(cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean draw_tilemap_canvas(GtkWidget *widget, cairo_t *cr, VramViewerWindow *window) {
|
||||||
|
GtkStyleContext *context = gtk_widget_get_style_context(widget);
|
||||||
|
int width = gtk_widget_get_allocated_width(widget);
|
||||||
|
int height = gtk_widget_get_allocated_height(widget);
|
||||||
|
|
||||||
|
gtk_render_background(context, cr, 0, 0, width, height);
|
||||||
|
gtk_render_frame(context, cr, 0, 0, width, height);
|
||||||
|
|
||||||
|
cairo_surface_t *surface = cairo_image_surface_create_for_data(
|
||||||
|
(unsigned char *) window->tilemap_buffer,
|
||||||
|
CAIRO_FORMAT_RGB24,
|
||||||
|
256,
|
||||||
|
256,
|
||||||
|
cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, 256)
|
||||||
|
);
|
||||||
|
|
||||||
|
cairo_scale(cr, 2.0, 2.0);
|
||||||
|
cairo_set_source_surface(cr, surface, 0, 0);
|
||||||
|
cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
|
||||||
|
cairo_paint(cr);
|
||||||
|
|
||||||
|
if (gtk_toggle_button_get_active(window->tilemap_toggle_grid_button)) {
|
||||||
|
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.25);
|
||||||
|
cairo_set_line_width(cr, 1);
|
||||||
|
|
||||||
|
const int divisions = 256 / 8;
|
||||||
|
|
||||||
|
for (int i = 0; i < divisions; i++) {
|
||||||
|
const int j = 256 * i;
|
||||||
|
|
||||||
|
cairo_move_to(cr, j / divisions, 0);
|
||||||
|
cairo_line_to(cr, j / divisions, 256);
|
||||||
|
cairo_move_to(cr, 0, j / divisions);
|
||||||
|
cairo_line_to(cr, 256, j / divisions);
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_stroke(cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gtk_toggle_button_get_active(window->tilemap_toggle_scrolling_button)) {
|
||||||
|
cairo_rectangle(cr, -2, -2, width + 2, height + 2);
|
||||||
|
|
||||||
|
for (unsigned x = 0; x < 2; x++) {
|
||||||
|
for (unsigned y = 0; y < 2; y++) {
|
||||||
|
Rect rect = window->scroll_rect;
|
||||||
|
rect.x -= 256 * x;
|
||||||
|
rect.y -= 256 * y;
|
||||||
|
|
||||||
|
cairo_rectangle(cr, rect.x, rect.y, rect.width, rect.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
|
||||||
|
cairo_set_line_width(cr, 2);
|
||||||
|
cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
|
||||||
|
cairo_set_source_rgba(cr, 0.2, 0.2, 0.2, 0.5);
|
||||||
|
cairo_fill_preserve(cr);
|
||||||
|
cairo_clip_preserve(cr);
|
||||||
|
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.6);
|
||||||
|
cairo_stroke(cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean tileset_canvas_motion(GtkWidget *widget, GdkEventMotion *event, VramViewerWindow *window) {
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
if (event->is_hint) {
|
||||||
|
gdk_window_get_pointer(event->window, &x, &y, NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x = event->x;
|
||||||
|
y = event->y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compensate for our canvas scale
|
||||||
|
x /= 2;
|
||||||
|
y /= 2;
|
||||||
|
|
||||||
|
uint8_t bank = x >= 128? 1 : 0;
|
||||||
|
x &= 127;
|
||||||
|
uint16_t tile = x / 8 + y / 8 * 16;
|
||||||
|
|
||||||
|
const char *format =
|
||||||
|
"Tile number"
|
||||||
|
" <span font_family=\"monospace\">$%02x</span>"
|
||||||
|
" at"
|
||||||
|
" <span font_family=\"monospace\">%d:$%04x</span>";
|
||||||
|
|
||||||
|
g_autofree char *markup = g_markup_printf_escaped(
|
||||||
|
format,
|
||||||
|
tile & 0xFF,
|
||||||
|
bank, 0x8000 + tile * 0x10
|
||||||
|
);
|
||||||
|
|
||||||
|
gtk_label_set_markup(window->status, markup);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean tilemap_canvas_motion(GtkWidget *widget, GdkEventMotion *event, VramViewerWindow *window) {
|
||||||
|
if (!window->gb_vram) {
|
||||||
|
gtk_label_set_text(window->status, "");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
if (event->is_hint) {
|
||||||
|
gdk_window_get_pointer(event->window, &x, &y, NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x = event->x;
|
||||||
|
y = event->y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compensate for our canvas scale
|
||||||
|
x /= 2;
|
||||||
|
y /= 2;
|
||||||
|
|
||||||
|
uint16_t map_offset = x / 8 + y / 8 * 32;
|
||||||
|
uint16_t map_base = 0x1800;
|
||||||
|
|
||||||
|
GB_map_type_t map_type = GB_MAP_AUTO;
|
||||||
|
const gchar *map_type_id = vram_viewer_get_tilemap_type_id(window);
|
||||||
|
if (g_strcmp0("auto", map_type_id) != 0) {
|
||||||
|
map_type = (g_strcmp0("9800", map_type_id) == 0)? GB_MAP_9800 : GB_MAP_9C00;
|
||||||
|
}
|
||||||
|
|
||||||
|
GB_tileset_type_t tileset_type = GB_TILESET_AUTO;
|
||||||
|
const gchar *tileset_type_id = vram_viewer_get_tileset_type_id(window);
|
||||||
|
if (g_strcmp0("auto", tileset_type_id) != 0) {
|
||||||
|
tileset_type = (g_strcmp0("8800", tileset_type_id) == 0)? GB_TILESET_8800 : GB_TILESET_8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map_type == GB_MAP_9C00 || (map_type == GB_MAP_AUTO && window->gb_lcdc & 0x08)) {
|
||||||
|
map_base = 0x1c00;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tileset_type == GB_TILESET_AUTO) {
|
||||||
|
tileset_type = (window->gb_lcdc & 0x10)? GB_TILESET_8800 : GB_TILESET_8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t tile = window->gb_vram[map_base + map_offset];
|
||||||
|
uint16_t tile_address = 0;
|
||||||
|
if (tileset_type == GB_TILESET_8000) {
|
||||||
|
tile_address = 0x8000 + tile * 0x10;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tile_address = 0x9000 + (int8_t)tile * 0x10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->is_cgb) {
|
||||||
|
uint8_t attributes = window->gb_vram[map_base + map_offset + 0x2000];
|
||||||
|
|
||||||
|
const char *format =
|
||||||
|
"Tile number"
|
||||||
|
" <span font_family=\"monospace\">$%02x</span>"
|
||||||
|
" <span font_family=\"monospace\">(%d:$%04x)</span>"
|
||||||
|
" at map address"
|
||||||
|
" <span font_family=\"monospace\">$%04x</span>"
|
||||||
|
" (Attributes: <span font_family=\"monospace\">%c%c%c%d%d</span>)";
|
||||||
|
|
||||||
|
g_autofree char *markup = g_markup_printf_escaped(
|
||||||
|
format,
|
||||||
|
tile,
|
||||||
|
attributes & 0x8? 1 : 0,
|
||||||
|
tile_address,
|
||||||
|
0x8000 + map_base + map_offset,
|
||||||
|
(attributes & 0x80) ? 'P' : '-',
|
||||||
|
(attributes & 0x40) ? 'V' : '-',
|
||||||
|
(attributes & 0x20) ? 'H' : '-',
|
||||||
|
attributes & 0x8? 1 : 0,
|
||||||
|
attributes & 0x7
|
||||||
|
);
|
||||||
|
|
||||||
|
gtk_label_set_markup(window->status, markup);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const char *format =
|
||||||
|
"Tile number"
|
||||||
|
" <span font_family=\"monospace\">$%02x ($%04x)</span>"
|
||||||
|
" at map address"
|
||||||
|
" <span font_family=\"monospace\">$%04x</span>";
|
||||||
|
|
||||||
|
g_autofree char *markup = g_markup_printf_escaped(
|
||||||
|
format,
|
||||||
|
tile,
|
||||||
|
tile_address,
|
||||||
|
0x8000 + map_base + map_offset
|
||||||
|
);
|
||||||
|
|
||||||
|
gtk_label_set_markup(window->status, markup);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vram_viewer_window_init(VramViewerWindow *window) {
|
||||||
|
gtk_widget_init_template(GTK_WIDGET(window));
|
||||||
|
|
||||||
|
window->tileset_buffer = g_new0(uint32_t, tileset_buffer_length);
|
||||||
|
window->tilemap_buffer = g_new0(uint32_t, tilemap_buffer_length);
|
||||||
|
|
||||||
|
window->is_cgb = false;
|
||||||
|
window->oam_count = 0;
|
||||||
|
window->oam_height = 0;
|
||||||
|
|
||||||
|
gtk_widget_add_events(GTK_WIDGET(window->tileset_canvas), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
|
||||||
|
gtk_widget_add_events(GTK_WIDGET(window->tilemap_canvas), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
|
||||||
|
|
||||||
|
set_combo_box_row_separator_func(GTK_CONTAINER(window));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vram_viewer_finalize(GObject *object) {
|
||||||
|
VramViewerWindow *window = (VramViewerWindow *) object;
|
||||||
|
|
||||||
|
g_free(window->tilemap_buffer);
|
||||||
|
g_free(window->tileset_buffer);
|
||||||
|
window->gb_vram = NULL;
|
||||||
|
|
||||||
|
G_OBJECT_CLASS(vram_viewer_window_parent_class)->finalize(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vram_viewer_window_class_init(VramViewerWindowClass *class) {
|
||||||
|
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), RESOURCE_PREFIX "ui/vram_viewer_window.ui");
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), VramViewerWindow, stack);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), VramViewerWindow, tileset_palette_selector);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), VramViewerWindow, tileset_toggle_grid_button);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), VramViewerWindow, tileset_canvas);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), VramViewerWindow, tilemap_palette_selector);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), VramViewerWindow, tilemap_tilemap_selector);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), VramViewerWindow, tilemap_toggle_grid_button);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), VramViewerWindow, tilemap_toggle_scrolling_button);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), VramViewerWindow, tilemap_tileset_selector);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), VramViewerWindow, tilemap_canvas);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), VramViewerWindow, sprites);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), VramViewerWindow, palettes);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), VramViewerWindow, palette_cell_renderer_0);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), VramViewerWindow, palette_cell_renderer_1);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), VramViewerWindow, palette_cell_renderer_2);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), VramViewerWindow, palette_cell_renderer_3);
|
||||||
|
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), VramViewerWindow, status);
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), visible_tab_changed);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), draw_tileset_canvas);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), draw_tilemap_canvas);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), tileset_canvas_motion);
|
||||||
|
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), tilemap_canvas_motion);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS(class)->finalize = vram_viewer_finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
VramViewerWindow *vram_viewer_window_new(void) {
|
||||||
|
return g_object_new(VRAM_VIEWER_WINDOW_TYPE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
const gchar *vram_viewer_active_tab_name(VramViewerWindow *window) {
|
||||||
|
return gtk_stack_get_visible_child_name(window->stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
const gchar *vram_viewer_get_tileset_palette_id(VramViewerWindow *window) {
|
||||||
|
return gtk_combo_box_get_active_id(GTK_COMBO_BOX(window->tileset_palette_selector));
|
||||||
|
}
|
||||||
|
|
||||||
|
const gchar *vram_viewer_get_tilemap_palette_id(VramViewerWindow *window) {
|
||||||
|
return gtk_combo_box_get_active_id(GTK_COMBO_BOX(window->tilemap_palette_selector));
|
||||||
|
}
|
||||||
|
|
||||||
|
const gchar *vram_viewer_get_tilemap_type_id(VramViewerWindow *window) {
|
||||||
|
return gtk_combo_box_get_active_id(GTK_COMBO_BOX(window->tilemap_tilemap_selector));
|
||||||
|
}
|
||||||
|
|
||||||
|
const gchar *vram_viewer_get_tileset_type_id(VramViewerWindow *window) {
|
||||||
|
return gtk_combo_box_get_active_id(GTK_COMBO_BOX(window->tilemap_tileset_selector));
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean update_sprite_list(VramViewerWindow *window) {
|
||||||
|
GtkTreeIter iter;
|
||||||
|
GtkTreeModel *model = gtk_tree_view_get_model(window->sprites);
|
||||||
|
GtkListStore *store;
|
||||||
|
|
||||||
|
if (!model) {
|
||||||
|
GtkListStore *new_store = gtk_list_store_new(7,
|
||||||
|
GDK_TYPE_PIXBUF, // Preview image
|
||||||
|
G_TYPE_STRING, // X position
|
||||||
|
G_TYPE_STRING, // Y position
|
||||||
|
G_TYPE_STRING, // Tile
|
||||||
|
G_TYPE_STRING, // Tile Address
|
||||||
|
G_TYPE_STRING, // OAM Address
|
||||||
|
G_TYPE_STRING // Attributes
|
||||||
|
);
|
||||||
|
|
||||||
|
gtk_tree_view_set_model(window->sprites, GTK_TREE_MODEL(new_store));
|
||||||
|
store = new_store;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
store = GTK_LIST_STORE(model);
|
||||||
|
gtk_list_store_clear(store);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
|
||||||
|
|
||||||
|
for (unsigned row = 0; row < window->oam_count; ++row) {
|
||||||
|
g_autoptr(GBytes) bytes = g_bytes_new(window->oam_info[row].image, 128 * sizeof(uint32_t));
|
||||||
|
g_autoptr(GdkPixbuf) pixbuf = gdk_pixbuf_new_from_bytes(
|
||||||
|
bytes,
|
||||||
|
GDK_COLORSPACE_RGB, true, 8, 8, window->oam_height, 8 * sizeof(uint32_t)
|
||||||
|
);
|
||||||
|
|
||||||
|
g_autoptr(GdkPixbuf) dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, 8 * 2, window->oam_height * 2);
|
||||||
|
|
||||||
|
gdk_pixbuf_scale(pixbuf, dest,
|
||||||
|
0, 0, 8 * 2, window->oam_height * 2,
|
||||||
|
0, 0, 2.0, 2.0,
|
||||||
|
GDK_INTERP_NEAREST
|
||||||
|
);
|
||||||
|
|
||||||
|
g_autofree gchar *str_1 = g_strdup_printf("%i", window->oam_info[row].x - 8);
|
||||||
|
g_autofree gchar *str_2 = g_strdup_printf("%i", window->oam_info[row].y - 16);
|
||||||
|
g_autofree gchar *str_3 = g_strdup_printf("$%02x", window->oam_info[row].tile);
|
||||||
|
g_autofree gchar *str_4 = g_strdup_printf("$%04x", 0x8000 + window->oam_info[row].tile * 0x10);
|
||||||
|
g_autofree gchar *str_5 = g_strdup_printf("$%04x", window->oam_info[row].oam_addr);
|
||||||
|
g_autofree gchar *str_6 = window->is_cgb
|
||||||
|
? g_strdup_printf("%c%c%c%d%d",
|
||||||
|
window->oam_info[row].flags & 0x80? 'P' : '-',
|
||||||
|
window->oam_info[row].flags & 0x40? 'Y' : '-',
|
||||||
|
window->oam_info[row].flags & 0x20? 'X' : '-',
|
||||||
|
window->oam_info[row].flags & 0x08? 1 : 0,
|
||||||
|
window->oam_info[row].flags & 0x07)
|
||||||
|
: g_strdup_printf("%c%c%c%d",
|
||||||
|
window->oam_info[row].flags & 0x80? 'P' : '-',
|
||||||
|
window->oam_info[row].flags & 0x40? 'Y' : '-',
|
||||||
|
window->oam_info[row].flags & 0x20? 'X' : '-',
|
||||||
|
window->oam_info[row].flags & 0x10? 1 : 0);
|
||||||
|
|
||||||
|
gtk_list_store_insert_with_values(store, &iter, -1,
|
||||||
|
0, dest,
|
||||||
|
1, str_1,
|
||||||
|
2, str_2,
|
||||||
|
3, str_3,
|
||||||
|
4, str_4,
|
||||||
|
5, str_5,
|
||||||
|
6, str_6,
|
||||||
|
-1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void palette_color_data_func(GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data_ptr) {
|
||||||
|
const gchar *title = gtk_tree_view_column_get_title(col);
|
||||||
|
const uint8_t color_index = g_ascii_strtoll(&title[6], NULL, 10);
|
||||||
|
const uint8_t column_index = 2 + (2 * color_index);
|
||||||
|
|
||||||
|
GValue color_val = G_VALUE_INIT;
|
||||||
|
gtk_tree_model_get_value(model, iter, column_index, &color_val);
|
||||||
|
gint color = g_value_get_int(&color_val);
|
||||||
|
gchar *color_string = g_strdup_printf("#%06x", color);
|
||||||
|
|
||||||
|
gint lightness = 0.299 * ((color >> 16) & 0xFF) + 0.587 * ((color >> 8) & 0xFF) + 0.114 * (color & 0xFF);
|
||||||
|
|
||||||
|
GValue color_str = G_VALUE_INIT;
|
||||||
|
g_value_init(&color_str, G_TYPE_STRING);
|
||||||
|
g_value_set_string(&color_str, color_string);
|
||||||
|
g_object_set_property(G_OBJECT(renderer), "background", &color_str);
|
||||||
|
|
||||||
|
GValue fg_color_str = G_VALUE_INIT;
|
||||||
|
g_value_init(&fg_color_str, G_TYPE_STRING);
|
||||||
|
g_value_set_static_string(&fg_color_str, (lightness > 0x7F)? "#000000" : "#FFFFFF");
|
||||||
|
g_object_set_property(G_OBJECT(renderer), "foreground", &fg_color_str);
|
||||||
|
|
||||||
|
g_value_unset(&color_val);
|
||||||
|
g_value_unset(&color_str);
|
||||||
|
g_value_unset(&fg_color_str);
|
||||||
|
g_free(color_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean update_palettes(VramViewerWindow *window) {
|
||||||
|
GtkTreeIter iter;
|
||||||
|
GtkTreeModel *model = gtk_tree_view_get_model(window->palettes);
|
||||||
|
GtkListStore *store;
|
||||||
|
|
||||||
|
if (!model) {
|
||||||
|
GtkListStore *new_store = gtk_list_store_new(9,
|
||||||
|
G_TYPE_STRING, // Name
|
||||||
|
|
||||||
|
G_TYPE_STRING, // Color 0 string
|
||||||
|
G_TYPE_INT, // Color 0 integer
|
||||||
|
|
||||||
|
G_TYPE_STRING, // Color 1 string
|
||||||
|
G_TYPE_INT, // Color 1 integer
|
||||||
|
|
||||||
|
G_TYPE_STRING, // Color 2 string
|
||||||
|
G_TYPE_INT, // Color 2 integer
|
||||||
|
|
||||||
|
G_TYPE_STRING, // Color 3 string
|
||||||
|
G_TYPE_INT // Color 3 integer
|
||||||
|
);
|
||||||
|
gtk_tree_view_set_model(window->palettes, GTK_TREE_MODEL(new_store));
|
||||||
|
store = new_store;
|
||||||
|
|
||||||
|
GtkTreeViewColumn *column_0 = gtk_tree_view_get_column(window->palettes, 1);
|
||||||
|
GtkTreeViewColumn *column_1 = gtk_tree_view_get_column(window->palettes, 2);
|
||||||
|
GtkTreeViewColumn *column_2 = gtk_tree_view_get_column(window->palettes, 3);
|
||||||
|
GtkTreeViewColumn *column_3 = gtk_tree_view_get_column(window->palettes, 4);
|
||||||
|
|
||||||
|
gtk_tree_view_column_set_cell_data_func(column_0, GTK_CELL_RENDERER(window->palette_cell_renderer_0), palette_color_data_func, NULL, NULL);
|
||||||
|
gtk_tree_view_column_set_cell_data_func(column_1, GTK_CELL_RENDERER(window->palette_cell_renderer_1), palette_color_data_func, NULL, NULL);
|
||||||
|
gtk_tree_view_column_set_cell_data_func(column_2, GTK_CELL_RENDERER(window->palette_cell_renderer_2), palette_color_data_func, NULL, NULL);
|
||||||
|
gtk_tree_view_column_set_cell_data_func(column_3, GTK_CELL_RENDERER(window->palette_cell_renderer_3), palette_color_data_func, NULL, NULL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
store = GTK_LIST_STORE(model);
|
||||||
|
gtk_list_store_clear(store);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
|
||||||
|
|
||||||
|
for (unsigned row = 0; row < 16; ++row) {
|
||||||
|
uint8_t offset = (row & 7) * 4;
|
||||||
|
|
||||||
|
uint16_t color_0 = (window->palette_data[row][((0 + offset) << 1) + 1] << 8) | window->palette_data[row][((0 + offset) << 1)];
|
||||||
|
uint16_t color_1 = (window->palette_data[row][((1 + offset) << 1) + 1] << 8) | window->palette_data[row][((1 + offset) << 1)];
|
||||||
|
uint16_t color_2 = (window->palette_data[row][((2 + offset) << 1) + 1] << 8) | window->palette_data[row][((2 + offset) << 1)];
|
||||||
|
uint16_t color_3 = (window->palette_data[row][((3 + offset) << 1) + 1] << 8) | window->palette_data[row][((3 + offset) << 1)];
|
||||||
|
|
||||||
|
g_autofree gchar *str_0 = g_strdup_printf("%s %d", row >=8 ? "Object" : "Background", row & 7);
|
||||||
|
g_autofree gchar *str_1 = g_strdup_printf("$%04x", color_0 & 0x7FFF);
|
||||||
|
g_autofree gchar *str_3 = g_strdup_printf("$%04x", color_1 & 0x7FFF);
|
||||||
|
g_autofree gchar *str_5 = g_strdup_printf("$%04x", color_2 & 0x7FFF);
|
||||||
|
g_autofree gchar *str_7 = g_strdup_printf("$%04x", color_3 & 0x7FFF);
|
||||||
|
|
||||||
|
gtk_list_store_insert_with_values(store, &iter, -1,
|
||||||
|
0, str_0,
|
||||||
|
1, str_1,
|
||||||
|
2, convert_color(color_0),
|
||||||
|
3, str_3,
|
||||||
|
4, convert_color(color_1),
|
||||||
|
5, str_5,
|
||||||
|
6, convert_color(color_2),
|
||||||
|
7, str_7,
|
||||||
|
8, convert_color(color_3),
|
||||||
|
-1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vram_viewer_update(VramViewerWindow *window, GB_gameboy_t *gb) {
|
||||||
|
if (!gtk_widget_is_visible(GTK_WIDGET(window))) return;
|
||||||
|
|
||||||
|
window->is_cgb = GB_is_cgb(gb);
|
||||||
|
window->gb_lcdc = ((uint8_t *)GB_get_direct_access(gb, GB_DIRECT_ACCESS_IO, NULL, NULL))[GB_IO_LCDC];
|
||||||
|
window->gb_vram = GB_get_direct_access(gb, GB_DIRECT_ACCESS_VRAM, NULL, NULL);
|
||||||
|
|
||||||
|
const gchar *active_tab_name = vram_viewer_active_tab_name(window);
|
||||||
|
|
||||||
|
if (g_strcmp0(active_tab_name, VRAM_VIEWER_TAB_TILESET) == 0) {
|
||||||
|
const gchar *palette_id = vram_viewer_get_tileset_palette_id(window);
|
||||||
|
|
||||||
|
GB_palette_type_t palette_type = g_str_has_prefix(palette_id, "bg")? GB_PALETTE_BACKGROUND : GB_PALETTE_OAM;
|
||||||
|
uint8_t palette_index = g_ascii_digit_value(palette_id[palette_type == GB_PALETTE_OAM ? 3 : 2]);
|
||||||
|
|
||||||
|
GB_draw_tileset(gb, window->tileset_buffer,
|
||||||
|
palette_type,
|
||||||
|
palette_index
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(active_tab_name, VRAM_VIEWER_TAB_TILEMAP) == 0) {
|
||||||
|
const gchar *palette_id = vram_viewer_get_tilemap_palette_id(window);
|
||||||
|
uint8_t palette_index = 0;
|
||||||
|
GB_palette_type_t palette_type = GB_PALETTE_AUTO;
|
||||||
|
|
||||||
|
if (g_strcmp0("auto", palette_id) != 0) {
|
||||||
|
palette_type = g_str_has_prefix(palette_id, "bg")? GB_PALETTE_BACKGROUND : GB_PALETTE_OAM;
|
||||||
|
palette_index = g_ascii_digit_value(palette_id[palette_type == GB_PALETTE_OAM ? 3 : 2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
GB_map_type_t map_type = GB_MAP_AUTO;
|
||||||
|
const gchar *map_type_id = vram_viewer_get_tilemap_type_id(window);
|
||||||
|
if (g_strcmp0("auto", map_type_id) != 0) {
|
||||||
|
map_type = (g_strcmp0("9800", map_type_id) == 0)? GB_MAP_9800 : GB_MAP_9C00;
|
||||||
|
}
|
||||||
|
|
||||||
|
GB_tileset_type_t tileset_type = GB_TILESET_AUTO;
|
||||||
|
const gchar *tileset_type_id = vram_viewer_get_tileset_type_id(window);
|
||||||
|
if (g_strcmp0("auto", tileset_type_id) != 0) {
|
||||||
|
tileset_type = (g_strcmp0("8800", tileset_type_id) == 0)? GB_TILESET_8800 : GB_TILESET_8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
GB_draw_tilemap(gb, window->tilemap_buffer,
|
||||||
|
palette_type,
|
||||||
|
palette_index,
|
||||||
|
map_type,
|
||||||
|
tileset_type
|
||||||
|
);
|
||||||
|
|
||||||
|
window->scroll_rect = (Rect){
|
||||||
|
GB_read_memory(gb, 0xFF00 | GB_IO_SCX),
|
||||||
|
GB_read_memory(gb, 0xFF00 | GB_IO_SCY),
|
||||||
|
160, 144
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(active_tab_name, VRAM_VIEWER_TAB_SPRITES) == 0) {
|
||||||
|
window->oam_count = GB_get_oam_info(gb, (GB_oam_info_t *)window->oam_info, &window->oam_height);
|
||||||
|
|
||||||
|
g_idle_add((GSourceFunc) update_sprite_list, window);
|
||||||
|
}
|
||||||
|
else if (g_strcmp0(active_tab_name, VRAM_VIEWER_TAB_PALETTES) == 0) {
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
for (unsigned row = 0; row < 16; ++row) {
|
||||||
|
uint8_t *palette_data = GB_get_direct_access(gb, row >= 8? GB_DIRECT_ACCESS_OBP : GB_DIRECT_ACCESS_BGP, &size, NULL);
|
||||||
|
memcpy(window->palette_data[row], palette_data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_idle_add((GSourceFunc) update_palettes, window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vram_viewer_clear(VramViewerWindow *window) {
|
||||||
|
g_idle_remove_by_data(window);
|
||||||
|
|
||||||
|
memset(window->tilemap_buffer, 0, tilemap_buffer_length * sizeof(uint32_t));
|
||||||
|
memset(window->tileset_buffer, 0, tileset_buffer_length * sizeof(uint32_t));
|
||||||
|
|
||||||
|
g_autoptr(GtkTreeModel) sprites_model = gtk_tree_view_get_model(window->sprites);
|
||||||
|
if (sprites_model) gtk_list_store_clear(GTK_LIST_STORE(sprites_model));
|
||||||
|
|
||||||
|
g_autoptr(GtkTreeModel) palettes_model = gtk_tree_view_get_model(window->palettes);
|
||||||
|
if (palettes_model) gtk_list_store_clear(GTK_LIST_STORE(palettes_model));
|
||||||
|
}
|
30
gtk3/widgets/vram_viewer_window.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef vram_viewer_window_h
|
||||||
|
#define vram_viewer_window_h
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <Core/gb.h>
|
||||||
|
|
||||||
|
#define VRAM_VIEWER_WINDOW_TYPE (vram_viewer_window_get_type())
|
||||||
|
G_DECLARE_FINAL_TYPE(VramViewerWindow, vram_viewer_window, SAMEBOY, VRAM_VIEWER_WINDOW, GtkWindow)
|
||||||
|
|
||||||
|
#define VRAM_VIEWER_TAB_TILESET "tileset"
|
||||||
|
#define VRAM_VIEWER_TAB_TILEMAP "tilemap"
|
||||||
|
#define VRAM_VIEWER_TAB_SPRITES "sprites"
|
||||||
|
#define VRAM_VIEWER_TAB_PALETTES "palettes"
|
||||||
|
|
||||||
|
VramViewerWindow *vram_viewer_window_new(void);
|
||||||
|
|
||||||
|
const gchar *vram_viewer_active_tab_name(VramViewerWindow *window);
|
||||||
|
|
||||||
|
const gchar *vram_viewer_get_tileset_palette_id(VramViewerWindow *window);
|
||||||
|
const gchar *vram_viewer_get_tilemap_palette_id(VramViewerWindow *window);
|
||||||
|
const gchar *vram_viewer_get_tilemap_type_id(VramViewerWindow *window);
|
||||||
|
const gchar *vram_viewer_get_tileset_type_id(VramViewerWindow *window);
|
||||||
|
|
||||||
|
uint32_t *vram_viewer_get_tileset_buffer(VramViewerWindow *window);
|
||||||
|
uint32_t *vram_viewer_get_tilemap_buffer(VramViewerWindow *window);
|
||||||
|
|
||||||
|
void vram_viewer_update(VramViewerWindow *window, GB_gameboy_t *gb);
|
||||||
|
void vram_viewer_clear(VramViewerWindow *window);
|
||||||
|
|
||||||
|
#endif
|