Monday, July 30, 2007

Custom Controller Configurations

A number of people have asked if I would be adding support for user-defined controller configurations in a future release of Daedalus. As it happens Daedalus has supported user-defined controller configurations from R7 onwards. From the readme file:

As of R7 Daedalus now allows user-configurable controls to be specified.
The desired controls can be chosen from the Rom Settings screen.

In order to define your own controller configuration you need to add a
new .ini file to the Daedalus/ControllerConfigs directory. There are a
few examples provided which should give an overview of what is possible.
I will look at providing a more thorough tutorial shortly.

The format really is quite simple, but it is very flexible and allows for a number of advanced configurations. Here is a simple configuration which is distributed with Daedalus (ControllerConfigs/dpad.ini):

Description=By default the PSP DPad maps to the N64 DPad. Hold Circle to map to the CButtons.

N64.Start = PSP.Start
N64.A = PSP.Cross
N64.B = PSP.Square
N64.Z = PSP.Triangle
N64.LTrigger = PSP.LTrigger
N64.RTrigger = PSP.RTrigger
N64.Up = !PSP.Circle & PSP.Up
N64.Down = !PSP.Circle & PSP.Down
N64.Left = !PSP.Circle & PSP.Left
N64.Right = !PSP.Circle & PSP.Right
N64.CUp = PSP.Circle & PSP.Up
N64.CDown = PSP.Circle & PSP.Down
N64.CLeft = PSP.Circle & PSP.Left
N64.CRight = PSP.Circle & PSP.Right

The file starts with two lines defining the name and description for the controller config. These strings are used in the UI when selecting configurations. The '[Buttons]' block defines the mapping from PSP controls to N64 controls. In this particular configuration the N64 d-pad is mapped to the PSP d-pad when the circle button is released. When circle is pressed, the PSP d-pad maps to the N64 c-buttons. This config is particularly useful for games which make heavy use of the d-pad.

In the [Buttons] section, the left hand side of each rule must consist of one of the following N64 control names:

N64.StartThe N64's start button
N64.AThe N64's A button
N64.BThe N64's B button
N64.ZThe N64's Z trigger
N64.LTriggerThe left trigger
N64.RTriggerThe right trigger
N64.UpUp on the N64's d-pad
N64.DownDown on the N64's d-pad
N64.LeftLeft on the N64's d-pad
N64.RightRight on the N64's d-pad
N64.CUpThe N64's C up button
N64.CDownThe N64's C down button
N64.CLeftThe N64's C left button
N64.CRightThe N64's C right button

N.B. There is currently no definition for the N64's analogue stick. By default this is always assumed to be bound to the PSP's analogue stick.

The right hand side of a rule consists of an expression defined from the following values:

PSP.StartThe PSP's start button
PSP.CrossThe PSP's cross button
PSP.SquareThe PSP's square button
PSP.TriangleThe PSP's triangle button
PSP.CircleThe PSP's circle button
PSP.LTriggerThe PSP's left shoulder button
PSP.RTriggerThe PSP's right shoulder button
PSP.UpUp on the PSP's d-pad
PSP.DownDown on the PSP's d-pad
PSP.LeftLeft on the PSP's d-pad
PSP.RightRight on the PSP's d-pad

N.B. You cannot use the PSP's select button when defining controller configurations, as this is reserved for the emulator's use.

Values can be combined using a few simple operations to allow rules to be constructed with more complex behaviour. For instance, the following line:

N64.CUp = PSP.Circle & PSP.Up

Tells Daedalus to report that the N64 C up button is pressed when both the circle AND d-pad up buttons are pressed on the PSP. The NOT operator (!) can be used to invert a value, for instance:

N64.Up = !PSP.Circle & PSP.Up

This rule tells Daedalus to report that the N64 d-pad up button is pressed when the PSP's circle button is not pressed while the d-pad up button is being pressed.

The available logical operators are:

expr & exprReturns the logical AND of the two expressionsN64.CUp=PSP.LTrigger & PSP.Up
expr | exprReturns the logical OR of the two expressionsN64.A=PSP.Cross | PSP.Circle
!exprReturns the logical NOT of the expressionN64.Up = !PSP.LTrigger & PSP.Up

