VOGONS


Reply 21 of 37, by Yushatak

User metadata
Rank Member
Rank
Member

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.

Reply 22 of 37, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

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).

Reply 23 of 37, by Yushatak

User metadata
Rank Member
Rank
Member

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;
}
}
Last edited by Yushatak on 2011-02-07, 00:28. Edited 5 times in total.

Reply 25 of 37, by Yushatak

User metadata
Rank Member
Rank
Member

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..

Last edited by Yushatak on 2013-06-02, 01:33. Edited 1 time in total.

Reply 26 of 37, by Yushatak

User metadata
Rank Member
Rank
Member

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.

Reply 27 of 37, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

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.

Reply 28 of 37, by Yushatak

User metadata
Rank Member
Rank
Member

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.

Reply 29 of 37, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

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!

Reply 30 of 37, by Yushatak

User metadata
Rank Member
Rank
Member

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.

Reply 32 of 37, by Yushatak

User metadata
Rank Member
Rank
Member

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.

Reply 35 of 37, by Yushatak

User metadata
Rank Member
Rank
Member

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).

Reply 37 of 37, by Yushatak

User metadata
Rank Member
Rank
Member

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).