bsnes v0.041 released

Archived bsnes development news, feature requests and bug reports. Forum is now located at http://board.byuu.org/
Locked
byuu

Post by byuu »

Fairly productive day. Have a hopefully-working model to rewrite the joypad mapping code.

Modern APIs just have no concept of D-pads as four buttons. They treat them as axes and POV hats, with zero consistency between controllers and APIs. So we drop joypad<n>.up,down,left,right. That gives us:

joypad<n>.axis<0-7>
joypad<n>.hat<0-3> (two axes to one stick, so four of each)
joypad<n>.button<0-95> (for stupid Linux 4-in-1 drivers)

Axis will give back a value of -32768 (low) to +32767 (high). When mapping occurs, it will determine the map value and append either ::low or ::high to the assignment identifier, eg joypad1.up = joypad00.axis01::low; joypad1.down = joypad00.axis01::high

I'll keep that value inside the InputObject class and update the state polling to account for it when the object type is a button, but the code type is a joypad axis.

Hats will be slightly different. They'll be a 4-bit unsigned value:

Code: Select all

enum hat_state { //uint4_t, clockwise rotation
  hat_center = 0,
  hat_up = 1,
  hat_right = 2,
  hat_down = 4,
  hat_left = 8,
};
They will map with ::up, ::down, ::left, ::right suffixes. Same strategy as above for encoding / decoding. Mapping won't handle corners fully, it'll just pick one or the other, so move the POV-hat cleanly to map properly, same deal as with axes really.

Not sure if it's worth the trouble to use the full 16-bit value ala DirectInput ... I've never seen a POV-hat with more than nine possible states anyway. Don't even know how a full 360-degree POV-hat would work with a "center" value and all. How far would you have to move before it rotated around its axis? All of that would be 'dead' space, which would just be weird.
FirebrandX
Trooper
Posts: 376
Joined: Tue Apr 19, 2005 11:08 pm
Location: DFW area, TX USA
Contact:

Post by FirebrandX »

Byuu, is there any way bsnes can be programmed to disable power saving feature? I keep forgetting and my screen wil go blank while playing and I have to madly grab at the mouse to bring the screen back up :oops:
NES NTSC palette file:

http://www.firebrandx.com/downloads/fbx2pal.zip
byuu

Post by byuu »

FirebrandX wrote:Byuu, is there any way bsnes can be programmed to disable power saving feature? I keep forgetting and my screen wil go blank while playing and I have to madly grab at the mouse to bring the screen back up :oops:
Yes, it's under Desktop->Right-click->Properties->Screen Saver->Screen Saver->(None).

In all seriousness, I still need to find a Qt function for it. Don't really want to fake key presses like I was doing with GTK+, and I can't respond to window messages as with Win32.
h4tred

Post by h4tred »

So even if it isn't clear to you today, things like UPX will fall into disuse eventually.
I beg to differ:

* Malware/keygen devs will continue to use obscure packers like FSG and the XMPlay dev will continue to use Petite for EXE compression. Sure it makes things a little more difficult, but it does hinder some reversing a little. Even though most packers can be undone using the ESP register trick, UPX/FSG/ASPack/etc included.
* Most components of packers are in fact part of some copy protections. Take
- Starforce
- Securom
- SafeDisc/SafeCast
- ASProtect/ASProtect SKE
- Armadillo
- Themida

for instance. They ALL use technology out of packers AND in cases THEY are used as packers themselves, as well as EXE protectors (since they offer things like anti-debug, VMs and the like.)

so why don't antivirii programs just un-upx the files and scan them yet
I just realized how obvious this is.
Because the devs are lazy retards. Some devs though, already do this for known packers.
byuu

Post by byuu »

New WIP.

I've added the centering code. Had to hide and show the window to prevent the Windows 'restore-from-taskbar' animation. That's causing Xorg events to not propagate quickly enough so sometimes the windows start minimized. I'll keep working on it.

