joncampbell123 / dosbox-x

DOSBox-X fork of the DOSBox project
GNU General Public License v2.0
2.81k stars 383 forks source link

Reduced dependency on essential third-party libraries to increase portability #192

Open ghost opened 8 years ago

ghost commented 8 years ago

It would be interesting to reduce dependency on the essential 3rd party libraries, particularly SDL. This would increase portability of the video/audio/input functions to other multimedia libraries, even within Linux where the SDL functions could be split among more than one library.

By using the dosbox/SDL2 patch as a reference, the essential SDL functions seem to mainly reside in the sdl* files - sdl_mapper, sdlmain, mixer, sdl_gui, and perhaps less critically in gui_tk and cdrom. If these functions are further scattered about the source code, then it may help to consolidate these functions into one or a few files. Likewise, the essential functions, such as the 'surface' output routine, could be identified as the essential video function for future ports, so that others would know how to construct a minimal build and which functions must be ported.

Is it possible to have dosbox-x dependent on just several 3rd party functions?

joncampbell123 commented 8 years ago

I would like to see that too! But, carefully. Take it one incremental step at a time. Perhaps it would help with issues surrounding non-US keyboards as noted.

ghost commented 8 years ago

The sdl input code in sdl_mapper seems more complex than the video/audio dependencies. I wonder if it would be easier to remove the joystick code by definition lines and also remove the internal mapper from that code. Would it be possible to exchange the internal mapper with a text based configuration file? This would remove a lot of the dependencies and allow for simpler keyboard functionality by use of other libraries. And it may make it easier to debug any input issues.

sikthehedgehog commented 8 years ago

Honestly I was gonna say that it's kind of dumb about SDL in particular since the whole point of that library is to be a portable abstraction of the OS APIs and that you'd be better off porting SDL instead. But then I realize DOSBox is still using SDL 1.2 which is not supported anymore, we should try getting it on SDL 2.0 instead which works better on modern systems (and supports new stuff, the biggest loss would be CD audio).

So maybe this could help with that as a side effect?

ghost commented 8 years ago

Post in the sdl2 thread. This issue is about the subject in the title instead.

joncampbell123 commented 8 years ago

I would be OK with dropping external CD-ROM support if it makes porting to SDL 2.0 easier. I have personal experience with device ioctl's to reimplement it later anyway, see my "jarchdvd" project as an example of a DVD ripping/backup utility.

joncampbell123 commented 8 years ago

@box-tortoise Not exactly, this is about reducing third party library dependence while the thread you're referring to explicitly focuses on SDL2.

joncampbell123 commented 8 years ago

Also, I personally haven't run DOS games directly off CD-ROM in ages. I've always used an ISO image or BIN/CUE combination because it means I can just pull the game off my NAS or a pen drive and unzip it to play it again instead of pulling out the CD.

ghost commented 8 years ago

I agree. That cd-rom code could be defined out.

ghost commented 8 years ago

If sdl is truly portable/abstract then the keyboard code in sdl_mapper wouldn't have OS specific code - which it does.

joncampbell123 commented 8 years ago

Eh, the problem is that at some level, code has to call OS specific code. In this case, SDL takes on the job of calling the OS specific code so that DOSBox (or anything else) doesn't have to.

sikthehedgehog commented 8 years ago

If sdl is truly portable/abstract then the keyboard code in sdl_mapper wouldn't have OS specific code - which it does.

