mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
313 lines
8.1 KiB
C++
313 lines
8.1 KiB
C++
/* 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.
|
|
*
|
|
*/
|
|
|
|
//include <cctype>
|
|
#include "ags/shared/util/wgt2allg.h"
|
|
#include "ags/shared/ac/common.h"
|
|
#include "ags/engine/ac/draw.h"
|
|
#include "ags/engine/ac/gamesetup.h"
|
|
#include "ags/engine/ac/gamestate.h"
|
|
#include "ags/engine/ac/gui.h"
|
|
#include "ags/engine/ac/keycode.h"
|
|
#include "ags/engine/ac/mouse.h"
|
|
#include "ags/engine/ac/sys_events.h"
|
|
#include "ags/engine/ac/runtime_defines.h"
|
|
#include "ags/shared/font/fonts.h"
|
|
#include "ags/engine/gui/cscidialog.h"
|
|
#include "ags/engine/gui/guidialog.h"
|
|
#include "ags/shared/gui/guimain.h"
|
|
#include "ags/engine/gui/mycontrols.h"
|
|
#include "ags/engine/main/game_run.h"
|
|
#include "ags/engine/gfx/graphicsdriver.h"
|
|
#include "ags/shared/gfx/bitmap.h"
|
|
#include "ags/engine/media/audio/audio_system.h"
|
|
#include "ags/engine/platform/base/agsplatformdriver.h"
|
|
#include "ags/engine/ac/timer.h"
|
|
#include "ags/globals.h"
|
|
|
|
namespace AGS3 {
|
|
|
|
using AGS::Shared::Bitmap;
|
|
namespace BitmapHelper = AGS::Shared::BitmapHelper;
|
|
|
|
extern IGraphicsDriver *gfxDriver;
|
|
extern GameSetup usetup;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// DIALOG SYSTEM STUFF below
|
|
|
|
int windowbackgroundcolor = COL254, pushbuttondarkcolor = COL255;
|
|
int pushbuttonlightcolor = COL253;
|
|
int topwindowhandle = -1;
|
|
int cbuttfont;
|
|
|
|
int acdialog_font;
|
|
|
|
int smcode = 0;
|
|
|
|
#define MAXCONTROLS 20
|
|
#define MAXSCREENWINDOWS 5
|
|
NewControl *vobjs[MAXCONTROLS];
|
|
OnScreenWindow oswi[MAXSCREENWINDOWS];
|
|
|
|
int controlid = 0;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void __my_wbutt(Bitmap *ds, int x1, int y1, int x2, int y2) {
|
|
color_t draw_color = ds->GetCompatibleColor(COL254); //wsetcolor(15);
|
|
ds->FillRect(Rect(x1, y1, x2, y2), draw_color);
|
|
draw_color = ds->GetCompatibleColor(0);
|
|
ds->DrawRect(Rect(x1, y1, x2, y2), draw_color);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
OnScreenWindow::OnScreenWindow() {
|
|
x = y = 0;
|
|
handle = -1;
|
|
oldtop = -1;
|
|
}
|
|
|
|
int CSCIGetVersion() {
|
|
return 0x0100;
|
|
}
|
|
|
|
int windowcount = 0, curswas = 0;
|
|
int win_x = 0, win_y = 0, win_width = 0, win_height = 0;
|
|
int CSCIDrawWindow(int xx, int yy, int wid, int hit) {
|
|
_G(ignore_bounds)++;
|
|
multiply_up(&xx, &yy, &wid, &hit);
|
|
int drawit = -1;
|
|
for (int aa = 0; aa < MAXSCREENWINDOWS; aa++) {
|
|
if (oswi[aa].handle < 0) {
|
|
drawit = aa;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (drawit < 0)
|
|
quit("Too many windows created.");
|
|
|
|
windowcount++;
|
|
// ags_domouse(DOMOUSE_DISABLE);
|
|
xx -= 2;
|
|
yy -= 2;
|
|
wid += 4;
|
|
hit += 4;
|
|
Bitmap *ds = prepare_gui_screen(xx, yy, wid, hit, true);
|
|
oswi[drawit].x = xx;
|
|
oswi[drawit].y = yy;
|
|
__my_wbutt(ds, 0, 0, wid - 1, hit - 1); // wbutt goes outside its area
|
|
// ags_domouse(DOMOUSE_ENABLE);
|
|
oswi[drawit].oldtop = topwindowhandle;
|
|
topwindowhandle = drawit;
|
|
oswi[drawit].handle = topwindowhandle;
|
|
win_x = xx;
|
|
win_y = yy;
|
|
win_width = wid;
|
|
win_height = hit;
|
|
return drawit;
|
|
}
|
|
|
|
void CSCIEraseWindow(int handl) {
|
|
// ags_domouse(DOMOUSE_DISABLE);
|
|
_G(ignore_bounds)--;
|
|
topwindowhandle = oswi[handl].oldtop;
|
|
oswi[handl].handle = -1;
|
|
// ags_domouse(DOMOUSE_ENABLE);
|
|
windowcount--;
|
|
clear_gui_screen();
|
|
}
|
|
|
|
int CSCIWaitMessage(CSCIMessage *cscim) {
|
|
for (int uu = 0; uu < MAXCONTROLS; uu++) {
|
|
if (vobjs[uu] != nullptr) {
|
|
// ags_domouse(DOMOUSE_DISABLE);
|
|
vobjs[uu]->drawifneeded();
|
|
// ags_domouse(DOMOUSE_ENABLE);
|
|
}
|
|
}
|
|
|
|
prepare_gui_screen(win_x, win_y, win_width, win_height, true);
|
|
|
|
while (1) {
|
|
update_audio_system_on_game_loop();
|
|
refresh_gui_screen();
|
|
|
|
cscim->id = -1;
|
|
cscim->code = 0;
|
|
smcode = 0;
|
|
int keywas;
|
|
if (run_service_key_controls(keywas) && !_GP(play).IsIgnoringInput()) {
|
|
if (keywas == 13) {
|
|
cscim->id = finddefaultcontrol(CNF_DEFAULT);
|
|
cscim->code = CM_COMMAND;
|
|
} else if (keywas == 27) {
|
|
cscim->id = finddefaultcontrol(CNF_CANCEL);
|
|
cscim->code = CM_COMMAND;
|
|
} else if ((keywas < 32) && (keywas != 8));
|
|
else if ((keywas >= 372) & (keywas <= 381) & (finddefaultcontrol(CNT_LISTBOX) >= 0))
|
|
vobjs[finddefaultcontrol(CNT_LISTBOX)]->processmessage(CTB_KEYPRESS, keywas, 0);
|
|
else if (finddefaultcontrol(CNT_TEXTBOX) >= 0)
|
|
vobjs[finddefaultcontrol(CNT_TEXTBOX)]->processmessage(CTB_KEYPRESS, keywas, 0);
|
|
|
|
if (cscim->id < 0) {
|
|
cscim->code = CM_KEYPRESS;
|
|
cscim->wParam = keywas;
|
|
}
|
|
}
|
|
|
|
int mbut, mwheelz;
|
|
if (run_service_mb_controls(mbut, mwheelz) && mbut >= 0 && !_GP(play).IsIgnoringInput()) {
|
|
if (checkcontrols()) {
|
|
cscim->id = controlid;
|
|
cscim->code = CM_COMMAND;
|
|
}
|
|
}
|
|
|
|
if (smcode) {
|
|
cscim->code = smcode;
|
|
cscim->id = controlid;
|
|
}
|
|
|
|
if (cscim->code > 0)
|
|
break;
|
|
|
|
WaitForNextFrame();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CSCICreateControl(int typeandflags, int xx, int yy, int wii, int hii, const char *title) {
|
|
multiply_up(&xx, &yy, &wii, &hii);
|
|
int usec = -1;
|
|
for (int hh = 1; hh < MAXCONTROLS; hh++) {
|
|
if (vobjs[hh] == nullptr) {
|
|
usec = hh;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (usec < 0)
|
|
quit("Too many controls created");
|
|
|
|
int type = typeandflags & 0x00ff; // 256 control types
|
|
if (type == CNT_PUSHBUTTON) {
|
|
if (wii == -1)
|
|
wii = wgettextwidth(title, cbuttfont) + 20;
|
|
|
|
vobjs[usec] = new MyPushButton(xx, yy, wii, hii, title);
|
|
|
|
} else if (type == CNT_LISTBOX) {
|
|
vobjs[usec] = new MyListBox(xx, yy, wii, hii);
|
|
} else if (type == CNT_LABEL) {
|
|
vobjs[usec] = new MyLabel(xx, yy, wii, title);
|
|
} else if (type == CNT_TEXTBOX) {
|
|
vobjs[usec] = new MyTextBox(xx, yy, wii, title);
|
|
} else
|
|
quit("Unknown control type requested");
|
|
|
|
vobjs[usec]->typeandflags = typeandflags;
|
|
vobjs[usec]->wlevel = topwindowhandle;
|
|
// ags_domouse(DOMOUSE_DISABLE);
|
|
vobjs[usec]->draw(get_gui_screen());
|
|
// ags_domouse(DOMOUSE_ENABLE);
|
|
return usec;
|
|
}
|
|
|
|
void CSCIDeleteControl(int haa) {
|
|
delete vobjs[haa];
|
|
vobjs[haa] = nullptr;
|
|
}
|
|
|
|
int CSCISendControlMessage(int haa, int mess, int wPar, NumberPtr lPar) {
|
|
if (vobjs[haa] == nullptr)
|
|
return -1;
|
|
return vobjs[haa]->processmessage(mess, wPar, lPar);
|
|
}
|
|
|
|
void multiply_up_to_game_res(int *x, int *y) {
|
|
x[0] = get_fixed_pixel_size(x[0]);
|
|
y[0] = get_fixed_pixel_size(y[0]);
|
|
}
|
|
|
|
// TODO: this is silly, make a uniform formula
|
|
void multiply_up(int *x1, int *y1, int *x2, int *y2) {
|
|
multiply_up_to_game_res(x1, y1);
|
|
multiply_up_to_game_res(x2, y2);
|
|
|
|
// adjust for 800x600
|
|
if ((GetBaseWidth() == 400) || (GetBaseWidth() == 800)) {
|
|
x1[0] = (x1[0] * 5) / 4;
|
|
x2[0] = (x2[0] * 5) / 4;
|
|
y1[0] = (y1[0] * 3) / 2;
|
|
y2[0] = (y2[0] * 3) / 2;
|
|
} else if (GetBaseWidth() == 1024) {
|
|
x1[0] = (x1[0] * 16) / 10;
|
|
x2[0] = (x2[0] * 16) / 10;
|
|
y1[0] = (y1[0] * 384) / 200;
|
|
y2[0] = (y2[0] * 384) / 200;
|
|
}
|
|
}
|
|
|
|
int checkcontrols() {
|
|
// NOTE: this is because old code was working with full game screen
|
|
const int mouseX = _G(mousex) - win_x;
|
|
const int mouseY = _G(mousey) - win_y;
|
|
|
|
smcode = 0;
|
|
for (int kk = 0; kk < MAXCONTROLS; kk++) {
|
|
if (vobjs[kk] != nullptr) {
|
|
if (vobjs[kk]->mouseisinarea(mouseX, mouseY)) {
|
|
controlid = kk;
|
|
return vobjs[kk]->pressedon(mouseX, mouseY);
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int finddefaultcontrol(int flagmask) {
|
|
for (int ff = 0; ff < MAXCONTROLS; ff++) {
|
|
if (vobjs[ff] == nullptr)
|
|
continue;
|
|
|
|
if (vobjs[ff]->wlevel != topwindowhandle)
|
|
continue;
|
|
|
|
if (vobjs[ff]->typeandflags & flagmask)
|
|
return ff;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int GetBaseWidth() {
|
|
return _GP(play).GetUIViewport().GetWidth();
|
|
}
|
|
|
|
} // namespace AGS3
|