I've also killed joypad<>::up, down, left, right; and added joypad<>::hat<0-3>.

So far, I've adapted the Qt UI to map analog axes. You'll see now when you map one that you get ::lo or ::hi to indicate the state direction at the time of assignment. I have not done this for hats, so only the 'up' direction will map currently.

I only know how to read the first two axes (first stick) on Windows, so it won't see any others yet.

For the mapping, I made it both range-sensitive (requires at least 75% force to map, 50% force to trigger) and distance-sensitive (prevents auto-assignment for those annoying analog sticks that flicker within a few points in any direction; also protects against those sixaxis buttons that are idle at +32767) -- the distance is at 512, and slow movement causes ~1,000+ movement based on ~20ms sampling, should be enough.

To prevent rapid assignment of the same analog axis when using the "Assign All ..." button, and because it makes no sense to allow it, I've added a check to make sure that each key assignment is unique to all previous ones. This doesn't apply to individual assignment in case you really do want one key to map to two inputs. It was that or add a ~200ms delay between each assignment.

The only thing my emulator doesn't handle completely are those six-axis buttons. Mostly because I have no way of telling what they are. I can't tell if a user is holding a stick south-east, or if it's a button not pressed. You can map them anyway, but it won't work as you expect a button to.

Lastly, I'm not sure how to support mouse pass-through just yet. Right now I block mouse input when the mouse isn't exclusively acquired. If I don't, then clicking to acquire the mouse will send a 'fire' command to the emulator. But if I do, then you can't use a mouse as a joypad.
tetsuo55
Regular
Posts: 307
Joined: Sat Mar 04, 2006 3:17 pm

Post by tetsuo55 »

Awesome

I will have to test this with my PS2 controllers.
When i press the button in the middle, the settings change dramatically, the d-pad changes from i think 4 buttons to a hat.

Do i understand correctly that you currently do not support the pressure sensitive buttons, instead treating them as pressed once they go over 50% pressure?
byuu

Post by byuu »

I will have to test this with my PS2 controllers.
Wait for hat + multi-axis on DirectInput support first, please :)
Do i understand correctly that you currently do not support the pressure sensitive buttons, instead treating them as pressed once they go over 50% pressure?
The pressure-sensitive buttons are screwy.

Basically, a thumb is centered at 0, 0. When you move it left, you get -32767, 0. Right = +32767, 0. Up = 0, -32767. Down = 0, +32767. It's two axes in one, and not pressing anything means you're centered at 0, 0.

But the buttons ... they start at +32767, and the harder you press them, the lower the value gets, down to -32767.

My mapping code works with the centered mode, and it tries to not let you assign keys by just barely tapping them. Reason being when you go to assign 'Up', you'll probably be a little to the left or right, so I don't want 'Down' right after to get assigned immediately. Sometimes you'll hit left or right some before up registers, too.

Because of that, I make a ~75% dead-zone in either direction, so that the stick has to be pretty obviously in a given direction to map to it.

That screws with these buttons badly. It means just barely tapping them will cause them to assign, while the middle area does nothing. If you open the assign window with button released and push it a bit, it gets assigned as ::hi, and it ends up thinking the button is held down when it's not. You have to press the button in to release it. Now, if you start the window with the button held down and let go, it maps it as ::lo, and you have to press down at least 75% of the way to trigger it. If you map both ::hi and ::lo, well ... have fun controlling the game that way :P

I also can't add sensitivity to the upper and lower bounds to make mapping these buttons harder, because a lot of drivers will map real D-pads (or POV hats) as analog axes, especially with those mode buttons. In that mode, left returns a hard -32767, center 0, etc. So if I require even ~1 for tolerance it won't allow mapping at all.

To protect against analog sticks and buttons that 'flicker' by +1, -1 every time you poll; I added that distance test to ensure it was moved more than these devices flicker by. That way it won't rapidly assign anything when you first open the capture window.

