View unanswered posts | View active topics It is currently Mon Feb 18, 2019 6:27 pm



This topic is locked, you cannot edit posts or make further replies.  [ 180 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7, 8  Next
bsnes v0.041 released 
Author Message
Post 
Meh, window is appearing on XP when placed at -1,-1. Changed that to 2560,1600 to stop that initial flicker before the windows appear centered. Also from the WIP I made it use showNormal() so it'll show windows even if they were previously minimized.

Quote:
Some people prefer baby seal meat.


I'm still not following your point. I've already added it. It took me a few days but it's done. Everything that worked before is exactly the same, but you now have the option of doing more. Binary size is the same, source code grew by ~2k (mostly due to extreme commenting.)

Not necessary, no; but I wanted it. Now we have it, and it's one more bit of polish (along with infinite cheat codes, infinite length descriptions in UTF-8, cheat code grouping and sorting, UPS support, single or multi user modes, resizable config windows, flexible theming and backdrop images, ...) that no other SNES emulator has yet :D

And tons of stuff I'm missing: savestates, rewind, SuperFX, SA-1, speed, macros / key combos, movies, netplay, ...

-----

This works well enough for Windows:

Code:
class Application : public QApplication {
public:
  #ifdef _WIN32
  bool winEventFilter(MSG *msg, long *result) {
    if(msg->message == WM_SYSCOMMAND) {
      if(msg->wParam == SC_SCREENSAVE || msg->wParam == SC_MONITORPOWER) {
        printf("blocked sleep\n");
        *result = 0;
        return true;
      }
    }

    return false;
  }
  #endif

  Application(int argc, char **argv) : QApplication(argc, argv) {}
};


Add XTestFakeKeyEvent sans XSync (to avoid X-Video stuttering issues per BearOso) and screensaver disable should be taken care of -- at least until someone works on the OS X port.


Tue Mar 24, 2009 7:15 pm
Regen Developer
Regen Developer
User avatar

Joined: Sun Feb 17, 2008 8:01 am
Posts: 533
Post 
byuu wrote:
This works well enough for Windows:


Umm....should just this suffice on Windows?

Code:
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, 0, SPIF_SENDCHANGE);


Tue Mar 24, 2009 8:11 pm
Profile WWW
Veteran

Joined: Wed Aug 04, 2004 5:43 pm
Posts: 861
Location: Sloop
Post 
You redesigned your site again and I can't access the WIP page anymore. It sounds like it would be a hassle for most people, though.

Quote:
that no other SNES emulator has yet :D


That might be because it's kind of useless (for this system), though. They allow the best translations, digital joypad for digital joypad and mouse for mouse.


Tue Mar 24, 2009 8:12 pm
Profile
ZSNES Shake Shake Prinny
User avatar

Joined: Wed Jul 28, 2004 4:15 pm
Posts: 5613
Location: PAL50, dood !
Post 
FitzRoy wrote:
Some people prefer baby seal meat.

Hey, it's pretty tasty and melts on the tongue. A real delicacy.

_________________
皆黙って俺について来い!!
Code:
<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)

Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54


Tue Mar 24, 2009 8:38 pm
Profile
Trooper
User avatar

Joined: Tue Apr 19, 2005 11:08 pm
Posts: 376
Location: DFW area, TX USA
Post 
byuu wrote:
(...flexible theming and backdrop images, ...)



Quickly figure out the code needed for my request on this:

A favorites database the user can make where the proper theme image is loaded with the game. :D

_________________
NES NTSC palette file:

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


Tue Mar 24, 2009 9:24 pm
Profile WWW
Post 
So how do you guys feel about bsnes requiring WinXP or newer (instead of Win2k or newer)?

If we do that, I can use RawInput without all the GetProcAddress bullshit. That'll allow independent mapping of multiple keyboards and mice. Really only super important for playable dual-Justifier support.

It would also allow support of pretty much any USB HID device, including barcode scanners and things like that. Not that I'd be all that interested in supporting said devices ... but you never know.

Quote:
A favorites database the user can make where the proper theme image is loaded with the game.


I wasn't really planning to do anything with that feature, but who knows for the future. Maybe just make it look for gamename.sfc + gamename.png and set that as the backdrop, if it exists. Assuming that's not too tough. Not promising I'll get around to it though ...


