DosBox MouseMove helper for absolute coordinates

Put simple Tips and Tricks that are not entire Tutorials in this forum
Lionautic
Posts: 2
Joined: 15 Jul 2020, 00:09

DosBox MouseMove helper for absolute coordinates

Post by Lionautic » 15 Jul 2020, 05:47

Here is a function for mouse moving in DosBox. It fixes some problems when using MouseMove with absolute coordinates in DosBox.

Could help if you have problems with:
  • mouse cursor does not move to the correct position
  • mouse cursor always moves to edges
  • mouse cursor moves only to the center of window width or window height

Code: Select all

CoordMode, Pixel, Client
CoordMode, Mouse, Client

; global vars
appOriginalWidth  := 320  ; original width of the dos app/game (common 320)
appOriginalHeight := 240  ; original height of the dos app/game (common 240)
appScreenScale    := 1    ; scale factor (see "Actions > #appScreenScale" in description below for the correct value)

DosBoxMouseMove(x, y) {
		
	global appOriginalWidth, appOriginalHeight, appScreenScale
	
	x := x * appScreenScale
	y := y * appScreenScale
		
	MouseMove, 0, 0
	
	while (x > 0)
	{
		if (x > appOriginalWidth) {
			MouseMove, appOriginalWidth, 0, 0, R
			x -= appOriginalWidth
		}
		else {
			MouseMove, x, 0, 0, R
			x = 0
		}
	}
	
	while (y > 0)
	{
		if (y > appOriginalHeight) {
			MouseMove, 0, appOriginalHeight, 0, R
			y -= appOriginalHeight
		}
		else {
			MouseMove, 0, y, 0, R
			y = 0
		}
	}	
}


Explanation

There are three layers of coordinates:
  • original app/game resolution (320x240)
  • DosBox basic resolution (640x480)
  • DosBox window resolution (can differ)

Conditions
  • MouseMove can not move more than the original resolution width or height to work exactly.
  • Every coordinate from ImageSearch or PixelSearch is based on the DosBox basic resolution.
  • The final MouseMove coordinates have to be converted to the DosBox window resolution.

Solution

We have to find a way that the different resolutions can interact with each other.
  • We want to use the same coordinates resolution. The best is to use the DosBox basic resolution because ImagesSearch and PixelSearch are using it.
  • We need to divide the total mouse distance in smaller MouseMove steps to get this done.

Actions

1) Convert coodinates from basic to window resolution #appScreenScale

We can do this by using a scale factor as a global variable which is the ratio between DosBox window resolution and DosBox basic resolution. When DosBox is run in the default window (640x480) appScreenScale is 1. If DosBox is run in a bigger window or fullscreen the factor depends on the real resolution and what DosBox makes out of it. It's a bit tricky. In short: DosBox scales the original resolution up until it fits best in the window. The scale basis is the original resolution. Example: for a screen with 1920x1080 it makes a window resolution of 1280x960 (4 x original resolution). Because this is twice of the DosBox basic resolution (640x480) appScreenScale is 2 in this case. Maby you have to play with the value depending on your screen.

2) Divide MouseMove in multiple steps

Because MouseMove can not move more than the original resolution, we have to use a simple trick. For example out of a distance of 400px we make two MouseMove actions, one with 320px and one with 80px.


Global vars

The global vars should be set at top of the script. If you change between different window sizes or fullscreen you have to update appScreenScale with the correct value.


This solution will probably not work in every use case.
Please let me know, if it does not work for you.
Last edited by Lionautic on 19 Jul 2020, 05:57, edited 1 time in total.

garry
Posts: 3736
Joined: 22 Dec 2013, 12:50

Re: DosBox MouseMove helper for absolute coordinates

Post by garry » 17 Jul 2020, 05:22

@Lionautic thank you for the script
I didn't use games , here a script only gwbasic or dBase-III , a menu to select programs
in gwbasic had problem with keys ( input / push any key etc ) , worked so far

Code: Select all

