Thread: Mouse in 800x600 24Bit Mode?

  1. #1
    Unregistered
    Guest

    Question Mouse in 800x600 24Bit Mode?

    Hi

    can anybody out there tell me how to draw a mouse cursor for 800x600 24bit color graphics mode?

    thx

  2. #2
    Linguistic Engineer... doubleanti's Avatar
    Join Date
    Aug 2001
    Location
    CA
    Posts
    2,459
    just draw it over... use a double buffering system... try to explain it more...
    hasafraggin shizigishin oppashigger...

  3. #3
    Disagreeably Disagreeable
    Join Date
    Aug 2001
    Posts
    711
    In VGA graphics when using a mouse, the cursor is automatically redrawn and everything, but in SVGA graphics it's not.

    So, you have to continually check to see if the mouse has moved. If it has, redraw it.

    The easiest way to do this would be to make an interrupt handler fire off when the mouse is moved.

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Well, I don't know if the easiest way is to install an interrupt handler for 33h. The 33h ISR will tell you where the mouse cursor is even on higher res modes, but it will not display the cursor. Instead of hooking the interrupt and re-inventing the wheel (the driver already does most of what you need) the easiest way is poll the mouse driver functions that return the mouse cursor position. Place your bitmap in your double buffer or directly to the screen, whichever is applicable in your program, and you will have a mouse cursor in 800x600 modes.

    In this method you will have to poll the driver within your main loop to continually check for mouse activity. However, this method is somewhat easier to implement than hooking the 33h interrupt.

  5. #5
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    One more thing. When the mouse driver returns the x,y of the cursor in cx and dx registers remember that the driver is not taking into account the bit depth of your current video mode. So, to place the cursor at the correct location, you will have to take the bit depth of your current mode into account.

  6. #6
    Unregistered
    Guest

    next trial

    hi

    OK i'll explain my problem better:
    i have the code for getting the mouse cursor x,y. Now in this mode i can't see the cursor. So i have to paint one for this mode. Now i'm asking you if i have to redraw the screen everywhere the mousecursor is moving above or if it exist an easier function which automatical redraws the screen.

    i'm currently use this code, wich has a (bios?) cursor. (if somebody has an idea to make it better...)
    Please tell me if i have to draw the cursor in any special register or sth. else.

    // Begin code
    union REGS rin,rout;
    int InitMouse(void)
    {
    rin.x.ax=0;
    int86(0x33,&rin,&rout);
    return (rout.x.ax);
    }
    void mouseoff(void)
    {
    rin.x.ax=2;
    int86(0x33,&rin,&rout);
    }
    void mouseon(void)
    {
    rin.x.ax=1;
    int86(0x33,&rin,&rout);
    }
    int eixx(void)
    {
    rin.x.ax=3;
    int86(0x33,&rin,&rout);
    return(rout.x.cx);
    }
    int eixy(void)
    {
    rin.x.ax=3;
    int86(0x33,&rin,&rout);
    return(rout.x.dx);
    }
    int button(void)
    {
    rin.x.ax=3;
    int86(0x33,&rin,&rout);
    return(rout.x.bx);
    }
    void SetMousePos(int x, int y)
    {
    rin.x.ax=4;
    rin.x.cx=x;
    rin.x.dx=y;
    int86(0x33,&rin,&rout);
    }
    // end of code
    bye

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    There are a couple of ways to accomplish what you want. First off, no there is not a function that will draw a mouse cursor on the screen in 800x600x16M or 24 bit mode. The hardware cursor, or the cursor that the mouse driver uses, is not designed for hi-color modes. This cannot be done just using an interrupt with the correct register values.

    As I said before, you retrieve the coordinates of the mouse cursor, which you already know how to do. Then:

    If you are double buffering, that is, drawing the screen to a buffer first and then copying the buffer to vid-ram (can only be done effectively in protected mode for 800x600 24 bit using the LFB) then you will draw your mouse cursor at x,y in the buffer - remember to take into account the bit depth for your mode.

    If you are not double buffering, that is, you are drawing the mouse cursor directly to the screen, you could use masks. The first mask will represent the area that the cursor does not occupy. This is called the screen mask. The second mask will only cover the areas that the cursor will occupy. This is called the cursor mask. It is similar to what you have to do when you call subfunction 9 on int 33h to change the mouse cursor. You must supply a cursor mask and a screen mask.

    I believe the order of operations is to AND the screen mask with existing screen information. Then XOR the cursor mask with the result of the above operation. To restore the background, you must recopy the rectangular area that the entire graphic used.

    If you do not want to mess with masks and you already have a sprite 'put' function that allows for transparent pixels then just use that function to place the mouse cursor. This might be easier since you could set up your mouse cursor exactly like all of your other bitmaps. Just use your transparent color on the areas that the cursor does not occupy. But, if you are not double-buffering there is a chance you will get flicker when you redraw the background image over the mouse cursor, effectively erasing the mouse cursor in preparation for a cursor move.

    To minimize flicker in a non-double buffer environment, only erase the mouse cursor when it is being moved, or when some screen operation needs to be done that will affect the mouse, such as re-drawing a button under the mouse.

    Code:
    struct tagMouse
    {
      int x;
      int y;
      int lastx;
      int lasty;
      int btndwn;
    }Mouse;
    
    void ResetMouse
    {
       union REGS regs;
       regs.x.ax=0x00;
       int86(0x33,& regs, & regs);
       if (regs.x.ax!=0xFFFF)
      {
         printf("Mouse driver not found.\n");
         exit(0);  //no error code - but will still exit
       }
      
       Mouse.x=regs.x.cx;
       Mouse.y=regs.x.dx;
       Mouse.lastx=Mouse.x;
       Mouse.lasty=Mouse.y;
       Mouse.btndwn=0;   //could be used to return num buttons on    
                                       //mouse - regs.x.bx
    
    }
    
    //Inline because will be called often - eliminate function call   
    //overhead
    inline void GetMousePosition(void)
    {
       union REGS regs;
       regs.x.ax=0x03;
       int86(0x33,& regs,& regs);
       Mouse.x=regs.x.cx;
       Mouse.y=regs.x.dx;
       Mouse.btndwn=regs.x.bx;
    }
    
    //Checks for mouse activity
    void CheckMouse(void)
    {
      GetMousePosition();
      if (Mouse.x!=Mouse.lastx || Mouse.y!=Mouse.lasty)
      {
        //Mouse has been moved on x or y coord
       //Redraw screen area with prior image to erase mouse
       //Draw mouse cursor at Mouse.x,Mouse.y to move cursor
       //These will be calls to your functions that draw the cursor, etc
       ....
       ....
    
       //Now set lastx and lasty to reflect new change
       Mouse.lastx=Mouse.x;
       Mouse.lasty=Mouse.y;
      }
      //Now you could check for button presses
      
      if (Mouse.btndwn==0x01)
      {
         //Button 1 pressed
         //Do something here......
         //Check to see if we overlap a button
         //If so, before we redraw the button as pushed -
         //we must erase the mouse cursor prior to redrawing
         //and replace the cursor after we are done
    
         //Clear btndwn - event has been processed and dealt with
         Mouse.btndwn=0;   
       }
    }

    Now the mouse cursor will only be erased with the screen image when the mouse has been moved or some other mouse event has happened. The flicker will very limited. This is not very elegant, but I usually make the mouse a global object unless I'm programming some type of advanced windowing system with a definite hierarchy. This could easily be implemented using classes, etc., and would eliminate the global mouse object (if that bothers you). All of this would become part of your graphics system. For multiple mode support, you would just override the pixel plotting function to deal with different modes, bit depths, color depths, etc. This way your mouse cursor could be displayed in other modes other than 800x600x24 bit since it uses the 'put' sprite function which in turn would use the appropriate plot pixel function.

    Hope this helps.

  8. #8
    Unregistered
    Guest

    Angry BIG PROBLEM

    Hi

    thanks this helps a little bit, but now I've got the problem that the cursor only appears between pixel 0,0 and about 700,200 and moves only every 5 pixels (OK the 5 pixel problem might be uninteresting but the other one...)

    if you've got an idea...

    bye

  9. #9
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Let's see...


    Since your offset is clearly beyond one bank at 700,200 I'll assume you are bank switching correctly. Make sure that the granularity of your video card for 800x600x16M is indeed 64k. If it is not, then your offset will be off and you will not be selecting the correct bank.

    There is also a case in 24-bit mode where you will have to bank switch amidst writing a pixel to the screen. In other words, part of the color information for one pixel belongs in another bank.
    If you are using the LFB, then this would not apply to you.

    I'll attach one of the Peroxide tutorials on VBE 2.0+ which will explain everything. You can get more tutorials at www.peroxide.dk. They are amidst making a game so not many new tutorials are there.

  10. #10
    Linguistic Engineer... doubleanti's Avatar
    Join Date
    Aug 2001
    Location
    CA
    Posts
    2,459
    oh, hmmm... when using VESA modes the mouse interrupts only generate increments of 8 in it's position variables. so, i'd suggest you set the limits to 8 times the size of your screen resolution, and translate... that could attribute to your pecularities...
    hasafraggin shizigishin oppashigger...

  11. #11
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I've not ran into that problem. Usually in hi-res modes I'm just doing mouse look functions and not cursor related stuff. If the driver limits the cursor to a certain area, then multiplying or whatever will move your cursor. But, if the driver doesn't know the new position, or accept the new position, then the cursor still won't work right.

    There is a function that allows you to set a bounding box for the mouse. It might be possible to set this box to the entire screen for your resolution. This way the driver would allow you to move beyond what it thinks is the edge of the screen.

    Well, I've looked at my docs and there seems to be two functions that might help you with this problem, if it is in fact due to the driver limiting the cursor range.

    Subfunction 07h - Set Horizontal Cursor Range

    IN: AX=0007h; CX=min col (pixels); DX=max col (pixels)

    OUT: none


    Subfunction 08h - Set Vertical Cursor Range

    IN: AX=0008h; CX=min row (pixels); DX=max row (pixels)

    OUT none

    If you are using subfunction 04h, try to set the cursor range beyond what it is currently allowing. If this works, then you know that the driver will allow you to set the range to a value beyond what it currently allows and the above functions would work.

    Remember your bit depth. The driver will not take this into account, so you will need to do some multiplies (hopefully left shifting) to get the cursor at the right point on the screen.

    Set your max row and min row according to your resolution w/o the bit depth. Your multiplies should correspond that when the driver reaches 800 on the horizontal - your cursor is at the far right edge of the screen.

  12. #12
    Linguistic Engineer... doubleanti's Avatar
    Join Date
    Aug 2001
    Location
    CA
    Posts
    2,459
    oh, speaking of interrupts... [and here's where i got my information too...] a great resource on interrupts is Ralph Brown's Interrupt List... i don't know where they currently serve it, but if anyone reads this, it's a good resource for DOS programmers...
    hasafraggin shizigishin oppashigger...

  13. #13
    Unregistered
    Guest
    Actually, I got my info from an earlier doc I had downloaded while at college. The doc no longer exists, or all links to it are broken, but you can get the same info from the interrupt list.

    Do not know where it is right now. Look up Ralph Brown's Interrupt List on www.excite.com or www.google.com. It should be near the top of the list as this thing is all over the Internet.

  14. #14
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    That was posted by Bubba. Apparently my browser did not auto log me in this time. Wonder why?

  15. #15
    Linguistic Engineer... doubleanti's Avatar
    Join Date
    Aug 2001
    Location
    CA
    Posts
    2,459
    hmmm... that has been a problem occasionally... it's never happened to me though, [i'm using IE5.5 btw]... that, and i'd know if i wasn't logged in since i'm a moderator... it'd be more obvious... do you go directly from your email notifications to the board? maybe that could have been the problem...

    oh, and i find it interesting where you got your information, i don't know what i'd do without my sweet sweet interrupt list... finding it otherwise was very difficult...
    hasafraggin shizigishin oppashigger...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Handling mouse in graphics mode in Turbo C/DOS
    By sureshkumarct in forum C Programming
    Replies: 2
    Last Post: 12-24-2006, 09:36 AM
  2. Problem in mouse position
    By Arangol in forum Game Programming
    Replies: 6
    Last Post: 08-08-2006, 07:07 AM
  3. How to change a mouse cursor in console mode
    By GaPe in forum Windows Programming
    Replies: 10
    Last Post: 07-03-2002, 07:42 AM
  4. Mouse support in console mode
    By GaPe in forum C Programming
    Replies: 1
    Last Post: 04-17-2002, 05:15 AM
  5. How I can Show the pointer of mouse int 800*600 256 color mode in Turbo C++?
    By hadizadeh in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 12-12-2001, 07:17 AM