Tue Mar 24, 2009 11:50 pm
Seen it all
User avatar

Joined: Mon Jan 03, 2005 5:04 pm
Posts: 2302
Location: Germany
Post 
byuu wrote:
So how do you guys feel about bsnes requiring WinXP or newer (instead of Win2k or newer)?

I switched from 98 to XP, so no problem for me.

_________________
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list


Wed Mar 25, 2009 12:06 am
Profile WWW
Rookie

Joined: Mon Jan 24, 2005 12:45 am
Posts: 20
Post 
I am in agreement. WinXP+


Wed Mar 25, 2009 12:27 am
Profile
Trooper
User avatar

Joined: Tue Apr 19, 2005 11:08 pm
Posts: 376
Location: DFW area, TX USA
Post 
byuu wrote:

Quote:
A favorites database the user can make where the proper theme image is loaded with the game.


I wasn't really planning to do anything with that feature, but who knows for the future. Maybe just make it look for gamename.sfc + gamename.png and set that as the backdrop, if it exists. Assuming that's not too tough. Not promising I'll get around to it though ...


That would be perfect if you can do that. My Chrono Trigger them image worked great while playing through it, but I want to make themes for each of the popular games like Metroid & Zelda.

_________________
NES NTSC palette file:

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


Wed Mar 25, 2009 12:30 am
Profile WWW
Justice is Blind
User avatar

Joined: Wed Jul 28, 2004 3:33 pm
Posts: 620
Location: Test
Post 
byuu wrote:

Quote:
P.S. What controller are you using that has so many buttons and axis?


http://www.amazon.co.uk/Thrustmaster-Tr ... B000U7RJ0W

What you don't see is L1/L2/R1/R2 and pressure-sensitive L3/R3. It does force-feedback and cost me $20 new.


Hoiw do you hold that thing!?

I try to use the back triggers but the edges nip at my fingers and annoy the crap out of me. Plus that tiny is 'tiny'.

I wish they made more like the Thrustmaster Firestorm Analog 3. Wish mine didn't break.

The presence of the two big back buttons ala N64 Z button really endeared that pad to me. I want more like it that don't kill my hands.

Also... I have problems believing that many still needing to use Windows 2000 have the computer specs to even run BSNES.


Last edited by Tallgeese on Wed Mar 25, 2009 1:09 am, edited 2 times in total.



Wed Mar 25, 2009 1:04 am
Profile ICQ YIM WWW
Zealot

Joined: Tue Nov 27, 2007 7:03 am
Posts: 1325
Post 
Whaaaaaaaaaaaa? that thing looks painful to hold.


Wed Mar 25, 2009 1:06 am
Profile
Justice is Blind
User avatar

Joined: Wed Jul 28, 2004 3:33 pm
Posts: 620
Location: Test
Post 
The one byuu posted, or the big bulky one I mentioned?

Which is this:

http://www.amazon.com/Thrustmaster-Fire ... B00008DWV5


Wed Mar 25, 2009 1:10 am
Profile ICQ YIM WWW
Zealot

Joined: Tue Nov 27, 2007 7:03 am
Posts: 1325
Post 
I meant his, though that one looks uncomfortable too.


Wed Mar 25, 2009 1:19 am
Profile
Zealot
User avatar

Joined: Wed Jul 28, 2004 3:31 am
Posts: 1140
Post 
byuu wrote:
Meh, window is appearing on XP when placed at -1,-1. Changed that to 2560,1600 to stop that initial flicker before the windows appear centered.

Yeah, negative coordinates are how a window is placed off the top or left of the primary monitor. Also, those coordinates could be on screen with some huge multi-monitor setup, so it might be a good idea to check GetSystemMetrics() for SM_CXVIRTUALSCREEN and SM_CYVIRTUALSCREEN as well as SM_XVIRTUALSCREEN and SM_YVIRTUALSCREEN. The first two retrieve the size of the total desktop area, while the latter two return the coordinates of the top left of the desktop. With the primary monitor being the top left, they would be zero, but if not, they would be negative numbers, so best to add them to the width/height for the lowest coordinates which would be off-screen. Whew.


Wed Mar 25, 2009 2:04 am
Profile WWW
Hazed

