I am currently working on a project in Computer Graphics in C language. Our professor wants us to make a project which consists of animation, but which gets triggered on clicking by mouse and not keyboard. I searched on the internet for solutions, but nothing has worked for me. The project is to be done in Turbo-C.
-
If your application is Windows-based, you can just monitor mouse messages. – Paul Ogilvie Mar 19 '19 at 11:26
-
Thank you for the reply. Can you please elaborate on the solution? – Sheldor2304 Mar 19 '19 at 11:41
-
4Turbo C is a MS DOS compiler. There is no built-in support for mouse drivers, so you have to code that part manually, which is a very painful thing to do. This would be far easier to do with a compiler younger than 30 years. Why are you training to write drivers for DOS? Your teacher believes it is the next big thing? It would be wiser to use a beginner-friendly tool chain. – Lundin Mar 19 '19 at 11:45
-
Btw you aren't likely to find solutions to this on the internet, because internet was not invented when Turbo C was released. – Lundin Mar 19 '19 at 11:47
-
Thank you for the reply. Actually, we have computer graphics as a subject in our curriculum in C language. And we are still being taught to code in Turbo C. So, I've got no other alternative than to do the above said. Well, can you please suggest on how to code manually for mouse drivers? – Sheldor2304 Mar 19 '19 at 11:50
-
MS DOS interrupt `0x33` has a set of mouse functions. You can look for material by Ralf Brown for further information, such as [this](http://www.ctyme.com/rbrown.htm). There may be third-party libraries out there for you to search out to save reinvention. – Weather Vane Mar 19 '19 at 11:53
-
Thank you, that was very helpful. @WeatherVane But, I'm unable to implement the interrupts in my code. Plus, I tried searching on the net, but didn't find much. Can you please give me an example of how to code with these interrupts? – Sheldor2304 Mar 19 '19 at 12:00
-
From memory I seem to recall `intdos()` function and you should be able to find material on that, such as [here](http://www.ousob.com/ng/borcpp/ng37854.php) but you must do your own research from the pointers given. – Weather Vane Mar 19 '19 at 12:06
-
What is the point of your professor if he has not made this clear!? There is some example mouse code for Turbo-C [here](https://www.programmingsimplified.com/c-program-restrict-mouse-pointer-in-circle), but it uses x86 16-bit real-mode software interrupt calls - it seems unlikely that this is what your professor intended, and if it is what is the point in learning a virtually obsolete technology. – Clifford Mar 19 '19 at 12:14
-
Actually `intdos` only calls interrupt `0x21` so function `int86()` would be better. – Weather Vane Mar 19 '19 at 12:14
-
@WeatherVane I tried to use int86 after seeing some videos on YouTube. But it's not working .. – Sheldor2304 Mar 19 '19 at 12:33
-
@Lundin I agree with the point you made, but I'm still a student so I've to follow my professor's instructions even if it is outdated. And also because this project would add up to my CGPA. – Sheldor2304 Mar 19 '19 at 12:36
-
@WeatherVane Yeah, that is more or less the scenario in our college. But learning with this makes us more adaptable to easier and advanced technologies. I think that is the aim of our curriculum to make us code in outdated compilers like Turbo C. Just my view, again, I'm still a student so please forgive if I've misquoted. :) – Sheldor2304 Mar 19 '19 at 12:39
-
@Sheldor2304 I haven't programmed mouse drivers for DOS since the late 90s, I don't remember much of it, sorry. TC was still in use until year 2000 roughly. – Lundin Mar 19 '19 at 12:48
-
see [Mouse program in Turbo CPP](https://stackoverflow.com/a/45561564/2521214) – Spektre Mar 20 '19 at 09:06
-
@Spektre It really helped! Thank you so much! :) – Sheldor2304 Mar 20 '19 at 13:34
1 Answers
You will need a DOS mouse driver installed. If using DOSBox one is already available. You need to make Interrupt calls to the mouse services1 routines via (Int 0x33). One of the best sources for DOS interrupt related information is Ralph Brown's Interrupt List. Turbo-C has support for calling BIOS services via the int86
function (include DOS.H).
Int 0x33 provides the mouse services, but for the purpose of getting you started the mouse functions that are immediately useful are:
- Show mouse cursor with Int 0x33/AX=1
- Hide mouse cursor with Int 0x33/AX=2
- Set initial mouse cursor position with Int 0x33/AX=4
- Get current mouse state including button information with Int 0x33/AX=3
Using the mouse interrupt information on RBIL to specify the input and output parameters you could create some basic mouse wrappers for your Turbo-C code. Basic wrappers would look like:
#include<stdio.h>
#include<conio.h>
#include<dos.h>
#define MOUSE_INT 0x33
#define MOUSE_FUNC_SHOW 1
#define MOUSE_FUNC_HIDE 2
#define MOUSE_FUNC_GETSTATE 3
#define MOUSE_FUNC_SETPOS 4
#define MOUSE_LEFT_BUTTON 0x01
#define MOUSE_RIGHT_BUTTON 0x02
typedef struct {
unsigned int cur_x;
unsigned int cur_y;
unsigned int buttons;
} mouse_state_t;
void mouse_hide()
{
union REGS regs_in, regs_out;
regs_in.x.ax = MOUSE_FUNC_HIDE;
int86(MOUSE_INT, ®s_in, ®s_out);
}
void mouse_show()
{
union REGS regs_in, regs_out;
regs_in.x.ax = MOUSE_FUNC_SHOW;
int86(MOUSE_INT, ®s_in, ®s_out);
}
void mouse_get_state(mouse_state_t *mouse_state)
{
union REGS regs_in, regs_out;
regs_in.x.ax = MOUSE_FUNC_GETSTATE;
int86(MOUSE_INT, ®s_in, ®s_out);
mouse_state->cur_x = regs_out.x.cx;
mouse_state->cur_y = regs_out.x.dx;
mouse_state->buttons = regs_out.x.bx;
/* buttons field is a bit mask. Bit 0 (lowest bit) is set when left
mouse button is pressed. Bit 1 is set when right mouse button is pressed */
}
void mouse_set_pos(int pos_x, int pos_y)
{
union REGS regs_in, regs_out;
regs_in.x.ax = MOUSE_FUNC_SETPOS;
regs_in.x.cx = pos_x;
regs_in.x.dx = pos_y;
int86(MOUSE_INT, ®s_in, ®s_out);
}
int main()
{
mouse_state_t mouse_state;
/* Show mouse and set initial position to middle of text screen */
clrscr();
mouse_show();
mouse_set_pos(80*8/2, 25*8/2);
/* Repeat until any key is pressed */
do
{
/* Get current mouse state and display it */
mouse_get_state(&mouse_state);
gotoxy(1, 1);
printf("Mouse X: %3d\n", mouse_state.cur_x);
printf("Mouse Y: %3d\n", mouse_state.cur_y);
printf("Buttons: %3d\n", mouse_state.buttons);
/* Display the button state as LEFT/RIGHT when pressed */
if (mouse_state.buttons & MOUSE_LEFT_BUTTON)
printf("LEFT ");
else
printf(" ");
if (mouse_state.buttons & MOUSE_RIGHT_BUTTON)
printf("RIGHT");
else
printf(" ");
} while (!kbhit());
mouse_hide();
return 0;
}
This code provides a mouse_show
, mouse_hide
, mouse_get_state
, and mouse_set_pos
functions to provide a basic mouse polling interface using Turbo-C's int86
function. The test code repeatedly updates the current mouse state in the upper left hand corner of the screen until a key is pressed. This is as it appears in DOSBox:
As you are doing a homework assignment I won't provide you code that checks the button state and draws images, but this is enough to allow you to determine the current mouse state and trigger the animation yourself.
The mouse interface should work in most of the standard graphics mode.
Footnotes
- 1Generally PC BIOSes do not support `Int 0x33` directly. A DOS mouse driver implements this interface to augment the standard BIOS services.
- 46,082
- 8
- 107
- 198