Compare commits

...

10 Commits

Author SHA1 Message Date
Fijxu 4eaedf8b7f Update 3DSController to modern libctru 2023-07-28 03:58:37 -04:00
Poke adfa864a99
Merge pull request #18 from Webbeh/master
Update README.md
2018-06-13 23:48:00 +09:30
Nicolas Glassey bd09cbb3f6
Update README.md 2018-06-13 16:14:41 +02:00
Poke 3d2b595a81
Merge pull request #14 from aprowe/master
Added Clamping to Joystick Values
2018-06-13 23:12:40 +09:30
Poke a184c5b707
Merge pull request #17 from Webbeh/master
Added Linux script with volume control
2018-06-13 23:06:43 +09:30
Weby 995b836824 Added Linux script with volume control 2018-06-13 12:47:18 +02:00
Alex Rowe f5bc0146d7 Added Clamping to Joystick Values
Added Clamp function to general.c
Now clamps all final joystick values to be from 0 - 32767 (2^15 - 1).

Output from the 3ds was giving a strange range on the values, even though the
code expected it to be in the range -128 to 128.

Was more like -146 to 146 on the c-stick, and -170 to 170 on the circle pad.
This may remove some of the resolution of the sticks, but increase compatability with programs.
2017-02-12 15:45:34 -06:00
Poke 63268cd32e Got CIA and 3DS building working
If I rename the .3ds to a .cxi citra runs it, so I guess that's working?
I don't have any way to test either of them properly though.
Hopefully they work.
The .rsf is from a template provided by daxtsu.
2015-11-12 20:55:03 +10:30
Poke b245090593 Version bump, fixed .ini instructions
Getting ready for a release I guess? Though CIA building isn't sorted
yet.
2015-11-12 14:51:43 +10:30
Poke 4a99a1ba4c Unified Pov styles, reorganised ini
New pref to choose between Pov or Keys for D Pad, making it work
similarly to C Pad, C Stick and Touch.
Will automatically check whether vJoy has 4-way Pov or Continuous Pov
enabled and choose the correct one to output.
2015-11-12 13:05:26 +10:30
25 changed files with 543 additions and 469 deletions

3
.gitignore vendored
View File

