Friday, August 12, 2011

Gabriel Knight on WeTab Dosbox finally useable

So I finally got that Gabriel Knight game to be useable on the Wetab with Dosbox. I must say that it took a good day of debugging through the doxbox mouse.cpp file but eventually I got myself an ok solution though I have no idea how extensible it is.

This post by Yushatak really helped get my exploratory juices running again:

http://vogons.zetafleet.com/viewtopic.php?t=27360&postdays=0&postorder=asc&start=0

So according to this post all I needed was to set emulate=0 inside the mouse.cpp file for dosbox, recompile and everything would work atleast in fullscreen.

Well further down the post Yushatak does make note of this not being universally effective. It appears that games under DOS did all sorts of weird stuff with the mouse coordinates.

First off I had to set autolock to false inside my dosbox.conf file. That atleast got the touchscreen to interact with the game. But what would happen was that the first screen with the Intro and the game selection menu my mouse worked perfectly however, on the first scene in the game where you start in St. George's bookshop the mouse would do some very funky stuff where if you clicked anywhere near the top of the screen the clicks were fine. While when you moved down to the bottom, the cursor moved slower than your finger as you moved down the screen.

I eventually ended up adding a few tens of printf statements to view the values of the mouse coordinates throughout the CursorMoved function and found that at some point after the Sierra intro screen and the actual game, the game would somehow reset the mouse.max_y value to 155 instead of 199 as it was on the first screen where everything worked normally. Now I followed this through and there is some sort of fraction that identifies where the mouse really is and that is multiplied by the max_y value to identify where the cursor will end up on the screen. So that explains why the cursor was moving with a varying rate as you moved down the screen...the percentage offset was changing on 0-155 pixel range while your finger was working through a 0-199 finger range. This probably sounds like gibberish but it's as close an analysis as I can come up with at the moment.

Anyhow by hardcoding mouse.max_y=199 into my mouse.cpp, I've gotten the game to behave correctly in gameplay. Now this only works in Windowed mode. In fullscreen my mouse cursor just goes and sits in the right lower corner of the screen and won't budge. For now I will be satisfied with the windowed mode though fullscreen would have really been my preference.

Below is the debug stuff along with the patch I added to mouse.cpp to get this to work. This file is under the src/ints folder in the dosbox source package.


