447 lines
8.5 KiB
C++
Raw Normal View History

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
/*
* This code is based on original Mortville Manor DOS source code
* Copyright (c) 1988-1989 Lankhor
*/
#include "common/endian.h"
#include "common/rect.h"
#include "mortevielle/mouse.h"
#include "mortevielle/mortevielle.h"
#include "mortevielle/var_mor.h"
2011-12-26 22:08:18 +01:00
namespace Mortevielle {
2011-12-26 17:57:54 +00:00
const int m_arrow = 0;
const int m_point_hand = 1;
2011-12-23 19:02:50 +00:00
bool int_m, clic;
2011-12-23 19:02:50 +00:00
2011-12-26 17:57:54 +00:00
int m_show,
x_s,
y_s,
p_o_s,
mouse_shwn;
2011-12-23 19:02:50 +00:00
int s_s[12][6];
2011-12-23 19:02:50 +00:00
/**
* Initialize the mouse
* @remarks Originally called 'init_mouse'
*/
void initMouse() {
registres reg;
2011-12-23 19:02:50 +00:00
mouse_shwn = 0;
x_s = 0;
y_s = 0;
p_o_s = 0;
g_vm->setMouseClick(false);
m_show = m_arrow;
2012-03-03 09:12:15 +01:00
if ((READ_LE_UINT16(&g_mem[0xcc]) == 0) && (READ_LE_UINT16(&g_mem[0xce]) == 0))
int_m = false;
if (int_m) {
reg._ax = 0;
intr(0x33, reg);
int_m = (reg._ax == -1);
if (int_m) {
reg._ax = 4;
reg._cx = 0;
reg._dx = 0;
intr(0x33, reg);
}
}
2011-12-23 19:02:50 +00:00
}
/**
* Hide the mouse
* @remarks Originally called 'hide_mouse'
*/
void hideMouse() {
2012-02-21 23:09:29 +01:00
--mouse_shwn;
if (mouse_shwn == 0) {
bool imp = odd(y_s);
int j = p_o_s;
switch (g_vm->_currGraphicalDevice) {
case MODE_CGA: {
int k = 0;
2011-12-30 22:09:59 +11:00
j = ((uint)y_s >> 1) * 80 + ((uint)x_s >> 2);
do {
2012-03-03 09:12:15 +01:00
WRITE_LE_UINT16(&g_mem[0xb000 * 16 + j], s_s[0][k]);
WRITE_LE_UINT16(&g_mem[0xb800 * 16 + j + 2], s_s[1][k]);
WRITE_LE_UINT16(&g_mem[0xba00 * 16 + j], s_s[2][k]);
WRITE_LE_UINT16(&g_mem[0xba00 * 16 + j + 2], s_s[3][k]);
j += 80;
2012-02-21 23:09:29 +01:00
++k;
} while (k < 5);
}
break;
case MODE_AMSTRAD1512:
for (int i = 0; i <= 3; ++i) {
2012-03-03 09:12:15 +01:00
g_port[0x3dd] = 1 << i;
int k = 0;
j = p_o_s;
do {
if (imp) {
2012-03-03 09:12:15 +01:00
WRITE_LE_UINT16(&g_mem[0xb800 * 16 + j], s_s[i][k]);
j += 80 - 0x2000;
} else {
2012-03-03 09:12:15 +01:00
WRITE_LE_UINT16(&g_mem[0xb800 * 16 + j], s_s[i][k]);
j += 0x2000;
}
imp = !imp;
2012-02-21 23:09:29 +01:00
++k;
} while (k < 8);
}
break;
case MODE_EGA: {
2012-03-03 09:12:15 +01:00
g_port[0x3c4] = 2;
g_port[0x3ce] = 8;
g_port[0x3cf] = 255;
int i = 0;
do {
2012-03-03 09:12:15 +01:00
g_port[0x3c5] = 1 << i;
int k = 0;
j = p_o_s;
do {
// Useless ?
// ps = mem[0xa000 * 16 + j];
2012-03-03 09:12:15 +01:00
g_mem[0xa000 * 16 + j] = lo(s_s[i][k]);
// Useless ??
// ps = mem[0xa000 * 16 + j + 1];
2012-03-03 09:12:15 +01:00
g_mem[0xa000 * 16 + j + 1] = hi(s_s[i][k]);
j += 80;
2012-02-21 23:09:29 +01:00
++k;
} while (k < 8);
++i;
} while (i != 4);
}
break;
case MODE_HERCULES:
2011-12-30 22:09:59 +11:00
j = ((uint)y_s >> 1) * 80 + ((uint)x_s >> 3);
for (int i = 0; i <= 5; ++i) {
for (int k = 0; k <= 3; ++k)
2012-03-03 09:12:15 +01:00
WRITE_LE_UINT16(&g_mem[0xb000 * 16 + k * 0x200 + j], s_s[i][k]);
j += 80;
}
break;
case MODE_TANDY: {
2011-12-30 22:09:59 +11:00
j = ((uint)y_s >> 2) * 160 + ((uint)x_s >> 1);
int k = 0;
do {
for (int i = 0; i <= 3; ++i) {
2012-03-03 09:12:15 +01:00
WRITE_LE_UINT16(&g_mem[0xb800 * 16 + 0x200 * i + j], s_s[k][i + (k << 2)]);
WRITE_LE_UINT16(&g_mem[0xb800 * 16 + 0x200 * i + j + 2], s_s[k + 3][i + (k << 2)]);
}
j += 160;
2012-02-21 23:09:29 +01:00
++k;
} while (k != 3);
}
break;
default:
break;
} // case Gd
}
2011-12-23 19:02:50 +00:00
}
/**
* Show mouse
* @remarks Originally called 'show_mouse'
*/
void showMouse() {
int k, l;
2011-12-23 19:02:50 +00:00
mouse_shwn = mouse_shwn + 1;
if (mouse_shwn != 1)
return;
int j = p_o_s;
bool imp = odd(y_s);
int i = x_s & 7;
switch (g_vm->_currGraphicalDevice) {
case MODE_CGA:
k = 0;
2011-12-30 22:09:59 +11:00
j = ((uint)y_s >> 1) * 80 + ((uint)x_s >> 2);
do {
2012-03-03 09:12:15 +01:00
s_s[0][k] = READ_LE_UINT16(&g_mem[0xb800 * 16 + j]);
s_s[1][k] = READ_LE_UINT16(&g_mem[0xb800 * 16 + j + 2]);
s_s[2][k] = READ_LE_UINT16(&g_mem[0xba00 * 16 + j]);
s_s[3][k] = READ_LE_UINT16(&g_mem[0xba00 * 16 + j + 2]);
j += 80;
2012-02-21 23:09:29 +01:00
++k;
} while (k < 5);
break;
case MODE_AMSTRAD1512:
for (i = 0; i <= 3; ++i) {
j = p_o_s;
imp = odd(y_s);
2012-03-03 09:12:15 +01:00
g_port[0x3de] = i;
k = 0;
do {
if (imp) {
2012-03-03 09:12:15 +01:00
s_s[i][k] = READ_LE_UINT16(&g_mem[0xb800 * 16 + j]);
j += 80 - 0x2000;
} else {
2012-03-03 09:12:15 +01:00
s_s[i][k] = READ_LE_UINT16(&g_mem[0xb800 * 16 + j]);
j += 0x2000;
}
imp = !imp;
2012-02-21 23:09:29 +01:00
++k;
} while (k < 8);
}
break;
case MODE_EGA:
2012-03-03 09:12:15 +01:00
g_port[0x3ce] = 4;
l = 0;
do {
2012-03-03 09:12:15 +01:00
g_port[0x3cf] = l;
k = 0;
j = p_o_s;
do {
2012-03-03 09:12:15 +01:00
s_s[l][k] = g_mem[0xa000 * 16 + j] + (g_mem[(0xa000 * 16) + j + 1] << 8);
j += 80;
2012-02-21 23:09:29 +01:00
++k;
} while (k < 8);
++l;
} while (l != 4);
break;
case MODE_HERCULES:
2011-12-30 22:09:59 +11:00
j = ((uint)y_s >> 1) * 80 + ((uint)x_s >> 3);
for (i = 0; i <= 5; ++i) {
for (k = 0; k <= 3; ++k)
2012-03-03 09:12:15 +01:00
s_s[i][k] = READ_LE_UINT16(&g_mem[0xb000 * 16 + k * 0x200 + j]);
j += 80;
}
break;
case MODE_TANDY:
2011-12-30 22:09:59 +11:00
j = ((uint)y_s >> 2) * 160 + ((uint)x_s >> 1);
k = 0;
do {
for (i = 0; i <= 3; ++i) {
2012-03-03 09:12:15 +01:00
s_s[k][i + (k << 2)] = READ_LE_UINT16(&g_mem[0xb800 * 16 + 0x200 * i + j]);
s_s[k + 3][i + (k << 2)] = READ_LE_UINT16(&g_mem[0xb800 * 16 + 0x200 * i + j + 2]);
}
j += 160;
2012-02-21 23:09:29 +01:00
++k;
} while (k != 3);
break;
default:
break;
} // case Gd
2011-12-23 19:02:50 +00:00
}
/**
* Set mouse position
* @remarks Originally called 'pos_mouse'
*/
void setMousePos(int x, int y) {
2012-03-02 08:38:41 +01:00
if (x > 314 * g_res)
x = 314 * g_res;
else if (x < 0)
x = 0;
if (y > 199)
y = 199;
else if (y < 0)
y = 0;
if ((x == x_s) && (y == y_s))
return;
// Set the new position
g_vm->setMousePos(Common::Point(x, y));
2011-12-23 19:02:50 +00:00
}
/**
* Get mouse poisition
* @remarks Originally called 'read_pos_mouse'
*/
void getMousePos_(int &x, int &y, int &c) {
x = g_vm->getMousePos().x;
y = g_vm->getMousePos().y;
c = g_vm->getMouseClick() ? 1 : 0;
2011-12-23 19:02:50 +00:00
}
/**
* Move mouse
* @remarks Originally called 'mov_mouse'
*/
void moveMouse(bool &funct, char &key) {
bool p_key;
char in1, in2;
int cx, cy, cd;
2011-12-23 19:02:50 +00:00
// Set defaults and check pending events
funct = false;
key = '\377';
2012-03-18 09:44:05 +01:00
p_key = g_vm->keyPressed();
// If mouse button clicked, return it
if (g_vm->getMouseClick())
return;
// Handle any pending keypresses
while (p_key) {
CHECK_QUIT;
2012-03-18 09:44:05 +01:00
in1 = g_vm->getChar();
getMousePos_(cx, cy, cd);
switch (toupper(in1)) {
case '4':
cx = cx - 8;
break;
case '2':
cy = cy + 8;
break;
case '6':
cx = cx + 8;
break;
case '8':
cy = cy - 8;
break;
case '7':
cy = 1;
cx = 1;
break;
case '1':
cx = 1;
cy = 190;
break;
case '9':
2012-03-02 08:38:41 +01:00
cx = 315 * g_res;
cy = 1;
break;
case '3':
cy = 190;
2012-03-02 08:38:41 +01:00
cx = 315 * g_res;
break;
case '5':
cy = 100;
2012-03-02 08:38:41 +01:00
cx = 155 * g_res;
break;
case ' ':
case '\15':
g_vm->setMouseClick(true);
return;
break;
case '\33':
2012-03-18 09:44:05 +01:00
p_key = g_vm->keyPressed();
if (p_key) {
2012-03-18 09:44:05 +01:00
in2 = g_vm->getChar();
if ((in2 >= ';') && (in2 <= 'D')) {
funct = true;
key = in2;
return;
} else {
switch (in2) {
case 'K':
2012-02-21 23:09:29 +01:00
--cx;
break;
case 'P':
2012-02-21 23:09:29 +01:00
++cy;
break;
case 'M':
cx += 2;
break;
case 'H':
2012-02-21 23:09:29 +01:00
--cy;
break;
case 'G':
--cx;
--cy;
break;
case 'I':
++cx;
--cy;
break;
case 'O':
--cx;
++cy;
break;
case 'Q':
++cx;
++cy;
break;
default:
break;
} // case
}
}
break;
case 'I':
2012-03-02 08:38:41 +01:00
cx = g_res * 32;
cy = 8;
break;
case 'D':
2012-03-02 08:38:41 +01:00
cx = 80 * g_res;
cy = 8;
break;
case 'A':
2012-03-02 08:38:41 +01:00
cx = 126 * g_res;
cy = 8;
break;
case 'S':
2012-03-02 08:38:41 +01:00
cx = 174 * g_res;
cy = 8;
break;
case 'P':
2012-03-02 08:38:41 +01:00
cx = 222 * g_res;
cy = 8;
break;
case 'F':
2012-03-02 08:38:41 +01:00
cx = g_res * 270;
cy = 8;
break;
case '\23':
g_vm->_soundOff = !g_vm->_soundOff;
return;
break;
case '\24': // ^T => mode tandy
funct = true;
key = '\11';
break;
case '\10': // ^H => mode Hercule
funct = true;
key = '\7';
break;
case '\1':
case '\3':
case '\5':
funct = true;
key = in1;
break;
default:
break;
}
setMousePos(cx, cy);
2012-03-18 09:44:05 +01:00
p_key = g_vm->keyPressed();
}
}
2011-12-26 22:08:18 +01:00
} // End of namespace Mortevielle