To be fair, that's also one of the reasons I mentioned SDL 2.0. To be more specific, 1.2's support for keyboard layouts is... kind of lackluster to say the least. With 2.0 I can figure out the virtual key from the scancode without much problem (in Sol I use this to show the proper label of a key regardless of layout) and it can handle IME input properly (which 1.2 can't do at all), although I'm not sure if IME support is useful here.

In any case keyboard layout support will remain a mess for the simple fact that DOS can completely override it, so having the emulated DOS itself take care of that really isn't much of a stretch. The problem is when it gets in that weird situation that it tries to use the host layout but only accepts the emulated layout, which can result in some keys becoming unusable (e.g. ES keyboard on US layout, you can't enter : because you're getting a Ñ and it gets filtered out).

In any case my point was that whatever extra abstraction is done for this would also help with transitioning the SDL version.

ghost commented 8 years ago

I agree with both of you. I would like if the input code was fully abstract or nearly so, at least in terms of coding style.

ghost commented 8 years ago

I meant that sdlmapper has os specific code and SDL code. I can find an example.

ghost commented 8 years ago
#if defined (MACOSX)
static SDLKey sdlkey_map[]={
    /* Main block printables */
    /*00-05*/ SDLK_a, SDLK_s, SDLK_d, SDLK_f, SDLK_h, SDLK_g,
#if defined (MACOSX)
            /* On Mac on US keyboards, scancode 0 is actually the 'a'
             * key.  For good measure exclude all printables from this
             * condition. */
            && (keysym.sym < SDLK_SPACE || keysym.sym > SDLK_WORLD_95)
#endif
#if defined (MACOSX)
    /* Intl Mac keyboards in US layout actually put U+00A7 SECTION SIGN here */
    {"lessthan",SDLK_WORLD_0},
#if defined (MACOSX)
        /* nothing */

It would be ideal to reduce the number of OS specific exceptions for porters and place these in a separate section of code so the essential parts are known. Also, it would be convenient to have a configure option to find the scancodes, although best if not SDL dependent.

The above is just for macosx, but the win32 code is extended, too.

ghost commented 8 years ago

And this could be abstracted further by definitions:

if (event->type!=SDL_KEYDOWN && event->type!=SDL_KEYUP) return false;

So that there is a central location of definitions for porting to non-sdl libraries.

ghost commented 8 years ago

@joncampbell123: does this commit mark the last of your windows support, or have you not ended windows support officially yet? Just curious so I know which commit I need to use for my final windows build to compile with VS2015 before I switch to Linux.

joncampbell123 commented 8 years ago

Yes, I would call that the last commit. The other reason is a branch point to begin porting to SDL 2, carefully

ghost commented 8 years ago

I looked over the keyboard functions in sdl_mapper since the joystick code can initially be defined out. There are two paths in the current code to process the keys of the keyboard, "usescancodes" on or off; although it requires an array of keys that may be OS specific. However, I agree that SDL2 and its implementation of scancodes is more portable and Allegro seems to use the same - so other libraries would more likely use this scheme, too.

There are just several lines to modify to do this and it should be possible to initially build dosbox-x with SDL1 and SDL2, so the keyboard could run off SDL2 while the remainder by the old way. This would allow for the slow replacement process that you suggested along with the ability to test as each section is modified.

The goal of simple portability should be met if the SDL dependent lines are well documented or placed in a single block of code.

The audio and possibly the threading should require little modification. Also, the video code changes should be fairly minimal since dosbox-x isn't loaded with all possible output modes.

ghost commented 8 years ago

Given the binary is linked with SDL1 and SDL2, here is a way to use only the SDL2 keyboard code without duplicating symbols in SDL1: http://stackoverflow.com/questions/1601900/dont-expose-symbols-from-a-used-library-in-own-static-library -and- http://stackoverflow.com/questions/9648655/how-to-hide-the-exported-symbols-name-within-a-shared-library

And here are code bits from the dosbox/sdl2 patch which are relevant to the keyboard input:

@@ -299,6 +301,9 @@ protected:
 };

+
+#if !SDL2
+
 #define MAX_SDLKEYS 323

 static bool usescancodes;
@@ -469,23 +474,42 @@ Bitu GetKeyCode(SDL_keysym keysym) {
    }
 }