The best part of all this, the drivers treat the buttons and sticks as exactly the same thing. I could "guess" which it is by examining their states at first run, but that has one serious problem: what if the user was holding the button down when that test runs, or the controller is sitting upside down and the analog stick is forced to one direction? It would throw off calibration until restarting.

And ultimately, I don't even think there's much use in those buttons anyway. No SNES peripheral we support would benefit from an analog button (though it may work well with hypothetical Lasabirdie support :P)
It does sound like a nice feature for ruby::input, so maybe I'll add Input::calibrate() to do just that.

Fun stuff, huh? :)
tetsuo55
Regular
Posts: 307
Joined: Sat Mar 04, 2006 3:17 pm

Post by tetsuo55 »

That's basically what i thought.

If you can test for button types i suggest doing so.
All consoles/Arcade cabinets do this anyway.

Try it with the N64 or PS2, if you hold the analogue stick like half way to the left, and then turn on the unit, keep holding it till the game starts to load.

The stick will be centered at the point you where holding it and controls will be all screwy (like mario will start walking to the right because "centered" means half way to right)

You can even put some kind of warning, Do not touch any buttons and leave all sticks centered when starting up bsnes for accurate button assigment
_willow_
Hazed
Posts: 51
Joined: Mon Dec 24, 2007 2:03 am
Location: Russia
Contact:

Post by _willow_ »

Code: Select all

LONG WINAPI MainWndProc ( 
    HWND    hWnd, 
    UINT    uMsg, 
    WPARAM  wParam, 
    LPARAM  lParam) 
{ 
....
switch (uMsg) 
{
....
 case WM_SYSCOMMAND: 
     if (wParam == SC_SCREENSAVE || wParam == SC_MONITORPOWER) 
            return 0; 
     return DefWindowProc (hWnd, uMsg, wParam, lParam); 
....
}
....
}
Once again byuu seems to ignore my code snippets.
byuu

Post by byuu »

_willow_ wrote:Once again byuu seems to ignore my code snippets.
And where do you suggest I register that wndproc when I'm using Qt to create and manage windows for me?
creaothceann
Seen it all
Posts: 2302
Joined: Mon Jan 03, 2005 5:04 pm
Location: Germany
Contact:

Post by creaothceann »

byuu wrote:And ultimately, I don't even think there's much use in those buttons anyway. No SNES peripheral we support would benefit from an analog button
You could control the mouse position that way. :D
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list
Verdauga Greeneyes
Regular
Posts: 347
Joined: Tue Mar 07, 2006 10:32 am
Location: The Netherlands

Post by Verdauga Greeneyes »

byuu wrote:But the buttons ... they start at +32767, and the harder you press them, the lower the value gets, down to -32767.

My mapping code works with the centered mode, and it tries to not let you assign keys by just barely tapping them. Reason being when you go to assign 'Up', you'll probably be a little to the left or right, so I don't want 'Down' right after to get assigned immediately. Sometimes you'll hit left or right some before up registers, too.

Because of that, I make a ~75% dead-zone in either direction, so that the stick has to be pretty obviously in a given direction to map to it.

That screws with these buttons badly. It means just barely tapping them will cause them to assign, while the middle area does nothing. If you open the assign window with button released and push it a bit, it gets assigned as ::hi, and it ends up thinking the button is held down when it's not. You have to press the button in to release it. Now, if you start the window with the button held down and let go, it maps it as ::lo, and you have to press down at least 75% of the way to trigger it. If you map both ::hi and ::lo, well ... have fun controlling the game that way :P
Can't you record the 'centered' state the moment button assignment begins? It should be pretty obvious that you shouldn't be touching your controller before assignment begins, so this should give bsnes an idea of the starting values to use. You don't have to save this information, just save the highest/lowest value (depending on which direction it moves in from the 'idle' value), and the largest deviation from that value that will still register as input.
byuu

Post by byuu »