void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate) {
printf("=====ENTER CUSRORMOVED====\n");
    printf("xrel is %f\n", xrel);
    printf("yrel is %f\n", yrel);
    printf("mouse.pixelPerMickey_x is %f\n", mouse.pixelPerMickey_x);
    printf("mouse.pixelPerMickey_y is %f\n", mouse.pixelPerMickey_y);
    printf("mouse.mickey x is %f \n",mouse.mickey_x);
    printf("mouse.mickey y is %f \n",mouse.mickey_y);
    
    
    printf("mouse.senv x is %f \n",mouse.senv_x);
    printf("mouse.senv y is %f \n",mouse.senv_y);
    printf("mouse. x is %f \n",mouse.x);
    printf("mouse. y is %f \n",mouse.y);
    printf("x is %f \n",x);
    printf("y is %f \n",y);

    printf("INITIALIZATION COMPLETE\n");
    float dx = xrel * mouse.pixelPerMickey_x;
    float dy = yrel * mouse.pixelPerMickey_y;
    
    printf("$> dx = xrel * mouse.pixelPerMickey_x = > %f = %f * %f\n",dx,xrel,mouse.pixelPerMickey_x);

    printf("$> dy = yrel * mouse.pixelPerMickey_y = > %f = %f * %f\n",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;    
    

    printf("mouse.mickey_x +=dx\n");    
    printf("mouse.mickey_y +=dy\n");

    mouse.mickey_x += dx;
    mouse.mickey_y += dy;

    printf("mouse.mickey x is %f \n",mouse.mickey_x);
    printf("mouse.mickey y is %f \n",mouse.mickey_y);
    printf("dx is %f \n",dx);
    printf("dy is %f \n",dy);
    printf("mouse. x is %f \n",mouse.x);
    printf("mouse. y is %f \n",mouse.y);
    printf("x is %f \n",x);
    printf("y is %f \n",y);
    
emulate=0;
    if (emulate) {
        printf("  ==Inside emulate\n");        
            
        printf("  mouse.x +=dx\n");        
        printf("  mouse.x +=dy\n");        
        mouse.x += dx;
        mouse.y += dy;
        printf("    currently x is %f \n",mouse.x);
        printf("    currently y is %f \n",mouse.y);
    } else {
        if (CurMode->type == M_TEXT) {
            printf("    ==Inside Curmode test\n");
            mouse.x = x*CurMode->swidth;
            mouse.y = y*CurMode->sheight * 8 / CurMode->cheight;
            
            printf("      currently CurMode->swidth is %f \n",CurMode->swidth);
            printf("      currently CurMode->sheight is %f \n",CurMode->sheight);
            printf("      currently CurMode->cheight is %f \n",CurMode->cheight);
            printf("      currently mouse.x is %f \n",mouse.x);
            printf("      currently mouse.y is %f \n",mouse.y);
            
                
        } else if ((mouse.max_x < 2048) || (mouse.max_y < 2048) || (mouse.max_x != mouse.max_y)) {
            printf("    ==Curmode else ((mouse.max_x < 2048) || (mouse.max_y < 2048) || (mouse.max_x != mouse.max_y))\n");
            if ((mouse.max_x > 0) && (mouse.max_y > 0)) {
                printf("    ==if(mouse.max_x > 0) && (mouse.max_y > 0)\n");

                mouse.max_y = 199;
                printf("      just set mouse.max_y is %i \n",mouse.max_y);

                printf("      currently mouse.max_x is %i \n",mouse.max_x);
                printf("      currently mouse.max_y is %i \n",mouse.max_y);        
                printf("      currently mouse.x is %f \n",mouse.x);
                printf("      currently mouse.y is %f \n",mouse.y);                
                printf("      currently x is %f \n",x);
                printf("      currently y is %f \n",y);                


                printf("  $>  mouse.x = x*mouse.max_x %f\n",x*mouse.max_x);
                printf("  $>  mouse.y = y*mouse.max_y %f\n",y*mouse.max_y);        
                mouse.x = x*mouse.max_x;
                mouse.y = y*mouse.max_y;

            } else {
                printf("    ==else(mouse.max_x > 0) && (mouse.max_y > 0)\n");
                printf("      $>  mouse.x += xrel\n");
                printf("      $>  mouse.y += yrel\n");    
                printf("      currently mouse.x is %f \n",mouse.x);
                printf("      currently mouse.y is %f \n",mouse.y);


                mouse.x += xrel;
                mouse.y += yrel;
                

                printf("      currently mouse.x is %f \n",mouse.x);
                printf("      currently mouse.y is %f \n",mouse.y);
            }
        } else { // Games faking relative movement through absolute coordinates. Quite surprising that this actually works..
            printf("    ==Curmode else faking relative motion\n");            
            
            mouse.x += xrel;
            mouse.y += yrel;
            
            printf("      $>  mouse.x += xrel\n");
            printf("      $>  mouse.y += yrel\n");    
            
            printf("      currently mouse.x is %f \n",mouse.x);
            printf("      currently mouse.y is %f \n",mouse.y);
        }
    }

    /* ignore constraints if using PS2 mouse callback in the bios */

    if (!useps2callback) {        
        printf("==useps2callback\n");
        if (mouse.x > mouse.max_x) mouse.x = mouse.max_x;
        if (mouse.x < mouse.min_x) mouse.x = mouse.min_x;
        if (mouse.y > mouse.max_y) mouse.y = mouse.max_y;
        if (mouse.y < mouse.min_y) mouse.y = mouse.min_y;
        printf("      currently mouse.x is %f \n",mouse.x);
        printf("      currently mouse.y is %f \n",mouse.y);    
    }

//mouse.y = mouse.y+50;
printf("===END CURMOVED===\n");
    
    Mouse_AddEvent(MOUSE_HAS_MOVED);
    DrawCursor();
}




No comments:

Post a Comment