Reply 20 of 37, by wd
Check out things like that:
http://sdl.beuc.net/sdl.wiki/SDL_GetWMInfo
(see the SDL_VERSION thing).
And add error checking to the functions, they usually return an error code.
Check out things like that:
http://sdl.beuc.net/sdl.wiki/SDL_GetWMInfo
(see the SDL_VERSION thing).
And add error checking to the functions, they usually return an error code.
Hrm, good catch. I'm shocked that that's relevant! 😮
*time passes*
O.O
It's fixed! THANK YOU!!!!!!!!!!!!!!!!!!!
I'd get excessively thankful, but I think that about covers it. 😁
I find that dragging the mouse around it's very slightly losing track of the exact point, but it's more than usable now and as good as I care to fight with it for (at least now, 🤣).
Edit: I just fixed a two-year-old bug without knowing C++, I think that's not half bad. 😜
Anybody care to work on the Linux/OSX side of this?
Also, wd, one more thing - where in the sourcetree are the configuration variables from the conf file? I'll need to add one for this.
Instead of making this a switch, it may be interesting to check if the touchpad
can be detected in some way, or why the SDL mouse functionality doesn't work.
Also you may want to check a number of other games, lemmings and lucas arts
adventures come to my mind.
The config system for SDL is in Config_Add_SDL (sdlmain.cpp).
Believe me, I'll be testing lots of games, because now I can finally use the mouse under DOSBox on my UMPC, which means I'll be playing them on it. 😁
The other two things are, at the moment, beyond me. I barely pulled this off, and it took help. A conf switch is a simple way to toggle it, but since I have learned a lot of C++ through this experience perhaps I'll further my learning by looking into the root cause in SDL - after all that would fix other programs on my (and other) device(s).
For now, here's some code snippets with checking blocks in place to toggle the code changes if a variable called "touchscreen" is 1 or 0:
sdlmain.cpp
static void HandleMouseMotion(SDL_MouseMotionEvent * motion) {
if (sdl.mouse.locked || !sdl.mouse.autoenable) {
if (touchscreen) {
POINT p;
GetCursorPos(&p);
HWND hwnd;
SDL_SysWMinfo wmi;
SDL_VERSION(&wmi.version); // this line is necessary!
SDL_GetWMInfo( &wmi );
hwnd = wmi.window;
ScreenToClient(hwnd,&p);
//LOG_MSG("%d,%d",p.x,p.y);
Mouse_CursorMoved(0.0f, 0.0f,
(float)(p.x-sdl.clip.x)/(sdl.clip.w-1)*sdl.mouse.sensitivity/100.0f,
(float)(p.y-sdl.clip.y)/(sdl.clip.h-1)*sdl.mouse.sensitivity/100.0f,
sdl.mouse.locked);
}
else
{
Mouse_CursorMoved((float)motion->xrel*sdl.mouse.sensitivity/100.0f,
(float)motion->yrel*sdl.mouse.sensitivity/100.0f,
(float)(motion->x-sdl.clip.x)/(sdl.clip.w-1)*sdl.mouse.sensitivity/100.0f,
(float)(motion->y-sdl.clip.y)/(sdl.clip.h-1)*sdl.mouse.sensitivity/100.0f,
sdl.mouse.locked);
}
}
}
void GFX_CaptureMouse(void) {
sdl.mouse.locked=!sdl.mouse.locked;
if (sdl.mouse.locked) and (!touchscreen) {
SDL_WM_GrabInput(SDL_GRAB_ON);
SDL_ShowCursor(SDL_DISABLE);
} else {
SDL_WM_GrabInput(SDL_GRAB_OFF);
if (sdl.mouse.autoenable || !sdl.mouse.autolock) SDL_ShowCursor(SDL_ENABLE);
}
mouselocked=sdl.mouse.locked;
}
If this is all I've got to do, then in sdlmain.cpp in the Config_Add_SDL() section:
Pbool = sdl_sec->Add_bool("touchscreen",Property::Changeable::Always,false);
Pbool->Set_help("Toggles Windows-specific alternative mouse routines for use with resistive (and possibly other) touchscreens.");
mouse.cpp
void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate) {
float dx = xrel * mouse.pixelPerMickey_x;
float dy = yrel * mouse.pixelPerMickey_y;
if((fabs(xrel) > 1.0) || (mouse.senv_x < 1.0)) dx *= mouse.senv_x;
if((fabs(yrel) > 1.0) || (mouse.senv_y < 1.0)) dy *= mouse.senv_y;
if (useps2callback) dy *= 2;
mouse.mickey_x += dx;
mouse.mickey_y += dy;
if (emulate) && (!touchscreen) {
mouse.x += dx;
mouse.y += dy;
} else {
if (CurMode->type == M_TEXT) {
mouse.x = x*CurMode->swidth;
mouse.y = y*CurMode->sheight * 8 / CurMode->cheight;
} else if ((mouse.max_x < 2048) || (mouse.max_y < 2048) || (mouse.max_x != mouse.max_y)) {
if ((mouse.max_x > 0) && (mouse.max_y > 0)) {
mouse.x = x*mouse.max_x;
mouse.y = y*mouse.max_y;
} else {
mouse.x += xrel;
mouse.y += yrel;
}
} else { // Games faking relative movement through absolute coordinates. Quite surprising that this actually works..
mouse.x += xrel;
mouse.y += yrel;
}
}
There are no changes to mouse.cpp, are there???
And the SDL_VERSION isn't random 😉 They're pre-filling that structure.
Yes, there is one small tiny change - in the "if (emulate)" line, you'll now find that it's "if (emulate) && (!touchscreen)" instead. The emulated section fails with my system because it relies on relative data which my routines don't provide.
Well, the SDL_VERSION seemed random to me, but I'll modify the comment accordingly.
I updated the above post with conf section changes and a an implied question sometime while you were posting.
Also, I realize this can't be committed or anything until there's a *nix routine or at least some detection code.. I presume DOSBox already detects what OS it's running on, what variable can I reference as a check to make sure my code doesn't try to activate on, say, Linux, if somebody were to enable to conf variable there?
Edit: One last problem. I can't seem to get the code to recognize the touchscreen variable. I've fixed other syntax errors in my then-untested code (will update once this is fixed too), but if I reference my new conf variable called "touchscreen" as just "touchscreen", it says it's not defined in the given scope, and if I try "sdl.touchscreen", it says the SDL block has no member with that name. What's the right way to access a conf var?
For my, and others' use until I get a better version complete with a toggle, etc., here's a working build locked into my mouse routines:
http://www.mediafire.com/download/bx0j323z6jz … OSBox+Touch.rar
Should work with normal mice too, but I've not tried.
Edit:
I just tested with Lemmings (vgalemmi.exe, CD version) and the cursor behaves strangely there, fullscreen and windowed. I don't really understand why it would behave differently in game A vs. game B, when a mouse works on either, and I managed to equate the touchscreen to a mouse for game A.
This is very disheartening.
Perhaps it's a question of the "maximum" values, the sdl clipping values, etc - I don't know. I do know that you can replace the motion function with a set coordinates function (using the same coordinates I've spent all this time working on getting), and that may prove more useful for many games.
More work to be done... *sigh*
Edit 6/1/2013: updated link to Mediafire, they changed their link structure and the old one died. Still getting contacted for this - there is definitely some interest, just not among those who can do anything about it..
I think I'll either modify the code on a per-game basis and do special cases where there's no windows version of a game and it requires a mouse to play under DOSBox and won't work under NTVDM/VDMSound, etc. (Dungeon Keeper, for example), or I'll dig into SDL. I'll start by digging into SDL, but if it proves too much I'll just fix DOSBox on a per-game basis for my own needs and release the various fix code - maybe someone will identify the root problem at some point if that's the path I take.
and if I try "sdl.touchscreen", it says the SDL block has no member with that name.
Check that typedef of the SDL_block or how it's called, you have to add the touchscreen boolean var there first.
I just tested with Lemmings (vgalemmi.exe, CD version) and the cursor behaves strangely there, fullscreen and windowed. I don't really understand why it would behave differently in game A vs. game B
Well it fully depends on what the game does with the coordinates (see my example of a game
that re-positions the cursor and draws a custom one at an arbitrary location, you will NEVER
get that in sync with your pen position).
Check if the mouse works for that game in windows/linux with the config option autolock set to false.
If it doesn't work there either there's not really much you can do about it.
Never say never, there's always *something* you can do about it. 😁
I.e., if I have to I can store the last coordinates of the mouse (starting with the middle of the DOSBox screen before any movement) and then each time the mouse function is called I could calculate relative movement and feed it in, for example.
Will continue to look into this after a break from it for at least a day.
So sdl.touchscreen would be the typical way to access a conf variable, then? I will look into that too.
that won't work as you don't know the position of the mouse that the game uses
Water flows down the stream
How to ask questions the smart way!
What about if I hook into somewhere that loops regularly, like the CPU code, and update mouse coordinates based on absolute position on the screen converted to relative coordinates (ScreenToClient) using Mouse_SetCursor()?
Or wait, would that be no improvement?
Could you provide me more information on how games use the cursor in DOS? I really am just becoming aware that they don't all keep track of absolute coordinates or lock the cursor to the middle and use absolute coordinates to calculate direction, as a modern FPS does.
Could you provide me more information on how games use the cursor in DOS?
Read what i wrote (twice). They can do anything they like, and some actually do that.
Well of course, I don't expect some blanket solution. I just figured perhaps there was some documentation on possible approaches to using mouse data from DOS. With that perhaps I could establish the most common methods and build a list of games that uses each, and a fix for each, and work out solution for multiple games instead of just the absolute-coordinate-accepting games that way.
Hi. I've just registered to say thanks. The file provided in this thread has allowed me to play Eye of the Beholder perfectly in window mode! 😀
Thanks a lot!!! I used your build and I can play several Old Dos wargames like V for Victory, Third Reich ... on HP 2310TI touch screen.
I found some documentation:
http://blogs.distant-earth.com/wp/?p=293
This suggests that with two lines of code, DOSBox could attain full touchscreen support...
It's been aeons since I dove into the DOSBox code regardless of knowing C/C++ or not, so I'm again rusty as crap. Would anybody care to shove those lines into a build? I'd be glad to test - I own two touchscreen PCs (one UMPC, one desktop, resistive and capacitative respectively).
could attain full touchscreen support...
Re-read *this* thread.
Reasons it doesn't work now:
-Everything expects relative input, touchscreens provide absolute input.
-DOS games handle mouse input in a variety of ways.
In this thread I solved the first problem, but only for Windows machines. This solution fixes it on any platform, and thus could actually go into the main DOSBox code as an option.
I also solved the second problem, but only for one type of input scheme. It is a common one, and thus works for a number of games, but not all by any means.
Anyway, fixing touchscreen support (which is what I said) is important, and this will do that. It won't make every game work with touchscreens, but it will make DOSBox work with them. I never meant to insinuate that every game would magically work if we changed those options.
I do have a new idea for mouse support, though. A hook could be planted in the code to load mouse coordinate handling algorithms from a file or variable defined in the conf file - this would allow for different mouse handling routines for any given program run automatically via conf file, and put the burden of making a given game work on the userbase, instead of the DOSBox devs. It'd have to provide some simple variables, like window position X/Y, window size X/Y, absolute cursor position X/Y, and then give you slots to define the math for the output X and Y of where the mouse is. This way a user can tweak it without constant recompiling and as extensive technical knowledge - just math and observation.
I don't expect anybody to jump on the bandwagon with my second idea here, but I think it's reasonable to make touchscreen input function properly with DOSBox without requiring a special build. Some programs/apps work right out of the box once you feed them proper coordinates (as this would).