creaothceann wrote:You could control the mouse position that way. :D
You'd have to hold the button half-way down to mean "don't move the mouse at all". Trust me, that's a lot easier than it sounds.
Can't you record the 'centered' state the moment button assignment begins?
I could, but it'd be a major pain in the ass, requiring me to mirror the entire input system state table. If I do this, I'll go with the one-time calibration on startup.
Verdauga Greeneyes
Regular
Posts: 347
Joined: Tue Mar 07, 2006 10:32 am
Location: The Netherlands

Post by Verdauga Greeneyes »

byuu wrote:If I do this, I'll go with the one-time calibration on startup.
Does that mean 'show the configuration dialog on first run' or 'poll the input states on startup'?
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Post by grinvader »

About the analog buttons:

You could make a special interpreter for them, i.e. (val>>1)-16383-(val<0).

Boom, instant noodles.
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
Nach
ZSNES Developer
ZSNES Developer
Posts: 3904
Joined: Tue Jul 27, 2004 10:54 pm
Location: Solar powered park bench
Contact:

Post by Nach »

byuu wrote:
_willow_ wrote:Once again byuu seems to ignore my code snippets.
And where do you suggest I register that wndproc when I'm using Qt to create and manage windows for me?
Probably here or here
May 9 2007 - NSRT 3.4, now with lots of hashing and even more accurate information! Go download it.
_____________
Insane Coding
_willow_
Hazed
Posts: 51
Joined: Mon Dec 24, 2007 2:03 am
Location: Russia
Contact:

Post by _willow_ »

byuu wrote:
_willow_ wrote:Once again byuu seems to ignore my code snippets.
And where do you suggest I register that wndproc when I'm using Qt to create and manage windows for me?

Code: Select all

HWND hWnd;

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    WNDCLASSEX MessageWindow = {0};

    MessageWindow.cbSize = sizeof(WNDCLASSEX);
    MessageWindow.lpfnWndProc = MainWndProc;
    MessageWindow.hInstance = hInstance;
    MessageWindow.lpszClassName = "VoidWindow";

    RegisterClassEx(&NullWindow);

    hWnd = CreateWindowEx(WS_EX_TOOLWINDOW, "VoidWindow", "VoidWindow", 0, 0, 0, 0, 0, 0, 0, HInstance, 0);

	.......
}

LRESULT CALLBACK MainWndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
    switch(Message)
    {
	case WM_SYSCOMMAND:
	     if (wParam == SC_SCREENSAVE || wParam == SC_MONITORPOWER) return 0;
		return DefWindowProc(hWnd, Message, wParam, lParam);
        case WM_CLOSE:
            DestroyWindow(hWnd);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
	    return DefWindowProc(hWnd, Message, wParam, lParam);
    }
    return 0;
}
Now byuu should say "Oh no!!! It looks like ass." :lol: But i do simply can't get how the program can live without messages. :? It's the way windows breathe.

BTW is it any way to bind multimedia keys in bsnes? I mean make use of "Play/Pause" and "Mute" buttons, etc.
byuu

Post by byuu »

Well, spent all day working on this:
http://i73.photobucket.com/albums/i221/ ... /stbc8.png
http://i73.photobucket.com/albums/i221/ ... /stbc7.png
http://i73.photobucket.com/albums/i221/ ... /stbc6.png

4:06:59 ... made it to #8 on the high score list, and I suspect the top four of cheating (almost a minute better time, I highly doubt that's possible.)
But i do simply can't get how the program can live without messages. Confused It's the way windows breathe.
... you're serious. Okay, http://doc.trolltech.com/4.5/index.html

I do not #include <windows.h> anywhere in my project. It is 100% cross-platform. There are no HWNDs, there are no MSGs, there are no WNDCLASSes, there are no WNDPROCs.

Meh, it doesn't matter anyway. I can implement it if I need to using platform-specific code to spawn an invisible messenger window or something. Just haven't gotten to it yet. Thanks for the code snippet.
BTW is it any way to bind multimedia keys in bsnes? I mean make use of "Play/Pause" and "Mute" buttons, etc.
Nope, sorry. Maybe in the future.
_willow_
Hazed
Posts: 51
Joined: Mon Dec 24, 2007 2:03 am
Location: Russia
Contact:

