1
0
Fork 0

+ draw mouse pointer

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@454
This commit is contained in:
Ulf Wohlers 2002-10-28 14:30:11 +00:00
parent dfb87ec9e3
commit 69ad2dee2d
3 changed files with 193 additions and 2 deletions

View file

@ -200,6 +200,8 @@ void INT10_GetSingleDacRegister(Bit8u index,Bit8u * red,Bit8u * green,Bit8u * bl
void INT10_SetDACBlock(Bit16u index,Bit16u count,PhysPt data);
void INT10_GetDACBlock(Bit16u index,Bit16u count,PhysPt data);
/* Mouse pointer */
void INT10_SetGfxControllerToDefault(void);
/* Sup Groups */
void INT10_SetupRomMemory(void);

View file

@ -411,3 +411,15 @@ void INT10_SetVideoMode(Bit8u mode) {
/* Set some interrupt vectors */
RealSetVec(0x43,int10_romarea.font_8_first);
};
void INT10_SetGfxControllerToDefault()
// reset gfx controller to default values
// needed for drawing mouse pointer
{
Bit8u line=FindVideoMode(real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)&127);
// Set Grafx Ctl
for(Bit8u i=0;i<=GRDC_MAX_REG;i++) {
IO_Write(VGAREG_GRDC_ADDRESS,(Bit8u)i);
IO_Write(VGAREG_GRDC_DATA,grdc_regs[vga_modes[line].grdcmodel][i]);
}
};

View file