Joined: Sat Jan 28, 2006 7:21 am
Posts: 76
Post 
byuu wrote:
So how do you guys feel about bsnes requiring WinXP or newer (instead of Win2k or newer)?


That is a good idea. 8)


Wed Mar 25, 2009 2:07 am
Profile
Locksmith of Hyrule
User avatar

Joined: Sun Aug 08, 2004 7:49 am
Posts: 3634
Location: 255.255.255.255
Post 
no problems here making bsnes XP+.

_________________
Image
<Nach> so why don't the two of you get your own room and leave us alone with this stupidity of yours?
NSRT here.


Wed Mar 25, 2009 2:33 am
Profile YIM WWW
Zealot

Joined: Tue Nov 27, 2007 7:03 am
Posts: 1325
Post 
Deathlike2 will get you for this!


Wed Mar 25, 2009 2:39 am
Profile
Post 
Okay, this is my first time writing a multi-threaded app, so let's see if I've done this correctly.

This is a simple app that spawns a thread to monitor WM_INPUT messages to an invisible window. It caches each message so that the main thread can periodically check to see how much the mouse has moved since the last check.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

#define _WIN32_WINNT 0x0501
#include <windows.h>

HANDLE RawInputMutex;
DWORD WINAPI RawInputThreadProc(void*);
LRESULT CALLBACK RawInputWindowProc(HWND, UINT, WPARAM, LPARAM);

class RawInput {
public:
  HWND hwnd;
  signed mouseMoveX;
  signed mouseMoveY;

  void init() {
    WNDCLASS wc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.hCursor = LoadCursor(0, IDC_ARROW);
    wc.hIcon = LoadIcon(0, IDI_APPLICATION);
    wc.hInstance = GetModuleHandle(0);
    wc.lpfnWndProc = RawInputWindowProc;
    wc.lpszClassName = "rawinputclass";
    wc.lpszMenuName = 0;
    wc.style = CS_HREDRAW | CS_VREDRAW;
    RegisterClass(&wc);

    hwnd = CreateWindow("rawinputclass", "rawinput", WS_POPUP,
      64, 64, 320, 240,
      0, 0, GetModuleHandle(0), 0);

    RAWINPUTDEVICELIST *list;
    unsigned devices = 0;
    GetRawInputDeviceList(NULL, &devices, sizeof(RAWINPUTDEVICELIST));
    list = (RAWINPUTDEVICELIST*)malloc(sizeof(RAWINPUTDEVICELIST) * devices);
    int n = GetRawInputDeviceList(list, &devices, sizeof(RAWINPUTDEVICELIST));

    for(unsigned i = 0; i < devices; i++) {
      unsigned size = 512;
      char buffer[512];
      GetRawInputDeviceInfo(list[i].hDevice, RIDI_DEVICENAME, buffer, &size);
      printf("Device '%s':\n", buffer);

      RID_DEVICE_INFO info;
      info.cbSize = sizeof(RID_DEVICE_INFO);

      size = info.cbSize;
      GetRawInputDeviceInfo(list[i].hDevice, RIDI_DEVICEINFO, &info, &size);

      if(info.dwType == RIM_TYPEMOUSE) {
        printf("Mouse %p\n", list[i].hDevice);
        printf("ID = %d\n", info.mouse.dwId);
        printf("Buttons = %d\n", info.mouse.dwNumberOfButtons);
        printf("DPI = %d\n", info.mouse.dwSampleRate);
      } else if(info.dwType == RIM_TYPEKEYBOARD) {
        printf("Keyboard\n");
        printf("Type = %d\n", info.keyboard.dwType);
        printf("Subtype = %d\n", info.keyboard.dwSubType);
        printf("Mode = %d\n", info.keyboard.dwKeyboardMode);
        printf("Function keys = %d\n", info.keyboard.dwNumberOfFunctionKeys);
        printf("Indicators = %d\n", info.keyboard.dwNumberOfIndicators);
        printf("Keys total = %d\n", info.keyboard.dwNumberOfKeysTotal);
      }

      printf("\n");
    }

    RAWINPUTDEVICE rid[2];

    rid[0].usUsagePage = 1;
    rid[0].usUsage = 2;
    rid[0].dwFlags = RIDEV_INPUTSINK;
    rid[0].hwndTarget = hwnd;

    rid[1].usUsagePage = 1;
    rid[1].usUsage = 6;
    rid[1].dwFlags = RIDEV_INPUTSINK;
    rid[1].hwndTarget = hwnd;

    RegisterRawInputDevices(rid, 2, sizeof(RAWINPUTDEVICE));
  }