/*
modified1  = 20160215
created1   = 20160215
description= Start DosBox and then GWBASIC or dBaseIII
#- NOTICE = DOSBOX.conf is now in folder M_DOSBOX\MY_DOSBOX
#- I use 4K monitor and WIN-10
#--------------------------
#settings changed to these :
#fullresolution  =1920x1080
#windowresolution=1920x1080
#output          =openglnb
*/

#warn
#NoEnv
SendMode Input
SetWorkingDir, %A_ScriptDir%
SetTitleMatchMode, 2
DetectHiddenWindows, On
SetKeyDelay,10,10
Gui,1:default
Gui,1: -DPIScale
SS_REALSIZECONTROL := 0x40
wa:=A_screenwidth,ha:=A_screenHeight,xx=100
;------------------
fddb=%a_scriptdir%\My_Dosbox
SetWorkingDir, %fddb%
p1  =%fddb%\dosbox.exe         ;- here is DOSBox.exe /SDL.dll / SDL_net.dll / dosbox.conf / DOSBox_help.txt
loop,%p1%
  SP1= %A_loopFileShortPath%
;-------------------
Gui,1: Color,Black , Black
Gui,1:Font,S12 cYellow,Lucida Console
;-------
x:=(wa*.1)/xx,y:=(ha*.1)/xx,w:=(wa*10)/xx,h:=(ha*45)/xx
Gui,1:Add, Listbox, cYellow  x%x% y%y% w%w% h%h% Sort vLB1 gLB
;-------
x:=(wa*12)/xx,y:=(ha*55)/xx,w:=(wa*8)/xx,h:=(ha*2.5)/xx
Gui,1:Add, Button  , x%x%  y%y%  w%w% h%h% gGwbasicx ,GWBASIC
;-------
x:=(wa*21)/xx,y:=(ha*55)/xx,w:=(wa*8)/xx,h:=(ha*2.5)/xx
Gui,1:Add, Button  , x%x%  y%y% w%w% h%h% gDBASEx   ,dBaseIII
;-------
x:=(wa*.1)/xx,y:=(ha*.1)/xx,w:=(wa*60)/xx,h:=(ha*60)/xx
Gui,1:Show, x%x%  y%y% w%w% h%h%,%a_scriptname%
OnExit, Exiting
gosub,gwbasicx
return
;-----------------------------------------------
act:
IfWinNotActive ,%SD%,,WinActivate,%SD%
  WinWaitActive,%SD%
return
;-------------------------------------
;-------------------------------------
gwbasicx:
Gui,1:submit,nohide
this=gwbasic
fd=%a_scriptdir%\My_DosBoxPrograms\gwbasic   ;- create first this directory and put here GWBASIC.exe
;ifnotexist,%fd%
;  filecreatedir,%fd%
p2=%fd%\gwbasic.exe                          ;- here is gwbasic.exe and *.bas files
f1=%fd%\Start1.bas                           ;- xy.bas
ifnotexist,%f1%
 fileappend,10 cls:key off:color 10`,0`r`n20 print "If fullscreen-mode then use ALT+ENTER":print "TIME= "; time$:print "DATE= ";date$:list`r`n,%f1%
ifnotexist,%p2%
  {
  msgbox, 262208,GWBASIC.exe NOT FOUND,GWBASIC.exe NOT EXISTS expected in this path=`n%fd%
  exitapp
  }
ext=bas
sd =GWBASIC
GuiControl,1:,LB1,|
;-------
gosub,rundosbox
gosub,act
;-------
xz=ahk_class SDL_app
var=TRI_AKGK
  SplitPath,f1,name, dir, ext, name_no_ext, drive
  sleep,2000
  sendinput,LOAD`"%name_no_ext%`"`r`n
  ;sendinput,LOAD `"%var%`"`r`n`r`n
  ;ControlSend,,{text}LOAD "tri_AKGK"`r`n,%xz% 
  sleep,2000
  sendinput,RUN`r`n
return
;----------------------------