@ -40,6 +40,27 @@ struct button_event {
#define POS_X (Bit16s)(mouse.x)
#define POS_Y (Bit16s)(mouse.y)
#define CURSORX 16
#define CURSORY 16
#define HIGHESTBIT (1<<(CURSORX-1))
static Bit16u defaultScreenMask[CURSORY] = {
0x3FFF, 0x1FFF, 0x0FFF, 0x07FF,
0x03FF, 0x01FF, 0x00FF, 0x007F,
0x003F, 0x001F, 0x01FF, 0x00FF,
0x30FF, 0xF87F, 0xF87F, 0xFCFF
};
static Bit16u defaultCursorMask[CURSORY] = {
0x0000, 0x4000, 0x6000, 0x7000,
0x7800, 0x7C00, 0x7E00, 0x7F00,
0x7F80, 0x7C00, 0x6C00, 0x4600,
0x0600, 0x0300, 0x0300, 0x0000
};
static Bit16u userdefScreenMask[CURSORY];
static Bit16u userdefCursorMask[CURSORY];
static struct {
Bit16u buttons;
Bit16u times_pressed[MOUSE_BUTTONS];
@ -57,6 +78,14 @@ static struct {
Bit32u events;
Bit16u sub_seg,sub_ofs;
Bit16u sub_mask;
bool background;
Bit16s backposx, backposy;
Bit8u backData[CURSORX*CURSORY];
Bit16u* screenMask;
Bit16u* cursorMask;
Bit16s clipx,clipy;
Bit16s hotx,hoty;
} mouse;
#define X_MICKEY 8
@ -79,8 +108,138 @@ INLINE void Mouse_AddEvent(Bit16u type) {
PIC_ActivateIRQ(12);
}
static void DrawCursor() {
static gfxReg[9];
void SaveVgaRegisters()
{
for (int i=0; i<9; i++) {
IO_Write (0x3CE,i);
gfxReg[i] = IO_Read(0x3CF);
};
// Set default
INT10_SetGfxControllerToDefault();
};
void RestoreVgaRegisters()
{
for (int i=0; i<9; i++) {
IO_Write(0x3CE,i);
IO_Write(0x3CF,gfxReg[i]);
};
};
void ClipCursorArea(Bit16s& x1, Bit16s& x2, Bit16s& y1, Bit16s& y2, Bit16u& addx1, Bit16u& addx2, Bit16u& addy)
{
addx1 = addx2 = addy = 0;
// Clip up
if (y1<0) {
addy += (-y1);
y1 = 0;
}
// Clip down
if (y2>mouse.clipy) {
y2 = mouse.clipy;
};
// Clip left
if (x1<0) {
addx1 += (-x1);
x1 = 0;
};
// Clip right
if (x2>mouse.clipx) {
addx2 = x2 - mouse.clipx;
x2 = mouse.clipx;
};
};
void RestoreCursorBackground()
{
if (mouse.shown<0) return;
SaveVgaRegisters();
if (mouse.background) {
// Restore background
Bit16s x,y;
Bit16u addx1,addx2,addy;
Bit16u dataPos = 0;
Bit16s x1 = mouse.backposx;
Bit16s y1 = mouse.backposy;
Bit16s x2 = x1 + CURSORX - 1;
Bit16s y2 = y1 + CURSORY - 1;
ClipCursorArea(x1, x2, y1, y2, addx1, addx2, addy);
dataPos = addy * CURSORX;
for (y=y1; y<=y2; y++) {
dataPos += addx1;
for (x=x1; x<=x2; x++) {
INT10_PutPixel(x,y,0,mouse.backData[dataPos++]);
};
dataPos += addx2;
};
mouse.background = false;
};
RestoreVgaRegisters();
};
void DrawCursor() {
if (mouse.shown<0) return;
// Get Clipping ranges
VGAMODES * curmode=GetCurrentMode();
if (!curmode) return;
mouse.clipx = curmode->swidth-1;
mouse.clipy = curmode->sheight-1;
RestoreCursorBackground();
SaveVgaRegisters();
// Save Background
Bit16s x,y;
Bit16u addx1,addx2,addy;
Bit16u dataPos = 0;
Bit16s x1 = POS_X - mouse.hotx;
Bit16s y1 = POS_Y - mouse.hoty;
Bit16s x2 = x1 + CURSORX - 1;
Bit16s y2 = y1 + CURSORY - 1;
ClipCursorArea(x1,x2,y1,y2, addx1, addx2, addy);
dataPos = addy * CURSORX;
for (y=y1; y<=y2; y++) {
dataPos += addx1;
for (x=x1; x<=x2; x++) {
INT10_GetPixel(x,y,0,&mouse.backData[dataPos++]);
};
dataPos += addx2;
};
mouse.background= true;
mouse.backposx = POS_X - mouse.hotx;
mouse.backposy = POS_Y - mouse.hoty;
// Draw Mousecursor
dataPos = addy * CURSORX;
for (y=y1; y<=y2; y++) {
Bit16u scMask = mouse.screenMask[addy+y-y1];
Bit16u cuMask = mouse.cursorMask[addy+y-y1];
if (addx1>0) { scMask<<=addx1; cuMask<<=addx1; dataPos += addx1; };
for (x=x1; x<=x2; x++) {
Bit8u pixel = 0;
// ScreenMask
if (scMask & HIGHESTBIT) pixel = mouse.backData[dataPos];
scMask<<=1;
// CursorMask
if (cuMask & HIGHESTBIT) pixel = pixel ^ 0x0F;
cuMask<<=1;
// Set Pixel
INT10_PutPixel(x,y,0,pixel);
dataPos++;
};
dataPos += addx2;
};
RestoreVgaRegisters();
}
void Mouse_CursorMoved(float x,float y) {
@ -158,6 +317,12 @@ static void mouse_reset(void) {
mouse.sub_mask=0;
mouse.sub_seg=0;
mouse.sub_ofs=0;
mouse.hotx = 0;
mouse.hoty = 0;
mouse.background = false;
mouse.screenMask = defaultScreenMask;
mouse.cursorMask = defaultCursorMask;
}
@ -172,8 +337,10 @@ static Bitu INT33_Handler(void) {
case 0x01: /* Show Mouse */
mouse.shown++;
if (mouse.shown>0) mouse.shown=0;
DrawCursor();
break;
case 0x02: /* Hide Mouse */
RestoreCursorBackground();
mouse.shown--;
break;
case 0x03: /* Return position and Button Status */
@ -184,6 +351,7 @@ static Bitu INT33_Handler(void) {
case 0x04: /* Position Mouse */
mouse.x=(float)reg_cx;
mouse.y=(float)reg_dx;
DrawCursor();
break;
case 0x05: /* Return Button Press Data */
{
@ -220,7 +388,16 @@ static Bitu INT33_Handler(void) {
mouse.max_y=reg_dx;
break;
case 0x09: /* Define GFX Cursor */
LOG_WARN("MOUSE:Define gfx cursor not supported");
{
PhysPt src = SegPhys(es)+reg_dx;
MEM_BlockRead(src ,userdefScreenMask,CURSORY*2);
MEM_BlockRead(src+CURSORY*2,userdefCursorMask,CURSORY*2);
mouse.screenMask = userdefScreenMask;
mouse.cursorMask = userdefCursorMask;
mouse.hotx = reg_bx;
mouse.hoty = reg_cx;
DrawCursor();
}
break;
case 0x0a: /* Define Text Cursor */
/* Don't see much need for supporting this */