  LRESULT wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
    if(msg == WM_INPUT) {
      unsigned size = 0;
      GetRawInputData((HRAWINPUT)lparam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER));
      RAWINPUT *input = (RAWINPUT*)malloc(size);
      GetRawInputData((HRAWINPUT)lparam, RID_INPUT, input, &size, sizeof(RAWINPUTHEADER));

      if(input->header.dwType == RIM_TYPEMOUSE) {
        WaitForSingleObject(RawInputMutex, INFINITE);
        mouseMoveX += input->data.mouse.lLastX;
        mouseMoveY += input->data.mouse.lLastY;
        ReleaseMutex(RawInputMutex);
      //input->header.hDevice
      //input->data.mouse.usButtonFlags
      } else if(input->header.dwType == RIM_TYPEKEYBOARD) {
      //input->data.keyboard.MakeCode
      //input->data.keyboard.Flags
      //input->data.keyboard.Message
      }

      free(input);
    }

    return DefWindowProc(hwnd, msg, wparam, lparam);
  }

  int main() {
    init();

    while(true) {
      MSG msg;
      GetMessage(&msg, hwnd, 0, 0);
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }

    return 0;
  }

  signed mouseX() {
    WaitForSingleObject(RawInputMutex, INFINITE);
    signed result = mouseMoveX;
    mouseMoveX = 0;
    ReleaseMutex(RawInputMutex);
    return result;
  }

  signed mouseY() {
    WaitForSingleObject(RawInputMutex, INFINITE);
    signed result = mouseMoveY;
    mouseMoveY = 0;
    ReleaseMutex(RawInputMutex);
    return result;
  }

  RawInput() : mouseMoveX(0), mouseMoveY(0) {
  }
} rawinput;

DWORD WINAPI RawInputThreadProc(void *param) {
  return rawinput.main();
}

LRESULT CALLBACK RawInputWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
  return rawinput.wndproc(hwnd, msg, wparam, lparam);
}

int main() {
  RawInputMutex = CreateMutex(NULL, FALSE, NULL);
  CreateThread(NULL, 0, RawInputThreadProc, 0, 0, NULL);

  while(true) {
    signed x = rawinput.mouseX(), y = rawinput.mouseY();
    if(x || y) printf("%5d, %5d\n", x, y);
    Sleep(20);
  }

  return 0;
}


Mutexes seem fairly slow, but not horribly so. I can WaitForSingleObject + ReleaseMutex about ~1.1 million times a second, so ~0.9ns per. Should be more than enough for an input driver, at least.


Wed Mar 25, 2009 7:10 pm
Hazed

Joined: Mon Dec 24, 2007 2:03 am
Posts: 51
Location: Russia
Post 
Oh no byuu, don't be paranoid! There is no need for mutexes.
You may use more gentle approach:

Code:
LRESULT wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
..
        //Atomic: adjust the movement accumulator.
        mouseMoveX += input->data.mouse.lLastX;
        //Atomic: adjust the movement accumulator.
        mouseMoveY += input->data.mouse.lLastY;
..
}


signed mouseX()
{
  //Atomic: get the result.
  register signed result = mouseMoveX;
  //Atomic: recalibrate the accumulator. (redefine the movement accumulator for new "zero" point)
  mouseMoveX -= result;
  return result;
}

signed mouseY()
{
  //Atomic: get the result.
  register signed result = mouseMoveY;
  //Atomic: recalibrate the accumulator. (redefine the movement accumulator for new "zero" point)
  mouseMoveY -= result;
  return result;
}


wndproc:
mouseMoveX += input->data.mouse.lLastX;
+= here is the atomic operation and do not require mutexes.

mouseX(), mouseY():
register signed result = mouseMoveX;
= here is the atomic operation too, so this code is iron safe, your mutex subroutine will die faster then single atomic ADD or MOV machine instructions.

Mutexes are the replacement for atomic operations, but there is TWO of them here. "mouseMove" and "result" are both ether basic integers or even registers