;=========== dBASE =================================
dBasex:
Gui,1:submit,nohide
this=dbase
fd=%a_scriptdir%\My_DosBoxPrograms\dbase           ;- create first this directory and put here dbase.exe
p2=%fd%\dbase.exe                                  ;- here is dbase.exe and dbf / prg files
ifnotexist,%fd%
  filecreatedir,%fd%
ifnotexist,%p2%
  {
  msgbox, 262208,dBase.exe NOT FOUND,dBase.exe NOT EXISTS expected in this path=`n%fd%
  exitapp
  }
sd=DBASE
ext:="dbf,prg"
GuiControl,1:,LB1,|
GuiControl,1:,LB1,_QUIT
;ifexist,%fd%\all.prg
;  GuiControl,1:,LB1,_do all
GuiControl,1:,LB1,_assist
;-------
gosub,rundosbox
gosub,act
;-------
sleep,2000
sendinput,`r
sleep,700
sendinput,set color to G`r
sleep,700
sendinput,clear`r
sleep,700
;sendinput,assist`r
return
;----------------------------
;===================================
rundosbox:
Gui,1:submit,nohide
;fs= -fullscreen
fs=
x:=(wa*12)/100,Y:=(ha*.1)/100,W:=(wa*46)/100,H:=(ha*42)/100
run,%comspec% /c %sp1% "%p2%" %fs% -noconsole,,hide,pid
WinWait, ahk_pid %pid%
xz=ahk_class SDL_app
IfWinNotActive ,%xz%,,WinActivate,%xz%
  WinWaitActive,%xz%
sleep,1000
WinMove,%xz%, ,%x%,%y%,%w%,%h%    ;- DOSBOX wit GWBASIC move to x=0 y=0 / no success with w and h
;------------
SetWorkingDir,%fd%
Loop,%fd%\*.*
    {
   If A_LoopFileExt in %Ext%
       {
       FX=%A_LoopFileName%
       stringlen,L1,FX
       stringmid,FA,FX,1,L1-4
       if (A_LoopFileExt="prg")
           fa=do %fa%
       GuiControl,1:,LB1,%FA%                     ;- display the files in listbox
       }
    }
GuiControl,1:ChooseString, LB1, %FA%          ;- last
settimer,aas1,2000
return
;-------------------------------------------------
;-------------------------------------------------
lb:
Gui,1:submit,nohide
GuiControlGet,LB1
IfWinNotActive ,%SD%,,WinActivate,%SD%
  WinWaitActive,%SD%
;-------
if (this="gwbasic")
  {
  sleep,1000
  sendinput,LOAD`"%lb1%`"`r`n
  sleep,700
  sendinput,RUN`r`n
  return
  }
;-------
if (this="dbase")
  {
  sendinput,{ESC}
  sleep,1000
  if (lb1="_QUIT")
     {
     sendinput,quit`r
     return
     }
  if (lb1="_assist")
     {
     sendinput,assist`r
     return
     }
  stringmid,xb1,lb1,1,3
  if (xb1="do ")
     {
     sendinput,%lb1%`r
     return
     }
  else
    {
    sendinput,use %lb1%`r
    sleep,1500
    sendinput,browse width 15`r
    return
    }
  return
  }
return
;-------------------------------

;===============================
aas1:
Process, Exist,dosbox.exe
if (ErrorLevel = 0)
   {
   GuiControl,1:,LB1,|
   settimer,aas1,off
   }
return
;----------------------------
Guiclose:
Exiting:
esc::
Process, Exist,DosBox.exe
if (ErrorLevel <> 0)
   Process, Close,DosBox.exe
exitapp
;========== END SCRIPT DOSBOX ======================
Image

Lionautic
Posts: 2
Joined: 15 Jul 2020, 00:09

Re: DosBox MouseMove helper for absolute coordinates

Post by Lionautic » 19 Jul 2020, 05:55

@garry Thanks for the feedback. The script should also work for non-game apps. I added it in my post.

Post Reply

Return to “Tips and Tricks (v1)”