Post by _willow_ »

Oh, i see.. I do like the things to be more native. Besides you are following the theoretical accuracy, may be descriptive things or self explanation and keeping things as much clear as possible do endeed make sense.
Never mind, one way or another it works and thanks for a great emulator!

Have you thought about rendering plugins for sound, input, video?
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Post by grinvader »

_willow_ wrote:plugins
You have 30 seconds to die on your own before I start helping you.
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
franpa
Gecko snack
Posts: 2374
Joined: Sun Aug 21, 2005 11:06 am
Location: Australia, QLD
Contact:

Post by franpa »

*prepares rusty axe to help*
Core i7 920 @ 2.66GHZ | ASUS P6T Motherboard | 8GB DDR3 1600 RAM | Gigabyte Geforce 760 4GB | Windows 10 Pro x64
funkyass
"God"
Posts: 1128
Joined: Tue Jul 27, 2004 11:24 pm

Post by funkyass »

franpa wrote:*prepares rusty axe to help*
*laughs as franpa decapitates himself*
Does [Kevin] Smith masturbate with steel wool too?

- Yes, but don’t change the subject.
FirebrandX
Trooper
Posts: 376
Joined: Tue Apr 19, 2005 11:08 pm
Location: DFW area, TX USA
Contact:

Post by FirebrandX »

byuu wrote:Well, spent all day working on this:
http://i73.photobucket.com/albums/i221/ ... /stbc8.png
http://i73.photobucket.com/albums/i221/ ... /stbc7.png
http://i73.photobucket.com/albums/i221/ ... /stbc6.png

4:06:59 ... made it to #8 on the high score list, and I suspect the top four of cheating (almost a minute better time, I highly doubt that's possible.)
What game is that? I thought it was "bubblebox" but that's just a site with a bunch of games on it. I know what you mean about the cheating on flash games. The top scores on several of the Adult Swim games were cheated and/or flash-hacked and many of which were proven to be mathematically impossible.

Hmm must be "spin the black circle" as far as I can tell.
NES NTSC palette file:

http://www.firebrandx.com/downloads/fbx2pal.zip
_willow_
Hazed
Posts: 51
Joined: Mon Dec 24, 2007 2:03 am
Location: Russia
Contact:

Post by _willow_ »

grinvader wrote:
_willow_ wrote:plugins
You have 30 seconds to die on your own before I start helping you.
No, it's not i propose to move all the code out of the core but to add the enumeration for auxiliary renderers support. It is not that silly. Just to add another renderer which adds the external modules. Not a thing would change for existed renderers classes except additional wrapper device.
Nightcrawler
Romhacking God
Posts: 922
Joined: Wed Jul 28, 2004 11:27 pm
Contact:

Post by Nightcrawler »

FirebrandX wrote:
byuu wrote:Well, spent all day working on this:
http://i73.photobucket.com/albums/i221/ ... /stbc8.png
http://i73.photobucket.com/albums/i221/ ... /stbc7.png
http://i73.photobucket.com/albums/i221/ ... /stbc6.png

4:06:59 ... made it to #8 on the high score list, and I suspect the top four of cheating (almost a minute better time, I highly doubt that's possible.)
What game is that? I thought it was "bubblebox" but that's just a site with a bunch of games on it. I know what you mean about the cheating on flash games. The top scores on several of the Adult Swim games were cheated and/or flash-hacked and many of which were proven to be mathematically impossible.

Hmm must be "spin the black circle" as far as I can tell.
Yeah. That cheating nonsense discourages me from really playing any online games with top scores like that. It sucks all the fun out of it.
[url=http://transcorp.romhacking.net]TransCorp[/url] - Home of the Dual Orb 2, Cho Mahou Tairyku Wozz, and Emerald Dragon SFC/SNES translations.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
Locked