EDIT:

//Atomic: get the result.
register signed result = mouseMoveX;
//Atomic: recalibrate the accumulator. (redefine the movement accumulator for new "zero" point)
mouseMoveX -= result;

There is highly unlikely something happens between those instructions but if it is, i do not care, i do already got my "result" and redefine the movement accumulator for new "zero" point. If something changed between two atomic operations that something would be the only thing in the accumulator. This new "zero" point would be 99,9999...% zero. If not zero then very close to it. If it's not zero then this offset would not accumulate.

Unless of cource you calling mouseX() by separate threads, then you'll need to unite two atomic operations with mutex but that is highly unlikely you'll ever need to broke mouse input into separate threads with chaotic order.


P.S. Nice to see you are moving right direction with WM_INPUT 8). I do really hope WM_INPUT will let to read all the extended keys on keyboard.


Wed Mar 25, 2009 9:04 pm
Profile WWW
Hazed

Joined: Mon Dec 24, 2007 2:03 am
Posts: 51
Location: Russia
Post 
You may find mouse wheel readings tricky too, that is how i did it in Berserker@Quake2:

Code:
//The delta was set to 120 to allow Microsoft or other vendors to build finer-resolution wheels later,
//including perhaps a freely-rotating wheel with no notches. The expectation is that such a device
//would send more messages per rotation, but with a smaller value in each message. To support this
//possibility, you should either add the incoming delta values until WHEEL_DELTA is reached (so for a
//delta-rotation you get the same response), or scroll partial lines in response to the more frequent
//messages. You could also choose your scroll granularity and accumulate deltas until it is reached.
WHEEL_DELTA_collector += static_cast<short>(raw->data.mouse.usButtonData); //wheel delta, signed
int i = WHEEL_DELTA_collector / WHEEL_DELTA;
if (i < 0)
{
...
}
else if (i > 0)
{
...
}
WHEEL_DELTA_collector %= WHEEL_DELTA;

_________________
quake2xp audio engineer


Wed Mar 25, 2009 9:46 pm
Profile WWW
Post 
Quote:
Unless of cource you calling mouseX() by separate threads, then you'll need to unite two atomic operations with mutex but that is highly unlikely you'll ever need to broke mouse input into separate threads with chaotic order.


That's exactly what I'm doing :P
The RawInput thread will be its own, for the sole purpose of catching window messages safely (Qt / DirectInput may fight for them with GetMessage(0, ...) otherwise.)

Quote:
P.S. Nice to see you are moving right direction with WM_INPUT Cool. I do really hope WM_INPUT will let to read all the extended keys on keyboard.


The reason I don't support other keys is mostly because I don't have a cross-platform way to name them something sane. And even when I tried anyway with something like keyNNN (n = random number), DirectInput was returning 0x80 for all my media keys.

So yeah, WM_INPUT might be better in that regard. I don't like the way you have to use MakeCode + Flags to distinguish left and right shift/control/alt, but ... it works. So whatever.


Wed Mar 25, 2009 11:17 pm
Hazed

Joined: Mon Dec 24, 2007 2:03 am
Posts: 51
Location: Russia
Post 
byuu wrote:
Quote:
Unless of cource you calling mouseX() by separate threads, then you'll need to unite two atomic operations with mutex but that is highly unlikely you'll ever need to broke mouse input into separate threads with chaotic order.


That's exactly what I'm doing :P
The RawInput thread will be its own, for the sole purpose of catching window messages safely (Qt / DirectInput may fight for them with GetMessage(0, ...) otherwise.)

Sometimes i'm way too emotional. Really important is to read the mouse movement within a single thread otherwise it's just have no sense, you'll just broke your input. What are you going to do with those X&Y deltas? I do suggest to do the refresh function in a single place.

Code:
DotheXthing_null(signed result){}

LRESULT wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
..
   if (input->data.mouse.lLastX)
   {
        //thread callbacks collection:
        DotheXthing_1(input->data.mouse.lLastX);
        DotheXthing_2(input->data.mouse.lLastX);
        DotheXthing_3(input->data.mouse.lLastX);
   }
..
}

//Atomic: to disable the callback:
DotheXthing_1 = DotheXthing_null;