@ -1,9 +1,6 @@
3DS/build/
3DS/*.elf
3DS/*stripped.elf
3DS/*.smdh
3DS/*.3ds
3DS/*.cia
PC/build/
*.pnproj
*.pnps

BIN
3DS/3DSController.3ds Normal file

Binary file not shown.

Binary file not shown.

BIN
3DS/3DSController.cia Normal file

Binary file not shown.

BIN
3DS/3DSController.smdh Normal file

Binary file not shown.

View File

@ -47,7 +47,7 @@ CFLAGS := -g -Wall -O2 -mword-relocations \
-fms-extensions \
$(ARCH)
CFLAGS += $(INCLUDE) -DARM11 -D_3DS
CFLAGS += $(INCLUDE) -D__3DS__
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
@ -150,7 +150,7 @@ endif
$(OUTPUT).3dsx : $(OUTPUT).elf
$(OUTPUT).3ds : $(OUTPUT)stripped.elf
makerom -f cci -o $(OUTPUT).3ds -rsf "$(TOPDIR)/cxi/gw_workaround.rsf" -target d -exefslogo -elf $(OUTPUT)stripped.elf -icon "$(TOPDIR)/cxi/icon.icn" -banner "$(TOPDIR)/cxi/banner.bnr"
makerom -f cci -o $(OUTPUT).3ds -rsf "$(TOPDIR)/cxi/build_cia.rsf" -target t -exefslogo -elf $(OUTPUT)stripped.elf -icon "$(TOPDIR)/cxi/icon.icn" -banner "$(TOPDIR)/cxi/banner.bnr"
$(OUTPUT).cia : $(OUTPUT)stripped.elf
makerom -f cia -o $(OUTPUT).cia -elf $(OUTPUT)stripped.elf -rsf "$(TOPDIR)/cxi/build_cia.rsf" -icon "$(TOPDIR)/cxi/icon.icn" -banner "$(TOPDIR)/cxi/banner.bnr" -exefslogo -target t

134
3DS/compile_commands.json Normal file
View File

@ -0,0 +1,134 @@
[
{
"arguments": [
"/opt/devkitpro/devkitARM/bin/arm-none-eabi-gcc",
"-g",
"-Wall",
"-O2",
"-mword-relocations",
"-fomit-frame-pointer",
"-ffast-math",
"-fms-extensions",
"-march=armv6k",
"-mtune=mpcore",
"-mfloat-abi=hard",
"-I/home/user/3DSController/3DS/include",
"-I/opt/devkitpro/libctru/include",
"-I/home/user/3DSController/3DS/build",
"-I/opt/devkitpro/devkitARM/arm-none-eabi/include/",
"-D__3DS__",
"-c",
"-o",
"drawing.o",
"/home/user/3DSController/3DS/source/drawing.c"
],
"directory": "/home/user/3DSController/3DS/build",
"file": "/home/user/3DSController/3DS/source/drawing.c",
"output": "/home/user/3DSController/3DS/build/drawing.o"
},
{
"arguments": [
"/opt/devkitpro/devkitARM/bin/arm-none-eabi-gcc",
"-g",
"-Wall",
"-O2",
"-mword-relocations",
"-fomit-frame-pointer",
"-ffast-math",
"-fms-extensions",
"-march=armv6k",
"-mtune=mpcore",
"-mfloat-abi=hard",
"-I/home/user/3DSController/3DS/include",
"-I/opt/devkitpro/libctru/include",
"-I/home/user/3DSController/3DS/build",
"-D__3DS__",
"-c",
"-o",
"inet_pton.o",
"/home/user/3DSController/3DS/source/inet_pton.c"
],
"directory": "/home/user/3DSController/3DS/build",
"file": "/home/user/3DSController/3DS/source/inet_pton.c",
"output": "/home/user/3DSController/3DS/build/inet_pton.o"
},
{
"arguments": [
"/opt/devkitpro/devkitARM/bin/arm-none-eabi-gcc",
"-g",
"-Wall",
"-O2",
"-mword-relocations",
"-fomit-frame-pointer",
"-ffast-math",
"-fms-extensions",
"-march=armv6k",
"-mtune=mpcore",
"-mfloat-abi=hard",
"-I/home/user/3DSController/3DS/include",
"-I/opt/devkitpro/libctru/include",
"-I/home/user/3DSController/3DS/build",
"-D__3DS__",
"-c",
"-o",
"input.o",
"/home/user/3DSController/3DS/source/input.c"
],
"directory": "/home/user/3DSController/3DS/build",
"file": "/home/user/3DSController/3DS/source/input.c",
"output": "/home/user/3DSController/3DS/build/input.o"
},
{
"arguments": [
"/opt/devkitpro/devkitARM/bin/arm-none-eabi-gcc",
"-g",
"-Wall",
"-O2",
"-mword-relocations",
"-fomit-frame-pointer",
"-ffast-math",
"-fms-extensions",
"-march=armv6k",
"-mtune=mpcore",
"-mfloat-abi=hard",
"-I/home/user/3DSController/3DS/include",
"-I/opt/devkitpro/libctru/include",
"-I/home/user/3DSController/3DS/build",
"-D__3DS__",
"-c",
"-o",
"keyboard.o",
"/home/user/3DSController/3DS/source/keyboard.c"
],
"directory": "/home/user/3DSController/3DS/build",
"file": "/home/user/3DSController/3DS/source/keyboard.c",
"output": "/home/user/3DSController/3DS/build/keyboard.o"
},
{
"arguments": [
"/opt/devkitpro/devkitARM/bin/arm-none-eabi-gcc",
"-g",
"-Wall",
"-O2",
"-mword-relocations",
"-fomit-frame-pointer",
"-ffast-math",
"-fms-extensions",
"-march=armv6k",
"-mtune=mpcore",
"-mfloat-abi=hard",
"-I/home/user/3DSController/3DS/include",
"-I/opt/devkitpro/libctru/include",
"-I/home/user/3DSController/3DS/build",
"-I/opt/devkitpro/devkitARM/arm-none-eabi/include/",
"-D__3DS__",
"-c",
"-o",
"main.o",
"/home/user/3DSController/3DS/source/main.c"
],
"directory": "/home/user/3DSController/3DS/build",
"file": "/home/user/3DSController/3DS/source/main.c",
"output": "/home/user/3DSController/3DS/build/main.o"
}
]

View File

@ -1,97 +1,70 @@
BasicInfo:
Title : "3DS Controller"
CompanyCode : "00"
ProductCode : "CTR-N-3DSC"
ContentType : Application # Application / SystemUpdate / Manual / Child / Trial
Logo : Nintendo # Nintendo / Licensed / Distributed / iQue / iQueForSystem
Rom:
# Specifies the root path of the file system to include in the ROM.
# HostRoot : "$(ROMFS_ROOT)"
RomFs:
# Specifies the root path of the read only file system to include in the ROM.
RootPath : "$(ROMFS_ROOT)"
TitleInfo:
UniqueId : 0xf0fc2 # This was/is the first real homebrew app. I hope this TID range is not used by any retail game/app.
Category : Application # Application / SystemApplication / Applet / Firmware / Base / DlpChild / Demo / Contents / SystemContents / SharedContents / AddOnContents / Patch / AutoUpdateContents
CardInfo:
MediaSize : 512MB # 128MB / 256MB / 512MB / 1GB / 2GB / 4GB / 8GB / 16GB / 32GB
MediaType : Card1 # Card1 / Card2
CardDevice : NorFlash # NorFlash / None
Category : Application
UniqueId : 0xf0fc2
Option:
UseOnSD : true # true if App is to be installed to SD
EnableCompress : true # Compresses exefs code
FreeProductCode : true # Removes limitations on ProductCode
EnableCrypt : false # Enables encryption for NCCH and CIA
MediaFootPadding : false # If true CCI files are created with padding
ExeFs: # these are the program segments from the ELF, check your elf for the appropriate segment names
ReadOnly:
- .rodata
- RO
ReadWrite:
- .data
- RO
Text:
- .init
- .text
- STUP_ENTRY
PlainRegion: # only used with SDK ELFs
# - .module_id
EnableCrypt : false # Enables encryption for NCCH and CIA
EnableCompress : true # Compresses where applicable (currently only exefs:/.code)
AccessControlInfo:
# UseOtherVariationSaveData : true
# UseExtSaveData : true
# ExtSaveDataId: 0xffffffff
# SystemSaveDataId1: 0x220
# SystemSaveDataId2: 0x00040010
# OtherUserSaveDataId1: 0x220
# OtherUserSaveDataId2: 0x330
# OtherUserSaveDataId3: 0x440
# UseExtendedSaveDataAccessControl: true
# AccessibleSaveDataIds: [0x101, 0x202, 0x303, 0x404, 0x505, 0x606]
CoreVersion : 2
# Exheader Format Version
DescVersion : 2
# Minimum Required Kernel Version (below is for 4.5.0)
ReleaseKernelMajor : "02"
ReleaseKernelMinor : "33"
# ExtData
UseExtSaveData : false # enables ExtData
#ExtSaveDataId : 0x300 # only set this when the ID is different to the UniqueId
# FS:USER Archive Access Permissions
# Uncomment as required
FileSystemAccess:
# - CategorySystemApplication
# - CategoryHardwareCheck
# - CategoryFileSystemTool
- Debug
# - TwlCardBackup
# - TwlNandData
# - Boss
#- CategorySystemApplication
#- CategoryHardwareCheck
- CategoryFileSystemTool
#- Debug
#- TwlCardBackup
#- TwlNandData
#- Boss
- DirectSdmc
# - Core
# - CtrNandRo
# - CtrNandRw
# - CtrNandRoWrite
# - CategorySystemSettings
# - CardBoard
# - ExportImportIvs
# - DirectSdmcWrite
# - SwitchCleanup
# - SaveDataMove
# - Shop
# - Shell
# - CategoryHomeMenu
IoAccessControl:
# - FsMountNand
# - FsMountNandRoWrite
# - FsMountTwln
# - FsMountWnand
# - FsMountCardSpi
# - UseSdif3
# - CreateSeed
# - UseCardSpi
#- Core
#- CtrNandRo
#- CtrNandRw
#- CtrNandRoWrite
#- CategorySystemSettings
#- CardBoard
#- ExportImportIvs
#- DirectSdmcWrite
#- SwitchCleanup
#- SaveDataMove
#- Shop
#- Shell
#- CategoryHomeMenu
# Process Settings
MemoryType : Application # Application/System/Base
SystemMode : 64MB # 64MB(Default)/96MB/80MB/72MB/32MB
IdealProcessor : 0
AffinityMask : 1
Priority : 16
MaxCpu : 0x9E # Default
HandleTableSize : 0x200
DisableDebug : true
EnableForceDebug : false
CanWriteSharedPage : true
@ -101,21 +74,23 @@ AccessControlInfo:
CanShareDeviceMemory : true
RunnableOnSleep : false
SpecialMemoryArrange : true
CoreVersion : 2
DescVersion : 2
ReleaseKernelMajor : "02"
ReleaseKernelMinor : "33"
MemoryType : Application # Application / System / Base
HandleTableSize: 512
IORegisterMapping:
- 1ff50000-1ff57fff
- 1ff70000-1ff77fff
# New3DS Exclusive Process Settings
SystemModeExt : Legacy # Legacy(Default)/124MB/178MB Legacy:Use Old3DS SystemMode
CpuSpeed : 804MHz # 256MHz(Default)/804MHz
EnableL2Cache : true # false(default)/true
CanAccessCore2 : true
# Virtual Address Mappings
IORegisterMapping:
- 1ff00000-1ff7ffff # DSP memory
MemoryMapping:
- 1f000000-1f5fffff:r
- 1f000000-1f5fffff:r # VRAM
# Accessible SVCs, <Name>:<ID>
SystemCallAccess:
ArbitrateAddress: 34
Backdoor: 123
Break: 60
CancelTimer: 28
ClearEvent: 25
@ -123,6 +98,7 @@ AccessControlInfo:
CloseHandle: 35
ConnectToPort: 45
ControlMemory: 1
ControlProcessMemory: 112
CreateAddressArbiter: 33
CreateEvent: 23
CreateMemoryBlock: 30
@ -166,25 +142,28 @@ AccessControlInfo:
UnmapMemoryBlock: 32
WaitSynchronization1: 36
WaitSynchronizationN: 37
InterruptNumbers:
ServiceAccessControl:
# Service List
# Maximum 34 services (32 if firmware is prior to 9.6.0)
ServiceAccessControl:
- APT:U
- $hioFIO
- $hostio0
- $hostio1
- ac:u
- am:net
- boss:U
- cam:u
- cecd:u
- cfg:nor
- cfg:u
- dlp:FKCL
- dlp:SRVR
- csnd:SND
- dsp::DSP
- frd:u
- fs:USER
- gsp::Gpu
- hid:USER
- http:C
- ir:rst
- ir:u
- ir:USER
- mic:u
- ndm:u
- news:u
@ -194,43 +173,47 @@ AccessControlInfo:
- soc:U
- ssl:C
- y2r:u
- ldr:ro
- ir:USER
- ir:rst
SystemControlInfo:
SaveDataSize: 0KB # It doesn't use any save data.
SaveDataSize: 0KB # Change if the app uses savedata
RemasterVersion: 2
StackSize: 0x40000
# JumpId: 0
# Modules that run services listed above should be included below
# Maximum 48 dependencies
# <module name>:<module titleid>
Dependency:
ac: 0x0004013000002402L
am: 0x0004013000001502L
boss: 0x0004013000003402L
camera: 0x0004013000001602L
cecd: 0x0004013000002602L
cfg: 0x0004013000001702L
codec: 0x0004013000001802L
csnd: 0x0004013000002702L
dlp: 0x0004013000002802L
dsp: 0x0004013000001a02L
friends: 0x0004013000003202L
gpio: 0x0004013000001b02L
gsp: 0x0004013000001c02L
hid: 0x0004013000001d02L
http: 0x0004013000002902L
i2c: 0x0004013000001e02L
ir: 0x0004013000003302L
mcu: 0x0004013000001f02L
mic: 0x0004013000002002L
ndm: 0x0004013000002b02L
news: 0x0004013000003502L
nim: 0x0004013000002c02L
nwm: 0x0004013000002d02L
pdn: 0x0004013000002102L
ps: 0x0004013000003102L
ptm: 0x0004013000002202L
ro: 0x0004013000003702L
socket: 0x0004013000002e02L
spi: 0x0004013000002302L
ssl: 0x0004013000002f02L
ac: 0x0004013000002402
act: 0x0004013000003802
am: 0x0004013000001502
boss: 0x0004013000003402
camera: 0x0004013000001602
cecd: 0x0004013000002602
cfg: 0x0004013000001702
codec: 0x0004013000001802
csnd: 0x0004013000002702
dlp: 0x0004013000002802
dsp: 0x0004013000001a02
friends: 0x0004013000003202
gpio: 0x0004013000001b02
gsp: 0x0004013000001c02
hid: 0x0004013000001d02
http: 0x0004013000002902
i2c: 0x0004013000001e02
ir: 0x0004013000003302
mcu: 0x0004013000001f02
mic: 0x0004013000002002
ndm: 0x0004013000002b02
news: 0x0004013000003502
nfc: 0x0004013000004002
nim: 0x0004013000002c02
nwm: 0x0004013000002d02
pdn: 0x0004013000002102
ps: 0x0004013000003102
ptm: 0x0004013000002202
qtm: 0x0004013020004202
ro: 0x0004013000003702
socket: 0x0004013000002e02
spi: 0x0004013000002302
ssl: 0x0004013000002f02

View File

@ -1,235 +0,0 @@
BasicInfo:
Title : "3DS Controller"
CompanyCode : "00"
ProductCode : "CTR-N-3DSC"
ContentType : Application
Logo : Nintendo # Nintendo / Licensed / Distributed / iQue / iQueForSystem
Rom:
# Specifies the root path of the file system to include in the ROM.
#HostRoot : "romfs"
TitleInfo:
UniqueId : 0xf0fc2
Category : Application
CardInfo:
MediaSize : 128MB # 128MB / 256MB / 512MB / 1GB / 2GB / 4GB
MediaType : Card1 # Card1 / Card2
CardDevice : NorFlash # NorFlash(Pick this if you use savedata) / None
Option:
FreeProductCode : true # Removes limitations on ProductCode
MediaFootPadding : false # If true CCI files are created with padding
EnableCrypt : true # Enables encryption for NCCH and CIA
EnableCompress : true # Compresses exefs code
ExeFs: # these are the program segments from the ELF, check your elf for the appropriate segment names
ReadOnly:
- .rodata
- RO
ReadWrite:
- .data
- RO
Text:
- .init
- .text
- STUP_ENTRY
PlainRegion: # only used with SDK ELFs
- .module_id
AccessControlInfo:
#UseExtSaveData : true
#ExtSaveDataId: 0xff3ff
#UseExtendedSaveDataAccessControl: true
#AccessibleSaveDataIds: [0x101, 0x202, 0x303, 0x404, 0x505, 0x606]
SystemControlInfo:
SaveDataSize: 128KB
RemasterVersion: 0
StackSize: 0x40000
# DO NOT EDIT BELOW HERE OR PROGRAMS WILL NOT LAUNCH (most likely)
AccessControlInfo:
FileSystemAccess:
- Debug
- DirectSdmc
- DirectSdmcWrite
IdealProcessor : 0
AffinityMask : 1
Priority : 16
MaxCpu : 0x9E # Default
CoreVersion : 2
DescVersion : 2
ReleaseKernelMajor : "02"
ReleaseKernelMinor : "33"
MemoryType : Application
HandleTableSize: 512
IORegisterMapping:
- 1ff50000-1ff57fff
- 1ff70000-1ff77fff
MemoryMapping:
- 1f000000-1f5fffff:r
SystemCallAccess:
ArbitrateAddress: 34
Break: 60
CancelTimer: 28
ClearEvent: 25
ClearTimer: 29
CloseHandle: 35
ConnectToPort: 45
ControlMemory: 1
CreateAddressArbiter: 33
CreateEvent: 23
CreateMemoryBlock: 30
CreateMutex: 19
CreateSemaphore: 21
CreateThread: 8
CreateTimer: 26
DuplicateHandle: 39
ExitProcess: 3
ExitThread: 9
GetCurrentProcessorNumber: 17
GetHandleInfo: 41
GetProcessId: 53
GetProcessIdOfThread: 54
GetProcessIdealProcessor: 6
GetProcessInfo: 43
GetResourceLimit: 56
GetResourceLimitCurrentValues: 58
GetResourceLimitLimitValues: 57
GetSystemInfo: 42
GetSystemTick: 40
GetThreadContext: 59
GetThreadId: 55
GetThreadIdealProcessor: 15
GetThreadInfo: 44
GetThreadPriority: 11
MapMemoryBlock: 31
OutputDebugString: 61
QueryMemory: 2
ReleaseMutex: 20
ReleaseSemaphore: 22
SendSyncRequest1: 46
SendSyncRequest2: 47
SendSyncRequest3: 48
SendSyncRequest4: 49
SendSyncRequest: 50
SetThreadPriority: 12
SetTimer: 27
SignalEvent: 24
SleepThread: 10
UnmapMemoryBlock: 32
WaitSynchronization1: 36
WaitSynchronizationN: 37
InterruptNumbers:
ServiceAccessControl:
- APT:U
- $hioFIO
- $hostio0
- $hostio1
- ac:u
- boss:U
- cam:u
- cecd:u
- cfg:u
- dlp:FKCL
- dlp:SRVR
- dsp::DSP
- frd:u
- fs:USER
- gsp::Gpu
- hid:USER
- http:C
- mic:u
- ndm:u
- news:u
- nwm::UDS
- ptm:u
- pxi:dev
- soc:U
- ssl:C
- y2r:u
- ldr:ro
- ir:USER
- ir:rst
SystemControlInfo:
Dependency:
ac: 0x0004013000002402L
am: 0x0004013000001502L
boss: 0x0004013000003402L
camera: 0x0004013000001602L
cecd: 0x0004013000002602L
cfg: 0x0004013000001702L
codec: 0x0004013000001802L
csnd: 0x0004013000002702L
dlp: 0x0004013000002802L
dsp: 0x0004013000001a02L
friends: 0x0004013000003202L
gpio: 0x0004013000001b02L
gsp: 0x0004013000001c02L
hid: 0x0004013000001d02L
http: 0x0004013000002902L
i2c: 0x0004013000001e02L
ir: 0x0004013000003302L
mcu: 0x0004013000001f02L
mic: 0x0004013000002002L
ndm: 0x0004013000002b02L
news: 0x0004013000003502L
nim: 0x0004013000002c02L
nwm: 0x0004013000002d02L
pdn: 0x0004013000002102L
ps: 0x0004013000003102L
ptm: 0x0004013000002202L
ro: 0x0004013000003702L
socket: 0x0004013000002e02L
spi: 0x0004013000002302L
ssl: 0x0004013000002f02L
CommonHeaderKey:
D: |
jL2yO86eUQnYbXIrzgFVMm7FVze0LglZ2f5g+c42hWoEdnb5BOotaMQPBfqt
aUyAEmzQPaoi/4l4V+hTJRXQfthVRqIEx27B84l8LA6Tl5Fy9PaQaQ+4yRfP
g6ylH2l0EikrIVjy2uMlFgl0QJCrG+QGKHftxhaGCifdAwFNmiZuyJ/TmktZ
0RCb66lYcr2h/p2G7SnpKUliS9h9KnpmG+UEgVYQUK+4SCfByUa9PxYGpT0E
nw1UcRz0gsBmdOqcgzwnAd9vVqgb42hVn6uQZyAl+j1RKiMWywZarazIR/k5
Lmr4+groimSEa+3ajyoIho9WaWTDmFU3mkhA2tUDIQ==
Exponent: |
AQAB
Modulus: |
zwCcsyCgMkdlieCgQMVXA6X2jmb1ICjup0Q+jk/AydPkOgsx7I/MjUymFEkU
vgXBtCKtzh3NKXtFFuW51tJ60GPOabLKuG0Qm5li+UXALrWhzWuvd5vv2FZI
dTQCbrq/MFS/M02xNtwqzWiBjE/LwqIdbrDAAvX4HGy0ydaQJ1DKYeQeph5D
lAGBw2nQ4izXhhuLaU3w8VQkIJHdhxIKI5gJY/20AGkG0vHD553Mh5kBINrWp
CRYmmJS8DCYbAiQtKbkeUfzHViGTZuj6PwaY8Mv39PGO47a++pt45IUyCEs4/
LjMS72cyfo8tU4twRGp76SFGYejYj3wGC1f/POQw==
Signature: |
BOPR0jL0BOV5Zx502BuPbOvi/hvOq5ID8Dz1MQfOjkey6FKP/6cb4f9YXpm6c
ZCHAZLo0GduKdMepiKPUq1rsbbAxkRdQdjOOusEWoxNA58x3E4373tCAhlqM2
DvuQERrIIQ/XnYLV9C3uw4efZwhFqog1jvVyoEHpuvs8xnYtGbsKQ8FrgLwXv
pOZYy9cSgq+jqLy2D9IxiowPcbq2cRlbW9d2xlUfpq0AohyuXQhpxn7d9RUor
9veoARRAdxRJK12EpcSoEM1LhTRYdJnSRCY3x3p6YIV3c+l1sWvaQwKt0sZ/U
8TTDx2gb9g7r/+U9icneu/zlqUpSkexCS009Q==
Descriptor: |
AP///wAABAACAAAAAAAFGJ4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiIAAAAAAAABBUFQ6VQAAACRo
aW9GSU8AJGhvc3RpbzAkaG9zdGlvMWFjOnUAAAAAYm9zczpVAABjYW06dQAA
AGNlY2Q6dQAAY2ZnOnUAAABkbHA6RktDTGRscDpTUlZSZHNwOjpEU1BmcmQ6
dQAAAGZzOlVTRVIAZ3NwOjpHcHVoaWQ6VVNFUmh0dHA6QwAAbWljOnUAAABu
ZG06dQAAAG5ld3M6dQAAbndtOjpVRFNwdG06dQAAAHB4aTpkZXYAc29jOlUA
AABzc2w6QwAAAHkycjp1AAAAbGRyOnJvAABpcjpVU0VSAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAABOn/rw/7//8ec/APIA8JH/APaR/1D/gf9Y/4H/cP+B/3j/gf8B
AQD/AAIA/iECAPz/////////////////////////////////////////////
////////////////////////////////////////AAAAAAAAAAAAAAAAAAAA
AAADAAAAAAAAAAAAAAAAAAI=

View File

@ -1,5 +1,6 @@
#pragma once
#include "3ds/types.h"
#ifndef REG_LCDBACKLIGHTMAIN
#define REG_LCDBACKLIGHTMAIN (u32)(0x1ED02240 - 0x1EB00000)
#endif
@ -8,13 +9,13 @@
#define REG_LCDBACKLIGHTSUB (u32)(0x1ED02A40 - 0x1EB00000)
#endif
inline void clearScreen(void);
void clearScreen(void);
#define drawPixelRGB(x, y, r, g, b) drawPixelRGBFramebuffer(0, x, y, r, g, b)
void drawPixelRGBFramebuffer(u8 *fb, int x, int y, u8 r, u8 g, u8 b);
#define drawBox(x, y, width, height, r, g, b) drawBoxFramebuffer(0, x, y, width, height, r, g, b)
inline void drawBoxFramebuffer(u8 *fb, int x, int y, int width, int height, u8 r, u8 g, u8 b);
void drawBoxFramebuffer(u8 *fb, int x, int y, int width, int height, u8 r, u8 g, u8 b);
#define drawString(sx, sy, text, ...) drawStringFramebuffer(0, sx, sy, text, ##__VA_ARGS__)
void drawStringFramebuffer(u8 *fb, int sx, int sy, char *text, ...);

View File

@ -8,4 +8,4 @@ extern unsigned char keyboardToggle;
extern unsigned char keyboardGfx[320 * 240 * 3];
void preRenderKeyboard(void);
inline void drawKeyboard(void);
void drawKeyboard(void);

View File

@ -162,14 +162,14 @@ static u32 brightnessSub;
void disableBacklight() {
u32 off = 0;
GSPGPU_ReadHWRegs(NULL, REG_LCDBACKLIGHTMAIN, &brightnessMain, 4);
GSPGPU_ReadHWRegs(NULL, REG_LCDBACKLIGHTSUB, &brightnessSub, 4);
GSPGPU_ReadHWRegs(REG_LCDBACKLIGHTMAIN, &brightnessMain, 4);
GSPGPU_ReadHWRegs(REG_LCDBACKLIGHTSUB, &brightnessSub, 4);
GSPGPU_WriteHWRegs(NULL, REG_LCDBACKLIGHTMAIN, &off, 4);
GSPGPU_WriteHWRegs(NULL, REG_LCDBACKLIGHTSUB, &off, 4);
GSPGPU_WriteHWRegs(REG_LCDBACKLIGHTMAIN, &off, 4);
GSPGPU_WriteHWRegs(REG_LCDBACKLIGHTSUB, &off, 4);
}
void enableBacklight() {
GSPGPU_WriteHWRegs(NULL, REG_LCDBACKLIGHTMAIN, &brightnessMain, 4);
GSPGPU_WriteHWRegs(NULL, REG_LCDBACKLIGHTSUB, &brightnessSub, 4);
GSPGPU_WriteHWRegs(REG_LCDBACKLIGHTMAIN, &brightnessMain, 4);
GSPGPU_WriteHWRegs(REG_LCDBACKLIGHTSUB, &brightnessSub, 4);
}

View File

@ -5,6 +5,7 @@
#include <3ds.h>
#include "3ds/services/soc.h"
#include "wireless.h"
#include "settings.h"
#include "drawing.h"
@ -39,7 +40,7 @@ int main(void) {
if(setjmp(exitJmp)) goto exit;
preRenderKeyboard();
// preRenderKeyboard();
clearScreen();
drawString(10, 10, "Initing FS...");
@ -53,10 +54,10 @@ int main(void) {
gfxFlushBuffers();
gfxSwapBuffers();
SOC_Initialize((u32 *)memalign(0x1000, 0x100000), 0x100000);
socInit((u32 *)memalign(0x1000, 0x100000), 0x100000);
u32 wifiStatus = 0;
ACU_GetWifiStatus(NULL, &wifiStatus);
ACU_GetWifiStatus(&wifiStatus);
if(!wifiStatus) {
hang("No WiFi! Is your wireless slider on?");
}
@ -78,7 +79,7 @@ int main(void) {
openSocket(settings.port);
sendConnectionRequest();
clearScreen();
// clearScreen();
gfxFlushBuffers();
gfxSwapBuffers();
@ -161,7 +162,7 @@ int main(void) {
enableBacklight();
SOC_Shutdown();
socExit();
svcCloseHandle(fileHandle);
fsExit();

View File

@ -3,6 +3,7 @@
#include <3ds.h>
#include "3ds/services/fs.h"
#include "wireless.h"
#include "settings.h"
@ -10,8 +11,8 @@
struct settings settings;
struct settings defaultSettings = {
IPString: "",
port: DEFAULT_PORT,
.IPString = "",
.port= DEFAULT_PORT,
};
Handle fileHandle;
@ -40,10 +41,12 @@ bool readSettings(void) {
u64 size;
u32 bytesRead;
FS_archive sdmcArchive = (FS_archive){ARCH_SDMC, (FS_path){PATH_EMPTY, 1, (u8*)""}};
FS_path filePath = FS_makePath(PATH_CHAR, "/3DSController.ini");
FS_ArchiveID sdmcArchiveID = (ARCHIVE_SDMC);
// FS_Archive sdmcArchive = (FS_Archive){ARCHIVE_SDMC, (FS_Path){PATH_EMPTY, 1, (u8*)""}};
FS_Path fileArchive = fsMakePath(PATH_EMPTY, NULL);
FS_Path filePath = fsMakePath(PATH_ASCII, "/3DSController.ini");
Result ret = FSUSER_OpenFileDirectly(NULL, &fileHandle, sdmcArchive, filePath, FS_OPEN_READ, FS_ATTRIBUTE_NONE);
Result ret = FSUSER_OpenFileDirectly(&fileHandle, sdmcArchiveID, fileArchive, filePath, FS_OPEN_READ, FS_ATTRIBUTE_HIDDEN);
if(ret) return false;
ret = FSFILE_GetSize(fileHandle, &size);

168
Linux/3DS_Controller.py Executable file
View File

@ -0,0 +1,168 @@
#!/usr/bin/env python
# Compatible with both Python 2.7.6 and 3.4.3
from __future__ import print_function
import socket, struct, time
import uinput
##########################################################
# CONFIGURABLE REGION START - Don't touch anything above #
##########################################################
port = 8889
#Valid values can be found in any of these locations on your Linux system (some may not exist):
# /usr/include/linux/input-event-codes.h
#The virtual device is defined on the device variable and the mapping of the keys on btn_map
#RECAP keynames (DO NOT TOUCH) are the keys that we expect commming from the 3ds, device is
#the virtual device that we define and btn_map maps what we recieve with our virtual device
btn_map = {
"A": uinput.BTN_A,
"B": uinput.BTN_B,
"X": uinput.BTN_X,
"Y": uinput.BTN_Y,
"L": uinput.BTN_TL,
"R": uinput.BTN_TR,
"ZL": uinput.BTN_THUMBL,
"ZR": uinput.BTN_THUMBR,
"Left": uinput.BTN_DPAD_LEFT,
"Right": uinput.BTN_DPAD_RIGHT,
"Up": uinput.BTN_DPAD_UP,
"Down": uinput.BTN_DPAD_DOWN,
"Start": uinput.BTN_START,
"Select": uinput.BTN_SELECT,
"Tap": uinput.BTN_MODE,
}
device = uinput.Device([
uinput.ABS_X + (-159, 159, 0, 10),
uinput.ABS_Y + (-159, 159, 0, 10),
uinput.ABS_RX + (-146, 146, 0, 16),
uinput.ABS_RY + (-146, 146, 0, 16),
uinput.ABS_VOLUME + (0, 63, 0, 0),
uinput.BTN_A,
uinput.BTN_B,
uinput.BTN_X,
uinput.BTN_Y,
uinput.BTN_TL,
uinput.BTN_TR,
uinput.BTN_THUMBL,
uinput.BTN_THUMBR,
uinput.BTN_DPAD_LEFT,
uinput.BTN_DPAD_RIGHT,
uinput.BTN_DPAD_UP,
uinput.BTN_DPAD_DOWN,
uinput.BTN_START,
uinput.BTN_SELECT,
uinput.BTN_MODE,
])
########################################################
# CONFIGURABLE REGION END - Don't touch anything below #
########################################################
def pprint(obj):
import pprint
pprint.PrettyPrinter().pprint(obj)
class x: pass
command = x()
command.CONNECT = 0
command.KEYS = 1
command.SCREENSHOT = 2
keynames = [
"A", "B", "Select", "Start", "Right", "Left", "Up", "Down",
"R", "L", "X", "Y", None, None, "ZL", "ZR",
None, None, None, None, "Tap", None, None, None,
"CSRight", "CSLeft", "CSUp", "CSDown", "CRight", "CLeft", "CUp", "CDown",
]
keys = x()
keys.A = 1<<0
keys.B = 1<<1
keys.Select = 1<<2
keys.Start = 1<<3
keys.Right = 1<<4
keys.Left = 1<<5
keys.Up = 1<<6
keys.Down = 1<<7
keys.R = 1<<8
keys.L = 1<<9
keys.X = 1<<10
keys.Y = 1<<11
keys.ZL = 1<<14 # (new 3DS only)
keys.ZR = 1<<15 # (new 3DS only)
keys.Tap = 1<<20 # Not actually provided by HID
keys.CSRight = 1<<24 # c-stick (new 3DS only)
keys.CSLeft = 1<<25 # c-stick (new 3DS only)
keys.CSUp = 1<<26 # c-stick (new 3DS only)
keys.CSDown = 1<<27 # c-stick (new 3DS only)
keys.CRight = 1<<28 # circle pad
keys.CLeft = 1<<29 # circle pad
keys.CUp = 1<<30 # circle pad
keys.CDown = 1<<31 # circle pad
def press_key(key):
device.emit(key, 1)
def release_key(key):
device.emit(key,0)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("", port))
prevkeys = 0
touch_start = 0
touch_last_x = 0
touch_last_y = 0
while True:
rawdata, addr = sock.recvfrom(4096)
rawdata = bytearray(rawdata)
#print("received message", rawdata, "from", addr)
if rawdata[0]==command.CONNECT:
print("Connected with 3DS at address",addr)
pass # CONNECT packets are empty
if rawdata[0]==command.KEYS:
fields = struct.unpack("<BBxxIhhHHhhBxxx", rawdata)
data = {
"command": fields[0],
"keyboardActive": fields[1],
"keys": fields[2],
"circleX": fields[3],
"circleY": fields[4],
"touchX": fields[5],
"touchY": fields[6],
"cstickX": fields[7],
"cstickY": fields[8],
"vol": fields[9],
}
#pprint(data)
newkeys = data["keys"] & ~prevkeys
oldkeys = ~data["keys"] & prevkeys
prevkeys = data["keys"]
for btnid in range(16):
if newkeys & (1<<btnid):
press_key(btn_map[keynames[btnid]])
if oldkeys & (1<<btnid):
release_key(btn_map[keynames[btnid]])
if newkeys & keys.Tap:
press_key(btn_map["Tap"])
if oldkeys & keys.Tap:
release_key(btn_map["Tap"])
device.emit(uinput.ABS_X, data["circleX"], syn=False)
device.emit(uinput.ABS_Y, 0-data["circleY"])
device.emit(uinput.ABS_RX, data["cstickX"], syn=False)
device.emit(uinput.ABS_RY, data["cstickY"])
device.emit(uinput.ABS_VOLUME, data["vol"])
if rawdata[0]==command.SCREENSHOT:
pass # unused by both 3DS and PC applications

Binary file not shown.

View File

@ -1,20 +1,20 @@
Default port is 8889, if you change this, you must change it in the 3DS's 3DSController.ini as well,
Circle Pad, C Stick and Touch can be MOUSE, JOYSTICK1 or JOYSTICK2
JOYSTICK1 uses X and Y. JOYSTICK2 uses Rx and Ry. These are 0, 1, 3 and 4 respectively, leaving 2 and 5 unused.
Circle Pad and C Stick may also be set to KEYS, which will enable Pad directions to map to regular keys (no vJoy necessary).
Throttle controls the delay between checking for new packets (in milliseconds), a high number will have slightly more lag between pressing a button on the 3DS and receiving it on the PC, however will make the application use less CPU. In my experience, 20 is a reasonable throttling amount,
Mouse Speed controls how fast the Circle Pad or Touch Screen moves the mouse. If set to 0 and using the Touch Screen, it will set to the absolute position, rather than moving relatively to last position,
vJoy Device chooses which device to connect to. Set this to 2 in a second instance of 3DSController to use a second 3DS at the same time, perhaps for multiplayer.
Buttons can be a letter for a keyboard key (like Q, W, E, R, T, or Y), a special keyboard key (like SPACE, CLICK, RIGHT CLICK, ENTER, BACKSPACE, SHIFT, TAB, LEFT, RIGHT, UP, DOWN, PAGE UP, PAGE DOWN, WINDOWS, ESCAPE, CONTROL or ALT), a joypad button (JOY1, JOY2, JOY3, to JOY16) or vJoy Hat Switch direction (NORTH, EAST, SOUTH or WEST) (The hat switch must be enabled in vJoy Config. 4 way only, not continuous!)
Circle Pad, C Stick and Touch can be MOUSE, JOYSTICK1, or JOYSTICK2.
JOYSTICK1 uses X and Y. JOYSTICK2 uses Rx and Ry. These are axes 0, 1, 3 and 4 respectively, leaving 2 and 5 unused.
KEYS will enable Pad directions (eg. Pad Left, C Stick Right) to map to regular keys (no vJoy necessary).
D Pad can be KEYS or POV. POV will automatically choose a continuous or 4 directional POV hat depending on what is set in your vJoy Config. KEYS will allow Left, Right and etc. to be buttons as previously.
Buttons can be a letter for a keyboard key (like Q, W, E, R, T, or Y), a special keyboard key (like SPACE, CLICK, RIGHT CLICK, ENTER, BACKSPACE, SHIFT, TAB, LEFT, RIGHT, UP, DOWN, PAGE UP, PAGE DOWN, WINDOWS, ESCAPE, CONTROL or ALT), or a joypad button (JOY1, JOY2, JOY3, to JOY16).
If you want to use JOY9 through JOY16 you need to reconfigure vJoy. Search for vJoy Config in your start menu and set buttons to 16.
Alternatively, you can disable a key by binding it to NONE,
Alternatively, you can disable any key by binding it to NONE.
Throttle controls the delay between checking for new packets (in milliseconds), a high number will have slightly more lag between pressing a button on the 3DS and receiving it on the PC, however will make the application use less CPU. In my experience, 20 is a reasonable throttling amount,
vJoy Device chooses which device to connect to. Set this to 2 in a second instance of 3DSController to use a second 3DS at the same time, perhaps for multiplayer.
Make sure to use a single space, not a tab for seperating settings,
@ -23,22 +23,24 @@ Make sure to use a single space, not a tab for seperating settings,
Port: 8889
Throttle: 20
Circle Pad: KEYS
C Stick: MOUSE
Touch: MOUSE
Mouse Speed: 3
vJoy Device: 1
Circle Pad: KEYS
C Stick: MOUSE
D Pad: KEYS
Touch: MOUSE
A: SPACE
B: CONTROL
X: E
B: E
X: CONTROL
Y: SHIFT
L: CLICK
R: RIGHT CLICK
ZL: RIGHT CLICK
ZR: LEFT CLICK
ZL: CONTROL
ZR: SHIFT
Start: ESCAPE
Select: ENTER
Select: Q
Tap: NONE
Left: A
@ -51,7 +53,7 @@ Pad Right: D
Pad Up: W
Pad Down: S
C Stick Left: 5
C Stick Right: 6
C Stick Up: 7
C Stick Down: 8
C Stick Left: NONE
C Stick Right: NONE
C Stick Up: NONE
C Stick Down: NONE

View File

@ -3,3 +3,5 @@
#include <stdio.h>
void error(const char *functionName);
int clamp(int val, int min, int max);

View File

@ -35,10 +35,6 @@
if(currentKeys & DSKey) joyButtons |= PCKey.joypadButton << 8;\
else joyButtons &= ~(PCKey.joypadButton << 8);\
}\
else if(PCKey.useJoypad == 3) {\
if(currentKeys & DSKey) hatButtons |= PCKey.joypadButton;\
else hatButtons &= ~(PCKey.joypadButton);\
}\
} while(0)
#define BIT(n) (1 << (n))
@ -111,4 +107,3 @@ extern struct touch currentTouch;
unsigned int mapVirtualKey(unsigned int key);
void simulateKeyNewpress(unsigned int key);
void simulateKeyRelease(unsigned int key);
void handleHat(unsigned int hat);

View File

@ -11,16 +11,22 @@ enum analogue {
keys,
};
enum dPad {
key,
pov,
cPov,
};
struct settings {
int port;
int throttle;
enum analogue circlePad;
enum analogue cStick;
enum analogue touch;
enum dPad dPad;
int mouseSpeed;
UINT vJoyDevice;
struct keyMapping A, B, X, Y, L, R, ZL, ZR, Start, Select, Tap, Left, Right, Up, Down, PadLeft, PadRight, PadUp, PadDown, CSLeft, CSRight, CSUp, CSDown;
bool isUsingPov;
};
extern struct settings settings;

View File

@ -5,14 +5,26 @@
void error(const char *functionName) {
char errorMsg[92];
ZeroMemory(errorMsg, 92);
sprintf(errorMsg, "Call to %s returned error %d!", (char *)functionName, WSAGetLastError());
MessageBox(NULL, errorMsg, "socketIndication", MB_OK);
closesocket(client);
closesocket(listener);
WSACleanup();
exit(0);
}
int clamp (int val, int min, int max) {
if (val < min) {
return min;
}
if (val > max) {
return max;
}
return val;
}

View File

@ -77,12 +77,4 @@ void simulateKeyRelease(unsigned int key) {
}
SendInput(1, &ip, sizeof(INPUT));
}
void handleHat(unsigned int hat) {
if(hat & BIT(0)) iReport.bHats = 0;
else if(hat & BIT(1)) iReport.bHats = 1;
else if(hat & BIT(2)) iReport.bHats = 2;
else if(hat & BIT(3)) iReport.bHats = 3;
else iReport.bHats = -1;
}
}

View File

@ -1,6 +1,6 @@
// 3DS Controller Server
#define VERSION 0.7
#define VERSION "0.7.2"
#include <stdio.h>
#include <stdbool.h>
@ -14,7 +14,7 @@
#include "keyboard.h"
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nShow) {
printf("3DS Controller Server %.1f\n", VERSION);
printf("3DS Controller Server %s\n", VERSION);
DWORD screenWidth = GetSystemMetrics(SM_CXSCREEN);
DWORD screenHeight = GetSystemMetrics(SM_CYSCREEN);
@ -28,7 +28,6 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nShow)
bool vJoy = true;
UINT iInterface = settings.vJoyDevice;
int hatButtons = 0;
iReport.wAxisX = JOY_MIDDLE;
iReport.wAxisY = JOY_MIDDLE;
@ -55,6 +54,8 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nShow)
ContPovNumber = GetVJDContPovNumber(iInterface);
//int DiscPovNumber = GetVJDDiscPovNumber(iInterface);
if((settings.dPad == pov) && !(ContPovNumber == 0)) settings.dPad = cPov;
if(vJoy && !updateJoystick(iInterface)) {
printf("vJoy failed (3)! Buttons will still work, but joystick won't work.\nIs vJoy device %d configured?\n",iInterface);
vJoy = false;
@ -128,7 +129,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nShow)
handleKey(KEY_B, settings.B);
handleKey(KEY_SELECT, settings.Select);
handleKey(KEY_START, settings.Start);
if(!settings.isUsingPov) { //Handle normally if not using POV in settings.
if(settings.dPad == key) { //Handle normally if not using POV in settings.
handleKey(KEY_DRIGHT, settings.Right);
handleKey(KEY_DLEFT, settings.Left);
handleKey(KEY_DUP, settings.Up);
@ -141,8 +142,6 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nShow)
handleKey(KEY_X, settings.X);
handleKey(KEY_Y, settings.Y);
handleHat(hatButtons);
if(settings.circlePad == keys) {
handleKey(KEY_CPAD_RIGHT, settings.PadRight);
handleKey(KEY_CPAD_LEFT, settings.PadLeft);
@ -201,52 +200,52 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nShow)
joyX = 16383; //Halfway between the x
joyY = 16383; //Halfway between the y
}
else if(settings.touch == joystick2) {
joyRX = 16383; //Halfway between the rx
joyRY = 16383; //Halfway between the ry
}
}
if(settings.circlePad == mouse) {
if(abs(circlePad.x) < settings.mouseSpeed * 3) circlePad.x = 0;
if(abs(circlePad.y) < settings.mouseSpeed * 3) circlePad.y = 0;
POINT p;
GetCursorPos(&p);
SetCursorPos(p.x + (circlePad.x * settings.mouseSpeed) / 32, p.y - (circlePad.y * settings.mouseSpeed) / 32);
}
else if(settings.circlePad == joystick1) {
joyX = (circlePad.x + 128) * 128;
joyY = (128 - circlePad.y) * 128;
joyX = clamp((circlePad.x + 128) * 128, 0, 32767);
joyY = clamp((128 - circlePad.y) * 128, 0, 32767);
}
else if(settings.circlePad == joystick2) {
joyRX = (circlePad.x + 128) * 128;
joyRY = (128 - circlePad.y) * 128;
joyRX = clamp((circlePad.x + 128) * 128, 0, 32767);
joyRY = clamp((128 - circlePad.y) * 128, 0, 32767);
}
if(settings.cStick == mouse) {
if(abs(cStick.x) < settings.mouseSpeed * 3) cStick.x = 0;
if(abs(cStick.y) < settings.mouseSpeed * 3) cStick.y = 0;
POINT p;
GetCursorPos(&p);
SetCursorPos(p.x + (cStick.x * settings.mouseSpeed) / 32, p.y - (cStick.y * settings.mouseSpeed) / 32);
}
else if(settings.cStick == joystick1) {
joyX = (cStick.x + 128) * 128;
joyY = (128 - cStick.y) * 128;
joyX = clamp((cStick.x + 128) * 128, 0, 32767);
joyY = clamp((128 - cStick.y) * 128, 0, 32767);
}
else if(settings.cStick == joystick2) {
joyRX = (cStick.x + 128) * 128;
joyRY = (128 - cStick.y) * 128;
joyRX = clamp((cStick.x + 128) * 128, 0, 32767);
joyRY = clamp((128 - cStick.y) * 128, 0, 32767);
}
if(settings.isUsingPov) {
if(settings.dPad == cPov) {
if((currentKeys & KEY_DUP) && !(currentKeys & KEY_DLEFT)) {
if((currentKeys & KEY_DRIGHT)) {
povHat = 4500;
@ -280,6 +279,14 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nShow)
}
else if(settings.dPad == pov) {
if((currentKeys & KEY_DUP) && !(currentKeys & KEY_DLEFT)) iReport.bHats = 0;
else if(currentKeys & KEY_DRIGHT) iReport.bHats = 1;
else if (currentKeys & KEY_DDOWN) iReport.bHats = 2;
else if (currentKeys & KEY_DLEFT) iReport.bHats = 3;
else iReport.bHats = -1;
}
joyVolume = volume * 512;
break;

View File

@ -32,7 +32,6 @@ struct settings defaultSettings = {
Start: { 1, {VK_RETURN} },
Select: { 1, {VK_BACK} },
Tap: { 1, {'T'} },
isUsingPov: false,
};
static bool getSetting(char *name, char *src, char *dest) {
@ -93,14 +92,6 @@ static struct keyMapping getButton(char *string) {
else if(strcmp(string, "JOY14") == 0) { k.useJoypad = 2; k.joypadButton = 1 << 5; }
else if(strcmp(string, "JOY15") == 0) { k.useJoypad = 2; k.joypadButton = 1 << 6; }
else if(strcmp(string, "JOY16") == 0) { k.useJoypad = 2; k.joypadButton = 1 << 7; }
else if(strcmp(string, "POV") == 0) {settings.isUsingPov = true;}
//No matter what the others are, if any are set to true then we are using the POV hat for the DPad
//This would mean if any setting at all is POV then the dpad is suddenly a POV.
else if(strcmp(string, "NORTH") == 0) { k.useJoypad = 3; k.joypadButton = 1 << 0; }
else if(strcmp(string, "EAST") == 0) { k.useJoypad = 3; k.joypadButton = 1 << 1; }
else if(strcmp(string, "SOUTH") == 0) { k.useJoypad = 3; k.joypadButton = 1 << 2; }
else if(strcmp(string, "WEST") == 0) { k.useJoypad = 3; k.joypadButton = 1 << 3; }
else k.virtualKey = (int)string[0];
@ -155,6 +146,11 @@ bool readSettings(void) {
else if(strcmp(setting, "KEYS") == 0) settings.cStick = keys;
}
if(getSetting("D Pad: ", buffer, setting)) {
if(strcmp(setting, "KEYS") == 0) settings.dPad = key;
if(strcmp(setting, "POV") == 0) settings.dPad = pov;
}
if(getSetting("Touch: ", buffer, setting)) {
if(strcmp(setting, "MOUSE") == 0) settings.touch = mouse;
else if(strcmp(setting, "JOYSTICK1") == 0) settings.touch = joystick1;

View File

@ -2,12 +2,12 @@
===
A 3DS homebrew application which allows you to use your 3DS as a wireless controller for Windows.
### Download
The latest release will always be downloadable from [here](https://github.com/CTurt/3DSController/releases/).
## Download
The latest release will always be downloadable from [here](https://github.com/Ordinaryperson2/3DSController/releases/).
If you are updating to 0.6 from an older version, you will need to make sure you update vJoy to the recommended version.
### Setup and Usage
## Setup and Usage
Firstly, if you want to be able to register the circle pad or touch screen as a joystick you will need to install [vJoy (version 2.0.5-120515 is preferable)](http://sourceforge.net/projects/vjoystick/files/Beta%202.x/2.0.5-120515/vJoy_205_050515.exe/download). However, if you just want to use keyboard buttons, this is not necessary.
Extract the archive and copy the executable in the `3DS` directory with the extension that applies to your loader: `3DSController.3dsx` and `3DSController.smdh` for Ninjhax, `3DSController.3ds` for flashcards, or `3DSController.cia` for CFWs, into your 3DS's SD card or flashcard's micro SD card.
@ -31,16 +31,26 @@ If using version 0.6 or above, up to 16 joystick buttons are available. If you w
If using version 0.7 or above, the output vJoy device is configurable. To output to a device other than 1 it must first be enabled in vJoyConfig.
If using Ninjhax press Start and Select to return to the Homebrew Loader, otherwise you can just exit with the Home button.
### Linux
You will need the [3DS_Controller.py](https://github.com/Ordinaryperson2/3DSController/blob/master/Linux/3DS_Controller.py) file.
### Configuration
This is a python (v2 and v3) script allowing the use of the console as an UInput device.
You will therefore need the package 'python-uinput' for this to work.
Works with all buttons, sliders and joysticks of all 3DS consoles, except for the Home and Power buttons and the 3D slider.
## Configuration
Find the line `Port: 8889` and change it to your desired port, do this for both the 3DS's `3DSController.ini` and the PC's `3DSController.ini`.
To use custom key bindings, just change the PC's `3DSController.ini` file, it should be straight forward.
### Linux
The configuration is in the 3DS_Controller.py file itself. It doesn't use the .ini.
### Troubleshooting
## Troubleshooting
- Make sure that you are using the 3DS and PC application from the same release,
- Make sure your 3DS has internet access (turn on the switch on the side of the 3DS so that an orange light shows) and is on the same network as your PC,
- Make sure that the `3DSController.ini` is in the root of your 3DS's SD card (not flashcard micro SD),
- Make sure that the `3DSController.ini` has the local IP of your computer, not your public IP,
- Make sure your firewall isn't blocking the application,
- Try using a different port (change the port for both the 3DS and PC's .ini file),
- Try using a different port (change the port for both the 3DS and PC's .ini file),