+#endif
+
+

 class CKeyBind;
 class CKeyBindGroup;

 class CKeyBind : public CBind {
 public:
+#if SDL2
+   CKeyBind(CBindList * _list,SDL_Scancode _key) : CBind(_list) {
+#else
    CKeyBind(CBindList * _list,SDLKey _key) : CBind(_list) {
+#endif
        key = _key;
    }
    void BindName(char * buf) {
+#if SDL2
+       sprintf(buf,"Key %s",SDL_GetScancodeName(key));
+#else
        sprintf(buf,"Key %s",SDL_GetKeyName(MapSDLCode((Bitu)key)));
+#endif
    }
    void ConfigName(char * buf) {
+#if SDL2
+       sprintf(buf,"key %d",key);
+#else
        sprintf(buf,"key %d",MapSDLCode((Bitu)key));
+#endif
    }
 public:
+#if SDL2
+   SDL_Scancode key;
+#else
    SDLKey key;
+#endif
 };

 class CKeyBindGroup : public  CBindGroup {
@@ -501,28 +525,44 @@ public:
        if (strncasecmp(buf,configname,strlen(configname))) return 0;
        StripWord(buf);char * num=StripWord(buf);
        Bitu code=ConvDecWord(num);
+#if SDL2
+       CBind * bind=CreateKeyBind((SDL_Scancode)code);
+#else
        if (usescancodes) {
            if (code<MAX_SDLKEYS) code=scancode_map[code];
            else code=0;
        }
        CBind * bind=CreateKeyBind((SDLKey)code);
+#endif
        return bind;
    }
    CBind * CreateEventBind(SDL_Event * event) {
        if (event->type!=SDL_KEYDOWN) return 0;
+#if SDL2
+       return CreateKeyBind(event->key.keysym.scancode);
+#else
        return CreateKeyBind((SDLKey)GetKeyCode(event->key.keysym));
+#endif
    };
    bool CheckEvent(SDL_Event * event) {
        if (event->type!=SDL_KEYDOWN && event->type!=SDL_KEYUP) return false;
+#if SDL2
+       Bitu key = event->key.keysym.scancode;
+#else
        Bitu key=GetKeyCode(event->key.keysym);
 //     LOG_MSG("key type %i is %x [%x %x]",event->type,key,event->key.keysym.sym,event->key.keysym.scancode);
        assert(Bitu(event->key.keysym.sym)<keys);
+#endif
        if (event->type==SDL_KEYDOWN) ActivateBindList(&lists[key],0x7fff,true);
        else DeactivateBindList(&lists[key],true);
        return 0;
    }
+#if SDL2
+   CBind * CreateKeyBind(SDL_Scancode _key) {
+#else
    CBind * CreateKeyBind(SDLKey _key) {
        if (!usescancodes) assert((Bitu)_key<keys);
+#endif
        return new CKeyBind(&lists[(Bitu)_key],_key);
    }
 private:
@@ -2042,6 +2141,49 @@ static struct {
    const char * eventend;
    Bitu key;
 } DefaultKeys[]={
+
+#if SDL2
+
+   {"f1",SDL_SCANCODE_F1},     {"f2",SDL_SCANCODE_F2},     {"f3",SDL_SCANCODE_F3},     {"f4",SDL_SCANCODE_F4},
+   {"f5",SDL_SCANCODE_F5},     {"f6",SDL_SCANCODE_F6},     {"f7",SDL_SCANCODE_F7},     {"f8",SDL_SCANCODE_F8},
+   {"f9",SDL_SCANCODE_F9},     {"f10",SDL_SCANCODE_F10},   {"f11",SDL_SCANCODE_F11},   {"f12",SDL_SCANCODE_F12},
+
+   {"1",SDL_SCANCODE_1},       {"2",SDL_SCANCODE_2},       {"3",SDL_SCANCODE_3},       {"4",SDL_SCANCODE_4},
+   {"5",SDL_SCANCODE_5},       {"6",SDL_SCANCODE_6},       {"7",SDL_SCANCODE_7},       {"8",SDL_SCANCODE_8},
+   {"9",SDL_SCANCODE_9},       {"0",SDL_SCANCODE_0},
+
+   {"a",SDL_SCANCODE_A},       {"b",SDL_SCANCODE_B},       {"c",SDL_SCANCODE_C},       {"d",SDL_SCANCODE_D},
+   {"e",SDL_SCANCODE_E},       {"f",SDL_SCANCODE_F},       {"g",SDL_SCANCODE_G},       {"h",SDL_SCANCODE_H},
+   {"i",SDL_SCANCODE_I},       {"j",SDL_SCANCODE_J},       {"k",SDL_SCANCODE_K},       {"l",SDL_SCANCODE_L},
+   {"m",SDL_SCANCODE_M},       {"n",SDL_SCANCODE_N},       {"o",SDL_SCANCODE_O},       {"p",SDL_SCANCODE_P},
+   {"q",SDL_SCANCODE_Q},       {"r",SDL_SCANCODE_R},       {"s",SDL_SCANCODE_S},       {"t",SDL_SCANCODE_T},
+   {"u",SDL_SCANCODE_U},       {"v",SDL_SCANCODE_V},       {"w",SDL_SCANCODE_W},       {"x",SDL_SCANCODE_X},
+   {"y",SDL_SCANCODE_Y},       {"z",SDL_SCANCODE_Z},       {"space",SDL_SCANCODE_SPACE},
+   {"esc",SDL_SCANCODE_ESCAPE},    {"equals",SDL_SCANCODE_EQUALS},     {"grave",SDL_SCANCODE_GRAVE},
+   {"tab",SDL_SCANCODE_TAB},       {"enter",SDL_SCANCODE_RETURN},      {"bspace",SDL_SCANCODE_BACKSPACE},
+   {"lbracket",SDL_SCANCODE_LEFTBRACKET},                      {"rbracket",SDL_SCANCODE_RIGHTBRACKET},
+   {"minus",SDL_SCANCODE_MINUS},   {"capslock",SDL_SCANCODE_CAPSLOCK}, {"semicolon",SDL_SCANCODE_SEMICOLON},
+   {"quote", SDL_SCANCODE_APOSTROPHE}, {"backslash",SDL_SCANCODE_BACKSLASH},   {"lshift",SDL_SCANCODE_LSHIFT},
+   {"rshift",SDL_SCANCODE_RSHIFT}, {"lalt",SDL_SCANCODE_LALT},         {"ralt",SDL_SCANCODE_RALT},
+   {"lctrl",SDL_SCANCODE_LCTRL},   {"rctrl",SDL_SCANCODE_RCTRL},       {"comma",SDL_SCANCODE_COMMA},
+   {"period",SDL_SCANCODE_PERIOD}, {"slash",SDL_SCANCODE_SLASH},       {"printscreen",SDL_SCANCODE_PRINTSCREEN},
+   {"scrolllock",SDL_SCANCODE_SCROLLLOCK}, {"pause",SDL_SCANCODE_PAUSE},       {"pagedown",SDL_SCANCODE_PAGEDOWN},
+   {"pageup",SDL_SCANCODE_PAGEUP}, {"insert",SDL_SCANCODE_INSERT},     {"home",SDL_SCANCODE_HOME},
+   {"delete",SDL_SCANCODE_DELETE}, {"end",SDL_SCANCODE_END},           {"up",SDL_SCANCODE_UP},
+   {"left",SDL_SCANCODE_LEFT},     {"down",SDL_SCANCODE_DOWN},         {"right",SDL_SCANCODE_RIGHT},
+   {"kp_0",SDL_SCANCODE_KP_0}, {"kp_1",SDL_SCANCODE_KP_1}, {"kp_2",SDL_SCANCODE_KP_2}, {"kp_3",SDL_SCANCODE_KP_3},
+   {"kp_4",SDL_SCANCODE_KP_4}, {"kp_5",SDL_SCANCODE_KP_5}, {"kp_6",SDL_SCANCODE_KP_6}, {"kp_7",SDL_SCANCODE_KP_7},
+   {"kp_8",SDL_SCANCODE_KP_8}, {"kp_9",SDL_SCANCODE_KP_9}, {"numlock",SDL_SCANCODE_NUMLOCKCLEAR},
+   {"kp_divide",SDL_SCANCODE_KP_DIVIDE},   {"kp_multiply",SDL_SCANCODE_KP_MULTIPLY},
+   {"kp_minus",SDL_SCANCODE_KP_MINUS},     {"kp_plus",SDL_SCANCODE_KP_PLUS},
+   {"kp_period",SDL_SCANCODE_KP_PERIOD},   {"kp_enter",SDL_SCANCODE_KP_ENTER},
+
+   /* Is that the extra backslash key ("less than" key) */
+   /* on some keyboards with the 102-keys layout??      */
+   {"lessthan",SDL_SCANCODE_NONUSBACKSLASH},
+
+#else
+
    {"f1",SDLK_F1},     {"f2",SDLK_F2},     {"f3",SDLK_F3},     {"f4",SDLK_F4},
    {"f5",SDLK_F5},     {"f6",SDLK_F6},     {"f7",SDLK_F7},     {"f8",SDLK_F8},
    {"f9",SDLK_F9},     {"f10",SDLK_F10},   {"f11",SDLK_F11},   {"f12",SDLK_F12},
@@ -2083,6 +2225,8 @@ static struct {
    {"lessthan",SDLK_LESS},
 #endif

+#endif
+
    {0,0}
 };
joncampbell123 commented 8 years ago

@box-tortoise I'm going to be busy with work and video production for awhile. Would you be ok if I gave you the ability to commit to this repo with Github's collaborator system?

ghost commented 8 years ago

That'd be great, thanks! Would it be best to make small fixes and enhancements only? But not alter the existing code which is known to work?

joncampbell123 commented 8 years ago

Keep the commits small and incremental, and you'll be fine. If you have any larger modifications or disruptive changes try to do them in a separate branch or repository in a way that you can later merge them in.

It is done.

ghost commented 8 years ago

Thank you! And for the guidance. :)

ghost commented 8 years ago

Here are the hints to isolate keyboard functions for porting away from SDL. Note that mapper_init is disabled, so this is an alternate path to mapping keys from dosbox-0.60. However, it is missing the modified keys used by dosbox for special functions (such as ctrl-f9 to exit) and also the enhanced keyboard emulation for starting a Windows guest.

diff -rupN dosbox-ORIG//src/gui/sdlmain.cpp dosbox//src/gui/sdlmain.cpp
--- dosbox-ORIG//src/gui/sdlmain.cpp    2016-08-06 21:57:24 -0400
+++ dosbox//src/gui/sdlmain.cpp 2016-08-12 21:44:39 -0400
@@ -86,6 +86,12 @@ void SHELL_Init(void);
 void CPU_Core_Dyn_X86_Shutdown(void);
 #endif

+#define KBD_MOD_ALT        0x1
+#define KBD_MOD_CTRL   0x2
+#define KBD_MOD_SHIFT  0x4
+
+static void HandleKey(SDL_KeyboardEvent * key);
+
 #if C_OPENGL
 #include "SDL_opengl.h"

@@ -1760,6 +1766,7 @@ void GFX_Events() {
            if (((event.key.keysym.sym == SDLK_TAB )) && (event.key.keysym.mod & KMOD_ALT)) break;
            // ignore tab events that arrive just after regaining focus. (likely the result of alt-tab)
            if ((event.key.keysym.sym == SDLK_TAB) && (GetTicks() - sdl.focus_ticks < 2)) break;
+           HandleKey(&event.key);
 #endif
 #if defined (MACOSX)           
        case SDL_KEYDOWN:
@@ -2261,7 +2268,7 @@ int main(int argc, char* argv[]) {
        }

        /* Init the keyMapper */
-       MAPPER_Init();
+       // MAPPER_Init();
        if (control->cmdline->FindExist("-startmapper")) MAPPER_RunInternal();

        bool run_machine;
@@ -2419,3 +2426,140 @@ void GFX_ShutDown(void) {
    if (sdl.mouse.locked) GFX_CaptureMouse();
    if (sdl.desktop.fullscreen) GFX_SwitchFullScreen();
 }
+
+static void HandleKey(SDL_KeyboardEvent * key) {
+   KBD_KEYS code;
+   switch (key->keysym.sym) {
+   case SDLK_1:code=KBD_1;break;
+   case SDLK_2:code=KBD_2;break;
+   case SDLK_3:code=KBD_3;break;
+   case SDLK_4:code=KBD_4;break;
+   case SDLK_5:code=KBD_5;break;
+   case SDLK_6:code=KBD_6;break;
+   case SDLK_7:code=KBD_7;break;
+   case SDLK_8:code=KBD_8;break;
+   case SDLK_9:code=KBD_9;break;
+   case SDLK_0:code=KBD_0;break;
+
+   case SDLK_q:code=KBD_q;break;
+   case SDLK_w:code=KBD_w;break;
+   case SDLK_e:code=KBD_e;break;
+   case SDLK_r:code=KBD_r;break;
+   case SDLK_t:code=KBD_t;break;
+   case SDLK_y:code=KBD_y;break;
+   case SDLK_u:code=KBD_u;break;
+   case SDLK_i:code=KBD_i;break;
+   case SDLK_o:code=KBD_o;break;
+   case SDLK_p:code=KBD_p;break;
+
+   case SDLK_a:code=KBD_a;break;
+   case SDLK_s:code=KBD_s;break;
+   case SDLK_d:code=KBD_d;break;
+   case SDLK_f:code=KBD_f;break;
+   case SDLK_g:code=KBD_g;break;
+   case SDLK_h:code=KBD_h;break;
+   case SDLK_j:code=KBD_j;break;
+   case SDLK_k:code=KBD_k;break;
+   case SDLK_l:code=KBD_l;break;
+
+   case SDLK_z:code=KBD_z;break;
+   case SDLK_x:code=KBD_x;break;
+   case SDLK_c:code=KBD_c;break;
+   case SDLK_v:code=KBD_v;break;
+   case SDLK_b:code=KBD_b;break;
+   case SDLK_n:code=KBD_n;break;
+   case SDLK_m:code=KBD_m;break;
+
+
+   case SDLK_F1:code=KBD_f1;break;
+   case SDLK_F2:code=KBD_f2;break;
+   case SDLK_F3:code=KBD_f3;break;
+   case SDLK_F4:code=KBD_f4;break;
+   case SDLK_F5:code=KBD_f5;break;
+   case SDLK_F6:code=KBD_f6;break;
+   case SDLK_F7:code=KBD_f7;break;
+   case SDLK_F8:code=KBD_f8;break;
+   case SDLK_F9:code=KBD_f9;break;
+   case SDLK_F10:code=KBD_f10;break;
+   case SDLK_F11:code=KBD_f11;break;
+   case SDLK_F12:code=KBD_f12;break;
+
+   case SDLK_ESCAPE:code=KBD_esc;break;
+   case SDLK_TAB:code=KBD_tab;break;
+   case SDLK_BACKSPACE:code=KBD_backspace;break;
+   case SDLK_RETURN:code=KBD_enter;break;
+   case SDLK_SPACE:code=KBD_space;break;
+
+   case SDLK_LALT:code=KBD_leftalt;break;
+   case SDLK_RALT:code=KBD_rightalt;break;
+   case SDLK_LCTRL:code=KBD_leftctrl;break;
+   case SDLK_RCTRL:code=KBD_rightctrl;break;
+   case SDLK_LSHIFT:code=KBD_leftshift;break;
+   case SDLK_RSHIFT:code=KBD_rightshift;break;
+
+   case SDLK_CAPSLOCK:code=KBD_capslock;break;
+   case SDLK_SCROLLOCK:code=KBD_scrolllock;break;
+   case SDLK_NUMLOCK:code=KBD_numlock;break;
+   
+   case SDLK_BACKQUOTE:code=KBD_grave;break;
+   case SDLK_MINUS:code=KBD_minus;break;
+   case SDLK_EQUALS:code=KBD_equals;break;
+   case SDLK_BACKSLASH:code=KBD_backslash;break;
+   case SDLK_LEFTBRACKET:code=KBD_leftbracket;break;
+   case SDLK_RIGHTBRACKET:code=KBD_rightbracket;break;
+
+   case SDLK_SEMICOLON:code=KBD_semicolon;break;
+   case SDLK_QUOTE:code=KBD_quote;break;
+   case SDLK_PERIOD:code=KBD_period;break;
+   case SDLK_COMMA:code=KBD_comma;break;
+   case SDLK_SLASH:code=KBD_slash;break;
+
+   case SDLK_INSERT:code=KBD_insert;break;
+   case SDLK_HOME:code=KBD_home;break;
+   case SDLK_PAGEUP:code=KBD_pageup;break;
+   case SDLK_DELETE:code=KBD_delete;break;
+   case SDLK_END:code=KBD_end;break;
+   case SDLK_PAGEDOWN:code=KBD_pagedown;break;
+   case SDLK_LEFT:code=KBD_left;break;
+   case SDLK_UP:code=KBD_up;break;
+   case SDLK_DOWN:code=KBD_down;break;
+   case SDLK_RIGHT:code=KBD_right;break;
+
+   case SDLK_KP1:code=KBD_kp1;break;
+   case SDLK_KP2:code=KBD_kp2;break;
+   case SDLK_KP3:code=KBD_kp3;break;
+   case SDLK_KP4:code=KBD_kp4;break;
+   case SDLK_KP5:code=KBD_kp5;break;
+   case SDLK_KP6:code=KBD_kp6;break;
+   case SDLK_KP7:code=KBD_kp7;break;
+   case SDLK_KP8:code=KBD_kp8;break;
+   case SDLK_KP9:code=KBD_kp9;break;
+   case SDLK_KP0:code=KBD_kp0;break;
+
+   // case SDLK_KP_DIVIDE:code=KBD_kpslash;break;
+   case SDLK_KP_MULTIPLY:code=KBD_kpmultiply;break;
+   case SDLK_KP_MINUS:code=KBD_kpminus;break;
+   case SDLK_KP_PLUS:code=KBD_kpplus;break;
+   case SDLK_KP_ENTER:code=KBD_kpenter;break;
+   case SDLK_KP_PERIOD:code=KBD_kpperiod;break;
+
+   /* Special Keys */
+   default:
+       code=KBD_1;
+       LOG(LOG_KEYBOARD,LOG_ERROR)("Unhandled SDL keysym %d",key->keysym.sym);
+       break;
+   }
+   /* Check the modifiers */
+   Bitu mod=
+       ((key->keysym.mod & KMOD_CTRL) ? KBD_MOD_CTRL : 0) |
+       ((key->keysym.mod & KMOD_ALT) ? KBD_MOD_ALT : 0) |
+       ((key->keysym.mod & KMOD_SHIFT) ? KBD_MOD_SHIFT : 0);
+   // Bitu ascii=key->keysym.unicode<128 ? key->keysym.unicode : 0;
+#ifdef MACOSX
+   // HACK: Fix backspace on Mac OS X 
+   // REMOVE ME oneday
+   if (code==KBD_backspace)
+       ascii=8;
+#endif
+   KEYBOARD_AddKey(code,(key->state==SDL_PRESSED));
+}
ghost commented 8 years ago

It doesn't seem that sdl_mapper.cpp uses any of the SDL thread functions. If true, could this line be removed from that file: #include "SDL_thread.h"?

Also, there is an alternative multithreading library here that handles high numbers of context switches per second: http://byuu.org/library/libco/. I don't think this applies to any of the emulation in dosbox-x, but perhaps PCem could benefit from it. That emulator uses multithreading in its 3d video emulation, but I don't know whether it meets the criterion of >100,000 context switches per second.

ghost commented 8 years ago

I verified that its context switching is not meeting that criterion. It's a few orders of magnitude lower, at least from logging wake_fifo_thread.

masaykh commented 8 years ago

maybe something more native? on windows it can be mingw thread library

ghost commented 8 years ago

Good suggestion.