You can also use parentheses to control the order of precedence, e.g.:

N64.CUp = PSP.Up | (PSP.LTrigger & PSP.Triangle)

Which defines a rule which defines that the N64 C up button is pressed when either up on the PSP d-pad is pressed, or when the left shoulder button and triangle are pressed.

No single controller mapping scheme can be provided which works well across all games, but using custom controller configs it should be possible to create a mapping which works well for any given game.

Post any questions you might have in the comment pages, and I'll do my best to answer them. If you come up with a good controller config for a game, email me (my name and I'll look at adding it for distribution with future releases of Daedalus.


(Apologies - for some reason my template in Blogger really screws up when I place tables in he post and inserts a ton of whitespace before the table. I've never quite figured out how to fix it, so we'll just have to live with it :)

(Fixed post date :)


XG917 said...

lol, i found out how to configure them! :-D

thanks for explaining everything, this works great. my fingers feel confortable playing n64 games now

Adam said...

This is the config I've been using for a while:

N64.Start = PSP.Start
N64.A = PSP.Cross
N64.B = PSP.Square
N64.Z = !PSP.Circle & PSP.LTrigger
N64.LTrigger = PSP.Circle & PSP.LTrigger
N64.RTrigger = PSP.RTrigger
N64.Up = PSP.Circle & PSP.Up
N64.Down = PSP.Circle & PSP.Down
N64.Left = PSP.Circle & PSP.Left
N64.Right = PSP.Circle & PSP.Right
N64.CUp = !PSP.Circle & PSP.Up
N64.CDown = !PSP.Circle & PSP.Down
N64.CLeft = !PSP.Circle & PSP.Triangle
N64.CRight = PSP.Circle & PSP.Triangle

It works pretty well for most games but probably needs some tweeking for first person shooters and side scrollers. I find mapping Z to the left shoulder button is a lot more intuitive than using it as one of the face buttons.
Just one question, if for example I mapped C Right to the circle button and D-Pad up to circle & PSP.up, when I press circle & up would it register both C Right and D-Pad up, or just D-Pad up? I've been using circle strictly as a shift button because I wasn't sure if it would mess up my other configurations if I mapped it to something (like C Right) by itself.

Ole Fossbakk said...

Thanks for putting all the control configurations in detail, it should help many of us out. I actually didn't know that the yellow C buttons were usable! :O

By the way, it says this post "was" posted in September 2007. Maybe a bug you should fix? :)

Again thanks.

Dustcrazy said...

Hey StrmnNrmn try editing the HTML code for you post. I've had to do that in the past with my blog. Also good luck and I hope to see support for CBFD!

Morgan said...

Good stuff, I hope you can post about what you can do with the 3 titles selected in my poll as well as the results of Wally's poll too.

Samuel said...

Hi Strmn_Nrmn,

could you implement a feature to use the remote for additional controls? Quake 2 PSP has is. You could look there for code examples should you need them.

Vincent Casuis said...

I been using custom configs since you realised them, I beleive I was 1 of the first to ask for it =)

While on the subject though, would it be possible to map stuff to the PSP remote thingy? (the mp3 thing the headphone jack uses) as that would be perfect for a set of <-V-> C buttons, just clip it to the psp with tape or somin xD

StrmnNrmn said...

@samuel/vincent: It sounds like it would be quite easy to support the PSP remote, but I'm not sure how usable it would be.

One of the things about the way the N64 controller is designed is that it's hard to use more than the dpad+stick or stick+face buttons at one time. I think this maps quite well to using a button like Circle to toggle between the two modes.

Still, if it's easy enough to add support for the remote, there's no reason no to.

Caesar said...

Hey, first of all, nice work and thanks for bringing this nice emulator to the PSP!!

I have two questions though, with the announcement of the new psp, sony states that it will have double the ram.

1. Will this help the emulator run smoother? (I'm guessing yet)
2. Would you develop another version of the emulator specifically to take advantage, or how would you do it?

Thanks for your time!!