//Atomic: to enable the callback:
DotheXthing_1 = DotheXthing_mycallback;


Like a pizza delivery, hot data right from the mouse drivers core for any possible realtime demands, any type of threads, concurrency, etc. Still no need for mutexes. Best of all you will win the ultimate latency here for each thread all together.

the idea is to make wndproc to be kind of router, when the actual thread reader would be:

Code:
signed X_accumulator_for_this_thread

DotheXthing_mycallback(signed mouse_X)
{
        //Atomic: adjust the movement accumulator.
        X_accumulator_for_this_thread += mouse_X;
}

now you may do whatever you want in your local thread processing:

//Atomic: get the result.
Give_me_my_result_at_last = X_accumulator_for_this_thread;
//Atomic: redefine the thread-wide movement accumulator
X_accumulator_for_this_thread -= Give_me_my_result_at_last;

"Give_me_my_result_at_last" is at your disposal now..


Each thread would have their own movement accumulators and all of the threads would have the freedom to go totally offsinc or even hangup and do any duties they want like if they were connected directly to the mouse driver core.

_________________
quake2xp audio engineer


Thu Mar 26, 2009 10:27 am
Profile WWW
Post 
New WIP. This version adds RawInput support.

I strongly recommend just deleting the old config file, because all the old bindings won't work. You may also need to select the driver manually from the advanced tab (it should be the default if no config file is found.)

I now allow up to sixteen keyboards, sixteen mice and sixteen joypads to be uniquely identified and independently mappable. So if anyone wants to setup a 6-man-per tag-team game of N-warp Daisakusen, now you can. And $50 for the first person to take a picture of said event for me ;)

While ZSNES beat me to mouse support with ManyMouse, I win with "ManyKeyboard" :P

And if anyone wants to get me one of those SNES barcode battler games + hardware, I'll try and emulate a generic USB HID barcode scanner.

Let's see ... currently the mouse assignment from the UI won't work. You'll need to edit bsnes.cfg. The format is:

mouseNN.x, mouseNN.y, mouseNN.z, mouseNN.buttonXX
NN = 0 - 16, XX = 0 - 4

Need to plan how I want to design a mouse capture window, so that will be a while still.

Also didn't get around to the screensaver disable code just yet. Took me seven hours straight and I just barely finished the RawInput driver in time.

Testing would be greatly appreciated.


Thu Mar 26, 2009 2:57 pm
Regular

Joined: Sat Mar 04, 2006 3:17 pm
Posts: 307
Post 
byuu wrote:
I now allow up to sixteen keyboards, sixteen mice and sixteen joypads to be uniquely identified and independently mappable.


Awesome!

Some questions:
1. These (could) in theory all work at the same time? or is there a real limit.
2. What is the button and axis limit now with these changes? (per device)


Thu Mar 26, 2009 3:15 pm
Profile
Post 
Oh yeah, the dwSampleRate setting in the RID_DEVICE_INFO_MOUSE struct is useless. Blank on my optical / laser mice :(

tetsuo55 wrote:
Awesome!

Some questions:
1. These (could) in theory all work at the same time? or is there a real limit.
2. What is the button and axis limit now with these changes? (per device)


1. Yes, they will all work at the same time.
2a. Keyboards [up to 16]: just the standard keys. Not even RawInput gives actual keycodes for extended media keys.
2b. Mice [up to 16]: up to three axes (Z, aka scroll wheel, is pretty useless though for the SNES), and up to 8 buttons (though the core APIs for both RawInput and Xlib only provide the first five button states.)
2c. Joypads [up to 16]: up to 8 POV hats (allows 4 directions per, so 32 unique states total), 16 axes (allows 2 directions per, so 32 unique states total), 96 buttons.

So in total? 16*115 + 16*(8+3) + 16*(32+32+96) = 1840 + 176 + 2560 = 4,576 unique, mappable buttons :P
Total bindable shortcuts for all emulated devices and UI items? 12*10 + 2*4 + 6 + 2*4 + 12 = 120+8+6+8+12 = 154.
Overkill = ~2,971%


Thu Mar 26, 2009 3:32 pm
Display posts from previous:  Sort by  
This topic is locked, you cannot edit posts or make further replies.   [ 180 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7, 8  Next

Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software.